svn commit: r215179 - in head: sbin/ipfw sys/netinet
sys/netinet/ipfw
Luigi Rizzo
luigi at FreeBSD.org
Fri Nov 12 13:05:17 UTC 2010
Author: luigi
Date: Fri Nov 12 13:05:17 2010
New Revision: 215179
URL: http://svn.freebsd.org/changeset/base/215179
Log:
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
Modified:
head/sbin/ipfw/ipfw.8
head/sbin/ipfw/ipfw2.c
head/sbin/ipfw/ipfw2.h
head/sys/netinet/ip_fw.h
head/sys/netinet/ipfw/ip_fw2.c
head/sys/netinet/ipfw/ip_fw_sockopt.c
Modified: head/sbin/ipfw/ipfw.8
==============================================================================
--- head/sbin/ipfw/ipfw.8 Fri Nov 12 13:02:26 2010 (r215178)
+++ head/sbin/ipfw/ipfw.8 Fri Nov 12 13:05:17 2010 (r215179)
@@ -1510,6 +1510,17 @@ interface.
Matches TCP packets that have the SYN bit set but no ACK bit.
This is the short form of
.Dq Li tcpflags\ syn,!ack .
+.It Cm sockarg
+Matches packets that are associated to a local socket and
+for which the SO_USER_COOKIE socket option has been set
+to a non-zero value. As a side effect, the value of the
+option is made available as
+.Cm tablearg
+value, which in turn can be used as
+.Cm skipto
+or
+.Cm pipe
+number.
.It Cm src-ip Ar ip-address
Matches IPv4 packets whose source IP is one of the address(es)
specified as an argument.
Modified: head/sbin/ipfw/ipfw2.c
==============================================================================
--- head/sbin/ipfw/ipfw2.c Fri Nov 12 13:02:26 2010 (r215178)
+++ head/sbin/ipfw/ipfw2.c Fri Nov 12 13:05:17 2010 (r215179)
@@ -266,6 +266,7 @@ static struct _s_x rule_options[] = {
{ "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 @@ show_ipfw(struct ip_fw *rule, int pcwidt
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 @@ read_options:
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;
Modified: head/sbin/ipfw/ipfw2.h
==============================================================================
--- head/sbin/ipfw/ipfw2.h Fri Nov 12 13:02:26 2010 (r215178)
+++ head/sbin/ipfw/ipfw2.h Fri Nov 12 13:05:17 2010 (r215179)
@@ -199,6 +199,7 @@ enum tokens {
TOK_FIB,
TOK_SETFIB,
TOK_LOOKUP,
+ TOK_SOCKARG,
};
/*
* the following macro returns an error message if we run out of
Modified: head/sys/netinet/ip_fw.h
==============================================================================
--- head/sys/netinet/ip_fw.h Fri Nov 12 13:02:26 2010 (r215178)
+++ head/sys/netinet/ip_fw.h Fri Nov 12 13:05:17 2010 (r215179)
@@ -192,10 +192,13 @@ enum ipfw_opcodes { /* arguments (4 byt
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.
Modified: head/sys/netinet/ipfw/ip_fw2.c
==============================================================================
--- head/sys/netinet/ipfw/ip_fw2.c Fri Nov 12 13:02:26 2010 (r215178)
+++ head/sys/netinet/ipfw/ip_fw2.c Fri Nov 12 13:05:17 2010 (r215179)
@@ -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) ?
Modified: head/sys/netinet/ipfw/ip_fw_sockopt.c
==============================================================================
--- head/sys/netinet/ipfw/ip_fw_sockopt.c Fri Nov 12 13:02:26 2010 (r215178)
+++ head/sys/netinet/ipfw/ip_fw_sockopt.c Fri Nov 12 13:05:17 2010 (r215179)
@@ -572,6 +572,7 @@ check_ipfw_struct(struct ip_fw *rule, in
case O_IPTOS:
case O_IPPRECEDENCE:
case O_IPVER:
+ case O_SOCKARG:
case O_TCPWIN:
case O_TCPFLAGS:
case O_TCPOPTS:
More information about the svn-src-head
mailing list