Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 27 Sep 2010 20:50:07 +0530
From:      Paul Joe <apauljoe@gmail.com>
To:        freebsd-net@freebsd.org
Cc:        Luigi Rizzo <rizzo@iet.unipi.it>
Subject:   Extending dummynet/ipfw
Message-ID:  <AANLkTi=GozyQv%2BxuXS7xT6Kzaa7XaFxAOrihKdKdnCge@mail.gmail.com>

next in thread | raw e-mail | index | archive | help

[-- Attachment #1 --]
Hi,

I have attached a patch which allows to do flow classifications in userland
(e.g based on url categories, LDAP users)
and do bandwidth control in kernel(dummynet).

The patch has

a) a setsocketopt, to associate a pipe to the socket.

b) an ipfw option(sockarg) to redirect flows to corresponding pipe.

Moreover, a member uint32_t is added to struct socket to hold the pipe info.

I guess this structure is not part of kernel userland ABI.

Please let me know your comments, which I would be glad to incorporate

Thanks,
Joe.

[-- Attachment #2 --]
Index: sbin/ipfw/ipfw2.c
===================================================================
RCS file: /home/ncvs/src/sbin/ipfw/ipfw2.c,v
retrieving revision 1.159
diff -c -u -r1.159 ipfw2.c
--- sbin/ipfw/ipfw2.c	19 Apr 2010 16:35:47 -0000	1.159
+++ sbin/ipfw/ipfw2.c	27 Sep 2010 14:25:47 -0000
@@ -266,6 +266,7 @@
 	{ "estab",		TOK_ESTAB },
 	{ "established",	TOK_ESTAB },
 	{ "setup",		TOK_SETUP },
+	{ "sockarg",		TOK_SOCKARG },
 	{ "tcpdatalen",		TOK_TCPDATALEN },
 	{ "tcpflags",		TOK_TCPFLAGS },
 	{ "tcpflgs",		TOK_TCPFLAGS },
@@ -1338,6 +1339,9 @@
 			case O_FIB:
 				printf(" fib %u", cmd->arg1 );
 				break;
+			case O_SOCKARG:
+				printf(" sockarg");
+				break;
 
 			case O_IN:
 				printf(cmd->len & F_NOT ? " out" : " in");
@@ -3531,6 +3535,9 @@
 			fill_cmd(cmd, O_FIB, 0, strtoul(*av, NULL, 0));
 			av++;
 			break;
+		case TOK_SOCKARG:
+			fill_cmd(cmd, O_SOCKARG, 0, 0);
+			break;
 
 		case TOK_LOOKUP: {
 			ipfw_insn_u32 *c = (ipfw_insn_u32 *)cmd;
Index: sbin/ipfw/ipfw2.h
===================================================================
RCS file: /home/ncvs/src/sbin/ipfw/ipfw2.h,v
retrieving revision 1.13
diff -c -u -r1.13 ipfw2.h
--- sbin/ipfw/ipfw2.h	19 Apr 2010 15:11:45 -0000	1.13
+++ sbin/ipfw/ipfw2.h	27 Sep 2010 14:25:47 -0000
@@ -199,6 +199,7 @@
 	TOK_FIB,
 	TOK_SETFIB,
 	TOK_LOOKUP,
+	TOK_SOCKARG,
 };
 /*
  * the following macro returns an error message if we run out of
Index: sys/kern/uipc_socket.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/uipc_socket.c,v
retrieving revision 1.350
diff -c -u -r1.350 uipc_socket.c
--- sys/kern/uipc_socket.c	18 Sep 2010 11:18:42 -0000	1.350
+++ sys/kern/uipc_socket.c	27 Sep 2010 14:25:52 -0000
@@ -123,6 +123,8 @@
 #include <sys/socketvar.h>
 #include <sys/resourcevar.h>
 #include <net/route.h>
+#include <netinet/in.h>
+#include <netinet/ip_var.h>
 #include <sys/signalvar.h>
 #include <sys/stat.h>
 #include <sys/sx.h>
@@ -2461,6 +2463,25 @@
 				so->so_fibnum = 0;
 			}
 			break;
+
+		case SO_USER_COOKIE:
+			if(ip_dn_io_ptr == NULL){
+				error = ENOPROTOOPT;
+				goto bad;
+			}
+
+			error = sooptcopyin(sopt, &optval, sizeof optval,
+						sizeof optval);
+			if (optval < 0 || error ){
+				error= EINVAL; 
+				goto bad;
+			}
+	
+			if(so->so_proto->pr_domain->dom_family == PF_INET) 
+				so->so_user_cookie = (uint32_t)optval;
+			
+			break;
+
 		case SO_SNDBUF:
 		case SO_RCVBUF:
 		case SO_SNDLOWAT:
Index: sys/netinet/ip_fw.h
===================================================================
RCS file: /home/ncvs/src/sys/netinet/ip_fw.h,v
retrieving revision 1.138
diff -c -u -r1.138 ip_fw.h
--- sys/netinet/ip_fw.h	15 Mar 2010 17:14:27 -0000	1.138
+++ sys/netinet/ip_fw.h	27 Sep 2010 14:25:53 -0000
@@ -192,10 +192,13 @@
 
 	O_SETFIB,		/* arg1=FIB number */
 	O_FIB,			/* arg1=FIB desired fib number */
+	
+	O_SOCKARG,		/* socket argument */
 
 	O_LAST_OPCODE		/* not an opcode!		*/
 };
 
+
 /*
  * The extension header are filtered only for presence using a bit
  * vector with a flag for each header.
Index: sys/netinet/ipfw/ip_fw2.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/ipfw/ip_fw2.c,v
retrieving revision 1.45
diff -c -u -r1.45 ip_fw2.c
--- sys/netinet/ipfw/ip_fw2.c	27 Jul 2010 14:26:34 -0000	1.45
+++ sys/netinet/ipfw/ip_fw2.c	27 Sep 2010 14:25:56 -0000
@@ -1801,6 +1801,39 @@
 					match = 1;
 				break;
 
+			case O_SOCKARG:	{
+				struct inpcb *inp = args->inp;
+				struct inpcbinfo *pi;
+				
+				if(is_ipv6)
+					break;
+
+				if(proto == IPPROTO_TCP)
+					pi = &V_tcbinfo;
+				else if (proto == IPPROTO_UDP)
+					pi = &V_udbinfo;
+				else
+					break;
+
+				/* For incomming packet, lookup up the 
+				inpcb using the src/dest ip/port tuple */
+				if(inp == NULL) {
+					INP_INFO_RLOCK(pi);
+					inp = in_pcblookup_hash(pi, 
+						src_ip, htons(src_port),
+						dst_ip, htons(dst_port),
+						0, NULL);
+					INP_INFO_RUNLOCK(pi);
+				}
+				
+				if(inp && inp->inp_socket) {
+					tablearg = inp->inp_socket->so_user_cookie;
+					if(tablearg)
+						match = 1;
+				}
+				break;
+			}
+
 			case O_TAGGED: {
 				struct m_tag *mtag;
 				uint32_t tag = (cmd->arg1 == IP_FW_TABLEARG) ?
Index: sys/netinet/ipfw/ip_fw_sockopt.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/ipfw/ip_fw_sockopt.c,v
retrieving revision 1.17
diff -c -u -r1.17 ip_fw_sockopt.c
--- sys/netinet/ipfw/ip_fw_sockopt.c	7 Apr 2010 08:23:58 -0000	1.17
+++ sys/netinet/ipfw/ip_fw_sockopt.c	27 Sep 2010 14:25:58 -0000
@@ -572,6 +572,7 @@
 		case O_IPTOS:
 		case O_IPPRECEDENCE:
 		case O_IPVER:
+		case O_SOCKARG:
 		case O_TCPWIN:
 		case O_TCPFLAGS:
 		case O_TCPOPTS:
Index: sys/sys/socket.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/socket.h,v
retrieving revision 1.105
diff -c -u -r1.105 socket.h
--- sys/sys/socket.h	9 Jan 2010 23:24:49 -0000	1.105
+++ sys/sys/socket.h	27 Sep 2010 14:25:59 -0000
@@ -137,6 +137,7 @@
 #define	SO_LISTENQLEN	0x1012		/* socket's complete queue length */
 #define	SO_LISTENINCQLEN	0x1013	/* socket's incomplete queue length */
 #define	SO_SETFIB	0x1014		/* use this FIB to route */
+#define	SO_USER_COOKIE	0x1015		/* use this pipe to throttle */
 #endif
 
 /*
Index: sys/sys/socketvar.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/socketvar.h,v
retrieving revision 1.174
diff -c -u -r1.174 socketvar.h
--- sys/sys/socketvar.h	18 Sep 2010 11:18:42 -0000	1.174
+++ sys/sys/socketvar.h	27 Sep 2010 14:25:59 -0000
@@ -118,6 +118,7 @@
 		char	*so_accept_filter_str;	/* saved user args */
 	} *so_accf;
 	int so_fibnum;		/* routing domain for this socket */
+	uint32_t so_user_cookie;
 };
 
 /*

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?AANLkTi=GozyQv%2BxuXS7xT6Kzaa7XaFxAOrihKdKdnCge>