tc: flower: Allow *_mac options to accept a mask

* The argument to src_mac and dst_mac may now take an optional mask
  to limit the scope of matching.
* This address is is documented as a LLADDR in keeping with ip-link(8).
* The formats accepted match those already output when dumping flower
  filters from the kernel.

Example of use of LLADDR with and without a mask:

tc qdisc add dev eth0 ingress
tc filter add dev eth0 protocol ip parent ffff: flower indev eth0 \
	src_mac 52:54:01:00:00:00/ff:ff:00:00:00:01 action drop
tc filter add dev eth0 protocol ip parent ffff: flower indev eth0 \
	src_mac 52:54:00:00:00:00/23 action drop
tc filter add dev eth0 protocol ip parent ffff: flower indev eth0 \
	src_mac 52:54:00:00:00:00 action drop

Signed-off-by: Simon Horman <simon.horman@netronome.com>
This commit is contained in:
Simon Horman 2016-12-16 14:54:37 +01:00 committed by Stephen Hemminger
parent b2a1f740aa
commit c2078f8dc4
2 changed files with 45 additions and 11 deletions

View 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
@ -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.

View File

@ -45,8 +45,8 @@ 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 PREFIX |\n"
" src_ip PREFIX |\n"
@ -58,6 +58,7 @@ static void explain(void)
" enc_src_ip PREFIX |\n"
" enc_key_id [ KEY-ID ] }\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"
@ -68,16 +69,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));
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,