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_two *frame,
42 			    struct tc_cls_flower_offload *flow, u8 key_type,
43 			    bool mask_version)
44 {
45 	struct flow_dissector_key_vlan *flow_vlan;
46 	u16 tmp_tci;
47 
48 	/* Populate the metadata frame. */
49 	frame->nfp_flow_key_layer = key_type;
50 	frame->mask_id = ~0;
51 
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;
70 	}
71 	frame->tci = cpu_to_be16(tmp_tci);
72 }
73 
74 static void
75 nfp_flower_compile_meta(struct nfp_flower_meta_one *frame, u8 key_type)
76 {
77 	frame->nfp_flow_key_layer = key_type;
78 	frame->mask_id = 0;
79 	frame->reserved = 0;
80 }
81 
82 static int
83 nfp_flower_compile_port(struct nfp_flower_in_port *frame, u32 cmsg_port,
84 			bool mask_version)
85 {
86 	if (mask_version) {
87 		frame->in_port = cpu_to_be32(~0);
88 		return 0;
89 	}
90 
91 	frame->in_port = cpu_to_be32(cmsg_port);
92 
93 	return 0;
94 }
95 
96 static void
97 nfp_flower_compile_mac(struct nfp_flower_mac_mpls *frame,
98 		       struct tc_cls_flower_offload *flow,
99 		       bool mask_version)
100 {
101 	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);
107 
108 	memset(frame, 0, sizeof(struct nfp_flower_mac_mpls));
109 
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]);
113 
114 	if (mask_version)
115 		frame->mpls_lse = cpu_to_be32(~0);
116 }
117 
118 static void
119 nfp_flower_compile_tport(struct nfp_flower_tp_ports *frame,
120 			 struct tc_cls_flower_offload *flow,
121 			 bool mask_version)
122 {
123 	struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
124 	struct flow_dissector_key_ports *flow_tp;
125 
126 	flow_tp = skb_flow_dissector_target(flow->dissector,
127 					    FLOW_DISSECTOR_KEY_PORTS,
128 					    target);
129 
130 	frame->port_src = flow_tp->src;
131 	frame->port_dst = flow_tp->dst;
132 }
133 
134 static void
135 nfp_flower_compile_ipv4(struct nfp_flower_ipv4 *frame,
136 			struct tc_cls_flower_offload *flow,
137 			bool mask_version)
138 {
139 	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);
150 
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;
156 	/* Wildcard TOS/TTL for now. */
157 	frame->tos = 0;
158 	frame->ttl = 0;
159 }
160 
161 static void
162 nfp_flower_compile_ipv6(struct nfp_flower_ipv6 *frame,
163 			struct tc_cls_flower_offload *flow,
164 			bool mask_version)
165 {
166 	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);
173 
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;
183 	/* Wildcard LABEL/TOS/TTL for now. */
184 	frame->ipv6_flow_label_exthdr = 0;
185 	frame->tos = 0;
186 	frame->ttl = 0;
187 }
188 
189 int nfp_flower_compile_flow_match(struct tc_cls_flower_offload *flow,
190 				  struct nfp_fl_key_ls *key_ls,
191 				  struct net_device *netdev,
192 				  struct nfp_fl_payload *nfp_flow)
193 {
194 	int err;
195 	u8 *ext;
196 	u8 *msk;
197 
198 	memset(nfp_flow->unmasked_data, 0, key_ls->key_size);
199 	memset(nfp_flow->mask_data, 0, key_ls->key_size);
200 
201 	ext = nfp_flow->unmasked_data;
202 	msk = nfp_flow->mask_data;
203 	if (NFP_FLOWER_LAYER_PORT & key_ls->key_layer) {
204 		/* Populate Exact Metadata. */
205 		nfp_flower_compile_meta_tci((struct nfp_flower_meta_two *)ext,
206 					    flow, key_ls->key_layer, false);
207 		/* Populate Mask Metadata. */
208 		nfp_flower_compile_meta_tci((struct nfp_flower_meta_two *)msk,
209 					    flow, key_ls->key_layer, true);
210 		ext += sizeof(struct nfp_flower_meta_two);
211 		msk += sizeof(struct nfp_flower_meta_two);
212 
213 		/* Populate Exact Port data. */
214 		err = nfp_flower_compile_port((struct nfp_flower_in_port *)ext,
215 					      nfp_repr_get_port_id(netdev),
216 					      false);
217 		if (err)
218 			return err;
219 
220 		/* Populate Mask Port Data. */
221 		err = nfp_flower_compile_port((struct nfp_flower_in_port *)msk,
222 					      nfp_repr_get_port_id(netdev),
223 					      true);
224 		if (err)
225 			return err;
226 
227 		ext += sizeof(struct nfp_flower_in_port);
228 		msk += sizeof(struct nfp_flower_in_port);
229 	} else {
230 		/* Populate Exact Metadata. */
231 		nfp_flower_compile_meta((struct nfp_flower_meta_one *)ext,
232 					key_ls->key_layer);
233 		/* Populate Mask Metadata. */
234 		nfp_flower_compile_meta((struct nfp_flower_meta_one *)msk,
235 					key_ls->key_layer);
236 		ext += sizeof(struct nfp_flower_meta_one);
237 		msk += sizeof(struct nfp_flower_meta_one);
238 	}
239 
240 	if (NFP_FLOWER_LAYER_META & key_ls->key_layer) {
241 		/* Additional Metadata Fields.
242 		 * Currently unsupported.
243 		 */
244 		return -EOPNOTSUPP;
245 	}
246 
247 	if (NFP_FLOWER_LAYER_MAC & key_ls->key_layer) {
248 		/* Populate Exact MAC Data. */
249 		nfp_flower_compile_mac((struct nfp_flower_mac_mpls *)ext,
250 				       flow, false);
251 		/* Populate Mask MAC Data. */
252 		nfp_flower_compile_mac((struct nfp_flower_mac_mpls *)msk,
253 				       flow, true);
254 		ext += sizeof(struct nfp_flower_mac_mpls);
255 		msk += sizeof(struct nfp_flower_mac_mpls);
256 	}
257 
258 	if (NFP_FLOWER_LAYER_TP & key_ls->key_layer) {
259 		/* Populate Exact TP Data. */
260 		nfp_flower_compile_tport((struct nfp_flower_tp_ports *)ext,
261 					 flow, false);
262 		/* Populate Mask TP Data. */
263 		nfp_flower_compile_tport((struct nfp_flower_tp_ports *)msk,
264 					 flow, true);
265 		ext += sizeof(struct nfp_flower_tp_ports);
266 		msk += sizeof(struct nfp_flower_tp_ports);
267 	}
268 
269 	if (NFP_FLOWER_LAYER_IPV4 & key_ls->key_layer) {
270 		/* Populate Exact IPv4 Data. */
271 		nfp_flower_compile_ipv4((struct nfp_flower_ipv4 *)ext,
272 					flow, false);
273 		/* Populate Mask IPv4 Data. */
274 		nfp_flower_compile_ipv4((struct nfp_flower_ipv4 *)msk,
275 					flow, true);
276 		ext += sizeof(struct nfp_flower_ipv4);
277 		msk += sizeof(struct nfp_flower_ipv4);
278 	}
279 
280 	if (NFP_FLOWER_LAYER_IPV6 & key_ls->key_layer) {
281 		/* Populate Exact IPv4 Data. */
282 		nfp_flower_compile_ipv6((struct nfp_flower_ipv6 *)ext,
283 					flow, false);
284 		/* Populate Mask IPv4 Data. */
285 		nfp_flower_compile_ipv6((struct nfp_flower_ipv6 *)msk,
286 					flow, true);
287 		ext += sizeof(struct nfp_flower_ipv6);
288 		msk += sizeof(struct nfp_flower_ipv6);
289 	}
290 
291 	return 0;
292 }
293