xref: /linux/drivers/net/ethernet/netronome/nfp/flower/match.c (revision 23202e099555e73339cd5ef1069ccdb995a733ca)
1 /*
2  * Copyright (C) 2017 Netronome Systems, Inc.
3  *
4  * This software is dual licensed under the GNU General License Version 2,
5  * June 1991 as shown in the file COPYING in the top-level directory of this
6  * source tree or the BSD 2-Clause License provided below.  You have the
7  * option to license this software under the complete terms of either license.
8  *
9  * The BSD 2-Clause License:
10  *
11  *     Redistribution and use in source and binary forms, with or
12  *     without modification, are permitted provided that the following
13  *     conditions are met:
14  *
15  *      1. Redistributions of source code must retain the above
16  *         copyright notice, this list of conditions and the following
17  *         disclaimer.
18  *
19  *      2. Redistributions in binary form must reproduce the above
20  *         copyright notice, this list of conditions and the following
21  *         disclaimer in the documentation and/or other materials
22  *         provided with the distribution.
23  *
24  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31  * SOFTWARE.
32  */
33 
34 #include <linux/bitfield.h>
35 #include <net/pkt_cls.h>
36 
37 #include "cmsg.h"
38 #include "main.h"
39 
40 static void
41 nfp_flower_compile_meta_tci(struct nfp_flower_meta_tci *frame,
42 			    struct tc_cls_flower_offload *flow, u8 key_type,
43 			    bool mask_version)
44 {
45 	struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
46 	struct flow_dissector_key_vlan *flow_vlan;
47 	u16 tmp_tci;
48 
49 	memset(frame, 0, sizeof(struct nfp_flower_meta_tci));
50 	/* Populate the metadata frame. */
51 	frame->nfp_flow_key_layer = key_type;
52 	frame->mask_id = ~0;
53 
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 		}
67 	}
68 }
69 
70 static int
71 nfp_flower_compile_port(struct nfp_flower_in_port *frame, u32 cmsg_port,
72 			bool mask_version, enum nfp_flower_tun_type tun_type)
73 {
74 	if (mask_version) {
75 		frame->in_port = cpu_to_be32(~0);
76 		return 0;
77 	}
78 
79 	if (tun_type)
80 		frame->in_port = cpu_to_be32(NFP_FL_PORT_TYPE_TUN | tun_type);
81 	else
82 		frame->in_port = cpu_to_be32(cmsg_port);
83 
84 	return 0;
85 }
86 
87 static void
88 nfp_flower_compile_mac(struct nfp_flower_mac_mpls *frame,
89 		       struct tc_cls_flower_offload *flow,
90 		       bool mask_version)
91 {
92 	struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
93 	struct flow_dissector_key_eth_addrs *addr;
94 
95 	memset(frame, 0, sizeof(struct nfp_flower_mac_mpls));
96 
97 	if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
98 		addr = skb_flow_dissector_target(flow->dissector,
99 						 FLOW_DISSECTOR_KEY_ETH_ADDRS,
100 						 target);
101 		/* Populate mac frame. */
102 		ether_addr_copy(frame->mac_dst, &addr->dst[0]);
103 		ether_addr_copy(frame->mac_src, &addr->src[0]);
104 	}
105 
106 	if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_MPLS)) {
107 		struct flow_dissector_key_mpls *mpls;
108 		u32 t_mpls;
109 
110 		mpls = skb_flow_dissector_target(flow->dissector,
111 						 FLOW_DISSECTOR_KEY_MPLS,
112 						 target);
113 
114 		t_mpls = FIELD_PREP(NFP_FLOWER_MASK_MPLS_LB, mpls->mpls_label) |
115 			 FIELD_PREP(NFP_FLOWER_MASK_MPLS_TC, mpls->mpls_tc) |
116 			 FIELD_PREP(NFP_FLOWER_MASK_MPLS_BOS, mpls->mpls_bos) |
117 			 NFP_FLOWER_MASK_MPLS_Q;
118 
119 		frame->mpls_lse = cpu_to_be32(t_mpls);
120 	}
121 }
122 
123 static void
124 nfp_flower_compile_tport(struct nfp_flower_tp_ports *frame,
125 			 struct tc_cls_flower_offload *flow,
126 			 bool mask_version)
127 {
128 	struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
129 	struct flow_dissector_key_ports *tp;
130 
131 	memset(frame, 0, sizeof(struct nfp_flower_tp_ports));
132 
133 	if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_PORTS)) {
134 		tp = skb_flow_dissector_target(flow->dissector,
135 					       FLOW_DISSECTOR_KEY_PORTS,
136 					       target);
137 		frame->port_src = tp->src;
138 		frame->port_dst = tp->dst;
139 	}
140 }
141 
142 static void
143 nfp_flower_compile_ipv4(struct nfp_flower_ipv4 *frame,
144 			struct tc_cls_flower_offload *flow,
145 			bool mask_version)
146 {
147 	struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
148 	struct flow_dissector_key_ipv4_addrs *addr;
149 	struct flow_dissector_key_basic *basic;
150 
151 	memset(frame, 0, sizeof(struct nfp_flower_ipv4));
152 
153 	if (dissector_uses_key(flow->dissector,
154 			       FLOW_DISSECTOR_KEY_IPV4_ADDRS)) {
155 		addr = skb_flow_dissector_target(flow->dissector,
156 						 FLOW_DISSECTOR_KEY_IPV4_ADDRS,
157 						 target);
158 		frame->ipv4_src = addr->src;
159 		frame->ipv4_dst = addr->dst;
160 	}
161 
162 	if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_BASIC)) {
163 		basic = skb_flow_dissector_target(flow->dissector,
164 						  FLOW_DISSECTOR_KEY_BASIC,
165 						  target);
166 		frame->proto = basic->ip_proto;
167 	}
168 
169 	if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_IP)) {
170 		struct flow_dissector_key_ip *flow_ip;
171 
172 		flow_ip = skb_flow_dissector_target(flow->dissector,
173 						    FLOW_DISSECTOR_KEY_IP,
174 						    target);
175 		frame->tos = flow_ip->tos;
176 		frame->ttl = flow_ip->ttl;
177 	}
178 }
179 
180 static void
181 nfp_flower_compile_ipv6(struct nfp_flower_ipv6 *frame,
182 			struct tc_cls_flower_offload *flow,
183 			bool mask_version)
184 {
185 	struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
186 	struct flow_dissector_key_ipv6_addrs *addr;
187 	struct flow_dissector_key_basic *basic;
188 
189 	memset(frame, 0, sizeof(struct nfp_flower_ipv6));
190 
191 	if (dissector_uses_key(flow->dissector,
192 			       FLOW_DISSECTOR_KEY_IPV6_ADDRS)) {
193 		addr = skb_flow_dissector_target(flow->dissector,
194 						 FLOW_DISSECTOR_KEY_IPV6_ADDRS,
195 						 target);
196 		frame->ipv6_src = addr->src;
197 		frame->ipv6_dst = addr->dst;
198 	}
199 
200 	if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_BASIC)) {
201 		basic = skb_flow_dissector_target(flow->dissector,
202 						  FLOW_DISSECTOR_KEY_BASIC,
203 						  target);
204 		frame->proto = basic->ip_proto;
205 	}
206 
207 	if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_IP)) {
208 		struct flow_dissector_key_ip *flow_ip;
209 
210 		flow_ip = skb_flow_dissector_target(flow->dissector,
211 						    FLOW_DISSECTOR_KEY_IP,
212 						    target);
213 		frame->tos = flow_ip->tos;
214 		frame->ttl = flow_ip->ttl;
215 	}
216 }
217 
218 static void
219 nfp_flower_compile_vxlan(struct nfp_flower_vxlan *frame,
220 			 struct tc_cls_flower_offload *flow,
221 			 bool mask_version, __be32 *tun_dst)
222 {
223 	struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
224 	struct flow_dissector_key_ipv4_addrs *vxlan_ips;
225 	struct flow_dissector_key_keyid *vni;
226 
227 	/* Wildcard TOS/TTL/GPE_FLAGS/NXT_PROTO for now. */
228 	memset(frame, 0, sizeof(struct nfp_flower_vxlan));
229 
230 	if (dissector_uses_key(flow->dissector,
231 			       FLOW_DISSECTOR_KEY_ENC_KEYID)) {
232 		u32 temp_vni;
233 
234 		vni = skb_flow_dissector_target(flow->dissector,
235 						FLOW_DISSECTOR_KEY_ENC_KEYID,
236 						target);
237 		temp_vni = be32_to_cpu(vni->keyid) << NFP_FL_TUN_VNI_OFFSET;
238 		frame->tun_id = cpu_to_be32(temp_vni);
239 	}
240 
241 	if (dissector_uses_key(flow->dissector,
242 			       FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS)) {
243 		vxlan_ips =
244 		   skb_flow_dissector_target(flow->dissector,
245 					     FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS,
246 					     target);
247 		frame->ip_src = vxlan_ips->src;
248 		frame->ip_dst = vxlan_ips->dst;
249 		*tun_dst = vxlan_ips->dst;
250 	}
251 }
252 
253 int nfp_flower_compile_flow_match(struct tc_cls_flower_offload *flow,
254 				  struct nfp_fl_key_ls *key_ls,
255 				  struct net_device *netdev,
256 				  struct nfp_fl_payload *nfp_flow)
257 {
258 	enum nfp_flower_tun_type tun_type = NFP_FL_TUNNEL_NONE;
259 	__be32 tun_dst, tun_dst_mask = 0;
260 	struct nfp_repr *netdev_repr;
261 	int err;
262 	u8 *ext;
263 	u8 *msk;
264 
265 	if (key_ls->key_layer & NFP_FLOWER_LAYER_VXLAN)
266 		tun_type = NFP_FL_TUNNEL_VXLAN;
267 
268 	memset(nfp_flow->unmasked_data, 0, key_ls->key_size);
269 	memset(nfp_flow->mask_data, 0, key_ls->key_size);
270 
271 	ext = nfp_flow->unmasked_data;
272 	msk = nfp_flow->mask_data;
273 
274 	/* Populate Exact Metadata. */
275 	nfp_flower_compile_meta_tci((struct nfp_flower_meta_tci *)ext,
276 				    flow, key_ls->key_layer, false);
277 	/* Populate Mask Metadata. */
278 	nfp_flower_compile_meta_tci((struct nfp_flower_meta_tci *)msk,
279 				    flow, key_ls->key_layer, true);
280 	ext += sizeof(struct nfp_flower_meta_tci);
281 	msk += sizeof(struct nfp_flower_meta_tci);
282 
283 	/* Populate Exact Port data. */
284 	err = nfp_flower_compile_port((struct nfp_flower_in_port *)ext,
285 				      nfp_repr_get_port_id(netdev),
286 				      false, tun_type);
287 	if (err)
288 		return err;
289 
290 	/* Populate Mask Port Data. */
291 	err = nfp_flower_compile_port((struct nfp_flower_in_port *)msk,
292 				      nfp_repr_get_port_id(netdev),
293 				      true, tun_type);
294 	if (err)
295 		return err;
296 
297 	ext += sizeof(struct nfp_flower_in_port);
298 	msk += sizeof(struct nfp_flower_in_port);
299 
300 	if (NFP_FLOWER_LAYER_MAC & key_ls->key_layer) {
301 		/* Populate Exact MAC Data. */
302 		nfp_flower_compile_mac((struct nfp_flower_mac_mpls *)ext,
303 				       flow, false);
304 		/* Populate Mask MAC Data. */
305 		nfp_flower_compile_mac((struct nfp_flower_mac_mpls *)msk,
306 				       flow, true);
307 		ext += sizeof(struct nfp_flower_mac_mpls);
308 		msk += sizeof(struct nfp_flower_mac_mpls);
309 	}
310 
311 	if (NFP_FLOWER_LAYER_TP & key_ls->key_layer) {
312 		/* Populate Exact TP Data. */
313 		nfp_flower_compile_tport((struct nfp_flower_tp_ports *)ext,
314 					 flow, false);
315 		/* Populate Mask TP Data. */
316 		nfp_flower_compile_tport((struct nfp_flower_tp_ports *)msk,
317 					 flow, true);
318 		ext += sizeof(struct nfp_flower_tp_ports);
319 		msk += sizeof(struct nfp_flower_tp_ports);
320 	}
321 
322 	if (NFP_FLOWER_LAYER_IPV4 & key_ls->key_layer) {
323 		/* Populate Exact IPv4 Data. */
324 		nfp_flower_compile_ipv4((struct nfp_flower_ipv4 *)ext,
325 					flow, false);
326 		/* Populate Mask IPv4 Data. */
327 		nfp_flower_compile_ipv4((struct nfp_flower_ipv4 *)msk,
328 					flow, true);
329 		ext += sizeof(struct nfp_flower_ipv4);
330 		msk += sizeof(struct nfp_flower_ipv4);
331 	}
332 
333 	if (NFP_FLOWER_LAYER_IPV6 & key_ls->key_layer) {
334 		/* Populate Exact IPv4 Data. */
335 		nfp_flower_compile_ipv6((struct nfp_flower_ipv6 *)ext,
336 					flow, false);
337 		/* Populate Mask IPv4 Data. */
338 		nfp_flower_compile_ipv6((struct nfp_flower_ipv6 *)msk,
339 					flow, true);
340 		ext += sizeof(struct nfp_flower_ipv6);
341 		msk += sizeof(struct nfp_flower_ipv6);
342 	}
343 
344 	if (key_ls->key_layer & NFP_FLOWER_LAYER_VXLAN) {
345 		/* Populate Exact VXLAN Data. */
346 		nfp_flower_compile_vxlan((struct nfp_flower_vxlan *)ext,
347 					 flow, false, &tun_dst);
348 		/* Populate Mask VXLAN Data. */
349 		nfp_flower_compile_vxlan((struct nfp_flower_vxlan *)msk,
350 					 flow, true, &tun_dst_mask);
351 		ext += sizeof(struct nfp_flower_vxlan);
352 		msk += sizeof(struct nfp_flower_vxlan);
353 
354 		/* Configure tunnel end point MAC. */
355 		if (nfp_netdev_is_nfp_repr(netdev)) {
356 			netdev_repr = netdev_priv(netdev);
357 			nfp_tunnel_write_macs(netdev_repr->app);
358 
359 			/* Store the tunnel destination in the rule data.
360 			 * This must be present and be an exact match.
361 			 */
362 			nfp_flow->nfp_tun_ipv4_addr = tun_dst;
363 			nfp_tunnel_add_ipv4_off(netdev_repr->app, tun_dst);
364 		}
365 	}
366 
367 	return 0;
368 }
369