Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107430569
D47784.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
26 KB
Referenced Files
None
Subscribers
None
D47784.diff
View Options
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:
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Jan 15, 1:37 AM (10 h, 7 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15803876
Default Alt Text
D47784.diff (26 KB)
Attached To
Mode
D47784: pf: add post-NAT src/dst address/port to pf_pdesc
Attached
Detach File
Event Timeline
Log In to Comment