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 ---