Changeset View
Changeset View
Standalone View
Standalone View
head/sys/netpfil/ipfw/ip_fw2.c
Show First 20 Lines • Show All 1,116 Lines • ▼ Show 20 Lines | #endif | ||||
/* | /* | ||||
* dyn_dir = MATCH_UNKNOWN when rules unchecked, | * dyn_dir = MATCH_UNKNOWN when rules unchecked, | ||||
* MATCH_NONE when checked and not matched (q = NULL), | * MATCH_NONE when checked and not matched (q = NULL), | ||||
* MATCH_FORWARD or MATCH_REVERSE otherwise (q != NULL) | * MATCH_FORWARD or MATCH_REVERSE otherwise (q != NULL) | ||||
*/ | */ | ||||
int dyn_dir = MATCH_UNKNOWN; | int dyn_dir = MATCH_UNKNOWN; | ||||
uint16_t dyn_name = 0; | uint16_t dyn_name = 0; | ||||
ipfw_dyn_rule *q = NULL; | struct ip_fw *q = NULL; | ||||
struct ip_fw_chain *chain = &V_layer3_chain; | struct ip_fw_chain *chain = &V_layer3_chain; | ||||
/* | /* | ||||
* We store in ulp a pointer to the upper layer protocol header. | * We store in ulp a pointer to the upper layer protocol header. | ||||
* In the ipv4 case this is easy to determine from the header, | * In the ipv4 case this is easy to determine from the header, | ||||
* but for ipv6 we might have some additional headers in the middle. | * but for ipv6 we might have some additional headers in the middle. | ||||
* ulp is NULL if not found. | * ulp is NULL if not found. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 1,168 Lines • ▼ Show 20 Lines | #endif /* !USERSPACE */ | ||||
* the entry is not found. | * the entry is not found. | ||||
* The result of the lookup is cached so that | * The result of the lookup is cached so that | ||||
* further instances of these opcodes become NOPs. | * further instances of these opcodes become NOPs. | ||||
* The jump to the next rule is done by setting | * The jump to the next rule is done by setting | ||||
* l=0, cmdlen=0. | * l=0, cmdlen=0. | ||||
*/ | */ | ||||
case O_LIMIT: | case O_LIMIT: | ||||
case O_KEEP_STATE: | case O_KEEP_STATE: | ||||
if (ipfw_install_state(chain, f, | if (ipfw_dyn_install_state(chain, f, | ||||
(ipfw_insn_limit *)cmd, args, tablearg)) { | (ipfw_insn_limit *)cmd, args, tablearg)) { | ||||
/* error or limit violation */ | /* error or limit violation */ | ||||
retval = IP_FW_DENY; | retval = IP_FW_DENY; | ||||
l = 0; /* exit inner loop */ | l = 0; /* exit inner loop */ | ||||
done = 1; /* exit outer loop */ | done = 1; /* exit outer loop */ | ||||
} | } | ||||
match = 1; | match = 1; | ||||
break; | break; | ||||
Show All 23 Lines | #endif /* !USERSPACE */ | ||||
* (dyn_dir != MATCH_UNKNOWN && dyn_name == 0) | * (dyn_dir != MATCH_UNKNOWN && dyn_name == 0) | ||||
* means previous lookup was for `any' name | * means previous lookup was for `any' name | ||||
* and it didn't find rule. No need to do | * and it didn't find rule. No need to do | ||||
* lookup again. | * lookup again. | ||||
*/ | */ | ||||
if ((dyn_dir == MATCH_UNKNOWN || | if ((dyn_dir == MATCH_UNKNOWN || | ||||
(dyn_name != 0 && | (dyn_name != 0 && | ||||
dyn_name != cmd->arg1)) && | dyn_name != cmd->arg1)) && | ||||
(q = ipfw_lookup_dyn_rule(&args->f_id, | (q = ipfw_dyn_lookup_state(&args->f_id, | ||||
&dyn_dir, proto == IPPROTO_TCP ? | ulp, pktlen, &dyn_dir, | ||||
TCP(ulp): NULL, | |||||
(dyn_name = cmd->arg1))) != NULL) { | (dyn_name = cmd->arg1))) != NULL) { | ||||
/* | /* | ||||
* Found dynamic entry, update stats | * Found dynamic entry, jump to the | ||||
* and jump to the 'action' part of | * 'action' part of the parent rule | ||||
* the parent rule by setting | * by setting f, cmd, l and clearing | ||||
* f, cmd, l and clearing cmdlen. | * cmdlen. | ||||
*/ | */ | ||||
IPFW_INC_DYN_COUNTER(q, pktlen); | f = q; | ||||
/* XXX we would like to have f_pos | /* XXX we would like to have f_pos | ||||
* readily accessible in the dynamic | * readily accessible in the dynamic | ||||
* rule, instead of having to | * rule, instead of having to | ||||
* lookup q->rule. | * lookup q->rule. | ||||
*/ | */ | ||||
f = q->rule; | |||||
f_pos = ipfw_find_rule(chain, | f_pos = ipfw_find_rule(chain, | ||||
f->rulenum, f->id); | f->rulenum, f->id); | ||||
cmd = ACTION_PTR(f); | cmd = ACTION_PTR(f); | ||||
l = f->cmd_len - f->act_ofs; | l = f->cmd_len - f->act_ofs; | ||||
ipfw_dyn_unlock(q); | |||||
cmdlen = 0; | cmdlen = 0; | ||||
match = 1; | match = 1; | ||||
break; | break; | ||||
} | } | ||||
/* | /* | ||||
* Dynamic entry not found. If CHECK_STATE, | * Dynamic entry not found. If CHECK_STATE, | ||||
* skip to next rule, if PROBE_STATE just | * skip to next rule, if PROBE_STATE just | ||||
* ignore and continue with next opcode. | * ignore and continue with next opcode. | ||||
▲ Show 20 Lines • Show All 195 Lines • ▼ Show 20 Lines | #endif | ||||
retval = IP_FW_DENY; | retval = IP_FW_DENY; | ||||
l = 0; /* exit inner loop */ | l = 0; /* exit inner loop */ | ||||
done = 1; /* exit outer loop */ | done = 1; /* exit outer loop */ | ||||
break; | break; | ||||
case O_FORWARD_IP: | case O_FORWARD_IP: | ||||
if (args->eh) /* not valid on layer2 pkts */ | if (args->eh) /* not valid on layer2 pkts */ | ||||
break; | break; | ||||
if (q == NULL || q->rule != f || | if (q != f || dyn_dir == MATCH_FORWARD) { | ||||
dyn_dir == MATCH_FORWARD) { | |||||
struct sockaddr_in *sa; | struct sockaddr_in *sa; | ||||
sa = &(((ipfw_insn_sa *)cmd)->sa); | sa = &(((ipfw_insn_sa *)cmd)->sa); | ||||
if (sa->sin_addr.s_addr == INADDR_ANY) { | if (sa->sin_addr.s_addr == INADDR_ANY) { | ||||
#ifdef INET6 | #ifdef INET6 | ||||
/* | /* | ||||
* We use O_FORWARD_IP opcode for | * We use O_FORWARD_IP opcode for | ||||
* fwd rule with tablearg, but tables | * fwd rule with tablearg, but tables | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | #endif | ||||
l = 0; /* exit inner loop */ | l = 0; /* exit inner loop */ | ||||
done = 1; /* exit outer loop */ | done = 1; /* exit outer loop */ | ||||
break; | break; | ||||
#ifdef INET6 | #ifdef INET6 | ||||
case O_FORWARD_IP6: | case O_FORWARD_IP6: | ||||
if (args->eh) /* not valid on layer2 pkts */ | if (args->eh) /* not valid on layer2 pkts */ | ||||
break; | break; | ||||
if (q == NULL || q->rule != f || | if (q != f || dyn_dir == MATCH_FORWARD) { | ||||
dyn_dir == MATCH_FORWARD) { | |||||
struct sockaddr_in6 *sin6; | struct sockaddr_in6 *sin6; | ||||
sin6 = &(((ipfw_insn_sa6 *)cmd)->sa); | sin6 = &(((ipfw_insn_sa6 *)cmd)->sa); | ||||
args->next_hop6 = sin6; | args->next_hop6 = sin6; | ||||
} | } | ||||
retval = IP_FW_PASS; | retval = IP_FW_PASS; | ||||
l = 0; /* exit inner loop */ | l = 0; /* exit inner loop */ | ||||
done = 1; /* exit outer loop */ | done = 1; /* exit outer loop */ | ||||
▲ Show 20 Lines • Show All 511 Lines • Show Last 20 Lines |