Changeset View
Changeset View
Standalone View
Standalone View
sys/netpfil/ipfw/ip_fw2.c
Show First 20 Lines • Show All 2,032 Lines • ▼ Show 20 Lines | #endif | ||||
case O_IP_SRC: | case O_IP_SRC: | ||||
match = is_ipv4 && | match = is_ipv4 && | ||||
(((ipfw_insn_ip *)cmd)->addr.s_addr == | (((ipfw_insn_ip *)cmd)->addr.s_addr == | ||||
src_ip.s_addr); | src_ip.s_addr); | ||||
break; | break; | ||||
case O_IP_DST_LOOKUP: | case O_IP_DST_LOOKUP: | ||||
{ | { | ||||
if (cmdlen > F_INSN_SIZE(ipfw_insn_u32)) { | |||||
void *pkey; | void *pkey; | ||||
uint32_t vidx, key; | uint32_t vidx, key; | ||||
uint16_t keylen; | uint16_t keylen = 0; /* zero if can't match the packet */ | ||||
if (cmdlen > F_INSN_SIZE(ipfw_insn_u32)) { | |||||
/* Determine lookup key type */ | /* Determine lookup key type */ | ||||
vidx = ((ipfw_insn_u32 *)cmd)->d[1]; | vidx = ((ipfw_insn_u32 *)cmd)->d[1]; | ||||
if (vidx != 4 /* uid */ && | switch (vidx) { | ||||
melifaro: Looks like there's plenty of options here.
Probably worth rethinking this part of code &… | |||||
Done Inline ActionsYeah, switch sounds good smalukav_gmail.com: Yeah, switch sounds good | |||||
vidx != 5 /* jail */ && | case LOOKUP_DST_IP: | ||||
is_ipv6 == 0 && is_ipv4 == 0) | case LOOKUP_SRC_IP: | ||||
/* Need IP frame */ | |||||
if (is_ipv6 == 0 && is_ipv4 == 0) | |||||
break; | break; | ||||
/* Determine key length */ | if (vidx == LOOKUP_DST_IP) | ||||
if (vidx == 0 /* dst-ip */ || | pkey = is_ipv6 ? | ||||
vidx == 1 /* src-ip */) | (void *)&args->f_id.dst_ip6: | ||||
(void *)&dst_ip; | |||||
else | |||||
pkey = is_ipv6 ? | |||||
(void *)&args->f_id.src_ip6: | |||||
(void *)&src_ip; | |||||
keylen = is_ipv6 ? | keylen = is_ipv6 ? | ||||
sizeof(struct in6_addr): | sizeof(struct in6_addr): | ||||
sizeof(in_addr_t); | sizeof(in_addr_t); | ||||
else { | break; | ||||
keylen = sizeof(key); | case LOOKUP_DST_PORT: | ||||
pkey = &key; | case LOOKUP_SRC_PORT: | ||||
} | /* Need IP frame */ | ||||
if (vidx == 0 /* dst-ip */) | if (is_ipv6 == 0 && is_ipv4 == 0) | ||||
pkey = is_ipv4 ? (void *)&dst_ip: | break; | ||||
(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 = IPV6_DSCP( | |||||
(struct ip6_hdr *)ip) >> 2; | |||||
key &= 0x3f; | |||||
} else if (vidx == 2 /* dst-port */ || | |||||
vidx == 3 /* src-port */) { | |||||
/* Skip fragments */ | /* Skip fragments */ | ||||
if (offset != 0) | if (offset != 0) | ||||
break; | break; | ||||
/* Skip proto without ports */ | /* Skip proto without ports */ | ||||
if (proto != IPPROTO_TCP && | if (proto != IPPROTO_TCP && | ||||
proto != IPPROTO_UDP && | proto != IPPROTO_UDP && | ||||
proto != IPPROTO_UDPLITE && | proto != IPPROTO_UDPLITE && | ||||
proto != IPPROTO_SCTP) | proto != IPPROTO_SCTP) | ||||
break; | break; | ||||
if (vidx == 2 /* dst-port */) | key = vidx == LOOKUP_DST_PORT ? | ||||
key = dst_port; | dst_port: | ||||
else | src_port; | ||||
key = src_port; | pkey = &key; | ||||
} | keylen = sizeof(key); | ||||
#ifndef USERSPACE | break; | ||||
else if (vidx == 4 /* uid */ || | case LOOKUP_UID: | ||||
vidx == 5 /* jail */) { | case LOOKUP_JAIL: | ||||
check_uidgid( | check_uidgid( | ||||
(ipfw_insn_u32 *)cmd, | (ipfw_insn_u32 *)cmd, | ||||
args, &ucred_lookup, | args, &ucred_lookup, | ||||
#ifdef __FreeBSD__ | |||||
&ucred_cache); | &ucred_cache); | ||||
if (vidx == 4 /* uid */) | key = vidx == LOOKUP_UID ? | ||||
key = ucred_cache->cr_uid; | ucred_cache->cr_uid: | ||||
else if (vidx == 5 /* jail */) | ucred_cache->cr_prison->pr_id; | ||||
key = ucred_cache->cr_prison->pr_id; | pkey = &key; | ||||
#else /* !__FreeBSD__ */ | keylen = sizeof(key); | ||||
(void *)&ucred_cache); | break; | ||||
if (vidx == 4 /* uid */) | case LOOKUP_DSCP: | ||||
key = ucred_cache.uid; | /* Need IP frame */ | ||||
else if (vidx == 5 /* jail */) | if (is_ipv6 == 0 && is_ipv4 == 0) | ||||
key = ucred_cache.xid; | break; | ||||
#endif /* !__FreeBSD__ */ | if (is_ipv6) | ||||
} | key = IPV6_DSCP( | ||||
#endif /* !USERSPACE */ | (struct ip6_hdr *)ip) >> 2; | ||||
else | else | ||||
key = ip->ip_tos >> 2; | |||||
pkey = &key; | |||||
keylen = sizeof(key); | |||||
break; | break; | ||||
case LOOKUP_DST_MAC: | |||||
case LOOKUP_SRC_MAC: | |||||
/* Need ether frame */ | |||||
if ((args->flags & IPFW_ARGS_ETHER) == 0) | |||||
break; | |||||
pkey = vidx == LOOKUP_DST_MAC ? | |||||
eh->ether_dhost: | |||||
eh->ether_shost; | |||||
keylen = ETHER_ADDR_LEN; | |||||
break; | |||||
} | |||||
if (keylen == 0) | |||||
break; | |||||
match = ipfw_lookup_table(chain, | match = ipfw_lookup_table(chain, | ||||
cmd->arg1, keylen, pkey, &vidx); | cmd->arg1, keylen, pkey, &vidx); | ||||
if (!match) | if (!match) | ||||
break; | break; | ||||
tablearg = vidx; | tablearg = vidx; | ||||
break; | break; | ||||
} | } | ||||
/* cmdlen =< F_INSN_SIZE(ipfw_insn_u32) */ | /* cmdlen =< F_INSN_SIZE(ipfw_insn_u32) */ | ||||
Show All 14 Lines | #endif | ||||
} else if (is_ipv6) { | } else if (is_ipv6) { | ||||
keylen = sizeof(struct in6_addr); | keylen = sizeof(struct in6_addr); | ||||
if (cmd->opcode == O_IP_DST_LOOKUP) | if (cmd->opcode == O_IP_DST_LOOKUP) | ||||
pkey = &args->f_id.dst_ip6; | pkey = &args->f_id.dst_ip6; | ||||
else | else | ||||
pkey = &args->f_id.src_ip6; | pkey = &args->f_id.src_ip6; | ||||
} else | } else | ||||
break; | 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_MAC_SRC_LOOKUP: | |||||
case O_MAC_DST_LOOKUP: | |||||
{ | |||||
void *pkey; | |||||
uint32_t vidx; | |||||
uint16_t keylen = ETHER_ADDR_LEN; | |||||
/* Need ether frame */ | |||||
if ((args->flags & IPFW_ARGS_ETHER) == 0) | |||||
break; | |||||
if (cmd->opcode == O_MAC_DST_LOOKUP) | |||||
pkey = eh->ether_dhost; | |||||
else | |||||
pkey = eh->ether_shost; | |||||
match = ipfw_lookup_table(chain, cmd->arg1, | match = ipfw_lookup_table(chain, cmd->arg1, | ||||
keylen, pkey, &vidx); | keylen, pkey, &vidx); | ||||
if (!match) | if (!match) | ||||
break; | break; | ||||
if (cmdlen == F_INSN_SIZE(ipfw_insn_u32)) { | if (cmdlen == F_INSN_SIZE(ipfw_insn_u32)) { | ||||
match = ((ipfw_insn_u32 *)cmd)->d[0] == | match = ((ipfw_insn_u32 *)cmd)->d[0] == | ||||
TARG_VAL(chain, vidx, tag); | TARG_VAL(chain, vidx, tag); | ||||
if (!match) | if (!match) | ||||
▲ Show 20 Lines • Show All 1,473 Lines • Show Last 20 Lines |
Looks like there's plenty of options here.
Probably worth rethinking this part of code & consider using switch() instead of many if's for each vidx?