]> git.proxmox.com Git - mirror_iproute2.git/blob - tc/f_flower.c
Merge branch 'iproute2-master' into iproute2-next
[mirror_iproute2.git] / tc / f_flower.c
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>
15 #include <string.h>
16 #include <net/if.h>
17 #include <linux/if_arp.h>
18 #include <linux/if_ether.h>
19 #include <linux/ip.h>
20 #include <linux/tc_act/tc_vlan.h>
21 #include <linux/mpls.h>
22
23 #include "utils.h"
24 #include "tc_util.h"
25 #include "rt_names.h"
26
27 enum flower_matching_flags {
28 FLOWER_IP_FLAGS,
29 };
30
31 enum flower_endpoint {
32 FLOWER_ENDPOINT_SRC,
33 FLOWER_ENDPOINT_DST
34 };
35
36 enum flower_icmp_field {
37 FLOWER_ICMP_FIELD_TYPE,
38 FLOWER_ICMP_FIELD_CODE
39 };
40
41 static void explain(void)
42 {
43 fprintf(stderr,
44 "Usage: ... flower [ MATCH-LIST ] [ verbose ]\n"
45 " [ skip_sw | skip_hw ]\n"
46 " [ action ACTION-SPEC ] [ classid CLASSID ]\n"
47 "\n"
48 "Where: MATCH-LIST := [ MATCH-LIST ] MATCH\n"
49 " MATCH := { indev DEV-NAME |\n"
50 " vlan_id VID |\n"
51 " vlan_prio PRIORITY |\n"
52 " vlan_ethtype [ ipv4 | ipv6 | ETH-TYPE ] |\n"
53 " cvlan_id VID |\n"
54 " cvlan_prio PRIORITY |\n"
55 " cvlan_ethtype [ ipv4 | ipv6 | ETH-TYPE ] |\n"
56 " dst_mac MASKED-LLADDR |\n"
57 " src_mac MASKED-LLADDR |\n"
58 " ip_proto [tcp | udp | sctp | icmp | icmpv6 | IP-PROTO ] |\n"
59 " ip_tos MASKED-IP_TOS |\n"
60 " ip_ttl MASKED-IP_TTL |\n"
61 " mpls_label LABEL |\n"
62 " mpls_tc TC |\n"
63 " mpls_bos BOS |\n"
64 " mpls_ttl TTL |\n"
65 " dst_ip PREFIX |\n"
66 " src_ip PREFIX |\n"
67 " dst_port PORT-NUMBER |\n"
68 " src_port PORT-NUMBER |\n"
69 " tcp_flags MASKED-TCP_FLAGS |\n"
70 " type MASKED-ICMP-TYPE |\n"
71 " code MASKED-ICMP-CODE |\n"
72 " arp_tip IPV4-PREFIX |\n"
73 " arp_sip IPV4-PREFIX |\n"
74 " arp_op [ request | reply | OP ] |\n"
75 " arp_tha MASKED-LLADDR |\n"
76 " arp_sha MASKED-LLADDR |\n"
77 " enc_dst_ip [ IPV4-ADDR | IPV6-ADDR ] |\n"
78 " enc_src_ip [ IPV4-ADDR | IPV6-ADDR ] |\n"
79 " enc_key_id [ KEY-ID ] |\n"
80 " enc_tos MASKED-IP_TOS |\n"
81 " enc_ttl MASKED-IP_TTL |\n"
82 " ip_flags IP-FLAGS | \n"
83 " enc_dst_port [ port_number ] }\n"
84 " FILTERID := X:Y:Z\n"
85 " MASKED_LLADDR := { LLADDR | LLADDR/MASK | LLADDR/BITS }\n"
86 " ACTION-SPEC := ... look at individual actions\n"
87 "\n"
88 "NOTE: CLASSID, IP-PROTO are parsed as hexadecimal input.\n"
89 "NOTE: There can be only used one mask per one prio. If user needs\n"
90 " to specify different mask, he has to use different prio.\n");
91 }
92
93 static int flower_parse_eth_addr(char *str, int addr_type, int mask_type,
94 struct nlmsghdr *n)
95 {
96 int ret, err = -1;
97 char addr[ETH_ALEN], *slash;
98
99 slash = strchr(str, '/');
100 if (slash)
101 *slash = '\0';
102
103 ret = ll_addr_a2n(addr, sizeof(addr), str);
104 if (ret < 0)
105 goto err;
106 addattr_l(n, MAX_MSG, addr_type, addr, sizeof(addr));
107
108 if (slash) {
109 unsigned bits;
110
111 if (!get_unsigned(&bits, slash + 1, 10)) {
112 uint64_t mask;
113
114 /* Extra 16 bit shift to push mac address into
115 * high bits of uint64_t
116 */
117 mask = htonll(0xffffffffffffULL << (16 + 48 - bits));
118 memcpy(addr, &mask, ETH_ALEN);
119 } else {
120 ret = ll_addr_a2n(addr, sizeof(addr), slash + 1);
121 if (ret < 0)
122 goto err;
123 }
124 } else {
125 memset(addr, 0xff, ETH_ALEN);
126 }
127 addattr_l(n, MAX_MSG, mask_type, addr, sizeof(addr));
128
129 err = 0;
130 err:
131 if (slash)
132 *slash = '/';
133 return err;
134 }
135
136 static bool eth_type_vlan(__be16 ethertype)
137 {
138 return ethertype == htons(ETH_P_8021Q) ||
139 ethertype == htons(ETH_P_8021AD);
140 }
141
142 static int flower_parse_vlan_eth_type(char *str, __be16 eth_type, int type,
143 __be16 *p_vlan_eth_type,
144 struct nlmsghdr *n)
145 {
146 __be16 vlan_eth_type;
147
148 if (!eth_type_vlan(eth_type)) {
149 fprintf(stderr, "Can't set \"%s\" if ethertype isn't 802.1Q or 802.1AD\n",
150 type == TCA_FLOWER_KEY_VLAN_ETH_TYPE ? "vlan_ethtype" : "cvlan_ethtype");
151 return -1;
152 }
153
154 if (ll_proto_a2n(&vlan_eth_type, str))
155 invarg("invalid vlan_ethtype", str);
156 addattr16(n, MAX_MSG, type, vlan_eth_type);
157 *p_vlan_eth_type = vlan_eth_type;
158 return 0;
159 }
160
161 struct flag_to_string {
162 int flag;
163 enum flower_matching_flags type;
164 char *string;
165 };
166
167 static struct flag_to_string flags_str[] = {
168 { TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT, FLOWER_IP_FLAGS, "frag" },
169 { TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST, FLOWER_IP_FLAGS, "firstfrag" },
170 };
171
172 static int flower_parse_matching_flags(char *str,
173 enum flower_matching_flags type,
174 __u32 *mtf, __u32 *mtf_mask)
175 {
176 char *token;
177 bool no;
178 bool found;
179 int i;
180
181 token = strtok(str, "/");
182
183 while (token) {
184 if (!strncmp(token, "no", 2)) {
185 no = true;
186 token += 2;
187 } else
188 no = false;
189
190 found = false;
191 for (i = 0; i < ARRAY_SIZE(flags_str); i++) {
192 if (type != flags_str[i].type)
193 continue;
194
195 if (!strcmp(token, flags_str[i].string)) {
196 if (no)
197 *mtf &= ~flags_str[i].flag;
198 else
199 *mtf |= flags_str[i].flag;
200
201 *mtf_mask |= flags_str[i].flag;
202 found = true;
203 break;
204 }
205 }
206 if (!found)
207 return -1;
208
209 token = strtok(NULL, "/");
210 }
211
212 return 0;
213 }
214
215 static int flower_parse_ip_proto(char *str, __be16 eth_type, int type,
216 __u8 *p_ip_proto, struct nlmsghdr *n)
217 {
218 int ret;
219 __u8 ip_proto;
220
221 if (eth_type != htons(ETH_P_IP) && eth_type != htons(ETH_P_IPV6))
222 goto err;
223
224 if (matches(str, "tcp") == 0) {
225 ip_proto = IPPROTO_TCP;
226 } else if (matches(str, "udp") == 0) {
227 ip_proto = IPPROTO_UDP;
228 } else if (matches(str, "sctp") == 0) {
229 ip_proto = IPPROTO_SCTP;
230 } else if (matches(str, "icmp") == 0) {
231 if (eth_type != htons(ETH_P_IP))
232 goto err;
233 ip_proto = IPPROTO_ICMP;
234 } else if (matches(str, "icmpv6") == 0) {
235 if (eth_type != htons(ETH_P_IPV6))
236 goto err;
237 ip_proto = IPPROTO_ICMPV6;
238 } else {
239 ret = get_u8(&ip_proto, str, 16);
240 if (ret)
241 return -1;
242 }
243 addattr8(n, MAX_MSG, type, ip_proto);
244 *p_ip_proto = ip_proto;
245 return 0;
246
247 err:
248 fprintf(stderr, "Illegal \"eth_type\" for ip proto\n");
249 return -1;
250 }
251
252 static int __flower_parse_ip_addr(char *str, int family,
253 int addr4_type, int mask4_type,
254 int addr6_type, int mask6_type,
255 struct nlmsghdr *n)
256 {
257 int ret;
258 inet_prefix addr;
259 int bits;
260 int i;
261
262 ret = get_prefix(&addr, str, family);
263 if (ret)
264 return -1;
265
266 if (family && (addr.family != family)) {
267 fprintf(stderr, "Illegal \"eth_type\" for ip address\n");
268 return -1;
269 }
270
271 addattr_l(n, MAX_MSG, addr.family == AF_INET ? addr4_type : addr6_type,
272 addr.data, addr.bytelen);
273
274 memset(addr.data, 0xff, addr.bytelen);
275 bits = addr.bitlen;
276 for (i = 0; i < addr.bytelen / 4; i++) {
277 if (!bits) {
278 addr.data[i] = 0;
279 } else if (bits / 32 >= 1) {
280 bits -= 32;
281 } else {
282 addr.data[i] <<= 32 - bits;
283 addr.data[i] = htonl(addr.data[i]);
284 bits = 0;
285 }
286 }
287
288 addattr_l(n, MAX_MSG, addr.family == AF_INET ? mask4_type : mask6_type,
289 addr.data, addr.bytelen);
290
291 return 0;
292 }
293
294 static int flower_parse_ip_addr(char *str, __be16 eth_type,
295 int addr4_type, int mask4_type,
296 int addr6_type, int mask6_type,
297 struct nlmsghdr *n)
298 {
299 int family;
300
301 if (eth_type == htons(ETH_P_IP)) {
302 family = AF_INET;
303 } else if (eth_type == htons(ETH_P_IPV6)) {
304 family = AF_INET6;
305 } else if (!eth_type) {
306 family = AF_UNSPEC;
307 } else {
308 return -1;
309 }
310
311 return __flower_parse_ip_addr(str, family, addr4_type, mask4_type,
312 addr6_type, mask6_type, n);
313 }
314
315 static bool flower_eth_type_arp(__be16 eth_type)
316 {
317 return eth_type == htons(ETH_P_ARP) || eth_type == htons(ETH_P_RARP);
318 }
319
320 static int flower_parse_arp_ip_addr(char *str, __be16 eth_type,
321 int addr_type, int mask_type,
322 struct nlmsghdr *n)
323 {
324 if (!flower_eth_type_arp(eth_type))
325 return -1;
326
327 return __flower_parse_ip_addr(str, AF_INET, addr_type, mask_type,
328 TCA_FLOWER_UNSPEC, TCA_FLOWER_UNSPEC, n);
329 }
330
331 static int flower_parse_u8(char *str, int value_type, int mask_type,
332 int (*value_from_name)(const char *str,
333 __u8 *value),
334 bool (*value_validate)(__u8 value),
335 struct nlmsghdr *n)
336 {
337 char *slash;
338 int ret, err = -1;
339 __u8 value, mask;
340
341 slash = strchr(str, '/');
342 if (slash)
343 *slash = '\0';
344
345 ret = value_from_name ? value_from_name(str, &value) : -1;
346 if (ret < 0) {
347 ret = get_u8(&value, str, 10);
348 if (ret)
349 goto err;
350 }
351
352 if (value_validate && !value_validate(value))
353 goto err;
354
355 if (slash) {
356 ret = get_u8(&mask, slash + 1, 10);
357 if (ret)
358 goto err;
359 }
360 else {
361 mask = UINT8_MAX;
362 }
363
364 addattr8(n, MAX_MSG, value_type, value);
365 addattr8(n, MAX_MSG, mask_type, mask);
366
367 err = 0;
368 err:
369 if (slash)
370 *slash = '/';
371 return err;
372 }
373
374 static const char *flower_print_arp_op_to_name(__u8 op)
375 {
376 switch (op) {
377 case ARPOP_REQUEST:
378 return "request";
379 case ARPOP_REPLY:
380 return "reply";
381 default:
382 return NULL;
383 }
384 }
385
386 static int flower_arp_op_from_name(const char *name, __u8 *op)
387 {
388 if (!strcmp(name, "request"))
389 *op = ARPOP_REQUEST;
390 else if (!strcmp(name, "reply"))
391 *op = ARPOP_REPLY;
392 else
393 return -1;
394
395 return 0;
396 }
397
398 static bool flow_arp_op_validate(__u8 op)
399 {
400 return !op || op == ARPOP_REQUEST || op == ARPOP_REPLY;
401 }
402
403 static int flower_parse_arp_op(char *str, __be16 eth_type,
404 int op_type, int mask_type,
405 struct nlmsghdr *n)
406 {
407 if (!flower_eth_type_arp(eth_type))
408 return -1;
409
410 return flower_parse_u8(str, op_type, mask_type, flower_arp_op_from_name,
411 flow_arp_op_validate, n);
412 }
413
414 static int flower_icmp_attr_type(__be16 eth_type, __u8 ip_proto,
415 enum flower_icmp_field field)
416 {
417 if (eth_type == htons(ETH_P_IP) && ip_proto == IPPROTO_ICMP)
418 return field == FLOWER_ICMP_FIELD_CODE ?
419 TCA_FLOWER_KEY_ICMPV4_CODE :
420 TCA_FLOWER_KEY_ICMPV4_TYPE;
421 else if (eth_type == htons(ETH_P_IPV6) && ip_proto == IPPROTO_ICMPV6)
422 return field == FLOWER_ICMP_FIELD_CODE ?
423 TCA_FLOWER_KEY_ICMPV6_CODE :
424 TCA_FLOWER_KEY_ICMPV6_TYPE;
425
426 return -1;
427 }
428
429 static int flower_icmp_attr_mask_type(__be16 eth_type, __u8 ip_proto,
430 enum flower_icmp_field field)
431 {
432 if (eth_type == htons(ETH_P_IP) && ip_proto == IPPROTO_ICMP)
433 return field == FLOWER_ICMP_FIELD_CODE ?
434 TCA_FLOWER_KEY_ICMPV4_CODE_MASK :
435 TCA_FLOWER_KEY_ICMPV4_TYPE_MASK;
436 else if (eth_type == htons(ETH_P_IPV6) && ip_proto == IPPROTO_ICMPV6)
437 return field == FLOWER_ICMP_FIELD_CODE ?
438 TCA_FLOWER_KEY_ICMPV6_CODE_MASK :
439 TCA_FLOWER_KEY_ICMPV6_TYPE_MASK;
440
441 return -1;
442 }
443
444 static int flower_parse_icmp(char *str, __u16 eth_type, __u8 ip_proto,
445 enum flower_icmp_field field, struct nlmsghdr *n)
446 {
447 int value_type, mask_type;
448
449 value_type = flower_icmp_attr_type(eth_type, ip_proto, field);
450 mask_type = flower_icmp_attr_mask_type(eth_type, ip_proto, field);
451 if (value_type < 0 || mask_type < 0)
452 return -1;
453
454 return flower_parse_u8(str, value_type, mask_type, NULL, NULL, n);
455 }
456
457 static int flower_port_attr_type(__u8 ip_proto, enum flower_endpoint endpoint)
458 {
459 if (ip_proto == IPPROTO_TCP)
460 return endpoint == FLOWER_ENDPOINT_SRC ?
461 TCA_FLOWER_KEY_TCP_SRC :
462 TCA_FLOWER_KEY_TCP_DST;
463 else if (ip_proto == IPPROTO_UDP)
464 return endpoint == FLOWER_ENDPOINT_SRC ?
465 TCA_FLOWER_KEY_UDP_SRC :
466 TCA_FLOWER_KEY_UDP_DST;
467 else if (ip_proto == IPPROTO_SCTP)
468 return endpoint == FLOWER_ENDPOINT_SRC ?
469 TCA_FLOWER_KEY_SCTP_SRC :
470 TCA_FLOWER_KEY_SCTP_DST;
471 else
472 return -1;
473 }
474
475 static int flower_parse_port(char *str, __u8 ip_proto,
476 enum flower_endpoint endpoint,
477 struct nlmsghdr *n)
478 {
479 int ret;
480 int type;
481 __be16 port;
482
483 type = flower_port_attr_type(ip_proto, endpoint);
484 if (type < 0)
485 return -1;
486
487 ret = get_be16(&port, str, 10);
488 if (ret)
489 return -1;
490
491 addattr16(n, MAX_MSG, type, port);
492
493 return 0;
494 }
495
496 #define TCP_FLAGS_MAX_MASK 0xfff
497
498 static int flower_parse_tcp_flags(char *str, int flags_type, int mask_type,
499 struct nlmsghdr *n)
500 {
501 char *slash;
502 int ret, err = -1;
503 __u16 flags;
504
505 slash = strchr(str, '/');
506 if (slash)
507 *slash = '\0';
508
509 ret = get_u16(&flags, str, 16);
510 if (ret < 0 || flags & ~TCP_FLAGS_MAX_MASK)
511 goto err;
512
513 addattr16(n, MAX_MSG, flags_type, htons(flags));
514
515 if (slash) {
516 ret = get_u16(&flags, slash + 1, 16);
517 if (ret < 0 || flags & ~TCP_FLAGS_MAX_MASK)
518 goto err;
519 } else {
520 flags = TCP_FLAGS_MAX_MASK;
521 }
522 addattr16(n, MAX_MSG, mask_type, htons(flags));
523
524 err = 0;
525 err:
526 if (slash)
527 *slash = '/';
528 return err;
529 }
530
531 static int flower_parse_ip_tos_ttl(char *str, int key_type, int mask_type,
532 struct nlmsghdr *n)
533 {
534 char *slash;
535 int ret, err = -1;
536 __u8 tos_ttl;
537
538 slash = strchr(str, '/');
539 if (slash)
540 *slash = '\0';
541
542 ret = get_u8(&tos_ttl, str, 10);
543 if (ret < 0)
544 ret = get_u8(&tos_ttl, str, 16);
545 if (ret < 0)
546 goto err;
547
548 addattr8(n, MAX_MSG, key_type, tos_ttl);
549
550 if (slash) {
551 ret = get_u8(&tos_ttl, slash + 1, 16);
552 if (ret < 0)
553 goto err;
554 } else {
555 tos_ttl = 0xff;
556 }
557 addattr8(n, MAX_MSG, mask_type, tos_ttl);
558
559 err = 0;
560 err:
561 if (slash)
562 *slash = '/';
563 return err;
564 }
565
566 static int flower_parse_key_id(const char *str, int type, struct nlmsghdr *n)
567 {
568 int ret;
569 __be32 key_id;
570
571 ret = get_be32(&key_id, str, 10);
572 if (!ret)
573 addattr32(n, MAX_MSG, type, key_id);
574
575 return ret;
576 }
577
578 static int flower_parse_enc_port(char *str, int type, struct nlmsghdr *n)
579 {
580 int ret;
581 __be16 port;
582
583 ret = get_be16(&port, str, 10);
584 if (ret)
585 return -1;
586
587 addattr16(n, MAX_MSG, type, port);
588
589 return 0;
590 }
591
592 static int flower_parse_opt(struct filter_util *qu, char *handle,
593 int argc, char **argv, struct nlmsghdr *n)
594 {
595 int ret;
596 struct tcmsg *t = NLMSG_DATA(n);
597 struct rtattr *tail;
598 __be16 eth_type = TC_H_MIN(t->tcm_info);
599 __be16 vlan_ethtype = 0;
600 __be16 cvlan_ethtype = 0;
601 __u8 ip_proto = 0xff;
602 __u32 flags = 0;
603 __u32 mtf = 0;
604 __u32 mtf_mask = 0;
605
606 if (handle) {
607 ret = get_u32(&t->tcm_handle, handle, 0);
608 if (ret) {
609 fprintf(stderr, "Illegal \"handle\"\n");
610 return -1;
611 }
612 }
613
614 tail = (struct rtattr *) (((void *) n) + NLMSG_ALIGN(n->nlmsg_len));
615 addattr_l(n, MAX_MSG, TCA_OPTIONS, NULL, 0);
616
617 if (argc == 0) {
618 /*at minimal we will match all ethertype packets */
619 goto parse_done;
620 }
621
622 while (argc > 0) {
623 if (matches(*argv, "classid") == 0 ||
624 matches(*argv, "flowid") == 0) {
625 unsigned int handle;
626
627 NEXT_ARG();
628 ret = get_tc_classid(&handle, *argv);
629 if (ret) {
630 fprintf(stderr, "Illegal \"classid\"\n");
631 return -1;
632 }
633 addattr_l(n, MAX_MSG, TCA_FLOWER_CLASSID, &handle, 4);
634 } else if (matches(*argv, "hw_tc") == 0) {
635 unsigned int handle;
636 __u32 tc;
637 char *end;
638
639 NEXT_ARG();
640 tc = strtoul(*argv, &end, 0);
641 if (*end) {
642 fprintf(stderr, "Illegal TC index\n");
643 return -1;
644 }
645 if (tc >= TC_QOPT_MAX_QUEUE) {
646 fprintf(stderr, "TC index exceeds max range\n");
647 return -1;
648 }
649 handle = TC_H_MAKE(TC_H_MAJ(t->tcm_parent),
650 TC_H_MIN(tc + TC_H_MIN_PRIORITY));
651 addattr_l(n, MAX_MSG, TCA_FLOWER_CLASSID, &handle,
652 sizeof(handle));
653 } else if (matches(*argv, "ip_flags") == 0) {
654 NEXT_ARG();
655 ret = flower_parse_matching_flags(*argv,
656 FLOWER_IP_FLAGS,
657 &mtf,
658 &mtf_mask);
659 if (ret < 0) {
660 fprintf(stderr, "Illegal \"ip_flags\"\n");
661 return -1;
662 }
663 } else if (matches(*argv, "verbose") == 0) {
664 flags |= TCA_CLS_FLAGS_VERBOSE;
665 } else if (matches(*argv, "skip_hw") == 0) {
666 flags |= TCA_CLS_FLAGS_SKIP_HW;
667 } else if (matches(*argv, "skip_sw") == 0) {
668 flags |= TCA_CLS_FLAGS_SKIP_SW;
669 } else if (matches(*argv, "indev") == 0) {
670 NEXT_ARG();
671 if (check_ifname(*argv))
672 invarg("\"indev\" not a valid ifname", *argv);
673 addattrstrz(n, MAX_MSG, TCA_FLOWER_INDEV, *argv);
674 } else if (matches(*argv, "vlan_id") == 0) {
675 __u16 vid;
676
677 NEXT_ARG();
678 if (!eth_type_vlan(eth_type)) {
679 fprintf(stderr, "Can't set \"vlan_id\" if ethertype isn't 802.1Q or 802.1AD\n");
680 return -1;
681 }
682 ret = get_u16(&vid, *argv, 10);
683 if (ret < 0 || vid & ~0xfff) {
684 fprintf(stderr, "Illegal \"vlan_id\"\n");
685 return -1;
686 }
687 addattr16(n, MAX_MSG, TCA_FLOWER_KEY_VLAN_ID, vid);
688 } else if (matches(*argv, "vlan_prio") == 0) {
689 __u8 vlan_prio;
690
691 NEXT_ARG();
692 if (!eth_type_vlan(eth_type)) {
693 fprintf(stderr, "Can't set \"vlan_prio\" if ethertype isn't 802.1Q or 802.1AD\n");
694 return -1;
695 }
696 ret = get_u8(&vlan_prio, *argv, 10);
697 if (ret < 0 || vlan_prio & ~0x7) {
698 fprintf(stderr, "Illegal \"vlan_prio\"\n");
699 return -1;
700 }
701 addattr8(n, MAX_MSG,
702 TCA_FLOWER_KEY_VLAN_PRIO, vlan_prio);
703 } else if (matches(*argv, "vlan_ethtype") == 0) {
704 NEXT_ARG();
705 ret = flower_parse_vlan_eth_type(*argv, eth_type,
706 TCA_FLOWER_KEY_VLAN_ETH_TYPE,
707 &vlan_ethtype, n);
708 if (ret < 0)
709 return -1;
710 } else if (matches(*argv, "cvlan_id") == 0) {
711 __u16 vid;
712
713 NEXT_ARG();
714 if (!eth_type_vlan(vlan_ethtype)) {
715 fprintf(stderr, "Can't set \"cvlan_id\" if inner vlan ethertype isn't 802.1Q or 802.1AD\n");
716 return -1;
717 }
718 ret = get_u16(&vid, *argv, 10);
719 if (ret < 0 || vid & ~0xfff) {
720 fprintf(stderr, "Illegal \"cvlan_id\"\n");
721 return -1;
722 }
723 addattr16(n, MAX_MSG, TCA_FLOWER_KEY_CVLAN_ID, vid);
724 } else if (matches(*argv, "cvlan_prio") == 0) {
725 __u8 cvlan_prio;
726
727 NEXT_ARG();
728 if (!eth_type_vlan(vlan_ethtype)) {
729 fprintf(stderr, "Can't set \"cvlan_prio\" if inner vlan ethertype isn't 802.1Q or 802.1AD\n");
730 return -1;
731 }
732 ret = get_u8(&cvlan_prio, *argv, 10);
733 if (ret < 0 || cvlan_prio & ~0x7) {
734 fprintf(stderr, "Illegal \"cvlan_prio\"\n");
735 return -1;
736 }
737 addattr8(n, MAX_MSG,
738 TCA_FLOWER_KEY_CVLAN_PRIO, cvlan_prio);
739 } else if (matches(*argv, "cvlan_ethtype") == 0) {
740 NEXT_ARG();
741 ret = flower_parse_vlan_eth_type(*argv, vlan_ethtype,
742 TCA_FLOWER_KEY_CVLAN_ETH_TYPE,
743 &cvlan_ethtype, n);
744 if (ret < 0)
745 return -1;
746 } else if (matches(*argv, "mpls_label") == 0) {
747 __u32 label;
748
749 NEXT_ARG();
750 if (eth_type != htons(ETH_P_MPLS_UC) &&
751 eth_type != htons(ETH_P_MPLS_MC)) {
752 fprintf(stderr,
753 "Can't set \"mpls_label\" if ethertype isn't MPLS\n");
754 return -1;
755 }
756 ret = get_u32(&label, *argv, 10);
757 if (ret < 0 || label & ~(MPLS_LS_LABEL_MASK >> MPLS_LS_LABEL_SHIFT)) {
758 fprintf(stderr, "Illegal \"mpls_label\"\n");
759 return -1;
760 }
761 addattr32(n, MAX_MSG, TCA_FLOWER_KEY_MPLS_LABEL, label);
762 } else if (matches(*argv, "mpls_tc") == 0) {
763 __u8 tc;
764
765 NEXT_ARG();
766 if (eth_type != htons(ETH_P_MPLS_UC) &&
767 eth_type != htons(ETH_P_MPLS_MC)) {
768 fprintf(stderr,
769 "Can't set \"mpls_tc\" if ethertype isn't MPLS\n");
770 return -1;
771 }
772 ret = get_u8(&tc, *argv, 10);
773 if (ret < 0 || tc & ~(MPLS_LS_TC_MASK >> MPLS_LS_TC_SHIFT)) {
774 fprintf(stderr, "Illegal \"mpls_tc\"\n");
775 return -1;
776 }
777 addattr8(n, MAX_MSG, TCA_FLOWER_KEY_MPLS_TC, tc);
778 } else if (matches(*argv, "mpls_bos") == 0) {
779 __u8 bos;
780
781 NEXT_ARG();
782 if (eth_type != htons(ETH_P_MPLS_UC) &&
783 eth_type != htons(ETH_P_MPLS_MC)) {
784 fprintf(stderr,
785 "Can't set \"mpls_bos\" if ethertype isn't MPLS\n");
786 return -1;
787 }
788 ret = get_u8(&bos, *argv, 10);
789 if (ret < 0 || bos & ~(MPLS_LS_S_MASK >> MPLS_LS_S_SHIFT)) {
790 fprintf(stderr, "Illegal \"mpls_bos\"\n");
791 return -1;
792 }
793 addattr8(n, MAX_MSG, TCA_FLOWER_KEY_MPLS_BOS, bos);
794 } else if (matches(*argv, "mpls_ttl") == 0) {
795 __u8 ttl;
796
797 NEXT_ARG();
798 if (eth_type != htons(ETH_P_MPLS_UC) &&
799 eth_type != htons(ETH_P_MPLS_MC)) {
800 fprintf(stderr,
801 "Can't set \"mpls_ttl\" if ethertype isn't MPLS\n");
802 return -1;
803 }
804 ret = get_u8(&ttl, *argv, 10);
805 if (ret < 0 || ttl & ~(MPLS_LS_TTL_MASK >> MPLS_LS_TTL_SHIFT)) {
806 fprintf(stderr, "Illegal \"mpls_ttl\"\n");
807 return -1;
808 }
809 addattr8(n, MAX_MSG, TCA_FLOWER_KEY_MPLS_TTL, ttl);
810 } else if (matches(*argv, "dst_mac") == 0) {
811 NEXT_ARG();
812 ret = flower_parse_eth_addr(*argv,
813 TCA_FLOWER_KEY_ETH_DST,
814 TCA_FLOWER_KEY_ETH_DST_MASK,
815 n);
816 if (ret < 0) {
817 fprintf(stderr, "Illegal \"dst_mac\"\n");
818 return -1;
819 }
820 } else if (matches(*argv, "src_mac") == 0) {
821 NEXT_ARG();
822 ret = flower_parse_eth_addr(*argv,
823 TCA_FLOWER_KEY_ETH_SRC,
824 TCA_FLOWER_KEY_ETH_SRC_MASK,
825 n);
826 if (ret < 0) {
827 fprintf(stderr, "Illegal \"src_mac\"\n");
828 return -1;
829 }
830 } else if (matches(*argv, "ip_proto") == 0) {
831 NEXT_ARG();
832 ret = flower_parse_ip_proto(*argv, cvlan_ethtype ?
833 cvlan_ethtype : vlan_ethtype ?
834 vlan_ethtype : eth_type,
835 TCA_FLOWER_KEY_IP_PROTO,
836 &ip_proto, n);
837 if (ret < 0) {
838 fprintf(stderr, "Illegal \"ip_proto\"\n");
839 return -1;
840 }
841 } else if (matches(*argv, "ip_tos") == 0) {
842 NEXT_ARG();
843 ret = flower_parse_ip_tos_ttl(*argv,
844 TCA_FLOWER_KEY_IP_TOS,
845 TCA_FLOWER_KEY_IP_TOS_MASK,
846 n);
847 if (ret < 0) {
848 fprintf(stderr, "Illegal \"ip_tos\"\n");
849 return -1;
850 }
851 } else if (matches(*argv, "ip_ttl") == 0) {
852 NEXT_ARG();
853 ret = flower_parse_ip_tos_ttl(*argv,
854 TCA_FLOWER_KEY_IP_TTL,
855 TCA_FLOWER_KEY_IP_TTL_MASK,
856 n);
857 if (ret < 0) {
858 fprintf(stderr, "Illegal \"ip_ttl\"\n");
859 return -1;
860 }
861 } else if (matches(*argv, "dst_ip") == 0) {
862 NEXT_ARG();
863 ret = flower_parse_ip_addr(*argv, cvlan_ethtype ?
864 cvlan_ethtype : vlan_ethtype ?
865 vlan_ethtype : eth_type,
866 TCA_FLOWER_KEY_IPV4_DST,
867 TCA_FLOWER_KEY_IPV4_DST_MASK,
868 TCA_FLOWER_KEY_IPV6_DST,
869 TCA_FLOWER_KEY_IPV6_DST_MASK,
870 n);
871 if (ret < 0) {
872 fprintf(stderr, "Illegal \"dst_ip\"\n");
873 return -1;
874 }
875 } else if (matches(*argv, "src_ip") == 0) {
876 NEXT_ARG();
877 ret = flower_parse_ip_addr(*argv, cvlan_ethtype ?
878 cvlan_ethtype : vlan_ethtype ?
879 vlan_ethtype : eth_type,
880 TCA_FLOWER_KEY_IPV4_SRC,
881 TCA_FLOWER_KEY_IPV4_SRC_MASK,
882 TCA_FLOWER_KEY_IPV6_SRC,
883 TCA_FLOWER_KEY_IPV6_SRC_MASK,
884 n);
885 if (ret < 0) {
886 fprintf(stderr, "Illegal \"src_ip\"\n");
887 return -1;
888 }
889 } else if (matches(*argv, "dst_port") == 0) {
890 NEXT_ARG();
891 ret = flower_parse_port(*argv, ip_proto,
892 FLOWER_ENDPOINT_DST, n);
893 if (ret < 0) {
894 fprintf(stderr, "Illegal \"dst_port\"\n");
895 return -1;
896 }
897 } else if (matches(*argv, "src_port") == 0) {
898 NEXT_ARG();
899 ret = flower_parse_port(*argv, ip_proto,
900 FLOWER_ENDPOINT_SRC, n);
901 if (ret < 0) {
902 fprintf(stderr, "Illegal \"src_port\"\n");
903 return -1;
904 }
905 } else if (matches(*argv, "tcp_flags") == 0) {
906 NEXT_ARG();
907 ret = flower_parse_tcp_flags(*argv,
908 TCA_FLOWER_KEY_TCP_FLAGS,
909 TCA_FLOWER_KEY_TCP_FLAGS_MASK,
910 n);
911 if (ret < 0) {
912 fprintf(stderr, "Illegal \"tcp_flags\"\n");
913 return -1;
914 }
915 } else if (matches(*argv, "type") == 0) {
916 NEXT_ARG();
917 ret = flower_parse_icmp(*argv, eth_type, ip_proto,
918 FLOWER_ICMP_FIELD_TYPE, n);
919 if (ret < 0) {
920 fprintf(stderr, "Illegal \"icmp type\"\n");
921 return -1;
922 }
923 } else if (matches(*argv, "code") == 0) {
924 NEXT_ARG();
925 ret = flower_parse_icmp(*argv, eth_type, ip_proto,
926 FLOWER_ICMP_FIELD_CODE, n);
927 if (ret < 0) {
928 fprintf(stderr, "Illegal \"icmp code\"\n");
929 return -1;
930 }
931 } else if (matches(*argv, "arp_tip") == 0) {
932 NEXT_ARG();
933 ret = flower_parse_arp_ip_addr(*argv, vlan_ethtype ?
934 vlan_ethtype : eth_type,
935 TCA_FLOWER_KEY_ARP_TIP,
936 TCA_FLOWER_KEY_ARP_TIP_MASK,
937 n);
938 if (ret < 0) {
939 fprintf(stderr, "Illegal \"arp_tip\"\n");
940 return -1;
941 }
942 } else if (matches(*argv, "arp_sip") == 0) {
943 NEXT_ARG();
944 ret = flower_parse_arp_ip_addr(*argv, vlan_ethtype ?
945 vlan_ethtype : eth_type,
946 TCA_FLOWER_KEY_ARP_SIP,
947 TCA_FLOWER_KEY_ARP_SIP_MASK,
948 n);
949 if (ret < 0) {
950 fprintf(stderr, "Illegal \"arp_sip\"\n");
951 return -1;
952 }
953 } else if (matches(*argv, "arp_op") == 0) {
954 NEXT_ARG();
955 ret = flower_parse_arp_op(*argv, vlan_ethtype ?
956 vlan_ethtype : eth_type,
957 TCA_FLOWER_KEY_ARP_OP,
958 TCA_FLOWER_KEY_ARP_OP_MASK,
959 n);
960 if (ret < 0) {
961 fprintf(stderr, "Illegal \"arp_op\"\n");
962 return -1;
963 }
964 } else if (matches(*argv, "arp_tha") == 0) {
965 NEXT_ARG();
966 ret = flower_parse_eth_addr(*argv,
967 TCA_FLOWER_KEY_ARP_THA,
968 TCA_FLOWER_KEY_ARP_THA_MASK,
969 n);
970 if (ret < 0) {
971 fprintf(stderr, "Illegal \"arp_tha\"\n");
972 return -1;
973 }
974 } else if (matches(*argv, "arp_sha") == 0) {
975 NEXT_ARG();
976 ret = flower_parse_eth_addr(*argv,
977 TCA_FLOWER_KEY_ARP_SHA,
978 TCA_FLOWER_KEY_ARP_SHA_MASK,
979 n);
980 if (ret < 0) {
981 fprintf(stderr, "Illegal \"arp_sha\"\n");
982 return -1;
983 }
984 } else if (matches(*argv, "enc_dst_ip") == 0) {
985 NEXT_ARG();
986 ret = flower_parse_ip_addr(*argv, 0,
987 TCA_FLOWER_KEY_ENC_IPV4_DST,
988 TCA_FLOWER_KEY_ENC_IPV4_DST_MASK,
989 TCA_FLOWER_KEY_ENC_IPV6_DST,
990 TCA_FLOWER_KEY_ENC_IPV6_DST_MASK,
991 n);
992 if (ret < 0) {
993 fprintf(stderr, "Illegal \"enc_dst_ip\"\n");
994 return -1;
995 }
996 } else if (matches(*argv, "enc_src_ip") == 0) {
997 NEXT_ARG();
998 ret = flower_parse_ip_addr(*argv, 0,
999 TCA_FLOWER_KEY_ENC_IPV4_SRC,
1000 TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK,
1001 TCA_FLOWER_KEY_ENC_IPV6_SRC,
1002 TCA_FLOWER_KEY_ENC_IPV6_SRC_MASK,
1003 n);
1004 if (ret < 0) {
1005 fprintf(stderr, "Illegal \"enc_src_ip\"\n");
1006 return -1;
1007 }
1008 } else if (matches(*argv, "enc_key_id") == 0) {
1009 NEXT_ARG();
1010 ret = flower_parse_key_id(*argv,
1011 TCA_FLOWER_KEY_ENC_KEY_ID, n);
1012 if (ret < 0) {
1013 fprintf(stderr, "Illegal \"enc_key_id\"\n");
1014 return -1;
1015 }
1016 } else if (matches(*argv, "enc_dst_port") == 0) {
1017 NEXT_ARG();
1018 ret = flower_parse_enc_port(*argv,
1019 TCA_FLOWER_KEY_ENC_UDP_DST_PORT, n);
1020 if (ret < 0) {
1021 fprintf(stderr, "Illegal \"enc_dst_port\"\n");
1022 return -1;
1023 }
1024 } else if (matches(*argv, "enc_tos") == 0) {
1025 NEXT_ARG();
1026 ret = flower_parse_ip_tos_ttl(*argv,
1027 TCA_FLOWER_KEY_ENC_IP_TOS,
1028 TCA_FLOWER_KEY_ENC_IP_TOS_MASK,
1029 n);
1030 if (ret < 0) {
1031 fprintf(stderr, "Illegal \"enc_tos\"\n");
1032 return -1;
1033 }
1034 } else if (matches(*argv, "enc_ttl") == 0) {
1035 NEXT_ARG();
1036 ret = flower_parse_ip_tos_ttl(*argv,
1037 TCA_FLOWER_KEY_ENC_IP_TTL,
1038 TCA_FLOWER_KEY_ENC_IP_TTL_MASK,
1039 n);
1040 if (ret < 0) {
1041 fprintf(stderr, "Illegal \"enc_ttl\"\n");
1042 return -1;
1043 }
1044 } else if (matches(*argv, "action") == 0) {
1045 NEXT_ARG();
1046 ret = parse_action(&argc, &argv, TCA_FLOWER_ACT, n);
1047 if (ret) {
1048 fprintf(stderr, "Illegal \"action\"\n");
1049 return -1;
1050 }
1051 continue;
1052 } else if (strcmp(*argv, "help") == 0) {
1053 explain();
1054 return -1;
1055 } else {
1056 fprintf(stderr, "What is \"%s\"?\n", *argv);
1057 explain();
1058 return -1;
1059 }
1060 argc--; argv++;
1061 }
1062
1063 parse_done:
1064 ret = addattr32(n, MAX_MSG, TCA_FLOWER_FLAGS, flags);
1065 if (ret)
1066 return ret;
1067
1068 if (mtf_mask) {
1069 ret = addattr32(n, MAX_MSG, TCA_FLOWER_KEY_FLAGS, htonl(mtf));
1070 if (ret)
1071 return ret;
1072
1073 ret = addattr32(n, MAX_MSG, TCA_FLOWER_KEY_FLAGS_MASK, htonl(mtf_mask));
1074 if (ret)
1075 return ret;
1076 }
1077
1078 if (eth_type != htons(ETH_P_ALL)) {
1079 ret = addattr16(n, MAX_MSG, TCA_FLOWER_KEY_ETH_TYPE, eth_type);
1080 if (ret)
1081 return ret;
1082 }
1083
1084 tail->rta_len = (((void *)n)+n->nlmsg_len) - (void *)tail;
1085
1086 return 0;
1087 }
1088
1089 static int __mask_bits(char *addr, size_t len)
1090 {
1091 int bits = 0;
1092 bool hole = false;
1093 int i;
1094 int j;
1095
1096 for (i = 0; i < len; i++, addr++) {
1097 for (j = 7; j >= 0; j--) {
1098 if (((*addr) >> j) & 0x1) {
1099 if (hole)
1100 return -1;
1101 bits++;
1102 } else if (bits) {
1103 hole = true;
1104 } else{
1105 return -1;
1106 }
1107 }
1108 }
1109 return bits;
1110 }
1111
1112 static void flower_print_eth_addr(char *name, struct rtattr *addr_attr,
1113 struct rtattr *mask_attr)
1114 {
1115 SPRINT_BUF(namefrm);
1116 SPRINT_BUF(out);
1117 SPRINT_BUF(b1);
1118 size_t done;
1119 int bits;
1120
1121 if (!addr_attr || RTA_PAYLOAD(addr_attr) != ETH_ALEN)
1122 return;
1123 done = sprintf(out, "%s",
1124 ll_addr_n2a(RTA_DATA(addr_attr), ETH_ALEN,
1125 0, b1, sizeof(b1)));
1126 if (mask_attr && RTA_PAYLOAD(mask_attr) == ETH_ALEN) {
1127 bits = __mask_bits(RTA_DATA(mask_attr), ETH_ALEN);
1128 if (bits < 0)
1129 sprintf(out + done, "/%s",
1130 ll_addr_n2a(RTA_DATA(mask_attr), ETH_ALEN,
1131 0, b1, sizeof(b1)));
1132 else if (bits < ETH_ALEN * 8)
1133 sprintf(out + done, "/%d", bits);
1134 }
1135
1136 sprintf(namefrm, "\n %s %%s", name);
1137 print_string(PRINT_ANY, name, namefrm, out);
1138 }
1139
1140 static void flower_print_eth_type(__be16 *p_eth_type,
1141 struct rtattr *eth_type_attr)
1142 {
1143 SPRINT_BUF(out);
1144 __be16 eth_type;
1145
1146 if (!eth_type_attr)
1147 return;
1148
1149 eth_type = rta_getattr_u16(eth_type_attr);
1150 if (eth_type == htons(ETH_P_IP))
1151 sprintf(out, "ipv4");
1152 else if (eth_type == htons(ETH_P_IPV6))
1153 sprintf(out, "ipv6");
1154 else if (eth_type == htons(ETH_P_ARP))
1155 sprintf(out, "arp");
1156 else if (eth_type == htons(ETH_P_RARP))
1157 sprintf(out, "rarp");
1158 else
1159 sprintf(out, "%04x", ntohs(eth_type));
1160
1161 print_string(PRINT_ANY, "eth_type", "\n eth_type %s", out);
1162 *p_eth_type = eth_type;
1163 }
1164
1165 static void flower_print_ip_proto(__u8 *p_ip_proto,
1166 struct rtattr *ip_proto_attr)
1167 {
1168 SPRINT_BUF(out);
1169 __u8 ip_proto;
1170
1171 if (!ip_proto_attr)
1172 return;
1173
1174 ip_proto = rta_getattr_u8(ip_proto_attr);
1175 if (ip_proto == IPPROTO_TCP)
1176 sprintf(out, "tcp");
1177 else if (ip_proto == IPPROTO_UDP)
1178 sprintf(out, "udp");
1179 else if (ip_proto == IPPROTO_SCTP)
1180 sprintf(out, "sctp");
1181 else if (ip_proto == IPPROTO_ICMP)
1182 sprintf(out, "icmp");
1183 else if (ip_proto == IPPROTO_ICMPV6)
1184 sprintf(out, "icmpv6");
1185 else
1186 sprintf(out, "%02x", ip_proto);
1187
1188 print_string(PRINT_ANY, "ip_proto", "\n ip_proto %s", out);
1189 *p_ip_proto = ip_proto;
1190 }
1191
1192 static void flower_print_ip_attr(const char *name, struct rtattr *key_attr,
1193 struct rtattr *mask_attr)
1194 {
1195 SPRINT_BUF(namefrm);
1196 SPRINT_BUF(out);
1197 size_t done;
1198
1199 if (!key_attr)
1200 return;
1201
1202 done = sprintf(out, "0x%x", rta_getattr_u8(key_attr));
1203 if (mask_attr)
1204 sprintf(out + done, "/%x", rta_getattr_u8(mask_attr));
1205
1206 print_string(PRINT_FP, NULL, "%s ", _SL_);
1207 sprintf(namefrm, "%s %%s", name);
1208 print_string(PRINT_ANY, name, namefrm, out);
1209 }
1210
1211 static void flower_print_matching_flags(char *name,
1212 enum flower_matching_flags type,
1213 struct rtattr *attr,
1214 struct rtattr *mask_attr)
1215 {
1216 int i;
1217 int count = 0;
1218 __u32 mtf;
1219 __u32 mtf_mask;
1220
1221 if (!mask_attr || RTA_PAYLOAD(mask_attr) != 4)
1222 return;
1223
1224 mtf = ntohl(rta_getattr_u32(attr));
1225 mtf_mask = ntohl(rta_getattr_u32(mask_attr));
1226
1227 for (i = 0; i < ARRAY_SIZE(flags_str); i++) {
1228 if (type != flags_str[i].type)
1229 continue;
1230 if (mtf_mask & flags_str[i].flag) {
1231 if (++count == 1) {
1232 print_string(PRINT_FP, NULL, "\n %s ", name);
1233 open_json_object(name);
1234 } else {
1235 print_string(PRINT_FP, NULL, "/", NULL);
1236 }
1237
1238 print_bool(PRINT_JSON, flags_str[i].string, NULL,
1239 mtf & flags_str[i].flag);
1240 if (mtf & flags_str[i].flag)
1241 print_string(PRINT_FP, NULL, "%s",
1242 flags_str[i].string);
1243 else
1244 print_string(PRINT_FP, NULL, "no%s",
1245 flags_str[i].string);
1246 }
1247 }
1248 if (count)
1249 close_json_object();
1250 }
1251
1252 static void flower_print_ip_addr(char *name, __be16 eth_type,
1253 struct rtattr *addr4_attr,
1254 struct rtattr *mask4_attr,
1255 struct rtattr *addr6_attr,
1256 struct rtattr *mask6_attr)
1257 {
1258 struct rtattr *addr_attr;
1259 struct rtattr *mask_attr;
1260 SPRINT_BUF(namefrm);
1261 SPRINT_BUF(out);
1262 size_t done;
1263 int family;
1264 size_t len;
1265 int bits;
1266
1267 if (eth_type == htons(ETH_P_IP)) {
1268 family = AF_INET;
1269 addr_attr = addr4_attr;
1270 mask_attr = mask4_attr;
1271 len = 4;
1272 } else if (eth_type == htons(ETH_P_IPV6)) {
1273 family = AF_INET6;
1274 addr_attr = addr6_attr;
1275 mask_attr = mask6_attr;
1276 len = 16;
1277 } else {
1278 return;
1279 }
1280 if (!addr_attr || RTA_PAYLOAD(addr_attr) != len)
1281 return;
1282 if (!mask_attr || RTA_PAYLOAD(mask_attr) != len)
1283 return;
1284 done = sprintf(out, "%s", rt_addr_n2a_rta(family, addr_attr));
1285 bits = __mask_bits(RTA_DATA(mask_attr), len);
1286 if (bits < 0)
1287 sprintf(out + done, "/%s", rt_addr_n2a_rta(family, mask_attr));
1288 else if (bits < len * 8)
1289 sprintf(out + done, "/%d", bits);
1290
1291 sprintf(namefrm, "\n %s %%s", name);
1292 print_string(PRINT_ANY, name, namefrm, out);
1293 }
1294 static void flower_print_ip4_addr(char *name, struct rtattr *addr_attr,
1295 struct rtattr *mask_attr)
1296 {
1297 return flower_print_ip_addr(name, htons(ETH_P_IP),
1298 addr_attr, mask_attr, 0, 0);
1299 }
1300
1301 static void flower_print_port(char *name, struct rtattr *attr)
1302 {
1303 SPRINT_BUF(namefrm);
1304
1305 if (!attr)
1306 return;
1307
1308 sprintf(namefrm,"\n %s %%u", name);
1309 print_hu(PRINT_ANY, name, namefrm, rta_getattr_be16(attr));
1310 }
1311
1312 static void flower_print_tcp_flags(const char *name, struct rtattr *flags_attr,
1313 struct rtattr *mask_attr)
1314 {
1315 SPRINT_BUF(namefrm);
1316 SPRINT_BUF(out);
1317 size_t done;
1318
1319 if (!flags_attr)
1320 return;
1321
1322 done = sprintf(out, "0x%x", rta_getattr_be16(flags_attr));
1323 if (mask_attr)
1324 sprintf(out + done, "/%x", rta_getattr_be16(mask_attr));
1325
1326 print_string(PRINT_FP, NULL, "%s ", _SL_);
1327 sprintf(namefrm, "%s %%s", name);
1328 print_string(PRINT_ANY, name, namefrm, out);
1329 }
1330
1331
1332 static void flower_print_key_id(const char *name, struct rtattr *attr)
1333 {
1334 SPRINT_BUF(namefrm);
1335
1336 if (!attr)
1337 return;
1338
1339 sprintf(namefrm,"\n %s %%u", name);
1340 print_uint(PRINT_ANY, name, namefrm, rta_getattr_be32(attr));
1341 }
1342
1343 static void flower_print_masked_u8(const char *name, struct rtattr *attr,
1344 struct rtattr *mask_attr,
1345 const char *(*value_to_str)(__u8 value))
1346 {
1347 const char *value_str = NULL;
1348 __u8 value, mask;
1349 SPRINT_BUF(namefrm);
1350 SPRINT_BUF(out);
1351 size_t done;
1352
1353 if (!attr)
1354 return;
1355
1356 value = rta_getattr_u8(attr);
1357 mask = mask_attr ? rta_getattr_u8(mask_attr) : UINT8_MAX;
1358 if (mask == UINT8_MAX && value_to_str)
1359 value_str = value_to_str(value);
1360
1361 if (value_str)
1362 done = sprintf(out, "%s", value_str);
1363 else
1364 done = sprintf(out, "%d", value);
1365
1366 if (mask != UINT8_MAX)
1367 sprintf(out + done, "/%d", mask);
1368
1369 sprintf(namefrm,"\n %s %%s", name);
1370 print_string(PRINT_ANY, name, namefrm, out);
1371 }
1372
1373 static void flower_print_u8(const char *name, struct rtattr *attr)
1374 {
1375 flower_print_masked_u8(name, attr, NULL, NULL);
1376 }
1377
1378 static void flower_print_u32(const char *name, struct rtattr *attr)
1379 {
1380 SPRINT_BUF(namefrm);
1381
1382 if (!attr)
1383 return;
1384
1385 sprintf(namefrm,"\n %s %%u", name);
1386 print_uint(PRINT_ANY, name, namefrm, rta_getattr_u32(attr));
1387 }
1388
1389 static void flower_print_arp_op(const char *name,
1390 struct rtattr *op_attr,
1391 struct rtattr *mask_attr)
1392 {
1393 flower_print_masked_u8(name, op_attr, mask_attr,
1394 flower_print_arp_op_to_name);
1395 }
1396
1397 static int flower_print_opt(struct filter_util *qu, FILE *f,
1398 struct rtattr *opt, __u32 handle)
1399 {
1400 struct rtattr *tb[TCA_FLOWER_MAX + 1];
1401 int nl_type, nl_mask_type;
1402 __be16 eth_type = 0;
1403 __u8 ip_proto = 0xff;
1404
1405 if (!opt)
1406 return 0;
1407
1408 parse_rtattr_nested(tb, TCA_FLOWER_MAX, opt);
1409
1410 if (handle)
1411 print_uint(PRINT_ANY, "handle", "handle 0x%x ", handle);
1412
1413 if (tb[TCA_FLOWER_CLASSID]) {
1414 __u32 h = rta_getattr_u32(tb[TCA_FLOWER_CLASSID]);
1415
1416 if (TC_H_MIN(h) < TC_H_MIN_PRIORITY ||
1417 TC_H_MIN(h) > (TC_H_MIN_PRIORITY + TC_QOPT_MAX_QUEUE - 1)) {
1418 SPRINT_BUF(b1);
1419 print_string(PRINT_ANY, "classid", "classid %s ",
1420 sprint_tc_classid(h, b1));
1421 } else {
1422 print_uint(PRINT_ANY, "hw_tc", "hw_tc %u ",
1423 TC_H_MIN(h) - TC_H_MIN_PRIORITY);
1424 }
1425 }
1426
1427 if (tb[TCA_FLOWER_INDEV]) {
1428 struct rtattr *attr = tb[TCA_FLOWER_INDEV];
1429
1430 print_string(PRINT_ANY, "indev", "\n indev %s",
1431 rta_getattr_str(attr));
1432 }
1433
1434 open_json_object("keys");
1435
1436 if (tb[TCA_FLOWER_KEY_VLAN_ID]) {
1437 struct rtattr *attr = tb[TCA_FLOWER_KEY_VLAN_ID];
1438
1439 print_uint(PRINT_ANY, "vlan_id", "\n vlan_id %u",
1440 rta_getattr_u16(attr));
1441 }
1442
1443 if (tb[TCA_FLOWER_KEY_VLAN_PRIO]) {
1444 struct rtattr *attr = tb[TCA_FLOWER_KEY_VLAN_PRIO];
1445
1446 print_uint(PRINT_ANY, "vlan_prio", "\n vlan_prio %d",
1447 rta_getattr_u8(attr));
1448 }
1449
1450 if (tb[TCA_FLOWER_KEY_VLAN_ETH_TYPE]) {
1451 SPRINT_BUF(buf);
1452 struct rtattr *attr = tb[TCA_FLOWER_KEY_VLAN_ETH_TYPE];
1453
1454 print_string(PRINT_ANY, "vlan_ethtype", "\n vlan_ethtype %s",
1455 ll_proto_n2a(rta_getattr_u16(attr),
1456 buf, sizeof(buf)));
1457 }
1458
1459 if (tb[TCA_FLOWER_KEY_CVLAN_ID]) {
1460 struct rtattr *attr = tb[TCA_FLOWER_KEY_CVLAN_ID];
1461
1462 print_uint(PRINT_ANY, "cvlan_id", "\n cvlan_id %u",
1463 rta_getattr_u16(attr));
1464 }
1465
1466 if (tb[TCA_FLOWER_KEY_CVLAN_PRIO]) {
1467 struct rtattr *attr = tb[TCA_FLOWER_KEY_CVLAN_PRIO];
1468
1469 print_uint(PRINT_ANY, "cvlan_prio", "\n cvlan_prio %d",
1470 rta_getattr_u8(attr));
1471 }
1472
1473 if (tb[TCA_FLOWER_KEY_CVLAN_ETH_TYPE]) {
1474 SPRINT_BUF(buf);
1475 struct rtattr *attr = tb[TCA_FLOWER_KEY_CVLAN_ETH_TYPE];
1476
1477 print_string(PRINT_ANY, "cvlan_ethtype", "\n cvlan_ethtype %s",
1478 ll_proto_n2a(rta_getattr_u16(attr),
1479 buf, sizeof(buf)));
1480 }
1481
1482 flower_print_eth_addr("dst_mac", tb[TCA_FLOWER_KEY_ETH_DST],
1483 tb[TCA_FLOWER_KEY_ETH_DST_MASK]);
1484 flower_print_eth_addr("src_mac", tb[TCA_FLOWER_KEY_ETH_SRC],
1485 tb[TCA_FLOWER_KEY_ETH_SRC_MASK]);
1486
1487 flower_print_eth_type(&eth_type, tb[TCA_FLOWER_KEY_ETH_TYPE]);
1488 flower_print_ip_proto(&ip_proto, tb[TCA_FLOWER_KEY_IP_PROTO]);
1489
1490 flower_print_ip_attr("ip_tos", tb[TCA_FLOWER_KEY_IP_TOS],
1491 tb[TCA_FLOWER_KEY_IP_TOS_MASK]);
1492 flower_print_ip_attr("ip_ttl", tb[TCA_FLOWER_KEY_IP_TTL],
1493 tb[TCA_FLOWER_KEY_IP_TTL_MASK]);
1494
1495 flower_print_u32("mpls_label", tb[TCA_FLOWER_KEY_MPLS_LABEL]);
1496 flower_print_u8("mpls_tc", tb[TCA_FLOWER_KEY_MPLS_TC]);
1497 flower_print_u8("mpls_bos", tb[TCA_FLOWER_KEY_MPLS_BOS]);
1498 flower_print_u8("mpls_ttl", tb[TCA_FLOWER_KEY_MPLS_TTL]);
1499
1500 flower_print_ip_addr("dst_ip", eth_type,
1501 tb[TCA_FLOWER_KEY_IPV4_DST],
1502 tb[TCA_FLOWER_KEY_IPV4_DST_MASK],
1503 tb[TCA_FLOWER_KEY_IPV6_DST],
1504 tb[TCA_FLOWER_KEY_IPV6_DST_MASK]);
1505
1506 flower_print_ip_addr("src_ip", eth_type,
1507 tb[TCA_FLOWER_KEY_IPV4_SRC],
1508 tb[TCA_FLOWER_KEY_IPV4_SRC_MASK],
1509 tb[TCA_FLOWER_KEY_IPV6_SRC],
1510 tb[TCA_FLOWER_KEY_IPV6_SRC_MASK]);
1511
1512 nl_type = flower_port_attr_type(ip_proto, FLOWER_ENDPOINT_DST);
1513 if (nl_type >= 0)
1514 flower_print_port("dst_port", tb[nl_type]);
1515 nl_type = flower_port_attr_type(ip_proto, FLOWER_ENDPOINT_SRC);
1516 if (nl_type >= 0)
1517 flower_print_port("src_port", tb[nl_type]);
1518
1519 flower_print_tcp_flags("tcp_flags", tb[TCA_FLOWER_KEY_TCP_FLAGS],
1520 tb[TCA_FLOWER_KEY_TCP_FLAGS_MASK]);
1521
1522 nl_type = flower_icmp_attr_type(eth_type, ip_proto,
1523 FLOWER_ICMP_FIELD_TYPE);
1524 nl_mask_type = flower_icmp_attr_mask_type(eth_type, ip_proto,
1525 FLOWER_ICMP_FIELD_TYPE);
1526 if (nl_type >= 0 && nl_mask_type >= 0)
1527 flower_print_masked_u8("icmp_type", tb[nl_type],
1528 tb[nl_mask_type], NULL);
1529
1530 nl_type = flower_icmp_attr_type(eth_type, ip_proto,
1531 FLOWER_ICMP_FIELD_CODE);
1532 nl_mask_type = flower_icmp_attr_mask_type(eth_type, ip_proto,
1533 FLOWER_ICMP_FIELD_CODE);
1534 if (nl_type >= 0 && nl_mask_type >= 0)
1535 flower_print_masked_u8("icmp_code", tb[nl_type],
1536 tb[nl_mask_type], NULL);
1537
1538 flower_print_ip4_addr("arp_sip", tb[TCA_FLOWER_KEY_ARP_SIP],
1539 tb[TCA_FLOWER_KEY_ARP_SIP_MASK]);
1540 flower_print_ip4_addr("arp_tip", tb[TCA_FLOWER_KEY_ARP_TIP],
1541 tb[TCA_FLOWER_KEY_ARP_TIP_MASK]);
1542 flower_print_arp_op("arp_op", tb[TCA_FLOWER_KEY_ARP_OP],
1543 tb[TCA_FLOWER_KEY_ARP_OP_MASK]);
1544 flower_print_eth_addr("arp_sha", tb[TCA_FLOWER_KEY_ARP_SHA],
1545 tb[TCA_FLOWER_KEY_ARP_SHA_MASK]);
1546 flower_print_eth_addr("arp_tha", tb[TCA_FLOWER_KEY_ARP_THA],
1547 tb[TCA_FLOWER_KEY_ARP_THA_MASK]);
1548
1549 flower_print_ip_addr("enc_dst_ip",
1550 tb[TCA_FLOWER_KEY_ENC_IPV4_DST_MASK] ?
1551 htons(ETH_P_IP) : htons(ETH_P_IPV6),
1552 tb[TCA_FLOWER_KEY_ENC_IPV4_DST],
1553 tb[TCA_FLOWER_KEY_ENC_IPV4_DST_MASK],
1554 tb[TCA_FLOWER_KEY_ENC_IPV6_DST],
1555 tb[TCA_FLOWER_KEY_ENC_IPV6_DST_MASK]);
1556
1557 flower_print_ip_addr("enc_src_ip",
1558 tb[TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK] ?
1559 htons(ETH_P_IP) : htons(ETH_P_IPV6),
1560 tb[TCA_FLOWER_KEY_ENC_IPV4_SRC],
1561 tb[TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK],
1562 tb[TCA_FLOWER_KEY_ENC_IPV6_SRC],
1563 tb[TCA_FLOWER_KEY_ENC_IPV6_SRC_MASK]);
1564
1565 flower_print_key_id("enc_key_id", tb[TCA_FLOWER_KEY_ENC_KEY_ID]);
1566
1567 flower_print_port("enc_dst_port", tb[TCA_FLOWER_KEY_ENC_UDP_DST_PORT]);
1568
1569 flower_print_ip_attr("enc_tos", tb[TCA_FLOWER_KEY_ENC_IP_TOS],
1570 tb[TCA_FLOWER_KEY_ENC_IP_TOS_MASK]);
1571 flower_print_ip_attr("enc_ttl", tb[TCA_FLOWER_KEY_ENC_IP_TTL],
1572 tb[TCA_FLOWER_KEY_ENC_IP_TTL_MASK]);
1573
1574 flower_print_matching_flags("ip_flags", FLOWER_IP_FLAGS,
1575 tb[TCA_FLOWER_KEY_FLAGS],
1576 tb[TCA_FLOWER_KEY_FLAGS_MASK]);
1577
1578 close_json_object();
1579
1580 if (tb[TCA_FLOWER_FLAGS]) {
1581 __u32 flags = rta_getattr_u32(tb[TCA_FLOWER_FLAGS]);
1582
1583 if (flags & TCA_CLS_FLAGS_SKIP_HW)
1584 print_bool(PRINT_ANY, "skip_hw", "\n skip_hw", true);
1585 if (flags & TCA_CLS_FLAGS_SKIP_SW)
1586 print_bool(PRINT_ANY, "skip_sw", "\n skip_sw", true);
1587
1588 if (flags & TCA_CLS_FLAGS_IN_HW)
1589 print_bool(PRINT_ANY, "in_hw", "\n in_hw", true);
1590 else if (flags & TCA_CLS_FLAGS_NOT_IN_HW)
1591 print_bool(PRINT_ANY, "not_in_hw", "\n not_in_hw", true);
1592 }
1593
1594 if (tb[TCA_FLOWER_ACT])
1595 tc_print_action(f, tb[TCA_FLOWER_ACT], 0);
1596
1597 return 0;
1598 }
1599
1600 struct filter_util flower_filter_util = {
1601 .id = "flower",
1602 .parse_fopt = flower_parse_opt,
1603 .print_fopt = flower_print_opt,
1604 };