diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2016-03-28 13:05:23 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2016-03-28 13:05:23 +0000 |
commit | c34fd143647785f537fc91dbbb64d8dabea78251 (patch) | |
tree | 83891f6ce9abfe35cd5de8fdebea02dfbd86cc59 | |
parent | 73a599e50a467f8754c4a51115e25ac13d271503 (diff) |
turn ifv_p into an interface index instead of a real pointer to the parent
ok mpi@ jmatthew@
-rw-r--r-- | sys/net/if_vlan.c | 81 | ||||
-rw-r--r-- | sys/net/if_vlan_var.h | 5 |
2 files changed, 57 insertions, 29 deletions
diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c index f675dc926ea..15b3dee3d30 100644 --- a/sys/net/if_vlan.c +++ b/sys/net/if_vlan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_vlan.c,v 1.155 2016/03/18 02:40:04 dlg Exp $ */ +/* $OpenBSD: if_vlan.c,v 1.156 2016/03/28 13:05:22 dlg Exp $ */ /* * Copyright 1998 Massachusetts Institute of Technology @@ -235,7 +235,12 @@ vlan_start(struct ifnet *ifp) uint8_t prio; ifv = ifp->if_softc; - ifp0 = ifv->ifv_p; + ifp0 = if_get(ifv->ifv_p); + if (ifp0 == NULL || (ifp0->if_flags & (IFF_UP|IFF_RUNNING)) != + (IFF_UP|IFF_RUNNING)) { + ifq_purge(&ifp->if_snd); + goto leave; + } for (;;) { IFQ_DEQUEUE(&ifp->if_snd, m); @@ -247,12 +252,6 @@ vlan_start(struct ifnet *ifp) bpf_mtap_ether(ifp->if_bpf, m, BPF_DIRECTION_OUT); #endif /* NBPFILTER > 0 */ - if ((ifp0->if_flags & (IFF_UP|IFF_RUNNING)) != - (IFF_UP|IFF_RUNNING)) { - ifp->if_oerrors++; - m_freem(m); - continue; - } /* IEEE 802.1p has prio 0 and 1 swapped */ prio = m->m_pkthdr.pf.prio; @@ -290,6 +289,9 @@ vlan_start(struct ifnet *ifp) } ifp->if_opackets++; } + +leave: + if_put(ifp0); } struct mbuf * @@ -358,7 +360,7 @@ vlan_input(struct ifnet *ifp0, struct mbuf *m, void *cookie) list = &tagh[TAG_HASH(tag)]; SRPL_FOREACH(ifv, list, &i, ifv_list) { - if (ifp0 == ifv->ifv_p && tag == ifv->ifv_tag && + if (ifp0->if_index == ifv->ifv_p && tag == ifv->ifv_tag && etype == ifv->ifv_type) break; } @@ -417,13 +419,13 @@ vlan_config(struct ifvlan *ifv, struct ifnet *ifp0, u_int16_t tag) if (ifp0->if_type != IFT_ETHER) return EPROTONOSUPPORT; - if (ifv->ifv_p == ifp0 && ifv->ifv_tag == tag) /* noop */ + if (ifp0->if_index == ifv->ifv_p && ifv->ifv_tag == tag) /* noop */ return (0); /* Remember existing interface flags and reset the interface */ flags = ifv->ifv_flags; vlan_unconfig(&ifv->ifv_if, ifp0); - ifv->ifv_p = ifp0; + ifv->ifv_p = ifp0->if_index; ifv->ifv_if.if_baudrate = ifp0->if_baudrate; if (ifp0->if_capabilities & IFCAP_VLAN_MTU) { @@ -509,8 +511,9 @@ vlan_unconfig(struct ifnet *ifp, struct ifnet *newifp0) struct ifnet *ifp0; ifv = ifp->if_softc; - if ((ifp0 = ifv->ifv_p) == NULL) - return 0; + ifp0 = if_get(ifv->ifv_p); + if (ifp0 == NULL) + goto disconnect; /* Unset promisc mode on the interface and its parent */ if (ifv->ifv_flags & IFVF_PROMISC) { @@ -544,8 +547,9 @@ vlan_unconfig(struct ifnet *ifp, struct ifnet *newifp0) */ vlan_multi_apply(ifv, ifp0, SIOCDELMULTI); +disconnect: /* Disconnect from parent. */ - ifv->ifv_p = NULL; + ifv->ifv_p = 0; ifv->ifv_if.if_mtu = ETHERMTU; ifv->ifv_if.if_hardmtu = ETHERMTU; ifv->ifv_flags = 0; @@ -557,6 +561,8 @@ vlan_unconfig(struct ifnet *ifp, struct ifnet *newifp0) bzero(LLADDR(sdl), ETHER_ADDR_LEN); bzero(ifv->ifv_ac.ac_enaddr, ETHER_ADDR_LEN); + if_put(ifp0); + return (0); } @@ -564,12 +570,22 @@ void vlan_vlandev_state(void *v) { struct ifvlan *ifv = v; + struct ifnet *ifp0; + int link_state = LINK_STATE_DOWN; + uint64_t baudrate = 0; - if (ifv->ifv_if.if_link_state == ifv->ifv_p->if_link_state) + ifp0 = if_get(ifv->ifv_p); + if (ifp0 != NULL) { + link_state = ifp0->if_link_state; + baudrate = ifp0->if_baudrate; + } + if_put(ifp0); + + if (ifv->ifv_if.if_link_state == link_state) return; - ifv->ifv_if.if_link_state = ifv->ifv_p->if_link_state; - ifv->ifv_if.if_baudrate = ifv->ifv_p->if_baudrate; + ifv->ifv_if.if_link_state = link_state; + ifv->ifv_if.if_baudrate = baudrate; if_link_state_change(&ifv->ifv_if); } @@ -577,17 +593,26 @@ int vlan_set_promisc(struct ifnet *ifp) { struct ifvlan *ifv = ifp->if_softc; + struct ifnet *ifp0; int error = 0; + ifp0 = if_get(ifv->ifv_p); + if (ifp0 == NULL) + goto leave; + if ((ifp->if_flags & IFF_PROMISC) != 0) { if ((ifv->ifv_flags & IFVF_PROMISC) == 0) - if ((error = ifpromisc(ifv->ifv_p, 1)) == 0) + if ((error = ifpromisc(ifp0, 1)) == 0) ifv->ifv_flags |= IFVF_PROMISC; } else { if ((ifv->ifv_flags & IFVF_PROMISC) != 0) - if ((error = ifpromisc(ifv->ifv_p, 0)) == 0) + if ((error = ifpromisc(ifp0, 0)) == 0) ifv->ifv_flags &= ~IFVF_PROMISC; } + +leave: + if_put(ifp0); + return (0); } @@ -608,14 +633,14 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) switch (cmd) { case SIOCSIFADDR: - if (ifv->ifv_p != NULL) + if (ifv->ifv_p != 0) ifp->if_flags |= IFF_UP; else error = EINVAL; break; case SIOCSIFMTU: - if (ifv->ifv_p != NULL) { + if (ifv->ifv_p != 0) { if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ifv->ifv_if.if_hardmtu) error = EINVAL; @@ -664,11 +689,13 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) case SIOCGETVLAN: bzero(&vlr, sizeof vlr); - if (ifv->ifv_p) { + ifp0 = if_get(ifv->ifv_p); + if (ifp0) { snprintf(vlr.vlr_parent, sizeof(vlr.vlr_parent), - "%s", ifv->ifv_p->if_xname); + "%s", ifp0->if_xname); vlr.vlr_tag = ifv->ifv_tag; } + if_put(ifp0); error = copyout(&vlr, ifr->ifr_data, sizeof vlr); break; case SIOCSIFFLAGS: @@ -676,7 +703,7 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) * For promiscuous mode, we enable promiscuous mode on * the parent if we need promiscuous on the VLAN interface. */ - if (ifv->ifv_p != NULL) + if (ifv->ifv_p != 0) error = vlan_set_promisc(ifp); break; @@ -725,9 +752,10 @@ vlan_multi_add(struct ifvlan *ifv, struct ifreq *ifr) memcpy(&mc->mc_addr, &ifr->ifr_addr, ifr->ifr_addr.sa_len); LIST_INSERT_HEAD(&ifv->vlan_mc_listhead, mc, mc_entries); - ifp0 = ifv->ifv_p; + ifp0 = if_get(ifv->ifv_p); error = (ifp0 == NULL) ? 0 : (*ifp0->if_ioctl)(ifp0, SIOCADDMULTI, (caddr_t)ifr); + if_put(ifp0); if (error != 0) goto ioctl_failed; @@ -778,9 +806,10 @@ vlan_multi_del(struct ifvlan *ifv, struct ifreq *ifr) if (!ISSET(ifv->ifv_if.if_flags, IFF_RUNNING)) goto forget; - ifp0 = ifv->ifv_p; + ifp0 = if_get(ifv->ifv_p); error = (ifp0 == NULL) ? 0 : (*ifp0->if_ioctl)(ifp0, SIOCDELMULTI, (caddr_t)ifr); + if_put(ifp0); if (error != 0) { (void)ether_addmulti(ifr, &ifv->ifv_ac); diff --git a/sys/net/if_vlan_var.h b/sys/net/if_vlan_var.h index d93a928406f..daae27eb5e4 100644 --- a/sys/net/if_vlan_var.h +++ b/sys/net/if_vlan_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_vlan_var.h,v 1.33 2016/03/14 03:48:47 dlg Exp $ */ +/* $OpenBSD: if_vlan_var.h,v 1.34 2016/03/28 13:05:22 dlg Exp $ */ /* * Copyright 1998 Massachusetts Institute of Technology @@ -61,9 +61,8 @@ struct vlan_mc_entry { struct ifvlan { struct arpcom ifv_ac; /* make this an interface */ - struct ifnet *ifv_p; /* parent interface of this vlan */ + unsigned int ifv_p; /* parent interface of this vlan */ struct ifv_linkmib { - int ifvm_parent; u_int16_t ifvm_proto; /* encapsulation ethertype */ u_int16_t ifvm_tag; /* tag to apply on packets leaving if */ u_int16_t ifvm_prio; /* prio to apply on packet leaving if */ |