Hi,
markus@ pointed out that it makes no sense to call pcb lookup from
pf during packet forwarding.
While there remove a useless ifp parameter form ip_output_ipsec_send().
ok?
bluhm
Index: net/pf.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/net/pf.c,v
retrieving revision 1.1046
diff -u -p -r1.1046 pf.c
--- net/pf.c 20 Nov 2017 10:35:24 -0000 1.1046
+++ net/pf.c 21 Nov 2017 14:18:32 -0000
@@ -6776,6 +6776,17 @@ pf_test(sa_family_t af, int fwdir, struc
}
pd.m->m_pkthdr.pf.flags |= PF_TAG_PROCESSED;
+ /*
+ * Avoid pcb-lookups from the forwarding path. They should never
+ * match and would case MP locking problems.
+ */
+ if (fwdir == PF_FWD) {
+ pd.lookup.done = -1;
+ pd.lookup.uid = UID_MAX;
+ pd.lookup.gid = GID_MAX;
+ pd.lookup.pid = NO_PID;
+ }
+
/* lock the lookup/write section of pf_test() */
PF_LOCK();
@@ -7072,7 +7083,8 @@ done:
#ifdef INET6
/* if reassembled packet passed, create new fragments */
- if (pf_status.reass && action == PF_PASS && pd.m && fwdir == PF_FWD) {
+ if (pf_status.reass && action == PF_PASS && pd.m && fwdir == PF_FWD &&
+ pd.af == AF_INET6) {
struct m_tag *mtag;
if ((mtag = m_tag_find(pd.m, PACKET_TAG_PF_REASSEMBLED, NULL)))
Index: netinet/ip_output.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_output.c,v
retrieving revision 1.343
diff -u -p -r1.343 ip_output.c
--- netinet/ip_output.c 26 Oct 2017 15:13:40 -0000 1.343
+++ netinet/ip_output.c 21 Nov 2017 14:12:45 -0000
@@ -84,8 +84,7 @@ struct tdb *
ip_output_ipsec_lookup(struct mbuf *m, int hlen, int *error, struct inpcb *inp,
int ipsecflowinfo);
int
-ip_output_ipsec_send(struct tdb *tdb, struct mbuf *m, struct ifnet *ifp,
- struct route *ro);
+ip_output_ipsec_send(struct tdb *, struct mbuf *, struct route *, int);
#endif /* IPSEC */
/*
@@ -404,7 +403,8 @@ sendit:
*/
if (tdb != NULL) {
/* Callee frees mbuf */
- error = ip_output_ipsec_send(tdb, m, ifp, ro);
+ error = ip_output_ipsec_send(tdb, m, ro,
+ (flags & IP_FORWARDING) ? 1 : 0);
goto done;
}
#endif /* IPSEC */
@@ -413,7 +413,8 @@ sendit:
* Packet filter
*/
#if NPF > 0
- if (pf_test(AF_INET, PF_OUT, ifp, &m) != PF_PASS) {
+ if (pf_test(AF_INET, (flags & IP_FORWARDING) ? PF_FWD : PF_OUT,
+ ifp, &m) != PF_PASS) {
error = EACCES;
m_freem(m);
goto done;
@@ -550,8 +551,7 @@ ip_output_ipsec_lookup(struct mbuf *m, i
}
int
-ip_output_ipsec_send(struct tdb *tdb, struct mbuf *m, struct ifnet *ifp,
- struct route *ro)
+ip_output_ipsec_send(struct tdb *tdb, struct mbuf *m, struct route *ro, int
fwd)
{
#if NPF > 0
struct ifnet *encif;
@@ -563,7 +563,7 @@ ip_output_ipsec_send(struct tdb *tdb, st
* Packet filter
*/
if ((encif = enc_getif(tdb->tdb_rdomain, tdb->tdb_tap)) == NULL ||
- pf_test(AF_INET, PF_OUT, encif, &m) != PF_PASS) {
+ pf_test(AF_INET, fwd ? PF_FWD : PF_OUT, encif, &m) != PF_PASS) {
m_freem(m);
return EACCES;
}