cls_flower.c (d8f9dfae49ce4ffb772dc10dd6578dc815b34c12) | cls_flower.c (79b1011cb33d166f531a1347a17e6602954e4eb1) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * net/sched/cls_flower.c Flower classifier 4 * 5 * Copyright (c) 2015 Jiri Pirko <jiri@resnulli.us> 6 */ 7 8#include <linux/kernel.h> --- 9 unchanged lines hidden (view full) --- 18#include <linux/mpls.h> 19 20#include <net/sch_generic.h> 21#include <net/pkt_cls.h> 22#include <net/ip.h> 23#include <net/flow_dissector.h> 24#include <net/geneve.h> 25#include <net/vxlan.h> | 1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * net/sched/cls_flower.c Flower classifier 4 * 5 * Copyright (c) 2015 Jiri Pirko <jiri@resnulli.us> 6 */ 7 8#include <linux/kernel.h> --- 9 unchanged lines hidden (view full) --- 18#include <linux/mpls.h> 19 20#include <net/sch_generic.h> 21#include <net/pkt_cls.h> 22#include <net/ip.h> 23#include <net/flow_dissector.h> 24#include <net/geneve.h> 25#include <net/vxlan.h> |
26#include <net/erspan.h> |
|
26 27#include <net/dst.h> 28#include <net/dst_metadata.h> 29 30#include <uapi/linux/netfilter/nf_conntrack_common.h> 31 32struct fl_flow_key { 33 struct flow_dissector_key_meta meta; --- 654 unchanged lines hidden (view full) --- 688}; 689 690static const struct nla_policy 691enc_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 }, 694 [TCA_FLOWER_KEY_ENC_OPTS_GENEVE] = { .type = NLA_NESTED }, 695 [TCA_FLOWER_KEY_ENC_OPTS_VXLAN] = { .type = NLA_NESTED }, | 27 28#include <net/dst.h> 29#include <net/dst_metadata.h> 30 31#include <uapi/linux/netfilter/nf_conntrack_common.h> 32 33struct fl_flow_key { 34 struct flow_dissector_key_meta meta; --- 654 unchanged lines hidden (view full) --- 689}; 690 691static const struct nla_policy 692enc_opts_policy[TCA_FLOWER_KEY_ENC_OPTS_MAX + 1] = { 693 [TCA_FLOWER_KEY_ENC_OPTS_UNSPEC] = { 694 .strict_start_type = TCA_FLOWER_KEY_ENC_OPTS_VXLAN }, 695 [TCA_FLOWER_KEY_ENC_OPTS_GENEVE] = { .type = NLA_NESTED }, 696 [TCA_FLOWER_KEY_ENC_OPTS_VXLAN] = { .type = NLA_NESTED }, |
697 [TCA_FLOWER_KEY_ENC_OPTS_ERSPAN] = { .type = NLA_NESTED }, |
|
696}; 697 698static const struct nla_policy 699geneve_opt_policy[TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX + 1] = { 700 [TCA_FLOWER_KEY_ENC_OPT_GENEVE_CLASS] = { .type = NLA_U16 }, 701 [TCA_FLOWER_KEY_ENC_OPT_GENEVE_TYPE] = { .type = NLA_U8 }, 702 [TCA_FLOWER_KEY_ENC_OPT_GENEVE_DATA] = { .type = NLA_BINARY, 703 .len = 128 }, 704}; 705 706static const struct nla_policy 707vxlan_opt_policy[TCA_FLOWER_KEY_ENC_OPT_VXLAN_MAX + 1] = { 708 [TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP] = { .type = NLA_U32 }, 709}; 710 | 698}; 699 700static const struct nla_policy 701geneve_opt_policy[TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX + 1] = { 702 [TCA_FLOWER_KEY_ENC_OPT_GENEVE_CLASS] = { .type = NLA_U16 }, 703 [TCA_FLOWER_KEY_ENC_OPT_GENEVE_TYPE] = { .type = NLA_U8 }, 704 [TCA_FLOWER_KEY_ENC_OPT_GENEVE_DATA] = { .type = NLA_BINARY, 705 .len = 128 }, 706}; 707 708static const struct nla_policy 709vxlan_opt_policy[TCA_FLOWER_KEY_ENC_OPT_VXLAN_MAX + 1] = { 710 [TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP] = { .type = NLA_U32 }, 711}; 712 |
713static const struct nla_policy 714erspan_opt_policy[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_MAX + 1] = { 715 [TCA_FLOWER_KEY_ENC_OPT_ERSPAN_VER] = { .type = NLA_U8 }, 716 [TCA_FLOWER_KEY_ENC_OPT_ERSPAN_INDEX] = { .type = NLA_U32 }, 717 [TCA_FLOWER_KEY_ENC_OPT_ERSPAN_DIR] = { .type = NLA_U8 }, 718 [TCA_FLOWER_KEY_ENC_OPT_ERSPAN_HWID] = { .type = NLA_U8 }, 719}; 720 |
|
711static void fl_set_key_val(struct nlattr **tb, 712 void *val, int val_type, 713 void *mask, int mask_type, int len) 714{ 715 if (!tb[val_type]) 716 return; 717 nla_memcpy(val, tb[val_type], len); 718 if (mask_type == TCA_FLOWER_UNSPEC || !tb[mask_type]) --- 248 unchanged lines hidden (view full) --- 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 | 721static void fl_set_key_val(struct nlattr **tb, 722 void *val, int val_type, 723 void *mask, int mask_type, int len) 724{ 725 if (!tb[val_type]) 726 return; 727 nla_memcpy(val, tb[val_type], len); 728 if (mask_type == TCA_FLOWER_UNSPEC || !tb[mask_type]) --- 248 unchanged lines hidden (view full) --- 977 } 978 979 if (tb[TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP]) 980 md->gbp = nla_get_u32(tb[TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP]); 981 982 return sizeof(*md); 983} 984 |
985static int fl_set_erspan_opt(const struct nlattr *nla, struct fl_flow_key *key, 986 int depth, int option_len, 987 struct netlink_ext_ack *extack) 988{ 989 struct nlattr *tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_MAX + 1]; 990 struct erspan_metadata *md; 991 int err; 992 993 md = (struct erspan_metadata *)&key->enc_opts.data[key->enc_opts.len]; 994 memset(md, 0xff, sizeof(*md)); 995 md->version = 1; 996 997 if (!depth) 998 return sizeof(*md); 999 1000 if (nla_type(nla) != TCA_FLOWER_KEY_ENC_OPTS_ERSPAN) { 1001 NL_SET_ERR_MSG(extack, "Non-erspan option type for mask"); 1002 return -EINVAL; 1003 } 1004 1005 err = nla_parse_nested(tb, TCA_FLOWER_KEY_ENC_OPT_ERSPAN_MAX, nla, 1006 erspan_opt_policy, extack); 1007 if (err < 0) 1008 return err; 1009 1010 if (!option_len && !tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_VER]) { 1011 NL_SET_ERR_MSG(extack, "Missing tunnel key erspan option ver"); 1012 return -EINVAL; 1013 } 1014 1015 if (tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_VER]) 1016 md->version = nla_get_u8(tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_VER]); 1017 1018 if (md->version == 1) { 1019 if (!option_len && !tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_INDEX]) { 1020 NL_SET_ERR_MSG(extack, "Missing tunnel key erspan option index"); 1021 return -EINVAL; 1022 } 1023 if (tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_INDEX]) { 1024 nla = tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_INDEX]; 1025 md->u.index = nla_get_be32(nla); 1026 } 1027 } else if (md->version == 2) { 1028 if (!option_len && (!tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_DIR] || 1029 !tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_HWID])) { 1030 NL_SET_ERR_MSG(extack, "Missing tunnel key erspan option dir or hwid"); 1031 return -EINVAL; 1032 } 1033 if (tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_DIR]) { 1034 nla = tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_DIR]; 1035 md->u.md2.dir = nla_get_u8(nla); 1036 } 1037 if (tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_HWID]) { 1038 nla = tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_HWID]; 1039 set_hwid(&md->u.md2, nla_get_u8(nla)); 1040 } 1041 } else { 1042 NL_SET_ERR_MSG(extack, "Tunnel key erspan option ver is incorrect"); 1043 return -EINVAL; 1044 } 1045 1046 return sizeof(*md); 1047} 1048 |
|
975static int fl_set_enc_opt(struct nlattr **tb, struct fl_flow_key *key, 976 struct fl_flow_key *mask, 977 struct netlink_ext_ack *extack) 978{ 979 const struct nlattr *nla_enc_key, *nla_opt_key, *nla_opt_msk = NULL; 980 int err, option_len, key_depth, msk_depth = 0; 981 982 err = nla_validate_nested_deprecated(tb[TCA_FLOWER_KEY_ENC_OPTS], --- 80 unchanged lines hidden (view full) --- 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 1068 if (msk_depth) 1069 nla_opt_msk = nla_next(nla_opt_msk, &msk_depth); 1070 break; | 1049static int fl_set_enc_opt(struct nlattr **tb, struct fl_flow_key *key, 1050 struct fl_flow_key *mask, 1051 struct netlink_ext_ack *extack) 1052{ 1053 const struct nlattr *nla_enc_key, *nla_opt_key, *nla_opt_msk = NULL; 1054 int err, option_len, key_depth, msk_depth = 0; 1055 1056 err = nla_validate_nested_deprecated(tb[TCA_FLOWER_KEY_ENC_OPTS], --- 80 unchanged lines hidden (view full) --- 1137 if (key->enc_opts.len != mask->enc_opts.len) { 1138 NL_SET_ERR_MSG(extack, "Key and mask miss aligned"); 1139 return -EINVAL; 1140 } 1141 1142 if (msk_depth) 1143 nla_opt_msk = nla_next(nla_opt_msk, &msk_depth); 1144 break; |
1145 case TCA_FLOWER_KEY_ENC_OPTS_ERSPAN: 1146 if (key->enc_opts.dst_opt_type) { 1147 NL_SET_ERR_MSG(extack, "Duplicate type for erspan options"); 1148 return -EINVAL; 1149 } 1150 option_len = 0; 1151 key->enc_opts.dst_opt_type = TUNNEL_ERSPAN_OPT; 1152 option_len = fl_set_erspan_opt(nla_opt_key, key, 1153 key_depth, option_len, 1154 extack); 1155 if (option_len < 0) 1156 return option_len; 1157 1158 key->enc_opts.len += option_len; 1159 /* At the same time we need to parse through the mask 1160 * in order to verify exact and mask attribute lengths. 1161 */ 1162 mask->enc_opts.dst_opt_type = TUNNEL_ERSPAN_OPT; 1163 option_len = fl_set_erspan_opt(nla_opt_msk, mask, 1164 msk_depth, option_len, 1165 extack); 1166 if (option_len < 0) 1167 return option_len; 1168 1169 mask->enc_opts.len += option_len; 1170 if (key->enc_opts.len != mask->enc_opts.len) { 1171 NL_SET_ERR_MSG(extack, "Key and mask miss aligned"); 1172 return -EINVAL; 1173 } 1174 1175 if (msk_depth) 1176 nla_opt_msk = nla_next(nla_opt_msk, &msk_depth); 1177 break; |
|
1071 default: 1072 NL_SET_ERR_MSG(extack, "Unknown tunnel option type"); 1073 return -EINVAL; 1074 } 1075 } 1076 1077 return 0; 1078} --- 1155 unchanged lines hidden (view full) --- 2234 nla_nest_end(skb, nest); 2235 return 0; 2236 2237nla_put_failure: 2238 nla_nest_cancel(skb, nest); 2239 return -EMSGSIZE; 2240} 2241 | 1178 default: 1179 NL_SET_ERR_MSG(extack, "Unknown tunnel option type"); 1180 return -EINVAL; 1181 } 1182 } 1183 1184 return 0; 1185} --- 1155 unchanged lines hidden (view full) --- 2341 nla_nest_end(skb, nest); 2342 return 0; 2343 2344nla_put_failure: 2345 nla_nest_cancel(skb, nest); 2346 return -EMSGSIZE; 2347} 2348 |
2349static int fl_dump_key_erspan_opt(struct sk_buff *skb, 2350 struct flow_dissector_key_enc_opts *enc_opts) 2351{ 2352 struct erspan_metadata *md; 2353 struct nlattr *nest; 2354 2355 nest = nla_nest_start_noflag(skb, TCA_FLOWER_KEY_ENC_OPTS_ERSPAN); 2356 if (!nest) 2357 goto nla_put_failure; 2358 2359 md = (struct erspan_metadata *)&enc_opts->data[0]; 2360 if (nla_put_u8(skb, TCA_FLOWER_KEY_ENC_OPT_ERSPAN_VER, md->version)) 2361 goto nla_put_failure; 2362 2363 if (md->version == 1 && 2364 nla_put_be32(skb, TCA_FLOWER_KEY_ENC_OPT_ERSPAN_INDEX, md->u.index)) 2365 goto nla_put_failure; 2366 2367 if (md->version == 2 && 2368 (nla_put_u8(skb, TCA_FLOWER_KEY_ENC_OPT_ERSPAN_DIR, 2369 md->u.md2.dir) || 2370 nla_put_u8(skb, TCA_FLOWER_KEY_ENC_OPT_ERSPAN_HWID, 2371 get_hwid(&md->u.md2)))) 2372 goto nla_put_failure; 2373 2374 nla_nest_end(skb, nest); 2375 return 0; 2376 2377nla_put_failure: 2378 nla_nest_cancel(skb, nest); 2379 return -EMSGSIZE; 2380} 2381 |
|
2242static int fl_dump_key_ct(struct sk_buff *skb, 2243 struct flow_dissector_key_ct *key, 2244 struct flow_dissector_key_ct *mask) 2245{ 2246 if (IS_ENABLED(CONFIG_NF_CONNTRACK) && 2247 fl_dump_key_val(skb, &key->ct_state, TCA_FLOWER_KEY_CT_STATE, 2248 &mask->ct_state, TCA_FLOWER_KEY_CT_STATE_MASK, 2249 sizeof(key->ct_state))) --- 42 unchanged lines hidden (view full) --- 2292 if (err) 2293 goto nla_put_failure; 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; | 2382static int fl_dump_key_ct(struct sk_buff *skb, 2383 struct flow_dissector_key_ct *key, 2384 struct flow_dissector_key_ct *mask) 2385{ 2386 if (IS_ENABLED(CONFIG_NF_CONNTRACK) && 2387 fl_dump_key_val(skb, &key->ct_state, TCA_FLOWER_KEY_CT_STATE, 2388 &mask->ct_state, TCA_FLOWER_KEY_CT_STATE_MASK, 2389 sizeof(key->ct_state))) --- 42 unchanged lines hidden (view full) --- 2432 if (err) 2433 goto nla_put_failure; 2434 break; 2435 case TUNNEL_VXLAN_OPT: 2436 err = fl_dump_key_vxlan_opt(skb, enc_opts); 2437 if (err) 2438 goto nla_put_failure; 2439 break; |
2440 case TUNNEL_ERSPAN_OPT: 2441 err = fl_dump_key_erspan_opt(skb, enc_opts); 2442 if (err) 2443 goto nla_put_failure; 2444 break; |
|
2300 default: 2301 goto nla_put_failure; 2302 } 2303 nla_nest_end(skb, nest); 2304 return 0; 2305 2306nla_put_failure: 2307 nla_nest_cancel(skb, nest); --- 347 unchanged lines hidden --- | 2445 default: 2446 goto nla_put_failure; 2447 } 2448 nla_nest_end(skb, nest); 2449 return 0; 2450 2451nla_put_failure: 2452 nla_nest_cancel(skb, nest); --- 347 unchanged lines hidden --- |