]> git.proxmox.com Git - mirror_iproute2.git/blob - tc/f_flower.c
Merge branch 'master' into net-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 <syslog.h>
16 #include <string.h>
17 #include <net/if.h>
18 #include <linux/if_arp.h>
19 #include <linux/if_ether.h>
20 #include <linux/ip.h>
21 #include <linux/tc_act/tc_vlan.h>
22
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 ]\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 " dst_mac MASKED-LLADDR |\n"
54 " src_mac MASKED-LLADDR |\n"
55 " ip_proto [tcp | udp | sctp | icmp | icmpv6 | IP-PROTO ] |\n"
56 " dst_ip PREFIX |\n"
57 " src_ip PREFIX |\n"
58 " dst_port PORT-NUMBER |\n"
59 " src_port PORT-NUMBER |\n"
60 " type MASKED-ICMP-TYPE |\n"
61 " code MASKED-ICMP-CODE |\n"
62 " arp_tip IPV4-PREFIX |\n"
63 " arp_sip IPV4-PREFIX |\n"
64 " arp_op [ request | reply | OP ] |\n"
65 " arp_tha MASKED-LLADDR |\n"
66 " arp_sha MASKED-LLADDR |\n"
67 " enc_dst_ip [ IPV4-ADDR | IPV6-ADDR ] |\n"
68 " enc_src_ip [ IPV4-ADDR | IPV6-ADDR ] |\n"
69 " enc_key_id [ KEY-ID ] |\n"
70 " ip_flags IP-FLAGS | \n"
71 " enc_dst_port [ port_number ] }\n"
72 " FILTERID := X:Y:Z\n"
73 " MASKED_LLADDR := { LLADDR | LLADDR/MASK | LLADDR/BITS }\n"
74 " ACTION-SPEC := ... look at individual actions\n"
75 "\n"
76 "NOTE: CLASSID, IP-PROTO are parsed as hexadecimal input.\n"
77 "NOTE: There can be only used one mask per one prio. If user needs\n"
78 " to specify different mask, he has to use different prio.\n");
79 }
80
81 static int flower_parse_eth_addr(char *str, int addr_type, int mask_type,
82 struct nlmsghdr *n)
83 {
84 int ret, err = -1;
85 char addr[ETH_ALEN], *slash;
86
87 slash = strchr(str, '/');
88 if (slash)
89 *slash = '\0';
90
91 ret = ll_addr_a2n(addr, sizeof(addr), str);
92 if (ret < 0)
93 goto err;
94 addattr_l(n, MAX_MSG, addr_type, addr, sizeof(addr));
95
96 if (slash) {
97 unsigned bits;
98
99 if (!get_unsigned(&bits, slash + 1, 10)) {
100 uint64_t mask;
101
102 /* Extra 16 bit shift to push mac address into
103 * high bits of uint64_t
104 */
105 mask = htonll(0xffffffffffffULL << (16 + 48 - bits));
106 memcpy(addr, &mask, ETH_ALEN);
107 } else {
108 ret = ll_addr_a2n(addr, sizeof(addr), slash + 1);
109 if (ret < 0)
110 goto err;
111 }
112 } else {
113 memset(addr, 0xff, ETH_ALEN);
114 }
115 addattr_l(n, MAX_MSG, mask_type, addr, sizeof(addr));
116
117 err = 0;
118 err:
119 if (slash)
120 *slash = '/';
121 return err;
122 }
123
124 static int flower_parse_vlan_eth_type(char *str, __be16 eth_type, int type,
125 __be16 *p_vlan_eth_type,
126 struct nlmsghdr *n)
127 {
128 __be16 vlan_eth_type;
129
130 if (eth_type != htons(ETH_P_8021Q)) {
131 fprintf(stderr,
132 "Can't set \"vlan_ethtype\" if ethertype isn't 802.1Q\n");
133 return -1;
134 }
135
136 if (ll_proto_a2n(&vlan_eth_type, str))
137 invarg("invalid vlan_ethtype", str);
138 addattr16(n, MAX_MSG, type, vlan_eth_type);
139 *p_vlan_eth_type = vlan_eth_type;
140 return 0;
141 }
142
143 struct flag_to_string {
144 int flag;
145 enum flower_matching_flags type;
146 char *string;
147 };
148
149 static struct flag_to_string flags_str[] = {
150 { TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT, FLOWER_IP_FLAGS, "frag" },
151 };
152
153 static int flower_parse_matching_flags(char *str,
154 enum flower_matching_flags type,
155 __u32 *mtf, __u32 *mtf_mask)
156 {
157 char *token;
158 bool no;
159 bool found;
160 int i;
161
162 token = strtok(str, "/");
163
164 while (token) {
165 if (!strncmp(token, "no", 2)) {
166 no = true;
167 token += 2;
168 } else
169 no = false;
170
171 found = false;
172 for (i = 0; i < ARRAY_SIZE(flags_str); i++) {
173 if (type != flags_str[i].type)
174 continue;
175
176 if (!strcmp(token, flags_str[i].string)) {
177 if (no)
178 *mtf &= ~flags_str[i].flag;
179 else
180 *mtf |= flags_str[i].flag;
181
182 *mtf_mask |= flags_str[i].flag;
183 found = true;
184 break;
185 }
186 }
187 if (!found)
188 return -1;
189
190 token = strtok(NULL, "/");
191 }
192
193 return 0;
194 }
195
196 static int flower_parse_ip_proto(char *str, __be16 eth_type, int type,
197 __u8 *p_ip_proto, struct nlmsghdr *n)
198 {
199 int ret;
200 __u8 ip_proto;
201
202 if (eth_type != htons(ETH_P_IP) && eth_type != htons(ETH_P_IPV6))
203 goto err;
204
205 if (matches(str, "tcp") == 0) {
206 ip_proto = IPPROTO_TCP;
207 } else if (matches(str, "udp") == 0) {
208 ip_proto = IPPROTO_UDP;
209 } else if (matches(str, "sctp") == 0) {
210 ip_proto = IPPROTO_SCTP;
211 } else if (matches(str, "icmp") == 0) {
212 if (eth_type != htons(ETH_P_IP))
213 goto err;
214 ip_proto = IPPROTO_ICMP;
215 } else if (matches(str, "icmpv6") == 0) {
216 if (eth_type != htons(ETH_P_IPV6))
217 goto err;
218 ip_proto = IPPROTO_ICMPV6;
219 } else {
220 ret = get_u8(&ip_proto, str, 16);
221 if (ret)
222 return -1;
223 }
224 addattr8(n, MAX_MSG, type, ip_proto);
225 *p_ip_proto = ip_proto;
226 return 0;
227
228 err:
229 fprintf(stderr, "Illegal \"eth_type\" for ip proto\n");
230 return -1;
231 }
232
233 static int __flower_parse_ip_addr(char *str, int family,
234 int addr4_type, int mask4_type,
235 int addr6_type, int mask6_type,
236 struct nlmsghdr *n)
237 {
238 int ret;
239 inet_prefix addr;
240 int bits;
241 int i;
242
243 ret = get_prefix(&addr, str, family);
244 if (ret)
245 return -1;
246
247 if (family && (addr.family != family)) {
248 fprintf(stderr, "Illegal \"eth_type\" for ip address\n");
249 return -1;
250 }
251
252 addattr_l(n, MAX_MSG, addr.family == AF_INET ? addr4_type : addr6_type,
253 addr.data, addr.bytelen);
254
255 memset(addr.data, 0xff, addr.bytelen);
256 bits = addr.bitlen;
257 for (i = 0; i < addr.bytelen / 4; i++) {
258 if (!bits) {
259 addr.data[i] = 0;
260 } else if (bits / 32 >= 1) {
261 bits -= 32;
262 } else {
263 addr.data[i] <<= 32 - bits;
264 addr.data[i] = htonl(addr.data[i]);
265 bits = 0;
266 }
267 }
268
269 addattr_l(n, MAX_MSG, addr.family == AF_INET ? mask4_type : mask6_type,
270 addr.data, addr.bytelen);
271
272 return 0;
273 }
274
275 static int flower_parse_ip_addr(char *str, __be16 eth_type,
276 int addr4_type, int mask4_type,
277 int addr6_type, int mask6_type,
278 struct nlmsghdr *n)
279 {
280 int family;
281
282 if (eth_type == htons(ETH_P_IP)) {
283 family = AF_INET;
284 } else if (eth_type == htons(ETH_P_IPV6)) {
285 family = AF_INET6;
286 } else if (!eth_type) {
287 family = AF_UNSPEC;
288 } else {
289 return -1;
290 }
291
292 return __flower_parse_ip_addr(str, family, addr4_type, addr6_type,
293 mask4_type, mask6_type, n);
294 }
295
296 static bool flower_eth_type_arp(__be16 eth_type)
297 {
298 return eth_type == htons(ETH_P_ARP) || eth_type == htons(ETH_P_RARP);
299 }
300
301 static int flower_parse_arp_ip_addr(char *str, __be16 eth_type,
302 int addr_type, int mask_type,
303 struct nlmsghdr *n)
304 {
305 if (!flower_eth_type_arp(eth_type))
306 return -1;
307
308 return __flower_parse_ip_addr(str, AF_INET, addr_type, mask_type,
309 TCA_FLOWER_UNSPEC, TCA_FLOWER_UNSPEC, n);
310 }
311
312 static int flower_parse_u8(char *str, int value_type, int mask_type,
313 int (*value_from_name)(const char *str,
314 __u8 *value),
315 bool (*value_validate)(__u8 value),
316 struct nlmsghdr *n)
317 {
318 char *slash;
319 int ret, err = -1;
320 __u8 value, mask;
321
322 slash = strchr(str, '/');
323 if (slash)
324 *slash = '\0';
325
326 ret = value_from_name ? value_from_name(str, &value) : -1;
327 if (ret < 0) {
328 ret = get_u8(&value, str, 10);
329 if (ret)
330 goto err;
331 }
332
333 if (value_validate && !value_validate(value))
334 goto err;
335
336 if (slash) {
337 ret = get_u8(&mask, slash + 1, 10);
338 if (ret)
339 goto err;
340 }
341 else {
342 mask = UINT8_MAX;
343 }
344
345 addattr8(n, MAX_MSG, value_type, value);
346 addattr8(n, MAX_MSG, mask_type, mask);
347
348 err = 0;
349 err:
350 if (slash)
351 *slash = '/';
352 return err;
353 }
354
355 static const char *flower_print_arp_op_to_name(__u8 op)
356 {
357 switch (op) {
358 case ARPOP_REQUEST:
359 return "request";
360 case ARPOP_REPLY:
361 return "reply";
362 default:
363 return NULL;
364 }
365 }
366
367 static int flower_arp_op_from_name(const char *name, __u8 *op)
368 {
369 if (!strcmp(name, "request"))
370 *op = ARPOP_REQUEST;
371 else if (!strcmp(name, "reply"))
372 *op = ARPOP_REPLY;
373 else
374 return -1;
375
376 return 0;
377 }
378
379 static bool flow_arp_op_validate(__u8 op)
380 {
381 return !op || op == ARPOP_REQUEST || op == ARPOP_REPLY;
382 }
383
384 static int flower_parse_arp_op(char *str, __be16 eth_type,
385 int op_type, int mask_type,
386 struct nlmsghdr *n)
387 {
388 if (!flower_eth_type_arp(eth_type))
389 return -1;
390
391 return flower_parse_u8(str, op_type, mask_type, flower_arp_op_from_name,
392 flow_arp_op_validate, n);
393 }
394
395 static int flower_icmp_attr_type(__be16 eth_type, __u8 ip_proto,
396 enum flower_icmp_field field)
397 {
398 if (eth_type == htons(ETH_P_IP) && ip_proto == IPPROTO_ICMP)
399 return field == FLOWER_ICMP_FIELD_CODE ?
400 TCA_FLOWER_KEY_ICMPV4_CODE :
401 TCA_FLOWER_KEY_ICMPV4_TYPE;
402 else if (eth_type == htons(ETH_P_IPV6) && ip_proto == IPPROTO_ICMPV6)
403 return field == FLOWER_ICMP_FIELD_CODE ?
404 TCA_FLOWER_KEY_ICMPV6_CODE :
405 TCA_FLOWER_KEY_ICMPV6_TYPE;
406
407 return -1;
408 }
409
410 static int flower_icmp_attr_mask_type(__be16 eth_type, __u8 ip_proto,
411 enum flower_icmp_field field)
412 {
413 if (eth_type == htons(ETH_P_IP) && ip_proto == IPPROTO_ICMP)
414 return field == FLOWER_ICMP_FIELD_CODE ?
415 TCA_FLOWER_KEY_ICMPV4_CODE_MASK :
416 TCA_FLOWER_KEY_ICMPV4_TYPE_MASK;
417 else if (eth_type == htons(ETH_P_IPV6) && ip_proto == IPPROTO_ICMPV6)
418 return field == FLOWER_ICMP_FIELD_CODE ?
419 TCA_FLOWER_KEY_ICMPV6_CODE_MASK :
420 TCA_FLOWER_KEY_ICMPV6_TYPE_MASK;
421
422 return -1;
423 }
424
425 static int flower_parse_icmp(char *str, __u16 eth_type, __u8 ip_proto,
426 enum flower_icmp_field field, struct nlmsghdr *n)
427 {
428 int value_type, mask_type;
429
430 value_type = flower_icmp_attr_type(eth_type, ip_proto, field);
431 mask_type = flower_icmp_attr_mask_type(eth_type, ip_proto, field);
432 if (value_type < 0 || mask_type < 0)
433 return -1;
434
435 return flower_parse_u8(str, value_type, mask_type, NULL, NULL, n);
436 }
437
438 static int flower_port_attr_type(__u8 ip_proto, enum flower_endpoint endpoint)
439 {
440 if (ip_proto == IPPROTO_TCP)
441 return endpoint == FLOWER_ENDPOINT_SRC ?
442 TCA_FLOWER_KEY_TCP_SRC :
443 TCA_FLOWER_KEY_TCP_DST;
444 else if (ip_proto == IPPROTO_UDP)
445 return endpoint == FLOWER_ENDPOINT_SRC ?
446 TCA_FLOWER_KEY_UDP_SRC :
447 TCA_FLOWER_KEY_UDP_DST;
448 else if (ip_proto == IPPROTO_SCTP)
449 return endpoint == FLOWER_ENDPOINT_SRC ?
450 TCA_FLOWER_KEY_SCTP_SRC :
451 TCA_FLOWER_KEY_SCTP_DST;
452 else
453 return -1;
454 }
455
456 static int flower_parse_port(char *str, __u8 ip_proto,
457 enum flower_endpoint endpoint,
458 struct nlmsghdr *n)
459 {
460 int ret;
461 int type;
462 __be16 port;
463
464 type = flower_port_attr_type(ip_proto, endpoint);
465 if (type < 0)
466 return -1;
467
468 ret = get_be16(&port, str, 10);
469 if (ret)
470 return -1;
471
472 addattr16(n, MAX_MSG, type, port);
473
474 return 0;
475 }
476
477 static int flower_parse_key_id(const char *str, int type, struct nlmsghdr *n)
478 {
479 int ret;
480 __be32 key_id;
481
482 ret = get_be32(&key_id, str, 10);
483 if (!ret)
484 addattr32(n, MAX_MSG, type, key_id);
485
486 return ret;
487 }
488
489 static int flower_parse_enc_port(char *str, int type, struct nlmsghdr *n)
490 {
491 int ret;
492 __be16 port;
493
494 ret = get_be16(&port, str, 10);
495 if (ret)
496 return -1;
497
498 addattr16(n, MAX_MSG, type, port);
499
500 return 0;
501 }
502
503 static int flower_parse_opt(struct filter_util *qu, char *handle,
504 int argc, char **argv, struct nlmsghdr *n)
505 {
506 int ret;
507 struct tcmsg *t = NLMSG_DATA(n);
508 struct rtattr *tail;
509 __be16 eth_type = TC_H_MIN(t->tcm_info);
510 __be16 vlan_ethtype = 0;
511 __u8 ip_proto = 0xff;
512 __u32 flags = 0;
513 __u32 mtf = 0;
514 __u32 mtf_mask = 0;
515
516 if (handle) {
517 ret = get_u32(&t->tcm_handle, handle, 0);
518 if (ret) {
519 fprintf(stderr, "Illegal \"handle\"\n");
520 return -1;
521 }
522 }
523
524 tail = (struct rtattr *) (((void *) n) + NLMSG_ALIGN(n->nlmsg_len));
525 addattr_l(n, MAX_MSG, TCA_OPTIONS, NULL, 0);
526
527 if (argc == 0) {
528 /*at minimal we will match all ethertype packets */
529 goto parse_done;
530 }
531
532 while (argc > 0) {
533 if (matches(*argv, "classid") == 0 ||
534 matches(*argv, "flowid") == 0) {
535 unsigned int handle;
536
537 NEXT_ARG();
538 ret = get_tc_classid(&handle, *argv);
539 if (ret) {
540 fprintf(stderr, "Illegal \"classid\"\n");
541 return -1;
542 }
543 addattr_l(n, MAX_MSG, TCA_FLOWER_CLASSID, &handle, 4);
544 } else if (matches(*argv, "ip_flags") == 0) {
545 NEXT_ARG();
546 ret = flower_parse_matching_flags(*argv,
547 FLOWER_IP_FLAGS,
548 &mtf,
549 &mtf_mask);
550 if (ret < 0) {
551 fprintf(stderr, "Illegal \"ip_flags\"\n");
552 return -1;
553 }
554 } else if (matches(*argv, "skip_hw") == 0) {
555 flags |= TCA_CLS_FLAGS_SKIP_HW;
556 } else if (matches(*argv, "skip_sw") == 0) {
557 flags |= TCA_CLS_FLAGS_SKIP_SW;
558 } else if (matches(*argv, "indev") == 0) {
559 char ifname[IFNAMSIZ] = {};
560
561 NEXT_ARG();
562 strncpy(ifname, *argv, sizeof(ifname) - 1);
563 addattrstrz(n, MAX_MSG, TCA_FLOWER_INDEV, ifname);
564 } else if (matches(*argv, "vlan_id") == 0) {
565 __u16 vid;
566
567 NEXT_ARG();
568 if (eth_type != htons(ETH_P_8021Q)) {
569 fprintf(stderr,
570 "Can't set \"vlan_id\" if ethertype isn't 802.1Q\n");
571 return -1;
572 }
573 ret = get_u16(&vid, *argv, 10);
574 if (ret < 0 || vid & ~0xfff) {
575 fprintf(stderr, "Illegal \"vlan_id\"\n");
576 return -1;
577 }
578 addattr16(n, MAX_MSG, TCA_FLOWER_KEY_VLAN_ID, vid);
579 } else if (matches(*argv, "vlan_prio") == 0) {
580 __u8 vlan_prio;
581
582 NEXT_ARG();
583 if (eth_type != htons(ETH_P_8021Q)) {
584 fprintf(stderr,
585 "Can't set \"vlan_prio\" if ethertype isn't 802.1Q\n");
586 return -1;
587 }
588 ret = get_u8(&vlan_prio, *argv, 10);
589 if (ret < 0 || vlan_prio & ~0x7) {
590 fprintf(stderr, "Illegal \"vlan_prio\"\n");
591 return -1;
592 }
593 addattr8(n, MAX_MSG,
594 TCA_FLOWER_KEY_VLAN_PRIO, vlan_prio);
595 } else if (matches(*argv, "vlan_ethtype") == 0) {
596 NEXT_ARG();
597 ret = flower_parse_vlan_eth_type(*argv, eth_type,
598 TCA_FLOWER_KEY_VLAN_ETH_TYPE,
599 &vlan_ethtype, n);
600 if (ret < 0)
601 return -1;
602 } else if (matches(*argv, "dst_mac") == 0) {
603 NEXT_ARG();
604 ret = flower_parse_eth_addr(*argv,
605 TCA_FLOWER_KEY_ETH_DST,
606 TCA_FLOWER_KEY_ETH_DST_MASK,
607 n);
608 if (ret < 0) {
609 fprintf(stderr, "Illegal \"dst_mac\"\n");
610 return -1;
611 }
612 } else if (matches(*argv, "src_mac") == 0) {
613 NEXT_ARG();
614 ret = flower_parse_eth_addr(*argv,
615 TCA_FLOWER_KEY_ETH_SRC,
616 TCA_FLOWER_KEY_ETH_SRC_MASK,
617 n);
618 if (ret < 0) {
619 fprintf(stderr, "Illegal \"src_mac\"\n");
620 return -1;
621 }
622 } else if (matches(*argv, "ip_proto") == 0) {
623 NEXT_ARG();
624 ret = flower_parse_ip_proto(*argv, vlan_ethtype ?
625 vlan_ethtype : eth_type,
626 TCA_FLOWER_KEY_IP_PROTO,
627 &ip_proto, n);
628 if (ret < 0) {
629 fprintf(stderr, "Illegal \"ip_proto\"\n");
630 return -1;
631 }
632 } else if (matches(*argv, "dst_ip") == 0) {
633 NEXT_ARG();
634 ret = flower_parse_ip_addr(*argv, vlan_ethtype ?
635 vlan_ethtype : eth_type,
636 TCA_FLOWER_KEY_IPV4_DST,
637 TCA_FLOWER_KEY_IPV4_DST_MASK,
638 TCA_FLOWER_KEY_IPV6_DST,
639 TCA_FLOWER_KEY_IPV6_DST_MASK,
640 n);
641 if (ret < 0) {
642 fprintf(stderr, "Illegal \"dst_ip\"\n");
643 return -1;
644 }
645 } else if (matches(*argv, "src_ip") == 0) {
646 NEXT_ARG();
647 ret = flower_parse_ip_addr(*argv, vlan_ethtype ?
648 vlan_ethtype : eth_type,
649 TCA_FLOWER_KEY_IPV4_SRC,
650 TCA_FLOWER_KEY_IPV4_SRC_MASK,
651 TCA_FLOWER_KEY_IPV6_SRC,
652 TCA_FLOWER_KEY_IPV6_SRC_MASK,
653 n);
654 if (ret < 0) {
655 fprintf(stderr, "Illegal \"src_ip\"\n");
656 return -1;
657 }
658 } else if (matches(*argv, "dst_port") == 0) {
659 NEXT_ARG();
660 ret = flower_parse_port(*argv, ip_proto,
661 FLOWER_ENDPOINT_DST, n);
662 if (ret < 0) {
663 fprintf(stderr, "Illegal \"dst_port\"\n");
664 return -1;
665 }
666 } else if (matches(*argv, "src_port") == 0) {
667 NEXT_ARG();
668 ret = flower_parse_port(*argv, ip_proto,
669 FLOWER_ENDPOINT_SRC, n);
670 if (ret < 0) {
671 fprintf(stderr, "Illegal \"src_port\"\n");
672 return -1;
673 }
674 } else if (matches(*argv, "type") == 0) {
675 NEXT_ARG();
676 ret = flower_parse_icmp(*argv, eth_type, ip_proto,
677 FLOWER_ICMP_FIELD_TYPE, n);
678 if (ret < 0) {
679 fprintf(stderr, "Illegal \"icmp type\"\n");
680 return -1;
681 }
682 } else if (matches(*argv, "code") == 0) {
683 NEXT_ARG();
684 ret = flower_parse_icmp(*argv, eth_type, ip_proto,
685 FLOWER_ICMP_FIELD_CODE, n);
686 if (ret < 0) {
687 fprintf(stderr, "Illegal \"icmp code\"\n");
688 return -1;
689 }
690 } else if (matches(*argv, "arp_tip") == 0) {
691 NEXT_ARG();
692 ret = flower_parse_arp_ip_addr(*argv, vlan_ethtype ?
693 vlan_ethtype : eth_type,
694 TCA_FLOWER_KEY_ARP_TIP,
695 TCA_FLOWER_KEY_ARP_TIP_MASK,
696 n);
697 if (ret < 0) {
698 fprintf(stderr, "Illegal \"arp_tip\"\n");
699 return -1;
700 }
701 } else if (matches(*argv, "arp_sip") == 0) {
702 NEXT_ARG();
703 ret = flower_parse_arp_ip_addr(*argv, vlan_ethtype ?
704 vlan_ethtype : eth_type,
705 TCA_FLOWER_KEY_ARP_SIP,
706 TCA_FLOWER_KEY_ARP_SIP_MASK,
707 n);
708 if (ret < 0) {
709 fprintf(stderr, "Illegal \"arp_sip\"\n");
710 return -1;
711 }
712 } else if (matches(*argv, "arp_op") == 0) {
713 NEXT_ARG();
714 ret = flower_parse_arp_op(*argv, vlan_ethtype ?
715 vlan_ethtype : eth_type,
716 TCA_FLOWER_KEY_ARP_OP,
717 TCA_FLOWER_KEY_ARP_OP_MASK,
718 n);
719 if (ret < 0) {
720 fprintf(stderr, "Illegal \"arp_op\"\n");
721 return -1;
722 }
723 } else if (matches(*argv, "arp_tha") == 0) {
724 NEXT_ARG();
725 ret = flower_parse_eth_addr(*argv,
726 TCA_FLOWER_KEY_ARP_THA,
727 TCA_FLOWER_KEY_ARP_THA_MASK,
728 n);
729 if (ret < 0) {
730 fprintf(stderr, "Illegal \"arp_tha\"\n");
731 return -1;
732 }
733 } else if (matches(*argv, "arp_sha") == 0) {
734 NEXT_ARG();
735 ret = flower_parse_eth_addr(*argv,
736 TCA_FLOWER_KEY_ARP_SHA,
737 TCA_FLOWER_KEY_ARP_SHA_MASK,
738 n);
739 if (ret < 0) {
740 fprintf(stderr, "Illegal \"arp_sha\"\n");
741 return -1;
742 }
743 } else if (matches(*argv, "enc_dst_ip") == 0) {
744 NEXT_ARG();
745 ret = flower_parse_ip_addr(*argv, 0,
746 TCA_FLOWER_KEY_ENC_IPV4_DST,
747 TCA_FLOWER_KEY_ENC_IPV4_DST_MASK,
748 TCA_FLOWER_KEY_ENC_IPV6_DST,
749 TCA_FLOWER_KEY_ENC_IPV6_DST_MASK,
750 n);
751 if (ret < 0) {
752 fprintf(stderr, "Illegal \"enc_dst_ip\"\n");
753 return -1;
754 }
755 } else if (matches(*argv, "enc_src_ip") == 0) {
756 NEXT_ARG();
757 ret = flower_parse_ip_addr(*argv, 0,
758 TCA_FLOWER_KEY_ENC_IPV4_SRC,
759 TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK,
760 TCA_FLOWER_KEY_ENC_IPV6_SRC,
761 TCA_FLOWER_KEY_ENC_IPV6_SRC_MASK,
762 n);
763 if (ret < 0) {
764 fprintf(stderr, "Illegal \"enc_src_ip\"\n");
765 return -1;
766 }
767 } else if (matches(*argv, "enc_key_id") == 0) {
768 NEXT_ARG();
769 ret = flower_parse_key_id(*argv,
770 TCA_FLOWER_KEY_ENC_KEY_ID, n);
771 if (ret < 0) {
772 fprintf(stderr, "Illegal \"enc_key_id\"\n");
773 return -1;
774 }
775 } else if (matches(*argv, "enc_dst_port") == 0) {
776 NEXT_ARG();
777 ret = flower_parse_enc_port(*argv,
778 TCA_FLOWER_KEY_ENC_UDP_DST_PORT, n);
779 if (ret < 0) {
780 fprintf(stderr, "Illegal \"enc_dst_port\"\n");
781 return -1;
782 }
783 } else if (matches(*argv, "action") == 0) {
784 NEXT_ARG();
785 ret = parse_action(&argc, &argv, TCA_FLOWER_ACT, n);
786 if (ret) {
787 fprintf(stderr, "Illegal \"action\"\n");
788 return -1;
789 }
790 continue;
791 } else if (strcmp(*argv, "help") == 0) {
792 explain();
793 return -1;
794 } else {
795 fprintf(stderr, "What is \"%s\"?\n", *argv);
796 explain();
797 return -1;
798 }
799 argc--; argv++;
800 }
801
802 parse_done:
803 ret = addattr32(n, MAX_MSG, TCA_FLOWER_FLAGS, flags);
804 if (ret)
805 return ret;
806
807 if (mtf_mask) {
808 ret = addattr32(n, MAX_MSG, TCA_FLOWER_KEY_FLAGS, htonl(mtf));
809 if (ret)
810 return ret;
811
812 ret = addattr32(n, MAX_MSG, TCA_FLOWER_KEY_FLAGS_MASK, htonl(mtf_mask));
813 if (ret)
814 return ret;
815 }
816
817 if (eth_type != htons(ETH_P_ALL)) {
818 ret = addattr16(n, MAX_MSG, TCA_FLOWER_KEY_ETH_TYPE, eth_type);
819 if (ret)
820 return ret;
821 }
822
823 tail->rta_len = (((void *)n)+n->nlmsg_len) - (void *)tail;
824
825 return 0;
826 }
827
828 static int __mask_bits(char *addr, size_t len)
829 {
830 int bits = 0;
831 bool hole = false;
832 int i;
833 int j;
834
835 for (i = 0; i < len; i++, addr++) {
836 for (j = 7; j >= 0; j--) {
837 if (((*addr) >> j) & 0x1) {
838 if (hole)
839 return -1;
840 bits++;
841 } else if (bits) {
842 hole = true;
843 } else{
844 return -1;
845 }
846 }
847 }
848 return bits;
849 }
850
851 static void flower_print_eth_addr(FILE *f, char *name,
852 struct rtattr *addr_attr,
853 struct rtattr *mask_attr)
854 {
855 SPRINT_BUF(b1);
856 int bits;
857
858 if (!addr_attr || RTA_PAYLOAD(addr_attr) != ETH_ALEN)
859 return;
860 fprintf(f, "\n %s %s", name, ll_addr_n2a(RTA_DATA(addr_attr), ETH_ALEN,
861 0, b1, sizeof(b1)));
862 if (!mask_attr || RTA_PAYLOAD(mask_attr) != ETH_ALEN)
863 return;
864 bits = __mask_bits(RTA_DATA(mask_attr), ETH_ALEN);
865 if (bits < 0)
866 fprintf(f, "/%s", ll_addr_n2a(RTA_DATA(mask_attr), ETH_ALEN,
867 0, b1, sizeof(b1)));
868 else if (bits < ETH_ALEN * 8)
869 fprintf(f, "/%d", bits);
870 }
871
872 static void flower_print_eth_type(FILE *f, __be16 *p_eth_type,
873 struct rtattr *eth_type_attr)
874 {
875 __be16 eth_type;
876
877 if (!eth_type_attr)
878 return;
879
880 eth_type = rta_getattr_u16(eth_type_attr);
881 fprintf(f, "\n eth_type ");
882 if (eth_type == htons(ETH_P_IP))
883 fprintf(f, "ipv4");
884 else if (eth_type == htons(ETH_P_IPV6))
885 fprintf(f, "ipv6");
886 else if (eth_type == htons(ETH_P_ARP))
887 fprintf(f, "arp");
888 else if (eth_type == htons(ETH_P_RARP))
889 fprintf(f, "rarp");
890 else
891 fprintf(f, "%04x", ntohs(eth_type));
892 *p_eth_type = eth_type;
893 }
894
895 static void flower_print_ip_proto(FILE *f, __u8 *p_ip_proto,
896 struct rtattr *ip_proto_attr)
897 {
898 __u8 ip_proto;
899
900 if (!ip_proto_attr)
901 return;
902
903 ip_proto = rta_getattr_u8(ip_proto_attr);
904 fprintf(f, "\n ip_proto ");
905 if (ip_proto == IPPROTO_TCP)
906 fprintf(f, "tcp");
907 else if (ip_proto == IPPROTO_UDP)
908 fprintf(f, "udp");
909 else if (ip_proto == IPPROTO_SCTP)
910 fprintf(f, "sctp");
911 else if (ip_proto == IPPROTO_ICMP)
912 fprintf(f, "icmp");
913 else if (ip_proto == IPPROTO_ICMPV6)
914 fprintf(f, "icmpv6");
915 else
916 fprintf(f, "%02x", ip_proto);
917 *p_ip_proto = ip_proto;
918 }
919
920 static void flower_print_matching_flags(FILE *f, char *name,
921 enum flower_matching_flags type,
922 struct rtattr *attr,
923 struct rtattr *mask_attr)
924 {
925 int i;
926 int count = 0;
927 __u32 mtf;
928 __u32 mtf_mask;
929
930 if (!mask_attr || RTA_PAYLOAD(mask_attr) != 4)
931 return;
932
933 mtf = ntohl(rta_getattr_u32(attr));
934 mtf_mask = ntohl(rta_getattr_u32(mask_attr));
935
936 for (i = 0; i < ARRAY_SIZE(flags_str); i++) {
937 if (type != flags_str[i].type)
938 continue;
939 if (mtf_mask & flags_str[i].flag) {
940 if (++count == 1)
941 fprintf(f, "\n %s ", name);
942 else
943 fprintf(f, "/");
944
945 if (mtf & flags_str[i].flag)
946 fprintf(f, "%s", flags_str[i].string);
947 else
948 fprintf(f, "no%s", flags_str[i].string);
949 }
950 }
951 }
952
953 static void flower_print_ip_addr(FILE *f, char *name, __be16 eth_type,
954 struct rtattr *addr4_attr,
955 struct rtattr *mask4_attr,
956 struct rtattr *addr6_attr,
957 struct rtattr *mask6_attr)
958 {
959 struct rtattr *addr_attr;
960 struct rtattr *mask_attr;
961 int family;
962 size_t len;
963 int bits;
964
965 if (eth_type == htons(ETH_P_IP)) {
966 family = AF_INET;
967 addr_attr = addr4_attr;
968 mask_attr = mask4_attr;
969 len = 4;
970 } else if (eth_type == htons(ETH_P_IPV6)) {
971 family = AF_INET6;
972 addr_attr = addr6_attr;
973 mask_attr = mask6_attr;
974 len = 16;
975 } else {
976 return;
977 }
978 if (!addr_attr || RTA_PAYLOAD(addr_attr) != len)
979 return;
980 fprintf(f, "\n %s %s", name, rt_addr_n2a_rta(family, addr_attr));
981 if (!mask_attr || RTA_PAYLOAD(mask_attr) != len)
982 return;
983 bits = __mask_bits(RTA_DATA(mask_attr), len);
984 if (bits < 0)
985 fprintf(f, "/%s", rt_addr_n2a_rta(family, mask_attr));
986 else if (bits < len * 8)
987 fprintf(f, "/%d", bits);
988 }
989 static void flower_print_ip4_addr(FILE *f, char *name,
990 struct rtattr *addr_attr,
991 struct rtattr *mask_attr)
992 {
993 return flower_print_ip_addr(f, name, htons(ETH_P_IP),
994 addr_attr, mask_attr, 0, 0);
995 }
996
997 static void flower_print_port(FILE *f, char *name, struct rtattr *attr)
998 {
999 if (attr)
1000 fprintf(f, "\n %s %d", name, rta_getattr_be16(attr));
1001 }
1002
1003 static void flower_print_key_id(FILE *f, const char *name,
1004 struct rtattr *attr)
1005 {
1006 if (attr)
1007 fprintf(f, "\n %s %d", name, rta_getattr_be32(attr));
1008 }
1009
1010 static void flower_print_masked_u8(FILE *f, const char *name,
1011 struct rtattr *attr,
1012 struct rtattr *mask_attr,
1013 const char *(*value_to_str)(__u8 value))
1014 {
1015 const char *value_str = NULL;
1016 __u8 value, mask;
1017
1018 if (!attr)
1019 return;
1020
1021 value = rta_getattr_u8(attr);
1022 mask = mask_attr ? rta_getattr_u8(mask_attr) : UINT8_MAX;
1023 if (mask == UINT8_MAX && value_to_str)
1024 value_str = value_to_str(value);
1025
1026 fprintf(f, "\n %s ", name);
1027
1028 if (value_str)
1029 fputs(value_str, f);
1030 else
1031 fprintf(f, "%d", value);
1032
1033 if (mask != UINT8_MAX)
1034 fprintf(f, "/%d", mask);
1035 }
1036
1037 static void flower_print_arp_op(FILE *f, const char *name,
1038 struct rtattr *op_attr,
1039 struct rtattr *mask_attr)
1040 {
1041 flower_print_masked_u8(f, name, op_attr, mask_attr,
1042 flower_print_arp_op_to_name);
1043 }
1044
1045 static int flower_print_opt(struct filter_util *qu, FILE *f,
1046 struct rtattr *opt, __u32 handle)
1047 {
1048 struct rtattr *tb[TCA_FLOWER_MAX + 1];
1049 int nl_type, nl_mask_type;
1050 __be16 eth_type = 0;
1051 __u8 ip_proto = 0xff;
1052
1053 if (!opt)
1054 return 0;
1055
1056 parse_rtattr_nested(tb, TCA_FLOWER_MAX, opt);
1057
1058 if (handle)
1059 fprintf(f, "handle 0x%x ", handle);
1060
1061 if (tb[TCA_FLOWER_CLASSID]) {
1062 SPRINT_BUF(b1);
1063 fprintf(f, "classid %s ",
1064 sprint_tc_classid(rta_getattr_u32(tb[TCA_FLOWER_CLASSID]),
1065 b1));
1066 }
1067
1068 if (tb[TCA_FLOWER_INDEV]) {
1069 struct rtattr *attr = tb[TCA_FLOWER_INDEV];
1070
1071 fprintf(f, "\n indev %s", rta_getattr_str(attr));
1072 }
1073
1074 if (tb[TCA_FLOWER_KEY_VLAN_ID]) {
1075 struct rtattr *attr = tb[TCA_FLOWER_KEY_VLAN_ID];
1076
1077 fprintf(f, "\n vlan_id %d", rta_getattr_u16(attr));
1078 }
1079
1080 if (tb[TCA_FLOWER_KEY_VLAN_PRIO]) {
1081 struct rtattr *attr = tb[TCA_FLOWER_KEY_VLAN_PRIO];
1082
1083 fprintf(f, "\n vlan_prio %d", rta_getattr_u8(attr));
1084 }
1085
1086 flower_print_eth_addr(f, "dst_mac", tb[TCA_FLOWER_KEY_ETH_DST],
1087 tb[TCA_FLOWER_KEY_ETH_DST_MASK]);
1088 flower_print_eth_addr(f, "src_mac", tb[TCA_FLOWER_KEY_ETH_SRC],
1089 tb[TCA_FLOWER_KEY_ETH_SRC_MASK]);
1090
1091 flower_print_eth_type(f, &eth_type, tb[TCA_FLOWER_KEY_ETH_TYPE]);
1092 flower_print_ip_proto(f, &ip_proto, tb[TCA_FLOWER_KEY_IP_PROTO]);
1093
1094 flower_print_ip_addr(f, "dst_ip", eth_type,
1095 tb[TCA_FLOWER_KEY_IPV4_DST],
1096 tb[TCA_FLOWER_KEY_IPV4_DST_MASK],
1097 tb[TCA_FLOWER_KEY_IPV6_DST],
1098 tb[TCA_FLOWER_KEY_IPV6_DST_MASK]);
1099
1100 flower_print_ip_addr(f, "src_ip", eth_type,
1101 tb[TCA_FLOWER_KEY_IPV4_SRC],
1102 tb[TCA_FLOWER_KEY_IPV4_SRC_MASK],
1103 tb[TCA_FLOWER_KEY_IPV6_SRC],
1104 tb[TCA_FLOWER_KEY_IPV6_SRC_MASK]);
1105
1106 nl_type = flower_port_attr_type(ip_proto, FLOWER_ENDPOINT_DST);
1107 if (nl_type >= 0)
1108 flower_print_port(f, "dst_port", tb[nl_type]);
1109 nl_type = flower_port_attr_type(ip_proto, FLOWER_ENDPOINT_SRC);
1110 if (nl_type >= 0)
1111 flower_print_port(f, "src_port", tb[nl_type]);
1112
1113 nl_type = flower_icmp_attr_type(eth_type, ip_proto,
1114 FLOWER_ICMP_FIELD_TYPE);
1115 nl_mask_type = flower_icmp_attr_mask_type(eth_type, ip_proto,
1116 FLOWER_ICMP_FIELD_TYPE);
1117 if (nl_type >= 0 && nl_mask_type >= 0)
1118 flower_print_masked_u8(f, "icmp_type", tb[nl_type],
1119 tb[nl_mask_type], NULL);
1120
1121 nl_type = flower_icmp_attr_type(eth_type, ip_proto,
1122 FLOWER_ICMP_FIELD_CODE);
1123 nl_mask_type = flower_icmp_attr_mask_type(eth_type, ip_proto,
1124 FLOWER_ICMP_FIELD_CODE);
1125 if (nl_type >= 0 && nl_mask_type >= 0)
1126 flower_print_masked_u8(f, "icmp_code", tb[nl_type],
1127 tb[nl_mask_type], NULL);
1128
1129 flower_print_ip4_addr(f, "arp_sip", tb[TCA_FLOWER_KEY_ARP_SIP],
1130 tb[TCA_FLOWER_KEY_ARP_SIP_MASK]);
1131 flower_print_ip4_addr(f, "arp_tip", tb[TCA_FLOWER_KEY_ARP_TIP],
1132 tb[TCA_FLOWER_KEY_ARP_TIP_MASK]);
1133 flower_print_arp_op(f, "arp_op", tb[TCA_FLOWER_KEY_ARP_OP],
1134 tb[TCA_FLOWER_KEY_ARP_OP_MASK]);
1135 flower_print_eth_addr(f, "arp_sha", tb[TCA_FLOWER_KEY_ARP_SHA],
1136 tb[TCA_FLOWER_KEY_ARP_SHA_MASK]);
1137 flower_print_eth_addr(f, "arp_tha", tb[TCA_FLOWER_KEY_ARP_THA],
1138 tb[TCA_FLOWER_KEY_ARP_THA_MASK]);
1139
1140 flower_print_ip_addr(f, "enc_dst_ip",
1141 tb[TCA_FLOWER_KEY_ENC_IPV4_DST_MASK] ?
1142 htons(ETH_P_IP) : htons(ETH_P_IPV6),
1143 tb[TCA_FLOWER_KEY_ENC_IPV4_DST],
1144 tb[TCA_FLOWER_KEY_ENC_IPV4_DST_MASK],
1145 tb[TCA_FLOWER_KEY_ENC_IPV6_DST],
1146 tb[TCA_FLOWER_KEY_ENC_IPV6_DST_MASK]);
1147
1148 flower_print_ip_addr(f, "enc_src_ip",
1149 tb[TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK] ?
1150 htons(ETH_P_IP) : htons(ETH_P_IPV6),
1151 tb[TCA_FLOWER_KEY_ENC_IPV4_SRC],
1152 tb[TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK],
1153 tb[TCA_FLOWER_KEY_ENC_IPV6_SRC],
1154 tb[TCA_FLOWER_KEY_ENC_IPV6_SRC_MASK]);
1155
1156 flower_print_key_id(f, "enc_key_id",
1157 tb[TCA_FLOWER_KEY_ENC_KEY_ID]);
1158
1159 flower_print_port(f, "enc_dst_port",
1160 tb[TCA_FLOWER_KEY_ENC_UDP_DST_PORT]);
1161
1162 flower_print_matching_flags(f, "ip_flags",
1163 FLOWER_IP_FLAGS,
1164 tb[TCA_FLOWER_KEY_FLAGS],
1165 tb[TCA_FLOWER_KEY_FLAGS_MASK]);
1166
1167 if (tb[TCA_FLOWER_FLAGS]) {
1168 __u32 flags = rta_getattr_u32(tb[TCA_FLOWER_FLAGS]);
1169
1170 if (flags & TCA_CLS_FLAGS_SKIP_HW)
1171 fprintf(f, "\n skip_hw");
1172 if (flags & TCA_CLS_FLAGS_SKIP_SW)
1173 fprintf(f, "\n skip_sw");
1174 }
1175
1176 if (tb[TCA_FLOWER_ACT])
1177 tc_print_action(f, tb[TCA_FLOWER_ACT]);
1178
1179 return 0;
1180 }
1181
1182 struct filter_util flower_filter_util = {
1183 .id = "flower",
1184 .parse_fopt = flower_parse_opt,
1185 .print_fopt = flower_print_opt,
1186 };