diff options
author | David S. Miller <davem@davemloft.net> | 2016-06-10 14:52:24 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-06-10 14:52:24 -0400 |
commit | 1578b0a5e92825334760741e5c166b8873886f1b (patch) | |
tree | ac8299191f37990111f7d4b615601f4356e24fea /net/netfilter | |
parent | 3d5479e92087f6249231e26a2d7327e86a8d0dfc (diff) | |
parent | 698ea54dde6768d4a96080d0fb796cb3a4eadaf8 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts:
net/sched/act_police.c
net/sched/sch_drr.c
net/sched/sch_hfsc.c
net/sched/sch_prio.c
net/sched/sch_red.c
net/sched/sch_tbf.c
In net-next the drop methods of the packet schedulers got removed, so
the bug fixes to them in 'net' are irrelevant.
A packet action unload crash fix conflicts with the addition of the
new firstuse timestamp.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/netfilter')
-rw-r--r-- | net/netfilter/ipvs/ip_vs_conn.c | 5 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_core.c | 5 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_ftp.c | 1 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_helper.c | 9 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_irc.c | 1 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_sane.c | 1 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_sip.c | 1 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_standalone.c | 2 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_tftp.c | 1 | ||||
-rw-r--r-- | net/netfilter/nf_queue.c | 17 | ||||
-rw-r--r-- | net/netfilter/nf_tables_api.c | 2 | ||||
-rw-r--r-- | net/netfilter/nfnetlink_queue.c | 20 | ||||
-rw-r--r-- | net/netfilter/x_tables.c | 4 |
13 files changed, 40 insertions, 29 deletions
diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c index 2cb3c626cd43..096a45103f14 100644 --- a/net/netfilter/ipvs/ip_vs_conn.c +++ b/net/netfilter/ipvs/ip_vs_conn.c | |||
@@ -762,7 +762,7 @@ static int expire_quiescent_template(struct netns_ipvs *ipvs, | |||
762 | * If available, return 1, otherwise invalidate this connection | 762 | * If available, return 1, otherwise invalidate this connection |
763 | * template and return 0. | 763 | * template and return 0. |
764 | */ | 764 | */ |
765 | int ip_vs_check_template(struct ip_vs_conn *ct) | 765 | int ip_vs_check_template(struct ip_vs_conn *ct, struct ip_vs_dest *cdest) |
766 | { | 766 | { |
767 | struct ip_vs_dest *dest = ct->dest; | 767 | struct ip_vs_dest *dest = ct->dest; |
768 | struct netns_ipvs *ipvs = ct->ipvs; | 768 | struct netns_ipvs *ipvs = ct->ipvs; |
@@ -772,7 +772,8 @@ int ip_vs_check_template(struct ip_vs_conn *ct) | |||
772 | */ | 772 | */ |
773 | if ((dest == NULL) || | 773 | if ((dest == NULL) || |
774 | !(dest->flags & IP_VS_DEST_F_AVAILABLE) || | 774 | !(dest->flags & IP_VS_DEST_F_AVAILABLE) || |
775 | expire_quiescent_template(ipvs, dest)) { | 775 | expire_quiescent_template(ipvs, dest) || |
776 | (cdest && (dest != cdest))) { | ||
776 | IP_VS_DBG_BUF(9, "check_template: dest not available for " | 777 | IP_VS_DBG_BUF(9, "check_template: dest not available for " |
777 | "protocol %s s:%s:%d v:%s:%d " | 778 | "protocol %s s:%s:%d v:%s:%d " |
778 | "-> d:%s:%d\n", | 779 | "-> d:%s:%d\n", |
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index 1207f20d24e4..2c1b498a7a27 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c | |||
@@ -321,7 +321,7 @@ ip_vs_sched_persist(struct ip_vs_service *svc, | |||
321 | 321 | ||
322 | /* Check if a template already exists */ | 322 | /* Check if a template already exists */ |
323 | ct = ip_vs_ct_in_get(¶m); | 323 | ct = ip_vs_ct_in_get(¶m); |
324 | if (!ct || !ip_vs_check_template(ct)) { | 324 | if (!ct || !ip_vs_check_template(ct, NULL)) { |
325 | struct ip_vs_scheduler *sched; | 325 | struct ip_vs_scheduler *sched; |
326 | 326 | ||
327 | /* | 327 | /* |
@@ -1154,7 +1154,8 @@ struct ip_vs_conn *ip_vs_new_conn_out(struct ip_vs_service *svc, | |||
1154 | vport, ¶m) < 0) | 1154 | vport, ¶m) < 0) |
1155 | return NULL; | 1155 | return NULL; |
1156 | ct = ip_vs_ct_in_get(¶m); | 1156 | ct = ip_vs_ct_in_get(¶m); |
1157 | if (!ct) { | 1157 | /* check if template exists and points to the same dest */ |
1158 | if (!ct || !ip_vs_check_template(ct, dest)) { | ||
1158 | ct = ip_vs_conn_new(¶m, dest->af, daddr, dport, | 1159 | ct = ip_vs_conn_new(¶m, dest->af, daddr, dport, |
1159 | IP_VS_CONN_F_TEMPLATE, dest, 0); | 1160 | IP_VS_CONN_F_TEMPLATE, dest, 0); |
1160 | if (!ct) { | 1161 | if (!ct) { |
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c index 883c691ec8d0..19efeba02abb 100644 --- a/net/netfilter/nf_conntrack_ftp.c +++ b/net/netfilter/nf_conntrack_ftp.c | |||
@@ -632,6 +632,7 @@ static int __init nf_conntrack_ftp_init(void) | |||
632 | if (ret) { | 632 | if (ret) { |
633 | pr_err("failed to register helper for pf: %d port: %d\n", | 633 | pr_err("failed to register helper for pf: %d port: %d\n", |
634 | ftp[i][j].tuple.src.l3num, ports[i]); | 634 | ftp[i][j].tuple.src.l3num, ports[i]); |
635 | ports_c = i; | ||
635 | nf_conntrack_ftp_fini(); | 636 | nf_conntrack_ftp_fini(); |
636 | return ret; | 637 | return ret; |
637 | } | 638 | } |
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index f703adb7e5f7..196cb39649e1 100644 --- a/net/netfilter/nf_conntrack_helper.c +++ b/net/netfilter/nf_conntrack_helper.c | |||
@@ -361,9 +361,10 @@ EXPORT_SYMBOL_GPL(nf_ct_helper_log); | |||
361 | 361 | ||
362 | int nf_conntrack_helper_register(struct nf_conntrack_helper *me) | 362 | int nf_conntrack_helper_register(struct nf_conntrack_helper *me) |
363 | { | 363 | { |
364 | int ret = 0; | 364 | struct nf_conntrack_tuple_mask mask = { .src.u.all = htons(0xFFFF) }; |
365 | struct nf_conntrack_helper *cur; | ||
366 | unsigned int h = helper_hash(&me->tuple); | 365 | unsigned int h = helper_hash(&me->tuple); |
366 | struct nf_conntrack_helper *cur; | ||
367 | int ret = 0; | ||
367 | 368 | ||
368 | BUG_ON(me->expect_policy == NULL); | 369 | BUG_ON(me->expect_policy == NULL); |
369 | BUG_ON(me->expect_class_max >= NF_CT_MAX_EXPECT_CLASSES); | 370 | BUG_ON(me->expect_class_max >= NF_CT_MAX_EXPECT_CLASSES); |
@@ -371,9 +372,7 @@ int nf_conntrack_helper_register(struct nf_conntrack_helper *me) | |||
371 | 372 | ||
372 | mutex_lock(&nf_ct_helper_mutex); | 373 | mutex_lock(&nf_ct_helper_mutex); |
373 | hlist_for_each_entry(cur, &nf_ct_helper_hash[h], hnode) { | 374 | hlist_for_each_entry(cur, &nf_ct_helper_hash[h], hnode) { |
374 | if (strncmp(cur->name, me->name, NF_CT_HELPER_NAME_LEN) == 0 && | 375 | if (nf_ct_tuple_src_mask_cmp(&cur->tuple, &me->tuple, &mask)) { |
375 | cur->tuple.src.l3num == me->tuple.src.l3num && | ||
376 | cur->tuple.dst.protonum == me->tuple.dst.protonum) { | ||
377 | ret = -EEXIST; | 376 | ret = -EEXIST; |
378 | goto out; | 377 | goto out; |
379 | } | 378 | } |
diff --git a/net/netfilter/nf_conntrack_irc.c b/net/netfilter/nf_conntrack_irc.c index 8b6da2719600..f97ac61d2536 100644 --- a/net/netfilter/nf_conntrack_irc.c +++ b/net/netfilter/nf_conntrack_irc.c | |||
@@ -271,6 +271,7 @@ static int __init nf_conntrack_irc_init(void) | |||
271 | if (ret) { | 271 | if (ret) { |
272 | pr_err("failed to register helper for pf: %u port: %u\n", | 272 | pr_err("failed to register helper for pf: %u port: %u\n", |
273 | irc[i].tuple.src.l3num, ports[i]); | 273 | irc[i].tuple.src.l3num, ports[i]); |
274 | ports_c = i; | ||
274 | nf_conntrack_irc_fini(); | 275 | nf_conntrack_irc_fini(); |
275 | return ret; | 276 | return ret; |
276 | } | 277 | } |
diff --git a/net/netfilter/nf_conntrack_sane.c b/net/netfilter/nf_conntrack_sane.c index 7523a575f6d1..3fcbaab83b3d 100644 --- a/net/netfilter/nf_conntrack_sane.c +++ b/net/netfilter/nf_conntrack_sane.c | |||
@@ -223,6 +223,7 @@ static int __init nf_conntrack_sane_init(void) | |||
223 | if (ret) { | 223 | if (ret) { |
224 | pr_err("failed to register helper for pf: %d port: %d\n", | 224 | pr_err("failed to register helper for pf: %d port: %d\n", |
225 | sane[i][j].tuple.src.l3num, ports[i]); | 225 | sane[i][j].tuple.src.l3num, ports[i]); |
226 | ports_c = i; | ||
226 | nf_conntrack_sane_fini(); | 227 | nf_conntrack_sane_fini(); |
227 | return ret; | 228 | return ret; |
228 | } | 229 | } |
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index 3e06402739e0..f72ba5587588 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c | |||
@@ -1669,6 +1669,7 @@ static int __init nf_conntrack_sip_init(void) | |||
1669 | if (ret) { | 1669 | if (ret) { |
1670 | pr_err("failed to register helper for pf: %u port: %u\n", | 1670 | pr_err("failed to register helper for pf: %u port: %u\n", |
1671 | sip[i][j].tuple.src.l3num, ports[i]); | 1671 | sip[i][j].tuple.src.l3num, ports[i]); |
1672 | ports_c = i; | ||
1672 | nf_conntrack_sip_fini(); | 1673 | nf_conntrack_sip_fini(); |
1673 | return ret; | 1674 | return ret; |
1674 | } | 1675 | } |
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index f87e84ebcec3..c026c472ea80 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c | |||
@@ -487,8 +487,6 @@ static struct ctl_table nf_ct_sysctl_table[] = { | |||
487 | { } | 487 | { } |
488 | }; | 488 | }; |
489 | 489 | ||
490 | #define NET_NF_CONNTRACK_MAX 2089 | ||
491 | |||
492 | static struct ctl_table nf_ct_netfilter_table[] = { | 490 | static struct ctl_table nf_ct_netfilter_table[] = { |
493 | { | 491 | { |
494 | .procname = "nf_conntrack_max", | 492 | .procname = "nf_conntrack_max", |
diff --git a/net/netfilter/nf_conntrack_tftp.c b/net/netfilter/nf_conntrack_tftp.c index 36f964066461..2e65b5430fba 100644 --- a/net/netfilter/nf_conntrack_tftp.c +++ b/net/netfilter/nf_conntrack_tftp.c | |||
@@ -142,6 +142,7 @@ static int __init nf_conntrack_tftp_init(void) | |||
142 | if (ret) { | 142 | if (ret) { |
143 | pr_err("failed to register helper for pf: %u port: %u\n", | 143 | pr_err("failed to register helper for pf: %u port: %u\n", |
144 | tftp[i][j].tuple.src.l3num, ports[i]); | 144 | tftp[i][j].tuple.src.l3num, ports[i]); |
145 | ports_c = i; | ||
145 | nf_conntrack_tftp_fini(); | 146 | nf_conntrack_tftp_fini(); |
146 | return ret; | 147 | return ret; |
147 | } | 148 | } |
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c index 5baa8e24e6ac..b19ad20a705c 100644 --- a/net/netfilter/nf_queue.c +++ b/net/netfilter/nf_queue.c | |||
@@ -26,23 +26,21 @@ | |||
26 | * Once the queue is registered it must reinject all packets it | 26 | * Once the queue is registered it must reinject all packets it |
27 | * receives, no matter what. | 27 | * receives, no matter what. |
28 | */ | 28 | */ |
29 | static const struct nf_queue_handler __rcu *queue_handler __read_mostly; | ||
30 | 29 | ||
31 | /* return EBUSY when somebody else is registered, return EEXIST if the | 30 | /* return EBUSY when somebody else is registered, return EEXIST if the |
32 | * same handler is registered, return 0 in case of success. */ | 31 | * same handler is registered, return 0 in case of success. */ |
33 | void nf_register_queue_handler(const struct nf_queue_handler *qh) | 32 | void nf_register_queue_handler(struct net *net, const struct nf_queue_handler *qh) |
34 | { | 33 | { |
35 | /* should never happen, we only have one queueing backend in kernel */ | 34 | /* should never happen, we only have one queueing backend in kernel */ |
36 | WARN_ON(rcu_access_pointer(queue_handler)); | 35 | WARN_ON(rcu_access_pointer(net->nf.queue_handler)); |
37 | rcu_assign_pointer(queue_handler, qh); | 36 | rcu_assign_pointer(net->nf.queue_handler, qh); |
38 | } | 37 | } |
39 | EXPORT_SYMBOL(nf_register_queue_handler); | 38 | EXPORT_SYMBOL(nf_register_queue_handler); |
40 | 39 | ||
41 | /* The caller must flush their queue before this */ | 40 | /* The caller must flush their queue before this */ |
42 | void nf_unregister_queue_handler(void) | 41 | void nf_unregister_queue_handler(struct net *net) |
43 | { | 42 | { |
44 | RCU_INIT_POINTER(queue_handler, NULL); | 43 | RCU_INIT_POINTER(net->nf.queue_handler, NULL); |
45 | synchronize_rcu(); | ||
46 | } | 44 | } |
47 | EXPORT_SYMBOL(nf_unregister_queue_handler); | 45 | EXPORT_SYMBOL(nf_unregister_queue_handler); |
48 | 46 | ||
@@ -103,7 +101,7 @@ void nf_queue_nf_hook_drop(struct net *net, struct nf_hook_ops *ops) | |||
103 | const struct nf_queue_handler *qh; | 101 | const struct nf_queue_handler *qh; |
104 | 102 | ||
105 | rcu_read_lock(); | 103 | rcu_read_lock(); |
106 | qh = rcu_dereference(queue_handler); | 104 | qh = rcu_dereference(net->nf.queue_handler); |
107 | if (qh) | 105 | if (qh) |
108 | qh->nf_hook_drop(net, ops); | 106 | qh->nf_hook_drop(net, ops); |
109 | rcu_read_unlock(); | 107 | rcu_read_unlock(); |
@@ -122,9 +120,10 @@ int nf_queue(struct sk_buff *skb, | |||
122 | struct nf_queue_entry *entry = NULL; | 120 | struct nf_queue_entry *entry = NULL; |
123 | const struct nf_afinfo *afinfo; | 121 | const struct nf_afinfo *afinfo; |
124 | const struct nf_queue_handler *qh; | 122 | const struct nf_queue_handler *qh; |
123 | struct net *net = state->net; | ||
125 | 124 | ||
126 | /* QUEUE == DROP if no one is waiting, to be safe. */ | 125 | /* QUEUE == DROP if no one is waiting, to be safe. */ |
127 | qh = rcu_dereference(queue_handler); | 126 | qh = rcu_dereference(net->nf.queue_handler); |
128 | if (!qh) { | 127 | if (!qh) { |
129 | status = -ESRCH; | 128 | status = -ESRCH; |
130 | goto err; | 129 | goto err; |
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 4d292b933b5c..7b7aa871a174 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c | |||
@@ -2647,6 +2647,8 @@ static int nf_tables_getset(struct net *net, struct sock *nlsk, | |||
2647 | /* Only accept unspec with dump */ | 2647 | /* Only accept unspec with dump */ |
2648 | if (nfmsg->nfgen_family == NFPROTO_UNSPEC) | 2648 | if (nfmsg->nfgen_family == NFPROTO_UNSPEC) |
2649 | return -EAFNOSUPPORT; | 2649 | return -EAFNOSUPPORT; |
2650 | if (!nla[NFTA_SET_TABLE]) | ||
2651 | return -EINVAL; | ||
2650 | 2652 | ||
2651 | set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME]); | 2653 | set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME]); |
2652 | if (IS_ERR(set)) | 2654 | if (IS_ERR(set)) |
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index aa93877ab6e2..5d36a0926b4a 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c | |||
@@ -557,7 +557,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, | |||
557 | 557 | ||
558 | if (entskb->tstamp.tv64) { | 558 | if (entskb->tstamp.tv64) { |
559 | struct nfqnl_msg_packet_timestamp ts; | 559 | struct nfqnl_msg_packet_timestamp ts; |
560 | struct timespec64 kts = ktime_to_timespec64(skb->tstamp); | 560 | struct timespec64 kts = ktime_to_timespec64(entskb->tstamp); |
561 | 561 | ||
562 | ts.sec = cpu_to_be64(kts.tv_sec); | 562 | ts.sec = cpu_to_be64(kts.tv_sec); |
563 | ts.usec = cpu_to_be64(kts.tv_nsec / NSEC_PER_USEC); | 563 | ts.usec = cpu_to_be64(kts.tv_nsec / NSEC_PER_USEC); |
@@ -1482,21 +1482,29 @@ static int __net_init nfnl_queue_net_init(struct net *net) | |||
1482 | net->nf.proc_netfilter, &nfqnl_file_ops)) | 1482 | net->nf.proc_netfilter, &nfqnl_file_ops)) |
1483 | return -ENOMEM; | 1483 | return -ENOMEM; |
1484 | #endif | 1484 | #endif |
1485 | nf_register_queue_handler(net, &nfqh); | ||
1485 | return 0; | 1486 | return 0; |
1486 | } | 1487 | } |
1487 | 1488 | ||
1488 | static void __net_exit nfnl_queue_net_exit(struct net *net) | 1489 | static void __net_exit nfnl_queue_net_exit(struct net *net) |
1489 | { | 1490 | { |
1491 | nf_unregister_queue_handler(net); | ||
1490 | #ifdef CONFIG_PROC_FS | 1492 | #ifdef CONFIG_PROC_FS |
1491 | remove_proc_entry("nfnetlink_queue", net->nf.proc_netfilter); | 1493 | remove_proc_entry("nfnetlink_queue", net->nf.proc_netfilter); |
1492 | #endif | 1494 | #endif |
1493 | } | 1495 | } |
1494 | 1496 | ||
1497 | static void nfnl_queue_net_exit_batch(struct list_head *net_exit_list) | ||
1498 | { | ||
1499 | synchronize_rcu(); | ||
1500 | } | ||
1501 | |||
1495 | static struct pernet_operations nfnl_queue_net_ops = { | 1502 | static struct pernet_operations nfnl_queue_net_ops = { |
1496 | .init = nfnl_queue_net_init, | 1503 | .init = nfnl_queue_net_init, |
1497 | .exit = nfnl_queue_net_exit, | 1504 | .exit = nfnl_queue_net_exit, |
1498 | .id = &nfnl_queue_net_id, | 1505 | .exit_batch = nfnl_queue_net_exit_batch, |
1499 | .size = sizeof(struct nfnl_queue_net), | 1506 | .id = &nfnl_queue_net_id, |
1507 | .size = sizeof(struct nfnl_queue_net), | ||
1500 | }; | 1508 | }; |
1501 | 1509 | ||
1502 | static int __init nfnetlink_queue_init(void) | 1510 | static int __init nfnetlink_queue_init(void) |
@@ -1517,7 +1525,6 @@ static int __init nfnetlink_queue_init(void) | |||
1517 | } | 1525 | } |
1518 | 1526 | ||
1519 | register_netdevice_notifier(&nfqnl_dev_notifier); | 1527 | register_netdevice_notifier(&nfqnl_dev_notifier); |
1520 | nf_register_queue_handler(&nfqh); | ||
1521 | return status; | 1528 | return status; |
1522 | 1529 | ||
1523 | cleanup_netlink_notifier: | 1530 | cleanup_netlink_notifier: |
@@ -1529,7 +1536,6 @@ out: | |||
1529 | 1536 | ||
1530 | static void __exit nfnetlink_queue_fini(void) | 1537 | static void __exit nfnetlink_queue_fini(void) |
1531 | { | 1538 | { |
1532 | nf_unregister_queue_handler(); | ||
1533 | unregister_netdevice_notifier(&nfqnl_dev_notifier); | 1539 | unregister_netdevice_notifier(&nfqnl_dev_notifier); |
1534 | nfnetlink_subsys_unregister(&nfqnl_subsys); | 1540 | nfnetlink_subsys_unregister(&nfqnl_subsys); |
1535 | netlink_unregister_notifier(&nfqnl_rtnl_notifier); | 1541 | netlink_unregister_notifier(&nfqnl_rtnl_notifier); |
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index c69c892231d7..2675d580c490 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c | |||
@@ -612,7 +612,7 @@ int xt_compat_check_entry_offsets(const void *base, const char *elems, | |||
612 | return -EINVAL; | 612 | return -EINVAL; |
613 | 613 | ||
614 | if (strcmp(t->u.user.name, XT_STANDARD_TARGET) == 0 && | 614 | if (strcmp(t->u.user.name, XT_STANDARD_TARGET) == 0 && |
615 | target_offset + sizeof(struct compat_xt_standard_target) != next_offset) | 615 | COMPAT_XT_ALIGN(target_offset + sizeof(struct compat_xt_standard_target)) != next_offset) |
616 | return -EINVAL; | 616 | return -EINVAL; |
617 | 617 | ||
618 | /* compat_xt_entry match has less strict aligment requirements, | 618 | /* compat_xt_entry match has less strict aligment requirements, |
@@ -694,7 +694,7 @@ int xt_check_entry_offsets(const void *base, | |||
694 | return -EINVAL; | 694 | return -EINVAL; |
695 | 695 | ||
696 | if (strcmp(t->u.user.name, XT_STANDARD_TARGET) == 0 && | 696 | if (strcmp(t->u.user.name, XT_STANDARD_TARGET) == 0 && |
697 | target_offset + sizeof(struct xt_standard_target) != next_offset) | 697 | XT_ALIGN(target_offset + sizeof(struct xt_standard_target)) != next_offset) |
698 | return -EINVAL; | 698 | return -EINVAL; |
699 | 699 | ||
700 | return xt_check_entry_match(elems, base + target_offset, | 700 | return xt_check_entry_match(elems, base + target_offset, |