summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorkjc <kjc@FreeBSD.org>1999-05-08 14:23:40 +0000
committerkjc <kjc@FreeBSD.org>1999-05-08 14:23:40 +0000
commit2193f1d43473d72602aedf1ecdcb5552687edc6a (patch)
treee8d66bc24ca2964d1f748747343b92c17b401f26 /sys
parentdda5cbbda41e442bf1eb739214a5c3ac36555d79 (diff)
downloadFreeBSD-src-2193f1d43473d72602aedf1ecdcb5552687edc6a.zip
FreeBSD-src-2193f1d43473d72602aedf1ecdcb5552687edc6a.tar.gz
clean up en atm driver
o fix DDB support - include "opt_ddb.h" - fix Debugger() arg pointed out by bde o back out pvc shadow interface support - it is currently not used - to make it easier to merge another implementation o misc minor cleanup
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/en/midway.c373
-rw-r--r--sys/net/if_atm.h41
-rw-r--r--sys/net/if_atmsubr.c296
3 files changed, 62 insertions, 648 deletions
diff --git a/sys/dev/en/midway.c b/sys/dev/en/midway.c
index 9ce2401..a999ff5 100644
--- a/sys/dev/en/midway.c
+++ b/sys/dev/en/midway.c
@@ -46,32 +46,6 @@
* I would also like to thank Werner for promptly answering email and being
* generally helpful.
*/
-/*
- * 1997/12/02 kjc
- * new features added:
- * - support vc/vp shaping
- * - integrate IPv6 support.
- * - support pvc shadow interface
- * (initial work on per-pvc-interface for ipv6 was done
- * by Katsushi Kobayashi <ikob@cc.uec.ac.jp> of the WIDE Project,
- * extensively modified by kjc.)
- * code cleanup:
- * - remove WMAYBE related code. ENI WMAYBE DMA doen't work.
- * - drop support of FreeBSD-2.1.x and FreeBSD-3.0-SNAP-970124.
- * - remove updating if_lastchange for every packet.
- * - BPF related code is moved to midway.c as it should be.
- * (bpfwrite should work if atm_pseudohdr and LLC/SNAP are
- * prepended.)
- * - BPF link type is changed to DLT_ATM_RFC1483.
- * BPF now understands only LLC/SNAP!! (because bpf can't
- * handle variable link header length.)
- * It is recommended to use LLC/SNAP instead of NULL
- * encapsulation for various reasons. (BPF, IPv6,
- * interoperability, etc.)
- * - altq queue implementation is moved from the driver internal
- * queue to if_snd.
- * - AFMAP related code cleanup.
- */
#undef EN_DEBUG
#undef EN_DEBUG_RANGE /* check ranges on en_read/en_write's? */
@@ -135,6 +109,12 @@
#include "en.h"
#include "opt_inet.h"
#include "opt_natm.h"
+#include "opt_ddb.h"
+/* enable DDBHOOK when DDB is available */
+#undef EN_DDBHOOK
+#ifdef DDB
+#define EN_DDBHOOK 1
+#endif
#endif
#if NEN > 0 || !defined(__FreeBSD__)
@@ -146,6 +126,7 @@
#include <sys/device.h>
#endif
#include <sys/sockio.h>
+#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/proc.h>
@@ -315,14 +296,6 @@ STATIC INLINE int en_sz2b __P((int)) __attribute__ ((unused));
STATIC INLINE void en_write __P((struct en_softc *, u_int32_t,
u_int32_t)) __attribute__ ((unused));
-#ifdef ATM_PVCEXT
-static int en_txctl __P((struct en_softc *, int, int, int));
-static int en_pvctx __P((struct en_softc *, struct pvctxreq *));
-static int en_pvctxget __P((struct en_softc *, struct pvctxreq *));
-static int en_pcr2txspeed __P((int));
-static int en_txspeed2pcr __P((int));
-#endif
-
/*
* macros/inline
*/
@@ -450,10 +423,8 @@ u_int32_t r;
{
#ifdef EN_DEBUG_RANGE
- if (r > MID_MAXOFF || (r % 4)) {
- printf("en_read out of range, r=0x%x\n", r);
- panic("en_read");
- }
+ if (r > MID_MAXOFF || (r % 4))
+ panic("en_read out of range, r=0x%x", r);
#endif
return(bus_space_read_4(sc->en_memt, sc->en_base, r));
@@ -471,10 +442,8 @@ u_int32_t r, v;
{
#ifdef EN_DEBUG_RANGE
- if (r > MID_MAXOFF || (r % 4)) {
- printf("en_write out of range, r=0x%x\n", r);
- panic("en_write");
- }
+ if (r > MID_MAXOFF || (r % 4))
+ panic("en_write out of range, r=0x%x", r);
#endif
bus_space_write_4(sc->en_memt, sc->en_base, r, v);
@@ -1260,34 +1229,6 @@ caddr_t data;
break;
#endif /* SIOCSIFMTU */
-#ifdef ATM_PVCEXT
- case SIOCSPVCTX:
- if ((error = suser(curproc)) == 0)
- error = en_pvctx(sc, (struct pvctxreq *)data);
- break;
-
- case SIOCGPVCTX:
- error = en_pvctxget(sc, (struct pvctxreq *)data);
- break;
-
- case SIOCSPVCSIF:
- do {
- struct ifnet *shadow;
-
- if ((error = suser(curproc)) != 0)
- break;
-
- if ((shadow = pvc_attach(ifp)) != NULL) {
- snprintf(ifr->ifr_name, sizeof(ifr->ifr_name),
- "%s%d", shadow->if_name, shadow->if_unit);
- }
- else
- error = ENOBUFS;
- } while (0);
- break;
-
-#endif /* ATM_PVCEXT */
-
default:
error = EINVAL;
break;
@@ -2019,6 +1960,7 @@ int chan;
struct en_launch launch;
int datalen = 0, dtqneed, len, ncells;
u_int8_t *cp;
+ struct ifnet *ifp;
#ifdef EN_DEBUG
printf("%s: tx%d: starting...\n", sc->sc_dev.dv_xname, chan);
@@ -2162,7 +2104,9 @@ again:
*/
EN_COUNT(sc->launch);
- sc->enif.if_opackets++;
+ ifp = &sc->enif;
+ ifp->if_opackets++;
+
if ((launch.atm_flags & EN_OBHDR) == 0) {
EN_COUNT(sc->lheader);
/* store tbd1/tbd2 in host byte order */
@@ -2177,7 +2121,7 @@ again:
en_txlaunch(sc, chan, &launch);
#if NBPFILTER > 0
- if (sc->enif.if_bpf) {
+ if (ifp->if_bpf) {
/*
* adjust the top of the mbuf to skip the pseudo atm header
* (and TBD, if present) before passing the packet to bpf,
@@ -2190,7 +2134,7 @@ again:
launch.t->m_data += size;
launch.t->m_len -= size;
- BPF_MTAP(&sc->enif, launch.t);
+ BPF_MTAP(ifp, launch.t);
launch.t->m_data -= size;
launch.t->m_len += size;
@@ -2592,6 +2536,7 @@ void *arg;
struct en_softc *sc = (struct en_softc *) arg;
struct mbuf *m;
struct atm_pseudohdr ah;
+ struct ifnet *ifp;
u_int32_t reg, kick, val, mask, chip, vci, slot, dtq, drq;
int lcv, idx, need_softserv = 0;
@@ -2613,7 +2558,11 @@ void *arg;
sc->sc_dev.dv_xname, reg, MID_INTBITS);
#ifdef EN_DEBUG
#ifdef DDB
+#ifdef __FreeBSD__
+ Debugger("en: unexpected error");
+#else
Debugger();
+#endif
#endif /* DDB */
sc->enif.if_flags &= ~IFF_RUNNING; /* FREEZE! */
#else
@@ -2726,10 +2675,9 @@ void *arg;
m = NULL;
} else {
IF_DEQUEUE(&sc->rxslot[slot].indma, m);
- if (!m) {
- printf("%s: lost mbuf in slot %d!\n", sc->sc_dev.dv_xname, slot);
- panic("enintr: drqsync");
- }
+ if (!m)
+ panic("enintr: drqsync: %s: lost mbuf in slot %d!",
+ sc->sc_dev.dv_xname, slot);
}
/* do something with this mbuf */
if (sc->rxslot[slot].oth_flags & ENOTHER_DRAIN) { /* drain? */
@@ -2757,14 +2705,16 @@ void *arg;
sc->sc_dev.dv_xname, slot, sc->rxslot[slot].atm_vci, m,
EN_DQ_LEN(drq), sc->rxslot[slot].rxhand);
#endif
-#if NBPFILTER > 0
- if (sc->enif.if_bpf)
- BPF_MTAP(&sc->enif, m);
-#endif /* NBPFILTER > 0 */
- sc->enif.if_ipackets++;
+ ifp = &sc->enif;
+ ifp->if_ipackets++;
+
+#if NBPFILTER > 0
+ if (ifp->if_bpf)
+ BPF_MTAP(ifp, m);
+#endif
- atm_input(&sc->enif, &ah, m, sc->rxslot[slot].rxhand);
+ atm_input(ifp, &ah, m, sc->rxslot[slot].rxhand);
}
}
@@ -2954,7 +2904,7 @@ defer: /* defer processing */
llc = (aal5 && (sc->rxslot[slot].atm_flags & ATM_PH_LLCSNAP)) ? 1 : 0;
rbd = EN_READ(sc, cur);
if (MID_RBD_ID(rbd) != MID_RBD_STDID)
- panic("en_service: id mismatch\n");
+ panic("en_service: id mismatch");
if (rbd & MID_RBD_T) {
mlen = 0; /* we've got trash */
@@ -2967,6 +2917,8 @@ defer: /* defer processing */
mlen = MID_RBD_SIZE + MID_CHDR_SIZE + MID_ATMDATASZ; /* 1 cell (ick!) */
fill = 0;
} else {
+ struct ifnet *ifp;
+
tlen = (MID_RBD_CNT(rbd) * MID_ATMDATASZ) + MID_RBD_SIZE;
pdu = cur + tlen - MID_PDU_SIZE;
if (pdu >= stop)
@@ -2974,12 +2926,25 @@ defer: /* defer processing */
pdu = EN_READ(sc, pdu); /* get PDU in correct byte order */
fill = tlen - MID_RBD_SIZE - MID_PDU_LEN(pdu);
if (fill < 0 || (rbd & MID_RBD_CRCERR) != 0) {
- printf("%s: %s, dropping frame\n", sc->sc_dev.dv_xname,
- (rbd & MID_RBD_CRCERR) ? "CRC error" : "invalid AAL5 PDU length");
- printf("%s: got %d cells (%d bytes), AAL5 len is %d bytes (pdu=0x%x)\n",
- sc->sc_dev.dv_xname, MID_RBD_CNT(rbd), tlen - MID_RBD_SIZE,
- MID_PDU_LEN(pdu), pdu);
+ static int first = 1;
+
+ if (first) {
+ printf("%s: %s, dropping frame\n", sc->sc_dev.dv_xname,
+ (rbd & MID_RBD_CRCERR) ?
+ "CRC error" : "invalid AAL5 PDU length");
+ printf("%s: got %d cells (%d bytes), AAL5 len is %d bytes (pdu=0x%x)\n",
+ sc->sc_dev.dv_xname, MID_RBD_CNT(rbd),
+ tlen - MID_RBD_SIZE, MID_PDU_LEN(pdu), pdu);
+#ifndef EN_DEBUG
+ printf("CRC error report disabled from now on!\n");
+ first = 0;
+#endif
+ }
fill = tlen;
+
+ ifp = &sc->enif;
+ ifp->if_ierrors++;
+
}
mlen = tlen - fill;
}
@@ -3481,234 +3446,4 @@ int unit, addr, len;
}
#endif
-#ifdef ATM_PVCEXT
-/*
- * ATM PVC extention: shaper control and pvc shadow interfaces
- */
-
-/* txspeed conversion derived from linux drivers/atm/eni.c
- by Werner Almesberger, EPFL LRC */
-static const int pre_div[] = { 4,16,128,2048 };
-
-static int en_pcr2txspeed(pcr)
- int pcr;
-{
- int pre, res, div;
-
- if (pcr == 0 || pcr > 347222)
- pre = res = 0; /* max rate */
- else {
- for (pre = 0; pre < 3; pre++)
- if (25000000/pre_div[pre]/64 <= pcr)
- break;
- div = pre_div[pre]*(pcr);
-#if 1
- /*
- * the shaper value should be rounded down,
- * instead of rounded up.
- * (which means "res" should be rounded up.)
- */
- res = (25000000 + div -1)/div - 1;
-#else
- res = 25000000/div-1;
-#endif
- if (res < 0)
- res = 0;
- if (res > 63)
- res = 63;
- }
- return ((pre << 6) + res);
-}
-
-static int en_txspeed2pcr(txspeed)
- int txspeed;
-{
- int pre, res, pcr;
-
- pre = (txspeed >> 6) & 0x3;
- res = txspeed & 0x3f;
- pcr = 25000000 / pre_div[pre] / (res+1);
- return (pcr);
-}
-
-/*
- * en_txctl selects a hardware transmit channel and sets the shaper value.
- * en_txctl should be called after enabling the vc by en_rxctl
- * since it assumes a transmit channel is already assigned by en_rxctl
- * to the vc.
- */
-static int en_txctl(sc, vci, joint_vci, pcr)
- struct en_softc *sc;
- int vci;
- int joint_vci;
- int pcr;
-{
- int txspeed, txchan, c, s;
-
- if (pcr)
- txspeed = en_pcr2txspeed(pcr);
- else
- txspeed = 0;
-
- s = splimp();
- txchan = sc->txvc2slot[vci];
- sc->txslot[txchan].nref--;
-
- /* select a slot */
- if (joint_vci != 0)
- /* use the same channel */
- txchan = sc->txvc2slot[joint_vci];
- if (pcr == 0)
- txchan = 0;
- else {
- for (c = 1, txchan = 1; c < EN_NTX; c++) {
- if (sc->txslot[c].nref < sc->txslot[txchan].nref)
- txchan = c;
- if (sc->txslot[txchan].nref == 0)
- break;
- }
- }
- sc->txvc2slot[vci] = txchan;
- sc->txslot[txchan].nref++;
-
- /* set the shaper parameter */
- sc->txspeed[vci] = (u_int8_t)txspeed;
-
- splx(s);
-#ifdef EN_DEBUG
- printf("VCI:%d PCR set to %d, tx channel %d\n", vci, pcr, txchan);
- if (joint_vci != 0)
- printf(" slot shared with VCI:%d\n", joint_vci);
-#endif
- return (0);
-}
-
-static int en_pvctx(sc, pvcreq)
- struct en_softc *sc;
- struct pvctxreq *pvcreq;
-{
- struct ifnet *ifp;
- struct atm_pseudoioctl api;
- struct atm_pseudohdr *pvc_aph, *pvc_joint;
- int vci, joint_vci, pcr;
- int error = 0;
-
- /* check vpi:vci values */
- pvc_aph = &pvcreq->pvc_aph;
- pvc_joint = &pvcreq->pvc_joint;
-
- vci = ATM_PH_VCI(pvc_aph);
- joint_vci = ATM_PH_VCI(pvc_joint);
- pcr = pvcreq->pvc_pcr;
-
- if (ATM_PH_VPI(pvc_aph) != 0 || vci >= MID_N_VC ||
- ATM_PH_VPI(pvc_joint) != 0 || joint_vci >= MID_N_VC)
- return (EADDRNOTAVAIL);
-
- if ((ifp = ifunit(pvcreq->pvc_ifname)) == NULL)
- return (ENXIO);
-
- if (pcr < 0) {
- /* negative pcr means disable the vc. */
- if (sc->rxvc2slot[vci] == RX_NONE)
- /* already disabled */
- return 0;
-
- ATM_PH_FLAGS(&api.aph) = 0;
- ATM_PH_VPI(&api.aph) = 0;
- ATM_PH_SETVCI(&api.aph, vci);
- api.rxhand = NULL;
-
- error = en_rxctl(sc, &api, 0);
-
- if (error == 0 && &sc->enif != ifp) {
- /* clear vc info of shadow interface */
- ATM_PH_SETVCI(&api.aph, 0);
- pvc_setaph(ifp, &api.aph);
- }
- return (error);
- }
-
- if (&sc->enif == ifp) {
- /* called for an en interface */
- if (sc->rxvc2slot[vci] == RX_NONE) {
- /* vc is not active */
- printf("%s%d: en_pvctx: rx not active! vci=%d\n",
- ifp->if_name, ifp->if_unit, vci);
- return (EINVAL);
- }
- }
- else {
- /* called for a shadow interface */
- if ((ifp->if_flags & IFF_POINTOPOINT) == 0) {
- printf("en_pvctx: if %s is not point-to-point!\n",
- pvcreq->pvc_ifname);
- return (EINVAL);
- }
- snprintf(pvcreq->pvc_ifname, sizeof(pvcreq->pvc_ifname),
- "%s%d", sc->enif.if_name, sc->enif.if_unit);
-
- ATM_PH_FLAGS(&api.aph) = ATM_PH_PVCSIF |
- (ATM_PH_FLAGS(pvc_aph) & (ATM_PH_AAL5|ATM_PH_LLCSNAP));
- ATM_PH_VPI(&api.aph) = 0;
- ATM_PH_SETVCI(&api.aph, vci);
- api.rxhand = ifp;
- pvc_setaph(ifp, &api.aph);
-
- if (sc->rxvc2slot[vci] == RX_NONE) {
- /* vc is not active, enable rx */
- error = en_rxctl(sc, &api, 1);
- if (error)
- return error;
- }
- else {
- /* vc is already active, update aph in softc */
- sc->rxslot[sc->rxvc2slot[vci]].atm_flags =
- ATM_PH_FLAGS(&api.aph);
- }
-
- }
-
- error = en_txctl(sc, vci, joint_vci, pcr);
-
- if (error == 0) {
- if (sc->txspeed[vci] != 0)
- pvcreq->pvc_pcr = en_txspeed2pcr(sc->txspeed[vci]);
- else
- pvcreq->pvc_pcr = 0;
- }
-
- return error;
-}
-
-static int en_pvctxget(sc, pvcreq)
- struct en_softc *sc;
- struct pvctxreq *pvcreq;
-{
- struct atm_pseudohdr *pvc_aph;
- int vci, slot;
-
- pvc_aph = &pvcreq->pvc_aph;
- vci = ATM_PH_VCI(pvc_aph);
-
- if ((slot = sc->rxvc2slot[vci]) == RX_NONE) {
- /* vc is not active */
- ATM_PH_FLAGS(pvc_aph) = 0;
- pvcreq->pvc_pcr = -1;
- }
- else {
- ATM_PH_FLAGS(pvc_aph) = sc->rxslot[slot].atm_flags;
- ATM_PH_VPI(pvc_aph) = 0;
- ATM_PH_SETVCI(pvc_aph, vci);
- if (sc->txspeed[vci])
- pvcreq->pvc_pcr = en_txspeed2pcr(sc->txspeed[vci]);
- else
- pvcreq->pvc_pcr = 0;
- }
-
- return (0);
-}
-
-#endif /* ATM_PVCEXT */
-
#endif /* NEN > 0 || !defined(__FreeBSD__) */
diff --git a/sys/net/if_atm.h b/sys/net/if_atm.h
index f1e2d8b..16b32a6 100644
--- a/sys/net/if_atm.h
+++ b/sys/net/if_atm.h
@@ -42,14 +42,6 @@
#endif
#endif /* freebsd doesn't define _KERNEL */
-#ifndef NO_ATM_PVCEXT
-/*
- * ATM_PVCEXT enables PVC extention: VP/VC shaping
- * and PVC shadow interfaces.
- */
-#define ATM_PVCEXT /* enable pvc extention */
-#endif
-
#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__)
#define RTALLOC1(A,B) rtalloc1((A),(B))
#elif defined(__FreeBSD__)
@@ -74,9 +66,6 @@ struct atm_pseudohdr {
#define ATM_PH_AAL5 0x01 /* use AAL5? (0 == aal0) */
#define ATM_PH_LLCSNAP 0x02 /* use the LLC SNAP encoding (iff aal5) */
-#ifdef ATM_PVCEXT
-#define ATM_PH_INERNAL 0x20 /* reserve for kernel internal use */
-#endif
#define ATM_PH_DRIVER7 0x40 /* reserve for driver's use */
#define ATM_PH_DRIVER8 0x80 /* reserve for driver's use */
@@ -95,28 +84,6 @@ struct atm_pseudoioctl {
#define SIOCATMENA _IOWR('a', 123, struct atm_pseudoioctl) /* enable */
#define SIOCATMDIS _IOWR('a', 124, struct atm_pseudoioctl) /* disable */
-#ifdef ATM_PVCEXT
-
-/* structure to control PVC transmitter */
-struct pvctxreq {
- /* first entry must be compatible with struct ifreq */
- char pvc_ifname[IFNAMSIZ]; /* if name, e.g. "en0" */
- struct atm_pseudohdr pvc_aph; /* (flags) + vpi:vci */
- struct atm_pseudohdr pvc_joint; /* for vp shaping: another vc
- to share the shaper */
- int pvc_pcr; /* peak cell rate (shaper value) */
-};
-
-/* use ifioctl for now */
-#define SIOCSPVCTX _IOWR('i', 95, struct pvctxreq)
-#define SIOCGPVCTX _IOWR('i', 96, struct pvctxreq)
-#define SIOCSPVCSIF _IOWR('i', 97, struct ifreq)
-#define SIOCGPVCSIF _IOWR('i', 98, struct ifreq)
-
-#ifdef _KERNEL
-#define ATM_PH_PVCSIF ATM_PH_INERNAL /* pvc shadow interface */
-#endif
-#endif /* ATM_PVCEXT */
/*
* XXX forget all the garbage in if_llc.h and do it the easy way
@@ -142,10 +109,4 @@ void atm_input __P((struct ifnet *, struct atm_pseudohdr *,
int atm_output __P((struct ifnet *, struct mbuf *, struct sockaddr *,
struct rtentry *));
#endif
-#ifdef ATM_PVCEXT
-char *shadow2if __P((char *));
-#ifdef _KERNEL
-struct ifnet *pvc_attach __P((struct ifnet *));
-int pvc_setaph __P((struct ifnet *, struct atm_pseudohdr *));
-#endif
-#endif
+
diff --git a/sys/net/if_atmsubr.c b/sys/net/if_atmsubr.c
index 9f56a9b..66cd09d 100644
--- a/sys/net/if_atmsubr.c
+++ b/sys/net/if_atmsubr.c
@@ -139,6 +139,10 @@ atm_output(ifp, m0, dst, rt0)
#if defined(INET) || defined(INET6)
case AF_INET:
case AF_INET6:
+ if (dst->sa_family == AF_INET6)
+ etype = htons(ETHERTYPE_IPV6);
+ else
+ etype = htons(ETHERTYPE_IP);
if (!atmresolve(rt, m, dst, &atmdst)) {
m = NULL;
/* XXX: atmresolve already free'd it */
@@ -146,18 +150,13 @@ atm_output(ifp, m0, dst, rt0)
/* XXX: put ATMARP stuff here */
/* XXX: watch who frees m on failure */
}
- if (dst->sa_family == AF_INET6)
- etype = htons(ETHERTYPE_IPV6);
- else
- etype = htons(ETHERTYPE_IP);
break;
#endif /* INET || INET6 */
case AF_UNSPEC:
/*
- * XXX: bpfwrite or output from a pvc shadow if.
- * assuming dst contains 12 bytes (atm pseudo
- * header (4) + LLC/SNAP (8))
+ * XXX: bpfwrite. assuming dst contains 12 bytes
+ * (atm pseudo header (4) + LLC/SNAP (8))
*/
bcopy(dst->sa_data, &atmdst, sizeof(atmdst));
llc_hdr = (struct atmllc *)(dst->sa_data + sizeof(atmdst));
@@ -242,18 +241,6 @@ atm_input(ifp, ah, m, rxhand)
}
ifp->if_ibytes += m->m_pkthdr.len;
-#ifdef ATM_PVCEXT
- if (ATM_PH_FLAGS(ah) & ATM_PH_PVCSIF) {
- /*
- * when PVC shadow interface is used, pointer to
- * the shadow interface is passed as rxhand.
- * override the receive interface of the packet.
- */
- m->m_pkthdr.rcvif = (struct ifnet *)rxhand;
- rxhand = NULL;
- }
-#endif /* ATM_PVCEXT */
-
if (rxhand) {
#ifdef NATM
struct natmpcb *npcb = rxhand;
@@ -336,6 +323,7 @@ atm_ifattach(ifp)
ifp->if_hdrlen = 0;
ifp->if_mtu = ATMMTU;
ifp->if_output = atm_output;
+ ifp->if_snd.ifq_maxlen = 50; /* dummy */
#if defined(__NetBSD__) || defined(__OpenBSD__)
for (ifa = ifp->if_addrlist.tqh_first; ifa != 0;
@@ -357,273 +345,3 @@ atm_ifattach(ifp)
}
}
-
-#ifdef ATM_PVCEXT
-/*
- * ATM PVC shadow interface: a trick to assign a shadow interface
- * to a PVC.
- * with shadow interface, each PVC looks like an individual
- * Point-to-Point interface.
- * as oposed to the NBMA model, a shadow interface is inherently
- * multicast capable (no LANE/MARS required).
- */
-struct pvcsif {
- struct ifnet sif_shadow; /* shadow ifnet structure per pvc */
- struct atm_pseudohdr sif_aph; /* flags + vpi:vci */
- struct ifnet *sif_ifp; /* pointer to the genuine interface */
-};
-
-static int pvc_output __P((struct ifnet *, struct mbuf *,
- struct sockaddr *, struct rtentry *));
-static int pvc_ioctl __P((struct ifnet *, u_long, caddr_t));
-
-/*
- * create and attach per pvc shadow interface
- * (currently detach is not supported)
- */
-static int pvc_number = 0;
-
-struct ifnet *
-pvc_attach(ifp)
- struct ifnet *ifp;
-{
- struct pvcsif *pvcsif;
- struct ifnet *shadow;
- struct ifaddr *ifa;
- struct sockaddr_dl *sdl;
- int s;
-
- MALLOC(pvcsif, struct pvcsif *, sizeof(struct pvcsif),
- M_DEVBUF, M_WAITOK);
- bzero(pvcsif, sizeof(struct pvcsif));
-
- pvcsif->sif_ifp = ifp;
- shadow = &pvcsif->sif_shadow;
-
- shadow->if_name = "pvc";
- shadow->if_unit = pvc_number++;
- shadow->if_flags = ifp->if_flags | (IFF_POINTOPOINT | IFF_MULTICAST);
- shadow->if_ioctl = pvc_ioctl;
- shadow->if_output = pvc_output;
- shadow->if_start = NULL;
- shadow->if_mtu = ifp->if_mtu;
- shadow->if_type = ifp->if_type;
- shadow->if_addrlen = ifp->if_addrlen;
- shadow->if_hdrlen = ifp->if_hdrlen;
- shadow->if_softc = pvcsif;
- shadow->if_snd.ifq_maxlen = 50; /* dummy */
-
- s = splimp();
- if_attach(shadow);
-
-#if defined(__NetBSD__) || defined(__OpenBSD__)
- for (ifa = shadow->if_addrlist.tqh_first; ifa != 0;
- ifa = ifa->ifa_list.tqe_next)
-#elif defined(__FreeBSD__) && (__FreeBSD__ > 2)
- for (ifa = shadow->if_addrhead.tqh_first; ifa;
- ifa = ifa->ifa_link.tqe_next)
-#elif defined(__FreeBSD__) || defined(__bsdi__)
- for (ifa = shadow->if_addrlist; ifa; ifa = ifa->ifa_next)
-#endif
- if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) &&
- sdl->sdl_family == AF_LINK) {
- sdl->sdl_type = IFT_ATM;
- sdl->sdl_alen = shadow->if_addrlen;
- break;
- }
- splx(s);
-
- return (shadow);
-}
-
-/*
- * pvc_output relays the packet to atm_output along with vpi:vci info.
- */
-static int
-pvc_output(shadow, m, dst, rt)
- struct ifnet *shadow;
- struct mbuf *m;
- struct sockaddr *dst;
- struct rtentry *rt;
-{
- struct pvcsif *pvcsif;
- struct sockaddr dst_addr;
- struct atmllc *atmllc;
- u_int16_t etype = 0;
- int error = 0;
-
- if ((shadow->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
- senderr(ENETDOWN);
-
- pvcsif = shadow->if_softc;
- if (ATM_PH_VCI(&pvcsif->sif_aph) == 0)
- senderr(ENETDOWN);
-
- /*
- * create a dummy sockaddr: (using bpfwrite interface)
- * put atm pseudo header and llc/snap into sa_data (12 bytes)
- * and mark it as AF_UNSPEC.
- */
- if (dst) {
- switch (dst->sa_family) {
-#if defined(INET) || defined(INET6)
- case AF_INET:
- case AF_INET6:
- if (dst->sa_family == AF_INET6)
- etype = htons(ETHERTYPE_IPV6);
- else
- etype = htons(ETHERTYPE_IP);
- break;
-#endif
-
- default:
- printf("%s%d: can't handle af%d\n", shadow->if_name,
- shadow->if_unit, dst->sa_family);
- senderr(EAFNOSUPPORT);
- }
- }
-
- dst_addr.sa_family = AF_UNSPEC;
- bcopy(&pvcsif->sif_aph, dst_addr.sa_data,
- sizeof(struct atm_pseudohdr));
- atmllc = (struct atmllc *)
- (dst_addr.sa_data + sizeof(struct atm_pseudohdr));
- bcopy(ATMLLC_HDR, atmllc->llchdr, sizeof(atmllc->llchdr));
- ATM_LLC_SETTYPE(atmllc, etype); /* note: already in network order */
-
- return atm_output(pvcsif->sif_ifp, m, &dst_addr, rt);
-
-bad:
- if (m)
- m_freem(m);
- return (error);
-}
-
-static int
-pvc_ioctl(shadow, cmd, data)
- struct ifnet *shadow;
- u_long cmd;
- caddr_t data;
-{
- struct ifnet *ifp;
- struct pvcsif *pvcsif;
- struct ifreq *ifr = (struct ifreq *) data;
- void (*ifa_rtrequest)(int, struct rtentry *, struct sockaddr *) = NULL;
- int error = 0;
-
- pvcsif = (struct pvcsif *)shadow->if_softc;
- ifp = pvcsif->sif_ifp;
- if (ifp == 0 || ifp->if_ioctl == 0)
- return (EOPNOTSUPP);
-
- /*
- * pre process
- */
- switch (cmd) {
- case SIOCGPVCSIF:
- snprintf(ifr->ifr_name, sizeof(ifr->ifr_name),
- "%s%d", ifp->if_name, ifp->if_unit);
- return (0);
-
- case SIOCGPVCTX:
- do {
- struct pvctxreq *pvcreq = (struct pvctxreq *)data;
-
- snprintf(pvcreq->pvc_ifname,
- sizeof(pvcreq->pvc_ifname), "%s%d",
- ifp->if_name, ifp->if_unit);
- pvcreq->pvc_aph = pvcsif->sif_aph;
- } while (0);
- break;
-
- case SIOCADDMULTI:
- case SIOCDELMULTI:
- if (ifr == 0)
- return (EAFNOSUPPORT); /* XXX */
- switch (ifr->ifr_addr.sa_family) {
-#ifdef INET
- case AF_INET:
- return (0);
-#endif
-#ifdef INET6
- case AF_INET6:
- return (0);
-#endif
- default:
- return (EAFNOSUPPORT);
- }
- break;
- case SIOCSIFADDR:
- if (ifp->if_flags & IFF_UP) {
- /* real if is already up */
- shadow->if_flags = ifp->if_flags |
- (IFF_POINTOPOINT|IFF_MULTICAST);
- return (0);
- }
- /*
- * XXX: save the rtrequest field since the atm driver
- * overwrites this field.
- */
- ifa_rtrequest = ((struct ifaddr *)data)->ifa_rtrequest;
- break;
-
- case SIOCSIFFLAGS:
- if ((shadow->if_flags & IFF_UP) == 0) {
- /*
- * interface down. don't pass this to
- * the real interface.
- */
- return (0);
- }
- if (shadow->if_flags & IFF_UP) {
- /*
- * interface up. if the real if is already up,
- * nothing to do.
- */
- if (ifp->if_flags & IFF_UP) {
- shadow->if_flags = ifp->if_flags |
- (IFF_POINTOPOINT|IFF_MULTICAST);
- return (0);
- }
- }
- break;
- }
-
- /*
- * pass the ioctl to the genuine interface
- */
- error = (*ifp->if_ioctl)(ifp, cmd, data);
-
- /*
- * post process
- */
- switch (cmd) {
- case SIOCSIFMTU:
- shadow->if_mtu = ifp->if_mtu;
- break;
- case SIOCSIFADDR:
- /* restore rtrequest */
- ((struct ifaddr *)data)->ifa_rtrequest = ifa_rtrequest;
- /* fall into... */
- case SIOCSIFFLAGS:
- /* update if_flags */
- shadow->if_flags = ifp->if_flags
- | (IFF_POINTOPOINT|IFF_MULTICAST);
- break;
- }
-
- return (error);
-}
-
-int pvc_setaph(shadow, aph)
- struct ifnet *shadow;
- struct atm_pseudohdr *aph;
-{
- struct pvcsif *pvcsif;
-
- pvcsif = shadow->if_softc;
- bcopy(aph, &pvcsif->sif_aph, sizeof(struct atm_pseudohdr));
- return (0);
-}
-
-#endif /* ATM_PVCEXT */
OpenPOWER on IntegriCloud