Page MenuHomeFreeBSD

D43499.diff
No OneTemporary

D43499.diff

diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -2297,6 +2297,7 @@
void pf_poolmask(struct pf_addr *, struct pf_addr*,
struct pf_addr *, struct pf_addr *, sa_family_t);
void pf_addr_inc(struct pf_addr *, sa_family_t);
+int pf_max_frag_size(struct mbuf *);
int pf_refragment6(struct ifnet *, struct mbuf **, struct m_tag *, bool);
#endif /* INET6 */
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -8510,6 +8510,18 @@
return (PF_PASS);
}
+ /*
+ * If we end up changing IP addresses (e.g. binat) the stack may get
+ * confused and fail to send the icmp6 packet too big error. Just send
+ * it here, before we do any NAT.
+ */
+ if (dir == PF_OUT && IN6_LINKMTU(ifp) < pf_max_frag_size(m)) {
+ PF_RULES_RUNLOCK();
+ *m0 = NULL;
+ icmp6_error(m, ICMP6_PACKET_TOO_BIG, 0, IN6_LINKMTU(ifp));
+ return (PF_DROP);
+ }
+
memset(&pd, 0, sizeof(pd));
TAILQ_INIT(&pd.sctp_multihome_jobs);
if (default_actions != NULL)
diff --git a/sys/netpfil/pf/pf_norm.c b/sys/netpfil/pf/pf_norm.c
--- a/sys/netpfil/pf/pf_norm.c
+++ b/sys/netpfil/pf/pf_norm.c
@@ -939,6 +939,21 @@
#endif /* INET6 */
#ifdef INET6
+int
+pf_max_frag_size(struct mbuf *m)
+{
+ struct m_tag *tag;
+ struct pf_fragment_tag *ftag;
+
+ tag = m_tag_find(m, PACKET_TAG_PF_REASSEMBLED, NULL);
+ if (tag == NULL)
+ return (m->m_pkthdr.len);
+
+ ftag = (struct pf_fragment_tag *)(tag + 1);
+
+ return (ftag->ft_maxlen);
+}
+
int
pf_refragment6(struct ifnet *ifp, struct mbuf **m0, struct m_tag *mtag,
bool forward)

File Metadata

Mime Type
text/plain
Expires
Thu, Apr 24, 9:58 PM (17 h, 31 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17767765
Default Alt Text
D43499.diff (1 KB)

Event Timeline