PERFORCE change 183628 for review
Alexandre Fiveg
afiveg at FreeBSD.org
Sat Sep 11 00:18:26 UTC 2010
http://p4web.freebsd.org/@@183628?ac=10
Change 183628 by afiveg at cottonmouth on 2010/09/11 00:17:30
Packets filtering functionalities are changed: 1. struct capt_object has now a new member "struct bpf_insn *fcode". 2. The new ioctl is added: IOCTL_SETFILTER 3. bpf_setfilter(3) has now the ringmap-hook - there will be ringmap_setfilter() called. 4. In the kernel the function ringmap_filter() is a wrapper around bpf_filter(9). 5. Explanation: The user-process calls pcap_compile(3), gets bpf_program's pointer, calls ioctl(IOCTL_SETFILTER) in (using ringmap_setfilter()). The kernels ioctl() copies bpf_insn into the kernel space, calls bpf_validate(9) in order to check the code and sets capt_object->fcode. The ringmap_filter() calls bpf_filter(9) in order to check whether the packet is accepted by filter. So, the capt_object represents now the thread, its packet-ring, queue (for multi queue adapters) and filtering program.
Affected files ...
.. //depot/projects/soc2010/ringmap/current/contrib/libpcap/pcap.c#22 edit
.. //depot/projects/soc2010/ringmap/current/contrib/libpcap/ringmap_pcap.c#34 edit
.. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/ringmap_8254.c#34 edit
.. //depot/projects/soc2010/ringmap/current/sys/net/ringmap.c#48 edit
.. //depot/projects/soc2010/ringmap/current/sys/net/ringmap.h#48 edit
.. //depot/projects/soc2010/ringmap/current/sys/net/ringmap_kernel.h#18 edit
.. //depot/projects/soc2010/ringmap/scripts/build_ringmap.sh#30 edit
.. //depot/projects/soc2010/ringmap/scripts/set_ringmap.sh#31 edit
.. //depot/projects/soc2010/ringmap/scripts/tailf_ringmap_msgs.sh#25 edit
Differences ...
==== //depot/projects/soc2010/ringmap/current/contrib/libpcap/pcap.c#22 (text+ko) ====
@@ -76,6 +76,7 @@
#include <sys/ioccom.h>
extern int init_mmapped_capturing(const char *device, pcap_t *);
+extern void ringmap_setfilter(struct bpf_program *);
#endif
@@ -1008,7 +1009,16 @@
int
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
{
+#ifdef RINGMAP
+ int err = p->setfilter_op(p, fp);
+
+ if (err == 0)
+ ringmap_setfilter(fp);
+
+ return (err);
+#else
return p->setfilter_op(p, fp);
+#endif
}
/*
==== //depot/projects/soc2010/ringmap/current/contrib/libpcap/ringmap_pcap.c#34 (text+ko) ====
@@ -25,17 +25,18 @@
#include "../../sys/net/ringmap.h"
-/* File descriptor of /dev/ringmap */
+/* File descriptor of /dev/iface */
int ringmap_cdev_fd = -1;
/*** F U N C T I O N S ***/
int init_mmapped_capturing(const char *device, pcap_t *);
void uninit_mmapped_capturing(pcap_t *);
int pcap_read_ringmap(pcap_t *, int , pcap_handler , u_char *);
+void ringmap_setfilter(struct bpf_program *);
/********************************************************
- * Open (/dev/ringmap) device to communicate with
+ * Open (/dev/iface) device to communicate with
* kernel. Map buffers by calling mmap (/dev/mem, ...)
* in space of our user process.
********************************************************/
@@ -52,7 +53,7 @@
sprintf(dev_path, "/dev/%s", device);
- /* Open /dev/ringmap device for communication with our driver */
+ /* Open /dev/ device for communication with our driver */
if ((ringmap_cdev_fd = open(dev_path, O_RDWR)) == -1) {
printf("[%s] Error by opening %s \n", __func__, dev_path);
perror("/dev/" RINGMAP_DEVICE);
@@ -221,6 +222,15 @@
RINGMAP_FUNC_DEBUG(end);
}
+void
+ringmap_setfilter(struct bpf_program *fp)
+{
+ if (ioctl(ringmap_cdev_fd, IOCTL_SETFILTER, (caddr_t)fp) == 0) {
+ RINGMAP_FUNC_DEBUG(Filter is set);
+ } else {
+ RINGMAP_WARN(Filter is not set!);
+ }
+}
int
pcap_read_ringmap(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/ringmap_8254.c#34 (text+ko) ====
@@ -11,6 +11,7 @@
#include <net/if_var.h>
#include <net/if_types.h>
#include <net/if_media.h>
+#include <net/bpf.h>
#include <net/ringmap.h>
@@ -31,7 +32,7 @@
extern devclass_t em_devclass;
extern void ringmap_print_slot(struct ring *, unsigned int);
extern void print_capt_obj(struct capt_object *);
-extern int ringmap_filter(struct ifnet *, struct capt_object *, int);
+extern int ringmap_filter(struct capt_object *, int);
struct ringmap_functions ringmap_8254_f = {
@@ -54,11 +55,7 @@
{
struct adapter *adapter = (struct adapter *)device_get_softc(co->rm->dev);
- RINGMAP_FUNC_DEBUG(start);
-
RINGMAP_HW_SYNC_TAIL(adapter, co->ring);
-
- RINGMAP_FUNC_DEBUG(end);
}
/* Set value from RDH to the ring->kernrp*/
@@ -67,11 +64,7 @@
{
struct adapter *adapter = (struct adapter *)device_get_softc(co->rm->dev);
- RINGMAP_FUNC_DEBUG(start);
-
RINGMAP_HW_SYNC_HEAD(adapter, co->ring);
-
- RINGMAP_FUNC_DEBUG(end);
}
@@ -134,9 +127,9 @@
SLIST_FOREACH(co, &rm->object_list, objects) {
if (co->ring != NULL) {
co->ring->slot[slot_num].is_ok = 1;
- co->ring->slot[slot_num].intr_num = co->ring->intr_num;;
+ co->ring->slot[slot_num].intr_num = co->ring->intr_num;
- ringmap_filter(adapter->ifp, co, slot_num);
+ ringmap_filter(co, slot_num);
#ifdef RINGMAP_TIMESTAMP
co->ring->slot[slot_num].ts = co->ring->last_ts;
==== //depot/projects/soc2010/ringmap/current/sys/net/ringmap.c#48 (text+ko) ====
@@ -45,7 +45,7 @@
void print_capt_obj(struct capt_object *);
struct ringmap * cdev2ringmap(struct cdev *);
struct ringmap * dev2ringmap(device_t);
-int ringmap_filter(struct ifnet *, struct capt_object *, int);
+int ringmap_filter(struct capt_object *, int);
d_open_t ringmap_open;
d_close_t ringmap_close;
@@ -468,9 +468,12 @@
ringmap_ioctl (struct cdev *cdev, u_long cmd, caddr_t data,
int fflag, struct thread *td)
{
- int err = 0, err_sleep = err_sleep;
+ int err = 0, err_sleep = err_sleep, size, flen;
+
struct ringmap *rm = NULL;
struct capt_object *co;
+ struct bpf_program *bpf_prog;
+ struct bpf_insn *fcode;
RINGMAP_IOCTL(start);
@@ -478,14 +481,14 @@
printf("[%s] pid = %d\n", __func__, td->td_proc->p_pid);
#endif
- if ( devfs_get_cdevpriv((void **)&co) ) {
+ if (devfs_get_cdevpriv((void **)&co)) {
RINGMAP_IOCTL(Error! Can not get private data!);
return (ENODEV);
}
rm = co->rm;
- switch( cmd ){
+ switch (cmd) {
/* Sleep and wait for new packets */
case IOCTL_SLEEP_WAIT:
@@ -524,10 +527,34 @@
RINGMAP_UNLOCK(rm);
break;
+ case IOCTL_SETFILTER:
+ bpf_prog = (struct bpf_program *)data;
+ flen = bpf_prog->bf_len;
+ if (flen > BPF_MAXINSNS) {
+ RINGMAP_ERROR("IOCTL_SETFILTER");
+ err = EINVAL;
+ goto out;
+ }
+
+ size = flen * sizeof(*bpf_prog->bf_insns);
+ fcode = (struct bpf_insn *)malloc(size, M_BPF, M_WAITOK);
+
+ if (copyin((caddr_t)bpf_prog->bf_insns, (caddr_t)fcode, size) == 0 &&
+ bpf_validate(fcode, (int)flen)) {
+ co->fcode = (struct bpf_insn *)fcode;
+ } else {
+ RINGMAP_ERROR("Could not set filter");
+ free((caddr_t)fcode, M_BPF);
+ err = EINVAL;
+ goto out;
+ }
+
+ break;
+
default:
RINGMAP_ERROR("Undefined command!");
- return (ENODEV);
- }
+ err = ENODEV;
+ }
out:
@@ -539,35 +566,19 @@
/* Paket filtering */
int
-ringmap_filter(struct ifnet *rcvif, struct capt_object *co, int slot_num)
+ringmap_filter(struct capt_object *co, int slot_num)
{
- struct bpf_if *bp = rcvif->if_bpf;
- struct bpf_d *d = NULL;
struct mbuf *mb = (struct mbuf *)K_MBUF(co->ring, slot_num);
- u_int pktlen = mb->m_len, slen;
+ unsigned int pktlen = mb->m_len, slen;
- BPFIF_LOCK(bp);
-
- LIST_FOREACH(d, &bp->bif_dlist, bd_next) {
- if (d->bd_pid == co->td->td_proc->p_pid)
- break;
- }
- if (d != NULL) {
- BPFD_LOCK(d);
-
- printf("ifdname: %s\n", rcvif->if_dname);
- ++d->bd_rcount;
- slen = bpf_filter(d->bd_rfilter, (u_char *)mb, pktlen, 0);
+ if (co->fcode != NULL) {
+ slen = bpf_filter(co->fcode, (u_char *)mb, pktlen, 0);
if (slen)
co->ring->slot[slot_num].filtered = 1;
else
co->ring->slot[slot_num].filtered = 0;
-
- BPFD_UNLOCK(d);
}
- BPFIF_UNLOCK(bp);
-
return (0);
}
==== //depot/projects/soc2010/ringmap/current/sys/net/ringmap.h#48 (text+ko) ====
@@ -135,6 +135,7 @@
unsigned long long intr_num;
/* Ring identification. Should be initialized with process ID */
+ /* TODO: use other ID. Using PID is a wrong way */
unsigned int pid;
/* Array of slots */
@@ -175,6 +176,11 @@
*/
#define IOCTL_SLEEP_WAIT _IO(RINGMAP_IOC_MAGIC, 5)
+/*
+ * Set filter programm for packet filtering
+ */
+#define IOCTL_SETFILTER _IOW(RINGMAP_IOC_MAGIC, 6, struct bpf_program)
+
/**********************************************
* Arithmetic in Ring Buffer
==== //depot/projects/soc2010/ringmap/current/sys/net/ringmap_kernel.h#18 (text+ko) ====
@@ -7,6 +7,8 @@
struct ring *ring;
void *que;
+ struct bpf_insn *fcode;
+
SLIST_ENTRY(capt_object) objects;
};
==== //depot/projects/soc2010/ringmap/scripts/build_ringmap.sh#30 (text+ko) ====
==== //depot/projects/soc2010/ringmap/scripts/set_ringmap.sh#31 (text+ko) ====
==== //depot/projects/soc2010/ringmap/scripts/tailf_ringmap_msgs.sh#25 (text+ko) ====
More information about the p4-projects
mailing list