o track changes to ethernet input packet handling

o track changes to bpf
o track changes to make ng hooks more private

Reviewed by:	many
Approved by:	re
This commit is contained in:
Sam Leffler 2002-11-14 23:44:37 +00:00
parent a3814acf84
commit edbb5246ff
3 changed files with 22 additions and 96 deletions

View File

@ -325,8 +325,7 @@ ng_eiface_start2(node_p node, hook_p hook, void *arg1, int arg2)
* Pass packet to bpf if there is a listener.
* XXX is this safe? locking?
*/
if (ifp->if_bpf)
bpf_mtap(ifp, m);
BPF_MTAP(ifp, m);
/* Copy length before the mbuf gets invalidated */
len = m->m_pkthdr.len;
@ -458,7 +457,7 @@ ng_eiface_constructor(node_p node)
*/
/* Attach the interface */
ether_ifattach(ifp, ETHER_BPF_SUPPORTED);
ether_ifattach(ifp, priv->arpcom.ac_enaddr);
/* Done */
return (0);
@ -602,9 +601,6 @@ ng_eiface_rcvdata(hook_p hook, item_p item)
{
priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
struct ifnet *const ifp = priv->ifp;
int s, error = 0;
struct ether_header *eh;
u_short ether_type;
struct mbuf *m;
NGI_GET_M(item, m);
@ -626,26 +622,10 @@ ng_eiface_rcvdata(hook_p hook, item_p item)
/* Update interface stats */
ifp->if_ipackets++;
eh = mtod(m, struct ether_header *);
ether_type = ntohs(eh->ether_type);
s = splimp();
m->m_pkthdr.len -= sizeof(*eh);
m->m_len -= sizeof(*eh);
if (m->m_len) {
m->m_data += sizeof(*eh);
} else {
if (ether_type == ETHERTYPE_ARP) {
m->m_len = m->m_next->m_len;
m->m_data = m->m_next->m_data;
}
}
splx(s);
ether_input(ifp, eh, m);
(*ifp->if_input)(ifp, m);
/* Done */
return (error);
return (0);
}
/*
@ -657,7 +637,7 @@ ng_eiface_rmnode(node_p node)
priv_p priv = NG_NODE_PRIVATE(node);
struct ifnet *const ifp = priv->ifp;
ether_ifdetach(ifp, ETHER_BPF_SUPPORTED);
ether_ifdetach(ifp);
ng_eiface_free_unit(priv->unit);
FREE(priv, M_NETGRAPH);
NG_NODE_SET_PRIVATE(node, NULL);

View File

@ -80,20 +80,22 @@ struct private {
};
typedef struct private *priv_p;
/* Hook pointers used by if_ethersubr.c to callback to netgraph */
extern void (*ng_ether_input_p)(struct ifnet *ifp, struct mbuf **mp);
extern void (*ng_ether_input_orphan_p)(struct ifnet *ifp, struct mbuf *m);
extern int (*ng_ether_output_p)(struct ifnet *ifp, struct mbuf **mp);
extern void (*ng_ether_attach_p)(struct ifnet *ifp);
extern void (*ng_ether_detach_p)(struct ifnet *ifp);
/* Functional hooks called from if_ethersubr.c */
static void ng_ether_input(struct ifnet *ifp,
struct mbuf **mp, struct ether_header *eh);
static void ng_ether_input_orphan(struct ifnet *ifp,
struct mbuf *m, struct ether_header *eh);
static void ng_ether_input(struct ifnet *ifp, struct mbuf **mp);
static void ng_ether_input_orphan(struct ifnet *ifp, struct mbuf *m);
static int ng_ether_output(struct ifnet *ifp, struct mbuf **mp);
static void ng_ether_attach(struct ifnet *ifp);
static void ng_ether_detach(struct ifnet *ifp);
/* Other functions */
static void ng_ether_input2(node_p node,
struct mbuf **mp, struct ether_header *eh);
static int ng_ether_glueback_header(struct mbuf **mp,
struct ether_header *eh);
static void ng_ether_input2(node_p node, struct mbuf **mp);
static int ng_ether_rcv_lower(node_p node, struct mbuf *m, meta_p meta);
static int ng_ether_rcv_upper(node_p node, struct mbuf *m, meta_p meta);
@ -209,8 +211,7 @@ NETGRAPH_INIT(ether, &ng_ether_typestruct);
* NOTE: this function will get called at splimp()
*/
static void
ng_ether_input(struct ifnet *ifp,
struct mbuf **mp, struct ether_header *eh)
ng_ether_input(struct ifnet *ifp, struct mbuf **mp)
{
const node_p node = IFP2NG(ifp);
const priv_p priv = NG_NODE_PRIVATE(node);
@ -218,7 +219,7 @@ ng_ether_input(struct ifnet *ifp,
/* If "lower" hook not connected, let packet continue */
if (priv->lower == NULL || priv->lowerOrphan)
return;
ng_ether_input2(node, mp, eh);
ng_ether_input2(node, mp);
}
/*
@ -228,8 +229,7 @@ ng_ether_input(struct ifnet *ifp,
* NOTE: this function will get called at splimp()
*/
static void
ng_ether_input_orphan(struct ifnet *ifp,
struct mbuf *m, struct ether_header *eh)
ng_ether_input_orphan(struct ifnet *ifp, struct mbuf *m)
{
const node_p node = IFP2NG(ifp);
const priv_p priv = NG_NODE_PRIVATE(node);
@ -239,7 +239,7 @@ ng_ether_input_orphan(struct ifnet *ifp,
m_freem(m);
return;
}
ng_ether_input2(node, &m, eh);
ng_ether_input2(node, &m);
if (m != NULL)
m_freem(m);
}
@ -252,15 +252,11 @@ ng_ether_input_orphan(struct ifnet *ifp,
* NOTE: this function will get called at splimp()
*/
static void
ng_ether_input2(node_p node, struct mbuf **mp, struct ether_header *eh)
ng_ether_input2(node_p node, struct mbuf **mp)
{
const priv_p priv = NG_NODE_PRIVATE(node);
int error;
/* Glue Ethernet header back on */
if ((error = ng_ether_glueback_header(mp, eh)) != 0)
return;
/* Send out lower/orphan hook */
NG_SEND_DATA_ONLY(error, priv->lower, *mp);
*mp = NULL;
@ -350,44 +346,6 @@ ng_ether_detach(struct ifnet *ifp)
ng_rmnode_self(node); /* remove all netgraph parts */
}
/*
* Optimization for gluing the Ethernet header back onto
* the front of an incoming packet.
*/
static int
ng_ether_glueback_header(struct mbuf **mp, struct ether_header *eh)
{
struct mbuf *m = *mp;
int error = 0;
/*
* Optimize for the case where the header is already in place
* at the front of the mbuf. This is actually quite likely
* because many Ethernet drivers generate packets this way.
*/
if (eh == mtod(m, struct ether_header *) - 1) {
m->m_len += sizeof(*eh);
m->m_data -= sizeof(*eh);
m->m_pkthdr.len += sizeof(*eh);
goto done;
}
/* Prepend the header back onto the front of the mbuf */
M_PREPEND(m, sizeof(*eh), M_DONTWAIT);
if (m == NULL) {
error = ENOBUFS;
goto done;
}
/* Copy header into front of mbuf */
bcopy(eh, mtod(m, void *), sizeof(*eh));
done:
/* Done */
*mp = m;
return error;
}
/******************************************************************
NETGRAPH NODE METHODS
******************************************************************/
@ -635,26 +593,14 @@ static int
ng_ether_rcv_upper(node_p node, struct mbuf *m, meta_p meta)
{
const priv_p priv = NG_NODE_PRIVATE(node);
struct ether_header *eh;
/* Discard meta info */
NG_FREE_META(meta);
/* Check length and pull off header */
if (m->m_pkthdr.len < sizeof(*eh)) {
NG_FREE_M(m);
return (EINVAL);
}
if (m->m_len < sizeof(*eh) && (m = m_pullup(m, sizeof(*eh))) == NULL)
return (ENOBUFS);
eh = mtod(m, struct ether_header *);
m->m_data += sizeof(*eh);
m->m_len -= sizeof(*eh);
m->m_pkthdr.len -= sizeof(*eh);
m->m_pkthdr.rcvif = priv->ifp;
/* Route packet back in */
ether_demux(priv->ifp, eh, m);
ether_demux(priv->ifp, m);
return (0);
}

View File

@ -490,7 +490,7 @@ ng_iface_bpftap(struct ifnet *ifp, struct mbuf *m, sa_family_t family)
m0.m_next = m;
m0.m_len = sizeof(family4);
m0.m_data = (char *)&family4;
bpf_mtap(ifp, &m0);
BPF_MTAP(ifp, &m0);
}
}