diff options
author | luigi <luigi@FreeBSD.org> | 2009-12-15 09:46:27 +0000 |
---|---|---|
committer | luigi <luigi@FreeBSD.org> | 2009-12-15 09:46:27 +0000 |
commit | 84d17b9dde0bca3ba11491efd293d666259c204f (patch) | |
tree | 6801a26cde90c352ef557ec26fb56589ca42c654 /sys/netinet | |
parent | 507718c519a5c35f2ef041763a9715b79c33b177 (diff) | |
download | FreeBSD-src-84d17b9dde0bca3ba11491efd293d666259c204f.zip FreeBSD-src-84d17b9dde0bca3ba11491efd293d666259c204f.tar.gz |
implement a new match option,
lookup {dst-ip|src-ip|dst-port|src-port|uid|jail} N
which searches the specified field in table N and sets tablearg
accordingly.
With dst-ip or src-ip the option replicates two existing options.
When used with other arguments, the option can be useful to
quickly dispatch traffic based on other fields.
Work supported by the Onelab project.
MFC after: 1 week
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/ipfw/ip_fw2.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/sys/netinet/ipfw/ip_fw2.c b/sys/netinet/ipfw/ip_fw2.c index 601d80e..7010e19 100644 --- a/sys/netinet/ipfw/ip_fw2.c +++ b/sys/netinet/ipfw/ip_fw2.c @@ -2819,6 +2819,36 @@ do { \ dst_ip.s_addr : src_ip.s_addr; uint32_t v = 0; + if (cmdlen > F_INSN_SIZE(ipfw_insn_u32)) { + /* generic lookup */ + v = ((ipfw_insn_u32 *)cmd)->d[1]; + if (v == 0) + a = dst_ip.s_addr; + else if (v == 1) + a = src_ip.s_addr; + else if (offset != 0) + break; + else if (proto != IPPROTO_TCP && + proto != IPPROTO_UDP) + break; + else if (v == 2) + a = dst_port; + else if (v == 3) + a = src_port; + else if (v == 4 || v == 5) { + check_uidgid( + (ipfw_insn_u32 *)cmd, + proto, oif, + dst_ip, dst_port, + src_ip, src_port, &ucred_cache, + &ucred_lookup, args->inp); + if (v == 4 /* O_UID */) + a = ucred_cache->cr_uid; + else if (v == 5 /* O_JAIL */) + a = ucred_cache->cr_prison->pr_id; + } else + break; + } match = lookup_table(chain, cmd->arg1, a, &v); if (!match) @@ -4160,6 +4190,7 @@ check_ipfw_struct(struct ip_fw *rule, int size) return (EINVAL); } if (cmdlen != F_INSN_SIZE(ipfw_insn) && + cmdlen != F_INSN_SIZE(ipfw_insn_u32) + 1 && cmdlen != F_INSN_SIZE(ipfw_insn_u32)) goto bad_size; break; |