]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/ofed/drivers/infiniband/core/addr.c
Ticks are 32-bit in FreeBSD.
[FreeBSD/FreeBSD.git] / sys / ofed / drivers / infiniband / core / addr.c
1 /*
2  * Copyright (c) 2005 Voltaire Inc.  All rights reserved.
3  * Copyright (c) 2002-2005, Network Appliance, Inc. All rights reserved.
4  * Copyright (c) 1999-2005, Mellanox Technologies, Inc. All rights reserved.
5  * Copyright (c) 2005 Intel Corporation.  All rights reserved.
6  *
7  * This software is available to you under a choice of one of two
8  * licenses.  You may choose to be licensed under the terms of the GNU
9  * General Public License (GPL) Version 2, available from the file
10  * COPYING in the main directory of this source tree, or the
11  * OpenIB.org BSD license below:
12  *
13  *     Redistribution and use in source and binary forms, with or
14  *     without modification, are permitted provided that the following
15  *     conditions are met:
16  *
17  *      - Redistributions of source code must retain the above
18  *        copyright notice, this list of conditions and the following
19  *        disclaimer.
20  *
21  *      - Redistributions in binary form must reproduce the above
22  *        copyright notice, this list of conditions and the following
23  *        disclaimer in the documentation and/or other materials
24  *        provided with the distribution.
25  *
26  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
30  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
31  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
32  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33  * SOFTWARE.
34  */
35
36 #include <linux/mutex.h>
37 #include <linux/inetdevice.h>
38 #include <linux/slab.h>
39 #include <linux/workqueue.h>
40 #include <linux/module.h>
41 #include <linux/notifier.h>
42 #include <net/route.h>
43 #include <net/netevent.h>
44 #include <rdma/ib_addr.h>
45 #include <netinet/if_ether.h>
46 #include <netinet6/scope6_var.h>
47
48
49 MODULE_AUTHOR("Sean Hefty");
50 MODULE_DESCRIPTION("IB Address Translation");
51 MODULE_LICENSE("Dual BSD/GPL");
52
53 struct addr_req {
54         struct list_head list;
55         struct sockaddr_storage src_addr;
56         struct sockaddr_storage dst_addr;
57         struct rdma_dev_addr *addr;
58         struct rdma_addr_client *client;
59         void *context;
60         void (*callback)(int status, struct sockaddr *src_addr,
61                          struct rdma_dev_addr *addr, void *context);
62         unsigned long timeout;
63         int status;
64 };
65
66 static void process_req(struct work_struct *work);
67
68 static DEFINE_MUTEX(lock);
69 static LIST_HEAD(req_list);
70 static struct delayed_work work;
71 static struct workqueue_struct *addr_wq;
72
73 static struct rdma_addr_client self;
74 void rdma_addr_register_client(struct rdma_addr_client *client)
75 {
76         atomic_set(&client->refcount, 1);
77         init_completion(&client->comp);
78 }
79 EXPORT_SYMBOL(rdma_addr_register_client);
80
81 static inline void put_client(struct rdma_addr_client *client)
82 {
83         if (atomic_dec_and_test(&client->refcount))
84                 complete(&client->comp);
85 }
86
87 void rdma_addr_unregister_client(struct rdma_addr_client *client)
88 {
89         put_client(client);
90         wait_for_completion(&client->comp);
91 }
92 EXPORT_SYMBOL(rdma_addr_unregister_client);
93
94 int rdma_copy_addr(struct rdma_dev_addr *dev_addr, struct ifnet *dev,
95                      const unsigned char *dst_dev_addr)
96 {
97         if (dev->if_type == IFT_INFINIBAND)
98                 dev_addr->dev_type = ARPHRD_INFINIBAND;
99         else if (dev->if_type == IFT_ETHER)
100                 dev_addr->dev_type = ARPHRD_ETHER;
101         else
102                 dev_addr->dev_type = 0;
103         memcpy(dev_addr->src_dev_addr, IF_LLADDR(dev), dev->if_addrlen);
104         memcpy(dev_addr->broadcast, __DECONST(char *, dev->if_broadcastaddr),
105             dev->if_addrlen);
106         if (dst_dev_addr)
107                 memcpy(dev_addr->dst_dev_addr, dst_dev_addr, dev->if_addrlen);
108         dev_addr->bound_dev_if = dev->if_index;
109         return 0;
110 }
111 EXPORT_SYMBOL(rdma_copy_addr);
112
113 #define SCOPE_ID_CACHE(_scope_id, _addr6) do {          \
114         (_addr6)->sin6_addr.s6_addr[3] = (_scope_id);   \
115         (_addr6)->sin6_scope_id = 0; } while (0)
116
117 #define SCOPE_ID_RESTORE(_scope_id, _addr6) do {        \
118         (_addr6)->sin6_scope_id = (_scope_id);          \
119         (_addr6)->sin6_addr.s6_addr[3] = 0; } while (0)
120
121 int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr,
122                       u16 *vlan_id)
123 {
124         struct net_device *dev;
125         int ret = -EADDRNOTAVAIL;
126
127         if (dev_addr->bound_dev_if) {
128                 dev = dev_get_by_index(&init_net, dev_addr->bound_dev_if);
129                 if (!dev)
130                         return -ENODEV;
131                 ret = rdma_copy_addr(dev_addr, dev, NULL);
132                 dev_put(dev);
133                 return ret;
134         }
135
136         switch (addr->sa_family) {
137         case AF_INET:
138                 dev = ip_dev_find(&init_net,
139                         ((struct sockaddr_in *) addr)->sin_addr.s_addr);
140
141                 if (!dev)
142                         return ret;
143
144                 ret = rdma_copy_addr(dev_addr, dev, NULL);
145                 if (vlan_id)
146                         *vlan_id = rdma_vlan_dev_vlan_id(dev);
147                 dev_put(dev);
148                 break;
149
150 #if defined(INET6)
151         case AF_INET6:
152                 {
153                         struct sockaddr_in6 *sin6;
154                         struct ifaddr *ifa;
155                         in_port_t port;
156                         uint32_t scope_id;
157
158                         sin6 = (struct sockaddr_in6 *)addr;
159                         port = sin6->sin6_port;
160                         sin6->sin6_port = 0;
161                         scope_id = sin6->sin6_scope_id;
162                         if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr))
163                                 SCOPE_ID_CACHE(scope_id, sin6);
164                         CURVNET_SET_QUIET(&init_net);
165                         ifa = ifa_ifwithaddr(addr);
166                         CURVNET_RESTORE();
167                         sin6->sin6_port = port;
168                         if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr))
169                                 SCOPE_ID_RESTORE(scope_id, sin6);
170                         if (ifa == NULL) {
171                                 ret = -ENODEV;
172                                 break;
173                         }
174                         ret = rdma_copy_addr(dev_addr, ifa->ifa_ifp, NULL);
175                         if (vlan_id)
176                                 *vlan_id = rdma_vlan_dev_vlan_id(ifa->ifa_ifp);
177                         ifa_free(ifa);
178                         break;
179                 }
180 #endif
181         default:
182                 break;
183         }
184         return ret;
185 }
186 EXPORT_SYMBOL(rdma_translate_ip);
187
188 static void set_timeout(unsigned long time)
189 {
190         int delay;      /* under FreeBSD ticks are 32-bit */
191
192         delay = time - jiffies;
193         if (delay <= 0)
194                 delay = 1;
195
196         mod_delayed_work(addr_wq, &work, delay);
197 }
198
199 static void queue_req(struct addr_req *req)
200 {
201         struct addr_req *temp_req;
202
203         mutex_lock(&lock);
204         list_for_each_entry_reverse(temp_req, &req_list, list) {
205                 if (time_after_eq(req->timeout, temp_req->timeout))
206                         break;
207         }
208
209         list_add(&req->list, &temp_req->list);
210
211         if (req_list.next == &req->list)
212                 set_timeout(req->timeout);
213         mutex_unlock(&lock);
214 }
215
216 static int addr_resolve(struct sockaddr *src_in,
217                         struct sockaddr *dst_in,
218                         struct rdma_dev_addr *addr)
219 {
220         struct sockaddr_in *sin;
221         struct sockaddr_in6 *sin6;
222         struct ifaddr *ifa;
223         struct ifnet *ifp;
224         struct rtentry *rte;
225 #if defined(INET) || defined(INET6)
226         in_port_t port;
227 #endif
228 #ifdef INET6
229         uint32_t scope_id;
230 #endif
231         u_char edst[MAX_ADDR_LEN];
232         int multi;
233         int bcast;
234         int is_gw = 0;
235         int error = 0;
236
237         CURVNET_SET_QUIET(&init_net);
238
239         /*
240          * Determine whether the address is unicast, multicast, or broadcast
241          * and whether the source interface is valid.
242          */
243         multi = 0;
244         bcast = 0;
245         sin = NULL;
246         sin6 = NULL;
247         ifp = NULL;
248         rte = NULL;
249         ifa = NULL;
250         ifp = NULL;
251         memset(edst, 0, sizeof(edst));
252 #ifdef INET6
253         scope_id = -1U;
254 #endif
255
256         switch (dst_in->sa_family) {
257 #ifdef INET
258         case AF_INET:
259                 sin = (struct sockaddr_in *)dst_in;
260                 if (sin->sin_addr.s_addr == INADDR_BROADCAST)
261                         bcast = 1;
262                 if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr)))
263                         multi = 1;
264                 sin = (struct sockaddr_in *)src_in;
265                 if (sin->sin_addr.s_addr != INADDR_ANY) {
266                         /*
267                          * Address comparison fails if the port is set
268                          * cache it here to be restored later.
269                          */
270                         port = sin->sin_port;
271                         sin->sin_port = 0;
272                         memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
273
274                         /*
275                          * If we have a source address to use look it
276                          * up first and verify that it is a local
277                          * interface:
278                          */
279                         CURVNET_SET_QUIET(&init_net);
280                         ifa = ifa_ifwithaddr(src_in);
281                         CURVNET_RESTORE();
282                         sin->sin_port = port;
283                         if (ifa == NULL) {
284                                 error = ENETUNREACH;
285                                 goto done;
286                         }
287                         ifp = ifa->ifa_ifp;
288                         ifa_free(ifa);
289                         if (bcast || multi)
290                                 goto mcast;
291                 }
292                 break;
293 #endif
294 #ifdef INET6
295         case AF_INET6:
296                 sin6 = (struct sockaddr_in6 *)dst_in;
297                 if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
298                         multi = 1;
299                 if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr)) {
300                         /*
301                          * The IB address comparison fails if the
302                          * scope ID is set and not part of the addr:
303                          */
304                         scope_id = sin6->sin6_scope_id;
305                         if (scope_id < 256)
306                                 SCOPE_ID_CACHE(scope_id, sin6);
307                 }
308                 sin6 = (struct sockaddr_in6 *)src_in;
309                 if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
310                         port = sin6->sin6_port;
311                         sin6->sin6_port = 0;
312                         if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr)) {
313                                 if (scope_id < 256)
314                                         SCOPE_ID_CACHE(scope_id, sin6);
315                         }
316
317                         /*
318                          * If we have a source address to use look it
319                          * up first and verify that it is a local
320                          * interface:
321                          */
322                         CURVNET_SET_QUIET(&init_net);
323                         ifa = ifa_ifwithaddr(src_in);
324                         CURVNET_RESTORE();
325                         sin6->sin6_port = port;
326                         if (ifa == NULL) {
327                                 error = ENETUNREACH;
328                                 goto done;
329                         }
330                         ifp = ifa->ifa_ifp;
331                         ifa_free(ifa);
332                         if (bcast || multi)
333                                 goto mcast;
334                 }
335                 break;
336 #endif
337         default:
338                 error = EINVAL;
339                 goto done;
340         }
341         /*
342          * Make sure the route exists and has a valid link.
343          */
344         rte = rtalloc1(dst_in, 1, 0);
345         if (rte == NULL || rte->rt_ifp == NULL || !RT_LINK_IS_UP(rte->rt_ifp)) {
346                 if (rte)
347                         RTFREE_LOCKED(rte);
348                 error = EHOSTUNREACH;
349                 goto done;
350         }
351         if (rte->rt_flags & RTF_GATEWAY)
352                 is_gw = 1;
353         /*
354          * If it's not multicast or broadcast and the route doesn't match the
355          * requested interface return unreachable.  Otherwise fetch the
356          * correct interface pointer and unlock the route.
357          */
358         if (multi || bcast) {
359                 if (ifp == NULL) {
360                         ifp = rte->rt_ifp;
361                         /* rt_ifa holds the route answer source address */
362                         ifa = rte->rt_ifa;
363                 }
364                 RTFREE_LOCKED(rte);
365         } else if (ifp && ifp != rte->rt_ifp) {
366                 RTFREE_LOCKED(rte);
367                 error = ENETUNREACH;
368                 goto done;
369         } else {
370                 if (ifp == NULL) {
371                         ifp = rte->rt_ifp;
372                         ifa = rte->rt_ifa;
373                 }
374                 RT_UNLOCK(rte);
375         }
376 #if defined(INET) || defined(INET6)
377 mcast:
378 #endif
379         if (bcast) {
380                 memcpy(edst, ifp->if_broadcastaddr, ifp->if_addrlen);
381                 goto done;
382         } else if (multi) {
383                 struct sockaddr *llsa;
384                 struct sockaddr_dl sdl;
385
386                 sdl.sdl_len = sizeof(sdl);
387                 llsa = (struct sockaddr *)&sdl;
388
389                 if (ifp->if_resolvemulti == NULL) {
390                         error = EOPNOTSUPP;
391                         goto done;
392                 }
393                 error = ifp->if_resolvemulti(ifp, &llsa, dst_in);
394                 if (error == 0) {
395                         memcpy(edst, LLADDR((struct sockaddr_dl *)llsa),
396                             ifp->if_addrlen);
397                 }
398                 goto done;
399         }
400         /*
401          * Resolve the link local address.
402          */
403         switch (dst_in->sa_family) {
404 #ifdef INET
405         case AF_INET:
406                 error = arpresolve(ifp, is_gw, NULL,
407                     is_gw ? rte->rt_gateway : dst_in, edst, NULL, NULL);
408                 break;
409 #endif
410 #ifdef INET6
411         case AF_INET6:
412                 error = nd6_resolve(ifp, is_gw, NULL,
413                     is_gw ? rte->rt_gateway : dst_in, edst, NULL, NULL);
414                 break;
415 #endif
416         default:
417                 KASSERT(0, ("rdma_addr_resolve: Unreachable"));
418                 error = EINVAL;
419                 break;
420         }
421         RTFREE(rte);
422 done:
423         if (error == 0)
424                 error = -rdma_copy_addr(addr, ifp, edst);
425         if (error == 0)
426                 memcpy(src_in, ifa->ifa_addr, ip_addr_size(ifa->ifa_addr));
427 #ifdef INET6
428         if (scope_id < 256) {
429                 sin6 = (struct sockaddr_in6 *)src_in;
430                 if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr))
431                         SCOPE_ID_RESTORE(scope_id, sin6);
432                 sin6 = (struct sockaddr_in6 *)dst_in;
433                 SCOPE_ID_RESTORE(scope_id, sin6);
434         }
435 #endif
436         if (error == EWOULDBLOCK)
437                 error = ENODATA;
438
439         CURVNET_RESTORE();
440         return -error;
441 }
442
443 static void process_req(struct work_struct *work)
444 {
445         struct addr_req *req, *temp_req;
446         struct sockaddr *src_in, *dst_in;
447         struct list_head done_list;
448
449         INIT_LIST_HEAD(&done_list);
450
451         mutex_lock(&lock);
452         list_for_each_entry_safe(req, temp_req, &req_list, list) {
453                 if (req->status == -ENODATA) {
454                         src_in = (struct sockaddr *) &req->src_addr;
455                         dst_in = (struct sockaddr *) &req->dst_addr;
456                         req->status = addr_resolve(src_in, dst_in, req->addr);
457                         if (req->status && time_after_eq(jiffies, req->timeout))
458                                 req->status = -ETIMEDOUT;
459                         else if (req->status == -ENODATA)
460                                 continue;
461                 }
462                 list_move_tail(&req->list, &done_list);
463         }
464
465         if (!list_empty(&req_list)) {
466                 req = list_entry(req_list.next, struct addr_req, list);
467                 set_timeout(req->timeout);
468         }
469         mutex_unlock(&lock);
470
471         list_for_each_entry_safe(req, temp_req, &done_list, list) {
472                 list_del(&req->list);
473                 req->callback(req->status, (struct sockaddr *) &req->src_addr,
474                         req->addr, req->context);
475                 put_client(req->client);
476                 kfree(req);
477         }
478 }
479
480 int rdma_resolve_ip(struct rdma_addr_client *client,
481                     struct sockaddr *src_addr, struct sockaddr *dst_addr,
482                     struct rdma_dev_addr *addr, int timeout_ms,
483                     void (*callback)(int status, struct sockaddr *src_addr,
484                                      struct rdma_dev_addr *addr, void *context),
485                     void *context)
486 {
487         struct sockaddr *src_in, *dst_in;
488         struct addr_req *req;
489         int ret = 0;
490
491         req = kzalloc(sizeof *req, GFP_KERNEL);
492         if (!req)
493                 return -ENOMEM;
494
495         src_in = (struct sockaddr *) &req->src_addr;
496         dst_in = (struct sockaddr *) &req->dst_addr;
497
498         if (src_addr) {
499                 if (src_addr->sa_family != dst_addr->sa_family) {
500                         ret = -EINVAL;
501                         goto err;
502                 }
503
504                 memcpy(src_in, src_addr, ip_addr_size(src_addr));
505         } else {
506                 src_in->sa_family = dst_addr->sa_family;
507         }
508
509         memcpy(dst_in, dst_addr, ip_addr_size(dst_addr));
510         req->addr = addr;
511         req->callback = callback;
512         req->context = context;
513         req->client = client;
514         atomic_inc(&client->refcount);
515
516         req->status = addr_resolve(src_in, dst_in, addr);
517         switch (req->status) {
518         case 0:
519                 req->timeout = jiffies;
520                 queue_req(req);
521                 break;
522         case -ENODATA:
523                 req->timeout = msecs_to_jiffies(timeout_ms) + jiffies;
524                 queue_req(req);
525                 break;
526         default:
527                 ret = req->status;
528                 atomic_dec(&client->refcount);
529                 goto err;
530         }
531         return ret;
532 err:
533         kfree(req);
534         return ret;
535 }
536 EXPORT_SYMBOL(rdma_resolve_ip);
537
538 void rdma_addr_cancel(struct rdma_dev_addr *addr)
539 {
540         struct addr_req *req, *temp_req;
541
542         mutex_lock(&lock);
543         list_for_each_entry_safe(req, temp_req, &req_list, list) {
544                 if (req->addr == addr) {
545                         req->status = -ECANCELED;
546                         req->timeout = jiffies;
547                         list_move(&req->list, &req_list);
548                         set_timeout(req->timeout);
549                         break;
550                 }
551         }
552         mutex_unlock(&lock);
553 }
554 EXPORT_SYMBOL(rdma_addr_cancel);
555
556 struct resolve_cb_context {
557         struct rdma_dev_addr *addr;
558         struct completion comp;
559 };
560
561 static void resolve_cb(int status, struct sockaddr *src_addr,
562              struct rdma_dev_addr *addr, void *context)
563 {
564         memcpy(((struct resolve_cb_context *)context)->addr, addr, sizeof(struct
565                                 rdma_dev_addr));
566         complete(&((struct resolve_cb_context *)context)->comp);
567 }
568
569 int rdma_addr_find_dmac_by_grh(union ib_gid *sgid, union ib_gid *dgid, u8 *dmac,
570                                u16 *vlan_id, u32 scope_id)
571 {
572         int ret = 0;
573         struct rdma_dev_addr dev_addr;
574         struct resolve_cb_context ctx;
575         struct net_device *dev;
576
577         union {
578                 struct sockaddr     _sockaddr;
579                 struct sockaddr_in  _sockaddr_in;
580                 struct sockaddr_in6 _sockaddr_in6;
581         } sgid_addr, dgid_addr;
582
583
584         ret = rdma_gid2ip(&sgid_addr._sockaddr, sgid, scope_id);
585         if (ret)
586                 return ret;
587
588         ret = rdma_gid2ip(&dgid_addr._sockaddr, dgid, scope_id);
589         if (ret)
590                 return ret;
591
592         memset(&dev_addr, 0, sizeof(dev_addr));
593
594         ctx.addr = &dev_addr;
595         init_completion(&ctx.comp);
596         ret = rdma_resolve_ip(&self, &sgid_addr._sockaddr, &dgid_addr._sockaddr,
597                         &dev_addr, 1000, resolve_cb, &ctx);
598         if (ret)
599                 return ret;
600
601         wait_for_completion(&ctx.comp);
602
603         memcpy(dmac, dev_addr.dst_dev_addr, ETH_ALEN);
604         dev = dev_get_by_index(&init_net, dev_addr.bound_dev_if);
605         if (!dev)
606                 return -ENODEV;
607         if (vlan_id)
608                 *vlan_id = rdma_vlan_dev_vlan_id(dev);
609         dev_put(dev);
610         return ret;
611 }
612 EXPORT_SYMBOL(rdma_addr_find_dmac_by_grh);
613
614 u32 rdma_get_ipv6_scope_id(struct ib_device *ib, u8 port_num)
615 {
616 #ifdef INET6
617         struct ifnet *ifp;
618         if (ib->get_netdev == NULL)
619                 return (-1U);
620         ifp = ib->get_netdev(ib, port_num);
621         if (ifp == NULL)
622                 return (-1U);
623         return (in6_getscopezone(ifp, IPV6_ADDR_SCOPE_LINKLOCAL));
624 #else
625         return (-1U);
626 #endif
627 }
628
629 int rdma_addr_find_smac_by_sgid(union ib_gid *sgid, u8 *smac, u16 *vlan_id,
630     u32 scope_id)
631 {
632         int ret = 0;
633         struct rdma_dev_addr dev_addr;
634         union {
635                 struct sockaddr     _sockaddr;
636                 struct sockaddr_in  _sockaddr_in;
637                 struct sockaddr_in6 _sockaddr_in6;
638         } gid_addr;
639
640         ret = rdma_gid2ip(&gid_addr._sockaddr, sgid, scope_id);
641         if (ret)
642                 return ret;
643         memset(&dev_addr, 0, sizeof(dev_addr));
644         ret = rdma_translate_ip(&gid_addr._sockaddr, &dev_addr, vlan_id);
645         if (ret)
646                 return ret;
647
648         memcpy(smac, dev_addr.src_dev_addr, ETH_ALEN);
649         return ret;
650 }
651 EXPORT_SYMBOL(rdma_addr_find_smac_by_sgid);
652
653 static int netevent_callback(struct notifier_block *self, unsigned long event,
654         void *ctx)
655 {
656         if (event == NETEVENT_NEIGH_UPDATE) {
657                         set_timeout(jiffies);
658                 }
659         return 0;
660 }
661
662 static struct notifier_block nb = {
663         .notifier_call = netevent_callback
664 };
665
666 static int __init addr_init(void)
667 {
668         INIT_DELAYED_WORK(&work, process_req);
669         addr_wq = create_singlethread_workqueue("ib_addr");
670         if (!addr_wq)
671                 return -ENOMEM;
672
673         register_netevent_notifier(&nb);
674         rdma_addr_register_client(&self);
675         return 0;
676 }
677
678 static void __exit addr_cleanup(void)
679 {
680         rdma_addr_unregister_client(&self);
681         unregister_netevent_notifier(&nb);
682         destroy_workqueue(addr_wq);
683 }
684
685 module_init(addr_init);
686 module_exit(addr_cleanup);