Skip to content

Commit 611aec1

Browse files
jahurleydavem330
authored andcommitted
nfp: compile flower vxlan tunnel metadata match fields
Compile ovs-tc flower vxlan metadata match fields for offloading. Only support offload of tunnel data when the VXLAN port specifically matches well known port 4789. Signed-off-by: John Hurley <[email protected]> Signed-off-by: Simon Horman <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 79ede4a commit 611aec1

File tree

4 files changed

+158
-12
lines changed

4 files changed

+158
-12
lines changed

drivers/net/ethernet/netronome/nfp/flower/cmsg.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,14 @@
8383
#define NFP_FL_PUSH_VLAN_CFI BIT(12)
8484
#define NFP_FL_PUSH_VLAN_VID GENMASK(11, 0)
8585

86+
/* Tunnel ports */
87+
#define NFP_FL_PORT_TYPE_TUN 0x50000000
88+
89+
enum nfp_flower_tun_type {
90+
NFP_FL_TUNNEL_NONE = 0,
91+
NFP_FL_TUNNEL_VXLAN = 2,
92+
};
93+
8694
struct nfp_fl_output {
8795
__be16 a_op;
8896
__be16 flags;
@@ -230,6 +238,36 @@ struct nfp_flower_ipv6 {
230238
struct in6_addr ipv6_dst;
231239
};
232240

241+
/* Flow Frame VXLAN --> Tunnel details (4W/16B)
242+
* -----------------------------------------------------------------
243+
* 3 2 1
244+
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
245+
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
246+
* | ipv4_addr_src |
247+
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
248+
* | ipv4_addr_dst |
249+
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
250+
* | tun_flags | tos | ttl |
251+
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
252+
* | gpe_flags | Reserved | Next Protocol |
253+
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
254+
* | VNI | Reserved |
255+
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
256+
*/
257+
struct nfp_flower_vxlan {
258+
__be32 ip_src;
259+
__be32 ip_dst;
260+
__be16 tun_flags;
261+
u8 tos;
262+
u8 ttl;
263+
u8 gpe_flags;
264+
u8 reserved[2];
265+
u8 nxt_proto;
266+
__be32 tun_id;
267+
};
268+
269+
#define NFP_FL_TUN_VNI_OFFSET 8
270+
233271
/* The base header for a control message packet.
234272
* Defines an 8-bit version, and an 8-bit type, padded
235273
* to a 32-bit word. Rest of the packet is type-specific.

drivers/net/ethernet/netronome/nfp/flower/main.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ struct nfp_app;
5858
#define NFP_FL_MASK_REUSE_TIME_NS 40000
5959
#define NFP_FL_MASK_ID_LOCATION 1
6060

61+
#define NFP_FL_VXLAN_PORT 4789
62+
6163
struct nfp_fl_mask_id {
6264
struct circ_buf mask_id_free_list;
6365
struct timespec64 *last_used;

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

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,17 @@ nfp_flower_compile_meta(struct nfp_flower_meta_one *frame, u8 key_type)
7777

7878
static int
7979
nfp_flower_compile_port(struct nfp_flower_in_port *frame, u32 cmsg_port,
80-
bool mask_version)
80+
bool mask_version, enum nfp_flower_tun_type tun_type)
8181
{
8282
if (mask_version) {
8383
frame->in_port = cpu_to_be32(~0);
8484
return 0;
8585
}
8686

87-
frame->in_port = cpu_to_be32(cmsg_port);
87+
if (tun_type)
88+
frame->in_port = cpu_to_be32(NFP_FL_PORT_TYPE_TUN | tun_type);
89+
else
90+
frame->in_port = cpu_to_be32(cmsg_port);
8891

8992
return 0;
9093
}
@@ -189,15 +192,53 @@ nfp_flower_compile_ipv6(struct nfp_flower_ipv6 *frame,
189192
}
190193
}
191194

195+
static void
196+
nfp_flower_compile_vxlan(struct nfp_flower_vxlan *frame,
197+
struct tc_cls_flower_offload *flow,
198+
bool mask_version)
199+
{
200+
struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
201+
struct flow_dissector_key_ipv4_addrs *vxlan_ips;
202+
struct flow_dissector_key_keyid *vni;
203+
204+
/* Wildcard TOS/TTL/GPE_FLAGS/NXT_PROTO for now. */
205+
memset(frame, 0, sizeof(struct nfp_flower_vxlan));
206+
207+
if (dissector_uses_key(flow->dissector,
208+
FLOW_DISSECTOR_KEY_ENC_KEYID)) {
209+
u32 temp_vni;
210+
211+
vni = skb_flow_dissector_target(flow->dissector,
212+
FLOW_DISSECTOR_KEY_ENC_KEYID,
213+
target);
214+
temp_vni = be32_to_cpu(vni->keyid) << NFP_FL_TUN_VNI_OFFSET;
215+
frame->tun_id = cpu_to_be32(temp_vni);
216+
}
217+
218+
if (dissector_uses_key(flow->dissector,
219+
FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS)) {
220+
vxlan_ips =
221+
skb_flow_dissector_target(flow->dissector,
222+
FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS,
223+
target);
224+
frame->ip_src = vxlan_ips->src;
225+
frame->ip_dst = vxlan_ips->dst;
226+
}
227+
}
228+
192229
int nfp_flower_compile_flow_match(struct tc_cls_flower_offload *flow,
193230
struct nfp_fl_key_ls *key_ls,
194231
struct net_device *netdev,
195232
struct nfp_fl_payload *nfp_flow)
196233
{
234+
enum nfp_flower_tun_type tun_type = NFP_FL_TUNNEL_NONE;
197235
int err;
198236
u8 *ext;
199237
u8 *msk;
200238

239+
if (key_ls->key_layer & NFP_FLOWER_LAYER_VXLAN)
240+
tun_type = NFP_FL_TUNNEL_VXLAN;
241+
201242
memset(nfp_flow->unmasked_data, 0, key_ls->key_size);
202243
memset(nfp_flow->mask_data, 0, key_ls->key_size);
203244

@@ -216,14 +257,14 @@ int nfp_flower_compile_flow_match(struct tc_cls_flower_offload *flow,
216257
/* Populate Exact Port data. */
217258
err = nfp_flower_compile_port((struct nfp_flower_in_port *)ext,
218259
nfp_repr_get_port_id(netdev),
219-
false);
260+
false, tun_type);
220261
if (err)
221262
return err;
222263

223264
/* Populate Mask Port Data. */
224265
err = nfp_flower_compile_port((struct nfp_flower_in_port *)msk,
225266
nfp_repr_get_port_id(netdev),
226-
true);
267+
true, tun_type);
227268
if (err)
228269
return err;
229270

@@ -291,5 +332,16 @@ int nfp_flower_compile_flow_match(struct tc_cls_flower_offload *flow,
291332
msk += sizeof(struct nfp_flower_ipv6);
292333
}
293334

335+
if (key_ls->key_layer & NFP_FLOWER_LAYER_VXLAN) {
336+
/* Populate Exact VXLAN Data. */
337+
nfp_flower_compile_vxlan((struct nfp_flower_vxlan *)ext,
338+
flow, false);
339+
/* Populate Mask VXLAN Data. */
340+
nfp_flower_compile_vxlan((struct nfp_flower_vxlan *)msk,
341+
flow, true);
342+
ext += sizeof(struct nfp_flower_vxlan);
343+
msk += sizeof(struct nfp_flower_vxlan);
344+
}
345+
294346
return 0;
295347
}

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

Lines changed: 62 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,25 @@
5252
BIT(FLOW_DISSECTOR_KEY_PORTS) | \
5353
BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS) | \
5454
BIT(FLOW_DISSECTOR_KEY_VLAN) | \
55+
BIT(FLOW_DISSECTOR_KEY_ENC_KEYID) | \
56+
BIT(FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS) | \
57+
BIT(FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS) | \
58+
BIT(FLOW_DISSECTOR_KEY_ENC_CONTROL) | \
59+
BIT(FLOW_DISSECTOR_KEY_ENC_PORTS) | \
5560
BIT(FLOW_DISSECTOR_KEY_IP))
5661

62+
#define NFP_FLOWER_WHITELIST_TUN_DISSECTOR \
63+
(BIT(FLOW_DISSECTOR_KEY_ENC_CONTROL) | \
64+
BIT(FLOW_DISSECTOR_KEY_ENC_KEYID) | \
65+
BIT(FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS) | \
66+
BIT(FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS) | \
67+
BIT(FLOW_DISSECTOR_KEY_ENC_PORTS))
68+
69+
#define NFP_FLOWER_WHITELIST_TUN_DISSECTOR_R \
70+
(BIT(FLOW_DISSECTOR_KEY_ENC_CONTROL) | \
71+
BIT(FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS) | \
72+
BIT(FLOW_DISSECTOR_KEY_ENC_PORTS))
73+
5774
static int
5875
nfp_flower_xmit_flow(struct net_device *netdev,
5976
struct nfp_fl_payload *nfp_flow, u8 mtype)
@@ -125,15 +142,58 @@ nfp_flower_calculate_key_layers(struct nfp_fl_key_ls *ret_key_ls,
125142
if (flow->dissector->used_keys & ~NFP_FLOWER_WHITELIST_DISSECTOR)
126143
return -EOPNOTSUPP;
127144

145+
/* If any tun dissector is used then the required set must be used. */
146+
if (flow->dissector->used_keys & NFP_FLOWER_WHITELIST_TUN_DISSECTOR &&
147+
(flow->dissector->used_keys & NFP_FLOWER_WHITELIST_TUN_DISSECTOR_R)
148+
!= NFP_FLOWER_WHITELIST_TUN_DISSECTOR_R)
149+
return -EOPNOTSUPP;
150+
151+
key_layer_two = 0;
152+
key_layer = NFP_FLOWER_LAYER_PORT | NFP_FLOWER_LAYER_MAC;
153+
key_size = sizeof(struct nfp_flower_meta_one) +
154+
sizeof(struct nfp_flower_in_port) +
155+
sizeof(struct nfp_flower_mac_mpls);
156+
128157
if (dissector_uses_key(flow->dissector,
129158
FLOW_DISSECTOR_KEY_ENC_CONTROL)) {
159+
struct flow_dissector_key_ipv4_addrs *mask_ipv4 = NULL;
160+
struct flow_dissector_key_ports *mask_enc_ports = NULL;
161+
struct flow_dissector_key_ports *enc_ports = NULL;
130162
struct flow_dissector_key_control *mask_enc_ctl =
131163
skb_flow_dissector_target(flow->dissector,
132164
FLOW_DISSECTOR_KEY_ENC_CONTROL,
133165
flow->mask);
134-
/* We are expecting a tunnel. For now we ignore offloading. */
135-
if (mask_enc_ctl->addr_type)
166+
struct flow_dissector_key_control *enc_ctl =
167+
skb_flow_dissector_target(flow->dissector,
168+
FLOW_DISSECTOR_KEY_ENC_CONTROL,
169+
flow->key);
170+
if (mask_enc_ctl->addr_type != 0xffff ||
171+
enc_ctl->addr_type != FLOW_DISSECTOR_KEY_IPV4_ADDRS)
136172
return -EOPNOTSUPP;
173+
174+
/* These fields are already verified as used. */
175+
mask_ipv4 =
176+
skb_flow_dissector_target(flow->dissector,
177+
FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS,
178+
flow->mask);
179+
if (mask_ipv4->dst != cpu_to_be32(~0))
180+
return -EOPNOTSUPP;
181+
182+
mask_enc_ports =
183+
skb_flow_dissector_target(flow->dissector,
184+
FLOW_DISSECTOR_KEY_ENC_PORTS,
185+
flow->mask);
186+
enc_ports =
187+
skb_flow_dissector_target(flow->dissector,
188+
FLOW_DISSECTOR_KEY_ENC_PORTS,
189+
flow->key);
190+
191+
if (mask_enc_ports->dst != cpu_to_be16(~0) ||
192+
enc_ports->dst != htons(NFP_FL_VXLAN_PORT))
193+
return -EOPNOTSUPP;
194+
195+
key_layer |= NFP_FLOWER_LAYER_VXLAN;
196+
key_size += sizeof(struct nfp_flower_vxlan);
137197
}
138198

139199
if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_BASIC)) {
@@ -151,12 +211,6 @@ nfp_flower_calculate_key_layers(struct nfp_fl_key_ls *ret_key_ls,
151211
FLOW_DISSECTOR_KEY_IP,
152212
flow->mask);
153213

154-
key_layer_two = 0;
155-
key_layer = NFP_FLOWER_LAYER_PORT | NFP_FLOWER_LAYER_MAC;
156-
key_size = sizeof(struct nfp_flower_meta_one) +
157-
sizeof(struct nfp_flower_in_port) +
158-
sizeof(struct nfp_flower_mac_mpls);
159-
160214
if (mask_basic && mask_basic->n_proto) {
161215
/* Ethernet type is present in the key. */
162216
switch (key_basic->n_proto) {

0 commit comments

Comments
 (0)