130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko/* 230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko * f_flower.c Flower Classifier 330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko * 430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko * This program is free software; you can distribute it and/or 530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko * modify it under the terms of the GNU General Public License 630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko * as published by the Free Software Foundation; either version 730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko * 2 of the License, or (at your option) any later version. 830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko * 930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko * Authors: Jiri Pirko <jiri@resnulli.us> 1030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko */ 1130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 1230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko#include <stdio.h> 1330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko#include <stdlib.h> 1430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko#include <unistd.h> 1530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko#include <syslog.h> 1630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko#include <string.h> 1730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko#include <net/if.h> 18f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman#include <linux/if_arp.h> 1930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko#include <linux/if_ether.h> 2030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko#include <linux/ip.h> 21745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion#include <linux/tc_act/tc_vlan.h> 2230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 2330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko#include "utils.h" 2430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko#include "tc_util.h" 2530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko#include "rt_names.h" 2630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 2708f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakeyenum flower_matching_flags { 2808f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey FLOWER_IP_FLAGS, 2908f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey}; 3008f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey 316910d65661a3718ef4b944251a0dec170027f3d5Simon Hormanenum flower_endpoint { 326910d65661a3718ef4b944251a0dec170027f3d5Simon Horman FLOWER_ENDPOINT_SRC, 336910d65661a3718ef4b944251a0dec170027f3d5Simon Horman FLOWER_ENDPOINT_DST 346910d65661a3718ef4b944251a0dec170027f3d5Simon Horman}; 356910d65661a3718ef4b944251a0dec170027f3d5Simon Horman 36eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Hormanenum flower_icmp_field { 37eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman FLOWER_ICMP_FIELD_TYPE, 38eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman FLOWER_ICMP_FIELD_CODE 39eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman}; 40eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman 4130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirkostatic void explain(void) 4230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko{ 43512caeb2737f1657d941945cc770a95882e1c1bbStephen Hemminger fprintf(stderr, 44512caeb2737f1657d941945cc770a95882e1c1bbStephen Hemminger "Usage: ... flower [ MATCH-LIST ]\n" 45512caeb2737f1657d941945cc770a95882e1c1bbStephen Hemminger " [ skip_sw | skip_hw ]\n" 46512caeb2737f1657d941945cc770a95882e1c1bbStephen Hemminger " [ action ACTION-SPEC ] [ classid CLASSID ]\n" 47512caeb2737f1657d941945cc770a95882e1c1bbStephen Hemminger "\n" 48512caeb2737f1657d941945cc770a95882e1c1bbStephen Hemminger "Where: MATCH-LIST := [ MATCH-LIST ] MATCH\n" 49512caeb2737f1657d941945cc770a95882e1c1bbStephen Hemminger " MATCH := { indev DEV-NAME |\n" 50512caeb2737f1657d941945cc770a95882e1c1bbStephen Hemminger " vlan_id VID |\n" 51512caeb2737f1657d941945cc770a95882e1c1bbStephen Hemminger " vlan_prio PRIORITY |\n" 52512caeb2737f1657d941945cc770a95882e1c1bbStephen Hemminger " vlan_ethtype [ ipv4 | ipv6 | ETH-TYPE ] |\n" 53c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman " dst_mac MASKED-LLADDR |\n" 54c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman " src_mac MASKED-LLADDR |\n" 55eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman " ip_proto [tcp | udp | sctp | icmp | icmpv6 | IP-PROTO ] |\n" 566ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz " ip_tos MASKED-IP_TOS |\n" 576ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz " ip_ttl MASKED-IP_TTL |\n" 58b2a1f740aa4d37b0a15a1a8ea866a29d5fab4591Simon Horman " dst_ip PREFIX |\n" 59b2a1f740aa4d37b0a15a1a8ea866a29d5fab4591Simon Horman " src_ip PREFIX |\n" 60512caeb2737f1657d941945cc770a95882e1c1bbStephen Hemminger " dst_port PORT-NUMBER |\n" 61bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai " src_port PORT-NUMBER |\n" 620c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko " tcp_flags MASKED-TCP_FLAGS |\n" 636374961a00d4b862bdf87c0f22af86d3ff7d0d67Simon Horman " type MASKED-ICMP-TYPE |\n" 646374961a00d4b862bdf87c0f22af86d3ff7d0d67Simon Horman " code MASKED-ICMP-CODE |\n" 65c7ec052bb8682a9889d1e71e2cb2ec780c9d5e26Simon Horman " arp_tip IPV4-PREFIX |\n" 66c7ec052bb8682a9889d1e71e2cb2ec780c9d5e26Simon Horman " arp_sip IPV4-PREFIX |\n" 67f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman " arp_op [ request | reply | OP ] |\n" 68f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman " arp_tha MASKED-LLADDR |\n" 69f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman " arp_sha MASKED-LLADDR |\n" 7010da552800d761fff60eabc067f599c4e403403aStephen Hemminger " enc_dst_ip [ IPV4-ADDR | IPV6-ADDR ] |\n" 7110da552800d761fff60eabc067f599c4e403403aStephen Hemminger " enc_src_ip [ IPV4-ADDR | IPV6-ADDR ] |\n" 72bf73c650ac93ae673291c584fe592ea70686e37eHadar Hen Zion " enc_key_id [ KEY-ID ] |\n" 7308f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey " ip_flags IP-FLAGS | \n" 74a5ae170ed87c6a096451c7a7b94950e7befd8878Simon Horman " enc_dst_port [ port_number ] }\n" 75512caeb2737f1657d941945cc770a95882e1c1bbStephen Hemminger " FILTERID := X:Y:Z\n" 76c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman " MASKED_LLADDR := { LLADDR | LLADDR/MASK | LLADDR/BITS }\n" 77512caeb2737f1657d941945cc770a95882e1c1bbStephen Hemminger " ACTION-SPEC := ... look at individual actions\n" 78512caeb2737f1657d941945cc770a95882e1c1bbStephen Hemminger "\n" 79328374dcfea968d9aa709475d4e3fc04b1d073bbStephen Hemminger "NOTE: CLASSID, IP-PROTO are parsed as hexadecimal input.\n" 80512caeb2737f1657d941945cc770a95882e1c1bbStephen Hemminger "NOTE: There can be only used one mask per one prio. If user needs\n" 81512caeb2737f1657d941945cc770a95882e1c1bbStephen Hemminger " to specify different mask, he has to use different prio.\n"); 8230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko} 8330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 8430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirkostatic int flower_parse_eth_addr(char *str, int addr_type, int mask_type, 8530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko struct nlmsghdr *n) 8630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko{ 87c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman int ret, err = -1; 88c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman char addr[ETH_ALEN], *slash; 89c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman 90c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman slash = strchr(str, '/'); 91c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman if (slash) 92c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman *slash = '\0'; 9330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 9430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko ret = ll_addr_a2n(addr, sizeof(addr), str); 9530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (ret < 0) 96c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman goto err; 9730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko addattr_l(n, MAX_MSG, addr_type, addr, sizeof(addr)); 98c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman 99c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman if (slash) { 100c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman unsigned bits; 101c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman 102c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman if (!get_unsigned(&bits, slash + 1, 10)) { 103c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman uint64_t mask; 104c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman 105c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman /* Extra 16 bit shift to push mac address into 106c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman * high bits of uint64_t 107c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman */ 108c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman mask = htonll(0xffffffffffffULL << (16 + 48 - bits)); 109c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman memcpy(addr, &mask, ETH_ALEN); 110c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman } else { 111c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman ret = ll_addr_a2n(addr, sizeof(addr), slash + 1); 112c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman if (ret < 0) 113c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman goto err; 114c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman } 115c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman } else { 116c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman memset(addr, 0xff, ETH_ALEN); 117c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman } 11830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko addattr_l(n, MAX_MSG, mask_type, addr, sizeof(addr)); 119c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman 120c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman err = 0; 121c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Hormanerr: 122c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman if (slash) 123c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman *slash = '/'; 124c2078f8dc48c572a5016c79c3a2a878b6e39e8eeSimon Horman return err; 12530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko} 12630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 127745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zionstatic int flower_parse_vlan_eth_type(char *str, __be16 eth_type, int type, 128512caeb2737f1657d941945cc770a95882e1c1bbStephen Hemminger __be16 *p_vlan_eth_type, 129512caeb2737f1657d941945cc770a95882e1c1bbStephen Hemminger struct nlmsghdr *n) 130745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion{ 131745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion __be16 vlan_eth_type; 132745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion 133745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion if (eth_type != htons(ETH_P_8021Q)) { 134512caeb2737f1657d941945cc770a95882e1c1bbStephen Hemminger fprintf(stderr, 135512caeb2737f1657d941945cc770a95882e1c1bbStephen Hemminger "Can't set \"vlan_ethtype\" if ethertype isn't 802.1Q\n"); 136745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion return -1; 137745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion } 138745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion 139745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion if (ll_proto_a2n(&vlan_eth_type, str)) 140745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion invarg("invalid vlan_ethtype", str); 141745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion addattr16(n, MAX_MSG, type, vlan_eth_type); 142745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion *p_vlan_eth_type = vlan_eth_type; 143745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion return 0; 144745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion} 145745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion 14608f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakeystruct flag_to_string { 14708f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey int flag; 14808f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey enum flower_matching_flags type; 14908f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey char *string; 15008f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey}; 15122a8f019891ca73295298384612008ff538e48faPaul Blakey 15208f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakeystatic struct flag_to_string flags_str[] = { 15308f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey { TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT, FLOWER_IP_FLAGS, "frag" }, 15408f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey}; 15522a8f019891ca73295298384612008ff538e48faPaul Blakey 15608f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakeystatic int flower_parse_matching_flags(char *str, 15708f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey enum flower_matching_flags type, 15808f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey __u32 *mtf, __u32 *mtf_mask) 15908f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey{ 16008f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey char *token; 16108f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey bool no; 16208f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey bool found; 16308f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey int i; 16422a8f019891ca73295298384612008ff538e48faPaul Blakey 16508f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey token = strtok(str, "/"); 16608f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey 16708f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey while (token) { 16808f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey if (!strncmp(token, "no", 2)) { 16908f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey no = true; 17008f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey token += 2; 17108f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey } else 17208f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey no = false; 17308f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey 17408f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey found = false; 17508f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey for (i = 0; i < ARRAY_SIZE(flags_str); i++) { 17608f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey if (type != flags_str[i].type) 17708f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey continue; 17808f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey 17908f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey if (!strcmp(token, flags_str[i].string)) { 18008f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey if (no) 18108f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey *mtf &= ~flags_str[i].flag; 18208f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey else 18308f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey *mtf |= flags_str[i].flag; 18408f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey 18508f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey *mtf_mask |= flags_str[i].flag; 18608f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey found = true; 18708f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey break; 18808f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey } 18908f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey } 19008f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey if (!found) 19122a8f019891ca73295298384612008ff538e48faPaul Blakey return -1; 19208f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey 19308f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey token = strtok(NULL, "/"); 19422a8f019891ca73295298384612008ff538e48faPaul Blakey } 19522a8f019891ca73295298384612008ff538e48faPaul Blakey 19622a8f019891ca73295298384612008ff538e48faPaul Blakey return 0; 19722a8f019891ca73295298384612008ff538e48faPaul Blakey} 19822a8f019891ca73295298384612008ff538e48faPaul Blakey 19930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirkostatic int flower_parse_ip_proto(char *str, __be16 eth_type, int type, 20030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko __u8 *p_ip_proto, struct nlmsghdr *n) 20130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko{ 20230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko int ret; 20330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko __u8 ip_proto; 20430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 205eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman if (eth_type != htons(ETH_P_IP) && eth_type != htons(ETH_P_IPV6)) 206eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman goto err; 207eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman 20830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (matches(str, "tcp") == 0) { 20930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko ip_proto = IPPROTO_TCP; 21030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } else if (matches(str, "udp") == 0) { 21130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko ip_proto = IPPROTO_UDP; 212a1fb0d484237b41f92ee17634880be80a0dcf51aSimon Horman } else if (matches(str, "sctp") == 0) { 213a1fb0d484237b41f92ee17634880be80a0dcf51aSimon Horman ip_proto = IPPROTO_SCTP; 214eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman } else if (matches(str, "icmp") == 0) { 215eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman if (eth_type != htons(ETH_P_IP)) 216eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman goto err; 217eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman ip_proto = IPPROTO_ICMP; 218eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman } else if (matches(str, "icmpv6") == 0) { 219eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman if (eth_type != htons(ETH_P_IPV6)) 220eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman goto err; 221eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman ip_proto = IPPROTO_ICMPV6; 22230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } else { 22330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko ret = get_u8(&ip_proto, str, 16); 22430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (ret) 22530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko return -1; 22630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } 22730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko addattr8(n, MAX_MSG, type, ip_proto); 22830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko *p_ip_proto = ip_proto; 22930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko return 0; 230eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman 231eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Hormanerr: 232eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman fprintf(stderr, "Illegal \"eth_type\" for ip proto\n"); 233eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman return -1; 23430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko} 23530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 236f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Hormanstatic int __flower_parse_ip_addr(char *str, int family, 237f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman int addr4_type, int mask4_type, 238f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman int addr6_type, int mask6_type, 239f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman struct nlmsghdr *n) 24030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko{ 24130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko int ret; 24230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko inet_prefix addr; 24330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko int bits; 24430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko int i; 24530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 24630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko ret = get_prefix(&addr, str, family); 24730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (ret) 24830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko return -1; 24930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 250bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai if (family && (addr.family != family)) { 251bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai fprintf(stderr, "Illegal \"eth_type\" for ip address\n"); 25230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko return -1; 253bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai } 25430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 25530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko addattr_l(n, MAX_MSG, addr.family == AF_INET ? addr4_type : addr6_type, 25630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko addr.data, addr.bytelen); 25730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 25830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko memset(addr.data, 0xff, addr.bytelen); 25930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko bits = addr.bitlen; 26030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko for (i = 0; i < addr.bytelen / 4; i++) { 26130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (!bits) { 26230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko addr.data[i] = 0; 26330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } else if (bits / 32 >= 1) { 26430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko bits -= 32; 26530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } else { 26630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko addr.data[i] <<= 32 - bits; 26730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko addr.data[i] = htonl(addr.data[i]); 26830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko bits = 0; 26930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } 27030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } 27130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 27230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko addattr_l(n, MAX_MSG, addr.family == AF_INET ? mask4_type : mask6_type, 27330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko addr.data, addr.bytelen); 27430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 27530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko return 0; 27630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko} 27730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 278f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Hormanstatic int flower_parse_ip_addr(char *str, __be16 eth_type, 279f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman int addr4_type, int mask4_type, 280f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman int addr6_type, int mask6_type, 281f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman struct nlmsghdr *n) 282f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman{ 283f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman int family; 284f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman 285f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman if (eth_type == htons(ETH_P_IP)) { 286f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman family = AF_INET; 287f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman } else if (eth_type == htons(ETH_P_IPV6)) { 288f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman family = AF_INET6; 289f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman } else if (!eth_type) { 290f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman family = AF_UNSPEC; 291f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman } else { 292f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman return -1; 293f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman } 294f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman 295164a9ff401e58ff9c0b90088a3aa96216e1d6e8aRoi Dayan return __flower_parse_ip_addr(str, family, addr4_type, mask4_type, 296164a9ff401e58ff9c0b90088a3aa96216e1d6e8aRoi Dayan addr6_type, mask6_type, n); 297f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman} 298f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman 299f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Hormanstatic bool flower_eth_type_arp(__be16 eth_type) 300f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman{ 301f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman return eth_type == htons(ETH_P_ARP) || eth_type == htons(ETH_P_RARP); 302f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman} 303f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman 304f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Hormanstatic int flower_parse_arp_ip_addr(char *str, __be16 eth_type, 305f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman int addr_type, int mask_type, 306f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman struct nlmsghdr *n) 307f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman{ 308f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman if (!flower_eth_type_arp(eth_type)) 309f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman return -1; 310f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman 311f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman return __flower_parse_ip_addr(str, AF_INET, addr_type, mask_type, 312f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman TCA_FLOWER_UNSPEC, TCA_FLOWER_UNSPEC, n); 313f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman} 314f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman 315180136e540ca16826c0069644222878ea8236f93Simon Hormanstatic int flower_parse_u8(char *str, int value_type, int mask_type, 316180136e540ca16826c0069644222878ea8236f93Simon Horman int (*value_from_name)(const char *str, 317180136e540ca16826c0069644222878ea8236f93Simon Horman __u8 *value), 318180136e540ca16826c0069644222878ea8236f93Simon Horman bool (*value_validate)(__u8 value), 319180136e540ca16826c0069644222878ea8236f93Simon Horman struct nlmsghdr *n) 320f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman{ 321f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman char *slash; 322f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman int ret, err = -1; 323180136e540ca16826c0069644222878ea8236f93Simon Horman __u8 value, mask; 324f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman 325f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman slash = strchr(str, '/'); 326f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman if (slash) 327f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman *slash = '\0'; 328f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman 329180136e540ca16826c0069644222878ea8236f93Simon Horman ret = value_from_name ? value_from_name(str, &value) : -1; 330180136e540ca16826c0069644222878ea8236f93Simon Horman if (ret < 0) { 331f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman ret = get_u8(&value, str, 10); 332f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman if (ret) 333f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman goto err; 334f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman } 335f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman 336180136e540ca16826c0069644222878ea8236f93Simon Horman if (value_validate && !value_validate(value)) 337180136e540ca16826c0069644222878ea8236f93Simon Horman goto err; 338180136e540ca16826c0069644222878ea8236f93Simon Horman 339f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman if (slash) { 340f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman ret = get_u8(&mask, slash + 1, 10); 341f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman if (ret) 342f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman goto err; 343f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman } 344f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman else { 345f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman mask = UINT8_MAX; 346f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman } 347f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman 348180136e540ca16826c0069644222878ea8236f93Simon Horman addattr8(n, MAX_MSG, value_type, value); 349f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman addattr8(n, MAX_MSG, mask_type, mask); 350f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman 351f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman err = 0; 352f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Hormanerr: 353f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman if (slash) 354f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman *slash = '/'; 355f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman return err; 356f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman} 357f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman 3589d36e54f36b8360766519bba79028aeb9ec3a762Simon Hormanstatic const char *flower_print_arp_op_to_name(__u8 op) 3599d36e54f36b8360766519bba79028aeb9ec3a762Simon Horman{ 3609d36e54f36b8360766519bba79028aeb9ec3a762Simon Horman switch (op) { 3619d36e54f36b8360766519bba79028aeb9ec3a762Simon Horman case ARPOP_REQUEST: 3629d36e54f36b8360766519bba79028aeb9ec3a762Simon Horman return "request"; 3639d36e54f36b8360766519bba79028aeb9ec3a762Simon Horman case ARPOP_REPLY: 3649d36e54f36b8360766519bba79028aeb9ec3a762Simon Horman return "reply"; 3659d36e54f36b8360766519bba79028aeb9ec3a762Simon Horman default: 3669d36e54f36b8360766519bba79028aeb9ec3a762Simon Horman return NULL; 3679d36e54f36b8360766519bba79028aeb9ec3a762Simon Horman } 3689d36e54f36b8360766519bba79028aeb9ec3a762Simon Horman} 3699d36e54f36b8360766519bba79028aeb9ec3a762Simon Horman 370180136e540ca16826c0069644222878ea8236f93Simon Hormanstatic int flower_arp_op_from_name(const char *name, __u8 *op) 371180136e540ca16826c0069644222878ea8236f93Simon Horman{ 372180136e540ca16826c0069644222878ea8236f93Simon Horman if (!strcmp(name, "request")) 373180136e540ca16826c0069644222878ea8236f93Simon Horman *op = ARPOP_REQUEST; 374180136e540ca16826c0069644222878ea8236f93Simon Horman else if (!strcmp(name, "reply")) 375180136e540ca16826c0069644222878ea8236f93Simon Horman *op = ARPOP_REPLY; 376180136e540ca16826c0069644222878ea8236f93Simon Horman else 377180136e540ca16826c0069644222878ea8236f93Simon Horman return -1; 378180136e540ca16826c0069644222878ea8236f93Simon Horman 379180136e540ca16826c0069644222878ea8236f93Simon Horman return 0; 380180136e540ca16826c0069644222878ea8236f93Simon Horman} 381180136e540ca16826c0069644222878ea8236f93Simon Horman 382180136e540ca16826c0069644222878ea8236f93Simon Hormanstatic bool flow_arp_op_validate(__u8 op) 383180136e540ca16826c0069644222878ea8236f93Simon Horman{ 384180136e540ca16826c0069644222878ea8236f93Simon Horman return !op || op == ARPOP_REQUEST || op == ARPOP_REPLY; 385180136e540ca16826c0069644222878ea8236f93Simon Horman} 386180136e540ca16826c0069644222878ea8236f93Simon Horman 387180136e540ca16826c0069644222878ea8236f93Simon Hormanstatic int flower_parse_arp_op(char *str, __be16 eth_type, 388180136e540ca16826c0069644222878ea8236f93Simon Horman int op_type, int mask_type, 389180136e540ca16826c0069644222878ea8236f93Simon Horman struct nlmsghdr *n) 390180136e540ca16826c0069644222878ea8236f93Simon Horman{ 391180136e540ca16826c0069644222878ea8236f93Simon Horman if (!flower_eth_type_arp(eth_type)) 392180136e540ca16826c0069644222878ea8236f93Simon Horman return -1; 393180136e540ca16826c0069644222878ea8236f93Simon Horman 394180136e540ca16826c0069644222878ea8236f93Simon Horman return flower_parse_u8(str, op_type, mask_type, flower_arp_op_from_name, 395180136e540ca16826c0069644222878ea8236f93Simon Horman flow_arp_op_validate, n); 396180136e540ca16826c0069644222878ea8236f93Simon Horman} 397180136e540ca16826c0069644222878ea8236f93Simon Horman 398eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Hormanstatic int flower_icmp_attr_type(__be16 eth_type, __u8 ip_proto, 399eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman enum flower_icmp_field field) 400eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman{ 401eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman if (eth_type == htons(ETH_P_IP) && ip_proto == IPPROTO_ICMP) 402eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman return field == FLOWER_ICMP_FIELD_CODE ? 403eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman TCA_FLOWER_KEY_ICMPV4_CODE : 404eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman TCA_FLOWER_KEY_ICMPV4_TYPE; 405eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman else if (eth_type == htons(ETH_P_IPV6) && ip_proto == IPPROTO_ICMPV6) 406eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman return field == FLOWER_ICMP_FIELD_CODE ? 407eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman TCA_FLOWER_KEY_ICMPV6_CODE : 408eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman TCA_FLOWER_KEY_ICMPV6_TYPE; 409eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman 410eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman return -1; 411eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman} 412eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman 4136374961a00d4b862bdf87c0f22af86d3ff7d0d67Simon Hormanstatic int flower_icmp_attr_mask_type(__be16 eth_type, __u8 ip_proto, 4146374961a00d4b862bdf87c0f22af86d3ff7d0d67Simon Horman enum flower_icmp_field field) 4156374961a00d4b862bdf87c0f22af86d3ff7d0d67Simon Horman{ 4166374961a00d4b862bdf87c0f22af86d3ff7d0d67Simon Horman if (eth_type == htons(ETH_P_IP) && ip_proto == IPPROTO_ICMP) 4176374961a00d4b862bdf87c0f22af86d3ff7d0d67Simon Horman return field == FLOWER_ICMP_FIELD_CODE ? 4186374961a00d4b862bdf87c0f22af86d3ff7d0d67Simon Horman TCA_FLOWER_KEY_ICMPV4_CODE_MASK : 4196374961a00d4b862bdf87c0f22af86d3ff7d0d67Simon Horman TCA_FLOWER_KEY_ICMPV4_TYPE_MASK; 4206374961a00d4b862bdf87c0f22af86d3ff7d0d67Simon Horman else if (eth_type == htons(ETH_P_IPV6) && ip_proto == IPPROTO_ICMPV6) 4216374961a00d4b862bdf87c0f22af86d3ff7d0d67Simon Horman return field == FLOWER_ICMP_FIELD_CODE ? 4226374961a00d4b862bdf87c0f22af86d3ff7d0d67Simon Horman TCA_FLOWER_KEY_ICMPV6_CODE_MASK : 4236374961a00d4b862bdf87c0f22af86d3ff7d0d67Simon Horman TCA_FLOWER_KEY_ICMPV6_TYPE_MASK; 4246374961a00d4b862bdf87c0f22af86d3ff7d0d67Simon Horman 4256374961a00d4b862bdf87c0f22af86d3ff7d0d67Simon Horman return -1; 4266374961a00d4b862bdf87c0f22af86d3ff7d0d67Simon Horman} 4276374961a00d4b862bdf87c0f22af86d3ff7d0d67Simon Horman 428eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Hormanstatic int flower_parse_icmp(char *str, __u16 eth_type, __u8 ip_proto, 429eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman enum flower_icmp_field field, struct nlmsghdr *n) 430eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman{ 4316374961a00d4b862bdf87c0f22af86d3ff7d0d67Simon Horman int value_type, mask_type; 432eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman 4336374961a00d4b862bdf87c0f22af86d3ff7d0d67Simon Horman value_type = flower_icmp_attr_type(eth_type, ip_proto, field); 4346374961a00d4b862bdf87c0f22af86d3ff7d0d67Simon Horman mask_type = flower_icmp_attr_mask_type(eth_type, ip_proto, field); 4356374961a00d4b862bdf87c0f22af86d3ff7d0d67Simon Horman if (value_type < 0 || mask_type < 0) 436eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman return -1; 437eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman 4386374961a00d4b862bdf87c0f22af86d3ff7d0d67Simon Horman return flower_parse_u8(str, value_type, mask_type, NULL, NULL, n); 439eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman} 440eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman 4416910d65661a3718ef4b944251a0dec170027f3d5Simon Hormanstatic int flower_port_attr_type(__u8 ip_proto, enum flower_endpoint endpoint) 44230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko{ 4436bd5b80cdcfbeb30b79c3ff07ce844f9e4f2c600Simon Horman if (ip_proto == IPPROTO_TCP) 4446910d65661a3718ef4b944251a0dec170027f3d5Simon Horman return endpoint == FLOWER_ENDPOINT_SRC ? 4456910d65661a3718ef4b944251a0dec170027f3d5Simon Horman TCA_FLOWER_KEY_TCP_SRC : 446a1fb0d484237b41f92ee17634880be80a0dcf51aSimon Horman TCA_FLOWER_KEY_TCP_DST; 4476bd5b80cdcfbeb30b79c3ff07ce844f9e4f2c600Simon Horman else if (ip_proto == IPPROTO_UDP) 4486910d65661a3718ef4b944251a0dec170027f3d5Simon Horman return endpoint == FLOWER_ENDPOINT_SRC ? 4496910d65661a3718ef4b944251a0dec170027f3d5Simon Horman TCA_FLOWER_KEY_UDP_SRC : 450a1fb0d484237b41f92ee17634880be80a0dcf51aSimon Horman TCA_FLOWER_KEY_UDP_DST; 4516bd5b80cdcfbeb30b79c3ff07ce844f9e4f2c600Simon Horman else if (ip_proto == IPPROTO_SCTP) 4526910d65661a3718ef4b944251a0dec170027f3d5Simon Horman return endpoint == FLOWER_ENDPOINT_SRC ? 4536910d65661a3718ef4b944251a0dec170027f3d5Simon Horman TCA_FLOWER_KEY_SCTP_SRC : 454a1fb0d484237b41f92ee17634880be80a0dcf51aSimon Horman TCA_FLOWER_KEY_SCTP_DST; 4556bd5b80cdcfbeb30b79c3ff07ce844f9e4f2c600Simon Horman else 45630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko return -1; 457a1fb0d484237b41f92ee17634880be80a0dcf51aSimon Horman} 458a1fb0d484237b41f92ee17634880be80a0dcf51aSimon Horman 4596910d65661a3718ef4b944251a0dec170027f3d5Simon Hormanstatic int flower_parse_port(char *str, __u8 ip_proto, 4606910d65661a3718ef4b944251a0dec170027f3d5Simon Horman enum flower_endpoint endpoint, 461a1fb0d484237b41f92ee17634880be80a0dcf51aSimon Horman struct nlmsghdr *n) 462a1fb0d484237b41f92ee17634880be80a0dcf51aSimon Horman{ 463a1fb0d484237b41f92ee17634880be80a0dcf51aSimon Horman int ret; 464a1fb0d484237b41f92ee17634880be80a0dcf51aSimon Horman int type; 465a1fb0d484237b41f92ee17634880be80a0dcf51aSimon Horman __be16 port; 466a1fb0d484237b41f92ee17634880be80a0dcf51aSimon Horman 4676910d65661a3718ef4b944251a0dec170027f3d5Simon Horman type = flower_port_attr_type(ip_proto, endpoint); 468a1fb0d484237b41f92ee17634880be80a0dcf51aSimon Horman if (type < 0) 469a1fb0d484237b41f92ee17634880be80a0dcf51aSimon Horman return -1; 47030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 4719f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca ret = get_be16(&port, str, 10); 47230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (ret) 47330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko return -1; 47430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 4759f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca addattr16(n, MAX_MSG, type, port); 47630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 47730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko return 0; 47830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko} 47930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 4800c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko#define TCP_FLAGS_MAX_MASK 0xfff 4810c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko 4820c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirkostatic int flower_parse_tcp_flags(char *str, int flags_type, int mask_type, 4830c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko struct nlmsghdr *n) 4840c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko{ 4850c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko char *slash; 4860c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko int ret, err = -1; 4870c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko __u16 flags; 4880c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko 4890c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko slash = strchr(str, '/'); 4900c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko if (slash) 4910c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko *slash = '\0'; 4920c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko 4930c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko ret = get_u16(&flags, str, 16); 4940c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko if (ret < 0 || flags & ~TCP_FLAGS_MAX_MASK) 4950c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko goto err; 4960c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko 4970c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko addattr16(n, MAX_MSG, flags_type, htons(flags)); 4980c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko 4990c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko if (slash) { 5000c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko ret = get_u16(&flags, slash + 1, 16); 5010c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko if (ret < 0 || flags & ~TCP_FLAGS_MAX_MASK) 5020c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko goto err; 5030c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko } else { 5040c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko flags = TCP_FLAGS_MAX_MASK; 5050c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko } 5060c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko addattr16(n, MAX_MSG, mask_type, htons(flags)); 5070c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko 5080c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko err = 0; 5090c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirkoerr: 5100c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko if (slash) 5110c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko *slash = '/'; 5120c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko return err; 5130c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko} 5140c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko 5156ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitzstatic int flower_parse_ip_tos_ttl(char *str, int key_type, int mask_type, 5166ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz struct nlmsghdr *n) 5176ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz{ 5186ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz char *slash; 5196ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz int ret, err = -1; 5206ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz __u8 tos_ttl; 5216ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz 5226ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz slash = strchr(str, '/'); 5236ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz if (slash) 5246ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz *slash = '\0'; 5256ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz 5266ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz ret = get_u8(&tos_ttl, str, 10); 5276ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz if (ret < 0) 5286ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz ret = get_u8(&tos_ttl, str, 16); 5296ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz if (ret < 0) 5306ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz goto err; 5316ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz 5326ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz addattr8(n, MAX_MSG, key_type, tos_ttl); 5336ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz 5346ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz if (slash) { 5356ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz ret = get_u8(&tos_ttl, slash + 1, 16); 5366ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz if (ret < 0) 5376ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz goto err; 5386ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz } else { 5396ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz tos_ttl = 0xff; 5406ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz } 5416ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz addattr8(n, MAX_MSG, mask_type, tos_ttl); 5426ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz 5436ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz err = 0; 5446ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitzerr: 5456ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz if (slash) 5466ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz *slash = '/'; 5476ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz return err; 5486ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz} 5496ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz 550bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadaistatic int flower_parse_key_id(const char *str, int type, struct nlmsghdr *n) 551bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai{ 552bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai int ret; 553bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai __be32 key_id; 554bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai 555bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai ret = get_be32(&key_id, str, 10); 556bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai if (!ret) 557bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai addattr32(n, MAX_MSG, type, key_id); 558bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai 559bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai return ret; 560bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai} 561bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai 56241aa17ff4668ce97ec27e5f4cdc20db7169b549bHadar Hen Zionstatic int flower_parse_enc_port(char *str, int type, struct nlmsghdr *n) 56341aa17ff4668ce97ec27e5f4cdc20db7169b549bHadar Hen Zion{ 56441aa17ff4668ce97ec27e5f4cdc20db7169b549bHadar Hen Zion int ret; 56541aa17ff4668ce97ec27e5f4cdc20db7169b549bHadar Hen Zion __be16 port; 56641aa17ff4668ce97ec27e5f4cdc20db7169b549bHadar Hen Zion 56741aa17ff4668ce97ec27e5f4cdc20db7169b549bHadar Hen Zion ret = get_be16(&port, str, 10); 56841aa17ff4668ce97ec27e5f4cdc20db7169b549bHadar Hen Zion if (ret) 56941aa17ff4668ce97ec27e5f4cdc20db7169b549bHadar Hen Zion return -1; 57041aa17ff4668ce97ec27e5f4cdc20db7169b549bHadar Hen Zion 57141aa17ff4668ce97ec27e5f4cdc20db7169b549bHadar Hen Zion addattr16(n, MAX_MSG, type, port); 57241aa17ff4668ce97ec27e5f4cdc20db7169b549bHadar Hen Zion 57341aa17ff4668ce97ec27e5f4cdc20db7169b549bHadar Hen Zion return 0; 57441aa17ff4668ce97ec27e5f4cdc20db7169b549bHadar Hen Zion} 57541aa17ff4668ce97ec27e5f4cdc20db7169b549bHadar Hen Zion 57630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirkostatic int flower_parse_opt(struct filter_util *qu, char *handle, 57730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko int argc, char **argv, struct nlmsghdr *n) 57830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko{ 57930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko int ret; 58030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko struct tcmsg *t = NLMSG_DATA(n); 58130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko struct rtattr *tail; 582488b41d020fb06428b90289f70a41210718f52b7Jamal Hadi Salim __be16 eth_type = TC_H_MIN(t->tcm_info); 583745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion __be16 vlan_ethtype = 0; 58430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko __u8 ip_proto = 0xff; 585cfcabf18d84a2f4908cb5b4489f67c2cd3f70426Amir Vadai __u32 flags = 0; 58608f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey __u32 mtf = 0; 58708f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey __u32 mtf_mask = 0; 58830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 58930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (handle) { 59030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko ret = get_u32(&t->tcm_handle, handle, 0); 59130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (ret) { 59230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko fprintf(stderr, "Illegal \"handle\"\n"); 59330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko return -1; 59430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } 59530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } 59630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 59730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko tail = (struct rtattr *) (((void *) n) + NLMSG_ALIGN(n->nlmsg_len)); 59830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko addattr_l(n, MAX_MSG, TCA_OPTIONS, NULL, 0); 59930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 600488b41d020fb06428b90289f70a41210718f52b7Jamal Hadi Salim if (argc == 0) { 601488b41d020fb06428b90289f70a41210718f52b7Jamal Hadi Salim /*at minimal we will match all ethertype packets */ 602488b41d020fb06428b90289f70a41210718f52b7Jamal Hadi Salim goto parse_done; 603488b41d020fb06428b90289f70a41210718f52b7Jamal Hadi Salim } 604488b41d020fb06428b90289f70a41210718f52b7Jamal Hadi Salim 60530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko while (argc > 0) { 60630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (matches(*argv, "classid") == 0 || 60730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko matches(*argv, "flowid") == 0) { 60832a121cba257954963fbdd56a1c4567c2efc779aStephen Hemminger unsigned int handle; 60930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 61030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko NEXT_ARG(); 61130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko ret = get_tc_classid(&handle, *argv); 61230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (ret) { 61330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko fprintf(stderr, "Illegal \"classid\"\n"); 61430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko return -1; 61530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } 61630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko addattr_l(n, MAX_MSG, TCA_FLOWER_CLASSID, &handle, 4); 61708f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey } else if (matches(*argv, "ip_flags") == 0) { 61822a8f019891ca73295298384612008ff538e48faPaul Blakey NEXT_ARG(); 61922a8f019891ca73295298384612008ff538e48faPaul Blakey ret = flower_parse_matching_flags(*argv, 62008f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey FLOWER_IP_FLAGS, 62108f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey &mtf, 62208f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey &mtf_mask); 62322a8f019891ca73295298384612008ff538e48faPaul Blakey if (ret < 0) { 62408f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey fprintf(stderr, "Illegal \"ip_flags\"\n"); 62522a8f019891ca73295298384612008ff538e48faPaul Blakey return -1; 62622a8f019891ca73295298384612008ff538e48faPaul Blakey } 627cfcabf18d84a2f4908cb5b4489f67c2cd3f70426Amir Vadai } else if (matches(*argv, "skip_hw") == 0) { 628cfcabf18d84a2f4908cb5b4489f67c2cd3f70426Amir Vadai flags |= TCA_CLS_FLAGS_SKIP_HW; 629cfcabf18d84a2f4908cb5b4489f67c2cd3f70426Amir Vadai } else if (matches(*argv, "skip_sw") == 0) { 630cfcabf18d84a2f4908cb5b4489f67c2cd3f70426Amir Vadai flags |= TCA_CLS_FLAGS_SKIP_SW; 63130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } else if (matches(*argv, "indev") == 0) { 63230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko NEXT_ARG(); 633625df645b703dc858d54784c35beff64464afae2Phil Sutter if (check_ifname(*argv)) 634625df645b703dc858d54784c35beff64464afae2Phil Sutter invarg("\"indev\" not a valid ifname", *argv); 635ee474849c85116ec36e387882447f737ac3fdefbPhil Sutter addattrstrz(n, MAX_MSG, TCA_FLOWER_INDEV, *argv); 636745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion } else if (matches(*argv, "vlan_id") == 0) { 637745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion __u16 vid; 638745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion 639745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion NEXT_ARG(); 640745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion if (eth_type != htons(ETH_P_8021Q)) { 641512caeb2737f1657d941945cc770a95882e1c1bbStephen Hemminger fprintf(stderr, 642512caeb2737f1657d941945cc770a95882e1c1bbStephen Hemminger "Can't set \"vlan_id\" if ethertype isn't 802.1Q\n"); 643745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion return -1; 644745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion } 645745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion ret = get_u16(&vid, *argv, 10); 646745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion if (ret < 0 || vid & ~0xfff) { 647745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion fprintf(stderr, "Illegal \"vlan_id\"\n"); 648745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion return -1; 649745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion } 650745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion addattr16(n, MAX_MSG, TCA_FLOWER_KEY_VLAN_ID, vid); 651745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion } else if (matches(*argv, "vlan_prio") == 0) { 652745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion __u8 vlan_prio; 653745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion 654745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion NEXT_ARG(); 655745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion if (eth_type != htons(ETH_P_8021Q)) { 656512caeb2737f1657d941945cc770a95882e1c1bbStephen Hemminger fprintf(stderr, 657512caeb2737f1657d941945cc770a95882e1c1bbStephen Hemminger "Can't set \"vlan_prio\" if ethertype isn't 802.1Q\n"); 658745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion return -1; 659745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion } 660745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion ret = get_u8(&vlan_prio, *argv, 10); 661745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion if (ret < 0 || vlan_prio & ~0x7) { 662745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion fprintf(stderr, "Illegal \"vlan_prio\"\n"); 663745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion return -1; 664745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion } 665512caeb2737f1657d941945cc770a95882e1c1bbStephen Hemminger addattr8(n, MAX_MSG, 666512caeb2737f1657d941945cc770a95882e1c1bbStephen Hemminger TCA_FLOWER_KEY_VLAN_PRIO, vlan_prio); 667745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion } else if (matches(*argv, "vlan_ethtype") == 0) { 668745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion NEXT_ARG(); 669745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion ret = flower_parse_vlan_eth_type(*argv, eth_type, 670512caeb2737f1657d941945cc770a95882e1c1bbStephen Hemminger TCA_FLOWER_KEY_VLAN_ETH_TYPE, 671512caeb2737f1657d941945cc770a95882e1c1bbStephen Hemminger &vlan_ethtype, n); 672745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion if (ret < 0) 673745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion return -1; 67430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } else if (matches(*argv, "dst_mac") == 0) { 67530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko NEXT_ARG(); 67630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko ret = flower_parse_eth_addr(*argv, 67730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko TCA_FLOWER_KEY_ETH_DST, 67830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko TCA_FLOWER_KEY_ETH_DST_MASK, 67930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko n); 68030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (ret < 0) { 68130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko fprintf(stderr, "Illegal \"dst_mac\"\n"); 68230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko return -1; 68330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } 68430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } else if (matches(*argv, "src_mac") == 0) { 68530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko NEXT_ARG(); 68630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko ret = flower_parse_eth_addr(*argv, 68730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko TCA_FLOWER_KEY_ETH_SRC, 68830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko TCA_FLOWER_KEY_ETH_SRC_MASK, 68930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko n); 69030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (ret < 0) { 69130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko fprintf(stderr, "Illegal \"src_mac\"\n"); 69230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko return -1; 69330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } 69430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } else if (matches(*argv, "ip_proto") == 0) { 69530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko NEXT_ARG(); 696745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion ret = flower_parse_ip_proto(*argv, vlan_ethtype ? 697745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion vlan_ethtype : eth_type, 69830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko TCA_FLOWER_KEY_IP_PROTO, 69930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko &ip_proto, n); 70030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (ret < 0) { 70130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko fprintf(stderr, "Illegal \"ip_proto\"\n"); 70230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko return -1; 70330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } 7046ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz } else if (matches(*argv, "ip_tos") == 0) { 7056ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz NEXT_ARG(); 7066ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz ret = flower_parse_ip_tos_ttl(*argv, 7076ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz TCA_FLOWER_KEY_IP_TOS, 7086ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz TCA_FLOWER_KEY_IP_TOS_MASK, 7096ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz n); 7106ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz if (ret < 0) { 7116ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz fprintf(stderr, "Illegal \"ip_tos\"\n"); 7126ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz return -1; 7136ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz } 7146ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz } else if (matches(*argv, "ip_ttl") == 0) { 7156ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz NEXT_ARG(); 7166ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz ret = flower_parse_ip_tos_ttl(*argv, 7176ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz TCA_FLOWER_KEY_IP_TTL, 7186ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz TCA_FLOWER_KEY_IP_TTL_MASK, 7196ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz n); 7206ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz if (ret < 0) { 7216ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz fprintf(stderr, "Illegal \"ip_ttl\"\n"); 7226ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz return -1; 7236ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz } 72430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } else if (matches(*argv, "dst_ip") == 0) { 72530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko NEXT_ARG(); 726745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion ret = flower_parse_ip_addr(*argv, vlan_ethtype ? 727745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion vlan_ethtype : eth_type, 72830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko TCA_FLOWER_KEY_IPV4_DST, 72930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko TCA_FLOWER_KEY_IPV4_DST_MASK, 73030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko TCA_FLOWER_KEY_IPV6_DST, 73130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko TCA_FLOWER_KEY_IPV6_DST_MASK, 73230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko n); 73330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (ret < 0) { 73430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko fprintf(stderr, "Illegal \"dst_ip\"\n"); 73530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko return -1; 73630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } 73730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } else if (matches(*argv, "src_ip") == 0) { 73830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko NEXT_ARG(); 739745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion ret = flower_parse_ip_addr(*argv, vlan_ethtype ? 740745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion vlan_ethtype : eth_type, 74130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko TCA_FLOWER_KEY_IPV4_SRC, 74230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko TCA_FLOWER_KEY_IPV4_SRC_MASK, 74330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko TCA_FLOWER_KEY_IPV6_SRC, 74430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko TCA_FLOWER_KEY_IPV6_SRC_MASK, 74530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko n); 74630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (ret < 0) { 74730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko fprintf(stderr, "Illegal \"src_ip\"\n"); 74830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko return -1; 74930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } 75030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } else if (matches(*argv, "dst_port") == 0) { 75130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko NEXT_ARG(); 7526910d65661a3718ef4b944251a0dec170027f3d5Simon Horman ret = flower_parse_port(*argv, ip_proto, 7536910d65661a3718ef4b944251a0dec170027f3d5Simon Horman FLOWER_ENDPOINT_DST, n); 75430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (ret < 0) { 75530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko fprintf(stderr, "Illegal \"dst_port\"\n"); 75630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko return -1; 75730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } 75830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } else if (matches(*argv, "src_port") == 0) { 75930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko NEXT_ARG(); 7606910d65661a3718ef4b944251a0dec170027f3d5Simon Horman ret = flower_parse_port(*argv, ip_proto, 7616910d65661a3718ef4b944251a0dec170027f3d5Simon Horman FLOWER_ENDPOINT_SRC, n); 76230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (ret < 0) { 76330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko fprintf(stderr, "Illegal \"src_port\"\n"); 76430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko return -1; 76530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } 7660c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko } else if (matches(*argv, "tcp_flags") == 0) { 7670c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko NEXT_ARG(); 7680c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko ret = flower_parse_tcp_flags(*argv, 7690c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko TCA_FLOWER_KEY_TCP_FLAGS, 7700c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko TCA_FLOWER_KEY_TCP_FLAGS_MASK, 7710c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko n); 7720c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko if (ret < 0) { 7730c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko fprintf(stderr, "Illegal \"tcp_flags\"\n"); 7740c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko return -1; 7750c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko } 776eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman } else if (matches(*argv, "type") == 0) { 777eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman NEXT_ARG(); 778eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman ret = flower_parse_icmp(*argv, eth_type, ip_proto, 779eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman FLOWER_ICMP_FIELD_TYPE, n); 780eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman if (ret < 0) { 781eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman fprintf(stderr, "Illegal \"icmp type\"\n"); 782eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman return -1; 783eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman } 784eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman } else if (matches(*argv, "code") == 0) { 785eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman NEXT_ARG(); 786eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman ret = flower_parse_icmp(*argv, eth_type, ip_proto, 787eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman FLOWER_ICMP_FIELD_CODE, n); 788eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman if (ret < 0) { 789eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman fprintf(stderr, "Illegal \"icmp code\"\n"); 790eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman return -1; 791eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman } 792f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman } else if (matches(*argv, "arp_tip") == 0) { 793f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman NEXT_ARG(); 794f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman ret = flower_parse_arp_ip_addr(*argv, vlan_ethtype ? 795f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman vlan_ethtype : eth_type, 796f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman TCA_FLOWER_KEY_ARP_TIP, 797f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman TCA_FLOWER_KEY_ARP_TIP_MASK, 798f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman n); 799f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman if (ret < 0) { 800f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman fprintf(stderr, "Illegal \"arp_tip\"\n"); 801f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman return -1; 802f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman } 803f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman } else if (matches(*argv, "arp_sip") == 0) { 804f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman NEXT_ARG(); 805f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman ret = flower_parse_arp_ip_addr(*argv, vlan_ethtype ? 806f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman vlan_ethtype : eth_type, 807f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman TCA_FLOWER_KEY_ARP_SIP, 808f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman TCA_FLOWER_KEY_ARP_SIP_MASK, 809f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman n); 810f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman if (ret < 0) { 811f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman fprintf(stderr, "Illegal \"arp_sip\"\n"); 812f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman return -1; 813f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman } 814f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman } else if (matches(*argv, "arp_op") == 0) { 815f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman NEXT_ARG(); 816f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman ret = flower_parse_arp_op(*argv, vlan_ethtype ? 817f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman vlan_ethtype : eth_type, 818f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman TCA_FLOWER_KEY_ARP_OP, 819f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman TCA_FLOWER_KEY_ARP_OP_MASK, 820f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman n); 821f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman if (ret < 0) { 822f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman fprintf(stderr, "Illegal \"arp_op\"\n"); 823f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman return -1; 824f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman } 825f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman } else if (matches(*argv, "arp_tha") == 0) { 826f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman NEXT_ARG(); 827f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman ret = flower_parse_eth_addr(*argv, 828f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman TCA_FLOWER_KEY_ARP_THA, 829f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman TCA_FLOWER_KEY_ARP_THA_MASK, 830f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman n); 831f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman if (ret < 0) { 832f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman fprintf(stderr, "Illegal \"arp_tha\"\n"); 833f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman return -1; 834f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman } 835f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman } else if (matches(*argv, "arp_sha") == 0) { 836f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman NEXT_ARG(); 837f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman ret = flower_parse_eth_addr(*argv, 838f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman TCA_FLOWER_KEY_ARP_SHA, 839f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman TCA_FLOWER_KEY_ARP_SHA_MASK, 840f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman n); 841f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman if (ret < 0) { 842f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman fprintf(stderr, "Illegal \"arp_sha\"\n"); 843f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman return -1; 844f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman } 845bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai } else if (matches(*argv, "enc_dst_ip") == 0) { 846bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai NEXT_ARG(); 847bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai ret = flower_parse_ip_addr(*argv, 0, 848bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai TCA_FLOWER_KEY_ENC_IPV4_DST, 849bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai TCA_FLOWER_KEY_ENC_IPV4_DST_MASK, 850bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai TCA_FLOWER_KEY_ENC_IPV6_DST, 851bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai TCA_FLOWER_KEY_ENC_IPV6_DST_MASK, 852bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai n); 853bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai if (ret < 0) { 854bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai fprintf(stderr, "Illegal \"enc_dst_ip\"\n"); 855bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai return -1; 856bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai } 857bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai } else if (matches(*argv, "enc_src_ip") == 0) { 858bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai NEXT_ARG(); 859bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai ret = flower_parse_ip_addr(*argv, 0, 860bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai TCA_FLOWER_KEY_ENC_IPV4_SRC, 861bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK, 862bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai TCA_FLOWER_KEY_ENC_IPV6_SRC, 863bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai TCA_FLOWER_KEY_ENC_IPV6_SRC_MASK, 864bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai n); 865bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai if (ret < 0) { 866bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai fprintf(stderr, "Illegal \"enc_src_ip\"\n"); 867bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai return -1; 868bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai } 869bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai } else if (matches(*argv, "enc_key_id") == 0) { 870bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai NEXT_ARG(); 871bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai ret = flower_parse_key_id(*argv, 872bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai TCA_FLOWER_KEY_ENC_KEY_ID, n); 873bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai if (ret < 0) { 874bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai fprintf(stderr, "Illegal \"enc_key_id\"\n"); 875bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai return -1; 876bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai } 87741aa17ff4668ce97ec27e5f4cdc20db7169b549bHadar Hen Zion } else if (matches(*argv, "enc_dst_port") == 0) { 87841aa17ff4668ce97ec27e5f4cdc20db7169b549bHadar Hen Zion NEXT_ARG(); 87941aa17ff4668ce97ec27e5f4cdc20db7169b549bHadar Hen Zion ret = flower_parse_enc_port(*argv, 88041aa17ff4668ce97ec27e5f4cdc20db7169b549bHadar Hen Zion TCA_FLOWER_KEY_ENC_UDP_DST_PORT, n); 88141aa17ff4668ce97ec27e5f4cdc20db7169b549bHadar Hen Zion if (ret < 0) { 88241aa17ff4668ce97ec27e5f4cdc20db7169b549bHadar Hen Zion fprintf(stderr, "Illegal \"enc_dst_port\"\n"); 88341aa17ff4668ce97ec27e5f4cdc20db7169b549bHadar Hen Zion return -1; 88441aa17ff4668ce97ec27e5f4cdc20db7169b549bHadar Hen Zion } 88530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } else if (matches(*argv, "action") == 0) { 88630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko NEXT_ARG(); 88730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko ret = parse_action(&argc, &argv, TCA_FLOWER_ACT, n); 88830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (ret) { 88930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko fprintf(stderr, "Illegal \"action\"\n"); 89030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko return -1; 89130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } 89230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko continue; 89330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } else if (strcmp(*argv, "help") == 0) { 89430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko explain(); 89530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko return -1; 89630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } else { 89730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko fprintf(stderr, "What is \"%s\"?\n", *argv); 89830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko explain(); 89930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko return -1; 90030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } 90130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko argc--; argv++; 90230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } 90330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 904488b41d020fb06428b90289f70a41210718f52b7Jamal Hadi Salimparse_done: 905c85609b25faff034d450b0106fac7932d6acf124Roi Dayan ret = addattr32(n, MAX_MSG, TCA_FLOWER_FLAGS, flags); 906c85609b25faff034d450b0106fac7932d6acf124Roi Dayan if (ret) 907c85609b25faff034d450b0106fac7932d6acf124Roi Dayan return ret; 908cfcabf18d84a2f4908cb5b4489f67c2cd3f70426Amir Vadai 90908f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey if (mtf_mask) { 91008f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey ret = addattr32(n, MAX_MSG, TCA_FLOWER_KEY_FLAGS, htonl(mtf)); 91108f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey if (ret) 91208f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey return ret; 91308f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey 91408f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey ret = addattr32(n, MAX_MSG, TCA_FLOWER_KEY_FLAGS_MASK, htonl(mtf_mask)); 91508f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey if (ret) 91608f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey return ret; 91708f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey } 91808f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey 9194f7d406f5dc89229d8aec8b723015c06db343e17Benjamin LaHaise if (eth_type != htons(ETH_P_ALL)) { 9204f7d406f5dc89229d8aec8b723015c06db343e17Benjamin LaHaise ret = addattr16(n, MAX_MSG, TCA_FLOWER_KEY_ETH_TYPE, eth_type); 9214f7d406f5dc89229d8aec8b723015c06db343e17Benjamin LaHaise if (ret) 9224f7d406f5dc89229d8aec8b723015c06db343e17Benjamin LaHaise return ret; 9234f7d406f5dc89229d8aec8b723015c06db343e17Benjamin LaHaise } 924488b41d020fb06428b90289f70a41210718f52b7Jamal Hadi Salim 92532a121cba257954963fbdd56a1c4567c2efc779aStephen Hemminger tail->rta_len = (((void *)n)+n->nlmsg_len) - (void *)tail; 92630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 92730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko return 0; 92830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko} 92930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 93030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirkostatic int __mask_bits(char *addr, size_t len) 93130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko{ 93230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko int bits = 0; 93330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko bool hole = false; 93430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko int i; 93530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko int j; 93630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 93730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko for (i = 0; i < len; i++, addr++) { 93830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko for (j = 7; j >= 0; j--) { 93930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (((*addr) >> j) & 0x1) { 94030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (hole) 94130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko return -1; 94230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko bits++; 94330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } else if (bits) { 94430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko hole = true; 94530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } else{ 94630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko return -1; 94730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } 94830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } 94930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } 95030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko return bits; 95130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko} 95230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 95330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirkostatic void flower_print_eth_addr(FILE *f, char *name, 95430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko struct rtattr *addr_attr, 95530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko struct rtattr *mask_attr) 95630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko{ 95730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko SPRINT_BUF(b1); 95830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko int bits; 95930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 96030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (!addr_attr || RTA_PAYLOAD(addr_attr) != ETH_ALEN) 96130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko return; 96230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko fprintf(f, "\n %s %s", name, ll_addr_n2a(RTA_DATA(addr_attr), ETH_ALEN, 96330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 0, b1, sizeof(b1))); 96430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (!mask_attr || RTA_PAYLOAD(mask_attr) != ETH_ALEN) 96530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko return; 96630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko bits = __mask_bits(RTA_DATA(mask_attr), ETH_ALEN); 96730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (bits < 0) 96830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko fprintf(f, "/%s", ll_addr_n2a(RTA_DATA(mask_attr), ETH_ALEN, 96930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 0, b1, sizeof(b1))); 97030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko else if (bits < ETH_ALEN * 8) 97130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko fprintf(f, "/%d", bits); 97230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko} 97330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 97430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirkostatic void flower_print_eth_type(FILE *f, __be16 *p_eth_type, 97530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko struct rtattr *eth_type_attr) 97630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko{ 97730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko __be16 eth_type; 97830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 97930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (!eth_type_attr) 98030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko return; 98130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 98230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko eth_type = rta_getattr_u16(eth_type_attr); 98330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko fprintf(f, "\n eth_type "); 98430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (eth_type == htons(ETH_P_IP)) 98530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko fprintf(f, "ipv4"); 98630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko else if (eth_type == htons(ETH_P_IPV6)) 98730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko fprintf(f, "ipv6"); 988f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman else if (eth_type == htons(ETH_P_ARP)) 989f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman fprintf(f, "arp"); 990f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman else if (eth_type == htons(ETH_P_RARP)) 991f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman fprintf(f, "rarp"); 99230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko else 99330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko fprintf(f, "%04x", ntohs(eth_type)); 99430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko *p_eth_type = eth_type; 99530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko} 99630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 99730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirkostatic void flower_print_ip_proto(FILE *f, __u8 *p_ip_proto, 99830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko struct rtattr *ip_proto_attr) 99930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko{ 100030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko __u8 ip_proto; 100130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 100230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (!ip_proto_attr) 100330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko return; 100430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 100530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko ip_proto = rta_getattr_u8(ip_proto_attr); 100630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko fprintf(f, "\n ip_proto "); 100730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (ip_proto == IPPROTO_TCP) 100830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko fprintf(f, "tcp"); 100930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko else if (ip_proto == IPPROTO_UDP) 101030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko fprintf(f, "udp"); 1011a1fb0d484237b41f92ee17634880be80a0dcf51aSimon Horman else if (ip_proto == IPPROTO_SCTP) 1012a1fb0d484237b41f92ee17634880be80a0dcf51aSimon Horman fprintf(f, "sctp"); 1013eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman else if (ip_proto == IPPROTO_ICMP) 1014eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman fprintf(f, "icmp"); 1015eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman else if (ip_proto == IPPROTO_ICMPV6) 1016eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman fprintf(f, "icmpv6"); 101730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko else 101830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko fprintf(f, "%02x", ip_proto); 101930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko *p_ip_proto = ip_proto; 102030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko} 102130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 10226ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitzstatic void flower_print_ip_attr(FILE *f, char *name, 10236ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz struct rtattr *key_attr, 10246ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz struct rtattr *mask_attr) 10256ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz{ 10266ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz if (!key_attr) 10276ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz return; 10286ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz 10296ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz fprintf(f, "\n %s %x", name, rta_getattr_u8(key_attr)); 10306ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz if (!mask_attr) 10316ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz return; 10326ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz fprintf(f, "/%x", rta_getattr_u8(mask_attr)); 10336ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz} 10346ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz 103522a8f019891ca73295298384612008ff538e48faPaul Blakeystatic void flower_print_matching_flags(FILE *f, char *name, 103608f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey enum flower_matching_flags type, 103722a8f019891ca73295298384612008ff538e48faPaul Blakey struct rtattr *attr, 103822a8f019891ca73295298384612008ff538e48faPaul Blakey struct rtattr *mask_attr) 103922a8f019891ca73295298384612008ff538e48faPaul Blakey{ 104008f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey int i; 104108f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey int count = 0; 104208f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey __u32 mtf; 104308f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey __u32 mtf_mask; 104408f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey 104522a8f019891ca73295298384612008ff538e48faPaul Blakey if (!mask_attr || RTA_PAYLOAD(mask_attr) != 4) 104622a8f019891ca73295298384612008ff538e48faPaul Blakey return; 104722a8f019891ca73295298384612008ff538e48faPaul Blakey 104808f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey mtf = ntohl(rta_getattr_u32(attr)); 104908f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey mtf_mask = ntohl(rta_getattr_u32(mask_attr)); 105008f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey 105108f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey for (i = 0; i < ARRAY_SIZE(flags_str); i++) { 105208f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey if (type != flags_str[i].type) 105308f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey continue; 105408f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey if (mtf_mask & flags_str[i].flag) { 105508f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey if (++count == 1) 105608f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey fprintf(f, "\n %s ", name); 105708f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey else 105808f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey fprintf(f, "/"); 105908f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey 106008f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey if (mtf & flags_str[i].flag) 106108f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey fprintf(f, "%s", flags_str[i].string); 106208f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey else 106308f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey fprintf(f, "no%s", flags_str[i].string); 106408f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey } 106508f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey } 106622a8f019891ca73295298384612008ff538e48faPaul Blakey} 106722a8f019891ca73295298384612008ff538e48faPaul Blakey 106830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirkostatic void flower_print_ip_addr(FILE *f, char *name, __be16 eth_type, 106930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko struct rtattr *addr4_attr, 107030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko struct rtattr *mask4_attr, 107130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko struct rtattr *addr6_attr, 107230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko struct rtattr *mask6_attr) 107330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko{ 107430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko struct rtattr *addr_attr; 107530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko struct rtattr *mask_attr; 107630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko int family; 107730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko size_t len; 107830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko int bits; 107930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 108030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (eth_type == htons(ETH_P_IP)) { 108130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko family = AF_INET; 108230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko addr_attr = addr4_attr; 108330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko mask_attr = mask4_attr; 108430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko len = 4; 108530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } else if (eth_type == htons(ETH_P_IPV6)) { 108630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko family = AF_INET6; 108730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko addr_attr = addr6_attr; 108830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko mask_attr = mask6_attr; 108930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko len = 16; 109030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } else { 109130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko return; 109230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } 109330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (!addr_attr || RTA_PAYLOAD(addr_attr) != len) 109430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko return; 10957faf1588a755edb9c9cabbe1d3211265e9826d28Phil Sutter fprintf(f, "\n %s %s", name, rt_addr_n2a_rta(family, addr_attr)); 109630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (!mask_attr || RTA_PAYLOAD(mask_attr) != len) 109730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko return; 109830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko bits = __mask_bits(RTA_DATA(mask_attr), len); 109930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (bits < 0) 11007faf1588a755edb9c9cabbe1d3211265e9826d28Phil Sutter fprintf(f, "/%s", rt_addr_n2a_rta(family, mask_attr)); 110130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko else if (bits < len * 8) 110230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko fprintf(f, "/%d", bits); 110330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko} 1104f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Hormanstatic void flower_print_ip4_addr(FILE *f, char *name, 1105f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman struct rtattr *addr_attr, 1106f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman struct rtattr *mask_attr) 1107f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman{ 1108f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman return flower_print_ip_addr(f, name, htons(ETH_P_IP), 1109f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman addr_attr, mask_attr, 0, 0); 1110f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman} 111130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 1112a1fb0d484237b41f92ee17634880be80a0dcf51aSimon Hormanstatic void flower_print_port(FILE *f, char *name, struct rtattr *attr) 111330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko{ 11146bd5b80cdcfbeb30b79c3ff07ce844f9e4f2c600Simon Horman if (attr) 11156bd5b80cdcfbeb30b79c3ff07ce844f9e4f2c600Simon Horman fprintf(f, "\n %s %d", name, rta_getattr_be16(attr)); 111630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko} 111730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 11180c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirkostatic void flower_print_tcp_flags(FILE *f, char *name, 11190c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko struct rtattr *flags_attr, 11200c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko struct rtattr *mask_attr) 11210c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko{ 11220c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko if (!flags_attr) 11230c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko return; 11240c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko fprintf(f, "\n %s %x", name, rta_getattr_be16(flags_attr)); 11250c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko if (!mask_attr) 11260c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko return; 11270c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko fprintf(f, "/%x", rta_getattr_be16(mask_attr)); 11280c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko} 11290c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko 11300c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko 1131bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadaistatic void flower_print_key_id(FILE *f, const char *name, 1132bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai struct rtattr *attr) 1133bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai{ 1134bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai if (attr) 1135bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai fprintf(f, "\n %s %d", name, rta_getattr_be32(attr)); 1136bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai} 1137bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai 11389d36e54f36b8360766519bba79028aeb9ec3a762Simon Hormanstatic void flower_print_masked_u8(FILE *f, const char *name, 11399d36e54f36b8360766519bba79028aeb9ec3a762Simon Horman struct rtattr *attr, 11409d36e54f36b8360766519bba79028aeb9ec3a762Simon Horman struct rtattr *mask_attr, 11419d36e54f36b8360766519bba79028aeb9ec3a762Simon Horman const char *(*value_to_str)(__u8 value)) 1142f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman{ 11439d36e54f36b8360766519bba79028aeb9ec3a762Simon Horman const char *value_str = NULL; 11449d36e54f36b8360766519bba79028aeb9ec3a762Simon Horman __u8 value, mask; 1145f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman 11469d36e54f36b8360766519bba79028aeb9ec3a762Simon Horman if (!attr) 1147f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman return; 1148f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman 11499d36e54f36b8360766519bba79028aeb9ec3a762Simon Horman value = rta_getattr_u8(attr); 1150f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman mask = mask_attr ? rta_getattr_u8(mask_attr) : UINT8_MAX; 11519d36e54f36b8360766519bba79028aeb9ec3a762Simon Horman if (mask == UINT8_MAX && value_to_str) 11529d36e54f36b8360766519bba79028aeb9ec3a762Simon Horman value_str = value_to_str(value); 1153f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman 1154f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman fprintf(f, "\n %s ", name); 1155f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman 11569d36e54f36b8360766519bba79028aeb9ec3a762Simon Horman if (value_str) 11579d36e54f36b8360766519bba79028aeb9ec3a762Simon Horman fputs(value_str, f); 1158f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman else 11599d36e54f36b8360766519bba79028aeb9ec3a762Simon Horman fprintf(f, "%d", value); 1160f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman 1161f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman if (mask != UINT8_MAX) 1162f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman fprintf(f, "/%d", mask); 1163f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman} 1164f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman 11659d36e54f36b8360766519bba79028aeb9ec3a762Simon Hormanstatic void flower_print_arp_op(FILE *f, const char *name, 11669d36e54f36b8360766519bba79028aeb9ec3a762Simon Horman struct rtattr *op_attr, 11679d36e54f36b8360766519bba79028aeb9ec3a762Simon Horman struct rtattr *mask_attr) 11689d36e54f36b8360766519bba79028aeb9ec3a762Simon Horman{ 11699d36e54f36b8360766519bba79028aeb9ec3a762Simon Horman flower_print_masked_u8(f, name, op_attr, mask_attr, 11709d36e54f36b8360766519bba79028aeb9ec3a762Simon Horman flower_print_arp_op_to_name); 11719d36e54f36b8360766519bba79028aeb9ec3a762Simon Horman} 11729d36e54f36b8360766519bba79028aeb9ec3a762Simon Horman 117330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirkostatic int flower_print_opt(struct filter_util *qu, FILE *f, 117430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko struct rtattr *opt, __u32 handle) 117530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko{ 117630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko struct rtattr *tb[TCA_FLOWER_MAX + 1]; 11776374961a00d4b862bdf87c0f22af86d3ff7d0d67Simon Horman int nl_type, nl_mask_type; 117830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko __be16 eth_type = 0; 117930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko __u8 ip_proto = 0xff; 118030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 118130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (!opt) 118230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko return 0; 118330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 118430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko parse_rtattr_nested(tb, TCA_FLOWER_MAX, opt); 118530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 118630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (handle) 118730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko fprintf(f, "handle 0x%x ", handle); 118830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 118930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (tb[TCA_FLOWER_CLASSID]) { 119030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko SPRINT_BUF(b1); 119130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko fprintf(f, "classid %s ", 1192488b41d020fb06428b90289f70a41210718f52b7Jamal Hadi Salim sprint_tc_classid(rta_getattr_u32(tb[TCA_FLOWER_CLASSID]), 1193488b41d020fb06428b90289f70a41210718f52b7Jamal Hadi Salim b1)); 119430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } 119530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 119630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko if (tb[TCA_FLOWER_INDEV]) { 119730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko struct rtattr *attr = tb[TCA_FLOWER_INDEV]; 119830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 119930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko fprintf(f, "\n indev %s", rta_getattr_str(attr)); 120030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko } 120130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 1202745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion if (tb[TCA_FLOWER_KEY_VLAN_ID]) { 1203745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion struct rtattr *attr = tb[TCA_FLOWER_KEY_VLAN_ID]; 1204745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion 1205745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion fprintf(f, "\n vlan_id %d", rta_getattr_u16(attr)); 1206745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion } 1207745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion 1208745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion if (tb[TCA_FLOWER_KEY_VLAN_PRIO]) { 1209745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion struct rtattr *attr = tb[TCA_FLOWER_KEY_VLAN_PRIO]; 1210745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion 1211745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion fprintf(f, "\n vlan_prio %d", rta_getattr_u8(attr)); 1212745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion } 1213745d91726006fcaa9006f491f9a596c4025cecf7Hadar Hen Zion 121430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko flower_print_eth_addr(f, "dst_mac", tb[TCA_FLOWER_KEY_ETH_DST], 121530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko tb[TCA_FLOWER_KEY_ETH_DST_MASK]); 121630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko flower_print_eth_addr(f, "src_mac", tb[TCA_FLOWER_KEY_ETH_SRC], 121730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko tb[TCA_FLOWER_KEY_ETH_SRC_MASK]); 121830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 121930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko flower_print_eth_type(f, ð_type, tb[TCA_FLOWER_KEY_ETH_TYPE]); 122030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko flower_print_ip_proto(f, &ip_proto, tb[TCA_FLOWER_KEY_IP_PROTO]); 122130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 12226ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz flower_print_ip_attr(f, "ip_tos", tb[TCA_FLOWER_KEY_IP_TOS], 12236ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz tb[TCA_FLOWER_KEY_IP_TOS_MASK]); 12246ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz flower_print_ip_attr(f, "ip_ttl", tb[TCA_FLOWER_KEY_IP_TTL], 12256ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz tb[TCA_FLOWER_KEY_IP_TTL_MASK]); 12266ea2c2b1cff676be2d01029a01cbd84d0675213cOr Gerlitz 122730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko flower_print_ip_addr(f, "dst_ip", eth_type, 122830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko tb[TCA_FLOWER_KEY_IPV4_DST], 122930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko tb[TCA_FLOWER_KEY_IPV4_DST_MASK], 123030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko tb[TCA_FLOWER_KEY_IPV6_DST], 123130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko tb[TCA_FLOWER_KEY_IPV6_DST_MASK]); 123230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 123330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko flower_print_ip_addr(f, "src_ip", eth_type, 123430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko tb[TCA_FLOWER_KEY_IPV4_SRC], 123530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko tb[TCA_FLOWER_KEY_IPV4_SRC_MASK], 123630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko tb[TCA_FLOWER_KEY_IPV6_SRC], 123730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko tb[TCA_FLOWER_KEY_IPV6_SRC_MASK]); 123830eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 1239b2141de1ad98517ffecc1feb99800cd36a26fd22Roi Dayan nl_type = flower_port_attr_type(ip_proto, FLOWER_ENDPOINT_DST); 12406bd5b80cdcfbeb30b79c3ff07ce844f9e4f2c600Simon Horman if (nl_type >= 0) 12416bd5b80cdcfbeb30b79c3ff07ce844f9e4f2c600Simon Horman flower_print_port(f, "dst_port", tb[nl_type]); 1242b2141de1ad98517ffecc1feb99800cd36a26fd22Roi Dayan nl_type = flower_port_attr_type(ip_proto, FLOWER_ENDPOINT_SRC); 12436bd5b80cdcfbeb30b79c3ff07ce844f9e4f2c600Simon Horman if (nl_type >= 0) 12446bd5b80cdcfbeb30b79c3ff07ce844f9e4f2c600Simon Horman flower_print_port(f, "src_port", tb[nl_type]); 124530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 12460c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko flower_print_tcp_flags(f, "tcp_flags", tb[TCA_FLOWER_KEY_TCP_FLAGS], 12470c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko tb[TCA_FLOWER_KEY_TCP_FLAGS_MASK]); 12480c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26aJiri Pirko 124981f6e5a7279eaab826ba8b291b98fb2e89df0572Simon Horman nl_type = flower_icmp_attr_type(eth_type, ip_proto, 125081f6e5a7279eaab826ba8b291b98fb2e89df0572Simon Horman FLOWER_ICMP_FIELD_TYPE); 12516374961a00d4b862bdf87c0f22af86d3ff7d0d67Simon Horman nl_mask_type = flower_icmp_attr_mask_type(eth_type, ip_proto, 12526374961a00d4b862bdf87c0f22af86d3ff7d0d67Simon Horman FLOWER_ICMP_FIELD_TYPE); 12536374961a00d4b862bdf87c0f22af86d3ff7d0d67Simon Horman if (nl_type >= 0 && nl_mask_type >= 0) 12546374961a00d4b862bdf87c0f22af86d3ff7d0d67Simon Horman flower_print_masked_u8(f, "icmp_type", tb[nl_type], 12556374961a00d4b862bdf87c0f22af86d3ff7d0d67Simon Horman tb[nl_mask_type], NULL); 12566374961a00d4b862bdf87c0f22af86d3ff7d0d67Simon Horman 125781f6e5a7279eaab826ba8b291b98fb2e89df0572Simon Horman nl_type = flower_icmp_attr_type(eth_type, ip_proto, 125881f6e5a7279eaab826ba8b291b98fb2e89df0572Simon Horman FLOWER_ICMP_FIELD_CODE); 12596374961a00d4b862bdf87c0f22af86d3ff7d0d67Simon Horman nl_mask_type = flower_icmp_attr_mask_type(eth_type, ip_proto, 12606374961a00d4b862bdf87c0f22af86d3ff7d0d67Simon Horman FLOWER_ICMP_FIELD_CODE); 12616374961a00d4b862bdf87c0f22af86d3ff7d0d67Simon Horman if (nl_type >= 0 && nl_mask_type >= 0) 12626374961a00d4b862bdf87c0f22af86d3ff7d0d67Simon Horman flower_print_masked_u8(f, "icmp_code", tb[nl_type], 12636374961a00d4b862bdf87c0f22af86d3ff7d0d67Simon Horman tb[nl_mask_type], NULL); 1264eb3b5696f16334b4513ad42882ca6bc35b78144dSimon Horman 1265f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman flower_print_ip4_addr(f, "arp_sip", tb[TCA_FLOWER_KEY_ARP_SIP], 1266f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman tb[TCA_FLOWER_KEY_ARP_SIP_MASK]); 1267f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman flower_print_ip4_addr(f, "arp_tip", tb[TCA_FLOWER_KEY_ARP_TIP], 1268f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman tb[TCA_FLOWER_KEY_ARP_TIP_MASK]); 1269f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman flower_print_arp_op(f, "arp_op", tb[TCA_FLOWER_KEY_ARP_OP], 1270f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman tb[TCA_FLOWER_KEY_ARP_OP_MASK]); 1271f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman flower_print_eth_addr(f, "arp_sha", tb[TCA_FLOWER_KEY_ARP_SHA], 1272f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman tb[TCA_FLOWER_KEY_ARP_SHA_MASK]); 1273f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman flower_print_eth_addr(f, "arp_tha", tb[TCA_FLOWER_KEY_ARP_THA], 1274f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman tb[TCA_FLOWER_KEY_ARP_THA_MASK]); 1275f888f4e20534ae44ec4c5a2cfc5209b105645a04Simon Horman 1276bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai flower_print_ip_addr(f, "enc_dst_ip", 1277bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai tb[TCA_FLOWER_KEY_ENC_IPV4_DST_MASK] ? 1278bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai htons(ETH_P_IP) : htons(ETH_P_IPV6), 1279bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai tb[TCA_FLOWER_KEY_ENC_IPV4_DST], 1280bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai tb[TCA_FLOWER_KEY_ENC_IPV4_DST_MASK], 1281bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai tb[TCA_FLOWER_KEY_ENC_IPV6_DST], 1282bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai tb[TCA_FLOWER_KEY_ENC_IPV6_DST_MASK]); 1283bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai 1284bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai flower_print_ip_addr(f, "enc_src_ip", 1285bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai tb[TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK] ? 1286bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai htons(ETH_P_IP) : htons(ETH_P_IPV6), 1287bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai tb[TCA_FLOWER_KEY_ENC_IPV4_SRC], 1288bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai tb[TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK], 1289bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai tb[TCA_FLOWER_KEY_ENC_IPV6_SRC], 1290bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai tb[TCA_FLOWER_KEY_ENC_IPV6_SRC_MASK]); 1291bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai 1292bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai flower_print_key_id(f, "enc_key_id", 1293bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai tb[TCA_FLOWER_KEY_ENC_KEY_ID]); 1294bb9b63b18e85f17e618469ecb139e78ca5a4a4fcAmir Vadai 129541aa17ff4668ce97ec27e5f4cdc20db7169b549bHadar Hen Zion flower_print_port(f, "enc_dst_port", 129641aa17ff4668ce97ec27e5f4cdc20db7169b549bHadar Hen Zion tb[TCA_FLOWER_KEY_ENC_UDP_DST_PORT]); 129741aa17ff4668ce97ec27e5f4cdc20db7169b549bHadar Hen Zion 129808f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey flower_print_matching_flags(f, "ip_flags", 129908f66c80c094eaa5d71abc0395fd114ff919af7aPaul Blakey FLOWER_IP_FLAGS, 130022a8f019891ca73295298384612008ff538e48faPaul Blakey tb[TCA_FLOWER_KEY_FLAGS], 130122a8f019891ca73295298384612008ff538e48faPaul Blakey tb[TCA_FLOWER_KEY_FLAGS_MASK]); 130222a8f019891ca73295298384612008ff538e48faPaul Blakey 1303512caeb2737f1657d941945cc770a95882e1c1bbStephen Hemminger if (tb[TCA_FLOWER_FLAGS]) { 1304cfcabf18d84a2f4908cb5b4489f67c2cd3f70426Amir Vadai __u32 flags = rta_getattr_u32(tb[TCA_FLOWER_FLAGS]); 1305cfcabf18d84a2f4908cb5b4489f67c2cd3f70426Amir Vadai 1306cfcabf18d84a2f4908cb5b4489f67c2cd3f70426Amir Vadai if (flags & TCA_CLS_FLAGS_SKIP_HW) 1307cfcabf18d84a2f4908cb5b4489f67c2cd3f70426Amir Vadai fprintf(f, "\n skip_hw"); 1308cfcabf18d84a2f4908cb5b4489f67c2cd3f70426Amir Vadai if (flags & TCA_CLS_FLAGS_SKIP_SW) 1309cfcabf18d84a2f4908cb5b4489f67c2cd3f70426Amir Vadai fprintf(f, "\n skip_sw"); 1310e57285b81a098ed705d683ce94f9abd1cc53438aOr Gerlitz 1311e57285b81a098ed705d683ce94f9abd1cc53438aOr Gerlitz if (flags & TCA_CLS_FLAGS_IN_HW) 1312e57285b81a098ed705d683ce94f9abd1cc53438aOr Gerlitz fprintf(f, "\n in_hw"); 1313e57285b81a098ed705d683ce94f9abd1cc53438aOr Gerlitz else if (flags & TCA_CLS_FLAGS_NOT_IN_HW) 1314e57285b81a098ed705d683ce94f9abd1cc53438aOr Gerlitz fprintf(f, "\n not_in_hw"); 1315cfcabf18d84a2f4908cb5b4489f67c2cd3f70426Amir Vadai } 1316cfcabf18d84a2f4908cb5b4489f67c2cd3f70426Amir Vadai 1317512caeb2737f1657d941945cc770a95882e1c1bbStephen Hemminger if (tb[TCA_FLOWER_ACT]) 13189e71352581954065ea4a6c0766f55fcb04ca0499Jamal Hadi Salim tc_print_action(f, tb[TCA_FLOWER_ACT], 0); 131930eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 132030eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko return 0; 132130eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko} 132230eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko 132330eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirkostruct filter_util flower_filter_util = { 132430eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko .id = "flower", 132530eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko .parse_fopt = flower_parse_opt, 132630eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko .print_fopt = flower_print_opt, 132730eb304ecd1dd7e452847fabea779de0dbe3f1a5Jiri Pirko}; 1328