Skip to content

Commit 86b956d

Browse files
vladimirolteandavem330
authored andcommitted
net: mscc: ocelot: support matching on EtherType
Currently, the filter's protocol is ignored except for a few special cases (IPv4 and IPv6). The EtherType can be matched inside VCAP IS2 by using a MAC_ETYPE key. So there are 2 cases in which EtherType matches are supported: - As part of a larger MAC_ETYPE rule, such as: tc filter add dev swp0 ingress protocol ip \ flower skip_sw src_mac 42:be:24:9b:76:20 action drop - Standalone (matching on protocol only): tc filter add dev swp0 ingress protocol arp \ flower skip_sw action drop As before, if the protocol is not specified, is it implicitly "all" and the EtherType mask in the MAC_ETYPE half key is set to zero. Signed-off-by: Vladimir Oltean <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 44dd5ef commit 86b956d

File tree

1 file changed

+19
-3
lines changed

1 file changed

+19
-3
lines changed

drivers/net/ethernet/mscc/ocelot_flower.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ static int ocelot_flower_parse(struct flow_cls_offload *f,
5151
{
5252
struct flow_rule *rule = flow_cls_offload_flow_rule(f);
5353
struct flow_dissector *dissector = rule->match.dissector;
54+
u16 proto = ntohs(f->common.protocol);
55+
bool match_protocol = true;
5456

5557
if (dissector->used_keys &
5658
~(BIT(FLOW_DISSECTOR_KEY_CONTROL) |
@@ -71,7 +73,6 @@ static int ocelot_flower_parse(struct flow_cls_offload *f,
7173

7274
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
7375
struct flow_match_eth_addrs match;
74-
u16 proto = ntohs(f->common.protocol);
7576

7677
/* The hw support mac matches only for MAC_ETYPE key,
7778
* therefore if other matches(port, tcp flags, etc) are added
@@ -114,18 +115,20 @@ static int ocelot_flower_parse(struct flow_cls_offload *f,
114115
match.key->ip_proto;
115116
ace->frame.ipv4.proto.mask[0] =
116117
match.mask->ip_proto;
118+
match_protocol = false;
117119
}
118120
if (ntohs(match.key->n_proto) == ETH_P_IPV6) {
119121
ace->type = OCELOT_ACE_TYPE_IPV6;
120122
ace->frame.ipv6.proto.value[0] =
121123
match.key->ip_proto;
122124
ace->frame.ipv6.proto.mask[0] =
123125
match.mask->ip_proto;
126+
match_protocol = false;
124127
}
125128
}
126129

127130
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV4_ADDRS) &&
128-
ntohs(f->common.protocol) == ETH_P_IP) {
131+
proto == ETH_P_IP) {
129132
struct flow_match_ipv4_addrs match;
130133
u8 *tmp;
131134

@@ -141,10 +144,11 @@ static int ocelot_flower_parse(struct flow_cls_offload *f,
141144

142145
tmp = &ace->frame.ipv4.dip.mask.addr[0];
143146
memcpy(tmp, &match.mask->dst, 4);
147+
match_protocol = false;
144148
}
145149

146150
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV6_ADDRS) &&
147-
ntohs(f->common.protocol) == ETH_P_IPV6) {
151+
proto == ETH_P_IPV6) {
148152
return -EOPNOTSUPP;
149153
}
150154

@@ -156,6 +160,7 @@ static int ocelot_flower_parse(struct flow_cls_offload *f,
156160
ace->frame.ipv4.sport.mask = ntohs(match.mask->src);
157161
ace->frame.ipv4.dport.value = ntohs(match.key->dst);
158162
ace->frame.ipv4.dport.mask = ntohs(match.mask->dst);
163+
match_protocol = false;
159164
}
160165

161166
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_VLAN)) {
@@ -167,9 +172,20 @@ static int ocelot_flower_parse(struct flow_cls_offload *f,
167172
ace->vlan.vid.mask = match.mask->vlan_id;
168173
ace->vlan.pcp.value[0] = match.key->vlan_priority;
169174
ace->vlan.pcp.mask[0] = match.mask->vlan_priority;
175+
match_protocol = false;
170176
}
171177

172178
finished_key_parsing:
179+
if (match_protocol && proto != ETH_P_ALL) {
180+
/* TODO: support SNAP, LLC etc */
181+
if (proto < ETH_P_802_3_MIN)
182+
return -EOPNOTSUPP;
183+
ace->type = OCELOT_ACE_TYPE_ETYPE;
184+
*(u16 *)ace->frame.etype.etype.value = htons(proto);
185+
*(u16 *)ace->frame.etype.etype.mask = 0xffff;
186+
}
187+
/* else, a rule of type OCELOT_ACE_TYPE_ANY is implicitly added */
188+
173189
ace->prio = f->common.prio;
174190
ace->id = f->cookie;
175191
return ocelot_flower_parse_action(f, ace);

0 commit comments

Comments
 (0)