Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 11 Sep 2010 00:18:24 GMT
From:      Alexandre Fiveg <afiveg@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 183628 for review
Message-ID:  <201009110018.o8B0IOHG040775@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <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) ====




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201009110018.o8B0IOHG040775>