58
58
#include <net/netevent.h>
59
59
#include <net/netlink.h>
60
60
#include <net/nexthop.h>
61
+ #include <net/lwtunnel.h>
61
62
62
63
#include <asm/uaccess.h>
63
64
@@ -1770,6 +1771,17 @@ int ip6_route_add(struct fib6_config *cfg)
1770
1771
1771
1772
rt -> dst .output = ip6_output ;
1772
1773
1774
+ if (cfg -> fc_encap ) {
1775
+ struct lwtunnel_state * lwtstate ;
1776
+
1777
+ err = lwtunnel_build_state (dev , cfg -> fc_encap_type ,
1778
+ cfg -> fc_encap , & lwtstate );
1779
+ if (err )
1780
+ goto out ;
1781
+ lwtunnel_state_get (lwtstate );
1782
+ rt -> rt6i_lwtstate = lwtstate ;
1783
+ }
1784
+
1773
1785
ipv6_addr_prefix (& rt -> rt6i_dst .addr , & cfg -> fc_dst , cfg -> fc_dst_len );
1774
1786
rt -> rt6i_dst .plen = cfg -> fc_dst_len ;
1775
1787
if (rt -> rt6i_dst .plen == 128 )
@@ -2595,6 +2607,8 @@ static const struct nla_policy rtm_ipv6_policy[RTA_MAX+1] = {
2595
2607
[RTA_METRICS ] = { .type = NLA_NESTED },
2596
2608
[RTA_MULTIPATH ] = { .len = sizeof (struct rtnexthop ) },
2597
2609
[RTA_PREF ] = { .type = NLA_U8 },
2610
+ [RTA_ENCAP_TYPE ] = { .type = NLA_U16 },
2611
+ [RTA_ENCAP ] = { .type = NLA_NESTED },
2598
2612
};
2599
2613
2600
2614
static int rtm_to_fib6_config (struct sk_buff * skb , struct nlmsghdr * nlh ,
@@ -2689,6 +2703,12 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
2689
2703
cfg -> fc_flags |= RTF_PREF (pref );
2690
2704
}
2691
2705
2706
+ if (tb [RTA_ENCAP ])
2707
+ cfg -> fc_encap = tb [RTA_ENCAP ];
2708
+
2709
+ if (tb [RTA_ENCAP_TYPE ])
2710
+ cfg -> fc_encap_type = nla_get_u16 (tb [RTA_ENCAP_TYPE ]);
2711
+
2692
2712
err = 0 ;
2693
2713
errout :
2694
2714
return err ;
@@ -2721,6 +2741,10 @@ static int ip6_route_multipath(struct fib6_config *cfg, int add)
2721
2741
r_cfg .fc_gateway = nla_get_in6_addr (nla );
2722
2742
r_cfg .fc_flags |= RTF_GATEWAY ;
2723
2743
}
2744
+ r_cfg .fc_encap = nla_find (attrs , attrlen , RTA_ENCAP );
2745
+ nla = nla_find (attrs , attrlen , RTA_ENCAP_TYPE );
2746
+ if (nla )
2747
+ r_cfg .fc_encap_type = nla_get_u16 (nla );
2724
2748
}
2725
2749
err = add ? ip6_route_add (& r_cfg ) : ip6_route_del (& r_cfg );
2726
2750
if (err ) {
@@ -2783,7 +2807,7 @@ static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh)
2783
2807
return ip6_route_add (& cfg );
2784
2808
}
2785
2809
2786
- static inline size_t rt6_nlmsg_size (void )
2810
+ static inline size_t rt6_nlmsg_size (struct rt6_info * rt )
2787
2811
{
2788
2812
return NLMSG_ALIGN (sizeof (struct rtmsg ))
2789
2813
+ nla_total_size (16 ) /* RTA_SRC */
@@ -2797,7 +2821,8 @@ static inline size_t rt6_nlmsg_size(void)
2797
2821
+ RTAX_MAX * nla_total_size (4 ) /* RTA_METRICS */
2798
2822
+ nla_total_size (sizeof (struct rta_cacheinfo ))
2799
2823
+ nla_total_size (TCP_CA_NAME_MAX ) /* RTAX_CC_ALGO */
2800
- + nla_total_size (1 ); /* RTA_PREF */
2824
+ + nla_total_size (1 ) /* RTA_PREF */
2825
+ + lwtunnel_get_encap_size (rt -> rt6i_lwtstate );
2801
2826
}
2802
2827
2803
2828
static int rt6_fill_node (struct net * net ,
@@ -2945,6 +2970,8 @@ static int rt6_fill_node(struct net *net,
2945
2970
if (nla_put_u8 (skb , RTA_PREF , IPV6_EXTRACT_PREF (rt -> rt6i_flags )))
2946
2971
goto nla_put_failure ;
2947
2972
2973
+ lwtunnel_fill_encap (skb , rt -> rt6i_lwtstate );
2974
+
2948
2975
nlmsg_end (skb , nlh );
2949
2976
return 0 ;
2950
2977
@@ -3071,7 +3098,7 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info)
3071
3098
err = - ENOBUFS ;
3072
3099
seq = info -> nlh ? info -> nlh -> nlmsg_seq : 0 ;
3073
3100
3074
- skb = nlmsg_new (rt6_nlmsg_size (), gfp_any ());
3101
+ skb = nlmsg_new (rt6_nlmsg_size (rt ), gfp_any ());
3075
3102
if (!skb )
3076
3103
goto errout ;
3077
3104
0 commit comments