aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/net_namespace.h37
-rw-r--r--include/net/netns/ipv4.h1
-rw-r--r--include/net/netns/ipv6.h1
-rw-r--r--net/ipv4/route.c16
-rw-r--r--net/ipv6/af_inet6.c1
-rw-r--r--net/ipv6/route.c4
-rw-r--r--net/xfrm/xfrm_policy.c8
-rw-r--r--security/selinux/include/xfrm.h7
8 files changed, 58 insertions, 17 deletions
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index 84e37b1ca9e1..1313456a0994 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -119,7 +119,6 @@ struct net {
119 struct netns_ipvs *ipvs; 119 struct netns_ipvs *ipvs;
120#endif 120#endif
121 struct sock *diag_nlsk; 121 struct sock *diag_nlsk;
122 atomic_t rt_genid;
123 atomic_t fnhe_genid; 122 atomic_t fnhe_genid;
124}; 123};
125 124
@@ -333,14 +332,42 @@ static inline void unregister_net_sysctl_table(struct ctl_table_header *header)
333} 332}
334#endif 333#endif
335 334
336static inline int rt_genid(struct net *net) 335static inline int rt_genid_ipv4(struct net *net)
337{ 336{
338 return atomic_read(&net->rt_genid); 337 return atomic_read(&net->ipv4.rt_genid);
339} 338}
340 339
341static inline void rt_genid_bump(struct net *net) 340static inline void rt_genid_bump_ipv4(struct net *net)
342{ 341{
343 atomic_inc(&net->rt_genid); 342 atomic_inc(&net->ipv4.rt_genid);
343}
344
345#if IS_ENABLED(CONFIG_IPV6)
346static inline int rt_genid_ipv6(struct net *net)
347{
348 return atomic_read(&net->ipv6.rt_genid);
349}
350
351static inline void rt_genid_bump_ipv6(struct net *net)
352{
353 atomic_inc(&net->ipv6.rt_genid);
354}
355#else
356static inline int rt_genid_ipv6(struct net *net)
357{
358 return 0;
359}
360
361static inline void rt_genid_bump_ipv6(struct net *net)
362{
363}
364#endif
365
366/* For callers who don't really care about whether it's IPv4 or IPv6 */
367static inline void rt_genid_bump_all(struct net *net)
368{
369 rt_genid_bump_ipv4(net);
370 rt_genid_bump_ipv6(net);
344} 371}
345 372
346static inline int fnhe_genid(struct net *net) 373static inline int fnhe_genid(struct net *net)
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
index 2ba9de89e8ec..bf2ec2202c56 100644
--- a/include/net/netns/ipv4.h
+++ b/include/net/netns/ipv4.h
@@ -77,5 +77,6 @@ struct netns_ipv4 {
77 struct fib_rules_ops *mr_rules_ops; 77 struct fib_rules_ops *mr_rules_ops;
78#endif 78#endif
79#endif 79#endif
80 atomic_t rt_genid;
80}; 81};
81#endif 82#endif
diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h
index 005e2c2e39a9..0fb2401197c5 100644
--- a/include/net/netns/ipv6.h
+++ b/include/net/netns/ipv6.h
@@ -72,6 +72,7 @@ struct netns_ipv6 {
72#endif 72#endif
73#endif 73#endif
74 atomic_t dev_addr_genid; 74 atomic_t dev_addr_genid;
75 atomic_t rt_genid;
75}; 76};
76 77
77#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6) 78#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index a9a54a236832..e805481eff72 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -435,12 +435,12 @@ static inline int ip_rt_proc_init(void)
435 435
436static inline bool rt_is_expired(const struct rtable *rth) 436static inline bool rt_is_expired(const struct rtable *rth)
437{ 437{
438 return rth->rt_genid != rt_genid(dev_net(rth->dst.dev)); 438 return rth->rt_genid != rt_genid_ipv4(dev_net(rth->dst.dev));
439} 439}
440 440
441void rt_cache_flush(struct net *net) 441void rt_cache_flush(struct net *net)
442{ 442{
443 rt_genid_bump(net); 443 rt_genid_bump_ipv4(net);
444} 444}
445 445
446static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst, 446static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst,
@@ -1458,7 +1458,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
1458#endif 1458#endif
1459 rth->dst.output = ip_rt_bug; 1459 rth->dst.output = ip_rt_bug;
1460 1460
1461 rth->rt_genid = rt_genid(dev_net(dev)); 1461 rth->rt_genid = rt_genid_ipv4(dev_net(dev));
1462 rth->rt_flags = RTCF_MULTICAST; 1462 rth->rt_flags = RTCF_MULTICAST;
1463 rth->rt_type = RTN_MULTICAST; 1463 rth->rt_type = RTN_MULTICAST;
1464 rth->rt_is_input= 1; 1464 rth->rt_is_input= 1;
@@ -1589,7 +1589,7 @@ static int __mkroute_input(struct sk_buff *skb,
1589 goto cleanup; 1589 goto cleanup;
1590 } 1590 }
1591 1591
1592 rth->rt_genid = rt_genid(dev_net(rth->dst.dev)); 1592 rth->rt_genid = rt_genid_ipv4(dev_net(rth->dst.dev));
1593 rth->rt_flags = flags; 1593 rth->rt_flags = flags;
1594 rth->rt_type = res->type; 1594 rth->rt_type = res->type;
1595 rth->rt_is_input = 1; 1595 rth->rt_is_input = 1;
@@ -1760,7 +1760,7 @@ local_input:
1760 rth->dst.tclassid = itag; 1760 rth->dst.tclassid = itag;
1761#endif 1761#endif
1762 1762
1763 rth->rt_genid = rt_genid(net); 1763 rth->rt_genid = rt_genid_ipv4(net);
1764 rth->rt_flags = flags|RTCF_LOCAL; 1764 rth->rt_flags = flags|RTCF_LOCAL;
1765 rth->rt_type = res.type; 1765 rth->rt_type = res.type;
1766 rth->rt_is_input = 1; 1766 rth->rt_is_input = 1;
@@ -1945,7 +1945,7 @@ add:
1945 1945
1946 rth->dst.output = ip_output; 1946 rth->dst.output = ip_output;
1947 1947
1948 rth->rt_genid = rt_genid(dev_net(dev_out)); 1948 rth->rt_genid = rt_genid_ipv4(dev_net(dev_out));
1949 rth->rt_flags = flags; 1949 rth->rt_flags = flags;
1950 rth->rt_type = type; 1950 rth->rt_type = type;
1951 rth->rt_is_input = 0; 1951 rth->rt_is_input = 0;
@@ -2227,7 +2227,7 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or
2227 rt->rt_iif = ort->rt_iif; 2227 rt->rt_iif = ort->rt_iif;
2228 rt->rt_pmtu = ort->rt_pmtu; 2228 rt->rt_pmtu = ort->rt_pmtu;
2229 2229
2230 rt->rt_genid = rt_genid(net); 2230 rt->rt_genid = rt_genid_ipv4(net);
2231 rt->rt_flags = ort->rt_flags; 2231 rt->rt_flags = ort->rt_flags;
2232 rt->rt_type = ort->rt_type; 2232 rt->rt_type = ort->rt_type;
2233 rt->rt_gateway = ort->rt_gateway; 2233 rt->rt_gateway = ort->rt_gateway;
@@ -2665,7 +2665,7 @@ static __net_initdata struct pernet_operations sysctl_route_ops = {
2665 2665
2666static __net_init int rt_genid_init(struct net *net) 2666static __net_init int rt_genid_init(struct net *net)
2667{ 2667{
2668 atomic_set(&net->rt_genid, 0); 2668 atomic_set(&net->ipv4.rt_genid, 0);
2669 atomic_set(&net->fnhe_genid, 0); 2669 atomic_set(&net->fnhe_genid, 0);
2670 get_random_bytes(&net->ipv4.dev_addr_genid, 2670 get_random_bytes(&net->ipv4.dev_addr_genid,
2671 sizeof(net->ipv4.dev_addr_genid)); 2671 sizeof(net->ipv4.dev_addr_genid));
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index a5ac969aeefe..0d1a9b153fbb 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -766,6 +766,7 @@ static int __net_init inet6_net_init(struct net *net)
766 766
767 net->ipv6.sysctl.bindv6only = 0; 767 net->ipv6.sysctl.bindv6only = 0;
768 net->ipv6.sysctl.icmpv6_time = 1*HZ; 768 net->ipv6.sysctl.icmpv6_time = 1*HZ;
769 atomic_set(&net->ipv6.rt_genid, 0);
769 770
770 err = ipv6_init_mibs(net); 771 err = ipv6_init_mibs(net);
771 if (err) 772 if (err)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 74ab1f74abcd..ce9616304521 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -283,7 +283,7 @@ static inline struct rt6_info *ip6_dst_alloc(struct net *net,
283 283
284 memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst)); 284 memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst));
285 rt6_init_peer(rt, table ? &table->tb6_peers : net->ipv6.peers); 285 rt6_init_peer(rt, table ? &table->tb6_peers : net->ipv6.peers);
286 rt->rt6i_genid = rt_genid(net); 286 rt->rt6i_genid = rt_genid_ipv6(net);
287 INIT_LIST_HEAD(&rt->rt6i_siblings); 287 INIT_LIST_HEAD(&rt->rt6i_siblings);
288 } 288 }
289 return rt; 289 return rt;
@@ -1061,7 +1061,7 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie)
1061 * DST_OBSOLETE_FORCE_CHK which forces validation calls down 1061 * DST_OBSOLETE_FORCE_CHK which forces validation calls down
1062 * into this function always. 1062 * into this function always.
1063 */ 1063 */
1064 if (rt->rt6i_genid != rt_genid(dev_net(rt->dst.dev))) 1064 if (rt->rt6i_genid != rt_genid_ipv6(dev_net(rt->dst.dev)))
1065 return NULL; 1065 return NULL;
1066 1066
1067 if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) 1067 if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie))
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index e52cab3591dd..d8da6b8c6ba8 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -660,7 +660,13 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
660 xfrm_pol_hold(policy); 660 xfrm_pol_hold(policy);
661 net->xfrm.policy_count[dir]++; 661 net->xfrm.policy_count[dir]++;
662 atomic_inc(&flow_cache_genid); 662 atomic_inc(&flow_cache_genid);
663 rt_genid_bump(net); 663
664 /* After previous checking, family can either be AF_INET or AF_INET6 */
665 if (policy->family == AF_INET)
666 rt_genid_bump_ipv4(net);
667 else
668 rt_genid_bump_ipv6(net);
669
664 if (delpol) { 670 if (delpol) {
665 xfrm_policy_requeue(delpol, policy); 671 xfrm_policy_requeue(delpol, policy);
666 __xfrm_policy_unlink(delpol, dir); 672 __xfrm_policy_unlink(delpol, dir);
diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h
index 65f67cb0aefb..6713f04e30ba 100644
--- a/security/selinux/include/xfrm.h
+++ b/security/selinux/include/xfrm.h
@@ -50,8 +50,13 @@ int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall);
50 50
51static inline void selinux_xfrm_notify_policyload(void) 51static inline void selinux_xfrm_notify_policyload(void)
52{ 52{
53 struct net *net;
54
53 atomic_inc(&flow_cache_genid); 55 atomic_inc(&flow_cache_genid);
54 rt_genid_bump(&init_net); 56 rtnl_lock();
57 for_each_net(net)
58 rt_genid_bump_all(net);
59 rtnl_unlock();
55} 60}
56#else 61#else
57static inline int selinux_xfrm_enabled(void) 62static inline int selinux_xfrm_enabled(void)