22
22
#include <net/ip.h>
23
23
#include <net/flow_dissector.h>
24
24
#include <net/geneve.h>
25
+ #include <net/vxlan.h>
25
26
26
27
#include <net/dst.h>
27
28
#include <net/dst_metadata.h>
@@ -688,7 +689,10 @@ static const struct nla_policy fl_policy[TCA_FLOWER_MAX + 1] = {
688
689
689
690
static const struct nla_policy
690
691
enc_opts_policy [TCA_FLOWER_KEY_ENC_OPTS_MAX + 1 ] = {
692
+ [TCA_FLOWER_KEY_ENC_OPTS_UNSPEC ] = {
693
+ .strict_start_type = TCA_FLOWER_KEY_ENC_OPTS_VXLAN },
691
694
[TCA_FLOWER_KEY_ENC_OPTS_GENEVE ] = { .type = NLA_NESTED },
695
+ [TCA_FLOWER_KEY_ENC_OPTS_VXLAN ] = { .type = NLA_NESTED },
692
696
};
693
697
694
698
static const struct nla_policy
@@ -699,6 +703,11 @@ geneve_opt_policy[TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX + 1] = {
699
703
.len = 128 },
700
704
};
701
705
706
+ static const struct nla_policy
707
+ vxlan_opt_policy [TCA_FLOWER_KEY_ENC_OPT_VXLAN_MAX + 1 ] = {
708
+ [TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP ] = { .type = NLA_U32 },
709
+ };
710
+
702
711
static void fl_set_key_val (struct nlattr * * tb ,
703
712
void * val , int val_type ,
704
713
void * mask , int mask_type , int len )
@@ -928,6 +937,41 @@ static int fl_set_geneve_opt(const struct nlattr *nla, struct fl_flow_key *key,
928
937
return sizeof (struct geneve_opt ) + data_len ;
929
938
}
930
939
940
+ static int fl_set_vxlan_opt (const struct nlattr * nla , struct fl_flow_key * key ,
941
+ int depth , int option_len ,
942
+ struct netlink_ext_ack * extack )
943
+ {
944
+ struct nlattr * tb [TCA_FLOWER_KEY_ENC_OPT_VXLAN_MAX + 1 ];
945
+ struct vxlan_metadata * md ;
946
+ int err ;
947
+
948
+ md = (struct vxlan_metadata * )& key -> enc_opts .data [key -> enc_opts .len ];
949
+ memset (md , 0xff , sizeof (* md ));
950
+
951
+ if (!depth )
952
+ return sizeof (* md );
953
+
954
+ if (nla_type (nla ) != TCA_FLOWER_KEY_ENC_OPTS_VXLAN ) {
955
+ NL_SET_ERR_MSG (extack , "Non-vxlan option type for mask" );
956
+ return - EINVAL ;
957
+ }
958
+
959
+ err = nla_parse_nested (tb , TCA_FLOWER_KEY_ENC_OPT_VXLAN_MAX , nla ,
960
+ vxlan_opt_policy , extack );
961
+ if (err < 0 )
962
+ return err ;
963
+
964
+ if (!option_len && !tb [TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP ]) {
965
+ NL_SET_ERR_MSG (extack , "Missing tunnel key vxlan option gbp" );
966
+ return - EINVAL ;
967
+ }
968
+
969
+ if (tb [TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP ])
970
+ md -> gbp = nla_get_u32 (tb [TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP ]);
971
+
972
+ return sizeof (* md );
973
+ }
974
+
931
975
static int fl_set_enc_opt (struct nlattr * * tb , struct fl_flow_key * key ,
932
976
struct fl_flow_key * mask ,
933
977
struct netlink_ext_ack * extack )
@@ -958,6 +1002,11 @@ static int fl_set_enc_opt(struct nlattr **tb, struct fl_flow_key *key,
958
1002
nla_len (tb [TCA_FLOWER_KEY_ENC_OPTS ]), key_depth ) {
959
1003
switch (nla_type (nla_opt_key )) {
960
1004
case TCA_FLOWER_KEY_ENC_OPTS_GENEVE :
1005
+ if (key -> enc_opts .dst_opt_type &&
1006
+ key -> enc_opts .dst_opt_type != TUNNEL_GENEVE_OPT ) {
1007
+ NL_SET_ERR_MSG (extack , "Duplicate type for geneve options" );
1008
+ return - EINVAL ;
1009
+ }
961
1010
option_len = 0 ;
962
1011
key -> enc_opts .dst_opt_type = TUNNEL_GENEVE_OPT ;
963
1012
option_len = fl_set_geneve_opt (nla_opt_key , key ,
@@ -983,6 +1032,39 @@ static int fl_set_enc_opt(struct nlattr **tb, struct fl_flow_key *key,
983
1032
return - EINVAL ;
984
1033
}
985
1034
1035
+ if (msk_depth )
1036
+ nla_opt_msk = nla_next (nla_opt_msk , & msk_depth );
1037
+ break ;
1038
+ case TCA_FLOWER_KEY_ENC_OPTS_VXLAN :
1039
+ if (key -> enc_opts .dst_opt_type ) {
1040
+ NL_SET_ERR_MSG (extack , "Duplicate type for vxlan options" );
1041
+ return - EINVAL ;
1042
+ }
1043
+ option_len = 0 ;
1044
+ key -> enc_opts .dst_opt_type = TUNNEL_VXLAN_OPT ;
1045
+ option_len = fl_set_vxlan_opt (nla_opt_key , key ,
1046
+ key_depth , option_len ,
1047
+ extack );
1048
+ if (option_len < 0 )
1049
+ return option_len ;
1050
+
1051
+ key -> enc_opts .len += option_len ;
1052
+ /* At the same time we need to parse through the mask
1053
+ * in order to verify exact and mask attribute lengths.
1054
+ */
1055
+ mask -> enc_opts .dst_opt_type = TUNNEL_VXLAN_OPT ;
1056
+ option_len = fl_set_vxlan_opt (nla_opt_msk , mask ,
1057
+ msk_depth , option_len ,
1058
+ extack );
1059
+ if (option_len < 0 )
1060
+ return option_len ;
1061
+
1062
+ mask -> enc_opts .len += option_len ;
1063
+ if (key -> enc_opts .len != mask -> enc_opts .len ) {
1064
+ NL_SET_ERR_MSG (extack , "Key and mask miss aligned" );
1065
+ return - EINVAL ;
1066
+ }
1067
+
986
1068
if (msk_depth )
987
1069
nla_opt_msk = nla_next (nla_opt_msk , & msk_depth );
988
1070
break ;
@@ -2135,6 +2217,28 @@ static int fl_dump_key_geneve_opt(struct sk_buff *skb,
2135
2217
return - EMSGSIZE ;
2136
2218
}
2137
2219
2220
+ static int fl_dump_key_vxlan_opt (struct sk_buff * skb ,
2221
+ struct flow_dissector_key_enc_opts * enc_opts )
2222
+ {
2223
+ struct vxlan_metadata * md ;
2224
+ struct nlattr * nest ;
2225
+
2226
+ nest = nla_nest_start_noflag (skb , TCA_FLOWER_KEY_ENC_OPTS_VXLAN );
2227
+ if (!nest )
2228
+ goto nla_put_failure ;
2229
+
2230
+ md = (struct vxlan_metadata * )& enc_opts -> data [0 ];
2231
+ if (nla_put_u32 (skb , TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP , md -> gbp ))
2232
+ goto nla_put_failure ;
2233
+
2234
+ nla_nest_end (skb , nest );
2235
+ return 0 ;
2236
+
2237
+ nla_put_failure :
2238
+ nla_nest_cancel (skb , nest );
2239
+ return - EMSGSIZE ;
2240
+ }
2241
+
2138
2242
static int fl_dump_key_ct (struct sk_buff * skb ,
2139
2243
struct flow_dissector_key_ct * key ,
2140
2244
struct flow_dissector_key_ct * mask )
@@ -2188,6 +2292,11 @@ static int fl_dump_key_options(struct sk_buff *skb, int enc_opt_type,
2188
2292
if (err )
2189
2293
goto nla_put_failure ;
2190
2294
break ;
2295
+ case TUNNEL_VXLAN_OPT :
2296
+ err = fl_dump_key_vxlan_opt (skb , enc_opts );
2297
+ if (err )
2298
+ goto nla_put_failure ;
2299
+ break ;
2191
2300
default :
2192
2301
goto nla_put_failure ;
2193
2302
}
0 commit comments