xref: /freebsd/sys/ofed/drivers/infiniband/core/ib_roce_gid_mgmt.c (revision d8afb9b13f4141dc42fb1eb1c7c6a45bd2cd0bc4)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0
3  *
4  * Copyright (c) 2015-2017, Mellanox Technologies inc.  All rights reserved.
5  *
6  * This software is available to you under a choice of one of two
7  * licenses.  You may choose to be licensed under the terms of the GNU
8  * General Public License (GPL) Version 2, available from the file
9  * COPYING in the main directory of this source tree, or the
10  * OpenIB.org BSD license below:
11  *
12  *     Redistribution and use in source and binary forms, with or
13  *     without modification, are permitted provided that the following
14  *     conditions are met:
15  *
16  *      - Redistributions of source code must retain the above
17  *        copyright notice, this list of conditions and the following
18  *        disclaimer.
19  *
20  *      - Redistributions in binary form must reproduce the above
21  *        copyright notice, this list of conditions and the following
22  *        disclaimer in the documentation and/or other materials
23  *        provided with the distribution.
24  *
25  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32  * SOFTWARE.
33  */
34 
35 #include <sys/cdefs.h>
36 #include "core_priv.h"
37 #include <sys/eventhandler.h>
38 
39 #include <linux/in.h>
40 #include <linux/in6.h>
41 #include <linux/rcupdate.h>
42 
43 #include <rdma/ib_cache.h>
44 #include <rdma/ib_addr.h>
45 
46 #include <netinet6/scope6_var.h>
47 
48 static struct workqueue_struct *roce_gid_mgmt_wq;
49 
50 enum gid_op_type {
51 	GID_DEL = 0,
52 	GID_ADD
53 };
54 
55 struct roce_netdev_event_work {
56 	struct work_struct work;
57 	if_t ndev;
58 };
59 
60 struct roce_rescan_work {
61 	struct work_struct	work;
62 	struct ib_device	*ib_dev;
63 };
64 
65 static const struct {
66 	bool (*is_supported)(const struct ib_device *device, u8 port_num);
67 	enum ib_gid_type gid_type;
68 } PORT_CAP_TO_GID_TYPE[] = {
69 	{rdma_protocol_roce_eth_encap, IB_GID_TYPE_ROCE},
70 	{rdma_protocol_roce_udp_encap, IB_GID_TYPE_ROCE_UDP_ENCAP},
71 };
72 
73 #define CAP_TO_GID_TABLE_SIZE	ARRAY_SIZE(PORT_CAP_TO_GID_TYPE)
74 
roce_gid_type_mask_support(struct ib_device * ib_dev,u8 port)75 unsigned long roce_gid_type_mask_support(struct ib_device *ib_dev, u8 port)
76 {
77 	int i;
78 	unsigned int ret_flags = 0;
79 
80 	if (!rdma_protocol_roce(ib_dev, port))
81 		return 1UL << IB_GID_TYPE_IB;
82 
83 	for (i = 0; i < CAP_TO_GID_TABLE_SIZE; i++)
84 		if (PORT_CAP_TO_GID_TYPE[i].is_supported(ib_dev, port))
85 			ret_flags |= 1UL << PORT_CAP_TO_GID_TYPE[i].gid_type;
86 
87 	return ret_flags;
88 }
89 EXPORT_SYMBOL(roce_gid_type_mask_support);
90 
update_gid(enum gid_op_type gid_op,struct ib_device * ib_dev,u8 port,union ib_gid * gid,if_t ndev)91 static void update_gid(enum gid_op_type gid_op, struct ib_device *ib_dev,
92     u8 port, union ib_gid *gid, if_t ndev)
93 {
94 	int i;
95 	unsigned long gid_type_mask = roce_gid_type_mask_support(ib_dev, port);
96 	struct ib_gid_attr gid_attr;
97 
98 	memset(&gid_attr, 0, sizeof(gid_attr));
99 	gid_attr.ndev = ndev;
100 
101 	for (i = 0; i != IB_GID_TYPE_SIZE; i++) {
102 		if ((1UL << i) & gid_type_mask) {
103 			gid_attr.gid_type = i;
104 			switch (gid_op) {
105 			case GID_ADD:
106 				ib_cache_gid_add(ib_dev, port,
107 						 gid, &gid_attr);
108 				break;
109 			case GID_DEL:
110 				ib_cache_gid_del(ib_dev, port,
111 						 gid, &gid_attr);
112 				break;
113 			}
114 		}
115 	}
116 }
117 
118 static bool
roce_gid_match_netdev(struct ib_device * ib_dev,u8 port,if_t idev,void * cookie)119 roce_gid_match_netdev(struct ib_device *ib_dev, u8 port,
120     if_t idev, void *cookie)
121 {
122 	if_t ndev = (if_t )cookie;
123 	if (idev == NULL)
124 		return (false);
125 	return (ndev == idev);
126 }
127 
128 static bool
roce_gid_match_all(struct ib_device * ib_dev,u8 port,if_t idev,void * cookie)129 roce_gid_match_all(struct ib_device *ib_dev, u8 port,
130     if_t idev, void *cookie)
131 {
132 	if (idev == NULL)
133 		return (false);
134 	return (true);
135 }
136 
137 static int
roce_gid_enum_netdev_default(struct ib_device * ib_dev,u8 port,if_t idev)138 roce_gid_enum_netdev_default(struct ib_device *ib_dev,
139     u8 port, if_t idev)
140 {
141 	unsigned long gid_type_mask;
142 
143 	gid_type_mask = roce_gid_type_mask_support(ib_dev, port);
144 
145 	ib_cache_gid_set_default_gid(ib_dev, port, idev, gid_type_mask,
146 				     IB_CACHE_GID_DEFAULT_MODE_SET);
147 
148 	return (hweight_long(gid_type_mask));
149 }
150 
151 struct ipx_entry {
152 	STAILQ_ENTRY(ipx_entry)	entry;
153 	union ipx_addr {
154 		struct sockaddr sa[0];
155 		struct sockaddr_in v4;
156 		struct sockaddr_in6 v6;
157 	} ipx_addr;
158 	if_t ndev;
159 };
160 
161 STAILQ_HEAD(ipx_queue, ipx_entry);
162 
163 #ifdef INET
164 static u_int
roce_gid_update_addr_ifa4_cb(void * arg,struct ifaddr * ifa,u_int count)165 roce_gid_update_addr_ifa4_cb(void *arg, struct ifaddr *ifa, u_int count)
166 {
167 	struct ipx_queue *ipx_head = arg;
168 	struct ipx_entry *entry;
169 
170 	entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
171 	if (entry == NULL)
172 		return (0);
173 	entry->ipx_addr.v4 = *((struct sockaddr_in *)ifa->ifa_addr);
174 	entry->ndev = ifa->ifa_ifp;
175 	STAILQ_INSERT_TAIL(ipx_head, entry, entry);
176 
177 	return (1);
178 }
179 #endif
180 
181 #ifdef INET6
182 static u_int
roce_gid_update_addr_ifa6_cb(void * arg,struct ifaddr * ifa,u_int count)183 roce_gid_update_addr_ifa6_cb(void *arg, struct ifaddr *ifa, u_int count)
184 {
185 	struct ipx_queue *ipx_head = arg;
186 	struct ipx_entry *entry;
187 
188 	entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
189 	if (entry == NULL)
190 		return (0);
191 	entry->ipx_addr.v6 = *((struct sockaddr_in6 *)ifa->ifa_addr);
192 	entry->ndev = ifa->ifa_ifp;
193 
194 	/* trash IPv6 scope ID */
195 	sa6_recoverscope(&entry->ipx_addr.v6);
196 	entry->ipx_addr.v6.sin6_scope_id = 0;
197 
198 	STAILQ_INSERT_TAIL(ipx_head, entry, entry);
199 
200 	return (1);
201 }
202 #endif
203 
204 static void
roce_gid_update_addr_callback(struct ib_device * device,u8 port,if_t ndev,void * cookie)205 roce_gid_update_addr_callback(struct ib_device *device, u8 port,
206     if_t ndev, void *cookie)
207 {
208 	struct epoch_tracker et;
209 	struct if_iter iter;
210 	struct ipx_entry *entry;
211 	VNET_ITERATOR_DECL(vnet_iter);
212 	const struct ib_gid_attr *sgid_attr;
213 	union ib_gid gid;
214 	if_t ifp;
215 	int default_gids;
216 	int gid_tbl_len;
217 	int i;
218 
219 	struct ipx_queue ipx_head;
220 
221 	STAILQ_INIT(&ipx_head);
222 
223 	/* make sure default GIDs are in */
224 	default_gids = roce_gid_enum_netdev_default(device, port, ndev);
225 
226 	VNET_LIST_RLOCK();
227 	VNET_FOREACH(vnet_iter) {
228 	    CURVNET_SET(vnet_iter);
229 	    NET_EPOCH_ENTER(et);
230 	    for (ifp = if_iter_start(&iter); ifp != NULL; ifp = if_iter_next(&iter)) {
231 		if (ifp != ndev) {
232 			if (if_gettype(ifp) != IFT_L2VLAN)
233 				continue;
234 			if (ndev != rdma_vlan_dev_real_dev(ifp))
235 				continue;
236 		}
237 
238 		/* clone address information for IPv4 and IPv6 */
239 #if defined(INET)
240 		if_foreach_addr_type(ifp, AF_INET, roce_gid_update_addr_ifa4_cb, &ipx_head);
241 #endif
242 #if defined(INET6)
243 		if_foreach_addr_type(ifp, AF_INET6, roce_gid_update_addr_ifa6_cb, &ipx_head);
244 #endif
245 	    }
246 	    NET_EPOCH_EXIT(et);
247 	    CURVNET_RESTORE();
248 	}
249 	VNET_LIST_RUNLOCK();
250 
251 	/* add missing GIDs, if any */
252 	STAILQ_FOREACH(entry, &ipx_head, entry) {
253 		unsigned long gid_type_mask = roce_gid_type_mask_support(device, port);
254 
255 		if (rdma_ip2gid(&entry->ipx_addr.sa[0], &gid) != 0)
256 			continue;
257 
258 		for (i = 0; i != IB_GID_TYPE_SIZE; i++) {
259 			if (!((1UL << i) & gid_type_mask))
260 				continue;
261 			/* check if entry found */
262 			sgid_attr = rdma_find_gid_by_port(device, &gid, i,
263                                                           port, entry->ndev);
264 			if (!IS_ERR(sgid_attr)) {
265 				rdma_put_gid_attr(sgid_attr);
266 				break;
267 			}
268 		}
269 		if (i != IB_GID_TYPE_SIZE)
270 			continue;
271 		/* add new GID */
272 		update_gid(GID_ADD, device, port, &gid, entry->ndev);
273 	}
274 
275 	gid_tbl_len = device->port_immutable[port].gid_tbl_len;
276 
277 	/* remove stale GIDs, if any */
278 	for (i = default_gids; i < gid_tbl_len; i++) {
279 		union ipx_addr ipx;
280 
281 		sgid_attr = rdma_get_gid_attr(device, port, i);
282 		if (IS_ERR(sgid_attr))
283 			continue;
284 
285 		ndev = sgid_attr->ndev;
286 		gid = sgid_attr->gid;
287 		rdma_put_gid_attr(sgid_attr);
288 
289 		/* check for valid network device pointer */
290 		if (ndev == NULL)
291 			continue;
292 
293 		/* don't delete empty entries */
294 		if (rdma_is_zero_gid(&gid))
295 			continue;
296 
297 		/* zero default */
298 		memset(&ipx, 0, sizeof(ipx));
299 
300 		rdma_gid2ip(&ipx.sa[0], &gid);
301 
302 		STAILQ_FOREACH(entry, &ipx_head, entry) {
303 			if (entry->ndev == ndev &&
304 			    memcmp(&entry->ipx_addr, &ipx, sizeof(ipx)) == 0)
305 				break;
306 		}
307 		/* check if entry found */
308 		if (entry != NULL)
309 			continue;
310 
311 		/* remove GID */
312 		update_gid(GID_DEL, device, port, &gid, ndev);
313 	}
314 
315 	while ((entry = STAILQ_FIRST(&ipx_head))) {
316 		STAILQ_REMOVE_HEAD(&ipx_head, entry);
317 		kfree(entry);
318 	}
319 }
320 
321 static void
roce_gid_queue_scan_event_handler(struct work_struct * _work)322 roce_gid_queue_scan_event_handler(struct work_struct *_work)
323 {
324 	struct roce_netdev_event_work *work =
325 		container_of(_work, struct roce_netdev_event_work, work);
326 
327 	ib_enum_all_roce_netdevs(roce_gid_match_netdev, work->ndev,
328 	    roce_gid_update_addr_callback, NULL);
329 
330 	dev_put(work->ndev);
331 	kfree(work);
332 }
333 
334 static void
roce_gid_queue_scan_event(if_t ndev)335 roce_gid_queue_scan_event(if_t ndev)
336 {
337 	struct roce_netdev_event_work *work;
338 
339 retry:
340 	switch (if_gettype(ndev)) {
341 	case IFT_ETHER:
342 		break;
343 	case IFT_L2VLAN:
344 		ndev = rdma_vlan_dev_real_dev(ndev);
345 		if (ndev != NULL)
346 			goto retry;
347 		/* FALLTHROUGH */
348 	default:
349 		return;
350 	}
351 
352 	work = kmalloc(sizeof(*work), GFP_ATOMIC);
353 	if (!work)
354 		return;
355 
356 	INIT_WORK(&work->work, roce_gid_queue_scan_event_handler);
357 	dev_hold(ndev);
358 
359 	work->ndev = ndev;
360 
361 	queue_work(roce_gid_mgmt_wq, &work->work);
362 }
363 
364 static void
roce_gid_delete_all_event_handler(struct work_struct * _work)365 roce_gid_delete_all_event_handler(struct work_struct *_work)
366 {
367 	struct roce_netdev_event_work *work =
368 		container_of(_work, struct roce_netdev_event_work, work);
369 
370 	ib_cache_gid_del_all_by_netdev(work->ndev);
371 	dev_put(work->ndev);
372 	kfree(work);
373 }
374 
375 static void
roce_gid_delete_all_event(if_t ndev)376 roce_gid_delete_all_event(if_t ndev)
377 {
378 	struct roce_netdev_event_work *work;
379 
380 	work = kmalloc(sizeof(*work), GFP_ATOMIC);
381 	if (!work)
382 		return;
383 
384 	INIT_WORK(&work->work, roce_gid_delete_all_event_handler);
385 	dev_hold(ndev);
386 	work->ndev = ndev;
387 	queue_work(roce_gid_mgmt_wq, &work->work);
388 
389 	/* make sure job is complete before returning */
390 	flush_workqueue(roce_gid_mgmt_wq);
391 }
392 
393 static int
inetaddr_event(struct notifier_block * this,unsigned long event,void * ptr)394 inetaddr_event(struct notifier_block *this, unsigned long event, void *ptr)
395 {
396 	if_t ndev = netdev_notifier_info_to_ifp(ptr);
397 
398 	switch (event) {
399 	case NETDEV_UNREGISTER:
400 		roce_gid_delete_all_event(ndev);
401 		break;
402 	case NETDEV_REGISTER:
403 	case NETDEV_CHANGEADDR:
404 	case NETDEV_CHANGEIFADDR:
405 		roce_gid_queue_scan_event(ndev);
406 		break;
407 	default:
408 		break;
409 	}
410 	return NOTIFY_DONE;
411 }
412 
413 static struct notifier_block nb_inetaddr = {
414 	.notifier_call = inetaddr_event
415 };
416 
417 static eventhandler_tag eh_ifnet_event;
418 
419 static void
roce_ifnet_event(void * arg,if_t ifp,int event)420 roce_ifnet_event(void *arg, if_t ifp, int event)
421 {
422 	if (event != IFNET_EVENT_PCP || is_vlan_dev(ifp))
423 		return;
424 
425 	/* make sure GID table is reloaded */
426 	roce_gid_delete_all_event(ifp);
427 	roce_gid_queue_scan_event(ifp);
428 }
429 
430 static void
roce_rescan_device_handler(struct work_struct * _work)431 roce_rescan_device_handler(struct work_struct *_work)
432 {
433 	struct roce_rescan_work *work =
434 	    container_of(_work, struct roce_rescan_work, work);
435 
436 	ib_enum_roce_netdev(work->ib_dev, roce_gid_match_all, NULL,
437 	    roce_gid_update_addr_callback, NULL);
438 	kfree(work);
439 }
440 
441 /* Caller must flush system workqueue before removing the ib_device */
roce_rescan_device(struct ib_device * ib_dev)442 int roce_rescan_device(struct ib_device *ib_dev)
443 {
444 	struct roce_rescan_work *work = kmalloc(sizeof(*work), GFP_KERNEL);
445 
446 	if (!work)
447 		return -ENOMEM;
448 
449 	work->ib_dev = ib_dev;
450 	INIT_WORK(&work->work, roce_rescan_device_handler);
451 	queue_work(roce_gid_mgmt_wq, &work->work);
452 
453 	return 0;
454 }
455 
roce_gid_mgmt_init(void)456 int __init roce_gid_mgmt_init(void)
457 {
458 	roce_gid_mgmt_wq = alloc_ordered_workqueue("roce_gid_mgmt_wq", 0);
459 	if (!roce_gid_mgmt_wq) {
460 		pr_warn("roce_gid_mgmt: can't allocate work queue\n");
461 		return -ENOMEM;
462 	}
463 
464 	register_inetaddr_notifier(&nb_inetaddr);
465 
466 	/*
467 	 * We rely on the netdevice notifier to enumerate all existing
468 	 * devices in the system. Register to this notifier last to
469 	 * make sure we will not miss any IP add/del callbacks.
470 	 */
471 	register_netdevice_notifier(&nb_inetaddr);
472 
473 	eh_ifnet_event = EVENTHANDLER_REGISTER(ifnet_event,
474 	    roce_ifnet_event, NULL, EVENTHANDLER_PRI_ANY);
475 
476 	return 0;
477 }
478 
roce_gid_mgmt_cleanup(void)479 void __exit roce_gid_mgmt_cleanup(void)
480 {
481 
482 	if (eh_ifnet_event != NULL)
483 		EVENTHANDLER_DEREGISTER(ifnet_event, eh_ifnet_event);
484 
485 	unregister_inetaddr_notifier(&nb_inetaddr);
486 	unregister_netdevice_notifier(&nb_inetaddr);
487 
488 	/*
489 	 * Ensure all gid deletion tasks complete before we go down,
490 	 * to avoid any reference to free'd memory. By the time
491 	 * ib-core is removed, all physical devices have been removed,
492 	 * so no issue with remaining hardware contexts.
493 	 */
494 	synchronize_rcu();
495 	drain_workqueue(roce_gid_mgmt_wq);
496 	destroy_workqueue(roce_gid_mgmt_wq);
497 }
498