1 /* $OpenBSD: if_ethersubr.c,v 1.61 2002/02/07 23:20:57 art 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 if (!nd6_storelladdr(ifp, rt, m, dst, (u_char *)edst)) 305 return(0); /* it must be impossible, but... */ 306 etype = htons(ETHERTYPE_IPV6); 307 break; 308 #endif 309 #ifdef NS 310 case AF_NS: 311 etype = htons(ETHERTYPE_NS); 312 bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host), 313 (caddr_t)edst, sizeof (edst)); 314 if (!bcmp((caddr_t)edst, (caddr_t)&ns_thishost, sizeof(edst))) 315 return (looutput(ifp, m, dst, rt)); 316 /* If broadcasting on a simplex interface, loopback a copy */ 317 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX)) 318 mcopy = m_copy(m, 0, (int)M_COPYALL); 319 break; 320 #endif 321 #ifdef IPX 322 case AF_IPX: 323 etype = htons(ETHERTYPE_IPX); 324 bcopy((caddr_t)&satosipx(dst)->sipx_addr.ipx_host, 325 (caddr_t)edst, sizeof (edst)); 326 /* If broadcasting on a simplex interface, loopback a copy */ 327 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX)) 328 mcopy = m_copy(m, 0, (int)M_COPYALL); 329 break; 330 #endif 331 #if 0 /*NRL INET6*/ 332 case AF_INET6: 333 /* 334 * The bottom line here is to either queue the outgoing packet 335 * in the discovery engine, or fill in edst with something 336 * that'll work. 337 */ 338 if (m->m_flags & M_MCAST) { 339 /* 340 * If multicast dest., then use IPv6 -> Ethernet 341 * mcast mapping. Really simple. 342 */ 343 ETHER_MAP_IPV6_MULTICAST(&((struct sockaddr_in6 *)dst)->sin6_addr, 344 edst); 345 } else { 346 /* Do unicast neighbor discovery stuff. */ 347 if (!ipv6_discov_resolve(ifp, rt, m, dst, edst)) 348 return 0; 349 } 350 etype = htons(ETHERTYPE_IPV6); 351 break; 352 #endif /* INET6 */ 353 #ifdef NETATALK 354 case AF_APPLETALK: { 355 struct at_ifaddr *aa; 356 357 if (!aarpresolve(ac, m, (struct sockaddr_at *)dst, edst)) { 358 #ifdef NETATALKDEBUG 359 extern char *prsockaddr(struct sockaddr *); 360 printf("aarpresolv: failed for %s\n", prsockaddr(dst)); 361 #endif /* NETATALKDEBUG */ 362 return (0); 363 } 364 365 /* 366 * ifaddr is the first thing in at_ifaddr 367 */ 368 aa = (struct at_ifaddr *)at_ifawithnet( 369 (struct sockaddr_at *)dst, 370 TAILQ_FIRST(&ifp->if_addrlist)); 371 if (aa == 0) 372 goto bad; 373 374 /* 375 * In the phase 2 case, we need to prepend an mbuf for the llc 376 * header. Since we must preserve the value of m, which is 377 * passed to us by value, we m_copy() the first mbuf, 378 * and use it for our llc header. 379 */ 380 if (aa->aa_flags & AFA_PHASE2) { 381 struct llc llc; 382 383 M_PREPEND(m, AT_LLC_SIZE, M_DONTWAIT); 384 if (m == NULL) 385 return (0); 386 /* 387 * FreeBSD doesn't count the LLC len in 388 * ifp->obytes, so they increment a length 389 * field here. We don't do this. 390 */ 391 llc.llc_dsap = llc.llc_ssap = LLC_SNAP_LSAP; 392 llc.llc_control = LLC_UI; 393 bcopy(at_org_code, llc.llc_snap.org_code, 394 sizeof(at_org_code)); 395 llc.llc_snap.ether_type = htons( ETHERTYPE_AT ); 396 bcopy(&llc, mtod(m, caddr_t), AT_LLC_SIZE); 397 etype = htons(m->m_pkthdr.len); 398 } else { 399 etype = htons(ETHERTYPE_AT); 400 } 401 } break; 402 #endif /* NETATALK */ 403 #ifdef ISO 404 case AF_ISO: { 405 int snpalen; 406 struct llc *l; 407 register struct sockaddr_dl *sdl; 408 409 if (rt && (sdl = (struct sockaddr_dl *)rt->rt_gateway) && 410 sdl->sdl_family == AF_LINK && sdl->sdl_alen > 0) { 411 bcopy(LLADDR(sdl), (caddr_t)edst, sizeof(edst)); 412 } else { 413 error = iso_snparesolve(ifp, (struct sockaddr_iso *)dst, 414 (char *)edst, &snpalen); 415 if (error) 416 goto bad; /* Not Resolved */ 417 } 418 /* If broadcasting on a simplex interface, loopback a copy */ 419 if (*edst & 1) 420 m->m_flags |= (M_BCAST|M_MCAST); 421 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX) && 422 (mcopy = m_copy(m, 0, (int)M_COPYALL))) { 423 M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT); 424 if (mcopy) { 425 eh = mtod(mcopy, struct ether_header *); 426 bcopy(edst, eh->ether_dhost, sizeof (edst)); 427 bcopy(ac->ac_enaddr, eh->ether_shost, 428 sizeof (edst)); 429 } 430 } 431 M_PREPEND(m, 3, M_DONTWAIT); 432 if (m == NULL) 433 return (0); 434 etype = htons(m->m_pkthdr.len); 435 l = mtod(m, struct llc *); 436 l->llc_dsap = l->llc_ssap = LLC_ISO_LSAP; 437 l->llc_control = LLC_UI; 438 #ifdef ARGO_DEBUG 439 if (argo_debug[D_ETHER]) { 440 int i; 441 printf("unoutput: sending pkt to: "); 442 for (i=0; i<6; i++) 443 printf("%x ", edst[i] & 0xff); 444 printf("\n"); 445 } 446 #endif 447 } break; 448 #endif /* ISO */ 449 /* case AF_NSAP: */ 450 case AF_CCITT: { 451 register struct sockaddr_dl *sdl = 452 (struct sockaddr_dl *) rt -> rt_gateway; 453 454 if (sdl && sdl->sdl_family == AF_LINK 455 && sdl->sdl_alen > 0) { 456 bcopy(LLADDR(sdl), (char *)edst, 457 sizeof(edst)); 458 } else goto bad; /* Not a link interface ? Funny ... */ 459 if ((ifp->if_flags & IFF_SIMPLEX) && (*edst & 1) && 460 (mcopy = m_copy(m, 0, (int)M_COPYALL))) { 461 M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT); 462 if (mcopy) { 463 eh = mtod(mcopy, struct ether_header *); 464 bcopy(edst, eh->ether_dhost, sizeof (edst)); 465 bcopy(ac->ac_enaddr, eh->ether_shost, 466 sizeof (edst)); 467 } 468 } 469 etype = htons(m->m_pkthdr.len); 470 #ifdef LLC_DEBUG 471 { 472 int i; 473 register struct llc *l = mtod(m, struct llc *); 474 475 printf("ether_output: sending LLC2 pkt to: "); 476 for (i=0; i<6; i++) 477 printf("%x ", edst[i] & 0xff); 478 printf(" len 0x%x dsap 0x%x ssap 0x%x control 0x%x\n", 479 m->m_pkthdr.len, l->llc_dsap & 0xff, l->llc_ssap &0xff, 480 l->llc_control & 0xff); 481 482 } 483 #endif /* LLC_DEBUG */ 484 } break; 485 486 case pseudo_AF_HDRCMPLT: 487 hdrcmplt = 1; 488 eh = (struct ether_header *)dst->sa_data; 489 bcopy((caddr_t)eh->ether_shost, (caddr_t)esrc, sizeof (esrc)); 490 /* FALLTHROUGH */ 491 492 case AF_UNSPEC: 493 eh = (struct ether_header *)dst->sa_data; 494 bcopy((caddr_t)eh->ether_dhost, (caddr_t)edst, sizeof (edst)); 495 /* AF_UNSPEC doesn't swap the byte order of the ether_type. */ 496 etype = eh->ether_type; 497 break; 498 499 default: 500 printf("%s: can't handle af%d\n", ifp->if_xname, 501 dst->sa_family); 502 senderr(EAFNOSUPPORT); 503 } 504 505 /* XXX Should we feed-back an unencrypted IPsec packet ? */ 506 if (mcopy) 507 (void) looutput(ifp, mcopy, dst, rt); 508 509 /* 510 * Add local net header. If no space in first mbuf, 511 * allocate another. 512 */ 513 M_PREPEND(m, sizeof (struct ether_header), M_DONTWAIT); 514 if (m == 0) 515 senderr(ENOBUFS); 516 eh = mtod(m, struct ether_header *); 517 bcopy((caddr_t)&etype,(caddr_t)&eh->ether_type, 518 sizeof(eh->ether_type)); 519 bcopy((caddr_t)edst, (caddr_t)eh->ether_dhost, sizeof (edst)); 520 if (hdrcmplt) 521 bcopy((caddr_t)esrc, (caddr_t)eh->ether_shost, 522 sizeof(eh->ether_shost)); 523 else 524 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)eh->ether_shost, 525 sizeof(eh->ether_shost)); 526 527 #if NBRIDGE > 0 528 /* 529 * Interfaces that are bridge members need special handling 530 * for output. 531 */ 532 if (ifp->if_bridge) { 533 struct m_tag *mtag; 534 535 /* 536 * Check if this packet has already been sent out through 537 * this bridge, in which case we simply send it out 538 * without further bridge processing. 539 */ 540 for (mtag = m_tag_find(m, PACKET_TAG_BRIDGE, NULL); mtag; 541 mtag = m_tag_find(m, PACKET_TAG_BRIDGE, mtag)) { 542 #ifdef DEBUG 543 /* Check that the information is there */ 544 if (mtag->m_tag_len != sizeof(caddr_t)) { 545 error = EINVAL; 546 goto bad; 547 } 548 #endif 549 if (!bcmp(&ifp->if_bridge, mtag + 1, sizeof(caddr_t))) 550 break; 551 } 552 if (mtag == NULL) { 553 /* Attach a tag so we can detect loops */ 554 mtag = m_tag_get(PACKET_TAG_BRIDGE, sizeof(caddr_t), 555 M_NOWAIT); 556 if (mtag == NULL) { 557 error = ENOBUFS; 558 goto bad; 559 } 560 bcopy(&ifp->if_bridge, mtag + 1, sizeof(caddr_t)); 561 m_tag_prepend(m, mtag); 562 bridge_output(ifp, m, NULL, NULL); 563 return (error); 564 } 565 } 566 #endif 567 568 mflags = m->m_flags; 569 len = m->m_pkthdr.len; 570 s = splimp(); 571 /* 572 * Queue message on interface, and start output if interface 573 * not yet active. 574 */ 575 IFQ_ENQUEUE(&ifp->if_snd, m, &pktattr, error); 576 if (error) { 577 /* mbuf is already freed */ 578 splx(s); 579 return (error); 580 } 581 ifp->if_obytes += len + sizeof (struct ether_header); 582 if (mflags & M_MCAST) 583 ifp->if_omcasts++; 584 if ((ifp->if_flags & IFF_OACTIVE) == 0) 585 (*ifp->if_start)(ifp); 586 splx(s); 587 return (error); 588 589 bad: 590 if (m) 591 m_freem(m); 592 return (error); 593 } 594 595 #ifdef ALTQ 596 /* 597 * This routine is a slight hack to allow a packet to be classified 598 * if the Ethernet headers are present. It will go away when ALTQ's 599 * classification engine understands link headers. 600 */ 601 void 602 altq_etherclassify(struct ifaltq *ifq, struct mbuf *m, 603 struct altq_pktattr *pktattr) 604 { 605 struct ether_header *eh; 606 u_int16_t ether_type; 607 int hlen, af, hdrsize; 608 caddr_t hdr; 609 610 hlen = ETHER_HDR_LEN; 611 eh = mtod(m, struct ether_header *); 612 613 ether_type = htons(eh->ether_type); 614 615 if (ether_type < ETHERMTU) { 616 /* LLC/SNAP */ 617 struct llc *llc = (struct llc *)(eh + 1); 618 hlen += 8; 619 620 if (m->m_len < hlen || 621 llc->llc_dsap != LLC_SNAP_LSAP || 622 llc->llc_ssap != LLC_SNAP_LSAP || 623 llc->llc_control != LLC_UI) { 624 /* Not SNAP. */ 625 goto bad; 626 } 627 628 ether_type = htons(llc->llc_un.type_snap.ether_type); 629 } 630 631 switch (ether_type) { 632 case ETHERTYPE_IP: 633 af = AF_INET; 634 hdrsize = 20; /* sizeof(struct ip) */ 635 break; 636 637 case ETHERTYPE_IPV6: 638 af = AF_INET6; 639 hdrsize = 40; /* sizeof(struct ip6_hdr) */ 640 break; 641 642 default: 643 af = AF_UNSPEC; 644 hdrsize = 0; 645 break; 646 } 647 648 if (m->m_len < (hlen + hdrsize)) { 649 /* 650 * Ethernet and protocol header not in a single 651 * mbuf. We can't cope with this situation right 652 * now (but it shouldn't ever happen, really, anyhow). 653 * XXX Should use m_pulldown(). 654 */ 655 #ifdef DEBUG 656 printf("altq_etherclassify: headers span multiple mbufs: " 657 "%d < %d\n", m->m_len, (hlen + hdrsize)); 658 #endif 659 goto bad; 660 } 661 662 m->m_data += hlen; 663 m->m_len -= hlen; 664 665 hdr = mtod(m, caddr_t); 666 667 if (ALTQ_NEEDS_CLASSIFY(ifq)) 668 pktattr->pattr_class = 669 (*ifq->altq_classify)(ifq->altq_clfier, m, af); 670 pktattr->pattr_af = af; 671 pktattr->pattr_hdr = hdr; 672 673 m->m_data -= hlen; 674 m->m_len += hlen; 675 676 return; 677 678 bad: 679 pktattr->pattr_class = NULL; 680 pktattr->pattr_hdr = NULL; 681 pktattr->pattr_af = AF_UNSPEC; 682 } 683 #endif /* ALTQ */ 684 685 /* 686 * Temporary function to migrate while 687 * removing ether_header * from ether_input(). 688 */ 689 void 690 ether_input_mbuf(ifp, m) 691 struct ifnet *ifp; 692 struct mbuf *m; 693 { 694 struct ether_header *eh; 695 696 eh = mtod(m, struct ether_header *); 697 m_adj(m, ETHER_HDR_LEN); 698 ether_input(ifp, eh, m); 699 } 700 701 /* 702 * Process a received Ethernet packet; 703 * the packet is in the mbuf chain m without 704 * the ether header, which is provided separately. 705 */ 706 void 707 ether_input(ifp, eh, m) 708 struct ifnet *ifp; 709 register struct ether_header *eh; 710 struct mbuf *m; 711 { 712 register struct ifqueue *inq; 713 u_int16_t etype; 714 int s, llcfound = 0; 715 register struct llc *l; 716 struct arpcom *ac; 717 718 if ((ifp->if_flags & IFF_UP) == 0) { 719 m_freem(m); 720 return; 721 } 722 if (ETHER_IS_MULTICAST(eh->ether_dhost)) { 723 if ((ifp->if_flags & IFF_SIMPLEX) == 0) { 724 struct ifaddr *ifa; 725 struct sockaddr_dl *sdl = NULL; 726 727 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 728 if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) && 729 sdl->sdl_family == AF_LINK) 730 break; 731 } 732 /* 733 * If this is not a simplex interface, drop the packet 734 * if it came from us. 735 */ 736 if (sdl && bcmp(LLADDR(sdl), eh->ether_shost, 737 ETHER_ADDR_LEN) == 0) { 738 m_freem(m); 739 return; 740 } 741 } 742 743 if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost, 744 sizeof(etherbroadcastaddr)) == 0) 745 m->m_flags |= M_BCAST; 746 else 747 m->m_flags |= M_MCAST; 748 ifp->if_imcasts++; 749 } 750 751 ifp->if_ibytes += m->m_pkthdr.len + sizeof (*eh); 752 753 etype = ntohs(eh->ether_type); 754 755 #if NBRIDGE > 0 756 /* 757 * Tap the packet off here for a bridge, if configured and 758 * active for this interface. bridge_input returns 759 * NULL if it has consumed the packet, otherwise, it 760 * gets processed as normal. 761 */ 762 if (ifp->if_bridge) { 763 if (m->m_flags & M_PROTO1) 764 m->m_flags &= ~M_PROTO1; 765 else { 766 m = bridge_input(ifp, eh, m); 767 if (m == NULL) 768 return; 769 /* The bridge has determined it's for us. */ 770 ifp = m->m_pkthdr.rcvif; 771 } 772 } 773 #endif 774 775 #if NVLAN > 0 776 if (etype == ETHERTYPE_8021Q) { 777 if (vlan_input(eh, m) < 0) 778 ifp->if_noproto++; 779 return; 780 } 781 #endif /* NVLAN > 0 */ 782 783 ac = (struct arpcom *)ifp; 784 785 /* 786 * If packet is unicast and we're in promiscuous mode, make sure it 787 * is for us. Drop otherwise. 788 */ 789 if ((m->m_flags & (M_BCAST|M_MCAST)) == 0 && 790 (ifp->if_flags & IFF_PROMISC)) { 791 if (bcmp(ac->ac_enaddr, (caddr_t)eh->ether_dhost, 792 ETHER_ADDR_LEN)) { 793 m_freem(m); 794 return; 795 } 796 } 797 798 decapsulate: 799 800 switch (etype) { 801 #ifdef INET 802 case ETHERTYPE_IP: 803 schednetisr(NETISR_IP); 804 inq = &ipintrq; 805 break; 806 807 case ETHERTYPE_ARP: 808 if (ifp->if_flags & IFF_NOARP) 809 goto dropanyway; 810 schednetisr(NETISR_ARP); 811 inq = &arpintrq; 812 break; 813 814 case ETHERTYPE_REVARP: 815 if (ifp->if_flags & IFF_NOARP) 816 goto dropanyway; 817 revarpinput(m); /* XXX queue? */ 818 return; 819 820 #endif 821 #ifdef INET6 822 /* 823 * Schedule IPv6 software interrupt for incoming IPv6 packet. 824 */ 825 case ETHERTYPE_IPV6: 826 schednetisr(NETISR_IPV6); 827 inq = &ip6intrq; 828 break; 829 #endif /* INET6 */ 830 #ifdef IPX 831 case ETHERTYPE_IPX: 832 schednetisr(NETISR_IPX); 833 inq = &ipxintrq; 834 break; 835 #endif 836 #ifdef NS 837 case ETHERTYPE_NS: 838 schednetisr(NETISR_NS); 839 inq = &nsintrq; 840 break; 841 #endif 842 #ifdef NETATALK 843 case ETHERTYPE_AT: 844 schednetisr(NETISR_ATALK); 845 inq = &atintrq1; 846 break; 847 case ETHERTYPE_AARP: 848 /* probably this should be done with a NETISR as well */ 849 /* XXX queue this */ 850 aarpinput((struct arpcom *)ifp, m); 851 return; 852 #endif 853 default: 854 if (llcfound || etype > ETHERMTU) 855 goto dropanyway; 856 llcfound = 1; 857 l = mtod(m, struct llc *); 858 switch (l->llc_dsap) { 859 case LLC_SNAP_LSAP: 860 #ifdef NETATALK 861 /* 862 * Some protocols (like Appletalk) need special 863 * handling depending on if they are type II 864 * or SNAP encapsulated. Everything else 865 * gets handled by stripping off the SNAP header 866 * and going back up to decapsulate. 867 */ 868 if (l->llc_control == LLC_UI && 869 l->llc_ssap == LLC_SNAP_LSAP && 870 Bcmp(&(l->llc_snap.org_code)[0], 871 at_org_code, sizeof(at_org_code)) == 0 && 872 ntohs(l->llc_snap.ether_type) == ETHERTYPE_AT) { 873 inq = &atintrq2; 874 m_adj(m, AT_LLC_SIZE); 875 schednetisr(NETISR_ATALK); 876 break; 877 } 878 879 if (l->llc_control == LLC_UI && 880 l->llc_ssap == LLC_SNAP_LSAP && 881 Bcmp(&(l->llc_snap.org_code)[0], 882 aarp_org_code, sizeof(aarp_org_code)) == 0 && 883 ntohs(l->llc_snap.ether_type) == ETHERTYPE_AARP) { 884 m_adj(m, AT_LLC_SIZE); 885 /* XXX Really this should use netisr too */ 886 aarpinput((struct arpcom *)ifp, m); 887 return; 888 } 889 #endif /* NETATALK */ 890 if (l->llc_control == LLC_UI && 891 l->llc_dsap == LLC_SNAP_LSAP && 892 l->llc_ssap == LLC_SNAP_LSAP) { 893 /* SNAP */ 894 if (m->m_pkthdr.len > etype) 895 m_adj(m, etype - m->m_pkthdr.len); 896 m->m_data += 6; /* XXX */ 897 m->m_len -= 6; /* XXX */ 898 m->m_pkthdr.len -= 6; /* XXX */ 899 M_PREPEND(m, sizeof *eh, M_DONTWAIT); 900 if (m == 0) 901 return; 902 *mtod(m, struct ether_header *) = *eh; 903 goto decapsulate; 904 } 905 goto dropanyway; 906 #ifdef ISO 907 case LLC_ISO_LSAP: 908 switch (l->llc_control) { 909 case LLC_UI: 910 /* LLC_UI_P forbidden in class 1 service */ 911 if ((l->llc_dsap == LLC_ISO_LSAP) && 912 (l->llc_ssap == LLC_ISO_LSAP)) { 913 /* LSAP for ISO */ 914 if (m->m_pkthdr.len > etype) 915 m_adj(m, etype - m->m_pkthdr.len); 916 m->m_data += 3; /* XXX */ 917 m->m_len -= 3; /* XXX */ 918 m->m_pkthdr.len -= 3; /* XXX */ 919 M_PREPEND(m, sizeof *eh, M_DONTWAIT); 920 if (m == 0) 921 return; 922 *mtod(m, struct ether_header *) = *eh; 923 #ifdef ARGO_DEBUG 924 if (argo_debug[D_ETHER]) 925 printf("clnp packet"); 926 #endif 927 schednetisr(NETISR_ISO); 928 inq = &clnlintrq; 929 break; 930 } 931 goto dropanyway; 932 933 case LLC_XID: 934 case LLC_XID_P: 935 if(m->m_len < 6) 936 goto dropanyway; 937 l->llc_window = 0; 938 l->llc_fid = 9; 939 l->llc_class = 1; 940 l->llc_dsap = l->llc_ssap = 0; 941 /* Fall through to */ 942 case LLC_TEST: 943 case LLC_TEST_P: 944 { 945 struct sockaddr sa; 946 register struct ether_header *eh2; 947 int i; 948 u_char c = l->llc_dsap; 949 950 l->llc_dsap = l->llc_ssap; 951 l->llc_ssap = c; 952 if (m->m_flags & (M_BCAST | M_MCAST)) 953 bcopy(ac->ac_enaddr, 954 eh->ether_dhost, 6); 955 sa.sa_family = AF_UNSPEC; 956 sa.sa_len = sizeof(sa); 957 eh2 = (struct ether_header *)sa.sa_data; 958 for (i = 0; i < 6; i++) { 959 eh2->ether_shost[i] = c = eh->ether_dhost[i]; 960 eh2->ether_dhost[i] = 961 eh->ether_dhost[i] = eh->ether_shost[i]; 962 eh->ether_shost[i] = c; 963 } 964 ifp->if_output(ifp, m, &sa, NULL); 965 return; 966 } 967 break; 968 } 969 #endif /* ISO */ 970 #ifdef CCITT 971 case LLC_X25_LSAP: 972 if (m->m_pkthdr.len > etype) 973 m_adj(m, etype - m->m_pkthdr.len); 974 M_PREPEND(m, sizeof(struct sdl_hdr) , M_DONTWAIT); 975 if (m == 0) 976 return; 977 if (!sdl_sethdrif(ifp, eh->ether_shost, LLC_X25_LSAP, 978 eh->ether_dhost, LLC_X25_LSAP, 6, 979 mtod(m, struct sdl_hdr *))) 980 panic("ETHER cons addr failure"); 981 mtod(m, struct sdl_hdr *)->sdlhdr_len = etype; 982 #ifdef LLC_DEBUG 983 printf("llc packet\n"); 984 #endif /* LLC_DEBUG */ 985 schednetisr(NETISR_CCITT); 986 inq = &llcintrq; 987 break; 988 #endif /* CCITT */ 989 dropanyway: 990 default: 991 m_freem(m); 992 return; 993 } 994 } 995 996 s = splimp(); 997 if (IF_QFULL(inq)) { 998 IF_DROP(inq); 999 m_freem(m); 1000 } else 1001 IF_ENQUEUE(inq, m); 1002 splx(s); 1003 } 1004 1005 /* 1006 * Convert Ethernet address to printable (loggable) representation. 1007 */ 1008 static char digits[] = "0123456789abcdef"; 1009 char * 1010 ether_sprintf(ap) 1011 register u_char *ap; 1012 { 1013 register int i; 1014 static char etherbuf[18]; 1015 register char *cp = etherbuf; 1016 1017 for (i = 0; i < 6; i++) { 1018 *cp++ = digits[*ap >> 4]; 1019 *cp++ = digits[*ap++ & 0xf]; 1020 *cp++ = ':'; 1021 } 1022 *--cp = 0; 1023 return (etherbuf); 1024 } 1025 1026 /* 1027 * Perform common duties while attaching to interface list 1028 */ 1029 void 1030 ether_ifattach(ifp) 1031 register struct ifnet *ifp; 1032 { 1033 register struct ifaddr *ifa; 1034 register struct sockaddr_dl *sdl; 1035 1036 /* 1037 * Any interface which provides a MAC address which is obviously 1038 * invalid gets whacked, so that users will notice. 1039 */ 1040 if (ETHER_IS_MULTICAST(((struct arpcom *)ifp)->ac_enaddr)) { 1041 ((struct arpcom *)ifp)->ac_enaddr[0] = 0x00; 1042 ((struct arpcom *)ifp)->ac_enaddr[1] = 0xfe; 1043 ((struct arpcom *)ifp)->ac_enaddr[2] = 0xe1; 1044 ((struct arpcom *)ifp)->ac_enaddr[3] = 0xba; 1045 ((struct arpcom *)ifp)->ac_enaddr[4] = 0xd0; 1046 /* 1047 * XXX use of random() by anything except the scheduler is 1048 * normally invalid, but this is boot time, so pre-scheduler, 1049 * and the random subsystem is not alive yet 1050 */ 1051 ((struct arpcom *)ifp)->ac_enaddr[5] = (u_char)random() & 0xff; 1052 } 1053 1054 ifp->if_type = IFT_ETHER; 1055 ifp->if_addrlen = 6; 1056 ifp->if_hdrlen = 14; 1057 ifp->if_mtu = ETHERMTU; 1058 ifp->if_output = ether_output; 1059 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 1060 if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) && 1061 sdl->sdl_family == AF_LINK) { 1062 sdl->sdl_type = IFT_ETHER; 1063 sdl->sdl_alen = ifp->if_addrlen; 1064 bcopy((caddr_t)((struct arpcom *)ifp)->ac_enaddr, 1065 LLADDR(sdl), ifp->if_addrlen); 1066 break; 1067 } 1068 } 1069 LIST_INIT(&((struct arpcom *)ifp)->ac_multiaddrs); 1070 #if NBPFILTER > 0 1071 bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header)); 1072 #endif 1073 } 1074 1075 void 1076 ether_ifdetach(ifp) 1077 struct ifnet *ifp; 1078 { 1079 struct arpcom *ac = (struct arpcom *)ifp; 1080 struct ether_multi *enm; 1081 1082 for (enm = LIST_FIRST(&ac->ac_multiaddrs); 1083 enm != LIST_END(&ac->ac_multiaddrs); 1084 enm = LIST_FIRST(&ac->ac_multiaddrs)) { 1085 LIST_REMOVE(enm, enm_list); 1086 free(enm, M_IFMADDR); 1087 } 1088 } 1089 1090 u_char ether_ipmulticast_min[6] = { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 }; 1091 u_char ether_ipmulticast_max[6] = { 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xff }; 1092 1093 #ifdef INET6 1094 u_char ether_ip6multicast_min[6] = { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 }; 1095 u_char ether_ip6multicast_max[6] = { 0x33, 0x33, 0xff, 0xff, 0xff, 0xff }; 1096 #endif 1097 1098 /* 1099 * Add an Ethernet multicast address or range of addresses to the list for a 1100 * given interface. 1101 */ 1102 int 1103 ether_addmulti(ifr, ac) 1104 struct ifreq *ifr; 1105 register struct arpcom *ac; 1106 { 1107 register struct ether_multi *enm; 1108 #ifdef INET 1109 struct sockaddr_in *sin; 1110 #endif 1111 #ifdef INET6 1112 struct sockaddr_in6 *sin6; 1113 #endif /* INET6 */ 1114 u_char addrlo[6]; 1115 u_char addrhi[6]; 1116 int s = splimp(); 1117 1118 switch (ifr->ifr_addr.sa_family) { 1119 1120 case AF_UNSPEC: 1121 bcopy(ifr->ifr_addr.sa_data, addrlo, 6); 1122 bcopy(addrlo, addrhi, 6); 1123 break; 1124 1125 #ifdef INET 1126 case AF_INET: 1127 sin = (struct sockaddr_in *)&(ifr->ifr_addr); 1128 if (sin->sin_addr.s_addr == INADDR_ANY) { 1129 /* 1130 * An IP address of INADDR_ANY means listen to all 1131 * of the Ethernet multicast addresses used for IP. 1132 * (This is for the sake of IP multicast routers.) 1133 */ 1134 bcopy(ether_ipmulticast_min, addrlo, 6); 1135 bcopy(ether_ipmulticast_max, addrhi, 6); 1136 } 1137 else { 1138 ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo); 1139 bcopy(addrlo, addrhi, 6); 1140 } 1141 break; 1142 #endif 1143 #ifdef INET6 1144 case AF_INET6: 1145 sin6 = (struct sockaddr_in6 *) 1146 &(((struct in6_ifreq *)ifr)->ifr_addr); 1147 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 1148 /* 1149 * An unspecified IPv6 address means listen to all 1150 * of the IPv6 multicast addresses on this Ethernet. 1151 * (Multicast routers like this.) 1152 */ 1153 bcopy(ether_ip6multicast_min, addrlo, ETHER_ADDR_LEN); 1154 bcopy(ether_ip6multicast_max, addrhi, ETHER_ADDR_LEN); 1155 } else { 1156 ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo); 1157 bcopy(addrlo, addrhi, ETHER_ADDR_LEN); 1158 } 1159 break; 1160 #endif /* INET6 */ 1161 1162 default: 1163 splx(s); 1164 return (EAFNOSUPPORT); 1165 } 1166 1167 /* 1168 * Verify that we have valid Ethernet multicast addresses. 1169 */ 1170 if ((addrlo[0] & 0x01) != 1 || (addrhi[0] & 0x01) != 1) { 1171 splx(s); 1172 return (EINVAL); 1173 } 1174 /* 1175 * See if the address range is already in the list. 1176 */ 1177 ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm); 1178 if (enm != NULL) { 1179 /* 1180 * Found it; just increment the reference count. 1181 */ 1182 ++enm->enm_refcount; 1183 splx(s); 1184 return (0); 1185 } 1186 /* 1187 * New address or range; malloc a new multicast record 1188 * and link it into the interface's multicast list. 1189 */ 1190 enm = (struct ether_multi *)malloc(sizeof(*enm), M_IFMADDR, M_NOWAIT); 1191 if (enm == NULL) { 1192 splx(s); 1193 return (ENOBUFS); 1194 } 1195 bcopy(addrlo, enm->enm_addrlo, 6); 1196 bcopy(addrhi, enm->enm_addrhi, 6); 1197 enm->enm_ac = ac; 1198 enm->enm_refcount = 1; 1199 LIST_INSERT_HEAD(&ac->ac_multiaddrs, enm, enm_list); 1200 ac->ac_multicnt++; 1201 splx(s); 1202 /* 1203 * Return ENETRESET to inform the driver that the list has changed 1204 * and its reception filter should be adjusted accordingly. 1205 */ 1206 return (ENETRESET); 1207 } 1208 1209 /* 1210 * Delete a multicast address record. 1211 */ 1212 int 1213 ether_delmulti(ifr, ac) 1214 struct ifreq *ifr; 1215 register struct arpcom *ac; 1216 { 1217 register struct ether_multi *enm; 1218 #ifdef INET 1219 struct sockaddr_in *sin; 1220 #endif 1221 #ifdef INET6 1222 struct sockaddr_in6 *sin6; 1223 #endif /* INET6 */ 1224 u_char addrlo[6]; 1225 u_char addrhi[6]; 1226 int s = splimp(); 1227 1228 switch (ifr->ifr_addr.sa_family) { 1229 1230 case AF_UNSPEC: 1231 bcopy(ifr->ifr_addr.sa_data, addrlo, 6); 1232 bcopy(addrlo, addrhi, 6); 1233 break; 1234 1235 #ifdef INET 1236 case AF_INET: 1237 sin = (struct sockaddr_in *)&(ifr->ifr_addr); 1238 if (sin->sin_addr.s_addr == INADDR_ANY) { 1239 /* 1240 * An IP address of INADDR_ANY means stop listening 1241 * to the range of Ethernet multicast addresses used 1242 * for IP. 1243 */ 1244 bcopy(ether_ipmulticast_min, addrlo, 6); 1245 bcopy(ether_ipmulticast_max, addrhi, 6); 1246 } 1247 else { 1248 ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo); 1249 bcopy(addrlo, addrhi, 6); 1250 } 1251 break; 1252 #endif 1253 #ifdef INET6 1254 case AF_INET6: 1255 sin6 = (struct sockaddr_in6 *)&(ifr->ifr_addr); 1256 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 1257 /* 1258 * An unspecified IPv6 address means stop listening to 1259 * all IPv6 multicast addresses on this Ethernet.' 1260 * 1261 * (This might not be healthy, given IPv6's reliance on 1262 * multicast for things like neighbor discovery. 1263 * Perhaps initializing all-nodes, solicited nodes, and 1264 * possibly all-routers for this interface afterwards 1265 * is not a bad idea.) 1266 */ 1267 bcopy(ether_ip6multicast_min, addrlo, ETHER_ADDR_LEN); 1268 bcopy(ether_ip6multicast_max, addrhi, ETHER_ADDR_LEN); 1269 } else { 1270 ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo); 1271 bcopy(addrlo, addrhi, ETHER_ADDR_LEN); 1272 } 1273 break; 1274 #endif /* INET6 */ 1275 1276 default: 1277 splx(s); 1278 return (EAFNOSUPPORT); 1279 } 1280 1281 /* 1282 * Look up the address in our list. 1283 */ 1284 ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm); 1285 if (enm == NULL) { 1286 splx(s); 1287 return (ENXIO); 1288 } 1289 if (--enm->enm_refcount != 0) { 1290 /* 1291 * Still some claims to this record. 1292 */ 1293 splx(s); 1294 return (0); 1295 } 1296 /* 1297 * No remaining claims to this record; unlink and free it. 1298 */ 1299 LIST_REMOVE(enm, enm_list); 1300 free(enm, M_IFMADDR); 1301 ac->ac_multicnt--; 1302 splx(s); 1303 /* 1304 * Return ENETRESET to inform the driver that the list has changed 1305 * and its reception filter should be adjusted accordingly. 1306 */ 1307 return (ENETRESET); 1308 } 1309