]> git.proxmox.com Git - mirror_iproute2.git/commitdiff
Merge branch 'master' into net-next
authorStephen Hemminger <stephen@networkplumber.org>
Fri, 13 Jan 2017 01:44:44 +0000 (17:44 -0800)
committerStephen Hemminger <stephen@networkplumber.org>
Fri, 13 Jan 2017 01:44:44 +0000 (17:44 -0800)
include/linux/pkt_cls.h
include/linux/rtnetlink.h
man/man8/tc-flower.8
tc/f_flower.c

index fef68c4c7a43f82ec94b3e4a9e4fa09d3e80f943..a081efbd61a27426a9e8bdd12e7c94c165a8d194 100644 (file)
@@ -4,7 +4,6 @@
 #include <linux/types.h>
 #include <linux/pkt_sched.h>
 
-
 /* Action attributes */
 enum {
        TCA_ACT_UNSPEC,
index 78a70c274518ca3fc1eca3ff85c8f6c96e5f43d9..998ac8ee20e7fec90627b86576bacfec87c82244 100644 (file)
@@ -350,6 +350,7 @@ struct rtnexthop {
 #define RTNH_F_ONLINK          4       /* Gateway is forced on link    */
 #define RTNH_F_OFFLOAD         8       /* offloaded route */
 #define RTNH_F_LINKDOWN                16      /* carrier-down on nexthop */
+#define RTNH_F_UNRESOLVED      32      /* The entry is unresolved (ipmr) */
 
 #define RTNH_COMPARE_MASK      (RTNH_F_DEAD | RTNH_F_LINKDOWN | RTNH_F_OFFLOAD)
 
index c5ddf3cbb14d924936133a63060f3513828d86f1..5904a9ecafdf269956d5c24b31c52e4407365655 100644 (file)
@@ -22,7 +22,7 @@ flower \- flow based traffic control filter
 .BR skip_sw " | " skip_hw
 .R " | { "
 .BR dst_mac " | " src_mac " } "
-.IR mac_address " | "
+.IR MASKED_LLADDR " | "
 .B vlan_id
 .IR VID " | "
 .B vlan_prio
@@ -31,8 +31,8 @@ flower \- flow based traffic control filter
 .IR ETH_TYPE " } | "
 .BR ip_proto " { " tcp " | " udp " | " sctp " | " icmp " | " icmpv6 " | "
 .IR IP_PROTO " } | { "
-.BR dst_ip " | " src_ip " } "
-.IR ipv4_address " | " ipv6_address " } | { "
+.BR dst_ip " | " src_ip " } "
+.IR PREFIX " | { "
 .BR dst_port " | " src_port " } "
 .IR port_number " } | "
 .B enc_key_id
@@ -40,7 +40,7 @@ flower \- flow based traffic control filter
 .BR enc_dst_ip " | " enc_src_ip " } { "
 .IR ipv4_address " | " ipv6_address " } | "
 .B enc_dst_port
-.IR UDP-PORT " | "
+.IR port_number
 .SH DESCRIPTION
 The
 .B flower
@@ -74,10 +74,15 @@ filter, or TC offload is not enabled for the interface, operation will fail.
 .BI skip_hw
 Do not process filter by hardware.
 .TP
-.BI dst_mac " mac_address"
+.BI dst_mac " MASKED_LLADDR"
 .TQ
-.BI src_mac " mac_address"
-Match on source or destination MAC address.
+.BI src_mac " MASKED_LLADDR"
+Match on source or destination MAC address.  A mask may be optionally
+provided to limit the bits of the address which are matched. A mask is
+provided by following the address with a slash and then the mask. It may be
+provided in LLADDR format, in which case it is a bitwise mask, or as a
+number of high bits to match. If the mask is missing then a match on all
+bits is assumed.
 .TP
 .BI vlan_id " VID"
 Match on vlan tag id.
@@ -103,14 +108,14 @@ may be
 .BR tcp ", " udp ", " sctp ", " icmp ", " icmpv6
 or an unsigned 8bit value in hexadecimal format.
 .TP
-.BI dst_ip " ADDRESS"
+.BI dst_ip " PREFIX"
 .TQ
-.BI src_ip " ADDRESS"
+.BI src_ip " PREFIX"
 Match on source or destination IP address.
-.I ADDRESS
-must be a valid IPv4 or IPv6 address, depending on
-.BR protocol
-option of tc filter.
+.I PREFIX
+must be a valid IPv4 or IPv6 address, depending on the \fBprotocol\fR
+option to tc filter, optionally followed by a slash and the prefix length.
+If the prefix is missing, \fBtc\fR assumes a full-length host match.
 .TP
 .BI dst_port " NUMBER"
 .TQ
@@ -128,16 +133,18 @@ which have to be specified in beforehand.
 .TP
 .BI enc_key_id " NUMBER"
 .TQ
-.BI enc_dst_ip " ADDRESS"
+.BI enc_dst_ip " PREFIX"
 .TQ
-.BI enc_src_ip " ADDRESS"
+.BI enc_src_ip " PREFIX"
 .TQ
 .BI enc_dst_port " NUMBER"
 Match on IP tunnel metadata. Key id
 .I NUMBER
 is a 32 bit tunnel key id (e.g. VNI for VXLAN tunnel).
-.I ADDRESS
-must be a valid IPv4 or IPv6 address. Dst port
+.I PREFIX
+must be a valid IPv4 or IPv6 address optionally followed by a slash and the
+prefix length. If the prefix is missing, \fBtc\fR assumes a full-length
+host match.  Dst port
 .I NUMBER
 is a 16 bit UDP dst port.
 .SH NOTES
index 71e9515f501ad39205288580b561a5b05d338812..99f5f8163ee0b571e432f9e615ebe56a7c8eb418 100644 (file)
@@ -45,11 +45,11 @@ static void explain(void)
                "                       vlan_id VID |\n"
                "                       vlan_prio PRIORITY |\n"
                "                       vlan_ethtype [ ipv4 | ipv6 | ETH-TYPE ] |\n"
-               "                       dst_mac MAC-ADDR |\n"
-               "                       src_mac MAC-ADDR |\n"
+               "                       dst_mac MASKED-LLADDR |\n"
+               "                       src_mac MASKED-LLADDR |\n"
                "                       ip_proto [tcp | udp | sctp | icmp | icmpv6 | IP-PROTO ] |\n"
-               "                       dst_ip [ IPV4-ADDR | IPV6-ADDR ] |\n"
-               "                       src_ip [ IPV4-ADDR | IPV6-ADDR ] |\n"
+               "                       dst_ip PREFIX |\n"
+               "                       src_ip PREFIX |\n"
                "                       dst_port PORT-NUMBER |\n"
                "                       src_port PORT-NUMBER |\n"
                "                       type ICMP-TYPE |\n"
@@ -57,8 +57,10 @@ static void explain(void)
                "                       enc_dst_ip [ IPV4-ADDR | IPV6-ADDR ] |\n"
                "                       enc_src_ip [ IPV4-ADDR | IPV6-ADDR ] |\n"
                "                       enc_key_id [ KEY-ID ] |\n"
-               "                       enc_dst_port [ UDP-PORT ] }\n"
+               "                       matching_flags MATCHING-FLAGS | \n"
+               "                       enc_dst_port [ port_number ] }\n"
                "       FILTERID := X:Y:Z\n"
+               "       MASKED_LLADDR := { LLADDR | LLADDR/MASK | LLADDR/BITS }\n"
                "       ACTION-SPEC := ... look at individual actions\n"
                "\n"
                "NOTE: CLASSID, IP-PROTO are parsed as hexadecimal input.\n"
@@ -69,16 +71,44 @@ static void explain(void)
 static int flower_parse_eth_addr(char *str, int addr_type, int mask_type,
                                 struct nlmsghdr *n)
 {
-       int ret;
-       char addr[ETH_ALEN];
+       int ret, err = -1;
+       char addr[ETH_ALEN], *slash;
+
+       slash = strchr(str, '/');
+       if (slash)
+               *slash = '\0';
 
        ret = ll_addr_a2n(addr, sizeof(addr), str);
        if (ret < 0)
-               return -1;
+               goto err;
        addattr_l(n, MAX_MSG, addr_type, addr, sizeof(addr));
-       memset(addr, 0xff, ETH_ALEN);
+
+       if (slash) {
+               unsigned bits;
+
+               if (!get_unsigned(&bits, slash + 1, 10)) {
+                       uint64_t mask;
+
+                       /* Extra 16 bit shift to push mac address into
+                        * high bits of uint64_t
+                        */
+                       mask = htonll(0xffffffffffffULL << (16 + 48 - bits));
+                       memcpy(addr, &mask, ETH_ALEN);
+               } else {
+                       ret = ll_addr_a2n(addr, sizeof(addr), slash + 1);
+                       if (ret < 0)
+                               goto err;
+               }
+       } else {
+               memset(addr, 0xff, ETH_ALEN);
+       }
        addattr_l(n, MAX_MSG, mask_type, addr, sizeof(addr));
-       return 0;
+
+       err = 0;
+err:
+       if (slash)
+               *slash = '/';
+       return err;
 }
 
 static int flower_parse_vlan_eth_type(char *str, __be16 eth_type, int type,
@@ -100,6 +130,31 @@ static int flower_parse_vlan_eth_type(char *str, __be16 eth_type, int type,
        return 0;
 }
 
+static int flower_parse_matching_flags(char *str, int type, int mask_type,
+                                      struct nlmsghdr *n)
+{
+       __u32 mtf, mtf_mask;
+       char *c;
+
+       c = strchr(str, '/');
+       if (c)
+               *c = '\0';
+
+       if (get_u32(&mtf, str, 0))
+               return -1;
+
+       if (c) {
+               if (get_u32(&mtf_mask, ++c, 0))
+                       return -1;
+       } else {
+               mtf_mask = 0xffffffff;
+       }
+
+       addattr32(n, MAX_MSG, type, htonl(mtf));
+       addattr32(n, MAX_MSG, mask_type, htonl(mtf_mask));
+       return 0;
+}
+
 static int flower_parse_ip_proto(char *str, __be16 eth_type, int type,
                                 __u8 *p_ip_proto, struct nlmsghdr *n)
 {
@@ -329,6 +384,16 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
                                return -1;
                        }
                        addattr_l(n, MAX_MSG, TCA_FLOWER_CLASSID, &handle, 4);
+               } else if (matches(*argv, "matching_flags") == 0) {
+                       NEXT_ARG();
+                       ret = flower_parse_matching_flags(*argv,
+                                                         TCA_FLOWER_KEY_FLAGS,
+                                                         TCA_FLOWER_KEY_FLAGS_MASK,
+                                                         n);
+                       if (ret < 0) {
+                               fprintf(stderr, "Illegal \"matching_flags\"\n");
+                               return -1;
+                       }
                } else if (matches(*argv, "skip_hw") == 0) {
                        flags |= TCA_CLS_FLAGS_SKIP_HW;
                } else if (matches(*argv, "skip_sw") == 0) {
@@ -627,6 +692,17 @@ static void flower_print_ip_proto(FILE *f, __u8 *p_ip_proto,
        *p_ip_proto = ip_proto;
 }
 
+static void flower_print_matching_flags(FILE *f, char *name,
+                                       struct rtattr *attr,
+                                       struct rtattr *mask_attr)
+{
+       if (!mask_attr || RTA_PAYLOAD(mask_attr) != 4)
+               return;
+
+       fprintf(f, "\n  %s 0x%08x/0x%08x", name, ntohl(rta_getattr_u32(attr)),
+               mask_attr ? ntohl(rta_getattr_u32(mask_attr)) : 0xffffffff);
+}
+
 static void flower_print_ip_addr(FILE *f, char *name, __be16 eth_type,
                                 struct rtattr *addr4_attr,
                                 struct rtattr *mask4_attr,
@@ -780,6 +856,10 @@ static int flower_print_opt(struct filter_util *qu, FILE *f,
        flower_print_port(f, "enc_dst_port",
                          tb[TCA_FLOWER_KEY_ENC_UDP_DST_PORT]);
 
+       flower_print_matching_flags(f, "matching_flags",
+                                   tb[TCA_FLOWER_KEY_FLAGS],
+                                   tb[TCA_FLOWER_KEY_FLAGS_MASK]);
+
        if (tb[TCA_FLOWER_FLAGS]) {
                __u32 flags = rta_getattr_u32(tb[TCA_FLOWER_FLAGS]);