aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2016-06-10 14:52:24 -0400
committerDavid S. Miller <davem@davemloft.net>2016-06-10 14:52:24 -0400
commit1578b0a5e92825334760741e5c166b8873886f1b (patch)
treeac8299191f37990111f7d4b615601f4356e24fea /net/netfilter
parent3d5479e92087f6249231e26a2d7327e86a8d0dfc (diff)
parent698ea54dde6768d4a96080d0fb796cb3a4eadaf8 (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.c5
-rw-r--r--net/netfilter/ipvs/ip_vs_core.c5
-rw-r--r--net/netfilter/nf_conntrack_ftp.c1
-rw-r--r--net/netfilter/nf_conntrack_helper.c9
-rw-r--r--net/netfilter/nf_conntrack_irc.c1
-rw-r--r--net/netfilter/nf_conntrack_sane.c1
-rw-r--r--net/netfilter/nf_conntrack_sip.c1
-rw-r--r--net/netfilter/nf_conntrack_standalone.c2
-rw-r--r--net/netfilter/nf_conntrack_tftp.c1
-rw-r--r--net/netfilter/nf_queue.c17
-rw-r--r--net/netfilter/nf_tables_api.c2
-rw-r--r--net/netfilter/nfnetlink_queue.c20
-rw-r--r--net/netfilter/x_tables.c4
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 */
765int ip_vs_check_template(struct ip_vs_conn *ct) 765int 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(&param); 323 ct = ip_vs_ct_in_get(&param);
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, &param) < 0) 1154 vport, &param) < 0)
1155 return NULL; 1155 return NULL;
1156 ct = ip_vs_ct_in_get(&param); 1156 ct = ip_vs_ct_in_get(&param);
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(&param, dest->af, daddr, dport, 1159 ct = ip_vs_conn_new(&param, 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
362int nf_conntrack_helper_register(struct nf_conntrack_helper *me) 362int 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
492static struct ctl_table nf_ct_netfilter_table[] = { 490static 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 */
29static 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. */
33void nf_register_queue_handler(const struct nf_queue_handler *qh) 32void 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}
39EXPORT_SYMBOL(nf_register_queue_handler); 38EXPORT_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 */
42void nf_unregister_queue_handler(void) 41void 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}
47EXPORT_SYMBOL(nf_unregister_queue_handler); 45EXPORT_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
1488static void __net_exit nfnl_queue_net_exit(struct net *net) 1489static 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
1497static void nfnl_queue_net_exit_batch(struct list_head *net_exit_list)
1498{
1499 synchronize_rcu();
1500}
1501
1495static struct pernet_operations nfnl_queue_net_ops = { 1502static 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
1502static int __init nfnetlink_queue_init(void) 1510static 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
1523cleanup_netlink_notifier: 1530cleanup_netlink_notifier:
@@ -1529,7 +1536,6 @@ out:
1529 1536
1530static void __exit nfnetlink_queue_fini(void) 1537static 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,