if_vlan.c (264517) | if_vlan.c (269492) |
---|---|
1/*- 2 * Copyright 1998 Massachusetts Institute of Technology 3 * 4 * Permission to use, copy, modify, and distribute this software and 5 * its documentation for any purpose and without fee is hereby 6 * granted, provided that both the above copyright notice and this 7 * permission notice appear in all copies, that both the above 8 * copyright notice and this permission notice appear in all --- 25 unchanged lines hidden (view full) --- 34 * we need to pretend to be enough of an Ethernet implementation 35 * to make arp work. The way we do this is by telling everyone 36 * that we are an Ethernet, and then catch the packets that 37 * ether_output() sends to us via if_transmit(), rewrite them for 38 * use by the real outgoing interface, and ask it to send them. 39 */ 40 41#include <sys/cdefs.h> | 1/*- 2 * Copyright 1998 Massachusetts Institute of Technology 3 * 4 * Permission to use, copy, modify, and distribute this software and 5 * its documentation for any purpose and without fee is hereby 6 * granted, provided that both the above copyright notice and this 7 * permission notice appear in all copies, that both the above 8 * copyright notice and this permission notice appear in all --- 25 unchanged lines hidden (view full) --- 34 * we need to pretend to be enough of an Ethernet implementation 35 * to make arp work. The way we do this is by telling everyone 36 * that we are an Ethernet, and then catch the packets that 37 * ether_output() sends to us via if_transmit(), rewrite them for 38 * use by the real outgoing interface, and ask it to send them. 39 */ 40 41#include <sys/cdefs.h> |
42__FBSDID("$FreeBSD: head/sys/net/if_vlan.c 264517 2014-04-15 21:48:35Z rmacklem $"); | 42__FBSDID("$FreeBSD: head/sys/net/if_vlan.c 269492 2014-08-04 00:58:12Z mav $"); |
43 44#include "opt_inet.h" 45#include "opt_vlan.h" 46 47#include <sys/param.h> 48#include <sys/eventhandler.h> 49#include <sys/kernel.h> 50#include <sys/lock.h> --- 404 unchanged lines hidden (view full) --- 455 456/* 457 * Program our multicast filter. What we're actually doing is 458 * programming the multicast filter of the parent. This has the 459 * side effect of causing the parent interface to receive multicast 460 * traffic that it doesn't really want, which ends up being discarded 461 * later by the upper protocol layers. Unfortunately, there's no way 462 * to avoid this: there really is only one physical interface. | 43 44#include "opt_inet.h" 45#include "opt_vlan.h" 46 47#include <sys/param.h> 48#include <sys/eventhandler.h> 49#include <sys/kernel.h> 50#include <sys/lock.h> --- 404 unchanged lines hidden (view full) --- 455 456/* 457 * Program our multicast filter. What we're actually doing is 458 * programming the multicast filter of the parent. This has the 459 * side effect of causing the parent interface to receive multicast 460 * traffic that it doesn't really want, which ends up being discarded 461 * later by the upper protocol layers. Unfortunately, there's no way 462 * to avoid this: there really is only one physical interface. |
463 * 464 * XXX: There is a possible race here if more than one thread is 465 * modifying the multicast state of the vlan interface at the same time. | |
466 */ 467static int 468vlan_setmulti(struct ifnet *ifp) 469{ 470 struct ifnet *ifp_p; | 463 */ 464static int 465vlan_setmulti(struct ifnet *ifp) 466{ 467 struct ifnet *ifp_p; |
471 struct ifmultiaddr *ifma, *rifma = NULL; | 468 struct ifmultiaddr *ifma; |
472 struct ifvlan *sc; 473 struct vlan_mc_entry *mc; 474 int error; 475 | 469 struct ifvlan *sc; 470 struct vlan_mc_entry *mc; 471 int error; 472 |
476 /*VLAN_LOCK_ASSERT();*/ 477 | |
478 /* Find the parent. */ 479 sc = ifp->if_softc; | 473 /* Find the parent. */ 474 sc = ifp->if_softc; |
475 TRUNK_LOCK_ASSERT(TRUNK(sc)); |
|
480 ifp_p = PARENT(sc); 481 482 CURVNET_SET_QUIET(ifp_p->if_vnet); 483 484 /* First, remove any existing filter entries. */ 485 while ((mc = SLIST_FIRST(&sc->vlan_mc_listhead)) != NULL) { | 476 ifp_p = PARENT(sc); 477 478 CURVNET_SET_QUIET(ifp_p->if_vnet); 479 480 /* First, remove any existing filter entries. */ 481 while ((mc = SLIST_FIRST(&sc->vlan_mc_listhead)) != NULL) { |
486 error = if_delmulti(ifp_p, (struct sockaddr *)&mc->mc_addr); 487 if (error) 488 return (error); | |
489 SLIST_REMOVE_HEAD(&sc->vlan_mc_listhead, mc_entries); | 482 SLIST_REMOVE_HEAD(&sc->vlan_mc_listhead, mc_entries); |
483 (void)if_delmulti(ifp_p, (struct sockaddr *)&mc->mc_addr); |
|
490 free(mc, M_VLAN); 491 } 492 493 /* Now program new ones. */ | 484 free(mc, M_VLAN); 485 } 486 487 /* Now program new ones. */ |
488 IF_ADDR_WLOCK(ifp); |
|
494 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 495 if (ifma->ifma_addr->sa_family != AF_LINK) 496 continue; 497 mc = malloc(sizeof(struct vlan_mc_entry), M_VLAN, M_NOWAIT); | 489 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 490 if (ifma->ifma_addr->sa_family != AF_LINK) 491 continue; 492 mc = malloc(sizeof(struct vlan_mc_entry), M_VLAN, M_NOWAIT); |
498 if (mc == NULL) | 493 if (mc == NULL) { 494 IF_ADDR_WUNLOCK(ifp); |
499 return (ENOMEM); | 495 return (ENOMEM); |
496 } |
|
500 bcopy(ifma->ifma_addr, &mc->mc_addr, ifma->ifma_addr->sa_len); 501 mc->mc_addr.sdl_index = ifp_p->if_index; 502 SLIST_INSERT_HEAD(&sc->vlan_mc_listhead, mc, mc_entries); | 497 bcopy(ifma->ifma_addr, &mc->mc_addr, ifma->ifma_addr->sa_len); 498 mc->mc_addr.sdl_index = ifp_p->if_index; 499 SLIST_INSERT_HEAD(&sc->vlan_mc_listhead, mc, mc_entries); |
500 } 501 IF_ADDR_WUNLOCK(ifp); 502 SLIST_FOREACH (mc, &sc->vlan_mc_listhead, mc_entries) { |
|
503 error = if_addmulti(ifp_p, (struct sockaddr *)&mc->mc_addr, | 503 error = if_addmulti(ifp_p, (struct sockaddr *)&mc->mc_addr, |
504 &rifma); | 504 NULL); |
505 if (error) 506 return (error); 507 } 508 509 CURVNET_RESTORE(); 510 return (0); 511} 512 --- 856 unchanged lines hidden (view full) --- 1369 vlan_setflags(ifp, 0); /* clear special flags on parent */ 1370 vlan_remhash(trunk, ifv); 1371 ifv->ifv_trunk = NULL; 1372 1373 /* 1374 * Check if we were the last. 1375 */ 1376 if (trunk->refcnt == 0) { | 505 if (error) 506 return (error); 507 } 508 509 CURVNET_RESTORE(); 510 return (0); 511} 512 --- 856 unchanged lines hidden (view full) --- 1369 vlan_setflags(ifp, 0); /* clear special flags on parent */ 1370 vlan_remhash(trunk, ifv); 1371 ifv->ifv_trunk = NULL; 1372 1373 /* 1374 * Check if we were the last. 1375 */ 1376 if (trunk->refcnt == 0) { |
1377 trunk->parent->if_vlantrunk = NULL; | 1377 parent->if_vlantrunk = NULL; |
1378 /* 1379 * XXXGL: If some ithread has already entered 1380 * vlan_input() and is now blocked on the trunk 1381 * lock, then it should preempt us right after 1382 * unlock and finish its work. Then we will acquire 1383 * lock again in trunk_destroy(). 1384 */ 1385 TRUNK_UNLOCK(trunk); --- 177 unchanged lines hidden (view full) --- 1563 1564static int 1565vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 1566{ 1567 struct ifnet *p; 1568 struct ifreq *ifr; 1569 struct ifaddr *ifa; 1570 struct ifvlan *ifv; | 1378 /* 1379 * XXXGL: If some ithread has already entered 1380 * vlan_input() and is now blocked on the trunk 1381 * lock, then it should preempt us right after 1382 * unlock and finish its work. Then we will acquire 1383 * lock again in trunk_destroy(). 1384 */ 1385 TRUNK_UNLOCK(trunk); --- 177 unchanged lines hidden (view full) --- 1563 1564static int 1565vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 1566{ 1567 struct ifnet *p; 1568 struct ifreq *ifr; 1569 struct ifaddr *ifa; 1570 struct ifvlan *ifv; |
1571 struct ifvlantrunk *trunk; |
|
1571 struct vlanreq vlr; 1572 int error = 0; 1573 1574 ifr = (struct ifreq *)data; 1575 ifa = (struct ifaddr *) data; 1576 ifv = ifp->if_softc; 1577 1578 switch (cmd) { --- 128 unchanged lines hidden (view full) --- 1707 break; 1708 1709 case SIOCADDMULTI: 1710 case SIOCDELMULTI: 1711 /* 1712 * If we don't have a parent, just remember the membership for 1713 * when we do. 1714 */ | 1572 struct vlanreq vlr; 1573 int error = 0; 1574 1575 ifr = (struct ifreq *)data; 1576 ifa = (struct ifaddr *) data; 1577 ifv = ifp->if_softc; 1578 1579 switch (cmd) { --- 128 unchanged lines hidden (view full) --- 1708 break; 1709 1710 case SIOCADDMULTI: 1711 case SIOCDELMULTI: 1712 /* 1713 * If we don't have a parent, just remember the membership for 1714 * when we do. 1715 */ |
1715 if (TRUNK(ifv) != NULL) | 1716 trunk = TRUNK(ifv); 1717 if (trunk != NULL) { 1718 TRUNK_LOCK(trunk); |
1716 error = vlan_setmulti(ifp); | 1719 error = vlan_setmulti(ifp); |
1720 TRUNK_UNLOCK(trunk); 1721 } |
|
1717 break; 1718 1719 default: 1720 error = EINVAL; 1721 break; 1722 } 1723 1724 return (error); 1725} | 1722 break; 1723 1724 default: 1725 error = EINVAL; 1726 break; 1727 } 1728 1729 return (error); 1730} |