On 12/07/13(Fri) 11:35, Mike Belopuhov wrote:
> Hi,
>
> As it was pointed out by dhill there are some rogue splnets in
> the tcp_input that shouldn't be there really. The only reason
> they're still there is to match overzealous splnets in bridge_
> broadcast. bridge_ifenqueue is the only function call in there
> that requires splnet protection since it's dealing with send
> queues. Narrowing the range of the splnet protection allows us
> to remove all splnet protection of the IPsec SPD and TDB code.
> This as well removes the only pf_test call done under IPL_NET.
>
> Below are essentially two diffs that are rather hard to separate.
> I've tested the diff with the gif-to-ethernet IPsec bridge but
> some additional IPsec and bridge testing won't hurt.
>
> mpi@ has provided some feedback already, so I'm really looking
> for OK's on this.
ok mpi@
> diff --git sys/net/if_bridge.c sys/net/if_bridge.c
> index 41d7b67..0ca2710 100644
> --- sys/net/if_bridge.c
> +++ sys/net/if_bridge.c
> @@ -969,12 +969,10 @@ bridge_output(struct ifnet *ifp, struct mbuf *m, struct
> sockaddr *sa,
> return (ENOBUFS);
> }
> eh = mtod(m, struct ether_header *);
> dst = (struct ether_addr *)&eh->ether_dhost[0];
>
> - s = splnet();
> -
> /*
> * If bridge is down, but original output interface is up,
> * go ahead and send out that interface. Otherwise the packet
> * is dropped below.
> */
> @@ -1007,11 +1005,10 @@ bridge_output(struct ifnet *ifp, struct mbuf *m,
> struct sockaddr *sa,
> */
> if ((mtag = m_tag_find(m, PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED,
> NULL)) != NULL) {
> ipsp_skipcrypto_unmark((struct tdb_ident *)(mtag + 1));
> m_freem(m);
> - splx(s);
> return (0);
> }
> #endif /* IPSEC */
> bridge_span(sc, NULL, m);
>
> @@ -1074,22 +1071,24 @@ bridge_output(struct ifnet *ifp, struct mbuf *m,
> struct sockaddr *sa,
> m1->m_pkthdr.len = len;
> }
> mc = m1;
> }
>
> + s = splnet();
> error = bridge_ifenqueue(sc, dst_if, mc);
> + splx(s);
> if (error)
> continue;
> }
> if (!used)
> m_freem(m);
> - splx(s);
> return (0);
> }
>
> sendunicast:
> bridge_span(sc, NULL, m);
> + s = splnet();
> if ((dst_if->if_flags & IFF_RUNNING) == 0) {
> m_freem(m);
> splx(s);
> return (ENETDOWN);
> }
> @@ -1251,13 +1250,11 @@ bridgeintr_frame(struct bridge_softc *sc, struct mbuf
> *m)
> * If the packet is a multicast or broadcast OR if we don't
> * know any better, forward it to all interfaces.
> */
> if ((m->m_flags & (M_BCAST | M_MCAST)) || dst_if == NULL) {
> sc->sc_if.if_imcasts++;
> - s = splnet();
> bridge_broadcast(sc, src_if, &eh, m);
> - splx(s);
> return;
> }
>
> /*
> * At this point, we're dealing with a unicast frame going to a
> @@ -1496,13 +1493,11 @@ bridge_broadcast(struct bridge_softc *sc, struct
> ifnet *ifp,
> struct ether_header *eh, struct mbuf *m)
> {
> struct bridge_iflist *p;
> struct mbuf *mc;
> struct ifnet *dst_if;
> - int len, used = 0;
> -
> - splassert(IPL_NET);
> + int len, s, used = 0;
>
> TAILQ_FOREACH(p, &sc->sc_iflist, next) {
> /*
> * Don't retransmit out of the same interface where
> * the packet was received from.
> @@ -1587,11 +1582,13 @@ bridge_broadcast(struct bridge_softc *sc, struct
> ifnet *ifp,
> len += ETHER_VLAN_ENCAP_LEN;
> #endif
> if ((len - ETHER_HDR_LEN) > dst_if->if_mtu)
> bridge_fragment(sc, dst_if, eh, mc);
> else {
> + s = splnet();
> bridge_ifenqueue(sc, dst_if, mc);
> + splx(s);
> }
> }
>
> if (!used)
> m_freem(m);
> @@ -1643,11 +1640,11 @@ bridge_span(struct bridge_softc *sc, struct
> ether_header *eh,
> struct mbuf *morig)
> {
> struct bridge_iflist *p;
> struct ifnet *ifp;
> struct mbuf *mc, *m;
> - int error;
> + int s, error;
>
> if (TAILQ_EMPTY(&sc->sc_spanlist))
> return;
>
> m = m_copym2(morig, 0, M_COPYALL, M_NOWAIT);
> @@ -1679,11 +1676,13 @@ bridge_span(struct bridge_softc *sc, struct
> ether_header *eh,
> if (mc == NULL) {
> sc->sc_if.if_oerrors++;
> continue;
> }
>
> + s = splnet();
> error = bridge_ifenqueue(sc, ifp, mc);
> + splx(s);
> if (error)
> continue;
> }
> m_freem(m);
> }
> diff --git sys/netinet/ip_input.c sys/netinet/ip_input.c
> index 664afbf..221a6f4 100644
> --- sys/netinet/ip_input.c
> +++ sys/netinet/ip_input.c
> @@ -243,11 +243,11 @@ ipv4_input(struct mbuf *m)
> {
> struct ip *ip;
> int hlen, len;
> in_addr_t pfrdr = 0;
> #ifdef IPSEC
> - int error, s;
> + int error;
> struct tdb *tdb;
> struct tdb_ident *tdbi;
> struct m_tag *mtag;
> #endif /* IPSEC */
>
> @@ -452,20 +452,18 @@ ipv4_input(struct mbuf *m)
> /*
> * IPsec policy check for forwarded packets. Look at
> * inner-most IPsec SA used.
> */
> mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL);
> - s = splnet();
> if (mtag != NULL) {
> tdbi = (struct tdb_ident *)(mtag + 1);
> tdb = gettdb(tdbi->rdomain, tdbi->spi,
> &tdbi->dst, tdbi->proto);
> } else
> tdb = NULL;
> ipsp_spd_lookup(m, AF_INET, hlen, &error,
> IPSP_DIRECTION_IN, tdb, NULL, 0);
> - splx(s);
>
> /* Error or otherwise drop-packet indication */
> if (error) {
> ipstat.ips_cantforward++;
> goto bad;
> @@ -495,11 +493,11 @@ ip_ours(struct mbuf *m)
> struct ip *ip = mtod(m, struct ip *);
> struct ipq *fp;
> struct ipqent *ipqe;
> int mff, hlen;
> #ifdef IPSEC
> - int error, s;
> + int error;
> struct tdb *tdb;
> struct tdb_ident *tdbi;
> struct m_tag *mtag;
> #endif /* IPSEC */
>
> @@ -637,20 +635,18 @@ found:
> * kinds of tunneling headers have been seen in-between the
> * IPsec headers), and I don't think we lose much functionality
> * that's needed in the real world (who uses bundles anyway ?).
> */
> mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL);
> - s = splnet();
> if (mtag) {
> tdbi = (struct tdb_ident *)(mtag + 1);
> tdb = gettdb(tdbi->rdomain, tdbi->spi, &tdbi->dst,
> tdbi->proto);
> } else
> tdb = NULL;
> ipsp_spd_lookup(m, AF_INET, hlen, &error, IPSP_DIRECTION_IN,
> tdb, NULL, 0);
> - splx(s);
>
> /* Error or otherwise drop-packet indication. */
> if (error) {
> ipstat.ips_cantforward++;
> goto bad;
> diff --git sys/netinet/ip_output.c sys/netinet/ip_output.c
> index e0e6b7d..088dd01 100644
> --- sys/netinet/ip_output.c
> +++ sys/netinet/ip_output.c
> @@ -107,11 +107,10 @@ ip_output(struct mbuf *m0, ...)
> struct tdb_ident *tdbi;
>
> struct inpcb *inp;
> struct tdb *tdb;
> u_int32_t ipsecflowinfo;
> - int s;
> #if NPF > 0
> struct ifnet *encif;
> #endif
> #endif /* IPSEC */
>
> @@ -254,16 +253,10 @@ reroute:
>
> #ifdef IPSEC
> if (!ipsec_in_use && inp == NULL)
> goto done_spd;
>
> - /*
> - * splnet is chosen over splsoftnet because we are not allowed to
> - * lower the level, and udp_output calls us in splnet().
> - */
> - s = splnet();
> -
> /* Do we have any pending SAs to apply ? */
> mtag = m_tag_find(m, PACKET_TAG_IPSEC_PENDING_TDB, NULL);
> if (mtag != NULL) {
> #ifdef DIAGNOSTIC
> if (mtag->m_tag_len != sizeof (struct tdb_ident))
> @@ -280,12 +273,10 @@ reroute:
> else
> tdb = ipsp_spd_lookup(m, AF_INET, hlen, &error,
> IPSP_DIRECTION_OUT, NULL, inp, ipsecflowinfo);
>
> if (tdb == NULL) {
> - splx(s);
> -
> if (error == 0) {
> /*
> * No IPsec processing required, we'll just send the
> * packet out.
> */
> @@ -316,21 +307,19 @@ reroute:
> if (tdbi->spi == tdb->tdb_spi &&
> tdbi->proto == tdb->tdb_sproto &&
> tdbi->rdomain == tdb->tdb_rdomain &&
> !bcmp(&tdbi->dst, &tdb->tdb_dst,
> sizeof(union sockaddr_union))) {
> - splx(s);
> sproto = 0; /* mark as no-IPsec-needed */
> goto done_spd;
> }
> }
>
> /* We need to do IPsec */
> bcopy(&tdb->tdb_dst, &sdst, sizeof(sdst));
> sspi = tdb->tdb_spi;
> sproto = tdb->tdb_sproto;
> - splx(s);
>
> /*
> * If it needs TCP/UDP hardware-checksumming, do the
> * computation now.
> */
> @@ -573,18 +562,15 @@ sendit:
> #ifdef IPSEC
> /*
> * Check if the packet needs encapsulation.
> */
> if (sproto != 0) {
> - s = splnet();
> -
> tdb = gettdb(rtable_l2(m->m_pkthdr.rdomain),
> sspi, &sdst, sproto);
> if (tdb == NULL) {
> DPRINTF(("ip_output: unknown TDB"));
> error = EHOSTUNREACH;
> - splx(s);
> m_freem(m);
> goto done;
> }
>
> /*
> @@ -593,16 +579,14 @@ sendit:
> #if NPF > 0
> if ((encif = enc_getif(tdb->tdb_rdomain,
> tdb->tdb_tap)) == NULL ||
> pf_test(AF_INET, PF_OUT, encif, &m, NULL) != PF_PASS) {
> error = EACCES;
> - splx(s);
> m_freem(m);
> goto done;
> }
> if (m == NULL) {
> - splx(s);
> goto done;
> }
> ip = mtod(m, struct ip *);
> hlen = ip->ip_hl << 2;
> /*
> @@ -625,11 +609,10 @@ sendit:
>
> transportmode = (tdb->tdb_dst.sa.sa_family == AF_INET)
> &&
> (tdb->tdb_dst.sin.sin_addr.s_addr ==
> ip->ip_dst.s_addr);
> icmp_mtu = tdb->tdb_mtu;
> - splx(s);
>
> /* Find a host route to store the mtu in */
> if (ro != NULL)
> rt = ro->ro_rt;
> /* but don't add a PMTU route for transport mode SAs */
> @@ -665,11 +648,10 @@ sendit:
> */
> m->m_flags &= ~(M_MCAST | M_BCAST);
>
> /* Callee frees mbuf */
> error = ipsp_process_packet(m, tdb, AF_INET, 0);
> - splx(s);
> return error; /* Nothing more to be done */
> }
>
> /*
> * If we got here and IPsec crypto processing didn't happen, drop it.
> diff --git sys/netinet/tcp_input.c sys/netinet/tcp_input.c
> index 4e39e7f..c44e796 100644
> --- sys/netinet/tcp_input.c
> +++ sys/netinet/tcp_input.c
> @@ -376,11 +376,11 @@ tcp_input(struct mbuf *m, ...)
> #endif /* INET6 */
> #ifdef IPSEC
> struct m_tag *mtag;
> struct tdb_ident *tdbi;
> struct tdb *tdb;
> - int error, s;
> + int error;
> #endif /* IPSEC */
> int af;
> #ifdef TCP_ECN
> u_char iptos;
> #endif
> @@ -884,22 +884,20 @@ findpcb:
> #endif
>
> #ifdef IPSEC
> /* Find most recent IPsec tag */
> mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL);
> - s = splnet();
> if (mtag != NULL) {
> tdbi = (struct tdb_ident *)(mtag + 1);
> tdb = gettdb(tdbi->rdomain, tdbi->spi,
> &tdbi->dst, tdbi->proto);
> } else
> tdb = NULL;
> ipsp_spd_lookup(m, af, iphlen, &error, IPSP_DIRECTION_IN,
> tdb, inp, 0);
> if (error) {
> tcpstat.tcps_rcvnosec++;
> - splx(s);
> goto drop;
> }
>
> /* Latch SA */
> if (inp->inp_tdb_in != tdb) {
> @@ -907,11 +905,10 @@ findpcb:
> tdb_add_inp(tdb, inp, 1);
> if (inp->inp_ipo == NULL) {
> inp->inp_ipo = ipsec_add_policy(inp, af,
> IPSP_DIRECTION_OUT);
> if (inp->inp_ipo == NULL) {
> - splx(s);
> goto drop;
> }
> }
> if (inp->inp_ipo->ipo_dstid == NULL &&
> tdb->tdb_srcid != NULL) {
> @@ -934,11 +931,10 @@ findpcb:
> TAILQ_REMOVE(&inp->inp_tdb_in->tdb_inp_in, inp,
> inp_tdb_in_next);
> inp->inp_tdb_in = NULL;
> }
> }
> - splx(s);
> #endif /* IPSEC */
>
> /*
> * Segment received on connection.
> * Reset idle time and keep-alive timer.
> @@ -967,11 +963,11 @@ findpcb:
> if (opti.ts_present && opti.ts_ecr) {
> int rtt_test;
>
> /* subtract out the tcp timestamp modulator */
> opti.ts_ecr -= tp->ts_modulate;
> -
> +
> /* make sure ts_ecr is sensible */
> rtt_test = tcp_now - opti.ts_ecr;
> if (rtt_test < 0 || rtt_test > TCP_RTT_MAX)
> opti.ts_ecr = 0;
> }
> diff --git sys/netinet/udp_usrreq.c sys/netinet/udp_usrreq.c
> index 2b5623f..b1f2c5c 100644
> --- sys/netinet/udp_usrreq.c
> +++ sys/netinet/udp_usrreq.c
> @@ -176,11 +176,11 @@ udp_input(struct mbuf *m, ...)
> #endif /* INET6 */
> #ifdef IPSEC
> struct m_tag *mtag;
> struct tdb_ident *tdbi;
> struct tdb *tdb;
> - int error, s;
> + int error;
> u_int32_t ipsecflowinfo = 0;
> #endif /* IPSEC */
>
> va_start(ap, m);
> iphlen = va_arg(ap, int);
> @@ -598,22 +598,20 @@ udp_input(struct mbuf *m, ...)
> m->m_pkthdr.pf.statekey = NULL;
> #endif
>
> #ifdef IPSEC
> mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL);
> - s = splnet();
> if (mtag != NULL) {
> tdbi = (struct tdb_ident *)(mtag + 1);
> tdb = gettdb(tdbi->rdomain, tdbi->spi,
> &tdbi->dst, tdbi->proto);
> } else
> tdb = NULL;
> ipsp_spd_lookup(m, srcsa.sa.sa_family, iphlen, &error,
> IPSP_DIRECTION_IN, tdb, inp, 0);
> if (error) {
> udpstat.udps_nosec++;
> - splx(s);
> goto bad;
> }
>
> /* Latch SA only if the socket is connected */
> if (inp->inp_tdb_in != tdb &&
> @@ -622,11 +620,10 @@ udp_input(struct mbuf *m, ...)
> tdb_add_inp(tdb, inp, 1);
> if (inp->inp_ipo == NULL) {
> inp->inp_ipo = ipsec_add_policy(inp,
> srcsa.sa.sa_family, IPSP_DIRECTION_OUT);
> if (inp->inp_ipo == NULL) {
> - splx(s);
> goto bad;
> }
> }
> if (inp->inp_ipo->ipo_dstid == NULL &&
> tdb->tdb_srcid != NULL) {
> @@ -653,11 +650,10 @@ udp_input(struct mbuf *m, ...)
> }
> /* create ipsec options while we know that tdb cannot be modified */
> if (tdb)
> ipsecflowinfo = tdb->tdb_spi;
>
> - splx(s);
> #endif /*IPSEC */
>
> opts = NULL;
> #ifdef INET6
> if (ip6 && (inp->inp_flags & IN6P_CONTROLOPTS ||
> diff --git sys/netinet6/ip6_forward.c sys/netinet6/ip6_forward.c
> index 4e2e459..0444352 100644
> --- sys/netinet6/ip6_forward.c
> +++ sys/netinet6/ip6_forward.c
> @@ -98,11 +98,10 @@ ip6_forward(struct mbuf *m, int srcrt)
> struct m_tag *mtag;
> union sockaddr_union sdst;
> struct tdb_ident *tdbi;
> u_int32_t sspi;
> struct tdb *tdb;
> - int s;
> #if NPF > 0
> struct ifnet *encif;
> #endif
> #endif /* IPSEC */
> u_int rtableid = 0;
> @@ -146,12 +145,10 @@ reroute:
>
> #ifdef IPSEC
> if (!ipsec_in_use)
> goto done_spd;
>
> - s = splnet();
> -
> /*
> * Check if there was an outgoing SA bound to the flow
> * from a transport protocol.
> */
>
> @@ -172,12 +169,10 @@ reroute:
> } else
> tdb = ipsp_spd_lookup(m, AF_INET6, sizeof(struct ip6_hdr),
> &error, IPSP_DIRECTION_OUT, NULL, NULL, 0);
>
> if (tdb == NULL) {
> - splx(s);
> -
> if (error == 0) {
> /*
> * No IPsec processing required, we'll just send the
> * packet out.
> */
> @@ -207,21 +202,19 @@ reroute:
> if (tdbi->spi == tdb->tdb_spi &&
> tdbi->proto == tdb->tdb_sproto &&
> tdbi->rdomain == tdb->tdb_rdomain &&
> !bcmp(&tdbi->dst, &tdb->tdb_dst,
> sizeof(union sockaddr_union))) {
> - splx(s);
> sproto = 0; /* mark as no-IPsec-needed */
> goto done_spd;
> }
> }
>
> /* We need to do IPsec */
> bcopy(&tdb->tdb_dst, &sdst, sizeof(sdst));
> sspi = tdb->tdb_spi;
> sproto = tdb->tdb_sproto;
> - splx(s);
> }
>
> /* Fall through to the routing/multicast handling code */
> done_spd:
> #endif /* IPSEC */
> @@ -335,34 +328,28 @@ reroute:
> * ipsp_process_packet will never come back to here.
> * XXX ipsp_process_packet() calls ip6_output(), and there'll be no
> * PMTU notification. is it okay?
> */
> if (sproto != 0) {
> - s = splnet();
> -
> tdb = gettdb(rtable_l2(m->m_pkthdr.rdomain),
> sspi, &sdst, sproto);
> if (tdb == NULL) {
> - splx(s);
> error = EHOSTUNREACH;
> m_freem(m);
> goto senderr; /*XXX*/
> }
>
> #if NPF > 0
> if ((encif = enc_getif(tdb->tdb_rdomain,
> tdb->tdb_tap)) == NULL ||
> pf_test(AF_INET6, PF_FWD, encif, &m, NULL) != PF_PASS) {
> - splx(s);
> error = EHOSTUNREACH;
> m_freem(m);
> goto senderr;
> }
> - if (m == NULL) {
> - splx(s);
> + if (m == NULL)
> goto senderr;
> - }
> ip6 = mtod(m, struct ip6_hdr *);
> /*
> * PF_TAG_REROUTE handling or not...
> * Packet is entering IPsec so the routing is
> * already overruled by the IPsec policy.
> @@ -374,11 +361,10 @@ reroute:
>
> m->m_flags &= ~(M_BCAST | M_MCAST); /* just in case */
>
> /* Callee frees mbuf */
> error = ipsp_process_packet(m, tdb, AF_INET6, 0);
> - splx(s);
> m_freem(mcopy);
> goto freert;
> }
> #endif /* IPSEC */
>
> diff --git sys/netinet6/ip6_output.c sys/netinet6/ip6_output.c
> index d9a11ce..88ccf90 100644
> --- sys/netinet6/ip6_output.c
> +++ sys/netinet6/ip6_output.c
> @@ -171,11 +171,10 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt,
> struct route_in6 *ro,
> struct m_tag *mtag;
> union sockaddr_union sdst;
> struct tdb_ident *tdbi;
> u_int32_t sspi;
> struct tdb *tdb;
> - int s;
> #if NPF > 0
> struct ifnet *encif;
> #endif
> #endif /* IPSEC */
>
> @@ -214,16 +213,10 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt,
> struct route_in6 *ro,
> #ifdef IPSEC
> if (!ipsec_in_use && !inp)
> goto done_spd;
>
> /*
> - * splnet is chosen over splsoftnet because we are not allowed to
> - * lower the level, and udp6_output calls us in splnet(). XXX check
> - */
> - s = splnet();
> -
> - /*
> * Check if there was an outgoing SA bound to the flow
> * from a transport protocol.
> */
> ip6 = mtod(m, struct ip6_hdr *);
>
> @@ -243,12 +236,10 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt,
> struct route_in6 *ro,
> } else
> tdb = ipsp_spd_lookup(m, AF_INET6, sizeof(struct ip6_hdr),
> &error, IPSP_DIRECTION_OUT, NULL, inp, 0);
>
> if (tdb == NULL) {
> - splx(s);
> -
> if (error == 0) {
> /*
> * No IPsec processing required, we'll just send the
> * packet out.
> */
> @@ -278,21 +269,19 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt,
> struct route_in6 *ro,
> if (tdbi->spi == tdb->tdb_spi &&
> tdbi->proto == tdb->tdb_sproto &&
> tdbi->rdomain == tdb->tdb_rdomain &&
> !bcmp(&tdbi->dst, &tdb->tdb_dst,
> sizeof(union sockaddr_union))) {
> - splx(s);
> sproto = 0; /* mark as no-IPsec-needed */
> goto done_spd;
> }
> }
>
> /* We need to do IPsec */
> bcopy(&tdb->tdb_dst, &sdst, sizeof(sdst));
> sspi = tdb->tdb_spi;
> sproto = tdb->tdb_sproto;
> - splx(s);
> }
>
> /* Fall through to the routing/multicast handling code */
> done_spd:
> #endif /* IPSEC */
> @@ -495,39 +484,33 @@ reroute:
> /*
> * Check if the packet needs encapsulation.
> * ipsp_process_packet will never come back to here.
> */
> if (sproto != 0) {
> - s = splnet();
> -
> /*
> * XXX what should we do if ip6_hlim == 0 and the
> * packet gets tunneled?
> */
>
> tdb = gettdb(rtable_l2(m->m_pkthdr.rdomain),
> sspi, &sdst, sproto);
> if (tdb == NULL) {
> - splx(s);
> error = EHOSTUNREACH;
> m_freem(m);
> goto done;
> }
>
> #if NPF > 0
> if ((encif = enc_getif(tdb->tdb_rdomain,
> tdb->tdb_tap)) == NULL ||
> pf_test(AF_INET6, PF_OUT, encif, &m, NULL) != PF_PASS) {
> - splx(s);
> error = EHOSTUNREACH;
> m_freem(m);
> goto done;
> }
> - if (m == NULL) {
> - splx(s);
> + if (m == NULL)
> goto done;
> - }
> ip6 = mtod(m, struct ip6_hdr *);
> /*
> * PF_TAG_REROUTE handling or not...
> * Packet is entering IPsec so the routing is
> * already overruled by the IPsec policy.
> @@ -545,11 +528,10 @@ reroute:
> * packet just because ip6_dst is different from what tdb has.
> * XXX
> */
> error = ipsp_process_packet(m, tdb, AF_INET6,
> exthdrs.ip6e_rthdr ? 1 : 0);
> - splx(s);
>
> return error; /* Nothing more to be done */
> }
> #endif /* IPSEC */
>
>