tc flower: use right ethertype in icmp/arp parsing

Currently the icmp and arp parsing functions are called with incorrect
ethtype in case of vlan or cvlan filter options. In this case either
cvlan_ethtype or vlan_ethtype has to be used. The ethtype is now updated
each time a vlan ethtype is matched during parsing.

Signed-off-by: Zahari Doychev <zahari.doychev@linux.com>
Signed-off-by: David Ahern <dsahern@gmail.com>
This commit is contained in:
Zahari Doychev 2020-11-10 08:53:55 +01:00 committed by David Ahern
parent 1ed00380b0
commit 4c551369e0

View File

@ -1324,9 +1324,9 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
bool mpls_format_old = false; bool mpls_format_old = false;
bool mpls_format_new = false; bool mpls_format_new = false;
struct rtattr *tail; struct rtattr *tail;
__be16 eth_type = TC_H_MIN(t->tcm_info); __be16 tc_proto = TC_H_MIN(t->tcm_info);
__be16 eth_type = tc_proto;
__be16 vlan_ethtype = 0; __be16 vlan_ethtype = 0;
__be16 cvlan_ethtype = 0;
__u8 ip_proto = 0xff; __u8 ip_proto = 0xff;
__u32 flags = 0; __u32 flags = 0;
__u32 mtf = 0; __u32 mtf = 0;
@ -1464,6 +1464,8 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
&vlan_ethtype, n); &vlan_ethtype, n);
if (ret < 0) if (ret < 0)
return -1; return -1;
/* get new ethtype for later parsing */
eth_type = vlan_ethtype;
} else if (matches(*argv, "cvlan_id") == 0) { } else if (matches(*argv, "cvlan_id") == 0) {
__u16 vid; __u16 vid;
@ -1495,9 +1497,10 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
TCA_FLOWER_KEY_CVLAN_PRIO, cvlan_prio); TCA_FLOWER_KEY_CVLAN_PRIO, cvlan_prio);
} else if (matches(*argv, "cvlan_ethtype") == 0) { } else if (matches(*argv, "cvlan_ethtype") == 0) {
NEXT_ARG(); NEXT_ARG();
/* get new ethtype for later parsing */
ret = flower_parse_vlan_eth_type(*argv, vlan_ethtype, ret = flower_parse_vlan_eth_type(*argv, vlan_ethtype,
TCA_FLOWER_KEY_CVLAN_ETH_TYPE, TCA_FLOWER_KEY_CVLAN_ETH_TYPE,
&cvlan_ethtype, n); &eth_type, n);
if (ret < 0) if (ret < 0)
return -1; return -1;
} else if (matches(*argv, "mpls") == 0) { } else if (matches(*argv, "mpls") == 0) {
@ -1627,9 +1630,7 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
} }
} else if (matches(*argv, "ip_proto") == 0) { } else if (matches(*argv, "ip_proto") == 0) {
NEXT_ARG(); NEXT_ARG();
ret = flower_parse_ip_proto(*argv, cvlan_ethtype ? ret = flower_parse_ip_proto(*argv, eth_type,
cvlan_ethtype : vlan_ethtype ?
vlan_ethtype : eth_type,
TCA_FLOWER_KEY_IP_PROTO, TCA_FLOWER_KEY_IP_PROTO,
&ip_proto, n); &ip_proto, n);
if (ret < 0) { if (ret < 0) {
@ -1658,9 +1659,7 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
} }
} else if (matches(*argv, "dst_ip") == 0) { } else if (matches(*argv, "dst_ip") == 0) {
NEXT_ARG(); NEXT_ARG();
ret = flower_parse_ip_addr(*argv, cvlan_ethtype ? ret = flower_parse_ip_addr(*argv, eth_type,
cvlan_ethtype : vlan_ethtype ?
vlan_ethtype : eth_type,
TCA_FLOWER_KEY_IPV4_DST, TCA_FLOWER_KEY_IPV4_DST,
TCA_FLOWER_KEY_IPV4_DST_MASK, TCA_FLOWER_KEY_IPV4_DST_MASK,
TCA_FLOWER_KEY_IPV6_DST, TCA_FLOWER_KEY_IPV6_DST,
@ -1672,9 +1671,7 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
} }
} else if (matches(*argv, "src_ip") == 0) { } else if (matches(*argv, "src_ip") == 0) {
NEXT_ARG(); NEXT_ARG();
ret = flower_parse_ip_addr(*argv, cvlan_ethtype ? ret = flower_parse_ip_addr(*argv, eth_type,
cvlan_ethtype : vlan_ethtype ?
vlan_ethtype : eth_type,
TCA_FLOWER_KEY_IPV4_SRC, TCA_FLOWER_KEY_IPV4_SRC,
TCA_FLOWER_KEY_IPV4_SRC_MASK, TCA_FLOWER_KEY_IPV4_SRC_MASK,
TCA_FLOWER_KEY_IPV6_SRC, TCA_FLOWER_KEY_IPV6_SRC,
@ -1728,8 +1725,7 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
} }
} else if (matches(*argv, "arp_tip") == 0) { } else if (matches(*argv, "arp_tip") == 0) {
NEXT_ARG(); NEXT_ARG();
ret = flower_parse_arp_ip_addr(*argv, vlan_ethtype ? ret = flower_parse_arp_ip_addr(*argv, eth_type,
vlan_ethtype : eth_type,
TCA_FLOWER_KEY_ARP_TIP, TCA_FLOWER_KEY_ARP_TIP,
TCA_FLOWER_KEY_ARP_TIP_MASK, TCA_FLOWER_KEY_ARP_TIP_MASK,
n); n);
@ -1739,8 +1735,7 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
} }
} else if (matches(*argv, "arp_sip") == 0) { } else if (matches(*argv, "arp_sip") == 0) {
NEXT_ARG(); NEXT_ARG();
ret = flower_parse_arp_ip_addr(*argv, vlan_ethtype ? ret = flower_parse_arp_ip_addr(*argv, eth_type,
vlan_ethtype : eth_type,
TCA_FLOWER_KEY_ARP_SIP, TCA_FLOWER_KEY_ARP_SIP,
TCA_FLOWER_KEY_ARP_SIP_MASK, TCA_FLOWER_KEY_ARP_SIP_MASK,
n); n);
@ -1750,8 +1745,7 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
} }
} else if (matches(*argv, "arp_op") == 0) { } else if (matches(*argv, "arp_op") == 0) {
NEXT_ARG(); NEXT_ARG();
ret = flower_parse_arp_op(*argv, vlan_ethtype ? ret = flower_parse_arp_op(*argv, eth_type,
vlan_ethtype : eth_type,
TCA_FLOWER_KEY_ARP_OP, TCA_FLOWER_KEY_ARP_OP,
TCA_FLOWER_KEY_ARP_OP_MASK, TCA_FLOWER_KEY_ARP_OP_MASK,
n); n);
@ -1894,8 +1888,8 @@ parse_done:
return ret; return ret;
} }
if (eth_type != htons(ETH_P_ALL)) { if (tc_proto != htons(ETH_P_ALL)) {
ret = addattr16(n, MAX_MSG, TCA_FLOWER_KEY_ETH_TYPE, eth_type); ret = addattr16(n, MAX_MSG, TCA_FLOWER_KEY_ETH_TYPE, tc_proto);
if (ret) if (ret)
return ret; return ret;
} }