10
10
#include <linux/skbuff.h>
11
11
#include <linux/rtnetlink.h>
12
12
#include <net/geneve.h>
13
+ #include <net/vxlan.h>
13
14
#include <net/netlink.h>
14
15
#include <net/pkt_sched.h>
15
16
#include <net/dst.h>
@@ -53,7 +54,10 @@ static int tunnel_key_act(struct sk_buff *skb, const struct tc_action *a,
53
54
54
55
static const struct nla_policy
55
56
enc_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 },
56
59
[TCA_TUNNEL_KEY_ENC_OPTS_GENEVE ] = { .type = NLA_NESTED },
60
+ [TCA_TUNNEL_KEY_ENC_OPTS_VXLAN ] = { .type = NLA_NESTED },
57
61
};
58
62
59
63
static const struct nla_policy
@@ -64,6 +68,11 @@ geneve_opt_policy[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX + 1] = {
64
68
.len = 128 },
65
69
};
66
70
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
+
67
76
static int
68
77
tunnel_key_copy_geneve_opt (const struct nlattr * nla , void * dst , int dst_len ,
69
78
struct netlink_ext_ack * extack )
@@ -116,10 +125,36 @@ tunnel_key_copy_geneve_opt(const struct nlattr *nla, void *dst, int dst_len,
116
125
return opt_len ;
117
126
}
118
127
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
+
119
154
static int tunnel_key_copy_opts (const struct nlattr * nla , u8 * dst ,
120
155
int dst_len , struct netlink_ext_ack * extack )
121
156
{
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 ;
123
158
const struct nlattr * attr , * head = nla_data (nla );
124
159
125
160
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,
130
165
nla_for_each_attr (attr , head , len , rem ) {
131
166
switch (nla_type (attr )) {
132
167
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
+ }
133
172
opt_len = tunnel_key_copy_geneve_opt (attr , dst ,
134
173
dst_len , extack );
135
174
if (opt_len < 0 )
@@ -139,6 +178,19 @@ static int tunnel_key_copy_opts(const struct nlattr *nla, u8 *dst,
139
178
dst_len -= opt_len ;
140
179
dst += opt_len ;
141
180
}
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 ;
142
194
break ;
143
195
}
144
196
}
@@ -174,6 +226,14 @@ static int tunnel_key_opts_set(struct nlattr *nla, struct ip_tunnel_info *info,
174
226
opts_len , extack );
175
227
#else
176
228
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 ;
177
237
#endif
178
238
default :
179
239
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,
451
511
return 0 ;
452
512
}
453
513
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
+
454
533
static int tunnel_key_opts_dump (struct sk_buff * skb ,
455
534
const struct ip_tunnel_info * info )
456
535
{
@@ -468,6 +547,10 @@ static int tunnel_key_opts_dump(struct sk_buff *skb,
468
547
err = tunnel_key_geneve_opts_dump (skb , info );
469
548
if (err )
470
549
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 ;
471
554
} else {
472
555
err_out :
473
556
nla_nest_cancel (skb , start );
0 commit comments