summaryrefslogtreecommitdiff
path: root/sys/net/pf_norm.c
diff options
context:
space:
mode:
authorDaniel Hartmeier <dhartmei@cvs.openbsd.org>2003-02-12 20:43:37 +0000
committerDaniel Hartmeier <dhartmei@cvs.openbsd.org>2003-02-12 20:43:37 +0000
commitee0de7c820b23b984936bf4dfbaded2a1ffbfe1c (patch)
tree12b5ded2eebbfe4566b4d510394cee640fed55a4 /sys/net/pf_norm.c
parent0fd3e77cc1aff7a9497b08c27013f38504d9e210 (diff)
Address the NFS problems recently discussed in various threads.
Change semantics of scrub option 'no-df' slightly: if the option is used, it now also applies to _fragments_ with IP_DF set, not just to complete packets. Hence, adding 'no-df' to 'scrub in all fragment reassemble' allows to clear IP_DF from fragments, so they don't get dropped but reassembled. This affects several UDP protocols that used PMTU discovery, mostly Linux' NFS implementation. In short, if you have 'scrub in all' now, you probably want to change that to 'scrub in all no-df', unless you want to drop fragments with IP_DF set (some people have good reasons to do the latter, hence the non-default option). ok frantzen@, henning@, cedric@
Diffstat (limited to 'sys/net/pf_norm.c')
-rw-r--r--sys/net/pf_norm.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/sys/net/pf_norm.c b/sys/net/pf_norm.c
index 410fccbe5f2..f05ef514260 100644
--- a/sys/net/pf_norm.c
+++ b/sys/net/pf_norm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_norm.c,v 1.53 2003/02/08 20:13:20 dhartmei Exp $ */
+/* $OpenBSD: pf_norm.c,v 1.54 2003/02/12 20:43:36 dhartmei Exp $ */
/*
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
@@ -830,11 +830,18 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct ifnet *ifp, u_short *reason)
if (hlen > h->ip_len)
goto drop;
+ /* Clear IP_DF if the rule uses the no-df option */
+ if (r->rule_flag & PFRULE_NODF)
+ h->ip_off &= ~IP_DF;
+
/* We will need other tests here */
if (!fragoff && !mff)
goto no_fragment;
- /* This can not happen */
+ /* We're dealing with a fragment now. Don't allow fragments
+ * with IP_DF to enter the cache. If the flag was cleared by
+ * no-df above, fine. Otherwise drop it.
+ */
if (h->ip_off & IP_DF) {
DPFPRINTF(("IP_DF\n"));
goto bad;
@@ -940,10 +947,7 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct ifnet *ifp, u_short *reason)
return (PF_PASS);
/* At this point, only IP_DF is allowed in ip_off */
- if (r->rule_flag & PFRULE_NODF)
- h->ip_off = 0;
- else
- h->ip_off &= IP_DF;
+ h->ip_off &= IP_DF;
/* Enforce a minimum ttl, may cause endless packet loops */
if (r->min_ttl && h->ip_ttl < r->min_ttl)