Deleted Added
full compact
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

--- 12 unchanged lines hidden (view full) ---

21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * $FreeBSD: head/sys/net/if_vlan.c 72484 2001-02-14 13:24:01Z asmodai $
29 * $FreeBSD: head/sys/net/if_vlan.c 74943 2001-03-28 15:52:12Z yar $
30 */
31
32/*
33 * if_vlan.c - pseudo-device driver for IEEE 802.1Q virtual LANs.
34 * Might be extended some day to also handle IEEE 802.1p priority
35 * tagging. This is sort of sneaky in the implementation, since
36 * we need to pretend to be enough of an Ethernet implementation
37 * to make arp work. The way we do this is by telling everyone

--- 77 unchanged lines hidden (view full) ---

115 struct vlan_mc_entry *mc = NULL;
116 struct sockaddr_dl sdl;
117 int error;
118
119 /* Find the parent. */
120 sc = ifp->if_softc;
121 ifp_p = sc->ifv_p;
122
123 sdl.sdl_len = ETHER_ADDR_LEN;
123 bzero((char *)&sdl, sizeof sdl);
124 sdl.sdl_len = sizeof sdl;
125 sdl.sdl_family = AF_LINK;
126 sdl.sdl_alen = ETHER_ADDR_LEN;
127
128 /* First, remove any existing filter entries. */
129 while(SLIST_FIRST(&sc->vlan_mc_listhead) != NULL) {
130 mc = SLIST_FIRST(&sc->vlan_mc_listhead);
131 bcopy((char *)&mc->mc_addr, LLADDR(&sdl), ETHER_ADDR_LEN);
132 error = if_delmulti(ifp_p, (struct sockaddr *)&sdl);
133 if (error)
134 return(error);
135 SLIST_REMOVE_HEAD(&sc->vlan_mc_listhead, mc_entries);
136 free(mc, M_DEVBUF);
137 }
138
139 /* Now program new ones. */
140 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
141 if (ifma->ifma_addr->sa_family != AF_LINK)
142 continue;
141 mc = malloc(sizeof(struct vlan_mc_entry), M_DEVBUF, M_NOWAIT);
143 mc = malloc(sizeof(struct vlan_mc_entry), M_DEVBUF, M_WAITOK);
144 bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
145 (char *)&mc->mc_addr, ETHER_ADDR_LEN);
146 SLIST_INSERT_HEAD(&sc->vlan_mc_listhead, mc, mc_entries);
147 error = if_addmulti(ifp_p, (struct sockaddr *)&sdl, &rifma);
148 if (error)
149 return(error);
150 }
151

--- 72 unchanged lines hidden (view full) ---

224 for (;;) {
225 IF_DEQUEUE(&ifp->if_snd, m);
226 if (m == 0)
227 break;
228 if (ifp->if_bpf)
229 bpf_mtap(ifp, m);
230
231 /*
232 * Do not run parent's if_start() if the parent is not up,
233 * or parent's driver will cause a system crash.
234 */
235 if ((p->if_flags & (IFF_UP | IFF_RUNNING)) !=
236 (IFF_UP | IFF_RUNNING)) {
237 m_freem(m);
238 ifp->if_data.ifi_collisions++;
239 continue;
240 }
241
242 /*
243 * If the LINK0 flag is set, it means the underlying interface
244 * can do VLAN tag insertion itself and doesn't require us to
245 * create a special header for it. In this case, we just pass
246 * the packet along. However, we need some way to tell the
247 * interface where the packet came from so that it knows how
248 * to find the VLAN tag to use, so we set the rcvif in the
249 * mbuf header to our ifnet.
250 *

--- 133 unchanged lines hidden (view full) ---

384 return EBUSY;
385 ifv->ifv_p = p;
386 if (p->if_data.ifi_hdrlen == sizeof(struct ether_vlan_header))
387 ifv->ifv_if.if_mtu = p->if_mtu;
388 else
389 ifv->ifv_if.if_mtu = p->if_data.ifi_mtu - EVL_ENCAPLEN;
390
391 /*
379 * Preserve the state of the LINK0 flag for ourselves.
392 * Copy only a selected subset of flags from the parent.
393 * Other flags are none of our business.
394 */
381 ifv->ifv_if.if_flags = (p->if_flags & ~(IFF_LINK0));
395 ifv->ifv_if.if_flags = (p->if_flags &
396 (IFF_BROADCAST | IFF_MULTICAST | IFF_SIMPLEX | IFF_POINTOPOINT));
397
398 /*
399 * Set up our ``Ethernet address'' to reflect the underlying
400 * physical interface's.
401 */
402 ifa1 = ifnet_addrs[ifv->ifv_if.if_index - 1];
403 ifa2 = ifnet_addrs[p->if_index - 1];
404 sdl1 = (struct sockaddr_dl *)ifa1->ifa_addr;

--- 107 unchanged lines hidden (view full) ---

512 break;
513
514 case SIOCSETVLAN:
515 error = copyin(ifr->ifr_data, &vlr, sizeof vlr);
516 if (error)
517 break;
518 if (vlr.vlr_parent[0] == '\0') {
519 vlan_unconfig(ifp);
505 if_down(ifp);
506 ifp->if_flags &= ~(IFF_UP|IFF_RUNNING);
520 if (ifp->if_flags & IFF_UP) {
521 int s = splimp();
522 if_down(ifp);
523 splx(s);
524 }
525 ifp->if_flags &= ~IFF_RUNNING;
526 break;
527 }
528 p = ifunit(vlr.vlr_parent);
529 if (p == 0) {
530 error = ENOENT;
531 break;
532 }
533 error = vlan_config(ifv, p);

--- 36 unchanged lines hidden ---