]> git.proxmox.com Git - mirror_iproute2.git/blame - tc/f_flower.c
tunnel: factorize printout of GRE key and flags
[mirror_iproute2.git] / tc / f_flower.c
CommitLineData
30eb304e
JP
1/*
2 * f_flower.c Flower Classifier
3 *
4 * This program is free software; you can distribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Authors: Jiri Pirko <jiri@resnulli.us>
10 */
11
12#include <stdio.h>
13#include <stdlib.h>
14#include <unistd.h>
30eb304e
JP
15#include <string.h>
16#include <net/if.h>
28747146 17#include <linux/limits.h>
f888f4e2 18#include <linux/if_arp.h>
30eb304e
JP
19#include <linux/if_ether.h>
20#include <linux/ip.h>
745d9172 21#include <linux/tc_act/tc_vlan.h>
7638ee13 22#include <linux/mpls.h>
30eb304e
JP
23
24#include "utils.h"
25#include "tc_util.h"
26#include "rt_names.h"
27
08f66c80
PB
28enum flower_matching_flags {
29 FLOWER_IP_FLAGS,
30};
31
6910d656
SH
32enum flower_endpoint {
33 FLOWER_ENDPOINT_SRC,
34 FLOWER_ENDPOINT_DST
35};
36
eb3b5696
SH
37enum flower_icmp_field {
38 FLOWER_ICMP_FIELD_TYPE,
39 FLOWER_ICMP_FIELD_CODE
40};
41
30eb304e
JP
42static void explain(void)
43{
512caeb2 44 fprintf(stderr,
8589eb4e
MC
45 "Usage: ... flower [ MATCH-LIST ] [ verbose ]\n"
46 " [ skip_sw | skip_hw ]\n"
47 " [ action ACTION-SPEC ] [ classid CLASSID ]\n"
512caeb2
SH
48 "\n"
49 "Where: MATCH-LIST := [ MATCH-LIST ] MATCH\n"
8589eb4e
MC
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_label LABEL |\n"
63 " mpls_tc TC |\n"
64 " mpls_bos BOS |\n"
65 " mpls_ttl TTL |\n"
66 " dst_ip PREFIX |\n"
67 " src_ip PREFIX |\n"
68 " dst_port PORT-NUMBER |\n"
69 " src_port PORT-NUMBER |\n"
70 " tcp_flags MASKED-TCP_FLAGS |\n"
71 " type MASKED-ICMP-TYPE |\n"
72 " code MASKED-ICMP-CODE |\n"
73 " arp_tip IPV4-PREFIX |\n"
74 " arp_sip IPV4-PREFIX |\n"
75 " arp_op [ request | reply | OP ] |\n"
76 " arp_tha MASKED-LLADDR |\n"
77 " arp_sha MASKED-LLADDR |\n"
78 " enc_dst_ip [ IPV4-ADDR | IPV6-ADDR ] |\n"
79 " enc_src_ip [ IPV4-ADDR | IPV6-ADDR ] |\n"
80 " enc_key_id [ KEY-ID ] |\n"
81 " enc_tos MASKED-IP_TOS |\n"
82 " enc_ttl MASKED-IP_TTL |\n"
83 " geneve_opts MASKED-OPTIONS |\n"
84 " ip_flags IP-FLAGS | \n"
85 " enc_dst_port [ port_number ] }\n"
86 " FILTERID := X:Y:Z\n"
87 " MASKED_LLADDR := { LLADDR | LLADDR/MASK | LLADDR/BITS }\n"
88 " ACTION-SPEC := ... look at individual actions\n"
512caeb2 89 "\n"
8589eb4e
MC
90 "NOTE: CLASSID, IP-PROTO are parsed as hexadecimal input.\n"
91 "NOTE: There can be only used one mask per one prio. If user needs\n"
92 " to specify different mask, he has to use different prio.\n");
30eb304e
JP
93}
94
95static int flower_parse_eth_addr(char *str, int addr_type, int mask_type,
96 struct nlmsghdr *n)
97{
c2078f8d
SH
98 int ret, err = -1;
99 char addr[ETH_ALEN], *slash;
100
101 slash = strchr(str, '/');
102 if (slash)
103 *slash = '\0';
30eb304e
JP
104
105 ret = ll_addr_a2n(addr, sizeof(addr), str);
106 if (ret < 0)
c2078f8d 107 goto err;
30eb304e 108 addattr_l(n, MAX_MSG, addr_type, addr, sizeof(addr));
c2078f8d
SH
109
110 if (slash) {
111 unsigned bits;
112
113 if (!get_unsigned(&bits, slash + 1, 10)) {
114 uint64_t mask;
115
116 /* Extra 16 bit shift to push mac address into
117 * high bits of uint64_t
118 */
119 mask = htonll(0xffffffffffffULL << (16 + 48 - bits));
120 memcpy(addr, &mask, ETH_ALEN);
121 } else {
122 ret = ll_addr_a2n(addr, sizeof(addr), slash + 1);
123 if (ret < 0)
124 goto err;
125 }
126 } else {
127 memset(addr, 0xff, ETH_ALEN);
128 }
30eb304e 129 addattr_l(n, MAX_MSG, mask_type, addr, sizeof(addr));
c2078f8d
SH
130
131 err = 0;
132err:
133 if (slash)
134 *slash = '/';
135 return err;
30eb304e
JP
136}
137
1f0a5dfd
JL
138static bool eth_type_vlan(__be16 ethertype)
139{
140 return ethertype == htons(ETH_P_8021Q) ||
141 ethertype == htons(ETH_P_8021AD);
142}
143
745d9172 144static int flower_parse_vlan_eth_type(char *str, __be16 eth_type, int type,
512caeb2
SH
145 __be16 *p_vlan_eth_type,
146 struct nlmsghdr *n)
745d9172
HHZ
147{
148 __be16 vlan_eth_type;
149
1f0a5dfd
JL
150 if (!eth_type_vlan(eth_type)) {
151 fprintf(stderr, "Can't set \"%s\" if ethertype isn't 802.1Q or 802.1AD\n",
152 type == TCA_FLOWER_KEY_VLAN_ETH_TYPE ? "vlan_ethtype" : "cvlan_ethtype");
745d9172
HHZ
153 return -1;
154 }
155
156 if (ll_proto_a2n(&vlan_eth_type, str))
157 invarg("invalid vlan_ethtype", str);
158 addattr16(n, MAX_MSG, type, vlan_eth_type);
159 *p_vlan_eth_type = vlan_eth_type;
160 return 0;
161}
162
08f66c80
PB
163struct flag_to_string {
164 int flag;
165 enum flower_matching_flags type;
166 char *string;
167};
22a8f019 168
08f66c80
PB
169static struct flag_to_string flags_str[] = {
170 { TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT, FLOWER_IP_FLAGS, "frag" },
fb4e6abf 171 { TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST, FLOWER_IP_FLAGS, "firstfrag" },
08f66c80 172};
22a8f019 173
08f66c80
PB
174static int flower_parse_matching_flags(char *str,
175 enum flower_matching_flags type,
176 __u32 *mtf, __u32 *mtf_mask)
177{
178 char *token;
179 bool no;
180 bool found;
181 int i;
22a8f019 182
08f66c80
PB
183 token = strtok(str, "/");
184
185 while (token) {
186 if (!strncmp(token, "no", 2)) {
187 no = true;
188 token += 2;
189 } else
190 no = false;
191
192 found = false;
193 for (i = 0; i < ARRAY_SIZE(flags_str); i++) {
194 if (type != flags_str[i].type)
195 continue;
196
197 if (!strcmp(token, flags_str[i].string)) {
198 if (no)
199 *mtf &= ~flags_str[i].flag;
200 else
201 *mtf |= flags_str[i].flag;
202
203 *mtf_mask |= flags_str[i].flag;
204 found = true;
205 break;
206 }
207 }
208 if (!found)
22a8f019 209 return -1;
08f66c80
PB
210
211 token = strtok(NULL, "/");
22a8f019
PB
212 }
213
22a8f019
PB
214 return 0;
215}
216
30eb304e
JP
217static int flower_parse_ip_proto(char *str, __be16 eth_type, int type,
218 __u8 *p_ip_proto, struct nlmsghdr *n)
219{
220 int ret;
221 __u8 ip_proto;
222
eb3b5696
SH
223 if (eth_type != htons(ETH_P_IP) && eth_type != htons(ETH_P_IPV6))
224 goto err;
225
30eb304e
JP
226 if (matches(str, "tcp") == 0) {
227 ip_proto = IPPROTO_TCP;
228 } else if (matches(str, "udp") == 0) {
229 ip_proto = IPPROTO_UDP;
a1fb0d48
SH
230 } else if (matches(str, "sctp") == 0) {
231 ip_proto = IPPROTO_SCTP;
eb3b5696
SH
232 } else if (matches(str, "icmp") == 0) {
233 if (eth_type != htons(ETH_P_IP))
234 goto err;
235 ip_proto = IPPROTO_ICMP;
236 } else if (matches(str, "icmpv6") == 0) {
237 if (eth_type != htons(ETH_P_IPV6))
238 goto err;
239 ip_proto = IPPROTO_ICMPV6;
30eb304e
JP
240 } else {
241 ret = get_u8(&ip_proto, str, 16);
242 if (ret)
243 return -1;
244 }
245 addattr8(n, MAX_MSG, type, ip_proto);
246 *p_ip_proto = ip_proto;
247 return 0;
eb3b5696
SH
248
249err:
250 fprintf(stderr, "Illegal \"eth_type\" for ip proto\n");
251 return -1;
30eb304e
JP
252}
253
f888f4e2
SH
254static int __flower_parse_ip_addr(char *str, int family,
255 int addr4_type, int mask4_type,
256 int addr6_type, int mask6_type,
257 struct nlmsghdr *n)
30eb304e
JP
258{
259 int ret;
260 inet_prefix addr;
30eb304e
JP
261 int bits;
262 int i;
263
30eb304e
JP
264 ret = get_prefix(&addr, str, family);
265 if (ret)
266 return -1;
267
bb9b63b1
AV
268 if (family && (addr.family != family)) {
269 fprintf(stderr, "Illegal \"eth_type\" for ip address\n");
30eb304e 270 return -1;
bb9b63b1 271 }
30eb304e
JP
272
273 addattr_l(n, MAX_MSG, addr.family == AF_INET ? addr4_type : addr6_type,
274 addr.data, addr.bytelen);
275
276 memset(addr.data, 0xff, addr.bytelen);
277 bits = addr.bitlen;
278 for (i = 0; i < addr.bytelen / 4; i++) {
279 if (!bits) {
280 addr.data[i] = 0;
281 } else if (bits / 32 >= 1) {
282 bits -= 32;
283 } else {
284 addr.data[i] <<= 32 - bits;
285 addr.data[i] = htonl(addr.data[i]);
286 bits = 0;
287 }
288 }
289
290 addattr_l(n, MAX_MSG, addr.family == AF_INET ? mask4_type : mask6_type,
291 addr.data, addr.bytelen);
292
293 return 0;
294}
295
f888f4e2
SH
296static int flower_parse_ip_addr(char *str, __be16 eth_type,
297 int addr4_type, int mask4_type,
298 int addr6_type, int mask6_type,
299 struct nlmsghdr *n)
300{
301 int family;
302
303 if (eth_type == htons(ETH_P_IP)) {
304 family = AF_INET;
305 } else if (eth_type == htons(ETH_P_IPV6)) {
306 family = AF_INET6;
307 } else if (!eth_type) {
308 family = AF_UNSPEC;
309 } else {
310 return -1;
311 }
312
164a9ff4
RD
313 return __flower_parse_ip_addr(str, family, addr4_type, mask4_type,
314 addr6_type, mask6_type, n);
f888f4e2
SH
315}
316
317static bool flower_eth_type_arp(__be16 eth_type)
318{
319 return eth_type == htons(ETH_P_ARP) || eth_type == htons(ETH_P_RARP);
320}
321
322static int flower_parse_arp_ip_addr(char *str, __be16 eth_type,
323 int addr_type, int mask_type,
324 struct nlmsghdr *n)
325{
326 if (!flower_eth_type_arp(eth_type))
327 return -1;
328
329 return __flower_parse_ip_addr(str, AF_INET, addr_type, mask_type,
330 TCA_FLOWER_UNSPEC, TCA_FLOWER_UNSPEC, n);
331}
332
180136e5
SH
333static int flower_parse_u8(char *str, int value_type, int mask_type,
334 int (*value_from_name)(const char *str,
335 __u8 *value),
336 bool (*value_validate)(__u8 value),
337 struct nlmsghdr *n)
f888f4e2
SH
338{
339 char *slash;
340 int ret, err = -1;
180136e5 341 __u8 value, mask;
f888f4e2
SH
342
343 slash = strchr(str, '/');
344 if (slash)
345 *slash = '\0';
346
180136e5
SH
347 ret = value_from_name ? value_from_name(str, &value) : -1;
348 if (ret < 0) {
f888f4e2
SH
349 ret = get_u8(&value, str, 10);
350 if (ret)
351 goto err;
f888f4e2
SH
352 }
353
180136e5
SH
354 if (value_validate && !value_validate(value))
355 goto err;
356
f888f4e2
SH
357 if (slash) {
358 ret = get_u8(&mask, slash + 1, 10);
359 if (ret)
360 goto err;
361 }
362 else {
363 mask = UINT8_MAX;
364 }
365
180136e5 366 addattr8(n, MAX_MSG, value_type, value);
f888f4e2
SH
367 addattr8(n, MAX_MSG, mask_type, mask);
368
369 err = 0;
370err:
371 if (slash)
372 *slash = '/';
373 return err;
374}
375
9d36e54f
SH
376static const char *flower_print_arp_op_to_name(__u8 op)
377{
378 switch (op) {
379 case ARPOP_REQUEST:
380 return "request";
381 case ARPOP_REPLY:
382 return "reply";
383 default:
384 return NULL;
385 }
386}
387
180136e5
SH
388static int flower_arp_op_from_name(const char *name, __u8 *op)
389{
390 if (!strcmp(name, "request"))
391 *op = ARPOP_REQUEST;
392 else if (!strcmp(name, "reply"))
393 *op = ARPOP_REPLY;
394 else
395 return -1;
396
397 return 0;
398}
399
400static bool flow_arp_op_validate(__u8 op)
401{
402 return !op || op == ARPOP_REQUEST || op == ARPOP_REPLY;
403}
404
405static int flower_parse_arp_op(char *str, __be16 eth_type,
406 int op_type, int mask_type,
407 struct nlmsghdr *n)
408{
409 if (!flower_eth_type_arp(eth_type))
410 return -1;
411
412 return flower_parse_u8(str, op_type, mask_type, flower_arp_op_from_name,
413 flow_arp_op_validate, n);
414}
415
eb3b5696
SH
416static int flower_icmp_attr_type(__be16 eth_type, __u8 ip_proto,
417 enum flower_icmp_field field)
418{
419 if (eth_type == htons(ETH_P_IP) && ip_proto == IPPROTO_ICMP)
420 return field == FLOWER_ICMP_FIELD_CODE ?
421 TCA_FLOWER_KEY_ICMPV4_CODE :
422 TCA_FLOWER_KEY_ICMPV4_TYPE;
423 else if (eth_type == htons(ETH_P_IPV6) && ip_proto == IPPROTO_ICMPV6)
424 return field == FLOWER_ICMP_FIELD_CODE ?
425 TCA_FLOWER_KEY_ICMPV6_CODE :
426 TCA_FLOWER_KEY_ICMPV6_TYPE;
427
428 return -1;
429}
430
6374961a
SH
431static int flower_icmp_attr_mask_type(__be16 eth_type, __u8 ip_proto,
432 enum flower_icmp_field field)
433{
434 if (eth_type == htons(ETH_P_IP) && ip_proto == IPPROTO_ICMP)
435 return field == FLOWER_ICMP_FIELD_CODE ?
436 TCA_FLOWER_KEY_ICMPV4_CODE_MASK :
437 TCA_FLOWER_KEY_ICMPV4_TYPE_MASK;
438 else if (eth_type == htons(ETH_P_IPV6) && ip_proto == IPPROTO_ICMPV6)
439 return field == FLOWER_ICMP_FIELD_CODE ?
440 TCA_FLOWER_KEY_ICMPV6_CODE_MASK :
441 TCA_FLOWER_KEY_ICMPV6_TYPE_MASK;
442
443 return -1;
444}
445
eb3b5696
SH
446static int flower_parse_icmp(char *str, __u16 eth_type, __u8 ip_proto,
447 enum flower_icmp_field field, struct nlmsghdr *n)
448{
6374961a 449 int value_type, mask_type;
eb3b5696 450
6374961a
SH
451 value_type = flower_icmp_attr_type(eth_type, ip_proto, field);
452 mask_type = flower_icmp_attr_mask_type(eth_type, ip_proto, field);
453 if (value_type < 0 || mask_type < 0)
eb3b5696
SH
454 return -1;
455
6374961a 456 return flower_parse_u8(str, value_type, mask_type, NULL, NULL, n);
eb3b5696
SH
457}
458
6910d656 459static int flower_port_attr_type(__u8 ip_proto, enum flower_endpoint endpoint)
30eb304e 460{
6bd5b80c 461 if (ip_proto == IPPROTO_TCP)
6910d656
SH
462 return endpoint == FLOWER_ENDPOINT_SRC ?
463 TCA_FLOWER_KEY_TCP_SRC :
a1fb0d48 464 TCA_FLOWER_KEY_TCP_DST;
6bd5b80c 465 else if (ip_proto == IPPROTO_UDP)
6910d656
SH
466 return endpoint == FLOWER_ENDPOINT_SRC ?
467 TCA_FLOWER_KEY_UDP_SRC :
a1fb0d48 468 TCA_FLOWER_KEY_UDP_DST;
6bd5b80c 469 else if (ip_proto == IPPROTO_SCTP)
6910d656
SH
470 return endpoint == FLOWER_ENDPOINT_SRC ?
471 TCA_FLOWER_KEY_SCTP_SRC :
a1fb0d48 472 TCA_FLOWER_KEY_SCTP_DST;
6bd5b80c 473 else
30eb304e 474 return -1;
a1fb0d48
SH
475}
476
8930840e
AN
477static int flower_port_range_attr_type(__u8 ip_proto, enum flower_endpoint type,
478 __be16 *min_port_type,
479 __be16 *max_port_type)
480{
481 if (ip_proto == IPPROTO_TCP || ip_proto == IPPROTO_UDP ||
482 ip_proto == IPPROTO_SCTP) {
483 if (type == FLOWER_ENDPOINT_SRC) {
484 *min_port_type = TCA_FLOWER_KEY_PORT_SRC_MIN;
485 *max_port_type = TCA_FLOWER_KEY_PORT_SRC_MAX;
486 } else {
487 *min_port_type = TCA_FLOWER_KEY_PORT_DST_MIN;
488 *max_port_type = TCA_FLOWER_KEY_PORT_DST_MAX;
489 }
490 } else {
491 return -1;
492 }
493 return 0;
494}
495
767b6fd6
LC
496/* parse range args in format 10-20 */
497static int parse_range(char *str, __be16 *min, __be16 *max)
498{
499 char *sep;
500
501 sep = strchr(str, '-');
502 if (sep) {
503 *sep = '\0';
504
505 if (get_be16(min, str, 10))
506 return -1;
507
508 if (get_be16(max, sep + 1, 10))
509 return -1;
510 } else {
511 if (get_be16(min, str, 10))
512 return -1;
513 }
514 return 0;
515}
516
6910d656
SH
517static int flower_parse_port(char *str, __u8 ip_proto,
518 enum flower_endpoint endpoint,
a1fb0d48
SH
519 struct nlmsghdr *n)
520{
767b6fd6
LC
521 __be16 min = 0;
522 __be16 max = 0;
a1fb0d48 523 int ret;
a1fb0d48 524
767b6fd6
LC
525 ret = parse_range(str, &min, &max);
526 if (ret)
527 return -1;
30eb304e 528
767b6fd6 529 if (min && max) {
8930840e 530 __be16 min_port_type, max_port_type;
30eb304e 531
8930840e
AN
532 if (max <= min) {
533 fprintf(stderr, "max value should be greater than min value\n");
534 return -1;
535 }
536 if (flower_port_range_attr_type(ip_proto, endpoint,
537 &min_port_type, &max_port_type))
538 return -1;
539
767b6fd6
LC
540 addattr16(n, MAX_MSG, min_port_type, min);
541 addattr16(n, MAX_MSG, max_port_type, max);
542 } else if (min && !max) {
543 int type;
544
545 type = flower_port_attr_type(ip_proto, endpoint);
546 if (type < 0)
547 return -1;
548 addattr16(n, MAX_MSG, type, min);
8930840e
AN
549 } else {
550 return -1;
551 }
30eb304e
JP
552 return 0;
553}
554
0c30d14d
JP
555#define TCP_FLAGS_MAX_MASK 0xfff
556
557static int flower_parse_tcp_flags(char *str, int flags_type, int mask_type,
558 struct nlmsghdr *n)
559{
560 char *slash;
561 int ret, err = -1;
562 __u16 flags;
563
564 slash = strchr(str, '/');
565 if (slash)
566 *slash = '\0';
567
568 ret = get_u16(&flags, str, 16);
569 if (ret < 0 || flags & ~TCP_FLAGS_MAX_MASK)
570 goto err;
571
572 addattr16(n, MAX_MSG, flags_type, htons(flags));
573
574 if (slash) {
575 ret = get_u16(&flags, slash + 1, 16);
576 if (ret < 0 || flags & ~TCP_FLAGS_MAX_MASK)
577 goto err;
578 } else {
579 flags = TCP_FLAGS_MAX_MASK;
580 }
581 addattr16(n, MAX_MSG, mask_type, htons(flags));
582
583 err = 0;
584err:
585 if (slash)
586 *slash = '/';
587 return err;
588}
589
6ea2c2b1
OG
590static int flower_parse_ip_tos_ttl(char *str, int key_type, int mask_type,
591 struct nlmsghdr *n)
592{
593 char *slash;
594 int ret, err = -1;
595 __u8 tos_ttl;
596
597 slash = strchr(str, '/');
598 if (slash)
599 *slash = '\0';
600
601 ret = get_u8(&tos_ttl, str, 10);
602 if (ret < 0)
603 ret = get_u8(&tos_ttl, str, 16);
604 if (ret < 0)
605 goto err;
606
607 addattr8(n, MAX_MSG, key_type, tos_ttl);
608
609 if (slash) {
610 ret = get_u8(&tos_ttl, slash + 1, 16);
611 if (ret < 0)
612 goto err;
613 } else {
614 tos_ttl = 0xff;
615 }
616 addattr8(n, MAX_MSG, mask_type, tos_ttl);
617
618 err = 0;
619err:
620 if (slash)
621 *slash = '/';
622 return err;
623}
624
bb9b63b1
AV
625static int flower_parse_key_id(const char *str, int type, struct nlmsghdr *n)
626{
627 int ret;
628 __be32 key_id;
629
630 ret = get_be32(&key_id, str, 10);
631 if (!ret)
632 addattr32(n, MAX_MSG, type, key_id);
633
634 return ret;
635}
636
41aa17ff
HHZ
637static int flower_parse_enc_port(char *str, int type, struct nlmsghdr *n)
638{
639 int ret;
640 __be16 port;
641
642 ret = get_be16(&port, str, 10);
643 if (ret)
644 return -1;
645
646 addattr16(n, MAX_MSG, type, port);
647
648 return 0;
649}
650
56155d4d
PJV
651static int flower_parse_geneve_opts(char *str, struct nlmsghdr *n)
652{
653 struct rtattr *nest;
654 char *token;
655 int i, err;
656
657 nest = addattr_nest(n, MAX_MSG, TCA_FLOWER_KEY_ENC_OPTS_GENEVE);
658
659 i = 1;
660 token = strsep(&str, ":");
661 while (token) {
662 switch (i) {
663 case TCA_FLOWER_KEY_ENC_OPT_GENEVE_CLASS:
664 {
665 __be16 opt_class;
666
667 if (!strlen(token))
668 break;
669 err = get_be16(&opt_class, token, 16);
670 if (err)
671 return err;
672
673 addattr16(n, MAX_MSG, i, opt_class);
674 break;
675 }
676 case TCA_FLOWER_KEY_ENC_OPT_GENEVE_TYPE:
677 {
678 __u8 opt_type;
679
680 if (!strlen(token))
681 break;
682 err = get_u8(&opt_type, token, 16);
683 if (err)
684 return err;
685
686 addattr8(n, MAX_MSG, i, opt_type);
687 break;
688 }
689 case TCA_FLOWER_KEY_ENC_OPT_GENEVE_DATA:
690 {
691 size_t token_len = strlen(token);
692 __u8 *opts;
693
694 if (!token_len)
695 break;
696 opts = malloc(token_len / 2);
697 if (!opts)
698 return -1;
699 if (hex2mem(token, opts, token_len / 2) < 0) {
700 free(opts);
701 return -1;
702 }
703 addattr_l(n, MAX_MSG, i, opts, token_len / 2);
704 free(opts);
705
706 break;
707 }
708 default:
709 fprintf(stderr, "Unknown \"geneve_opts\" type\n");
710 return -1;
711 }
712
713 token = strsep(&str, ":");
714 i++;
715 }
716 addattr_nest_end(n, nest);
717
718 return 0;
719}
720
721static int flower_parse_enc_opt_part(char *str, struct nlmsghdr *n)
722{
723 char *token;
724 int err;
725
726 token = strsep(&str, ",");
727 while (token) {
728 err = flower_parse_geneve_opts(token, n);
729 if (err)
730 return err;
731
732 token = strsep(&str, ",");
733 }
734
735 return 0;
736}
737
738static int flower_check_enc_opt_key(char *key)
739{
740 int key_len, col_cnt = 0;
741
742 key_len = strlen(key);
743 while ((key = strchr(key, ':'))) {
744 if (strlen(key) == key_len)
745 return -1;
746
747 key_len = strlen(key) - 1;
748 col_cnt++;
749 key++;
750 }
751
752 if (col_cnt != 2 || !key_len)
753 return -1;
754
755 return 0;
756}
757
758static int flower_parse_enc_opts(char *str, struct nlmsghdr *n)
759{
760 char key[XATTR_SIZE_MAX], mask[XATTR_SIZE_MAX];
761 int data_len, key_len, mask_len, err;
762 char *token, *slash;
763 struct rtattr *nest;
764
765 key_len = 0;
766 mask_len = 0;
767 token = strsep(&str, ",");
768 while (token) {
769 slash = strchr(token, '/');
770 if (slash)
771 *slash = '\0';
772
773 if ((key_len + strlen(token) > XATTR_SIZE_MAX) ||
774 flower_check_enc_opt_key(token))
775 return -1;
776
777 strcpy(&key[key_len], token);
778 key_len += strlen(token) + 1;
779 key[key_len - 1] = ',';
780
781 if (!slash) {
782 /* Pad out mask when not provided */
783 if (mask_len + strlen(token) > XATTR_SIZE_MAX)
784 return -1;
785
786 data_len = strlen(rindex(token, ':'));
787 sprintf(&mask[mask_len], "ffff:ff:");
788 mask_len += 8;
789 memset(&mask[mask_len], 'f', data_len - 1);
790 mask_len += data_len;
791 mask[mask_len - 1] = ',';
792 token = strsep(&str, ",");
793 continue;
794 }
795
796 if (mask_len + strlen(slash + 1) > XATTR_SIZE_MAX)
797 return -1;
798
799 strcpy(&mask[mask_len], slash + 1);
800 mask_len += strlen(slash + 1) + 1;
801 mask[mask_len - 1] = ',';
802
803 *slash = '/';
804 token = strsep(&str, ",");
805 }
806 key[key_len - 1] = '\0';
807 mask[mask_len - 1] = '\0';
808
809 nest = addattr_nest(n, MAX_MSG, TCA_FLOWER_KEY_ENC_OPTS);
810 err = flower_parse_enc_opt_part(key, n);
811 if (err)
812 return err;
813 addattr_nest_end(n, nest);
814
815 nest = addattr_nest(n, MAX_MSG, TCA_FLOWER_KEY_ENC_OPTS_MASK);
816 err = flower_parse_enc_opt_part(mask, n);
817 if (err)
818 return err;
819 addattr_nest_end(n, nest);
820
821 return 0;
822}
823
30eb304e
JP
824static int flower_parse_opt(struct filter_util *qu, char *handle,
825 int argc, char **argv, struct nlmsghdr *n)
826{
827 int ret;
828 struct tcmsg *t = NLMSG_DATA(n);
829 struct rtattr *tail;
488b41d0 830 __be16 eth_type = TC_H_MIN(t->tcm_info);
745d9172 831 __be16 vlan_ethtype = 0;
1f0a5dfd 832 __be16 cvlan_ethtype = 0;
30eb304e 833 __u8 ip_proto = 0xff;
cfcabf18 834 __u32 flags = 0;
08f66c80
PB
835 __u32 mtf = 0;
836 __u32 mtf_mask = 0;
30eb304e 837
30eb304e
JP
838 if (handle) {
839 ret = get_u32(&t->tcm_handle, handle, 0);
840 if (ret) {
841 fprintf(stderr, "Illegal \"handle\"\n");
842 return -1;
843 }
844 }
845
846 tail = (struct rtattr *) (((void *) n) + NLMSG_ALIGN(n->nlmsg_len));
847 addattr_l(n, MAX_MSG, TCA_OPTIONS, NULL, 0);
848
488b41d0
JHS
849 if (argc == 0) {
850 /*at minimal we will match all ethertype packets */
851 goto parse_done;
852 }
853
30eb304e
JP
854 while (argc > 0) {
855 if (matches(*argv, "classid") == 0 ||
856 matches(*argv, "flowid") == 0) {
32a121cb 857 unsigned int handle;
30eb304e
JP
858
859 NEXT_ARG();
860 ret = get_tc_classid(&handle, *argv);
861 if (ret) {
862 fprintf(stderr, "Illegal \"classid\"\n");
863 return -1;
864 }
865 addattr_l(n, MAX_MSG, TCA_FLOWER_CLASSID, &handle, 4);
0d575c4d
AN
866 } else if (matches(*argv, "hw_tc") == 0) {
867 unsigned int handle;
868 __u32 tc;
869 char *end;
870
871 NEXT_ARG();
872 tc = strtoul(*argv, &end, 0);
873 if (*end) {
874 fprintf(stderr, "Illegal TC index\n");
875 return -1;
876 }
877 if (tc >= TC_QOPT_MAX_QUEUE) {
878 fprintf(stderr, "TC index exceeds max range\n");
879 return -1;
880 }
881 handle = TC_H_MAKE(TC_H_MAJ(t->tcm_parent),
882 TC_H_MIN(tc + TC_H_MIN_PRIORITY));
883 addattr_l(n, MAX_MSG, TCA_FLOWER_CLASSID, &handle,
884 sizeof(handle));
08f66c80 885 } else if (matches(*argv, "ip_flags") == 0) {
22a8f019
PB
886 NEXT_ARG();
887 ret = flower_parse_matching_flags(*argv,
08f66c80
PB
888 FLOWER_IP_FLAGS,
889 &mtf,
890 &mtf_mask);
22a8f019 891 if (ret < 0) {
08f66c80 892 fprintf(stderr, "Illegal \"ip_flags\"\n");
22a8f019
PB
893 return -1;
894 }
ac6a4c22
MRL
895 } else if (matches(*argv, "verbose") == 0) {
896 flags |= TCA_CLS_FLAGS_VERBOSE;
cfcabf18
AV
897 } else if (matches(*argv, "skip_hw") == 0) {
898 flags |= TCA_CLS_FLAGS_SKIP_HW;
899 } else if (matches(*argv, "skip_sw") == 0) {
900 flags |= TCA_CLS_FLAGS_SKIP_SW;
30eb304e 901 } else if (matches(*argv, "indev") == 0) {
30eb304e 902 NEXT_ARG();
625df645
PS
903 if (check_ifname(*argv))
904 invarg("\"indev\" not a valid ifname", *argv);
ee474849 905 addattrstrz(n, MAX_MSG, TCA_FLOWER_INDEV, *argv);
745d9172
HHZ
906 } else if (matches(*argv, "vlan_id") == 0) {
907 __u16 vid;
908
909 NEXT_ARG();
1f0a5dfd
JL
910 if (!eth_type_vlan(eth_type)) {
911 fprintf(stderr, "Can't set \"vlan_id\" if ethertype isn't 802.1Q or 802.1AD\n");
745d9172
HHZ
912 return -1;
913 }
914 ret = get_u16(&vid, *argv, 10);
915 if (ret < 0 || vid & ~0xfff) {
916 fprintf(stderr, "Illegal \"vlan_id\"\n");
917 return -1;
918 }
919 addattr16(n, MAX_MSG, TCA_FLOWER_KEY_VLAN_ID, vid);
920 } else if (matches(*argv, "vlan_prio") == 0) {
921 __u8 vlan_prio;
922
923 NEXT_ARG();
1f0a5dfd
JL
924 if (!eth_type_vlan(eth_type)) {
925 fprintf(stderr, "Can't set \"vlan_prio\" if ethertype isn't 802.1Q or 802.1AD\n");
745d9172
HHZ
926 return -1;
927 }
928 ret = get_u8(&vlan_prio, *argv, 10);
929 if (ret < 0 || vlan_prio & ~0x7) {
930 fprintf(stderr, "Illegal \"vlan_prio\"\n");
931 return -1;
932 }
512caeb2
SH
933 addattr8(n, MAX_MSG,
934 TCA_FLOWER_KEY_VLAN_PRIO, vlan_prio);
745d9172
HHZ
935 } else if (matches(*argv, "vlan_ethtype") == 0) {
936 NEXT_ARG();
937 ret = flower_parse_vlan_eth_type(*argv, eth_type,
512caeb2
SH
938 TCA_FLOWER_KEY_VLAN_ETH_TYPE,
939 &vlan_ethtype, n);
745d9172
HHZ
940 if (ret < 0)
941 return -1;
1f0a5dfd
JL
942 } else if (matches(*argv, "cvlan_id") == 0) {
943 __u16 vid;
944
945 NEXT_ARG();
946 if (!eth_type_vlan(vlan_ethtype)) {
947 fprintf(stderr, "Can't set \"cvlan_id\" if inner vlan ethertype isn't 802.1Q or 802.1AD\n");
948 return -1;
949 }
950 ret = get_u16(&vid, *argv, 10);
951 if (ret < 0 || vid & ~0xfff) {
952 fprintf(stderr, "Illegal \"cvlan_id\"\n");
953 return -1;
954 }
955 addattr16(n, MAX_MSG, TCA_FLOWER_KEY_CVLAN_ID, vid);
956 } else if (matches(*argv, "cvlan_prio") == 0) {
957 __u8 cvlan_prio;
958
959 NEXT_ARG();
960 if (!eth_type_vlan(vlan_ethtype)) {
961 fprintf(stderr, "Can't set \"cvlan_prio\" if inner vlan ethertype isn't 802.1Q or 802.1AD\n");
962 return -1;
963 }
964 ret = get_u8(&cvlan_prio, *argv, 10);
965 if (ret < 0 || cvlan_prio & ~0x7) {
966 fprintf(stderr, "Illegal \"cvlan_prio\"\n");
967 return -1;
968 }
969 addattr8(n, MAX_MSG,
970 TCA_FLOWER_KEY_CVLAN_PRIO, cvlan_prio);
971 } else if (matches(*argv, "cvlan_ethtype") == 0) {
972 NEXT_ARG();
973 ret = flower_parse_vlan_eth_type(*argv, vlan_ethtype,
974 TCA_FLOWER_KEY_CVLAN_ETH_TYPE,
975 &cvlan_ethtype, n);
976 if (ret < 0)
977 return -1;
7638ee13
BL
978 } else if (matches(*argv, "mpls_label") == 0) {
979 __u32 label;
980
981 NEXT_ARG();
982 if (eth_type != htons(ETH_P_MPLS_UC) &&
983 eth_type != htons(ETH_P_MPLS_MC)) {
984 fprintf(stderr,
985 "Can't set \"mpls_label\" if ethertype isn't MPLS\n");
986 return -1;
987 }
988 ret = get_u32(&label, *argv, 10);
989 if (ret < 0 || label & ~(MPLS_LS_LABEL_MASK >> MPLS_LS_LABEL_SHIFT)) {
990 fprintf(stderr, "Illegal \"mpls_label\"\n");
991 return -1;
992 }
993 addattr32(n, MAX_MSG, TCA_FLOWER_KEY_MPLS_LABEL, label);
994 } else if (matches(*argv, "mpls_tc") == 0) {
995 __u8 tc;
996
997 NEXT_ARG();
998 if (eth_type != htons(ETH_P_MPLS_UC) &&
999 eth_type != htons(ETH_P_MPLS_MC)) {
1000 fprintf(stderr,
1001 "Can't set \"mpls_tc\" if ethertype isn't MPLS\n");
1002 return -1;
1003 }
1004 ret = get_u8(&tc, *argv, 10);
1005 if (ret < 0 || tc & ~(MPLS_LS_TC_MASK >> MPLS_LS_TC_SHIFT)) {
1006 fprintf(stderr, "Illegal \"mpls_tc\"\n");
1007 return -1;
1008 }
1009 addattr8(n, MAX_MSG, TCA_FLOWER_KEY_MPLS_TC, tc);
1010 } else if (matches(*argv, "mpls_bos") == 0) {
1011 __u8 bos;
1012
1013 NEXT_ARG();
1014 if (eth_type != htons(ETH_P_MPLS_UC) &&
1015 eth_type != htons(ETH_P_MPLS_MC)) {
1016 fprintf(stderr,
1017 "Can't set \"mpls_bos\" if ethertype isn't MPLS\n");
1018 return -1;
1019 }
1020 ret = get_u8(&bos, *argv, 10);
1021 if (ret < 0 || bos & ~(MPLS_LS_S_MASK >> MPLS_LS_S_SHIFT)) {
1022 fprintf(stderr, "Illegal \"mpls_bos\"\n");
1023 return -1;
1024 }
1025 addattr8(n, MAX_MSG, TCA_FLOWER_KEY_MPLS_BOS, bos);
1026 } else if (matches(*argv, "mpls_ttl") == 0) {
1027 __u8 ttl;
1028
1029 NEXT_ARG();
1030 if (eth_type != htons(ETH_P_MPLS_UC) &&
1031 eth_type != htons(ETH_P_MPLS_MC)) {
1032 fprintf(stderr,
1033 "Can't set \"mpls_ttl\" if ethertype isn't MPLS\n");
1034 return -1;
1035 }
1036 ret = get_u8(&ttl, *argv, 10);
1037 if (ret < 0 || ttl & ~(MPLS_LS_TTL_MASK >> MPLS_LS_TTL_SHIFT)) {
1038 fprintf(stderr, "Illegal \"mpls_ttl\"\n");
1039 return -1;
1040 }
1041 addattr8(n, MAX_MSG, TCA_FLOWER_KEY_MPLS_TTL, ttl);
30eb304e
JP
1042 } else if (matches(*argv, "dst_mac") == 0) {
1043 NEXT_ARG();
1044 ret = flower_parse_eth_addr(*argv,
1045 TCA_FLOWER_KEY_ETH_DST,
1046 TCA_FLOWER_KEY_ETH_DST_MASK,
1047 n);
1048 if (ret < 0) {
1049 fprintf(stderr, "Illegal \"dst_mac\"\n");
1050 return -1;
1051 }
1052 } else if (matches(*argv, "src_mac") == 0) {
1053 NEXT_ARG();
1054 ret = flower_parse_eth_addr(*argv,
1055 TCA_FLOWER_KEY_ETH_SRC,
1056 TCA_FLOWER_KEY_ETH_SRC_MASK,
1057 n);
1058 if (ret < 0) {
1059 fprintf(stderr, "Illegal \"src_mac\"\n");
1060 return -1;
1061 }
30eb304e
JP
1062 } else if (matches(*argv, "ip_proto") == 0) {
1063 NEXT_ARG();
1f0a5dfd
JL
1064 ret = flower_parse_ip_proto(*argv, cvlan_ethtype ?
1065 cvlan_ethtype : vlan_ethtype ?
745d9172 1066 vlan_ethtype : eth_type,
30eb304e
JP
1067 TCA_FLOWER_KEY_IP_PROTO,
1068 &ip_proto, n);
1069 if (ret < 0) {
1070 fprintf(stderr, "Illegal \"ip_proto\"\n");
1071 return -1;
1072 }
6ea2c2b1
OG
1073 } else if (matches(*argv, "ip_tos") == 0) {
1074 NEXT_ARG();
1075 ret = flower_parse_ip_tos_ttl(*argv,
1076 TCA_FLOWER_KEY_IP_TOS,
1077 TCA_FLOWER_KEY_IP_TOS_MASK,
1078 n);
1079 if (ret < 0) {
1080 fprintf(stderr, "Illegal \"ip_tos\"\n");
1081 return -1;
1082 }
1083 } else if (matches(*argv, "ip_ttl") == 0) {
1084 NEXT_ARG();
1085 ret = flower_parse_ip_tos_ttl(*argv,
1086 TCA_FLOWER_KEY_IP_TTL,
1087 TCA_FLOWER_KEY_IP_TTL_MASK,
1088 n);
1089 if (ret < 0) {
1090 fprintf(stderr, "Illegal \"ip_ttl\"\n");
1091 return -1;
1092 }
30eb304e
JP
1093 } else if (matches(*argv, "dst_ip") == 0) {
1094 NEXT_ARG();
1f0a5dfd
JL
1095 ret = flower_parse_ip_addr(*argv, cvlan_ethtype ?
1096 cvlan_ethtype : vlan_ethtype ?
745d9172 1097 vlan_ethtype : eth_type,
30eb304e
JP
1098 TCA_FLOWER_KEY_IPV4_DST,
1099 TCA_FLOWER_KEY_IPV4_DST_MASK,
1100 TCA_FLOWER_KEY_IPV6_DST,
1101 TCA_FLOWER_KEY_IPV6_DST_MASK,
1102 n);
1103 if (ret < 0) {
1104 fprintf(stderr, "Illegal \"dst_ip\"\n");
1105 return -1;
1106 }
1107 } else if (matches(*argv, "src_ip") == 0) {
1108 NEXT_ARG();
1f0a5dfd
JL
1109 ret = flower_parse_ip_addr(*argv, cvlan_ethtype ?
1110 cvlan_ethtype : vlan_ethtype ?
745d9172 1111 vlan_ethtype : eth_type,
30eb304e
JP
1112 TCA_FLOWER_KEY_IPV4_SRC,
1113 TCA_FLOWER_KEY_IPV4_SRC_MASK,
1114 TCA_FLOWER_KEY_IPV6_SRC,
1115 TCA_FLOWER_KEY_IPV6_SRC_MASK,
1116 n);
1117 if (ret < 0) {
1118 fprintf(stderr, "Illegal \"src_ip\"\n");
1119 return -1;
1120 }
1121 } else if (matches(*argv, "dst_port") == 0) {
1122 NEXT_ARG();
dd7d522a
DA
1123 ret = flower_parse_port(*argv, ip_proto,
1124 FLOWER_ENDPOINT_DST, n);
1125 if (ret < 0) {
1126 fprintf(stderr, "Illegal \"dst_port\"\n");
1127 return -1;
30eb304e
JP
1128 }
1129 } else if (matches(*argv, "src_port") == 0) {
1130 NEXT_ARG();
dd7d522a
DA
1131 ret = flower_parse_port(*argv, ip_proto,
1132 FLOWER_ENDPOINT_SRC, n);
1133 if (ret < 0) {
1134 fprintf(stderr, "Illegal \"src_port\"\n");
1135 return -1;
30eb304e 1136 }
0c30d14d
JP
1137 } else if (matches(*argv, "tcp_flags") == 0) {
1138 NEXT_ARG();
1139 ret = flower_parse_tcp_flags(*argv,
1140 TCA_FLOWER_KEY_TCP_FLAGS,
1141 TCA_FLOWER_KEY_TCP_FLAGS_MASK,
1142 n);
1143 if (ret < 0) {
1144 fprintf(stderr, "Illegal \"tcp_flags\"\n");
1145 return -1;
1146 }
eb3b5696
SH
1147 } else if (matches(*argv, "type") == 0) {
1148 NEXT_ARG();
1149 ret = flower_parse_icmp(*argv, eth_type, ip_proto,
1150 FLOWER_ICMP_FIELD_TYPE, n);
1151 if (ret < 0) {
1152 fprintf(stderr, "Illegal \"icmp type\"\n");
1153 return -1;
1154 }
1155 } else if (matches(*argv, "code") == 0) {
1156 NEXT_ARG();
1157 ret = flower_parse_icmp(*argv, eth_type, ip_proto,
1158 FLOWER_ICMP_FIELD_CODE, n);
1159 if (ret < 0) {
1160 fprintf(stderr, "Illegal \"icmp code\"\n");
1161 return -1;
1162 }
f888f4e2
SH
1163 } else if (matches(*argv, "arp_tip") == 0) {
1164 NEXT_ARG();
1165 ret = flower_parse_arp_ip_addr(*argv, vlan_ethtype ?
1166 vlan_ethtype : eth_type,
1167 TCA_FLOWER_KEY_ARP_TIP,
1168 TCA_FLOWER_KEY_ARP_TIP_MASK,
1169 n);
1170 if (ret < 0) {
1171 fprintf(stderr, "Illegal \"arp_tip\"\n");
1172 return -1;
1173 }
1174 } else if (matches(*argv, "arp_sip") == 0) {
1175 NEXT_ARG();
1176 ret = flower_parse_arp_ip_addr(*argv, vlan_ethtype ?
1177 vlan_ethtype : eth_type,
1178 TCA_FLOWER_KEY_ARP_SIP,
1179 TCA_FLOWER_KEY_ARP_SIP_MASK,
1180 n);
1181 if (ret < 0) {
1182 fprintf(stderr, "Illegal \"arp_sip\"\n");
1183 return -1;
1184 }
1185 } else if (matches(*argv, "arp_op") == 0) {
1186 NEXT_ARG();
1187 ret = flower_parse_arp_op(*argv, vlan_ethtype ?
1188 vlan_ethtype : eth_type,
1189 TCA_FLOWER_KEY_ARP_OP,
1190 TCA_FLOWER_KEY_ARP_OP_MASK,
1191 n);
1192 if (ret < 0) {
1193 fprintf(stderr, "Illegal \"arp_op\"\n");
1194 return -1;
1195 }
1196 } else if (matches(*argv, "arp_tha") == 0) {
1197 NEXT_ARG();
1198 ret = flower_parse_eth_addr(*argv,
1199 TCA_FLOWER_KEY_ARP_THA,
1200 TCA_FLOWER_KEY_ARP_THA_MASK,
1201 n);
1202 if (ret < 0) {
1203 fprintf(stderr, "Illegal \"arp_tha\"\n");
1204 return -1;
1205 }
1206 } else if (matches(*argv, "arp_sha") == 0) {
1207 NEXT_ARG();
1208 ret = flower_parse_eth_addr(*argv,
1209 TCA_FLOWER_KEY_ARP_SHA,
1210 TCA_FLOWER_KEY_ARP_SHA_MASK,
1211 n);
1212 if (ret < 0) {
1213 fprintf(stderr, "Illegal \"arp_sha\"\n");
1214 return -1;
1215 }
bb9b63b1
AV
1216 } else if (matches(*argv, "enc_dst_ip") == 0) {
1217 NEXT_ARG();
1218 ret = flower_parse_ip_addr(*argv, 0,
1219 TCA_FLOWER_KEY_ENC_IPV4_DST,
1220 TCA_FLOWER_KEY_ENC_IPV4_DST_MASK,
1221 TCA_FLOWER_KEY_ENC_IPV6_DST,
1222 TCA_FLOWER_KEY_ENC_IPV6_DST_MASK,
1223 n);
1224 if (ret < 0) {
1225 fprintf(stderr, "Illegal \"enc_dst_ip\"\n");
1226 return -1;
1227 }
1228 } else if (matches(*argv, "enc_src_ip") == 0) {
1229 NEXT_ARG();
1230 ret = flower_parse_ip_addr(*argv, 0,
1231 TCA_FLOWER_KEY_ENC_IPV4_SRC,
1232 TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK,
1233 TCA_FLOWER_KEY_ENC_IPV6_SRC,
1234 TCA_FLOWER_KEY_ENC_IPV6_SRC_MASK,
1235 n);
1236 if (ret < 0) {
1237 fprintf(stderr, "Illegal \"enc_src_ip\"\n");
1238 return -1;
1239 }
1240 } else if (matches(*argv, "enc_key_id") == 0) {
1241 NEXT_ARG();
1242 ret = flower_parse_key_id(*argv,
1243 TCA_FLOWER_KEY_ENC_KEY_ID, n);
1244 if (ret < 0) {
1245 fprintf(stderr, "Illegal \"enc_key_id\"\n");
1246 return -1;
1247 }
41aa17ff
HHZ
1248 } else if (matches(*argv, "enc_dst_port") == 0) {
1249 NEXT_ARG();
1250 ret = flower_parse_enc_port(*argv,
1251 TCA_FLOWER_KEY_ENC_UDP_DST_PORT, n);
1252 if (ret < 0) {
1253 fprintf(stderr, "Illegal \"enc_dst_port\"\n");
1254 return -1;
1255 }
761ec9e2
OG
1256 } else if (matches(*argv, "enc_tos") == 0) {
1257 NEXT_ARG();
1258 ret = flower_parse_ip_tos_ttl(*argv,
1259 TCA_FLOWER_KEY_ENC_IP_TOS,
1260 TCA_FLOWER_KEY_ENC_IP_TOS_MASK,
1261 n);
1262 if (ret < 0) {
1263 fprintf(stderr, "Illegal \"enc_tos\"\n");
1264 return -1;
1265 }
1266 } else if (matches(*argv, "enc_ttl") == 0) {
1267 NEXT_ARG();
1268 ret = flower_parse_ip_tos_ttl(*argv,
1269 TCA_FLOWER_KEY_ENC_IP_TTL,
1270 TCA_FLOWER_KEY_ENC_IP_TTL_MASK,
1271 n);
1272 if (ret < 0) {
1273 fprintf(stderr, "Illegal \"enc_ttl\"\n");
1274 return -1;
1275 }
56155d4d
PJV
1276 } else if (matches(*argv, "geneve_opts") == 0) {
1277 NEXT_ARG();
1278 ret = flower_parse_enc_opts(*argv, n);
1279 if (ret < 0) {
1280 fprintf(stderr, "Illegal \"geneve_opts\"\n");
1281 return -1;
1282 }
30eb304e
JP
1283 } else if (matches(*argv, "action") == 0) {
1284 NEXT_ARG();
1285 ret = parse_action(&argc, &argv, TCA_FLOWER_ACT, n);
1286 if (ret) {
1287 fprintf(stderr, "Illegal \"action\"\n");
1288 return -1;
1289 }
1290 continue;
1291 } else if (strcmp(*argv, "help") == 0) {
1292 explain();
1293 return -1;
1294 } else {
1295 fprintf(stderr, "What is \"%s\"?\n", *argv);
1296 explain();
1297 return -1;
1298 }
1299 argc--; argv++;
1300 }
1301
488b41d0 1302parse_done:
c85609b2
RD
1303 ret = addattr32(n, MAX_MSG, TCA_FLOWER_FLAGS, flags);
1304 if (ret)
1305 return ret;
cfcabf18 1306
08f66c80
PB
1307 if (mtf_mask) {
1308 ret = addattr32(n, MAX_MSG, TCA_FLOWER_KEY_FLAGS, htonl(mtf));
1309 if (ret)
1310 return ret;
1311
1312 ret = addattr32(n, MAX_MSG, TCA_FLOWER_KEY_FLAGS_MASK, htonl(mtf_mask));
1313 if (ret)
1314 return ret;
1315 }
1316
4f7d406f
BL
1317 if (eth_type != htons(ETH_P_ALL)) {
1318 ret = addattr16(n, MAX_MSG, TCA_FLOWER_KEY_ETH_TYPE, eth_type);
1319 if (ret)
1320 return ret;
1321 }
488b41d0 1322
32a121cb 1323 tail->rta_len = (((void *)n)+n->nlmsg_len) - (void *)tail;
30eb304e
JP
1324
1325 return 0;
1326}
1327
1328static int __mask_bits(char *addr, size_t len)
1329{
1330 int bits = 0;
1331 bool hole = false;
1332 int i;
1333 int j;
1334
1335 for (i = 0; i < len; i++, addr++) {
1336 for (j = 7; j >= 0; j--) {
1337 if (((*addr) >> j) & 0x1) {
1338 if (hole)
1339 return -1;
1340 bits++;
1341 } else if (bits) {
1342 hole = true;
1343 } else{
1344 return -1;
1345 }
1346 }
1347 }
1348 return bits;
1349}
1350
e28b88a4 1351static void flower_print_eth_addr(char *name, struct rtattr *addr_attr,
30eb304e
JP
1352 struct rtattr *mask_attr)
1353{
e28b88a4
JP
1354 SPRINT_BUF(namefrm);
1355 SPRINT_BUF(out);
30eb304e 1356 SPRINT_BUF(b1);
e28b88a4 1357 size_t done;
30eb304e
JP
1358 int bits;
1359
1360 if (!addr_attr || RTA_PAYLOAD(addr_attr) != ETH_ALEN)
1361 return;
e28b88a4
JP
1362 done = sprintf(out, "%s",
1363 ll_addr_n2a(RTA_DATA(addr_attr), ETH_ALEN,
1364 0, b1, sizeof(b1)));
1365 if (mask_attr && RTA_PAYLOAD(mask_attr) == ETH_ALEN) {
1366 bits = __mask_bits(RTA_DATA(mask_attr), ETH_ALEN);
1367 if (bits < 0)
1368 sprintf(out + done, "/%s",
1369 ll_addr_n2a(RTA_DATA(mask_attr), ETH_ALEN,
1370 0, b1, sizeof(b1)));
1371 else if (bits < ETH_ALEN * 8)
1372 sprintf(out + done, "/%d", bits);
1373 }
1374
1375 sprintf(namefrm, "\n %s %%s", name);
1376 print_string(PRINT_ANY, name, namefrm, out);
30eb304e
JP
1377}
1378
e28b88a4 1379static void flower_print_eth_type(__be16 *p_eth_type,
30eb304e
JP
1380 struct rtattr *eth_type_attr)
1381{
e28b88a4 1382 SPRINT_BUF(out);
30eb304e
JP
1383 __be16 eth_type;
1384
1385 if (!eth_type_attr)
1386 return;
1387
1388 eth_type = rta_getattr_u16(eth_type_attr);
30eb304e 1389 if (eth_type == htons(ETH_P_IP))
e28b88a4 1390 sprintf(out, "ipv4");
30eb304e 1391 else if (eth_type == htons(ETH_P_IPV6))
e28b88a4 1392 sprintf(out, "ipv6");
f888f4e2 1393 else if (eth_type == htons(ETH_P_ARP))
e28b88a4 1394 sprintf(out, "arp");
f888f4e2 1395 else if (eth_type == htons(ETH_P_RARP))
e28b88a4 1396 sprintf(out, "rarp");
30eb304e 1397 else
e28b88a4
JP
1398 sprintf(out, "%04x", ntohs(eth_type));
1399
1400 print_string(PRINT_ANY, "eth_type", "\n eth_type %s", out);
30eb304e
JP
1401 *p_eth_type = eth_type;
1402}
1403
e28b88a4 1404static void flower_print_ip_proto(__u8 *p_ip_proto,
30eb304e
JP
1405 struct rtattr *ip_proto_attr)
1406{
e28b88a4 1407 SPRINT_BUF(out);
30eb304e
JP
1408 __u8 ip_proto;
1409
1410 if (!ip_proto_attr)
1411 return;
1412
1413 ip_proto = rta_getattr_u8(ip_proto_attr);
30eb304e 1414 if (ip_proto == IPPROTO_TCP)
e28b88a4 1415 sprintf(out, "tcp");
30eb304e 1416 else if (ip_proto == IPPROTO_UDP)
e28b88a4 1417 sprintf(out, "udp");
a1fb0d48 1418 else if (ip_proto == IPPROTO_SCTP)
e28b88a4 1419 sprintf(out, "sctp");
eb3b5696 1420 else if (ip_proto == IPPROTO_ICMP)
e28b88a4 1421 sprintf(out, "icmp");
eb3b5696 1422 else if (ip_proto == IPPROTO_ICMPV6)
e28b88a4 1423 sprintf(out, "icmpv6");
30eb304e 1424 else
e28b88a4
JP
1425 sprintf(out, "%02x", ip_proto);
1426
1427 print_string(PRINT_ANY, "ip_proto", "\n ip_proto %s", out);
30eb304e
JP
1428 *p_ip_proto = ip_proto;
1429}
1430
e8bd3955 1431static void flower_print_ip_attr(const char *name, struct rtattr *key_attr,
6ea2c2b1
OG
1432 struct rtattr *mask_attr)
1433{
e28b88a4
JP
1434 SPRINT_BUF(namefrm);
1435 SPRINT_BUF(out);
1436 size_t done;
1437
6ea2c2b1
OG
1438 if (!key_attr)
1439 return;
1440
e8bd3955 1441 done = sprintf(out, "0x%x", rta_getattr_u8(key_attr));
e28b88a4
JP
1442 if (mask_attr)
1443 sprintf(out + done, "/%x", rta_getattr_u8(mask_attr));
1444
e8bd3955
KL
1445 print_string(PRINT_FP, NULL, "%s ", _SL_);
1446 sprintf(namefrm, "%s %%s", name);
e28b88a4 1447 print_string(PRINT_ANY, name, namefrm, out);
6ea2c2b1
OG
1448}
1449
e28b88a4 1450static void flower_print_matching_flags(char *name,
08f66c80 1451 enum flower_matching_flags type,
22a8f019
PB
1452 struct rtattr *attr,
1453 struct rtattr *mask_attr)
1454{
08f66c80
PB
1455 int i;
1456 int count = 0;
1457 __u32 mtf;
1458 __u32 mtf_mask;
1459
22a8f019
PB
1460 if (!mask_attr || RTA_PAYLOAD(mask_attr) != 4)
1461 return;
1462
08f66c80
PB
1463 mtf = ntohl(rta_getattr_u32(attr));
1464 mtf_mask = ntohl(rta_getattr_u32(mask_attr));
1465
1466 for (i = 0; i < ARRAY_SIZE(flags_str); i++) {
1467 if (type != flags_str[i].type)
1468 continue;
1469 if (mtf_mask & flags_str[i].flag) {
e28b88a4
JP
1470 if (++count == 1) {
1471 print_string(PRINT_FP, NULL, "\n %s ", name);
1472 open_json_object(name);
1473 } else {
1474 print_string(PRINT_FP, NULL, "/", NULL);
1475 }
08f66c80 1476
e28b88a4
JP
1477 print_bool(PRINT_JSON, flags_str[i].string, NULL,
1478 mtf & flags_str[i].flag);
08f66c80 1479 if (mtf & flags_str[i].flag)
e28b88a4
JP
1480 print_string(PRINT_FP, NULL, "%s",
1481 flags_str[i].string);
08f66c80 1482 else
e28b88a4
JP
1483 print_string(PRINT_FP, NULL, "no%s",
1484 flags_str[i].string);
08f66c80
PB
1485 }
1486 }
e28b88a4
JP
1487 if (count)
1488 close_json_object();
22a8f019
PB
1489}
1490
e28b88a4 1491static void flower_print_ip_addr(char *name, __be16 eth_type,
30eb304e
JP
1492 struct rtattr *addr4_attr,
1493 struct rtattr *mask4_attr,
1494 struct rtattr *addr6_attr,
1495 struct rtattr *mask6_attr)
1496{
30eb304e
JP
1497 struct rtattr *addr_attr;
1498 struct rtattr *mask_attr;
e28b88a4
JP
1499 SPRINT_BUF(namefrm);
1500 SPRINT_BUF(out);
1501 size_t done;
30eb304e
JP
1502 int family;
1503 size_t len;
1504 int bits;
1505
1506 if (eth_type == htons(ETH_P_IP)) {
1507 family = AF_INET;
1508 addr_attr = addr4_attr;
1509 mask_attr = mask4_attr;
1510 len = 4;
1511 } else if (eth_type == htons(ETH_P_IPV6)) {
1512 family = AF_INET6;
1513 addr_attr = addr6_attr;
1514 mask_attr = mask6_attr;
1515 len = 16;
1516 } else {
1517 return;
1518 }
1519 if (!addr_attr || RTA_PAYLOAD(addr_attr) != len)
1520 return;
30eb304e
JP
1521 if (!mask_attr || RTA_PAYLOAD(mask_attr) != len)
1522 return;
e28b88a4 1523 done = sprintf(out, "%s", rt_addr_n2a_rta(family, addr_attr));
30eb304e
JP
1524 bits = __mask_bits(RTA_DATA(mask_attr), len);
1525 if (bits < 0)
e28b88a4 1526 sprintf(out + done, "/%s", rt_addr_n2a_rta(family, mask_attr));
30eb304e 1527 else if (bits < len * 8)
e28b88a4
JP
1528 sprintf(out + done, "/%d", bits);
1529
1530 sprintf(namefrm, "\n %s %%s", name);
1531 print_string(PRINT_ANY, name, namefrm, out);
30eb304e 1532}
e28b88a4 1533static void flower_print_ip4_addr(char *name, struct rtattr *addr_attr,
f888f4e2
SH
1534 struct rtattr *mask_attr)
1535{
e28b88a4 1536 return flower_print_ip_addr(name, htons(ETH_P_IP),
f888f4e2
SH
1537 addr_attr, mask_attr, 0, 0);
1538}
30eb304e 1539
e28b88a4 1540static void flower_print_port(char *name, struct rtattr *attr)
30eb304e 1541{
e28b88a4
JP
1542 SPRINT_BUF(namefrm);
1543
1544 if (!attr)
1545 return;
1546
1547 sprintf(namefrm,"\n %s %%u", name);
0b01f088 1548 print_hu(PRINT_ANY, name, namefrm, rta_getattr_be16(attr));
30eb304e
JP
1549}
1550
8930840e
AN
1551static void flower_print_port_range(char *name, struct rtattr *min_attr,
1552 struct rtattr *max_attr)
1553{
1554 if (!min_attr || !max_attr)
1555 return;
1556
1557 if (is_json_context()) {
1558 open_json_object(name);
1559 print_hu(PRINT_JSON, "start", NULL, rta_getattr_be16(min_attr));
1560 print_hu(PRINT_JSON, "end", NULL, rta_getattr_be16(max_attr));
1561 close_json_object();
1562 } else {
1563 SPRINT_BUF(namefrm);
1564 SPRINT_BUF(out);
1565 size_t done;
1566
1567 done = sprintf(out, "%u", rta_getattr_be16(min_attr));
1568 sprintf(out + done, "-%u", rta_getattr_be16(max_attr));
1569 sprintf(namefrm, "\n %s %%s", name);
1570 print_string(PRINT_ANY, name, namefrm, out);
1571 }
1572}
1573
e8bd3955 1574static void flower_print_tcp_flags(const char *name, struct rtattr *flags_attr,
e28b88a4 1575 struct rtattr *mask_attr)
0c30d14d 1576{
e28b88a4
JP
1577 SPRINT_BUF(namefrm);
1578 SPRINT_BUF(out);
1579 size_t done;
1580
0c30d14d
JP
1581 if (!flags_attr)
1582 return;
e28b88a4 1583
e8bd3955 1584 done = sprintf(out, "0x%x", rta_getattr_be16(flags_attr));
e28b88a4 1585 if (mask_attr)
e8bd3955 1586 sprintf(out + done, "/%x", rta_getattr_be16(mask_attr));
e28b88a4 1587
e8bd3955
KL
1588 print_string(PRINT_FP, NULL, "%s ", _SL_);
1589 sprintf(namefrm, "%s %%s", name);
e28b88a4 1590 print_string(PRINT_ANY, name, namefrm, out);
0c30d14d
JP
1591}
1592
1593
e28b88a4 1594static void flower_print_key_id(const char *name, struct rtattr *attr)
bb9b63b1 1595{
e28b88a4
JP
1596 SPRINT_BUF(namefrm);
1597
1598 if (!attr)
1599 return;
1600
1601 sprintf(namefrm,"\n %s %%u", name);
1602 print_uint(PRINT_ANY, name, namefrm, rta_getattr_be32(attr));
bb9b63b1
AV
1603}
1604
56155d4d
PJV
1605static void flower_print_geneve_opts(const char *name, struct rtattr *attr,
1606 char *strbuf)
1607{
1608 struct rtattr *tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX + 1];
1609 int ii, data_len, offset = 0, slen = 0;
1610 struct rtattr *i = RTA_DATA(attr);
1611 int rem = RTA_PAYLOAD(attr);
1612 __u8 type, data_r[rem];
1613 char data[rem * 2 + 1];
1614 __u16 class;
1615
1616 open_json_array(PRINT_JSON, name);
1617 while (rem) {
1618 parse_rtattr(tb, TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX, i, rem);
1619 class = rta_getattr_be16(tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_CLASS]);
1620 type = rta_getattr_u8(tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_TYPE]);
1621 data_len = RTA_PAYLOAD(tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_DATA]);
1622 hexstring_n2a(RTA_DATA(tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_DATA]),
1623 data_len, data, sizeof(data));
1624 hex2mem(data, data_r, data_len);
1625 offset += data_len + 20;
1626 rem -= data_len + 20;
1627 i = RTA_DATA(attr) + offset;
1628
1629 open_json_object(NULL);
1630 print_uint(PRINT_JSON, "class", NULL, class);
1631 print_uint(PRINT_JSON, "type", NULL, type);
1632 open_json_array(PRINT_JSON, "data");
1633 for (ii = 0; ii < data_len; ii++)
1634 print_uint(PRINT_JSON, NULL, NULL, data_r[ii]);
1635 close_json_array(PRINT_JSON, "data");
1636 close_json_object();
1637
1638 slen += sprintf(strbuf + slen, "%04x:%02x:%s",
1639 class, type, data);
1640 if (rem)
1641 slen += sprintf(strbuf + slen, ",");
1642 }
1643 close_json_array(PRINT_JSON, name);
1644}
1645
1646static void flower_print_geneve_parts(const char *name, struct rtattr *attr,
1647 char *key, char *mask)
1648{
1649 char *namefrm = "\n geneve_opt %s";
1650 char *key_token, *mask_token, *out;
1651 int len;
1652
1653 out = malloc(RTA_PAYLOAD(attr) * 4 + 3);
1654 if (!out)
1655 return;
1656
1657 len = 0;
1658 key_token = strsep(&key, ",");
1659 mask_token = strsep(&mask, ",");
1660 while (key_token) {
1661 len += sprintf(&out[len], "%s/%s,", key_token, mask_token);
1662 mask_token = strsep(&mask, ",");
1663 key_token = strsep(&key, ",");
1664 }
1665
1666 out[len - 1] = '\0';
1667 print_string(PRINT_FP, name, namefrm, out);
1668 free(out);
1669}
1670
1671static void flower_print_enc_opts(const char *name, struct rtattr *attr,
1672 struct rtattr *mask_attr)
1673{
1674 struct rtattr *key_tb[TCA_FLOWER_KEY_ENC_OPTS_MAX + 1];
1675 struct rtattr *msk_tb[TCA_FLOWER_KEY_ENC_OPTS_MAX + 1];
1676 char *key, *msk;
1677
1678 if (!attr)
1679 return;
1680
1681 key = malloc(RTA_PAYLOAD(attr) * 2 + 1);
1682 if (!key)
1683 return;
1684
1685 msk = malloc(RTA_PAYLOAD(attr) * 2 + 1);
1686 if (!msk)
1687 goto err_key_free;
1688
1689 parse_rtattr_nested(key_tb, TCA_FLOWER_KEY_ENC_OPTS_MAX, attr);
1690 flower_print_geneve_opts("geneve_opt_key",
1691 key_tb[TCA_FLOWER_KEY_ENC_OPTS_GENEVE], key);
1692
1693 parse_rtattr_nested(msk_tb, TCA_FLOWER_KEY_ENC_OPTS_MAX, mask_attr);
1694 flower_print_geneve_opts("geneve_opt_mask",
1695 msk_tb[TCA_FLOWER_KEY_ENC_OPTS_GENEVE], msk);
1696
1697 flower_print_geneve_parts(name, attr, key, msk);
1698
1699 free(msk);
1700err_key_free:
1701 free(key);
1702}
1703
e28b88a4 1704static void flower_print_masked_u8(const char *name, struct rtattr *attr,
9d36e54f
SH
1705 struct rtattr *mask_attr,
1706 const char *(*value_to_str)(__u8 value))
f888f4e2 1707{
9d36e54f
SH
1708 const char *value_str = NULL;
1709 __u8 value, mask;
e28b88a4
JP
1710 SPRINT_BUF(namefrm);
1711 SPRINT_BUF(out);
1712 size_t done;
f888f4e2 1713
9d36e54f 1714 if (!attr)
f888f4e2
SH
1715 return;
1716
9d36e54f 1717 value = rta_getattr_u8(attr);
f888f4e2 1718 mask = mask_attr ? rta_getattr_u8(mask_attr) : UINT8_MAX;
9d36e54f
SH
1719 if (mask == UINT8_MAX && value_to_str)
1720 value_str = value_to_str(value);
f888f4e2 1721
9d36e54f 1722 if (value_str)
e28b88a4 1723 done = sprintf(out, "%s", value_str);
f888f4e2 1724 else
e28b88a4 1725 done = sprintf(out, "%d", value);
f888f4e2
SH
1726
1727 if (mask != UINT8_MAX)
e28b88a4
JP
1728 sprintf(out + done, "/%d", mask);
1729
1730 sprintf(namefrm,"\n %s %%s", name);
1731 print_string(PRINT_ANY, name, namefrm, out);
f888f4e2
SH
1732}
1733
e28b88a4 1734static void flower_print_u8(const char *name, struct rtattr *attr)
7638ee13 1735{
e28b88a4 1736 flower_print_masked_u8(name, attr, NULL, NULL);
7638ee13
BL
1737}
1738
e28b88a4 1739static void flower_print_u32(const char *name, struct rtattr *attr)
7638ee13 1740{
e28b88a4 1741 SPRINT_BUF(namefrm);
7638ee13
BL
1742
1743 if (!attr)
1744 return;
1745
e28b88a4
JP
1746 sprintf(namefrm,"\n %s %%u", name);
1747 print_uint(PRINT_ANY, name, namefrm, rta_getattr_u32(attr));
7638ee13
BL
1748}
1749
e28b88a4 1750static void flower_print_arp_op(const char *name,
9d36e54f
SH
1751 struct rtattr *op_attr,
1752 struct rtattr *mask_attr)
1753{
e28b88a4 1754 flower_print_masked_u8(name, op_attr, mask_attr,
9d36e54f
SH
1755 flower_print_arp_op_to_name);
1756}
1757
30eb304e
JP
1758static int flower_print_opt(struct filter_util *qu, FILE *f,
1759 struct rtattr *opt, __u32 handle)
1760{
1761 struct rtattr *tb[TCA_FLOWER_MAX + 1];
8930840e 1762 __be16 min_port_type, max_port_type;
6374961a 1763 int nl_type, nl_mask_type;
30eb304e
JP
1764 __be16 eth_type = 0;
1765 __u8 ip_proto = 0xff;
1766
1767 if (!opt)
1768 return 0;
1769
1770 parse_rtattr_nested(tb, TCA_FLOWER_MAX, opt);
1771
1772 if (handle)
e28b88a4 1773 print_uint(PRINT_ANY, "handle", "handle 0x%x ", handle);
30eb304e
JP
1774
1775 if (tb[TCA_FLOWER_CLASSID]) {
0d575c4d
AN
1776 __u32 h = rta_getattr_u32(tb[TCA_FLOWER_CLASSID]);
1777
1778 if (TC_H_MIN(h) < TC_H_MIN_PRIORITY ||
1779 TC_H_MIN(h) > (TC_H_MIN_PRIORITY + TC_QOPT_MAX_QUEUE - 1)) {
1780 SPRINT_BUF(b1);
e28b88a4
JP
1781 print_string(PRINT_ANY, "classid", "classid %s ",
1782 sprint_tc_classid(h, b1));
0d575c4d 1783 } else {
e28b88a4
JP
1784 print_uint(PRINT_ANY, "hw_tc", "hw_tc %u ",
1785 TC_H_MIN(h) - TC_H_MIN_PRIORITY);
0d575c4d 1786 }
30eb304e
JP
1787 }
1788
1789 if (tb[TCA_FLOWER_INDEV]) {
1790 struct rtattr *attr = tb[TCA_FLOWER_INDEV];
1791
e28b88a4
JP
1792 print_string(PRINT_ANY, "indev", "\n indev %s",
1793 rta_getattr_str(attr));
30eb304e
JP
1794 }
1795
e28b88a4
JP
1796 open_json_object("keys");
1797
745d9172
HHZ
1798 if (tb[TCA_FLOWER_KEY_VLAN_ID]) {
1799 struct rtattr *attr = tb[TCA_FLOWER_KEY_VLAN_ID];
1800
e28b88a4
JP
1801 print_uint(PRINT_ANY, "vlan_id", "\n vlan_id %u",
1802 rta_getattr_u16(attr));
745d9172
HHZ
1803 }
1804
1805 if (tb[TCA_FLOWER_KEY_VLAN_PRIO]) {
1806 struct rtattr *attr = tb[TCA_FLOWER_KEY_VLAN_PRIO];
1807
e28b88a4
JP
1808 print_uint(PRINT_ANY, "vlan_prio", "\n vlan_prio %d",
1809 rta_getattr_u8(attr));
745d9172
HHZ
1810 }
1811
1f0a5dfd
JL
1812 if (tb[TCA_FLOWER_KEY_VLAN_ETH_TYPE]) {
1813 SPRINT_BUF(buf);
1814 struct rtattr *attr = tb[TCA_FLOWER_KEY_VLAN_ETH_TYPE];
1815
1816 print_string(PRINT_ANY, "vlan_ethtype", "\n vlan_ethtype %s",
1817 ll_proto_n2a(rta_getattr_u16(attr),
1818 buf, sizeof(buf)));
1819 }
1820
1821 if (tb[TCA_FLOWER_KEY_CVLAN_ID]) {
1822 struct rtattr *attr = tb[TCA_FLOWER_KEY_CVLAN_ID];
1823
1824 print_uint(PRINT_ANY, "cvlan_id", "\n cvlan_id %u",
1825 rta_getattr_u16(attr));
1826 }
1827
1828 if (tb[TCA_FLOWER_KEY_CVLAN_PRIO]) {
1829 struct rtattr *attr = tb[TCA_FLOWER_KEY_CVLAN_PRIO];
1830
1831 print_uint(PRINT_ANY, "cvlan_prio", "\n cvlan_prio %d",
1832 rta_getattr_u8(attr));
1833 }
1834
1835 if (tb[TCA_FLOWER_KEY_CVLAN_ETH_TYPE]) {
1836 SPRINT_BUF(buf);
1837 struct rtattr *attr = tb[TCA_FLOWER_KEY_CVLAN_ETH_TYPE];
1838
1839 print_string(PRINT_ANY, "cvlan_ethtype", "\n cvlan_ethtype %s",
1840 ll_proto_n2a(rta_getattr_u16(attr),
1841 buf, sizeof(buf)));
1842 }
1843
e28b88a4 1844 flower_print_eth_addr("dst_mac", tb[TCA_FLOWER_KEY_ETH_DST],
30eb304e 1845 tb[TCA_FLOWER_KEY_ETH_DST_MASK]);
e28b88a4 1846 flower_print_eth_addr("src_mac", tb[TCA_FLOWER_KEY_ETH_SRC],
30eb304e
JP
1847 tb[TCA_FLOWER_KEY_ETH_SRC_MASK]);
1848
e28b88a4
JP
1849 flower_print_eth_type(&eth_type, tb[TCA_FLOWER_KEY_ETH_TYPE]);
1850 flower_print_ip_proto(&ip_proto, tb[TCA_FLOWER_KEY_IP_PROTO]);
30eb304e 1851
e28b88a4 1852 flower_print_ip_attr("ip_tos", tb[TCA_FLOWER_KEY_IP_TOS],
6ea2c2b1 1853 tb[TCA_FLOWER_KEY_IP_TOS_MASK]);
e28b88a4 1854 flower_print_ip_attr("ip_ttl", tb[TCA_FLOWER_KEY_IP_TTL],
6ea2c2b1
OG
1855 tb[TCA_FLOWER_KEY_IP_TTL_MASK]);
1856
e28b88a4
JP
1857 flower_print_u32("mpls_label", tb[TCA_FLOWER_KEY_MPLS_LABEL]);
1858 flower_print_u8("mpls_tc", tb[TCA_FLOWER_KEY_MPLS_TC]);
1859 flower_print_u8("mpls_bos", tb[TCA_FLOWER_KEY_MPLS_BOS]);
1860 flower_print_u8("mpls_ttl", tb[TCA_FLOWER_KEY_MPLS_TTL]);
7638ee13 1861
e28b88a4 1862 flower_print_ip_addr("dst_ip", eth_type,
30eb304e
JP
1863 tb[TCA_FLOWER_KEY_IPV4_DST],
1864 tb[TCA_FLOWER_KEY_IPV4_DST_MASK],
1865 tb[TCA_FLOWER_KEY_IPV6_DST],
1866 tb[TCA_FLOWER_KEY_IPV6_DST_MASK]);
1867
e28b88a4 1868 flower_print_ip_addr("src_ip", eth_type,
30eb304e
JP
1869 tb[TCA_FLOWER_KEY_IPV4_SRC],
1870 tb[TCA_FLOWER_KEY_IPV4_SRC_MASK],
1871 tb[TCA_FLOWER_KEY_IPV6_SRC],
1872 tb[TCA_FLOWER_KEY_IPV6_SRC_MASK]);
1873
b2141de1 1874 nl_type = flower_port_attr_type(ip_proto, FLOWER_ENDPOINT_DST);
6bd5b80c 1875 if (nl_type >= 0)
e28b88a4 1876 flower_print_port("dst_port", tb[nl_type]);
b2141de1 1877 nl_type = flower_port_attr_type(ip_proto, FLOWER_ENDPOINT_SRC);
6bd5b80c 1878 if (nl_type >= 0)
e28b88a4 1879 flower_print_port("src_port", tb[nl_type]);
30eb304e 1880
8930840e
AN
1881 if (!flower_port_range_attr_type(ip_proto, FLOWER_ENDPOINT_DST,
1882 &min_port_type, &max_port_type))
1883 flower_print_port_range("dst_port",
1884 tb[min_port_type], tb[max_port_type]);
1885
1886 if (!flower_port_range_attr_type(ip_proto, FLOWER_ENDPOINT_SRC,
1887 &min_port_type, &max_port_type))
1888 flower_print_port_range("src_port",
1889 tb[min_port_type], tb[max_port_type]);
1890
e28b88a4 1891 flower_print_tcp_flags("tcp_flags", tb[TCA_FLOWER_KEY_TCP_FLAGS],
0c30d14d
JP
1892 tb[TCA_FLOWER_KEY_TCP_FLAGS_MASK]);
1893
81f6e5a7
SH
1894 nl_type = flower_icmp_attr_type(eth_type, ip_proto,
1895 FLOWER_ICMP_FIELD_TYPE);
6374961a
SH
1896 nl_mask_type = flower_icmp_attr_mask_type(eth_type, ip_proto,
1897 FLOWER_ICMP_FIELD_TYPE);
1898 if (nl_type >= 0 && nl_mask_type >= 0)
e28b88a4 1899 flower_print_masked_u8("icmp_type", tb[nl_type],
6374961a
SH
1900 tb[nl_mask_type], NULL);
1901
81f6e5a7
SH
1902 nl_type = flower_icmp_attr_type(eth_type, ip_proto,
1903 FLOWER_ICMP_FIELD_CODE);
6374961a
SH
1904 nl_mask_type = flower_icmp_attr_mask_type(eth_type, ip_proto,
1905 FLOWER_ICMP_FIELD_CODE);
1906 if (nl_type >= 0 && nl_mask_type >= 0)
e28b88a4 1907 flower_print_masked_u8("icmp_code", tb[nl_type],
6374961a 1908 tb[nl_mask_type], NULL);
eb3b5696 1909
e28b88a4 1910 flower_print_ip4_addr("arp_sip", tb[TCA_FLOWER_KEY_ARP_SIP],
f888f4e2 1911 tb[TCA_FLOWER_KEY_ARP_SIP_MASK]);
e28b88a4 1912 flower_print_ip4_addr("arp_tip", tb[TCA_FLOWER_KEY_ARP_TIP],
f888f4e2 1913 tb[TCA_FLOWER_KEY_ARP_TIP_MASK]);
e28b88a4 1914 flower_print_arp_op("arp_op", tb[TCA_FLOWER_KEY_ARP_OP],
f888f4e2 1915 tb[TCA_FLOWER_KEY_ARP_OP_MASK]);
e28b88a4 1916 flower_print_eth_addr("arp_sha", tb[TCA_FLOWER_KEY_ARP_SHA],
f888f4e2 1917 tb[TCA_FLOWER_KEY_ARP_SHA_MASK]);
e28b88a4 1918 flower_print_eth_addr("arp_tha", tb[TCA_FLOWER_KEY_ARP_THA],
f888f4e2
SH
1919 tb[TCA_FLOWER_KEY_ARP_THA_MASK]);
1920
e28b88a4 1921 flower_print_ip_addr("enc_dst_ip",
bb9b63b1
AV
1922 tb[TCA_FLOWER_KEY_ENC_IPV4_DST_MASK] ?
1923 htons(ETH_P_IP) : htons(ETH_P_IPV6),
1924 tb[TCA_FLOWER_KEY_ENC_IPV4_DST],
1925 tb[TCA_FLOWER_KEY_ENC_IPV4_DST_MASK],
1926 tb[TCA_FLOWER_KEY_ENC_IPV6_DST],
1927 tb[TCA_FLOWER_KEY_ENC_IPV6_DST_MASK]);
1928
e28b88a4 1929 flower_print_ip_addr("enc_src_ip",
bb9b63b1
AV
1930 tb[TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK] ?
1931 htons(ETH_P_IP) : htons(ETH_P_IPV6),
1932 tb[TCA_FLOWER_KEY_ENC_IPV4_SRC],
1933 tb[TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK],
1934 tb[TCA_FLOWER_KEY_ENC_IPV6_SRC],
1935 tb[TCA_FLOWER_KEY_ENC_IPV6_SRC_MASK]);
1936
e28b88a4 1937 flower_print_key_id("enc_key_id", tb[TCA_FLOWER_KEY_ENC_KEY_ID]);
bb9b63b1 1938
e28b88a4 1939 flower_print_port("enc_dst_port", tb[TCA_FLOWER_KEY_ENC_UDP_DST_PORT]);
41aa17ff 1940
761ec9e2
OG
1941 flower_print_ip_attr("enc_tos", tb[TCA_FLOWER_KEY_ENC_IP_TOS],
1942 tb[TCA_FLOWER_KEY_ENC_IP_TOS_MASK]);
1943 flower_print_ip_attr("enc_ttl", tb[TCA_FLOWER_KEY_ENC_IP_TTL],
1944 tb[TCA_FLOWER_KEY_ENC_IP_TTL_MASK]);
56155d4d
PJV
1945 flower_print_enc_opts("enc_opt", tb[TCA_FLOWER_KEY_ENC_OPTS],
1946 tb[TCA_FLOWER_KEY_ENC_OPTS_MASK]);
761ec9e2 1947
e28b88a4 1948 flower_print_matching_flags("ip_flags", FLOWER_IP_FLAGS,
22a8f019
PB
1949 tb[TCA_FLOWER_KEY_FLAGS],
1950 tb[TCA_FLOWER_KEY_FLAGS_MASK]);
1951
e28b88a4
JP
1952 close_json_object();
1953
512caeb2 1954 if (tb[TCA_FLOWER_FLAGS]) {
cfcabf18
AV
1955 __u32 flags = rta_getattr_u32(tb[TCA_FLOWER_FLAGS]);
1956
1957 if (flags & TCA_CLS_FLAGS_SKIP_HW)
e28b88a4 1958 print_bool(PRINT_ANY, "skip_hw", "\n skip_hw", true);
cfcabf18 1959 if (flags & TCA_CLS_FLAGS_SKIP_SW)
e28b88a4 1960 print_bool(PRINT_ANY, "skip_sw", "\n skip_sw", true);
e57285b8 1961
f6b498f9 1962 if (flags & TCA_CLS_FLAGS_IN_HW) {
e28b88a4 1963 print_bool(PRINT_ANY, "in_hw", "\n in_hw", true);
f6b498f9
VB
1964
1965 if (tb[TCA_FLOWER_IN_HW_COUNT]) {
1966 __u32 count = rta_getattr_u32(tb[TCA_FLOWER_IN_HW_COUNT]);
1967
1968 print_uint(PRINT_ANY, "in_hw_count",
1969 " in_hw_count %u", count);
1970 }
1971 }
e57285b8 1972 else if (flags & TCA_CLS_FLAGS_NOT_IN_HW)
e28b88a4 1973 print_bool(PRINT_ANY, "not_in_hw", "\n not_in_hw", true);
cfcabf18
AV
1974 }
1975
512caeb2 1976 if (tb[TCA_FLOWER_ACT])
9e713525 1977 tc_print_action(f, tb[TCA_FLOWER_ACT], 0);
30eb304e
JP
1978
1979 return 0;
1980}
1981
1982struct filter_util flower_filter_util = {
1983 .id = "flower",
1984 .parse_fopt = flower_parse_opt,
1985 .print_fopt = flower_print_opt,
1986};