Submit #3126 ยป bpf_biocfeedback.patch
sys/net/bpf.c | ||
---|---|---|
struct mbuf *nm_mbuf;
|
||
struct ifnet *nm_ifp;
|
||
struct sockaddr *nm_dst;
|
||
boolean_t nm_feedback;
|
||
};
|
||
MALLOC_DEFINE(M_BPF, "BPF", "BPF data");
|
||
... | ... | |
d->bd_bufsize = bpf_bufsize;
|
||
d->bd_sig = SIGIO;
|
||
d->bd_seesent = 1;
|
||
d->bd_feedback = 0;
|
||
callout_init(&d->bd_callout);
|
||
lwkt_reltoken(&bpf_token);
|
||
... | ... | |
{
|
||
struct netmsg_bpf_output *bmsg = (struct netmsg_bpf_output *)msg;
|
||
struct ifnet *ifp = bmsg->nm_ifp;
|
||
struct mbuf *mc = NULL;
|
||
int error;
|
||
if (bmsg->nm_feedback) {
|
||
mc = m_dup(bmsg->nm_mbuf, M_NOWAIT);
|
||
if (mc != NULL)
|
||
mc->m_pkthdr.rcvif = ifp;
|
||
}
|
||
/*
|
||
* The driver frees the mbuf.
|
||
*/
|
||
error = ifp->if_output(ifp, bmsg->nm_mbuf, bmsg->nm_dst, NULL);
|
||
lwkt_replymsg(&msg->lmsg, error);
|
||
if (mc != NULL) {
|
||
if (error == 0) {
|
||
mc->m_flags &= ~M_HASH;
|
||
(*ifp->if_input)(ifp, mc, NULL, -1);
|
||
} else {
|
||
m_freem(mc);
|
||
}
|
||
}
|
||
}
|
||
static int
|
||
... | ... | |
bmsg.nm_ifp = ifp;
|
||
bmsg.nm_dst = &dst;
|
||
if (d->bd_feedback)
|
||
bmsg.nm_feedback = TRUE;
|
||
else
|
||
bmsg.nm_feedback = FALSE;
|
||
ret = lwkt_domsg(netisr_cpuport(0), &bmsg.base.lmsg, 0);
|
||
lwkt_reltoken(&bpf_token);
|
||
return ret;
|
||
... | ... | |
* BIOCVERSION Get filter language version.
|
||
* BIOCGHDRCMPLT Get "header already complete" flag
|
||
* BIOCSHDRCMPLT Set "header already complete" flag
|
||
* BIOCSFEEDBACK Set packet feedback mode.
|
||
* BIOCGFEEDBACK Get packet feedback mode.
|
||
* BIOCGSEESENT Get "see packets sent" flag
|
||
* BIOCSSEESENT Set "see packets sent" flag
|
||
* BIOCLOCK Set "locked" flag
|
||
... | ... | |
d->bd_async = *(int *)ap->a_data;
|
||
break;
|
||
/*
|
||
* Set "feed packets from bpf back to input" mode
|
||
*/
|
||
case BIOCSFEEDBACK:
|
||
d->bd_feedback = *(int *)ap->a_data;
|
||
break;
|
||
/*
|
||
* Get "feed packets from bpf back to input" mode
|
||
*/
|
||
case BIOCGFEEDBACK:
|
||
*(u_int *)ap->a_data = d->bd_feedback;
|
||
break;
|
||
case FIOSETOWN:
|
||
error = fsetown(*(int *)ap->a_data, &d->bd_sigio);
|
||
break;
|
sys/net/bpf.h | ||
---|---|---|
#define BIOCGDLTLIST _IOWR('B',121, struct bpf_dltlist)
|
||
#define BIOCLOCK _IO('B', 122)
|
||
#define BIOCSETWF _IOW('B',123, struct bpf_program)
|
||
#define BIOCGFEEDBACK _IOR('B',124, u_int)
|
||
#define BIOCSFEEDBACK _IOW('B',125, u_int)
|
||
#define BIOCFEEDBACK BIOCSFEEDBACK /* FreeBSD name */
|
||
/*
|
||
* Structure prepended to each packet.
|
sys/net/bpfdesc.h | ||
---|---|---|
u_char bd_immediate; /* true to return on packet arrival */
|
||
int bd_hdrcmplt; /* false to fill in src lladdr automatically */
|
||
int bd_seesent; /* true if bpf should see sent packets */
|
||
int bd_feedback; /* true to feed back sent packets */
|
||
int bd_async; /* non-zero if packet reception should generate signal */
|
||
int bd_sig; /* signal to send upon packet reception */
|
||
struct sigio * bd_sigio; /* information for async I/O */
|