1 /* $OpenBSD: if_ethersubr.c,v 1.55 2001/08/19 15:28:24 jason Exp $ */ 2 /* $NetBSD: if_ethersubr.c,v 1.19 1996/05/07 02:40:30 thorpej Exp $ */ 3 4 /* 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the project nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 /* 34 * Copyright (c) 1982, 1989, 1993 35 * The Regents of the University of California. All rights reserved. 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted provided that the following conditions 39 * are met: 40 * 1. Redistributions of source code must retain the above copyright 41 * notice, this list of conditions and the following disclaimer. 42 * 2. Redistributions in binary form must reproduce the above copyright 43 * notice, this list of conditions and the following disclaimer in the 44 * documentation and/or other materials provided with the distribution. 45 * 3. All advertising materials mentioning features or use of this software 46 * must display the following acknowledgement: 47 * This product includes software developed by the University of 48 * California, Berkeley and its contributors. 49 * 4. Neither the name of the University nor the names of its contributors 50 * may be used to endorse or promote products derived from this software 51 * without specific prior written permission. 52 * 53 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 54 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 56 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 63 * SUCH DAMAGE. 64 * 65 * @(#)if_ethersubr.c 8.1 (Berkeley) 6/10/93 66 */ 67 68 /* 69 %%% portions-copyright-nrl-95 70 Portions of this software are Copyright 1995-1998 by Randall Atkinson, 71 Ronald Lee, Daniel McDonald, Bao Phan, and Chris Winters. All Rights 72 Reserved. All rights under this copyright have been assigned to the US 73 Naval Research Laboratory (NRL). The NRL Copyright Notice and License 74 Agreement Version 1.1 (January 17, 1995) applies to these portions of the 75 software. 76 You should have received a copy of the license with this software. If you 77 didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>. 78 */ 79 80 #include "bpfilter.h" 81 82 #include <sys/param.h> 83 #include <sys/systm.h> 84 #include <sys/kernel.h> 85 #include <sys/malloc.h> 86 #include <sys/mbuf.h> 87 #include <sys/protosw.h> 88 #include <sys/socket.h> 89 #include <sys/ioctl.h> 90 #include <sys/errno.h> 91 #include <sys/syslog.h> 92 #include <sys/timeout.h> 93 94 #include <machine/cpu.h> 95 96 #include <net/if.h> 97 #include <net/netisr.h> 98 #include <net/route.h> 99 #include <net/if_llc.h> 100 #include <net/if_dl.h> 101 #include <net/if_types.h> 102 103 #include <netinet/in.h> 104 #ifdef INET 105 #include <netinet/in_var.h> 106 #endif 107 #include <netinet/if_ether.h> 108 #include <netinet/ip_ipsp.h> 109 110 #if NBPFILTER > 0 111 #include <net/bpf.h> 112 #endif 113 114 #include "bridge.h" 115 #if NBRIDGE > 0 116 #include <net/if_bridge.h> 117 #endif 118 119 #include "vlan.h" 120 #if NVLAN > 0 121 #include <net/if_vlan_var.h> 122 #endif /* NVLAN > 0 */ 123 124 #ifdef INET6 125 #ifndef INET 126 #include <netinet/in.h> 127 #endif 128 #include <netinet6/in6_var.h> 129 #include <netinet6/nd6.h> 130 #endif 131 132 #ifdef NS 133 #include <netns/ns.h> 134 #include <netns/ns_if.h> 135 #endif 136 137 #ifdef IPX 138 #include <netipx/ipx.h> 139 #include <netipx/ipx_if.h> 140 #endif 141 142 #ifdef ISO 143 #include <netiso/argo_debug.h> 144 #include <netiso/iso.h> 145 #include <netiso/iso_var.h> 146 #include <netiso/iso_snpac.h> 147 #endif 148 149 #include <netccitt/x25.h> 150 #include <netccitt/pk.h> 151 #include <netccitt/pk_extern.h> 152 #include <netccitt/dll.h> 153 #include <netccitt/llc_var.h> 154 155 #ifdef NETATALK 156 #include <netatalk/at.h> 157 #include <netatalk/at_var.h> 158 #include <netatalk/at_extern.h> 159 160 extern u_char at_org_code[ 3 ]; 161 extern u_char aarp_org_code[ 3 ]; 162 #endif /* NETATALK */ 163 164 #if defined(CCITT) 165 #include <sys/socketvar.h> 166 #endif 167 168 u_char etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 169 #define senderr(e) { error = (e); goto bad;} 170 171 172 int 173 ether_ioctl(ifp, arp, cmd, data) 174 register struct ifnet *ifp; 175 struct arpcom *arp; 176 u_long cmd; 177 caddr_t data; 178 { 179 struct ifaddr *ifa = (struct ifaddr *)data; 180 int error = 0; 181 182 switch (cmd) { 183 184 #if defined(CCITT) 185 case SIOCSIFCONF_X25: 186 ifp->if_flags |= IFF_UP; 187 ifa->ifa_rtrequest = cons_rtrequest; 188 error = x25_llcglue(PRC_IFUP, ifa->ifa_addr); 189 break; 190 #endif /* CCITT */ 191 case SIOCSIFADDR: 192 switch (ifa->ifa_addr->sa_family) { 193 #ifdef IPX 194 case AF_IPX: 195 { 196 struct ipx_addr *ina = &IA_SIPX(ifa)->sipx_addr; 197 198 if (ipx_nullhost(*ina)) 199 ina->ipx_host = 200 *(union ipx_host *)(arp->ac_enaddr); 201 else 202 bcopy(ina->ipx_host.c_host, 203 arp->ac_enaddr, sizeof(arp->ac_enaddr)); 204 break; 205 } 206 #endif /* IPX */ 207 #ifdef NETATALK 208 case AF_APPLETALK: 209 /* Nothing to do. */ 210 break; 211 #endif /* NETATALK */ 212 #ifdef NS 213 /* XXX - This code is probably wrong. */ 214 case AF_NS: 215 { 216 struct ns_addr *ina = &IA_SNS(ifa)->sns_addr; 217 218 if (ns_nullhost(*ina)) 219 ina->x_host = 220 *(union ns_host *)(arp->ac_enaddr); 221 else 222 bcopy(ina->x_host.c_host, 223 arp->ac_enaddr, sizeof(arp->ac_enaddr)); 224 break; 225 } 226 #endif /* NS */ 227 } 228 break; 229 default: 230 break; 231 } 232 233 return error; 234 } 235 236 /* 237 * Ethernet output routine. 238 * Encapsulate a packet of type family for the local net. 239 * Assumes that ifp is actually pointer to arpcom structure. 240 */ 241 int 242 ether_output(ifp, m0, dst, rt0) 243 register struct ifnet *ifp; 244 struct mbuf *m0; 245 struct sockaddr *dst; 246 struct rtentry *rt0; 247 { 248 u_int16_t etype; 249 int s, len, error = 0, hdrcmplt = 0; 250 u_char edst[6], esrc[6]; 251 register struct mbuf *m = m0; 252 register struct rtentry *rt; 253 struct mbuf *mcopy = (struct mbuf *)0; 254 register struct ether_header *eh; 255 struct arpcom *ac = (struct arpcom *)ifp; 256 short mflags; 257 ALTQ_DECL(struct altq_pktattr pktattr;) 258 259 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) 260 senderr(ENETDOWN); 261 if ((rt = rt0) != NULL) { 262 if ((rt->rt_flags & RTF_UP) == 0) { 263 if ((rt0 = rt = rtalloc1(dst, 1)) != NULL) 264 rt->rt_refcnt--; 265 else 266 senderr(EHOSTUNREACH); 267 } 268 if (rt->rt_flags & RTF_GATEWAY) { 269 if (rt->rt_gwroute == 0) 270 goto lookup; 271 if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) { 272 rtfree(rt); rt = rt0; 273 lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1); 274 if ((rt = rt->rt_gwroute) == 0) 275 senderr(EHOSTUNREACH); 276 } 277 } 278 if (rt->rt_flags & RTF_REJECT) 279 if (rt->rt_rmx.rmx_expire == 0 || 280 time.tv_sec < rt->rt_rmx.rmx_expire) 281 senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH); 282 } 283 284 /* 285 * if the queueing discipline needs packet classification, 286 * do it before prepending link headers. 287 */ 288 IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family, &pktattr); 289 290 switch (dst->sa_family) { 291 292 #ifdef INET 293 case AF_INET: 294 if (!arpresolve(ac, rt, m, dst, edst)) 295 return (0); /* if not yet resolved */ 296 /* If broadcasting on a simplex interface, loopback a copy */ 297 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX)) 298 mcopy = m_copy(m, 0, (int)M_COPYALL); 299 etype = htons(ETHERTYPE_IP); 300 break; 301 #endif 302 #ifdef INET6 303 case AF_INET6: 304 #ifndef OLDIP6OUTPUT 305 if (!nd6_storelladdr(ifp, rt, m, dst, (u_char *)edst)) 306 return(0); /* it must be impossible, but... */ 307 #else 308 if (!nd6_resolve(ifp, rt, m, dst, (u_char *)edst)) 309 return(0); /* if not yet resolves */ 310 #endif 311 etype = htons(ETHERTYPE_IPV6); 312 break; 313 #endif 314 #ifdef NS 315 case AF_NS: 316 etype = htons(ETHERTYPE_NS); 317 bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host), 318 (caddr_t)edst, sizeof (edst)); 319 if (!bcmp((caddr_t)edst, (caddr_t)&ns_thishost, sizeof(edst))) 320 return (looutput(ifp, m, dst, rt)); 321 /* If broadcasting on a simplex interface, loopback a copy */ 322 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX)) 323 mcopy = m_copy(m, 0, (int)M_COPYALL); 324 break; 325 #endif 326 #ifdef IPX 327 case AF_IPX: 328 etype = htons(ETHERTYPE_IPX); 329 bcopy((caddr_t)&satosipx(dst)->sipx_addr.ipx_host, 330 (caddr_t)edst, sizeof (edst)); 331 /* If broadcasting on a simplex interface, loopback a copy */ 332 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX)) 333 mcopy = m_copy(m, 0, (int)M_COPYALL); 334 break; 335 #endif 336 #if 0 /*NRL INET6*/ 337 case AF_INET6: 338 /* 339 * The bottom line here is to either queue the outgoing packet 340 * in the discovery engine, or fill in edst with something 341 * that'll work. 342 */ 343 if (m->m_flags & M_MCAST) { 344 /* 345 * If multicast dest., then use IPv6 -> Ethernet 346 * mcast mapping. Really simple. 347 */ 348 ETHER_MAP_IPV6_MULTICAST(&((struct sockaddr_in6 *)dst)->sin6_addr, 349 edst); 350 } else { 351 /* Do unicast neighbor discovery stuff. */ 352 if (!ipv6_discov_resolve(ifp, rt, m, dst, edst)) 353 return 0; 354 } 355 etype = htons(ETHERTYPE_IPV6); 356 break; 357 #endif /* INET6 */ 358 #ifdef NETATALK 359 case AF_APPLETALK: { 360 struct at_ifaddr *aa; 361 362 if (!aarpresolve(ac, m, (struct sockaddr_at *)dst, edst)) { 363 #ifdef NETATALKDEBUG 364 extern char *prsockaddr(struct sockaddr *); 365 printf("aarpresolv: failed for %s\n", prsockaddr(dst)); 366 #endif /* NETATALKDEBUG */ 367 return (0); 368 } 369 370 /* 371 * ifaddr is the first thing in at_ifaddr 372 */ 373 aa = (struct at_ifaddr *)at_ifawithnet( 374 (struct sockaddr_at *)dst, 375 ifp->if_addrlist.tqh_first); 376 if (aa == 0) 377 goto bad; 378 379 /* 380 * In the phase 2 case, we need to prepend an mbuf for the llc 381 * header. Since we must preserve the value of m, which is 382 * passed to us by value, we m_copy() the first mbuf, 383 * and use it for our llc header. 384 */ 385 if ( aa->aa_flags & AFA_PHASE2 ) { 386 struct llc llc; 387 388 /* XXX Really this should use netisr too */ 389 M_PREPEND(m, AT_LLC_SIZE, M_WAIT); 390 /* 391 * FreeBSD doesn't count the LLC len in 392 * ifp->obytes, so they increment a length 393 * field here. We don't do this. 394 */ 395 llc.llc_dsap = llc.llc_ssap = LLC_SNAP_LSAP; 396 llc.llc_control = LLC_UI; 397 bcopy(at_org_code, llc.llc_snap.org_code, 398 sizeof(at_org_code)); 399 llc.llc_snap.ether_type = htons( ETHERTYPE_AT ); 400 bcopy(&llc, mtod(m, caddr_t), AT_LLC_SIZE); 401 etype = htons(m->m_pkthdr.len); 402 } else { 403 etype = htons(ETHERTYPE_AT); 404 } 405 } break; 406 #endif /* NETATALK */ 407 #ifdef ISO 408 case AF_ISO: { 409 int snpalen; 410 struct llc *l; 411 register struct sockaddr_dl *sdl; 412 413 if (rt && (sdl = (struct sockaddr_dl *)rt->rt_gateway) && 414 sdl->sdl_family == AF_LINK && sdl->sdl_alen > 0) { 415 bcopy(LLADDR(sdl), (caddr_t)edst, sizeof(edst)); 416 } else { 417 error = iso_snparesolve(ifp, (struct sockaddr_iso *)dst, 418 (char *)edst, &snpalen); 419 if (error) 420 goto bad; /* Not Resolved */ 421 } 422 /* If broadcasting on a simplex interface, loopback a copy */ 423 if (*edst & 1) 424 m->m_flags |= (M_BCAST|M_MCAST); 425 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX) && 426 (mcopy = m_copy(m, 0, (int)M_COPYALL))) { 427 M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT); 428 if (mcopy) { 429 eh = mtod(mcopy, struct ether_header *); 430 bcopy(edst, eh->ether_dhost, sizeof (edst)); 431 bcopy(ac->ac_enaddr, eh->ether_shost, 432 sizeof (edst)); 433 } 434 } 435 M_PREPEND(m, 3, M_DONTWAIT); 436 if (m == NULL) 437 return (0); 438 etype = htons(m->m_pkthdr.len); 439 l = mtod(m, struct llc *); 440 l->llc_dsap = l->llc_ssap = LLC_ISO_LSAP; 441 l->llc_control = LLC_UI; 442 #ifdef ARGO_DEBUG 443 if (argo_debug[D_ETHER]) { 444 int i; 445 printf("unoutput: sending pkt to: "); 446 for (i=0; i<6; i++) 447 printf("%x ", edst[i] & 0xff); 448 printf("\n"); 449 } 450 #endif 451 } break; 452 #endif /* ISO */ 453 /* case AF_NSAP: */ 454 case AF_CCITT: { 455 register struct sockaddr_dl *sdl = 456 (struct sockaddr_dl *) rt -> rt_gateway; 457 458 if (sdl && sdl->sdl_family == AF_LINK 459 && sdl->sdl_alen > 0) { 460 bcopy(LLADDR(sdl), (char *)edst, 461 sizeof(edst)); 462 } else goto bad; /* Not a link interface ? Funny ... */ 463 if ((ifp->if_flags & IFF_SIMPLEX) && (*edst & 1) && 464 (mcopy = m_copy(m, 0, (int)M_COPYALL))) { 465 M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT); 466 if (mcopy) { 467 eh = mtod(mcopy, struct ether_header *); 468 bcopy(edst, eh->ether_dhost, sizeof (edst)); 469 bcopy(ac->ac_enaddr, eh->ether_shost, 470 sizeof (edst)); 471 } 472 } 473 etype = htons(m->m_pkthdr.len); 474 #ifdef LLC_DEBUG 475 { 476 int i; 477 register struct llc *l = mtod(m, struct llc *); 478 479 printf("ether_output: sending LLC2 pkt to: "); 480 for (i=0; i<6; i++) 481 printf("%x ", edst[i] & 0xff); 482 printf(" len 0x%x dsap 0x%x ssap 0x%x control 0x%x\n", 483 m->m_pkthdr.len, l->llc_dsap & 0xff, l->llc_ssap &0xff, 484 l->llc_control & 0xff); 485 486 } 487 #endif /* LLC_DEBUG */ 488 } break; 489 490 case pseudo_AF_HDRCMPLT: 491 hdrcmplt = 1; 492 eh = (struct ether_header *)dst->sa_data; 493 bcopy((caddr_t)eh->ether_shost, (caddr_t)esrc, sizeof (esrc)); 494 /* FALLTHROUGH */ 495 496 case AF_UNSPEC: 497 eh = (struct ether_header *)dst->sa_data; 498 bcopy((caddr_t)eh->ether_dhost, (caddr_t)edst, sizeof (edst)); 499 /* AF_UNSPEC doesn't swap the byte order of the ether_type. */ 500 etype = eh->ether_type; 501 break; 502 503 default: 504 printf("%s: can't handle af%d\n", ifp->if_xname, 505 dst->sa_family); 506 senderr(EAFNOSUPPORT); 507 } 508 509 /* XXX Should we feed-back an unencrypted IPsec packet ? */ 510 if (mcopy) 511 (void) looutput(ifp, mcopy, dst, rt); 512 513 /* 514 * Add local net header. If no space in first mbuf, 515 * allocate another. 516 */ 517 M_PREPEND(m, sizeof (struct ether_header), M_DONTWAIT); 518 if (m == 0) 519 senderr(ENOBUFS); 520 eh = mtod(m, struct ether_header *); 521 bcopy((caddr_t)&etype,(caddr_t)&eh->ether_type, 522 sizeof(eh->ether_type)); 523 bcopy((caddr_t)edst, (caddr_t)eh->ether_dhost, sizeof (edst)); 524 if (hdrcmplt) 525 bcopy((caddr_t)esrc, (caddr_t)eh->ether_shost, 526 sizeof(eh->ether_shost)); 527 else 528 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)eh->ether_shost, 529 sizeof(eh->ether_shost)); 530 531 #if NBRIDGE > 0 532 /* 533 * Interfaces that are bridge members need special handling 534 * for output. 535 */ 536 if (ifp->if_bridge) { 537 struct m_tag *mtag; 538 539 /* 540 * Check if this packet has already been sent out through 541 * this bridge, in which case we simply send it out 542 * without further bridge processing. 543 */ 544 for (mtag = m_tag_find(m, PACKET_TAG_BRIDGE, NULL); mtag; 545 mtag = m_tag_find(m, PACKET_TAG_BRIDGE, mtag)) { 546 #ifdef DEBUG 547 /* Check that the information is there */ 548 if (mtag->m_tag_len != sizeof(caddr_t)) { 549 error = EINVAL; 550 goto bad; 551 } 552 #endif 553 if (!bcmp(&ifp->if_bridge, mtag + 1, sizeof(caddr_t))) 554 break; 555 } 556 if (mtag == NULL) { 557 /* Attach a tag so we can detect loops */ 558 mtag = m_tag_get(PACKET_TAG_BRIDGE, sizeof(caddr_t), 559 M_NOWAIT); 560 if (mtag == NULL) { 561 error = ENOBUFS; 562 goto bad; 563 } 564 bcopy(&ifp->if_bridge, mtag + 1, sizeof(caddr_t)); 565 m_tag_prepend(m, mtag); 566 bridge_output(ifp, m, NULL, NULL); 567 return (error); 568 } 569 } 570 #endif 571 572 mflags = m->m_flags; 573 len = m->m_pkthdr.len; 574 s = splimp(); 575 /* 576 * Queue message on interface, and start output if interface 577 * not yet active. 578 */ 579 IFQ_ENQUEUE(&ifp->if_snd, m, &pktattr, error); 580 if (error) { 581 /* mbuf is already freed */ 582 splx(s); 583 return (error); 584 } 585 ifp->if_obytes += len + sizeof (struct ether_header); 586 if (mflags & M_MCAST) 587 ifp->if_omcasts++; 588 if ((ifp->if_flags & IFF_OACTIVE) == 0) 589 (*ifp->if_start)(ifp); 590 splx(s); 591 return (error); 592 593 bad: 594 if (m) 595 m_freem(m); 596 return (error); 597 } 598 599 #ifdef ALTQ 600 /* 601 * This routine is a slight hack to allow a packet to be classified 602 * if the Ethernet headers are present. It will go away when ALTQ's 603 * classification engine understands link headers. 604 */ 605 void 606 altq_etherclassify(struct ifaltq *ifq, struct mbuf *m, 607 struct altq_pktattr *pktattr) 608 { 609 struct ether_header *eh; 610 u_int16_t ether_type; 611 int hlen, af, hdrsize; 612 caddr_t hdr; 613 614 hlen = ETHER_HDR_LEN; 615 eh = mtod(m, struct ether_header *); 616 617 ether_type = htons(eh->ether_type); 618 619 if (ether_type < ETHERMTU) { 620 /* LLC/SNAP */ 621 struct llc *llc = (struct llc *)(eh + 1); 622 hlen += 8; 623 624 if (m->m_len < hlen || 625 llc->llc_dsap != LLC_SNAP_LSAP || 626 llc->llc_ssap != LLC_SNAP_LSAP || 627 llc->llc_control != LLC_UI) { 628 /* Not SNAP. */ 629 goto bad; 630 } 631 632 ether_type = htons(llc->llc_un.type_snap.ether_type); 633 } 634 635 switch (ether_type) { 636 case ETHERTYPE_IP: 637 af = AF_INET; 638 hdrsize = 20; /* sizeof(struct ip) */ 639 break; 640 641 case ETHERTYPE_IPV6: 642 af = AF_INET6; 643 hdrsize = 40; /* sizeof(struct ip6_hdr) */ 644 break; 645 646 default: 647 af = AF_UNSPEC; 648 hdrsize = 0; 649 break; 650 } 651 652 if (m->m_len < (hlen + hdrsize)) { 653 /* 654 * Ethernet and protocol header not in a single 655 * mbuf. We can't cope with this situation right 656 * now (but it shouldn't ever happen, really, anyhow). 657 * XXX Should use m_pulldown(). 658 */ 659 printf("altq_etherclassify: headers span multiple mbufs: " 660 "%d < %d\n", m->m_len, (hlen + hdrsize)); 661 goto bad; 662 } 663 664 m->m_data += hlen; 665 m->m_len -= hlen; 666 667 hdr = mtod(m, caddr_t); 668 669 if (ALTQ_NEEDS_CLASSIFY(ifq)) 670 pktattr->pattr_class = 671 (*ifq->altq_classify)(ifq->altq_clfier, m, af); 672 pktattr->pattr_af = af; 673 pktattr->pattr_hdr = hdr; 674 675 m->m_data -= hlen; 676 m->m_len += hlen; 677 678 return; 679 680 bad: 681 pktattr->pattr_class = NULL; 682 pktattr->pattr_hdr = NULL; 683 pktattr->pattr_af = AF_UNSPEC; 684 } 685 #endif /* ALTQ */ 686 687 /* 688 * Temporary function to migrate while 689 * removing ether_header * from ether_input(). 690 */ 691 void 692 ether_input_mbuf(ifp, m) 693 struct ifnet *ifp; 694 struct mbuf *m; 695 { 696 struct ether_header *eh; 697 698 eh = mtod(m, struct ether_header *); 699 m_adj(m, ETHER_HDR_LEN); 700 ether_input(ifp, eh, m); 701 } 702 703 /* 704 * Process a received Ethernet packet; 705 * the packet is in the mbuf chain m without 706 * the ether header, which is provided separately. 707 */ 708 void 709 ether_input(ifp, eh, m) 710 struct ifnet *ifp; 711 register struct ether_header *eh; 712 struct mbuf *m; 713 { 714 register struct ifqueue *inq; 715 u_int16_t etype; 716 int s, llcfound = 0; 717 register struct llc *l; 718 struct arpcom *ac; 719 720 if ((ifp->if_flags & IFF_UP) == 0) { 721 m_freem(m); 722 return; 723 } 724 if (ETHER_IS_MULTICAST(eh->ether_dhost)) { 725 if ((ifp->if_flags & IFF_SIMPLEX) == 0) { 726 struct ifaddr *ifa; 727 struct sockaddr_dl *sdl = NULL; 728 729 for (ifa = ifp->if_addrlist.tqh_first; ifa != 0; 730 ifa = ifa->ifa_list.tqe_next) 731 if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) && 732 sdl->sdl_family == AF_LINK) 733 break; 734 735 /* 736 * If this is not a simplex interface, drop the packet 737 * if it came from us. 738 */ 739 if (sdl && bcmp(LLADDR(sdl), eh->ether_shost, 740 ETHER_ADDR_LEN) == 0) { 741 m_freem(m); 742 return; 743 } 744 } 745 746 if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost, 747 sizeof(etherbroadcastaddr)) == 0) 748 m->m_flags |= M_BCAST; 749 else 750 m->m_flags |= M_MCAST; 751 ifp->if_imcasts++; 752 } 753 754 ifp->if_ibytes += m->m_pkthdr.len + sizeof (*eh); 755 756 etype = ntohs(eh->ether_type); 757 758 #if NBRIDGE > 0 759 /* 760 * Tap the packet off here for a bridge, if configured and 761 * active for this interface. bridge_input returns 762 * NULL if it has consumed the packet, otherwise, it 763 * gets processed as normal. 764 */ 765 if (ifp->if_bridge) { 766 if (m->m_flags & M_PROTO1) 767 m->m_flags &= ~M_PROTO1; 768 else { 769 m = bridge_input(ifp, eh, m); 770 if (m == NULL) 771 return; 772 /* The bridge has determined it's for us. */ 773 ifp = m->m_pkthdr.rcvif; 774 } 775 } 776 #endif 777 778 #if NVLAN > 0 779 if (etype == ETHERTYPE_8021Q) { 780 if (vlan_input(eh, m) < 0) 781 ifp->if_noproto++; 782 return; 783 } 784 #endif /* NVLAN > 0 */ 785 786 ac = (struct arpcom *)ifp; 787 788 /* 789 * If packet is unicast and we're in promiscuous mode, make sure it 790 * is for us. Drop otherwise. 791 */ 792 if ((m->m_flags & (M_BCAST|M_MCAST)) == 0 && 793 (ifp->if_flags & IFF_PROMISC)) { 794 if (bcmp(ac->ac_enaddr, (caddr_t)eh->ether_dhost, 795 ETHER_ADDR_LEN)) { 796 m_freem(m); 797 return; 798 } 799 } 800 801 decapsulate: 802 803 switch (etype) { 804 #ifdef INET 805 case ETHERTYPE_IP: 806 schednetisr(NETISR_IP); 807 inq = &ipintrq; 808 break; 809 810 case ETHERTYPE_ARP: 811 if (ifp->if_flags & IFF_NOARP) 812 goto dropanyway; 813 schednetisr(NETISR_ARP); 814 inq = &arpintrq; 815 break; 816 817 case ETHERTYPE_REVARP: 818 if (ifp->if_flags & IFF_NOARP) 819 goto dropanyway; 820 revarpinput(m); /* XXX queue? */ 821 return; 822 823 #endif 824 #ifdef INET6 825 /* 826 * Schedule IPv6 software interrupt for incoming IPv6 packet. 827 */ 828 case ETHERTYPE_IPV6: 829 schednetisr(NETISR_IPV6); 830 inq = &ip6intrq; 831 break; 832 #endif /* INET6 */ 833 #ifdef IPX 834 case ETHERTYPE_IPX: 835 schednetisr(NETISR_IPX); 836 inq = &ipxintrq; 837 break; 838 #endif 839 #ifdef NS 840 case ETHERTYPE_NS: 841 schednetisr(NETISR_NS); 842 inq = &nsintrq; 843 break; 844 #endif 845 #ifdef NETATALK 846 case ETHERTYPE_AT: 847 schednetisr(NETISR_ATALK); 848 inq = &atintrq1; 849 break; 850 case ETHERTYPE_AARP: 851 /* probably this should be done with a NETISR as well */ 852 /* XXX queue this */ 853 aarpinput((struct arpcom *)ifp, m); 854 return; 855 #endif 856 default: 857 if (llcfound || etype > ETHERMTU) 858 goto dropanyway; 859 llcfound = 1; 860 l = mtod(m, struct llc *); 861 switch (l->llc_dsap) { 862 case LLC_SNAP_LSAP: 863 #ifdef NETATALK 864 /* 865 * Some protocols (like Appletalk) need special 866 * handling depending on if they are type II 867 * or SNAP encapsulated. Everything else 868 * gets handled by stripping off the SNAP header 869 * and going back up to decapsulate. 870 */ 871 if (l->llc_control == LLC_UI && 872 l->llc_ssap == LLC_SNAP_LSAP && 873 Bcmp(&(l->llc_snap.org_code)[0], 874 at_org_code, sizeof(at_org_code)) == 0 && 875 ntohs(l->llc_snap.ether_type) == ETHERTYPE_AT) { 876 inq = &atintrq2; 877 m_adj(m, AT_LLC_SIZE); 878 schednetisr(NETISR_ATALK); 879 break; 880 } 881 882 if (l->llc_control == LLC_UI && 883 l->llc_ssap == LLC_SNAP_LSAP && 884 Bcmp(&(l->llc_snap.org_code)[0], 885 aarp_org_code, sizeof(aarp_org_code)) == 0 && 886 ntohs(l->llc_snap.ether_type) == ETHERTYPE_AARP) { 887 m_adj(m, AT_LLC_SIZE); 888 /* XXX Really this should use netisr too */ 889 aarpinput((struct arpcom *)ifp, m); 890 return; 891 } 892 #endif /* NETATALK */ 893 if (l->llc_control == LLC_UI && 894 l->llc_dsap == LLC_SNAP_LSAP && 895 l->llc_ssap == LLC_SNAP_LSAP) { 896 /* SNAP */ 897 if (m->m_pkthdr.len > etype) 898 m_adj(m, etype - m->m_pkthdr.len); 899 m->m_data += 6; /* XXX */ 900 m->m_len -= 6; /* XXX */ 901 m->m_pkthdr.len -= 6; /* XXX */ 902 M_PREPEND(m, sizeof *eh, M_DONTWAIT); 903 if (m == 0) 904 return; 905 *mtod(m, struct ether_header *) = *eh; 906 goto decapsulate; 907 } 908 goto dropanyway; 909 #ifdef ISO 910 case LLC_ISO_LSAP: 911 switch (l->llc_control) { 912 case LLC_UI: 913 /* LLC_UI_P forbidden in class 1 service */ 914 if ((l->llc_dsap == LLC_ISO_LSAP) && 915 (l->llc_ssap == LLC_ISO_LSAP)) { 916 /* LSAP for ISO */ 917 if (m->m_pkthdr.len > etype) 918 m_adj(m, etype - m->m_pkthdr.len); 919 m->m_data += 3; /* XXX */ 920 m->m_len -= 3; /* XXX */ 921 m->m_pkthdr.len -= 3; /* XXX */ 922 M_PREPEND(m, sizeof *eh, M_DONTWAIT); 923 if (m == 0) 924 return; 925 *mtod(m, struct ether_header *) = *eh; 926 #ifdef ARGO_DEBUG 927 if (argo_debug[D_ETHER]) 928 printf("clnp packet"); 929 #endif 930 schednetisr(NETISR_ISO); 931 inq = &clnlintrq; 932 break; 933 } 934 goto dropanyway; 935 936 case LLC_XID: 937 case LLC_XID_P: 938 if(m->m_len < 6) 939 goto dropanyway; 940 l->llc_window = 0; 941 l->llc_fid = 9; 942 l->llc_class = 1; 943 l->llc_dsap = l->llc_ssap = 0; 944 /* Fall through to */ 945 case LLC_TEST: 946 case LLC_TEST_P: 947 { 948 struct sockaddr sa; 949 register struct ether_header *eh2; 950 int i; 951 u_char c = l->llc_dsap; 952 953 l->llc_dsap = l->llc_ssap; 954 l->llc_ssap = c; 955 if (m->m_flags & (M_BCAST | M_MCAST)) 956 bcopy(ac->ac_enaddr, 957 eh->ether_dhost, 6); 958 sa.sa_family = AF_UNSPEC; 959 sa.sa_len = sizeof(sa); 960 eh2 = (struct ether_header *)sa.sa_data; 961 for (i = 0; i < 6; i++) { 962 eh2->ether_shost[i] = c = eh->ether_dhost[i]; 963 eh2->ether_dhost[i] = 964 eh->ether_dhost[i] = eh->ether_shost[i]; 965 eh->ether_shost[i] = c; 966 } 967 ifp->if_output(ifp, m, &sa, NULL); 968 return; 969 } 970 break; 971 } 972 #endif /* ISO */ 973 #ifdef CCITT 974 case LLC_X25_LSAP: 975 if (m->m_pkthdr.len > etype) 976 m_adj(m, etype - m->m_pkthdr.len); 977 M_PREPEND(m, sizeof(struct sdl_hdr) , M_DONTWAIT); 978 if (m == 0) 979 return; 980 if (!sdl_sethdrif(ifp, eh->ether_shost, LLC_X25_LSAP, 981 eh->ether_dhost, LLC_X25_LSAP, 6, 982 mtod(m, struct sdl_hdr *))) 983 panic("ETHER cons addr failure"); 984 mtod(m, struct sdl_hdr *)->sdlhdr_len = etype; 985 #ifdef LLC_DEBUG 986 printf("llc packet\n"); 987 #endif /* LLC_DEBUG */ 988 schednetisr(NETISR_CCITT); 989 inq = &llcintrq; 990 break; 991 #endif /* CCITT */ 992 dropanyway: 993 default: 994 m_freem(m); 995 return; 996 } 997 } 998 999 s = splimp(); 1000 if (IF_QFULL(inq)) { 1001 IF_DROP(inq); 1002 m_freem(m); 1003 } else 1004 IF_ENQUEUE(inq, m); 1005 splx(s); 1006 } 1007 1008 /* 1009 * Convert Ethernet address to printable (loggable) representation. 1010 */ 1011 static char digits[] = "0123456789abcdef"; 1012 char * 1013 ether_sprintf(ap) 1014 register u_char *ap; 1015 { 1016 register int i; 1017 static char etherbuf[18]; 1018 register char *cp = etherbuf; 1019 1020 for (i = 0; i < 6; i++) { 1021 *cp++ = digits[*ap >> 4]; 1022 *cp++ = digits[*ap++ & 0xf]; 1023 *cp++ = ':'; 1024 } 1025 *--cp = 0; 1026 return (etherbuf); 1027 } 1028 1029 /* 1030 * Perform common duties while attaching to interface list 1031 */ 1032 void 1033 ether_ifattach(ifp) 1034 register struct ifnet *ifp; 1035 { 1036 register struct ifaddr *ifa; 1037 register struct sockaddr_dl *sdl; 1038 1039 /* 1040 * Any interface which provides a MAC address which is obviously 1041 * invalid gets whacked, so that users will notice. 1042 */ 1043 if (ETHER_IS_MULTICAST(((struct arpcom *)ifp)->ac_enaddr)) { 1044 ((struct arpcom *)ifp)->ac_enaddr[0] = 0x00; 1045 ((struct arpcom *)ifp)->ac_enaddr[1] = 0xfe; 1046 ((struct arpcom *)ifp)->ac_enaddr[2] = 0xe1; 1047 ((struct arpcom *)ifp)->ac_enaddr[3] = 0xba; 1048 ((struct arpcom *)ifp)->ac_enaddr[4] = 0xd0; 1049 ((struct arpcom *)ifp)->ac_enaddr[5] = (u_char)arc4random(); 1050 } 1051 1052 ifp->if_type = IFT_ETHER; 1053 ifp->if_addrlen = 6; 1054 ifp->if_hdrlen = 14; 1055 ifp->if_mtu = ETHERMTU; 1056 ifp->if_output = ether_output; 1057 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 1058 if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) && 1059 sdl->sdl_family == AF_LINK) { 1060 sdl->sdl_type = IFT_ETHER; 1061 sdl->sdl_alen = ifp->if_addrlen; 1062 bcopy((caddr_t)((struct arpcom *)ifp)->ac_enaddr, 1063 LLADDR(sdl), ifp->if_addrlen); 1064 break; 1065 } 1066 } 1067 LIST_INIT(&((struct arpcom *)ifp)->ac_multiaddrs); 1068 #if NBPFILTER > 0 1069 bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header)); 1070 #endif 1071 } 1072 1073 void 1074 ether_ifdetach(ifp) 1075 struct ifnet *ifp; 1076 { 1077 struct arpcom *ac = (struct arpcom *)ifp; 1078 struct ether_multi *enm; 1079 1080 for (enm = LIST_FIRST(&ac->ac_multiaddrs); 1081 enm != LIST_END(&ac->ac_multiaddrs); 1082 enm = LIST_FIRST(&ac->ac_multiaddrs)) { 1083 LIST_REMOVE(enm, enm_list); 1084 free(enm, M_IFMADDR); 1085 } 1086 } 1087 1088 u_char ether_ipmulticast_min[6] = { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 }; 1089 u_char ether_ipmulticast_max[6] = { 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xff }; 1090 1091 #ifdef INET6 1092 u_char ether_ip6multicast_min[6] = { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 }; 1093 u_char ether_ip6multicast_max[6] = { 0x33, 0x33, 0xff, 0xff, 0xff, 0xff }; 1094 #endif 1095 1096 /* 1097 * Add an Ethernet multicast address or range of addresses to the list for a 1098 * given interface. 1099 */ 1100 int 1101 ether_addmulti(ifr, ac) 1102 struct ifreq *ifr; 1103 register struct arpcom *ac; 1104 { 1105 register struct ether_multi *enm; 1106 #ifdef INET 1107 struct sockaddr_in *sin; 1108 #endif 1109 #ifdef INET6 1110 struct sockaddr_in6 *sin6; 1111 #endif /* INET6 */ 1112 u_char addrlo[6]; 1113 u_char addrhi[6]; 1114 int s = splimp(); 1115 1116 switch (ifr->ifr_addr.sa_family) { 1117 1118 case AF_UNSPEC: 1119 bcopy(ifr->ifr_addr.sa_data, addrlo, 6); 1120 bcopy(addrlo, addrhi, 6); 1121 break; 1122 1123 #ifdef INET 1124 case AF_INET: 1125 sin = (struct sockaddr_in *)&(ifr->ifr_addr); 1126 if (sin->sin_addr.s_addr == INADDR_ANY) { 1127 /* 1128 * An IP address of INADDR_ANY means listen to all 1129 * of the Ethernet multicast addresses used for IP. 1130 * (This is for the sake of IP multicast routers.) 1131 */ 1132 bcopy(ether_ipmulticast_min, addrlo, 6); 1133 bcopy(ether_ipmulticast_max, addrhi, 6); 1134 } 1135 else { 1136 ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo); 1137 bcopy(addrlo, addrhi, 6); 1138 } 1139 break; 1140 #endif 1141 #ifdef INET6 1142 case AF_INET6: 1143 sin6 = (struct sockaddr_in6 *) 1144 &(((struct in6_ifreq *)ifr)->ifr_addr); 1145 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 1146 /* 1147 * An unspecified IPv6 address means listen to all 1148 * of the IPv6 multicast addresses on this Ethernet. 1149 * (Multicast routers like this.) 1150 */ 1151 bcopy(ether_ip6multicast_min, addrlo, ETHER_ADDR_LEN); 1152 bcopy(ether_ip6multicast_max, addrhi, ETHER_ADDR_LEN); 1153 } else { 1154 ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo); 1155 bcopy(addrlo, addrhi, ETHER_ADDR_LEN); 1156 } 1157 break; 1158 #endif /* INET6 */ 1159 1160 default: 1161 splx(s); 1162 return (EAFNOSUPPORT); 1163 } 1164 1165 /* 1166 * Verify that we have valid Ethernet multicast addresses. 1167 */ 1168 if ((addrlo[0] & 0x01) != 1 || (addrhi[0] & 0x01) != 1) { 1169 splx(s); 1170 return (EINVAL); 1171 } 1172 /* 1173 * See if the address range is already in the list. 1174 */ 1175 ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm); 1176 if (enm != NULL) { 1177 /* 1178 * Found it; just increment the reference count. 1179 */ 1180 ++enm->enm_refcount; 1181 splx(s); 1182 return (0); 1183 } 1184 /* 1185 * New address or range; malloc a new multicast record 1186 * and link it into the interface's multicast list. 1187 */ 1188 enm = (struct ether_multi *)malloc(sizeof(*enm), M_IFMADDR, M_NOWAIT); 1189 if (enm == NULL) { 1190 splx(s); 1191 return (ENOBUFS); 1192 } 1193 bcopy(addrlo, enm->enm_addrlo, 6); 1194 bcopy(addrhi, enm->enm_addrhi, 6); 1195 enm->enm_ac = ac; 1196 enm->enm_refcount = 1; 1197 LIST_INSERT_HEAD(&ac->ac_multiaddrs, enm, enm_list); 1198 ac->ac_multicnt++; 1199 splx(s); 1200 /* 1201 * Return ENETRESET to inform the driver that the list has changed 1202 * and its reception filter should be adjusted accordingly. 1203 */ 1204 return (ENETRESET); 1205 } 1206 1207 /* 1208 * Delete a multicast address record. 1209 */ 1210 int 1211 ether_delmulti(ifr, ac) 1212 struct ifreq *ifr; 1213 register struct arpcom *ac; 1214 { 1215 register struct ether_multi *enm; 1216 #ifdef INET 1217 struct sockaddr_in *sin; 1218 #endif 1219 #ifdef INET6 1220 struct sockaddr_in6 *sin6; 1221 #endif /* INET6 */ 1222 u_char addrlo[6]; 1223 u_char addrhi[6]; 1224 int s = splimp(); 1225 1226 switch (ifr->ifr_addr.sa_family) { 1227 1228 case AF_UNSPEC: 1229 bcopy(ifr->ifr_addr.sa_data, addrlo, 6); 1230 bcopy(addrlo, addrhi, 6); 1231 break; 1232 1233 #ifdef INET 1234 case AF_INET: 1235 sin = (struct sockaddr_in *)&(ifr->ifr_addr); 1236 if (sin->sin_addr.s_addr == INADDR_ANY) { 1237 /* 1238 * An IP address of INADDR_ANY means stop listening 1239 * to the range of Ethernet multicast addresses used 1240 * for IP. 1241 */ 1242 bcopy(ether_ipmulticast_min, addrlo, 6); 1243 bcopy(ether_ipmulticast_max, addrhi, 6); 1244 } 1245 else { 1246 ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo); 1247 bcopy(addrlo, addrhi, 6); 1248 } 1249 break; 1250 #endif 1251 #ifdef INET6 1252 case AF_INET6: 1253 sin6 = (struct sockaddr_in6 *)&(ifr->ifr_addr); 1254 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 1255 /* 1256 * An unspecified IPv6 address means stop listening to 1257 * all IPv6 multicast addresses on this Ethernet.' 1258 * 1259 * (This might not be healthy, given IPv6's reliance on 1260 * multicast for things like neighbor discovery. 1261 * Perhaps initializing all-nodes, solicited nodes, and 1262 * possibly all-routers for this interface afterwards 1263 * is not a bad idea.) 1264 */ 1265 bcopy(ether_ip6multicast_min, addrlo, ETHER_ADDR_LEN); 1266 bcopy(ether_ip6multicast_max, addrhi, ETHER_ADDR_LEN); 1267 } else { 1268 ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo); 1269 bcopy(addrlo, addrhi, ETHER_ADDR_LEN); 1270 } 1271 break; 1272 #endif /* INET6 */ 1273 1274 default: 1275 splx(s); 1276 return (EAFNOSUPPORT); 1277 } 1278 1279 /* 1280 * Look up the address in our list. 1281 */ 1282 ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm); 1283 if (enm == NULL) { 1284 splx(s); 1285 return (ENXIO); 1286 } 1287 if (--enm->enm_refcount != 0) { 1288 /* 1289 * Still some claims to this record. 1290 */ 1291 splx(s); 1292 return (0); 1293 } 1294 /* 1295 * No remaining claims to this record; unlink and free it. 1296 */ 1297 LIST_REMOVE(enm, enm_list); 1298 free(enm, M_IFMADDR); 1299 ac->ac_multicnt--; 1300 splx(s); 1301 /* 1302 * Return ENETRESET to inform the driver that the list has changed 1303 * and its reception filter should be adjusted accordingly. 1304 */ 1305 return (ENETRESET); 1306 } 1307