Commit 8b6f92b1 authored by David S. Miller's avatar David S. Miller
parents 467388f2 325fb5b4
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#define _XT_NFLOG_TARGET #define _XT_NFLOG_TARGET
#define XT_NFLOG_DEFAULT_GROUP 0x1 #define XT_NFLOG_DEFAULT_GROUP 0x1
#define XT_NFLOG_DEFAULT_THRESHOLD 1 #define XT_NFLOG_DEFAULT_THRESHOLD 0
#define XT_NFLOG_MASK 0x0 #define XT_NFLOG_MASK 0x0
......
...@@ -59,7 +59,7 @@ static inline int nf_conntrack_confirm(struct sk_buff *skb) ...@@ -59,7 +59,7 @@ static inline int nf_conntrack_confirm(struct sk_buff *skb)
struct nf_conn *ct = (struct nf_conn *)skb->nfct; struct nf_conn *ct = (struct nf_conn *)skb->nfct;
int ret = NF_ACCEPT; int ret = NF_ACCEPT;
if (ct) { if (ct && ct != &nf_conntrack_untracked) {
if (!nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct)) if (!nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct))
ret = __nf_conntrack_confirm(skb); ret = __nf_conntrack_confirm(skb);
nf_ct_deliver_cached_events(ct); nf_ct_deliver_cached_events(ct);
......
...@@ -201,8 +201,9 @@ icmpv6_error(struct net *net, struct sk_buff *skb, unsigned int dataoff, ...@@ -201,8 +201,9 @@ icmpv6_error(struct net *net, struct sk_buff *skb, unsigned int dataoff,
if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING && if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
nf_ip6_checksum(skb, hooknum, dataoff, IPPROTO_ICMPV6)) { nf_ip6_checksum(skb, hooknum, dataoff, IPPROTO_ICMPV6)) {
nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL, if (LOG_INVALID(net, IPPROTO_ICMPV6))
"nf_ct_icmpv6: ICMPv6 checksum failed\n"); nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL,
"nf_ct_icmpv6: ICMPv6 checksum failed ");
return -NF_ACCEPT; return -NF_ACCEPT;
} }
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
#endif #endif
#define NFULNL_NLBUFSIZ_DEFAULT NLMSG_GOODSIZE #define NFULNL_NLBUFSIZ_DEFAULT NLMSG_GOODSIZE
#define NFULNL_TIMEOUT_DEFAULT HZ /* every second */ #define NFULNL_TIMEOUT_DEFAULT 100 /* every second */
#define NFULNL_QTHRESH_DEFAULT 100 /* 100 packets */ #define NFULNL_QTHRESH_DEFAULT 100 /* 100 packets */
#define NFULNL_COPY_RANGE_MAX 0xFFFF /* max packet size is limited by 16-bit struct nfattr nfa_len field */ #define NFULNL_COPY_RANGE_MAX 0xFFFF /* max packet size is limited by 16-bit struct nfattr nfa_len field */
...@@ -590,8 +590,10 @@ nfulnl_log_packet(u_int8_t pf, ...@@ -590,8 +590,10 @@ nfulnl_log_packet(u_int8_t pf,
qthreshold = inst->qthreshold; qthreshold = inst->qthreshold;
/* per-rule qthreshold overrides per-instance */ /* per-rule qthreshold overrides per-instance */
if (qthreshold > li->u.ulog.qthreshold) if (li->u.ulog.qthreshold)
qthreshold = li->u.ulog.qthreshold; if (qthreshold > li->u.ulog.qthreshold)
qthreshold = li->u.ulog.qthreshold;
switch (inst->copy_mode) { switch (inst->copy_mode) {
case NFULNL_COPY_META: case NFULNL_COPY_META:
......
...@@ -827,59 +827,143 @@ static const struct file_operations xt_table_ops = { ...@@ -827,59 +827,143 @@ static const struct file_operations xt_table_ops = {
.release = seq_release_net, .release = seq_release_net,
}; };
static void *xt_match_seq_start(struct seq_file *seq, loff_t *pos) /*
* Traverse state for ip{,6}_{tables,matches} for helping crossing
* the multi-AF mutexes.
*/
struct nf_mttg_trav {
struct list_head *head, *curr;
uint8_t class, nfproto;
};
enum {
MTTG_TRAV_INIT,
MTTG_TRAV_NFP_UNSPEC,
MTTG_TRAV_NFP_SPEC,
MTTG_TRAV_DONE,
};
static void *xt_mttg_seq_next(struct seq_file *seq, void *v, loff_t *ppos,
bool is_target)
{ {
struct proc_dir_entry *pde = (struct proc_dir_entry *)seq->private; static const uint8_t next_class[] = {
u_int16_t af = (unsigned long)pde->data; [MTTG_TRAV_NFP_UNSPEC] = MTTG_TRAV_NFP_SPEC,
[MTTG_TRAV_NFP_SPEC] = MTTG_TRAV_DONE,
};
struct nf_mttg_trav *trav = seq->private;
switch (trav->class) {
case MTTG_TRAV_INIT:
trav->class = MTTG_TRAV_NFP_UNSPEC;
mutex_lock(&xt[NFPROTO_UNSPEC].mutex);
trav->head = trav->curr = is_target ?
&xt[NFPROTO_UNSPEC].target : &xt[NFPROTO_UNSPEC].match;
break;
case MTTG_TRAV_NFP_UNSPEC:
trav->curr = trav->curr->next;
if (trav->curr != trav->head)
break;
mutex_unlock(&xt[NFPROTO_UNSPEC].mutex);
mutex_lock(&xt[trav->nfproto].mutex);
trav->head = trav->curr = is_target ?
&xt[trav->nfproto].target : &xt[trav->nfproto].match;
trav->class = next_class[trav->class];
break;
case MTTG_TRAV_NFP_SPEC:
trav->curr = trav->curr->next;
if (trav->curr != trav->head)
break;
/* fallthru, _stop will unlock */
default:
return NULL;
}
mutex_lock(&xt[af].mutex); if (ppos != NULL)
return seq_list_start(&xt[af].match, *pos); ++*ppos;
return trav;
} }
static void *xt_match_seq_next(struct seq_file *seq, void *v, loff_t *pos) static void *xt_mttg_seq_start(struct seq_file *seq, loff_t *pos,
bool is_target)
{ {
struct proc_dir_entry *pde = (struct proc_dir_entry *)seq->private; struct nf_mttg_trav *trav = seq->private;
u_int16_t af = (unsigned long)pde->data; unsigned int j;
return seq_list_next(v, &xt[af].match, pos); trav->class = MTTG_TRAV_INIT;
for (j = 0; j < *pos; ++j)
if (xt_mttg_seq_next(seq, NULL, NULL, is_target) == NULL)
return NULL;
return trav;
} }
static void xt_match_seq_stop(struct seq_file *seq, void *v) static void xt_mttg_seq_stop(struct seq_file *seq, void *v)
{ {
struct proc_dir_entry *pde = seq->private; struct nf_mttg_trav *trav = seq->private;
u_int16_t af = (unsigned long)pde->data;
switch (trav->class) {
case MTTG_TRAV_NFP_UNSPEC:
mutex_unlock(&xt[NFPROTO_UNSPEC].mutex);
break;
case MTTG_TRAV_NFP_SPEC:
mutex_unlock(&xt[trav->nfproto].mutex);
break;
}
}
mutex_unlock(&xt[af].mutex); static void *xt_match_seq_start(struct seq_file *seq, loff_t *pos)
{
return xt_mttg_seq_start(seq, pos, false);
} }
static int xt_match_seq_show(struct seq_file *seq, void *v) static void *xt_match_seq_next(struct seq_file *seq, void *v, loff_t *ppos)
{ {
struct xt_match *match = list_entry(v, struct xt_match, list); return xt_mttg_seq_next(seq, v, ppos, false);
}
if (strlen(match->name)) static int xt_match_seq_show(struct seq_file *seq, void *v)
return seq_printf(seq, "%s\n", match->name); {
else const struct nf_mttg_trav *trav = seq->private;
return 0; const struct xt_match *match;
switch (trav->class) {
case MTTG_TRAV_NFP_UNSPEC:
case MTTG_TRAV_NFP_SPEC:
if (trav->curr == trav->head)
return 0;
match = list_entry(trav->curr, struct xt_match, list);
return (*match->name == '\0') ? 0 :
seq_printf(seq, "%s\n", match->name);
}
return 0;
} }
static const struct seq_operations xt_match_seq_ops = { static const struct seq_operations xt_match_seq_ops = {
.start = xt_match_seq_start, .start = xt_match_seq_start,
.next = xt_match_seq_next, .next = xt_match_seq_next,
.stop = xt_match_seq_stop, .stop = xt_mttg_seq_stop,
.show = xt_match_seq_show, .show = xt_match_seq_show,
}; };
static int xt_match_open(struct inode *inode, struct file *file) static int xt_match_open(struct inode *inode, struct file *file)
{ {
struct seq_file *seq;
struct nf_mttg_trav *trav;
int ret; int ret;
ret = seq_open(file, &xt_match_seq_ops); trav = kmalloc(sizeof(*trav), GFP_KERNEL);
if (!ret) { if (trav == NULL)
struct seq_file *seq = file->private_data; return -ENOMEM;
seq->private = PDE(inode); ret = seq_open(file, &xt_match_seq_ops);
if (ret < 0) {
kfree(trav);
return ret;
} }
return ret;
seq = file->private_data;
seq->private = trav;
trav->nfproto = (unsigned long)PDE(inode)->data;
return 0;
} }
static const struct file_operations xt_match_ops = { static const struct file_operations xt_match_ops = {
...@@ -887,62 +971,63 @@ static const struct file_operations xt_match_ops = { ...@@ -887,62 +971,63 @@ static const struct file_operations xt_match_ops = {
.open = xt_match_open, .open = xt_match_open,
.read = seq_read, .read = seq_read,
.llseek = seq_lseek, .llseek = seq_lseek,
.release = seq_release, .release = seq_release_private,
}; };
static void *xt_target_seq_start(struct seq_file *seq, loff_t *pos) static void *xt_target_seq_start(struct seq_file *seq, loff_t *pos)
{ {
struct proc_dir_entry *pde = (struct proc_dir_entry *)seq->private; return xt_mttg_seq_start(seq, pos, true);
u_int16_t af = (unsigned long)pde->data;
mutex_lock(&xt[af].mutex);
return seq_list_start(&xt[af].target, *pos);
} }
static void *xt_target_seq_next(struct seq_file *seq, void *v, loff_t *pos) static void *xt_target_seq_next(struct seq_file *seq, void *v, loff_t *ppos)
{ {
struct proc_dir_entry *pde = (struct proc_dir_entry *)seq->private; return xt_mttg_seq_next(seq, v, ppos, true);
u_int16_t af = (unsigned long)pde->data;
return seq_list_next(v, &xt[af].target, pos);
}
static void xt_target_seq_stop(struct seq_file *seq, void *v)
{
struct proc_dir_entry *pde = seq->private;
u_int16_t af = (unsigned long)pde->data;
mutex_unlock(&xt[af].mutex);
} }
static int xt_target_seq_show(struct seq_file *seq, void *v) static int xt_target_seq_show(struct seq_file *seq, void *v)
{ {
struct xt_target *target = list_entry(v, struct xt_target, list); const struct nf_mttg_trav *trav = seq->private;
const struct xt_target *target;
if (strlen(target->name))
return seq_printf(seq, "%s\n", target->name); switch (trav->class) {
else case MTTG_TRAV_NFP_UNSPEC:
return 0; case MTTG_TRAV_NFP_SPEC:
if (trav->curr == trav->head)
return 0;
target = list_entry(trav->curr, struct xt_target, list);
return (*target->name == '\0') ? 0 :
seq_printf(seq, "%s\n", target->name);
}
return 0;
} }
static const struct seq_operations xt_target_seq_ops = { static const struct seq_operations xt_target_seq_ops = {
.start = xt_target_seq_start, .start = xt_target_seq_start,
.next = xt_target_seq_next, .next = xt_target_seq_next,
.stop = xt_target_seq_stop, .stop = xt_mttg_seq_stop,
.show = xt_target_seq_show, .show = xt_target_seq_show,
}; };
static int xt_target_open(struct inode *inode, struct file *file) static int xt_target_open(struct inode *inode, struct file *file)
{ {
struct seq_file *seq;
struct nf_mttg_trav *trav;
int ret; int ret;
ret = seq_open(file, &xt_target_seq_ops); trav = kmalloc(sizeof(*trav), GFP_KERNEL);
if (!ret) { if (trav == NULL)
struct seq_file *seq = file->private_data; return -ENOMEM;
seq->private = PDE(inode); ret = seq_open(file, &xt_target_seq_ops);
if (ret < 0) {
kfree(trav);
return ret;
} }
return ret;
seq = file->private_data;
seq->private = trav;
trav->nfproto = (unsigned long)PDE(inode)->data;
return 0;
} }
static const struct file_operations xt_target_ops = { static const struct file_operations xt_target_ops = {
...@@ -950,7 +1035,7 @@ static const struct file_operations xt_target_ops = { ...@@ -950,7 +1035,7 @@ static const struct file_operations xt_target_ops = {
.open = xt_target_open, .open = xt_target_open,
.read = seq_read, .read = seq_read,
.llseek = seq_lseek, .llseek = seq_lseek,
.release = seq_release, .release = seq_release_private,
}; };
#define FORMAT_TABLES "_tables_names" #define FORMAT_TABLES "_tables_names"
......
...@@ -542,7 +542,7 @@ recent_mt_proc_write(struct file *file, const char __user *input, ...@@ -542,7 +542,7 @@ recent_mt_proc_write(struct file *file, const char __user *input,
struct recent_entry *e; struct recent_entry *e;
char buf[sizeof("+b335:1d35:1e55:dead:c0de:1715:5afe:c0de")]; char buf[sizeof("+b335:1d35:1e55:dead:c0de:1715:5afe:c0de")];
const char *c = buf; const char *c = buf;
union nf_inet_addr addr; union nf_inet_addr addr = {};
u_int16_t family; u_int16_t family;
bool add, succ; bool add, succ;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment