1010#include <linux/skbuff.h>
1111#include <linux/rtnetlink.h>
1212#include <net/geneve.h>
13+ #include <net/vxlan.h>
1314#include <net/netlink.h>
1415#include <net/pkt_sched.h>
1516#include <net/dst.h>
@@ -53,7 +54,10 @@ static int tunnel_key_act(struct sk_buff *skb, const struct tc_action *a,
5354
5455static const struct nla_policy
5556enc_opts_policy [TCA_TUNNEL_KEY_ENC_OPTS_MAX + 1 ] = {
57+ [TCA_TUNNEL_KEY_ENC_OPTS_UNSPEC ] = {
58+ .strict_start_type = TCA_TUNNEL_KEY_ENC_OPTS_VXLAN },
5659 [TCA_TUNNEL_KEY_ENC_OPTS_GENEVE ] = { .type = NLA_NESTED },
60+ [TCA_TUNNEL_KEY_ENC_OPTS_VXLAN ] = { .type = NLA_NESTED },
5761};
5862
5963static const struct nla_policy
@@ -64,6 +68,11 @@ geneve_opt_policy[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX + 1] = {
6468 .len = 128 },
6569};
6670
71+ static const struct nla_policy
72+ vxlan_opt_policy [TCA_TUNNEL_KEY_ENC_OPT_VXLAN_MAX + 1 ] = {
73+ [TCA_TUNNEL_KEY_ENC_OPT_VXLAN_GBP ] = { .type = NLA_U32 },
74+ };
75+
6776static int
6877tunnel_key_copy_geneve_opt (const struct nlattr * nla , void * dst , int dst_len ,
6978 struct netlink_ext_ack * extack )
@@ -116,10 +125,36 @@ tunnel_key_copy_geneve_opt(const struct nlattr *nla, void *dst, int dst_len,
116125 return opt_len ;
117126}
118127
128+ static int
129+ tunnel_key_copy_vxlan_opt (const struct nlattr * nla , void * dst , int dst_len ,
130+ struct netlink_ext_ack * extack )
131+ {
132+ struct nlattr * tb [TCA_TUNNEL_KEY_ENC_OPT_VXLAN_MAX + 1 ];
133+ int err ;
134+
135+ err = nla_parse_nested (tb , TCA_TUNNEL_KEY_ENC_OPT_VXLAN_MAX , nla ,
136+ vxlan_opt_policy , extack );
137+ if (err < 0 )
138+ return err ;
139+
140+ if (!tb [TCA_TUNNEL_KEY_ENC_OPT_VXLAN_GBP ]) {
141+ NL_SET_ERR_MSG (extack , "Missing tunnel key vxlan option gbp" );
142+ return - EINVAL ;
143+ }
144+
145+ if (dst ) {
146+ struct vxlan_metadata * md = dst ;
147+
148+ md -> gbp = nla_get_u32 (tb [TCA_TUNNEL_KEY_ENC_OPT_VXLAN_GBP ]);
149+ }
150+
151+ return sizeof (struct vxlan_metadata );
152+ }
153+
119154static int tunnel_key_copy_opts (const struct nlattr * nla , u8 * dst ,
120155 int dst_len , struct netlink_ext_ack * extack )
121156{
122- int err , rem , opt_len , len = nla_len (nla ), opts_len = 0 ;
157+ int err , rem , opt_len , len = nla_len (nla ), opts_len = 0 , type = 0 ;
123158 const struct nlattr * attr , * head = nla_data (nla );
124159
125160 err = nla_validate_deprecated (head , len , TCA_TUNNEL_KEY_ENC_OPTS_MAX ,
@@ -130,6 +165,10 @@ static int tunnel_key_copy_opts(const struct nlattr *nla, u8 *dst,
130165 nla_for_each_attr (attr , head , len , rem ) {
131166 switch (nla_type (attr )) {
132167 case TCA_TUNNEL_KEY_ENC_OPTS_GENEVE :
168+ if (type && type != TUNNEL_GENEVE_OPT ) {
169+ NL_SET_ERR_MSG (extack , "Duplicate type for geneve options" );
170+ return - EINVAL ;
171+ }
133172 opt_len = tunnel_key_copy_geneve_opt (attr , dst ,
134173 dst_len , extack );
135174 if (opt_len < 0 )
@@ -139,6 +178,19 @@ static int tunnel_key_copy_opts(const struct nlattr *nla, u8 *dst,
139178 dst_len -= opt_len ;
140179 dst += opt_len ;
141180 }
181+ type = TUNNEL_GENEVE_OPT ;
182+ break ;
183+ case TCA_TUNNEL_KEY_ENC_OPTS_VXLAN :
184+ if (type ) {
185+ NL_SET_ERR_MSG (extack , "Duplicate type for vxlan options" );
186+ return - EINVAL ;
187+ }
188+ opt_len = tunnel_key_copy_vxlan_opt (attr , dst ,
189+ dst_len , extack );
190+ if (opt_len < 0 )
191+ return opt_len ;
192+ opts_len += opt_len ;
193+ type = TUNNEL_VXLAN_OPT ;
142194 break ;
143195 }
144196 }
@@ -174,6 +226,14 @@ static int tunnel_key_opts_set(struct nlattr *nla, struct ip_tunnel_info *info,
174226 opts_len , extack );
175227#else
176228 return - EAFNOSUPPORT ;
229+ #endif
230+ case TCA_TUNNEL_KEY_ENC_OPTS_VXLAN :
231+ #if IS_ENABLED (CONFIG_INET )
232+ info -> key .tun_flags |= TUNNEL_VXLAN_OPT ;
233+ return tunnel_key_copy_opts (nla , ip_tunnel_info_opts (info ),
234+ opts_len , extack );
235+ #else
236+ return - EAFNOSUPPORT ;
177237#endif
178238 default :
179239 NL_SET_ERR_MSG (extack , "Cannot set tunnel options for unknown tunnel type" );
@@ -451,6 +511,25 @@ static int tunnel_key_geneve_opts_dump(struct sk_buff *skb,
451511 return 0 ;
452512}
453513
514+ static int tunnel_key_vxlan_opts_dump (struct sk_buff * skb ,
515+ const struct ip_tunnel_info * info )
516+ {
517+ struct vxlan_metadata * md = (struct vxlan_metadata * )(info + 1 );
518+ struct nlattr * start ;
519+
520+ start = nla_nest_start_noflag (skb , TCA_TUNNEL_KEY_ENC_OPTS_VXLAN );
521+ if (!start )
522+ return - EMSGSIZE ;
523+
524+ if (nla_put_u32 (skb , TCA_TUNNEL_KEY_ENC_OPT_VXLAN_GBP , md -> gbp )) {
525+ nla_nest_cancel (skb , start );
526+ return - EMSGSIZE ;
527+ }
528+
529+ nla_nest_end (skb , start );
530+ return 0 ;
531+ }
532+
454533static int tunnel_key_opts_dump (struct sk_buff * skb ,
455534 const struct ip_tunnel_info * info )
456535{
@@ -468,6 +547,10 @@ static int tunnel_key_opts_dump(struct sk_buff *skb,
468547 err = tunnel_key_geneve_opts_dump (skb , info );
469548 if (err )
470549 goto err_out ;
550+ } else if (info -> key .tun_flags & TUNNEL_VXLAN_OPT ) {
551+ err = tunnel_key_vxlan_opts_dump (skb , info );
552+ if (err )
553+ goto err_out ;
471554 } else {
472555err_out :
473556 nla_nest_cancel (skb , start );
0 commit comments