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/etherdevice.h>
35 #include <linux/inetdevice.h>
36 #include <net/netevent.h>
37 #include <linux/idr.h>
38 #include <net/dst_metadata.h>
39 #include <net/arp.h>
40 
41 #include "cmsg.h"
42 #include "main.h"
43 #include "../nfp_net_repr.h"
44 #include "../nfp_net.h"
45 
46 #define NFP_FL_MAX_ROUTES               32
47 
48 /**
49  * struct nfp_tun_active_tuns - periodic message of active tunnels
50  * @seq:		sequence number of the message
51  * @count:		number of tunnels report in message
52  * @flags:		options part of the request
53  * @tun_info.ipv4:		dest IPv4 address of active route
54  * @tun_info.egress_port:	port the encapsulated packet egressed
55  * @tun_info.extra:		reserved for future use
56  * @tun_info:		tunnels that have sent traffic in reported period
57  */
58 struct nfp_tun_active_tuns {
59 	__be32 seq;
60 	__be32 count;
61 	__be32 flags;
62 	struct route_ip_info {
63 		__be32 ipv4;
64 		__be32 egress_port;
65 		__be32 extra[2];
66 	} tun_info[];
67 };
68 
69 /**
70  * struct nfp_tun_neigh - neighbour/route entry on the NFP
71  * @dst_ipv4:	destination IPv4 address
72  * @src_ipv4:	source IPv4 address
73  * @dst_addr:	destination MAC address
74  * @src_addr:	source MAC address
75  * @port_id:	NFP port to output packet on - associated with source IPv4
76  */
77 struct nfp_tun_neigh {
78 	__be32 dst_ipv4;
79 	__be32 src_ipv4;
80 	u8 dst_addr[ETH_ALEN];
81 	u8 src_addr[ETH_ALEN];
82 	__be32 port_id;
83 };
84 
85 /**
86  * struct nfp_tun_req_route_ipv4 - NFP requests a route/neighbour lookup
87  * @ingress_port:	ingress port of packet that signalled request
88  * @ipv4_addr:		destination ipv4 address for route
89  * @reserved:		reserved for future use
90  */
91 struct nfp_tun_req_route_ipv4 {
92 	__be32 ingress_port;
93 	__be32 ipv4_addr;
94 	__be32 reserved[2];
95 };
96 
97 /**
98  * struct nfp_ipv4_route_entry - routes that are offloaded to the NFP
99  * @ipv4_addr:	destination of route
100  * @list:	list pointer
101  */
102 struct nfp_ipv4_route_entry {
103 	__be32 ipv4_addr;
104 	struct list_head list;
105 };
106 
107 #define NFP_FL_IPV4_ADDRS_MAX        32
108 
109 /**
110  * struct nfp_tun_ipv4_addr - set the IP address list on the NFP
111  * @count:	number of IPs populated in the array
112  * @ipv4_addr:	array of IPV4_ADDRS_MAX 32 bit IPv4 addresses
113  */
114 struct nfp_tun_ipv4_addr {
115 	__be32 count;
116 	__be32 ipv4_addr[NFP_FL_IPV4_ADDRS_MAX];
117 };
118 
119 /**
120  * struct nfp_ipv4_addr_entry - cached IPv4 addresses
121  * @ipv4_addr:	IP address
122  * @ref_count:	number of rules currently using this IP
123  * @list:	list pointer
124  */
125 struct nfp_ipv4_addr_entry {
126 	__be32 ipv4_addr;
127 	int ref_count;
128 	struct list_head list;
129 };
130 
131 /**
132  * struct nfp_tun_mac_addr - configure MAC address of tunnel EP on NFP
133  * @reserved:	reserved for future use
134  * @count:	number of MAC addresses in the message
135  * @addresses.index:	index of MAC address in the lookup table
136  * @addresses.addr:	interface MAC address
137  * @addresses:	series of MACs to offload
138  */
139 struct nfp_tun_mac_addr {
140 	__be16 reserved;
141 	__be16 count;
142 	struct index_mac_addr {
143 		__be16 index;
144 		u8 addr[ETH_ALEN];
145 	} addresses[];
146 };
147 
148 /**
149  * struct nfp_tun_mac_offload_entry - list of MACs to offload
150  * @index:	index of MAC address for offloading
151  * @addr:	interface MAC address
152  * @list:	list pointer
153  */
154 struct nfp_tun_mac_offload_entry {
155 	__be16 index;
156 	u8 addr[ETH_ALEN];
157 	struct list_head list;
158 };
159 
160 #define NFP_MAX_MAC_INDEX       0xff
161 
162 /**
163  * struct nfp_tun_mac_non_nfp_idx - converts non NFP netdev ifindex to 8-bit id
164  * @ifindex:	netdev ifindex of the device
165  * @index:	index of netdevs mac on NFP
166  * @list:	list pointer
167  */
168 struct nfp_tun_mac_non_nfp_idx {
169 	int ifindex;
170 	u8 index;
171 	struct list_head list;
172 };
173 
174 void nfp_tunnel_keep_alive(struct nfp_app *app, struct sk_buff *skb)
175 {
176 	struct nfp_tun_active_tuns *payload;
177 	struct net_device *netdev;
178 	int count, i, pay_len;
179 	struct neighbour *n;
180 	__be32 ipv4_addr;
181 	u32 port;
182 
183 	payload = nfp_flower_cmsg_get_data(skb);
184 	count = be32_to_cpu(payload->count);
185 	if (count > NFP_FL_MAX_ROUTES) {
186 		nfp_flower_cmsg_warn(app, "Tunnel keep-alive request exceeds max routes.\n");
187 		return;
188 	}
189 
190 	pay_len = nfp_flower_cmsg_get_data_len(skb);
191 	if (pay_len != sizeof(struct nfp_tun_active_tuns) +
192 	    sizeof(struct route_ip_info) * count) {
193 		nfp_flower_cmsg_warn(app, "Corruption in tunnel keep-alive message.\n");
194 		return;
195 	}
196 
197 	for (i = 0; i < count; i++) {
198 		ipv4_addr = payload->tun_info[i].ipv4;
199 		port = be32_to_cpu(payload->tun_info[i].egress_port);
200 		netdev = nfp_app_repr_get(app, port);
201 		if (!netdev)
202 			continue;
203 
204 		n = neigh_lookup(&arp_tbl, &ipv4_addr, netdev);
205 		if (!n)
206 			continue;
207 
208 		/* Update the used timestamp of neighbour */
209 		neigh_event_send(n, NULL);
210 		neigh_release(n);
211 	}
212 }
213 
214 static bool nfp_tun_is_netdev_to_offload(struct net_device *netdev)
215 {
216 	if (!netdev->rtnl_link_ops)
217 		return false;
218 	if (!strcmp(netdev->rtnl_link_ops->kind, "openvswitch"))
219 		return true;
220 	if (!strcmp(netdev->rtnl_link_ops->kind, "vxlan"))
221 		return true;
222 
223 	return false;
224 }
225 
226 static int
227 nfp_flower_xmit_tun_conf(struct nfp_app *app, u8 mtype, u16 plen, void *pdata,
228 			 gfp_t flag)
229 {
230 	struct sk_buff *skb;
231 	unsigned char *msg;
232 
233 	skb = nfp_flower_cmsg_alloc(app, plen, mtype, flag);
234 	if (!skb)
235 		return -ENOMEM;
236 
237 	msg = nfp_flower_cmsg_get_data(skb);
238 	memcpy(msg, pdata, nfp_flower_cmsg_get_data_len(skb));
239 
240 	nfp_ctrl_tx(app->ctrl, skb);
241 	return 0;
242 }
243 
244 static bool nfp_tun_has_route(struct nfp_app *app, __be32 ipv4_addr)
245 {
246 	struct nfp_flower_priv *priv = app->priv;
247 	struct nfp_ipv4_route_entry *entry;
248 	struct list_head *ptr, *storage;
249 
250 	spin_lock_bh(&priv->nfp_neigh_off_lock);
251 	list_for_each_safe(ptr, storage, &priv->nfp_neigh_off_list) {
252 		entry = list_entry(ptr, struct nfp_ipv4_route_entry, list);
253 		if (entry->ipv4_addr == ipv4_addr) {
254 			spin_unlock_bh(&priv->nfp_neigh_off_lock);
255 			return true;
256 		}
257 	}
258 	spin_unlock_bh(&priv->nfp_neigh_off_lock);
259 	return false;
260 }
261 
262 static void nfp_tun_add_route_to_cache(struct nfp_app *app, __be32 ipv4_addr)
263 {
264 	struct nfp_flower_priv *priv = app->priv;
265 	struct nfp_ipv4_route_entry *entry;
266 	struct list_head *ptr, *storage;
267 
268 	spin_lock_bh(&priv->nfp_neigh_off_lock);
269 	list_for_each_safe(ptr, storage, &priv->nfp_neigh_off_list) {
270 		entry = list_entry(ptr, struct nfp_ipv4_route_entry, list);
271 		if (entry->ipv4_addr == ipv4_addr) {
272 			spin_unlock_bh(&priv->nfp_neigh_off_lock);
273 			return;
274 		}
275 	}
276 	entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
277 	if (!entry) {
278 		spin_unlock_bh(&priv->nfp_neigh_off_lock);
279 		nfp_flower_cmsg_warn(app, "Mem error when storing new route.\n");
280 		return;
281 	}
282 
283 	entry->ipv4_addr = ipv4_addr;
284 	list_add_tail(&entry->list, &priv->nfp_neigh_off_list);
285 	spin_unlock_bh(&priv->nfp_neigh_off_lock);
286 }
287 
288 static void nfp_tun_del_route_from_cache(struct nfp_app *app, __be32 ipv4_addr)
289 {
290 	struct nfp_flower_priv *priv = app->priv;
291 	struct nfp_ipv4_route_entry *entry;
292 	struct list_head *ptr, *storage;
293 
294 	spin_lock_bh(&priv->nfp_neigh_off_lock);
295 	list_for_each_safe(ptr, storage, &priv->nfp_neigh_off_list) {
296 		entry = list_entry(ptr, struct nfp_ipv4_route_entry, list);
297 		if (entry->ipv4_addr == ipv4_addr) {
298 			list_del(&entry->list);
299 			kfree(entry);
300 			break;
301 		}
302 	}
303 	spin_unlock_bh(&priv->nfp_neigh_off_lock);
304 }
305 
306 static void
307 nfp_tun_write_neigh(struct net_device *netdev, struct nfp_app *app,
308 		    struct flowi4 *flow, struct neighbour *neigh, gfp_t flag)
309 {
310 	struct nfp_tun_neigh payload;
311 
312 	/* Only offload representor IPv4s for now. */
313 	if (!nfp_netdev_is_nfp_repr(netdev))
314 		return;
315 
316 	memset(&payload, 0, sizeof(struct nfp_tun_neigh));
317 	payload.dst_ipv4 = flow->daddr;
318 
319 	/* If entry has expired send dst IP with all other fields 0. */
320 	if (!(neigh->nud_state & NUD_VALID)) {
321 		nfp_tun_del_route_from_cache(app, payload.dst_ipv4);
322 		/* Trigger ARP to verify invalid neighbour state. */
323 		neigh_event_send(neigh, NULL);
324 		goto send_msg;
325 	}
326 
327 	/* Have a valid neighbour so populate rest of entry. */
328 	payload.src_ipv4 = flow->saddr;
329 	ether_addr_copy(payload.src_addr, netdev->dev_addr);
330 	neigh_ha_snapshot(payload.dst_addr, neigh, netdev);
331 	payload.port_id = cpu_to_be32(nfp_repr_get_port_id(netdev));
332 	/* Add destination of new route to NFP cache. */
333 	nfp_tun_add_route_to_cache(app, payload.dst_ipv4);
334 
335 send_msg:
336 	nfp_flower_xmit_tun_conf(app, NFP_FLOWER_CMSG_TYPE_TUN_NEIGH,
337 				 sizeof(struct nfp_tun_neigh),
338 				 (unsigned char *)&payload, flag);
339 }
340 
341 static int
342 nfp_tun_neigh_event_handler(struct notifier_block *nb, unsigned long event,
343 			    void *ptr)
344 {
345 	struct nfp_flower_priv *app_priv;
346 	struct netevent_redirect *redir;
347 	struct flowi4 flow = {};
348 	struct neighbour *n;
349 	struct nfp_app *app;
350 	struct rtable *rt;
351 	int err;
352 
353 	switch (event) {
354 	case NETEVENT_REDIRECT:
355 		redir = (struct netevent_redirect *)ptr;
356 		n = redir->neigh;
357 		break;
358 	case NETEVENT_NEIGH_UPDATE:
359 		n = (struct neighbour *)ptr;
360 		break;
361 	default:
362 		return NOTIFY_DONE;
363 	}
364 
365 	flow.daddr = *(__be32 *)n->primary_key;
366 
367 	/* Only concerned with route changes for representors. */
368 	if (!nfp_netdev_is_nfp_repr(n->dev))
369 		return NOTIFY_DONE;
370 
371 	app_priv = container_of(nb, struct nfp_flower_priv, nfp_tun_neigh_nb);
372 	app = app_priv->app;
373 
374 	/* Only concerned with changes to routes already added to NFP. */
375 	if (!nfp_tun_has_route(app, flow.daddr))
376 		return NOTIFY_DONE;
377 
378 #if IS_ENABLED(CONFIG_INET)
379 	/* Do a route lookup to populate flow data. */
380 	rt = ip_route_output_key(dev_net(n->dev), &flow);
381 	err = PTR_ERR_OR_ZERO(rt);
382 	if (err)
383 		return NOTIFY_DONE;
384 #else
385 	return NOTIFY_DONE;
386 #endif
387 
388 	flow.flowi4_proto = IPPROTO_UDP;
389 	nfp_tun_write_neigh(n->dev, app, &flow, n, GFP_ATOMIC);
390 
391 	return NOTIFY_OK;
392 }
393 
394 void nfp_tunnel_request_route(struct nfp_app *app, struct sk_buff *skb)
395 {
396 	struct nfp_tun_req_route_ipv4 *payload;
397 	struct net_device *netdev;
398 	struct flowi4 flow = {};
399 	struct neighbour *n;
400 	struct rtable *rt;
401 	int err;
402 
403 	payload = nfp_flower_cmsg_get_data(skb);
404 
405 	netdev = nfp_app_repr_get(app, be32_to_cpu(payload->ingress_port));
406 	if (!netdev)
407 		goto route_fail_warning;
408 
409 	flow.daddr = payload->ipv4_addr;
410 	flow.flowi4_proto = IPPROTO_UDP;
411 
412 #if IS_ENABLED(CONFIG_INET)
413 	/* Do a route lookup on same namespace as ingress port. */
414 	rt = ip_route_output_key(dev_net(netdev), &flow);
415 	err = PTR_ERR_OR_ZERO(rt);
416 	if (err)
417 		goto route_fail_warning;
418 #else
419 	goto route_fail_warning;
420 #endif
421 
422 	/* Get the neighbour entry for the lookup */
423 	n = dst_neigh_lookup(&rt->dst, &flow.daddr);
424 	ip_rt_put(rt);
425 	if (!n)
426 		goto route_fail_warning;
427 	nfp_tun_write_neigh(n->dev, app, &flow, n, GFP_KERNEL);
428 	neigh_release(n);
429 	return;
430 
431 route_fail_warning:
432 	nfp_flower_cmsg_warn(app, "Requested route not found.\n");
433 }
434 
435 static void nfp_tun_write_ipv4_list(struct nfp_app *app)
436 {
437 	struct nfp_flower_priv *priv = app->priv;
438 	struct nfp_ipv4_addr_entry *entry;
439 	struct nfp_tun_ipv4_addr payload;
440 	struct list_head *ptr, *storage;
441 	int count;
442 
443 	memset(&payload, 0, sizeof(struct nfp_tun_ipv4_addr));
444 	mutex_lock(&priv->nfp_ipv4_off_lock);
445 	count = 0;
446 	list_for_each_safe(ptr, storage, &priv->nfp_ipv4_off_list) {
447 		if (count >= NFP_FL_IPV4_ADDRS_MAX) {
448 			mutex_unlock(&priv->nfp_ipv4_off_lock);
449 			nfp_flower_cmsg_warn(app, "IPv4 offload exceeds limit.\n");
450 			return;
451 		}
452 		entry = list_entry(ptr, struct nfp_ipv4_addr_entry, list);
453 		payload.ipv4_addr[count++] = entry->ipv4_addr;
454 	}
455 	payload.count = cpu_to_be32(count);
456 	mutex_unlock(&priv->nfp_ipv4_off_lock);
457 
458 	nfp_flower_xmit_tun_conf(app, NFP_FLOWER_CMSG_TYPE_TUN_IPS,
459 				 sizeof(struct nfp_tun_ipv4_addr),
460 				 &payload, GFP_KERNEL);
461 }
462 
463 void nfp_tunnel_add_ipv4_off(struct nfp_app *app, __be32 ipv4)
464 {
465 	struct nfp_flower_priv *priv = app->priv;
466 	struct nfp_ipv4_addr_entry *entry;
467 	struct list_head *ptr, *storage;
468 
469 	mutex_lock(&priv->nfp_ipv4_off_lock);
470 	list_for_each_safe(ptr, storage, &priv->nfp_ipv4_off_list) {
471 		entry = list_entry(ptr, struct nfp_ipv4_addr_entry, list);
472 		if (entry->ipv4_addr == ipv4) {
473 			entry->ref_count++;
474 			mutex_unlock(&priv->nfp_ipv4_off_lock);
475 			return;
476 		}
477 	}
478 
479 	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
480 	if (!entry) {
481 		mutex_unlock(&priv->nfp_ipv4_off_lock);
482 		nfp_flower_cmsg_warn(app, "Mem error when offloading IP address.\n");
483 		return;
484 	}
485 	entry->ipv4_addr = ipv4;
486 	entry->ref_count = 1;
487 	list_add_tail(&entry->list, &priv->nfp_ipv4_off_list);
488 	mutex_unlock(&priv->nfp_ipv4_off_lock);
489 
490 	nfp_tun_write_ipv4_list(app);
491 }
492 
493 void nfp_tunnel_del_ipv4_off(struct nfp_app *app, __be32 ipv4)
494 {
495 	struct nfp_flower_priv *priv = app->priv;
496 	struct nfp_ipv4_addr_entry *entry;
497 	struct list_head *ptr, *storage;
498 
499 	mutex_lock(&priv->nfp_ipv4_off_lock);
500 	list_for_each_safe(ptr, storage, &priv->nfp_ipv4_off_list) {
501 		entry = list_entry(ptr, struct nfp_ipv4_addr_entry, list);
502 		if (entry->ipv4_addr == ipv4) {
503 			entry->ref_count--;
504 			if (!entry->ref_count) {
505 				list_del(&entry->list);
506 				kfree(entry);
507 			}
508 			break;
509 		}
510 	}
511 	mutex_unlock(&priv->nfp_ipv4_off_lock);
512 
513 	nfp_tun_write_ipv4_list(app);
514 }
515 
516 void nfp_tunnel_write_macs(struct nfp_app *app)
517 {
518 	struct nfp_flower_priv *priv = app->priv;
519 	struct nfp_tun_mac_offload_entry *entry;
520 	struct nfp_tun_mac_addr *payload;
521 	struct list_head *ptr, *storage;
522 	int mac_count, err, pay_size;
523 
524 	mutex_lock(&priv->nfp_mac_off_lock);
525 	if (!priv->nfp_mac_off_count) {
526 		mutex_unlock(&priv->nfp_mac_off_lock);
527 		return;
528 	}
529 
530 	pay_size = sizeof(struct nfp_tun_mac_addr) +
531 		   sizeof(struct index_mac_addr) * priv->nfp_mac_off_count;
532 
533 	payload = kzalloc(pay_size, GFP_KERNEL);
534 	if (!payload) {
535 		mutex_unlock(&priv->nfp_mac_off_lock);
536 		return;
537 	}
538 
539 	payload->count = cpu_to_be16(priv->nfp_mac_off_count);
540 
541 	mac_count = 0;
542 	list_for_each_safe(ptr, storage, &priv->nfp_mac_off_list) {
543 		entry = list_entry(ptr, struct nfp_tun_mac_offload_entry,
544 				   list);
545 		payload->addresses[mac_count].index = entry->index;
546 		ether_addr_copy(payload->addresses[mac_count].addr,
547 				entry->addr);
548 		mac_count++;
549 	}
550 
551 	err = nfp_flower_xmit_tun_conf(app, NFP_FLOWER_CMSG_TYPE_TUN_MAC,
552 				       pay_size, payload, GFP_KERNEL);
553 
554 	kfree(payload);
555 
556 	if (err) {
557 		mutex_unlock(&priv->nfp_mac_off_lock);
558 		/* Write failed so retain list for future retry. */
559 		return;
560 	}
561 
562 	/* If list was successfully offloaded, flush it. */
563 	list_for_each_safe(ptr, storage, &priv->nfp_mac_off_list) {
564 		entry = list_entry(ptr, struct nfp_tun_mac_offload_entry,
565 				   list);
566 		list_del(&entry->list);
567 		kfree(entry);
568 	}
569 
570 	priv->nfp_mac_off_count = 0;
571 	mutex_unlock(&priv->nfp_mac_off_lock);
572 }
573 
574 static int nfp_tun_get_mac_idx(struct nfp_app *app, int ifindex)
575 {
576 	struct nfp_flower_priv *priv = app->priv;
577 	struct nfp_tun_mac_non_nfp_idx *entry;
578 	struct list_head *ptr, *storage;
579 	int idx;
580 
581 	mutex_lock(&priv->nfp_mac_index_lock);
582 	list_for_each_safe(ptr, storage, &priv->nfp_mac_index_list) {
583 		entry = list_entry(ptr, struct nfp_tun_mac_non_nfp_idx, list);
584 		if (entry->ifindex == ifindex) {
585 			idx = entry->index;
586 			mutex_unlock(&priv->nfp_mac_index_lock);
587 			return idx;
588 		}
589 	}
590 
591 	idx = ida_simple_get(&priv->nfp_mac_off_ids, 0,
592 			     NFP_MAX_MAC_INDEX, GFP_KERNEL);
593 	if (idx < 0) {
594 		mutex_unlock(&priv->nfp_mac_index_lock);
595 		return idx;
596 	}
597 
598 	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
599 	if (!entry) {
600 		mutex_unlock(&priv->nfp_mac_index_lock);
601 		return -ENOMEM;
602 	}
603 	entry->ifindex = ifindex;
604 	entry->index = idx;
605 	list_add_tail(&entry->list, &priv->nfp_mac_index_list);
606 	mutex_unlock(&priv->nfp_mac_index_lock);
607 
608 	return idx;
609 }
610 
611 static void nfp_tun_del_mac_idx(struct nfp_app *app, int ifindex)
612 {
613 	struct nfp_flower_priv *priv = app->priv;
614 	struct nfp_tun_mac_non_nfp_idx *entry;
615 	struct list_head *ptr, *storage;
616 
617 	mutex_lock(&priv->nfp_mac_index_lock);
618 	list_for_each_safe(ptr, storage, &priv->nfp_mac_index_list) {
619 		entry = list_entry(ptr, struct nfp_tun_mac_non_nfp_idx, list);
620 		if (entry->ifindex == ifindex) {
621 			ida_simple_remove(&priv->nfp_mac_off_ids,
622 					  entry->index);
623 			list_del(&entry->list);
624 			kfree(entry);
625 			break;
626 		}
627 	}
628 	mutex_unlock(&priv->nfp_mac_index_lock);
629 }
630 
631 static void nfp_tun_add_to_mac_offload_list(struct net_device *netdev,
632 					    struct nfp_app *app)
633 {
634 	struct nfp_flower_priv *priv = app->priv;
635 	struct nfp_tun_mac_offload_entry *entry;
636 	u16 nfp_mac_idx;
637 	int port = 0;
638 
639 	/* Check if MAC should be offloaded. */
640 	if (!is_valid_ether_addr(netdev->dev_addr))
641 		return;
642 
643 	if (nfp_netdev_is_nfp_repr(netdev))
644 		port = nfp_repr_get_port_id(netdev);
645 	else if (!nfp_tun_is_netdev_to_offload(netdev))
646 		return;
647 
648 	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
649 	if (!entry) {
650 		nfp_flower_cmsg_warn(app, "Mem fail when offloading MAC.\n");
651 		return;
652 	}
653 
654 	if (FIELD_GET(NFP_FLOWER_CMSG_PORT_TYPE, port) ==
655 	    NFP_FLOWER_CMSG_PORT_TYPE_PHYS_PORT) {
656 		nfp_mac_idx = port << 8 | NFP_FLOWER_CMSG_PORT_TYPE_PHYS_PORT;
657 	} else if (FIELD_GET(NFP_FLOWER_CMSG_PORT_TYPE, port) ==
658 		   NFP_FLOWER_CMSG_PORT_TYPE_PCIE_PORT) {
659 		port = FIELD_GET(NFP_FLOWER_CMSG_PORT_VNIC, port);
660 		nfp_mac_idx = port << 8 | NFP_FLOWER_CMSG_PORT_TYPE_PCIE_PORT;
661 	} else {
662 		/* Must assign our own unique 8-bit index. */
663 		int idx = nfp_tun_get_mac_idx(app, netdev->ifindex);
664 
665 		if (idx < 0) {
666 			nfp_flower_cmsg_warn(app, "Can't assign non-repr MAC index.\n");
667 			kfree(entry);
668 			return;
669 		}
670 		nfp_mac_idx = idx << 8 | NFP_FLOWER_CMSG_PORT_TYPE_OTHER_PORT;
671 	}
672 
673 	entry->index = cpu_to_be16(nfp_mac_idx);
674 	ether_addr_copy(entry->addr, netdev->dev_addr);
675 
676 	mutex_lock(&priv->nfp_mac_off_lock);
677 	priv->nfp_mac_off_count++;
678 	list_add_tail(&entry->list, &priv->nfp_mac_off_list);
679 	mutex_unlock(&priv->nfp_mac_off_lock);
680 }
681 
682 static int nfp_tun_mac_event_handler(struct notifier_block *nb,
683 				     unsigned long event, void *ptr)
684 {
685 	struct nfp_flower_priv *app_priv;
686 	struct net_device *netdev;
687 	struct nfp_app *app;
688 
689 	if (event == NETDEV_DOWN || event == NETDEV_UNREGISTER) {
690 		app_priv = container_of(nb, struct nfp_flower_priv,
691 					nfp_tun_mac_nb);
692 		app = app_priv->app;
693 		netdev = netdev_notifier_info_to_dev(ptr);
694 
695 		/* If non-nfp netdev then free its offload index. */
696 		if (nfp_tun_is_netdev_to_offload(netdev))
697 			nfp_tun_del_mac_idx(app, netdev->ifindex);
698 	} else if (event == NETDEV_UP || event == NETDEV_CHANGEADDR ||
699 		   event == NETDEV_REGISTER) {
700 		app_priv = container_of(nb, struct nfp_flower_priv,
701 					nfp_tun_mac_nb);
702 		app = app_priv->app;
703 		netdev = netdev_notifier_info_to_dev(ptr);
704 
705 		nfp_tun_add_to_mac_offload_list(netdev, app);
706 
707 		/* Force a list write to keep NFP up to date. */
708 		nfp_tunnel_write_macs(app);
709 	}
710 	return NOTIFY_OK;
711 }
712 
713 int nfp_tunnel_config_start(struct nfp_app *app)
714 {
715 	struct nfp_flower_priv *priv = app->priv;
716 	struct net_device *netdev;
717 	int err;
718 
719 	/* Initialise priv data for MAC offloading. */
720 	priv->nfp_mac_off_count = 0;
721 	mutex_init(&priv->nfp_mac_off_lock);
722 	INIT_LIST_HEAD(&priv->nfp_mac_off_list);
723 	priv->nfp_tun_mac_nb.notifier_call = nfp_tun_mac_event_handler;
724 	mutex_init(&priv->nfp_mac_index_lock);
725 	INIT_LIST_HEAD(&priv->nfp_mac_index_list);
726 	ida_init(&priv->nfp_mac_off_ids);
727 
728 	/* Initialise priv data for IPv4 offloading. */
729 	mutex_init(&priv->nfp_ipv4_off_lock);
730 	INIT_LIST_HEAD(&priv->nfp_ipv4_off_list);
731 
732 	/* Initialise priv data for neighbour offloading. */
733 	spin_lock_init(&priv->nfp_neigh_off_lock);
734 	INIT_LIST_HEAD(&priv->nfp_neigh_off_list);
735 	priv->nfp_tun_neigh_nb.notifier_call = nfp_tun_neigh_event_handler;
736 
737 	err = register_netdevice_notifier(&priv->nfp_tun_mac_nb);
738 	if (err)
739 		goto err_free_mac_ida;
740 
741 	err = register_netevent_notifier(&priv->nfp_tun_neigh_nb);
742 	if (err)
743 		goto err_unreg_mac_nb;
744 
745 	/* Parse netdevs already registered for MACs that need offloaded. */
746 	rtnl_lock();
747 	for_each_netdev(&init_net, netdev)
748 		nfp_tun_add_to_mac_offload_list(netdev, app);
749 	rtnl_unlock();
750 
751 	return 0;
752 
753 err_unreg_mac_nb:
754 	unregister_netdevice_notifier(&priv->nfp_tun_mac_nb);
755 err_free_mac_ida:
756 	ida_destroy(&priv->nfp_mac_off_ids);
757 	return err;
758 }
759 
760 void nfp_tunnel_config_stop(struct nfp_app *app)
761 {
762 	struct nfp_tun_mac_offload_entry *mac_entry;
763 	struct nfp_flower_priv *priv = app->priv;
764 	struct nfp_ipv4_route_entry *route_entry;
765 	struct nfp_tun_mac_non_nfp_idx *mac_idx;
766 	struct nfp_ipv4_addr_entry *ip_entry;
767 	struct list_head *ptr, *storage;
768 
769 	unregister_netdevice_notifier(&priv->nfp_tun_mac_nb);
770 	unregister_netevent_notifier(&priv->nfp_tun_neigh_nb);
771 
772 	/* Free any memory that may be occupied by MAC list. */
773 	list_for_each_safe(ptr, storage, &priv->nfp_mac_off_list) {
774 		mac_entry = list_entry(ptr, struct nfp_tun_mac_offload_entry,
775 				       list);
776 		list_del(&mac_entry->list);
777 		kfree(mac_entry);
778 	}
779 
780 	/* Free any memory that may be occupied by MAC index list. */
781 	list_for_each_safe(ptr, storage, &priv->nfp_mac_index_list) {
782 		mac_idx = list_entry(ptr, struct nfp_tun_mac_non_nfp_idx,
783 				     list);
784 		list_del(&mac_idx->list);
785 		kfree(mac_idx);
786 	}
787 
788 	ida_destroy(&priv->nfp_mac_off_ids);
789 
790 	/* Free any memory that may be occupied by ipv4 list. */
791 	list_for_each_safe(ptr, storage, &priv->nfp_ipv4_off_list) {
792 		ip_entry = list_entry(ptr, struct nfp_ipv4_addr_entry, list);
793 		list_del(&ip_entry->list);
794 		kfree(ip_entry);
795 	}
796 
797 	/* Free any memory that may be occupied by the route list. */
798 	list_for_each_safe(ptr, storage, &priv->nfp_neigh_off_list) {
799 		route_entry = list_entry(ptr, struct nfp_ipv4_route_entry,
800 					 list);
801 		list_del(&route_entry->list);
802 		kfree(route_entry);
803 	}
804 }
805