summaryrefslogtreecommitdiffstats
path: root/sys/netpfil
diff options
context:
space:
mode:
authorglebius <glebius@FreeBSD.org>2014-04-16 09:25:20 +0000
committerglebius <glebius@FreeBSD.org>2014-04-16 09:25:20 +0000
commit97ee1da70b055aaff943e5c687ba1b67b44ece05 (patch)
treec7c569bb1fbd59950fc9bacd57d0c53c1d53ba9f /sys/netpfil
parent721d16d187d784256a8c2688e27f34f1b004eb49 (diff)
downloadFreeBSD-src-97ee1da70b055aaff943e5c687ba1b67b44ece05.zip
FreeBSD-src-97ee1da70b055aaff943e5c687ba1b67b44ece05.tar.gz
Backout r257223,r257224,r257225,r257246,r257710. The changes caused
some regressions in ICMP handling, and right now me and Baptiste are out of time on analyzing them. PR: 188253
Diffstat (limited to 'sys/netpfil')
-rw-r--r--sys/netpfil/pf/pf.c416
-rw-r--r--sys/netpfil/pf/pf_lb.c23
2 files changed, 84 insertions, 355 deletions
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index aae5123..eb2d44a 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -210,8 +210,6 @@ static void pf_change_ap(struct pf_addr *, u_int16_t *,
u_int16_t, u_int8_t, sa_family_t);
static int pf_modulate_sack(struct mbuf *, int, struct pf_pdesc *,
struct tcphdr *, struct pf_state_peer *);
-static int pf_icmp_mapping(struct pf_pdesc *, uint8_t, int *,
- int *, uint16_t *, uint16_t *);
static void pf_change_icmp(struct pf_addr *, u_int16_t *,
struct pf_addr *, struct pf_addr *, u_int16_t,
u_int16_t *, u_int16_t *, u_int16_t *,
@@ -258,10 +256,6 @@ static int pf_test_state_tcp(struct pf_state **, int,
static int pf_test_state_udp(struct pf_state **, int,
struct pfi_kif *, struct mbuf *, int,
void *, struct pf_pdesc *);
-static int pf_icmp_state_lookup(struct pf_state_key_cmp *,
- struct pf_pdesc *, struct pf_state **, struct mbuf *,
- int, struct pfi_kif *, uint16_t, uint16_t,
- int, int *, int);
static int pf_test_state_icmp(struct pf_state **, int,
struct pfi_kif *, struct mbuf *, int,
void *, struct pf_pdesc *, u_short *);
@@ -310,8 +304,6 @@ VNET_DECLARE(int, pf_end_threads);
VNET_DEFINE(struct pf_limit, pf_limits[PF_LIMIT_MAX]);
-enum { PF_ICMP_MULTI_NONE, PF_ICMP_MULTI_SOLICITED, PF_ICMP_MULTI_LINK };
-
#define PACKET_LOOPED(pd) ((pd)->pf_mtag && \
(pd)->pf_mtag->flags & PF_PACKET_LOOPED)
@@ -2057,155 +2049,6 @@ pf_change_a6(struct pf_addr *a, u_int16_t *c, struct pf_addr *an, u_int8_t u)
}
#endif /* INET6 */
-static int
-pf_icmp_mapping(struct pf_pdesc *pd, uint8_t type,
- int *icmp_dir, int *multi, uint16_t *icmpid, uint16_t *icmptype)
-{
- /*
- * ICMP types marked with PF_OUT are typically responses to
- * PF_IN, and will match states in the opposite direction.
- * PF_IN ICMP types need to match a state with that type.
- */
- *icmp_dir = PF_OUT;
- *multi = PF_ICMP_MULTI_LINK;
- /* Queries (and responses) */
- switch (type) {
- case ICMP_ECHO:
- *icmp_dir = PF_IN;
- case ICMP_ECHOREPLY:
- *icmptype = ICMP_ECHO;
- *icmpid = pd->hdr.icmp->icmp_id;
- break;
-
- case ICMP_TSTAMP:
- *icmp_dir = PF_IN;
- case ICMP_TSTAMPREPLY:
- *icmptype = ICMP_TSTAMP;
- *icmpid = pd->hdr.icmp->icmp_id;
- break;
-
- case ICMP_IREQ:
- *icmp_dir = PF_IN;
- case ICMP_IREQREPLY:
- *icmptype = ICMP_IREQ;
- *icmpid = pd->hdr.icmp->icmp_id;
- break;
-
- case ICMP_MASKREQ:
- *icmp_dir = PF_IN;
- case ICMP_MASKREPLY:
- *icmptype = ICMP_MASKREQ;
- *icmpid = pd->hdr.icmp->icmp_id;
- break;
-
- case ICMP_IPV6_WHEREAREYOU:
- *icmp_dir = PF_IN;
- case ICMP_IPV6_IAMHERE:
- *icmptype = ICMP_IPV6_WHEREAREYOU;
- *icmpid = 0; /* Nothing sane to match on! */
- break;
-
- case ICMP_MOBILE_REGREQUEST:
- *icmp_dir = PF_IN;
- case ICMP_MOBILE_REGREPLY:
- *icmptype = ICMP_MOBILE_REGREQUEST;
- *icmpid = 0; /* Nothing sane to match on! */
- break;
-
- case ICMP_ROUTERSOLICIT:
- *icmp_dir = PF_IN;
- case ICMP_ROUTERADVERT:
- *icmptype = ICMP_MOBILE_REGREQUEST;
- *icmpid = 0; /* Nothing sane to match on! */
- break;
-
-#ifdef INET6
- case ICMP6_ECHO_REQUEST:
- *icmp_dir = PF_IN;
- case ICMP6_ECHO_REPLY:
- *icmptype = ICMP6_ECHO_REPLY;
- *icmpid = 0; /* Nothing sane to match on! */
- break;
-
- case MLD_LISTENER_QUERY:
- *icmp_dir = PF_IN;
- case MLD_LISTENER_REPORT: {
- struct mld_hdr *mld = (void *)pd->hdr.icmp6;
-
- *icmptype = MLD_LISTENER_QUERY;
- /* generate fake id for these messages */
- *icmpid = (mld->mld_addr.s6_addr32[0] ^
- mld->mld_addr.s6_addr32[1] ^
- mld->mld_addr.s6_addr32[2] ^
- mld->mld_addr.s6_addr32[3]) & 0xffff;
- break;
- }
-
- /* ICMP6_FQDN and ICMP6_NI query/reply are the same type as ICMP6_WRU */
- case ICMP6_WRUREQUEST:
- *icmp_dir = PF_IN;
- case ICMP6_WRUREPLY:
- *icmptype = ICMP6_WRUREQUEST;
- *icmpid = 0; /* Nothing sane to match on! */
- break;
-
- case MLD_MTRACE:
- *icmp_dir = PF_IN;
- case MLD_MTRACE_RESP:
- *icmptype = MLD_MTRACE;
- *icmpid = 0; /* Nothing sane to match on! */
- break;
-
- case ND_NEIGHBOR_SOLICIT:
- *icmp_dir = PF_IN;
- case ND_NEIGHBOR_ADVERT: {
- struct nd_neighbor_solicit *nd = (void *)pd->hdr.icmp6;
-
- *icmptype = ND_NEIGHBOR_SOLICIT;
- *multi = PF_ICMP_MULTI_SOLICITED;
- /* generate fake id for these messages */
- *icmpid = (nd->nd_ns_target.s6_addr32[0] ^
- nd->nd_ns_target.s6_addr32[1] ^
- nd->nd_ns_target.s6_addr32[2] ^
- nd->nd_ns_target.s6_addr32[3]) & 0xffff;
- break;
- }
-
-#endif /* INET6 */
- /* These ICMP types map to other connections */
- case ICMP_UNREACH:
- case ICMP_SOURCEQUENCH:
- case ICMP_REDIRECT:
- case ICMP_TIMXCEED:
- case ICMP_PARAMPROB:
-#ifdef INET6
- /*
- * ICMP6_TIME_EXCEEDED is the same type as ICMP_UNREACH
- * ND_REDIRECT can't be in this list because the triggering packet
- * header is optional.
- */
- case ICMP6_PACKET_TOO_BIG:
-#endif /* INET6 */
- /* These will not be used, but set them anyways */
- *icmp_dir = PF_IN;
- *icmptype = htons(type);
- *icmpid = 0;
- return (1); /* These types are matched to other state */
- /*
- * All remaining ICMP types get their own states,
- * and will only match in one direction.
- */
- default:
- *icmp_dir = PF_IN;
- *icmptype = type;
- *icmpid = 0;
- break;
- }
- *icmptype = htons(*icmptype);
-
- return (0);
-}
-
static void
pf_change_icmp(struct pf_addr *ia, u_int16_t *ip, struct pf_addr *oa,
struct pf_addr *na, u_int16_t np, u_int16_t *pc, u_int16_t *h2c,
@@ -3180,8 +3023,8 @@ pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction,
int tag = -1, rtableid = -1;
int asd = 0;
int match = 0;
- int state_icmp = 0, icmp_dir, multi;
- uint16_t sport = 0 , dport = 0, virtual_type = 0, virtual_id = 0;
+ int state_icmp = 0;
+ u_int16_t sport = 0, dport = 0;
u_int16_t bproto_sum = 0, bip_sum = 0;
u_int8_t icmptype = 0, icmpcode = 0;
struct pf_anchor_stackframe anchor_stack[PF_ANCHOR_STACKSIZE];
@@ -3210,38 +3053,33 @@ pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction,
case IPPROTO_ICMP:
if (pd->af != AF_INET)
break;
+ sport = dport = pd->hdr.icmp->icmp_id;
hdrlen = sizeof(*pd->hdr.icmp);
icmptype = pd->hdr.icmp->icmp_type;
icmpcode = pd->hdr.icmp->icmp_code;
- 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;
- } else {
- sport = virtual_type;
- dport = virtual_id;
- }
+ if (icmptype == ICMP_UNREACH ||
+ icmptype == ICMP_SOURCEQUENCH ||
+ icmptype == ICMP_REDIRECT ||
+ icmptype == ICMP_TIMXCEED ||
+ icmptype == ICMP_PARAMPROB)
+ state_icmp++;
break;
#endif /* INET */
#ifdef INET6
case IPPROTO_ICMPV6:
if (af != AF_INET6)
break;
+ sport = dport = pd->hdr.icmp6->icmp6_id;
hdrlen = sizeof(*pd->hdr.icmp6);
icmptype = pd->hdr.icmp6->icmp6_type;
icmpcode = pd->hdr.icmp6->icmp6_code;
- 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;
- } else {
- sport = virtual_type;
- dport = virtual_id;
- }
+ if (icmptype == ICMP6_DST_UNREACH ||
+ icmptype == ICMP6_PACKET_TOO_BIG ||
+ icmptype == ICMP6_TIME_EXCEEDED ||
+ icmptype == ICMP6_PARAM_PROB)
+ state_icmp++;
break;
#endif /* INET6 */
default:
@@ -3311,6 +3149,7 @@ pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction,
break;
#ifdef INET
case IPPROTO_ICMP:
+ nk->port[0] = nk->port[1];
if (PF_ANEQ(saddr, &nk->addr[pd->sidx], AF_INET))
pf_change_a(&saddr->v4.s_addr, pd->ip_sum,
nk->addr[pd->sidx].v4.s_addr, 0);
@@ -3319,12 +3158,11 @@ pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction,
pf_change_a(&daddr->v4.s_addr, pd->ip_sum,
nk->addr[pd->didx].v4.s_addr, 0);
- if (virtual_type == ICMP_ECHO &&
- nk->port[pd->sidx] != pd->hdr.icmp->icmp_id) {
+ if (nk->port[1] != pd->hdr.icmp->icmp_id) {
pd->hdr.icmp->icmp_cksum = pf_cksum_fixup(
pd->hdr.icmp->icmp_cksum, sport,
- nk->port[pd->sidx], 0);
- pd->hdr.icmp->icmp_id = nk->port[pd->sidx];
+ nk->port[1], 0);
+ pd->hdr.icmp->icmp_id = nk->port[1];
pd->sport = &pd->hdr.icmp->icmp_id;
}
m_copyback(m, off, ICMP_MINLEN, (caddr_t)pd->hdr.icmp);
@@ -4546,69 +4384,13 @@ pf_test_state_udp(struct pf_state **state, int direction, struct pfi_kif *kif,
}
static int
-pf_icmp_state_lookup(struct pf_state_key_cmp *key, struct pf_pdesc *pd,
- struct pf_state **state, struct mbuf *m, int direction, struct pfi_kif *kif,
- uint16_t icmpid, uint16_t type, int icmp_dir, int *iidx, int multi)
-{
-
- key->af = pd->af;
- key->proto = pd->proto;
- if (icmp_dir == PF_IN) {
- *iidx = pd->sidx;
- key->port[pd->sidx] = icmpid;
- key->port[pd->didx] = type;
- } else {
- *iidx = pd->didx;
- key->port[pd->sidx] = type;
- key->port[pd->didx] = icmpid;
- }
-#ifdef INET6
- if (pd->af == AF_INET6 && multi != PF_ICMP_MULTI_NONE) {
- switch (multi) {
- case PF_ICMP_MULTI_SOLICITED:
- key->addr[pd->sidx].addr32[0] = IPV6_ADDR_INT32_MLL;
- key->addr[pd->sidx].addr32[1] = 0;
- key->addr[pd->sidx].addr32[2] = IPV6_ADDR_INT32_ONE;
- key->addr[pd->sidx].addr32[3] = pd->src->addr32[3];
- key->addr[pd->sidx].addr8[12] = 0xff;
- break;
- case PF_ICMP_MULTI_LINK:
- key->addr[pd->sidx].addr32[0] = IPV6_ADDR_INT32_MLL;
- key->addr[pd->sidx].addr32[1] = 0;
- key->addr[pd->sidx].addr32[2] = 0;
- key->addr[pd->sidx].addr32[3] = IPV6_ADDR_INT32_ONE;
- break;
- }
- } else
-#endif
- PF_ACPY(&key->addr[pd->sidx], pd->src, key->af);
- PF_ACPY(&key->addr[pd->didx], pd->dst, key->af);
-
- STATE_LOOKUP(kif, key, direction, *state, pd);
-
- /* Is this ICMP message flowing in right direction? */
- if ((*state)->rule.ptr->type &&
- (((*state)->direction == direction) ?
- PF_IN : PF_OUT) != icmp_dir) {
- if (V_pf_status.debug >= PF_DEBUG_MISC) {
- printf("pf: icmp type %d in wrong direction (%d): ",
- icmp_dir, direction);
- pf_print_state(*state);
- printf("\n");
- }
- return (PF_DROP);
- }
- return (-1);
-}
-
-static int
pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
struct mbuf *m, int off, void *h, struct pf_pdesc *pd, u_short *reason)
{
struct pf_addr *saddr = pd->src, *daddr = pd->dst;
- u_int16_t icmpid = 0, *icmpsum, virtual_id, virtual_type;
+ u_int16_t icmpid = 0, *icmpsum;
u_int8_t icmptype;
- int icmp_dir, iidx, ret, multi;
+ int state_icmp = 0;
struct pf_state_key_cmp key;
bzero(&key, sizeof(key));
@@ -4619,6 +4401,12 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
icmpid = pd->hdr.icmp->icmp_id;
icmpsum = &pd->hdr.icmp->icmp_cksum;
+ if (icmptype == ICMP_UNREACH ||
+ icmptype == ICMP_SOURCEQUENCH ||
+ icmptype == ICMP_REDIRECT ||
+ icmptype == ICMP_TIMXCEED ||
+ icmptype == ICMP_PARAMPROB)
+ state_icmp++;
break;
#endif /* INET */
#ifdef INET6
@@ -4627,35 +4415,34 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
icmpid = pd->hdr.icmp6->icmp6_id;
icmpsum = &pd->hdr.icmp6->icmp6_cksum;
+ if (icmptype == ICMP6_DST_UNREACH ||
+ icmptype == ICMP6_PACKET_TOO_BIG ||
+ icmptype == ICMP6_TIME_EXCEEDED ||
+ icmptype == ICMP6_PARAM_PROB)
+ state_icmp++;
break;
#endif /* INET6 */
- default:
- panic("%s: proto %d\n", __func__, pd->proto);
}
- if (pf_icmp_mapping(pd, icmptype, &icmp_dir, &multi,
- &virtual_id, &virtual_type) == 0) {
+ if (!state_icmp) {
+
/*
* ICMP query/reply message not related to a TCP/UDP packet.
* Search for an ICMP state.
*/
- ret = pf_icmp_state_lookup(&key, pd, state, m, direction,
- kif, virtual_id, virtual_type, icmp_dir, &iidx,
- PF_ICMP_MULTI_NONE);
- if (ret >= 0) {
- if (ret == PF_DROP && pd->af == AF_INET6 &&
- icmp_dir == PF_OUT) {
- if (*state)
- PF_STATE_UNLOCK(*state);
- ret = pf_icmp_state_lookup(&key, pd, state, m,
- direction, kif, virtual_id, virtual_type,
- icmp_dir, &iidx, multi);
- if (ret >= 0)
- return (ret);
- } else
- return (ret);
+ key.af = pd->af;
+ key.proto = pd->proto;
+ key.port[0] = key.port[1] = icmpid;
+ if (direction == PF_IN) { /* wire side, straight */
+ PF_ACPY(&key.addr[0], pd->src, key.af);
+ PF_ACPY(&key.addr[1], pd->dst, key.af);
+ } else { /* stack side, reverse */
+ PF_ACPY(&key.addr[1], pd->src, key.af);
+ PF_ACPY(&key.addr[0], pd->dst, key.af);
}
+ STATE_LOOKUP(kif, &key, direction, *state, pd);
+
(*state)->expire = time_uptime;
(*state)->timeout = PFTM_ICMP_ERROR_REPLY;
@@ -4678,13 +4465,14 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
pd->ip_sum,
nk->addr[pd->didx].v4.s_addr, 0);
- if (nk->port[iidx] !=
+ if (nk->port[0] !=
pd->hdr.icmp->icmp_id) {
pd->hdr.icmp->icmp_cksum =
pf_cksum_fixup(
pd->hdr.icmp->icmp_cksum, icmpid,
- nk->port[iidx], 0);
- pd->hdr.icmp->icmp_id = nk->port[iidx];
+ nk->port[pd->sidx], 0);
+ pd->hdr.icmp->icmp_id =
+ nk->port[pd->sidx];
}
m_copyback(m, off, ICMP_MINLEN,
@@ -5034,15 +4822,13 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
return (PF_DROP);
}
- pd2.hdr.icmp = &iih;
- pf_icmp_mapping(&pd2, iih.icmp_type,
- &icmp_dir, &multi, &virtual_id, &virtual_type);
+ key.af = pd2.af;
+ key.proto = IPPROTO_ICMP;
+ PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af);
+ PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af);
+ key.port[0] = key.port[1] = iih.icmp_id;
- ret = pf_icmp_state_lookup(&key, &pd2, state, m,
- direction, kif, virtual_id, virtual_type,
- icmp_dir, &iidx, PF_ICMP_MULTI_NONE);
- if (ret >= 0)
- return (ret);
+ STATE_LOOKUP(kif, &key, direction, *state, pd);
/* translate source/destination address, if necessary */
if ((*state)->key[PF_SK_WIRE] !=
@@ -5052,20 +4838,20 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
if (PF_ANEQ(pd2.src,
&nk->addr[pd2.sidx], pd2.af) ||
- (virtual_type == ICMP_ECHO &&
- nk->port[iidx] != iih.icmp_id))
- pf_change_icmp(pd2.src,
- (virtual_type == ICMP_ECHO) ?
- &iih.icmp_id : NULL,
+ nk->port[pd2.sidx] != iih.icmp_id)
+ pf_change_icmp(pd2.src, &iih.icmp_id,
daddr, &nk->addr[pd2.sidx],
nk->port[pd2.sidx], NULL,
pd2.ip_sum, icmpsum,
pd->ip_sum, 0, AF_INET);
if (PF_ANEQ(pd2.dst,
- &nk->addr[pd2.didx], pd2.af))
- pf_change_icmp(pd2.dst, NULL, NULL,
- &nk->addr[pd2.didx], 0, NULL,
+ &nk->addr[pd2.didx], pd2.af) ||
+ nk->port[pd2.didx] != iih.icmp_id)
+ pf_change_icmp(pd2.dst, &iih.icmp_id,
+ NULL, /* XXX Inbound NAT? */
+ &nk->addr[pd2.didx],
+ nk->port[pd2.didx], NULL,
pd2.ip_sum, icmpsum,
pd->ip_sum, 0, AF_INET);
@@ -5089,26 +4875,13 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
return (PF_DROP);
}
- pd2.hdr.icmp6 = &iih;
- pf_icmp_mapping(&pd2, iih.icmp6_type,
- &icmp_dir, &multi, &virtual_id, &virtual_type);
- ret = pf_icmp_state_lookup(&key, &pd2, state, m,
- direction, kif, virtual_id, virtual_type,
- icmp_dir, &iidx, PF_ICMP_MULTI_NONE);
- if (ret >= 0) {
- if (ret == PF_DROP && pd->af == AF_INET6 &&
- icmp_dir == PF_OUT) {
- if (*state)
- PF_STATE_UNLOCK(*state);
- ret = pf_icmp_state_lookup(&key, pd,
- state, m, direction, kif,
- virtual_id, virtual_type,
- icmp_dir, &iidx, multi);
- if (ret >= 0)
- return (ret);
- } else
- return (ret);
- }
+ key.af = pd2.af;
+ key.proto = IPPROTO_ICMPV6;
+ PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af);
+ PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af);
+ key.port[0] = key.port[1] = iih.icmp6_id;
+
+ STATE_LOOKUP(kif, &key, direction, *state, pd);
/* translate source/destination address, if necessary */
if ((*state)->key[PF_SK_WIRE] !=
@@ -5118,21 +4891,20 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
if (PF_ANEQ(pd2.src,
&nk->addr[pd2.sidx], pd2.af) ||
- ((virtual_type == ICMP6_ECHO_REQUEST) &&
- nk->port[pd2.sidx] != iih.icmp6_id))
- pf_change_icmp(pd2.src,
- (virtual_type == ICMP6_ECHO_REQUEST)
- ? &iih.icmp6_id : NULL,
+ nk->port[pd2.sidx] != iih.icmp6_id)
+ pf_change_icmp(pd2.src, &iih.icmp6_id,
daddr, &nk->addr[pd2.sidx],
- (virtual_type == ICMP6_ECHO_REQUEST)
- ? nk->port[iidx] : 0, NULL,
+ nk->port[pd2.sidx], NULL,
pd2.ip_sum, icmpsum,
pd->ip_sum, 0, AF_INET6);
if (PF_ANEQ(pd2.dst,
- &nk->addr[pd2.didx], pd2.af))
- pf_change_icmp(pd2.dst, NULL, NULL,
- &nk->addr[pd2.didx], 0, NULL,
+ &nk->addr[pd2.didx], pd2.af) ||
+ nk->port[pd2.didx] != iih.icmp6_id)
+ pf_change_icmp(pd2.dst, &iih.icmp6_id,
+ NULL, /* XXX Inbound NAT? */
+ &nk->addr[pd2.didx],
+ nk->port[pd2.didx], NULL,
pd2.ip_sum, icmpsum,
pd->ip_sum, 0, AF_INET6);
@@ -6455,32 +6227,10 @@ pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp)
}
case IPPROTO_ICMPV6: {
- union {
- struct icmp6_hdr icmp6;
- struct mld_hdr mld;
- struct nd_neighbor_solicit nd;
- } ih;
- size_t icmp_hlen = sizeof(struct icmp6_hdr);
-
- pd.hdr.icmp6 = &ih.icmp6;
- if (!pf_pull_hdr(m, off, &ih, icmp_hlen,
- &action, &reason, AF_INET6)) {
- log = action != PF_PASS;
- goto done;
- }
- /* ICMP headers we look further into to match state */
- switch (ih.icmp6.icmp6_type) {
- case MLD_LISTENER_QUERY:
- case MLD_LISTENER_REPORT:
- icmp_hlen = sizeof(struct mld_hdr);
- break;
- case ND_NEIGHBOR_SOLICIT:
- case ND_NEIGHBOR_ADVERT:
- icmp_hlen = sizeof(struct nd_neighbor_solicit);
- break;
- }
- if (icmp_hlen > sizeof(struct icmp6_hdr) &&
- !pf_pull_hdr(m, off, &ih, icmp_hlen,
+ struct icmp6_hdr ih;
+
+ pd.hdr.icmp6 = &ih;
+ if (!pf_pull_hdr(m, off, &ih, sizeof(ih),
&action, &reason, AF_INET6)) {
log = action != PF_PASS;
goto done;
diff --git a/sys/netpfil/pf/pf_lb.c b/sys/netpfil/pf/pf_lb.c
index 62789f5..d65fb0e 100644
--- a/sys/netpfil/pf/pf_lb.c
+++ b/sys/netpfil/pf/pf_lb.c
@@ -53,15 +53,6 @@ __FBSDID("$FreeBSD$");
#include <net/pfvar.h>
#include <net/if_pflog.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/ip_icmp.h>
-
-#ifdef INET6
-#include <netinet/ip6.h>
-#include <netinet/icmp6.h>
-#endif
-
#define DPFPRINTF(n, x) if (V_pf_status.debug >= (n)) printf x
static void pf_hash(struct pf_addr *, struct pf_addr *,
@@ -232,21 +223,9 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r,
if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn))
return (1);
- switch (proto) {
- case IPPROTO_ICMP:
- if (dport != htons(ICMP_ECHO))
- return (0);
- low = 1;
- high = 65535;
- break;
-#ifdef INET6
- case IPPROTO_ICMPV6:
- if (dport != htons(ICMP6_ECHO_REQUEST))
- return (0);
+ if (proto == IPPROTO_ICMP) {
low = 1;
high = 65535;
- break;
-#endif
}
bzero(&key, sizeof(key));
OpenPOWER on IntegriCloud