diff options
author | Daniel Hartmeier <dhartmei@cvs.openbsd.org> | 2003-02-12 20:43:37 +0000 |
---|---|---|
committer | Daniel Hartmeier <dhartmei@cvs.openbsd.org> | 2003-02-12 20:43:37 +0000 |
commit | ee0de7c820b23b984936bf4dfbaded2a1ffbfe1c (patch) | |
tree | 12b5ded2eebbfe4566b4d510394cee640fed55a4 /sys/net/pf_norm.c | |
parent | 0fd3e77cc1aff7a9497b08c27013f38504d9e210 (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.c | 16 |
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) |