aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-27 19:52:32 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-27 19:52:32 -0400
commitde8856d2c11f562c60ed9340a83db4a4f829a6e6 (patch)
tree0b871e5f4cf3204c4c6243c7622c4787d56d48ee /net
parent66f03c614c0902ccf7d6160459362a9352f33271 (diff)
parent94f826b8076e2cb92242061e92f21b5baa3eccc2 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller: 1) Name string overrun fix in gianfar driver from Joe Perches. 2) VHOST bug fixes from Michael S. Tsirkin and Nadav Har'El 3) Fix dependencies on xt_LOG netfilter module, from Pablo Neira Ayuso. 4) Fix RCU locking in xt_CT, also from Pablo Neira Ayuso. 5) Add a parameter to skb_add_rx_frag() so we can fix the truesize adjustments in the drivers that use it. The individual drivers aren't fixed by this commit, but will be dealt with using follow-on commits. From Eric Dumazet. 6) Add some device IDs to qmi_wwan driver, from Andrew Bird. 7) Fix a potential rcu_read_lock() imbalancein rt6_fill_node(). From Eric Dumazet. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: net: fix a potential rcu_read_lock() imbalance in rt6_fill_node() net: add a truesize parameter to skb_add_rx_frag() gianfar: Fix possible overrun and simplify interrupt name field creation USB: qmi_wwan: Add ZTE (Vodafone) K3570-Z and K3571-Z net interfaces USB: option: Ignore ZTE (Vodafone) K3570/71 net interfaces USB: qmi_wwan: Add ZTE (Vodafone) K3565-Z and K4505-Z net interfaces qlcnic: Bug fix for LRO netfilter: nf_conntrack: permanently attach timeout policy to conntrack netfilter: xt_CT: fix assignation of the generic protocol tracker netfilter: xt_CT: missing rcu_read_lock section in timeout assignment netfilter: cttimeout: fix dependency with l4protocol conntrack module netfilter: xt_LOG: use CONFIG_IP6_NF_IPTABLES instead of CONFIG_IPV6 vhost: fix release path lockdep checks vhost: don't forget to schedule() tools/virtio: stub out strong barriers tools/virtio: add linux/hrtimer.h stub tools/virtio: add linux/module.h stub
Diffstat (limited to 'net')
-rw-r--r--net/core/skbuff.c4
-rw-r--r--net/ipv6/route.c8
-rw-r--r--net/netfilter/nf_conntrack_core.c39
-rw-r--r--net/netfilter/nf_conntrack_proto.c21
-rw-r--r--net/netfilter/nfnetlink_cttimeout.c45
-rw-r--r--net/netfilter/xt_CT.c31
-rw-r--r--net/netfilter/xt_LOG.c12
7 files changed, 103 insertions, 57 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 6eb656acdfe5..a690cae91cdd 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -321,12 +321,12 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev,
321EXPORT_SYMBOL(__netdev_alloc_skb); 321EXPORT_SYMBOL(__netdev_alloc_skb);
322 322
323void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off, 323void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off,
324 int size) 324 int size, unsigned int truesize)
325{ 325{
326 skb_fill_page_desc(skb, i, page, off, size); 326 skb_fill_page_desc(skb, i, page, off, size);
327 skb->len += size; 327 skb->len += size;
328 skb->data_len += size; 328 skb->data_len += size;
329 skb->truesize += size; 329 skb->truesize += truesize;
330} 330}
331EXPORT_SYMBOL(skb_add_rx_frag); 331EXPORT_SYMBOL(skb_add_rx_frag);
332 332
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 24c456e8aa1d..496b62712fe8 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -2474,8 +2474,12 @@ static int rt6_fill_node(struct net *net,
2474 2474
2475 rcu_read_lock(); 2475 rcu_read_lock();
2476 n = dst_get_neighbour_noref(&rt->dst); 2476 n = dst_get_neighbour_noref(&rt->dst);
2477 if (n) 2477 if (n) {
2478 NLA_PUT(skb, RTA_GATEWAY, 16, &n->primary_key); 2478 if (nla_put(skb, RTA_GATEWAY, 16, &n->primary_key) < 0) {
2479 rcu_read_unlock();
2480 goto nla_put_failure;
2481 }
2482 }
2479 rcu_read_unlock(); 2483 rcu_read_unlock();
2480 2484
2481 if (rt->dst.dev) 2485 if (rt->dst.dev)
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 7b48035826ee..cbdb754dbb10 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -768,8 +768,7 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
768 struct nf_conntrack_l3proto *l3proto, 768 struct nf_conntrack_l3proto *l3proto,
769 struct nf_conntrack_l4proto *l4proto, 769 struct nf_conntrack_l4proto *l4proto,
770 struct sk_buff *skb, 770 struct sk_buff *skb,
771 unsigned int dataoff, u32 hash, 771 unsigned int dataoff, u32 hash)
772 unsigned int *timeouts)
773{ 772{
774 struct nf_conn *ct; 773 struct nf_conn *ct;
775 struct nf_conn_help *help; 774 struct nf_conn_help *help;
@@ -777,6 +776,8 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
777 struct nf_conntrack_ecache *ecache; 776 struct nf_conntrack_ecache *ecache;
778 struct nf_conntrack_expect *exp; 777 struct nf_conntrack_expect *exp;
779 u16 zone = tmpl ? nf_ct_zone(tmpl) : NF_CT_DEFAULT_ZONE; 778 u16 zone = tmpl ? nf_ct_zone(tmpl) : NF_CT_DEFAULT_ZONE;
779 struct nf_conn_timeout *timeout_ext;
780 unsigned int *timeouts;
780 781
781 if (!nf_ct_invert_tuple(&repl_tuple, tuple, l3proto, l4proto)) { 782 if (!nf_ct_invert_tuple(&repl_tuple, tuple, l3proto, l4proto)) {
782 pr_debug("Can't invert tuple.\n"); 783 pr_debug("Can't invert tuple.\n");
@@ -788,12 +789,21 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
788 if (IS_ERR(ct)) 789 if (IS_ERR(ct))
789 return (struct nf_conntrack_tuple_hash *)ct; 790 return (struct nf_conntrack_tuple_hash *)ct;
790 791
792 timeout_ext = tmpl ? nf_ct_timeout_find(tmpl) : NULL;
793 if (timeout_ext)
794 timeouts = NF_CT_TIMEOUT_EXT_DATA(timeout_ext);
795 else
796 timeouts = l4proto->get_timeouts(net);
797
791 if (!l4proto->new(ct, skb, dataoff, timeouts)) { 798 if (!l4proto->new(ct, skb, dataoff, timeouts)) {
792 nf_conntrack_free(ct); 799 nf_conntrack_free(ct);
793 pr_debug("init conntrack: can't track with proto module\n"); 800 pr_debug("init conntrack: can't track with proto module\n");
794 return NULL; 801 return NULL;
795 } 802 }
796 803
804 if (timeout_ext)
805 nf_ct_timeout_ext_add(ct, timeout_ext->timeout, GFP_ATOMIC);
806
797 nf_ct_acct_ext_add(ct, GFP_ATOMIC); 807 nf_ct_acct_ext_add(ct, GFP_ATOMIC);
798 nf_ct_tstamp_ext_add(ct, GFP_ATOMIC); 808 nf_ct_tstamp_ext_add(ct, GFP_ATOMIC);
799 809
@@ -854,8 +864,7 @@ resolve_normal_ct(struct net *net, struct nf_conn *tmpl,
854 struct nf_conntrack_l3proto *l3proto, 864 struct nf_conntrack_l3proto *l3proto,
855 struct nf_conntrack_l4proto *l4proto, 865 struct nf_conntrack_l4proto *l4proto,
856 int *set_reply, 866 int *set_reply,
857 enum ip_conntrack_info *ctinfo, 867 enum ip_conntrack_info *ctinfo)
858 unsigned int *timeouts)
859{ 868{
860 struct nf_conntrack_tuple tuple; 869 struct nf_conntrack_tuple tuple;
861 struct nf_conntrack_tuple_hash *h; 870 struct nf_conntrack_tuple_hash *h;
@@ -875,7 +884,7 @@ resolve_normal_ct(struct net *net, struct nf_conn *tmpl,
875 h = __nf_conntrack_find_get(net, zone, &tuple, hash); 884 h = __nf_conntrack_find_get(net, zone, &tuple, hash);
876 if (!h) { 885 if (!h) {
877 h = init_conntrack(net, tmpl, &tuple, l3proto, l4proto, 886 h = init_conntrack(net, tmpl, &tuple, l3proto, l4proto,
878 skb, dataoff, hash, timeouts); 887 skb, dataoff, hash);
879 if (!h) 888 if (!h)
880 return NULL; 889 return NULL;
881 if (IS_ERR(h)) 890 if (IS_ERR(h))
@@ -964,19 +973,8 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum,
964 goto out; 973 goto out;
965 } 974 }
966 975
967 /* Decide what timeout policy we want to apply to this flow. */
968 if (tmpl) {
969 timeout_ext = nf_ct_timeout_find(tmpl);
970 if (timeout_ext)
971 timeouts = NF_CT_TIMEOUT_EXT_DATA(timeout_ext);
972 else
973 timeouts = l4proto->get_timeouts(net);
974 } else
975 timeouts = l4proto->get_timeouts(net);
976
977 ct = resolve_normal_ct(net, tmpl, skb, dataoff, pf, protonum, 976 ct = resolve_normal_ct(net, tmpl, skb, dataoff, pf, protonum,
978 l3proto, l4proto, &set_reply, &ctinfo, 977 l3proto, l4proto, &set_reply, &ctinfo);
979 timeouts);
980 if (!ct) { 978 if (!ct) {
981 /* Not valid part of a connection */ 979 /* Not valid part of a connection */
982 NF_CT_STAT_INC_ATOMIC(net, invalid); 980 NF_CT_STAT_INC_ATOMIC(net, invalid);
@@ -993,6 +991,13 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum,
993 991
994 NF_CT_ASSERT(skb->nfct); 992 NF_CT_ASSERT(skb->nfct);
995 993
994 /* Decide what timeout policy we want to apply to this flow. */
995 timeout_ext = nf_ct_timeout_find(ct);
996 if (timeout_ext)
997 timeouts = NF_CT_TIMEOUT_EXT_DATA(timeout_ext);
998 else
999 timeouts = l4proto->get_timeouts(net);
1000
996 ret = l4proto->packet(ct, skb, dataoff, ctinfo, pf, hooknum, timeouts); 1001 ret = l4proto->packet(ct, skb, dataoff, ctinfo, pf, hooknum, timeouts);
997 if (ret <= 0) { 1002 if (ret <= 0) {
998 /* Invalid: inverse of the return code tells 1003 /* Invalid: inverse of the return code tells
diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
index 5701c8dd783c..be3da2c8cdc5 100644
--- a/net/netfilter/nf_conntrack_proto.c
+++ b/net/netfilter/nf_conntrack_proto.c
@@ -127,6 +127,27 @@ void nf_ct_l3proto_module_put(unsigned short l3proto)
127} 127}
128EXPORT_SYMBOL_GPL(nf_ct_l3proto_module_put); 128EXPORT_SYMBOL_GPL(nf_ct_l3proto_module_put);
129 129
130struct nf_conntrack_l4proto *
131nf_ct_l4proto_find_get(u_int16_t l3num, u_int8_t l4num)
132{
133 struct nf_conntrack_l4proto *p;
134
135 rcu_read_lock();
136 p = __nf_ct_l4proto_find(l3num, l4num);
137 if (!try_module_get(p->me))
138 p = &nf_conntrack_l4proto_generic;
139 rcu_read_unlock();
140
141 return p;
142}
143EXPORT_SYMBOL_GPL(nf_ct_l4proto_find_get);
144
145void nf_ct_l4proto_put(struct nf_conntrack_l4proto *p)
146{
147 module_put(p->me);
148}
149EXPORT_SYMBOL_GPL(nf_ct_l4proto_put);
150
130static int kill_l3proto(struct nf_conn *i, void *data) 151static int kill_l3proto(struct nf_conn *i, void *data)
131{ 152{
132 return nf_ct_l3num(i) == ((struct nf_conntrack_l3proto *)data)->l3proto; 153 return nf_ct_l3num(i) == ((struct nf_conntrack_l3proto *)data)->l3proto;
diff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c
index fec29a43de4d..2b9e79f5ef05 100644
--- a/net/netfilter/nfnetlink_cttimeout.c
+++ b/net/netfilter/nfnetlink_cttimeout.c
@@ -98,11 +98,13 @@ cttimeout_new_timeout(struct sock *ctnl, struct sk_buff *skb,
98 break; 98 break;
99 } 99 }
100 100
101 l4proto = __nf_ct_l4proto_find(l3num, l4num); 101 l4proto = nf_ct_l4proto_find_get(l3num, l4num);
102 102
103 /* This protocol is not supportted, skip. */ 103 /* This protocol is not supportted, skip. */
104 if (l4proto->l4proto != l4num) 104 if (l4proto->l4proto != l4num) {
105 return -EOPNOTSUPP; 105 ret = -EOPNOTSUPP;
106 goto err_proto_put;
107 }
106 108
107 if (matching) { 109 if (matching) {
108 if (nlh->nlmsg_flags & NLM_F_REPLACE) { 110 if (nlh->nlmsg_flags & NLM_F_REPLACE) {
@@ -110,20 +112,25 @@ cttimeout_new_timeout(struct sock *ctnl, struct sk_buff *skb,
110 * different kind, sorry. 112 * different kind, sorry.
111 */ 113 */
112 if (matching->l3num != l3num || 114 if (matching->l3num != l3num ||
113 matching->l4num != l4num) 115 matching->l4proto->l4proto != l4num) {
114 return -EINVAL; 116 ret = -EINVAL;
117 goto err_proto_put;
118 }
115 119
116 ret = ctnl_timeout_parse_policy(matching, l4proto, 120 ret = ctnl_timeout_parse_policy(matching, l4proto,
117 cda[CTA_TIMEOUT_DATA]); 121 cda[CTA_TIMEOUT_DATA]);
118 return ret; 122 return ret;
119 } 123 }
120 return -EBUSY; 124 ret = -EBUSY;
125 goto err_proto_put;
121 } 126 }
122 127
123 timeout = kzalloc(sizeof(struct ctnl_timeout) + 128 timeout = kzalloc(sizeof(struct ctnl_timeout) +
124 l4proto->ctnl_timeout.obj_size, GFP_KERNEL); 129 l4proto->ctnl_timeout.obj_size, GFP_KERNEL);
125 if (timeout == NULL) 130 if (timeout == NULL) {
126 return -ENOMEM; 131 ret = -ENOMEM;
132 goto err_proto_put;
133 }
127 134
128 ret = ctnl_timeout_parse_policy(timeout, l4proto, 135 ret = ctnl_timeout_parse_policy(timeout, l4proto,
129 cda[CTA_TIMEOUT_DATA]); 136 cda[CTA_TIMEOUT_DATA]);
@@ -132,13 +139,15 @@ cttimeout_new_timeout(struct sock *ctnl, struct sk_buff *skb,
132 139
133 strcpy(timeout->name, nla_data(cda[CTA_TIMEOUT_NAME])); 140 strcpy(timeout->name, nla_data(cda[CTA_TIMEOUT_NAME]));
134 timeout->l3num = l3num; 141 timeout->l3num = l3num;
135 timeout->l4num = l4num; 142 timeout->l4proto = l4proto;
136 atomic_set(&timeout->refcnt, 1); 143 atomic_set(&timeout->refcnt, 1);
137 list_add_tail_rcu(&timeout->head, &cttimeout_list); 144 list_add_tail_rcu(&timeout->head, &cttimeout_list);
138 145
139 return 0; 146 return 0;
140err: 147err:
141 kfree(timeout); 148 kfree(timeout);
149err_proto_put:
150 nf_ct_l4proto_put(l4proto);
142 return ret; 151 return ret;
143} 152}
144 153
@@ -149,7 +158,7 @@ ctnl_timeout_fill_info(struct sk_buff *skb, u32 pid, u32 seq, u32 type,
149 struct nlmsghdr *nlh; 158 struct nlmsghdr *nlh;
150 struct nfgenmsg *nfmsg; 159 struct nfgenmsg *nfmsg;
151 unsigned int flags = pid ? NLM_F_MULTI : 0; 160 unsigned int flags = pid ? NLM_F_MULTI : 0;
152 struct nf_conntrack_l4proto *l4proto; 161 struct nf_conntrack_l4proto *l4proto = timeout->l4proto;
153 162
154 event |= NFNL_SUBSYS_CTNETLINK_TIMEOUT << 8; 163 event |= NFNL_SUBSYS_CTNETLINK_TIMEOUT << 8;
155 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*nfmsg), flags); 164 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*nfmsg), flags);
@@ -163,20 +172,10 @@ ctnl_timeout_fill_info(struct sk_buff *skb, u32 pid, u32 seq, u32 type,
163 172
164 NLA_PUT_STRING(skb, CTA_TIMEOUT_NAME, timeout->name); 173 NLA_PUT_STRING(skb, CTA_TIMEOUT_NAME, timeout->name);
165 NLA_PUT_BE16(skb, CTA_TIMEOUT_L3PROTO, htons(timeout->l3num)); 174 NLA_PUT_BE16(skb, CTA_TIMEOUT_L3PROTO, htons(timeout->l3num));
166 NLA_PUT_U8(skb, CTA_TIMEOUT_L4PROTO, timeout->l4num); 175 NLA_PUT_U8(skb, CTA_TIMEOUT_L4PROTO, timeout->l4proto->l4proto);
167 NLA_PUT_BE32(skb, CTA_TIMEOUT_USE, 176 NLA_PUT_BE32(skb, CTA_TIMEOUT_USE,
168 htonl(atomic_read(&timeout->refcnt))); 177 htonl(atomic_read(&timeout->refcnt)));
169 178
170 l4proto = __nf_ct_l4proto_find(timeout->l3num, timeout->l4num);
171
172 /* If the timeout object does not match the layer 4 protocol tracker,
173 * then skip dumping the data part since we don't know how to
174 * interpret it. This may happen for UPDlite, SCTP and DCCP since
175 * you can unload the module.
176 */
177 if (timeout->l4num != l4proto->l4proto)
178 goto out;
179
180 if (likely(l4proto->ctnl_timeout.obj_to_nlattr)) { 179 if (likely(l4proto->ctnl_timeout.obj_to_nlattr)) {
181 struct nlattr *nest_parms; 180 struct nlattr *nest_parms;
182 int ret; 181 int ret;
@@ -192,7 +191,7 @@ ctnl_timeout_fill_info(struct sk_buff *skb, u32 pid, u32 seq, u32 type,
192 191
193 nla_nest_end(skb, nest_parms); 192 nla_nest_end(skb, nest_parms);
194 } 193 }
195out: 194
196 nlmsg_end(skb, nlh); 195 nlmsg_end(skb, nlh);
197 return skb->len; 196 return skb->len;
198 197
@@ -293,6 +292,7 @@ static int ctnl_timeout_try_del(struct ctnl_timeout *timeout)
293 if (atomic_dec_and_test(&timeout->refcnt)) { 292 if (atomic_dec_and_test(&timeout->refcnt)) {
294 /* We are protected by nfnl mutex. */ 293 /* We are protected by nfnl mutex. */
295 list_del_rcu(&timeout->head); 294 list_del_rcu(&timeout->head);
295 nf_ct_l4proto_put(timeout->l4proto);
296 kfree_rcu(timeout, rcu_head); 296 kfree_rcu(timeout, rcu_head);
297 } else { 297 } else {
298 /* still in use, restore reference counter. */ 298 /* still in use, restore reference counter. */
@@ -417,6 +417,7 @@ static void __exit cttimeout_exit(void)
417 /* We are sure that our objects have no clients at this point, 417 /* We are sure that our objects have no clients at this point,
418 * it's safe to release them all without checking refcnt. 418 * it's safe to release them all without checking refcnt.
419 */ 419 */
420 nf_ct_l4proto_put(cur->l4proto);
420 kfree_rcu(cur, rcu_head); 421 kfree_rcu(cur, rcu_head);
421 } 422 }
422#ifdef CONFIG_NF_CONNTRACK_TIMEOUT 423#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c
index b873445df444..0c8e43810ce3 100644
--- a/net/netfilter/xt_CT.c
+++ b/net/netfilter/xt_CT.c
@@ -14,8 +14,10 @@
14#include <linux/netfilter/x_tables.h> 14#include <linux/netfilter/x_tables.h>
15#include <linux/netfilter/xt_CT.h> 15#include <linux/netfilter/xt_CT.h>
16#include <net/netfilter/nf_conntrack.h> 16#include <net/netfilter/nf_conntrack.h>
17#include <net/netfilter/nf_conntrack_l4proto.h>
17#include <net/netfilter/nf_conntrack_helper.h> 18#include <net/netfilter/nf_conntrack_helper.h>
18#include <net/netfilter/nf_conntrack_ecache.h> 19#include <net/netfilter/nf_conntrack_ecache.h>
20#include <net/netfilter/nf_conntrack_l4proto.h>
19#include <net/netfilter/nf_conntrack_timeout.h> 21#include <net/netfilter/nf_conntrack_timeout.h>
20#include <net/netfilter/nf_conntrack_zones.h> 22#include <net/netfilter/nf_conntrack_zones.h>
21 23
@@ -217,50 +219,59 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par)
217 struct ctnl_timeout *timeout; 219 struct ctnl_timeout *timeout;
218 struct nf_conn_timeout *timeout_ext; 220 struct nf_conn_timeout *timeout_ext;
219 221
222 rcu_read_lock();
220 timeout_find_get = 223 timeout_find_get =
221 rcu_dereference(nf_ct_timeout_find_get_hook); 224 rcu_dereference(nf_ct_timeout_find_get_hook);
222 225
223 if (timeout_find_get) { 226 if (timeout_find_get) {
224 const struct ipt_entry *e = par->entryinfo; 227 const struct ipt_entry *e = par->entryinfo;
228 struct nf_conntrack_l4proto *l4proto;
225 229
226 if (e->ip.invflags & IPT_INV_PROTO) { 230 if (e->ip.invflags & IPT_INV_PROTO) {
227 ret = -EINVAL; 231 ret = -EINVAL;
228 pr_info("You cannot use inversion on " 232 pr_info("You cannot use inversion on "
229 "L4 protocol\n"); 233 "L4 protocol\n");
230 goto err3; 234 goto err4;
231 } 235 }
232 timeout = timeout_find_get(info->timeout); 236 timeout = timeout_find_get(info->timeout);
233 if (timeout == NULL) { 237 if (timeout == NULL) {
234 ret = -ENOENT; 238 ret = -ENOENT;
235 pr_info("No such timeout policy \"%s\"\n", 239 pr_info("No such timeout policy \"%s\"\n",
236 info->timeout); 240 info->timeout);
237 goto err3; 241 goto err4;
238 } 242 }
239 if (timeout->l3num != par->family) { 243 if (timeout->l3num != par->family) {
240 ret = -EINVAL; 244 ret = -EINVAL;
241 pr_info("Timeout policy `%s' can only be " 245 pr_info("Timeout policy `%s' can only be "
242 "used by L3 protocol number %d\n", 246 "used by L3 protocol number %d\n",
243 info->timeout, timeout->l3num); 247 info->timeout, timeout->l3num);
244 goto err3; 248 goto err4;
245 } 249 }
246 if (timeout->l4num != e->ip.proto) { 250 /* Make sure the timeout policy matches any existing
251 * protocol tracker, otherwise default to generic.
252 */
253 l4proto = __nf_ct_l4proto_find(par->family,
254 e->ip.proto);
255 if (timeout->l4proto->l4proto != l4proto->l4proto) {
247 ret = -EINVAL; 256 ret = -EINVAL;
248 pr_info("Timeout policy `%s' can only be " 257 pr_info("Timeout policy `%s' can only be "
249 "used by L4 protocol number %d\n", 258 "used by L4 protocol number %d\n",
250 info->timeout, timeout->l4num); 259 info->timeout,
251 goto err3; 260 timeout->l4proto->l4proto);
261 goto err4;
252 } 262 }
253 timeout_ext = nf_ct_timeout_ext_add(ct, timeout, 263 timeout_ext = nf_ct_timeout_ext_add(ct, timeout,
254 GFP_KERNEL); 264 GFP_KERNEL);
255 if (timeout_ext == NULL) { 265 if (timeout_ext == NULL) {
256 ret = -ENOMEM; 266 ret = -ENOMEM;
257 goto err3; 267 goto err4;
258 } 268 }
259 } else { 269 } else {
260 ret = -ENOENT; 270 ret = -ENOENT;
261 pr_info("Timeout policy base is empty\n"); 271 pr_info("Timeout policy base is empty\n");
262 goto err3; 272 goto err4;
263 } 273 }
274 rcu_read_unlock();
264 } 275 }
265#endif 276#endif
266 277
@@ -270,6 +281,8 @@ out:
270 info->ct = ct; 281 info->ct = ct;
271 return 0; 282 return 0;
272 283
284err4:
285 rcu_read_unlock();
273err3: 286err3:
274 nf_conntrack_free(ct); 287 nf_conntrack_free(ct);
275err2: 288err2:
@@ -311,6 +324,7 @@ static void xt_ct_tg_destroy_v1(const struct xt_tgdtor_param *par)
311 nf_ct_l3proto_module_put(par->family); 324 nf_ct_l3proto_module_put(par->family);
312 325
313#ifdef CONFIG_NF_CONNTRACK_TIMEOUT 326#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
327 rcu_read_lock();
314 timeout_put = rcu_dereference(nf_ct_timeout_put_hook); 328 timeout_put = rcu_dereference(nf_ct_timeout_put_hook);
315 329
316 if (timeout_put) { 330 if (timeout_put) {
@@ -318,6 +332,7 @@ static void xt_ct_tg_destroy_v1(const struct xt_tgdtor_param *par)
318 if (timeout_ext) 332 if (timeout_ext)
319 timeout_put(timeout_ext->timeout); 333 timeout_put(timeout_ext->timeout);
320 } 334 }
335 rcu_read_unlock();
321#endif 336#endif
322 } 337 }
323 nf_ct_put(info->ct); 338 nf_ct_put(info->ct);
diff --git a/net/netfilter/xt_LOG.c b/net/netfilter/xt_LOG.c
index f99f8dee238b..ff5f75fddb15 100644
--- a/net/netfilter/xt_LOG.c
+++ b/net/netfilter/xt_LOG.c
@@ -480,7 +480,7 @@ ipt_log_packet(u_int8_t pf,
480 sb_close(m); 480 sb_close(m);
481} 481}
482 482
483#if IS_ENABLED(CONFIG_IPV6) 483#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
484/* One level of recursion won't kill us */ 484/* One level of recursion won't kill us */
485static void dump_ipv6_packet(struct sbuff *m, 485static void dump_ipv6_packet(struct sbuff *m,
486 const struct nf_loginfo *info, 486 const struct nf_loginfo *info,
@@ -824,7 +824,7 @@ log_tg(struct sk_buff *skb, const struct xt_action_param *par)
824 if (par->family == NFPROTO_IPV4) 824 if (par->family == NFPROTO_IPV4)
825 ipt_log_packet(NFPROTO_IPV4, par->hooknum, skb, par->in, 825 ipt_log_packet(NFPROTO_IPV4, par->hooknum, skb, par->in,
826 par->out, &li, loginfo->prefix); 826 par->out, &li, loginfo->prefix);
827#if IS_ENABLED(CONFIG_IPV6) 827#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
828 else if (par->family == NFPROTO_IPV6) 828 else if (par->family == NFPROTO_IPV6)
829 ip6t_log_packet(NFPROTO_IPV6, par->hooknum, skb, par->in, 829 ip6t_log_packet(NFPROTO_IPV6, par->hooknum, skb, par->in,
830 par->out, &li, loginfo->prefix); 830 par->out, &li, loginfo->prefix);
@@ -864,7 +864,7 @@ static struct xt_target log_tg_regs[] __read_mostly = {
864 .checkentry = log_tg_check, 864 .checkentry = log_tg_check,
865 .me = THIS_MODULE, 865 .me = THIS_MODULE,
866 }, 866 },
867#if IS_ENABLED(CONFIG_IPV6) 867#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
868 { 868 {
869 .name = "LOG", 869 .name = "LOG",
870 .family = NFPROTO_IPV6, 870 .family = NFPROTO_IPV6,
@@ -882,7 +882,7 @@ static struct nf_logger ipt_log_logger __read_mostly = {
882 .me = THIS_MODULE, 882 .me = THIS_MODULE,
883}; 883};
884 884
885#if IS_ENABLED(CONFIG_IPV6) 885#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
886static struct nf_logger ip6t_log_logger __read_mostly = { 886static struct nf_logger ip6t_log_logger __read_mostly = {
887 .name = "ip6t_LOG", 887 .name = "ip6t_LOG",
888 .logfn = &ip6t_log_packet, 888 .logfn = &ip6t_log_packet,
@@ -899,7 +899,7 @@ static int __init log_tg_init(void)
899 return ret; 899 return ret;
900 900
901 nf_log_register(NFPROTO_IPV4, &ipt_log_logger); 901 nf_log_register(NFPROTO_IPV4, &ipt_log_logger);
902#if IS_ENABLED(CONFIG_IPV6) 902#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
903 nf_log_register(NFPROTO_IPV6, &ip6t_log_logger); 903 nf_log_register(NFPROTO_IPV6, &ip6t_log_logger);
904#endif 904#endif
905 return 0; 905 return 0;
@@ -908,7 +908,7 @@ static int __init log_tg_init(void)
908static void __exit log_tg_exit(void) 908static void __exit log_tg_exit(void)
909{ 909{
910 nf_log_unregister(&ipt_log_logger); 910 nf_log_unregister(&ipt_log_logger);
911#if IS_ENABLED(CONFIG_IPV6) 911#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
912 nf_log_unregister(&ip6t_log_logger); 912 nf_log_unregister(&ip6t_log_logger);
913#endif 913#endif
914 xt_unregister_targets(log_tg_regs, ARRAY_SIZE(log_tg_regs)); 914 xt_unregister_targets(log_tg_regs, ARRAY_SIZE(log_tg_regs));