From owner-svn-src-head@FreeBSD.ORG Wed Apr 16 09:25:21 2014 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 50D41FCB; Wed, 16 Apr 2014 09:25:21 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 30B651374; Wed, 16 Apr 2014 09:25:21 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s3G9PL6F036451; Wed, 16 Apr 2014 09:25:21 GMT (envelope-from glebius@svn.freebsd.org) Received: (from glebius@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s3G9PKi0036449; Wed, 16 Apr 2014 09:25:20 GMT (envelope-from glebius@svn.freebsd.org) Message-Id: <201404160925.s3G9PKi0036449@svn.freebsd.org> From: Gleb Smirnoff Date: Wed, 16 Apr 2014 09:25:20 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r264521 - head/sys/netpfil/pf X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 16 Apr 2014 09:25:21 -0000 Author: glebius Date: Wed Apr 16 09:25:20 2014 New Revision: 264521 URL: http://svnweb.freebsd.org/changeset/base/264521 Log: 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 Modified: head/sys/netpfil/pf/pf.c head/sys/netpfil/pf/pf_lb.c Modified: head/sys/netpfil/pf/pf.c ============================================================================== --- head/sys/netpfil/pf/pf.c Wed Apr 16 05:31:54 2014 (r264520) +++ head/sys/netpfil/pf/pf.c Wed Apr 16 09:25:20 2014 (r264521) @@ -210,8 +210,6 @@ static void pf_change_ap(struct pf_add 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 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_ } #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 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 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 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_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 **stat } 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 **sta 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 **sta 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 **sta 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 **sta return (PF_DROP); } - pd2.hdr.icmp = &iih; - pf_icmp_mapping(&pd2, iih.icmp_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) - return (ret); + 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; + + 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 **sta 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 **sta 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 **sta 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, str } 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); + struct icmp6_hdr ih; - 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, + pd.hdr.icmp6 = &ih; + if (!pf_pull_hdr(m, off, &ih, sizeof(ih), &action, &reason, AF_INET6)) { log = action != PF_PASS; goto done; Modified: head/sys/netpfil/pf/pf_lb.c ============================================================================== --- head/sys/netpfil/pf/pf_lb.c Wed Apr 16 05:31:54 2014 (r264520) +++ head/sys/netpfil/pf/pf_lb.c Wed Apr 16 09:25:20 2014 (r264521) @@ -53,15 +53,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include -#include -#include - -#ifdef INET6 -#include -#include -#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 pr 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));