From e4207ed0486c7620b284918fe21444eab6ae0589 Mon Sep 17 00:00:00 2001 From: dlg Date: Wed, 26 May 2021 06:44:28 +0000 Subject: [PATCH] add support for pf divert-to on tpmr, like what was done for veb(4). when a divert-to rule applies to a packet, pf doesnt take the packet away and shove it in the socket directly. pf marks the packet, and then ip (or ipv6) input processing looks at the mark and picks the local socket to queue it on. because tpmr operates at layer 2, ip input has no chance to look at the packet and let the divert socket steal it. bridge(4) and now veb(4) handle this by checking if the packet has the pf divert to mark set on it and calls ip input if it's set. this copies the semantic to tpmr. --- sys/net/if_tpmr.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/sys/net/if_tpmr.c b/sys/net/if_tpmr.c index 981a7d5a09b..753379a446b 100644 --- a/sys/net/if_tpmr.c +++ b/sys/net/if_tpmr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_tpmr.c,v 1.24 2021/03/05 06:44:09 dlg Exp $ */ +/* $OpenBSD: if_tpmr.c,v 1.25 2021/05/26 06:44:28 dlg Exp $ */ /* * Copyright (c) 2019 The University of Queensland @@ -247,15 +247,20 @@ tpmr_pf(struct ifnet *ifp0, int dir, struct mbuf *m) { struct ether_header *eh, copy; sa_family_t af = AF_UNSPEC; + void (*ip_input)(struct ifnet *, struct mbuf *) = NULL; eh = mtod(m, struct ether_header *); switch (ntohs(eh->ether_type)) { case ETHERTYPE_IP: af = AF_INET; + ip_input = ipv4_input; break; +#ifdef INET6 case ETHERTYPE_IPV6: af = AF_INET6; + ip_input = ipv6_input; break; +#endif default: return (m); } @@ -270,6 +275,11 @@ tpmr_pf(struct ifnet *ifp0, int dir, struct mbuf *m) if (m == NULL) return (NULL); + if (dir == PF_IN && ISSET(m->m_pkthdr.pf.flags, PF_TAG_DIVERTED)) { + (*ip_input)(ifp0, m); + return (NULL); + } + m = m_prepend(m, sizeof(*eh), M_DONTWAIT); if (m == NULL) return (NULL); -- 2.20.1