Skip to content

Commit c73c8a8

Browse files
committed
Merge branch 'nfp-flow-dissector-layer'
Pieter Jansen van Vuuren says: ==================== nfp: fix layer calculation and flow dissector use Previously when calculating the supported key layers MPLS, IPv4/6 TTL and TOS were not considered. Formerly flow dissectors were referenced without first checking that they are in use and correctly populated by TC. Additionally this patch set fixes the incorrect use of mask field for vlan matching. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 77146b5 + 6afd33e commit c73c8a8

File tree

2 files changed

+113
-86
lines changed

2 files changed

+113
-86
lines changed

drivers/net/ethernet/netronome/nfp/flower/match.c

Lines changed: 71 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -42,33 +42,29 @@ nfp_flower_compile_meta_tci(struct nfp_flower_meta_two *frame,
4242
struct tc_cls_flower_offload *flow, u8 key_type,
4343
bool mask_version)
4444
{
45+
struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
4546
struct flow_dissector_key_vlan *flow_vlan;
4647
u16 tmp_tci;
4748

49+
memset(frame, 0, sizeof(struct nfp_flower_meta_two));
4850
/* Populate the metadata frame. */
4951
frame->nfp_flow_key_layer = key_type;
5052
frame->mask_id = ~0;
5153

52-
if (mask_version) {
53-
frame->tci = cpu_to_be16(~0);
54-
return;
55-
}
56-
57-
flow_vlan = skb_flow_dissector_target(flow->dissector,
58-
FLOW_DISSECTOR_KEY_VLAN,
59-
flow->key);
60-
61-
/* Populate the tci field. */
62-
if (!flow_vlan->vlan_id) {
63-
tmp_tci = 0;
64-
} else {
65-
tmp_tci = FIELD_PREP(NFP_FLOWER_MASK_VLAN_PRIO,
66-
flow_vlan->vlan_priority) |
67-
FIELD_PREP(NFP_FLOWER_MASK_VLAN_VID,
68-
flow_vlan->vlan_id) |
69-
NFP_FLOWER_MASK_VLAN_CFI;
54+
if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_VLAN)) {
55+
flow_vlan = skb_flow_dissector_target(flow->dissector,
56+
FLOW_DISSECTOR_KEY_VLAN,
57+
target);
58+
/* Populate the tci field. */
59+
if (flow_vlan->vlan_id) {
60+
tmp_tci = FIELD_PREP(NFP_FLOWER_MASK_VLAN_PRIO,
61+
flow_vlan->vlan_priority) |
62+
FIELD_PREP(NFP_FLOWER_MASK_VLAN_VID,
63+
flow_vlan->vlan_id) |
64+
NFP_FLOWER_MASK_VLAN_CFI;
65+
frame->tci = cpu_to_be16(tmp_tci);
66+
}
7067
}
71-
frame->tci = cpu_to_be16(tmp_tci);
7268
}
7369

7470
static void
@@ -99,17 +95,18 @@ nfp_flower_compile_mac(struct nfp_flower_mac_mpls *frame,
9995
bool mask_version)
10096
{
10197
struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
102-
struct flow_dissector_key_eth_addrs *flow_mac;
103-
104-
flow_mac = skb_flow_dissector_target(flow->dissector,
105-
FLOW_DISSECTOR_KEY_ETH_ADDRS,
106-
target);
98+
struct flow_dissector_key_eth_addrs *addr;
10799

108100
memset(frame, 0, sizeof(struct nfp_flower_mac_mpls));
109101

110-
/* Populate mac frame. */
111-
ether_addr_copy(frame->mac_dst, &flow_mac->dst[0]);
112-
ether_addr_copy(frame->mac_src, &flow_mac->src[0]);
102+
if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
103+
addr = skb_flow_dissector_target(flow->dissector,
104+
FLOW_DISSECTOR_KEY_ETH_ADDRS,
105+
target);
106+
/* Populate mac frame. */
107+
ether_addr_copy(frame->mac_dst, &addr->dst[0]);
108+
ether_addr_copy(frame->mac_src, &addr->src[0]);
109+
}
113110

114111
if (mask_version)
115112
frame->mpls_lse = cpu_to_be32(~0);
@@ -121,14 +118,17 @@ nfp_flower_compile_tport(struct nfp_flower_tp_ports *frame,
121118
bool mask_version)
122119
{
123120
struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
124-
struct flow_dissector_key_ports *flow_tp;
121+
struct flow_dissector_key_ports *tp;
125122

126-
flow_tp = skb_flow_dissector_target(flow->dissector,
127-
FLOW_DISSECTOR_KEY_PORTS,
128-
target);
123+
memset(frame, 0, sizeof(struct nfp_flower_tp_ports));
129124

130-
frame->port_src = flow_tp->src;
131-
frame->port_dst = flow_tp->dst;
125+
if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_PORTS)) {
126+
tp = skb_flow_dissector_target(flow->dissector,
127+
FLOW_DISSECTOR_KEY_PORTS,
128+
target);
129+
frame->port_src = tp->src;
130+
frame->port_dst = tp->dst;
131+
}
132132
}
133133

134134
static void
@@ -137,25 +137,27 @@ nfp_flower_compile_ipv4(struct nfp_flower_ipv4 *frame,
137137
bool mask_version)
138138
{
139139
struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
140-
struct flow_dissector_key_ipv4_addrs *flow_ipv4;
141-
struct flow_dissector_key_basic *flow_basic;
142-
143-
flow_ipv4 = skb_flow_dissector_target(flow->dissector,
144-
FLOW_DISSECTOR_KEY_IPV4_ADDRS,
145-
target);
146-
147-
flow_basic = skb_flow_dissector_target(flow->dissector,
148-
FLOW_DISSECTOR_KEY_BASIC,
149-
target);
140+
struct flow_dissector_key_ipv4_addrs *addr;
141+
struct flow_dissector_key_basic *basic;
150142

151-
/* Populate IPv4 frame. */
152-
frame->reserved = 0;
153-
frame->ipv4_src = flow_ipv4->src;
154-
frame->ipv4_dst = flow_ipv4->dst;
155-
frame->proto = flow_basic->ip_proto;
156143
/* Wildcard TOS/TTL for now. */
157-
frame->tos = 0;
158-
frame->ttl = 0;
144+
memset(frame, 0, sizeof(struct nfp_flower_ipv4));
145+
146+
if (dissector_uses_key(flow->dissector,
147+
FLOW_DISSECTOR_KEY_IPV4_ADDRS)) {
148+
addr = skb_flow_dissector_target(flow->dissector,
149+
FLOW_DISSECTOR_KEY_IPV4_ADDRS,
150+
target);
151+
frame->ipv4_src = addr->src;
152+
frame->ipv4_dst = addr->dst;
153+
}
154+
155+
if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_BASIC)) {
156+
basic = skb_flow_dissector_target(flow->dissector,
157+
FLOW_DISSECTOR_KEY_BASIC,
158+
target);
159+
frame->proto = basic->ip_proto;
160+
}
159161
}
160162

161163
static void
@@ -164,26 +166,27 @@ nfp_flower_compile_ipv6(struct nfp_flower_ipv6 *frame,
164166
bool mask_version)
165167
{
166168
struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
167-
struct flow_dissector_key_ipv6_addrs *flow_ipv6;
168-
struct flow_dissector_key_basic *flow_basic;
169-
170-
flow_ipv6 = skb_flow_dissector_target(flow->dissector,
171-
FLOW_DISSECTOR_KEY_IPV6_ADDRS,
172-
target);
169+
struct flow_dissector_key_ipv6_addrs *addr;
170+
struct flow_dissector_key_basic *basic;
173171

174-
flow_basic = skb_flow_dissector_target(flow->dissector,
175-
FLOW_DISSECTOR_KEY_BASIC,
176-
target);
177-
178-
/* Populate IPv6 frame. */
179-
frame->reserved = 0;
180-
frame->ipv6_src = flow_ipv6->src;
181-
frame->ipv6_dst = flow_ipv6->dst;
182-
frame->proto = flow_basic->ip_proto;
183172
/* Wildcard LABEL/TOS/TTL for now. */
184-
frame->ipv6_flow_label_exthdr = 0;
185-
frame->tos = 0;
186-
frame->ttl = 0;
173+
memset(frame, 0, sizeof(struct nfp_flower_ipv6));
174+
175+
if (dissector_uses_key(flow->dissector,
176+
FLOW_DISSECTOR_KEY_IPV6_ADDRS)) {
177+
addr = skb_flow_dissector_target(flow->dissector,
178+
FLOW_DISSECTOR_KEY_IPV6_ADDRS,
179+
target);
180+
frame->ipv6_src = addr->src;
181+
frame->ipv6_dst = addr->dst;
182+
}
183+
184+
if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_BASIC)) {
185+
basic = skb_flow_dissector_target(flow->dissector,
186+
FLOW_DISSECTOR_KEY_BASIC,
187+
target);
188+
frame->proto = basic->ip_proto;
189+
}
187190
}
188191

189192
int nfp_flower_compile_flow_match(struct tc_cls_flower_offload *flow,

drivers/net/ethernet/netronome/nfp/flower/offload.c

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -105,43 +105,62 @@ static int
105105
nfp_flower_calculate_key_layers(struct nfp_fl_key_ls *ret_key_ls,
106106
struct tc_cls_flower_offload *flow)
107107
{
108-
struct flow_dissector_key_control *mask_enc_ctl;
109-
struct flow_dissector_key_basic *mask_basic;
110-
struct flow_dissector_key_basic *key_basic;
108+
struct flow_dissector_key_basic *mask_basic = NULL;
109+
struct flow_dissector_key_basic *key_basic = NULL;
110+
struct flow_dissector_key_ip *mask_ip = NULL;
111111
u32 key_layer_two;
112112
u8 key_layer;
113113
int key_size;
114114

115-
mask_enc_ctl = skb_flow_dissector_target(flow->dissector,
116-
FLOW_DISSECTOR_KEY_ENC_CONTROL,
117-
flow->mask);
115+
if (dissector_uses_key(flow->dissector,
116+
FLOW_DISSECTOR_KEY_ENC_CONTROL)) {
117+
struct flow_dissector_key_control *mask_enc_ctl =
118+
skb_flow_dissector_target(flow->dissector,
119+
FLOW_DISSECTOR_KEY_ENC_CONTROL,
120+
flow->mask);
121+
/* We are expecting a tunnel. For now we ignore offloading. */
122+
if (mask_enc_ctl->addr_type)
123+
return -EOPNOTSUPP;
124+
}
118125

119-
mask_basic = skb_flow_dissector_target(flow->dissector,
120-
FLOW_DISSECTOR_KEY_BASIC,
121-
flow->mask);
126+
if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_BASIC)) {
127+
mask_basic = skb_flow_dissector_target(flow->dissector,
128+
FLOW_DISSECTOR_KEY_BASIC,
129+
flow->mask);
130+
131+
key_basic = skb_flow_dissector_target(flow->dissector,
132+
FLOW_DISSECTOR_KEY_BASIC,
133+
flow->key);
134+
}
135+
136+
if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_IP))
137+
mask_ip = skb_flow_dissector_target(flow->dissector,
138+
FLOW_DISSECTOR_KEY_IP,
139+
flow->mask);
122140

123-
key_basic = skb_flow_dissector_target(flow->dissector,
124-
FLOW_DISSECTOR_KEY_BASIC,
125-
flow->key);
126141
key_layer_two = 0;
127142
key_layer = NFP_FLOWER_LAYER_PORT | NFP_FLOWER_LAYER_MAC;
128143
key_size = sizeof(struct nfp_flower_meta_one) +
129144
sizeof(struct nfp_flower_in_port) +
130145
sizeof(struct nfp_flower_mac_mpls);
131146

132-
/* We are expecting a tunnel. For now we ignore offloading. */
133-
if (mask_enc_ctl->addr_type)
134-
return -EOPNOTSUPP;
135-
136-
if (mask_basic->n_proto) {
147+
if (mask_basic && mask_basic->n_proto) {
137148
/* Ethernet type is present in the key. */
138149
switch (key_basic->n_proto) {
139150
case cpu_to_be16(ETH_P_IP):
151+
if (mask_ip && mask_ip->tos)
152+
return -EOPNOTSUPP;
153+
if (mask_ip && mask_ip->ttl)
154+
return -EOPNOTSUPP;
140155
key_layer |= NFP_FLOWER_LAYER_IPV4;
141156
key_size += sizeof(struct nfp_flower_ipv4);
142157
break;
143158

144159
case cpu_to_be16(ETH_P_IPV6):
160+
if (mask_ip && mask_ip->tos)
161+
return -EOPNOTSUPP;
162+
if (mask_ip && mask_ip->ttl)
163+
return -EOPNOTSUPP;
145164
key_layer |= NFP_FLOWER_LAYER_IPV6;
146165
key_size += sizeof(struct nfp_flower_ipv6);
147166
break;
@@ -152,6 +171,11 @@ nfp_flower_calculate_key_layers(struct nfp_fl_key_ls *ret_key_ls,
152171
case cpu_to_be16(ETH_P_ARP):
153172
return -EOPNOTSUPP;
154173

174+
/* Currently we do not offload MPLS. */
175+
case cpu_to_be16(ETH_P_MPLS_UC):
176+
case cpu_to_be16(ETH_P_MPLS_MC):
177+
return -EOPNOTSUPP;
178+
155179
/* Will be included in layer 2. */
156180
case cpu_to_be16(ETH_P_8021Q):
157181
break;
@@ -166,7 +190,7 @@ nfp_flower_calculate_key_layers(struct nfp_fl_key_ls *ret_key_ls,
166190
}
167191
}
168192

169-
if (mask_basic->ip_proto) {
193+
if (mask_basic && mask_basic->ip_proto) {
170194
/* Ethernet type is present in the key. */
171195
switch (key_basic->ip_proto) {
172196
case IPPROTO_TCP:

0 commit comments

Comments
 (0)