diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -1600,6 +1600,9 @@ char any[0]; } hdr; + struct pf_addr nsaddr; /* src address after NAT */ + struct pf_addr ndaddr; /* dst address after NAT */ + struct pfi_kkif *kif; /* incomming interface */ struct mbuf *m; @@ -1609,6 +1612,8 @@ u_int16_t *dport; u_int16_t osport; u_int16_t odport; + u_int16_t nsport; /* src port after NAT */ + u_int16_t ndport; /* dst port after NAT */ struct pf_mtag *pf_mtag; struct pf_rule_actions act; @@ -2644,13 +2649,11 @@ struct pf_ksrc_node **, struct pf_srchash **); u_short pf_get_translation(struct pf_pdesc *, int, struct pf_state_key **, struct pf_state_key **, - struct pf_addr *, struct pf_addr *, - uint16_t, uint16_t, struct pf_kanchor_stackframe *, - struct pf_krule **, + struct pf_kanchor_stackframe *, struct pf_krule **, struct pf_udp_mapping **udp_mapping); struct pf_state_key *pf_state_key_setup(struct pf_pdesc *, - struct pf_addr *, struct pf_addr *, u_int16_t, u_int16_t); + u_int16_t, u_int16_t); struct pf_state_key *pf_state_key_clone(const struct pf_state_key *); void pf_rule_to_actions(struct pf_krule *, struct pf_rule_actions *); diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -1653,9 +1653,7 @@ } struct pf_state_key * -pf_state_key_setup(struct pf_pdesc *pd, - struct pf_addr *saddr, struct pf_addr *daddr, u_int16_t sport, - u_int16_t dport) +pf_state_key_setup(struct pf_pdesc *pd, u_int16_t sport, u_int16_t dport) { struct pf_state_key *sk; @@ -4898,8 +4896,6 @@ struct pf_kruleset **rsm, struct inpcb *inp) { struct pf_krule *nr = NULL; - struct pf_addr * const saddr = pd->src; - struct pf_addr * const daddr = pd->dst; struct pf_krule *r, *a = NULL; struct pf_kruleset *ruleset = NULL; struct pf_krule_slist match_rules; @@ -4912,7 +4908,7 @@ int asd = 0; int match = 0; int state_icmp = 0, icmp_dir, multi; - u_int16_t sport = 0, dport = 0, virtual_type, virtual_id; + u_int16_t virtual_type, virtual_id; u_int16_t bproto_sum = 0, bip_sum = 0; u_int8_t icmptype = 0, icmpcode = 0; struct pf_kanchor_stackframe anchor_stack[PF_ANCHOR_STACKSIZE]; @@ -4920,6 +4916,9 @@ PF_RULES_RASSERT(); + PF_ACPY(&pd->nsaddr, pd->src, pd->af); + PF_ACPY(&pd->ndaddr, pd->dst, pd->af); + SLIST_INIT(&match_rules); if (inp != NULL) { @@ -4931,16 +4930,16 @@ switch (pd->virtual_proto) { case IPPROTO_TCP: - sport = th->th_sport; - dport = th->th_dport; + pd->nsport = th->th_sport; + pd->ndport = th->th_dport; break; case IPPROTO_UDP: - sport = pd->hdr.udp.uh_sport; - dport = pd->hdr.udp.uh_dport; + pd->nsport = pd->hdr.udp.uh_sport; + pd->ndport = pd->hdr.udp.uh_dport; break; case IPPROTO_SCTP: - sport = pd->hdr.sctp.src_port; - dport = pd->hdr.sctp.dest_port; + pd->nsport = pd->hdr.sctp.src_port; + pd->ndport = pd->hdr.sctp.dest_port; break; #ifdef INET case IPPROTO_ICMP: @@ -4950,11 +4949,11 @@ state_icmp = pf_icmp_mapping(pd, icmptype, &icmp_dir, &multi, &virtual_id, &virtual_type); if (icmp_dir == PF_IN) { - sport = virtual_id; - dport = virtual_type; + pd->nsport = virtual_id; + pd->ndport = virtual_type; } else { - sport = virtual_type; - dport = virtual_id; + pd->nsport = virtual_type; + pd->ndport = virtual_id; } break; #endif /* INET */ @@ -4966,27 +4965,27 @@ state_icmp = pf_icmp_mapping(pd, icmptype, &icmp_dir, &multi, &virtual_id, &virtual_type); if (icmp_dir == PF_IN) { - sport = virtual_id; - dport = virtual_type; + pd->nsport = virtual_id; + pd->ndport = virtual_type; } else { - sport = virtual_type; - dport = virtual_id; + pd->nsport = virtual_type; + pd->ndport = virtual_id; } break; #endif /* INET6 */ default: - sport = dport = 0; + pd->nsport = pd->ndport = 0; break; } - pd->osport = sport; - pd->odport = dport; + pd->osport = pd->nsport; + pd->odport = pd->ndport; r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); /* check packet for BINAT/NAT/RDR */ - transerror = pf_get_translation(pd, pd->off, &sk, &nk, saddr, daddr, - sport, dport, anchor_stack, &nr, &udp_mapping); + transerror = pf_get_translation(pd, pd->off, &sk, &nk, anchor_stack, + &nr, &udp_mapping); switch (transerror) { default: /* A translation error occurred. */ @@ -5011,82 +5010,94 @@ case IPPROTO_TCP: bproto_sum = th->th_sum; - if (PF_ANEQ(saddr, &nk->addr[pd->sidx], pd->af) || - nk->port[pd->sidx] != sport) { - pf_change_ap(pd->m, saddr, &th->th_sport, pd->ip_sum, - &th->th_sum, &nk->addr[pd->sidx], + if (PF_ANEQ(&pd->nsaddr, &nk->addr[pd->sidx], pd->af) || + nk->port[pd->sidx] != pd->nsport) { + pf_change_ap(pd->m, pd->src, &th->th_sport, + pd->ip_sum, &th->th_sum, &nk->addr[pd->sidx], nk->port[pd->sidx], 0, pd->af); pd->sport = &th->th_sport; - sport = th->th_sport; + pd->nsport = th->th_sport; + PF_ACPY(&pd->nsaddr, pd->src, pd->af); } - if (PF_ANEQ(daddr, &nk->addr[pd->didx], pd->af) || - nk->port[pd->didx] != dport) { - pf_change_ap(pd->m, daddr, &th->th_dport, pd->ip_sum, - &th->th_sum, &nk->addr[pd->didx], + if (PF_ANEQ(&pd->ndaddr, &nk->addr[pd->didx], pd->af) || + nk->port[pd->didx] != pd->ndport) { + pf_change_ap(pd->m, pd->dst, &th->th_dport, + pd->ip_sum, &th->th_sum, &nk->addr[pd->didx], nk->port[pd->didx], 0, pd->af); - dport = th->th_dport; + pd->ndport = th->th_dport; pd->dport = &th->th_dport; + PF_ACPY(&pd->ndaddr, pd->dst, pd->af); } rewrite++; break; case IPPROTO_UDP: bproto_sum = pd->hdr.udp.uh_sum; - if (PF_ANEQ(saddr, &nk->addr[pd->sidx], pd->af) || - nk->port[pd->sidx] != sport) { - pf_change_ap(pd->m, saddr, &pd->hdr.udp.uh_sport, + if (PF_ANEQ(&pd->nsaddr, &nk->addr[pd->sidx], pd->af) || + nk->port[pd->sidx] != pd->nsport) { + pf_change_ap(pd->m, pd->src, + &pd->hdr.udp.uh_sport, pd->ip_sum, &pd->hdr.udp.uh_sum, &nk->addr[pd->sidx], nk->port[pd->sidx], 1, pd->af); - sport = pd->hdr.udp.uh_sport; + pd->nsport = pd->hdr.udp.uh_sport; pd->sport = &pd->hdr.udp.uh_sport; + PF_ACPY(&pd->nsaddr, pd->src, pd->af); } - if (PF_ANEQ(daddr, &nk->addr[pd->didx], pd->af) || - nk->port[pd->didx] != dport) { - pf_change_ap(pd->m, daddr, &pd->hdr.udp.uh_dport, + if (PF_ANEQ(&pd->ndaddr, &nk->addr[pd->didx], pd->af) || + nk->port[pd->didx] != pd->ndport) { + pf_change_ap(pd->m, pd->dst, + &pd->hdr.udp.uh_dport, pd->ip_sum, &pd->hdr.udp.uh_sum, &nk->addr[pd->didx], nk->port[pd->didx], 1, pd->af); - dport = pd->hdr.udp.uh_dport; + pd->ndport = pd->hdr.udp.uh_dport; pd->dport = &pd->hdr.udp.uh_dport; + PF_ACPY(&pd->ndaddr, pd->dst, pd->af); } rewrite++; break; case IPPROTO_SCTP: { uint16_t checksum = 0; - if (PF_ANEQ(saddr, &nk->addr[pd->sidx], pd->af) || - nk->port[pd->sidx] != sport) { - pf_change_ap(pd->m, saddr, &pd->hdr.sctp.src_port, - pd->ip_sum, &checksum, + if (PF_ANEQ(&pd->nsaddr, &nk->addr[pd->sidx], pd->af) || + nk->port[pd->sidx] != pd->nsport) { + pf_change_ap(pd->m, pd->src, + &pd->hdr.sctp.src_port, pd->ip_sum, &checksum, &nk->addr[pd->sidx], nk->port[pd->sidx], 1, pd->af); + PF_ACPY(&pd->nsaddr, pd->src, pd->af); } - if (PF_ANEQ(daddr, &nk->addr[pd->didx], pd->af) || - nk->port[pd->didx] != dport) { - pf_change_ap(pd->m, daddr, &pd->hdr.sctp.dest_port, - pd->ip_sum, &checksum, + if (PF_ANEQ(&pd->ndaddr, &nk->addr[pd->didx], pd->af) || + nk->port[pd->didx] != pd->ndport) { + pf_change_ap(pd->m, pd->dst, + &pd->hdr.sctp.dest_port, pd->ip_sum, &checksum, &nk->addr[pd->didx], nk->port[pd->didx], 1, pd->af); + PF_ACPY(&pd->ndaddr, pd->dst, pd->af); } break; } #ifdef INET case IPPROTO_ICMP: - if (PF_ANEQ(saddr, &nk->addr[pd->sidx], AF_INET)) - pf_change_a(&saddr->v4.s_addr, pd->ip_sum, + if (PF_ANEQ(&pd->nsaddr, &nk->addr[pd->sidx], AF_INET)) { + pf_change_a(&pd->src->v4.s_addr, pd->ip_sum, nk->addr[pd->sidx].v4.s_addr, 0); + PF_ACPY(&pd->nsaddr, pd->src, pd->af); + } - if (PF_ANEQ(daddr, &nk->addr[pd->didx], AF_INET)) - pf_change_a(&daddr->v4.s_addr, pd->ip_sum, + if (PF_ANEQ(&pd->ndaddr, &nk->addr[pd->didx], AF_INET)) { + pf_change_a(&pd->dst->v4.s_addr, pd->ip_sum, nk->addr[pd->didx].v4.s_addr, 0); + PF_ACPY(&pd->ndaddr, pd->dst, pd->af); + } if (virtual_type == htons(ICMP_ECHO) && nk->port[pd->sidx] != pd->hdr.icmp.icmp_id) { pd->hdr.icmp.icmp_cksum = pf_cksum_fixup( - pd->hdr.icmp.icmp_cksum, sport, + pd->hdr.icmp.icmp_cksum, pd->nsport, nk->port[pd->sidx], 0); pd->hdr.icmp.icmp_id = nk->port[pd->sidx]; pd->sport = &pd->hdr.icmp.icmp_id; @@ -5096,13 +5107,17 @@ #endif /* INET */ #ifdef INET6 case IPPROTO_ICMPV6: - if (PF_ANEQ(saddr, &nk->addr[pd->sidx], AF_INET6)) - pf_change_a6(saddr, &pd->hdr.icmp6.icmp6_cksum, + if (PF_ANEQ(&pd->nsaddr, &nk->addr[pd->sidx], AF_INET6)) { + pf_change_a6(pd->src, &pd->hdr.icmp6.icmp6_cksum, &nk->addr[pd->sidx], 0); + PF_ACPY(&pd->nsaddr, pd->src, pd->af); + } - if (PF_ANEQ(daddr, &nk->addr[pd->didx], AF_INET6)) - pf_change_a6(daddr, &pd->hdr.icmp6.icmp6_cksum, + if (PF_ANEQ(&pd->ndaddr, &nk->addr[pd->didx], AF_INET6)) { + pf_change_a6(pd->dst, &pd->hdr.icmp6.icmp6_cksum, &nk->addr[pd->didx], 0); + PF_ACPY(&pd->ndaddr, pd->dst, pd->af); + } rewrite++; break; #endif /* INET */ @@ -5110,28 +5125,36 @@ switch (pd->af) { #ifdef INET case AF_INET: - if (PF_ANEQ(saddr, - &nk->addr[pd->sidx], AF_INET)) - pf_change_a(&saddr->v4.s_addr, + if (PF_ANEQ(&pd->nsaddr, + &nk->addr[pd->sidx], AF_INET)) { + pf_change_a(&pd->src->v4.s_addr, pd->ip_sum, nk->addr[pd->sidx].v4.s_addr, 0); + PF_ACPY(&pd->nsaddr, pd->src, pd->af); + } - if (PF_ANEQ(daddr, - &nk->addr[pd->didx], AF_INET)) - pf_change_a(&daddr->v4.s_addr, + if (PF_ANEQ(&pd->ndaddr, + &nk->addr[pd->didx], AF_INET)) { + pf_change_a(&pd->dst->v4.s_addr, pd->ip_sum, nk->addr[pd->didx].v4.s_addr, 0); + PF_ACPY(&pd->ndaddr, pd->dst, pd->af); + } break; #endif /* INET */ #ifdef INET6 case AF_INET6: - if (PF_ANEQ(saddr, - &nk->addr[pd->sidx], AF_INET6)) - PF_ACPY(saddr, &nk->addr[pd->sidx], pd->af); + if (PF_ANEQ(&pd->nsaddr, + &nk->addr[pd->sidx], AF_INET6)) { + PF_ACPY(&pd->nsaddr, &nk->addr[pd->sidx], pd->af); + PF_ACPY(pd->src, &nk->addr[pd->sidx], pd->af); + } - if (PF_ANEQ(daddr, - &nk->addr[pd->didx], AF_INET6)) - PF_ACPY(daddr, &nk->addr[pd->didx], pd->af); + if (PF_ANEQ(&pd->ndaddr, + &nk->addr[pd->didx], AF_INET6)) { + PF_ACPY(&pd->ndaddr, &nk->addr[pd->didx], pd->af); + PF_ACPY(pd->dst, &nk->addr[pd->didx], pd->af); + } break; #endif /* INET */ } @@ -5151,10 +5174,10 @@ r->skip[PF_SKIP_AF]); PF_TEST_ATTRIB(r->proto && r->proto != pd->proto, r->skip[PF_SKIP_PROTO]); - PF_TEST_ATTRIB(PF_MISMATCHAW(&r->src.addr, saddr, pd->af, + PF_TEST_ATTRIB(PF_MISMATCHAW(&r->src.addr, &pd->nsaddr, pd->af, r->src.neg, pd->kif, M_GETFIB(pd->m)), r->skip[PF_SKIP_SRC_ADDR]); - PF_TEST_ATTRIB(PF_MISMATCHAW(&r->dst.addr, daddr, pd->af, + PF_TEST_ATTRIB(PF_MISMATCHAW(&r->dst.addr, &pd->ndaddr, pd->af, r->dst.neg, NULL, M_GETFIB(pd->m)), r->skip[PF_SKIP_DST_ADDR]); switch (pd->virtual_proto) { @@ -5180,11 +5203,11 @@ case IPPROTO_UDP: /* tcp/udp only. port_op always 0 in other cases */ PF_TEST_ATTRIB(r->src.port_op && !pf_match_port(r->src.port_op, - r->src.port[0], r->src.port[1], sport), + r->src.port[0], r->src.port[1], pd->nsport), r->skip[PF_SKIP_SRC_PORT]); /* tcp/udp only. port_op always 0 in other cases */ PF_TEST_ATTRIB(r->dst.port_op && !pf_match_port(r->dst.port_op, - r->dst.port[0], r->dst.port[1], dport), + r->dst.port[0], r->dst.port[1], pd->ndport), r->skip[PF_SKIP_DST_PORT]); /* tcp/udp only. uid.op always 0 in other cases */ PF_TEST_ATTRIB(r->uid.op && (pd->lookup.done || (pd->lookup.done = @@ -5539,7 +5562,7 @@ __func__, nr, sk, nk)); MPASS(pd->sport == NULL || (pd->osport == *pd->sport)); MPASS(pd->dport == NULL || (pd->odport == *pd->dport)); - sk = pf_state_key_setup(pd, pd->src, pd->dst, pd->osport, pd->odport); + sk = pf_state_key_setup(pd, pd->osport, pd->odport); if (sk == NULL) goto csfailed; nk = sk; diff --git a/sys/netpfil/pf/pf_lb.c b/sys/netpfil/pf/pf_lb.c --- a/sys/netpfil/pf/pf_lb.c +++ b/sys/netpfil/pf/pf_lb.c @@ -64,13 +64,10 @@ static void pf_hash(struct pf_addr *, struct pf_addr *, struct pf_poolhashkey *, sa_family_t); static struct pf_krule *pf_match_translation(struct pf_pdesc *, - struct pf_addr *, u_int16_t, - struct pf_addr *, uint16_t, int, - struct pf_kanchor_stackframe *); -static int pf_get_sport(sa_family_t, uint8_t, struct pf_krule *, - struct pf_addr *, uint16_t, struct pf_addr *, uint16_t, struct pf_addr *, - uint16_t *, uint16_t, uint16_t, struct pf_ksrc_node **, struct pf_srchash**, - struct pf_udp_mapping **); + int, struct pf_kanchor_stackframe *); +static int pf_get_sport(struct pf_pdesc *, struct pf_krule *, + struct pf_addr *, uint16_t *, uint16_t, uint16_t, struct pf_ksrc_node **, + struct pf_srchash **, struct pf_udp_mapping **); static bool pf_islinklocal(const sa_family_t, const struct pf_addr *); #define mix(a,b,c) \ @@ -132,9 +129,7 @@ static struct pf_krule * pf_match_translation(struct pf_pdesc *pd, - struct pf_addr *saddr, u_int16_t sport, - struct pf_addr *daddr, uint16_t dport, int rs_num, - struct pf_kanchor_stackframe *anchor_stack) + int rs_num, struct pf_kanchor_stackframe *anchor_stack) { struct pf_krule *r, *rm = NULL; struct pf_kruleset *ruleset = NULL; @@ -165,24 +160,24 @@ r = r->skip[PF_SKIP_AF]; else if (r->proto && r->proto != pd->proto) r = r->skip[PF_SKIP_PROTO]; - else if (PF_MISMATCHAW(&src->addr, saddr, pd->af, + else if (PF_MISMATCHAW(&src->addr, &pd->nsaddr, pd->af, src->neg, pd->kif, M_GETFIB(pd->m))) r = r->skip[src == &r->src ? PF_SKIP_SRC_ADDR : PF_SKIP_DST_ADDR]; else if (src->port_op && !pf_match_port(src->port_op, - src->port[0], src->port[1], sport)) + src->port[0], src->port[1], pd->nsport)) r = r->skip[src == &r->src ? PF_SKIP_SRC_PORT : PF_SKIP_DST_PORT]; else if (dst != NULL && - PF_MISMATCHAW(&dst->addr, daddr, pd->af, dst->neg, NULL, + PF_MISMATCHAW(&dst->addr, &pd->ndaddr, pd->af, dst->neg, NULL, M_GETFIB(pd->m))) r = r->skip[PF_SKIP_DST_ADDR]; - else if (xdst != NULL && PF_MISMATCHAW(xdst, daddr, pd->af, + else if (xdst != NULL && PF_MISMATCHAW(xdst, &pd->ndaddr, pd->af, 0, NULL, M_GETFIB(pd->m))) r = TAILQ_NEXT(r, entries); else if (dst != NULL && dst->port_op && !pf_match_port(dst->port_op, dst->port[0], - dst->port[1], dport)) + dst->port[1], pd->ndport)) r = r->skip[PF_SKIP_DST_PORT]; else if (r->match_tag && !pf_match_tag(pd->m, r, &tag, pd->pf_mtag ? pd->pf_mtag->tag : 0)) @@ -222,11 +217,10 @@ } static int -pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_krule *r, - struct pf_addr *saddr, uint16_t sport, struct pf_addr *daddr, - uint16_t dport, struct pf_addr *naddr, uint16_t *nport, uint16_t low, - uint16_t high, struct pf_ksrc_node **sn, struct pf_srchash **sh, - struct pf_udp_mapping **udp_mapping) +pf_get_sport(struct pf_pdesc *pd, struct pf_krule *r, + struct pf_addr *naddr, uint16_t *nport, uint16_t low, + uint16_t high, struct pf_ksrc_node **sn, + struct pf_srchash **sh, struct pf_udp_mapping **udp_mapping) { struct pf_state_key_cmp key; struct pf_addr init_addr; @@ -240,35 +234,36 @@ * from the mapping. In this case we have to look up the src_node as * pf_map_addr would. */ - if (proto == IPPROTO_UDP && (r->rdr.opts & PF_POOL_ENDPI)) { + if (pd->proto == IPPROTO_UDP && (r->rdr.opts & PF_POOL_ENDPI)) { struct pf_udp_endpoint_cmp udp_source; bzero(&udp_source, sizeof(udp_source)); - udp_source.af = af; - PF_ACPY(&udp_source.addr, saddr, af); - udp_source.port = sport; + udp_source.af = pd->af; + PF_ACPY(&udp_source.addr, &pd->nsaddr, pd->af); + udp_source.port = pd->nsport; *udp_mapping = pf_udp_mapping_find(&udp_source); if (*udp_mapping) { - PF_ACPY(naddr, &(*udp_mapping)->endpoints[1].addr, af); + PF_ACPY(naddr, &(*udp_mapping)->endpoints[1].addr, pd->af); *nport = (*udp_mapping)->endpoints[1].port; /* Try to find a src_node as per pf_map_addr(). */ if (*sn == NULL && r->rdr.opts & PF_POOL_STICKYADDR && (r->rdr.opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) - *sn = pf_find_src_node(saddr, r, af, sh, false); + *sn = pf_find_src_node(&pd->nsaddr, r, pd->af, sh, false); if (*sn != NULL) PF_SRC_NODE_UNLOCK(*sn); return (0); } else { - *udp_mapping = pf_udp_mapping_create(af, saddr, sport, &init_addr, 0); + *udp_mapping = pf_udp_mapping_create(pd->af, &pd->nsaddr, + pd->nsport, &init_addr, 0); if (*udp_mapping == NULL) return (1); } } - if (pf_map_addr_sn(af, r, saddr, naddr, NULL, &init_addr, sn, sh)) + if (pf_map_addr_sn(pd->af, r, &pd->nsaddr, naddr, NULL, &init_addr, sn, sh)) goto failed; - if (proto == IPPROTO_ICMP) { + if (pd->proto == IPPROTO_ICMP) { if (*nport == htons(ICMP_ECHO)) { low = 1; high = 65535; @@ -276,7 +271,7 @@ return (0); /* Don't try to modify non-echo ICMP */ } #ifdef INET6 - if (proto == IPPROTO_ICMPV6) { + if (pd->proto == IPPROTO_ICMPV6) { if (*nport == htons(ICMP6_ECHO_REQUEST)) { low = 1; high = 65535; @@ -286,37 +281,37 @@ #endif /* INET6 */ bzero(&key, sizeof(key)); - key.af = af; - key.proto = proto; - key.port[0] = dport; - PF_ACPY(&key.addr[0], daddr, key.af); + key.af = pd->af; + key.proto = pd->proto; + key.port[0] = pd->ndport; + PF_ACPY(&key.addr[0], &pd->ndaddr, key.af); do { PF_ACPY(&key.addr[1], naddr, key.af); if (*udp_mapping) - PF_ACPY(&(*udp_mapping)->endpoints[1].addr, naddr, af); + PF_ACPY(&(*udp_mapping)->endpoints[1].addr, naddr, pd->af); /* * port search; start random, step; * similar 2 portloop in in_pcbbind */ - if (proto == IPPROTO_SCTP) { - key.port[1] = sport; + if (pd->proto == IPPROTO_SCTP) { + key.port[1] = pd->nsport; if (!pf_find_state_all_exists(&key, PF_IN)) { - *nport = sport; + *nport = pd->nsport; return (0); } else { return (1); /* Fail mapping. */ } - } else if (!(proto == IPPROTO_TCP || proto == IPPROTO_UDP || - proto == IPPROTO_ICMP) || (low == 0 && high == 0)) { + } else if (!(pd->proto == IPPROTO_TCP || pd->proto == IPPROTO_UDP || + pd->proto == IPPROTO_ICMP) || (low == 0 && high == 0)) { /* * XXX bug: icmp states don't use the id on both sides. * (traceroute -I through nat) */ - key.port[1] = sport; + key.port[1] = pd->nsport; if (!pf_find_state_all_exists(&key, PF_IN)) { - *nport = sport; + *nport = pd->nsport; return (0); } } else if (low == high) { @@ -362,7 +357,7 @@ } tmp = cut; for (tmp -= 1; tmp >= low && tmp <= 0xffff; --tmp) { - if (proto == IPPROTO_UDP && + if (pd->proto == IPPROTO_UDP && (r->rdr.opts & PF_POOL_ENDPI)) { (*udp_mapping)->endpoints[1].port = htons(tmp); if (pf_udp_mapping_insert(*udp_mapping) == 0) { @@ -387,7 +382,8 @@ * of free port choices for the current one. */ (*sn) = NULL; - if (pf_map_addr_sn(af, r, saddr, naddr, NULL, &init_addr, sn, sh)) + if (pf_map_addr_sn(pd->af, r, &pd->nsaddr, naddr, NULL, + &init_addr, sn, sh)) return (1); break; case PF_POOL_NONE: @@ -396,7 +392,7 @@ default: return (1); } - } while (! PF_AEQ(&init_addr, naddr, af) ); + } while (! PF_AEQ(&init_addr, naddr, pd->af) ); failed: uma_zfree(V_pf_udp_mapping_z, *udp_mapping); @@ -413,9 +409,8 @@ } static int -pf_get_mape_sport(sa_family_t af, u_int8_t proto, struct pf_krule *r, - struct pf_addr *saddr, uint16_t sport, struct pf_addr *daddr, - uint16_t dport, struct pf_addr *naddr, uint16_t *nport, +pf_get_mape_sport(struct pf_pdesc *pd, struct pf_krule *r, + struct pf_addr *naddr, uint16_t *nport, struct pf_ksrc_node **sn, struct pf_srchash **sh, struct pf_udp_mapping **udp_mapping) { @@ -436,13 +431,13 @@ for (i = cut; i <= ahigh; i++) { low = (i << ashift) | psmask; - if (!pf_get_sport(af, proto, r, saddr, sport, daddr, dport, + if (!pf_get_sport(pd, r, naddr, nport, low, low | highmask, sn, sh, udp_mapping)) return (0); } for (i = cut - 1; i > 0; i--) { low = (i << ashift) | psmask; - if (!pf_get_sport(af, proto, r, saddr, sport, daddr, dport, + if (!pf_get_sport(pd, r, naddr, nport, low, low | highmask, sn, sh, udp_mapping)) return (0); } @@ -699,8 +694,7 @@ u_short pf_get_translation(struct pf_pdesc *pd, int off, - struct pf_state_key **skp, struct pf_state_key **nkp, struct pf_addr *saddr, - struct pf_addr *daddr, uint16_t sport, uint16_t dport, + struct pf_state_key **skp, struct pf_state_key **nkp, struct pf_kanchor_stackframe *anchor_stack, struct pf_krule **rp, struct pf_udp_mapping **udp_mapping) { @@ -719,19 +713,13 @@ *rp = NULL; if (pd->dir == PF_OUT) { - r = pf_match_translation(pd, saddr, - sport, daddr, dport, PF_RULESET_BINAT, anchor_stack); + r = pf_match_translation(pd, PF_RULESET_BINAT, anchor_stack); if (r == NULL) - r = pf_match_translation(pd, - saddr, sport, daddr, dport, PF_RULESET_NAT, - anchor_stack); + r = pf_match_translation(pd, PF_RULESET_NAT, anchor_stack); } else { - r = pf_match_translation(pd, saddr, - sport, daddr, dport, PF_RULESET_RDR, anchor_stack); + r = pf_match_translation(pd, PF_RULESET_RDR, anchor_stack); if (r == NULL) - r = pf_match_translation(pd, - saddr, sport, daddr, dport, PF_RULESET_BINAT, - anchor_stack); + r = pf_match_translation(pd, PF_RULESET_BINAT, anchor_stack); } if (r == NULL) @@ -744,7 +732,7 @@ return (PFRES_MAX); } - *skp = pf_state_key_setup(pd, saddr, daddr, sport, dport); + *skp = pf_state_key_setup(pd, pd->nsport, pd->ndport); if (*skp == NULL) return (PFRES_MEMORY); *nkp = pf_state_key_clone(*skp); @@ -767,9 +755,8 @@ high = r->rdr.proxy_port[1]; } if (r->rdr.mape.offset > 0) { - if (pf_get_mape_sport(pd->af, pd->proto, r, saddr, - sport, daddr, dport, naddr, nportp, &sn, &sh, - udp_mapping)) { + if (pf_get_mape_sport(pd, r, naddr, nportp, &sn, + &sh, udp_mapping)) { DPFPRINTF(PF_DEBUG_MISC, ("pf: MAP-E port allocation (%u/%u/%u)" " failed\n", @@ -779,9 +766,8 @@ reason = PFRES_MAPFAILED; goto notrans; } - } else if (pf_get_sport(pd->af, pd->proto, r, saddr, sport, - daddr, dport, naddr, nportp, low, high, &sn, &sh, - udp_mapping)) { + } else if (pf_get_sport(pd, r, naddr, nportp, low, high, &sn, + &sh, udp_mapping)) { DPFPRINTF(PF_DEBUG_MISC, ("pf: NAT proxy port allocation (%u-%u) failed\n", r->rdr.proxy_port[0], r->rdr.proxy_port[1])); @@ -805,7 +791,7 @@ &r->rdr.cur->addr.p.dyn-> pfid_addr4, &r->rdr.cur->addr.p.dyn-> - pfid_mask4, saddr, AF_INET); + pfid_mask4, &pd->nsaddr, AF_INET); break; #endif /* INET */ #ifdef INET6 @@ -819,14 +805,14 @@ &r->rdr.cur->addr.p.dyn-> pfid_addr6, &r->rdr.cur->addr.p.dyn-> - pfid_mask6, saddr, AF_INET6); + pfid_mask6, &pd->nsaddr, AF_INET6); break; #endif /* INET6 */ } } else PF_POOLMASK(naddr, &r->rdr.cur->addr.v.a.addr, - &r->rdr.cur->addr.v.a.mask, saddr, + &r->rdr.cur->addr.v.a.mask, &pd->nsaddr, pd->af); break; case PF_IN: @@ -841,7 +827,7 @@ PF_POOLMASK(naddr, &r->src.addr.p.dyn->pfid_addr4, &r->src.addr.p.dyn->pfid_mask4, - daddr, AF_INET); + &pd->ndaddr, AF_INET); break; #endif /* INET */ #ifdef INET6 @@ -853,13 +839,13 @@ PF_POOLMASK(naddr, &r->src.addr.p.dyn->pfid_addr6, &r->src.addr.p.dyn->pfid_mask6, - daddr, AF_INET6); + &pd->ndaddr, AF_INET6); break; #endif /* INET6 */ } } else PF_POOLMASK(naddr, &r->src.addr.v.a.addr, - &r->src.addr.v.a.mask, daddr, pd->af); + &r->src.addr.v.a.mask, &pd->ndaddr, pd->af); break; } break; @@ -868,12 +854,13 @@ int tries; uint16_t cut, low, high, nport; - reason = pf_map_addr_sn(pd->af, r, saddr, naddr, NULL, NULL, &sn, &sh); + reason = pf_map_addr_sn(pd->af, r, &pd->nsaddr, naddr, NULL, + NULL, &sn, &sh); if (reason != 0) goto notrans; if ((r->rdr.opts & PF_POOL_TYPEMASK) == PF_POOL_BITMASK) PF_POOLMASK(naddr, naddr, &r->rdr.cur->addr.v.a.mask, - daddr, pd->af); + &pd->ndaddr, pd->af); /* Do not change SCTP ports. */ if (pd->proto == IPPROTO_SCTP) @@ -882,7 +869,7 @@ if (r->rdr.proxy_port[1]) { uint32_t tmp_nport; - tmp_nport = ((ntohs(dport) - ntohs(r->dst.port[0])) % + tmp_nport = ((ntohs(pd->ndport) - ntohs(r->dst.port[0])) % (r->rdr.proxy_port[1] - r->rdr.proxy_port[0] + 1)) + r->rdr.proxy_port[0]; @@ -893,7 +880,7 @@ } else if (r->rdr.proxy_port[0]) nport = htons(r->rdr.proxy_port[0]); else - nport = dport; + nport = pd->ndport; /* * Update the destination port. @@ -909,8 +896,8 @@ bzero(&key, sizeof(key)); key.af = pd->af; key.proto = pd->proto; - key.port[0] = sport; - PF_ACPY(&key.addr[0], saddr, key.af); + key.port[0] = pd->nsport; + PF_ACPY(&key.addr[0], &pd->nsaddr, key.af); key.port[1] = nport; PF_ACPY(&key.addr[1], naddr, key.af); @@ -957,7 +944,7 @@ out: DPFPRINTF(PF_DEBUG_MISC, ("pf: RDR source port allocation %u->%u\n", - ntohs(sport), ntohs((*nkp)->port[0]))); + ntohs(pd->nsport), ntohs((*nkp)->port[0]))); break; } default: