route.c (9c63cd5a955ce8a3de1776a9e4b6b89c69b2a09e) | route.c (8104891b86b212de77063660c0c062b427526fa6) |
---|---|
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 --- 65 unchanged lines hidden (view full) --- 74static void ip6_dst_ifdown(struct dst_entry *, 75 struct net_device *dev, int how); 76static int ip6_dst_gc(struct dst_ops *ops); 77 78static int ip6_pkt_discard(struct sk_buff *skb); 79static int ip6_pkt_discard_out(struct sk_buff *skb); 80static void ip6_link_failure(struct sk_buff *skb); 81static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu); | 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 --- 65 unchanged lines hidden (view full) --- 74static void ip6_dst_ifdown(struct dst_entry *, 75 struct net_device *dev, int how); 76static int ip6_dst_gc(struct dst_ops *ops); 77 78static int ip6_pkt_discard(struct sk_buff *skb); 79static int ip6_pkt_discard_out(struct sk_buff *skb); 80static void ip6_link_failure(struct sk_buff *skb); 81static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu); |
82static void rt6_do_redirect(struct dst_entry *dst, struct sk_buff *skb); |
|
82 83#ifdef CONFIG_IPV6_ROUTE_INFO 84static struct rt6_info *rt6_add_route_info(struct net *net, 85 const struct in6_addr *prefix, int prefixlen, 86 const struct in6_addr *gwaddr, int ifindex, 87 unsigned int pref); 88static struct rt6_info *rt6_get_route_info(struct net *net, 89 const struct in6_addr *prefix, int prefixlen, --- 4 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 | 83 84#ifdef CONFIG_IPV6_ROUTE_INFO 85static struct rt6_info *rt6_add_route_info(struct net *net, 86 const struct in6_addr *prefix, int prefixlen, 87 const struct in6_addr *gwaddr, int ifindex, 88 unsigned int pref); 89static struct rt6_info *rt6_get_route_info(struct net *net, 90 const struct in6_addr *prefix, int prefixlen, --- 4 unchanged lines hidden (view full) --- 95{ 96 struct rt6_info *rt = (struct rt6_info *) dst; 97 struct inet_peer *peer; 98 u32 *p = NULL; 99 100 if (!(rt->dst.flags & DST_HOST)) 101 return NULL; 102 |
102 if (!rt->rt6i_peer) 103 rt6_bind_peer(rt, 1); 104 105 peer = rt->rt6i_peer; | 103 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 --- 4 unchanged lines hidden (view full) --- 118 p = __DST_METRICS_PTR(prev); 119 if (prev & DST_METRICS_READ_ONLY) 120 p = NULL; 121 } 122 } 123 return p; 124} 125 | 104 if (peer) { 105 u32 *old_p = __DST_METRICS_PTR(old); 106 unsigned long prev, new; 107 108 p = peer->metrics; 109 if (inet_metrics_new(peer)) 110 memcpy(p, old_p, sizeof(u32) * RTAX_MAX); 111 --- 4 unchanged lines hidden (view full) --- 116 p = __DST_METRICS_PTR(prev); 117 if (prev & DST_METRICS_READ_ONLY) 118 p = NULL; 119 } 120 } 121 return p; 122} 123 |
126static inline const void *choose_neigh_daddr(struct rt6_info *rt, const void *daddr) | 124static inline const void *choose_neigh_daddr(struct rt6_info *rt, 125 struct sk_buff *skb, 126 const void *daddr) |
127{ 128 struct in6_addr *p = &rt->rt6i_gateway; 129 130 if (!ipv6_addr_any(p)) 131 return (const void *) p; | 127{ 128 struct in6_addr *p = &rt->rt6i_gateway; 129 130 if (!ipv6_addr_any(p)) 131 return (const void *) p; |
132 else if (skb) 133 return &ipv6_hdr(skb)->daddr; |
|
132 return daddr; 133} 134 | 134 return daddr; 135} 136 |
135static struct neighbour *ip6_neigh_lookup(const struct dst_entry *dst, const void *daddr) | 137static struct neighbour *ip6_neigh_lookup(const struct dst_entry *dst, 138 struct sk_buff *skb, 139 const void *daddr) |
136{ 137 struct rt6_info *rt = (struct rt6_info *) dst; 138 struct neighbour *n; 139 | 140{ 141 struct rt6_info *rt = (struct rt6_info *) dst; 142 struct neighbour *n; 143 |
140 daddr = choose_neigh_daddr(rt, daddr); | 144 daddr = choose_neigh_daddr(rt, skb, daddr); |
141 n = __ipv6_neigh_lookup(&nd_tbl, dst->dev, daddr); 142 if (n) 143 return n; 144 return neigh_create(&nd_tbl, daddr, dst->dev); 145} 146 147static int rt6_bind_neighbour(struct rt6_info *rt, struct net_device *dev) 148{ 149 struct neighbour *n = __ipv6_neigh_lookup(&nd_tbl, dev, &rt->rt6i_gateway); 150 if (!n) { 151 n = neigh_create(&nd_tbl, &rt->rt6i_gateway, dev); 152 if (IS_ERR(n)) 153 return PTR_ERR(n); 154 } | 145 n = __ipv6_neigh_lookup(&nd_tbl, dst->dev, daddr); 146 if (n) 147 return n; 148 return neigh_create(&nd_tbl, daddr, dst->dev); 149} 150 151static int rt6_bind_neighbour(struct rt6_info *rt, struct net_device *dev) 152{ 153 struct neighbour *n = __ipv6_neigh_lookup(&nd_tbl, dev, &rt->rt6i_gateway); 154 if (!n) { 155 n = neigh_create(&nd_tbl, &rt->rt6i_gateway, dev); 156 if (IS_ERR(n)) 157 return PTR_ERR(n); 158 } |
155 dst_set_neighbour(&rt->dst, n); | 159 rt->n = n; |
156 157 return 0; 158} 159 160static struct dst_ops ip6_dst_ops_template = { 161 .family = AF_INET6, 162 .protocol = cpu_to_be16(ETH_P_IPV6), 163 .gc = ip6_dst_gc, 164 .gc_thresh = 1024, 165 .check = ip6_dst_check, 166 .default_advmss = ip6_default_advmss, 167 .mtu = ip6_mtu, 168 .cow_metrics = ipv6_cow_metrics, 169 .destroy = ip6_dst_destroy, 170 .ifdown = ip6_dst_ifdown, 171 .negative_advice = ip6_negative_advice, 172 .link_failure = ip6_link_failure, 173 .update_pmtu = ip6_rt_update_pmtu, | 160 161 return 0; 162} 163 164static struct dst_ops ip6_dst_ops_template = { 165 .family = AF_INET6, 166 .protocol = cpu_to_be16(ETH_P_IPV6), 167 .gc = ip6_dst_gc, 168 .gc_thresh = 1024, 169 .check = ip6_dst_check, 170 .default_advmss = ip6_default_advmss, 171 .mtu = ip6_mtu, 172 .cow_metrics = ipv6_cow_metrics, 173 .destroy = ip6_dst_destroy, 174 .ifdown = ip6_dst_ifdown, 175 .negative_advice = ip6_negative_advice, 176 .link_failure = ip6_link_failure, 177 .update_pmtu = ip6_rt_update_pmtu, |
178 .redirect = rt6_do_redirect, |
|
174 .local_out = __ip6_local_out, 175 .neigh_lookup = ip6_neigh_lookup, 176}; 177 178static unsigned int ip6_blackhole_mtu(const struct dst_entry *dst) 179{ 180 unsigned int mtu = dst_metric_raw(dst, RTAX_MTU); 181 182 return mtu ? : dst->dev->mtu; 183} 184 185static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) 186{ 187} 188 | 179 .local_out = __ip6_local_out, 180 .neigh_lookup = ip6_neigh_lookup, 181}; 182 183static unsigned int ip6_blackhole_mtu(const struct dst_entry *dst) 184{ 185 unsigned int mtu = dst_metric_raw(dst, RTAX_MTU); 186 187 return mtu ? : dst->dev->mtu; 188} 189 190static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) 191{ 192} 193 |
194static void ip6_rt_blackhole_redirect(struct dst_entry *dst, struct sk_buff *skb) 195{ 196} 197 |
|
189static u32 *ip6_rt_blackhole_cow_metrics(struct dst_entry *dst, 190 unsigned long old) 191{ 192 return NULL; 193} 194 195static struct dst_ops ip6_dst_blackhole_ops = { 196 .family = AF_INET6, 197 .protocol = cpu_to_be16(ETH_P_IPV6), 198 .destroy = ip6_dst_destroy, 199 .check = ip6_dst_check, 200 .mtu = ip6_blackhole_mtu, 201 .default_advmss = ip6_default_advmss, 202 .update_pmtu = ip6_rt_blackhole_update_pmtu, | 198static u32 *ip6_rt_blackhole_cow_metrics(struct dst_entry *dst, 199 unsigned long old) 200{ 201 return NULL; 202} 203 204static struct dst_ops ip6_dst_blackhole_ops = { 205 .family = AF_INET6, 206 .protocol = cpu_to_be16(ETH_P_IPV6), 207 .destroy = ip6_dst_destroy, 208 .check = ip6_dst_check, 209 .mtu = ip6_blackhole_mtu, 210 .default_advmss = ip6_default_advmss, 211 .update_pmtu = ip6_rt_blackhole_update_pmtu, |
212 .redirect = ip6_rt_blackhole_redirect, |
|
203 .cow_metrics = ip6_rt_blackhole_cow_metrics, 204 .neigh_lookup = ip6_neigh_lookup, 205}; 206 207static const u32 ip6_template_metrics[RTAX_MAX] = { 208 [RTAX_HOPLIMIT - 1] = 255, 209}; 210 --- 45 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 */ | 213 .cow_metrics = ip6_rt_blackhole_cow_metrics, 214 .neigh_lookup = ip6_neigh_lookup, 215}; 216 217static const u32 ip6_template_metrics[RTAX_MAX] = { 218 [RTAX_HOPLIMIT - 1] = 255, 219}; 220 --- 45 unchanged lines hidden (view full) --- 266 .rt6i_protocol = RTPROT_KERNEL, 267 .rt6i_metric = ~(u32) 0, 268 .rt6i_ref = ATOMIC_INIT(1), 269}; 270 271#endif 272 273/* allocate dst with ip6_dst_ops */ |
264static inline struct rt6_info *ip6_dst_alloc(struct dst_ops *ops, | 274static inline struct rt6_info *ip6_dst_alloc(struct net *net, |
265 struct net_device *dev, | 275 struct net_device *dev, |
266 int flags) | 276 int flags, 277 struct fib6_table *table) |
267{ | 278{ |
268 struct rt6_info *rt = dst_alloc(ops, dev, 0, 0, flags); | 279 struct rt6_info *rt = dst_alloc(&net->ipv6.ip6_dst_ops, dev, 280 0, 0, flags); |
269 | 281 |
270 if (rt) 271 memset(&rt->rt6i_table, 0, 272 sizeof(*rt) - sizeof(struct dst_entry)); | 282 if (rt) { 283 struct dst_entry *dst = &rt->dst; |
273 | 284 |
285 memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst)); 286 rt6_init_peer(rt, table ? &table->tb6_peers : net->ipv6.peers); 287 } |
|
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; | 288 return rt; 289} 290 291static void ip6_dst_destroy(struct dst_entry *dst) 292{ 293 struct rt6_info *rt = (struct rt6_info *)dst; 294 struct inet6_dev *idev = rt->rt6i_idev; |
281 struct inet_peer *peer = rt->rt6i_peer; | |
282 | 295 |
296 if (rt->n) 297 neigh_release(rt->n); 298 |
|
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 | 299 if (!(rt->dst.flags & DST_HOST)) 300 dst_destroy_metrics_generic(dst); 301 302 if (idev) { 303 rt->rt6i_idev = NULL; 304 in6_dev_put(idev); 305 } 306 307 if (!(rt->rt6i_flags & RTF_EXPIRES) && dst->from) 308 dst_release(dst->from); 309 |
294 if (peer) { 295 rt->rt6i_peer = NULL; | 310 if (rt6_has_peer(rt)) { 311 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{ | 312 inet_putpeer(peer); 313 } 314} 315 316static atomic_t __rt6_peer_genid = ATOMIC_INIT(0); 317 318static u32 rt6_peer_genid(void) 319{ 320 return atomic_read(&__rt6_peer_genid); 321} 322 323void rt6_bind_peer(struct rt6_info *rt, int create) 324{ |
325 struct inet_peer_base *base; |
|
309 struct inet_peer *peer; 310 | 326 struct inet_peer *peer; 327 |
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(); | 328 base = inetpeer_base_ptr(rt->_rt6i_peer); 329 if (!base) 330 return; 331 332 peer = inet_getpeer_v6(base, &rt->rt6i_dst.addr, create); 333 if (peer) { 334 if (!rt6_set_peer(rt, peer)) 335 inet_putpeer(peer); 336 else 337 rt->rt6i_peer_genid = rt6_peer_genid(); 338 } |
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 = 324 dev_net(dev)->loopback_dev; 325 | 339} 340 341static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev, 342 int how) 343{ 344 struct rt6_info *rt = (struct rt6_info *)dst; 345 struct inet6_dev *idev = rt->rt6i_idev; 346 struct net_device *loopback_dev = 347 dev_net(dev)->loopback_dev; 348 |
326 if (dev != loopback_dev && idev && idev->dev == dev) { 327 struct inet6_dev *loopback_idev = 328 in6_dev_get(loopback_dev); 329 if (loopback_idev) { 330 rt->rt6i_idev = loopback_idev; 331 in6_dev_put(idev); | 349 if (dev != loopback_dev) { 350 if (idev && idev->dev == dev) { 351 struct inet6_dev *loopback_idev = 352 in6_dev_get(loopback_dev); 353 if (loopback_idev) { 354 rt->rt6i_idev = loopback_idev; 355 in6_dev_put(idev); 356 } |
332 } | 357 } |
358 if (rt->n && rt->n->dev == dev) { 359 rt->n->dev = loopback_dev; 360 dev_hold(loopback_dev); 361 dev_put(dev); 362 } |
|
333 } 334} 335 336static bool rt6_check_expired(const struct rt6_info *rt) 337{ 338 struct rt6_info *ort = NULL; 339 340 if (rt->rt6i_flags & RTF_EXPIRES) { --- 72 unchanged lines hidden (view full) --- 413 * Okay, this does not seem to be appropriate 414 * for now, however, we need to check if it 415 * is really so; aka Router Reachability Probing. 416 * 417 * Router Reachability Probe MUST be rate-limited 418 * to no more than one per minute. 419 */ 420 rcu_read_lock(); | 363 } 364} 365 366static bool rt6_check_expired(const struct rt6_info *rt) 367{ 368 struct rt6_info *ort = NULL; 369 370 if (rt->rt6i_flags & RTF_EXPIRES) { --- 72 unchanged lines hidden (view full) --- 443 * Okay, this does not seem to be appropriate 444 * for now, however, we need to check if it 445 * is really so; aka Router Reachability Probing. 446 * 447 * Router Reachability Probe MUST be rate-limited 448 * to no more than one per minute. 449 */ 450 rcu_read_lock(); |
421 neigh = rt ? dst_get_neighbour_noref(&rt->dst) : NULL; | 451 neigh = rt ? rt->n : NULL; |
422 if (!neigh || (neigh->nud_state & NUD_VALID)) 423 goto out; 424 read_lock_bh(&neigh->lock); 425 if (!(neigh->nud_state & NUD_VALID) && 426 time_after(jiffies, neigh->updated + rt->rt6i_idev->cnf.rtr_probe_interval)) { 427 struct in6_addr mcaddr; 428 struct in6_addr *target; 429 --- 30 unchanged lines hidden (view full) --- 460} 461 462static inline int rt6_check_neigh(struct rt6_info *rt) 463{ 464 struct neighbour *neigh; 465 int m; 466 467 rcu_read_lock(); | 452 if (!neigh || (neigh->nud_state & NUD_VALID)) 453 goto out; 454 read_lock_bh(&neigh->lock); 455 if (!(neigh->nud_state & NUD_VALID) && 456 time_after(jiffies, neigh->updated + rt->rt6i_idev->cnf.rtr_probe_interval)) { 457 struct in6_addr mcaddr; 458 struct in6_addr *target; 459 --- 30 unchanged lines hidden (view full) --- 490} 491 492static inline int rt6_check_neigh(struct rt6_info *rt) 493{ 494 struct neighbour *neigh; 495 int m; 496 497 rcu_read_lock(); |
468 neigh = dst_get_neighbour_noref(&rt->dst); | 498 neigh = rt->n; |
469 if (rt->rt6i_flags & RTF_NONEXTHOP || 470 !(rt->rt6i_flags & RTF_GATEWAY)) 471 m = 1; 472 else if (neigh) { 473 read_lock_bh(&neigh->lock); 474 if (neigh->nud_state & NUD_VALID) 475 m = 2; 476#ifdef CONFIG_IPV6_ROUTER_PREF --- 330 unchanged lines hidden (view full) --- 807 808static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, 809 const struct in6_addr *daddr) 810{ 811 struct rt6_info *rt = ip6_rt_copy(ort, daddr); 812 813 if (rt) { 814 rt->rt6i_flags |= RTF_CACHE; | 499 if (rt->rt6i_flags & RTF_NONEXTHOP || 500 !(rt->rt6i_flags & RTF_GATEWAY)) 501 m = 1; 502 else if (neigh) { 503 read_lock_bh(&neigh->lock); 504 if (neigh->nud_state & NUD_VALID) 505 m = 2; 506#ifdef CONFIG_IPV6_ROUTER_PREF --- 330 unchanged lines hidden (view full) --- 837 838static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, 839 const struct in6_addr *daddr) 840{ 841 struct rt6_info *rt = ip6_rt_copy(ort, daddr); 842 843 if (rt) { 844 rt->rt6i_flags |= RTF_CACHE; |
815 dst_set_neighbour(&rt->dst, neigh_clone(dst_get_neighbour_noref_raw(&ort->dst))); | 845 rt->n = neigh_clone(ort->n); |
816 } 817 return rt; 818} 819 820static struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, int oif, 821 struct flowi6 *fl6, int flags) 822{ 823 struct fib6_node *fn; --- 17 unchanged lines hidden (view full) --- 841 BACKTRACK(net, &fl6->saddr); 842 if (rt == net->ipv6.ip6_null_entry || 843 rt->rt6i_flags & RTF_CACHE) 844 goto out; 845 846 dst_hold(&rt->dst); 847 read_unlock_bh(&table->tb6_lock); 848 | 846 } 847 return rt; 848} 849 850static struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, int oif, 851 struct flowi6 *fl6, int flags) 852{ 853 struct fib6_node *fn; --- 17 unchanged lines hidden (view full) --- 871 BACKTRACK(net, &fl6->saddr); 872 if (rt == net->ipv6.ip6_null_entry || 873 rt->rt6i_flags & RTF_CACHE) 874 goto out; 875 876 dst_hold(&rt->dst); 877 read_unlock_bh(&table->tb6_lock); 878 |
849 if (!dst_get_neighbour_noref_raw(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP)) | 879 if (!rt->n && !(rt->rt6i_flags & RTF_NONEXTHOP)) |
850 nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr); 851 else if (!(rt->dst.flags & DST_HOST)) 852 nrt = rt6_alloc_clone(rt, &fl6->daddr); 853 else 854 goto out2; 855 856 dst_release(&rt->dst); 857 rt = nrt ? : net->ipv6.ip6_null_entry; --- 68 unchanged lines hidden (view full) --- 926 return ip6_pol_route(net, table, fl6->flowi6_oif, fl6, flags); 927} 928 929struct dst_entry * ip6_route_output(struct net *net, const struct sock *sk, 930 struct flowi6 *fl6) 931{ 932 int flags = 0; 933 | 880 nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr); 881 else if (!(rt->dst.flags & DST_HOST)) 882 nrt = rt6_alloc_clone(rt, &fl6->daddr); 883 else 884 goto out2; 885 886 dst_release(&rt->dst); 887 rt = nrt ? : net->ipv6.ip6_null_entry; --- 68 unchanged lines hidden (view full) --- 956 return ip6_pol_route(net, table, fl6->flowi6_oif, fl6, flags); 957} 958 959struct dst_entry * ip6_route_output(struct net *net, const struct sock *sk, 960 struct flowi6 *fl6) 961{ 962 int flags = 0; 963 |
964 fl6->flowi6_iif = net->loopback_dev->ifindex; 965 |
|
934 if ((sk && sk->sk_bound_dev_if) || rt6_need_strict(&fl6->daddr)) 935 flags |= RT6_LOOKUP_F_IFACE; 936 937 if (!ipv6_addr_any(&fl6->saddr)) 938 flags |= RT6_LOOKUP_F_HAS_SADDR; 939 else if (sk) 940 flags |= rt6_srcprefs2flags(inet6_sk(sk)->srcprefs); 941 --- 4 unchanged lines hidden (view full) --- 946 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) { | 966 if ((sk && sk->sk_bound_dev_if) || rt6_need_strict(&fl6->daddr)) 967 flags |= RT6_LOOKUP_F_IFACE; 968 969 if (!ipv6_addr_any(&fl6->saddr)) 970 flags |= RT6_LOOKUP_F_HAS_SADDR; 971 else if (sk) 972 flags |= rt6_srcprefs2flags(inet6_sk(sk)->srcprefs); 973 --- 4 unchanged lines hidden (view full) --- 978 979struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_orig) 980{ 981 struct rt6_info *rt, *ort = (struct rt6_info *) dst_orig; 982 struct dst_entry *new = NULL; 983 984 rt = dst_alloc(&ip6_dst_blackhole_ops, ort->dst.dev, 1, 0, 0); 985 if (rt) { |
954 memset(&rt->rt6i_table, 0, sizeof(*rt) - sizeof(struct dst_entry)); 955 | |
956 new = &rt->dst; 957 | 986 new = &rt->dst; 987 |
988 memset(new + 1, 0, sizeof(*rt) - sizeof(*new)); 989 rt6_init_peer(rt, net->ipv6.peers); 990 |
|
958 new->__use = 1; 959 new->input = dst_discard; 960 new->output = dst_discard; 961 962 if (dst_metrics_read_only(&ort->dst)) 963 new->_metrics = ort->dst._metrics; 964 else 965 dst_copy_metrics(new, &ort->dst); --- 25 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()) { | 991 new->__use = 1; 992 new->input = dst_discard; 993 new->output = dst_discard; 994 995 if (dst_metrics_read_only(&ort->dst)) 996 new->_metrics = ort->dst._metrics; 997 else 998 dst_copy_metrics(new, &ort->dst); --- 25 unchanged lines hidden (view full) --- 1024static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie) 1025{ 1026 struct rt6_info *rt; 1027 1028 rt = (struct rt6_info *) dst; 1029 1030 if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) { 1031 if (rt->rt6i_peer_genid != rt6_peer_genid()) { |
999 if (!rt->rt6i_peer) | 1032 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 | 1033 rt6_bind_peer(rt, 0); 1034 rt->rt6i_peer_genid = rt6_peer_genid(); 1035 } 1036 return dst; 1037 } 1038 return NULL; 1039} 1040 --- 29 unchanged lines hidden (view full) --- 1070 rt->rt6i_node->fn_sernum = -1; 1071 } 1072} 1073 1074static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu) 1075{ 1076 struct rt6_info *rt6 = (struct rt6_info*)dst; 1077 |
1078 dst_confirm(dst); |
|
1045 if (mtu < dst_mtu(dst) && rt6->rt6i_dst.plen == 128) { | 1079 if (mtu < dst_mtu(dst) && rt6->rt6i_dst.plen == 128) { |
1080 struct net *net = dev_net(dst->dev); 1081 |
|
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); | 1082 rt6->rt6i_flags |= RTF_MODIFIED; 1083 if (mtu < IPV6_MIN_MTU) { 1084 u32 features = dst_metric(dst, RTAX_FEATURES); 1085 mtu = IPV6_MIN_MTU; 1086 features |= RTAX_FEATURE_ALLFRAG; 1087 dst_metric_set(dst, RTAX_FEATURES, features); 1088 } 1089 dst_metric_set(dst, RTAX_MTU, mtu); |
1090 rt6_update_expires(rt6, net->ipv6.sysctl.ip6_rt_mtu_expires); |
|
1054 } 1055} 1056 | 1091 } 1092} 1093 |
1094void ip6_update_pmtu(struct sk_buff *skb, struct net *net, __be32 mtu, 1095 int oif, u32 mark) 1096{ 1097 const struct ipv6hdr *iph = (struct ipv6hdr *) skb->data; 1098 struct dst_entry *dst; 1099 struct flowi6 fl6; 1100 1101 memset(&fl6, 0, sizeof(fl6)); 1102 fl6.flowi6_oif = oif; 1103 fl6.flowi6_mark = mark; 1104 fl6.flowi6_flags = 0; 1105 fl6.daddr = iph->daddr; 1106 fl6.saddr = iph->saddr; 1107 fl6.flowlabel = (*(__be32 *) iph) & IPV6_FLOWINFO_MASK; 1108 1109 dst = ip6_route_output(net, NULL, &fl6); 1110 if (!dst->error) 1111 ip6_rt_update_pmtu(dst, ntohl(mtu)); 1112 dst_release(dst); 1113} 1114EXPORT_SYMBOL_GPL(ip6_update_pmtu); 1115 1116void ip6_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, __be32 mtu) 1117{ 1118 ip6_update_pmtu(skb, sock_net(sk), mtu, 1119 sk->sk_bound_dev_if, sk->sk_mark); 1120} 1121EXPORT_SYMBOL_GPL(ip6_sk_update_pmtu); 1122 1123void ip6_redirect(struct sk_buff *skb, struct net *net, int oif, u32 mark) 1124{ 1125 const struct ipv6hdr *iph = (struct ipv6hdr *) skb->data; 1126 struct dst_entry *dst; 1127 struct flowi6 fl6; 1128 1129 memset(&fl6, 0, sizeof(fl6)); 1130 fl6.flowi6_oif = oif; 1131 fl6.flowi6_mark = mark; 1132 fl6.flowi6_flags = 0; 1133 fl6.daddr = iph->daddr; 1134 fl6.saddr = iph->saddr; 1135 fl6.flowlabel = (*(__be32 *) iph) & IPV6_FLOWINFO_MASK; 1136 1137 dst = ip6_route_output(net, NULL, &fl6); 1138 if (!dst->error) 1139 rt6_do_redirect(dst, skb); 1140 dst_release(dst); 1141} 1142EXPORT_SYMBOL_GPL(ip6_redirect); 1143 1144void ip6_sk_redirect(struct sk_buff *skb, struct sock *sk) 1145{ 1146 ip6_redirect(skb, sock_net(sk), sk->sk_bound_dev_if, sk->sk_mark); 1147} 1148EXPORT_SYMBOL_GPL(ip6_sk_redirect); 1149 |
|
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 | 1150static unsigned int ip6_default_advmss(const struct dst_entry *dst) 1151{ 1152 struct net_device *dev = dst->dev; 1153 unsigned int mtu = dst_mtu(dst); 1154 struct net *net = dev_net(dev); 1155 1156 mtu -= sizeof(struct ipv6hdr) + sizeof(struct tcphdr); 1157 --- 40 unchanged lines hidden (view full) --- 1198 struct dst_entry *dst; 1199 struct rt6_info *rt; 1200 struct inet6_dev *idev = in6_dev_get(dev); 1201 struct net *net = dev_net(dev); 1202 1203 if (unlikely(!idev)) 1204 return ERR_PTR(-ENODEV); 1205 |
1113 rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, dev, 0); | 1206 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); 1122 else { | 1207 if (unlikely(!rt)) { 1208 in6_dev_put(idev); 1209 dst = ERR_PTR(-ENOMEM); 1210 goto out; 1211 } 1212 1213 if (neigh) 1214 neigh_hold(neigh); 1215 else { |
1123 neigh = ip6_neigh_lookup(&rt->dst, &fl6->daddr); | 1216 neigh = ip6_neigh_lookup(&rt->dst, NULL, &fl6->daddr); |
1124 if (IS_ERR(neigh)) { 1125 in6_dev_put(idev); 1126 dst_free(&rt->dst); 1127 return ERR_CAST(neigh); 1128 } 1129 } 1130 1131 rt->dst.flags |= DST_HOST; 1132 rt->dst.output = ip6_output; | 1217 if (IS_ERR(neigh)) { 1218 in6_dev_put(idev); 1219 dst_free(&rt->dst); 1220 return ERR_CAST(neigh); 1221 } 1222 } 1223 1224 rt->dst.flags |= DST_HOST; 1225 rt->dst.output = ip6_output; |
1133 dst_set_neighbour(&rt->dst, neigh); | 1226 rt->n = neigh; |
1134 atomic_set(&rt->dst.__refcnt, 1); 1135 rt->rt6i_dst.addr = fl6->daddr; 1136 rt->rt6i_dst.plen = 128; 1137 rt->rt6i_idev = idev; 1138 dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255); 1139 1140 spin_lock_bh(&icmp6_dst_lock); 1141 rt->dst.next = icmp6_dst_gc_list; --- 145 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 | 1227 atomic_set(&rt->dst.__refcnt, 1); 1228 rt->rt6i_dst.addr = fl6->daddr; 1229 rt->rt6i_dst.plen = 128; 1230 rt->rt6i_idev = idev; 1231 dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255); 1232 1233 spin_lock_bh(&icmp6_dst_lock); 1234 rt->dst.next = icmp6_dst_gc_list; --- 145 unchanged lines hidden (view full) --- 1380 } 1381 } else { 1382 table = fib6_new_table(net, cfg->fc_table); 1383 } 1384 1385 if (!table) 1386 goto out; 1387 |
1295 rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, NULL, DST_NOCOUNT); | 1388 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 --- 237 unchanged lines hidden (view full) --- 1541 return __ip6_del_rt(rt, &cfg->fc_nlinfo); 1542 } 1543 } 1544 read_unlock_bh(&table->tb6_lock); 1545 1546 return err; 1547} 1548 | 1389 1390 if (!rt) { 1391 err = -ENOMEM; 1392 goto out; 1393 } 1394 1395 rt->dst.obsolete = -1; 1396 --- 237 unchanged lines hidden (view full) --- 1634 return __ip6_del_rt(rt, &cfg->fc_nlinfo); 1635 } 1636 } 1637 read_unlock_bh(&table->tb6_lock); 1638 1639 return err; 1640} 1641 |
1549/* 1550 * Handle redirects 1551 */ 1552struct ip6rd_flowi { 1553 struct flowi6 fl6; 1554 struct in6_addr gateway; 1555}; 1556 1557static struct rt6_info *__ip6_route_redirect(struct net *net, 1558 struct fib6_table *table, 1559 struct flowi6 *fl6, 1560 int flags) | 1642static void rt6_do_redirect(struct dst_entry *dst, struct sk_buff *skb) |
1561{ | 1643{ |
1562 struct ip6rd_flowi *rdfl = (struct ip6rd_flowi *)fl6; 1563 struct rt6_info *rt; 1564 struct fib6_node *fn; | 1644 struct net *net = dev_net(skb->dev); 1645 struct netevent_redirect netevent; 1646 struct rt6_info *rt, *nrt = NULL; 1647 const struct in6_addr *target; 1648 struct ndisc_options ndopts; 1649 const struct in6_addr *dest; 1650 struct neighbour *old_neigh; 1651 struct inet6_dev *in6_dev; 1652 struct neighbour *neigh; 1653 struct icmp6hdr *icmph; 1654 int optlen, on_link; 1655 u8 *lladdr; |
1565 | 1656 |
1566 /* 1567 * Get the "current" route for this destination and 1568 * check if the redirect has come from approriate router. 1569 * 1570 * RFC 2461 specifies that redirects should only be 1571 * accepted if they come from the nexthop to the target. 1572 * Due to the way the routes are chosen, this notion 1573 * is a bit fuzzy and one might need to check all possible 1574 * routes. 1575 */ | 1657 optlen = skb->tail - skb->transport_header; 1658 optlen -= sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr); |
1576 | 1659 |
1577 read_lock_bh(&table->tb6_lock); 1578 fn = fib6_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr); 1579restart: 1580 for (rt = fn->leaf; rt; rt = rt->dst.rt6_next) { 1581 /* 1582 * Current route is on-link; redirect is always invalid. 1583 * 1584 * Seems, previous statement is not true. It could 1585 * be node, which looks for us as on-link (f.e. proxy ndisc) 1586 * But then router serving it might decide, that we should 1587 * know truth 8)8) --ANK (980726). 1588 */ 1589 if (rt6_check_expired(rt)) 1590 continue; 1591 if (!(rt->rt6i_flags & RTF_GATEWAY)) 1592 continue; 1593 if (fl6->flowi6_oif != rt->dst.dev->ifindex) 1594 continue; 1595 if (!ipv6_addr_equal(&rdfl->gateway, &rt->rt6i_gateway)) 1596 continue; 1597 break; | 1660 if (optlen < 0) { 1661 net_dbg_ratelimited("rt6_do_redirect: packet too short\n"); 1662 return; |
1598 } 1599 | 1663 } 1664 |
1600 if (!rt) 1601 rt = net->ipv6.ip6_null_entry; 1602 BACKTRACK(net, &fl6->saddr); 1603out: 1604 dst_hold(&rt->dst); | 1665 icmph = icmp6_hdr(skb); 1666 target = (const struct in6_addr *) (icmph + 1); 1667 dest = target + 1; |
1605 | 1668 |
1606 read_unlock_bh(&table->tb6_lock); | 1669 if (ipv6_addr_is_multicast(dest)) { 1670 net_dbg_ratelimited("rt6_do_redirect: destination address is multicast\n"); 1671 return; 1672 } |
1607 | 1673 |
1608 return rt; 1609}; | 1674 on_link = 0; 1675 if (ipv6_addr_equal(dest, target)) { 1676 on_link = 1; 1677 } else if (ipv6_addr_type(target) != 1678 (IPV6_ADDR_UNICAST|IPV6_ADDR_LINKLOCAL)) { 1679 net_dbg_ratelimited("rt6_do_redirect: target address is not link-local unicast\n"); 1680 return; 1681 } |
1610 | 1682 |
1611static struct rt6_info *ip6_route_redirect(const struct in6_addr *dest, 1612 const struct in6_addr *src, 1613 const struct in6_addr *gateway, 1614 struct net_device *dev) 1615{ 1616 int flags = RT6_LOOKUP_F_HAS_SADDR; 1617 struct net *net = dev_net(dev); 1618 struct ip6rd_flowi rdfl = { 1619 .fl6 = { 1620 .flowi6_oif = dev->ifindex, 1621 .daddr = *dest, 1622 .saddr = *src, 1623 }, 1624 }; | 1683 in6_dev = __in6_dev_get(skb->dev); 1684 if (!in6_dev) 1685 return; 1686 if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_redirects) 1687 return; |
1625 | 1688 |
1626 rdfl.gateway = *gateway; | 1689 /* RFC2461 8.1: 1690 * The IP source address of the Redirect MUST be the same as the current 1691 * first-hop router for the specified ICMP Destination Address. 1692 */ |
1627 | 1693 |
1628 if (rt6_need_strict(dest)) 1629 flags |= RT6_LOOKUP_F_IFACE; | 1694 if (!ndisc_parse_options((u8*)(dest + 1), optlen, &ndopts)) { 1695 net_dbg_ratelimited("rt6_redirect: invalid ND options\n"); 1696 return; 1697 } |
1630 | 1698 |
1631 return (struct rt6_info *)fib6_rule_lookup(net, &rdfl.fl6, 1632 flags, __ip6_route_redirect); 1633} | 1699 lladdr = NULL; 1700 if (ndopts.nd_opts_tgt_lladdr) { 1701 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_tgt_lladdr, 1702 skb->dev); 1703 if (!lladdr) { 1704 net_dbg_ratelimited("rt6_redirect: invalid link-layer address length\n"); 1705 return; 1706 } 1707 } |
1634 | 1708 |
1635void rt6_redirect(const struct in6_addr *dest, const struct in6_addr *src, 1636 const struct in6_addr *saddr, 1637 struct neighbour *neigh, u8 *lladdr, int on_link) 1638{ 1639 struct rt6_info *rt, *nrt = NULL; 1640 struct netevent_redirect netevent; 1641 struct net *net = dev_net(neigh->dev); 1642 1643 rt = ip6_route_redirect(dest, src, saddr, neigh->dev); 1644 | 1709 rt = (struct rt6_info *) dst; |
1645 if (rt == net->ipv6.ip6_null_entry) { 1646 net_dbg_ratelimited("rt6_redirect: source isn't a valid nexthop for redirect target\n"); | 1710 if (rt == net->ipv6.ip6_null_entry) { 1711 net_dbg_ratelimited("rt6_redirect: source isn't a valid nexthop for redirect target\n"); |
1647 goto out; | 1712 return; |
1648 } 1649 | 1713 } 1714 |
1715 /* Redirect received -> path was valid. 1716 * Look, redirects are sent only in response to data packets, 1717 * so that this nexthop apparently is reachable. --ANK 1718 */ 1719 dst_confirm(&rt->dst); 1720 1721 neigh = __neigh_lookup(&nd_tbl, target, skb->dev, 1); 1722 if (!neigh) 1723 return; 1724 1725 /* Duplicate redirect: silently ignore. */ 1726 old_neigh = rt->n; 1727 if (neigh == old_neigh) 1728 goto out; 1729 |
|
1650 /* 1651 * We have finally decided to accept it. 1652 */ 1653 1654 neigh_update(neigh, lladdr, NUD_STALE, 1655 NEIGH_UPDATE_F_WEAK_OVERRIDE| 1656 NEIGH_UPDATE_F_OVERRIDE| 1657 (on_link ? 0 : (NEIGH_UPDATE_F_OVERRIDE_ISROUTER| 1658 NEIGH_UPDATE_F_ISROUTER)) 1659 ); 1660 | 1730 /* 1731 * We have finally decided to accept it. 1732 */ 1733 1734 neigh_update(neigh, lladdr, NUD_STALE, 1735 NEIGH_UPDATE_F_WEAK_OVERRIDE| 1736 NEIGH_UPDATE_F_OVERRIDE| 1737 (on_link ? 0 : (NEIGH_UPDATE_F_OVERRIDE_ISROUTER| 1738 NEIGH_UPDATE_F_ISROUTER)) 1739 ); 1740 |
1661 /* 1662 * Redirect received -> path was valid. 1663 * Look, redirects are sent only in response to data packets, 1664 * so that this nexthop apparently is reachable. --ANK 1665 */ 1666 dst_confirm(&rt->dst); 1667 1668 /* Duplicate redirect: silently ignore. */ 1669 if (neigh == dst_get_neighbour_noref_raw(&rt->dst)) 1670 goto out; 1671 | |
1672 nrt = ip6_rt_copy(rt, dest); 1673 if (!nrt) 1674 goto out; 1675 1676 nrt->rt6i_flags = RTF_GATEWAY|RTF_UP|RTF_DYNAMIC|RTF_CACHE; 1677 if (on_link) 1678 nrt->rt6i_flags &= ~RTF_GATEWAY; 1679 1680 nrt->rt6i_gateway = *(struct in6_addr *)neigh->primary_key; | 1741 nrt = ip6_rt_copy(rt, dest); 1742 if (!nrt) 1743 goto out; 1744 1745 nrt->rt6i_flags = RTF_GATEWAY|RTF_UP|RTF_DYNAMIC|RTF_CACHE; 1746 if (on_link) 1747 nrt->rt6i_flags &= ~RTF_GATEWAY; 1748 1749 nrt->rt6i_gateway = *(struct in6_addr *)neigh->primary_key; |
1681 dst_set_neighbour(&nrt->dst, neigh_clone(neigh)); | 1750 nrt->n = neigh_clone(neigh); |
1682 1683 if (ip6_ins_rt(nrt)) 1684 goto out; 1685 1686 netevent.old = &rt->dst; | 1751 1752 if (ip6_ins_rt(nrt)) 1753 goto out; 1754 1755 netevent.old = &rt->dst; |
1756 netevent.old_neigh = old_neigh; |
|
1687 netevent.new = &nrt->dst; | 1757 netevent.new = &nrt->dst; |
1758 netevent.new_neigh = neigh; 1759 netevent.daddr = dest; |
|
1688 call_netevent_notifiers(NETEVENT_REDIRECT, &netevent); 1689 1690 if (rt->rt6i_flags & RTF_CACHE) { | 1760 call_netevent_notifiers(NETEVENT_REDIRECT, &netevent); 1761 1762 if (rt->rt6i_flags & RTF_CACHE) { |
1763 rt = (struct rt6_info *) dst_clone(&rt->dst); |
|
1691 ip6_del_rt(rt); | 1764 ip6_del_rt(rt); |
1692 return; | |
1693 } 1694 1695out: | 1765 } 1766 1767out: |
1696 dst_release(&rt->dst); | 1768 neigh_release(neigh); |
1697} 1698 1699/* | 1769} 1770 1771/* |
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); | 1772 * Misc support functions 1773 */ 1774 1775static struct rt6_info *ip6_rt_copy(struct rt6_info *ort, 1776 const struct in6_addr *dest) 1777{ 1778 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); | 1779 struct rt6_info *rt = ip6_dst_alloc(net, ort->dst.dev, 0, 1780 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); | 1781 1782 if (rt) { 1783 rt->dst.input = ort->dst.input; 1784 rt->dst.output = ort->dst.output; 1785 rt->dst.flags |= DST_HOST; 1786 1787 rt->rt6i_dst.addr = *dest; 1788 rt->rt6i_dst.plen = 128; --- 267 unchanged lines hidden (view full) --- 2056 * Allocate a dst for local (unicast / anycast) address. 2057 */ 2058 2059struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, 2060 const struct in6_addr *addr, 2061 bool anycast) 2062{ 2063 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); | 2064 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); --- 279 unchanged lines hidden (view full) --- 2391} 2392 2393static int rt6_fill_node(struct net *net, 2394 struct sk_buff *skb, struct rt6_info *rt, 2395 struct in6_addr *dst, struct in6_addr *src, 2396 int iif, int type, u32 pid, u32 seq, 2397 int prefix, int nowait, unsigned int flags) 2398{ | 2065 int err; 2066 2067 if (!rt) { 2068 net_warn_ratelimited("Maximum number of routes reached, consider increasing route/max_size\n"); 2069 return ERR_PTR(-ENOMEM); 2070 } 2071 2072 in6_dev_hold(idev); --- 279 unchanged lines hidden (view full) --- 2352} 2353 2354static int rt6_fill_node(struct net *net, 2355 struct sk_buff *skb, struct rt6_info *rt, 2356 struct in6_addr *dst, struct in6_addr *src, 2357 int iif, int type, u32 pid, u32 seq, 2358 int prefix, int nowait, unsigned int flags) 2359{ |
2399 const struct inet_peer *peer; | |
2400 struct rtmsg *rtm; 2401 struct nlmsghdr *nlh; 2402 long expires; 2403 u32 table; 2404 struct neighbour *n; | 2360 struct rtmsg *rtm; 2361 struct nlmsghdr *nlh; 2362 long expires; 2363 u32 table; 2364 struct neighbour *n; |
2405 u32 ts, tsage; | |
2406 2407 if (prefix) { /* user wants prefix routes only */ 2408 if (!(rt->rt6i_flags & RTF_PREFIX_RT)) { 2409 /* success since this is not a prefix route */ 2410 return 1; 2411 } 2412 } 2413 --- 81 unchanged lines hidden (view full) --- 2495 if (nla_put(skb, RTA_PREFSRC, 16, &saddr_buf)) 2496 goto nla_put_failure; 2497 } 2498 2499 if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0) 2500 goto nla_put_failure; 2501 2502 rcu_read_lock(); | 2365 2366 if (prefix) { /* user wants prefix routes only */ 2367 if (!(rt->rt6i_flags & RTF_PREFIX_RT)) { 2368 /* success since this is not a prefix route */ 2369 return 1; 2370 } 2371 } 2372 --- 81 unchanged lines hidden (view full) --- 2454 if (nla_put(skb, RTA_PREFSRC, 16, &saddr_buf)) 2455 goto nla_put_failure; 2456 } 2457 2458 if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0) 2459 goto nla_put_failure; 2460 2461 rcu_read_lock(); |
2503 n = dst_get_neighbour_noref(&rt->dst); | 2462 n = rt->n; |
2504 if (n) { 2505 if (nla_put(skb, RTA_GATEWAY, 16, &n->primary_key) < 0) { 2506 rcu_read_unlock(); 2507 goto nla_put_failure; 2508 } 2509 } 2510 rcu_read_unlock(); 2511 --- 4 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 | 2463 if (n) { 2464 if (nla_put(skb, RTA_GATEWAY, 16, &n->primary_key) < 0) { 2465 rcu_read_unlock(); 2466 goto nla_put_failure; 2467 } 2468 } 2469 rcu_read_unlock(); 2470 --- 4 unchanged lines hidden (view full) --- 2475 goto nla_put_failure; 2476 if (!(rt->rt6i_flags & RTF_EXPIRES)) 2477 expires = 0; 2478 else if (rt->dst.expires - jiffies < INT_MAX) 2479 expires = rt->dst.expires - jiffies; 2480 else 2481 expires = INT_MAX; 2482 |
2524 peer = rt->rt6i_peer; 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) | 2483 if (rtnl_put_cacheinfo(skb, &rt->dst, 0, expires, rt->dst.error) < 0) |
2533 goto nla_put_failure; 2534 2535 return nlmsg_end(skb, nlh); 2536 2537nla_put_failure: 2538 nlmsg_cancel(skb, nlh); 2539 return -EMSGSIZE; 2540} --- 176 unchanged lines hidden (view full) --- 2717 seq_printf(m, "%pi6 %02x ", &rt->rt6i_dst.addr, rt->rt6i_dst.plen); 2718 2719#ifdef CONFIG_IPV6_SUBTREES 2720 seq_printf(m, "%pi6 %02x ", &rt->rt6i_src.addr, rt->rt6i_src.plen); 2721#else 2722 seq_puts(m, "00000000000000000000000000000000 00 "); 2723#endif 2724 rcu_read_lock(); | 2484 goto nla_put_failure; 2485 2486 return nlmsg_end(skb, nlh); 2487 2488nla_put_failure: 2489 nlmsg_cancel(skb, nlh); 2490 return -EMSGSIZE; 2491} --- 176 unchanged lines hidden (view full) --- 2668 seq_printf(m, "%pi6 %02x ", &rt->rt6i_dst.addr, rt->rt6i_dst.plen); 2669 2670#ifdef CONFIG_IPV6_SUBTREES 2671 seq_printf(m, "%pi6 %02x ", &rt->rt6i_src.addr, rt->rt6i_src.plen); 2672#else 2673 seq_puts(m, "00000000000000000000000000000000 00 "); 2674#endif 2675 rcu_read_lock(); |
2725 n = dst_get_neighbour_noref(&rt->dst); | 2676 n = rt->n; |
2726 if (n) { 2727 seq_printf(m, "%pi6", n->primary_key); 2728 } else { 2729 seq_puts(m, "00000000000000000000000000000000"); 2730 } 2731 rcu_read_unlock(); 2732 seq_printf(m, " %08x %08x %08x %08x %8s\n", 2733 rt->rt6i_metric, atomic_read(&rt->dst.__refcnt), --- 268 unchanged lines hidden (view full) --- 3002#endif 3003} 3004 3005static struct pernet_operations ip6_route_net_ops = { 3006 .init = ip6_route_net_init, 3007 .exit = ip6_route_net_exit, 3008}; 3009 | 2677 if (n) { 2678 seq_printf(m, "%pi6", n->primary_key); 2679 } else { 2680 seq_puts(m, "00000000000000000000000000000000"); 2681 } 2682 rcu_read_unlock(); 2683 seq_printf(m, " %08x %08x %08x %08x %8s\n", 2684 rt->rt6i_metric, atomic_read(&rt->dst.__refcnt), --- 268 unchanged lines hidden (view full) --- 2953#endif 2954} 2955 2956static struct pernet_operations ip6_route_net_ops = { 2957 .init = ip6_route_net_init, 2958 .exit = ip6_route_net_exit, 2959}; 2960 |
2961static int __net_init ipv6_inetpeer_init(struct net *net) 2962{ 2963 struct inet_peer_base *bp = kmalloc(sizeof(*bp), GFP_KERNEL); 2964 2965 if (!bp) 2966 return -ENOMEM; 2967 inet_peer_base_init(bp); 2968 net->ipv6.peers = bp; 2969 return 0; 2970} 2971 2972static void __net_exit ipv6_inetpeer_exit(struct net *net) 2973{ 2974 struct inet_peer_base *bp = net->ipv6.peers; 2975 2976 net->ipv6.peers = NULL; 2977 inetpeer_invalidate_tree(bp); 2978 kfree(bp); 2979} 2980 2981static struct pernet_operations ipv6_inetpeer_ops = { 2982 .init = ipv6_inetpeer_init, 2983 .exit = ipv6_inetpeer_exit, 2984}; 2985 |
|
3010static struct pernet_operations ip6_route_net_late_ops = { 3011 .init = ip6_route_net_init_late, 3012 .exit = ip6_route_net_exit_late, 3013}; 3014 3015static struct notifier_block ip6_route_dev_notifier = { 3016 .notifier_call = ip6_route_dev_notify, 3017 .priority = 0, --- 9 unchanged lines hidden (view full) --- 3027 SLAB_HWCACHE_ALIGN, NULL); 3028 if (!ip6_dst_ops_template.kmem_cachep) 3029 goto out; 3030 3031 ret = dst_entries_init(&ip6_dst_blackhole_ops); 3032 if (ret) 3033 goto out_kmem_cache; 3034 | 2986static struct pernet_operations ip6_route_net_late_ops = { 2987 .init = ip6_route_net_init_late, 2988 .exit = ip6_route_net_exit_late, 2989}; 2990 2991static struct notifier_block ip6_route_dev_notifier = { 2992 .notifier_call = ip6_route_dev_notify, 2993 .priority = 0, --- 9 unchanged lines hidden (view full) --- 3003 SLAB_HWCACHE_ALIGN, NULL); 3004 if (!ip6_dst_ops_template.kmem_cachep) 3005 goto out; 3006 3007 ret = dst_entries_init(&ip6_dst_blackhole_ops); 3008 if (ret) 3009 goto out_kmem_cache; 3010 |
3035 ret = register_pernet_subsys(&ip6_route_net_ops); | 3011 ret = register_pernet_subsys(&ipv6_inetpeer_ops); |
3036 if (ret) 3037 goto out_dst_entries; 3038 | 3012 if (ret) 3013 goto out_dst_entries; 3014 |
3015 ret = register_pernet_subsys(&ip6_route_net_ops); 3016 if (ret) 3017 goto out_register_inetpeer; 3018 |
|
3039 ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops_template.kmem_cachep; 3040 3041 /* Registering of the loopback is done before this portion of code, 3042 * the loopback reference in rt6_info will not be taken, do it 3043 * manually for init_net */ 3044 init_net.ipv6.ip6_null_entry->dst.dev = init_net.loopback_dev; 3045 init_net.ipv6.ip6_null_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); 3046 #ifdef CONFIG_IPV6_MULTIPLE_TABLES --- 36 unchanged lines hidden (view full) --- 3083fib6_rules_init: 3084 fib6_rules_cleanup(); 3085xfrm6_init: 3086 xfrm6_fini(); 3087out_fib6_init: 3088 fib6_gc_cleanup(); 3089out_register_subsys: 3090 unregister_pernet_subsys(&ip6_route_net_ops); | 3019 ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops_template.kmem_cachep; 3020 3021 /* Registering of the loopback is done before this portion of code, 3022 * the loopback reference in rt6_info will not be taken, do it 3023 * manually for init_net */ 3024 init_net.ipv6.ip6_null_entry->dst.dev = init_net.loopback_dev; 3025 init_net.ipv6.ip6_null_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); 3026 #ifdef CONFIG_IPV6_MULTIPLE_TABLES --- 36 unchanged lines hidden (view full) --- 3063fib6_rules_init: 3064 fib6_rules_cleanup(); 3065xfrm6_init: 3066 xfrm6_fini(); 3067out_fib6_init: 3068 fib6_gc_cleanup(); 3069out_register_subsys: 3070 unregister_pernet_subsys(&ip6_route_net_ops); |
3071out_register_inetpeer: 3072 unregister_pernet_subsys(&ipv6_inetpeer_ops); |
|
3091out_dst_entries: 3092 dst_entries_destroy(&ip6_dst_blackhole_ops); 3093out_kmem_cache: 3094 kmem_cache_destroy(ip6_dst_ops_template.kmem_cachep); 3095 goto out; 3096} 3097 3098void ip6_route_cleanup(void) 3099{ 3100 unregister_netdevice_notifier(&ip6_route_dev_notifier); 3101 unregister_pernet_subsys(&ip6_route_net_late_ops); 3102 fib6_rules_cleanup(); 3103 xfrm6_fini(); 3104 fib6_gc_cleanup(); | 3073out_dst_entries: 3074 dst_entries_destroy(&ip6_dst_blackhole_ops); 3075out_kmem_cache: 3076 kmem_cache_destroy(ip6_dst_ops_template.kmem_cachep); 3077 goto out; 3078} 3079 3080void ip6_route_cleanup(void) 3081{ 3082 unregister_netdevice_notifier(&ip6_route_dev_notifier); 3083 unregister_pernet_subsys(&ip6_route_net_late_ops); 3084 fib6_rules_cleanup(); 3085 xfrm6_fini(); 3086 fib6_gc_cleanup(); |
3087 unregister_pernet_subsys(&ipv6_inetpeer_ops); |
|
3105 unregister_pernet_subsys(&ip6_route_net_ops); 3106 dst_entries_destroy(&ip6_dst_blackhole_ops); 3107 kmem_cache_destroy(ip6_dst_ops_template.kmem_cachep); 3108} | 3088 unregister_pernet_subsys(&ip6_route_net_ops); 3089 dst_entries_destroy(&ip6_dst_blackhole_ops); 3090 kmem_cache_destroy(ip6_dst_ops_template.kmem_cachep); 3091} |