From owner-p4-projects@FreeBSD.ORG Sat Sep 11 00:18:26 2010 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id D548B106566C; Sat, 11 Sep 2010 00:18:25 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D827D106564A for ; Sat, 11 Sep 2010 00:18:24 +0000 (UTC) (envelope-from afiveg@FreeBSD.org) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:4f8:fff6::2d]) by mx1.freebsd.org (Postfix) with ESMTP id BBBAA8FC18 for ; Sat, 11 Sep 2010 00:18:24 +0000 (UTC) Received: from skunkworks.freebsd.org (localhost [127.0.0.1]) by skunkworks.freebsd.org (8.14.4/8.14.4) with ESMTP id o8B0IOJ9040778 for ; Sat, 11 Sep 2010 00:18:24 GMT (envelope-from afiveg@FreeBSD.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.4/8.14.4/Submit) id o8B0IOHG040775 for perforce@freebsd.org; Sat, 11 Sep 2010 00:18:24 GMT (envelope-from afiveg@FreeBSD.org) Date: Sat, 11 Sep 2010 00:18:24 GMT Message-Id: <201009110018.o8B0IOHG040775@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to afiveg@FreeBSD.org using -f From: Alexandre Fiveg To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 183628 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 11 Sep 2010 00:18:26 -0000 http://p4web.freebsd.org/@@183628?ac=10 Change 183628 by afiveg@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 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 #include #include +#include #include @@ -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) ====