1 /*- 2 * Copyright (c) 2020 Mellanox Technologies. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 */ 25 26 #include "opt_inet.h" 27 #include "opt_inet6.h" 28 #include "opt_kbd.h" 29 30 #include <sys/cdefs.h> 31 #include <sys/param.h> 32 #include <sys/systm.h> 33 #include <sys/devctl.h> 34 #include <sys/eventhandler.h> 35 #include <sys/kernel.h> 36 #include <sys/mbuf.h> 37 #include <sys/module.h> 38 #include <sys/socket.h> 39 #include <sys/sysctl.h> 40 #ifdef KDB 41 #include <sys/kdb.h> 42 #endif 43 44 #include <net/bpf.h> 45 #include <net/ethernet.h> 46 #include <net/infiniband.h> 47 #include <net/if.h> 48 #include <net/if_var.h> 49 #include <net/if_private.h> 50 #include <net/if_dl.h> 51 #include <net/if_media.h> 52 #include <net/if_lagg.h> 53 #include <net/if_llatbl.h> 54 #include <net/if_types.h> 55 #include <net/netisr.h> 56 #include <net/route.h> 57 #include <netinet/if_ether.h> 58 #include <netinet/in.h> 59 #include <netinet/ip6.h> 60 #include <netinet6/in6_var.h> 61 #include <netinet6/nd6.h> 62 63 #include <security/mac/mac_framework.h> 64 65 /* if_lagg(4) support */ 66 struct mbuf *(*lagg_input_infiniband_p)(struct ifnet *, struct mbuf *); 67 68 #ifdef INET 69 static inline void 70 infiniband_ipv4_multicast_map(uint32_t addr, 71 const uint8_t *broadcast, uint8_t *buf) 72 { 73 uint8_t scope; 74 75 addr = ntohl(addr); 76 scope = broadcast[5] & 0xF; 77 78 buf[0] = 0; 79 buf[1] = 0xff; 80 buf[2] = 0xff; 81 buf[3] = 0xff; 82 buf[4] = 0xff; 83 buf[5] = 0x10 | scope; 84 buf[6] = 0x40; 85 buf[7] = 0x1b; 86 buf[8] = broadcast[8]; 87 buf[9] = broadcast[9]; 88 buf[10] = 0; 89 buf[11] = 0; 90 buf[12] = 0; 91 buf[13] = 0; 92 buf[14] = 0; 93 buf[15] = 0; 94 buf[16] = (addr >> 24) & 0xff; 95 buf[17] = (addr >> 16) & 0xff; 96 buf[18] = (addr >> 8) & 0xff; 97 buf[19] = addr & 0xff; 98 } 99 #endif 100 101 #ifdef INET6 102 static inline void 103 infiniband_ipv6_multicast_map(const struct in6_addr *addr, 104 const uint8_t *broadcast, uint8_t *buf) 105 { 106 uint8_t scope; 107 108 scope = broadcast[5] & 0xF; 109 110 buf[0] = 0; 111 buf[1] = 0xff; 112 buf[2] = 0xff; 113 buf[3] = 0xff; 114 buf[4] = 0xff; 115 buf[5] = 0x10 | scope; 116 buf[6] = 0x60; 117 buf[7] = 0x1b; 118 buf[8] = broadcast[8]; 119 buf[9] = broadcast[9]; 120 memcpy(&buf[10], &addr->s6_addr[6], 10); 121 } 122 #endif 123 124 /* 125 * This is for clients that have an infiniband_header in the mbuf. 126 */ 127 void 128 infiniband_bpf_mtap(struct ifnet *ifp, struct mbuf *mb) 129 { 130 struct infiniband_header *ibh; 131 struct ether_header eh; 132 133 if (!bpf_peers_present(ifp->if_bpf)) 134 return; 135 136 M_ASSERTVALID(mb); 137 if (mb->m_len < sizeof(*ibh)) 138 return; 139 140 ibh = mtod(mb, struct infiniband_header *); 141 eh.ether_type = ibh->ib_protocol; 142 memset(eh.ether_shost, 0, ETHER_ADDR_LEN); 143 memcpy(eh.ether_dhost, ibh->ib_hwaddr + 4, ETHER_ADDR_LEN); 144 mb->m_data += sizeof(*ibh); 145 mb->m_len -= sizeof(*ibh); 146 mb->m_pkthdr.len -= sizeof(*ibh); 147 bpf_mtap2(ifp->if_bpf, &eh, sizeof(eh), mb); 148 mb->m_data -= sizeof(*ibh); 149 mb->m_len += sizeof(*ibh); 150 mb->m_pkthdr.len += sizeof(*ibh); 151 } 152 153 static void 154 update_mbuf_csumflags(struct mbuf *src, struct mbuf *dst) 155 { 156 int csum_flags = 0; 157 158 if (src->m_pkthdr.csum_flags & CSUM_IP) 159 csum_flags |= (CSUM_IP_CHECKED|CSUM_IP_VALID); 160 if (src->m_pkthdr.csum_flags & CSUM_DELAY_DATA) 161 csum_flags |= (CSUM_DATA_VALID|CSUM_PSEUDO_HDR); 162 if (src->m_pkthdr.csum_flags & CSUM_SCTP) 163 csum_flags |= CSUM_SCTP_VALID; 164 dst->m_pkthdr.csum_flags |= csum_flags; 165 if (csum_flags & CSUM_DATA_VALID) 166 dst->m_pkthdr.csum_data = 0xffff; 167 } 168 169 /* 170 * Handle link-layer encapsulation requests. 171 */ 172 static int 173 infiniband_requestencap(struct ifnet *ifp, struct if_encap_req *req) 174 { 175 struct infiniband_header *ih; 176 struct arphdr *ah; 177 uint16_t etype; 178 const uint8_t *lladdr; 179 180 if (req->rtype != IFENCAP_LL) 181 return (EOPNOTSUPP); 182 183 if (req->bufsize < INFINIBAND_HDR_LEN) 184 return (ENOMEM); 185 186 ih = (struct infiniband_header *)req->buf; 187 lladdr = req->lladdr; 188 req->lladdr_off = 0; 189 190 switch (req->family) { 191 case AF_INET: 192 etype = htons(ETHERTYPE_IP); 193 break; 194 case AF_INET6: 195 etype = htons(ETHERTYPE_IPV6); 196 break; 197 case AF_ARP: 198 ah = (struct arphdr *)req->hdata; 199 ah->ar_hrd = htons(ARPHRD_INFINIBAND); 200 201 switch (ntohs(ah->ar_op)) { 202 case ARPOP_REVREQUEST: 203 case ARPOP_REVREPLY: 204 etype = htons(ETHERTYPE_REVARP); 205 break; 206 case ARPOP_REQUEST: 207 case ARPOP_REPLY: 208 default: 209 etype = htons(ETHERTYPE_ARP); 210 break; 211 } 212 213 if (req->flags & IFENCAP_FLAG_BROADCAST) 214 lladdr = ifp->if_broadcastaddr; 215 break; 216 default: 217 return (EAFNOSUPPORT); 218 } 219 220 ih->ib_protocol = etype; 221 ih->ib_reserved = 0; 222 memcpy(ih->ib_hwaddr, lladdr, INFINIBAND_ADDR_LEN); 223 req->bufsize = sizeof(struct infiniband_header); 224 225 return (0); 226 } 227 228 static int 229 infiniband_resolve_addr(struct ifnet *ifp, struct mbuf *m, 230 const struct sockaddr *dst, struct route *ro, uint8_t *phdr, 231 uint32_t *pflags, struct llentry **plle) 232 { 233 #if defined(INET) || defined(INET6) 234 struct infiniband_header *ih = (struct infiniband_header *)phdr; 235 #endif 236 uint32_t lleflags = 0; 237 int error = 0; 238 239 if (plle) 240 *plle = NULL; 241 242 switch (dst->sa_family) { 243 #ifdef INET 244 case AF_INET: 245 if ((m->m_flags & (M_BCAST | M_MCAST)) == 0) { 246 error = arpresolve(ifp, 0, m, dst, phdr, &lleflags, plle); 247 } else { 248 if (m->m_flags & M_BCAST) { 249 memcpy(ih->ib_hwaddr, ifp->if_broadcastaddr, 250 INFINIBAND_ADDR_LEN); 251 } else { 252 infiniband_ipv4_multicast_map( 253 ((const struct sockaddr_in *)dst)->sin_addr.s_addr, 254 ifp->if_broadcastaddr, ih->ib_hwaddr); 255 } 256 ih->ib_protocol = htons(ETHERTYPE_IP); 257 ih->ib_reserved = 0; 258 } 259 break; 260 #endif 261 #ifdef INET6 262 case AF_INET6: 263 if ((m->m_flags & M_MCAST) == 0) { 264 int af = RO_GET_FAMILY(ro, dst); 265 error = nd6_resolve(ifp, LLE_SF(af, 0), m, dst, phdr, 266 &lleflags, plle); 267 } else { 268 infiniband_ipv6_multicast_map( 269 &((const struct sockaddr_in6 *)dst)->sin6_addr, 270 ifp->if_broadcastaddr, ih->ib_hwaddr); 271 ih->ib_protocol = htons(ETHERTYPE_IPV6); 272 ih->ib_reserved = 0; 273 } 274 break; 275 #endif 276 default: 277 if_printf(ifp, "can't handle af%d\n", dst->sa_family); 278 if (m != NULL) 279 m_freem(m); 280 return (EAFNOSUPPORT); 281 } 282 283 if (error == EHOSTDOWN) { 284 if (ro != NULL && (ro->ro_flags & RT_HAS_GW) != 0) 285 error = EHOSTUNREACH; 286 } 287 288 if (error != 0) 289 return (error); 290 291 *pflags = RT_MAY_LOOP; 292 if (lleflags & LLE_IFADDR) 293 *pflags |= RT_L2_ME; 294 295 return (0); 296 } 297 298 /* 299 * Infiniband output routine. 300 */ 301 static int 302 infiniband_output(struct ifnet *ifp, struct mbuf *m, 303 const struct sockaddr *dst, struct route *ro) 304 { 305 uint8_t linkhdr[INFINIBAND_HDR_LEN]; 306 uint8_t *phdr; 307 struct llentry *lle = NULL; 308 struct infiniband_header *ih; 309 int error = 0; 310 int hlen; /* link layer header length */ 311 uint32_t pflags; 312 bool addref; 313 314 NET_EPOCH_ASSERT(); 315 316 addref = false; 317 phdr = NULL; 318 pflags = 0; 319 if (ro != NULL) { 320 /* XXX BPF uses ro_prepend */ 321 if (ro->ro_prepend != NULL) { 322 phdr = ro->ro_prepend; 323 hlen = ro->ro_plen; 324 } else if (!(m->m_flags & (M_BCAST | M_MCAST))) { 325 if ((ro->ro_flags & RT_LLE_CACHE) != 0) { 326 lle = ro->ro_lle; 327 if (lle != NULL && 328 (lle->la_flags & LLE_VALID) == 0) { 329 LLE_FREE(lle); 330 lle = NULL; /* redundant */ 331 ro->ro_lle = NULL; 332 } 333 if (lle == NULL) { 334 /* if we lookup, keep cache */ 335 addref = 1; 336 } else 337 /* 338 * Notify LLE code that 339 * the entry was used 340 * by datapath. 341 */ 342 llentry_provide_feedback(lle); 343 } 344 if (lle != NULL) { 345 phdr = lle->r_linkdata; 346 hlen = lle->r_hdrlen; 347 pflags = lle->r_flags; 348 } 349 } 350 } 351 352 #ifdef MAC 353 error = mac_ifnet_check_transmit(ifp, m); 354 if (error) 355 goto bad; 356 #endif 357 358 M_PROFILE(m); 359 if (ifp->if_flags & IFF_MONITOR) { 360 error = ENETDOWN; 361 goto bad; 362 } 363 if (!((ifp->if_flags & IFF_UP) && 364 (ifp->if_drv_flags & IFF_DRV_RUNNING))) { 365 error = ENETDOWN; 366 goto bad; 367 } 368 369 if (phdr == NULL) { 370 /* No prepend data supplied. Try to calculate ourselves. */ 371 phdr = linkhdr; 372 hlen = INFINIBAND_HDR_LEN; 373 error = infiniband_resolve_addr(ifp, m, dst, ro, phdr, &pflags, 374 addref ? &lle : NULL); 375 if (addref && lle != NULL) 376 ro->ro_lle = lle; 377 if (error != 0) 378 return (error == EWOULDBLOCK ? 0 : error); 379 } 380 381 if ((pflags & RT_L2_ME) != 0) { 382 update_mbuf_csumflags(m, m); 383 return (if_simloop(ifp, m, RO_GET_FAMILY(ro, dst), 0)); 384 } 385 386 /* 387 * Add local infiniband header. If no space in first mbuf, 388 * allocate another. 389 */ 390 M_PREPEND(m, INFINIBAND_HDR_LEN, M_NOWAIT); 391 if (m == NULL) { 392 error = ENOBUFS; 393 goto bad; 394 } 395 if ((pflags & RT_HAS_HEADER) == 0) { 396 ih = mtod(m, struct infiniband_header *); 397 memcpy(ih, phdr, hlen); 398 } 399 400 /* 401 * Queue message on interface, update output statistics if 402 * successful, and start output if interface not yet active. 403 */ 404 return (ifp->if_transmit(ifp, m)); 405 bad: 406 if (m != NULL) 407 m_freem(m); 408 return (error); 409 } 410 411 /* 412 * Process a received Infiniband packet. 413 */ 414 static void 415 infiniband_input(struct ifnet *ifp, struct mbuf *m) 416 { 417 struct infiniband_header *ibh; 418 struct epoch_tracker et; 419 int isr; 420 bool needs_epoch; 421 422 needs_epoch = (ifp->if_flags & IFF_NEEDSEPOCH); 423 #ifdef INVARIANTS 424 /* 425 * This temporary code is here to prevent epoch unaware and unmarked 426 * drivers to panic the system. Once all drivers are taken care of, 427 * the whole INVARIANTS block should go away. 428 */ 429 if (!needs_epoch && !in_epoch(net_epoch_preempt)) { 430 static bool printedonce; 431 432 needs_epoch = true; 433 if (!printedonce) { 434 printedonce = true; 435 if_printf(ifp, "called %s w/o net epoch! " 436 "PLEASE file a bug report.", __func__); 437 #ifdef KDB 438 kdb_backtrace(); 439 #endif 440 } 441 } 442 #endif 443 444 CURVNET_SET_QUIET(ifp->if_vnet); 445 if (__predict_false(needs_epoch)) 446 NET_EPOCH_ENTER(et); 447 448 if ((ifp->if_flags & IFF_UP) == 0) { 449 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); 450 m_freem(m); 451 goto done; 452 } 453 454 ibh = mtod(m, struct infiniband_header *); 455 456 /* 457 * Reset layer specific mbuf flags to avoid confusing upper 458 * layers: 459 */ 460 m->m_flags &= ~M_VLANTAG; 461 m_clrprotoflags(m); 462 463 if (INFINIBAND_IS_MULTICAST(ibh->ib_hwaddr)) { 464 if (memcmp(ibh->ib_hwaddr, ifp->if_broadcastaddr, 465 ifp->if_addrlen) == 0) 466 m->m_flags |= M_BCAST; 467 else 468 m->m_flags |= M_MCAST; 469 if_inc_counter(ifp, IFCOUNTER_IMCASTS, 1); 470 } 471 472 /* Let BPF have it before we strip the header. */ 473 infiniband_bpf_mtap(ifp, m); 474 475 /* Allow monitor mode to claim this frame, after stats are updated. */ 476 if (ifp->if_flags & IFF_MONITOR) { 477 m_freem(m); 478 goto done; 479 } 480 481 /* Direct packet to correct FIB based on interface config. */ 482 M_SETFIB(m, ifp->if_fib); 483 484 /* Handle input from a lagg<N> port */ 485 if (ifp->if_type == IFT_INFINIBANDLAG) { 486 KASSERT(lagg_input_infiniband_p != NULL, 487 ("%s: if_lagg not loaded!", __func__)); 488 m = (*lagg_input_infiniband_p)(ifp, m); 489 if (__predict_false(m == NULL)) 490 goto done; 491 ifp = m->m_pkthdr.rcvif; 492 } 493 494 /* 495 * Dispatch frame to upper layer. 496 */ 497 switch (ibh->ib_protocol) { 498 #ifdef INET 499 case htons(ETHERTYPE_IP): 500 isr = NETISR_IP; 501 break; 502 503 case htons(ETHERTYPE_ARP): 504 if (ifp->if_flags & IFF_NOARP) { 505 /* Discard packet if ARP is disabled on interface */ 506 m_freem(m); 507 goto done; 508 } 509 isr = NETISR_ARP; 510 break; 511 #endif 512 #ifdef INET6 513 case htons(ETHERTYPE_IPV6): 514 isr = NETISR_IPV6; 515 break; 516 #endif 517 default: 518 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); 519 m_freem(m); 520 goto done; 521 } 522 523 /* Strip off the Infiniband header. */ 524 m_adj(m, INFINIBAND_HDR_LEN); 525 526 #ifdef MAC 527 /* 528 * Tag the mbuf with an appropriate MAC label before any other 529 * consumers can get to it. 530 */ 531 mac_ifnet_create_mbuf(ifp, m); 532 #endif 533 /* Allow monitor mode to claim this frame, after stats are updated. */ 534 netisr_dispatch(isr, m); 535 done: 536 if (__predict_false(needs_epoch)) 537 NET_EPOCH_EXIT(et); 538 CURVNET_RESTORE(); 539 } 540 541 static int 542 infiniband_resolvemulti(struct ifnet *ifp, struct sockaddr **llsa, 543 struct sockaddr *sa) 544 { 545 struct sockaddr_dl *sdl; 546 #ifdef INET 547 struct sockaddr_in *sin; 548 #endif 549 #ifdef INET6 550 struct sockaddr_in6 *sin6; 551 #endif 552 uint8_t *e_addr; 553 554 switch (sa->sa_family) { 555 case AF_LINK: 556 /* 557 * No mapping needed. Just check that it's a valid MC address. 558 */ 559 sdl = (struct sockaddr_dl *)sa; 560 e_addr = LLADDR(sdl); 561 if (!INFINIBAND_IS_MULTICAST(e_addr)) 562 return (EADDRNOTAVAIL); 563 *llsa = NULL; 564 return 0; 565 566 #ifdef INET 567 case AF_INET: 568 sin = (struct sockaddr_in *)sa; 569 if (!IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) 570 return (EADDRNOTAVAIL); 571 sdl = link_init_sdl(ifp, *llsa, IFT_INFINIBAND); 572 sdl->sdl_alen = INFINIBAND_ADDR_LEN; 573 e_addr = LLADDR(sdl); 574 infiniband_ipv4_multicast_map( 575 sin->sin_addr.s_addr, ifp->if_broadcastaddr, e_addr); 576 *llsa = (struct sockaddr *)sdl; 577 return (0); 578 #endif 579 #ifdef INET6 580 case AF_INET6: 581 sin6 = (struct sockaddr_in6 *)sa; 582 /* 583 * An IP6 address of 0 means listen to all of the 584 * multicast address used for IP6. This has no meaning 585 * in infiniband. 586 */ 587 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) 588 return (EADDRNOTAVAIL); 589 if (!IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) 590 return (EADDRNOTAVAIL); 591 sdl = link_init_sdl(ifp, *llsa, IFT_INFINIBAND); 592 sdl->sdl_alen = INFINIBAND_ADDR_LEN; 593 e_addr = LLADDR(sdl); 594 infiniband_ipv6_multicast_map( 595 &sin6->sin6_addr, ifp->if_broadcastaddr, e_addr); 596 *llsa = (struct sockaddr *)sdl; 597 return (0); 598 #endif 599 default: 600 return (EAFNOSUPPORT); 601 } 602 } 603 604 void 605 infiniband_ifattach(struct ifnet *ifp, const uint8_t *lla, const uint8_t *llb) 606 { 607 struct sockaddr_dl *sdl; 608 struct ifaddr *ifa; 609 int i; 610 611 ifp->if_addrlen = INFINIBAND_ADDR_LEN; 612 ifp->if_hdrlen = INFINIBAND_HDR_LEN; 613 ifp->if_mtu = INFINIBAND_MTU; 614 if_attach(ifp); 615 ifp->if_output = infiniband_output; 616 ifp->if_input = infiniband_input; 617 ifp->if_resolvemulti = infiniband_resolvemulti; 618 ifp->if_requestencap = infiniband_requestencap; 619 620 if (ifp->if_baudrate == 0) 621 ifp->if_baudrate = IF_Gbps(10); /* default value */ 622 if (llb != NULL) 623 ifp->if_broadcastaddr = llb; 624 625 ifa = ifp->if_addr; 626 KASSERT(ifa != NULL, ("%s: no lladdr!\n", __func__)); 627 sdl = (struct sockaddr_dl *)ifa->ifa_addr; 628 sdl->sdl_type = IFT_INFINIBAND; 629 sdl->sdl_alen = ifp->if_addrlen; 630 631 if (lla != NULL) { 632 memcpy(LLADDR(sdl), lla, ifp->if_addrlen); 633 634 if (ifp->if_hw_addr != NULL) 635 memcpy(ifp->if_hw_addr, lla, ifp->if_addrlen); 636 } else { 637 lla = LLADDR(sdl); 638 } 639 640 /* Attach ethernet compatible network device */ 641 bpfattach(ifp, DLT_EN10MB, ETHER_HDR_LEN); 642 643 /* Announce Infiniband MAC address if non-zero. */ 644 for (i = 0; i < ifp->if_addrlen; i++) 645 if (lla[i] != 0) 646 break; 647 if (i != ifp->if_addrlen) 648 if_printf(ifp, "Infiniband address: %20D\n", lla, ":"); 649 650 /* Add necessary bits are setup; announce it now. */ 651 EVENTHANDLER_INVOKE(infiniband_ifattach_event, ifp); 652 653 if (IS_DEFAULT_VNET(curvnet)) 654 devctl_notify("INFINIBAND", ifp->if_xname, "IFATTACH", NULL); 655 } 656 657 /* 658 * Perform common duties while detaching an Infiniband interface 659 */ 660 void 661 infiniband_ifdetach(struct ifnet *ifp) 662 { 663 bpfdetach(ifp); 664 if_detach(ifp); 665 } 666 667 static int 668 infiniband_modevent(module_t mod, int type, void *data) 669 { 670 switch (type) { 671 case MOD_LOAD: 672 case MOD_UNLOAD: 673 return (0); 674 default: 675 return (EOPNOTSUPP); 676 } 677 } 678 679 static moduledata_t infiniband_mod = { 680 .name = "if_infiniband", 681 .evhand = &infiniband_modevent, 682 }; 683 684 DECLARE_MODULE(if_infiniband, infiniband_mod, SI_SUB_INIT_IF, SI_ORDER_ANY); 685 MODULE_VERSION(if_infiniband, 1); 686