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 */
|
||