summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorMarkus Friedl <markus@cvs.openbsd.org>2003-12-03 14:55:59 +0000
committerMarkus Friedl <markus@cvs.openbsd.org>2003-12-03 14:55:59 +0000
commitdf5bbc914d2ca35493ec7cacf0c23ad043634b10 (patch)
tree4a6e623275717b228e6b441339d35d989753dd68 /sys/net
parente90c50ef1e680cf6d41ba406eb0e767bbfef0fbd (diff)
add support for ifconfig clone/destroy; ok henning deraadt
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/if_bridge.c126
-rw-r--r--sys/net/if_bridge.h3
-rw-r--r--sys/net/if_vlan.c113
-rw-r--r--sys/net/if_vlan_var.h3
4 files changed, 163 insertions, 82 deletions
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 23d83c3315b..81a53cb7ac4 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bridge.c,v 1.125 2003/10/02 05:50:34 itojun Exp $ */
+/* $OpenBSD: if_bridge.c,v 1.126 2003/12/03 14:55:58 markus Exp $ */
/*
* Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
@@ -122,9 +122,6 @@
extern int ifqmaxlen;
-struct bridge_softc *bridgectl;
-int nbridge;
-
void bridgeattach(int);
int bridge_ioctl(struct ifnet *, u_long, caddr_t);
void bridge_start(struct ifnet *);
@@ -169,6 +166,8 @@ void bridge_send_icmp_err(struct bridge_softc *, struct ifnet *,
#ifdef IPSEC
int bridge_ipsec(int, int, int, struct mbuf *);
#endif
+int bridge_clone_create(struct if_clone *, int);
+void bridge_clone_destroy(struct ifnet *ifp);
#define ETHERADDR_IS_IP_MCAST(a) \
/* struct etheraddr *a; */ \
@@ -176,47 +175,97 @@ int bridge_ipsec(int, int, int, struct mbuf *);
(a)->ether_addr_octet[1] == 0x00 && \
(a)->ether_addr_octet[2] == 0x5e)
+LIST_HEAD(, bridge_softc) bridge_list;
+
+struct if_clone bridge_cloner =
+ IF_CLONE_INITIALIZER("bridge", bridge_clone_create, bridge_clone_destroy);
+
+/* ARGSUSED */
void
bridgeattach(int n)
{
+ LIST_INIT(&bridge_list);
+ if_clone_attach(&bridge_cloner);
+}
+
+int
+bridge_clone_create(struct if_clone *ifc, int unit)
+{
struct bridge_softc *sc;
struct ifnet *ifp;
- int i;
+ int s;
- bridgectl = malloc(n * sizeof(*sc), M_DEVBUF, M_NOWAIT);
- if (!bridgectl)
- return;
- nbridge = n;
- bzero(bridgectl, n * sizeof(*sc));
- for (sc = bridgectl, i = 0; i < nbridge; i++, sc++) {
-
- sc->sc_brtmax = BRIDGE_RTABLE_MAX;
- sc->sc_brttimeout = BRIDGE_RTABLE_TIMEOUT;
- sc->sc_bridge_max_age = BSTP_DEFAULT_MAX_AGE;
- sc->sc_bridge_hello_time = BSTP_DEFAULT_HELLO_TIME;
- sc->sc_bridge_forward_delay= BSTP_DEFAULT_FORWARD_DELAY;
- sc->sc_bridge_priority = BSTP_DEFAULT_BRIDGE_PRIORITY;
- sc->sc_hold_time = BSTP_DEFAULT_HOLD_TIME;
- timeout_set(&sc->sc_brtimeout, bridge_timer, sc);
- LIST_INIT(&sc->sc_iflist);
- LIST_INIT(&sc->sc_spanlist);
- ifp = &sc->sc_if;
- snprintf(ifp->if_xname, sizeof ifp->if_xname, "bridge%d", i);
- ifp->if_softc = sc;
- ifp->if_mtu = ETHERMTU;
- ifp->if_ioctl = bridge_ioctl;
- ifp->if_output = bridge_output;
- ifp->if_start = bridge_start;
- ifp->if_type = IFT_BRIDGE;
- ifp->if_snd.ifq_maxlen = ifqmaxlen;
- ifp->if_hdrlen = sizeof(struct ether_header);
- if_attach(ifp);
- if_alloc_sadl(ifp);
+ sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT);
+ if (!sc)
+ return (ENOMEM);
+ bzero(sc, sizeof(*sc));
+
+ sc->sc_brtmax = BRIDGE_RTABLE_MAX;
+ sc->sc_brttimeout = BRIDGE_RTABLE_TIMEOUT;
+ sc->sc_bridge_max_age = BSTP_DEFAULT_MAX_AGE;
+ sc->sc_bridge_hello_time = BSTP_DEFAULT_HELLO_TIME;
+ sc->sc_bridge_forward_delay= BSTP_DEFAULT_FORWARD_DELAY;
+ sc->sc_bridge_priority = BSTP_DEFAULT_BRIDGE_PRIORITY;
+ sc->sc_hold_time = BSTP_DEFAULT_HOLD_TIME;
+ timeout_set(&sc->sc_brtimeout, bridge_timer, sc);
+ LIST_INIT(&sc->sc_iflist);
+ LIST_INIT(&sc->sc_spanlist);
+ ifp = &sc->sc_if;
+ snprintf(ifp->if_xname, sizeof ifp->if_xname, "%s%d", ifc->ifc_name,
+ unit);
+ ifp->if_softc = sc;
+ ifp->if_mtu = ETHERMTU;
+ ifp->if_ioctl = bridge_ioctl;
+ ifp->if_output = bridge_output;
+ ifp->if_start = bridge_start;
+ ifp->if_type = IFT_BRIDGE;
+ ifp->if_snd.ifq_maxlen = ifqmaxlen;
+ ifp->if_hdrlen = sizeof(struct ether_header);
+ if_attach(ifp);
+ if_alloc_sadl(ifp);
#if NBPFILTER > 0
- bpfattach(&sc->sc_if.if_bpf, ifp,
- DLT_EN10MB, sizeof(struct ether_header));
+ bpfattach(&sc->sc_if.if_bpf, ifp,
+ DLT_EN10MB, sizeof(struct ether_header));
#endif
+ s = splnet();
+ LIST_INSERT_HEAD(&bridge_list, sc, sc_list);
+ splx(s);
+
+ return (0);
+}
+
+void
+bridge_clone_destroy(struct ifnet *ifp)
+{
+ struct bridge_softc *sc = ifp->if_softc;
+ struct bridge_iflist *bif;
+ int s;
+
+ bridge_stop(sc);
+ while ((bif = LIST_FIRST(&sc->sc_iflist)) != NULL) {
+ /* XXX shared with ioctl and detach */
+ /* XXX promisc disable? */
+ LIST_REMOVE(bif, next);
+ bridge_rtdelete(sc, bif->ifp, 0);
+ bridge_flushrule(bif);
+ bif->ifp->if_bridge = NULL;
+ free(bif, M_DEVBUF);
+ }
+ while ((bif = LIST_FIRST(&sc->sc_spanlist)) != NULL) {
+ LIST_REMOVE(bif, next);
+ free(bif, M_DEVBUF);
}
+
+ s = splnet();
+ LIST_REMOVE(sc, sc_list);
+ splx(s);
+
+#if NBPFILTER > 0
+ bpfdetach(ifp);
+#endif
+ if_detach(ifp);
+
+ free(sc, M_DEVBUF);
}
int
@@ -1027,10 +1076,9 @@ bridgeintr(void)
{
struct bridge_softc *sc;
struct mbuf *m;
- int i, s;
+ int s;
- for (i = 0; i < nbridge; i++) {
- sc = &bridgectl[i];
+ LIST_FOREACH(sc, &bridge_list, sc_list) {
for (;;) {
s = splimp();
IF_DEQUEUE(&sc->sc_if.if_snd, m);
diff --git a/sys/net/if_bridge.h b/sys/net/if_bridge.h
index 8e36e2076c3..1bbde37f079 100644
--- a/sys/net/if_bridge.h
+++ b/sys/net/if_bridge.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bridge.h,v 1.25 2003/07/15 03:41:15 jason Exp $ */
+/* $OpenBSD: if_bridge.h,v 1.26 2003/12/03 14:55:58 markus Exp $ */
/*
* Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
@@ -235,6 +235,7 @@ struct bridge_rtnode {
*/
struct bridge_softc {
struct ifnet sc_if; /* the interface */
+ LIST_ENTRY(bridge_softc) sc_list; /* all bridges */
u_int64_t sc_designated_root;
u_int64_t sc_bridge_id;
struct bridge_iflist *sc_root_port;
diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c
index 990128f85bd..7b87936dcd5 100644
--- a/sys/net/if_vlan.c
+++ b/sys/net/if_vlan.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_vlan.c,v 1.41 2003/08/15 20:32:19 tedu Exp $ */
+/* $OpenBSD: if_vlan.c,v 1.42 2003/12/03 14:55:58 markus Exp $ */
/*
* Copyright 1998 Massachusetts Institute of Technology
*
@@ -79,10 +79,6 @@
#include <net/if_vlan_var.h>
extern struct ifaddr **ifnet_addrs;
-
-struct ifvlan *ifv_softc;
-int nifvlan;
-
extern int ifqmaxlen;
void vlan_start (struct ifnet *ifp);
@@ -95,40 +91,79 @@ int vlan_set_promisc (struct ifnet *ifp);
int vlan_ether_addmulti(struct ifvlan *, struct ifreq *);
int vlan_ether_delmulti(struct ifvlan *, struct ifreq *);
void vlan_ether_purgemulti(struct ifvlan *);
+int vlan_clone_create(struct if_clone *, int);
+void vlan_clone_destroy(struct ifnet *);
+
+LIST_HEAD(, ifvlan) vlan_list;
+struct if_clone vlan_cloner =
+ IF_CLONE_INITIALIZER("vlan", vlan_clone_create, vlan_clone_destroy);
+
+/* ARGSUSED */
void
vlanattach(int count)
{
+ LIST_INIT(&vlan_list);
+ if_clone_attach(&vlan_cloner);
+}
+
+int
+vlan_clone_create(struct if_clone *ifc, int unit)
+{
+ struct ifvlan *ifv;
struct ifnet *ifp;
- int i;
+ int s;
+
+ ifv = malloc(sizeof(*ifv), M_DEVBUF, M_NOWAIT);
+ if (!ifv)
+ return (ENOMEM);
+ bzero(ifv, sizeof(*ifv));
+
+ LIST_INIT(&ifv->vlan_mc_listhead);
+ ifp = &ifv->ifv_if;
+ ifp->if_softc = ifv;
+ snprintf(ifp->if_xname, sizeof ifp->if_xname, "%s%d", ifc->ifc_name,
+ unit);
+ /* NB: flags are not set here */
+ /* NB: mtu is not set here */
+
+ ifp->if_start = vlan_start;
+ ifp->if_ioctl = vlan_ioctl;
+ ifp->if_output = ether_output;
+ IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
+ IFQ_SET_READY(&ifp->if_snd);
+ if_attach(ifp);
+ ether_ifattach(ifp);
+
+ /* Now undo some of the damage... */
+ ifp->if_type = IFT_8021_VLAN;
+ ifp->if_hdrlen = EVL_ENCAPLEN;
+
+ s = splnet();
+ LIST_INSERT_HEAD(&vlan_list, ifv, ifv_list);
+ splx(s);
- MALLOC(ifv_softc, struct ifvlan *, count * sizeof(struct ifvlan),
- M_DEVBUF, M_NOWAIT);
- if (ifv_softc == NULL)
- panic("vlanattach: MALLOC failed");
- nifvlan = count;
- bzero(ifv_softc, nifvlan * sizeof(struct ifvlan));
-
- for (i = 0; i < nifvlan; i++) {
- LIST_INIT(&ifv_softc[i].vlan_mc_listhead);
- ifp = &ifv_softc[i].ifv_if;
- ifp->if_softc = &ifv_softc[i];
- snprintf(ifp->if_xname, sizeof ifp->if_xname, "vlan%d", i);
- /* NB: flags are not set here */
- /* NB: mtu is not set here */
-
- ifp->if_start = vlan_start;
- ifp->if_ioctl = vlan_ioctl;
- ifp->if_output = ether_output;
- IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
- IFQ_SET_READY(&ifp->if_snd);
- if_attach(ifp);
- ether_ifattach(ifp);
-
- /* Now undo some of the damage... */
- ifp->if_type = IFT_8021_VLAN;
- ifp->if_hdrlen = EVL_ENCAPLEN;
- }
+ return (0);
+}
+
+void
+vlan_clone_destroy(struct ifnet *ifp)
+{
+ struct ifvlan *ifv = ifp->if_softc;
+ int s;
+
+ s = splnet();
+ LIST_REMOVE(ifv, ifv_list);
+ splx(s);
+
+ vlan_unconfig(ifp);
+#if NBPFILTER > 0
+ bpfdetach(ifp);
+#endif
+ ether_ifdetach(ifp);
+ if_detach(ifp);
+
+ free(ifv, M_DEVBUF);
}
void
@@ -237,18 +272,16 @@ vlan_start(struct ifnet *ifp)
int
vlan_input_tag(struct mbuf *m, u_int16_t t)
{
- int i;
struct ifvlan *ifv;
struct ether_vlan_header vh;
t = EVL_VLANOFTAG(t);
- for (i = 0; i < nifvlan; i++) {
- ifv = &ifv_softc[i];
+ LIST_FOREACH(ifv, &vlan_list, ifv_list) {
if (m->m_pkthdr.rcvif == ifv->ifv_p && t == ifv->ifv_tag)
break;
}
- if (i >= nifvlan) {
+ if (ifv == NULL) {
if (m->m_pkthdr.len < sizeof(struct ether_header)) {
m_freem(m);
return (-1);
@@ -304,7 +337,6 @@ vlan_input(eh, m)
struct ether_header *eh;
struct mbuf *m;
{
- int i;
struct ifvlan *ifv;
u_int tag;
struct ifnet *ifp = m->m_pkthdr.rcvif;
@@ -317,13 +349,12 @@ vlan_input(eh, m)
tag = EVL_VLANOFTAG(ntohs(*mtod(m, u_int16_t *)));
- for (i = 0; i < nifvlan; i++) {
- ifv = &ifv_softc[i];
+ LIST_FOREACH(ifv, &vlan_list, ifv_list) {
if (m->m_pkthdr.rcvif == ifv->ifv_p && tag == ifv->ifv_tag)
break;
}
- if (i >= nifvlan || (ifv->ifv_if.if_flags & (IFF_UP|IFF_RUNNING)) !=
+ if (ifv == NULL || (ifv->ifv_if.if_flags & (IFF_UP|IFF_RUNNING)) !=
(IFF_UP|IFF_RUNNING)) {
m_freem(m);
return -1; /* so ether_input can take note */
diff --git a/sys/net/if_vlan_var.h b/sys/net/if_vlan_var.h
index 8c4882f87c2..d80e3dc838e 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.9 2003/02/01 00:14:40 chris Exp $ */
+/* $OpenBSD: if_vlan_var.h,v 1.10 2003/12/03 14:55:58 markus Exp $ */
/*
* Copyright 1998 Massachusetts Institute of Technology
@@ -54,6 +54,7 @@ struct ifvlan {
u_int16_t ifvm_tag; /* tag to apply on packets leaving if */
} ifv_mib;
LIST_HEAD(__vlan_mchead, vlan_mc_entry) vlan_mc_listhead;
+ LIST_ENTRY(ifvlan) ifv_list; /* all vlan interfaces */
int ifv_flags;
};