diff options
author | luigi <luigi@FreeBSD.org> | 2010-11-12 13:05:17 +0000 |
---|---|---|
committer | luigi <luigi@FreeBSD.org> | 2010-11-12 13:05:17 +0000 |
commit | e7ccc85b8fa77badd0aebc86e7657d29f3710e08 (patch) | |
tree | fe24fb085ca1922cd3a49053ea6e53a072b83c11 /sys/netinet | |
parent | d5e8d236f4009fc2611f996c317e94b2c8649cf5 (diff) | |
download | FreeBSD-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.h | 3 | ||||
-rw-r--r-- | sys/netinet/ipfw/ip_fw2.c | 33 | ||||
-rw-r--r-- | sys/netinet/ipfw/ip_fw_sockopt.c | 1 |
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: |