Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F136301723
D9873.id26016.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D9873.id26016.diff
View Options
Index: head/sys/netpfil/ipfw/ip_fw2.c
===================================================================
--- head/sys/netpfil/ipfw/ip_fw2.c
+++ head/sys/netpfil/ipfw/ip_fw2.c
@@ -382,8 +382,8 @@
/* Check by name or by IP address */
if (cmd->name[0] != '\0') { /* match by name */
if (cmd->name[0] == '\1') /* use tablearg to match */
- return ipfw_lookup_table_extended(chain, cmd->p.kidx, 0,
- &ifp->if_index, tablearg);
+ return ipfw_lookup_table(chain, cmd->p.kidx, 0,
+ &ifp->if_index, tablearg);
/* Check name */
if (cmd->p.glob) {
if (fnmatch(cmd->name, ifp->if_xname, 0) == 0)
@@ -1455,86 +1455,130 @@
src_ip.s_addr);
break;
- case O_IP_SRC_LOOKUP:
case O_IP_DST_LOOKUP:
- if (is_ipv4) {
- uint32_t key =
- (cmd->opcode == O_IP_DST_LOOKUP) ?
- dst_ip.s_addr : src_ip.s_addr;
- uint32_t v = 0;
-
- if (cmdlen > F_INSN_SIZE(ipfw_insn_u32)) {
- /* generic lookup. The key must be
- * in 32bit big-endian format.
- */
- v = ((ipfw_insn_u32 *)cmd)->d[1];
- if (v == 0)
- key = dst_ip.s_addr;
- else if (v == 1)
- key = src_ip.s_addr;
- else if (v == 6) /* dscp */
- key = (ip->ip_tos >> 2) & 0x3f;
- else if (offset != 0)
- break;
- else if (proto != IPPROTO_TCP &&
- proto != IPPROTO_UDP)
- break;
- else if (v == 2)
- key = dst_port;
- else if (v == 3)
- key = src_port;
+ {
+ void *pkey;
+ uint32_t vidx, key;
+ uint16_t keylen;
+
+ if (cmdlen > F_INSN_SIZE(ipfw_insn_u32)) {
+ /* Determine lookup key type */
+ vidx = ((ipfw_insn_u32 *)cmd)->d[1];
+ if (vidx != 4 /* uid */ &&
+ vidx != 5 /* jail */ &&
+ is_ipv6 == 0 && is_ipv4 == 0)
+ break;
+ /* Determine key length */
+ if (vidx == 0 /* dst-ip */ ||
+ vidx == 1 /* src-ip */)
+ keylen = is_ipv6 ?
+ sizeof(struct in6_addr):
+ sizeof(in_addr_t);
+ else {
+ keylen = sizeof(key);
+ pkey = &key;
+ }
+ if (vidx == 0 /* dst-ip */)
+ pkey = is_ipv4 ? (void *)&dst_ip:
+ (void *)&args->f_id.dst_ip6;
+ else if (vidx == 1 /* src-ip */)
+ pkey = is_ipv4 ? (void *)&src_ip:
+ (void *)&args->f_id.src_ip6;
+ else if (vidx == 6 /* dscp */) {
+ if (is_ipv4)
+ key = ip->ip_tos >> 2;
+ else {
+ key = args->f_id.flow_id6;
+ key = (key & 0x0f) << 2 |
+ (key & 0xf000) >> 14;
+ }
+ key &= 0x3f;
+ } else if (vidx == 2 /* dst-port */ ||
+ vidx == 3 /* src-port */) {
+ /* Skip fragments */
+ if (offset != 0)
+ break;
+ /* Skip proto without ports */
+ if (proto != IPPROTO_TCP &&
+ proto != IPPROTO_UDP &&
+ proto != IPPROTO_SCTP)
+ break;
+ if (vidx == 2 /* dst-port */)
+ key = dst_port;
+ else
+ key = src_port;
+ }
#ifndef USERSPACE
- else if (v == 4 || v == 5) {
- check_uidgid(
- (ipfw_insn_u32 *)cmd,
- args, &ucred_lookup,
+ else if (vidx == 4 /* uid */ ||
+ vidx == 5 /* jail */) {
+ check_uidgid(
+ (ipfw_insn_u32 *)cmd,
+ args, &ucred_lookup,
#ifdef __FreeBSD__
- &ucred_cache);
- if (v == 4 /* O_UID */)
- key = ucred_cache->cr_uid;
- else if (v == 5 /* O_JAIL */)
- key = ucred_cache->cr_prison->pr_id;
+ &ucred_cache);
+ if (vidx == 4 /* uid */)
+ key = ucred_cache->cr_uid;
+ else if (vidx == 5 /* jail */)
+ key = ucred_cache->cr_prison->pr_id;
#else /* !__FreeBSD__ */
- (void *)&ucred_cache);
- if (v ==4 /* O_UID */)
- key = ucred_cache.uid;
- else if (v == 5 /* O_JAIL */)
- key = ucred_cache.xid;
+ (void *)&ucred_cache);
+ if (vidx == 4 /* uid */)
+ key = ucred_cache.uid;
+ else if (vidx == 5 /* jail */)
+ key = ucred_cache.xid;
#endif /* !__FreeBSD__ */
}
#endif /* !USERSPACE */
else
- break;
- }
- match = ipfw_lookup_table(chain,
- cmd->arg1, key, &v);
- if (!match)
+ break;
+ match = ipfw_lookup_table(chain,
+ cmd->arg1, keylen, pkey, &vidx);
+ if (!match)
+ break;
+ tablearg = vidx;
break;
- if (cmdlen == F_INSN_SIZE(ipfw_insn_u32))
- match = ((ipfw_insn_u32 *)cmd)->d[0] ==
- TARG_VAL(chain, v, tag);
- else
- tablearg = v;
+ }
+ /* cmdlen =< F_INSN_SIZE(ipfw_insn_u32) */
+ /* FALLTHROUGH */
+ }
+ case O_IP_SRC_LOOKUP:
+ {
+ void *pkey;
+ uint32_t vidx;
+ uint16_t keylen;
+
+ if (is_ipv4) {
+ keylen = sizeof(in_addr_t);
+ if (cmd->opcode == O_IP_DST_LOOKUP)
+ pkey = &dst_ip;
+ else
+ pkey = &src_ip;
} else if (is_ipv6) {
- uint32_t v = 0;
- void *pkey = (cmd->opcode == O_IP_DST_LOOKUP) ?
- &args->f_id.dst_ip6: &args->f_id.src_ip6;
- match = ipfw_lookup_table_extended(chain,
- cmd->arg1,
- sizeof(struct in6_addr),
- pkey, &v);
- if (cmdlen == F_INSN_SIZE(ipfw_insn_u32))
- match = ((ipfw_insn_u32 *)cmd)->d[0] ==
- TARG_VAL(chain, v, tag);
- if (match)
- tablearg = v;
+ keylen = sizeof(struct in6_addr);
+ if (cmd->opcode == O_IP_DST_LOOKUP)
+ pkey = &args->f_id.dst_ip6;
+ else
+ pkey = &args->f_id.src_ip6;
+ } else
+ break;
+ match = ipfw_lookup_table(chain, cmd->arg1,
+ keylen, pkey, &vidx);
+ if (!match)
+ break;
+ if (cmdlen == F_INSN_SIZE(ipfw_insn_u32)) {
+ match = ((ipfw_insn_u32 *)cmd)->d[0] ==
+ TARG_VAL(chain, vidx, tag);
+ if (!match)
+ break;
}
+ tablearg = vidx;
break;
+ }
case O_IP_FLOW_LOOKUP:
{
uint32_t v = 0;
- match = ipfw_lookup_table_extended(chain,
+ match = ipfw_lookup_table(chain,
cmd->arg1, 0, &args->f_id, &v);
if (cmdlen == F_INSN_SIZE(ipfw_insn_u32))
match = ((ipfw_insn_u32 *)cmd)->d[0] ==
Index: head/sys/netpfil/ipfw/ip_fw_private.h
===================================================================
--- head/sys/netpfil/ipfw/ip_fw_private.h
+++ head/sys/netpfil/ipfw/ip_fw_private.h
@@ -741,10 +741,8 @@
typedef int (table_lookup_t)(struct table_info *ti, void *key, uint32_t keylen,
uint32_t *val);
-int ipfw_lookup_table(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
- uint32_t *val);
-int ipfw_lookup_table_extended(struct ip_fw_chain *ch, uint16_t tbl,
- uint16_t plen, void *paddr, uint32_t *val);
+int ipfw_lookup_table(struct ip_fw_chain *ch, uint16_t tbl, uint16_t plen,
+ void *paddr, uint32_t *val);
struct named_object *ipfw_objhash_lookup_table_kidx(struct ip_fw_chain *ch,
uint16_t kidx);
int ipfw_ref_table(struct ip_fw_chain *ch, ipfw_obj_ntlv *ntlv, uint16_t *kidx);
Index: head/sys/netpfil/ipfw/ip_fw_sockopt.c
===================================================================
--- head/sys/netpfil/ipfw/ip_fw_sockopt.c
+++ head/sys/netpfil/ipfw/ip_fw_sockopt.c
@@ -1826,6 +1826,8 @@
break;
case O_IP_SRC_LOOKUP:
+ if (cmdlen > F_INSN_SIZE(ipfw_insn_u32))
+ goto bad_size;
case O_IP_DST_LOOKUP:
if (cmd->arg1 >= V_fw_tables_max) {
printf("ipfw: invalid table number %d\n",
Index: head/sys/netpfil/ipfw/ip_fw_table.c
===================================================================
--- head/sys/netpfil/ipfw/ip_fw_table.c
+++ head/sys/netpfil/ipfw/ip_fw_table.c
@@ -1657,30 +1657,13 @@
}
/*
- * Lookup an IP @addr in table @tbl.
- * Stores found value in @val.
- *
- * Returns 1 if @addr was found.
- */
-int
-ipfw_lookup_table(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
- uint32_t *val)
-{
- struct table_info *ti;
-
- ti = KIDX_TO_TI(ch, tbl);
-
- return (ti->lookup(ti, &addr, sizeof(in_addr_t), val));
-}
-
-/*
* Lookup an arbtrary key @paddr of legth @plen in table @tbl.
* Stores found value in @val.
*
* Returns 1 if key was found.
*/
int
-ipfw_lookup_table_extended(struct ip_fw_chain *ch, uint16_t tbl, uint16_t plen,
+ipfw_lookup_table(struct ip_fw_chain *ch, uint16_t tbl, uint16_t plen,
void *paddr, uint32_t *val)
{
struct table_info *ti;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Nov 18, 2:54 AM (13 h, 58 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25442345
Default Alt Text
D9873.id26016.diff (8 KB)
Attached To
Mode
D9873: Fix ipfw tables related PR 217262 and 217292
Attached
Detach File
Event Timeline
Log In to Comment