route.c (3732ce72b45a2a145803558758821bf198751276) | route.c (127eb7cd3c210afead788991a30950a9e36759ea) |
---|---|
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 --- 40 unchanged lines hidden (view full) --- 49#include <net/ipv6.h> 50#include <net/ip6_fib.h> 51#include <net/ip6_route.h> 52#include <net/ndisc.h> 53#include <net/addrconf.h> 54#include <net/tcp.h> 55#include <linux/rtnetlink.h> 56#include <net/dst.h> | 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 --- 40 unchanged lines hidden (view full) --- 49#include <net/ipv6.h> 50#include <net/ip6_fib.h> 51#include <net/ip6_route.h> 52#include <net/ndisc.h> 53#include <net/addrconf.h> 54#include <net/tcp.h> 55#include <linux/rtnetlink.h> 56#include <net/dst.h> |
57#include <net/dst_metadata.h> |
|
57#include <net/xfrm.h> 58#include <net/netevent.h> 59#include <net/netlink.h> 60#include <net/nexthop.h> | 58#include <net/xfrm.h> 59#include <net/netevent.h> 60#include <net/netlink.h> 61#include <net/nexthop.h> |
62#include <net/lwtunnel.h> 63#include <net/ip_tunnels.h> |
|
61 62#include <asm/uaccess.h> 63 64#ifdef CONFIG_SYSCTL 65#include <linux/sysctl.h> 66#endif 67 68enum rt6_nud_state { --- 461 unchanged lines hidden (view full) --- 530 531static void rt6_probe_deferred(struct work_struct *w) 532{ 533 struct in6_addr mcaddr; 534 struct __rt6_probe_work *work = 535 container_of(w, struct __rt6_probe_work, work); 536 537 addrconf_addr_solict_mult(&work->target, &mcaddr); | 64 65#include <asm/uaccess.h> 66 67#ifdef CONFIG_SYSCTL 68#include <linux/sysctl.h> 69#endif 70 71enum rt6_nud_state { --- 461 unchanged lines hidden (view full) --- 533 534static void rt6_probe_deferred(struct work_struct *w) 535{ 536 struct in6_addr mcaddr; 537 struct __rt6_probe_work *work = 538 container_of(w, struct __rt6_probe_work, work); 539 540 addrconf_addr_solict_mult(&work->target, &mcaddr); |
538 ndisc_send_ns(work->dev, NULL, &work->target, &mcaddr, NULL); | 541 ndisc_send_ns(work->dev, NULL, &work->target, &mcaddr, NULL, NULL); |
539 dev_put(work->dev); 540 kfree(work); 541} 542 543static void rt6_probe(struct rt6_info *rt) 544{ | 542 dev_put(work->dev); 543 kfree(work); 544} 545 546static void rt6_probe(struct rt6_info *rt) 547{ |
548 struct __rt6_probe_work *work; |
|
545 struct neighbour *neigh; 546 /* 547 * Okay, this does not seem to be appropriate 548 * for now, however, we need to check if it 549 * is really so; aka Router Reachability Probing. 550 * 551 * Router Reachability Probe MUST be rate-limited 552 * to no more than one per minute. 553 */ 554 if (!rt || !(rt->rt6i_flags & RTF_GATEWAY)) 555 return; 556 rcu_read_lock_bh(); 557 neigh = __ipv6_neigh_lookup_noref(rt->dst.dev, &rt->rt6i_gateway); 558 if (neigh) { | 549 struct neighbour *neigh; 550 /* 551 * Okay, this does not seem to be appropriate 552 * for now, however, we need to check if it 553 * is really so; aka Router Reachability Probing. 554 * 555 * Router Reachability Probe MUST be rate-limited 556 * to no more than one per minute. 557 */ 558 if (!rt || !(rt->rt6i_flags & RTF_GATEWAY)) 559 return; 560 rcu_read_lock_bh(); 561 neigh = __ipv6_neigh_lookup_noref(rt->dst.dev, &rt->rt6i_gateway); 562 if (neigh) { |
559 write_lock(&neigh->lock); | |
560 if (neigh->nud_state & NUD_VALID) 561 goto out; | 563 if (neigh->nud_state & NUD_VALID) 564 goto out; |
562 } | |
563 | 565 |
564 if (!neigh || 565 time_after(jiffies, neigh->updated + rt->rt6i_idev->cnf.rtr_probe_interval)) { 566 struct __rt6_probe_work *work; 567 | 566 work = NULL; 567 write_lock(&neigh->lock); 568 if (!(neigh->nud_state & NUD_VALID) && 569 time_after(jiffies, 570 neigh->updated + 571 rt->rt6i_idev->cnf.rtr_probe_interval)) { 572 work = kmalloc(sizeof(*work), GFP_ATOMIC); 573 if (work) 574 __neigh_set_probe_once(neigh); 575 } 576 write_unlock(&neigh->lock); 577 } else { |
568 work = kmalloc(sizeof(*work), GFP_ATOMIC); | 578 work = kmalloc(sizeof(*work), GFP_ATOMIC); |
579 } |
|
569 | 580 |
570 if (neigh && work) 571 __neigh_set_probe_once(neigh); | 581 if (work) { 582 INIT_WORK(&work->work, rt6_probe_deferred); 583 work->target = rt->rt6i_gateway; 584 dev_hold(rt->dst.dev); 585 work->dev = rt->dst.dev; 586 schedule_work(&work->work); 587 } |
572 | 588 |
573 if (neigh) 574 write_unlock(&neigh->lock); 575 576 if (work) { 577 INIT_WORK(&work->work, rt6_probe_deferred); 578 work->target = rt->rt6i_gateway; 579 dev_hold(rt->dst.dev); 580 work->dev = rt->dst.dev; 581 schedule_work(&work->work); 582 } 583 } else { | |
584out: | 589out: |
585 write_unlock(&neigh->lock); 586 } | |
587 rcu_read_unlock_bh(); 588} 589#else 590static inline void rt6_probe(struct rt6_info *rt) 591{ 592} 593#endif 594 --- 62 unchanged lines hidden (view full) --- 657} 658 659static struct rt6_info *find_match(struct rt6_info *rt, int oif, int strict, 660 int *mpri, struct rt6_info *match, 661 bool *do_rr) 662{ 663 int m; 664 bool match_do_rr = false; | 590 rcu_read_unlock_bh(); 591} 592#else 593static inline void rt6_probe(struct rt6_info *rt) 594{ 595} 596#endif 597 --- 62 unchanged lines hidden (view full) --- 660} 661 662static struct rt6_info *find_match(struct rt6_info *rt, int oif, int strict, 663 int *mpri, struct rt6_info *match, 664 bool *do_rr) 665{ 666 int m; 667 bool match_do_rr = false; |
668 struct inet6_dev *idev = rt->rt6i_idev; 669 struct net_device *dev = rt->dst.dev; |
|
665 | 670 |
671 if (dev && !netif_carrier_ok(dev) && 672 idev->cnf.ignore_routes_with_linkdown) 673 goto out; 674 |
|
666 if (rt6_check_expired(rt)) 667 goto out; 668 669 m = rt6_score_route(rt, oif, strict); 670 if (m == RT6_NUD_FAIL_DO_RR) { 671 match_do_rr = true; 672 m = 0; /* lowest valid score */ 673 } else if (m == RT6_NUD_FAIL_HARD) { --- 475 unchanged lines hidden (view full) --- 1149 return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_input); 1150} 1151 1152void ip6_route_input(struct sk_buff *skb) 1153{ 1154 const struct ipv6hdr *iph = ipv6_hdr(skb); 1155 struct net *net = dev_net(skb->dev); 1156 int flags = RT6_LOOKUP_F_HAS_SADDR; | 675 if (rt6_check_expired(rt)) 676 goto out; 677 678 m = rt6_score_route(rt, oif, strict); 679 if (m == RT6_NUD_FAIL_DO_RR) { 680 match_do_rr = true; 681 m = 0; /* lowest valid score */ 682 } else if (m == RT6_NUD_FAIL_HARD) { --- 475 unchanged lines hidden (view full) --- 1158 return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_input); 1159} 1160 1161void ip6_route_input(struct sk_buff *skb) 1162{ 1163 const struct ipv6hdr *iph = ipv6_hdr(skb); 1164 struct net *net = dev_net(skb->dev); 1165 int flags = RT6_LOOKUP_F_HAS_SADDR; |
1166 struct ip_tunnel_info *tun_info; |
|
1157 struct flowi6 fl6 = { 1158 .flowi6_iif = skb->dev->ifindex, 1159 .daddr = iph->daddr, 1160 .saddr = iph->saddr, 1161 .flowlabel = ip6_flowinfo(iph), 1162 .flowi6_mark = skb->mark, 1163 .flowi6_proto = iph->nexthdr, 1164 }; 1165 | 1167 struct flowi6 fl6 = { 1168 .flowi6_iif = skb->dev->ifindex, 1169 .daddr = iph->daddr, 1170 .saddr = iph->saddr, 1171 .flowlabel = ip6_flowinfo(iph), 1172 .flowi6_mark = skb->mark, 1173 .flowi6_proto = iph->nexthdr, 1174 }; 1175 |
1176 tun_info = skb_tunnel_info(skb); 1177 if (tun_info && tun_info->mode == IP_TUNNEL_INFO_RX) 1178 fl6.flowi6_tun_key.tun_id = tun_info->key.tun_id; 1179 skb_dst_drop(skb); |
|
1166 skb_dst_set(skb, ip6_route_input_lookup(net, skb->dev, &fl6, flags)); 1167} 1168 1169static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table *table, 1170 struct flowi6 *fl6, int flags) 1171{ 1172 return ip6_pol_route(net, table, fl6->flowi6_oif, fl6, flags); 1173} --- 622 unchanged lines hidden (view full) --- 1796 rt->dst.input = ip6_mc_input; 1797 else if (cfg->fc_flags & RTF_LOCAL) 1798 rt->dst.input = ip6_input; 1799 else 1800 rt->dst.input = ip6_forward; 1801 1802 rt->dst.output = ip6_output; 1803 | 1180 skb_dst_set(skb, ip6_route_input_lookup(net, skb->dev, &fl6, flags)); 1181} 1182 1183static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table *table, 1184 struct flowi6 *fl6, int flags) 1185{ 1186 return ip6_pol_route(net, table, fl6->flowi6_oif, fl6, flags); 1187} --- 622 unchanged lines hidden (view full) --- 1810 rt->dst.input = ip6_mc_input; 1811 else if (cfg->fc_flags & RTF_LOCAL) 1812 rt->dst.input = ip6_input; 1813 else 1814 rt->dst.input = ip6_forward; 1815 1816 rt->dst.output = ip6_output; 1817 |
1818 if (cfg->fc_encap) { 1819 struct lwtunnel_state *lwtstate; 1820 1821 err = lwtunnel_build_state(dev, cfg->fc_encap_type, 1822 cfg->fc_encap, AF_INET6, cfg, 1823 &lwtstate); 1824 if (err) 1825 goto out; 1826 rt->dst.lwtstate = lwtstate_get(lwtstate); 1827 if (lwtunnel_output_redirect(rt->dst.lwtstate)) { 1828 rt->dst.lwtstate->orig_output = rt->dst.output; 1829 rt->dst.output = lwtunnel_output; 1830 } 1831 if (lwtunnel_input_redirect(rt->dst.lwtstate)) { 1832 rt->dst.lwtstate->orig_input = rt->dst.input; 1833 rt->dst.input = lwtunnel_input; 1834 } 1835 } 1836 |
|
1804 ipv6_addr_prefix(&rt->rt6i_dst.addr, &cfg->fc_dst, cfg->fc_dst_len); 1805 rt->rt6i_dst.plen = cfg->fc_dst_len; 1806 if (rt->rt6i_dst.plen == 128) 1807 rt->dst.flags |= DST_HOST; 1808 1809#ifdef CONFIG_IPV6_SUBTREES 1810 ipv6_addr_prefix(&rt->rt6i_src.addr, &cfg->fc_src, cfg->fc_src_len); 1811 rt->rt6i_src.plen = cfg->fc_src_len; --- 363 unchanged lines hidden (view full) --- 2175 rt->rt6i_flags = ort->rt6i_flags; 2176 rt6_set_from(rt, ort); 2177 rt->rt6i_metric = ort->rt6i_metric; 2178#ifdef CONFIG_IPV6_SUBTREES 2179 rt->rt6i_src = ort->rt6i_src; 2180#endif 2181 rt->rt6i_prefsrc = ort->rt6i_prefsrc; 2182 rt->rt6i_table = ort->rt6i_table; | 1837 ipv6_addr_prefix(&rt->rt6i_dst.addr, &cfg->fc_dst, cfg->fc_dst_len); 1838 rt->rt6i_dst.plen = cfg->fc_dst_len; 1839 if (rt->rt6i_dst.plen == 128) 1840 rt->dst.flags |= DST_HOST; 1841 1842#ifdef CONFIG_IPV6_SUBTREES 1843 ipv6_addr_prefix(&rt->rt6i_src.addr, &cfg->fc_src, cfg->fc_src_len); 1844 rt->rt6i_src.plen = cfg->fc_src_len; --- 363 unchanged lines hidden (view full) --- 2208 rt->rt6i_flags = ort->rt6i_flags; 2209 rt6_set_from(rt, ort); 2210 rt->rt6i_metric = ort->rt6i_metric; 2211#ifdef CONFIG_IPV6_SUBTREES 2212 rt->rt6i_src = ort->rt6i_src; 2213#endif 2214 rt->rt6i_prefsrc = ort->rt6i_prefsrc; 2215 rt->rt6i_table = ort->rt6i_table; |
2216 rt->dst.lwtstate = lwtstate_get(ort->dst.lwtstate); |
|
2183} 2184 2185#ifdef CONFIG_IPV6_ROUTE_INFO 2186static struct rt6_info *rt6_get_route_info(struct net *net, 2187 const struct in6_addr *prefix, int prefixlen, 2188 const struct in6_addr *gwaddr, int ifindex) 2189{ 2190 struct fib6_node *fn; --- 432 unchanged lines hidden (view full) --- 2623static const struct nla_policy rtm_ipv6_policy[RTA_MAX+1] = { 2624 [RTA_GATEWAY] = { .len = sizeof(struct in6_addr) }, 2625 [RTA_OIF] = { .type = NLA_U32 }, 2626 [RTA_IIF] = { .type = NLA_U32 }, 2627 [RTA_PRIORITY] = { .type = NLA_U32 }, 2628 [RTA_METRICS] = { .type = NLA_NESTED }, 2629 [RTA_MULTIPATH] = { .len = sizeof(struct rtnexthop) }, 2630 [RTA_PREF] = { .type = NLA_U8 }, | 2217} 2218 2219#ifdef CONFIG_IPV6_ROUTE_INFO 2220static struct rt6_info *rt6_get_route_info(struct net *net, 2221 const struct in6_addr *prefix, int prefixlen, 2222 const struct in6_addr *gwaddr, int ifindex) 2223{ 2224 struct fib6_node *fn; --- 432 unchanged lines hidden (view full) --- 2657static const struct nla_policy rtm_ipv6_policy[RTA_MAX+1] = { 2658 [RTA_GATEWAY] = { .len = sizeof(struct in6_addr) }, 2659 [RTA_OIF] = { .type = NLA_U32 }, 2660 [RTA_IIF] = { .type = NLA_U32 }, 2661 [RTA_PRIORITY] = { .type = NLA_U32 }, 2662 [RTA_METRICS] = { .type = NLA_NESTED }, 2663 [RTA_MULTIPATH] = { .len = sizeof(struct rtnexthop) }, 2664 [RTA_PREF] = { .type = NLA_U8 }, |
2665 [RTA_ENCAP_TYPE] = { .type = NLA_U16 }, 2666 [RTA_ENCAP] = { .type = NLA_NESTED }, |
|
2631}; 2632 2633static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, 2634 struct fib6_config *cfg) 2635{ 2636 struct rtmsg *rtm; 2637 struct nlattr *tb[RTA_MAX+1]; 2638 unsigned int pref; --- 78 unchanged lines hidden (view full) --- 2717 if (tb[RTA_PREF]) { 2718 pref = nla_get_u8(tb[RTA_PREF]); 2719 if (pref != ICMPV6_ROUTER_PREF_LOW && 2720 pref != ICMPV6_ROUTER_PREF_HIGH) 2721 pref = ICMPV6_ROUTER_PREF_MEDIUM; 2722 cfg->fc_flags |= RTF_PREF(pref); 2723 } 2724 | 2667}; 2668 2669static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, 2670 struct fib6_config *cfg) 2671{ 2672 struct rtmsg *rtm; 2673 struct nlattr *tb[RTA_MAX+1]; 2674 unsigned int pref; --- 78 unchanged lines hidden (view full) --- 2753 if (tb[RTA_PREF]) { 2754 pref = nla_get_u8(tb[RTA_PREF]); 2755 if (pref != ICMPV6_ROUTER_PREF_LOW && 2756 pref != ICMPV6_ROUTER_PREF_HIGH) 2757 pref = ICMPV6_ROUTER_PREF_MEDIUM; 2758 cfg->fc_flags |= RTF_PREF(pref); 2759 } 2760 |
2761 if (tb[RTA_ENCAP]) 2762 cfg->fc_encap = tb[RTA_ENCAP]; 2763 2764 if (tb[RTA_ENCAP_TYPE]) 2765 cfg->fc_encap_type = nla_get_u16(tb[RTA_ENCAP_TYPE]); 2766 |
|
2725 err = 0; 2726errout: 2727 return err; 2728} 2729 2730static int ip6_route_multipath(struct fib6_config *cfg, int add) 2731{ 2732 struct fib6_config r_cfg; --- 16 unchanged lines hidden (view full) --- 2749 if (attrlen > 0) { 2750 struct nlattr *nla, *attrs = rtnh_attrs(rtnh); 2751 2752 nla = nla_find(attrs, attrlen, RTA_GATEWAY); 2753 if (nla) { 2754 r_cfg.fc_gateway = nla_get_in6_addr(nla); 2755 r_cfg.fc_flags |= RTF_GATEWAY; 2756 } | 2767 err = 0; 2768errout: 2769 return err; 2770} 2771 2772static int ip6_route_multipath(struct fib6_config *cfg, int add) 2773{ 2774 struct fib6_config r_cfg; --- 16 unchanged lines hidden (view full) --- 2791 if (attrlen > 0) { 2792 struct nlattr *nla, *attrs = rtnh_attrs(rtnh); 2793 2794 nla = nla_find(attrs, attrlen, RTA_GATEWAY); 2795 if (nla) { 2796 r_cfg.fc_gateway = nla_get_in6_addr(nla); 2797 r_cfg.fc_flags |= RTF_GATEWAY; 2798 } |
2799 r_cfg.fc_encap = nla_find(attrs, attrlen, RTA_ENCAP); 2800 nla = nla_find(attrs, attrlen, RTA_ENCAP_TYPE); 2801 if (nla) 2802 r_cfg.fc_encap_type = nla_get_u16(nla); |
|
2757 } 2758 err = add ? ip6_route_add(&r_cfg) : ip6_route_del(&r_cfg); 2759 if (err) { 2760 last_err = err; 2761 /* If we are trying to remove a route, do not stop the 2762 * loop when ip6_route_del() fails (because next hop is 2763 * already gone), we should try to remove all next hops. 2764 */ --- 46 unchanged lines hidden (view full) --- 2811 return err; 2812 2813 if (cfg.fc_mp) 2814 return ip6_route_multipath(&cfg, 1); 2815 else 2816 return ip6_route_add(&cfg); 2817} 2818 | 2803 } 2804 err = add ? ip6_route_add(&r_cfg) : ip6_route_del(&r_cfg); 2805 if (err) { 2806 last_err = err; 2807 /* If we are trying to remove a route, do not stop the 2808 * loop when ip6_route_del() fails (because next hop is 2809 * already gone), we should try to remove all next hops. 2810 */ --- 46 unchanged lines hidden (view full) --- 2857 return err; 2858 2859 if (cfg.fc_mp) 2860 return ip6_route_multipath(&cfg, 1); 2861 else 2862 return ip6_route_add(&cfg); 2863} 2864 |
2819static inline size_t rt6_nlmsg_size(void) | 2865static inline size_t rt6_nlmsg_size(struct rt6_info *rt) |
2820{ 2821 return NLMSG_ALIGN(sizeof(struct rtmsg)) 2822 + nla_total_size(16) /* RTA_SRC */ 2823 + nla_total_size(16) /* RTA_DST */ 2824 + nla_total_size(16) /* RTA_GATEWAY */ 2825 + nla_total_size(16) /* RTA_PREFSRC */ 2826 + nla_total_size(4) /* RTA_TABLE */ 2827 + nla_total_size(4) /* RTA_IIF */ 2828 + nla_total_size(4) /* RTA_OIF */ 2829 + nla_total_size(4) /* RTA_PRIORITY */ 2830 + RTAX_MAX * nla_total_size(4) /* RTA_METRICS */ 2831 + nla_total_size(sizeof(struct rta_cacheinfo)) 2832 + nla_total_size(TCP_CA_NAME_MAX) /* RTAX_CC_ALGO */ | 2866{ 2867 return NLMSG_ALIGN(sizeof(struct rtmsg)) 2868 + nla_total_size(16) /* RTA_SRC */ 2869 + nla_total_size(16) /* RTA_DST */ 2870 + nla_total_size(16) /* RTA_GATEWAY */ 2871 + nla_total_size(16) /* RTA_PREFSRC */ 2872 + nla_total_size(4) /* RTA_TABLE */ 2873 + nla_total_size(4) /* RTA_IIF */ 2874 + nla_total_size(4) /* RTA_OIF */ 2875 + nla_total_size(4) /* RTA_PRIORITY */ 2876 + RTAX_MAX * nla_total_size(4) /* RTA_METRICS */ 2877 + nla_total_size(sizeof(struct rta_cacheinfo)) 2878 + nla_total_size(TCP_CA_NAME_MAX) /* RTAX_CC_ALGO */ |
2833 + nla_total_size(1); /* RTA_PREF */ | 2879 + nla_total_size(1) /* RTA_PREF */ 2880 + lwtunnel_get_encap_size(rt->dst.lwtstate); |
2834} 2835 2836static int rt6_fill_node(struct net *net, 2837 struct sk_buff *skb, struct rt6_info *rt, 2838 struct in6_addr *dst, struct in6_addr *src, 2839 int iif, int type, u32 portid, u32 seq, 2840 int prefix, int nowait, unsigned int flags) 2841{ --- 44 unchanged lines hidden (view full) --- 2886 } 2887 else if (rt->rt6i_flags & RTF_LOCAL) 2888 rtm->rtm_type = RTN_LOCAL; 2889 else if (rt->dst.dev && (rt->dst.dev->flags & IFF_LOOPBACK)) 2890 rtm->rtm_type = RTN_LOCAL; 2891 else 2892 rtm->rtm_type = RTN_UNICAST; 2893 rtm->rtm_flags = 0; | 2881} 2882 2883static int rt6_fill_node(struct net *net, 2884 struct sk_buff *skb, struct rt6_info *rt, 2885 struct in6_addr *dst, struct in6_addr *src, 2886 int iif, int type, u32 portid, u32 seq, 2887 int prefix, int nowait, unsigned int flags) 2888{ --- 44 unchanged lines hidden (view full) --- 2933 } 2934 else if (rt->rt6i_flags & RTF_LOCAL) 2935 rtm->rtm_type = RTN_LOCAL; 2936 else if (rt->dst.dev && (rt->dst.dev->flags & IFF_LOOPBACK)) 2937 rtm->rtm_type = RTN_LOCAL; 2938 else 2939 rtm->rtm_type = RTN_UNICAST; 2940 rtm->rtm_flags = 0; |
2941 if (!netif_carrier_ok(rt->dst.dev)) { 2942 rtm->rtm_flags |= RTNH_F_LINKDOWN; 2943 if (rt->rt6i_idev->cnf.ignore_routes_with_linkdown) 2944 rtm->rtm_flags |= RTNH_F_DEAD; 2945 } |
|
2894 rtm->rtm_scope = RT_SCOPE_UNIVERSE; 2895 rtm->rtm_protocol = rt->rt6i_protocol; 2896 if (rt->rt6i_flags & RTF_DYNAMIC) 2897 rtm->rtm_protocol = RTPROT_REDIRECT; 2898 else if (rt->rt6i_flags & RTF_ADDRCONF) { 2899 if (rt->rt6i_flags & (RTF_DEFAULT | RTF_ROUTEINFO)) 2900 rtm->rtm_protocol = RTPROT_RA; 2901 else --- 71 unchanged lines hidden (view full) --- 2973 expires = (rt->rt6i_flags & RTF_EXPIRES) ? rt->dst.expires - jiffies : 0; 2974 2975 if (rtnl_put_cacheinfo(skb, &rt->dst, 0, expires, rt->dst.error) < 0) 2976 goto nla_put_failure; 2977 2978 if (nla_put_u8(skb, RTA_PREF, IPV6_EXTRACT_PREF(rt->rt6i_flags))) 2979 goto nla_put_failure; 2980 | 2946 rtm->rtm_scope = RT_SCOPE_UNIVERSE; 2947 rtm->rtm_protocol = rt->rt6i_protocol; 2948 if (rt->rt6i_flags & RTF_DYNAMIC) 2949 rtm->rtm_protocol = RTPROT_REDIRECT; 2950 else if (rt->rt6i_flags & RTF_ADDRCONF) { 2951 if (rt->rt6i_flags & (RTF_DEFAULT | RTF_ROUTEINFO)) 2952 rtm->rtm_protocol = RTPROT_RA; 2953 else --- 71 unchanged lines hidden (view full) --- 3025 expires = (rt->rt6i_flags & RTF_EXPIRES) ? rt->dst.expires - jiffies : 0; 3026 3027 if (rtnl_put_cacheinfo(skb, &rt->dst, 0, expires, rt->dst.error) < 0) 3028 goto nla_put_failure; 3029 3030 if (nla_put_u8(skb, RTA_PREF, IPV6_EXTRACT_PREF(rt->rt6i_flags))) 3031 goto nla_put_failure; 3032 |
3033 lwtunnel_fill_encap(skb, rt->dst.lwtstate); 3034 |
|
2981 nlmsg_end(skb, nlh); 2982 return 0; 2983 2984nla_put_failure: 2985 nlmsg_cancel(skb, nlh); 2986 return -EMSGSIZE; 2987} 2988 --- 110 unchanged lines hidden (view full) --- 3099 struct sk_buff *skb; 3100 struct net *net = info->nl_net; 3101 u32 seq; 3102 int err; 3103 3104 err = -ENOBUFS; 3105 seq = info->nlh ? info->nlh->nlmsg_seq : 0; 3106 | 3035 nlmsg_end(skb, nlh); 3036 return 0; 3037 3038nla_put_failure: 3039 nlmsg_cancel(skb, nlh); 3040 return -EMSGSIZE; 3041} 3042 --- 110 unchanged lines hidden (view full) --- 3153 struct sk_buff *skb; 3154 struct net *net = info->nl_net; 3155 u32 seq; 3156 int err; 3157 3158 err = -ENOBUFS; 3159 seq = info->nlh ? info->nlh->nlmsg_seq : 0; 3160 |
3107 skb = nlmsg_new(rt6_nlmsg_size(), gfp_any()); | 3161 skb = nlmsg_new(rt6_nlmsg_size(rt), gfp_any()); |
3108 if (!skb) 3109 goto errout; 3110 3111 err = rt6_fill_node(net, skb, rt, NULL, NULL, 0, 3112 event, info->portid, seq, 0, 0, 0); 3113 if (err < 0) { 3114 /* -EMSGSIZE implies BUG in rt6_nlmsg_size() */ 3115 WARN_ON(err == -EMSGSIZE); --- 439 unchanged lines hidden --- | 3162 if (!skb) 3163 goto errout; 3164 3165 err = rt6_fill_node(net, skb, rt, NULL, NULL, 0, 3166 event, info->portid, seq, 0, 0, 0); 3167 if (err < 0) { 3168 /* -EMSGSIZE implies BUG in rt6_nlmsg_size() */ 3169 WARN_ON(err == -EMSGSIZE); --- 439 unchanged lines hidden --- |