summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authorluigi <luigi@FreeBSD.org>2010-11-12 13:05:17 +0000
committerluigi <luigi@FreeBSD.org>2010-11-12 13:05:17 +0000
commite7ccc85b8fa77badd0aebc86e7657d29f3710e08 (patch)
treefe24fb085ca1922cd3a49053ea6e53a072b83c11 /sys/netinet
parentd5e8d236f4009fc2611f996c317e94b2c8649cf5 (diff)
downloadFreeBSD-src-e7ccc85b8fa77badd0aebc86e7657d29f3710e08.zip
FreeBSD-src-e7ccc85b8fa77badd0aebc86e7657d29f3710e08.tar.gz
The first customer of the SO_USER_COOKIE option:
the "sockarg" ipfw option matches packets associated to a local socket and with a non-zero so_user_cookie value. The value is made available as tablearg, so it can be used as a skipto target or pipe number in ipfw/dummynet rules. Code by Paul Joe, manpage by me. Submitted by: Paul Joe MFC after: 1 week
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/ip_fw.h3
-rw-r--r--sys/netinet/ipfw/ip_fw2.c33
-rw-r--r--sys/netinet/ipfw/ip_fw_sockopt.c1
3 files changed, 37 insertions, 0 deletions
diff --git a/sys/netinet/ip_fw.h b/sys/netinet/ip_fw.h
index cf5d8d0..fdcc5fd 100644
--- a/sys/netinet/ip_fw.h
+++ b/sys/netinet/ip_fw.h
@@ -192,10 +192,13 @@ enum ipfw_opcodes { /* arguments (4 byte each) */
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.
diff --git a/sys/netinet/ipfw/ip_fw2.c b/sys/netinet/ipfw/ip_fw2.c
index c291089..43b2d11 100644
--- a/sys/netinet/ipfw/ip_fw2.c
+++ b/sys/netinet/ipfw/ip_fw2.c
@@ -1801,6 +1801,39 @@ do { \
match = 1;
break;
+ case O_SOCKARG: {
+ struct inpcb *inp = args->inp;
+ struct inpcbinfo *pi;
+
+ if (is_ipv6) /* XXX can we remove this ? */
+ 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) ?
diff --git a/sys/netinet/ipfw/ip_fw_sockopt.c b/sys/netinet/ipfw/ip_fw_sockopt.c
index c505728..0c903ee 100644
--- a/sys/netinet/ipfw/ip_fw_sockopt.c
+++ b/sys/netinet/ipfw/ip_fw_sockopt.c
@@ -572,6 +572,7 @@ check_ipfw_struct(struct ip_fw *rule, int size)
case O_IPTOS:
case O_IPPRECEDENCE:
case O_IPVER:
+ case O_SOCKARG:
case O_TCPWIN:
case O_TCPFLAGS:
case O_TCPOPTS:
OpenPOWER on IntegriCloud