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