route.c (9a64e8e0ace51b309fdcff4b4754b3649250382a) | route.c (81aded24675ebda5de8a68843250ad15584ac38a) |
---|---|
1/* 2 * Linux INET6 implementation 3 * FIB front-end. 4 * 5 * Authors: 6 * Pedro Roque <roque@di.fc.ul.pt> 7 * 8 * This program is free software; you can redistribute it and/or --- 85 unchanged lines hidden (view full) --- 94{ 95 struct rt6_info *rt = (struct rt6_info *) dst; 96 struct inet_peer *peer; 97 u32 *p = NULL; 98 99 if (!(rt->dst.flags & DST_HOST)) 100 return NULL; 101 | 1/* 2 * Linux INET6 implementation 3 * FIB front-end. 4 * 5 * Authors: 6 * Pedro Roque <roque@di.fc.ul.pt> 7 * 8 * This program is free software; you can redistribute it and/or --- 85 unchanged lines hidden (view full) --- 94{ 95 struct rt6_info *rt = (struct rt6_info *) dst; 96 struct inet_peer *peer; 97 u32 *p = NULL; 98 99 if (!(rt->dst.flags & DST_HOST)) 100 return NULL; 101 |
102 if (!rt->rt6i_peer) 103 rt6_bind_peer(rt, 1); 104 105 peer = rt->rt6i_peer; | 102 peer = rt6_get_peer_create(rt); |
106 if (peer) { 107 u32 *old_p = __DST_METRICS_PTR(old); 108 unsigned long prev, new; 109 110 p = peer->metrics; 111 if (inet_metrics_new(peer)) 112 memcpy(p, old_p, sizeof(u32) * RTAX_MAX); 113 --- 142 unchanged lines hidden (view full) --- 256 .rt6i_protocol = RTPROT_KERNEL, 257 .rt6i_metric = ~(u32) 0, 258 .rt6i_ref = ATOMIC_INIT(1), 259}; 260 261#endif 262 263/* allocate dst with ip6_dst_ops */ | 103 if (peer) { 104 u32 *old_p = __DST_METRICS_PTR(old); 105 unsigned long prev, new; 106 107 p = peer->metrics; 108 if (inet_metrics_new(peer)) 109 memcpy(p, old_p, sizeof(u32) * RTAX_MAX); 110 --- 142 unchanged lines hidden (view full) --- 253 .rt6i_protocol = RTPROT_KERNEL, 254 .rt6i_metric = ~(u32) 0, 255 .rt6i_ref = ATOMIC_INIT(1), 256}; 257 258#endif 259 260/* allocate dst with ip6_dst_ops */ |
264static inline struct rt6_info *ip6_dst_alloc(struct dst_ops *ops, | 261static inline struct rt6_info *ip6_dst_alloc(struct net *net, |
265 struct net_device *dev, | 262 struct net_device *dev, |
266 int flags) | 263 int flags, 264 struct fib6_table *table) |
267{ | 265{ |
268 struct rt6_info *rt = dst_alloc(ops, dev, 0, 0, flags); | 266 struct rt6_info *rt = dst_alloc(&net->ipv6.ip6_dst_ops, dev, 267 0, 0, flags); |
269 | 268 |
270 if (rt) | 269 if (rt) { |
271 memset(&rt->rt6i_table, 0, 272 sizeof(*rt) - sizeof(struct dst_entry)); | 270 memset(&rt->rt6i_table, 0, 271 sizeof(*rt) - sizeof(struct dst_entry)); |
273 | 272 rt6_init_peer(rt, table ? &table->tb6_peers : net->ipv6.peers); 273 } |
274 return rt; 275} 276 277static void ip6_dst_destroy(struct dst_entry *dst) 278{ 279 struct rt6_info *rt = (struct rt6_info *)dst; 280 struct inet6_dev *idev = rt->rt6i_idev; | 274 return rt; 275} 276 277static void ip6_dst_destroy(struct dst_entry *dst) 278{ 279 struct rt6_info *rt = (struct rt6_info *)dst; 280 struct inet6_dev *idev = rt->rt6i_idev; |
281 struct inet_peer *peer = rt->rt6i_peer; | |
282 283 if (!(rt->dst.flags & DST_HOST)) 284 dst_destroy_metrics_generic(dst); 285 286 if (idev) { 287 rt->rt6i_idev = NULL; 288 in6_dev_put(idev); 289 } 290 291 if (!(rt->rt6i_flags & RTF_EXPIRES) && dst->from) 292 dst_release(dst->from); 293 | 281 282 if (!(rt->dst.flags & DST_HOST)) 283 dst_destroy_metrics_generic(dst); 284 285 if (idev) { 286 rt->rt6i_idev = NULL; 287 in6_dev_put(idev); 288 } 289 290 if (!(rt->rt6i_flags & RTF_EXPIRES) && dst->from) 291 dst_release(dst->from); 292 |
294 if (peer) { 295 rt->rt6i_peer = NULL; | 293 if (rt6_has_peer(rt)) { 294 struct inet_peer *peer = rt6_peer_ptr(rt); |
296 inet_putpeer(peer); 297 } 298} 299 300static atomic_t __rt6_peer_genid = ATOMIC_INIT(0); 301 302static u32 rt6_peer_genid(void) 303{ 304 return atomic_read(&__rt6_peer_genid); 305} 306 307void rt6_bind_peer(struct rt6_info *rt, int create) 308{ | 295 inet_putpeer(peer); 296 } 297} 298 299static atomic_t __rt6_peer_genid = ATOMIC_INIT(0); 300 301static u32 rt6_peer_genid(void) 302{ 303 return atomic_read(&__rt6_peer_genid); 304} 305 306void rt6_bind_peer(struct rt6_info *rt, int create) 307{ |
308 struct inet_peer_base *base; |
|
309 struct inet_peer *peer; 310 | 309 struct inet_peer *peer; 310 |
311 peer = inet_getpeer_v6(&rt->rt6i_dst.addr, create); 312 if (peer && cmpxchg(&rt->rt6i_peer, NULL, peer) != NULL) 313 inet_putpeer(peer); 314 else 315 rt->rt6i_peer_genid = rt6_peer_genid(); | 311 base = inetpeer_base_ptr(rt->_rt6i_peer); 312 if (!base) 313 return; 314 315 peer = inet_getpeer_v6(base, &rt->rt6i_dst.addr, create); 316 if (peer) { 317 if (!rt6_set_peer(rt, peer)) 318 inet_putpeer(peer); 319 else 320 rt->rt6i_peer_genid = rt6_peer_genid(); 321 } |
316} 317 318static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev, 319 int how) 320{ 321 struct rt6_info *rt = (struct rt6_info *)dst; 322 struct inet6_dev *idev = rt->rt6i_idev; 323 struct net_device *loopback_dev = --- 623 unchanged lines hidden (view full) --- 947struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_orig) 948{ 949 struct rt6_info *rt, *ort = (struct rt6_info *) dst_orig; 950 struct dst_entry *new = NULL; 951 952 rt = dst_alloc(&ip6_dst_blackhole_ops, ort->dst.dev, 1, 0, 0); 953 if (rt) { 954 memset(&rt->rt6i_table, 0, sizeof(*rt) - sizeof(struct dst_entry)); | 322} 323 324static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev, 325 int how) 326{ 327 struct rt6_info *rt = (struct rt6_info *)dst; 328 struct inet6_dev *idev = rt->rt6i_idev; 329 struct net_device *loopback_dev = --- 623 unchanged lines hidden (view full) --- 953struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_orig) 954{ 955 struct rt6_info *rt, *ort = (struct rt6_info *) dst_orig; 956 struct dst_entry *new = NULL; 957 958 rt = dst_alloc(&ip6_dst_blackhole_ops, ort->dst.dev, 1, 0, 0); 959 if (rt) { 960 memset(&rt->rt6i_table, 0, sizeof(*rt) - sizeof(struct dst_entry)); |
961 rt6_init_peer(rt, net->ipv6.peers); |
|
955 956 new = &rt->dst; 957 958 new->__use = 1; 959 new->input = dst_discard; 960 new->output = dst_discard; 961 962 if (dst_metrics_read_only(&ort->dst)) --- 28 unchanged lines hidden (view full) --- 991static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie) 992{ 993 struct rt6_info *rt; 994 995 rt = (struct rt6_info *) dst; 996 997 if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) { 998 if (rt->rt6i_peer_genid != rt6_peer_genid()) { | 962 963 new = &rt->dst; 964 965 new->__use = 1; 966 new->input = dst_discard; 967 new->output = dst_discard; 968 969 if (dst_metrics_read_only(&ort->dst)) --- 28 unchanged lines hidden (view full) --- 998static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie) 999{ 1000 struct rt6_info *rt; 1001 1002 rt = (struct rt6_info *) dst; 1003 1004 if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) { 1005 if (rt->rt6i_peer_genid != rt6_peer_genid()) { |
999 if (!rt->rt6i_peer) | 1006 if (!rt6_has_peer(rt)) |
1000 rt6_bind_peer(rt, 0); 1001 rt->rt6i_peer_genid = rt6_peer_genid(); 1002 } 1003 return dst; 1004 } 1005 return NULL; 1006} 1007 --- 29 unchanged lines hidden (view full) --- 1037 rt->rt6i_node->fn_sernum = -1; 1038 } 1039} 1040 1041static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu) 1042{ 1043 struct rt6_info *rt6 = (struct rt6_info*)dst; 1044 | 1007 rt6_bind_peer(rt, 0); 1008 rt->rt6i_peer_genid = rt6_peer_genid(); 1009 } 1010 return dst; 1011 } 1012 return NULL; 1013} 1014 --- 29 unchanged lines hidden (view full) --- 1044 rt->rt6i_node->fn_sernum = -1; 1045 } 1046} 1047 1048static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu) 1049{ 1050 struct rt6_info *rt6 = (struct rt6_info*)dst; 1051 |
1052 dst_confirm(dst); |
|
1045 if (mtu < dst_mtu(dst) && rt6->rt6i_dst.plen == 128) { | 1053 if (mtu < dst_mtu(dst) && rt6->rt6i_dst.plen == 128) { |
1054 struct net *net = dev_net(dst->dev); 1055 |
|
1046 rt6->rt6i_flags |= RTF_MODIFIED; 1047 if (mtu < IPV6_MIN_MTU) { 1048 u32 features = dst_metric(dst, RTAX_FEATURES); 1049 mtu = IPV6_MIN_MTU; 1050 features |= RTAX_FEATURE_ALLFRAG; 1051 dst_metric_set(dst, RTAX_FEATURES, features); 1052 } 1053 dst_metric_set(dst, RTAX_MTU, mtu); | 1056 rt6->rt6i_flags |= RTF_MODIFIED; 1057 if (mtu < IPV6_MIN_MTU) { 1058 u32 features = dst_metric(dst, RTAX_FEATURES); 1059 mtu = IPV6_MIN_MTU; 1060 features |= RTAX_FEATURE_ALLFRAG; 1061 dst_metric_set(dst, RTAX_FEATURES, features); 1062 } 1063 dst_metric_set(dst, RTAX_MTU, mtu); |
1064 rt6_update_expires(rt6, net->ipv6.sysctl.ip6_rt_mtu_expires); |
|
1054 } 1055} 1056 | 1065 } 1066} 1067 |
1068void ip6_update_pmtu(struct sk_buff *skb, struct net *net, u32 mtu, 1069 int oif, __be32 mark) 1070{ 1071 const struct ipv6hdr *iph = (struct ipv6hdr *) skb->data; 1072 struct dst_entry *dst; 1073 struct flowi6 fl6; 1074 1075 memset(&fl6, 0, sizeof(fl6)); 1076 fl6.flowi6_oif = oif; 1077 fl6.flowi6_mark = mark; 1078 fl6.flowi6_flags = FLOWI_FLAG_PRECOW_METRICS; 1079 fl6.daddr = iph->daddr; 1080 fl6.saddr = iph->saddr; 1081 fl6.flowlabel = (*(__be32 *) iph) & IPV6_FLOWINFO_MASK; 1082 1083 dst = ip6_route_output(net, NULL, &fl6); 1084 if (!dst->error) 1085 ip6_rt_update_pmtu(dst, ntohl(mtu)); 1086 dst_release(dst); 1087} 1088EXPORT_SYMBOL_GPL(ip6_update_pmtu); 1089 1090void ip6_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, __be32 mtu) 1091{ 1092 ip6_update_pmtu(skb, sock_net(sk), mtu, 1093 sk->sk_bound_dev_if, sk->sk_mark); 1094} 1095EXPORT_SYMBOL_GPL(ip6_sk_update_pmtu); 1096 |
|
1057static unsigned int ip6_default_advmss(const struct dst_entry *dst) 1058{ 1059 struct net_device *dev = dst->dev; 1060 unsigned int mtu = dst_mtu(dst); 1061 struct net *net = dev_net(dev); 1062 1063 mtu -= sizeof(struct ipv6hdr) + sizeof(struct tcphdr); 1064 --- 40 unchanged lines hidden (view full) --- 1105 struct dst_entry *dst; 1106 struct rt6_info *rt; 1107 struct inet6_dev *idev = in6_dev_get(dev); 1108 struct net *net = dev_net(dev); 1109 1110 if (unlikely(!idev)) 1111 return ERR_PTR(-ENODEV); 1112 | 1097static unsigned int ip6_default_advmss(const struct dst_entry *dst) 1098{ 1099 struct net_device *dev = dst->dev; 1100 unsigned int mtu = dst_mtu(dst); 1101 struct net *net = dev_net(dev); 1102 1103 mtu -= sizeof(struct ipv6hdr) + sizeof(struct tcphdr); 1104 --- 40 unchanged lines hidden (view full) --- 1145 struct dst_entry *dst; 1146 struct rt6_info *rt; 1147 struct inet6_dev *idev = in6_dev_get(dev); 1148 struct net *net = dev_net(dev); 1149 1150 if (unlikely(!idev)) 1151 return ERR_PTR(-ENODEV); 1152 |
1113 rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, dev, 0); | 1153 rt = ip6_dst_alloc(net, dev, 0, NULL); |
1114 if (unlikely(!rt)) { 1115 in6_dev_put(idev); 1116 dst = ERR_PTR(-ENOMEM); 1117 goto out; 1118 } 1119 1120 if (neigh) 1121 neigh_hold(neigh); --- 165 unchanged lines hidden (view full) --- 1287 } 1288 } else { 1289 table = fib6_new_table(net, cfg->fc_table); 1290 } 1291 1292 if (!table) 1293 goto out; 1294 | 1154 if (unlikely(!rt)) { 1155 in6_dev_put(idev); 1156 dst = ERR_PTR(-ENOMEM); 1157 goto out; 1158 } 1159 1160 if (neigh) 1161 neigh_hold(neigh); --- 165 unchanged lines hidden (view full) --- 1327 } 1328 } else { 1329 table = fib6_new_table(net, cfg->fc_table); 1330 } 1331 1332 if (!table) 1333 goto out; 1334 |
1295 rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, NULL, DST_NOCOUNT); | 1335 rt = ip6_dst_alloc(net, NULL, DST_NOCOUNT, table); |
1296 1297 if (!rt) { 1298 err = -ENOMEM; 1299 goto out; 1300 } 1301 1302 rt->dst.obsolete = -1; 1303 --- 388 unchanged lines hidden (view full) --- 1692 return; 1693 } 1694 1695out: 1696 dst_release(&rt->dst); 1697} 1698 1699/* | 1336 1337 if (!rt) { 1338 err = -ENOMEM; 1339 goto out; 1340 } 1341 1342 rt->dst.obsolete = -1; 1343 --- 388 unchanged lines hidden (view full) --- 1732 return; 1733 } 1734 1735out: 1736 dst_release(&rt->dst); 1737} 1738 1739/* |
1700 * Handle ICMP "packet too big" messages 1701 * i.e. Path MTU discovery 1702 */ 1703 1704static void rt6_do_pmtu_disc(const struct in6_addr *daddr, const struct in6_addr *saddr, 1705 struct net *net, u32 pmtu, int ifindex) 1706{ 1707 struct rt6_info *rt, *nrt; 1708 int allfrag = 0; 1709again: 1710 rt = rt6_lookup(net, daddr, saddr, ifindex, 0); 1711 if (!rt) 1712 return; 1713 1714 if (rt6_check_expired(rt)) { 1715 ip6_del_rt(rt); 1716 goto again; 1717 } 1718 1719 if (pmtu >= dst_mtu(&rt->dst)) 1720 goto out; 1721 1722 if (pmtu < IPV6_MIN_MTU) { 1723 /* 1724 * According to RFC2460, PMTU is set to the IPv6 Minimum Link 1725 * MTU (1280) and a fragment header should always be included 1726 * after a node receiving Too Big message reporting PMTU is 1727 * less than the IPv6 Minimum Link MTU. 1728 */ 1729 pmtu = IPV6_MIN_MTU; 1730 allfrag = 1; 1731 } 1732 1733 /* New mtu received -> path was valid. 1734 They are sent only in response to data packets, 1735 so that this nexthop apparently is reachable. --ANK 1736 */ 1737 dst_confirm(&rt->dst); 1738 1739 /* Host route. If it is static, it would be better 1740 not to override it, but add new one, so that 1741 when cache entry will expire old pmtu 1742 would return automatically. 1743 */ 1744 if (rt->rt6i_flags & RTF_CACHE) { 1745 dst_metric_set(&rt->dst, RTAX_MTU, pmtu); 1746 if (allfrag) { 1747 u32 features = dst_metric(&rt->dst, RTAX_FEATURES); 1748 features |= RTAX_FEATURE_ALLFRAG; 1749 dst_metric_set(&rt->dst, RTAX_FEATURES, features); 1750 } 1751 rt6_update_expires(rt, net->ipv6.sysctl.ip6_rt_mtu_expires); 1752 rt->rt6i_flags |= RTF_MODIFIED; 1753 goto out; 1754 } 1755 1756 /* Network route. 1757 Two cases are possible: 1758 1. It is connected route. Action: COW 1759 2. It is gatewayed route or NONEXTHOP route. Action: clone it. 1760 */ 1761 if (!dst_get_neighbour_noref_raw(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP)) 1762 nrt = rt6_alloc_cow(rt, daddr, saddr); 1763 else 1764 nrt = rt6_alloc_clone(rt, daddr); 1765 1766 if (nrt) { 1767 dst_metric_set(&nrt->dst, RTAX_MTU, pmtu); 1768 if (allfrag) { 1769 u32 features = dst_metric(&nrt->dst, RTAX_FEATURES); 1770 features |= RTAX_FEATURE_ALLFRAG; 1771 dst_metric_set(&nrt->dst, RTAX_FEATURES, features); 1772 } 1773 1774 /* According to RFC 1981, detecting PMTU increase shouldn't be 1775 * happened within 5 mins, the recommended timer is 10 mins. 1776 * Here this route expiration time is set to ip6_rt_mtu_expires 1777 * which is 10 mins. After 10 mins the decreased pmtu is expired 1778 * and detecting PMTU increase will be automatically happened. 1779 */ 1780 rt6_update_expires(nrt, net->ipv6.sysctl.ip6_rt_mtu_expires); 1781 nrt->rt6i_flags |= RTF_DYNAMIC; 1782 ip6_ins_rt(nrt); 1783 } 1784out: 1785 dst_release(&rt->dst); 1786} 1787 1788void rt6_pmtu_discovery(const struct in6_addr *daddr, const struct in6_addr *saddr, 1789 struct net_device *dev, u32 pmtu) 1790{ 1791 struct net *net = dev_net(dev); 1792 1793 /* 1794 * RFC 1981 states that a node "MUST reduce the size of the packets it 1795 * is sending along the path" that caused the Packet Too Big message. 1796 * Since it's not possible in the general case to determine which 1797 * interface was used to send the original packet, we update the MTU 1798 * on the interface that will be used to send future packets. We also 1799 * update the MTU on the interface that received the Packet Too Big in 1800 * case the original packet was forced out that interface with 1801 * SO_BINDTODEVICE or similar. This is the next best thing to the 1802 * correct behaviour, which would be to update the MTU on all 1803 * interfaces. 1804 */ 1805 rt6_do_pmtu_disc(daddr, saddr, net, pmtu, 0); 1806 rt6_do_pmtu_disc(daddr, saddr, net, pmtu, dev->ifindex); 1807} 1808 1809/* | |
1810 * Misc support functions 1811 */ 1812 1813static struct rt6_info *ip6_rt_copy(struct rt6_info *ort, 1814 const struct in6_addr *dest) 1815{ 1816 struct net *net = dev_net(ort->dst.dev); | 1740 * Misc support functions 1741 */ 1742 1743static struct rt6_info *ip6_rt_copy(struct rt6_info *ort, 1744 const struct in6_addr *dest) 1745{ 1746 struct net *net = dev_net(ort->dst.dev); |
1817 struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, 1818 ort->dst.dev, 0); | 1747 struct rt6_info *rt = ip6_dst_alloc(net, ort->dst.dev, 0, 1748 ort->rt6i_table); |
1819 1820 if (rt) { 1821 rt->dst.input = ort->dst.input; 1822 rt->dst.output = ort->dst.output; 1823 rt->dst.flags |= DST_HOST; 1824 1825 rt->rt6i_dst.addr = *dest; 1826 rt->rt6i_dst.plen = 128; --- 267 unchanged lines hidden (view full) --- 2094 * Allocate a dst for local (unicast / anycast) address. 2095 */ 2096 2097struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, 2098 const struct in6_addr *addr, 2099 bool anycast) 2100{ 2101 struct net *net = dev_net(idev->dev); | 1749 1750 if (rt) { 1751 rt->dst.input = ort->dst.input; 1752 rt->dst.output = ort->dst.output; 1753 rt->dst.flags |= DST_HOST; 1754 1755 rt->rt6i_dst.addr = *dest; 1756 rt->rt6i_dst.plen = 128; --- 267 unchanged lines hidden (view full) --- 2024 * Allocate a dst for local (unicast / anycast) address. 2025 */ 2026 2027struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, 2028 const struct in6_addr *addr, 2029 bool anycast) 2030{ 2031 struct net *net = dev_net(idev->dev); |
2102 struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, 2103 net->loopback_dev, 0); | 2032 struct rt6_info *rt = ip6_dst_alloc(net, net->loopback_dev, 0, NULL); |
2104 int err; 2105 2106 if (!rt) { 2107 net_warn_ratelimited("Maximum number of routes reached, consider increasing route/max_size\n"); 2108 return ERR_PTR(-ENOMEM); 2109 } 2110 2111 in6_dev_hold(idev); --- 404 unchanged lines hidden (view full) --- 2516 goto nla_put_failure; 2517 if (!(rt->rt6i_flags & RTF_EXPIRES)) 2518 expires = 0; 2519 else if (rt->dst.expires - jiffies < INT_MAX) 2520 expires = rt->dst.expires - jiffies; 2521 else 2522 expires = INT_MAX; 2523 | 2033 int err; 2034 2035 if (!rt) { 2036 net_warn_ratelimited("Maximum number of routes reached, consider increasing route/max_size\n"); 2037 return ERR_PTR(-ENOMEM); 2038 } 2039 2040 in6_dev_hold(idev); --- 404 unchanged lines hidden (view full) --- 2445 goto nla_put_failure; 2446 if (!(rt->rt6i_flags & RTF_EXPIRES)) 2447 expires = 0; 2448 else if (rt->dst.expires - jiffies < INT_MAX) 2449 expires = rt->dst.expires - jiffies; 2450 else 2451 expires = INT_MAX; 2452 |
2524 peer = rt->rt6i_peer; | 2453 peer = NULL; 2454 if (rt6_has_peer(rt)) 2455 peer = rt6_peer_ptr(rt); |
2525 ts = tsage = 0; 2526 if (peer && peer->tcp_ts_stamp) { 2527 ts = peer->tcp_ts; 2528 tsage = get_seconds() - peer->tcp_ts_stamp; 2529 } 2530 2531 if (rtnl_put_cacheinfo(skb, &rt->dst, 0, ts, tsage, 2532 expires, rt->dst.error) < 0) --- 460 unchanged lines hidden (view full) --- 2993 dst_entries_destroy(&net->ipv6.ip6_dst_ops); 2994} 2995 2996static struct pernet_operations ip6_route_net_ops = { 2997 .init = ip6_route_net_init, 2998 .exit = ip6_route_net_exit, 2999}; 3000 | 2456 ts = tsage = 0; 2457 if (peer && peer->tcp_ts_stamp) { 2458 ts = peer->tcp_ts; 2459 tsage = get_seconds() - peer->tcp_ts_stamp; 2460 } 2461 2462 if (rtnl_put_cacheinfo(skb, &rt->dst, 0, ts, tsage, 2463 expires, rt->dst.error) < 0) --- 460 unchanged lines hidden (view full) --- 2924 dst_entries_destroy(&net->ipv6.ip6_dst_ops); 2925} 2926 2927static struct pernet_operations ip6_route_net_ops = { 2928 .init = ip6_route_net_init, 2929 .exit = ip6_route_net_exit, 2930}; 2931 |
2932static int __net_init ipv6_inetpeer_init(struct net *net) 2933{ 2934 struct inet_peer_base *bp = kmalloc(sizeof(*bp), GFP_KERNEL); 2935 2936 if (!bp) 2937 return -ENOMEM; 2938 inet_peer_base_init(bp); 2939 net->ipv6.peers = bp; 2940 return 0; 2941} 2942 2943static void __net_exit ipv6_inetpeer_exit(struct net *net) 2944{ 2945 struct inet_peer_base *bp = net->ipv6.peers; 2946 2947 net->ipv6.peers = NULL; 2948 inetpeer_invalidate_tree(bp); 2949 kfree(bp); 2950} 2951 2952static struct pernet_operations ipv6_inetpeer_ops = { 2953 .init = ipv6_inetpeer_init, 2954 .exit = ipv6_inetpeer_exit, 2955}; 2956 |
|
3001static struct notifier_block ip6_route_dev_notifier = { 3002 .notifier_call = ip6_route_dev_notify, 3003 .priority = 0, 3004}; 3005 3006int __init ip6_route_init(void) 3007{ 3008 int ret; --- 8 unchanged lines hidden (view full) --- 3017 ret = dst_entries_init(&ip6_dst_blackhole_ops); 3018 if (ret) 3019 goto out_kmem_cache; 3020 3021 ret = register_pernet_subsys(&ip6_route_net_ops); 3022 if (ret) 3023 goto out_dst_entries; 3024 | 2957static struct notifier_block ip6_route_dev_notifier = { 2958 .notifier_call = ip6_route_dev_notify, 2959 .priority = 0, 2960}; 2961 2962int __init ip6_route_init(void) 2963{ 2964 int ret; --- 8 unchanged lines hidden (view full) --- 2973 ret = dst_entries_init(&ip6_dst_blackhole_ops); 2974 if (ret) 2975 goto out_kmem_cache; 2976 2977 ret = register_pernet_subsys(&ip6_route_net_ops); 2978 if (ret) 2979 goto out_dst_entries; 2980 |
2981 ret = register_pernet_subsys(&ipv6_inetpeer_ops); 2982 if (ret) 2983 goto out_register_subsys; 2984 |
|
3025 ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops_template.kmem_cachep; 3026 3027 /* Registering of the loopback is done before this portion of code, 3028 * the loopback reference in rt6_info will not be taken, do it 3029 * manually for init_net */ 3030 init_net.ipv6.ip6_null_entry->dst.dev = init_net.loopback_dev; 3031 init_net.ipv6.ip6_null_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); 3032 #ifdef CONFIG_IPV6_MULTIPLE_TABLES 3033 init_net.ipv6.ip6_prohibit_entry->dst.dev = init_net.loopback_dev; 3034 init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); 3035 init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev; 3036 init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); 3037 #endif 3038 ret = fib6_init(); 3039 if (ret) | 2985 ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops_template.kmem_cachep; 2986 2987 /* Registering of the loopback is done before this portion of code, 2988 * the loopback reference in rt6_info will not be taken, do it 2989 * manually for init_net */ 2990 init_net.ipv6.ip6_null_entry->dst.dev = init_net.loopback_dev; 2991 init_net.ipv6.ip6_null_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); 2992 #ifdef CONFIG_IPV6_MULTIPLE_TABLES 2993 init_net.ipv6.ip6_prohibit_entry->dst.dev = init_net.loopback_dev; 2994 init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); 2995 init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev; 2996 init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); 2997 #endif 2998 ret = fib6_init(); 2999 if (ret) |
3040 goto out_register_subsys; | 3000 goto out_register_inetpeer; |
3041 3042 ret = xfrm6_init(); 3043 if (ret) 3044 goto out_fib6_init; 3045 3046 ret = fib6_rules_init(); 3047 if (ret) 3048 goto xfrm6_init; --- 12 unchanged lines hidden (view full) --- 3061 return ret; 3062 3063fib6_rules_init: 3064 fib6_rules_cleanup(); 3065xfrm6_init: 3066 xfrm6_fini(); 3067out_fib6_init: 3068 fib6_gc_cleanup(); | 3001 3002 ret = xfrm6_init(); 3003 if (ret) 3004 goto out_fib6_init; 3005 3006 ret = fib6_rules_init(); 3007 if (ret) 3008 goto xfrm6_init; --- 12 unchanged lines hidden (view full) --- 3021 return ret; 3022 3023fib6_rules_init: 3024 fib6_rules_cleanup(); 3025xfrm6_init: 3026 xfrm6_fini(); 3027out_fib6_init: 3028 fib6_gc_cleanup(); |
3029out_register_inetpeer: 3030 unregister_pernet_subsys(&ipv6_inetpeer_ops); |
|
3069out_register_subsys: 3070 unregister_pernet_subsys(&ip6_route_net_ops); 3071out_dst_entries: 3072 dst_entries_destroy(&ip6_dst_blackhole_ops); 3073out_kmem_cache: 3074 kmem_cache_destroy(ip6_dst_ops_template.kmem_cachep); 3075 goto out; 3076} 3077 3078void ip6_route_cleanup(void) 3079{ 3080 unregister_netdevice_notifier(&ip6_route_dev_notifier); 3081 fib6_rules_cleanup(); 3082 xfrm6_fini(); 3083 fib6_gc_cleanup(); | 3031out_register_subsys: 3032 unregister_pernet_subsys(&ip6_route_net_ops); 3033out_dst_entries: 3034 dst_entries_destroy(&ip6_dst_blackhole_ops); 3035out_kmem_cache: 3036 kmem_cache_destroy(ip6_dst_ops_template.kmem_cachep); 3037 goto out; 3038} 3039 3040void ip6_route_cleanup(void) 3041{ 3042 unregister_netdevice_notifier(&ip6_route_dev_notifier); 3043 fib6_rules_cleanup(); 3044 xfrm6_fini(); 3045 fib6_gc_cleanup(); |
3046 unregister_pernet_subsys(&ipv6_inetpeer_ops); |
|
3084 unregister_pernet_subsys(&ip6_route_net_ops); 3085 dst_entries_destroy(&ip6_dst_blackhole_ops); 3086 kmem_cache_destroy(ip6_dst_ops_template.kmem_cachep); 3087} | 3047 unregister_pernet_subsys(&ip6_route_net_ops); 3048 dst_entries_destroy(&ip6_dst_blackhole_ops); 3049 kmem_cache_destroy(ip6_dst_ops_template.kmem_cachep); 3050} |