Changeset View
Changeset View
Standalone View
Standalone View
sys/net/bpf.c
Show First 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | |||||
#include <sys/socket.h> | #include <sys/socket.h> | ||||
#ifdef DDB | #ifdef DDB | ||||
#include <ddb/ddb.h> | #include <ddb/ddb.h> | ||||
#endif | #endif | ||||
#include <net/if.h> | #include <net/if.h> | ||||
#include <net/if_var.h> | #include <net/if_var.h> | ||||
#include <net/if_vlan_var.h> | |||||
#include <net/if_dl.h> | #include <net/if_dl.h> | ||||
#include <net/bpf.h> | #include <net/bpf.h> | ||||
#include <net/bpf_buffer.h> | #include <net/bpf_buffer.h> | ||||
#ifdef BPF_JITTER | #ifdef BPF_JITTER | ||||
#include <net/bpf_jitter.h> | #include <net/bpf_jitter.h> | ||||
#endif | #endif | ||||
#include <net/bpf_zerocopy.h> | #include <net/bpf_zerocopy.h> | ||||
#include <net/bpfdesc.h> | #include <net/bpfdesc.h> | ||||
Show All 36 Lines | #ifdef BPF_JITTER | ||||
bpf_jit_filter *func; | bpf_jit_filter *func; | ||||
#endif | #endif | ||||
void *buffer[0]; | void *buffer[0]; | ||||
}; | }; | ||||
#if defined(DEV_BPF) || defined(NETGRAPH_BPF) | #if defined(DEV_BPF) || defined(NETGRAPH_BPF) | ||||
#define PRINET 26 /* interruptible */ | #define PRINET 26 /* interruptible */ | ||||
#define BPF_PRIO_MAX 7 | |||||
afedorov: Maybe we should tmove this definition to <net/if_vlan_var.h> and use it in bpf and pf code? | |||||
Done Inline ActionsWe should. I have a local patch for that (and to dedupe this the bpf and pf functions) pending. It'll turn up in phab in a few minutes. kp: We should. I have a local patch for that (and to dedupe this the bpf and pf functions) pending. | |||||
#define SIZEOF_BPF_HDR(type) \ | #define SIZEOF_BPF_HDR(type) \ | ||||
(offsetof(type, bh_hdrlen) + sizeof(((type *)0)->bh_hdrlen)) | (offsetof(type, bh_hdrlen) + sizeof(((type *)0)->bh_hdrlen)) | ||||
#ifdef COMPAT_FREEBSD32 | #ifdef COMPAT_FREEBSD32 | ||||
#include <sys/mount.h> | #include <sys/mount.h> | ||||
#include <compat/freebsd32/freebsd32.h> | #include <compat/freebsd32/freebsd32.h> | ||||
#define BPF_ALIGNMENT32 sizeof(int32_t) | #define BPF_ALIGNMENT32 sizeof(int32_t) | ||||
▲ Show 20 Lines • Show All 831 Lines • ▼ Show 20 Lines | |||||
#ifdef MAC | #ifdef MAC | ||||
mac_bpfdesc_init(d); | mac_bpfdesc_init(d); | ||||
mac_bpfdesc_create(td->td_ucred, d); | mac_bpfdesc_create(td->td_ucred, d); | ||||
#endif | #endif | ||||
mtx_init(&d->bd_lock, devtoname(dev), "bpf cdev lock", MTX_DEF); | mtx_init(&d->bd_lock, devtoname(dev), "bpf cdev lock", MTX_DEF); | ||||
callout_init_mtx(&d->bd_callout, &d->bd_lock, 0); | callout_init_mtx(&d->bd_callout, &d->bd_lock, 0); | ||||
knlist_init_mtx(&d->bd_sel.si_note, &d->bd_lock); | knlist_init_mtx(&d->bd_sel.si_note, &d->bd_lock); | ||||
/* Disable VLAN pcp tagging. */ | |||||
d->bd_pcp = 0; | |||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
* bpfread - read next chunk of packets from buffers | * bpfread - read next chunk of packets from buffers | ||||
*/ | */ | ||||
static int | static int | ||||
bpfread(struct cdev *dev, struct uio *uio, int ioflag) | bpfread(struct cdev *dev, struct uio *uio, int ioflag) | ||||
▲ Show 20 Lines • Show All 175 Lines • ▼ Show 20 Lines | if (!bpf_canfreebuf(d) && d->bd_hlen != 0) | ||||
return (1); | return (1); | ||||
if ((d->bd_immediate || d->bd_state == BPF_TIMED_OUT) && | if ((d->bd_immediate || d->bd_state == BPF_TIMED_OUT) && | ||||
d->bd_slen != 0) | d->bd_slen != 0) | ||||
return (1); | return (1); | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
bpf_setpcp(struct mbuf *m, u_int8_t prio) | |||||
Not Done Inline ActionsThis function completely copies https://github.com/freebsd/freebsd-src/blob/main/sys/netpfil/pf/pf.c#L2712 Can it also be made common for pf and bpf? afedorov: This function completely copies https://github.com/freebsd/freebsd… | |||||
Done Inline ActionsYes. Expect a patch soon. I'd prefer to keep it out of this one, for merge reasons. kp: Yes. Expect a patch soon. I'd prefer to keep it out of this one, for merge reasons. | |||||
{ | |||||
struct m_tag *mtag; | |||||
KASSERT(prio <= BPF_PRIO_MAX, | |||||
("%s with invalid pcp", __func__)); | |||||
mtag = m_tag_locate(m, MTAG_8021Q, MTAG_8021Q_PCP_OUT, NULL); | |||||
if (mtag == NULL) { | |||||
mtag = m_tag_alloc(MTAG_8021Q, MTAG_8021Q_PCP_OUT, | |||||
sizeof(uint8_t), M_NOWAIT); | |||||
if (mtag == NULL) | |||||
return (ENOMEM); | |||||
m_tag_prepend(m, mtag); | |||||
} | |||||
*(uint8_t *)(mtag + 1) = prio; | |||||
return (0); | |||||
} | |||||
static int | |||||
bpfwrite(struct cdev *dev, struct uio *uio, int ioflag) | bpfwrite(struct cdev *dev, struct uio *uio, int ioflag) | ||||
{ | { | ||||
struct route ro; | struct route ro; | ||||
struct sockaddr dst; | struct sockaddr dst; | ||||
struct epoch_tracker et; | struct epoch_tracker et; | ||||
struct bpf_if *bp; | struct bpf_if *bp; | ||||
struct bpf_d *d; | struct bpf_d *d; | ||||
struct ifnet *ifp; | struct ifnet *ifp; | ||||
▲ Show 20 Lines • Show All 83 Lines • ▼ Show 20 Lines | #endif | ||||
bzero(&ro, sizeof(ro)); | bzero(&ro, sizeof(ro)); | ||||
if (hlen != 0) { | if (hlen != 0) { | ||||
ro.ro_prepend = (u_char *)&dst.sa_data; | ro.ro_prepend = (u_char *)&dst.sa_data; | ||||
ro.ro_plen = hlen; | ro.ro_plen = hlen; | ||||
ro.ro_flags = RT_HAS_HEADER; | ro.ro_flags = RT_HAS_HEADER; | ||||
} | } | ||||
if (d->bd_pcp != 0) | |||||
bpf_setpcp(m, d->bd_pcp); | |||||
Not Done Inline Actionsbpf_setpcp() return an error which ignored. afedorov: bpf_setpcp() return an error which ignored. | |||||
Not Done Inline ActionsYes. I think I prefer it this way, on the grounds that sending a packet with the wrong PCP is better than not sending it at all, but that's not a strong opinion. kp: Yes. I think I prefer it this way, on the grounds that sending a packet with the wrong PCP is… | |||||
/* Avoid possible recursion on BPFD_LOCK(). */ | /* Avoid possible recursion on BPFD_LOCK(). */ | ||||
NET_EPOCH_ENTER(et); | NET_EPOCH_ENTER(et); | ||||
BPFD_UNLOCK(d); | BPFD_UNLOCK(d); | ||||
error = (*ifp->if_output)(ifp, m, &dst, &ro); | error = (*ifp->if_output)(ifp, m, &dst, &ro); | ||||
if (error) | if (error) | ||||
counter_u64_add(d->bd_wdcount, 1); | counter_u64_add(d->bd_wdcount, 1); | ||||
if (mc != NULL) { | if (mc != NULL) { | ||||
▲ Show 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | |||||
* BIOCSTSTAMP Set time stamp format and resolution. | * BIOCSTSTAMP Set time stamp format and resolution. | ||||
* BIOCLOCK Set "locked" flag | * BIOCLOCK Set "locked" flag | ||||
* BIOCFEEDBACK Set packet feedback mode. | * BIOCFEEDBACK Set packet feedback mode. | ||||
* BIOCSETZBUF Set current zero-copy buffer locations. | * BIOCSETZBUF Set current zero-copy buffer locations. | ||||
* BIOCGETZMAX Get maximum zero-copy buffer size. | * BIOCGETZMAX Get maximum zero-copy buffer size. | ||||
* BIOCROTZBUF Force rotation of zero-copy buffer | * BIOCROTZBUF Force rotation of zero-copy buffer | ||||
* BIOCSETBUFMODE Set buffer mode. | * BIOCSETBUFMODE Set buffer mode. | ||||
* BIOCGETBUFMODE Get current buffer mode. | * BIOCGETBUFMODE Get current buffer mode. | ||||
* BIOCSETVLANPCP Set VLAN PCP tag. | |||||
Not Done Inline ActionsMay be: BIOCSETPCP -> BIOCSETVLANPCP? afedorov: May be: BIOCSETPCP -> BIOCSETVLANPCP? | |||||
Done Inline ActionsYeah, that makes sense. I'll update this patch. kp: Yeah, that makes sense. I'll update this patch. | |||||
*/ | */ | ||||
/* ARGSUSED */ | /* ARGSUSED */ | ||||
static int | static int | ||||
bpfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, | bpfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, | ||||
struct thread *td) | struct thread *td) | ||||
{ | { | ||||
struct bpf_d *d; | struct bpf_d *d; | ||||
int error; | int error; | ||||
▲ Show 20 Lines • Show All 534 Lines • ▼ Show 20 Lines | #endif | ||||
case BIOCSETZBUF: | case BIOCSETZBUF: | ||||
error = bpf_ioctl_setzbuf(td, d, (struct bpf_zbuf *)addr); | error = bpf_ioctl_setzbuf(td, d, (struct bpf_zbuf *)addr); | ||||
break; | break; | ||||
case BIOCROTZBUF: | case BIOCROTZBUF: | ||||
error = bpf_ioctl_rotzbuf(td, d, (struct bpf_zbuf *)addr); | error = bpf_ioctl_rotzbuf(td, d, (struct bpf_zbuf *)addr); | ||||
break; | break; | ||||
case BIOCSETVLANPCP: | |||||
{ | |||||
u_int pcp; | |||||
pcp = *(u_int *)addr; | |||||
if (pcp > BPF_PRIO_MAX || pcp < 0) { | |||||
error = EINVAL; | |||||
break; | |||||
} | |||||
d->bd_pcp = pcp; | |||||
break; | |||||
} | |||||
} | } | ||||
CURVNET_RESTORE(); | CURVNET_RESTORE(); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Set d's packet filter program to fp. If this file already has a filter, | * Set d's packet filter program to fp. If this file already has a filter, | ||||
* free it and replace it. Returns EINVAL for bogus requests. | * free it and replace it. Returns EINVAL for bogus requests. | ||||
▲ Show 20 Lines • Show All 1,181 Lines • Show Last 20 Lines |
Maybe we should tmove this definition to <net/if_vlan_var.h> and use it in bpf and pf code?