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