1
2
3
4
5
6
7
8#include <stdio.h>
9#include <stdlib.h>
10#include <unistd.h>
11#include <string.h>
12#include <net/if.h>
13
14#include <linux/if_arp.h>
15#include <linux/if_ether.h>
16#include <linux/ip.h>
17#include <linux/tc_act/tc_vlan.h>
18#include <linux/mpls.h>
19#include <linux/ppp_defs.h>
20
21#include "utils.h"
22#include "tc_util.h"
23#include "rt_names.h"
24
25
26#define FLOWER_OPTS_MAX 4096
27
28#ifndef IPPROTO_L2TP
29#define IPPROTO_L2TP 115
30#endif
31
32enum flower_matching_flags {
33 FLOWER_IP_FLAGS,
34 FLOWER_ENC_DST_FLAGS,
35};
36
37enum flower_endpoint {
38 FLOWER_ENDPOINT_SRC,
39 FLOWER_ENDPOINT_DST
40};
41
42enum flower_icmp_field {
43 FLOWER_ICMP_FIELD_TYPE,
44 FLOWER_ICMP_FIELD_CODE
45};
46
47static void explain(void)
48{
49 fprintf(stderr,
50 "Usage: ... flower [ MATCH-LIST ] [ verbose ]\n"
51 " [ skip_sw | skip_hw ]\n"
52 " [ action ACTION-SPEC ] [ classid CLASSID ]\n"
53 "\n"
54 "Where: MATCH-LIST := [ MATCH-LIST ] MATCH\n"
55 " MATCH := { indev DEV-NAME |\n"
56 " num_of_vlans VLANS_COUNT |\n"
57 " vlan_id VID |\n"
58 " vlan_prio PRIORITY |\n"
59 " vlan_ethtype [ ipv4 | ipv6 | ETH-TYPE ] |\n"
60 " cvlan_id VID |\n"
61 " cvlan_prio PRIORITY |\n"
62 " cvlan_ethtype [ ipv4 | ipv6 | ETH-TYPE ] |\n"
63 " pppoe_sid PSID |\n"
64 " ppp_proto [ ipv4 | ipv6 | mpls_uc | mpls_mc | PPP_PROTO ] |\n"
65 " dst_mac MASKED-LLADDR |\n"
66 " src_mac MASKED-LLADDR |\n"
67 " ip_proto [tcp | udp | sctp | icmp | icmpv6 | l2tp | esp | ah | IP-PROTO ] |\n"
68 " ip_tos MASKED-IP_TOS |\n"
69 " ip_ttl MASKED-IP_TTL |\n"
70 " mpls LSE-LIST |\n"
71 " mpls_label LABEL |\n"
72 " mpls_tc TC |\n"
73 " mpls_bos BOS |\n"
74 " mpls_ttl TTL |\n"
75 " spi SPI-INDEX |\n"
76 " l2tpv3_sid LSID |\n"
77 " dst_ip PREFIX |\n"
78 " src_ip PREFIX |\n"
79 " dst_port PORT-NUMBER |\n"
80 " src_port PORT-NUMBER |\n"
81 " tcp_flags MASKED-TCP_FLAGS |\n"
82 " type MASKED-ICMP-TYPE |\n"
83 " code MASKED-ICMP-CODE |\n"
84 " arp_tip IPV4-PREFIX |\n"
85 " arp_sip IPV4-PREFIX |\n"
86 " arp_op [ request | reply | OP ] |\n"
87 " arp_tha MASKED-LLADDR |\n"
88 " arp_sha MASKED-LLADDR |\n"
89 " enc_dst_ip [ IPV4-ADDR | IPV6-ADDR ] |\n"
90 " enc_src_ip [ IPV4-ADDR | IPV6-ADDR ] |\n"
91 " enc_key_id [ KEY-ID ] |\n"
92 " enc_tos MASKED-IP_TOS |\n"
93 " enc_ttl MASKED-IP_TTL |\n"
94 " geneve_opts MASKED-OPTIONS |\n"
95 " vxlan_opts MASKED-OPTIONS |\n"
96 " erspan_opts MASKED-OPTIONS |\n"
97 " gtp_opts MASKED-OPTIONS |\n"
98 " pfcp_opts MASKED-OPTIONS |\n"
99 " ip_flags IP-FLAGS |\n"
100 " l2_miss L2_MISS |\n"
101 " enc_dst_port [ port_number ] |\n"
102 " ct_state MASKED_CT_STATE |\n"
103 " ct_label MASKED_CT_LABEL |\n"
104 " ct_mark MASKED_CT_MARK |\n"
105 " ct_zone MASKED_CT_ZONE |\n"
106 " cfm CFM |\n"
107 " enc_flags ENCFLAG-LIST }\n"
108 " LSE-LIST := [ LSE-LIST ] LSE\n"
109 " LSE := lse depth DEPTH { label LABEL | tc TC | bos BOS | ttl TTL }\n"
110 " FILTERID := X:Y:Z\n"
111 " MASKED_LLADDR := { LLADDR | LLADDR/MASK | LLADDR/BITS }\n"
112 " MASKED_CT_STATE := combination of {+|-} and flags trk,est,new,rel,rpl,inv\n"
113 " CFM := { mdl LEVEL | op OPCODE }\n"
114 " ENCFLAG-LIST := [ ENCFLAG-LIST/ ]ENCFLAG\n"
115 " ENCFLAG := { [no]tuncsum | [no]tundf | [no]tunoam | [no]tuncrit }\n"
116 " ACTION-SPEC := ... look at individual actions\n"
117 "\n"
118 "NOTE: CLASSID, IP-PROTO are parsed as hexadecimal input.\n"
119 "NOTE: There can be only used one mask per one prio. If user needs\n"
120 " to specify different mask, he has to use different prio.\n");
121}
122
123
124static void print_indent_name_value(const char *name, const char *value)
125{
126 print_string(PRINT_FP, NULL, "%s ", _SL_);
127 print_string_name_value(name, value);
128}
129
130static void print_uint_indent_name_value(const char *name, unsigned int value)
131{
132 print_string(PRINT_FP, NULL, " ", NULL);
133 print_uint_name_value(name, value);
134}
135
136static int flower_parse_eth_addr(char *str, int addr_type, int mask_type,
137 struct nlmsghdr *n)
138{
139 int ret, err = -1;
140 char addr[ETH_ALEN], *slash;
141
142 slash = strchr(str, '/');
143 if (slash)
144 *slash = '\0';
145
146 ret = ll_addr_a2n(addr, sizeof(addr), str);
147 if (ret < 0)
148 goto err;
149 addattr_l(n, MAX_MSG, addr_type, addr, sizeof(addr));
150
151 if (slash) {
152 unsigned int bits;
153
154 if (!get_unsigned(&bits, slash + 1, 10)) {
155 uint64_t mask;
156
157
158
159
160 mask = htonll(0xffffffffffffULL << (16 + 48 - bits));
161 memcpy(addr, &mask, ETH_ALEN);
162 } else {
163 ret = ll_addr_a2n(addr, sizeof(addr), slash + 1);
164 if (ret < 0)
165 goto err;
166 }
167 } else {
168 memset(addr, 0xff, ETH_ALEN);
169 }
170 addattr_l(n, MAX_MSG, mask_type, addr, sizeof(addr));
171
172 err = 0;
173err:
174 if (slash)
175 *slash = '/';
176 return err;
177}
178
179static bool eth_type_vlan(__be16 ethertype, bool good_num_of_vlans)
180{
181 return ethertype == htons(ETH_P_8021Q) ||
182 ethertype == htons(ETH_P_8021AD) ||
183 good_num_of_vlans;
184}
185
186static int flower_parse_vlan_eth_type(char *str, __be16 eth_type, int type,
187 __be16 *p_vlan_eth_type,
188 struct nlmsghdr *n, bool good_num_of_vlans)
189{
190 __be16 vlan_eth_type;
191
192 if (!eth_type_vlan(eth_type, good_num_of_vlans)) {
193 fprintf(stderr, "Can't set \"%s\" if ethertype isn't 802.1Q or 802.1AD and num_of_vlans %s\n",
194 type == TCA_FLOWER_KEY_VLAN_ETH_TYPE ? "vlan_ethtype" : "cvlan_ethtype",
195 type == TCA_FLOWER_KEY_VLAN_ETH_TYPE ? "is 0" : "less than 2");
196 return -1;
197 }
198
199 if (ll_proto_a2n(&vlan_eth_type, str))
200 invarg("invalid vlan_ethtype", str);
201 addattr16(n, MAX_MSG, type, vlan_eth_type);
202 *p_vlan_eth_type = vlan_eth_type;
203 return 0;
204}
205
206struct flag_to_string {
207 int flag;
208 enum flower_matching_flags type;
209 char *string;
210};
211
212static struct flag_to_string flags_str[] = {
213 { TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT, FLOWER_IP_FLAGS, "frag" },
214 { TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST, FLOWER_IP_FLAGS, "firstfrag" },
215 { TCA_FLOWER_KEY_FLAGS_TUNNEL_CSUM, FLOWER_ENC_DST_FLAGS, "tuncsum" },
216 { TCA_FLOWER_KEY_FLAGS_TUNNEL_DONT_FRAGMENT, FLOWER_ENC_DST_FLAGS, "tundf" },
217 { TCA_FLOWER_KEY_FLAGS_TUNNEL_OAM, FLOWER_ENC_DST_FLAGS, "tunoam" },
218 { TCA_FLOWER_KEY_FLAGS_TUNNEL_CRIT_OPT, FLOWER_ENC_DST_FLAGS, "tuncrit" },
219};
220
221static int flower_parse_matching_flags(char *str,
222 enum flower_matching_flags type,
223 __u32 *mtf, __u32 *mtf_mask)
224{
225 char *token;
226 bool no;
227 bool found;
228 int i;
229
230 token = strtok(str, "/");
231
232 while (token) {
233 if (!strncmp(token, "no", 2)) {
234 no = true;
235 token += 2;
236 } else
237 no = false;
238
239 found = false;
240 for (i = 0; i < ARRAY_SIZE(flags_str); i++) {
241 if (type != flags_str[i].type)
242 continue;
243
244 if (!strcmp(token, flags_str[i].string)) {
245 if (no)
246 *mtf &= ~flags_str[i].flag;
247 else
248 *mtf |= flags_str[i].flag;
249
250 *mtf_mask |= flags_str[i].flag;
251 found = true;
252 break;
253 }
254 }
255 if (!found)
256 return -1;
257
258 token = strtok(NULL, "/");
259 }
260
261 return 0;
262}
263
264static int flower_parse_u16(char *str, int value_type, int mask_type,
265 struct nlmsghdr *n, bool be)
266{
267 __u16 value, mask;
268 char *slash;
269
270 slash = strchr(str, '/');
271 if (slash)
272 *slash = '\0';
273
274 if (get_u16(&value, str, 0))
275 return -1;
276
277 if (slash) {
278 if (get_u16(&mask, slash + 1, 0))
279 return -1;
280 } else {
281 mask = UINT16_MAX;
282 }
283
284 if (be) {
285 value = htons(value);
286 mask = htons(mask);
287 }
288 addattr16(n, MAX_MSG, value_type, value);
289 addattr16(n, MAX_MSG, mask_type, mask);
290
291 return 0;
292}
293
294static int flower_parse_u32(char *str, int value_type, int mask_type,
295 struct nlmsghdr *n)
296{
297 __u32 value, mask;
298 char *slash;
299
300 slash = strchr(str, '/');
301 if (slash)
302 *slash = '\0';
303
304 if (get_u32(&value, str, 0))
305 return -1;
306
307 if (slash) {
308 if (get_u32(&mask, slash + 1, 0))
309 return -1;
310 } else {
311 mask = UINT32_MAX;
312 }
313
314 addattr32(n, MAX_MSG, value_type, value);
315 addattr32(n, MAX_MSG, mask_type, mask);
316
317 return 0;
318}
319
320static int flower_parse_ct_mark(char *str, struct nlmsghdr *n)
321{
322 return flower_parse_u32(str,
323 TCA_FLOWER_KEY_CT_MARK,
324 TCA_FLOWER_KEY_CT_MARK_MASK,
325 n);
326}
327
328static int flower_parse_ct_zone(char *str, struct nlmsghdr *n)
329{
330 return flower_parse_u16(str,
331 TCA_FLOWER_KEY_CT_ZONE,
332 TCA_FLOWER_KEY_CT_ZONE_MASK,
333 n,
334 false);
335}
336
337static int flower_parse_ct_labels(char *str, struct nlmsghdr *n)
338{
339#define LABELS_SIZE 16
340 uint8_t labels[LABELS_SIZE], lmask[LABELS_SIZE];
341 char *slash, *mask = NULL;
342 size_t slen, slen_mask = 0;
343
344 slash = index(str, '/');
345 if (slash) {
346 *slash = 0;
347 mask = slash + 1;
348 slen_mask = strlen(mask);
349 }
350
351 slen = strlen(str);
352 if (slen > LABELS_SIZE * 2 || slen_mask > LABELS_SIZE * 2) {
353 char errmsg[128];
354
355 snprintf(errmsg, sizeof(errmsg),
356 "%zd Max allowed size %d",
357 slen, LABELS_SIZE*2);
358 invarg(errmsg, str);
359 }
360
361 if (hex2mem(str, labels, slen / 2) < 0)
362 invarg("labels must be a hex string\n", str);
363 addattr_l(n, MAX_MSG, TCA_FLOWER_KEY_CT_LABELS, labels, slen / 2);
364
365 if (mask) {
366 if (hex2mem(mask, lmask, slen_mask / 2) < 0)
367 invarg("labels mask must be a hex string\n", mask);
368 } else {
369 memset(lmask, 0xff, sizeof(lmask));
370 slen_mask = sizeof(lmask) * 2;
371 }
372 addattr_l(n, MAX_MSG, TCA_FLOWER_KEY_CT_LABELS_MASK, lmask,
373 slen_mask / 2);
374
375 return 0;
376}
377
378static struct flower_ct_states {
379 char *str;
380 int flag;
381} flower_ct_states[] = {
382 { "trk", TCA_FLOWER_KEY_CT_FLAGS_TRACKED },
383 { "new", TCA_FLOWER_KEY_CT_FLAGS_NEW },
384 { "est", TCA_FLOWER_KEY_CT_FLAGS_ESTABLISHED },
385 { "rel", TCA_FLOWER_KEY_CT_FLAGS_RELATED },
386 { "inv", TCA_FLOWER_KEY_CT_FLAGS_INVALID },
387 { "rpl", TCA_FLOWER_KEY_CT_FLAGS_REPLY },
388};
389
390static int flower_parse_ct_state(char *str, struct nlmsghdr *n)
391{
392 int flags = 0, mask = 0, len, i;
393 bool p;
394
395 while (*str != '\0') {
396 if (*str == '+')
397 p = true;
398 else if (*str == '-')
399 p = false;
400 else
401 return -1;
402
403 for (i = 0; i < ARRAY_SIZE(flower_ct_states); i++) {
404 len = strlen(flower_ct_states[i].str);
405 if (strncmp(str + 1, flower_ct_states[i].str, len))
406 continue;
407
408 if (p)
409 flags |= flower_ct_states[i].flag;
410 mask |= flower_ct_states[i].flag;
411 break;
412 }
413
414 if (i == ARRAY_SIZE(flower_ct_states))
415 return -1;
416
417 str += len + 1;
418 }
419
420 addattr16(n, MAX_MSG, TCA_FLOWER_KEY_CT_STATE, flags);
421 addattr16(n, MAX_MSG, TCA_FLOWER_KEY_CT_STATE_MASK, mask);
422 return 0;
423}
424
425static int flower_parse_ip_proto(char *str, __be16 eth_type, int type,
426 __u8 *p_ip_proto, struct nlmsghdr *n)
427{
428 int ret;
429 __u8 ip_proto;
430
431 if (eth_type != htons(ETH_P_IP) && eth_type != htons(ETH_P_IPV6))
432 goto err;
433
434 if (matches(str, "tcp") == 0) {
435 ip_proto = IPPROTO_TCP;
436 } else if (matches(str, "udp") == 0) {
437 ip_proto = IPPROTO_UDP;
438 } else if (matches(str, "sctp") == 0) {
439 ip_proto = IPPROTO_SCTP;
440 } else if (matches(str, "icmp") == 0) {
441 if (eth_type != htons(ETH_P_IP))
442 goto err;
443 ip_proto = IPPROTO_ICMP;
444 } else if (matches(str, "icmpv6") == 0) {
445 if (eth_type != htons(ETH_P_IPV6))
446 goto err;
447 ip_proto = IPPROTO_ICMPV6;
448 } else if (!strcmp(str, "l2tp")) {
449 if (eth_type != htons(ETH_P_IP) &&
450 eth_type != htons(ETH_P_IPV6))
451 goto err;
452 ip_proto = IPPROTO_L2TP;
453 } else if (!strcmp(str, "esp")) {
454 if (eth_type != htons(ETH_P_IP) &&
455 eth_type != htons(ETH_P_IPV6))
456 goto err;
457 ip_proto = IPPROTO_ESP;
458 } else if (!strcmp(str, "ah")) {
459 if (eth_type != htons(ETH_P_IP) &&
460 eth_type != htons(ETH_P_IPV6))
461 goto err;
462 ip_proto = IPPROTO_AH;
463 } else {
464 ret = get_u8(&ip_proto, str, 16);
465 if (ret)
466 return -1;
467 }
468 addattr8(n, MAX_MSG, type, ip_proto);
469 *p_ip_proto = ip_proto;
470 return 0;
471
472err:
473 fprintf(stderr, "Illegal \"eth_type\" for ip proto\n");
474 return -1;
475}
476
477static int __flower_parse_ip_addr(char *str, int family,
478 int addr4_type, int mask4_type,
479 int addr6_type, int mask6_type,
480 struct nlmsghdr *n)
481{
482 int ret;
483 inet_prefix addr;
484 int bits;
485 int i;
486
487 ret = get_prefix(&addr, str, family);
488 if (ret)
489 return -1;
490
491 if (family && (addr.family != family)) {
492 fprintf(stderr, "Illegal \"eth_type\" for ip address\n");
493 return -1;
494 }
495
496 addattr_l(n, MAX_MSG, addr.family == AF_INET ? addr4_type : addr6_type,
497 addr.data, addr.bytelen);
498
499 memset(addr.data, 0xff, addr.bytelen);
500 bits = addr.bitlen;
501 for (i = 0; i < addr.bytelen / 4; i++) {
502 if (!bits) {
503 addr.data[i] = 0;
504 } else if (bits / 32 >= 1) {
505 bits -= 32;
506 } else {
507 addr.data[i] <<= 32 - bits;
508 addr.data[i] = htonl(addr.data[i]);
509 bits = 0;
510 }
511 }
512
513 addattr_l(n, MAX_MSG, addr.family == AF_INET ? mask4_type : mask6_type,
514 addr.data, addr.bytelen);
515
516 return 0;
517}
518
519static int flower_parse_ip_addr(char *str, __be16 eth_type,
520 int addr4_type, int mask4_type,
521 int addr6_type, int mask6_type,
522 struct nlmsghdr *n)
523{
524 int family;
525
526 if (eth_type == htons(ETH_P_IP)) {
527 family = AF_INET;
528 } else if (eth_type == htons(ETH_P_IPV6)) {
529 family = AF_INET6;
530 } else if (!eth_type) {
531 family = AF_UNSPEC;
532 } else {
533 return -1;
534 }
535
536 return __flower_parse_ip_addr(str, family, addr4_type, mask4_type,
537 addr6_type, mask6_type, n);
538}
539
540static bool flower_eth_type_arp(__be16 eth_type)
541{
542 return eth_type == htons(ETH_P_ARP) || eth_type == htons(ETH_P_RARP);
543}
544
545static int flower_parse_arp_ip_addr(char *str, __be16 eth_type,
546 int addr_type, int mask_type,
547 struct nlmsghdr *n)
548{
549 if (!flower_eth_type_arp(eth_type))
550 return -1;
551
552 return __flower_parse_ip_addr(str, AF_INET, addr_type, mask_type,
553 TCA_FLOWER_UNSPEC, TCA_FLOWER_UNSPEC, n);
554}
555
556static int flower_parse_u8(char *str, int value_type, int mask_type,
557 int (*value_from_name)(const char *str,
558 __u8 *value),
559 bool (*value_validate)(__u8 value),
560 struct nlmsghdr *n)
561{
562 char *slash;
563 int ret, err = -1;
564 __u8 value, mask;
565
566 slash = strchr(str, '/');
567 if (slash)
568 *slash = '\0';
569
570 ret = value_from_name ? value_from_name(str, &value) : -1;
571 if (ret < 0) {
572 ret = get_u8(&value, str, 10);
573 if (ret)
574 goto err;
575 }
576
577 if (value_validate && !value_validate(value))
578 goto err;
579
580 if (slash) {
581 ret = get_u8(&mask, slash + 1, 10);
582 if (ret)
583 goto err;
584 } else {
585 mask = UINT8_MAX;
586 }
587
588 addattr8(n, MAX_MSG, value_type, value);
589 addattr8(n, MAX_MSG, mask_type, mask);
590
591 err = 0;
592err:
593 if (slash)
594 *slash = '/';
595 return err;
596}
597
598static const char *flower_print_arp_op_to_name(__u8 op)
599{
600 switch (op) {
601 case ARPOP_REQUEST:
602 return "request";
603 case ARPOP_REPLY:
604 return "reply";
605 default:
606 return NULL;
607 }
608}
609
610static int flower_arp_op_from_name(const char *name, __u8 *op)
611{
612 if (!strcmp(name, "request"))
613 *op = ARPOP_REQUEST;
614 else if (!strcmp(name, "reply"))
615 *op = ARPOP_REPLY;
616 else
617 return -1;
618
619 return 0;
620}
621
622static bool flow_arp_op_validate(__u8 op)
623{
624 return !op || op == ARPOP_REQUEST || op == ARPOP_REPLY;
625}
626
627static int flower_parse_arp_op(char *str, __be16 eth_type,
628 int op_type, int mask_type,
629 struct nlmsghdr *n)
630{
631 if (!flower_eth_type_arp(eth_type))
632 return -1;
633
634 return flower_parse_u8(str, op_type, mask_type, flower_arp_op_from_name,
635 flow_arp_op_validate, n);
636}
637
638static int flower_icmp_attr_type(__be16 eth_type, __u8 ip_proto,
639 enum flower_icmp_field field)
640{
641 if (eth_type == htons(ETH_P_IP) && ip_proto == IPPROTO_ICMP)
642 return field == FLOWER_ICMP_FIELD_CODE ?
643 TCA_FLOWER_KEY_ICMPV4_CODE :
644 TCA_FLOWER_KEY_ICMPV4_TYPE;
645 else if (eth_type == htons(ETH_P_IPV6) && ip_proto == IPPROTO_ICMPV6)
646 return field == FLOWER_ICMP_FIELD_CODE ?
647 TCA_FLOWER_KEY_ICMPV6_CODE :
648 TCA_FLOWER_KEY_ICMPV6_TYPE;
649
650 return -1;
651}
652
653static int flower_icmp_attr_mask_type(__be16 eth_type, __u8 ip_proto,
654 enum flower_icmp_field field)
655{
656 if (eth_type == htons(ETH_P_IP) && ip_proto == IPPROTO_ICMP)
657 return field == FLOWER_ICMP_FIELD_CODE ?
658 TCA_FLOWER_KEY_ICMPV4_CODE_MASK :
659 TCA_FLOWER_KEY_ICMPV4_TYPE_MASK;
660 else if (eth_type == htons(ETH_P_IPV6) && ip_proto == IPPROTO_ICMPV6)
661 return field == FLOWER_ICMP_FIELD_CODE ?
662 TCA_FLOWER_KEY_ICMPV6_CODE_MASK :
663 TCA_FLOWER_KEY_ICMPV6_TYPE_MASK;
664
665 return -1;
666}
667
668static int flower_parse_icmp(char *str, __u16 eth_type, __u8 ip_proto,
669 enum flower_icmp_field field, struct nlmsghdr *n)
670{
671 int value_type, mask_type;
672
673 value_type = flower_icmp_attr_type(eth_type, ip_proto, field);
674 mask_type = flower_icmp_attr_mask_type(eth_type, ip_proto, field);
675 if (value_type < 0 || mask_type < 0)
676 return -1;
677
678 return flower_parse_u8(str, value_type, mask_type, NULL, NULL, n);
679}
680
681static int flower_parse_spi(char *str, __u8 ip_proto, struct nlmsghdr *n)
682{
683 __be32 spi;
684 int ret;
685
686 if (ip_proto != IPPROTO_UDP && ip_proto != IPPROTO_ESP && ip_proto != IPPROTO_AH) {
687 fprintf(stderr,
688 "Can't set \"spi\" if ip_proto isn't ESP/UDP/AH\n");
689 return -1;
690 }
691
692 ret = get_be32(&spi, str, 16);
693 if (ret < 0) {
694 fprintf(stderr, "Illegal \"spi index\"\n");
695 return -1;
696 }
697
698 addattr32(n, MAX_MSG, TCA_FLOWER_KEY_SPI, spi);
699 addattr32(n, MAX_MSG, TCA_FLOWER_KEY_SPI_MASK, UINT32_MAX);
700
701 return 0;
702}
703
704static int flower_parse_l2tpv3(char *str, __u8 ip_proto,
705 struct nlmsghdr *n)
706{
707 __be32 sid;
708 int ret;
709
710 if (ip_proto != IPPROTO_L2TP) {
711 fprintf(stderr,
712 "Can't set \"l2tpv3_sid\" if ip_proto isn't l2tp\n");
713 return -1;
714 }
715 ret = get_be32(&sid, str, 10);
716 if (ret < 0) {
717 fprintf(stderr, "Illegal \"l2tpv3 session id\"\n");
718 return -1;
719 }
720 addattr32(n, MAX_MSG, TCA_FLOWER_KEY_L2TPV3_SID, sid);
721
722 return 0;
723}
724
725static int flower_port_attr_type(__u8 ip_proto, enum flower_endpoint endpoint)
726{
727 if (ip_proto == IPPROTO_TCP)
728 return endpoint == FLOWER_ENDPOINT_SRC ?
729 TCA_FLOWER_KEY_TCP_SRC :
730 TCA_FLOWER_KEY_TCP_DST;
731 else if (ip_proto == IPPROTO_UDP)
732 return endpoint == FLOWER_ENDPOINT_SRC ?
733 TCA_FLOWER_KEY_UDP_SRC :
734 TCA_FLOWER_KEY_UDP_DST;
735 else if (ip_proto == IPPROTO_SCTP)
736 return endpoint == FLOWER_ENDPOINT_SRC ?
737 TCA_FLOWER_KEY_SCTP_SRC :
738 TCA_FLOWER_KEY_SCTP_DST;
739 else
740 return -1;
741}
742
743static int flower_port_attr_mask_type(__u8 ip_proto,
744 enum flower_endpoint endpoint)
745{
746 switch (ip_proto) {
747 case IPPROTO_TCP:
748 return endpoint == FLOWER_ENDPOINT_SRC ?
749 TCA_FLOWER_KEY_TCP_SRC_MASK :
750 TCA_FLOWER_KEY_TCP_DST_MASK;
751 case IPPROTO_UDP:
752 return endpoint == FLOWER_ENDPOINT_SRC ?
753 TCA_FLOWER_KEY_UDP_SRC_MASK :
754 TCA_FLOWER_KEY_UDP_DST_MASK;
755 case IPPROTO_SCTP:
756 return endpoint == FLOWER_ENDPOINT_SRC ?
757 TCA_FLOWER_KEY_SCTP_SRC_MASK :
758 TCA_FLOWER_KEY_SCTP_DST_MASK;
759 default:
760 return -1;
761 }
762}
763
764static int flower_port_range_attr_type(__u8 ip_proto, enum flower_endpoint type,
765 __be16 *min_port_type,
766 __be16 *max_port_type)
767{
768 if (ip_proto == IPPROTO_TCP || ip_proto == IPPROTO_UDP ||
769 ip_proto == IPPROTO_SCTP) {
770 if (type == FLOWER_ENDPOINT_SRC) {
771 *min_port_type = TCA_FLOWER_KEY_PORT_SRC_MIN;
772 *max_port_type = TCA_FLOWER_KEY_PORT_SRC_MAX;
773 } else {
774 *min_port_type = TCA_FLOWER_KEY_PORT_DST_MIN;
775 *max_port_type = TCA_FLOWER_KEY_PORT_DST_MAX;
776 }
777 } else {
778 return -1;
779 }
780 return 0;
781}
782
783
784static int parse_range(char *str, __be16 *min, __be16 *max, bool *p_is_range)
785{
786 char *sep;
787
788 sep = strchr(str, '-');
789 if (sep) {
790 *sep = '\0';
791
792 if (get_be16(min, str, 10))
793 return -1;
794
795 if (get_be16(max, sep + 1, 10))
796 return -1;
797
798 *p_is_range = true;
799 } else {
800 if (get_be16(min, str, 10))
801 return -1;
802 }
803 return 0;
804}
805
806static int flower_parse_port(char *str, __u8 ip_proto,
807 enum flower_endpoint endpoint,
808 struct nlmsghdr *n)
809{
810 bool is_range = false;
811 char *slash = NULL;
812 __be16 min = 0;
813 __be16 max = 0;
814 int ret;
815
816 ret = parse_range(str, &min, &max, &is_range);
817 if (ret) {
818 slash = strchr(str, '/');
819 if (!slash)
820 return -1;
821 }
822
823 if (is_range) {
824 __be16 min_port_type, max_port_type;
825
826 if (ntohs(max) <= ntohs(min)) {
827 fprintf(stderr, "max value should be greater than min value\n");
828 return -1;
829 }
830 if (flower_port_range_attr_type(ip_proto, endpoint,
831 &min_port_type, &max_port_type))
832 return -1;
833
834 addattr16(n, MAX_MSG, min_port_type, min);
835 addattr16(n, MAX_MSG, max_port_type, max);
836 } else {
837 int type;
838
839 type = flower_port_attr_type(ip_proto, endpoint);
840 if (type < 0)
841 return -1;
842
843 if (!slash) {
844 addattr16(n, MAX_MSG, type, min);
845 } else {
846 int mask_type;
847
848 mask_type = flower_port_attr_mask_type(ip_proto,
849 endpoint);
850 if (mask_type < 0)
851 return -1;
852 return flower_parse_u16(str, type, mask_type, n, true);
853 }
854 }
855 return 0;
856}
857
858#define TCP_FLAGS_MAX_MASK 0xfff
859
860static int flower_parse_tcp_flags(char *str, int flags_type, int mask_type,
861 struct nlmsghdr *n)
862{
863 char *slash;
864 int ret, err = -1;
865 __u16 flags;
866
867 slash = strchr(str, '/');
868 if (slash)
869 *slash = '\0';
870
871 ret = get_u16(&flags, str, 16);
872 if (ret < 0 || flags & ~TCP_FLAGS_MAX_MASK)
873 goto err;
874
875 addattr16(n, MAX_MSG, flags_type, htons(flags));
876
877 if (slash) {
878 ret = get_u16(&flags, slash + 1, 16);
879 if (ret < 0 || flags & ~TCP_FLAGS_MAX_MASK)
880 goto err;
881 } else {
882 flags = TCP_FLAGS_MAX_MASK;
883 }
884 addattr16(n, MAX_MSG, mask_type, htons(flags));
885
886 err = 0;
887err:
888 if (slash)
889 *slash = '/';
890 return err;
891}
892
893static int flower_parse_ip_tos_ttl(char *str, int key_type, int mask_type,
894 struct nlmsghdr *n)
895{
896 char *slash;
897 int ret, err = -1;
898 __u8 tos_ttl;
899
900 slash = strchr(str, '/');
901 if (slash)
902 *slash = '\0';
903
904 ret = get_u8(&tos_ttl, str, 10);
905 if (ret < 0)
906 ret = get_u8(&tos_ttl, str, 16);
907 if (ret < 0)
908 goto err;
909
910 addattr8(n, MAX_MSG, key_type, tos_ttl);
911
912 if (slash) {
913 ret = get_u8(&tos_ttl, slash + 1, 16);
914 if (ret < 0)
915 goto err;
916 } else {
917 tos_ttl = 0xff;
918 }
919 addattr8(n, MAX_MSG, mask_type, tos_ttl);
920
921 err = 0;
922err:
923 if (slash)
924 *slash = '/';
925 return err;
926}
927
928static int flower_parse_key_id(const char *str, int type, struct nlmsghdr *n)
929{
930 int ret;
931 __be32 key_id;
932
933 ret = get_be32(&key_id, str, 10);
934 if (!ret)
935 addattr32(n, MAX_MSG, type, key_id);
936
937 return ret;
938}
939
940static int flower_parse_enc_port(char *str, int type, struct nlmsghdr *n)
941{
942 int ret;
943 __be16 port;
944
945 ret = get_be16(&port, str, 10);
946 if (ret)
947 return -1;
948
949 addattr16(n, MAX_MSG, type, port);
950
951 return 0;
952}
953
954static int flower_parse_geneve_opt(char *str, struct nlmsghdr *n)
955{
956 struct rtattr *nest;
957 char *token;
958 int i, err;
959
960 nest = addattr_nest(n, MAX_MSG, TCA_FLOWER_KEY_ENC_OPTS_GENEVE);
961
962 i = 1;
963 token = strsep(&str, ":");
964 while (token) {
965 switch (i) {
966 case TCA_FLOWER_KEY_ENC_OPT_GENEVE_CLASS:
967 {
968 __be16 opt_class;
969
970 if (!strlen(token))
971 break;
972 err = get_be16(&opt_class, token, 16);
973 if (err)
974 return err;
975
976 addattr16(n, MAX_MSG, i, opt_class);
977 break;
978 }
979 case TCA_FLOWER_KEY_ENC_OPT_GENEVE_TYPE:
980 {
981 __u8 opt_type;
982
983 if (!strlen(token))
984 break;
985 err = get_u8(&opt_type, token, 16);
986 if (err)
987 return err;
988
989 addattr8(n, MAX_MSG, i, opt_type);
990 break;
991 }
992 case TCA_FLOWER_KEY_ENC_OPT_GENEVE_DATA:
993 {
994 size_t token_len = strlen(token);
995 __u8 *opts;
996
997 if (!token_len)
998 break;
999 opts = malloc(token_len / 2);
1000 if (!opts)
1001 return -1;
1002 if (hex2mem(token, opts, token_len / 2) < 0) {
1003 free(opts);
1004 return -1;
1005 }
1006 addattr_l(n, MAX_MSG, i, opts, token_len / 2);
1007 free(opts);
1008
1009 break;
1010 }
1011 default:
1012 fprintf(stderr, "Unknown \"geneve_opts\" type\n");
1013 return -1;
1014 }
1015
1016 token = strsep(&str, ":");
1017 i++;
1018 }
1019 addattr_nest_end(n, nest);
1020
1021 return 0;
1022}
1023
1024static int flower_parse_vxlan_opt(char *str, struct nlmsghdr *n)
1025{
1026 struct rtattr *nest;
1027 __u32 gbp;
1028 int err;
1029
1030 nest = addattr_nest(n, MAX_MSG,
1031 TCA_FLOWER_KEY_ENC_OPTS_VXLAN | NLA_F_NESTED);
1032
1033 err = get_u32(&gbp, str, 0);
1034 if (err)
1035 return err;
1036 addattr32(n, MAX_MSG, TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP, gbp);
1037
1038 addattr_nest_end(n, nest);
1039
1040 return 0;
1041}
1042
1043static int flower_parse_erspan_opt(char *str, struct nlmsghdr *n)
1044{
1045 struct rtattr *nest;
1046 char *token;
1047 int i, err;
1048
1049 nest = addattr_nest(n, MAX_MSG,
1050 TCA_FLOWER_KEY_ENC_OPTS_ERSPAN | NLA_F_NESTED);
1051
1052 i = 1;
1053 token = strsep(&str, ":");
1054 while (token) {
1055 switch (i) {
1056 case TCA_FLOWER_KEY_ENC_OPT_ERSPAN_VER:
1057 {
1058 __u8 opt_type;
1059
1060 if (!strlen(token))
1061 break;
1062 err = get_u8(&opt_type, token, 0);
1063 if (err)
1064 return err;
1065
1066 addattr8(n, MAX_MSG, i, opt_type);
1067 break;
1068 }
1069 case TCA_FLOWER_KEY_ENC_OPT_ERSPAN_INDEX:
1070 {
1071 __be32 opt_index;
1072
1073 if (!strlen(token))
1074 break;
1075 err = get_be32(&opt_index, token, 0);
1076 if (err)
1077 return err;
1078
1079 addattr32(n, MAX_MSG, i, opt_index);
1080 break;
1081 }
1082 case TCA_FLOWER_KEY_ENC_OPT_ERSPAN_DIR:
1083 {
1084 __u8 opt_type;
1085
1086 if (!strlen(token))
1087 break;
1088 err = get_u8(&opt_type, token, 0);
1089 if (err)
1090 return err;
1091
1092 addattr8(n, MAX_MSG, i, opt_type);
1093 break;
1094 }
1095 case TCA_FLOWER_KEY_ENC_OPT_ERSPAN_HWID:
1096 {
1097 __u8 opt_type;
1098
1099 if (!strlen(token))
1100 break;
1101 err = get_u8(&opt_type, token, 0);
1102 if (err)
1103 return err;
1104
1105 addattr8(n, MAX_MSG, i, opt_type);
1106 break;
1107 }
1108 default:
1109 fprintf(stderr, "Unknown \"geneve_opts\" type\n");
1110 return -1;
1111 }
1112
1113 token = strsep(&str, ":");
1114 i++;
1115 }
1116 addattr_nest_end(n, nest);
1117
1118 return 0;
1119}
1120
1121static int flower_parse_gtp_opt(char *str, struct nlmsghdr *n)
1122{
1123 struct rtattr *nest;
1124 char *token;
1125 int arg, err;
1126
1127 nest = addattr_nest(n, MAX_MSG, TCA_FLOWER_KEY_ENC_OPTS_GTP | NLA_F_NESTED);
1128
1129 token = strsep(&str, ":");
1130 for (arg = 1; arg <= TCA_FLOWER_KEY_ENC_OPT_GTP_MAX; arg++) {
1131 switch (arg) {
1132 case TCA_FLOWER_KEY_ENC_OPT_GTP_PDU_TYPE:
1133 {
1134 __u8 pdu_type;
1135
1136 if (!strlen(token))
1137 break;
1138 err = get_u8(&pdu_type, token, 16);
1139 if (err)
1140 return err;
1141 addattr8(n, MAX_MSG, arg, pdu_type);
1142 break;
1143 }
1144 case TCA_FLOWER_KEY_ENC_OPT_GTP_QFI:
1145 {
1146 __u8 qfi;
1147
1148 if (!strlen(token))
1149 break;
1150 err = get_u8(&qfi, token, 16);
1151 if (err)
1152 return err;
1153 addattr8(n, MAX_MSG, arg, qfi);
1154 break;
1155 }
1156 default:
1157 fprintf(stderr, "Unknown \"gtp_opts\" type\n");
1158 return -1;
1159 }
1160 token = strsep(&str, ":");
1161 }
1162 addattr_nest_end(n, nest);
1163
1164 return 0;
1165}
1166
1167static int flower_parse_pfcp_opt(char *str, struct nlmsghdr *n)
1168{
1169 struct rtattr *nest;
1170 char *token;
1171 int i, err;
1172
1173 nest = addattr_nest(n, MAX_MSG,
1174 TCA_FLOWER_KEY_ENC_OPTS_PFCP | NLA_F_NESTED);
1175
1176 i = 1;
1177 token = strsep(&str, ":");
1178 while (token) {
1179 switch (i) {
1180 case TCA_FLOWER_KEY_ENC_OPT_PFCP_TYPE:
1181 {
1182 __u8 opt_type;
1183
1184 if (!strlen(token))
1185 break;
1186 err = get_u8(&opt_type, token, 16);
1187 if (err)
1188 return err;
1189
1190 addattr8(n, MAX_MSG, i, opt_type);
1191 break;
1192 }
1193 case TCA_FLOWER_KEY_ENC_OPT_PFCP_SEID:
1194 {
1195 __be64 opt_seid;;
1196
1197 if (!strlen(token))
1198 break;
1199 err = get_be64(&opt_seid, token, 16);
1200 if (err)
1201 return err;
1202
1203 addattr64(n, MAX_MSG, i, opt_seid);
1204 break;
1205 }
1206 default:
1207 fprintf(stderr, "Unknown \"pfcp_opts\" type\n");
1208 return -1;
1209 }
1210
1211 token = strsep(&str, ":");
1212 i++;
1213 }
1214 addattr_nest_end(n, nest);
1215
1216 return 0;
1217}
1218
1219static int flower_parse_geneve_opts(char *str, struct nlmsghdr *n)
1220{
1221 char *token;
1222 int err;
1223
1224 token = strsep(&str, ",");
1225 while (token) {
1226 err = flower_parse_geneve_opt(token, n);
1227 if (err)
1228 return err;
1229
1230 token = strsep(&str, ",");
1231 }
1232
1233 return 0;
1234}
1235
1236static int flower_check_enc_opt_key(char *key)
1237{
1238 int key_len, col_cnt = 0;
1239
1240 key_len = strlen(key);
1241 while ((key = strchr(key, ':'))) {
1242 if (strlen(key) == key_len)
1243 return -1;
1244
1245 key_len = strlen(key) - 1;
1246 col_cnt++;
1247 key++;
1248 }
1249
1250 if (col_cnt != 2 || !key_len)
1251 return -1;
1252
1253 return 0;
1254}
1255
1256static int flower_parse_enc_opts_geneve(char *str, struct nlmsghdr *n)
1257{
1258 char key[FLOWER_OPTS_MAX], mask[FLOWER_OPTS_MAX];
1259 int data_len, key_len, mask_len, err;
1260 char *token, *slash;
1261 struct rtattr *nest;
1262
1263 key_len = 0;
1264 mask_len = 0;
1265 token = strsep(&str, ",");
1266 while (token) {
1267 slash = strchr(token, '/');
1268 if (slash)
1269 *slash = '\0';
1270
1271 if ((key_len + strlen(token) > FLOWER_OPTS_MAX) ||
1272 flower_check_enc_opt_key(token))
1273 return -1;
1274
1275 strcpy(&key[key_len], token);
1276 key_len += strlen(token) + 1;
1277 key[key_len - 1] = ',';
1278
1279 if (!slash) {
1280
1281 if (mask_len + strlen(token) > FLOWER_OPTS_MAX)
1282 return -1;
1283
1284 data_len = strlen(rindex(token, ':'));
1285 sprintf(&mask[mask_len], "ffff:ff:");
1286 mask_len += 8;
1287 memset(&mask[mask_len], 'f', data_len - 1);
1288 mask_len += data_len;
1289 mask[mask_len - 1] = ',';
1290 token = strsep(&str, ",");
1291 continue;
1292 }
1293
1294 if (mask_len + strlen(slash + 1) > FLOWER_OPTS_MAX)
1295 return -1;
1296
1297 strcpy(&mask[mask_len], slash + 1);
1298 mask_len += strlen(slash + 1) + 1;
1299 mask[mask_len - 1] = ',';
1300
1301 *slash = '/';
1302 token = strsep(&str, ",");
1303 }
1304 key[key_len - 1] = '\0';
1305 mask[mask_len - 1] = '\0';
1306
1307 nest = addattr_nest(n, MAX_MSG, TCA_FLOWER_KEY_ENC_OPTS);
1308 err = flower_parse_geneve_opts(key, n);
1309 if (err)
1310 return err;
1311 addattr_nest_end(n, nest);
1312
1313 nest = addattr_nest(n, MAX_MSG, TCA_FLOWER_KEY_ENC_OPTS_MASK);
1314 err = flower_parse_geneve_opts(mask, n);
1315 if (err)
1316 return err;
1317 addattr_nest_end(n, nest);
1318
1319 return 0;
1320}
1321
1322static int flower_parse_enc_opts_vxlan(char *str, struct nlmsghdr *n)
1323{
1324 char key[FLOWER_OPTS_MAX], mask[FLOWER_OPTS_MAX];
1325 struct rtattr *nest;
1326 char *slash;
1327 int err;
1328
1329 slash = strchr(str, '/');
1330 if (slash) {
1331 *slash++ = '\0';
1332 if (strlen(slash) > FLOWER_OPTS_MAX)
1333 return -1;
1334 strcpy(mask, slash);
1335 } else {
1336 strcpy(mask, "0xffffffff");
1337 }
1338
1339 if (strlen(str) > FLOWER_OPTS_MAX)
1340 return -1;
1341 strcpy(key, str);
1342
1343 nest = addattr_nest(n, MAX_MSG, TCA_FLOWER_KEY_ENC_OPTS | NLA_F_NESTED);
1344 err = flower_parse_vxlan_opt(str, n);
1345 if (err)
1346 return err;
1347 addattr_nest_end(n, nest);
1348
1349 nest = addattr_nest(n, MAX_MSG,
1350 TCA_FLOWER_KEY_ENC_OPTS_MASK | NLA_F_NESTED);
1351 err = flower_parse_vxlan_opt(mask, n);
1352 if (err)
1353 return err;
1354 addattr_nest_end(n, nest);
1355
1356 return 0;
1357}
1358
1359static int flower_parse_enc_opts_erspan(char *str, struct nlmsghdr *n)
1360{
1361 char key[FLOWER_OPTS_MAX], mask[FLOWER_OPTS_MAX];
1362 struct rtattr *nest;
1363 char *slash;
1364 int err;
1365
1366
1367 slash = strchr(str, '/');
1368 if (slash) {
1369 *slash++ = '\0';
1370 if (strlen(slash) > FLOWER_OPTS_MAX)
1371 return -1;
1372 strcpy(mask, slash);
1373 } else {
1374 int index;
1375
1376 slash = strchr(str, ':');
1377 index = (int)(slash - str);
1378 memcpy(mask, str, index);
1379 strcpy(mask + index, ":0xffffffff:0xff:0xff");
1380 }
1381
1382 if (strlen(str) > FLOWER_OPTS_MAX)
1383 return -1;
1384 strcpy(key, str);
1385
1386 nest = addattr_nest(n, MAX_MSG, TCA_FLOWER_KEY_ENC_OPTS | NLA_F_NESTED);
1387 err = flower_parse_erspan_opt(key, n);
1388 if (err)
1389 return err;
1390 addattr_nest_end(n, nest);
1391
1392 nest = addattr_nest(n, MAX_MSG,
1393 TCA_FLOWER_KEY_ENC_OPTS_MASK | NLA_F_NESTED);
1394 err = flower_parse_erspan_opt(mask, n);
1395 if (err)
1396 return err;
1397 addattr_nest_end(n, nest);
1398
1399 return 0;
1400}
1401
1402static int flower_parse_enc_opts_gtp(char *str, struct nlmsghdr *n)
1403{
1404 char key[FLOWER_OPTS_MAX], mask[FLOWER_OPTS_MAX];
1405 struct rtattr *nest;
1406 char *slash;
1407 int err;
1408
1409 slash = strchr(str, '/');
1410 if (slash) {
1411 *slash++ = '\0';
1412 if (strlen(slash) > FLOWER_OPTS_MAX)
1413 return -1;
1414 strcpy(mask, slash);
1415 } else
1416 strcpy(mask, "ff:ff");
1417
1418 if (strlen(str) > FLOWER_OPTS_MAX)
1419 return -1;
1420 strcpy(key, str);
1421
1422 nest = addattr_nest(n, MAX_MSG, TCA_FLOWER_KEY_ENC_OPTS | NLA_F_NESTED);
1423 err = flower_parse_gtp_opt(key, n);
1424 if (err)
1425 return err;
1426 addattr_nest_end(n, nest);
1427
1428 nest = addattr_nest(n, MAX_MSG, TCA_FLOWER_KEY_ENC_OPTS_MASK | NLA_F_NESTED);
1429 err = flower_parse_gtp_opt(mask, n);
1430 if (err)
1431 return err;
1432 addattr_nest_end(n, nest);
1433
1434 return 0;
1435}
1436
1437static int flower_parse_enc_opts_pfcp(char *str, struct nlmsghdr *n)
1438{
1439 char key[FLOWER_OPTS_MAX], mask[FLOWER_OPTS_MAX];
1440 struct rtattr *nest;
1441 char *slash;
1442 int err;
1443
1444
1445 slash = strchr(str, '/');
1446 if (slash) {
1447 *slash++ = '\0';
1448 if (strlen(slash) > FLOWER_OPTS_MAX)
1449 return -1;
1450 strcpy(mask, slash);
1451 } else {
1452 strcpy(mask, "ff:ffffffffffffffff");
1453 }
1454
1455 if (strlen(str) > FLOWER_OPTS_MAX)
1456 return -1;
1457 strcpy(key, str);
1458
1459 nest = addattr_nest(n, MAX_MSG, TCA_FLOWER_KEY_ENC_OPTS | NLA_F_NESTED);
1460 err = flower_parse_pfcp_opt(key, n);
1461 if (err)
1462 return err;
1463 addattr_nest_end(n, nest);
1464
1465 nest = addattr_nest(n, MAX_MSG,
1466 TCA_FLOWER_KEY_ENC_OPTS_MASK | NLA_F_NESTED);
1467 err = flower_parse_pfcp_opt(mask, n);
1468 if (err)
1469 return err;
1470 addattr_nest_end(n, nest);
1471
1472 return 0;
1473}
1474
1475static int flower_parse_mpls_lse(int *argc_p, char ***argv_p,
1476 struct nlmsghdr *nlh)
1477{
1478 struct rtattr *lse_attr;
1479 char **argv = *argv_p;
1480 int argc = *argc_p;
1481 __u8 depth = 0;
1482 int ret;
1483
1484 lse_attr = addattr_nest(nlh, MAX_MSG,
1485 TCA_FLOWER_KEY_MPLS_OPTS_LSE | NLA_F_NESTED);
1486
1487 while (argc > 0) {
1488 if (matches(*argv, "depth") == 0) {
1489 NEXT_ARG();
1490 ret = get_u8(&depth, *argv, 10);
1491 if (ret < 0 || depth < 1) {
1492 fprintf(stderr, "Illegal \"depth\"\n");
1493 return -1;
1494 }
1495 addattr8(nlh, MAX_MSG,
1496 TCA_FLOWER_KEY_MPLS_OPT_LSE_DEPTH, depth);
1497 } else if (matches(*argv, "label") == 0) {
1498 __u32 label;
1499
1500 NEXT_ARG();
1501 ret = get_u32(&label, *argv, 10);
1502 if (ret < 0 ||
1503 label & ~(MPLS_LS_LABEL_MASK >> MPLS_LS_LABEL_SHIFT)) {
1504 fprintf(stderr, "Illegal \"label\"\n");
1505 return -1;
1506 }
1507 addattr32(nlh, MAX_MSG,
1508 TCA_FLOWER_KEY_MPLS_OPT_LSE_LABEL, label);
1509 } else if (matches(*argv, "tc") == 0) {
1510 __u8 tc;
1511
1512 NEXT_ARG();
1513 ret = get_u8(&tc, *argv, 10);
1514 if (ret < 0 ||
1515 tc & ~(MPLS_LS_TC_MASK >> MPLS_LS_TC_SHIFT)) {
1516 fprintf(stderr, "Illegal \"tc\"\n");
1517 return -1;
1518 }
1519 addattr8(nlh, MAX_MSG, TCA_FLOWER_KEY_MPLS_OPT_LSE_TC,
1520 tc);
1521 } else if (matches(*argv, "bos") == 0) {
1522 __u8 bos;
1523
1524 NEXT_ARG();
1525 ret = get_u8(&bos, *argv, 10);
1526 if (ret < 0 || bos & ~(MPLS_LS_S_MASK >> MPLS_LS_S_SHIFT)) {
1527 fprintf(stderr, "Illegal \"bos\"\n");
1528 return -1;
1529 }
1530 addattr8(nlh, MAX_MSG, TCA_FLOWER_KEY_MPLS_OPT_LSE_BOS,
1531 bos);
1532 } else if (matches(*argv, "ttl") == 0) {
1533 __u8 ttl;
1534
1535 NEXT_ARG();
1536 ret = get_u8(&ttl, *argv, 10);
1537 if (ret < 0) {
1538 fprintf(stderr, "Illegal \"ttl\"\n");
1539 return -1;
1540 }
1541 addattr8(nlh, MAX_MSG, TCA_FLOWER_KEY_MPLS_OPT_LSE_TTL,
1542 ttl);
1543 } else {
1544 break;
1545 }
1546 argc--; argv++;
1547 }
1548
1549 if (!depth) {
1550 missarg("depth");
1551 return -1;
1552 }
1553
1554 addattr_nest_end(nlh, lse_attr);
1555
1556 *argc_p = argc;
1557 *argv_p = argv;
1558
1559 return 0;
1560}
1561
1562static int flower_parse_mpls(int *argc_p, char ***argv_p, struct nlmsghdr *nlh)
1563{
1564 struct rtattr *mpls_attr;
1565 char **argv = *argv_p;
1566 int argc = *argc_p;
1567
1568 mpls_attr = addattr_nest(nlh, MAX_MSG,
1569 TCA_FLOWER_KEY_MPLS_OPTS | NLA_F_NESTED);
1570
1571 while (argc > 0) {
1572 if (matches(*argv, "lse") == 0) {
1573 NEXT_ARG();
1574 if (flower_parse_mpls_lse(&argc, &argv, nlh) < 0)
1575 return -1;
1576 } else {
1577 break;
1578 }
1579 }
1580
1581 addattr_nest_end(nlh, mpls_attr);
1582
1583 *argc_p = argc;
1584 *argv_p = argv;
1585
1586 return 0;
1587}
1588
1589static int flower_parse_cfm(int *argc_p, char ***argv_p, __be16 eth_type,
1590 struct nlmsghdr *n)
1591{
1592 struct rtattr *cfm_attr;
1593 char **argv = *argv_p;
1594 int argc = *argc_p;
1595 int ret;
1596
1597 if (eth_type != htons(ETH_P_CFM)) {
1598 fprintf(stderr,
1599 "Can't set attribute if ethertype isn't CFM\n");
1600 return -1;
1601 }
1602
1603 cfm_attr = addattr_nest(n, MAX_MSG, TCA_FLOWER_KEY_CFM | NLA_F_NESTED);
1604
1605 while (argc > 0) {
1606 if (!strcmp(*argv, "mdl")) {
1607 __u8 val;
1608
1609 NEXT_ARG();
1610 ret = get_u8(&val, *argv, 10);
1611 if (ret < 0) {
1612 fprintf(stderr, "Illegal \"cfm md level\"\n");
1613 return -1;
1614 }
1615 addattr8(n, MAX_MSG, TCA_FLOWER_KEY_CFM_MD_LEVEL, val);
1616 } else if (!strcmp(*argv, "op")) {
1617 __u8 val;
1618
1619 NEXT_ARG();
1620 ret = get_u8(&val, *argv, 10);
1621 if (ret < 0) {
1622 fprintf(stderr, "Illegal \"cfm opcode\"\n");
1623 return -1;
1624 }
1625 addattr8(n, MAX_MSG, TCA_FLOWER_KEY_CFM_OPCODE, val);
1626 } else {
1627 break;
1628 }
1629 argc--; argv++;
1630 }
1631
1632 addattr_nest_end(n, cfm_attr);
1633
1634 *argc_p = argc;
1635 *argv_p = argv;
1636
1637 return 0;
1638}
1639
1640static int flower_parse_opt(const struct filter_util *qu, char *handle,
1641 int argc, char **argv, struct nlmsghdr *n)
1642{
1643 int ret;
1644 struct tcmsg *t = NLMSG_DATA(n);
1645 bool mpls_format_old = false;
1646 bool mpls_format_new = false;
1647 struct rtattr *tail;
1648 __be16 tc_proto = TC_H_MIN(t->tcm_info);
1649 __be16 eth_type = tc_proto;
1650 __be16 vlan_ethtype = 0;
1651 __u8 num_of_vlans = 0;
1652 __u8 ip_proto = 0xff;
1653 __u32 flags = 0;
1654 __u32 mtf = 0;
1655 __u32 mtf_mask = 0;
1656 __u32 dst_flags = 0;
1657 __u32 dst_flags_mask = 0;
1658
1659 if (handle) {
1660 ret = get_u32(&t->tcm_handle, handle, 0);
1661 if (ret) {
1662 fprintf(stderr, "Illegal \"handle\"\n");
1663 return -1;
1664 }
1665 }
1666
1667 tail = (struct rtattr *) (((void *) n) + NLMSG_ALIGN(n->nlmsg_len));
1668 addattr_l(n, MAX_MSG, TCA_OPTIONS, NULL, 0);
1669
1670 if (argc == 0) {
1671
1672 goto parse_done;
1673 }
1674
1675 while (argc > 0) {
1676 if (matches(*argv, "classid") == 0 ||
1677 matches(*argv, "flowid") == 0) {
1678 unsigned int classid;
1679
1680 NEXT_ARG();
1681 ret = get_tc_classid(&classid, *argv);
1682 if (ret) {
1683 fprintf(stderr, "Illegal \"classid\"\n");
1684 return -1;
1685 }
1686 addattr_l(n, MAX_MSG, TCA_FLOWER_CLASSID, &classid, 4);
1687 } else if (matches(*argv, "hw_tc") == 0) {
1688 unsigned int classid;
1689 __u32 tc;
1690 char *end;
1691
1692 NEXT_ARG();
1693 tc = strtoul(*argv, &end, 0);
1694 if (*end) {
1695 fprintf(stderr, "Illegal TC index\n");
1696 return -1;
1697 }
1698 if (tc >= TC_QOPT_MAX_QUEUE) {
1699 fprintf(stderr, "TC index exceeds max range\n");
1700 return -1;
1701 }
1702 classid = TC_H_MAKE(TC_H_MAJ(t->tcm_parent),
1703 TC_H_MIN(tc + TC_H_MIN_PRIORITY));
1704 addattr_l(n, MAX_MSG, TCA_FLOWER_CLASSID, &classid,
1705 sizeof(classid));
1706 } else if (matches(*argv, "ip_flags") == 0) {
1707 NEXT_ARG();
1708 ret = flower_parse_matching_flags(*argv,
1709 FLOWER_IP_FLAGS,
1710 &mtf,
1711 &mtf_mask);
1712 if (ret < 0) {
1713 fprintf(stderr, "Illegal \"ip_flags\"\n");
1714 return -1;
1715 }
1716 } else if (strcmp(*argv, "l2_miss") == 0) {
1717 __u8 l2_miss;
1718
1719 NEXT_ARG();
1720 if (get_u8(&l2_miss, *argv, 10)) {
1721 fprintf(stderr, "Illegal \"l2_miss\"\n");
1722 return -1;
1723 }
1724 addattr8(n, MAX_MSG, TCA_FLOWER_L2_MISS, l2_miss);
1725 } else if (matches(*argv, "verbose") == 0) {
1726 flags |= TCA_CLS_FLAGS_VERBOSE;
1727 } else if (matches(*argv, "skip_hw") == 0) {
1728 flags |= TCA_CLS_FLAGS_SKIP_HW;
1729 } else if (matches(*argv, "skip_sw") == 0) {
1730 flags |= TCA_CLS_FLAGS_SKIP_SW;
1731 } else if (matches(*argv, "ct_state") == 0) {
1732 NEXT_ARG();
1733 ret = flower_parse_ct_state(*argv, n);
1734 if (ret < 0) {
1735 fprintf(stderr, "Illegal \"ct_state\"\n");
1736 return -1;
1737 }
1738 } else if (matches(*argv, "ct_zone") == 0) {
1739 NEXT_ARG();
1740 ret = flower_parse_ct_zone(*argv, n);
1741 if (ret < 0) {
1742 fprintf(stderr, "Illegal \"ct_zone\"\n");
1743 return -1;
1744 }
1745 } else if (matches(*argv, "ct_mark") == 0) {
1746 NEXT_ARG();
1747 ret = flower_parse_ct_mark(*argv, n);
1748 if (ret < 0) {
1749 fprintf(stderr, "Illegal \"ct_mark\"\n");
1750 return -1;
1751 }
1752 } else if (matches(*argv, "ct_label") == 0) {
1753 NEXT_ARG();
1754 ret = flower_parse_ct_labels(*argv, n);
1755 if (ret < 0) {
1756 fprintf(stderr, "Illegal \"ct_label\"\n");
1757 return -1;
1758 }
1759 } else if (matches(*argv, "indev") == 0) {
1760 NEXT_ARG();
1761 if (check_ifname(*argv))
1762 invarg("\"indev\" not a valid ifname", *argv);
1763 addattrstrz(n, MAX_MSG, TCA_FLOWER_INDEV, *argv);
1764 } else if (strcmp(*argv, "num_of_vlans") == 0) {
1765 NEXT_ARG();
1766 ret = get_u8(&num_of_vlans, *argv, 10);
1767 if (ret < 0) {
1768 fprintf(stderr, "Illegal \"num_of_vlans\"\n");
1769 return -1;
1770 }
1771 addattr8(n, MAX_MSG,
1772 TCA_FLOWER_KEY_NUM_OF_VLANS, num_of_vlans);
1773 } else if (matches(*argv, "vlan_id") == 0) {
1774 __u16 vid;
1775
1776 NEXT_ARG();
1777 if (!eth_type_vlan(tc_proto, num_of_vlans > 0)) {
1778 fprintf(stderr, "Can't set \"vlan_id\" if ethertype isn't 802.1Q or 802.1AD"
1779 " and num_of_vlans is 0\n");
1780 return -1;
1781 }
1782 ret = get_u16(&vid, *argv, 10);
1783 if (ret < 0 || vid & ~0xfff) {
1784 fprintf(stderr, "Illegal \"vlan_id\"\n");
1785 return -1;
1786 }
1787 addattr16(n, MAX_MSG, TCA_FLOWER_KEY_VLAN_ID, vid);
1788 } else if (matches(*argv, "vlan_prio") == 0) {
1789 __u8 vlan_prio;
1790
1791 NEXT_ARG();
1792 if (!eth_type_vlan(tc_proto, num_of_vlans > 0)) {
1793 fprintf(stderr, "Can't set \"vlan_prio\" if ethertype isn't 802.1Q or 802.1AD"
1794 " and num_of_vlans is 0\n");
1795 return -1;
1796 }
1797 ret = get_u8(&vlan_prio, *argv, 10);
1798 if (ret < 0 || vlan_prio & ~0x7) {
1799 fprintf(stderr, "Illegal \"vlan_prio\"\n");
1800 return -1;
1801 }
1802 addattr8(n, MAX_MSG,
1803 TCA_FLOWER_KEY_VLAN_PRIO, vlan_prio);
1804 } else if (matches(*argv, "vlan_ethtype") == 0) {
1805 NEXT_ARG();
1806 ret = flower_parse_vlan_eth_type(*argv, eth_type,
1807 TCA_FLOWER_KEY_VLAN_ETH_TYPE,
1808 &vlan_ethtype, n, num_of_vlans > 0);
1809 if (ret < 0)
1810 return -1;
1811
1812 eth_type = vlan_ethtype;
1813 } else if (matches(*argv, "cvlan_id") == 0) {
1814 __u16 vid;
1815
1816 NEXT_ARG();
1817 if (!eth_type_vlan(vlan_ethtype, num_of_vlans > 1)) {
1818 fprintf(stderr, "Can't set \"cvlan_id\" if inner vlan ethertype isn't 802.1Q or 802.1AD"
1819 " and num_of_vlans is less than 2\n");
1820 return -1;
1821 }
1822 ret = get_u16(&vid, *argv, 10);
1823 if (ret < 0 || vid & ~0xfff) {
1824 fprintf(stderr, "Illegal \"cvlan_id\"\n");
1825 return -1;
1826 }
1827 addattr16(n, MAX_MSG, TCA_FLOWER_KEY_CVLAN_ID, vid);
1828 } else if (matches(*argv, "cvlan_prio") == 0) {
1829 __u8 cvlan_prio;
1830
1831 NEXT_ARG();
1832 if (!eth_type_vlan(vlan_ethtype, num_of_vlans > 1)) {
1833 fprintf(stderr, "Can't set \"cvlan_prio\" if inner vlan ethertype isn't 802.1Q or 802.1AD"
1834 " and num_of_vlans is less than 2\n");
1835 return -1;
1836 }
1837 ret = get_u8(&cvlan_prio, *argv, 10);
1838 if (ret < 0 || cvlan_prio & ~0x7) {
1839 fprintf(stderr, "Illegal \"cvlan_prio\"\n");
1840 return -1;
1841 }
1842 addattr8(n, MAX_MSG,
1843 TCA_FLOWER_KEY_CVLAN_PRIO, cvlan_prio);
1844 } else if (matches(*argv, "cvlan_ethtype") == 0) {
1845 NEXT_ARG();
1846
1847 ret = flower_parse_vlan_eth_type(*argv, vlan_ethtype,
1848 TCA_FLOWER_KEY_CVLAN_ETH_TYPE,
1849 ð_type, n, num_of_vlans > 1);
1850 if (ret < 0)
1851 return -1;
1852 } else if (matches(*argv, "mpls") == 0) {
1853 NEXT_ARG();
1854 if (eth_type != htons(ETH_P_MPLS_UC) &&
1855 eth_type != htons(ETH_P_MPLS_MC)) {
1856 fprintf(stderr,
1857 "Can't set \"mpls\" if ethertype isn't MPLS\n");
1858 return -1;
1859 }
1860 if (mpls_format_old) {
1861 fprintf(stderr,
1862 "Can't set \"mpls\" if \"mpls_label\", \"mpls_tc\", \"mpls_bos\" or \"mpls_ttl\" is set\n");
1863 return -1;
1864 }
1865 mpls_format_new = true;
1866 if (flower_parse_mpls(&argc, &argv, n) < 0)
1867 return -1;
1868 continue;
1869 } else if (matches(*argv, "mpls_label") == 0) {
1870 __u32 label;
1871
1872 NEXT_ARG();
1873 if (eth_type != htons(ETH_P_MPLS_UC) &&
1874 eth_type != htons(ETH_P_MPLS_MC)) {
1875 fprintf(stderr,
1876 "Can't set \"mpls_label\" if ethertype isn't MPLS\n");
1877 return -1;
1878 }
1879 if (mpls_format_new) {
1880 fprintf(stderr,
1881 "Can't set \"mpls_label\" if \"mpls\" is set\n");
1882 return -1;
1883 }
1884 mpls_format_old = true;
1885 ret = get_u32(&label, *argv, 10);
1886 if (ret < 0 || label & ~(MPLS_LS_LABEL_MASK >> MPLS_LS_LABEL_SHIFT)) {
1887 fprintf(stderr, "Illegal \"mpls_label\"\n");
1888 return -1;
1889 }
1890 addattr32(n, MAX_MSG, TCA_FLOWER_KEY_MPLS_LABEL, label);
1891 } else if (matches(*argv, "mpls_tc") == 0) {
1892 __u8 tc;
1893
1894 NEXT_ARG();
1895 if (eth_type != htons(ETH_P_MPLS_UC) &&
1896 eth_type != htons(ETH_P_MPLS_MC)) {
1897 fprintf(stderr,
1898 "Can't set \"mpls_tc\" if ethertype isn't MPLS\n");
1899 return -1;
1900 }
1901 if (mpls_format_new) {
1902 fprintf(stderr,
1903 "Can't set \"mpls_tc\" if \"mpls\" is set\n");
1904 return -1;
1905 }
1906 mpls_format_old = true;
1907 ret = get_u8(&tc, *argv, 10);
1908 if (ret < 0 || tc & ~(MPLS_LS_TC_MASK >> MPLS_LS_TC_SHIFT)) {
1909 fprintf(stderr, "Illegal \"mpls_tc\"\n");
1910 return -1;
1911 }
1912 addattr8(n, MAX_MSG, TCA_FLOWER_KEY_MPLS_TC, tc);
1913 } else if (matches(*argv, "mpls_bos") == 0) {
1914 __u8 bos;
1915
1916 NEXT_ARG();
1917 if (eth_type != htons(ETH_P_MPLS_UC) &&
1918 eth_type != htons(ETH_P_MPLS_MC)) {
1919 fprintf(stderr,
1920 "Can't set \"mpls_bos\" if ethertype isn't MPLS\n");
1921 return -1;
1922 }
1923 if (mpls_format_new) {
1924 fprintf(stderr,
1925 "Can't set \"mpls_bos\" if \"mpls\" is set\n");
1926 return -1;
1927 }
1928 mpls_format_old = true;
1929 ret = get_u8(&bos, *argv, 10);
1930 if (ret < 0 || bos & ~(MPLS_LS_S_MASK >> MPLS_LS_S_SHIFT)) {
1931 fprintf(stderr, "Illegal \"mpls_bos\"\n");
1932 return -1;
1933 }
1934 addattr8(n, MAX_MSG, TCA_FLOWER_KEY_MPLS_BOS, bos);
1935 } else if (matches(*argv, "mpls_ttl") == 0) {
1936 __u8 ttl;
1937
1938 NEXT_ARG();
1939 if (eth_type != htons(ETH_P_MPLS_UC) &&
1940 eth_type != htons(ETH_P_MPLS_MC)) {
1941 fprintf(stderr,
1942 "Can't set \"mpls_ttl\" if ethertype isn't MPLS\n");
1943 return -1;
1944 }
1945 if (mpls_format_new) {
1946 fprintf(stderr,
1947 "Can't set \"mpls_ttl\" if \"mpls\" is set\n");
1948 return -1;
1949 }
1950 mpls_format_old = true;
1951 ret = get_u8(&ttl, *argv, 10);
1952 if (ret < 0) {
1953 fprintf(stderr, "Illegal \"mpls_ttl\"\n");
1954 return -1;
1955 }
1956 addattr8(n, MAX_MSG, TCA_FLOWER_KEY_MPLS_TTL, ttl);
1957 } else if (matches(*argv, "dst_mac") == 0) {
1958 NEXT_ARG();
1959 ret = flower_parse_eth_addr(*argv,
1960 TCA_FLOWER_KEY_ETH_DST,
1961 TCA_FLOWER_KEY_ETH_DST_MASK,
1962 n);
1963 if (ret < 0) {
1964 fprintf(stderr, "Illegal \"dst_mac\"\n");
1965 return -1;
1966 }
1967 } else if (matches(*argv, "src_mac") == 0) {
1968 NEXT_ARG();
1969 ret = flower_parse_eth_addr(*argv,
1970 TCA_FLOWER_KEY_ETH_SRC,
1971 TCA_FLOWER_KEY_ETH_SRC_MASK,
1972 n);
1973 if (ret < 0) {
1974 fprintf(stderr, "Illegal \"src_mac\"\n");
1975 return -1;
1976 }
1977 } else if (matches(*argv, "ip_proto") == 0) {
1978 NEXT_ARG();
1979 ret = flower_parse_ip_proto(*argv, eth_type,
1980 TCA_FLOWER_KEY_IP_PROTO,
1981 &ip_proto, n);
1982 if (ret < 0) {
1983 fprintf(stderr, "Illegal \"ip_proto\"\n");
1984 return -1;
1985 }
1986 } else if (matches(*argv, "ip_tos") == 0) {
1987 NEXT_ARG();
1988 ret = flower_parse_ip_tos_ttl(*argv,
1989 TCA_FLOWER_KEY_IP_TOS,
1990 TCA_FLOWER_KEY_IP_TOS_MASK,
1991 n);
1992 if (ret < 0) {
1993 fprintf(stderr, "Illegal \"ip_tos\"\n");
1994 return -1;
1995 }
1996 } else if (matches(*argv, "ip_ttl") == 0) {
1997 NEXT_ARG();
1998 ret = flower_parse_ip_tos_ttl(*argv,
1999 TCA_FLOWER_KEY_IP_TTL,
2000 TCA_FLOWER_KEY_IP_TTL_MASK,
2001 n);
2002 if (ret < 0) {
2003 fprintf(stderr, "Illegal \"ip_ttl\"\n");
2004 return -1;
2005 }
2006 } else if (matches(*argv, "dst_ip") == 0) {
2007 NEXT_ARG();
2008 ret = flower_parse_ip_addr(*argv, eth_type,
2009 TCA_FLOWER_KEY_IPV4_DST,
2010 TCA_FLOWER_KEY_IPV4_DST_MASK,
2011 TCA_FLOWER_KEY_IPV6_DST,
2012 TCA_FLOWER_KEY_IPV6_DST_MASK,
2013 n);
2014 if (ret < 0) {
2015 fprintf(stderr, "Illegal \"dst_ip\"\n");
2016 return -1;
2017 }
2018 } else if (matches(*argv, "src_ip") == 0) {
2019 NEXT_ARG();
2020 ret = flower_parse_ip_addr(*argv, eth_type,
2021 TCA_FLOWER_KEY_IPV4_SRC,
2022 TCA_FLOWER_KEY_IPV4_SRC_MASK,
2023 TCA_FLOWER_KEY_IPV6_SRC,
2024 TCA_FLOWER_KEY_IPV6_SRC_MASK,
2025 n);
2026 if (ret < 0) {
2027 fprintf(stderr, "Illegal \"src_ip\"\n");
2028 return -1;
2029 }
2030 } else if (matches(*argv, "dst_port") == 0) {
2031 NEXT_ARG();
2032 ret = flower_parse_port(*argv, ip_proto,
2033 FLOWER_ENDPOINT_DST, n);
2034 if (ret < 0) {
2035 fprintf(stderr, "Illegal \"dst_port\"\n");
2036 return -1;
2037 }
2038 } else if (matches(*argv, "src_port") == 0) {
2039 NEXT_ARG();
2040 ret = flower_parse_port(*argv, ip_proto,
2041 FLOWER_ENDPOINT_SRC, n);
2042 if (ret < 0) {
2043 fprintf(stderr, "Illegal \"src_port\"\n");
2044 return -1;
2045 }
2046 } else if (matches(*argv, "tcp_flags") == 0) {
2047 NEXT_ARG();
2048 ret = flower_parse_tcp_flags(*argv,
2049 TCA_FLOWER_KEY_TCP_FLAGS,
2050 TCA_FLOWER_KEY_TCP_FLAGS_MASK,
2051 n);
2052 if (ret < 0) {
2053 fprintf(stderr, "Illegal \"tcp_flags\"\n");
2054 return -1;
2055 }
2056 } else if (matches(*argv, "type") == 0) {
2057 NEXT_ARG();
2058 ret = flower_parse_icmp(*argv, eth_type, ip_proto,
2059 FLOWER_ICMP_FIELD_TYPE, n);
2060 if (ret < 0) {
2061 fprintf(stderr, "Illegal \"icmp type\"\n");
2062 return -1;
2063 }
2064 } else if (matches(*argv, "code") == 0) {
2065 NEXT_ARG();
2066 ret = flower_parse_icmp(*argv, eth_type, ip_proto,
2067 FLOWER_ICMP_FIELD_CODE, n);
2068 if (ret < 0) {
2069 fprintf(stderr, "Illegal \"icmp code\"\n");
2070 return -1;
2071 }
2072 } else if (!strcmp(*argv, "l2tpv3_sid")) {
2073 NEXT_ARG();
2074 ret = flower_parse_l2tpv3(*argv, ip_proto, n);
2075 if (ret < 0)
2076 return -1;
2077 } else if (!strcmp(*argv, "spi")) {
2078 NEXT_ARG();
2079 ret = flower_parse_spi(*argv, ip_proto, n);
2080 if (ret < 0)
2081 return -1;
2082 } else if (matches(*argv, "arp_tip") == 0) {
2083 NEXT_ARG();
2084 ret = flower_parse_arp_ip_addr(*argv, eth_type,
2085 TCA_FLOWER_KEY_ARP_TIP,
2086 TCA_FLOWER_KEY_ARP_TIP_MASK,
2087 n);
2088 if (ret < 0) {
2089 fprintf(stderr, "Illegal \"arp_tip\"\n");
2090 return -1;
2091 }
2092 } else if (matches(*argv, "arp_sip") == 0) {
2093 NEXT_ARG();
2094 ret = flower_parse_arp_ip_addr(*argv, eth_type,
2095 TCA_FLOWER_KEY_ARP_SIP,
2096 TCA_FLOWER_KEY_ARP_SIP_MASK,
2097 n);
2098 if (ret < 0) {
2099 fprintf(stderr, "Illegal \"arp_sip\"\n");
2100 return -1;
2101 }
2102 } else if (matches(*argv, "arp_op") == 0) {
2103 NEXT_ARG();
2104 ret = flower_parse_arp_op(*argv, eth_type,
2105 TCA_FLOWER_KEY_ARP_OP,
2106 TCA_FLOWER_KEY_ARP_OP_MASK,
2107 n);
2108 if (ret < 0) {
2109 fprintf(stderr, "Illegal \"arp_op\"\n");
2110 return -1;
2111 }
2112 } else if (matches(*argv, "arp_tha") == 0) {
2113 NEXT_ARG();
2114 ret = flower_parse_eth_addr(*argv,
2115 TCA_FLOWER_KEY_ARP_THA,
2116 TCA_FLOWER_KEY_ARP_THA_MASK,
2117 n);
2118 if (ret < 0) {
2119 fprintf(stderr, "Illegal \"arp_tha\"\n");
2120 return -1;
2121 }
2122 } else if (matches(*argv, "arp_sha") == 0) {
2123 NEXT_ARG();
2124 ret = flower_parse_eth_addr(*argv,
2125 TCA_FLOWER_KEY_ARP_SHA,
2126 TCA_FLOWER_KEY_ARP_SHA_MASK,
2127 n);
2128 if (ret < 0) {
2129 fprintf(stderr, "Illegal \"arp_sha\"\n");
2130 return -1;
2131 }
2132
2133 } else if (!strcmp(*argv, "pppoe_sid")) {
2134 __be16 sid;
2135
2136 NEXT_ARG();
2137 if (eth_type != htons(ETH_P_PPP_SES)) {
2138 fprintf(stderr,
2139 "Can't set \"pppoe_sid\" if ethertype isn't PPPoE session\n");
2140 return -1;
2141 }
2142 ret = get_be16(&sid, *argv, 10);
2143 if (ret < 0) {
2144 fprintf(stderr, "Illegal \"pppoe_sid\"\n");
2145 return -1;
2146 }
2147 addattr16(n, MAX_MSG, TCA_FLOWER_KEY_PPPOE_SID, sid);
2148 } else if (!strcmp(*argv, "ppp_proto")) {
2149 __be16 proto;
2150
2151 NEXT_ARG();
2152 if (eth_type != htons(ETH_P_PPP_SES)) {
2153 fprintf(stderr,
2154 "Can't set \"ppp_proto\" if ethertype isn't PPPoE session\n");
2155 return -1;
2156 }
2157 if (ppp_proto_a2n(&proto, *argv))
2158 invarg("invalid ppp_proto", *argv);
2159
2160 if (proto == htons(PPP_IP))
2161 eth_type = htons(ETH_P_IP);
2162 else if (proto == htons(PPP_IPV6))
2163 eth_type = htons(ETH_P_IPV6);
2164 else if (proto == htons(PPP_MPLS_UC))
2165 eth_type = htons(ETH_P_MPLS_UC);
2166 else if (proto == htons(PPP_MPLS_MC))
2167 eth_type = htons(ETH_P_MPLS_MC);
2168 addattr16(n, MAX_MSG, TCA_FLOWER_KEY_PPP_PROTO, proto);
2169 } else if (matches(*argv, "enc_dst_ip") == 0) {
2170 NEXT_ARG();
2171 ret = flower_parse_ip_addr(*argv, 0,
2172 TCA_FLOWER_KEY_ENC_IPV4_DST,
2173 TCA_FLOWER_KEY_ENC_IPV4_DST_MASK,
2174 TCA_FLOWER_KEY_ENC_IPV6_DST,
2175 TCA_FLOWER_KEY_ENC_IPV6_DST_MASK,
2176 n);
2177 if (ret < 0) {
2178 fprintf(stderr, "Illegal \"enc_dst_ip\"\n");
2179 return -1;
2180 }
2181 } else if (matches(*argv, "enc_src_ip") == 0) {
2182 NEXT_ARG();
2183 ret = flower_parse_ip_addr(*argv, 0,
2184 TCA_FLOWER_KEY_ENC_IPV4_SRC,
2185 TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK,
2186 TCA_FLOWER_KEY_ENC_IPV6_SRC,
2187 TCA_FLOWER_KEY_ENC_IPV6_SRC_MASK,
2188 n);
2189 if (ret < 0) {
2190 fprintf(stderr, "Illegal \"enc_src_ip\"\n");
2191 return -1;
2192 }
2193 } else if (matches(*argv, "enc_key_id") == 0) {
2194 NEXT_ARG();
2195 ret = flower_parse_key_id(*argv,
2196 TCA_FLOWER_KEY_ENC_KEY_ID, n);
2197 if (ret < 0) {
2198 fprintf(stderr, "Illegal \"enc_key_id\"\n");
2199 return -1;
2200 }
2201 } else if (matches(*argv, "enc_dst_port") == 0) {
2202 NEXT_ARG();
2203 ret = flower_parse_enc_port(*argv,
2204 TCA_FLOWER_KEY_ENC_UDP_DST_PORT, n);
2205 if (ret < 0) {
2206 fprintf(stderr, "Illegal \"enc_dst_port\"\n");
2207 return -1;
2208 }
2209 } else if (matches(*argv, "enc_tos") == 0) {
2210 NEXT_ARG();
2211 ret = flower_parse_ip_tos_ttl(*argv,
2212 TCA_FLOWER_KEY_ENC_IP_TOS,
2213 TCA_FLOWER_KEY_ENC_IP_TOS_MASK,
2214 n);
2215 if (ret < 0) {
2216 fprintf(stderr, "Illegal \"enc_tos\"\n");
2217 return -1;
2218 }
2219 } else if (matches(*argv, "enc_ttl") == 0) {
2220 NEXT_ARG();
2221 ret = flower_parse_ip_tos_ttl(*argv,
2222 TCA_FLOWER_KEY_ENC_IP_TTL,
2223 TCA_FLOWER_KEY_ENC_IP_TTL_MASK,
2224 n);
2225 if (ret < 0) {
2226 fprintf(stderr, "Illegal \"enc_ttl\"\n");
2227 return -1;
2228 }
2229 } else if (matches(*argv, "geneve_opts") == 0) {
2230 NEXT_ARG();
2231 ret = flower_parse_enc_opts_geneve(*argv, n);
2232 if (ret < 0) {
2233 fprintf(stderr, "Illegal \"geneve_opts\"\n");
2234 return -1;
2235 }
2236 } else if (matches(*argv, "vxlan_opts") == 0) {
2237 NEXT_ARG();
2238 ret = flower_parse_enc_opts_vxlan(*argv, n);
2239 if (ret < 0) {
2240 fprintf(stderr, "Illegal \"vxlan_opts\"\n");
2241 return -1;
2242 }
2243 } else if (matches(*argv, "erspan_opts") == 0) {
2244 NEXT_ARG();
2245 ret = flower_parse_enc_opts_erspan(*argv, n);
2246 if (ret < 0) {
2247 fprintf(stderr, "Illegal \"erspan_opts\"\n");
2248 return -1;
2249 }
2250 } else if (!strcmp(*argv, "gtp_opts")) {
2251 NEXT_ARG();
2252 ret = flower_parse_enc_opts_gtp(*argv, n);
2253 if (ret < 0) {
2254 fprintf(stderr, "Illegal \"gtp_opts\"\n");
2255 return -1;
2256 }
2257 } else if (!strcmp(*argv, "pfcp_opts")) {
2258 NEXT_ARG();
2259 ret = flower_parse_enc_opts_pfcp(*argv, n);
2260 if (ret < 0) {
2261 fprintf(stderr, "Illegal \"pfcp_opts\"\n");
2262 return -1;
2263 }
2264 } else if (!strcmp(*argv, "enc_flags")) {
2265 NEXT_ARG();
2266 ret = flower_parse_matching_flags(*argv,
2267 FLOWER_ENC_DST_FLAGS,
2268 &dst_flags,
2269 &dst_flags_mask);
2270
2271 if (ret < 0) {
2272 fprintf(stderr, "Illegal \"enc_flags\"\n");
2273 return -1;
2274 }
2275 } else if (matches(*argv, "action") == 0) {
2276 NEXT_ARG();
2277 ret = parse_action(&argc, &argv, TCA_FLOWER_ACT, n);
2278 if (ret) {
2279 fprintf(stderr, "Illegal \"action\"\n");
2280 return -1;
2281 }
2282 continue;
2283 } else if (!strcmp(*argv, "cfm")) {
2284 NEXT_ARG();
2285 ret = flower_parse_cfm(&argc, &argv, eth_type, n);
2286 if (ret < 0)
2287 return -1;
2288 continue;
2289 } else {
2290 if (strcmp(*argv, "help") != 0)
2291 fprintf(stderr, "What is \"%s\"?\n", *argv);
2292 explain();
2293 return -1;
2294 }
2295 argc--; argv++;
2296 }
2297
2298parse_done:
2299 ret = addattr32(n, MAX_MSG, TCA_FLOWER_FLAGS, flags);
2300 if (ret)
2301 return ret;
2302
2303 if (mtf_mask) {
2304 ret = addattr32(n, MAX_MSG, TCA_FLOWER_KEY_FLAGS, htonl(mtf));
2305 if (ret)
2306 return ret;
2307
2308 ret = addattr32(n, MAX_MSG, TCA_FLOWER_KEY_FLAGS_MASK, htonl(mtf_mask));
2309 if (ret)
2310 return ret;
2311 }
2312
2313 if (dst_flags_mask) {
2314 ret = addattr32(n, MAX_MSG, TCA_FLOWER_KEY_ENC_FLAGS,
2315 htonl(dst_flags));
2316 if (ret)
2317 return ret;
2318 ret = addattr32(n, MAX_MSG, TCA_FLOWER_KEY_ENC_FLAGS_MASK,
2319 htonl(dst_flags_mask));
2320 if (ret)
2321 return ret;
2322 }
2323
2324 if (tc_proto != htons(ETH_P_ALL)) {
2325 ret = addattr16(n, MAX_MSG, TCA_FLOWER_KEY_ETH_TYPE, tc_proto);
2326 if (ret)
2327 return ret;
2328 }
2329
2330 tail->rta_len = (((void *)n)+n->nlmsg_len) - (void *)tail;
2331
2332 return 0;
2333}
2334
2335static int __mask_bits(char *addr, size_t len)
2336{
2337 int bits = 0;
2338 bool hole = false;
2339 int i;
2340 int j;
2341
2342 for (i = 0; i < len; i++, addr++) {
2343 for (j = 7; j >= 0; j--) {
2344 if (((*addr) >> j) & 0x1) {
2345 if (hole)
2346 return -1;
2347 bits++;
2348 } else if (bits) {
2349 hole = true;
2350 } else {
2351 return -1;
2352 }
2353 }
2354 }
2355 return bits;
2356}
2357
2358static void flower_print_eth_addr(const char *name, struct rtattr *addr_attr,
2359 struct rtattr *mask_attr)
2360{
2361 SPRINT_BUF(out);
2362 SPRINT_BUF(b1);
2363 size_t done;
2364 int bits;
2365
2366 if (!addr_attr || RTA_PAYLOAD(addr_attr) != ETH_ALEN)
2367 return;
2368 done = sprintf(out, "%s",
2369 ll_addr_n2a(RTA_DATA(addr_attr), ETH_ALEN,
2370 0, b1, sizeof(b1)));
2371 if (mask_attr && RTA_PAYLOAD(mask_attr) == ETH_ALEN) {
2372 bits = __mask_bits(RTA_DATA(mask_attr), ETH_ALEN);
2373 if (bits < 0)
2374 sprintf(out + done, "/%s",
2375 ll_addr_n2a(RTA_DATA(mask_attr), ETH_ALEN,
2376 0, b1, sizeof(b1)));
2377 else if (bits < ETH_ALEN * 8)
2378 sprintf(out + done, "/%d", bits);
2379 }
2380
2381 print_indent_name_value(name, out);
2382}
2383
2384static void flower_print_eth_type(__be16 *p_eth_type,
2385 struct rtattr *eth_type_attr)
2386{
2387 SPRINT_BUF(out);
2388 __be16 eth_type;
2389
2390 if (!eth_type_attr)
2391 return;
2392
2393 eth_type = rta_getattr_u16(eth_type_attr);
2394 if (eth_type == htons(ETH_P_IP))
2395 sprintf(out, "ipv4");
2396 else if (eth_type == htons(ETH_P_IPV6))
2397 sprintf(out, "ipv6");
2398 else if (eth_type == htons(ETH_P_ARP))
2399 sprintf(out, "arp");
2400 else if (eth_type == htons(ETH_P_RARP))
2401 sprintf(out, "rarp");
2402 else
2403 sprintf(out, "%04x", ntohs(eth_type));
2404
2405 print_nl();
2406 print_string(PRINT_ANY, "eth_type", " eth_type %s", out);
2407 *p_eth_type = eth_type;
2408}
2409
2410static void flower_print_ip_proto(__u8 *p_ip_proto,
2411 struct rtattr *ip_proto_attr)
2412{
2413 SPRINT_BUF(out);
2414 __u8 ip_proto;
2415
2416 if (!ip_proto_attr)
2417 return;
2418
2419 ip_proto = rta_getattr_u8(ip_proto_attr);
2420 if (ip_proto == IPPROTO_TCP)
2421 sprintf(out, "tcp");
2422 else if (ip_proto == IPPROTO_UDP)
2423 sprintf(out, "udp");
2424 else if (ip_proto == IPPROTO_SCTP)
2425 sprintf(out, "sctp");
2426 else if (ip_proto == IPPROTO_ICMP)
2427 sprintf(out, "icmp");
2428 else if (ip_proto == IPPROTO_ICMPV6)
2429 sprintf(out, "icmpv6");
2430 else if (ip_proto == IPPROTO_L2TP)
2431 sprintf(out, "l2tp");
2432 else if (ip_proto == IPPROTO_ESP)
2433 sprintf(out, "esp");
2434 else if (ip_proto == IPPROTO_AH)
2435 sprintf(out, "ah");
2436 else
2437 sprintf(out, "0x%02x", ip_proto);
2438
2439 print_nl();
2440 print_string(PRINT_ANY, "ip_proto", " ip_proto %s", out);
2441 *p_ip_proto = ip_proto;
2442}
2443
2444static void flower_print_ip_attr(const char *name, struct rtattr *key_attr,
2445 struct rtattr *mask_attr)
2446{
2447 print_masked_u8(name, key_attr, mask_attr, true);
2448}
2449
2450static void flower_print_matching_flags(char *name,
2451 enum flower_matching_flags type,
2452 struct rtattr *attr,
2453 struct rtattr *mask_attr)
2454{
2455 int i;
2456 int count = 0;
2457 __u32 mtf;
2458 __u32 mtf_mask;
2459
2460 if (!mask_attr || RTA_PAYLOAD(mask_attr) != 4)
2461 return;
2462
2463 mtf = ntohl(rta_getattr_u32(attr));
2464 mtf_mask = ntohl(rta_getattr_u32(mask_attr));
2465
2466 for (i = 0; i < ARRAY_SIZE(flags_str); i++) {
2467 if (type != flags_str[i].type)
2468 continue;
2469 if (mtf_mask & flags_str[i].flag) {
2470 if (++count == 1) {
2471 print_nl();
2472 print_string(PRINT_FP, NULL, " %s ", name);
2473 open_json_object(name);
2474 } else {
2475 print_string(PRINT_FP, NULL, "/", NULL);
2476 }
2477
2478 print_bool(PRINT_JSON, flags_str[i].string, NULL,
2479 mtf & flags_str[i].flag);
2480 if (mtf & flags_str[i].flag)
2481 print_string(PRINT_FP, NULL, "%s",
2482 flags_str[i].string);
2483 else
2484 print_string(PRINT_FP, NULL, "no%s",
2485 flags_str[i].string);
2486 }
2487 }
2488 if (count)
2489 close_json_object();
2490}
2491
2492static void flower_print_ip_addr(char *name, __be16 eth_type,
2493 struct rtattr *addr4_attr,
2494 struct rtattr *mask4_attr,
2495 struct rtattr *addr6_attr,
2496 struct rtattr *mask6_attr)
2497{
2498 struct rtattr *addr_attr;
2499 struct rtattr *mask_attr;
2500 SPRINT_BUF(out);
2501 size_t done;
2502 int family;
2503 size_t len;
2504 int bits;
2505
2506 if (eth_type == htons(ETH_P_IP)) {
2507 family = AF_INET;
2508 addr_attr = addr4_attr;
2509 mask_attr = mask4_attr;
2510 len = 4;
2511 } else if (eth_type == htons(ETH_P_IPV6)) {
2512 family = AF_INET6;
2513 addr_attr = addr6_attr;
2514 mask_attr = mask6_attr;
2515 len = 16;
2516 } else {
2517 return;
2518 }
2519 if (!addr_attr || RTA_PAYLOAD(addr_attr) != len)
2520 return;
2521 if (!mask_attr || RTA_PAYLOAD(mask_attr) != len)
2522 return;
2523 done = sprintf(out, "%s", rt_addr_n2a_rta(family, addr_attr));
2524 bits = __mask_bits(RTA_DATA(mask_attr), len);
2525 if (bits < 0)
2526 sprintf(out + done, "/%s", rt_addr_n2a_rta(family, mask_attr));
2527 else if (bits < len * 8)
2528 sprintf(out + done, "/%d", bits);
2529
2530 print_indent_name_value(name, out);
2531}
2532
2533static void flower_print_ip4_addr(char *name, struct rtattr *addr_attr,
2534 struct rtattr *mask_attr)
2535{
2536 return flower_print_ip_addr(name, htons(ETH_P_IP),
2537 addr_attr, mask_attr, 0, 0);
2538}
2539
2540static void flower_print_port(char *name, struct rtattr *attr,
2541 struct rtattr *mask_attr)
2542{
2543 print_masked_be16(name, attr, mask_attr, true);
2544}
2545
2546static void flower_print_port_range(char *name, struct rtattr *min_attr,
2547 struct rtattr *max_attr)
2548{
2549 if (!min_attr || !max_attr)
2550 return;
2551
2552 if (is_json_context()) {
2553 open_json_object(name);
2554 print_hu(PRINT_JSON, "start", NULL, rta_getattr_be16(min_attr));
2555 print_hu(PRINT_JSON, "end", NULL, rta_getattr_be16(max_attr));
2556 close_json_object();
2557 } else {
2558 SPRINT_BUF(out);
2559 size_t done;
2560
2561 done = sprintf(out, "%u", rta_getattr_be16(min_attr));
2562 sprintf(out + done, "-%u", rta_getattr_be16(max_attr));
2563 print_indent_name_value(name, out);
2564 }
2565}
2566
2567static void flower_print_tcp_flags(const char *name, struct rtattr *flags_attr,
2568 struct rtattr *mask_attr)
2569{
2570 SPRINT_BUF(out);
2571 size_t done;
2572
2573 if (!flags_attr)
2574 return;
2575
2576 done = sprintf(out, "0x%x", rta_getattr_be16(flags_attr));
2577 if (mask_attr)
2578 sprintf(out + done, "/%x", rta_getattr_be16(mask_attr));
2579
2580 print_indent_name_value(name, out);
2581}
2582
2583static void flower_print_ct_state(struct rtattr *flags_attr,
2584 struct rtattr *mask_attr)
2585{
2586 SPRINT_BUF(out);
2587 uint16_t state;
2588 uint16_t state_mask;
2589 size_t done = 0;
2590 int i;
2591
2592 if (!flags_attr)
2593 return;
2594
2595 state = rta_getattr_u16(flags_attr);
2596 if (mask_attr)
2597 state_mask = rta_getattr_u16(mask_attr);
2598 else
2599 state_mask = UINT16_MAX;
2600
2601 for (i = 0; i < ARRAY_SIZE(flower_ct_states); i++) {
2602 if (!(state_mask & flower_ct_states[i].flag))
2603 continue;
2604
2605 if (state & flower_ct_states[i].flag)
2606 done += sprintf(out + done, "+%s",
2607 flower_ct_states[i].str);
2608 else
2609 done += sprintf(out + done, "-%s",
2610 flower_ct_states[i].str);
2611 }
2612
2613 print_nl();
2614 print_string(PRINT_ANY, "ct_state", " ct_state %s", out);
2615}
2616
2617static void flower_print_ct_label(struct rtattr *attr,
2618 struct rtattr *mask_attr)
2619{
2620 const unsigned char *str;
2621 bool print_mask = false;
2622 int data_len, i;
2623 char out[128];
2624 char *p;
2625
2626 if (!attr)
2627 return;
2628
2629 data_len = RTA_PAYLOAD(attr);
2630 hexstring_n2a(RTA_DATA(attr), data_len, out, sizeof(out));
2631 p = out + data_len*2;
2632
2633 data_len = RTA_PAYLOAD(attr);
2634 str = RTA_DATA(mask_attr);
2635 if (data_len != 16)
2636 print_mask = true;
2637 for (i = 0; !print_mask && i < data_len; i++) {
2638 if (str[i] != 0xff)
2639 print_mask = true;
2640 }
2641 if (print_mask) {
2642 *p++ = '/';
2643 hexstring_n2a(RTA_DATA(mask_attr), data_len, p,
2644 sizeof(out)-(p-out));
2645 p += data_len*2;
2646 }
2647 *p = '\0';
2648
2649 print_nl();
2650 print_string(PRINT_ANY, "ct_label", " ct_label %s", out);
2651}
2652
2653static void flower_print_ct_zone(struct rtattr *attr,
2654 struct rtattr *mask_attr)
2655{
2656 print_masked_u16("ct_zone", attr, mask_attr, true);
2657}
2658
2659static void flower_print_ct_mark(struct rtattr *attr,
2660 struct rtattr *mask_attr)
2661{
2662 print_masked_u32("ct_mark", attr, mask_attr, true);
2663}
2664
2665static void flower_print_key_id(const char *name, struct rtattr *attr)
2666{
2667 if (!attr)
2668 return;
2669
2670 print_nl();
2671 print_uint_indent_name_value(name, rta_getattr_be32(attr));
2672}
2673
2674static void flower_print_geneve_opts(const char *name, struct rtattr *attr,
2675 char *strbuf)
2676{
2677 struct rtattr *tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX + 1];
2678 int ii, data_len, offset = 0, slen = 0;
2679 struct rtattr *i = RTA_DATA(attr);
2680 int rem = RTA_PAYLOAD(attr);
2681 __u8 type, data_r[rem];
2682 char data[rem * 2 + 1];
2683 __u16 class;
2684
2685 open_json_array(PRINT_JSON, name);
2686 while (rem) {
2687 parse_rtattr(tb, TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX, i, rem);
2688 class = rta_getattr_be16(tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_CLASS]);
2689 type = rta_getattr_u8(tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_TYPE]);
2690 data_len = RTA_PAYLOAD(tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_DATA]);
2691 hexstring_n2a(RTA_DATA(tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_DATA]),
2692 data_len, data, sizeof(data));
2693 hex2mem(data, data_r, data_len);
2694 offset += data_len + 20;
2695 rem -= data_len + 20;
2696 i = RTA_DATA(attr) + offset;
2697
2698 open_json_object(NULL);
2699 print_uint(PRINT_JSON, "class", NULL, class);
2700 print_uint(PRINT_JSON, "type", NULL, type);
2701 open_json_array(PRINT_JSON, "data");
2702 for (ii = 0; ii < data_len; ii++)
2703 print_uint(PRINT_JSON, NULL, NULL, data_r[ii]);
2704 close_json_array(PRINT_JSON, "data");
2705 close_json_object();
2706
2707 slen += sprintf(strbuf + slen, "%04x:%02x:%s",
2708 class, type, data);
2709 if (rem)
2710 slen += sprintf(strbuf + slen, ",");
2711 }
2712 close_json_array(PRINT_JSON, name);
2713}
2714
2715static void flower_print_vxlan_opts(const char *name, struct rtattr *attr,
2716 char *strbuf)
2717{
2718 struct rtattr *tb[TCA_FLOWER_KEY_ENC_OPT_VXLAN_MAX + 1];
2719 struct rtattr *i = RTA_DATA(attr);
2720 int rem = RTA_PAYLOAD(attr);
2721 __u32 gbp;
2722
2723 parse_rtattr(tb, TCA_FLOWER_KEY_ENC_OPT_VXLAN_MAX, i, rem);
2724 gbp = rta_getattr_u32(tb[TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP]);
2725
2726 open_json_array(PRINT_JSON, name);
2727 open_json_object(NULL);
2728 print_uint(PRINT_JSON, "gbp", NULL, gbp);
2729 close_json_object();
2730 close_json_array(PRINT_JSON, name);
2731
2732 sprintf(strbuf, "%u", gbp);
2733}
2734
2735static void flower_print_erspan_opts(const char *name, struct rtattr *attr,
2736 char *strbuf)
2737{
2738 struct rtattr *tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_MAX + 1];
2739 __u8 ver, hwid, dir;
2740 __u32 idx;
2741
2742 parse_rtattr(tb, TCA_FLOWER_KEY_ENC_OPT_ERSPAN_MAX, RTA_DATA(attr),
2743 RTA_PAYLOAD(attr));
2744 ver = rta_getattr_u8(tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_VER]);
2745 if (ver == 1) {
2746 idx = rta_getattr_be32(tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_INDEX]);
2747 hwid = 0;
2748 dir = 0;
2749 } else {
2750 idx = 0;
2751 hwid = rta_getattr_u8(tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_HWID]);
2752 dir = rta_getattr_u8(tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_DIR]);
2753 }
2754
2755 open_json_array(PRINT_JSON, name);
2756 open_json_object(NULL);
2757 print_uint(PRINT_JSON, "ver", NULL, ver);
2758 print_uint(PRINT_JSON, "index", NULL, idx);
2759 print_uint(PRINT_JSON, "dir", NULL, dir);
2760 print_uint(PRINT_JSON, "hwid", NULL, hwid);
2761 close_json_object();
2762 close_json_array(PRINT_JSON, name);
2763
2764 sprintf(strbuf, "%u:%u:%u:%u", ver, idx, dir, hwid);
2765}
2766
2767static void flower_print_gtp_opts(const char *name, struct rtattr *attr,
2768 char *strbuf, int len)
2769{
2770 struct rtattr *tb[TCA_FLOWER_KEY_ENC_OPT_GTP_MAX + 1];
2771 __u8 pdu_type, qfi;
2772
2773 parse_rtattr(tb, TCA_FLOWER_KEY_ENC_OPT_GTP_MAX, RTA_DATA(attr),
2774 RTA_PAYLOAD(attr));
2775
2776 pdu_type = rta_getattr_u8(tb[TCA_FLOWER_KEY_ENC_OPT_GTP_PDU_TYPE]);
2777 qfi = rta_getattr_u8(tb[TCA_FLOWER_KEY_ENC_OPT_GTP_QFI]);
2778
2779 snprintf(strbuf, len, "%02x:%02x", pdu_type, qfi);
2780}
2781
2782static void flower_print_pfcp_opts(const char *name, struct rtattr *attr,
2783 char *strbuf, int len)
2784{
2785 struct rtattr *tb[TCA_FLOWER_KEY_ENC_OPT_PFCP_MAX + 1];
2786 struct rtattr *i = RTA_DATA(attr);
2787 int rem = RTA_PAYLOAD(attr);
2788 __be64 seid;
2789 __u8 type;
2790
2791 parse_rtattr(tb, TCA_FLOWER_KEY_ENC_OPT_PFCP_MAX, i, rem);
2792 type = rta_getattr_u8(tb[TCA_FLOWER_KEY_ENC_OPT_PFCP_TYPE]);
2793 seid = rta_getattr_be64(tb[TCA_FLOWER_KEY_ENC_OPT_PFCP_SEID]);
2794
2795 open_json_array(PRINT_JSON, name);
2796 open_json_object(NULL);
2797 print_uint(PRINT_JSON, "type", NULL, type);
2798 print_uint(PRINT_JSON, "seid", NULL, seid);
2799 close_json_object();
2800 close_json_array(PRINT_JSON, name);
2801
2802 snprintf(strbuf, len, "%02x:%llx", type, seid);
2803}
2804
2805static void __attribute__((format(printf, 2, 0)))
2806flower_print_enc_parts(const char *name, const char *namefrm,
2807 struct rtattr *attr, char *key, char *mask)
2808{
2809 char *key_token, *mask_token, *out;
2810 int len;
2811
2812 out = malloc(RTA_PAYLOAD(attr) * 4 + 3);
2813 if (!out)
2814 return;
2815
2816 len = 0;
2817 key_token = strsep(&key, ",");
2818 mask_token = strsep(&mask, ",");
2819 while (key_token) {
2820 len += sprintf(&out[len], "%s/%s,", key_token, mask_token);
2821 mask_token = strsep(&mask, ",");
2822 key_token = strsep(&key, ",");
2823 }
2824
2825 out[len - 1] = '\0';
2826 print_nl();
2827 print_string(PRINT_FP, name, namefrm, out);
2828 free(out);
2829}
2830
2831static void flower_print_enc_opts(const char *name, struct rtattr *attr,
2832 struct rtattr *mask_attr)
2833{
2834 struct rtattr *key_tb[TCA_FLOWER_KEY_ENC_OPTS_MAX + 1];
2835 struct rtattr *msk_tb[TCA_FLOWER_KEY_ENC_OPTS_MAX + 1];
2836 char *key, *msk;
2837 int len;
2838
2839 if (!attr)
2840 return;
2841
2842 len = RTA_PAYLOAD(attr) * 2 + 1;
2843
2844 key = malloc(len);
2845 if (!key)
2846 return;
2847
2848 msk = malloc(len);
2849 if (!msk)
2850 goto err_key_free;
2851
2852 parse_rtattr_nested(key_tb, TCA_FLOWER_KEY_ENC_OPTS_MAX, attr);
2853 parse_rtattr_nested(msk_tb, TCA_FLOWER_KEY_ENC_OPTS_MAX, mask_attr);
2854
2855 if (key_tb[TCA_FLOWER_KEY_ENC_OPTS_GENEVE]) {
2856 flower_print_geneve_opts("geneve_opt_key",
2857 key_tb[TCA_FLOWER_KEY_ENC_OPTS_GENEVE], key);
2858
2859 if (msk_tb[TCA_FLOWER_KEY_ENC_OPTS_GENEVE])
2860 flower_print_geneve_opts("geneve_opt_mask",
2861 msk_tb[TCA_FLOWER_KEY_ENC_OPTS_GENEVE], msk);
2862
2863 flower_print_enc_parts(name, " geneve_opts %s", attr, key,
2864 msk);
2865 } else if (key_tb[TCA_FLOWER_KEY_ENC_OPTS_VXLAN]) {
2866 flower_print_vxlan_opts("vxlan_opt_key",
2867 key_tb[TCA_FLOWER_KEY_ENC_OPTS_VXLAN], key);
2868
2869 if (msk_tb[TCA_FLOWER_KEY_ENC_OPTS_VXLAN])
2870 flower_print_vxlan_opts("vxlan_opt_mask",
2871 msk_tb[TCA_FLOWER_KEY_ENC_OPTS_VXLAN], msk);
2872
2873 flower_print_enc_parts(name, " vxlan_opts %s", attr, key,
2874 msk);
2875 } else if (key_tb[TCA_FLOWER_KEY_ENC_OPTS_ERSPAN]) {
2876 flower_print_erspan_opts("erspan_opt_key",
2877 key_tb[TCA_FLOWER_KEY_ENC_OPTS_ERSPAN], key);
2878
2879 if (msk_tb[TCA_FLOWER_KEY_ENC_OPTS_ERSPAN])
2880 flower_print_erspan_opts("erspan_opt_mask",
2881 msk_tb[TCA_FLOWER_KEY_ENC_OPTS_ERSPAN], msk);
2882
2883 flower_print_enc_parts(name, " erspan_opts %s", attr, key,
2884 msk);
2885 } else if (key_tb[TCA_FLOWER_KEY_ENC_OPTS_GTP]) {
2886 flower_print_gtp_opts("gtp_opt_key",
2887 key_tb[TCA_FLOWER_KEY_ENC_OPTS_GTP],
2888 key, len);
2889
2890 if (msk_tb[TCA_FLOWER_KEY_ENC_OPTS_GTP])
2891 flower_print_gtp_opts("gtp_opt_mask",
2892 msk_tb[TCA_FLOWER_KEY_ENC_OPTS_GTP],
2893 msk, len);
2894
2895 flower_print_enc_parts(name, " gtp_opts %s", attr, key,
2896 msk);
2897 } else if (key_tb[TCA_FLOWER_KEY_ENC_OPTS_PFCP]) {
2898 flower_print_pfcp_opts("pfcp_opt_key",
2899 key_tb[TCA_FLOWER_KEY_ENC_OPTS_PFCP],
2900 key, len);
2901
2902 if (msk_tb[TCA_FLOWER_KEY_ENC_OPTS_PFCP])
2903 flower_print_pfcp_opts("pfcp_opt_mask",
2904 msk_tb[TCA_FLOWER_KEY_ENC_OPTS_PFCP],
2905 msk, len);
2906
2907 flower_print_enc_parts(name, " pfcp_opts %s", attr, key,
2908 msk);
2909 }
2910
2911 free(msk);
2912err_key_free:
2913 free(key);
2914}
2915
2916static void flower_print_masked_u8(const char *name, struct rtattr *attr,
2917 struct rtattr *mask_attr,
2918 const char *(*value_to_str)(__u8 value))
2919{
2920 const char *value_str = NULL;
2921 __u8 value, mask;
2922 SPRINT_BUF(out);
2923 size_t done;
2924
2925 if (!attr)
2926 return;
2927
2928 value = rta_getattr_u8(attr);
2929 mask = mask_attr ? rta_getattr_u8(mask_attr) : UINT8_MAX;
2930 if (mask == UINT8_MAX && value_to_str)
2931 value_str = value_to_str(value);
2932
2933 if (value_str)
2934 done = sprintf(out, "%s", value_str);
2935 else
2936 done = sprintf(out, "%d", value);
2937
2938 if (mask != UINT8_MAX)
2939 sprintf(out + done, "/%d", mask);
2940
2941 print_indent_name_value(name, out);
2942}
2943
2944static void flower_print_u8(const char *name, struct rtattr *attr)
2945{
2946 flower_print_masked_u8(name, attr, NULL, NULL);
2947}
2948
2949static void flower_print_u32(const char *name, struct rtattr *attr)
2950{
2951 if (!attr)
2952 return;
2953
2954 print_nl();
2955 print_uint_indent_name_value(name, rta_getattr_u32(attr));
2956}
2957
2958static void flower_print_mpls_opt_lse(struct rtattr *lse)
2959{
2960 struct rtattr *tb[TCA_FLOWER_KEY_MPLS_OPT_LSE_MAX + 1];
2961 struct rtattr *attr;
2962
2963 if (lse->rta_type != (TCA_FLOWER_KEY_MPLS_OPTS_LSE | NLA_F_NESTED)) {
2964 fprintf(stderr, "rta_type 0x%x, expecting 0x%x (0x%x & 0x%x)\n",
2965 lse->rta_type,
2966 TCA_FLOWER_KEY_MPLS_OPTS_LSE & NLA_F_NESTED,
2967 TCA_FLOWER_KEY_MPLS_OPTS_LSE, NLA_F_NESTED);
2968 return;
2969 }
2970
2971 parse_rtattr(tb, TCA_FLOWER_KEY_MPLS_OPT_LSE_MAX, RTA_DATA(lse),
2972 RTA_PAYLOAD(lse));
2973
2974 print_nl();
2975 print_string(PRINT_FP, NULL, " lse", NULL);
2976 open_json_object(NULL);
2977 attr = tb[TCA_FLOWER_KEY_MPLS_OPT_LSE_DEPTH];
2978 if (attr)
2979 print_hhu(PRINT_ANY, "depth", " depth %u",
2980 rta_getattr_u8(attr));
2981 attr = tb[TCA_FLOWER_KEY_MPLS_OPT_LSE_LABEL];
2982 if (attr)
2983 print_uint(PRINT_ANY, "label", " label %u",
2984 rta_getattr_u32(attr));
2985 attr = tb[TCA_FLOWER_KEY_MPLS_OPT_LSE_TC];
2986 if (attr)
2987 print_hhu(PRINT_ANY, "tc", " tc %u", rta_getattr_u8(attr));
2988 attr = tb[TCA_FLOWER_KEY_MPLS_OPT_LSE_BOS];
2989 if (attr)
2990 print_hhu(PRINT_ANY, "bos", " bos %u", rta_getattr_u8(attr));
2991 attr = tb[TCA_FLOWER_KEY_MPLS_OPT_LSE_TTL];
2992 if (attr)
2993 print_hhu(PRINT_ANY, "ttl", " ttl %u", rta_getattr_u8(attr));
2994 close_json_object();
2995}
2996
2997static void flower_print_mpls_opts(struct rtattr *attr)
2998{
2999 struct rtattr *lse;
3000 int rem;
3001
3002 if (!attr || !(attr->rta_type & NLA_F_NESTED))
3003 return;
3004
3005 print_nl();
3006 print_string(PRINT_FP, NULL, " mpls", NULL);
3007 open_json_array(PRINT_JSON, "mpls");
3008 rem = RTA_PAYLOAD(attr);
3009 lse = RTA_DATA(attr);
3010 while (RTA_OK(lse, rem)) {
3011 flower_print_mpls_opt_lse(lse);
3012 lse = RTA_NEXT(lse, rem);
3013 };
3014 if (rem)
3015 fprintf(stderr, "!!!Deficit %d, rta_len=%d\n",
3016 rem, lse->rta_len);
3017 close_json_array(PRINT_JSON, NULL);
3018}
3019
3020static void flower_print_arp_op(const char *name,
3021 struct rtattr *op_attr,
3022 struct rtattr *mask_attr)
3023{
3024 flower_print_masked_u8(name, op_attr, mask_attr,
3025 flower_print_arp_op_to_name);
3026}
3027
3028static void flower_print_cfm(struct rtattr *attr)
3029{
3030 struct rtattr *tb[TCA_FLOWER_KEY_CFM_OPT_MAX + 1];
3031
3032 if (!attr || !(attr->rta_type & NLA_F_NESTED))
3033 return;
3034
3035 parse_rtattr(tb, TCA_FLOWER_KEY_CFM_OPT_MAX, RTA_DATA(attr),
3036 RTA_PAYLOAD(attr));
3037
3038 print_nl();
3039 print_string(PRINT_FP, NULL, " cfm", NULL);
3040 open_json_object("cfm");
3041
3042 if (tb[TCA_FLOWER_KEY_CFM_MD_LEVEL])
3043 print_hhu(PRINT_ANY, "mdl", " mdl %u",
3044 rta_getattr_u8(tb[TCA_FLOWER_KEY_CFM_MD_LEVEL]));
3045
3046 if (tb[TCA_FLOWER_KEY_CFM_OPCODE])
3047 print_hhu(PRINT_ANY, "op", " op %u",
3048 rta_getattr_u8(tb[TCA_FLOWER_KEY_CFM_OPCODE]));
3049
3050 close_json_object();
3051}
3052
3053static int flower_print_opt(const struct filter_util *qu, FILE *f,
3054 struct rtattr *opt, __u32 handle)
3055{
3056 struct rtattr *tb[TCA_FLOWER_MAX + 1];
3057 __be16 min_port_type, max_port_type;
3058 int nl_type, nl_mask_type;
3059 __be16 eth_type = 0;
3060 __u8 ip_proto = 0xff;
3061
3062 if (!opt)
3063 return 0;
3064
3065 parse_rtattr_nested(tb, TCA_FLOWER_MAX, opt);
3066
3067 if (handle)
3068 print_uint(PRINT_ANY, "handle", "handle 0x%x ", handle);
3069
3070 if (tb[TCA_FLOWER_CLASSID]) {
3071 __u32 h = rta_getattr_u32(tb[TCA_FLOWER_CLASSID]);
3072
3073 if (TC_H_MIN(h) < TC_H_MIN_PRIORITY ||
3074 TC_H_MIN(h) > (TC_H_MIN_PRIORITY + TC_QOPT_MAX_QUEUE - 1)) {
3075 SPRINT_BUF(b1);
3076 print_string(PRINT_ANY, "classid", "classid %s ",
3077 sprint_tc_classid(h, b1));
3078 } else {
3079 print_uint(PRINT_ANY, "hw_tc", "hw_tc %u ",
3080 TC_H_MIN(h) - TC_H_MIN_PRIORITY);
3081 }
3082 }
3083
3084 if (tb[TCA_FLOWER_INDEV]) {
3085 struct rtattr *attr = tb[TCA_FLOWER_INDEV];
3086
3087 print_nl();
3088 print_string(PRINT_ANY, "indev", " indev %s",
3089 rta_getattr_str(attr));
3090 }
3091
3092 open_json_object("keys");
3093
3094 if (tb[TCA_FLOWER_KEY_NUM_OF_VLANS]) {
3095 struct rtattr *attr = tb[TCA_FLOWER_KEY_NUM_OF_VLANS];
3096
3097 print_nl();
3098 print_uint(PRINT_ANY, "num_of_vlans", " num_of_vlans %d",
3099 rta_getattr_u8(attr));
3100 }
3101
3102 if (tb[TCA_FLOWER_KEY_VLAN_ID]) {
3103 struct rtattr *attr = tb[TCA_FLOWER_KEY_VLAN_ID];
3104
3105 print_nl();
3106 print_uint(PRINT_ANY, "vlan_id", " vlan_id %u",
3107 rta_getattr_u16(attr));
3108 }
3109
3110 if (tb[TCA_FLOWER_KEY_VLAN_PRIO]) {
3111 struct rtattr *attr = tb[TCA_FLOWER_KEY_VLAN_PRIO];
3112
3113 print_nl();
3114 print_uint(PRINT_ANY, "vlan_prio", " vlan_prio %d",
3115 rta_getattr_u8(attr));
3116 }
3117
3118 if (tb[TCA_FLOWER_KEY_VLAN_ETH_TYPE]) {
3119 SPRINT_BUF(buf);
3120 struct rtattr *attr = tb[TCA_FLOWER_KEY_VLAN_ETH_TYPE];
3121
3122 print_nl();
3123 print_string(PRINT_ANY, "vlan_ethtype", " vlan_ethtype %s",
3124 ll_proto_n2a(rta_getattr_u16(attr),
3125 buf, sizeof(buf)));
3126 }
3127
3128 if (tb[TCA_FLOWER_KEY_CVLAN_ID]) {
3129 struct rtattr *attr = tb[TCA_FLOWER_KEY_CVLAN_ID];
3130
3131 print_nl();
3132 print_uint(PRINT_ANY, "cvlan_id", " cvlan_id %u",
3133 rta_getattr_u16(attr));
3134 }
3135
3136 if (tb[TCA_FLOWER_KEY_CVLAN_PRIO]) {
3137 struct rtattr *attr = tb[TCA_FLOWER_KEY_CVLAN_PRIO];
3138
3139 print_nl();
3140 print_uint(PRINT_ANY, "cvlan_prio", " cvlan_prio %d",
3141 rta_getattr_u8(attr));
3142 }
3143
3144 if (tb[TCA_FLOWER_KEY_CVLAN_ETH_TYPE]) {
3145 SPRINT_BUF(buf);
3146 struct rtattr *attr = tb[TCA_FLOWER_KEY_CVLAN_ETH_TYPE];
3147
3148 print_nl();
3149 print_string(PRINT_ANY, "cvlan_ethtype", " cvlan_ethtype %s",
3150 ll_proto_n2a(rta_getattr_u16(attr),
3151 buf, sizeof(buf)));
3152 }
3153
3154 flower_print_eth_addr("dst_mac", tb[TCA_FLOWER_KEY_ETH_DST],
3155 tb[TCA_FLOWER_KEY_ETH_DST_MASK]);
3156 flower_print_eth_addr("src_mac", tb[TCA_FLOWER_KEY_ETH_SRC],
3157 tb[TCA_FLOWER_KEY_ETH_SRC_MASK]);
3158
3159 flower_print_eth_type(ð_type, tb[TCA_FLOWER_KEY_ETH_TYPE]);
3160 flower_print_ip_proto(&ip_proto, tb[TCA_FLOWER_KEY_IP_PROTO]);
3161
3162 flower_print_ip_attr("ip_tos", tb[TCA_FLOWER_KEY_IP_TOS],
3163 tb[TCA_FLOWER_KEY_IP_TOS_MASK]);
3164 flower_print_ip_attr("ip_ttl", tb[TCA_FLOWER_KEY_IP_TTL],
3165 tb[TCA_FLOWER_KEY_IP_TTL_MASK]);
3166
3167 flower_print_mpls_opts(tb[TCA_FLOWER_KEY_MPLS_OPTS]);
3168 flower_print_u32("mpls_label", tb[TCA_FLOWER_KEY_MPLS_LABEL]);
3169 flower_print_u8("mpls_tc", tb[TCA_FLOWER_KEY_MPLS_TC]);
3170 flower_print_u8("mpls_bos", tb[TCA_FLOWER_KEY_MPLS_BOS]);
3171 flower_print_u8("mpls_ttl", tb[TCA_FLOWER_KEY_MPLS_TTL]);
3172
3173 flower_print_ip_addr("dst_ip", eth_type,
3174 tb[TCA_FLOWER_KEY_IPV4_DST],
3175 tb[TCA_FLOWER_KEY_IPV4_DST_MASK],
3176 tb[TCA_FLOWER_KEY_IPV6_DST],
3177 tb[TCA_FLOWER_KEY_IPV6_DST_MASK]);
3178
3179 flower_print_ip_addr("src_ip", eth_type,
3180 tb[TCA_FLOWER_KEY_IPV4_SRC],
3181 tb[TCA_FLOWER_KEY_IPV4_SRC_MASK],
3182 tb[TCA_FLOWER_KEY_IPV6_SRC],
3183 tb[TCA_FLOWER_KEY_IPV6_SRC_MASK]);
3184
3185 nl_type = flower_port_attr_type(ip_proto, FLOWER_ENDPOINT_DST);
3186 nl_mask_type = flower_port_attr_mask_type(ip_proto, FLOWER_ENDPOINT_DST);
3187 if (nl_type >= 0)
3188 flower_print_port("dst_port", tb[nl_type], tb[nl_mask_type]);
3189 nl_type = flower_port_attr_type(ip_proto, FLOWER_ENDPOINT_SRC);
3190 nl_mask_type = flower_port_attr_mask_type(ip_proto, FLOWER_ENDPOINT_SRC);
3191 if (nl_type >= 0)
3192 flower_print_port("src_port", tb[nl_type], tb[nl_mask_type]);
3193
3194 if (!flower_port_range_attr_type(ip_proto, FLOWER_ENDPOINT_DST,
3195 &min_port_type, &max_port_type))
3196 flower_print_port_range("dst_port",
3197 tb[min_port_type], tb[max_port_type]);
3198
3199 if (!flower_port_range_attr_type(ip_proto, FLOWER_ENDPOINT_SRC,
3200 &min_port_type, &max_port_type))
3201 flower_print_port_range("src_port",
3202 tb[min_port_type], tb[max_port_type]);
3203
3204 flower_print_tcp_flags("tcp_flags", tb[TCA_FLOWER_KEY_TCP_FLAGS],
3205 tb[TCA_FLOWER_KEY_TCP_FLAGS_MASK]);
3206
3207 nl_type = flower_icmp_attr_type(eth_type, ip_proto,
3208 FLOWER_ICMP_FIELD_TYPE);
3209 nl_mask_type = flower_icmp_attr_mask_type(eth_type, ip_proto,
3210 FLOWER_ICMP_FIELD_TYPE);
3211 if (nl_type >= 0 && nl_mask_type >= 0)
3212 flower_print_masked_u8("icmp_type", tb[nl_type],
3213 tb[nl_mask_type], NULL);
3214
3215 nl_type = flower_icmp_attr_type(eth_type, ip_proto,
3216 FLOWER_ICMP_FIELD_CODE);
3217 nl_mask_type = flower_icmp_attr_mask_type(eth_type, ip_proto,
3218 FLOWER_ICMP_FIELD_CODE);
3219 if (nl_type >= 0 && nl_mask_type >= 0)
3220 flower_print_masked_u8("icmp_code", tb[nl_type],
3221 tb[nl_mask_type], NULL);
3222
3223 if (tb[TCA_FLOWER_KEY_L2TPV3_SID]) {
3224 struct rtattr *attr = tb[TCA_FLOWER_KEY_L2TPV3_SID];
3225
3226 print_nl();
3227 print_uint(PRINT_ANY, "l2tpv3_sid", " l2tpv3_sid %u",
3228 rta_getattr_be32(attr));
3229 }
3230
3231 if (tb[TCA_FLOWER_KEY_SPI]) {
3232 struct rtattr *attr = tb[TCA_FLOWER_KEY_SPI];
3233
3234 print_nl();
3235 print_hex(PRINT_ANY, "spi", " spi 0x%x",
3236 rta_getattr_be32(attr));
3237 }
3238
3239 flower_print_ip4_addr("arp_sip", tb[TCA_FLOWER_KEY_ARP_SIP],
3240 tb[TCA_FLOWER_KEY_ARP_SIP_MASK]);
3241 flower_print_ip4_addr("arp_tip", tb[TCA_FLOWER_KEY_ARP_TIP],
3242 tb[TCA_FLOWER_KEY_ARP_TIP_MASK]);
3243 flower_print_arp_op("arp_op", tb[TCA_FLOWER_KEY_ARP_OP],
3244 tb[TCA_FLOWER_KEY_ARP_OP_MASK]);
3245 flower_print_eth_addr("arp_sha", tb[TCA_FLOWER_KEY_ARP_SHA],
3246 tb[TCA_FLOWER_KEY_ARP_SHA_MASK]);
3247 flower_print_eth_addr("arp_tha", tb[TCA_FLOWER_KEY_ARP_THA],
3248 tb[TCA_FLOWER_KEY_ARP_THA_MASK]);
3249
3250 if (tb[TCA_FLOWER_KEY_PPPOE_SID]) {
3251 struct rtattr *attr = tb[TCA_FLOWER_KEY_PPPOE_SID];
3252
3253 print_nl();
3254 print_uint(PRINT_ANY, "pppoe_sid", " pppoe_sid %u",
3255 rta_getattr_be16(attr));
3256 }
3257
3258 if (tb[TCA_FLOWER_KEY_PPP_PROTO]) {
3259 SPRINT_BUF(buf);
3260 struct rtattr *attr = tb[TCA_FLOWER_KEY_PPP_PROTO];
3261
3262 print_nl();
3263 print_string(PRINT_ANY, "ppp_proto", " ppp_proto %s",
3264 ppp_proto_n2a(rta_getattr_u16(attr),
3265 buf, sizeof(buf)));
3266 }
3267
3268 flower_print_ip_addr("enc_dst_ip",
3269 tb[TCA_FLOWER_KEY_ENC_IPV4_DST_MASK] ?
3270 htons(ETH_P_IP) : htons(ETH_P_IPV6),
3271 tb[TCA_FLOWER_KEY_ENC_IPV4_DST],
3272 tb[TCA_FLOWER_KEY_ENC_IPV4_DST_MASK],
3273 tb[TCA_FLOWER_KEY_ENC_IPV6_DST],
3274 tb[TCA_FLOWER_KEY_ENC_IPV6_DST_MASK]);
3275
3276 flower_print_ip_addr("enc_src_ip",
3277 tb[TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK] ?
3278 htons(ETH_P_IP) : htons(ETH_P_IPV6),
3279 tb[TCA_FLOWER_KEY_ENC_IPV4_SRC],
3280 tb[TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK],
3281 tb[TCA_FLOWER_KEY_ENC_IPV6_SRC],
3282 tb[TCA_FLOWER_KEY_ENC_IPV6_SRC_MASK]);
3283
3284 flower_print_key_id("enc_key_id", tb[TCA_FLOWER_KEY_ENC_KEY_ID]);
3285
3286 flower_print_port("enc_dst_port", tb[TCA_FLOWER_KEY_ENC_UDP_DST_PORT],
3287 tb[TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK]);
3288
3289 flower_print_ip_attr("enc_tos", tb[TCA_FLOWER_KEY_ENC_IP_TOS],
3290 tb[TCA_FLOWER_KEY_ENC_IP_TOS_MASK]);
3291 flower_print_ip_attr("enc_ttl", tb[TCA_FLOWER_KEY_ENC_IP_TTL],
3292 tb[TCA_FLOWER_KEY_ENC_IP_TTL_MASK]);
3293 flower_print_enc_opts("enc_opt", tb[TCA_FLOWER_KEY_ENC_OPTS],
3294 tb[TCA_FLOWER_KEY_ENC_OPTS_MASK]);
3295
3296 flower_print_matching_flags("ip_flags", FLOWER_IP_FLAGS,
3297 tb[TCA_FLOWER_KEY_FLAGS],
3298 tb[TCA_FLOWER_KEY_FLAGS_MASK]);
3299
3300 flower_print_matching_flags("enc_flags", FLOWER_ENC_DST_FLAGS,
3301 tb[TCA_FLOWER_KEY_ENC_FLAGS],
3302 tb[TCA_FLOWER_KEY_ENC_FLAGS_MASK]);
3303
3304 if (tb[TCA_FLOWER_L2_MISS]) {
3305 struct rtattr *attr = tb[TCA_FLOWER_L2_MISS];
3306
3307 print_nl();
3308 print_uint(PRINT_ANY, "l2_miss", " l2_miss %u",
3309 rta_getattr_u8(attr));
3310 }
3311
3312 flower_print_ct_state(tb[TCA_FLOWER_KEY_CT_STATE],
3313 tb[TCA_FLOWER_KEY_CT_STATE_MASK]);
3314 flower_print_ct_zone(tb[TCA_FLOWER_KEY_CT_ZONE],
3315 tb[TCA_FLOWER_KEY_CT_ZONE_MASK]);
3316 flower_print_ct_mark(tb[TCA_FLOWER_KEY_CT_MARK],
3317 tb[TCA_FLOWER_KEY_CT_MARK_MASK]);
3318 flower_print_ct_label(tb[TCA_FLOWER_KEY_CT_LABELS],
3319 tb[TCA_FLOWER_KEY_CT_LABELS_MASK]);
3320
3321 flower_print_cfm(tb[TCA_FLOWER_KEY_CFM]);
3322
3323 close_json_object();
3324
3325 if (tb[TCA_FLOWER_FLAGS]) {
3326 __u32 flags = rta_getattr_u32(tb[TCA_FLOWER_FLAGS]);
3327
3328 if (flags & TCA_CLS_FLAGS_SKIP_HW) {
3329 print_nl();
3330 print_bool(PRINT_ANY, "skip_hw", " skip_hw", true);
3331 }
3332 if (flags & TCA_CLS_FLAGS_SKIP_SW) {
3333 print_nl();
3334 print_bool(PRINT_ANY, "skip_sw", " skip_sw", true);
3335 }
3336 if (flags & TCA_CLS_FLAGS_IN_HW) {
3337 print_nl();
3338 print_bool(PRINT_ANY, "in_hw", " in_hw", true);
3339
3340 if (tb[TCA_FLOWER_IN_HW_COUNT]) {
3341 __u32 count = rta_getattr_u32(tb[TCA_FLOWER_IN_HW_COUNT]);
3342
3343 print_uint(PRINT_ANY, "in_hw_count",
3344 " in_hw_count %u", count);
3345 }
3346 } else if (flags & TCA_CLS_FLAGS_NOT_IN_HW) {
3347 print_nl();
3348 print_bool(PRINT_ANY, "not_in_hw", " not_in_hw", true);
3349 }
3350 }
3351
3352 if (tb[TCA_FLOWER_ACT])
3353 tc_print_action(f, tb[TCA_FLOWER_ACT], 0);
3354
3355 return 0;
3356}
3357
3358struct filter_util flower_filter_util = {
3359 .id = "flower",
3360 .parse_fopt = flower_parse_opt,
3361 .print_fopt = flower_print_opt,
3362};
3363