summaryrefslogtreecommitdiffstats
path: root/sys/net
diff options
context:
space:
mode:
authorbrooks <brooks@FreeBSD.org>2005-06-10 16:49:24 +0000
committerbrooks <brooks@FreeBSD.org>2005-06-10 16:49:24 +0000
commit567ba9b00a248431e7c1147c4e079fd7a11b9ecf (patch)
treef65b6d7834b40dfcd48534829a0a1e9529ab87ee /sys/net
parent3eaa67c3ad947d85be5350e0e184cd6ee5b93a52 (diff)
downloadFreeBSD-src-567ba9b00a248431e7c1147c4e079fd7a11b9ecf.zip
FreeBSD-src-567ba9b00a248431e7c1147c4e079fd7a11b9ecf.tar.gz
Stop embedding struct ifnet at the top of driver softcs. Instead the
struct ifnet or the layer 2 common structure it was embedded in have been replaced with a struct ifnet pointer to be filled by a call to the new function, if_alloc(). The layer 2 common structure is also allocated via if_alloc() based on the interface type. It is hung off the new struct ifnet member, if_l2com. This change removes the size of these structures from the kernel ABI and will allow us to better manage them as interfaces come and go. Other changes of note: - Struct arpcom is no longer referenced in normal interface code. Instead the Ethernet address is accessed via the IFP2ENADDR() macro. To enforce this ac_enaddr has been renamed to _ac_enaddr. - The second argument to ether_ifattach is now always the mac address from driver private storage rather than sometimes being ac_enaddr. Reviewed by: sobomax, sam
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/bpf.c2
-rw-r--r--sys/net/bridge.c2
-rw-r--r--sys/net/bridge.h1
-rw-r--r--sys/net/bridgestp.c4
-rw-r--r--sys/net/firewire.h3
-rw-r--r--sys/net/if.c108
-rw-r--r--sys/net/if_arc.h2
-rw-r--r--sys/net/if_arcsubr.c58
-rw-r--r--sys/net/if_arp.h17
-rw-r--r--sys/net/if_atm.h13
-rw-r--r--sys/net/if_atmsubr.c44
-rw-r--r--sys/net/if_bridge.c72
-rw-r--r--sys/net/if_bridgevar.h2
-rw-r--r--sys/net/if_disc.c15
-rw-r--r--sys/net/if_ef.c43
-rw-r--r--sys/net/if_ethersubr.c63
-rw-r--r--sys/net/if_faith.c38
-rw-r--r--sys/net/if_fddisubr.c16
-rw-r--r--sys/net/if_fwsubr.c60
-rw-r--r--sys/net/if_gif.c49
-rw-r--r--sys/net/if_gif.h3
-rw-r--r--sys/net/if_gre.c43
-rw-r--r--sys/net/if_gre.h3
-rw-r--r--sys/net/if_iso88025subr.c58
-rw-r--r--sys/net/if_loop.c30
-rw-r--r--sys/net/if_ppp.c75
-rw-r--r--sys/net/if_pppvar.h3
-rw-r--r--sys/net/if_sl.c143
-rw-r--r--sys/net/if_slvar.h3
-rw-r--r--sys/net/if_sppp.h5
-rw-r--r--sys/net/if_spppfr.c2
-rw-r--r--sys/net/if_spppsubr.c115
-rw-r--r--sys/net/if_stf.c34
-rw-r--r--sys/net/if_tap.c33
-rw-r--r--sys/net/if_tapvar.h3
-rw-r--r--sys/net/if_tun.c55
-rw-r--r--sys/net/if_types.h1
-rw-r--r--sys/net/if_var.h28
-rw-r--r--sys/net/if_vlan.c53
-rw-r--r--sys/net/ppp_tty.c48
40 files changed, 847 insertions, 503 deletions
diff --git a/sys/net/bpf.c b/sys/net/bpf.c
index 9c9ca7e..ac81ff1 100644
--- a/sys/net/bpf.c
+++ b/sys/net/bpf.c
@@ -1018,7 +1018,7 @@ bpf_setif(d, ifr)
if (ifp == NULL || ifp != theywant)
continue;
/* skip additional entry */
- if (bp->bif_driverp != (struct bpf_if **)&ifp->if_bpf)
+ if (bp->bif_driverp != &ifp->if_bpf)
continue;
mtx_unlock(&bpf_mtx);
diff --git a/sys/net/bridge.c b/sys/net/bridge.c
index 1011f10..82a24fa 100644
--- a/sys/net/bridge.c
+++ b/sys/net/bridge.c
@@ -352,7 +352,7 @@ add_cluster(u_int16_t cluster_id, struct ifnet *ifp)
n_clusters++;
found:
c = clusters + i; /* the right cluster ... */
- ETHER_ADDR_COPY(c->my_macs[c->ports].etheraddr, IFP2AC(ifp)->ac_enaddr);
+ ETHER_ADDR_COPY(c->my_macs[c->ports].etheraddr, IFP2ENADDR(ifp));
c->ports++;
return c;
bad:
diff --git a/sys/net/bridge.h b/sys/net/bridge.h
index 7eb3b2d..76594f5 100644
--- a/sys/net/bridge.h
+++ b/sys/net/bridge.h
@@ -42,7 +42,6 @@ struct cluster_softc; /* opaque here, defined in bridge.c */
struct bdg_softc {
struct ifnet *ifp ;
- /* also ((struct arpcom *)ifp)->ac_enaddr is the eth. addr */
int flags ;
#define IFF_BDG_PROMISC 0x0001 /* set promisc mode on this if. */
#define IFF_MUTE 0x0002 /* mute this if for bridging. */
diff --git a/sys/net/bridgestp.c b/sys/net/bridgestp.c
index a1a487b..476e026 100644
--- a/sys/net/bridgestp.c
+++ b/sys/net/bridgestp.c
@@ -66,8 +66,6 @@ __FBSDID("$FreeBSD$");
#include <netinet/if_ether.h>
#include <net/if_bridgevar.h>
-#define sc_if ifb_ac.ac_if
-
/* BPDU message types */
#define BSTP_MSGTYPE_CFG 0x00 /* Configuration */
#define BSTP_MSGTYPE_TCN 0x80 /* Topology chg notification */
@@ -1139,7 +1137,7 @@ bstp_tick(void *arg)
bstp_hold_timer_expiry(sc, bif);
}
- if (sc->sc_if.if_flags & IFF_RUNNING)
+ if (sc->sc_ifp->if_flags & IFF_RUNNING)
callout_reset(&sc->sc_bstpcallout, hz, bstp_tick, sc);
BRIDGE_UNLOCK(sc);
diff --git a/sys/net/firewire.h b/sys/net/firewire.h
index 5c63a05..d47b822 100644
--- a/sys/net/firewire.h
+++ b/sys/net/firewire.h
@@ -121,7 +121,7 @@ struct fw_reass {
STAILQ_HEAD(fw_reass_list, fw_reass);
struct fw_com {
- struct ifnet fc_if;
+ struct ifnet *fc_ifp;
struct fw_hwaddr fc_hwaddr;
struct firewire_comm *fc_fc;
uint8_t fc_broadcast_channel;
@@ -129,6 +129,7 @@ struct fw_com {
uint16_t fc_node; /* our nodeid */
struct fw_reass_list fc_frags; /* partial datagrams */
};
+#define IFP2FWC(ifp) ((struct fw_com *)(ifp)->if_l2com)
extern void firewire_input(struct ifnet *ifp, struct mbuf *m, uint16_t src);
extern void firewire_ifattach(struct ifnet *, struct fw_hwaddr *);
diff --git a/sys/net/if.c b/sys/net/if.c
index d2d179f..4f3082a 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -127,6 +127,8 @@ struct ifindex_entry *ifindex_table = NULL;
int ifqmaxlen = IFQ_MAXLEN;
struct ifnethead ifnet; /* depend on static init XXX */
struct mtx ifnet_lock;
+static if_com_alloc_t *if_com_alloc[256];
+static if_com_free_t *if_com_free[256];
static int if_indexlim = 8;
static struct knlist ifklist;
@@ -143,6 +145,7 @@ static struct filterops netdev_filtops =
SYSINIT(interfaces, SI_SUB_INIT_IF, SI_ORDER_FIRST, if_init, NULL)
SYSINIT(interface_check, SI_SUB_PROTO_IF, SI_ORDER_FIRST, if_check, NULL)
+MALLOC_DEFINE(M_IFNET, "ifnet", "interface internals");
MALLOC_DEFINE(M_IFADDR, "ifaddr", "interface address");
MALLOC_DEFINE(M_IFMADDR, "ether_multi", "link-level multicast address");
@@ -291,10 +294,10 @@ if_grow(void)
if_indexlim <<= 1;
n = if_indexlim * sizeof(*e);
- e = malloc(n, M_IFADDR, M_WAITOK | M_ZERO);
+ e = malloc(n, M_IFNET, M_WAITOK | M_ZERO);
if (ifindex_table != NULL) {
memcpy((caddr_t)e, (caddr_t)ifindex_table, n/2);
- free((caddr_t)ifindex_table, M_IFADDR);
+ free((caddr_t)ifindex_table, M_IFNET);
}
ifindex_table = e;
}
@@ -325,6 +328,7 @@ if_check(void *dummy __unused)
if_slowtimo(0);
}
+/* XXX: should be locked. */
static int
if_findindex(struct ifnet *ifp)
{
@@ -339,7 +343,7 @@ if_findindex(struct ifnet *ifp)
case IFT_ISO88025:
case IFT_L2VLAN:
case IFT_BRIDGE:
- snprintf(eaddr, 18, "%6D", IFP2AC(ifp)->ac_enaddr, ":");
+ snprintf(eaddr, 18, "%6D", IFP2ENADDR(ifp), ":");
break;
default:
eaddr[0] = '\0';
@@ -376,6 +380,59 @@ found:
}
/*
+ * Allocate a struct ifnet and in index for an interface.
+ */
+struct ifnet*
+if_alloc(u_char type)
+{
+ struct ifnet *ifp;
+
+ ifp = malloc(sizeof(struct ifnet), M_IFNET, M_WAITOK|M_ZERO);
+
+ /* XXX: This should fail it index it is too big */
+ ifp->if_index = if_findindex(ifp);
+ if (ifp->if_index > if_index)
+ if_index = ifp->if_index;
+ if (if_index >= if_indexlim)
+ if_grow();
+
+ ifnet_byindex(ifp->if_index) = ifp;
+
+ ifp->if_type = type;
+
+ if (if_com_alloc[type] != NULL) {
+ ifp->if_l2com = if_com_alloc[type](type, ifp);
+ if (ifp->if_l2com == NULL)
+ free(ifp, M_IFNET);
+ }
+
+ return (ifp);
+}
+
+void
+if_free(struct ifnet *ifp)
+{
+
+ if_free_type(ifp, ifp->if_type);
+}
+
+void
+if_free_type(struct ifnet *ifp, u_char type)
+{
+
+ if (ifp != ifnet_byindex(ifp->if_index)) {
+ if_printf(ifp, "%s: value was not if_alloced, skipping\n",
+ __func__);
+ return;
+ }
+
+ if (if_com_free[type] != NULL)
+ if_com_free[type](ifp->if_l2com, type);
+
+ free(ifp, M_IFNET);
+};
+
+/*
* Attach an interface to the
* list of "active" interfaces.
*/
@@ -387,6 +444,10 @@ if_attach(struct ifnet *ifp)
struct sockaddr_dl *sdl;
struct ifaddr *ifa;
+ if (ifp->if_index == 0 || ifp != ifnet_byindex(ifp->if_index))
+ panic ("%s: BUG: if_attach called without if_alloc'd input()\n",
+ ifp->if_xname);
+
TASK_INIT(&ifp->if_starttask, 0, if_start_deferred, ifp);
TASK_INIT(&ifp->if_linktask, 0, do_link_state_change, ifp);
IF_AFDATA_LOCK_INIT(ifp);
@@ -407,20 +468,13 @@ if_attach(struct ifnet *ifp)
knlist_init(&ifp->if_klist, NULL);
getmicrotime(&ifp->if_lastchange);
ifp->if_data.ifi_epoch = time_uptime;
+ ifp->if_data.ifi_datalen = sizeof(struct if_data);
#ifdef MAC
mac_init_ifnet(ifp);
mac_create_ifnet(ifp);
#endif
- ifp->if_index = if_findindex(ifp);
- if (ifp->if_index > if_index)
- if_index = ifp->if_index;
- if (if_index >= if_indexlim)
- if_grow();
- ifp->if_data.ifi_datalen = sizeof(struct if_data);
-
- ifnet_byindex(ifp->if_index) = ifp;
ifdev_byindex(ifp->if_index) = make_dev(&net_cdevsw,
unit2minor(ifp->if_index),
UID_ROOT, GID_WHEEL, 0600, "%s/%s",
@@ -572,7 +626,7 @@ if_purgeaddrs(struct ifnet *ifp)
/*
* Detach an interface, removing it from the
- * list of "active" interfaces.
+ * list of "active" interfaces and freeing the struct ifnet.
*/
void
if_detach(struct ifnet *ifp)
@@ -1942,7 +1996,7 @@ if_setlladdr(struct ifnet *ifp, const u_char *lladdr, int len)
case IFT_ISO88025:
case IFT_L2VLAN:
case IFT_BRIDGE:
- bcopy(lladdr, IFP2AC(ifp)->ac_enaddr, len);
+ bcopy(lladdr, IFP2ENADDR(ifp), len);
/*
* XXX We also need to store the lladdr in LLADDR(sdl),
* which is done below. This is a pain because we must
@@ -2066,7 +2120,7 @@ if_start_deferred(void *context, int pending)
KASSERT(debug_mpsafenet != 0, ("if_start_deferred: debug.mpsafenet"));
GIANT_REQUIRED;
- ifp = (struct ifnet *)context;
+ ifp = context;
(ifp->if_start)(ifp);
}
@@ -2094,3 +2148,29 @@ if_handoff(struct ifqueue *ifq, struct mbuf *m, struct ifnet *ifp, int adjust)
if_start(ifp);
return (1);
}
+
+void
+if_register_com_alloc(u_char type,
+ if_com_alloc_t *a, if_com_free_t *f)
+{
+
+ KASSERT(if_com_alloc[type] == NULL,
+ ("if_register_com_alloc: %d already registered", type));
+ KASSERT(if_com_free[type] == NULL,
+ ("if_register_com_alloc: %d free already registered", type));
+
+ if_com_alloc[type] = a;
+ if_com_free[type] = f;
+}
+
+void
+if_deregister_com_alloc(u_char type)
+{
+
+ KASSERT(if_com_alloc[type] == NULL,
+ ("if_deregister_com_alloc: %d not registered", type));
+ KASSERT(if_com_free[type] == NULL,
+ ("if_deregister_com_alloc: %d free not registered", type));
+ if_com_alloc[type] = NULL;
+ if_com_free[type] = NULL;
+}
diff --git a/sys/net/if_arc.h b/sys/net/if_arc.h
index 461f1b4..7274829 100644
--- a/sys/net/if_arc.h
+++ b/sys/net/if_arc.h
@@ -102,7 +102,7 @@ struct arc_header {
#define ARC_PHDS_MAXMTU 60480
struct arccom {
- struct ifnet ac_if; /* network-visible interface */
+ struct ifnet *ac_ifp; /* network-visible interface */
u_int16_t ac_seqid; /* seq. id used by PHDS encap. */
diff --git a/sys/net/if_arcsubr.c b/sys/net/if_arcsubr.c
index 39022ef..e944f49 100644
--- a/sys/net/if_arcsubr.c
+++ b/sys/net/if_arcsubr.c
@@ -80,8 +80,6 @@
#include <netipx/ipx_if.h>
#endif
-MODULE_VERSION(arcnet, 1);
-
#define ARCNET_ALLOW_BROKEN_ARP
static struct mbuf *arc_defrag(struct ifnet *, struct mbuf *);
@@ -254,7 +252,7 @@ arc_frag_init(ifp)
{
struct arccom *ac;
- ac = (struct arccom *)ifp;
+ ac = (struct arccom *)ifp->if_l2com;
ac->curr_frag = 0;
}
@@ -266,7 +264,7 @@ arc_frag_next(ifp)
struct mbuf *m;
struct arc_header *ah;
- ac = (struct arccom *)ifp;
+ ac = (struct arccom *)ifp->if_l2com;
if ((m = ac->curr_frag) == 0) {
int tfrags;
@@ -367,7 +365,7 @@ arc_defrag(ifp, m)
int newflen;
u_char src,dst,typ;
- ac = (struct arccom *)ifp;
+ ac = (struct arccom *)ifp->if_l2com;
if (m->m_len < ARC_HDRNEWLEN) {
m = m_pullup(m, ARC_HDRNEWLEN);
@@ -641,7 +639,6 @@ arc_ifattach(ifp, lla)
struct arccom *ac;
if_attach(ifp);
- ifp->if_type = IFT_ARCNET;
ifp->if_addrlen = 1;
ifp->if_hdrlen = ARC_HDRLEN;
ifp->if_mtu = 1500;
@@ -661,7 +658,7 @@ arc_ifattach(ifp, lla)
if (ifp->if_flags & IFF_BROADCAST)
ifp->if_flags |= IFF_MULTICAST|IFF_ALLMULTI;
- ac = (struct arccom *)ifp;
+ ac = (struct arccom *)ifp->if_l2com;
ac->ac_seqid = (time_second) & 0xFFFF; /* try to make seqid unique */
if (lla == 0) {
/* XXX this message isn't entirely clear, to me -- cgd */
@@ -846,3 +843,50 @@ arc_resolvemulti(ifp, llsa, sa)
return EAFNOSUPPORT;
}
}
+
+MALLOC_DEFINE(M_ARCCOM, "arccom", "ARCNET interface internals");
+
+static void*
+arc_alloc(u_char type, struct ifnet *ifp)
+{
+ struct arccom *ac;
+
+ ac = malloc(sizeof(struct arccom), M_ARCCOM, M_WAITOK | M_ZERO);
+ ac->ac_ifp = ifp;
+
+ return (ac);
+}
+
+static void
+arc_free(void *com, u_char type)
+{
+
+ free(com, M_ARCCOM);
+}
+
+static int
+arc_modevent(module_t mod, int type, void *data)
+{
+
+ switch (type) {
+ case MOD_LOAD:
+ if_register_com_alloc(IFT_ARCNET, arc_alloc, arc_free);
+ break;
+ case MOD_UNLOAD:
+ if_deregister_com_alloc(IFT_ARCNET);
+ break;
+ default:
+ return EOPNOTSUPP;
+ }
+
+ return (0);
+}
+
+static moduledata_t arc_mod = {
+ "arcnet",
+ arc_modevent,
+ 0
+};
+
+DECLARE_MODULE(arcnet, arc_mod, SI_SUB_INIT_IF, SI_ORDER_ANY);
+MODULE_VERSION(arcnet, 1);
diff --git a/sys/net/if_arp.h b/sys/net/if_arp.h
index 71f078b..9aa63c6 100644
--- a/sys/net/if_arp.h
+++ b/sys/net/if_arp.h
@@ -99,21 +99,16 @@ struct arpreq {
#ifdef _KERNEL
/*
* Structure shared between the ethernet driver modules and
- * the address resolution code. For example, each ec_softc or il_softc
- * begins with this structure.
- * The code is written so that each *_softc _must_ begin with a
- * struct arpcom, which in turn _must_ begin with a struct ifnet.
+ * the address resolution code.
*/
struct arpcom {
- /*
- * The ifnet struct _must_ be at the head of this structure.
- */
- struct ifnet ac_if; /* network-visible interface */
- u_char ac_enaddr[6]; /* ethernet hardware address */
- int now_unused; /* XXX was length of ac_multiaddrs list */
+ struct ifnet *ac_ifp; /* network-visible interface */
+ u_char _ac_enaddr[6]; /* ethernet hardware address */
void *ac_netgraph; /* ng_ether(4) netgraph node info */
};
-#define IFP2AC(ifp) ((struct arpcom *)(ifp))
+#define IFP2AC(ifp) ((struct arpcom *)(ifp->if_l2com))
+#define IFP2ENADDR(ifp) (IFP2AC(ifp)->_ac_enaddr)
+#define AC2IFP(ac) ((ac)->ac_ifp)
#endif
diff --git a/sys/net/if_atm.h b/sys/net/if_atm.h
index 4084569..4b07f36 100644
--- a/sys/net/if_atm.h
+++ b/sys/net/if_atm.h
@@ -176,11 +176,12 @@ struct atmio_vcctable {
* this structure.
*/
struct ifatm {
- struct ifnet ifnet; /* required by if_var.h */
+ struct ifnet *ifp;
struct ifatm_mib mib; /* exported data */
void *phy; /* usually SUNI */
void *ngpriv; /* netgraph link */
};
+#define IFP2IFATM(ifp) ((struct ifatm *)(ifp)->if_l2com)
#endif
/*
@@ -304,7 +305,7 @@ void atm_event(struct ifnet *, u_int, void *);
_arg.vpi = (VPI); \
_arg.vci = (VCI); \
_arg.busy = (BUSY); \
- atm_event(&(ATMIF)->ifnet, ATMEV_FLOW_CONTROL, &_arg); \
+ atm_event((ATMIF)->ifp, ATMEV_FLOW_CONTROL, &_arg); \
} while (0)
#define ATMEV_SEND_VCC_CHANGED(ATMIF, VPI, VCI, UP) \
@@ -313,16 +314,16 @@ void atm_event(struct ifnet *, u_int, void *);
_arg.vpi = (VPI); \
_arg.vci = (VCI); \
_arg.up = (UP); \
- atm_event(&(ATMIF)->ifnet, ATMEV_VCC_CHANGED, &_arg); \
+ atm_event((ATMIF)->ifp, ATMEV_VCC_CHANGED, &_arg); \
} while (0)
#define ATMEV_SEND_IFSTATE_CHANGED(ATMIF, CARRIER) \
do { \
struct atmev_ifstate_changed _arg; \
- _arg.running = (((ATMIF)->ifnet.if_flags & \
+ _arg.running = (((ATMIF)->ifp->if_flags & \
IFF_RUNNING) != 0); \
_arg.carrier = ((CARRIER) != 0); \
- atm_event(&(ATMIF)->ifnet, ATMEV_IFSTATE_CHANGED, &_arg); \
+ atm_event((ATMIF)->ifp, ATMEV_IFSTATE_CHANGED, &_arg); \
} while (0)
#define ATMEV_SEND_ACR_CHANGED(ATMIF, VPI, VCI, ACR) \
@@ -331,6 +332,6 @@ void atm_event(struct ifnet *, u_int, void *);
_arg.vpi = (VPI); \
_arg.vci = (VCI); \
_arg.acr= (ACR); \
- atm_event(&(ATMIF)->ifnet, ATMEV_ACR_CHANGED, &_arg); \
+ atm_event((ATMIF)->ifp, ATMEV_ACR_CHANGED, &_arg); \
} while (0)
#endif
diff --git a/sys/net/if_atmsubr.c b/sys/net/if_atmsubr.c
index a5f7b11..1350f5a 100644
--- a/sys/net/if_atmsubr.c
+++ b/sys/net/if_atmsubr.c
@@ -98,6 +98,8 @@ void (*atm_harp_event_p)(struct ifnet *, uint32_t, void *);
SYSCTL_NODE(_hw, OID_AUTO, atm, CTLFLAG_RW, 0, "ATM hardware");
+MALLOC_DEFINE(M_IFATM, "ifatm", "atm interface internals");
+
#ifndef ETHERTYPE_IPV6
#define ETHERTYPE_IPV6 0x86dd
#endif
@@ -359,9 +361,8 @@ atm_ifattach(struct ifnet *ifp)
{
struct ifaddr *ifa;
struct sockaddr_dl *sdl;
- struct ifatm *ifatm = ifp->if_softc;
+ struct ifatm *ifatm = ifp->if_l2com;
- ifp->if_type = IFT_ATM;
ifp->if_addrlen = 0;
ifp->if_hdrlen = 0;
if_attach(ifp);
@@ -481,11 +482,46 @@ atm_event(struct ifnet *ifp, u_int event, void *arg)
(*atm_harp_event_p)(ifp, event, arg);
}
+static void *
+atm_alloc(u_char type, struct ifnet *ifp)
+{
+ struct ifatm *ifatm;
+
+ ifatm = malloc(sizeof(struct ifatm), M_IFATM, M_WAITOK | M_ZERO);
+ ifatm->ifp = ifp;
+
+ return (ifatm);
+}
+
+static void
+atm_free(void *com, u_char type)
+{
+
+ free(com, M_IFATM);
+}
+
+static int
+atm_modevent(module_t mod, int type, void *data)
+{
+ switch (type) {
+ case MOD_LOAD:
+ if_register_com_alloc(IFT_ATM, atm_alloc, atm_free);
+ break;
+ case MOD_UNLOAD:
+ if_deregister_com_alloc(IFT_ATM);
+ break;
+ default:
+ return (EOPNOTSUPP);
+ }
+
+ return (0);
+}
+
static moduledata_t atm_mod = {
"atm",
- NULL,
+ atm_modevent,
0
};
-DECLARE_MODULE(atm, atm_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
+DECLARE_MODULE(atm, atm_mod, SI_SUB_INIT_IF, SI_ORDER_ANY);
MODULE_VERSION(atm, 1);
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index df52232..0b4fa9d 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -130,7 +130,6 @@ __FBSDID("$FreeBSD$");
#include <netinet/ip_fw.h>
#include <netinet/ip_dummynet.h>
-#define sc_if ifb_ac.ac_if
/*
* Size of the route hash table. Must be a power of two.
*/
@@ -357,7 +356,7 @@ bridge_modevent(module_t mod, int type, void *data)
case MOD_UNLOAD:
if_clone_detach(&bridge_cloner);
while (!LIST_EMPTY(&bridge_list))
- bridge_clone_destroy(&LIST_FIRST(&bridge_list)->sc_if);
+ bridge_clone_destroy(LIST_FIRST(&bridge_list)->sc_ifp);
uma_zdestroy(bridge_rtnode_zone);
bridge_input_p = NULL;
bridge_output_p = NULL;
@@ -419,10 +418,11 @@ bridge_clone_create(struct if_clone *ifc, int unit)
{
struct bridge_softc *sc;
struct ifnet *ifp;
+ u_char eaddr[6];
sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO);
BRIDGE_LOCK_INIT(sc);
- ifp = &sc->sc_if;
+ ifp = sc->sc_ifp;
sc->sc_brtmax = BRIDGE_RTABLE_MAX;
sc->sc_brttimeout = BRIDGE_RTABLE_TIMEOUT;
@@ -457,12 +457,12 @@ bridge_clone_create(struct if_clone *ifc, int unit)
* Generate a random ethernet address and use the private AC:DE:48
* OUI code.
*/
- arc4rand( &sc->ifb_ac.ac_enaddr, ETHER_ADDR_LEN, 1);
- sc->ifb_ac.ac_enaddr[0] = 0xAC;
- sc->ifb_ac.ac_enaddr[1] = 0xDE;
- sc->ifb_ac.ac_enaddr[2] = 0x48;
+ arc4rand(eaddr, ETHER_ADDR_LEN, 1);
+ eaddr[0] = 0xAC;
+ eaddr[1] = 0xDE;
+ eaddr[2] = 0x48;
- ether_ifattach(ifp, sc->ifb_ac.ac_enaddr);
+ ether_ifattach(ifp, eaddr);
/* Now undo some of the damage... */
ifp->if_baudrate = 0;
ifp->if_type = IFT_BRIDGE;
@@ -693,7 +693,7 @@ bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif)
free(bif, M_DEVBUF);
- if (sc->sc_if.if_flags & IFF_RUNNING)
+ if (sc->sc_ifp->if_flags & IFF_RUNNING)
bstp_initialization(sc);
}
@@ -711,7 +711,7 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg)
if (ifs == NULL)
return (ENOENT);
- if (sc->sc_if.if_mtu != ifs->if_mtu)
+ if (sc->sc_ifp->if_mtu != ifs->if_mtu)
return (EINVAL);
if (ifs->if_bridge == sc)
@@ -753,7 +753,7 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg)
*/
LIST_INSERT_HEAD(&sc->sc_iflist, bif, bif_next);
- if (sc->sc_if.if_flags & IFF_RUNNING)
+ if (sc->sc_ifp->if_flags & IFF_RUNNING)
bstp_initialization(sc);
else
bstp_stop(sc);
@@ -830,7 +830,7 @@ bridge_ioctl_sifflags(struct bridge_softc *sc, void *arg)
bif->bif_flags = req->ifbr_ifsflags;
- if (sc->sc_if.if_flags & IFF_RUNNING)
+ if (sc->sc_ifp->if_flags & IFF_RUNNING)
bstp_initialization(sc);
return (0);
@@ -1031,7 +1031,7 @@ bridge_ioctl_spri(struct bridge_softc *sc, void *arg)
sc->sc_bridge_priority = param->ifbrp_prio;
- if (sc->sc_if.if_flags & IFF_RUNNING)
+ if (sc->sc_ifp->if_flags & IFF_RUNNING)
bstp_initialization(sc);
return (0);
@@ -1060,7 +1060,7 @@ bridge_ioctl_sht(struct bridge_softc *sc, void *arg)
return (EINVAL);
sc->sc_bridge_hello_time = param->ifbrp_hellotime << 8;
- if (sc->sc_if.if_flags & IFF_RUNNING)
+ if (sc->sc_ifp->if_flags & IFF_RUNNING)
bstp_initialization(sc);
return (0);
@@ -1089,7 +1089,7 @@ bridge_ioctl_sfd(struct bridge_softc *sc, void *arg)
return (EINVAL);
sc->sc_bridge_forward_delay = param->ifbrp_fwddelay << 8;
- if (sc->sc_if.if_flags & IFF_RUNNING)
+ if (sc->sc_ifp->if_flags & IFF_RUNNING)
bstp_initialization(sc);
return (0);
@@ -1118,7 +1118,7 @@ bridge_ioctl_sma(struct bridge_softc *sc, void *arg)
return (EINVAL);
sc->sc_bridge_max_age = param->ifbrp_maxage << 8;
- if (sc->sc_if.if_flags & IFF_RUNNING)
+ if (sc->sc_ifp->if_flags & IFF_RUNNING)
bstp_initialization(sc);
return (0);
@@ -1138,7 +1138,7 @@ bridge_ioctl_sifprio(struct bridge_softc *sc, void *arg)
bif->bif_priority = req->ifbr_priority;
- if (sc->sc_if.if_flags & IFF_RUNNING)
+ if (sc->sc_ifp->if_flags & IFF_RUNNING)
bstp_initialization(sc);
return (0);
@@ -1158,7 +1158,7 @@ bridge_ioctl_sifcost(struct bridge_softc *sc, void *arg)
bif->bif_path_cost = req->ifbr_path_cost;
- if (sc->sc_if.if_flags & IFF_RUNNING)
+ if (sc->sc_ifp->if_flags & IFF_RUNNING)
bstp_initialization(sc);
return (0);
@@ -1193,7 +1193,7 @@ static void
bridge_init(void *xsc)
{
struct bridge_softc *sc = (struct bridge_softc *)xsc;
- struct ifnet *ifp = &sc->sc_if;
+ struct ifnet *ifp = sc->sc_ifp;
if (ifp->if_flags & IFF_RUNNING)
return;
@@ -1246,7 +1246,7 @@ bridge_enqueue(struct bridge_softc *sc, struct ifnet *dst_ifp, struct mbuf *m,
m->m_pkthdr.csum_flags = 0;
if (runfilt && inet_pfil_hook.ph_busy_count >= 0) {
- if (bridge_pfil(&m, &sc->sc_if, dst_ifp, PFIL_OUT) != 0)
+ if (bridge_pfil(&m, sc->sc_ifp, dst_ifp, PFIL_OUT) != 0)
return;
}
if (m == NULL)
@@ -1257,13 +1257,13 @@ bridge_enqueue(struct bridge_softc *sc, struct ifnet *dst_ifp, struct mbuf *m,
IFQ_ENQUEUE(&dst_ifp->if_snd, m, err);
if (err == 0) {
- sc->sc_if.if_opackets++;
- sc->sc_if.if_obytes += len;
+ sc->sc_ifp->if_opackets++;
+ sc->sc_ifp->if_obytes += len;
dst_ifp->if_obytes += len;
if (mflags & M_MCAST) {
- sc->sc_if.if_omcasts++;
+ sc->sc_ifp->if_omcasts++;
dst_ifp->if_omcasts++;
}
}
@@ -1334,7 +1334,7 @@ bridge_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa,
* go ahead and send out that interface. Otherwise, the packet
* is dropped below.
*/
- if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) {
+ if ((sc->sc_ifp->if_flags & IFF_RUNNING) == 0) {
dst_if = ifp;
goto sendunicast;
}
@@ -1384,7 +1384,7 @@ bridge_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa,
} else {
mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
if (mc == NULL) {
- sc->sc_if.if_oerrors++;
+ sc->sc_ifp->if_oerrors++;
continue;
}
}
@@ -1472,10 +1472,10 @@ bridge_forward(struct bridge_softc *sc, struct mbuf *m)
src_if = m->m_pkthdr.rcvif;
BRIDGE_LOCK_ASSERT(sc);
- ifp = &sc->sc_if;
+ ifp = sc->sc_ifp;
- sc->sc_if.if_ipackets++;
- sc->sc_if.if_ibytes += m->m_pkthdr.len;
+ sc->sc_ifp->if_ipackets++;
+ sc->sc_ifp->if_ibytes += m->m_pkthdr.len;
/*
* Look up the bridge_iflist.
@@ -1543,7 +1543,7 @@ bridge_forward(struct bridge_softc *sc, struct mbuf *m)
}
} else {
/* ...forward it to all interfaces. */
- sc->sc_if.if_imcasts++;
+ sc->sc_ifp->if_imcasts++;
dst_if = NULL;
}
@@ -1615,7 +1615,7 @@ bridge_input(struct ifnet *ifp, struct mbuf *m)
struct ether_header *eh;
struct mbuf *mc;
- if ((sc->sc_if.if_flags & IFF_RUNNING) == 0)
+ if ((sc->sc_ifp->if_flags & IFF_RUNNING) == 0)
return (m);
BRIDGE_LOCK(sc);
@@ -1627,7 +1627,7 @@ bridge_input(struct ifnet *ifp, struct mbuf *m)
eh = mtod(m, struct ether_header *);
- if (memcmp(eh->ether_dhost, sc->ifb_ac.ac_enaddr,
+ if (memcmp(eh->ether_dhost, IFP2ENADDR(sc->sc_ifp),
ETHER_ADDR_LEN) == 0) {
/*
* If the packet is for us, set the packets source as the
@@ -1640,9 +1640,9 @@ bridge_input(struct ifnet *ifp, struct mbuf *m)
*/
/* Mark the packet as arriving on the bridge interface */
- m->m_pkthdr.rcvif = &sc->sc_if;
- BPF_MTAP(&sc->sc_if, m);
- sc->sc_if.if_ipackets++;
+ m->m_pkthdr.rcvif = sc->sc_ifp;
+ BPF_MTAP(sc->sc_ifp, m);
+ sc->sc_ifp->if_ipackets++;
BRIDGE_UNLOCK(sc);
return (m);
@@ -1778,7 +1778,7 @@ bridge_broadcast(struct bridge_softc *sc, struct ifnet *src_if,
} else {
mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
if (mc == NULL) {
- sc->sc_if.if_oerrors++;
+ sc->sc_ifp->if_oerrors++;
continue;
}
}
@@ -1909,7 +1909,7 @@ bridge_timer(void *arg)
bridge_rtage(sc);
BRIDGE_UNLOCK(sc);
- if (sc->sc_if.if_flags & IFF_RUNNING)
+ if (sc->sc_ifp->if_flags & IFF_RUNNING)
callout_reset(&sc->sc_brcallout,
bridge_rtable_prune_period * hz, bridge_timer, sc);
}
diff --git a/sys/net/if_bridgevar.h b/sys/net/if_bridgevar.h
index 705ed85..1bc948b 100644
--- a/sys/net/if_bridgevar.h
+++ b/sys/net/if_bridgevar.h
@@ -262,7 +262,7 @@ struct bridge_rtnode {
* Software state for each bridge.
*/
struct bridge_softc {
- struct arpcom ifb_ac; /* make this an interface */
+ struct ifnet *sc_ifp; /* make this an interface */
LIST_ENTRY(bridge_softc) sc_list;
struct mtx sc_mtx;
struct cv sc_cv;
diff --git a/sys/net/if_disc.c b/sys/net/if_disc.c
index 3068b44..7789b29 100644
--- a/sys/net/if_disc.c
+++ b/sys/net/if_disc.c
@@ -62,7 +62,7 @@
#define DISCNAME "disc"
struct disc_softc {
- struct ifnet sc_if; /* must be first */
+ struct ifnet *sc_ifp; /* must be first */
LIST_ENTRY(disc_softc) sc_list;
};
@@ -86,8 +86,11 @@ disc_clone_create(struct if_clone *ifc, int unit)
struct disc_softc *sc;
sc = malloc(sizeof(struct disc_softc), M_DISC, M_WAITOK | M_ZERO);
-
- ifp = &sc->sc_if;
+ ifp = sc->sc_ifp = if_alloc(IFT_LOOP);
+ if (ifp == NULL) {
+ free(sc, M_DISC);
+ return (ENOSPC);
+ }
ifp->if_softc = sc;
if_initname(ifp, ifc->ifc_name, unit);
@@ -95,7 +98,6 @@ disc_clone_create(struct if_clone *ifc, int unit)
ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST;
ifp->if_ioctl = discioctl;
ifp->if_output = discoutput;
- ifp->if_type = IFT_LOOP;
ifp->if_hdrlen = 0;
ifp->if_addrlen = 0;
ifp->if_snd.ifq_maxlen = 20;
@@ -112,8 +114,9 @@ static void
disc_destroy(struct disc_softc *sc)
{
- bpfdetach(&sc->sc_if);
- if_detach(&sc->sc_if);
+ bpfdetach(sc->sc_ifp);
+ if_detach(sc->sc_ifp);
+ if_free(sc->sc_ifp);
free(sc, M_DISC);
}
diff --git a/sys/net/if_ef.c b/sys/net/if_ef.c
index fa8ac6e..f615485 100644
--- a/sys/net/if_ef.c
+++ b/sys/net/if_ef.c
@@ -86,8 +86,8 @@
#define EFERROR(format, args...) printf("%s: "format, __func__ ,## args)
struct efnet {
- struct arpcom ef_ac;
- struct ifnet * ef_ifp;
+ struct ifnet *ef_ifp;
+ struct ifnet *ef_pifp;
int ef_frametype;
};
@@ -125,7 +125,7 @@ static int ef_unload(void);
static int
ef_attach(struct efnet *sc)
{
- struct ifnet *ifp = (struct ifnet*)&sc->ef_ac.ac_if;
+ struct ifnet *ifp = sc->ef_ifp;
struct ifaddr *ifa2;
struct sockaddr_dl *sdl2;
@@ -137,7 +137,7 @@ ef_attach(struct efnet *sc)
/*
* Attach the interface
*/
- ifa2 = ifaddr_byindex(sc->ef_ifp->if_index);
+ ifa2 = ifaddr_byindex(sc->ef_pifp->if_index);
sdl2 = (struct sockaddr_dl *)ifa2->ifa_addr;
ether_ifattach(ifp, LLADDR(sdl2));
@@ -145,8 +145,6 @@ ef_attach(struct efnet *sc)
ifp->if_type = IFT_XETHER;
ifp->if_flags |= IFF_RUNNING;
- bcopy(LLADDR(sdl2), sc->ef_ac.ac_enaddr, ETHER_ADDR_LEN);
-
EFDEBUG("%s: attached\n", ifp->if_xname);
return 1;
}
@@ -157,24 +155,14 @@ ef_attach(struct efnet *sc)
static int
ef_detach(struct efnet *sc)
{
- struct ifnet *ifp = (struct ifnet*)&sc->ef_ac.ac_if;
+ struct ifnet *ifp = sc->ef_ifp;
int s;
s = splimp();
- if (ifp->if_flags & IFF_UP) {
- if_down(ifp);
- if (ifp->if_flags & IFF_RUNNING) {
- /* find internet addresses and delete routes */
- register struct ifaddr *ifa;
- TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
- rtinit(ifa, (int)RTM_DELETE, 0);
- }
- }
- }
- IFNET_WLOCK();
- TAILQ_REMOVE(&ifnet, ifp, if_link);
- IFNET_WUNLOCK();
+ ether_ifdetach(ifp);
+ if_free(ifp);
+
splx(s);
return 0;
}
@@ -227,7 +215,7 @@ ef_start(struct ifnet *ifp)
int error;
ifp->if_flags |= IFF_OACTIVE;
- p = sc->ef_ifp;
+ p = sc->ef_pifp;
EFDEBUG("\n");
for (;;) {
@@ -377,7 +365,7 @@ ef_input(struct ifnet *ifp, struct ether_header *eh, struct mbuf *m)
EFDEBUG("Can't find if for %d\n", ft);
return EPROTONOSUPPORT;
}
- eifp = &efp->ef_ac.ac_if;
+ eifp = efp->ef_ifp;
if ((eifp->if_flags & IFF_UP) == 0)
return EPROTONOSUPPORT;
eifp->if_ibytes += m->m_pkthdr.len + sizeof (*eh);
@@ -486,9 +474,11 @@ ef_clone(struct ef_link *efl, int ft)
M_WAITOK | M_ZERO);
if (efp == NULL)
return ENOMEM;
- efp->ef_ifp = ifp;
+ efp->ef_pifp = ifp;
efp->ef_frametype = ft;
- eifp = &efp->ef_ac.ac_if;
+ eifp = efp->ef_ifp = if_alloc(IFT_ETHER);
+ if (ifp == NULL)
+ return (ENOSPC);
snprintf(eifp->if_xname, IFNAMSIZ,
"%sf%d", ifp->if_xname, efp->ef_frametype);
eifp->if_dname = "ef";
@@ -545,8 +535,11 @@ ef_load(void)
SLIST_INSERT_HEAD(&efdev, efl, el_next);
SLIST_FOREACH(efl, &efdev, el_next) {
for (d = 0; d < EF_NFT; d++)
- if (efl->el_units[d])
+ if (efl->el_units[d]) {
+ if (efl->el_units[d]->ef_pifp != NULL)
+ if_free(efl->el_units[d]->ef_pifp);
free(efl->el_units[d], M_IFADDR);
+ }
free(efl, M_IFADDR);
}
return error;
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c
index 6082624..cf0b299 100644
--- a/sys/net/if_ethersubr.c
+++ b/sys/net/if_ethersubr.c
@@ -125,6 +125,9 @@ static const u_char etherbroadcastaddr[ETHER_ADDR_LEN] =
static int ether_resolvemulti(struct ifnet *, struct sockaddr **,
struct sockaddr *);
+/* XXX: should be in an arp support file, not here */
+MALLOC_DEFINE(M_ARPCOM, "arpcom", "802.* interface internals");
+
#define senderr(e) do { error = (e); goto bad;} while (0)
#if defined(INET) || defined(INET6)
@@ -285,7 +288,7 @@ ether_output(struct ifnet *ifp, struct mbuf *m,
(void)memcpy(eh->ether_shost, esrc,
sizeof(eh->ether_shost));
else
- (void)memcpy(eh->ether_shost, IFP2AC(ifp)->ac_enaddr,
+ (void)memcpy(eh->ether_shost, IFP2ENADDR(ifp),
sizeof(eh->ether_shost));
/*
@@ -670,7 +673,7 @@ ether_demux(struct ifnet *ifp, struct mbuf *m)
/*
* XXX: Okay, we need to call carp_forus() and - if it is for
* us jump over code that does the normal check
- * "ac_enaddr == ether_dhost". The check sequence is a bit
+ * "IFP2ENADDR(ifp) == ether_dhost". The check sequence is a bit
* different from OpenBSD, so we jump over as few code as
* possible, to catch _all_ sanity checks. This needs
* evaluation, to see if the carp ether_dhost values break any
@@ -694,7 +697,7 @@ ether_demux(struct ifnet *ifp, struct mbuf *m)
if ((ifp->if_flags & IFF_PROMISC) != 0
&& !ETHER_IS_MULTICAST(eh->ether_dhost)
&& bcmp(eh->ether_dhost,
- IFP2AC(ifp)->ac_enaddr, ETHER_ADDR_LEN) != 0
+ IFP2ENADDR(ifp), ETHER_ADDR_LEN) != 0
&& (ifp->if_flags & IFF_PPROMISC) == 0) {
m_freem(m);
return;
@@ -891,7 +894,6 @@ ether_ifattach(struct ifnet *ifp, const u_int8_t *llc)
struct ifaddr *ifa;
struct sockaddr_dl *sdl;
- ifp->if_type = IFT_ETHER;
ifp->if_addrlen = ETHER_ADDR_LEN;
ifp->if_hdrlen = ETHER_HDR_LEN;
if_attach(ifp);
@@ -913,8 +915,8 @@ ether_ifattach(struct ifnet *ifp, const u_int8_t *llc)
* XXX: This doesn't belong here; we do it until
* XXX: all drivers are cleaned up
*/
- if (llc != IFP2AC(ifp)->ac_enaddr)
- bcopy(llc, IFP2AC(ifp)->ac_enaddr, ifp->if_addrlen);
+ if (llc != IFP2ENADDR(ifp))
+ bcopy(llc, IFP2ENADDR(ifp), ifp->if_addrlen);
bpfattach(ifp, DLT_EN10MB, ETHER_HDR_LEN);
if (ng_ether_attach_p != NULL)
@@ -1051,16 +1053,15 @@ ether_ioctl(struct ifnet *ifp, int command, caddr_t data)
case AF_IPX:
{
struct ipx_addr *ina = &(IA_SIPX(ifa)->sipx_addr);
- struct arpcom *ac = IFP2AC(ifp);
if (ipx_nullhost(*ina))
ina->x_host =
*(union ipx_host *)
- ac->ac_enaddr;
+ IFP2ENADDR(ifp);
else {
bcopy((caddr_t) ina->x_host.c_host,
- (caddr_t) ac->ac_enaddr,
- sizeof(ac->ac_enaddr));
+ (caddr_t) IFP2ENADDR(ifp),
+ ETHER_ADDR_LEN);
}
/*
@@ -1081,7 +1082,7 @@ ether_ioctl(struct ifnet *ifp, int command, caddr_t data)
struct sockaddr *sa;
sa = (struct sockaddr *) & ifr->ifr_data;
- bcopy(IFP2AC(ifp)->ac_enaddr,
+ bcopy(IFP2ENADDR(ifp),
(caddr_t) sa->sa_data, ETHER_ADDR_LEN);
}
break;
@@ -1182,11 +1183,47 @@ ether_resolvemulti(struct ifnet *ifp, struct sockaddr **llsa,
}
}
+static void*
+ether_alloc(u_char type, struct ifnet *ifp)
+{
+ struct arpcom *ac;
+
+ ac = malloc(sizeof(struct arpcom), M_ARPCOM, M_WAITOK | M_ZERO);
+ ac->ac_ifp = ifp;
+
+ return (ac);
+}
+
+static void
+ether_free(void *com, u_char type)
+{
+
+ free(com, M_ARPCOM);
+}
+
+static int
+ether_modevent(module_t mod, int type, void *data)
+{
+
+ switch (type) {
+ case MOD_LOAD:
+ if_register_com_alloc(IFT_ETHER, ether_alloc, ether_free);
+ break;
+ case MOD_UNLOAD:
+ if_deregister_com_alloc(IFT_ETHER);
+ break;
+ default:
+ return EOPNOTSUPP;
+ }
+
+ return (0);
+}
+
static moduledata_t ether_mod = {
"ether",
- NULL,
+ ether_modevent,
0
};
-DECLARE_MODULE(ether, ether_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
+DECLARE_MODULE(ether, ether_mod, SI_SUB_INIT_IF, SI_ORDER_ANY);
MODULE_VERSION(ether, 1);
diff --git a/sys/net/if_faith.c b/sys/net/if_faith.c
index 392ff0d..5835811 100644
--- a/sys/net/if_faith.c
+++ b/sys/net/if_faith.c
@@ -83,7 +83,7 @@
#define FAITHNAME "faith"
struct faith_softc {
- struct ifnet sc_if; /* must be first */
+ struct ifnet *sc_ifp;
LIST_ENTRY(faith_softc) sc_list;
};
@@ -165,24 +165,29 @@ faith_clone_create(ifc, unit)
struct if_clone *ifc;
int unit;
{
+ struct ifnet *ifp;
struct faith_softc *sc;
sc = malloc(sizeof(struct faith_softc), M_FAITH, M_WAITOK | M_ZERO);
+ ifp = sc->sc_ifp = if_alloc(IFT_FAITH);
+ if (ifp == NULL) {
+ free(sc, M_FAITH);
+ return (ENOSPC);
+ }
- sc->sc_if.if_softc = sc;
- if_initname(&sc->sc_if, ifc->ifc_name, unit);
+ ifp->if_softc = sc;
+ if_initname(sc->sc_ifp, ifc->ifc_name, unit);
- sc->sc_if.if_mtu = FAITHMTU;
+ ifp->if_mtu = FAITHMTU;
/* Change to BROADCAST experimentaly to announce its prefix. */
- sc->sc_if.if_flags = /* IFF_LOOPBACK */ IFF_BROADCAST | IFF_MULTICAST;
- sc->sc_if.if_ioctl = faithioctl;
- sc->sc_if.if_output = faithoutput;
- sc->sc_if.if_type = IFT_FAITH;
- sc->sc_if.if_hdrlen = 0;
- sc->sc_if.if_addrlen = 0;
- sc->sc_if.if_snd.ifq_maxlen = ifqmaxlen;
- if_attach(&sc->sc_if);
- bpfattach(&sc->sc_if, DLT_NULL, sizeof(u_int));
+ ifp->if_flags = /* IFF_LOOPBACK */ IFF_BROADCAST | IFF_MULTICAST;
+ ifp->if_ioctl = faithioctl;
+ ifp->if_output = faithoutput;
+ ifp->if_hdrlen = 0;
+ ifp->if_addrlen = 0;
+ ifp->if_snd.ifq_maxlen = ifqmaxlen;
+ if_attach(ifp);
+ bpfattach(ifp, DLT_NULL, sizeof(u_int));
mtx_lock(&faith_mtx);
LIST_INSERT_HEAD(&faith_softc_list, sc, sc_list);
mtx_unlock(&faith_mtx);
@@ -193,8 +198,9 @@ static void
faith_destroy(struct faith_softc *sc)
{
- bpfdetach(&sc->sc_if);
- if_detach(&sc->sc_if);
+ bpfdetach(sc->sc_ifp);
+ if_detach(sc->sc_ifp);
+ if_free(sc->sc_ifp);
free(sc, M_FAITH);
}
@@ -202,7 +208,7 @@ static void
faith_clone_destroy(ifp)
struct ifnet *ifp;
{
- struct faith_softc *sc = (void *) ifp;
+ struct faith_softc *sc = ifp->if_softc;
mtx_lock(&faith_mtx);
LIST_REMOVE(sc, sc_list);
diff --git a/sys/net/if_fddisubr.c b/sys/net/if_fddisubr.c
index 6cc8e20..dd6b451 100644
--- a/sys/net/if_fddisubr.c
+++ b/sys/net/if_fddisubr.c
@@ -308,7 +308,7 @@ fddi_output(ifp, m, dst, rt0)
if (hdrcmplt)
bcopy((caddr_t)esrc, (caddr_t)fh->fddi_shost, FDDI_ADDR_LEN);
else
- bcopy(IFP2AC(ifp)->ac_enaddr, (caddr_t)fh->fddi_shost,
+ bcopy(IFP2ENADDR(ifp), (caddr_t)fh->fddi_shost,
FDDI_ADDR_LEN);
/*
@@ -418,7 +418,7 @@ fddi_input(ifp, m)
* is in promiscuous mode.
*/
if ((ifp->if_flags & IFF_PROMISC) && ((fh->fddi_dhost[0] & 1) == 0) &&
- (bcmp(IFP2AC(ifp)->ac_enaddr, (caddr_t)fh->fddi_dhost,
+ (bcmp(IFP2ENADDR(ifp), (caddr_t)fh->fddi_dhost,
FDDI_ADDR_LEN) != 0))
goto dropanyway;
@@ -585,7 +585,7 @@ fddi_ifattach(ifp, bpf)
sdl = (struct sockaddr_dl *)ifa->ifa_addr;
sdl->sdl_type = IFT_FDDI;
sdl->sdl_alen = ifp->if_addrlen;
- bcopy(IFP2AC(ifp)->ac_enaddr, LLADDR(sdl), ifp->if_addrlen);
+ bcopy(IFP2ENADDR(ifp), LLADDR(sdl), ifp->if_addrlen);
if (bpf)
bpfattach(ifp, DLT_FDDI, FDDI_HDR_LEN);
@@ -638,18 +638,16 @@ fddi_ioctl (ifp, command, data)
*/
case AF_IPX: {
struct ipx_addr *ina;
- struct arpcom *ac;
ina = &(IA_SIPX(ifa)->sipx_addr);
- ac = IFP2AC(ifp);
if (ipx_nullhost(*ina)) {
ina->x_host = *(union ipx_host *)
- ac->ac_enaddr;
+ IFP2ENADDR(ifp);
} else {
bcopy((caddr_t) ina->x_host.c_host,
- (caddr_t) ac->ac_enaddr,
- sizeof(ac->ac_enaddr));
+ (caddr_t) IFP2ENADDR(ifp),
+ ETHER_ADDR_LEN);
}
/*
@@ -668,7 +666,7 @@ fddi_ioctl (ifp, command, data)
struct sockaddr *sa;
sa = (struct sockaddr *) & ifr->ifr_data;
- bcopy(IFP2AC(ifp)->ac_enaddr,
+ bcopy(IFP2ENADDR(ifp),
(caddr_t) sa->sa_data, FDDI_ADDR_LEN);
}
diff --git a/sys/net/if_fwsubr.c b/sys/net/if_fwsubr.c
index 7cbd7ac..b3884b5 100644
--- a/sys/net/if_fwsubr.c
+++ b/sys/net/if_fwsubr.c
@@ -40,6 +40,7 @@
#include <sys/mac.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
+#include <sys/module.h>
#include <sys/socket.h>
#include <sys/sockio.h>
@@ -63,6 +64,8 @@
#define IFP2FC(IFP) ((struct fw_com *)IFP)
+MALLOC_DEFINE(M_FWCOM, "fw_com", "firewire interface internals");
+
struct fw_hwaddr firewire_broadcastaddr = {
0xffffffff,
0xffffffff,
@@ -76,7 +79,7 @@ static int
firewire_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
struct rtentry *rt0)
{
- struct fw_com *fc = (struct fw_com *) ifp;
+ struct fw_com *fc = IFP2FC(ifp);
int error, type;
struct rtentry *rt;
struct m_tag *mtag;
@@ -167,7 +170,7 @@ firewire_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
#ifdef INET6
case AF_INET6:
if (unicast) {
- error = nd6_storelladdr(&fc->fc_if, rt, m, dst,
+ error = nd6_storelladdr(fc->fc_ifp, rt, m, dst,
(u_char *) destfw);
if (error)
return (error);
@@ -492,7 +495,7 @@ bad:
void
firewire_input(struct ifnet *ifp, struct mbuf *m, uint16_t src)
{
- struct fw_com *fc = (struct fw_com *) ifp;
+ struct fw_com *fc = IFP2FC(ifp);
union fw_encap *enc;
int type, isr;
@@ -740,7 +743,7 @@ firewire_resolvemulti(struct ifnet *ifp, struct sockaddr **llsa,
void
firewire_ifattach(struct ifnet *ifp, struct fw_hwaddr *llc)
{
- struct fw_com *fc = (struct fw_com *) ifp;
+ struct fw_com *fc = IFP2FC(ifp);
struct ifaddr *ifa;
struct sockaddr_dl *sdl;
static const char* speeds[] = {
@@ -751,7 +754,6 @@ firewire_ifattach(struct ifnet *ifp, struct fw_hwaddr *llc)
fc->fc_speed = llc->sspd;
STAILQ_INIT(&fc->fc_frags);
- ifp->if_type = IFT_IEEE1394;
ifp->if_addrlen = sizeof(struct fw_hwaddr);
ifp->if_hdrlen = 0;
if_attach(ifp);
@@ -788,7 +790,7 @@ firewire_ifdetach(struct ifnet *ifp)
void
firewire_busreset(struct ifnet *ifp)
{
- struct fw_com *fc = (struct fw_com *) ifp;
+ struct fw_com *fc = IFP2FC(ifp);
struct fw_reass *r;
struct mbuf *m;
@@ -805,3 +807,49 @@ firewire_busreset(struct ifnet *ifp)
free(r, M_TEMP);
}
}
+
+static void *
+firewire_alloc(u_char type, struct ifnet *ifp)
+{
+ struct fw_com *fc;
+
+ fc = malloc(sizeof(struct fw_com), M_FWCOM, M_WAITOK | M_ZERO);
+ fc->fc_ifp = ifp;
+
+ return (fc);
+}
+
+static void
+firewire_free(void *com, u_char type)
+{
+
+ free(com, M_FWCOM);
+}
+
+static int
+firewire_modevent(module_t mod, int type, void *data)
+{
+
+ switch (type) {
+ case MOD_LOAD:
+ if_register_com_alloc(IFT_IEEE1394,
+ firewire_alloc, firewire_free);
+ break;
+ case MOD_UNLOAD:
+ if_deregister_com_alloc(IFT_IEEE1394);
+ break;
+ default:
+ return (EOPNOTSUPP);
+ }
+
+ return (0);
+}
+
+static moduledata_t firewire_mod = {
+ "firewire",
+ firewire_modevent,
+ 0
+};
+
+DECLARE_MODULE(firewire, firewire_mod, SI_SUB_INIT_IF, SI_ORDER_ANY);
+MODULE_VERSION(firewire, 1);
diff --git a/sys/net/if_gif.c b/sys/net/if_gif.c
index 6d00fd8..4c243b6 100644
--- a/sys/net/if_gif.c
+++ b/sys/net/if_gif.c
@@ -144,9 +144,14 @@ gif_clone_create(ifc, unit)
struct gif_softc *sc;
sc = malloc(sizeof(struct gif_softc), M_GIF, M_WAITOK | M_ZERO);
+ GIF2IFP(sc) = if_alloc(IFT_GIF);
+ if (GIF2IFP(sc) == NULL) {
+ free(sc, M_GIF);
+ return (ENOSPC);
+ }
- sc->gif_if.if_softc = sc;
- if_initname(&sc->gif_if, ifc->ifc_name, unit);
+ GIF2IFP(sc)->if_softc = sc;
+ if_initname(GIF2IFP(sc), ifc->ifc_name, unit);
gifattach0(sc);
@@ -163,27 +168,26 @@ gifattach0(sc)
sc->encap_cookie4 = sc->encap_cookie6 = NULL;
- sc->gif_if.if_addrlen = 0;
- sc->gif_if.if_mtu = GIF_MTU;
- sc->gif_if.if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
+ GIF2IFP(sc)->if_addrlen = 0;
+ GIF2IFP(sc)->if_mtu = GIF_MTU;
+ GIF2IFP(sc)->if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
#if 0
/* turn off ingress filter */
- sc->gif_if.if_flags |= IFF_LINK2;
-#endif
- sc->gif_if.if_ioctl = gif_ioctl;
- sc->gif_if.if_output = gif_output;
- sc->gif_if.if_type = IFT_GIF;
- sc->gif_if.if_snd.ifq_maxlen = IFQ_MAXLEN;
- if_attach(&sc->gif_if);
- bpfattach(&sc->gif_if, DLT_NULL, sizeof(u_int));
+ GIF2IFP(sc)->if_flags |= IFF_LINK2;
+#endif
+ GIF2IFP(sc)->if_ioctl = gif_ioctl;
+ GIF2IFP(sc)->if_output = gif_output;
+ GIF2IFP(sc)->if_snd.ifq_maxlen = IFQ_MAXLEN;
+ if_attach(GIF2IFP(sc));
+ bpfattach(GIF2IFP(sc), DLT_NULL, sizeof(u_int));
if (ng_gif_attach_p != NULL)
- (*ng_gif_attach_p)(&sc->gif_if);
+ (*ng_gif_attach_p)(GIF2IFP(sc));
}
static void
gif_destroy(struct gif_softc *sc)
{
- struct ifnet *ifp = &sc->gif_if;
+ struct ifnet *ifp = GIF2IFP(sc);
int err;
gif_delete_tunnel(ifp);
@@ -204,6 +208,7 @@ gif_destroy(struct gif_softc *sc)
(*ng_gif_detach_p)(ifp);
bpfdetach(ifp);
if_detach(ifp);
+ if_free(ifp);
free(sc, M_GIF);
}
@@ -284,7 +289,7 @@ gif_encapcheck(m, off, proto, arg)
if (sc == NULL)
return 0;
- if ((sc->gif_if.if_flags & IFF_UP) == 0)
+ if ((GIF2IFP(sc)->if_flags & IFF_UP) == 0)
return 0;
/* no physical address */
@@ -339,7 +344,7 @@ gif_output(ifp, m, dst, rt)
struct sockaddr *dst;
struct rtentry *rt; /* added in net2 */
{
- struct gif_softc *sc = (struct gif_softc*)ifp;
+ struct gif_softc *sc = ifp->if_softc;
struct m_tag *mtag;
int error = 0;
int gif_called;
@@ -507,7 +512,7 @@ gif_ioctl(ifp, cmd, data)
u_long cmd;
caddr_t data;
{
- struct gif_softc *sc = (struct gif_softc*)ifp;
+ struct gif_softc *sc = ifp->if_softc;
struct ifreq *ifr = (struct ifreq*)data;
int error = 0, size;
struct sockaddr *dst, *src;
@@ -628,12 +633,12 @@ gif_ioctl(ifp, cmd, data)
break;
}
- error = gif_set_tunnel(&sc->gif_if, src, dst);
+ error = gif_set_tunnel(GIF2IFP(sc), src, dst);
break;
#ifdef SIOCDIFPHYADDR
case SIOCDIFPHYADDR:
- gif_delete_tunnel(&sc->gif_if);
+ gif_delete_tunnel(GIF2IFP(sc));
break;
#endif
@@ -751,7 +756,7 @@ gif_set_tunnel(ifp, src, dst)
struct sockaddr *src;
struct sockaddr *dst;
{
- struct gif_softc *sc = (struct gif_softc *)ifp;
+ struct gif_softc *sc = ifp->if_softc;
struct gif_softc *sc2;
struct sockaddr *osrc, *odst, *sa;
int s;
@@ -860,7 +865,7 @@ void
gif_delete_tunnel(ifp)
struct ifnet *ifp;
{
- struct gif_softc *sc = (struct gif_softc *)ifp;
+ struct gif_softc *sc = ifp->if_softc;
int s;
s = splnet();
diff --git a/sys/net/if_gif.h b/sys/net/if_gif.h
index dc92ae1..831c7f7 100644
--- a/sys/net/if_gif.h
+++ b/sys/net/if_gif.h
@@ -56,7 +56,7 @@ extern void (*ng_gif_attach_p)(struct ifnet *ifp);
extern void (*ng_gif_detach_p)(struct ifnet *ifp);
struct gif_softc {
- struct ifnet gif_if; /* common area - must be at the top */
+ struct ifnet *gif_ifp;
struct sockaddr *gif_psrc; /* Physical src addr */
struct sockaddr *gif_pdst; /* Physical dst addr */
union {
@@ -71,6 +71,7 @@ struct gif_softc {
void *gif_netgraph; /* ng_gif(4) netgraph node info */
LIST_ENTRY(gif_softc) gif_list; /* all gif's are linked */
};
+#define GIF2IFP(sc) ((sc)->gif_ifp)
#define gif_ro gifsc_gifscr.gifscr_ro
#ifdef INET6
diff --git a/sys/net/if_gre.c b/sys/net/if_gre.c
index a2a7831..407784d 100644
--- a/sys/net/if_gre.c
+++ b/sys/net/if_gre.c
@@ -169,24 +169,24 @@ gre_clone_create(ifc, unit)
sc = malloc(sizeof(struct gre_softc), M_GRE, M_WAITOK | M_ZERO);
- if_initname(&sc->sc_if, ifc->ifc_name, unit);
- sc->sc_if.if_softc = sc;
- sc->sc_if.if_snd.ifq_maxlen = IFQ_MAXLEN;
- sc->sc_if.if_type = IFT_TUNNEL;
- sc->sc_if.if_addrlen = 0;
- sc->sc_if.if_hdrlen = 24; /* IP + GRE */
- sc->sc_if.if_mtu = GREMTU;
- sc->sc_if.if_flags = IFF_POINTOPOINT|IFF_MULTICAST;
- sc->sc_if.if_output = gre_output;
- sc->sc_if.if_ioctl = gre_ioctl;
+ if_initname(GRE2IFP(sc), ifc->ifc_name, unit);
+ GRE2IFP(sc)->if_softc = sc;
+ GRE2IFP(sc)->if_snd.ifq_maxlen = IFQ_MAXLEN;
+ GRE2IFP(sc)->if_type = IFT_TUNNEL;
+ GRE2IFP(sc)->if_addrlen = 0;
+ GRE2IFP(sc)->if_hdrlen = 24; /* IP + GRE */
+ GRE2IFP(sc)->if_mtu = GREMTU;
+ GRE2IFP(sc)->if_flags = IFF_POINTOPOINT|IFF_MULTICAST;
+ GRE2IFP(sc)->if_output = gre_output;
+ GRE2IFP(sc)->if_ioctl = gre_ioctl;
sc->g_dst.s_addr = sc->g_src.s_addr = INADDR_ANY;
sc->g_proto = IPPROTO_GRE;
- sc->sc_if.if_flags |= IFF_LINK0;
+ GRE2IFP(sc)->if_flags |= IFF_LINK0;
sc->encap = NULL;
sc->called = 0;
sc->wccp_ver = WCCP_V1;
- if_attach(&sc->sc_if);
- bpfattach(&sc->sc_if, DLT_NULL, sizeof(u_int32_t));
+ if_attach(GRE2IFP(sc));
+ bpfattach(GRE2IFP(sc), DLT_NULL, sizeof(u_int32_t));
mtx_lock(&gre_mtx);
LIST_INSERT_HEAD(&gre_softc_list, sc, sc_list);
mtx_unlock(&gre_mtx);
@@ -201,8 +201,9 @@ gre_destroy(struct gre_softc *sc)
if (sc->encap != NULL)
encap_detach(sc->encap);
#endif
- bpfdetach(&sc->sc_if);
- if_detach(&sc->sc_if);
+ bpfdetach(GRE2IFP(sc));
+ if_detach(GRE2IFP(sc));
+ if_free(GRE2IFP(sc));
free(sc, M_GRE);
}
@@ -239,7 +240,7 @@ gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
*/
if (++(sc->called) > max_gre_nesting) {
printf("%s: gre_output: recursively called too many "
- "times(%d)\n", if_name(&sc->sc_if), sc->called);
+ "times(%d)\n", if_name(GRE2IFP(sc)), sc->called);
m_freem(m);
error = EIO; /* is there better errno? */
goto end;
@@ -444,7 +445,7 @@ gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
ifp->if_mtu = ifr->ifr_mtu;
break;
case SIOCGIFMTU:
- ifr->ifr_mtu = sc->sc_if.if_mtu;
+ ifr->ifr_mtu = GRE2IFP(sc)->if_mtu;
break;
case SIOCADDMULTI:
case SIOCDELMULTI:
@@ -524,7 +525,7 @@ gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
&in_gre_protosw : &in_mobile_protosw, sc);
if (sc->encap == NULL)
printf("%s: unable to attach encap\n",
- if_name(&sc->sc_if));
+ if_name(GRE2IFP(sc)));
#endif
if (sc->route.ro_rt != 0) /* free old route */
RTFREE(sc->route.ro_rt);
@@ -670,7 +671,7 @@ gre_compute_route(struct gre_softc *sc)
* but this is not possible. Should work though. XXX
* there is a simpler way ...
*/
- if ((sc->sc_if.if_flags & IFF_LINK1) == 0) {
+ if ((GRE2IFP(sc)->if_flags & IFF_LINK1) == 0) {
a = ntohl(sc->g_dst.s_addr);
b = a & 0x01;
c = a & 0xfffffffe;
@@ -681,7 +682,7 @@ gre_compute_route(struct gre_softc *sc)
}
#ifdef DIAGNOSTIC
- printf("%s: searching for a route to %s", if_name(&sc->sc_if),
+ printf("%s: searching for a route to %s", if_name(GRE2IFP(sc)),
inet_ntoa(((struct sockaddr_in *)&ro->ro_dst)->sin_addr));
#endif
@@ -705,7 +706,7 @@ gre_compute_route(struct gre_softc *sc)
* now change it back - else ip_output will just drop
* the route and search one to this interface ...
*/
- if ((sc->sc_if.if_flags & IFF_LINK1) == 0)
+ if ((GRE2IFP(sc)->if_flags & IFF_LINK1) == 0)
((struct sockaddr_in *)&ro->ro_dst)->sin_addr = sc->g_dst;
#ifdef DIAGNOSTIC
diff --git a/sys/net/if_gre.h b/sys/net/if_gre.h
index ef9fa4e..6c8e853 100644
--- a/sys/net/if_gre.h
+++ b/sys/net/if_gre.h
@@ -55,7 +55,7 @@ typedef enum {
} wccp_ver_t;
struct gre_softc {
- struct ifnet sc_if;
+ struct ifnet *sc_ifp;
LIST_ENTRY(gre_softc) sc_list;
int gre_unit;
int gre_flags;
@@ -71,6 +71,7 @@ struct gre_softc {
wccp_ver_t wccp_ver; /* version of the WCCP */
};
+#define GRE2IFP(sc) ((sc)->sc_ifp)
struct gre_h {
diff --git a/sys/net/if_iso88025subr.c b/sys/net/if_iso88025subr.c
index ff88371..d497143 100644
--- a/sys/net/if_iso88025subr.c
+++ b/sys/net/if_iso88025subr.c
@@ -123,7 +123,7 @@ iso88025_ifattach(struct ifnet *ifp, int bpf)
sdl = (struct sockaddr_dl *)ifa->ifa_addr;
sdl->sdl_type = IFT_ISO88025;
sdl->sdl_alen = ifp->if_addrlen;
- bcopy(IFP2AC(ifp)->ac_enaddr, LLADDR(sdl), ifp->if_addrlen);
+ bcopy(IFP2ENADDR(ifp), LLADDR(sdl), ifp->if_addrlen);
if (bpf)
bpfattach(ifp, DLT_IEEE802, ISO88025_HDR_LEN);
@@ -176,17 +176,15 @@ iso88025_ioctl(struct ifnet *ifp, int command, caddr_t data)
*/
case AF_IPX: {
struct ipx_addr *ina;
- struct arpcom *ac;
ina = &(IA_SIPX(ifa)->sipx_addr);
- ac = IFP2AC(ifp);
if (ipx_nullhost(*ina))
ina->x_host = *(union ipx_host *)
- ac->ac_enaddr;
+ IFP2ENADDR(ifp);
else
bcopy((caddr_t) ina->x_host.c_host,
- (caddr_t) ac->ac_enaddr,
+ (caddr_t) IFP2ENADDR(ifp),
ISO88025_ADDR_LEN);
/*
@@ -206,7 +204,7 @@ iso88025_ioctl(struct ifnet *ifp, int command, caddr_t data)
struct sockaddr *sa;
sa = (struct sockaddr *) & ifr->ifr_data;
- bcopy(IFP2AC(ifp)->ac_enaddr,
+ bcopy(IFP2ENADDR(ifp),
(caddr_t) sa->sa_data, ISO88025_ADDR_LEN);
}
break;
@@ -272,7 +270,7 @@ iso88025_output(ifp, m, dst, rt0)
/* Generate a generic 802.5 header for the packet */
gen_th.ac = TR_AC;
gen_th.fc = TR_LLC_FRAME;
- (void)memcpy((caddr_t)gen_th.iso88025_shost, IFP2AC(ifp)->ac_enaddr,
+ (void)memcpy((caddr_t)gen_th.iso88025_shost, IFP2ENADDR(ifp),
ISO88025_ADDR_LEN);
if (rif_len) {
gen_th.iso88025_shost[0] |= TR_RII;
@@ -517,7 +515,7 @@ iso88025_input(ifp, m)
*/
if ((ifp->if_flags & IFF_PROMISC) &&
((th->iso88025_dhost[0] & 1) == 0) &&
- (bcmp(IFP2AC(ifp)->ac_enaddr, (caddr_t) th->iso88025_dhost,
+ (bcmp(IFP2ENADDR(ifp), (caddr_t) th->iso88025_dhost,
ISO88025_ADDR_LEN) != 0))
goto dropanyway;
@@ -638,7 +636,6 @@ iso88025_input(ifp, m)
int i;
u_char c;
- ac = IFP2AC(ifp);
c = l->llc_dsap;
if (th->iso88025_shost[0] & TR_RII) { /* XXX */
@@ -648,7 +645,7 @@ iso88025_input(ifp, m)
l->llc_dsap = l->llc_ssap;
l->llc_ssap = c;
if (m->m_flags & (M_BCAST | M_MCAST))
- bcopy((caddr_t)ac->ac_enaddr,
+ bcopy((caddr_t)IFP2ENADDR(ifp),
(caddr_t)th->iso88025_dhost,
ISO88025_ADDR_LEN);
sa.sa_family = AF_UNSPEC;
@@ -774,9 +771,48 @@ iso88025_resolvemulti (ifp, llsa, sa)
return (0);
}
+MALLOC_DEFINE(M_ISO88025, "arpcom", "802.5 interface internals");
+
+static void*
+iso88025_alloc(u_char type, struct ifnet *ifp)
+{
+ struct arpcom *ac;
+
+ ac = malloc(sizeof(struct arpcom), M_ISO88025, M_WAITOK | M_ZERO);
+ ac->ac_ifp = ifp;
+
+ return (ac);
+}
+
+static void
+iso88025_free(void *com, u_char type)
+{
+
+ free(com, M_ISO88025);
+}
+
+static int
+iso88025_modevent(module_t mod, int type, void *data)
+{
+
+ switch (type) {
+ case MOD_LOAD:
+ if_register_com_alloc(IFT_ISO88025, iso88025_alloc,
+ iso88025_free);
+ break;
+ case MOD_UNLOAD:
+ if_deregister_com_alloc(IFT_ISO88025);
+ break;
+ default:
+ return EOPNOTSUPP;
+ }
+
+ return (0);
+}
+
static moduledata_t iso88025_mod = {
"iso88025",
- NULL,
+ iso88025_modevent,
0
};
diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c
index a48ab8c..d10d859 100644
--- a/sys/net/if_loop.c
+++ b/sys/net/if_loop.c
@@ -93,7 +93,7 @@
#define LONAME "lo"
struct lo_softc {
- struct ifnet sc_if; /* network-visible interface */
+ struct ifnet *sc_ifp;
LIST_ENTRY(lo_softc) sc_next;
};
@@ -129,6 +129,7 @@ lo_clone_destroy(ifp)
mtx_unlock(&lo_mtx);
bpfdetach(ifp);
if_detach(ifp);
+ if_free(ifp);
free(sc, M_LO);
}
@@ -137,25 +138,30 @@ lo_clone_create(ifc, unit)
struct if_clone *ifc;
int unit;
{
+ struct ifnet *ifp;
struct lo_softc *sc;
MALLOC(sc, struct lo_softc *, sizeof(*sc), M_LO, M_WAITOK | M_ZERO);
+ ifp = sc->sc_ifp = if_alloc(IFT_LOOP);
+ if (ifp == NULL) {
+ free(sc, M_LO);
+ return (ENOSPC);
+ }
- if_initname(&sc->sc_if, ifc->ifc_name, unit);
- sc->sc_if.if_mtu = LOMTU;
- sc->sc_if.if_flags = IFF_LOOPBACK | IFF_MULTICAST;
- sc->sc_if.if_ioctl = loioctl;
- sc->sc_if.if_output = looutput;
- sc->sc_if.if_type = IFT_LOOP;
- sc->sc_if.if_snd.ifq_maxlen = ifqmaxlen;
- sc->sc_if.if_softc = sc;
- if_attach(&sc->sc_if);
- bpfattach(&sc->sc_if, DLT_NULL, sizeof(u_int));
+ if_initname(ifp, ifc->ifc_name, unit);
+ ifp->if_mtu = LOMTU;
+ ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST;
+ ifp->if_ioctl = loioctl;
+ ifp->if_output = looutput;
+ ifp->if_snd.ifq_maxlen = ifqmaxlen;
+ ifp->if_softc = sc;
+ if_attach(ifp);
+ bpfattach(ifp, DLT_NULL, sizeof(u_int));
mtx_lock(&lo_mtx);
LIST_INSERT_HEAD(&lo_list, sc, sc_next);
mtx_unlock(&lo_mtx);
if (loif == NULL)
- loif = &sc->sc_if;
+ loif = ifp;
return (0);
}
diff --git a/sys/net/if_ppp.c b/sys/net/if_ppp.c
index cece192..b59ed39 100644
--- a/sys/net/if_ppp.c
+++ b/sys/net/if_ppp.c
@@ -223,26 +223,32 @@ static struct compressor *ppp_compressors[8] = {
static int
ppp_clone_create(struct if_clone *ifc, int unit)
{
+ struct ifnet *ifp;
struct ppp_softc *sc;
sc = malloc(sizeof(struct ppp_softc), M_PPP, M_WAITOK | M_ZERO);
- sc->sc_if.if_softc = sc;
- if_initname(&sc->sc_if, ifc->ifc_name, unit);
- sc->sc_if.if_mtu = PPP_MTU;
- sc->sc_if.if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
- sc->sc_if.if_type = IFT_PPP;
- sc->sc_if.if_hdrlen = PPP_HDRLEN;
- sc->sc_if.if_ioctl = pppsioctl;
- sc->sc_if.if_output = pppoutput;
- sc->sc_if.if_snd.ifq_maxlen = IFQ_MAXLEN;
+ ifp = sc->sc_ifp = if_alloc(IFT_PPP);
+ if (ifp == NULL) {
+ free(sc, M_PPP);
+ return (ENOSPC);
+ }
+
+ ifp->if_softc = sc;
+ if_initname(ifp, ifc->ifc_name, unit);
+ ifp->if_mtu = PPP_MTU;
+ ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
+ ifp->if_hdrlen = PPP_HDRLEN;
+ ifp->if_ioctl = pppsioctl;
+ ifp->if_output = pppoutput;
+ ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
sc->sc_inq.ifq_maxlen = IFQ_MAXLEN;
sc->sc_fastq.ifq_maxlen = IFQ_MAXLEN;
sc->sc_rawq.ifq_maxlen = IFQ_MAXLEN;
mtx_init(&sc->sc_inq.ifq_mtx, "ppp_inq", NULL, MTX_DEF);
mtx_init(&sc->sc_fastq.ifq_mtx, "ppp_fastq", NULL, MTX_DEF);
mtx_init(&sc->sc_rawq.ifq_mtx, "ppp_rawq", NULL, MTX_DEF);
- if_attach(&sc->sc_if);
- bpfattach(&sc->sc_if, DLT_PPP, PPP_HDRLEN);
+ if_attach(ifp);
+ bpfattach(ifp, DLT_PPP, PPP_HDRLEN);
PPP_LIST_LOCK();
LIST_INSERT_HEAD(&ppp_softc_list, sc, sc_list);
@@ -256,9 +262,10 @@ ppp_destroy(struct ppp_softc *sc)
{
struct ifnet *ifp;
- ifp = &sc->sc_if;
+ ifp = PPP2IFP(sc);
bpfdetach(ifp);
if_detach(ifp);
+ if_free(ifp);
mtx_destroy(&sc->sc_rawq.ifq_mtx);
mtx_destroy(&sc->sc_fastq.ifq_mtx);
mtx_destroy(&sc->sc_inq.ifq_mtx);
@@ -396,9 +403,9 @@ pppdealloc(sc)
{
struct mbuf *m;
- if_down(&sc->sc_if);
- sc->sc_if.if_flags &= ~(IFF_UP|IFF_RUNNING);
- getmicrotime(&sc->sc_if.if_lastchange);
+ if_down(PPP2IFP(sc));
+ PPP2IFP(sc)->if_flags &= ~(IFF_UP|IFF_RUNNING);
+ getmicrotime(&PPP2IFP(sc)->if_lastchange);
sc->sc_devp = NULL;
sc->sc_xfer = 0;
IF_DRAIN(&sc->sc_rawq);
@@ -467,7 +474,7 @@ pppioctl(sc, cmd, data, flag, td)
break;
case PPPIOCGUNIT:
- *(int *)data = sc->sc_if.if_dunit;
+ *(int *)data = PPP2IFP(sc)->if_dunit;
break;
case PPPIOCGFLAGS:
@@ -547,7 +554,7 @@ pppioctl(sc, cmd, data, flag, td)
sc->sc_xc_state = (*cp)->comp_alloc(ccp_option, nb);
if (sc->sc_xc_state == NULL) {
if (sc->sc_flags & SC_DEBUG)
- if_printf(&sc->sc_if, "comp_alloc failed\n");
+ if_printf(PPP2IFP(sc), "comp_alloc failed\n");
error = ENOBUFS;
}
splimp();
@@ -561,7 +568,7 @@ pppioctl(sc, cmd, data, flag, td)
sc->sc_rc_state = (*cp)->decomp_alloc(ccp_option, nb);
if (sc->sc_rc_state == NULL) {
if (sc->sc_flags & SC_DEBUG)
- if_printf(&sc->sc_if, "decomp_alloc failed\n");
+ if_printf(PPP2IFP(sc), "decomp_alloc failed\n");
error = ENOBUFS;
}
splimp();
@@ -571,7 +578,7 @@ pppioctl(sc, cmd, data, flag, td)
break;
}
if (sc->sc_flags & SC_DEBUG)
- if_printf(&sc->sc_if, "no compressor for [%x %x %x], %x\n",
+ if_printf(PPP2IFP(sc), "no compressor for [%x %x %x], %x\n",
ccp_option[0], ccp_option[1], ccp_option[2], nb);
error = EINVAL; /* no handler found */
break;
@@ -724,14 +731,14 @@ pppsioctl(ifp, cmd, data)
if (ifr->ifr_mtu > PPP_MAXMTU)
error = EINVAL;
else {
- sc->sc_if.if_mtu = ifr->ifr_mtu;
+ PPP2IFP(sc)->if_mtu = ifr->ifr_mtu;
if (sc->sc_setmtu)
(*sc->sc_setmtu)(sc);
}
break;
case SIOCGIFMTU:
- ifr->ifr_mtu = sc->sc_if.if_mtu;
+ ifr->ifr_mtu = PPP2IFP(sc)->if_mtu;
break;
case SIOCADDMULTI:
@@ -959,7 +966,7 @@ pppoutput(ifp, m0, dst, rtp)
if (_IF_QFULL(ifq) && dst->sa_family != AF_UNSPEC) {
_IF_DROP(ifq);
IF_UNLOCK(ifq);
- sc->sc_if.if_oerrors++;
+ PPP2IFP(sc)->if_oerrors++;
sc->sc_stats.ppp_oerrors++;
error = ENOBUFS;
goto bad;
@@ -1010,9 +1017,9 @@ ppp_requeue(sc)
*mpp = m->m_nextpkt;
m->m_nextpkt = NULL;
ifq = (m->m_flags & M_HIGHPRI)? &sc->sc_fastq:
- (struct ifqueue *)&sc->sc_if.if_snd;
+ (struct ifqueue *)&PPP2IFP(sc)->if_snd;
if (! IF_HANDOFF(ifq, m, NULL)) {
- sc->sc_if.if_oerrors++;
+ PPP2IFP(sc)->if_oerrors++;
sc->sc_stats.ppp_oerrors++;
}
break;
@@ -1067,7 +1074,7 @@ ppp_dequeue(sc)
*/
IF_DEQUEUE(&sc->sc_fastq, m);
if (m == NULL)
- IF_DEQUEUE(&sc->sc_if.if_snd, m);
+ IF_DEQUEUE(&PPP2IFP(sc)->if_snd, m);
if (m == NULL)
return NULL;
@@ -1137,7 +1144,7 @@ ppp_dequeue(sc)
slen = m_length(m, NULL);
clen = (*sc->sc_xcomp->compress)
- (sc->sc_xc_state, &mcomp, m, slen, sc->sc_if.if_mtu + PPP_HDRLEN);
+ (sc->sc_xc_state, &mcomp, m, slen, PPP2IFP(sc)->if_mtu + PPP_HDRLEN);
if (mcomp != NULL) {
if (sc->sc_flags & SC_CCP_UP) {
/* Send the compressed packet instead of the original. */
@@ -1192,7 +1199,7 @@ pppintr()
LIST_FOREACH(sc, &ppp_softc_list, sc_list) {
s = splimp();
if (!(sc->sc_flags & SC_TBUSY)
- && (sc->sc_if.if_snd.ifq_head || sc->sc_fastq.ifq_head)) {
+ && (PPP2IFP(sc)->if_snd.ifq_head || sc->sc_fastq.ifq_head)) {
sc->sc_flags |= SC_TBUSY;
splx(s);
(*sc->sc_start)(sc);
@@ -1205,7 +1212,7 @@ pppintr()
if (m == NULL)
break;
#ifdef MAC
- mac_create_mbuf_from_ifnet(&sc->sc_if, m);
+ mac_create_mbuf_from_ifnet(PPP2IFP(sc), m);
#endif
ppp_inproc(sc, m);
}
@@ -1273,7 +1280,7 @@ ppp_ccp(sc, m, rcvd)
if (sc->sc_xc_state != NULL
&& (*sc->sc_xcomp->comp_init)
(sc->sc_xc_state, dp + CCP_HDRLEN, slen - CCP_HDRLEN,
- sc->sc_if.if_dunit, 0, sc->sc_flags & SC_DEBUG)) {
+ PPP2IFP(sc)->if_dunit, 0, sc->sc_flags & SC_DEBUG)) {
s = splimp();
sc->sc_flags |= SC_COMP_RUN;
splx(s);
@@ -1283,7 +1290,7 @@ ppp_ccp(sc, m, rcvd)
if (sc->sc_rc_state != NULL
&& (*sc->sc_rcomp->decomp_init)
(sc->sc_rc_state, dp + CCP_HDRLEN, slen - CCP_HDRLEN,
- sc->sc_if.if_dunit, 0, sc->sc_mru,
+ PPP2IFP(sc)->if_dunit, 0, sc->sc_mru,
sc->sc_flags & SC_DEBUG)) {
s = splimp();
sc->sc_flags |= SC_DECOMP_RUN;
@@ -1363,7 +1370,7 @@ ppp_inproc(sc, m)
struct ppp_softc *sc;
struct mbuf *m;
{
- struct ifnet *ifp = &sc->sc_if;
+ struct ifnet *ifp = PPP2IFP(sc);
int isr;
int s, ilen = 0, xlen, proto, rv;
u_char *cp, adrs, ctrl;
@@ -1577,7 +1584,7 @@ ppp_inproc(sc, m)
}
/* See if bpf wants to look at the packet. */
- BPF_MTAP(&sc->sc_if, m);
+ BPF_MTAP(PPP2IFP(sc), m);
isr = -1;
switch (proto) {
@@ -1605,7 +1612,7 @@ ppp_inproc(sc, m)
/*
* IPX packet - take off the ppp header and pass it up to IPX.
*/
- if ((sc->sc_if.if_flags & IFF_UP) == 0
+ if ((PPP2IFP(sc)->if_flags & IFF_UP) == 0
/* XXX: || sc->sc_npmode[NP_IPX] != NPMODE_PASS*/) {
/* interface is down - drop the packet. */
m_freem(m);
@@ -1649,7 +1656,7 @@ ppp_inproc(sc, m)
bad:
if (m)
m_freem(m);
- sc->sc_if.if_ierrors++;
+ PPP2IFP(sc)->if_ierrors++;
sc->sc_stats.ppp_ierrors++;
}
diff --git a/sys/net/if_pppvar.h b/sys/net/if_pppvar.h
index daa263c..f103df5 100644
--- a/sys/net/if_pppvar.h
+++ b/sys/net/if_pppvar.h
@@ -54,7 +54,7 @@
* Structure describing each ppp unit.
*/
struct ppp_softc {
- struct ifnet sc_if; /* network-visible interface */
+ struct ifnet *sc_ifp; /* network-visible interface */
/*hi*/ u_int sc_flags; /* control/status bits; see if_ppp.h */
struct callout_handle sc_ch; /* Used for scheduling timeouts */
void *sc_devp; /* pointer to device-dep structure */
@@ -99,6 +99,7 @@ struct ppp_softc {
int sc_rawin_count; /* # in sc_rawin */
LIST_ENTRY(ppp_softc) sc_list;
};
+#define PPP2IFP(sc) ((sc)->sc_ifp)
struct ppp_softc *pppalloc(pid_t pid);
void pppdealloc(struct ppp_softc *sc);
diff --git a/sys/net/if_sl.c b/sys/net/if_sl.c
index 0617037..a03ba1c 100644
--- a/sys/net/if_sl.c
+++ b/sys/net/if_sl.c
@@ -231,10 +231,10 @@ static size_t st_unit_max = 0;
static int
slisunitfree(int unit)
{
- struct sl_softc *nc;
+ struct sl_softc *sc;
- LIST_FOREACH(nc, &sl_list, sl_next) {
- if (nc->sc_if.if_dunit == unit)
+ LIST_FOREACH(sc, &sl_list, sl_next) {
+ if (SL2IFP(sc)->if_dunit == unit)
return (0);
}
return (1);
@@ -291,6 +291,11 @@ slcreate(void)
struct mbuf *m;
MALLOC(sc, struct sl_softc *, sizeof(*sc), M_SL, M_WAITOK | M_ZERO);
+ sc->sc_ifp = if_alloc(IFT_SLIP);
+ if (sc->sc_ifp == NULL) {
+ free(sc, M_SL);
+ return (NULL);
+ }
m = m_gethdr(M_TRYWAIT, MT_DATA);
if (m != NULL) {
@@ -313,22 +318,21 @@ slcreate(void)
sc->sc_mp = sc->sc_buf;
sl_compress_init(&sc->sc_comp, -1);
- sc->sc_if.if_softc = sc;
- sc->sc_if.if_mtu = SLMTU;
- sc->sc_if.if_flags =
+ SL2IFP(sc)->if_softc = sc;
+ SL2IFP(sc)->if_mtu = SLMTU;
+ SL2IFP(sc)->if_flags =
#ifdef SLIP_IFF_OPTS
SLIP_IFF_OPTS;
#else
IFF_POINTOPOINT | SC_AUTOCOMP | IFF_MULTICAST | IFF_NEEDSGIANT;
#endif
- sc->sc_if.if_type = IFT_SLIP;
- sc->sc_if.if_ioctl = slioctl;
- sc->sc_if.if_output = sloutput;
- sc->sc_if.if_start = slstart;
- sc->sc_if.if_snd.ifq_maxlen = 50;
+ SL2IFP(sc)->if_ioctl = slioctl;
+ SL2IFP(sc)->if_output = sloutput;
+ SL2IFP(sc)->if_start = slstart;
+ SL2IFP(sc)->if_snd.ifq_maxlen = 50;
sc->sc_fastq.ifq_maxlen = 32;
- sc->sc_if.if_linkmib = sc;
- sc->sc_if.if_linkmiblen = sizeof *sc;
+ SL2IFP(sc)->if_linkmib = sc;
+ SL2IFP(sc)->if_linkmiblen = sizeof *sc;
mtx_init(&sc->sc_fastq.ifq_mtx, "sl_fastq", NULL, MTX_DEF);
/*
@@ -341,11 +345,11 @@ slcreate(void)
continue;
break;
}
- if_initname(&sc->sc_if, "sl", unit);
+ if_initname(SL2IFP(sc), "sl", unit);
LIST_INSERT_HEAD(&sl_list, sc, sl_next);
- if_attach(&sc->sc_if);
- bpfattach(&sc->sc_if, DLT_SLIP, SLIP_HDRLEN);
+ if_attach(SL2IFP(sc));
+ bpfattach(SL2IFP(sc), DLT_SLIP, SLIP_HDRLEN);
return sc;
}
@@ -371,7 +375,7 @@ slopen(struct cdev *dev, register struct tty *tp)
tp->t_hotchar = FRAME_END;
sc->sc_ttyp = tp;
- sc->sc_if.if_baudrate = tp->t_ospeed;
+ SL2IFP(sc)->if_baudrate = tp->t_ospeed;
ttyflush(tp, FREAD | FWRITE);
/*
@@ -386,12 +390,12 @@ slopen(struct cdev *dev, register struct tty *tp)
*/
clist_alloc_cblocks(&tp->t_canq, 0, 0);
clist_alloc_cblocks(&tp->t_outq,
- SLIP_HIWAT + 2 * sc->sc_if.if_mtu + 1,
- SLIP_HIWAT + 2 * sc->sc_if.if_mtu + 1);
+ SLIP_HIWAT + 2 * SL2IFP(sc)->if_mtu + 1,
+ SLIP_HIWAT + 2 * SL2IFP(sc)->if_mtu + 1);
clist_alloc_cblocks(&tp->t_rawq, 0, 0);
s = splnet();
- if_up(&sc->sc_if);
+ if_up(SL2IFP(sc));
splx(s);
return (0);
}
@@ -399,8 +403,9 @@ slopen(struct cdev *dev, register struct tty *tp)
static void
sldestroy(struct sl_softc *sc)
{
- bpfdetach(&sc->sc_if);
- if_detach(&sc->sc_if);
+ bpfdetach(SL2IFP(sc));
+ if_detach(SL2IFP(sc));
+ if_free(SL2IFP(sc));
LIST_REMOVE(sc, sl_next);
m_free(sc->sc_mbuf);
mtx_destroy(&sc->sc_fastq.ifq_mtx);
@@ -437,7 +442,7 @@ slclose(struct tty *tp, int flag)
sc->sc_keepalive = 0;
untimeout(sl_keepalive, sc, sc->sc_kahandle);
}
- if_down(&sc->sc_if);
+ if_down(SL2IFP(sc));
sc->sc_ttyp = NULL;
sldestroy(sc);
}
@@ -460,7 +465,7 @@ sltioctl(struct tty *tp, u_long cmd, caddr_t data, int flag,
s = splimp();
switch (cmd) {
case SLIOCGUNIT:
- *(int *)data = sc->sc_if.if_dunit;
+ *(int *)data = SL2IFP(sc)->if_dunit;
break;
case SLIOCSUNIT:
@@ -469,27 +474,27 @@ sltioctl(struct tty *tp, u_long cmd, caddr_t data, int flag,
splx(s);
return (ENXIO);
}
- if (sc->sc_if.if_dunit != unit) {
+ if (SL2IFP(sc)->if_dunit != unit) {
if (!slisunitfree(unit)) {
splx(s);
return (ENXIO);
}
- wasup = sc->sc_if.if_flags & IFF_UP;
- bpfdetach(&sc->sc_if);
- if_detach(&sc->sc_if);
+ wasup = SL2IFP(sc)->if_flags & IFF_UP;
+ bpfdetach(SL2IFP(sc));
+ if_detach(SL2IFP(sc));
LIST_REMOVE(sc, sl_next);
- if_initname(&sc->sc_if, "sl", unit);
+ if_initname(SL2IFP(sc), "sl", unit);
LIST_INSERT_HEAD(&sl_list, sc, sl_next);
- if_attach(&sc->sc_if);
- bpfattach(&sc->sc_if, DLT_SLIP, SLIP_HDRLEN);
+ if_attach(SL2IFP(sc));
+ bpfattach(SL2IFP(sc), DLT_SLIP, SLIP_HDRLEN);
if (wasup)
- if_up(&sc->sc_if);
+ if_up(SL2IFP(sc));
else
- if_down(&sc->sc_if);
+ if_down(SL2IFP(sc));
clist_alloc_cblocks(&tp->t_outq,
- SLIP_HIWAT + 2 * sc->sc_if.if_mtu + 1,
- SLIP_HIWAT + 2 * sc->sc_if.if_mtu + 1);
+ SLIP_HIWAT + 2 * SL2IFP(sc)->if_mtu + 1,
+ SLIP_HIWAT + 2 * SL2IFP(sc)->if_mtu + 1);
}
slmarkstatic(unit);
break;
@@ -559,7 +564,7 @@ sloutput(struct ifnet *ifp, register struct mbuf *m, struct sockaddr *dst,
if (dst->sa_family != AF_INET) {
if_printf(ifp, "af%d not supported\n", dst->sa_family);
m_freem(m);
- sc->sc_if.if_noproto++;
+ SL2IFP(sc)->if_noproto++;
return (EAFNOSUPPORT);
}
@@ -572,17 +577,17 @@ sloutput(struct ifnet *ifp, register struct mbuf *m, struct sockaddr *dst,
return (EHOSTUNREACH);
}
ip = mtod(m, struct ip *);
- if (sc->sc_if.if_flags & SC_NOICMP && ip->ip_p == IPPROTO_ICMP) {
+ if (SL2IFP(sc)->if_flags & SC_NOICMP && ip->ip_p == IPPROTO_ICMP) {
m_freem(m);
return (ENETRESET); /* XXX ? */
}
if (ip->ip_tos & IPTOS_LOWDELAY &&
- !ALTQ_IS_ENABLED(&sc->sc_if.if_snd))
- error = !(IF_HANDOFF(&sc->sc_fastq, m, &sc->sc_if));
+ !ALTQ_IS_ENABLED(&SL2IFP(sc)->if_snd))
+ error = !(IF_HANDOFF(&sc->sc_fastq, m, SL2IFP(sc)));
else
- IFQ_HANDOFF(&sc->sc_if, m, error);
+ IFQ_HANDOFF(SL2IFP(sc), m, error);
if (error) {
- sc->sc_if.if_oerrors++;
+ SL2IFP(sc)->if_oerrors++;
return (ENOBUFS);
}
return (0);
@@ -644,9 +649,9 @@ sltstart(struct tty *tp)
s = splimp();
IF_DEQUEUE(&sc->sc_fastq, m);
if (m)
- sc->sc_if.if_omcasts++; /* XXX */
+ SL2IFP(sc)->if_omcasts++; /* XXX */
else
- IF_DEQUEUE(&sc->sc_if.if_snd, m);
+ IF_DEQUEUE(&SL2IFP(sc)->if_snd, m);
splx(s);
if (m == NULL)
return 0;
@@ -657,7 +662,7 @@ sltstart(struct tty *tp)
* queueing, and the connection id compression will get
* munged when this happens.
*/
- if (sc->sc_if.if_bpf) {
+ if (SL2IFP(sc)->if_bpf) {
/*
* We need to save the TCP/IP header before it's
* compressed. To avoid complicated code, we just
@@ -687,11 +692,11 @@ sltstart(struct tty *tp)
}
ip = mtod(m, struct ip *);
if (ip->ip_v == IPVERSION && ip->ip_p == IPPROTO_TCP) {
- if (sc->sc_if.if_flags & SC_COMPRESS)
+ if (SL2IFP(sc)->if_flags & SC_COMPRESS)
*mtod(m, u_char *) |= sl_compress_tcp(m, ip,
&sc->sc_comp, 1);
}
- if (sc->sc_if.if_bpf && sc->bpfbuf) {
+ if (SL2IFP(sc)->if_bpf && sc->bpfbuf) {
/*
* Put the SLIP pseudo-"link header" in place. The
* compressed header is now at the beginning of the
@@ -699,7 +704,7 @@ sltstart(struct tty *tp)
*/
sc->bpfbuf[SLX_DIR] = SLIPDIR_OUT;
bcopy(mtod(m, caddr_t), &sc->bpfbuf[SLX_CHDR], CHDR_LEN);
- BPF_TAP(&sc->sc_if, sc->bpfbuf, len + SLIP_HDRLEN);
+ BPF_TAP(SL2IFP(sc), sc->bpfbuf, len + SLIP_HDRLEN);
}
/*
@@ -712,7 +717,7 @@ sltstart(struct tty *tp)
*/
if (cfreecount < CLISTRESERVE + SLTMAX) {
m_freem(m);
- sc->sc_if.if_collisions++;
+ SL2IFP(sc)->if_collisions++;
continue;
}
@@ -723,7 +728,7 @@ sltstart(struct tty *tp)
* the line may have been idle for some time.
*/
if (tp->t_outq.c_cc == 0) {
- ++sc->sc_if.if_obytes;
+ ++SL2IFP(sc)->if_obytes;
(void) putc(FRAME_END, &tp->t_outq);
}
@@ -755,7 +760,7 @@ sltstart(struct tty *tp)
if (b_to_q((char *)bp, cp - bp,
&tp->t_outq))
break;
- sc->sc_if.if_obytes += cp - bp;
+ SL2IFP(sc)->if_obytes += cp - bp;
}
/*
* If there are characters left in the mbuf,
@@ -771,7 +776,7 @@ sltstart(struct tty *tp)
(void) unputc(&tp->t_outq);
break;
}
- sc->sc_if.if_obytes += 2;
+ SL2IFP(sc)->if_obytes += 2;
}
}
m = m_free(m);
@@ -787,10 +792,10 @@ sltstart(struct tty *tp)
*/
(void) unputc(&tp->t_outq);
(void) putc(FRAME_END, &tp->t_outq);
- sc->sc_if.if_collisions++;
+ SL2IFP(sc)->if_collisions++;
} else {
- ++sc->sc_if.if_obytes;
- sc->sc_if.if_opackets++;
+ ++SL2IFP(sc)->if_obytes;
+ SL2IFP(sc)->if_opackets++;
}
}
return 0;
@@ -837,7 +842,7 @@ sl_btom(struct sl_softc *sc, register int len)
m->m_len = len;
m->m_pkthdr.len = len;
- m->m_pkthdr.rcvif = &sc->sc_if;
+ m->m_pkthdr.rcvif = SL2IFP(sc);
return (m);
}
@@ -862,9 +867,9 @@ slinput(int c, struct tty *tp)
}
c &= TTY_CHARMASK;
- ++sc->sc_if.if_ibytes;
+ ++SL2IFP(sc)->if_ibytes;
- if (sc->sc_if.if_flags & IFF_DEBUG) {
+ if (SL2IFP(sc)->if_flags & IFF_DEBUG) {
if (c == ABT_ESC) {
/*
* If we have a previous abort, see whether
@@ -917,7 +922,7 @@ slinput(int c, struct tty *tp)
/* less than min length packet - ignore */
goto newpack;
- if (sc->sc_if.if_bpf) {
+ if (SL2IFP(sc)->if_bpf) {
/*
* Save the compressed header, so we
* can tack it on later. Note that we
@@ -941,22 +946,22 @@ slinput(int c, struct tty *tp)
* it's a reasonable packet, decompress it and then
* enable compression. Otherwise, drop it.
*/
- if (sc->sc_if.if_flags & SC_COMPRESS) {
+ if (SL2IFP(sc)->if_flags & SC_COMPRESS) {
len = sl_uncompress_tcp(&sc->sc_buf, len,
(u_int)c, &sc->sc_comp);
if (len <= 0)
goto error;
- } else if ((sc->sc_if.if_flags & SC_AUTOCOMP) &&
+ } else if ((SL2IFP(sc)->if_flags & SC_AUTOCOMP) &&
c == TYPE_UNCOMPRESSED_TCP && len >= 40) {
len = sl_uncompress_tcp(&sc->sc_buf, len,
(u_int)c, &sc->sc_comp);
if (len <= 0)
goto error;
- sc->sc_if.if_flags |= SC_COMPRESS;
+ SL2IFP(sc)->if_flags |= SC_COMPRESS;
} else
goto error;
}
- if (sc->sc_if.if_bpf) {
+ if (SL2IFP(sc)->if_bpf) {
/*
* Put the SLIP pseudo-"link header" in place.
* We couldn't do this any earlier since
@@ -967,21 +972,21 @@ slinput(int c, struct tty *tp)
hp[SLX_DIR] = SLIPDIR_IN;
bcopy(chdr, &hp[SLX_CHDR], CHDR_LEN);
- BPF_TAP(&sc->sc_if, hp, len + SLIP_HDRLEN);
+ BPF_TAP(SL2IFP(sc), hp, len + SLIP_HDRLEN);
}
m = sl_btom(sc, len);
if (m == NULL)
goto error;
- sc->sc_if.if_ipackets++;
+ SL2IFP(sc)->if_ipackets++;
- if ((sc->sc_if.if_flags & IFF_UP) == 0) {
+ if ((SL2IFP(sc)->if_flags & IFF_UP) == 0) {
m_freem(m);
goto newpack;
}
if (netisr_queue(NETISR_IP, m)) { /* (0) on success. */
- sc->sc_if.if_ierrors++;
- sc->sc_if.if_iqdrops++;
+ SL2IFP(sc)->if_ierrors++;
+ SL2IFP(sc)->if_iqdrops++;
}
goto newpack;
}
@@ -995,7 +1000,7 @@ slinput(int c, struct tty *tp)
sc->sc_flags |= SC_ERROR;
error:
- sc->sc_if.if_ierrors++;
+ SL2IFP(sc)->if_ierrors++;
newpack:
sc->sc_mp = sc->sc_buf = sc->sc_ep - SLRMAX;
sc->sc_escape = 0;
@@ -1103,7 +1108,7 @@ sl_outfill(void *chan)
if (sc->sc_outfill && tp != NULL) {
if (sc->sc_flags & SC_OUTWAIT) {
s = splimp ();
- ++sc->sc_if.if_obytes;
+ ++SL2IFP(sc)->if_obytes;
(void) putc(FRAME_END, &tp->t_outq);
(*tp->t_oproc)(tp);
splx (s);
diff --git a/sys/net/if_slvar.h b/sys/net/if_slvar.h
index 2de9533..e6b6d2c 100644
--- a/sys/net/if_slvar.h
+++ b/sys/net/if_slvar.h
@@ -43,7 +43,7 @@
* of sl_softc.)
*/
struct sl_softc {
- struct ifnet sc_if; /* network-visible interface */
+ struct ifnet *sc_ifp; /* network-visible interface */
struct ifqueue sc_fastq; /* interactive output queue */
struct tty *sc_ttyp; /* pointer to tty structure */
struct mbuf *sc_mbuf; /* pointer to mbuf containing buffer */
@@ -67,6 +67,7 @@ struct sl_softc {
LIST_ENTRY(sl_softc) sl_next;
u_char *bpfbuf; /* hang buffer for bpf here */
};
+#define SL2IFP(sc) ((sc)->sc_ifp)
/* internal flags */
#define SC_ERROR 0x0001 /* had an input error */
diff --git a/sys/net/if_sppp.h b/sys/net/if_sppp.h
index 39267ae..97f94b3 100644
--- a/sys/net/if_sppp.h
+++ b/sys/net/if_sppp.h
@@ -136,8 +136,7 @@ struct spppreq {
#ifdef _KERNEL
struct sppp {
- /* NB: pp_if _must_ be first */
- struct ifnet pp_if; /* network interface data */
+ struct ifnet *pp_ifp; /* network interface data */
struct ifqueue pp_fastq; /* fast output queue */
struct ifqueue pp_cpq; /* PPP control protocol queue */
struct sppp *pp_next; /* next interface in keepalive list */
@@ -204,6 +203,8 @@ struct sppp {
void (*if_start) (struct ifnet *);
struct callout ifstart_callout; /* if_start () scheduler */
};
+#define IFP2SP(ifp) ((struct sppp *)(ifp)->if_l2com)
+#define SP2IFP(sp) ((sp)->pp_ifp)
/* bits for pp_flags */
#define PP_KEEPALIVE 0x01 /* use keepalive protocol */
diff --git a/sys/net/if_spppfr.c b/sys/net/if_spppfr.c
index 7989df9..ae4f959 100644
--- a/sys/net/if_spppfr.c
+++ b/sys/net/if_spppfr.c
@@ -159,7 +159,7 @@ struct arp_req {
/* almost every function needs these */
#define STDDCL \
- struct ifnet *ifp = &sp->pp_if; \
+ struct ifnet *ifp = SP2IFP(sp); \
int debug = ifp->if_flags & IFF_DEBUG
static void sppp_fr_arp (struct sppp *sp, struct arp_req *req, u_short addr);
diff --git a/sys/net/if_spppsubr.c b/sys/net/if_spppsubr.c
index d7cf484..b1cd8fe 100644
--- a/sys/net/if_spppsubr.c
+++ b/sys/net/if_spppsubr.c
@@ -198,6 +198,8 @@
#define STATE_ACK_SENT 8
#define STATE_OPENED 9
+MALLOC_DEFINE(M_SPPP, "sppp", "synchronous PPP interface internals");
+
struct ppp_header {
u_char address;
u_char control;
@@ -264,22 +266,22 @@ struct cp {
#define SPPP_LOCK(sp) \
do { \
- if (!((sp)->pp_if.if_flags & IFF_NEEDSGIANT)) \
+ if (!(SP2IFP(sp)->if_flags & IFF_NEEDSGIANT)) \
mtx_lock (&(sp)->mtx); \
} while (0)
#define SPPP_UNLOCK(sp) \
do { \
- if (!((sp)->pp_if.if_flags & IFF_NEEDSGIANT)) \
+ if (!(SP2IFP(sp)->if_flags & IFF_NEEDSGIANT)) \
mtx_unlock (&(sp)->mtx); \
} while (0)
#define SPPP_LOCK_ASSERT(sp) \
do { \
- if (!((sp)->pp_if.if_flags & IFF_NEEDSGIANT)) \
+ if (!(SP2IFP(sp)->if_flags & IFF_NEEDSGIANT)) \
mtx_assert (&(sp)->mtx, MA_OWNED); \
} while (0)
#define SPPP_LOCK_OWNED(sp) \
- (!((sp)->pp_if.if_flags & IFF_NEEDSGIANT) && \
+ (!(SP2IFP(sp)->if_flags & IFF_NEEDSGIANT) && \
mtx_owned (&sp->mtx))
#ifdef INET
@@ -300,7 +302,7 @@ static const u_short interactive_ports[8] = {
/* almost every function needs these */
#define STDDCL \
- struct ifnet *ifp = &sp->pp_if; \
+ struct ifnet *ifp = SP2IFP(sp); \
int debug = ifp->if_flags & IFF_DEBUG
static int sppp_output(struct ifnet *ifp, struct mbuf *m,
@@ -490,13 +492,39 @@ static const struct cp *cps[IDX_COUNT] = {
&chap, /* IDX_CHAP */
};
+static void*
+sppp_alloc(u_char type, struct ifnet *ifp)
+{
+ struct sppp *sp;
+
+ sp = malloc(sizeof(struct sppp), M_SPPP, M_WAITOK | M_ZERO);
+ sp->pp_ifp = ifp;
+
+ return (sp);
+}
+
+static void
+sppp_free(void *com, u_char type)
+{
+
+ free(com, M_SPPP);
+}
+
static int
sppp_modevent(module_t mod, int type, void *unused)
{
switch (type) {
case MOD_LOAD:
+ /*
+ * XXX: should probably be IFT_SPPP, but it's fairly
+ * harmless to allocate struct sppp's for non-sppp
+ * interfaces.
+ */
+
+ if_register_com_alloc(IFT_PPP, sppp_alloc, sppp_free);
break;
case MOD_UNLOAD:
+ /* if_deregister_com_alloc(IFT_PPP); */
return EACCES;
default:
return EOPNOTSUPP;
@@ -523,7 +551,7 @@ sppp_input(struct ifnet *ifp, struct mbuf *m)
{
struct ppp_header *h;
int isr = -1;
- struct sppp *sp = (struct sppp *)ifp;
+ struct sppp *sp = IFP2SP(ifp);
u_char *iphdr;
int hlen, vjlen, do_account = 0;
int debug;
@@ -708,7 +736,7 @@ sppp_input(struct ifnet *ifp, struct mbuf *m)
++ifp->if_noproto;
goto invalid;
case CISCO_KEEPALIVE:
- sppp_cisco_input ((struct sppp*) ifp, m);
+ sppp_cisco_input (sp, m);
m_freem (m);
SPPP_UNLOCK(sp);
return;
@@ -769,7 +797,7 @@ sppp_ifstart_sched(void *dummy)
{
struct sppp *sp = dummy;
- sp->if_start(&sp->pp_if);
+ sp->if_start(SP2IFP(sp));
}
/* if_start () wrapper function. We use it to schedule real if_start () for
@@ -778,7 +806,7 @@ sppp_ifstart_sched(void *dummy)
static void
sppp_ifstart(struct ifnet *ifp)
{
- struct sppp *sp = (struct sppp*) ifp;
+ struct sppp *sp = IFP2SP(ifp);
if (SPPP_LOCK_OWNED(sp)) {
if (callout_pending(&sp->ifstart_callout))
@@ -797,7 +825,7 @@ static int
sppp_output(struct ifnet *ifp, struct mbuf *m,
struct sockaddr *dst, struct rtentry *rt)
{
- struct sppp *sp = (struct sppp*) ifp;
+ struct sppp *sp = IFP2SP(ifp);
struct ppp_header *h;
struct ifqueue *ifq = NULL;
int s, error, rv = 0;
@@ -1039,7 +1067,7 @@ out:
void
sppp_attach(struct ifnet *ifp)
{
- struct sppp *sp = (struct sppp*) ifp;
+ struct sppp *sp = IFP2SP(ifp);
/* Initialize mtx lock */
mtx_init(&sp->mtx, "sppp", MTX_NETWORK_LOCK, MTX_DEF | MTX_RECURSE);
@@ -1050,14 +1078,13 @@ sppp_attach(struct ifnet *ifp)
callout_reset(&sp->keepalive_callout, hz * 10, sppp_keepalive,
(void *)sp);
- sp->pp_if.if_mtu = PP_MTU;
- sp->pp_if.if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
- sp->pp_if.if_type = IFT_PPP;
- sp->pp_if.if_output = sppp_output;
+ ifp->if_mtu = PP_MTU;
+ ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
+ ifp->if_output = sppp_output;
#if 0
sp->pp_flags = PP_KEEPALIVE;
#endif
- sp->pp_if.if_snd.ifq_maxlen = 32;
+ ifp->if_snd.ifq_maxlen = 32;
sp->pp_fastq.ifq_maxlen = 32;
sp->pp_cpq.ifq_maxlen = 20;
sp->pp_loopcnt = 0;
@@ -1095,7 +1122,7 @@ sppp_attach(struct ifnet *ifp)
void
sppp_detach(struct ifnet *ifp)
{
- struct sppp *sp = (struct sppp*) ifp;
+ struct sppp *sp = IFP2SP(ifp);
int i;
KASSERT(mtx_initialized(&sp->mtx), ("sppp mutex is not initialized"));
@@ -1121,9 +1148,9 @@ sppp_detach(struct ifnet *ifp)
static void
sppp_flush_unlocked(struct ifnet *ifp)
{
- struct sppp *sp = (struct sppp*) ifp;
+ struct sppp *sp = IFP2SP(ifp);
- sppp_qflush ((struct ifqueue *)&sp->pp_if.if_snd);
+ sppp_qflush ((struct ifqueue *)&SP2IFP(sp)->if_snd);
sppp_qflush (&sp->pp_fastq);
sppp_qflush (&sp->pp_cpq);
}
@@ -1131,7 +1158,7 @@ sppp_flush_unlocked(struct ifnet *ifp)
void
sppp_flush(struct ifnet *ifp)
{
- struct sppp *sp = (struct sppp*) ifp;
+ struct sppp *sp = IFP2SP(ifp);
SPPP_LOCK(sp);
sppp_flush_unlocked (ifp);
@@ -1144,13 +1171,13 @@ sppp_flush(struct ifnet *ifp)
int
sppp_isempty(struct ifnet *ifp)
{
- struct sppp *sp = (struct sppp*) ifp;
+ struct sppp *sp = IFP2SP(ifp);
int empty, s;
s = splimp();
SPPP_LOCK(sp);
empty = !sp->pp_fastq.ifq_head && !sp->pp_cpq.ifq_head &&
- !sp->pp_if.if_snd.ifq_head;
+ !SP2IFP(sp)->if_snd.ifq_head;
SPPP_UNLOCK(sp);
splx(s);
return (empty);
@@ -1162,7 +1189,7 @@ sppp_isempty(struct ifnet *ifp)
struct mbuf *
sppp_dequeue(struct ifnet *ifp)
{
- struct sppp *sp = (struct sppp*) ifp;
+ struct sppp *sp = IFP2SP(ifp);
struct mbuf *m;
int s;
@@ -1180,7 +1207,7 @@ sppp_dequeue(struct ifnet *ifp)
sp->pp_mode == PP_FR)) {
IF_DEQUEUE(&sp->pp_fastq, m);
if (m == NULL)
- IF_DEQUEUE (&sp->pp_if.if_snd, m);
+ IF_DEQUEUE (&SP2IFP(sp)->if_snd, m);
}
SPPP_UNLOCK(sp);
splx(s);
@@ -1193,7 +1220,7 @@ sppp_dequeue(struct ifnet *ifp)
struct mbuf *
sppp_pick(struct ifnet *ifp)
{
- struct sppp *sp = (struct sppp*)ifp;
+ struct sppp *sp = IFP2SP(ifp);
struct mbuf *m;
int s;
@@ -1206,7 +1233,7 @@ sppp_pick(struct ifnet *ifp)
sp->pp_mode == IFF_CISCO ||
sp->pp_mode == PP_FR))
if ((m = sp->pp_fastq.ifq_head) == NULL)
- m = sp->pp_if.if_snd.ifq_head;
+ m = SP2IFP(sp)->if_snd.ifq_head;
SPPP_UNLOCK(sp);
splx (s);
return (m);
@@ -1219,7 +1246,7 @@ int
sppp_ioctl(struct ifnet *ifp, IOCTL_CMD_T cmd, void *data)
{
struct ifreq *ifr = (struct ifreq*) data;
- struct sppp *sp = (struct sppp*) ifp;
+ struct sppp *sp = IFP2SP(ifp);
int s, rv, going_up, going_down, newmode;
s = splimp();
@@ -2207,7 +2234,7 @@ sppp_lcp_init(struct sppp *sp)
sp->lcp.max_configure = 10;
sp->lcp.max_failure = 10;
callout_init(&sp->ch[IDX_LCP],
- (sp->pp_if.if_flags & IFF_NEEDSGIANT) ? 0 : CALLOUT_MPSAFE);
+ (SP2IFP(sp)->if_flags & IFF_NEEDSGIANT) ? 0 : CALLOUT_MPSAFE);
}
static void
@@ -2902,7 +2929,7 @@ sppp_ipcp_init(struct sppp *sp)
sp->pp_seq[IDX_IPCP] = 0;
sp->pp_rseq[IDX_IPCP] = 0;
callout_init(&sp->ch[IDX_IPCP],
- (sp->pp_if.if_flags & IFF_NEEDSGIANT) ? 0 : CALLOUT_MPSAFE);
+ (SP2IFP(sp)->if_flags & IFF_NEEDSGIANT) ? 0 : CALLOUT_MPSAFE);
}
static void
@@ -2985,7 +3012,7 @@ static int
sppp_ipcp_RCR(struct sppp *sp, struct lcp_header *h, int len)
{
u_char *buf, *r, *p;
- struct ifnet *ifp = &sp->pp_if;
+ struct ifnet *ifp = SP2IFP(sp);
int rlen, origlen, debug = ifp->if_flags & IFF_DEBUG;
u_long hisaddr, desiredaddr;
int gotmyaddr = 0;
@@ -3193,7 +3220,7 @@ static void
sppp_ipcp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len)
{
u_char *buf, *p;
- struct ifnet *ifp = &sp->pp_if;
+ struct ifnet *ifp = SP2IFP(sp);
int debug = ifp->if_flags & IFF_DEBUG;
len -= 4;
@@ -3237,7 +3264,7 @@ static void
sppp_ipcp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len)
{
u_char *buf, *p;
- struct ifnet *ifp = &sp->pp_if;
+ struct ifnet *ifp = SP2IFP(sp);
int debug = ifp->if_flags & IFF_DEBUG;
int desiredcomp;
u_long wantaddr;
@@ -3386,7 +3413,7 @@ sppp_ipv6cp_init(struct sppp *sp)
sp->pp_seq[IDX_IPV6CP] = 0;
sp->pp_rseq[IDX_IPV6CP] = 0;
callout_init(&sp->ch[IDX_IPV6CP],
- (sp->pp_if.if_flags & IFF_NEEDSGIANT) ? 0 : CALLOUT_MPSAFE);
+ (SP2IFP(sp)->if_flags & IFF_NEEDSGIANT) ? 0 : CALLOUT_MPSAFE);
}
static void
@@ -3455,7 +3482,7 @@ static int
sppp_ipv6cp_RCR(struct sppp *sp, struct lcp_header *h, int len)
{
u_char *buf, *r, *p;
- struct ifnet *ifp = &sp->pp_if;
+ struct ifnet *ifp = SP2IFP(sp);
int rlen, origlen, debug = ifp->if_flags & IFF_DEBUG;
struct in6_addr myaddr, desiredaddr, suggestaddr;
int ifidcount;
@@ -3544,7 +3571,7 @@ sppp_ipv6cp_RCR(struct sppp *sp, struct lcp_header *h, int len)
nohisaddr = IN6_IS_ADDR_UNSPECIFIED(&desiredaddr);
desiredaddr.s6_addr16[0] = htons(0xfe80);
- desiredaddr.s6_addr16[1] = htons(sp->pp_if.if_index);
+ desiredaddr.s6_addr16[1] = htons(SP2IFP(sp)->if_index);
if (!collision && !nohisaddr) {
/* no collision, hisaddr known - Conf-Ack */
@@ -3614,7 +3641,7 @@ static void
sppp_ipv6cp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len)
{
u_char *buf, *p;
- struct ifnet *ifp = &sp->pp_if;
+ struct ifnet *ifp = SP2IFP(sp);
int debug = ifp->if_flags & IFF_DEBUG;
len -= 4;
@@ -3659,7 +3686,7 @@ static void
sppp_ipv6cp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len)
{
u_char *buf, *p;
- struct ifnet *ifp = &sp->pp_if;
+ struct ifnet *ifp = SP2IFP(sp);
int debug = ifp->if_flags & IFF_DEBUG;
struct in6_addr suggestaddr;
@@ -3687,7 +3714,7 @@ sppp_ipv6cp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len)
break;
bzero(&suggestaddr, sizeof(suggestaddr));
suggestaddr.s6_addr16[0] = htons(0xfe80);
- suggestaddr.s6_addr16[1] = htons(sp->pp_if.if_index);
+ suggestaddr.s6_addr16[1] = htons(SP2IFP(sp)->if_index);
bcopy(&p[2], &suggestaddr.s6_addr[8], 8);
sp->ipv6cp.opts |= (1 << IPV6CP_OPT_IFID);
@@ -4187,7 +4214,7 @@ sppp_chap_init(struct sppp *sp)
sp->pp_seq[IDX_CHAP] = 0;
sp->pp_rseq[IDX_CHAP] = 0;
callout_init(&sp->ch[IDX_CHAP],
- (sp->pp_if.if_flags & IFF_NEEDSGIANT) ? 0 : CALLOUT_MPSAFE);
+ (SP2IFP(sp)->if_flags & IFF_NEEDSGIANT) ? 0 : CALLOUT_MPSAFE);
}
static void
@@ -4527,9 +4554,9 @@ sppp_pap_init(struct sppp *sp)
sp->pp_seq[IDX_PAP] = 0;
sp->pp_rseq[IDX_PAP] = 0;
callout_init(&sp->ch[IDX_PAP],
- (sp->pp_if.if_flags & IFF_NEEDSGIANT) ? 0 : CALLOUT_MPSAFE);
+ (SP2IFP(sp)->if_flags & IFF_NEEDSGIANT) ? 0 : CALLOUT_MPSAFE);
callout_init(&sp->pap_my_to_ch,
- (sp->pp_if.if_flags & IFF_NEEDSGIANT) ? 0 : CALLOUT_MPSAFE);
+ (SP2IFP(sp)->if_flags & IFF_NEEDSGIANT) ? 0 : CALLOUT_MPSAFE);
}
static void
@@ -4781,7 +4808,7 @@ static void
sppp_keepalive(void *dummy)
{
struct sppp *sp = (struct sppp*)dummy;
- struct ifnet *ifp = &sp->pp_if;
+ struct ifnet *ifp = SP2IFP(sp);
int s;
s = splimp();
@@ -4838,7 +4865,7 @@ out:
void
sppp_get_ip_addrs(struct sppp *sp, u_long *src, u_long *dst, u_long *srcmask)
{
- struct ifnet *ifp = &sp->pp_if;
+ struct ifnet *ifp = SP2IFP(sp);
struct ifaddr *ifa;
struct sockaddr_in *si, *sm;
u_long ssrc, ddst;
@@ -4966,7 +4993,7 @@ static void
sppp_get_ip6_addrs(struct sppp *sp, struct in6_addr *src, struct in6_addr *dst,
struct in6_addr *srcmask)
{
- struct ifnet *ifp = &sp->pp_if;
+ struct ifnet *ifp = SP2IFP(sp);
struct ifaddr *ifa;
struct sockaddr_in6 *si, *sm;
struct in6_addr ssrc, ddst;
diff --git a/sys/net/if_stf.c b/sys/net/if_stf.c
index 6c9c468..072c505 100644
--- a/sys/net/if_stf.c
+++ b/sys/net/if_stf.c
@@ -131,7 +131,7 @@
#define GET_V4(x) ((caddr_t)(&(x)->s6_addr16[1]))
struct stf_softc {
- struct ifnet sc_if; /* common area */
+ struct ifnet *sc_ifp;
union {
struct route __sc_ro4;
struct route_in6 __sc_ro6; /* just for safety */
@@ -140,6 +140,7 @@ struct stf_softc {
const struct encaptab *encap_cookie;
LIST_ENTRY(stf_softc) sc_list; /* all stf's are linked */
};
+#define STF2IFP(sc) ((sc)->sc_ifp)
/*
* All mutable global variables in if_stf.c are protected by stf_mtx.
@@ -214,7 +215,12 @@ stf_clone_create(struct if_clone *ifc, char *name, size_t len)
return (err);
sc = malloc(sizeof(struct stf_softc), M_STF, M_WAITOK | M_ZERO);
- ifp = &sc->sc_if;
+ ifp = sc->sc_ifp = if_alloc(IFT_STF);
+ if (ifp == NULL) {
+ free(sc, M_STF);
+ ifc_free_unit(ifc, unit);
+ return (ENOSPC);
+ }
/*
* Set the name manually rather then using if_initname because
* we don't conform to the default naming convention for interfaces.
@@ -235,7 +241,6 @@ stf_clone_create(struct if_clone *ifc, char *name, size_t len)
ifp->if_mtu = IPV6_MMTU;
ifp->if_ioctl = stf_ioctl;
ifp->if_output = stf_output;
- ifp->if_type = IFT_STF;
ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
if_attach(ifp);
bpfattach(ifp, DLT_NULL, sizeof(u_int));
@@ -252,8 +257,9 @@ stf_destroy(struct stf_softc *sc)
err = encap_detach(sc->encap_cookie);
KASSERT(err == 0, ("Unexpected error detaching encap_cookie"));
- bpfdetach(&sc->sc_if);
- if_detach(&sc->sc_if);
+ bpfdetach(STF2IFP(sc));
+ if_detach(STF2IFP(sc));
+ if_free(STF2IFP(sc));
free(sc, M_STF);
}
@@ -261,7 +267,7 @@ stf_destroy(struct stf_softc *sc)
static int
stf_clone_destroy(struct if_clone *ifc, struct ifnet *ifp)
{
- struct stf_softc *sc = (void *) ifp;
+ struct stf_softc *sc = ifp->if_softc;
mtx_lock(&stf_mtx);
LIST_REMOVE(sc, sc_list);
@@ -332,11 +338,11 @@ stf_encapcheck(m, off, proto, arg)
if (sc == NULL)
return 0;
- if ((sc->sc_if.if_flags & IFF_UP) == 0)
+ if ((STF2IFP(sc)->if_flags & IFF_UP) == 0)
return 0;
/* IFF_LINK0 means "no decapsulation" */
- if ((sc->sc_if.if_flags & IFF_LINK0) != 0)
+ if ((STF2IFP(sc)->if_flags & IFF_LINK0) != 0)
return 0;
if (proto != IPPROTO_IPV6)
@@ -348,7 +354,7 @@ stf_encapcheck(m, off, proto, arg)
if (ip.ip_v != 4)
return 0;
- ia6 = stf_getsrcifa6(&sc->sc_if);
+ ia6 = stf_getsrcifa6(STF2IFP(sc));
if (ia6 == NULL)
return 0;
@@ -440,7 +446,7 @@ stf_output(ifp, m, dst, rt)
}
#endif
- sc = (struct stf_softc*)ifp;
+ sc = ifp->if_softc;
dst6 = (struct sockaddr_in6 *)dst;
/* just in case */
@@ -609,7 +615,7 @@ stf_checkaddr4(sc, in, inifp)
/*
* perform ingress filter
*/
- if (sc && (sc->sc_if.if_flags & IFF_LINK2) == 0 && inifp) {
+ if (sc && (STF2IFP(sc)->if_flags & IFF_LINK2) == 0 && inifp) {
struct sockaddr_in sin;
struct rtentry *rt;
@@ -621,7 +627,7 @@ stf_checkaddr4(sc, in, inifp)
if (!rt || rt->rt_ifp != inifp) {
#if 0
log(LOG_WARNING, "%s: packet from 0x%x dropped "
- "due to ingress filter\n", if_name(&sc->sc_if),
+ "due to ingress filter\n", if_name(STF2IFP(sc)),
(u_int32_t)ntohl(sin.sin_addr.s_addr));
#endif
if (rt)
@@ -684,12 +690,12 @@ in_stf_input(m, off)
sc = (struct stf_softc *)encap_getarg(m);
- if (sc == NULL || (sc->sc_if.if_flags & IFF_UP) == 0) {
+ if (sc == NULL || (STF2IFP(sc)->if_flags & IFF_UP) == 0) {
m_freem(m);
return;
}
- ifp = &sc->sc_if;
+ ifp = STF2IFP(sc);
#ifdef MAC
mac_create_mbuf_from_ifnet(ifp, m);
diff --git a/sys/net/if_tap.c b/sys/net/if_tap.c
index dc76f44..f6ee9b0 100644
--- a/sys/net/if_tap.c
+++ b/sys/net/if_tap.c
@@ -62,6 +62,7 @@
#include <net/if.h>
#include <net/if_arp.h>
#include <net/route.h>
+#include <net/if_types.h>
#include <netinet/in.h>
@@ -191,7 +192,7 @@ tapmodevent(mod, type, data)
SLIST_REMOVE_HEAD(&taphead, tap_next);
mtx_unlock(&tapmtx);
- ifp = &tp->tap_if;
+ ifp = tp->tap_ifp;
TAPDEBUG("detaching %s\n", ifp->if_xname);
@@ -202,6 +203,7 @@ tapmodevent(mod, type, data)
destroy_dev(tp->tap_dev);
s = splimp();
ether_ifdetach(ifp);
+ if_free_type(ifp, IFT_ETHER);
splx(s);
mtx_destroy(&tp->tap_mtx);
@@ -284,6 +286,7 @@ tapcreate(dev)
unsigned short macaddr_hi;
int unit, s;
char *name = NULL;
+ u_char eaddr[6];
dev->si_flags &= ~SI_CHEAPCLONE;
@@ -309,12 +312,14 @@ tapcreate(dev)
/* generate fake MAC address: 00 bd xx xx xx unit_no */
macaddr_hi = htons(0x00bd);
- bcopy(&macaddr_hi, &tp->arpcom.ac_enaddr[0], sizeof(short));
- bcopy(&ticks, &tp->arpcom.ac_enaddr[2], sizeof(long));
- tp->arpcom.ac_enaddr[5] = (u_char)unit;
+ bcopy(&macaddr_hi, eaddr, sizeof(short));
+ bcopy(&ticks, &eaddr[2], sizeof(long));
+ eaddr[5] = (u_char)unit;
/* fill the rest and attach interface */
- ifp = &tp->tap_if;
+ ifp = tp->tap_ifp = if_alloc(IFT_ETHER);
+ if (ifp == NULL)
+ panic("%s%d: can not if_alloc()", name, unit);
ifp->if_softc = tp;
if_initname(ifp, name, unit);
ifp->if_init = tapifinit;
@@ -328,7 +333,7 @@ tapcreate(dev)
tp->tap_dev = dev;
s = splimp();
- ether_ifattach(ifp, tp->arpcom.ac_enaddr);
+ ether_ifattach(ifp, eaddr);
splx(s);
mtx_lock(&tp->tap_mtx);
@@ -379,10 +384,10 @@ tapopen(dev, flag, mode, td)
return (EBUSY);
}
- bcopy(tp->arpcom.ac_enaddr, tp->ether_addr, sizeof(tp->ether_addr));
+ bcopy(IFP2ENADDR(tp->tap_ifp), tp->ether_addr, sizeof(tp->ether_addr));
tp->tap_pid = td->td_proc->p_pid;
tp->tap_flags |= TAP_OPEN;
- ifp = &tp->tap_if;
+ ifp = tp->tap_ifp;
mtx_unlock(&tp->tap_mtx);
s = splimp();
@@ -410,7 +415,7 @@ tapclose(dev, foo, bar, td)
{
struct ifaddr *ifa;
struct tap_softc *tp = dev->si_drv1;
- struct ifnet *ifp = &tp->tap_if;
+ struct ifnet *ifp = tp->tap_ifp;
int s;
/* junk all pending output */
@@ -462,7 +467,7 @@ tapifinit(xtp)
void *xtp;
{
struct tap_softc *tp = (struct tap_softc *)xtp;
- struct ifnet *ifp = &tp->tap_if;
+ struct ifnet *ifp = tp->tap_ifp;
TAPDEBUG("initializing %s\n", ifp->if_xname);
@@ -601,7 +606,7 @@ tapioctl(dev, cmd, data, flag, td)
struct thread *td;
{
struct tap_softc *tp = dev->si_drv1;
- struct ifnet *ifp = &tp->tap_if;
+ struct ifnet *ifp = tp->tap_ifp;
struct tapinfo *tapp = NULL;
int s;
int f;
@@ -723,7 +728,7 @@ tapread(dev, uio, flag)
int flag;
{
struct tap_softc *tp = dev->si_drv1;
- struct ifnet *ifp = &tp->tap_if;
+ struct ifnet *ifp = tp->tap_ifp;
struct mbuf *m = NULL;
int error = 0, len, s;
@@ -797,7 +802,7 @@ tapwrite(dev, uio, flag)
int flag;
{
struct tap_softc *tp = dev->si_drv1;
- struct ifnet *ifp = &tp->tap_if;
+ struct ifnet *ifp = tp->tap_ifp;
struct mbuf *m;
int error = 0;
@@ -843,7 +848,7 @@ tappoll(dev, events, td)
struct thread *td;
{
struct tap_softc *tp = dev->si_drv1;
- struct ifnet *ifp = &tp->tap_if;
+ struct ifnet *ifp = tp->tap_ifp;
int s, revents = 0;
TAPDEBUG("%s polling, minor = %#x\n",
diff --git a/sys/net/if_tapvar.h b/sys/net/if_tapvar.h
index 1017bae..21bac50 100644
--- a/sys/net/if_tapvar.h
+++ b/sys/net/if_tapvar.h
@@ -46,8 +46,7 @@
* Other fields locked by owning subsystems.
*/
struct tap_softc {
- struct arpcom arpcom; /* ethernet common data */
-#define tap_if arpcom.ac_if
+ struct ifnet *tap_ifp;
u_short tap_flags; /* misc flags */
#define TAP_OPEN (1 << 0)
#define TAP_INITED (1 << 1)
diff --git a/sys/net/if_tun.c b/sys/net/if_tun.c
index cd209cb..310ff49 100644
--- a/sys/net/if_tun.c
+++ b/sys/net/if_tun.c
@@ -85,11 +85,12 @@ struct tun_softc {
* being slightly stale informationally.
*/
pid_t tun_pid; /* owning pid */
- struct ifnet tun_if; /* the interface */
+ struct ifnet *tun_ifp; /* the interface */
struct sigio *tun_sigio; /* information for async I/O */
struct selinfo tun_rsel; /* read select */
struct mtx tun_mtx; /* protect mutable softc fields */
};
+#define TUN2IFP(sc) ((sc)->tun_ifp)
#define TUNDEBUG if (tundebug) if_printf
#define TUNNAME "tun"
@@ -169,11 +170,12 @@ tun_destroy(struct tun_softc *tp)
/* Unlocked read. */
KASSERT((tp->tun_flags & TUN_OPEN) == 0,
- ("tununits is out of sync - unit %d", tp->tun_if.if_dunit));
+ ("tununits is out of sync - unit %d", TUN2IFP(tp)->if_dunit));
dev = tp->tun_dev;
- bpfdetach(&tp->tun_if);
- if_detach(&tp->tun_if);
+ bpfdetach(TUN2IFP(tp));
+ if_detach(TUN2IFP(tp));
+ if_free(TUN2IFP(tp));
destroy_dev(dev);
mtx_destroy(&tp->tun_mtx);
free(tp, M_TUN);
@@ -250,6 +252,7 @@ tunstart(struct ifnet *ifp)
selwakeuppri(&tp->tun_rsel, PZERO + 1);
}
+/* XXX: should return an error code so it can fail. */
static void
tuncreate(struct cdev *dev)
{
@@ -266,14 +269,16 @@ tuncreate(struct cdev *dev)
TAILQ_INSERT_TAIL(&tunhead, sc, tun_list);
mtx_unlock(&tunmtx);
- ifp = &sc->tun_if;
+ ifp = sc->tun_ifp = if_alloc(IFT_PPP);
+ if (ifp == NULL)
+ panic("%s%d: failed to if_alloc() interface.\n",
+ TUNNAME, dev2unit(dev));
if_initname(ifp, TUNNAME, dev2unit(dev));
ifp->if_mtu = TUNMTU;
ifp->if_ioctl = tunifioctl;
ifp->if_output = tunoutput;
ifp->if_start = tunstart;
ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
- ifp->if_type = IFT_PPP;
ifp->if_softc = sc;
IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
ifp->if_snd.ifq_drv_maxlen = 0;
@@ -315,7 +320,7 @@ tunopen(struct cdev *dev, int flag, int mode, struct thread *td)
tp->tun_flags |= TUN_OPEN;
mtx_unlock(&tp->tun_mtx);
- ifp = &tp->tun_if;
+ ifp = TUN2IFP(tp);
TUNDEBUG(ifp, "open\n");
return (0);
@@ -333,7 +338,7 @@ tunclose(struct cdev *dev, int foo, int bar, struct thread *td)
int s;
tp = dev->si_drv1;
- ifp = &tp->tun_if;
+ ifp = TUN2IFP(tp);
mtx_lock(&tp->tun_mtx);
tp->tun_flags &= ~TUN_OPEN;
@@ -568,18 +573,18 @@ tunioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td
tunp = (struct tuninfo *)data;
if (tunp->mtu < IF_MINMTU)
return (EINVAL);
- if (tp->tun_if.if_mtu != tunp->mtu
+ if (TUN2IFP(tp)->if_mtu != tunp->mtu
&& (error = suser(td)) != 0)
return (error);
- tp->tun_if.if_mtu = tunp->mtu;
- tp->tun_if.if_type = tunp->type;
- tp->tun_if.if_baudrate = tunp->baudrate;
+ TUN2IFP(tp)->if_mtu = tunp->mtu;
+ TUN2IFP(tp)->if_type = tunp->type;
+ TUN2IFP(tp)->if_baudrate = tunp->baudrate;
break;
case TUNGIFINFO:
tunp = (struct tuninfo *)data;
- tunp->mtu = tp->tun_if.if_mtu;
- tunp->type = tp->tun_if.if_type;
- tunp->baudrate = tp->tun_if.if_baudrate;
+ tunp->mtu = TUN2IFP(tp)->if_mtu;
+ tunp->type = TUN2IFP(tp)->if_type;
+ tunp->baudrate = TUN2IFP(tp)->if_baudrate;
break;
case TUNSDEBUG:
tundebug = *(int *)data;
@@ -613,15 +618,15 @@ tunioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td
break;
case TUNSIFMODE:
/* deny this if UP */
- if (tp->tun_if.if_flags & IFF_UP)
+ if (TUN2IFP(tp)->if_flags & IFF_UP)
return(EBUSY);
switch (*(int *)data & ~IFF_MULTICAST) {
case IFF_POINTOPOINT:
case IFF_BROADCAST:
- tp->tun_if.if_flags &=
+ TUN2IFP(tp)->if_flags &=
~(IFF_BROADCAST|IFF_POINTOPOINT|IFF_MULTICAST);
- tp->tun_if.if_flags |= *(int *)data;
+ TUN2IFP(tp)->if_flags |= *(int *)data;
break;
default:
return(EINVAL);
@@ -644,13 +649,13 @@ tunioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td
break;
case FIONREAD:
s = splimp();
- if (!IFQ_IS_EMPTY(&tp->tun_if.if_snd)) {
+ if (!IFQ_IS_EMPTY(&TUN2IFP(tp)->if_snd)) {
struct mbuf *mb;
- IFQ_LOCK(&tp->tun_if.if_snd);
- IFQ_POLL_NOLOCK(&tp->tun_if.if_snd, mb);
+ IFQ_LOCK(&TUN2IFP(tp)->if_snd);
+ IFQ_POLL_NOLOCK(&TUN2IFP(tp)->if_snd, mb);
for( *(int *)data = 0; mb != 0; mb = mb->m_next)
*(int *)data += mb->m_len;
- IFQ_UNLOCK(&tp->tun_if.if_snd);
+ IFQ_UNLOCK(&TUN2IFP(tp)->if_snd);
} else
*(int *)data = 0;
splx(s);
@@ -685,7 +690,7 @@ static int
tunread(struct cdev *dev, struct uio *uio, int flag)
{
struct tun_softc *tp = dev->si_drv1;
- struct ifnet *ifp = &tp->tun_if;
+ struct ifnet *ifp = TUN2IFP(tp);
struct mbuf *m;
int error=0, len, s;
@@ -741,7 +746,7 @@ static int
tunwrite(struct cdev *dev, struct uio *uio, int flag)
{
struct tun_softc *tp = dev->si_drv1;
- struct ifnet *ifp = &tp->tun_if;
+ struct ifnet *ifp = TUN2IFP(tp);
struct mbuf *m;
int error = 0;
uint32_t family;
@@ -831,7 +836,7 @@ tunpoll(struct cdev *dev, int events, struct thread *td)
{
int s;
struct tun_softc *tp = dev->si_drv1;
- struct ifnet *ifp = &tp->tun_if;
+ struct ifnet *ifp = TUN2IFP(tp);
int revents = 0;
struct mbuf *m;
diff --git a/sys/net/if_types.h b/sys/net/if_types.h
index 1dff5c2..2d25b69 100644
--- a/sys/net/if_types.h
+++ b/sys/net/if_types.h
@@ -249,4 +249,5 @@
#define IFT_PFLOG 0xf6
#define IFT_PFSYNC 0xf7
#define IFT_CARP 0xf8 /* Common Address Redundancy Protocol */
+#define IFT_IPXIP 0xf9
#endif /* !_NET_IF_TYPES_H_ */
diff --git a/sys/net/if_var.h b/sys/net/if_var.h
index b189a70..4b0f421 100644
--- a/sys/net/if_var.h
+++ b/sys/net/if_var.h
@@ -109,27 +109,9 @@ struct ifqueue {
* (Would like to call this struct ``if'', but C isn't PL/1.)
*/
-/*
- * NB: For FreeBSD, it is assumed that each NIC driver's softc starts with
- * one of these structures, typically held within an arpcom structure.
- *
- * struct <foo>_softc {
- * struct arpcom {
- * struct ifnet ac_if;
- * ...
- * } <arpcom> ;
- * ...
- * };
- *
- * The assumption is used in a number of places, including many
- * files in sys/net, device drivers, and sys/dev/mii.c:miibus_attach().
- *
- * Unfortunately devices' softc are opaque, so we depend on this layout
- * to locate the struct ifnet from the softc in the generic code.
- *
- */
struct ifnet {
void *if_softc; /* pointer to driver state */
+ void *if_l2com; /* pointer to protocol bits */
TAILQ_ENTRY(ifnet) if_link; /* all struct ifnets are chained */
char if_xname[IFNAMSIZ]; /* external name (name + unit) */
const char *if_dname; /* driver name */
@@ -628,11 +610,14 @@ extern int if_index;
int if_addmulti(struct ifnet *, struct sockaddr *, struct ifmultiaddr **);
int if_allmulti(struct ifnet *, int);
+struct ifnet* if_alloc(u_char);
void if_attach(struct ifnet *);
int if_delmulti(struct ifnet *, struct sockaddr *);
void if_detach(struct ifnet *);
void if_purgeaddrs(struct ifnet *);
void if_down(struct ifnet *);
+void if_free(struct ifnet *);
+void if_free_type(struct ifnet *, u_char);
void if_initname(struct ifnet *, const char *, int);
void if_link_state_change(struct ifnet *, int);
int if_printf(struct ifnet *, const char *, ...) __printflike(2, 3);
@@ -652,6 +637,11 @@ struct ifaddr *ifaof_ifpforaddr(struct sockaddr *, struct ifnet *);
struct ifmultiaddr *ifmaof_ifpforaddr(struct sockaddr *, struct ifnet *);
int if_simloop(struct ifnet *ifp, struct mbuf *m, int af, int hlen);
+typedef void *if_com_alloc_t(u_char type, struct ifnet *ifp);
+typedef void if_com_free_t(void *com, u_char type);
+void if_register_com_alloc(u_char type, if_com_alloc_t *a, if_com_free_t *f);
+void if_deregister_com_alloc(u_char type);
+
#define IF_LLADDR(ifp) \
LLADDR((struct sockaddr_dl *) ifaddr_byindex((ifp)->if_index)->ifa_addr)
diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c
index 77cc178..f909dbe 100644
--- a/sys/net/if_vlan.c
+++ b/sys/net/if_vlan.c
@@ -76,7 +76,7 @@ struct vlan_mc_entry {
};
struct ifvlan {
- struct arpcom ifv_ac; /* make this an interface */
+ struct ifnet *ifv_ifp;
struct ifnet *ifv_p; /* parent inteface of this vlan */
struct ifv_linkmib {
int ifvm_parent;
@@ -90,7 +90,6 @@ struct ifvlan {
LIST_ENTRY(ifvlan) ifv_list;
int ifv_flags;
};
-#define ifv_if ifv_ac.ac_if
#define ifv_tag ifv_mib.ifvm_tag
#define ifv_encaplen ifv_mib.ifvm_encaplen
#define ifv_mtufudge ifv_mib.ifvm_mtufudge
@@ -244,7 +243,7 @@ vlan_modevent(module_t mod, int type, void *data)
vlan_link_state_p = NULL;
while (!LIST_EMPTY(&ifv_list))
vlan_clone_destroy(&vlan_cloner,
- &LIST_FIRST(&ifv_list)->ifv_if);
+ LIST_FIRST(&ifv_list)->ifv_ifp);
VLAN_LOCK_DESTROY();
break;
default:
@@ -323,6 +322,7 @@ vlan_clone_create(struct if_clone *ifc, char *name, size_t len)
struct ifvlan *ifv;
struct ifnet *ifp;
struct ifnet *p;
+ u_char eaddr[6] = {0,0,0,0,0,0};
if ((p = vlan_clone_match_ethertag(ifc, name, &tag)) != NULL) {
ethertag = 1;
@@ -359,7 +359,12 @@ vlan_clone_create(struct if_clone *ifc, char *name, size_t len)
}
ifv = malloc(sizeof(struct ifvlan), M_VLAN, M_WAITOK | M_ZERO);
- ifp = &ifv->ifv_if;
+ ifp = ifv->ifv_ifp = if_alloc(IFT_ETHER);
+ if (ifp == NULL) {
+ ifc_free_unit(ifc, unit);
+ free(ifv, M_VLAN);
+ return (ENOSPC);
+ }
SLIST_INIT(&ifv->vlan_mc_listhead);
ifp->if_softc = ifv;
@@ -379,7 +384,7 @@ vlan_clone_create(struct if_clone *ifc, char *name, size_t len)
ifp->if_start = vlan_start;
ifp->if_ioctl = vlan_ioctl;
ifp->if_snd.ifq_maxlen = ifqmaxlen;
- ether_ifattach(ifp, ifv->ifv_ac.ac_enaddr);
+ ether_ifattach(ifp, eaddr);
/* Now undo some of the damage... */
ifp->if_baudrate = 0;
ifp->if_type = IFT_L2VLAN;
@@ -402,6 +407,7 @@ vlan_clone_create(struct if_clone *ifc, char *name, size_t len)
vlan_unconfig(ifp);
VLAN_UNLOCK();
ether_ifdetach(ifp);
+ if_free_type(ifp, IFT_ETHER);
free(ifv, M_VLAN);
return (error);
@@ -431,6 +437,7 @@ vlan_clone_destroy(struct if_clone *ifc, struct ifnet *ifp)
VLAN_UNLOCK();
ether_ifdetach(ifp);
+ if_free(ifp);
free(ifv, M_VLAN);
@@ -600,7 +607,7 @@ vlan_input(struct ifnet *ifp, struct mbuf *m)
if (ifp == ifv->ifv_p && tag == ifv->ifv_tag)
break;
- if (ifv == NULL || (ifv->ifv_if.if_flags & IFF_UP) == 0) {
+ if (ifv == NULL || (ifv->ifv_ifp->if_flags & IFF_UP) == 0) {
VLAN_UNLOCK();
m_freem(m);
ifp->if_noproto++;
@@ -626,11 +633,11 @@ vlan_input(struct ifnet *ifp, struct mbuf *m)
m_adj(m, ETHER_VLAN_ENCAP_LEN);
}
- m->m_pkthdr.rcvif = &ifv->ifv_if;
- ifv->ifv_if.if_ipackets++;
+ m->m_pkthdr.rcvif = ifv->ifv_ifp;
+ ifv->ifv_ifp->if_ipackets++;
/* Pass it back through the parent's input routine. */
- (*ifp->if_input)(&ifv->ifv_if, m);
+ (*ifp->if_input)(ifv->ifv_ifp, m);
}
static int
@@ -680,14 +687,14 @@ vlan_config(struct ifvlan *ifv, struct ifnet *p)
}
ifv->ifv_p = p;
- ifv->ifv_if.if_mtu = p->if_mtu - ifv->ifv_mtufudge;
+ ifv->ifv_ifp->if_mtu = p->if_mtu - ifv->ifv_mtufudge;
/*
* Copy only a selected subset of flags from the parent.
* Other flags are none of our business.
*/
- ifv->ifv_if.if_flags = (p->if_flags &
+ ifv->ifv_ifp->if_flags = (p->if_flags &
(IFF_BROADCAST | IFF_MULTICAST | IFF_SIMPLEX | IFF_POINTOPOINT));
- ifv->ifv_if.if_link_state = p->if_link_state;
+ ifv->ifv_ifp->if_link_state = p->if_link_state;
#if 0
/*
@@ -701,27 +708,27 @@ vlan_config(struct ifvlan *ifv, struct ifnet *p)
* assisted checksumming flags.
*/
if (p->if_capabilities & IFCAP_VLAN_HWTAGGING)
- ifv->ifv_if.if_capabilities |= p->if_capabilities & IFCAP_HWCSUM;
+ ifv->ifv_ifpif_capabilities |= p->if_capabilities & IFCAP_HWCSUM;
#endif
/*
* Set up our ``Ethernet address'' to reflect the underlying
* physical interface's.
*/
- ifa1 = ifaddr_byindex(ifv->ifv_if.if_index);
+ ifa1 = ifaddr_byindex(ifv->ifv_ifp->if_index);
ifa2 = ifaddr_byindex(p->if_index);
sdl1 = (struct sockaddr_dl *)ifa1->ifa_addr;
sdl2 = (struct sockaddr_dl *)ifa2->ifa_addr;
sdl1->sdl_type = IFT_ETHER;
sdl1->sdl_alen = ETHER_ADDR_LEN;
bcopy(LLADDR(sdl2), LLADDR(sdl1), ETHER_ADDR_LEN);
- bcopy(LLADDR(sdl2), ifv->ifv_ac.ac_enaddr, ETHER_ADDR_LEN);
+ bcopy(LLADDR(sdl2), IFP2ENADDR(ifv->ifv_ifp), ETHER_ADDR_LEN);
/*
* Configure multicast addresses that may already be
* joined on the vlan device.
*/
- (void)vlan_setmulti(&ifv->ifv_if); /* XXX: VLAN lock held */
+ (void)vlan_setmulti(ifv->ifv_ifp); /* XXX: VLAN lock held */
return (0);
}
@@ -772,17 +779,17 @@ vlan_unconfig(struct ifnet *ifp)
/* Disconnect from parent. */
ifv->ifv_p = NULL;
- ifv->ifv_if.if_mtu = ETHERMTU; /* XXX why not 0? */
+ ifv->ifv_ifp->if_mtu = ETHERMTU; /* XXX why not 0? */
ifv->ifv_flags = 0;
- ifv->ifv_if.if_link_state = LINK_STATE_UNKNOWN;
+ ifv->ifv_ifp->if_link_state = LINK_STATE_UNKNOWN;
/* Clear our MAC address. */
- ifa = ifaddr_byindex(ifv->ifv_if.if_index);
+ ifa = ifaddr_byindex(ifv->ifv_ifp->if_index);
sdl = (struct sockaddr_dl *)ifa->ifa_addr;
sdl->sdl_type = IFT_ETHER;
sdl->sdl_alen = ETHER_ADDR_LEN;
bzero(LLADDR(sdl), ETHER_ADDR_LEN);
- bzero(ifv->ifv_ac.ac_enaddr, ETHER_ADDR_LEN);
+ bzero(IFP2ENADDR(ifv->ifv_ifp), ETHER_ADDR_LEN);
return (0);
}
@@ -819,7 +826,7 @@ vlan_link_state(struct ifnet *ifp, int link)
VLAN_LOCK();
LIST_FOREACH(ifv, &ifv_list, ifv_list) {
if (ifv->ifv_p == ifp)
- if_link_state_change(&ifv->ifv_if,
+ if_link_state_change(ifv->ifv_ifp,
ifv->ifv_p->if_link_state);
}
VLAN_UNLOCK();
@@ -846,7 +853,7 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
switch (ifa->ifa_addr->sa_family) {
#ifdef INET
case AF_INET:
- arp_ifinit(&ifv->ifv_if, ifa);
+ arp_ifinit(ifv->ifv_ifp, ifa);
break;
#endif
default:
@@ -859,7 +866,7 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
struct sockaddr *sa;
sa = (struct sockaddr *) &ifr->ifr_data;
- bcopy(IFP2AC(ifp)->ac_enaddr, (caddr_t)sa->sa_data,
+ bcopy(IFP2ENADDR(ifp), (caddr_t)sa->sa_data,
ETHER_ADDR_LEN);
}
break;
diff --git a/sys/net/ppp_tty.c b/sys/net/ppp_tty.c
index 3c25bab..38647f2 100644
--- a/sys/net/ppp_tty.c
+++ b/sys/net/ppp_tty.c
@@ -207,9 +207,9 @@ pppopen(dev, tp)
sc->sc_setmtu = pppasyncsetmtu;
sc->sc_outm = NULL;
pppgetm(sc);
- sc->sc_if.if_flags |= IFF_RUNNING;
- getmicrotime(&sc->sc_if.if_lastchange);
- sc->sc_if.if_baudrate = tp->t_ospeed;
+ PPP2IFP(sc)->if_flags |= IFF_RUNNING;
+ getmicrotime(&PPP2IFP(sc)->if_lastchange);
+ PPP2IFP(sc)->if_baudrate = tp->t_ospeed;
tp->t_hotchar = PPP_FLAG;
ttyflush(tp, FREAD | FWRITE);
@@ -220,8 +220,8 @@ pppopen(dev, tp)
* We also pass 1 byte tokens through t_canq...
*/
clist_alloc_cblocks(&tp->t_canq, 1, 1);
- clist_alloc_cblocks(&tp->t_outq, sc->sc_if.if_mtu + PPP_HIWAT,
- sc->sc_if.if_mtu + PPP_HIWAT);
+ clist_alloc_cblocks(&tp->t_outq, PPP2IFP(sc)->if_mtu + PPP_HIWAT,
+ PPP2IFP(sc)->if_mtu + PPP_HIWAT);
clist_alloc_cblocks(&tp->t_rawq, 0, 0);
splx(s);
@@ -293,8 +293,8 @@ register struct ppp_softc *sc;
s = spltty();
if (tp != NULL)
- clist_alloc_cblocks(&tp->t_outq, sc->sc_if.if_mtu + PPP_HIWAT,
- sc->sc_if.if_mtu + PPP_HIWAT);
+ clist_alloc_cblocks(&tp->t_outq, PPP2IFP(sc)->if_mtu + PPP_HIWAT,
+ PPP2IFP(sc)->if_mtu + PPP_HIWAT);
splx(s);
}
@@ -379,7 +379,7 @@ pppwrite(tp, uio, flag)
return (EINVAL);
if (sc == NULL)
return EIO;
- if (uio->uio_resid > sc->sc_if.if_mtu + PPP_HDRLEN ||
+ if (uio->uio_resid > PPP2IFP(sc)->if_mtu + PPP_HDRLEN ||
uio->uio_resid < PPP_HDRLEN)
return (EMSGSIZE);
@@ -410,7 +410,7 @@ pppwrite(tp, uio, flag)
m0->m_len -= PPP_HDRLEN;
/* call the upper layer to "transmit" it... */
- error = pppoutput(&sc->sc_if, m0, &dst, (struct rtentry *)0);
+ error = pppoutput(PPP2IFP(sc), m0, &dst, (struct rtentry *)0);
splx(s);
return (error);
}
@@ -576,7 +576,7 @@ pppasyncstart(sc)
/* Calculate the FCS for the first mbuf's worth. */
sc->sc_outfcs = pppfcs(PPP_INITFCS, mtod(m, u_char *), m->m_len);
- getmicrotime(&sc->sc_if.if_lastchange);
+ getmicrotime(&PPP2IFP(sc)->if_lastchange);
}
for (;;) {
@@ -839,14 +839,14 @@ pppinput(c, tp)
if ((tp->t_state & TS_CONNECTED) == 0) {
if (sc->sc_flags & SC_DEBUG)
- if_printf(&sc->sc_if, "no carrier\n");
+ if_printf(PPP2IFP(sc), "no carrier\n");
goto flush;
}
if (c & TTY_ERRORMASK) {
/* framing error or overrun on this char - abort packet */
if (sc->sc_flags & SC_DEBUG)
- if_printf(&sc->sc_if, "line error %x\n", c & TTY_ERRORMASK);
+ if_printf(PPP2IFP(sc), "line error %x\n", c & TTY_ERRORMASK);
goto flush;
}
@@ -902,9 +902,9 @@ pppinput(c, tp)
sc->sc_flags |= SC_PKTLOST; /* note the dropped packet */
if ((sc->sc_flags & (SC_FLUSH | SC_ESCAPED)) == 0){
if (sc->sc_flags & SC_DEBUG)
- if_printf(&sc->sc_if, "bad fcs %x, pkt len %d\n",
+ if_printf(PPP2IFP(sc), "bad fcs %x, pkt len %d\n",
sc->sc_fcs, ilen);
- sc->sc_if.if_ierrors++;
+ PPP2IFP(sc)->if_ierrors++;
sc->sc_stats.ppp_ierrors++;
} else
sc->sc_flags &= ~(SC_FLUSH | SC_ESCAPED);
@@ -915,9 +915,9 @@ pppinput(c, tp)
if (ilen < PPP_HDRLEN + PPP_FCSLEN) {
if (ilen) {
if (sc->sc_flags & SC_DEBUG)
- if_printf(&sc->sc_if, "too short (%d)\n", ilen);
+ if_printf(PPP2IFP(sc), "too short (%d)\n", ilen);
s = spltty();
- sc->sc_if.if_ierrors++;
+ PPP2IFP(sc)->if_ierrors++;
sc->sc_stats.ppp_ierrors++;
sc->sc_flags |= SC_PKTLOST;
splx(s);
@@ -987,7 +987,7 @@ pppinput(c, tp)
pppgetm(sc);
if (sc->sc_m == NULL) {
if (sc->sc_flags & SC_DEBUG)
- if_printf(&sc->sc_if, "no input mbufs!\n");
+ if_printf(PPP2IFP(sc), "no input mbufs!\n");
goto flush;
}
}
@@ -1000,7 +1000,7 @@ pppinput(c, tp)
if (c != PPP_ALLSTATIONS) {
if (sc->sc_flags & SC_REJ_COMP_AC) {
if (sc->sc_flags & SC_DEBUG)
- if_printf(&sc->sc_if,
+ if_printf(PPP2IFP(sc),
"garbage received: 0x%x (need 0xFF)\n", c);
goto flush;
}
@@ -1012,7 +1012,7 @@ pppinput(c, tp)
}
if (sc->sc_ilen == 1 && c != PPP_UI) {
if (sc->sc_flags & SC_DEBUG)
- if_printf(&sc->sc_if, "missing UI (0x3), got 0x%x\n", c);
+ if_printf(PPP2IFP(sc), "missing UI (0x3), got 0x%x\n", c);
goto flush;
}
if (sc->sc_ilen == 2 && (c & 1) == 1) {
@@ -1023,7 +1023,7 @@ pppinput(c, tp)
}
if (sc->sc_ilen == 3 && (c & 1) == 0) {
if (sc->sc_flags & SC_DEBUG)
- if_printf(&sc->sc_if, "bad protocol %x\n",
+ if_printf(PPP2IFP(sc), "bad protocol %x\n",
(sc->sc_mp[-1] << 8) + c);
goto flush;
}
@@ -1031,7 +1031,7 @@ pppinput(c, tp)
/* packet beyond configured mru? */
if (++sc->sc_ilen > sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN) {
if (sc->sc_flags & SC_DEBUG)
- if_printf(&sc->sc_if, "packet too big\n");
+ if_printf(PPP2IFP(sc), "packet too big\n");
goto flush;
}
@@ -1042,7 +1042,7 @@ pppinput(c, tp)
pppgetm(sc);
if (m->m_next == NULL) {
if (sc->sc_flags & SC_DEBUG)
- if_printf(&sc->sc_if, "too few input mbufs!\n");
+ if_printf(PPP2IFP(sc), "too few input mbufs!\n");
goto flush;
}
}
@@ -1060,7 +1060,7 @@ pppinput(c, tp)
flush:
if (!(sc->sc_flags & SC_FLUSH)) {
s = spltty();
- sc->sc_if.if_ierrors++;
+ PPP2IFP(sc)->if_ierrors++;
sc->sc_stats.ppp_ierrors++;
sc->sc_flags |= SC_FLUSH;
splx(s);
@@ -1081,7 +1081,7 @@ ppplogchar(sc, c)
sc->sc_rawin[sc->sc_rawin_count++] = c;
if (sc->sc_rawin_count >= sizeof(sc->sc_rawin)
|| (c < 0 && sc->sc_rawin_count > 0)) {
- printf("%s input: %*D", sc->sc_if.if_xname,
+ printf("%s input: %*D", PPP2IFP(sc)->if_xname,
sc->sc_rawin_count, sc->sc_rawin, " ");
sc->sc_rawin_count = 0;
}
OpenPOWER on IntegriCloud