2 * SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0
4 * Copyright (c) 2015-2017, Mellanox Technologies inc. All rights reserved.
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:
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
16 * - Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
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.
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
35 #include <sys/cdefs.h>
36 __FBSDID("$FreeBSD$");
38 #include "core_priv.h"
41 #include <linux/in6.h>
42 #include <linux/rcupdate.h>
44 #include <rdma/ib_cache.h>
45 #include <rdma/ib_addr.h>
47 #include <netinet6/scope6_var.h>
49 static struct workqueue_struct *roce_gid_mgmt_wq;
56 struct roce_netdev_event_work {
57 struct work_struct work;
58 struct net_device *ndev;
61 struct roce_rescan_work {
62 struct work_struct work;
63 struct ib_device *ib_dev;
67 bool (*is_supported)(const struct ib_device *device, u8 port_num);
68 enum ib_gid_type gid_type;
69 } PORT_CAP_TO_GID_TYPE[] = {
70 {rdma_protocol_roce_eth_encap, IB_GID_TYPE_ROCE},
71 {rdma_protocol_roce_udp_encap, IB_GID_TYPE_ROCE_UDP_ENCAP},
74 #define CAP_TO_GID_TABLE_SIZE ARRAY_SIZE(PORT_CAP_TO_GID_TYPE)
76 unsigned long roce_gid_type_mask_support(struct ib_device *ib_dev, u8 port)
79 unsigned int ret_flags = 0;
81 if (!rdma_protocol_roce(ib_dev, port))
82 return 1UL << IB_GID_TYPE_IB;
84 for (i = 0; i < CAP_TO_GID_TABLE_SIZE; i++)
85 if (PORT_CAP_TO_GID_TYPE[i].is_supported(ib_dev, port))
86 ret_flags |= 1UL << PORT_CAP_TO_GID_TYPE[i].gid_type;
90 EXPORT_SYMBOL(roce_gid_type_mask_support);
92 static void update_gid(enum gid_op_type gid_op, struct ib_device *ib_dev,
93 u8 port, union ib_gid *gid, struct net_device *ndev)
96 unsigned long gid_type_mask = roce_gid_type_mask_support(ib_dev, port);
97 struct ib_gid_attr gid_attr;
99 memset(&gid_attr, 0, sizeof(gid_attr));
100 gid_attr.ndev = ndev;
102 for (i = 0; i != IB_GID_TYPE_SIZE; i++) {
103 if ((1UL << i) & gid_type_mask) {
104 gid_attr.gid_type = i;
107 ib_cache_gid_add(ib_dev, port,
111 ib_cache_gid_del(ib_dev, port,
120 roce_gid_match_netdev(struct ib_device *ib_dev, u8 port,
121 struct net_device *idev, void *cookie)
123 struct net_device *ndev = (struct net_device *)cookie;
126 return (ndev == idev);
130 roce_gid_match_all(struct ib_device *ib_dev, u8 port,
131 struct net_device *idev, void *cookie)
139 roce_gid_enum_netdev_default(struct ib_device *ib_dev,
140 u8 port, struct net_device *idev)
142 unsigned long gid_type_mask;
144 gid_type_mask = roce_gid_type_mask_support(ib_dev, port);
146 ib_cache_gid_set_default_gid(ib_dev, port, idev, gid_type_mask,
147 IB_CACHE_GID_DEFAULT_MODE_SET);
149 return (hweight_long(gid_type_mask));
153 roce_gid_update_addr_callback(struct ib_device *device, u8 port,
154 struct net_device *ndev, void *cookie)
157 STAILQ_ENTRY(ipx_entry) entry;
159 struct sockaddr sa[0];
160 struct sockaddr_in v4;
161 struct sockaddr_in6 v6;
163 struct net_device *ndev;
165 struct ipx_entry *entry;
166 struct net_device *idev;
167 #if defined(INET) || defined(INET6)
170 VNET_ITERATOR_DECL(vnet_iter);
171 struct ib_gid_attr gid_attr;
177 STAILQ_HEAD(, ipx_entry) ipx_head;
179 STAILQ_INIT(&ipx_head);
181 /* make sure default GIDs are in */
182 default_gids = roce_gid_enum_netdev_default(device, port, ndev);
185 VNET_FOREACH(vnet_iter) {
186 CURVNET_SET(vnet_iter);
188 CK_STAILQ_FOREACH(idev, &V_ifnet, if_link) {
189 struct epoch_tracker et;
192 if (idev->if_type != IFT_L2VLAN)
194 if (ndev != rdma_vlan_dev_real_dev(idev))
198 /* clone address information for IPv4 and IPv6 */
201 CK_STAILQ_FOREACH(ifa, &idev->if_addrhead, ifa_link) {
202 if (ifa->ifa_addr == NULL ||
203 ifa->ifa_addr->sa_family != AF_INET)
205 entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
207 pr_warn("roce_gid_update_addr_callback: "
208 "couldn't allocate entry for IPv4 update\n");
211 entry->ipx_addr.v4 = *((struct sockaddr_in *)ifa->ifa_addr);
213 STAILQ_INSERT_TAIL(&ipx_head, entry, entry);
217 CK_STAILQ_FOREACH(ifa, &idev->if_addrhead, ifa_link) {
218 if (ifa->ifa_addr == NULL ||
219 ifa->ifa_addr->sa_family != AF_INET6)
221 entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
223 pr_warn("roce_gid_update_addr_callback: "
224 "couldn't allocate entry for IPv6 update\n");
227 entry->ipx_addr.v6 = *((struct sockaddr_in6 *)ifa->ifa_addr);
230 /* trash IPv6 scope ID */
231 sa6_recoverscope(&entry->ipx_addr.v6);
232 entry->ipx_addr.v6.sin6_scope_id = 0;
234 STAILQ_INSERT_TAIL(&ipx_head, entry, entry);
244 /* add missing GIDs, if any */
245 STAILQ_FOREACH(entry, &ipx_head, entry) {
246 unsigned long gid_type_mask = roce_gid_type_mask_support(device, port);
248 if (rdma_ip2gid(&entry->ipx_addr.sa[0], &gid) != 0)
251 for (i = 0; i != IB_GID_TYPE_SIZE; i++) {
252 if (!((1UL << i) & gid_type_mask))
254 /* check if entry found */
255 if (ib_find_cached_gid_by_port(device, &gid, i,
256 port, entry->ndev, &index_num) == 0)
259 if (i != IB_GID_TYPE_SIZE)
262 update_gid(GID_ADD, device, port, &gid, entry->ndev);
265 /* remove stale GIDs, if any */
266 for (i = default_gids; ib_get_cached_gid(device, port, i, &gid, &gid_attr) == 0; i++) {
269 /* check for valid network device pointer */
270 ndev = gid_attr.ndev;
275 /* don't delete empty entries */
276 if (memcmp(&gid, &zgid, sizeof(zgid)) == 0)
280 memset(&ipx, 0, sizeof(ipx));
282 rdma_gid2ip(&ipx.sa[0], &gid);
284 STAILQ_FOREACH(entry, &ipx_head, entry) {
285 if (entry->ndev == ndev &&
286 memcmp(&entry->ipx_addr, &ipx, sizeof(ipx)) == 0)
289 /* check if entry found */
294 update_gid(GID_DEL, device, port, &gid, ndev);
297 while ((entry = STAILQ_FIRST(&ipx_head))) {
298 STAILQ_REMOVE_HEAD(&ipx_head, entry);
304 roce_gid_queue_scan_event_handler(struct work_struct *_work)
306 struct roce_netdev_event_work *work =
307 container_of(_work, struct roce_netdev_event_work, work);
309 ib_enum_all_roce_netdevs(roce_gid_match_netdev, work->ndev,
310 roce_gid_update_addr_callback, NULL);
317 roce_gid_queue_scan_event(struct net_device *ndev)
319 struct roce_netdev_event_work *work;
322 switch (ndev->if_type) {
326 ndev = rdma_vlan_dev_real_dev(ndev);
334 work = kmalloc(sizeof(*work), GFP_ATOMIC);
336 pr_warn("roce_gid_mgmt: Couldn't allocate work for addr_event\n");
340 INIT_WORK(&work->work, roce_gid_queue_scan_event_handler);
345 queue_work(roce_gid_mgmt_wq, &work->work);
349 roce_gid_delete_all_event_handler(struct work_struct *_work)
351 struct roce_netdev_event_work *work =
352 container_of(_work, struct roce_netdev_event_work, work);
354 ib_cache_gid_del_all_by_netdev(work->ndev);
360 roce_gid_delete_all_event(struct net_device *ndev)
362 struct roce_netdev_event_work *work;
364 work = kmalloc(sizeof(*work), GFP_ATOMIC);
366 pr_warn("roce_gid_mgmt: Couldn't allocate work for addr_event\n");
370 INIT_WORK(&work->work, roce_gid_delete_all_event_handler);
373 queue_work(roce_gid_mgmt_wq, &work->work);
375 /* make sure job is complete before returning */
376 flush_workqueue(roce_gid_mgmt_wq);
380 inetaddr_event(struct notifier_block *this, unsigned long event, void *ptr)
382 struct net_device *ndev = ptr;
385 case NETDEV_UNREGISTER:
386 roce_gid_delete_all_event(ndev);
388 case NETDEV_REGISTER:
389 case NETDEV_CHANGEADDR:
390 case NETDEV_CHANGEIFADDR:
391 roce_gid_queue_scan_event(ndev);
399 static struct notifier_block nb_inetaddr = {
400 .notifier_call = inetaddr_event
403 static eventhandler_tag eh_ifnet_event;
406 roce_ifnet_event(void *arg, struct ifnet *ifp, int event)
408 if (event != IFNET_EVENT_PCP || is_vlan_dev(ifp))
411 /* make sure GID table is reloaded */
412 roce_gid_delete_all_event(ifp);
413 roce_gid_queue_scan_event(ifp);
417 roce_rescan_device_handler(struct work_struct *_work)
419 struct roce_rescan_work *work =
420 container_of(_work, struct roce_rescan_work, work);
422 ib_enum_roce_netdev(work->ib_dev, roce_gid_match_all, NULL,
423 roce_gid_update_addr_callback, NULL);
427 /* Caller must flush system workqueue before removing the ib_device */
428 int roce_rescan_device(struct ib_device *ib_dev)
430 struct roce_rescan_work *work = kmalloc(sizeof(*work), GFP_KERNEL);
435 work->ib_dev = ib_dev;
436 INIT_WORK(&work->work, roce_rescan_device_handler);
437 queue_work(roce_gid_mgmt_wq, &work->work);
442 int __init roce_gid_mgmt_init(void)
444 roce_gid_mgmt_wq = alloc_ordered_workqueue("roce_gid_mgmt_wq", 0);
445 if (!roce_gid_mgmt_wq) {
446 pr_warn("roce_gid_mgmt: can't allocate work queue\n");
450 register_inetaddr_notifier(&nb_inetaddr);
453 * We rely on the netdevice notifier to enumerate all existing
454 * devices in the system. Register to this notifier last to
455 * make sure we will not miss any IP add/del callbacks.
457 register_netdevice_notifier(&nb_inetaddr);
459 eh_ifnet_event = EVENTHANDLER_REGISTER(ifnet_event,
460 roce_ifnet_event, NULL, EVENTHANDLER_PRI_ANY);
465 void __exit roce_gid_mgmt_cleanup(void)
468 if (eh_ifnet_event != NULL)
469 EVENTHANDLER_DEREGISTER(ifnet_event, eh_ifnet_event);
471 unregister_inetaddr_notifier(&nb_inetaddr);
472 unregister_netdevice_notifier(&nb_inetaddr);
475 * Ensure all gid deletion tasks complete before we go down,
476 * to avoid any reference to free'd memory. By the time
477 * ib-core is removed, all physical devices have been removed,
478 * so no issue with remaining hardware contexts.
481 drain_workqueue(roce_gid_mgmt_wq);
482 destroy_workqueue(roce_gid_mgmt_wq);