diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/802/mrp.c | 4 | ||||
-rw-r--r-- | net/bridge/br_if.c | 3 | ||||
-rw-r--r-- | net/bridge/br_private.h | 1 | ||||
-rw-r--r-- | net/bridge/br_stp_if.c | 1 | ||||
-rw-r--r-- | net/ipv4/esp4.c | 6 | ||||
-rw-r--r-- | net/ipv4/ip_fragment.c | 14 | ||||
-rw-r--r-- | net/ipv4/syncookies.c | 4 | ||||
-rw-r--r-- | net/ipv4/tcp_output.c | 8 | ||||
-rw-r--r-- | net/ipv6/addrconf.c | 24 | ||||
-rw-r--r-- | net/ipv6/addrconf_core.c | 19 | ||||
-rw-r--r-- | net/ipv6/reassembly.c | 12 | ||||
-rw-r--r-- | net/netfilter/ipset/ip_set_hash_ipportnet.c | 18 | ||||
-rw-r--r-- | net/netfilter/ipset/ip_set_hash_net.c | 22 | ||||
-rw-r--r-- | net/netfilter/ipset/ip_set_hash_netiface.c | 22 | ||||
-rw-r--r-- | net/netfilter/ipset/ip_set_hash_netport.c | 18 | ||||
-rw-r--r-- | net/netfilter/ipset/ip_set_list_set.c | 10 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_sip.c | 6 | ||||
-rw-r--r-- | net/netfilter/nf_nat_core.c | 40 |
18 files changed, 153 insertions, 79 deletions
diff --git a/net/802/mrp.c b/net/802/mrp.c index a4cc3229952a..e085bcc754f6 100644 --- a/net/802/mrp.c +++ b/net/802/mrp.c | |||
@@ -870,8 +870,12 @@ void mrp_uninit_applicant(struct net_device *dev, struct mrp_application *appl) | |||
870 | * all pending messages before the applicant is gone. | 870 | * all pending messages before the applicant is gone. |
871 | */ | 871 | */ |
872 | del_timer_sync(&app->join_timer); | 872 | del_timer_sync(&app->join_timer); |
873 | |||
874 | spin_lock(&app->lock); | ||
873 | mrp_mad_event(app, MRP_EVENT_TX); | 875 | mrp_mad_event(app, MRP_EVENT_TX); |
874 | mrp_pdu_queue(app); | 876 | mrp_pdu_queue(app); |
877 | spin_unlock(&app->lock); | ||
878 | |||
875 | mrp_queue_xmit(app); | 879 | mrp_queue_xmit(app); |
876 | 880 | ||
877 | dev_mc_del(dev, appl->group_address); | 881 | dev_mc_del(dev, appl->group_address); |
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index ef1b91431c6b..459dab22b3f6 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c | |||
@@ -67,7 +67,8 @@ void br_port_carrier_check(struct net_bridge_port *p) | |||
67 | struct net_device *dev = p->dev; | 67 | struct net_device *dev = p->dev; |
68 | struct net_bridge *br = p->br; | 68 | struct net_bridge *br = p->br; |
69 | 69 | ||
70 | if (netif_running(dev) && netif_oper_up(dev)) | 70 | if (!(p->flags & BR_ADMIN_COST) && |
71 | netif_running(dev) && netif_oper_up(dev)) | ||
71 | p->path_cost = port_cost(dev); | 72 | p->path_cost = port_cost(dev); |
72 | 73 | ||
73 | if (!netif_running(br->dev)) | 74 | if (!netif_running(br->dev)) |
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 3cbf5beb3d4b..d2c043a857b6 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h | |||
@@ -156,6 +156,7 @@ struct net_bridge_port | |||
156 | #define BR_BPDU_GUARD 0x00000002 | 156 | #define BR_BPDU_GUARD 0x00000002 |
157 | #define BR_ROOT_BLOCK 0x00000004 | 157 | #define BR_ROOT_BLOCK 0x00000004 |
158 | #define BR_MULTICAST_FAST_LEAVE 0x00000008 | 158 | #define BR_MULTICAST_FAST_LEAVE 0x00000008 |
159 | #define BR_ADMIN_COST 0x00000010 | ||
159 | 160 | ||
160 | #ifdef CONFIG_BRIDGE_IGMP_SNOOPING | 161 | #ifdef CONFIG_BRIDGE_IGMP_SNOOPING |
161 | u32 multicast_startup_queries_sent; | 162 | u32 multicast_startup_queries_sent; |
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c index 0bdb4ebd362b..d45e760141bb 100644 --- a/net/bridge/br_stp_if.c +++ b/net/bridge/br_stp_if.c | |||
@@ -288,6 +288,7 @@ int br_stp_set_path_cost(struct net_bridge_port *p, unsigned long path_cost) | |||
288 | path_cost > BR_MAX_PATH_COST) | 288 | path_cost > BR_MAX_PATH_COST) |
289 | return -ERANGE; | 289 | return -ERANGE; |
290 | 290 | ||
291 | p->flags |= BR_ADMIN_COST; | ||
291 | p->path_cost = path_cost; | 292 | p->path_cost = path_cost; |
292 | br_configuration_update(p->br); | 293 | br_configuration_update(p->br); |
293 | br_port_state_selection(p->br); | 294 | br_port_state_selection(p->br); |
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 3b4f0cd2e63e..4cfe34d4cc96 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c | |||
@@ -139,8 +139,6 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) | |||
139 | 139 | ||
140 | /* skb is pure payload to encrypt */ | 140 | /* skb is pure payload to encrypt */ |
141 | 141 | ||
142 | err = -ENOMEM; | ||
143 | |||
144 | esp = x->data; | 142 | esp = x->data; |
145 | aead = esp->aead; | 143 | aead = esp->aead; |
146 | alen = crypto_aead_authsize(aead); | 144 | alen = crypto_aead_authsize(aead); |
@@ -176,8 +174,10 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) | |||
176 | } | 174 | } |
177 | 175 | ||
178 | tmp = esp_alloc_tmp(aead, nfrags + sglists, seqhilen); | 176 | tmp = esp_alloc_tmp(aead, nfrags + sglists, seqhilen); |
179 | if (!tmp) | 177 | if (!tmp) { |
178 | err = -ENOMEM; | ||
180 | goto error; | 179 | goto error; |
180 | } | ||
181 | 181 | ||
182 | seqhi = esp_tmp_seqhi(tmp); | 182 | seqhi = esp_tmp_seqhi(tmp); |
183 | iv = esp_tmp_iv(aead, tmp, seqhilen); | 183 | iv = esp_tmp_iv(aead, tmp, seqhilen); |
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index a6445b843ef4..52c273ea05c3 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c | |||
@@ -248,8 +248,7 @@ static void ip_expire(unsigned long arg) | |||
248 | if (!head->dev) | 248 | if (!head->dev) |
249 | goto out_rcu_unlock; | 249 | goto out_rcu_unlock; |
250 | 250 | ||
251 | /* skb dst is stale, drop it, and perform route lookup again */ | 251 | /* skb has no dst, perform route lookup again */ |
252 | skb_dst_drop(head); | ||
253 | iph = ip_hdr(head); | 252 | iph = ip_hdr(head); |
254 | err = ip_route_input_noref(head, iph->daddr, iph->saddr, | 253 | err = ip_route_input_noref(head, iph->daddr, iph->saddr, |
255 | iph->tos, head->dev); | 254 | iph->tos, head->dev); |
@@ -523,9 +522,16 @@ found: | |||
523 | qp->q.max_size = skb->len + ihl; | 522 | qp->q.max_size = skb->len + ihl; |
524 | 523 | ||
525 | if (qp->q.last_in == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) && | 524 | if (qp->q.last_in == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) && |
526 | qp->q.meat == qp->q.len) | 525 | qp->q.meat == qp->q.len) { |
527 | return ip_frag_reasm(qp, prev, dev); | 526 | unsigned long orefdst = skb->_skb_refdst; |
528 | 527 | ||
528 | skb->_skb_refdst = 0UL; | ||
529 | err = ip_frag_reasm(qp, prev, dev); | ||
530 | skb->_skb_refdst = orefdst; | ||
531 | return err; | ||
532 | } | ||
533 | |||
534 | skb_dst_drop(skb); | ||
529 | inet_frag_lru_move(&qp->q); | 535 | inet_frag_lru_move(&qp->q); |
530 | return -EINPROGRESS; | 536 | return -EINPROGRESS; |
531 | 537 | ||
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index ef54377fb11c..397e0f69435f 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c | |||
@@ -349,8 +349,8 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, | |||
349 | * hasn't changed since we received the original syn, but I see | 349 | * hasn't changed since we received the original syn, but I see |
350 | * no easy way to do this. | 350 | * no easy way to do this. |
351 | */ | 351 | */ |
352 | flowi4_init_output(&fl4, 0, sk->sk_mark, RT_CONN_FLAGS(sk), | 352 | flowi4_init_output(&fl4, sk->sk_bound_dev_if, sk->sk_mark, |
353 | RT_SCOPE_UNIVERSE, IPPROTO_TCP, | 353 | RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE, IPPROTO_TCP, |
354 | inet_sk_flowi_flags(sk), | 354 | inet_sk_flowi_flags(sk), |
355 | (opt && opt->srr) ? opt->faddr : ireq->rmt_addr, | 355 | (opt && opt->srr) ? opt->faddr : ireq->rmt_addr, |
356 | ireq->loc_addr, th->source, th->dest); | 356 | ireq->loc_addr, th->source, th->dest); |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index b44cf81d8178..509912a5ff98 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -2388,8 +2388,12 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) | |||
2388 | */ | 2388 | */ |
2389 | TCP_SKB_CB(skb)->when = tcp_time_stamp; | 2389 | TCP_SKB_CB(skb)->when = tcp_time_stamp; |
2390 | 2390 | ||
2391 | /* make sure skb->data is aligned on arches that require it */ | 2391 | /* make sure skb->data is aligned on arches that require it |
2392 | if (unlikely(NET_IP_ALIGN && ((unsigned long)skb->data & 3))) { | 2392 | * and check if ack-trimming & collapsing extended the headroom |
2393 | * beyond what csum_start can cover. | ||
2394 | */ | ||
2395 | if (unlikely((NET_IP_ALIGN && ((unsigned long)skb->data & 3)) || | ||
2396 | skb_headroom(skb) >= 0xFFFF)) { | ||
2393 | struct sk_buff *nskb = __pskb_copy(skb, MAX_TCP_HEADER, | 2397 | struct sk_buff *nskb = __pskb_copy(skb, MAX_TCP_HEADER, |
2394 | GFP_ATOMIC); | 2398 | GFP_ATOMIC); |
2395 | return nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) : | 2399 | return nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) : |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index a459c4f5b769..dae802c0af7c 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -168,8 +168,6 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev, | |||
168 | static bool ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr, | 168 | static bool ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr, |
169 | struct net_device *dev); | 169 | struct net_device *dev); |
170 | 170 | ||
171 | static ATOMIC_NOTIFIER_HEAD(inet6addr_chain); | ||
172 | |||
173 | static struct ipv6_devconf ipv6_devconf __read_mostly = { | 171 | static struct ipv6_devconf ipv6_devconf __read_mostly = { |
174 | .forwarding = 0, | 172 | .forwarding = 0, |
175 | .hop_limit = IPV6_DEFAULT_HOPLIMIT, | 173 | .hop_limit = IPV6_DEFAULT_HOPLIMIT, |
@@ -837,7 +835,7 @@ out2: | |||
837 | rcu_read_unlock_bh(); | 835 | rcu_read_unlock_bh(); |
838 | 836 | ||
839 | if (likely(err == 0)) | 837 | if (likely(err == 0)) |
840 | atomic_notifier_call_chain(&inet6addr_chain, NETDEV_UP, ifa); | 838 | inet6addr_notifier_call_chain(NETDEV_UP, ifa); |
841 | else { | 839 | else { |
842 | kfree(ifa); | 840 | kfree(ifa); |
843 | ifa = ERR_PTR(err); | 841 | ifa = ERR_PTR(err); |
@@ -927,7 +925,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) | |||
927 | 925 | ||
928 | ipv6_ifa_notify(RTM_DELADDR, ifp); | 926 | ipv6_ifa_notify(RTM_DELADDR, ifp); |
929 | 927 | ||
930 | atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifp); | 928 | inet6addr_notifier_call_chain(NETDEV_DOWN, ifp); |
931 | 929 | ||
932 | /* | 930 | /* |
933 | * Purge or update corresponding prefix | 931 | * Purge or update corresponding prefix |
@@ -2988,7 +2986,7 @@ static int addrconf_ifdown(struct net_device *dev, int how) | |||
2988 | 2986 | ||
2989 | if (state != INET6_IFADDR_STATE_DEAD) { | 2987 | if (state != INET6_IFADDR_STATE_DEAD) { |
2990 | __ipv6_ifa_notify(RTM_DELADDR, ifa); | 2988 | __ipv6_ifa_notify(RTM_DELADDR, ifa); |
2991 | atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa); | 2989 | inet6addr_notifier_call_chain(NETDEV_DOWN, ifa); |
2992 | } | 2990 | } |
2993 | in6_ifa_put(ifa); | 2991 | in6_ifa_put(ifa); |
2994 | 2992 | ||
@@ -4869,22 +4867,6 @@ static struct pernet_operations addrconf_ops = { | |||
4869 | .exit = addrconf_exit_net, | 4867 | .exit = addrconf_exit_net, |
4870 | }; | 4868 | }; |
4871 | 4869 | ||
4872 | /* | ||
4873 | * Device notifier | ||
4874 | */ | ||
4875 | |||
4876 | int register_inet6addr_notifier(struct notifier_block *nb) | ||
4877 | { | ||
4878 | return atomic_notifier_chain_register(&inet6addr_chain, nb); | ||
4879 | } | ||
4880 | EXPORT_SYMBOL(register_inet6addr_notifier); | ||
4881 | |||
4882 | int unregister_inet6addr_notifier(struct notifier_block *nb) | ||
4883 | { | ||
4884 | return atomic_notifier_chain_unregister(&inet6addr_chain, nb); | ||
4885 | } | ||
4886 | EXPORT_SYMBOL(unregister_inet6addr_notifier); | ||
4887 | |||
4888 | static struct rtnl_af_ops inet6_ops = { | 4870 | static struct rtnl_af_ops inet6_ops = { |
4889 | .family = AF_INET6, | 4871 | .family = AF_INET6, |
4890 | .fill_link_af = inet6_fill_link_af, | 4872 | .fill_link_af = inet6_fill_link_af, |
diff --git a/net/ipv6/addrconf_core.c b/net/ipv6/addrconf_core.c index d051e5f4bf34..72104562c864 100644 --- a/net/ipv6/addrconf_core.c +++ b/net/ipv6/addrconf_core.c | |||
@@ -78,3 +78,22 @@ int __ipv6_addr_type(const struct in6_addr *addr) | |||
78 | } | 78 | } |
79 | EXPORT_SYMBOL(__ipv6_addr_type); | 79 | EXPORT_SYMBOL(__ipv6_addr_type); |
80 | 80 | ||
81 | static ATOMIC_NOTIFIER_HEAD(inet6addr_chain); | ||
82 | |||
83 | int register_inet6addr_notifier(struct notifier_block *nb) | ||
84 | { | ||
85 | return atomic_notifier_chain_register(&inet6addr_chain, nb); | ||
86 | } | ||
87 | EXPORT_SYMBOL(register_inet6addr_notifier); | ||
88 | |||
89 | int unregister_inet6addr_notifier(struct notifier_block *nb) | ||
90 | { | ||
91 | return atomic_notifier_chain_unregister(&inet6addr_chain, nb); | ||
92 | } | ||
93 | EXPORT_SYMBOL(unregister_inet6addr_notifier); | ||
94 | |||
95 | int inet6addr_notifier_call_chain(unsigned long val, void *v) | ||
96 | { | ||
97 | return atomic_notifier_call_chain(&inet6addr_chain, val, v); | ||
98 | } | ||
99 | EXPORT_SYMBOL(inet6addr_notifier_call_chain); | ||
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index 196ab9347ad1..0ba10e53a629 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c | |||
@@ -330,9 +330,17 @@ found: | |||
330 | } | 330 | } |
331 | 331 | ||
332 | if (fq->q.last_in == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) && | 332 | if (fq->q.last_in == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) && |
333 | fq->q.meat == fq->q.len) | 333 | fq->q.meat == fq->q.len) { |
334 | return ip6_frag_reasm(fq, prev, dev); | 334 | int res; |
335 | unsigned long orefdst = skb->_skb_refdst; | ||
336 | |||
337 | skb->_skb_refdst = 0UL; | ||
338 | res = ip6_frag_reasm(fq, prev, dev); | ||
339 | skb->_skb_refdst = orefdst; | ||
340 | return res; | ||
341 | } | ||
335 | 342 | ||
343 | skb_dst_drop(skb); | ||
336 | inet_frag_lru_move(&fq->q); | 344 | inet_frag_lru_move(&fq->q); |
337 | return -1; | 345 | return -1; |
338 | 346 | ||
diff --git a/net/netfilter/ipset/ip_set_hash_ipportnet.c b/net/netfilter/ipset/ip_set_hash_ipportnet.c index f2627226a087..10a30b4fc7db 100644 --- a/net/netfilter/ipset/ip_set_hash_ipportnet.c +++ b/net/netfilter/ipset/ip_set_hash_ipportnet.c | |||
@@ -104,6 +104,15 @@ hash_ipportnet4_data_flags(struct hash_ipportnet4_elem *dst, u32 flags) | |||
104 | dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); | 104 | dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); |
105 | } | 105 | } |
106 | 106 | ||
107 | static inline void | ||
108 | hash_ipportnet4_data_reset_flags(struct hash_ipportnet4_elem *dst, u32 *flags) | ||
109 | { | ||
110 | if (dst->nomatch) { | ||
111 | *flags = IPSET_FLAG_NOMATCH; | ||
112 | dst->nomatch = 0; | ||
113 | } | ||
114 | } | ||
115 | |||
107 | static inline int | 116 | static inline int |
108 | hash_ipportnet4_data_match(const struct hash_ipportnet4_elem *elem) | 117 | hash_ipportnet4_data_match(const struct hash_ipportnet4_elem *elem) |
109 | { | 118 | { |
@@ -414,6 +423,15 @@ hash_ipportnet6_data_flags(struct hash_ipportnet6_elem *dst, u32 flags) | |||
414 | dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); | 423 | dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); |
415 | } | 424 | } |
416 | 425 | ||
426 | static inline void | ||
427 | hash_ipportnet6_data_reset_flags(struct hash_ipportnet6_elem *dst, u32 *flags) | ||
428 | { | ||
429 | if (dst->nomatch) { | ||
430 | *flags = IPSET_FLAG_NOMATCH; | ||
431 | dst->nomatch = 0; | ||
432 | } | ||
433 | } | ||
434 | |||
417 | static inline int | 435 | static inline int |
418 | hash_ipportnet6_data_match(const struct hash_ipportnet6_elem *elem) | 436 | hash_ipportnet6_data_match(const struct hash_ipportnet6_elem *elem) |
419 | { | 437 | { |
diff --git a/net/netfilter/ipset/ip_set_hash_net.c b/net/netfilter/ipset/ip_set_hash_net.c index 4b677cf6bf7d..d6a59154d710 100644 --- a/net/netfilter/ipset/ip_set_hash_net.c +++ b/net/netfilter/ipset/ip_set_hash_net.c | |||
@@ -87,7 +87,16 @@ hash_net4_data_copy(struct hash_net4_elem *dst, | |||
87 | static inline void | 87 | static inline void |
88 | hash_net4_data_flags(struct hash_net4_elem *dst, u32 flags) | 88 | hash_net4_data_flags(struct hash_net4_elem *dst, u32 flags) |
89 | { | 89 | { |
90 | dst->nomatch = flags & IPSET_FLAG_NOMATCH; | 90 | dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); |
91 | } | ||
92 | |||
93 | static inline void | ||
94 | hash_net4_data_reset_flags(struct hash_net4_elem *dst, u32 *flags) | ||
95 | { | ||
96 | if (dst->nomatch) { | ||
97 | *flags = IPSET_FLAG_NOMATCH; | ||
98 | dst->nomatch = 0; | ||
99 | } | ||
91 | } | 100 | } |
92 | 101 | ||
93 | static inline int | 102 | static inline int |
@@ -308,7 +317,16 @@ hash_net6_data_copy(struct hash_net6_elem *dst, | |||
308 | static inline void | 317 | static inline void |
309 | hash_net6_data_flags(struct hash_net6_elem *dst, u32 flags) | 318 | hash_net6_data_flags(struct hash_net6_elem *dst, u32 flags) |
310 | { | 319 | { |
311 | dst->nomatch = flags & IPSET_FLAG_NOMATCH; | 320 | dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); |
321 | } | ||
322 | |||
323 | static inline void | ||
324 | hash_net6_data_reset_flags(struct hash_net6_elem *dst, u32 *flags) | ||
325 | { | ||
326 | if (dst->nomatch) { | ||
327 | *flags = IPSET_FLAG_NOMATCH; | ||
328 | dst->nomatch = 0; | ||
329 | } | ||
312 | } | 330 | } |
313 | 331 | ||
314 | static inline int | 332 | static inline int |
diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c b/net/netfilter/ipset/ip_set_hash_netiface.c index 6ba985f1c96f..f2b0a3c30130 100644 --- a/net/netfilter/ipset/ip_set_hash_netiface.c +++ b/net/netfilter/ipset/ip_set_hash_netiface.c | |||
@@ -198,7 +198,16 @@ hash_netiface4_data_copy(struct hash_netiface4_elem *dst, | |||
198 | static inline void | 198 | static inline void |
199 | hash_netiface4_data_flags(struct hash_netiface4_elem *dst, u32 flags) | 199 | hash_netiface4_data_flags(struct hash_netiface4_elem *dst, u32 flags) |
200 | { | 200 | { |
201 | dst->nomatch = flags & IPSET_FLAG_NOMATCH; | 201 | dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); |
202 | } | ||
203 | |||
204 | static inline void | ||
205 | hash_netiface4_data_reset_flags(struct hash_netiface4_elem *dst, u32 *flags) | ||
206 | { | ||
207 | if (dst->nomatch) { | ||
208 | *flags = IPSET_FLAG_NOMATCH; | ||
209 | dst->nomatch = 0; | ||
210 | } | ||
202 | } | 211 | } |
203 | 212 | ||
204 | static inline int | 213 | static inline int |
@@ -494,7 +503,7 @@ hash_netiface6_data_copy(struct hash_netiface6_elem *dst, | |||
494 | static inline void | 503 | static inline void |
495 | hash_netiface6_data_flags(struct hash_netiface6_elem *dst, u32 flags) | 504 | hash_netiface6_data_flags(struct hash_netiface6_elem *dst, u32 flags) |
496 | { | 505 | { |
497 | dst->nomatch = flags & IPSET_FLAG_NOMATCH; | 506 | dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); |
498 | } | 507 | } |
499 | 508 | ||
500 | static inline int | 509 | static inline int |
@@ -504,6 +513,15 @@ hash_netiface6_data_match(const struct hash_netiface6_elem *elem) | |||
504 | } | 513 | } |
505 | 514 | ||
506 | static inline void | 515 | static inline void |
516 | hash_netiface6_data_reset_flags(struct hash_netiface6_elem *dst, u32 *flags) | ||
517 | { | ||
518 | if (dst->nomatch) { | ||
519 | *flags = IPSET_FLAG_NOMATCH; | ||
520 | dst->nomatch = 0; | ||
521 | } | ||
522 | } | ||
523 | |||
524 | static inline void | ||
507 | hash_netiface6_data_zero_out(struct hash_netiface6_elem *elem) | 525 | hash_netiface6_data_zero_out(struct hash_netiface6_elem *elem) |
508 | { | 526 | { |
509 | elem->elem = 0; | 527 | elem->elem = 0; |
diff --git a/net/netfilter/ipset/ip_set_hash_netport.c b/net/netfilter/ipset/ip_set_hash_netport.c index af20c0c5ced2..349deb672a2d 100644 --- a/net/netfilter/ipset/ip_set_hash_netport.c +++ b/net/netfilter/ipset/ip_set_hash_netport.c | |||
@@ -104,6 +104,15 @@ hash_netport4_data_flags(struct hash_netport4_elem *dst, u32 flags) | |||
104 | dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); | 104 | dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); |
105 | } | 105 | } |
106 | 106 | ||
107 | static inline void | ||
108 | hash_netport4_data_reset_flags(struct hash_netport4_elem *dst, u32 *flags) | ||
109 | { | ||
110 | if (dst->nomatch) { | ||
111 | *flags = IPSET_FLAG_NOMATCH; | ||
112 | dst->nomatch = 0; | ||
113 | } | ||
114 | } | ||
115 | |||
107 | static inline int | 116 | static inline int |
108 | hash_netport4_data_match(const struct hash_netport4_elem *elem) | 117 | hash_netport4_data_match(const struct hash_netport4_elem *elem) |
109 | { | 118 | { |
@@ -375,6 +384,15 @@ hash_netport6_data_flags(struct hash_netport6_elem *dst, u32 flags) | |||
375 | dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); | 384 | dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); |
376 | } | 385 | } |
377 | 386 | ||
387 | static inline void | ||
388 | hash_netport6_data_reset_flags(struct hash_netport6_elem *dst, u32 *flags) | ||
389 | { | ||
390 | if (dst->nomatch) { | ||
391 | *flags = IPSET_FLAG_NOMATCH; | ||
392 | dst->nomatch = 0; | ||
393 | } | ||
394 | } | ||
395 | |||
378 | static inline int | 396 | static inline int |
379 | hash_netport6_data_match(const struct hash_netport6_elem *elem) | 397 | hash_netport6_data_match(const struct hash_netport6_elem *elem) |
380 | { | 398 | { |
diff --git a/net/netfilter/ipset/ip_set_list_set.c b/net/netfilter/ipset/ip_set_list_set.c index 8371c2bac2e4..09c744aa8982 100644 --- a/net/netfilter/ipset/ip_set_list_set.c +++ b/net/netfilter/ipset/ip_set_list_set.c | |||
@@ -174,9 +174,13 @@ list_set_add(struct list_set *map, u32 i, ip_set_id_t id, | |||
174 | { | 174 | { |
175 | const struct set_elem *e = list_set_elem(map, i); | 175 | const struct set_elem *e = list_set_elem(map, i); |
176 | 176 | ||
177 | if (i == map->size - 1 && e->id != IPSET_INVALID_ID) | 177 | if (e->id != IPSET_INVALID_ID) { |
178 | /* Last element replaced: e.g. add new,before,last */ | 178 | const struct set_elem *x = list_set_elem(map, map->size - 1); |
179 | ip_set_put_byindex(e->id); | 179 | |
180 | /* Last element replaced or pushed off */ | ||
181 | if (x->id != IPSET_INVALID_ID) | ||
182 | ip_set_put_byindex(x->id); | ||
183 | } | ||
180 | if (with_timeout(map->timeout)) | 184 | if (with_timeout(map->timeout)) |
181 | list_elem_tadd(map, i, id, ip_set_timeout_set(timeout)); | 185 | list_elem_tadd(map, i, id, ip_set_timeout_set(timeout)); |
182 | else | 186 | else |
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index 0e7d423324c3..e0c4373b4747 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c | |||
@@ -1593,10 +1593,8 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff, | |||
1593 | end += strlen("\r\n\r\n") + clen; | 1593 | end += strlen("\r\n\r\n") + clen; |
1594 | 1594 | ||
1595 | msglen = origlen = end - dptr; | 1595 | msglen = origlen = end - dptr; |
1596 | if (msglen > datalen) { | 1596 | if (msglen > datalen) |
1597 | nf_ct_helper_log(skb, ct, "incomplete/bad SIP message"); | 1597 | return NF_ACCEPT; |
1598 | return NF_DROP; | ||
1599 | } | ||
1600 | 1598 | ||
1601 | ret = process_sip_msg(skb, ct, protoff, dataoff, | 1599 | ret = process_sip_msg(skb, ct, protoff, dataoff, |
1602 | &dptr, &msglen); | 1600 | &dptr, &msglen); |
diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c index 8d5769c6d16e..ad24be070e53 100644 --- a/net/netfilter/nf_nat_core.c +++ b/net/netfilter/nf_nat_core.c | |||
@@ -467,33 +467,22 @@ EXPORT_SYMBOL_GPL(nf_nat_packet); | |||
467 | struct nf_nat_proto_clean { | 467 | struct nf_nat_proto_clean { |
468 | u8 l3proto; | 468 | u8 l3proto; |
469 | u8 l4proto; | 469 | u8 l4proto; |
470 | bool hash; | ||
471 | }; | 470 | }; |
472 | 471 | ||
473 | /* Clear NAT section of all conntracks, in case we're loaded again. */ | 472 | /* kill conntracks with affected NAT section */ |
474 | static int nf_nat_proto_clean(struct nf_conn *i, void *data) | 473 | static int nf_nat_proto_remove(struct nf_conn *i, void *data) |
475 | { | 474 | { |
476 | const struct nf_nat_proto_clean *clean = data; | 475 | const struct nf_nat_proto_clean *clean = data; |
477 | struct nf_conn_nat *nat = nfct_nat(i); | 476 | struct nf_conn_nat *nat = nfct_nat(i); |
478 | 477 | ||
479 | if (!nat) | 478 | if (!nat) |
480 | return 0; | 479 | return 0; |
481 | if (!(i->status & IPS_SRC_NAT_DONE)) | 480 | |
482 | return 0; | ||
483 | if ((clean->l3proto && nf_ct_l3num(i) != clean->l3proto) || | 481 | if ((clean->l3proto && nf_ct_l3num(i) != clean->l3proto) || |
484 | (clean->l4proto && nf_ct_protonum(i) != clean->l4proto)) | 482 | (clean->l4proto && nf_ct_protonum(i) != clean->l4proto)) |
485 | return 0; | 483 | return 0; |
486 | 484 | ||
487 | if (clean->hash) { | 485 | return i->status & IPS_NAT_MASK ? 1 : 0; |
488 | spin_lock_bh(&nf_nat_lock); | ||
489 | hlist_del_rcu(&nat->bysource); | ||
490 | spin_unlock_bh(&nf_nat_lock); | ||
491 | } else { | ||
492 | memset(nat, 0, sizeof(*nat)); | ||
493 | i->status &= ~(IPS_NAT_MASK | IPS_NAT_DONE_MASK | | ||
494 | IPS_SEQ_ADJUST); | ||
495 | } | ||
496 | return 0; | ||
497 | } | 486 | } |
498 | 487 | ||
499 | static void nf_nat_l4proto_clean(u8 l3proto, u8 l4proto) | 488 | static void nf_nat_l4proto_clean(u8 l3proto, u8 l4proto) |
@@ -505,16 +494,8 @@ static void nf_nat_l4proto_clean(u8 l3proto, u8 l4proto) | |||
505 | struct net *net; | 494 | struct net *net; |
506 | 495 | ||
507 | rtnl_lock(); | 496 | rtnl_lock(); |
508 | /* Step 1 - remove from bysource hash */ | ||
509 | clean.hash = true; | ||
510 | for_each_net(net) | 497 | for_each_net(net) |
511 | nf_ct_iterate_cleanup(net, nf_nat_proto_clean, &clean); | 498 | nf_ct_iterate_cleanup(net, nf_nat_proto_remove, &clean); |
512 | synchronize_rcu(); | ||
513 | |||
514 | /* Step 2 - clean NAT section */ | ||
515 | clean.hash = false; | ||
516 | for_each_net(net) | ||
517 | nf_ct_iterate_cleanup(net, nf_nat_proto_clean, &clean); | ||
518 | rtnl_unlock(); | 499 | rtnl_unlock(); |
519 | } | 500 | } |
520 | 501 | ||
@@ -526,16 +507,9 @@ static void nf_nat_l3proto_clean(u8 l3proto) | |||
526 | struct net *net; | 507 | struct net *net; |
527 | 508 | ||
528 | rtnl_lock(); | 509 | rtnl_lock(); |
529 | /* Step 1 - remove from bysource hash */ | ||
530 | clean.hash = true; | ||
531 | for_each_net(net) | ||
532 | nf_ct_iterate_cleanup(net, nf_nat_proto_clean, &clean); | ||
533 | synchronize_rcu(); | ||
534 | 510 | ||
535 | /* Step 2 - clean NAT section */ | ||
536 | clean.hash = false; | ||
537 | for_each_net(net) | 511 | for_each_net(net) |
538 | nf_ct_iterate_cleanup(net, nf_nat_proto_clean, &clean); | 512 | nf_ct_iterate_cleanup(net, nf_nat_proto_remove, &clean); |
539 | rtnl_unlock(); | 513 | rtnl_unlock(); |
540 | } | 514 | } |
541 | 515 | ||
@@ -773,7 +747,7 @@ static void __net_exit nf_nat_net_exit(struct net *net) | |||
773 | { | 747 | { |
774 | struct nf_nat_proto_clean clean = {}; | 748 | struct nf_nat_proto_clean clean = {}; |
775 | 749 | ||
776 | nf_ct_iterate_cleanup(net, &nf_nat_proto_clean, &clean); | 750 | nf_ct_iterate_cleanup(net, &nf_nat_proto_remove, &clean); |
777 | synchronize_rcu(); | 751 | synchronize_rcu(); |
778 | nf_ct_free_hashtable(net->ct.nat_bysource, net->ct.nat_htable_size); | 752 | nf_ct_free_hashtable(net->ct.nat_bysource, net->ct.nat_htable_size); |
779 | } | 753 | } |