1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2 /* Copyright (C) 2017-2018 Netronome Systems, Inc. */
3 
4 #include <linux/etherdevice.h>
5 #include <linux/inetdevice.h>
6 #include <net/netevent.h>
7 #include <linux/idr.h>
8 #include <net/dst_metadata.h>
9 #include <net/arp.h>
10 
11 #include "cmsg.h"
12 #include "main.h"
13 #include "../nfp_net_repr.h"
14 #include "../nfp_net.h"
15 
16 #define NFP_FL_MAX_ROUTES               32
17 
18 #define NFP_TUN_PRE_TUN_RULE_LIMIT	32
19 #define NFP_TUN_PRE_TUN_RULE_DEL	BIT(0)
20 #define NFP_TUN_PRE_TUN_IDX_BIT		BIT(3)
21 #define NFP_TUN_PRE_TUN_IPV6_BIT	BIT(7)
22 
23 /**
24  * struct nfp_tun_pre_tun_rule - rule matched before decap
25  * @flags:		options for the rule offset
26  * @port_idx:		index of destination MAC address for the rule
27  * @vlan_tci:		VLAN info associated with MAC
28  * @host_ctx_id:	stats context of rule to update
29  */
30 struct nfp_tun_pre_tun_rule {
31 	__be32 flags;
32 	__be16 port_idx;
33 	__be16 vlan_tci;
34 	__be32 host_ctx_id;
35 };
36 
37 /**
38  * struct nfp_tun_active_tuns - periodic message of active tunnels
39  * @seq:		sequence number of the message
40  * @count:		number of tunnels report in message
41  * @flags:		options part of the request
42  * @tun_info.ipv4:		dest IPv4 address of active route
43  * @tun_info.egress_port:	port the encapsulated packet egressed
44  * @tun_info.extra:		reserved for future use
45  * @tun_info:		tunnels that have sent traffic in reported period
46  */
47 struct nfp_tun_active_tuns {
48 	__be32 seq;
49 	__be32 count;
50 	__be32 flags;
51 	struct route_ip_info {
52 		__be32 ipv4;
53 		__be32 egress_port;
54 		__be32 extra[2];
55 	} tun_info[];
56 };
57 
58 /**
59  * struct nfp_tun_active_tuns_v6 - periodic message of active IPv6 tunnels
60  * @seq:		sequence number of the message
61  * @count:		number of tunnels report in message
62  * @flags:		options part of the request
63  * @tun_info.ipv6:		dest IPv6 address of active route
64  * @tun_info.egress_port:	port the encapsulated packet egressed
65  * @tun_info.extra:		reserved for future use
66  * @tun_info:		tunnels that have sent traffic in reported period
67  */
68 struct nfp_tun_active_tuns_v6 {
69 	__be32 seq;
70 	__be32 count;
71 	__be32 flags;
72 	struct route_ip_info_v6 {
73 		struct in6_addr ipv6;
74 		__be32 egress_port;
75 		__be32 extra[2];
76 	} tun_info[];
77 };
78 
79 /**
80  * struct nfp_tun_req_route_ipv4 - NFP requests a route/neighbour lookup
81  * @ingress_port:	ingress port of packet that signalled request
82  * @ipv4_addr:		destination ipv4 address for route
83  * @reserved:		reserved for future use
84  */
85 struct nfp_tun_req_route_ipv4 {
86 	__be32 ingress_port;
87 	__be32 ipv4_addr;
88 	__be32 reserved[2];
89 };
90 
91 /**
92  * struct nfp_tun_req_route_ipv6 - NFP requests an IPv6 route/neighbour lookup
93  * @ingress_port:	ingress port of packet that signalled request
94  * @ipv6_addr:		destination ipv6 address for route
95  */
96 struct nfp_tun_req_route_ipv6 {
97 	__be32 ingress_port;
98 	struct in6_addr ipv6_addr;
99 };
100 
101 /**
102  * struct nfp_offloaded_route - routes that are offloaded to the NFP
103  * @list:	list pointer
104  * @ip_add:	destination of route - can be IPv4 or IPv6
105  */
106 struct nfp_offloaded_route {
107 	struct list_head list;
108 	u8 ip_add[];
109 };
110 
111 #define NFP_FL_IPV4_ADDRS_MAX        32
112 
113 /**
114  * struct nfp_tun_ipv4_addr - set the IP address list on the NFP
115  * @count:	number of IPs populated in the array
116  * @ipv4_addr:	array of IPV4_ADDRS_MAX 32 bit IPv4 addresses
117  */
118 struct nfp_tun_ipv4_addr {
119 	__be32 count;
120 	__be32 ipv4_addr[NFP_FL_IPV4_ADDRS_MAX];
121 };
122 
123 /**
124  * struct nfp_ipv4_addr_entry - cached IPv4 addresses
125  * @ipv4_addr:	IP address
126  * @ref_count:	number of rules currently using this IP
127  * @list:	list pointer
128  */
129 struct nfp_ipv4_addr_entry {
130 	__be32 ipv4_addr;
131 	int ref_count;
132 	struct list_head list;
133 };
134 
135 #define NFP_FL_IPV6_ADDRS_MAX        4
136 
137 /**
138  * struct nfp_tun_ipv6_addr - set the IP address list on the NFP
139  * @count:	number of IPs populated in the array
140  * @ipv6_addr:	array of IPV6_ADDRS_MAX 128 bit IPv6 addresses
141  */
142 struct nfp_tun_ipv6_addr {
143 	__be32 count;
144 	struct in6_addr ipv6_addr[NFP_FL_IPV6_ADDRS_MAX];
145 };
146 
147 #define NFP_TUN_MAC_OFFLOAD_DEL_FLAG	0x2
148 
149 /**
150  * struct nfp_tun_mac_addr_offload - configure MAC address of tunnel EP on NFP
151  * @flags:	MAC address offload options
152  * @count:	number of MAC addresses in the message (should be 1)
153  * @index:	index of MAC address in the lookup table
154  * @addr:	interface MAC address
155  */
156 struct nfp_tun_mac_addr_offload {
157 	__be16 flags;
158 	__be16 count;
159 	__be16 index;
160 	u8 addr[ETH_ALEN];
161 };
162 
163 enum nfp_flower_mac_offload_cmd {
164 	NFP_TUNNEL_MAC_OFFLOAD_ADD =		0,
165 	NFP_TUNNEL_MAC_OFFLOAD_DEL =		1,
166 	NFP_TUNNEL_MAC_OFFLOAD_MOD =		2,
167 };
168 
169 #define NFP_MAX_MAC_INDEX       0xff
170 
171 /**
172  * struct nfp_tun_offloaded_mac - hashtable entry for an offloaded MAC
173  * @ht_node:		Hashtable entry
174  * @addr:		Offloaded MAC address
175  * @index:		Offloaded index for given MAC address
176  * @ref_count:		Number of devs using this MAC address
177  * @repr_list:		List of reprs sharing this MAC address
178  * @bridge_count:	Number of bridge/internal devs with MAC
179  */
180 struct nfp_tun_offloaded_mac {
181 	struct rhash_head ht_node;
182 	u8 addr[ETH_ALEN];
183 	u16 index;
184 	int ref_count;
185 	struct list_head repr_list;
186 	int bridge_count;
187 };
188 
189 static const struct rhashtable_params offloaded_macs_params = {
190 	.key_offset	= offsetof(struct nfp_tun_offloaded_mac, addr),
191 	.head_offset	= offsetof(struct nfp_tun_offloaded_mac, ht_node),
192 	.key_len	= ETH_ALEN,
193 	.automatic_shrinking	= true,
194 };
195 
196 void nfp_tunnel_keep_alive(struct nfp_app *app, struct sk_buff *skb)
197 {
198 	struct nfp_tun_active_tuns *payload;
199 	struct net_device *netdev;
200 	int count, i, pay_len;
201 	struct neighbour *n;
202 	__be32 ipv4_addr;
203 	u32 port;
204 
205 	payload = nfp_flower_cmsg_get_data(skb);
206 	count = be32_to_cpu(payload->count);
207 	if (count > NFP_FL_MAX_ROUTES) {
208 		nfp_flower_cmsg_warn(app, "Tunnel keep-alive request exceeds max routes.\n");
209 		return;
210 	}
211 
212 	pay_len = nfp_flower_cmsg_get_data_len(skb);
213 	if (pay_len != struct_size(payload, tun_info, count)) {
214 		nfp_flower_cmsg_warn(app, "Corruption in tunnel keep-alive message.\n");
215 		return;
216 	}
217 
218 	rcu_read_lock();
219 	for (i = 0; i < count; i++) {
220 		ipv4_addr = payload->tun_info[i].ipv4;
221 		port = be32_to_cpu(payload->tun_info[i].egress_port);
222 		netdev = nfp_app_dev_get(app, port, NULL);
223 		if (!netdev)
224 			continue;
225 
226 		n = neigh_lookup(&arp_tbl, &ipv4_addr, netdev);
227 		if (!n)
228 			continue;
229 
230 		/* Update the used timestamp of neighbour */
231 		neigh_event_send(n, NULL);
232 		neigh_release(n);
233 	}
234 	rcu_read_unlock();
235 }
236 
237 void nfp_tunnel_keep_alive_v6(struct nfp_app *app, struct sk_buff *skb)
238 {
239 #if IS_ENABLED(CONFIG_IPV6)
240 	struct nfp_tun_active_tuns_v6 *payload;
241 	struct net_device *netdev;
242 	int count, i, pay_len;
243 	struct neighbour *n;
244 	void *ipv6_add;
245 	u32 port;
246 
247 	payload = nfp_flower_cmsg_get_data(skb);
248 	count = be32_to_cpu(payload->count);
249 	if (count > NFP_FL_IPV6_ADDRS_MAX) {
250 		nfp_flower_cmsg_warn(app, "IPv6 tunnel keep-alive request exceeds max routes.\n");
251 		return;
252 	}
253 
254 	pay_len = nfp_flower_cmsg_get_data_len(skb);
255 	if (pay_len != struct_size(payload, tun_info, count)) {
256 		nfp_flower_cmsg_warn(app, "Corruption in tunnel keep-alive message.\n");
257 		return;
258 	}
259 
260 	rcu_read_lock();
261 	for (i = 0; i < count; i++) {
262 		ipv6_add = &payload->tun_info[i].ipv6;
263 		port = be32_to_cpu(payload->tun_info[i].egress_port);
264 		netdev = nfp_app_dev_get(app, port, NULL);
265 		if (!netdev)
266 			continue;
267 
268 		n = neigh_lookup(&nd_tbl, ipv6_add, netdev);
269 		if (!n)
270 			continue;
271 
272 		/* Update the used timestamp of neighbour */
273 		neigh_event_send(n, NULL);
274 		neigh_release(n);
275 	}
276 	rcu_read_unlock();
277 #endif
278 }
279 
280 static int
281 nfp_flower_xmit_tun_conf(struct nfp_app *app, u8 mtype, u16 plen, void *pdata,
282 			 gfp_t flag)
283 {
284 	struct nfp_flower_priv *priv = app->priv;
285 	struct sk_buff *skb;
286 	unsigned char *msg;
287 
288 	if (!(priv->flower_ext_feats & NFP_FL_FEATS_DECAP_V2) &&
289 	    (mtype == NFP_FLOWER_CMSG_TYPE_TUN_NEIGH ||
290 	     mtype == NFP_FLOWER_CMSG_TYPE_TUN_NEIGH_V6))
291 		plen -= sizeof(struct nfp_tun_neigh_ext);
292 
293 	if (!(priv->flower_ext_feats & NFP_FL_FEATS_TUNNEL_NEIGH_LAG) &&
294 	    (mtype == NFP_FLOWER_CMSG_TYPE_TUN_NEIGH ||
295 	     mtype == NFP_FLOWER_CMSG_TYPE_TUN_NEIGH_V6))
296 		plen -= sizeof(struct nfp_tun_neigh_lag);
297 
298 	skb = nfp_flower_cmsg_alloc(app, plen, mtype, flag);
299 	if (!skb)
300 		return -ENOMEM;
301 
302 	msg = nfp_flower_cmsg_get_data(skb);
303 	memcpy(msg, pdata, nfp_flower_cmsg_get_data_len(skb));
304 
305 	nfp_ctrl_tx(app->ctrl, skb);
306 	return 0;
307 }
308 
309 static void
310 nfp_tun_mutual_link(struct nfp_predt_entry *predt,
311 		    struct nfp_neigh_entry *neigh)
312 {
313 	struct nfp_fl_payload *flow_pay = predt->flow_pay;
314 	struct nfp_tun_neigh_ext *ext;
315 	struct nfp_tun_neigh *common;
316 
317 	if (flow_pay->pre_tun_rule.is_ipv6 != neigh->is_ipv6)
318 		return;
319 
320 	/* In the case of bonding it is possible that there might already
321 	 * be a flow linked (as the MAC address gets shared). If a flow
322 	 * is already linked just return.
323 	 */
324 	if (neigh->flow)
325 		return;
326 
327 	common = neigh->is_ipv6 ?
328 		 &((struct nfp_tun_neigh_v6 *)neigh->payload)->common :
329 		 &((struct nfp_tun_neigh_v4 *)neigh->payload)->common;
330 	ext = neigh->is_ipv6 ?
331 		 &((struct nfp_tun_neigh_v6 *)neigh->payload)->ext :
332 		 &((struct nfp_tun_neigh_v4 *)neigh->payload)->ext;
333 
334 	if (memcmp(flow_pay->pre_tun_rule.loc_mac,
335 		   common->src_addr, ETH_ALEN) ||
336 	    memcmp(flow_pay->pre_tun_rule.rem_mac,
337 		   common->dst_addr, ETH_ALEN))
338 		return;
339 
340 	list_add(&neigh->list_head, &predt->nn_list);
341 	neigh->flow = predt;
342 	ext->host_ctx = flow_pay->meta.host_ctx_id;
343 	ext->vlan_tci = flow_pay->pre_tun_rule.vlan_tci;
344 	ext->vlan_tpid = flow_pay->pre_tun_rule.vlan_tpid;
345 }
346 
347 static void
348 nfp_tun_link_predt_entries(struct nfp_app *app,
349 			   struct nfp_neigh_entry *nn_entry)
350 {
351 	struct nfp_flower_priv *priv = app->priv;
352 	struct nfp_predt_entry *predt, *tmp;
353 
354 	list_for_each_entry_safe(predt, tmp, &priv->predt_list, list_head) {
355 		nfp_tun_mutual_link(predt, nn_entry);
356 	}
357 }
358 
359 void nfp_tun_link_and_update_nn_entries(struct nfp_app *app,
360 					struct nfp_predt_entry *predt)
361 {
362 	struct nfp_flower_priv *priv = app->priv;
363 	struct nfp_neigh_entry *nn_entry;
364 	struct rhashtable_iter iter;
365 	size_t neigh_size;
366 	u8 type;
367 
368 	rhashtable_walk_enter(&priv->neigh_table, &iter);
369 	rhashtable_walk_start(&iter);
370 	while ((nn_entry = rhashtable_walk_next(&iter)) != NULL) {
371 		if (IS_ERR(nn_entry))
372 			continue;
373 		nfp_tun_mutual_link(predt, nn_entry);
374 		neigh_size = nn_entry->is_ipv6 ?
375 			     sizeof(struct nfp_tun_neigh_v6) :
376 			     sizeof(struct nfp_tun_neigh_v4);
377 		type = nn_entry->is_ipv6 ? NFP_FLOWER_CMSG_TYPE_TUN_NEIGH_V6 :
378 					   NFP_FLOWER_CMSG_TYPE_TUN_NEIGH;
379 		nfp_flower_xmit_tun_conf(app, type, neigh_size,
380 					 nn_entry->payload,
381 					 GFP_ATOMIC);
382 	}
383 	rhashtable_walk_stop(&iter);
384 	rhashtable_walk_exit(&iter);
385 }
386 
387 static void nfp_tun_cleanup_nn_entries(struct nfp_app *app)
388 {
389 	struct nfp_flower_priv *priv = app->priv;
390 	struct nfp_neigh_entry *neigh;
391 	struct nfp_tun_neigh_ext *ext;
392 	struct rhashtable_iter iter;
393 	size_t neigh_size;
394 	u8 type;
395 
396 	rhashtable_walk_enter(&priv->neigh_table, &iter);
397 	rhashtable_walk_start(&iter);
398 	while ((neigh = rhashtable_walk_next(&iter)) != NULL) {
399 		if (IS_ERR(neigh))
400 			continue;
401 		ext = neigh->is_ipv6 ?
402 			 &((struct nfp_tun_neigh_v6 *)neigh->payload)->ext :
403 			 &((struct nfp_tun_neigh_v4 *)neigh->payload)->ext;
404 		ext->host_ctx = cpu_to_be32(U32_MAX);
405 		ext->vlan_tpid = cpu_to_be16(U16_MAX);
406 		ext->vlan_tci = cpu_to_be16(U16_MAX);
407 
408 		neigh_size = neigh->is_ipv6 ?
409 			     sizeof(struct nfp_tun_neigh_v6) :
410 			     sizeof(struct nfp_tun_neigh_v4);
411 		type = neigh->is_ipv6 ? NFP_FLOWER_CMSG_TYPE_TUN_NEIGH_V6 :
412 					   NFP_FLOWER_CMSG_TYPE_TUN_NEIGH;
413 		nfp_flower_xmit_tun_conf(app, type, neigh_size, neigh->payload,
414 					 GFP_ATOMIC);
415 
416 		rhashtable_remove_fast(&priv->neigh_table, &neigh->ht_node,
417 				       neigh_table_params);
418 		if (neigh->flow)
419 			list_del(&neigh->list_head);
420 		kfree(neigh);
421 	}
422 	rhashtable_walk_stop(&iter);
423 	rhashtable_walk_exit(&iter);
424 }
425 
426 void nfp_tun_unlink_and_update_nn_entries(struct nfp_app *app,
427 					  struct nfp_predt_entry *predt)
428 {
429 	struct nfp_neigh_entry *neigh, *tmp;
430 	struct nfp_tun_neigh_ext *ext;
431 	size_t neigh_size;
432 	u8 type;
433 
434 	list_for_each_entry_safe(neigh, tmp, &predt->nn_list, list_head) {
435 		ext = neigh->is_ipv6 ?
436 			 &((struct nfp_tun_neigh_v6 *)neigh->payload)->ext :
437 			 &((struct nfp_tun_neigh_v4 *)neigh->payload)->ext;
438 		neigh->flow = NULL;
439 		ext->host_ctx = cpu_to_be32(U32_MAX);
440 		ext->vlan_tpid = cpu_to_be16(U16_MAX);
441 		ext->vlan_tci = cpu_to_be16(U16_MAX);
442 		list_del(&neigh->list_head);
443 		neigh_size = neigh->is_ipv6 ?
444 			     sizeof(struct nfp_tun_neigh_v6) :
445 			     sizeof(struct nfp_tun_neigh_v4);
446 		type = neigh->is_ipv6 ? NFP_FLOWER_CMSG_TYPE_TUN_NEIGH_V6 :
447 					   NFP_FLOWER_CMSG_TYPE_TUN_NEIGH;
448 		nfp_flower_xmit_tun_conf(app, type, neigh_size, neigh->payload,
449 					 GFP_ATOMIC);
450 	}
451 }
452 
453 static void
454 nfp_tun_write_neigh(struct net_device *netdev, struct nfp_app *app,
455 		    void *flow, struct neighbour *neigh, bool is_ipv6,
456 		    bool override)
457 {
458 	bool neigh_invalid = !(neigh->nud_state & NUD_VALID) || neigh->dead;
459 	size_t neigh_size = is_ipv6 ? sizeof(struct nfp_tun_neigh_v6) :
460 			    sizeof(struct nfp_tun_neigh_v4);
461 	unsigned long cookie = (unsigned long)neigh;
462 	struct nfp_flower_priv *priv = app->priv;
463 	struct nfp_tun_neigh_lag lag_info;
464 	struct nfp_neigh_entry *nn_entry;
465 	u32 port_id;
466 	u8 mtype;
467 
468 	port_id = nfp_flower_get_port_id_from_netdev(app, netdev);
469 	if (!port_id)
470 		return;
471 
472 	if ((port_id & NFP_FL_LAG_OUT) == NFP_FL_LAG_OUT) {
473 		memset(&lag_info, 0, sizeof(struct nfp_tun_neigh_lag));
474 		nfp_flower_lag_get_info_from_netdev(app, netdev, &lag_info);
475 	}
476 
477 	spin_lock_bh(&priv->predt_lock);
478 	nn_entry = rhashtable_lookup_fast(&priv->neigh_table, &cookie,
479 					  neigh_table_params);
480 	if (!nn_entry && !neigh_invalid) {
481 		struct nfp_tun_neigh_ext *ext;
482 		struct nfp_tun_neigh_lag *lag;
483 		struct nfp_tun_neigh *common;
484 
485 		nn_entry = kzalloc(sizeof(*nn_entry) + neigh_size,
486 				   GFP_ATOMIC);
487 		if (!nn_entry)
488 			goto err;
489 
490 		nn_entry->payload = (char *)&nn_entry[1];
491 		nn_entry->neigh_cookie = cookie;
492 		nn_entry->is_ipv6 = is_ipv6;
493 		nn_entry->flow = NULL;
494 		if (is_ipv6) {
495 			struct flowi6 *flowi6 = (struct flowi6 *)flow;
496 			struct nfp_tun_neigh_v6 *payload;
497 
498 			payload = (struct nfp_tun_neigh_v6 *)nn_entry->payload;
499 			payload->src_ipv6 = flowi6->saddr;
500 			payload->dst_ipv6 = flowi6->daddr;
501 			common = &payload->common;
502 			ext = &payload->ext;
503 			lag = &payload->lag;
504 			mtype = NFP_FLOWER_CMSG_TYPE_TUN_NEIGH_V6;
505 		} else {
506 			struct flowi4 *flowi4 = (struct flowi4 *)flow;
507 			struct nfp_tun_neigh_v4 *payload;
508 
509 			payload = (struct nfp_tun_neigh_v4 *)nn_entry->payload;
510 			payload->src_ipv4 = flowi4->saddr;
511 			payload->dst_ipv4 = flowi4->daddr;
512 			common = &payload->common;
513 			ext = &payload->ext;
514 			lag = &payload->lag;
515 			mtype = NFP_FLOWER_CMSG_TYPE_TUN_NEIGH;
516 		}
517 		ext->host_ctx = cpu_to_be32(U32_MAX);
518 		ext->vlan_tpid = cpu_to_be16(U16_MAX);
519 		ext->vlan_tci = cpu_to_be16(U16_MAX);
520 		ether_addr_copy(common->src_addr, netdev->dev_addr);
521 		neigh_ha_snapshot(common->dst_addr, neigh, netdev);
522 
523 		if ((port_id & NFP_FL_LAG_OUT) == NFP_FL_LAG_OUT)
524 			memcpy(lag, &lag_info, sizeof(struct nfp_tun_neigh_lag));
525 		common->port_id = cpu_to_be32(port_id);
526 
527 		if (rhashtable_insert_fast(&priv->neigh_table,
528 					   &nn_entry->ht_node,
529 					   neigh_table_params))
530 			goto err;
531 
532 		nfp_tun_link_predt_entries(app, nn_entry);
533 		nfp_flower_xmit_tun_conf(app, mtype, neigh_size,
534 					 nn_entry->payload,
535 					 GFP_ATOMIC);
536 	} else if (nn_entry && neigh_invalid) {
537 		if (is_ipv6) {
538 			struct flowi6 *flowi6 = (struct flowi6 *)flow;
539 			struct nfp_tun_neigh_v6 *payload;
540 
541 			payload = (struct nfp_tun_neigh_v6 *)nn_entry->payload;
542 			memset(payload, 0, sizeof(struct nfp_tun_neigh_v6));
543 			payload->dst_ipv6 = flowi6->daddr;
544 			mtype = NFP_FLOWER_CMSG_TYPE_TUN_NEIGH_V6;
545 		} else {
546 			struct flowi4 *flowi4 = (struct flowi4 *)flow;
547 			struct nfp_tun_neigh_v4 *payload;
548 
549 			payload = (struct nfp_tun_neigh_v4 *)nn_entry->payload;
550 			memset(payload, 0, sizeof(struct nfp_tun_neigh_v4));
551 			payload->dst_ipv4 = flowi4->daddr;
552 			mtype = NFP_FLOWER_CMSG_TYPE_TUN_NEIGH;
553 		}
554 		/* Trigger ARP to verify invalid neighbour state. */
555 		neigh_event_send(neigh, NULL);
556 		rhashtable_remove_fast(&priv->neigh_table,
557 				       &nn_entry->ht_node,
558 				       neigh_table_params);
559 
560 		nfp_flower_xmit_tun_conf(app, mtype, neigh_size,
561 					 nn_entry->payload,
562 					 GFP_ATOMIC);
563 
564 		if (nn_entry->flow)
565 			list_del(&nn_entry->list_head);
566 		kfree(nn_entry);
567 	} else if (nn_entry && !neigh_invalid) {
568 		struct nfp_tun_neigh *common;
569 		u8 dst_addr[ETH_ALEN];
570 		bool is_mac_change;
571 
572 		if (is_ipv6) {
573 			struct nfp_tun_neigh_v6 *payload;
574 
575 			payload = (struct nfp_tun_neigh_v6 *)nn_entry->payload;
576 			common = &payload->common;
577 			mtype = NFP_FLOWER_CMSG_TYPE_TUN_NEIGH_V6;
578 		} else {
579 			struct nfp_tun_neigh_v4 *payload;
580 
581 			payload = (struct nfp_tun_neigh_v4 *)nn_entry->payload;
582 			common = &payload->common;
583 			mtype = NFP_FLOWER_CMSG_TYPE_TUN_NEIGH;
584 		}
585 
586 		ether_addr_copy(dst_addr, common->dst_addr);
587 		neigh_ha_snapshot(common->dst_addr, neigh, netdev);
588 		is_mac_change = !ether_addr_equal(dst_addr, common->dst_addr);
589 		if (override || is_mac_change) {
590 			if (is_mac_change && nn_entry->flow) {
591 				list_del(&nn_entry->list_head);
592 				nn_entry->flow = NULL;
593 			}
594 			nfp_tun_link_predt_entries(app, nn_entry);
595 			nfp_flower_xmit_tun_conf(app, mtype, neigh_size,
596 						 nn_entry->payload,
597 						 GFP_ATOMIC);
598 		}
599 	}
600 
601 	spin_unlock_bh(&priv->predt_lock);
602 	return;
603 
604 err:
605 	kfree(nn_entry);
606 	spin_unlock_bh(&priv->predt_lock);
607 	nfp_flower_cmsg_warn(app, "Neighbour configuration failed.\n");
608 }
609 
610 static int
611 nfp_tun_neigh_event_handler(struct notifier_block *nb, unsigned long event,
612 			    void *ptr)
613 {
614 	struct nfp_flower_priv *app_priv;
615 	struct netevent_redirect *redir;
616 	struct neighbour *n;
617 	struct nfp_app *app;
618 	bool neigh_invalid;
619 	int err;
620 
621 	switch (event) {
622 	case NETEVENT_REDIRECT:
623 		redir = (struct netevent_redirect *)ptr;
624 		n = redir->neigh;
625 		break;
626 	case NETEVENT_NEIGH_UPDATE:
627 		n = (struct neighbour *)ptr;
628 		break;
629 	default:
630 		return NOTIFY_DONE;
631 	}
632 
633 	neigh_invalid = !(n->nud_state & NUD_VALID) || n->dead;
634 
635 	app_priv = container_of(nb, struct nfp_flower_priv, tun.neigh_nb);
636 	app = app_priv->app;
637 
638 	if (!nfp_flower_get_port_id_from_netdev(app, n->dev))
639 		return NOTIFY_DONE;
640 
641 #if IS_ENABLED(CONFIG_INET)
642 	if (n->tbl->family == AF_INET6) {
643 #if IS_ENABLED(CONFIG_IPV6)
644 		struct flowi6 flow6 = {};
645 
646 		flow6.daddr = *(struct in6_addr *)n->primary_key;
647 		if (!neigh_invalid) {
648 			struct dst_entry *dst;
649 			/* Use ipv6_dst_lookup_flow to populate flow6->saddr
650 			 * and other fields. This information is only needed
651 			 * for new entries, lookup can be skipped when an entry
652 			 * gets invalidated - as only the daddr is needed for
653 			 * deleting.
654 			 */
655 			dst = ip6_dst_lookup_flow(dev_net(n->dev), NULL,
656 						  &flow6, NULL);
657 			if (IS_ERR(dst))
658 				return NOTIFY_DONE;
659 
660 			dst_release(dst);
661 		}
662 		nfp_tun_write_neigh(n->dev, app, &flow6, n, true, false);
663 #else
664 		return NOTIFY_DONE;
665 #endif /* CONFIG_IPV6 */
666 	} else {
667 		struct flowi4 flow4 = {};
668 
669 		flow4.daddr = *(__be32 *)n->primary_key;
670 		if (!neigh_invalid) {
671 			struct rtable *rt;
672 			/* Use ip_route_output_key to populate flow4->saddr and
673 			 * other fields. This information is only needed for
674 			 * new entries, lookup can be skipped when an entry
675 			 * gets invalidated - as only the daddr is needed for
676 			 * deleting.
677 			 */
678 			rt = ip_route_output_key(dev_net(n->dev), &flow4);
679 			err = PTR_ERR_OR_ZERO(rt);
680 			if (err)
681 				return NOTIFY_DONE;
682 
683 			ip_rt_put(rt);
684 		}
685 		nfp_tun_write_neigh(n->dev, app, &flow4, n, false, false);
686 	}
687 #else
688 	return NOTIFY_DONE;
689 #endif /* CONFIG_INET */
690 
691 	return NOTIFY_OK;
692 }
693 
694 void nfp_tunnel_request_route_v4(struct nfp_app *app, struct sk_buff *skb)
695 {
696 	struct nfp_tun_req_route_ipv4 *payload;
697 	struct net_device *netdev;
698 	struct flowi4 flow = {};
699 	struct neighbour *n;
700 	struct rtable *rt;
701 	int err;
702 
703 	payload = nfp_flower_cmsg_get_data(skb);
704 
705 	rcu_read_lock();
706 	netdev = nfp_app_dev_get(app, be32_to_cpu(payload->ingress_port), NULL);
707 	if (!netdev)
708 		goto fail_rcu_unlock;
709 
710 	flow.daddr = payload->ipv4_addr;
711 	flow.flowi4_proto = IPPROTO_UDP;
712 
713 #if IS_ENABLED(CONFIG_INET)
714 	/* Do a route lookup on same namespace as ingress port. */
715 	rt = ip_route_output_key(dev_net(netdev), &flow);
716 	err = PTR_ERR_OR_ZERO(rt);
717 	if (err)
718 		goto fail_rcu_unlock;
719 #else
720 	goto fail_rcu_unlock;
721 #endif
722 
723 	/* Get the neighbour entry for the lookup */
724 	n = dst_neigh_lookup(&rt->dst, &flow.daddr);
725 	ip_rt_put(rt);
726 	if (!n)
727 		goto fail_rcu_unlock;
728 	nfp_tun_write_neigh(n->dev, app, &flow, n, false, true);
729 	neigh_release(n);
730 	rcu_read_unlock();
731 	return;
732 
733 fail_rcu_unlock:
734 	rcu_read_unlock();
735 	nfp_flower_cmsg_warn(app, "Requested route not found.\n");
736 }
737 
738 void nfp_tunnel_request_route_v6(struct nfp_app *app, struct sk_buff *skb)
739 {
740 	struct nfp_tun_req_route_ipv6 *payload;
741 	struct net_device *netdev;
742 	struct flowi6 flow = {};
743 	struct dst_entry *dst;
744 	struct neighbour *n;
745 
746 	payload = nfp_flower_cmsg_get_data(skb);
747 
748 	rcu_read_lock();
749 	netdev = nfp_app_dev_get(app, be32_to_cpu(payload->ingress_port), NULL);
750 	if (!netdev)
751 		goto fail_rcu_unlock;
752 
753 	flow.daddr = payload->ipv6_addr;
754 	flow.flowi6_proto = IPPROTO_UDP;
755 
756 #if IS_ENABLED(CONFIG_INET) && IS_ENABLED(CONFIG_IPV6)
757 	dst = ipv6_stub->ipv6_dst_lookup_flow(dev_net(netdev), NULL, &flow,
758 					      NULL);
759 	if (IS_ERR(dst))
760 		goto fail_rcu_unlock;
761 #else
762 	goto fail_rcu_unlock;
763 #endif
764 
765 	n = dst_neigh_lookup(dst, &flow.daddr);
766 	dst_release(dst);
767 	if (!n)
768 		goto fail_rcu_unlock;
769 
770 	nfp_tun_write_neigh(n->dev, app, &flow, n, true, true);
771 	neigh_release(n);
772 	rcu_read_unlock();
773 	return;
774 
775 fail_rcu_unlock:
776 	rcu_read_unlock();
777 	nfp_flower_cmsg_warn(app, "Requested IPv6 route not found.\n");
778 }
779 
780 static void nfp_tun_write_ipv4_list(struct nfp_app *app)
781 {
782 	struct nfp_flower_priv *priv = app->priv;
783 	struct nfp_ipv4_addr_entry *entry;
784 	struct nfp_tun_ipv4_addr payload;
785 	struct list_head *ptr, *storage;
786 	int count;
787 
788 	memset(&payload, 0, sizeof(struct nfp_tun_ipv4_addr));
789 	mutex_lock(&priv->tun.ipv4_off_lock);
790 	count = 0;
791 	list_for_each_safe(ptr, storage, &priv->tun.ipv4_off_list) {
792 		if (count >= NFP_FL_IPV4_ADDRS_MAX) {
793 			mutex_unlock(&priv->tun.ipv4_off_lock);
794 			nfp_flower_cmsg_warn(app, "IPv4 offload exceeds limit.\n");
795 			return;
796 		}
797 		entry = list_entry(ptr, struct nfp_ipv4_addr_entry, list);
798 		payload.ipv4_addr[count++] = entry->ipv4_addr;
799 	}
800 	payload.count = cpu_to_be32(count);
801 	mutex_unlock(&priv->tun.ipv4_off_lock);
802 
803 	nfp_flower_xmit_tun_conf(app, NFP_FLOWER_CMSG_TYPE_TUN_IPS,
804 				 sizeof(struct nfp_tun_ipv4_addr),
805 				 &payload, GFP_KERNEL);
806 }
807 
808 void nfp_tunnel_add_ipv4_off(struct nfp_app *app, __be32 ipv4)
809 {
810 	struct nfp_flower_priv *priv = app->priv;
811 	struct nfp_ipv4_addr_entry *entry;
812 	struct list_head *ptr, *storage;
813 
814 	mutex_lock(&priv->tun.ipv4_off_lock);
815 	list_for_each_safe(ptr, storage, &priv->tun.ipv4_off_list) {
816 		entry = list_entry(ptr, struct nfp_ipv4_addr_entry, list);
817 		if (entry->ipv4_addr == ipv4) {
818 			entry->ref_count++;
819 			mutex_unlock(&priv->tun.ipv4_off_lock);
820 			return;
821 		}
822 	}
823 
824 	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
825 	if (!entry) {
826 		mutex_unlock(&priv->tun.ipv4_off_lock);
827 		nfp_flower_cmsg_warn(app, "Mem error when offloading IP address.\n");
828 		return;
829 	}
830 	entry->ipv4_addr = ipv4;
831 	entry->ref_count = 1;
832 	list_add_tail(&entry->list, &priv->tun.ipv4_off_list);
833 	mutex_unlock(&priv->tun.ipv4_off_lock);
834 
835 	nfp_tun_write_ipv4_list(app);
836 }
837 
838 void nfp_tunnel_del_ipv4_off(struct nfp_app *app, __be32 ipv4)
839 {
840 	struct nfp_flower_priv *priv = app->priv;
841 	struct nfp_ipv4_addr_entry *entry;
842 	struct list_head *ptr, *storage;
843 
844 	mutex_lock(&priv->tun.ipv4_off_lock);
845 	list_for_each_safe(ptr, storage, &priv->tun.ipv4_off_list) {
846 		entry = list_entry(ptr, struct nfp_ipv4_addr_entry, list);
847 		if (entry->ipv4_addr == ipv4) {
848 			entry->ref_count--;
849 			if (!entry->ref_count) {
850 				list_del(&entry->list);
851 				kfree(entry);
852 			}
853 			break;
854 		}
855 	}
856 	mutex_unlock(&priv->tun.ipv4_off_lock);
857 
858 	nfp_tun_write_ipv4_list(app);
859 }
860 
861 static void nfp_tun_write_ipv6_list(struct nfp_app *app)
862 {
863 	struct nfp_flower_priv *priv = app->priv;
864 	struct nfp_ipv6_addr_entry *entry;
865 	struct nfp_tun_ipv6_addr payload;
866 	int count = 0;
867 
868 	memset(&payload, 0, sizeof(struct nfp_tun_ipv6_addr));
869 	mutex_lock(&priv->tun.ipv6_off_lock);
870 	list_for_each_entry(entry, &priv->tun.ipv6_off_list, list) {
871 		if (count >= NFP_FL_IPV6_ADDRS_MAX) {
872 			nfp_flower_cmsg_warn(app, "Too many IPv6 tunnel endpoint addresses, some cannot be offloaded.\n");
873 			break;
874 		}
875 		payload.ipv6_addr[count++] = entry->ipv6_addr;
876 	}
877 	mutex_unlock(&priv->tun.ipv6_off_lock);
878 	payload.count = cpu_to_be32(count);
879 
880 	nfp_flower_xmit_tun_conf(app, NFP_FLOWER_CMSG_TYPE_TUN_IPS_V6,
881 				 sizeof(struct nfp_tun_ipv6_addr),
882 				 &payload, GFP_KERNEL);
883 }
884 
885 struct nfp_ipv6_addr_entry *
886 nfp_tunnel_add_ipv6_off(struct nfp_app *app, struct in6_addr *ipv6)
887 {
888 	struct nfp_flower_priv *priv = app->priv;
889 	struct nfp_ipv6_addr_entry *entry;
890 
891 	mutex_lock(&priv->tun.ipv6_off_lock);
892 	list_for_each_entry(entry, &priv->tun.ipv6_off_list, list)
893 		if (!memcmp(&entry->ipv6_addr, ipv6, sizeof(*ipv6))) {
894 			entry->ref_count++;
895 			mutex_unlock(&priv->tun.ipv6_off_lock);
896 			return entry;
897 		}
898 
899 	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
900 	if (!entry) {
901 		mutex_unlock(&priv->tun.ipv6_off_lock);
902 		nfp_flower_cmsg_warn(app, "Mem error when offloading IP address.\n");
903 		return NULL;
904 	}
905 	entry->ipv6_addr = *ipv6;
906 	entry->ref_count = 1;
907 	list_add_tail(&entry->list, &priv->tun.ipv6_off_list);
908 	mutex_unlock(&priv->tun.ipv6_off_lock);
909 
910 	nfp_tun_write_ipv6_list(app);
911 
912 	return entry;
913 }
914 
915 void
916 nfp_tunnel_put_ipv6_off(struct nfp_app *app, struct nfp_ipv6_addr_entry *entry)
917 {
918 	struct nfp_flower_priv *priv = app->priv;
919 	bool freed = false;
920 
921 	mutex_lock(&priv->tun.ipv6_off_lock);
922 	if (!--entry->ref_count) {
923 		list_del(&entry->list);
924 		kfree(entry);
925 		freed = true;
926 	}
927 	mutex_unlock(&priv->tun.ipv6_off_lock);
928 
929 	if (freed)
930 		nfp_tun_write_ipv6_list(app);
931 }
932 
933 static int
934 __nfp_tunnel_offload_mac(struct nfp_app *app, const u8 *mac, u16 idx, bool del)
935 {
936 	struct nfp_tun_mac_addr_offload payload;
937 
938 	memset(&payload, 0, sizeof(payload));
939 
940 	if (del)
941 		payload.flags = cpu_to_be16(NFP_TUN_MAC_OFFLOAD_DEL_FLAG);
942 
943 	/* FW supports multiple MACs per cmsg but restrict to single. */
944 	payload.count = cpu_to_be16(1);
945 	payload.index = cpu_to_be16(idx);
946 	ether_addr_copy(payload.addr, mac);
947 
948 	return nfp_flower_xmit_tun_conf(app, NFP_FLOWER_CMSG_TYPE_TUN_MAC,
949 					sizeof(struct nfp_tun_mac_addr_offload),
950 					&payload, GFP_KERNEL);
951 }
952 
953 static bool nfp_tunnel_port_is_phy_repr(int port)
954 {
955 	if (FIELD_GET(NFP_FLOWER_CMSG_PORT_TYPE, port) ==
956 	    NFP_FLOWER_CMSG_PORT_TYPE_PHYS_PORT)
957 		return true;
958 
959 	return false;
960 }
961 
962 static u16 nfp_tunnel_get_mac_idx_from_phy_port_id(int port)
963 {
964 	return port << 8 | NFP_FLOWER_CMSG_PORT_TYPE_PHYS_PORT;
965 }
966 
967 static u16 nfp_tunnel_get_global_mac_idx_from_ida(int id)
968 {
969 	return id << 8 | NFP_FLOWER_CMSG_PORT_TYPE_OTHER_PORT;
970 }
971 
972 static int nfp_tunnel_get_ida_from_global_mac_idx(u16 nfp_mac_idx)
973 {
974 	return nfp_mac_idx >> 8;
975 }
976 
977 static bool nfp_tunnel_is_mac_idx_global(u16 nfp_mac_idx)
978 {
979 	return (nfp_mac_idx & 0xff) == NFP_FLOWER_CMSG_PORT_TYPE_OTHER_PORT;
980 }
981 
982 static struct nfp_tun_offloaded_mac *
983 nfp_tunnel_lookup_offloaded_macs(struct nfp_app *app, const u8 *mac)
984 {
985 	struct nfp_flower_priv *priv = app->priv;
986 
987 	return rhashtable_lookup_fast(&priv->tun.offloaded_macs, mac,
988 				      offloaded_macs_params);
989 }
990 
991 static void
992 nfp_tunnel_offloaded_macs_inc_ref_and_link(struct nfp_tun_offloaded_mac *entry,
993 					   struct net_device *netdev, bool mod)
994 {
995 	if (nfp_netdev_is_nfp_repr(netdev)) {
996 		struct nfp_flower_repr_priv *repr_priv;
997 		struct nfp_repr *repr;
998 
999 		repr = netdev_priv(netdev);
1000 		repr_priv = repr->app_priv;
1001 
1002 		/* If modifing MAC, remove repr from old list first. */
1003 		if (mod)
1004 			list_del(&repr_priv->mac_list);
1005 
1006 		list_add_tail(&repr_priv->mac_list, &entry->repr_list);
1007 	} else if (nfp_flower_is_supported_bridge(netdev)) {
1008 		entry->bridge_count++;
1009 	}
1010 
1011 	entry->ref_count++;
1012 }
1013 
1014 static int
1015 nfp_tunnel_add_shared_mac(struct nfp_app *app, struct net_device *netdev,
1016 			  int port, bool mod)
1017 {
1018 	struct nfp_flower_priv *priv = app->priv;
1019 	struct nfp_tun_offloaded_mac *entry;
1020 	int ida_idx = -1, err;
1021 	u16 nfp_mac_idx = 0;
1022 
1023 	entry = nfp_tunnel_lookup_offloaded_macs(app, netdev->dev_addr);
1024 	if (entry && nfp_tunnel_is_mac_idx_global(entry->index)) {
1025 		if (entry->bridge_count ||
1026 		    !nfp_flower_is_supported_bridge(netdev)) {
1027 			nfp_tunnel_offloaded_macs_inc_ref_and_link(entry,
1028 								   netdev, mod);
1029 			return 0;
1030 		}
1031 
1032 		/* MAC is global but matches need to go to pre_tun table. */
1033 		nfp_mac_idx = entry->index | NFP_TUN_PRE_TUN_IDX_BIT;
1034 	}
1035 
1036 	if (!nfp_mac_idx) {
1037 		/* Assign a global index if non-repr or MAC is now shared. */
1038 		if (entry || !port) {
1039 			ida_idx = ida_alloc_max(&priv->tun.mac_off_ids,
1040 						NFP_MAX_MAC_INDEX, GFP_KERNEL);
1041 			if (ida_idx < 0)
1042 				return ida_idx;
1043 
1044 			nfp_mac_idx =
1045 				nfp_tunnel_get_global_mac_idx_from_ida(ida_idx);
1046 
1047 			if (nfp_flower_is_supported_bridge(netdev))
1048 				nfp_mac_idx |= NFP_TUN_PRE_TUN_IDX_BIT;
1049 
1050 		} else {
1051 			nfp_mac_idx =
1052 				nfp_tunnel_get_mac_idx_from_phy_port_id(port);
1053 		}
1054 	}
1055 
1056 	if (!entry) {
1057 		entry = kzalloc(sizeof(*entry), GFP_KERNEL);
1058 		if (!entry) {
1059 			err = -ENOMEM;
1060 			goto err_free_ida;
1061 		}
1062 
1063 		ether_addr_copy(entry->addr, netdev->dev_addr);
1064 		INIT_LIST_HEAD(&entry->repr_list);
1065 
1066 		if (rhashtable_insert_fast(&priv->tun.offloaded_macs,
1067 					   &entry->ht_node,
1068 					   offloaded_macs_params)) {
1069 			err = -ENOMEM;
1070 			goto err_free_entry;
1071 		}
1072 	}
1073 
1074 	err = __nfp_tunnel_offload_mac(app, netdev->dev_addr,
1075 				       nfp_mac_idx, false);
1076 	if (err) {
1077 		/* If not shared then free. */
1078 		if (!entry->ref_count)
1079 			goto err_remove_hash;
1080 		goto err_free_ida;
1081 	}
1082 
1083 	entry->index = nfp_mac_idx;
1084 	nfp_tunnel_offloaded_macs_inc_ref_and_link(entry, netdev, mod);
1085 
1086 	return 0;
1087 
1088 err_remove_hash:
1089 	rhashtable_remove_fast(&priv->tun.offloaded_macs, &entry->ht_node,
1090 			       offloaded_macs_params);
1091 err_free_entry:
1092 	kfree(entry);
1093 err_free_ida:
1094 	if (ida_idx != -1)
1095 		ida_free(&priv->tun.mac_off_ids, ida_idx);
1096 
1097 	return err;
1098 }
1099 
1100 static int
1101 nfp_tunnel_del_shared_mac(struct nfp_app *app, struct net_device *netdev,
1102 			  const u8 *mac, bool mod)
1103 {
1104 	struct nfp_flower_priv *priv = app->priv;
1105 	struct nfp_flower_repr_priv *repr_priv;
1106 	struct nfp_tun_offloaded_mac *entry;
1107 	struct nfp_repr *repr;
1108 	u16 nfp_mac_idx;
1109 	int ida_idx;
1110 
1111 	entry = nfp_tunnel_lookup_offloaded_macs(app, mac);
1112 	if (!entry)
1113 		return 0;
1114 
1115 	entry->ref_count--;
1116 	/* If del is part of a mod then mac_list is still in use elsewhere. */
1117 	if (nfp_netdev_is_nfp_repr(netdev) && !mod) {
1118 		repr = netdev_priv(netdev);
1119 		repr_priv = repr->app_priv;
1120 		list_del(&repr_priv->mac_list);
1121 	}
1122 
1123 	if (nfp_flower_is_supported_bridge(netdev)) {
1124 		entry->bridge_count--;
1125 
1126 		if (!entry->bridge_count && entry->ref_count) {
1127 			nfp_mac_idx = entry->index & ~NFP_TUN_PRE_TUN_IDX_BIT;
1128 			if (__nfp_tunnel_offload_mac(app, mac, nfp_mac_idx,
1129 						     false)) {
1130 				nfp_flower_cmsg_warn(app, "MAC offload index revert failed on %s.\n",
1131 						     netdev_name(netdev));
1132 				return 0;
1133 			}
1134 
1135 			entry->index = nfp_mac_idx;
1136 			return 0;
1137 		}
1138 	}
1139 
1140 	/* If MAC is now used by 1 repr set the offloaded MAC index to port. */
1141 	if (entry->ref_count == 1 && list_is_singular(&entry->repr_list)) {
1142 		int port, err;
1143 
1144 		repr_priv = list_first_entry(&entry->repr_list,
1145 					     struct nfp_flower_repr_priv,
1146 					     mac_list);
1147 		repr = repr_priv->nfp_repr;
1148 		port = nfp_repr_get_port_id(repr->netdev);
1149 		nfp_mac_idx = nfp_tunnel_get_mac_idx_from_phy_port_id(port);
1150 		err = __nfp_tunnel_offload_mac(app, mac, nfp_mac_idx, false);
1151 		if (err) {
1152 			nfp_flower_cmsg_warn(app, "MAC offload index revert failed on %s.\n",
1153 					     netdev_name(netdev));
1154 			return 0;
1155 		}
1156 
1157 		ida_idx = nfp_tunnel_get_ida_from_global_mac_idx(entry->index);
1158 		ida_free(&priv->tun.mac_off_ids, ida_idx);
1159 		entry->index = nfp_mac_idx;
1160 		return 0;
1161 	}
1162 
1163 	if (entry->ref_count)
1164 		return 0;
1165 
1166 	WARN_ON_ONCE(rhashtable_remove_fast(&priv->tun.offloaded_macs,
1167 					    &entry->ht_node,
1168 					    offloaded_macs_params));
1169 
1170 	if (nfp_flower_is_supported_bridge(netdev))
1171 		nfp_mac_idx = entry->index & ~NFP_TUN_PRE_TUN_IDX_BIT;
1172 	else
1173 		nfp_mac_idx = entry->index;
1174 
1175 	/* If MAC has global ID then extract and free the ida entry. */
1176 	if (nfp_tunnel_is_mac_idx_global(nfp_mac_idx)) {
1177 		ida_idx = nfp_tunnel_get_ida_from_global_mac_idx(entry->index);
1178 		ida_free(&priv->tun.mac_off_ids, ida_idx);
1179 	}
1180 
1181 	kfree(entry);
1182 
1183 	return __nfp_tunnel_offload_mac(app, mac, 0, true);
1184 }
1185 
1186 static int
1187 nfp_tunnel_offload_mac(struct nfp_app *app, struct net_device *netdev,
1188 		       enum nfp_flower_mac_offload_cmd cmd)
1189 {
1190 	struct nfp_flower_non_repr_priv *nr_priv = NULL;
1191 	bool non_repr = false, *mac_offloaded;
1192 	u8 *off_mac = NULL;
1193 	int err, port = 0;
1194 
1195 	if (nfp_netdev_is_nfp_repr(netdev)) {
1196 		struct nfp_flower_repr_priv *repr_priv;
1197 		struct nfp_repr *repr;
1198 
1199 		repr = netdev_priv(netdev);
1200 		if (repr->app != app)
1201 			return 0;
1202 
1203 		repr_priv = repr->app_priv;
1204 		if (repr_priv->on_bridge)
1205 			return 0;
1206 
1207 		mac_offloaded = &repr_priv->mac_offloaded;
1208 		off_mac = &repr_priv->offloaded_mac_addr[0];
1209 		port = nfp_repr_get_port_id(netdev);
1210 		if (!nfp_tunnel_port_is_phy_repr(port))
1211 			return 0;
1212 	} else if (nfp_fl_is_netdev_to_offload(netdev)) {
1213 		nr_priv = nfp_flower_non_repr_priv_get(app, netdev);
1214 		if (!nr_priv)
1215 			return -ENOMEM;
1216 
1217 		mac_offloaded = &nr_priv->mac_offloaded;
1218 		off_mac = &nr_priv->offloaded_mac_addr[0];
1219 		non_repr = true;
1220 	} else {
1221 		return 0;
1222 	}
1223 
1224 	if (!is_valid_ether_addr(netdev->dev_addr)) {
1225 		err = -EINVAL;
1226 		goto err_put_non_repr_priv;
1227 	}
1228 
1229 	if (cmd == NFP_TUNNEL_MAC_OFFLOAD_MOD && !*mac_offloaded)
1230 		cmd = NFP_TUNNEL_MAC_OFFLOAD_ADD;
1231 
1232 	switch (cmd) {
1233 	case NFP_TUNNEL_MAC_OFFLOAD_ADD:
1234 		err = nfp_tunnel_add_shared_mac(app, netdev, port, false);
1235 		if (err)
1236 			goto err_put_non_repr_priv;
1237 
1238 		if (non_repr)
1239 			__nfp_flower_non_repr_priv_get(nr_priv);
1240 
1241 		*mac_offloaded = true;
1242 		ether_addr_copy(off_mac, netdev->dev_addr);
1243 		break;
1244 	case NFP_TUNNEL_MAC_OFFLOAD_DEL:
1245 		/* Only attempt delete if add was successful. */
1246 		if (!*mac_offloaded)
1247 			break;
1248 
1249 		if (non_repr)
1250 			__nfp_flower_non_repr_priv_put(nr_priv);
1251 
1252 		*mac_offloaded = false;
1253 
1254 		err = nfp_tunnel_del_shared_mac(app, netdev, netdev->dev_addr,
1255 						false);
1256 		if (err)
1257 			goto err_put_non_repr_priv;
1258 
1259 		break;
1260 	case NFP_TUNNEL_MAC_OFFLOAD_MOD:
1261 		/* Ignore if changing to the same address. */
1262 		if (ether_addr_equal(netdev->dev_addr, off_mac))
1263 			break;
1264 
1265 		err = nfp_tunnel_add_shared_mac(app, netdev, port, true);
1266 		if (err)
1267 			goto err_put_non_repr_priv;
1268 
1269 		/* Delete the previous MAC address. */
1270 		err = nfp_tunnel_del_shared_mac(app, netdev, off_mac, true);
1271 		if (err)
1272 			nfp_flower_cmsg_warn(app, "Failed to remove offload of replaced MAC addr on %s.\n",
1273 					     netdev_name(netdev));
1274 
1275 		ether_addr_copy(off_mac, netdev->dev_addr);
1276 		break;
1277 	default:
1278 		err = -EINVAL;
1279 		goto err_put_non_repr_priv;
1280 	}
1281 
1282 	if (non_repr)
1283 		__nfp_flower_non_repr_priv_put(nr_priv);
1284 
1285 	return 0;
1286 
1287 err_put_non_repr_priv:
1288 	if (non_repr)
1289 		__nfp_flower_non_repr_priv_put(nr_priv);
1290 
1291 	return err;
1292 }
1293 
1294 int nfp_tunnel_mac_event_handler(struct nfp_app *app,
1295 				 struct net_device *netdev,
1296 				 unsigned long event, void *ptr)
1297 {
1298 	int err;
1299 
1300 	if (event == NETDEV_DOWN) {
1301 		err = nfp_tunnel_offload_mac(app, netdev,
1302 					     NFP_TUNNEL_MAC_OFFLOAD_DEL);
1303 		if (err)
1304 			nfp_flower_cmsg_warn(app, "Failed to delete offload MAC on %s.\n",
1305 					     netdev_name(netdev));
1306 	} else if (event == NETDEV_UP) {
1307 		err = nfp_tunnel_offload_mac(app, netdev,
1308 					     NFP_TUNNEL_MAC_OFFLOAD_ADD);
1309 		if (err)
1310 			nfp_flower_cmsg_warn(app, "Failed to offload MAC on %s.\n",
1311 					     netdev_name(netdev));
1312 	} else if (event == NETDEV_CHANGEADDR) {
1313 		/* Only offload addr change if netdev is already up. */
1314 		if (!(netdev->flags & IFF_UP))
1315 			return NOTIFY_OK;
1316 
1317 		err = nfp_tunnel_offload_mac(app, netdev,
1318 					     NFP_TUNNEL_MAC_OFFLOAD_MOD);
1319 		if (err)
1320 			nfp_flower_cmsg_warn(app, "Failed to offload MAC change on %s.\n",
1321 					     netdev_name(netdev));
1322 	} else if (event == NETDEV_CHANGEUPPER) {
1323 		/* If a repr is attached to a bridge then tunnel packets
1324 		 * entering the physical port are directed through the bridge
1325 		 * datapath and cannot be directly detunneled. Therefore,
1326 		 * associated offloaded MACs and indexes should not be used
1327 		 * by fw for detunneling.
1328 		 */
1329 		struct netdev_notifier_changeupper_info *info = ptr;
1330 		struct net_device *upper = info->upper_dev;
1331 		struct nfp_flower_repr_priv *repr_priv;
1332 		struct nfp_repr *repr;
1333 
1334 		if (!nfp_netdev_is_nfp_repr(netdev) ||
1335 		    !nfp_flower_is_supported_bridge(upper))
1336 			return NOTIFY_OK;
1337 
1338 		repr = netdev_priv(netdev);
1339 		if (repr->app != app)
1340 			return NOTIFY_OK;
1341 
1342 		repr_priv = repr->app_priv;
1343 
1344 		if (info->linking) {
1345 			if (nfp_tunnel_offload_mac(app, netdev,
1346 						   NFP_TUNNEL_MAC_OFFLOAD_DEL))
1347 				nfp_flower_cmsg_warn(app, "Failed to delete offloaded MAC on %s.\n",
1348 						     netdev_name(netdev));
1349 			repr_priv->on_bridge = true;
1350 		} else {
1351 			repr_priv->on_bridge = false;
1352 
1353 			if (!(netdev->flags & IFF_UP))
1354 				return NOTIFY_OK;
1355 
1356 			if (nfp_tunnel_offload_mac(app, netdev,
1357 						   NFP_TUNNEL_MAC_OFFLOAD_ADD))
1358 				nfp_flower_cmsg_warn(app, "Failed to offload MAC on %s.\n",
1359 						     netdev_name(netdev));
1360 		}
1361 	}
1362 	return NOTIFY_OK;
1363 }
1364 
1365 int nfp_flower_xmit_pre_tun_flow(struct nfp_app *app,
1366 				 struct nfp_fl_payload *flow)
1367 {
1368 	struct nfp_flower_priv *app_priv = app->priv;
1369 	struct nfp_tun_offloaded_mac *mac_entry;
1370 	struct nfp_flower_meta_tci *key_meta;
1371 	struct nfp_tun_pre_tun_rule payload;
1372 	struct net_device *internal_dev;
1373 	int err;
1374 
1375 	if (app_priv->pre_tun_rule_cnt == NFP_TUN_PRE_TUN_RULE_LIMIT)
1376 		return -ENOSPC;
1377 
1378 	memset(&payload, 0, sizeof(struct nfp_tun_pre_tun_rule));
1379 
1380 	internal_dev = flow->pre_tun_rule.dev;
1381 	payload.vlan_tci = flow->pre_tun_rule.vlan_tci;
1382 	payload.host_ctx_id = flow->meta.host_ctx_id;
1383 
1384 	/* Lookup MAC index for the pre-tunnel rule egress device.
1385 	 * Note that because the device is always an internal port, it will
1386 	 * have a constant global index so does not need to be tracked.
1387 	 */
1388 	mac_entry = nfp_tunnel_lookup_offloaded_macs(app,
1389 						     internal_dev->dev_addr);
1390 	if (!mac_entry)
1391 		return -ENOENT;
1392 
1393 	/* Set/clear IPV6 bit. cpu_to_be16() swap will lead to MSB being
1394 	 * set/clear for port_idx.
1395 	 */
1396 	key_meta = (struct nfp_flower_meta_tci *)flow->unmasked_data;
1397 	if (key_meta->nfp_flow_key_layer & NFP_FLOWER_LAYER_IPV6)
1398 		mac_entry->index |= NFP_TUN_PRE_TUN_IPV6_BIT;
1399 	else
1400 		mac_entry->index &= ~NFP_TUN_PRE_TUN_IPV6_BIT;
1401 
1402 	payload.port_idx = cpu_to_be16(mac_entry->index);
1403 
1404 	/* Copy mac id and vlan to flow - dev may not exist at delete time. */
1405 	flow->pre_tun_rule.vlan_tci = payload.vlan_tci;
1406 	flow->pre_tun_rule.port_idx = payload.port_idx;
1407 
1408 	err = nfp_flower_xmit_tun_conf(app, NFP_FLOWER_CMSG_TYPE_PRE_TUN_RULE,
1409 				       sizeof(struct nfp_tun_pre_tun_rule),
1410 				       (unsigned char *)&payload, GFP_KERNEL);
1411 	if (err)
1412 		return err;
1413 
1414 	app_priv->pre_tun_rule_cnt++;
1415 
1416 	return 0;
1417 }
1418 
1419 int nfp_flower_xmit_pre_tun_del_flow(struct nfp_app *app,
1420 				     struct nfp_fl_payload *flow)
1421 {
1422 	struct nfp_flower_priv *app_priv = app->priv;
1423 	struct nfp_tun_pre_tun_rule payload;
1424 	u32 tmp_flags = 0;
1425 	int err;
1426 
1427 	memset(&payload, 0, sizeof(struct nfp_tun_pre_tun_rule));
1428 
1429 	tmp_flags |= NFP_TUN_PRE_TUN_RULE_DEL;
1430 	payload.flags = cpu_to_be32(tmp_flags);
1431 	payload.vlan_tci = flow->pre_tun_rule.vlan_tci;
1432 	payload.port_idx = flow->pre_tun_rule.port_idx;
1433 
1434 	err = nfp_flower_xmit_tun_conf(app, NFP_FLOWER_CMSG_TYPE_PRE_TUN_RULE,
1435 				       sizeof(struct nfp_tun_pre_tun_rule),
1436 				       (unsigned char *)&payload, GFP_KERNEL);
1437 	if (err)
1438 		return err;
1439 
1440 	app_priv->pre_tun_rule_cnt--;
1441 
1442 	return 0;
1443 }
1444 
1445 int nfp_tunnel_config_start(struct nfp_app *app)
1446 {
1447 	struct nfp_flower_priv *priv = app->priv;
1448 	int err;
1449 
1450 	/* Initialise rhash for MAC offload tracking. */
1451 	err = rhashtable_init(&priv->tun.offloaded_macs,
1452 			      &offloaded_macs_params);
1453 	if (err)
1454 		return err;
1455 
1456 	ida_init(&priv->tun.mac_off_ids);
1457 
1458 	/* Initialise priv data for IPv4/v6 offloading. */
1459 	mutex_init(&priv->tun.ipv4_off_lock);
1460 	INIT_LIST_HEAD(&priv->tun.ipv4_off_list);
1461 	mutex_init(&priv->tun.ipv6_off_lock);
1462 	INIT_LIST_HEAD(&priv->tun.ipv6_off_list);
1463 
1464 	/* Initialise priv data for neighbour offloading. */
1465 	priv->tun.neigh_nb.notifier_call = nfp_tun_neigh_event_handler;
1466 
1467 	err = register_netevent_notifier(&priv->tun.neigh_nb);
1468 	if (err) {
1469 		rhashtable_free_and_destroy(&priv->tun.offloaded_macs,
1470 					    nfp_check_rhashtable_empty, NULL);
1471 		return err;
1472 	}
1473 
1474 	return 0;
1475 }
1476 
1477 void nfp_tunnel_config_stop(struct nfp_app *app)
1478 {
1479 	struct nfp_flower_priv *priv = app->priv;
1480 	struct nfp_ipv4_addr_entry *ip_entry;
1481 	struct list_head *ptr, *storage;
1482 
1483 	unregister_netevent_notifier(&priv->tun.neigh_nb);
1484 
1485 	ida_destroy(&priv->tun.mac_off_ids);
1486 
1487 	/* Free any memory that may be occupied by ipv4 list. */
1488 	list_for_each_safe(ptr, storage, &priv->tun.ipv4_off_list) {
1489 		ip_entry = list_entry(ptr, struct nfp_ipv4_addr_entry, list);
1490 		list_del(&ip_entry->list);
1491 		kfree(ip_entry);
1492 	}
1493 
1494 	mutex_destroy(&priv->tun.ipv6_off_lock);
1495 
1496 	/* Destroy rhash. Entries should be cleaned on netdev notifier unreg. */
1497 	rhashtable_free_and_destroy(&priv->tun.offloaded_macs,
1498 				    nfp_check_rhashtable_empty, NULL);
1499 
1500 	nfp_tun_cleanup_nn_entries(app);
1501 }
1502