netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next] ipv4: fix DO and PROBE pmtu mode regarding local fragmentation with UFO/CORK
@ 2013-10-25 19:40 Hannes Frederic Sowa
  2013-10-27 14:37 ` Hannes Frederic Sowa
  2013-10-27 16:29 ` [PATCH net-next v2] " Hannes Frederic Sowa
  0 siblings, 2 replies; 4+ messages in thread
From: Hannes Frederic Sowa @ 2013-10-25 19:40 UTC (permalink / raw)
  To: netdev

UFO as well as UDP_CORK do not respect IP_PMTUDISC_DO and
IP_PMTUDISC_PROBE well enough.

UFO enabled packet delivery just appends all frags to the cork and hands
it over to the network card. So we just deliver non-DF udp fragments
(DF-flag may get overwritten by hardware or virtual UFO enabled
interface).

UDP_CORK does enqueue the data until the cork is disengaged. At this
point it sets the correct IP_DF and local_df flags and hands it over to
ip_fragment which in this case will generate an icmp error which gets
appended to the error socket queue. This is not reflected in the syscall
error (of course, if UFO is enabled this also won't happen).

Improve this by checking the pmtudisc flags before appending data to the
socket and if we still can fit all data in one packet when IP_PMTUDISC_DO
or IP_PMTUDISC_PROBE is set, only then proceed.

Maybe, we can relax some other checks around ip_fragment. This needs
more research.

Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
---
 net/ipv4/ip_output.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 8fbac7d..27dc1b3 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -810,7 +810,7 @@ static int __ip_append_data(struct sock *sk,
 	int copy;
 	int err;
 	int offset = 0;
-	unsigned int maxfraglen, fragheaderlen;
+	unsigned int maxfraglen, fragheaderlen, maxmsgsize;
 	int csummode = CHECKSUM_NONE;
 	struct rtable *rt = (struct rtable *)cork->dst;
 
@@ -823,8 +823,10 @@ static int __ip_append_data(struct sock *sk,
 
 	fragheaderlen = sizeof(struct iphdr) + (opt ? opt->optlen : 0);
 	maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen;
+	maxmsgsize = (inet->pmtudisc >= IP_PMTUDISC_DO) ?
+		     maxfraglen : 0xFFFF;
 
-	if (cork->length + length > 0xFFFF - fragheaderlen) {
+	if (cork->length + length > maxmsgsize - fragheaderlen) {
 		ip_local_error(sk, EMSGSIZE, fl4->daddr, inet->inet_dport,
 			       mtu-exthdrlen);
 		return -EMSGSIZE;
@@ -1122,7 +1124,7 @@ ssize_t	ip_append_page(struct sock *sk, struct flowi4 *fl4, struct page *page,
 	int mtu;
 	int len;
 	int err;
-	unsigned int maxfraglen, fragheaderlen, fraggap;
+	unsigned int maxfraglen, fragheaderlen, fraggap, maxmsgsize;
 
 	if (inet->hdrincl)
 		return -EPERM;
@@ -1146,8 +1148,10 @@ ssize_t	ip_append_page(struct sock *sk, struct flowi4 *fl4, struct page *page,
 
 	fragheaderlen = sizeof(struct iphdr) + (opt ? opt->optlen : 0);
 	maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen;
+	maxmsgsize = (inet->pmtudisc >= IP_PMTUDISC_DO) ?
+		     maxfraglen : 0xFFFF;
 
-	if (cork->length + size > 0xFFFF - fragheaderlen) {
+	if (cork->length + size > maxmsgsize - fragheaderlen) {
 		ip_local_error(sk, EMSGSIZE, fl4->daddr, inet->inet_dport, mtu);
 		return -EMSGSIZE;
 	}
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH net-next] ipv4: fix DO and PROBE pmtu mode regarding local fragmentation with UFO/CORK
  2013-10-25 19:40 [PATCH net-next] ipv4: fix DO and PROBE pmtu mode regarding local fragmentation with UFO/CORK Hannes Frederic Sowa
@ 2013-10-27 14:37 ` Hannes Frederic Sowa
  2013-10-27 16:29 ` [PATCH net-next v2] " Hannes Frederic Sowa
  1 sibling, 0 replies; 4+ messages in thread
From: Hannes Frederic Sowa @ 2013-10-27 14:37 UTC (permalink / raw)
  To: netdev

On Fri, Oct 25, 2013 at 09:40:03PM +0200, Hannes Frederic Sowa wrote:
>  	fragheaderlen = sizeof(struct iphdr) + (opt ? opt->optlen : 0);
>  	maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen;
> +	maxmsgsize = (inet->pmtudisc >= IP_PMTUDISC_DO) ?
> +		     maxfraglen : 0xFFFF;

Oops, sorry. I just realized that the check is too strict. The 64
bit boundary restricton is solely used if we are actually generating
fragments. So I should have used mtu directly instead of maxfraglen.

This should only matter in case of some unusual MTUs but I will send a
corrected patch as soon as I am at home.

Greetings,

  Hannes

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH net-next v2] ipv4: fix DO and PROBE pmtu mode regarding local fragmentation with UFO/CORK
  2013-10-25 19:40 [PATCH net-next] ipv4: fix DO and PROBE pmtu mode regarding local fragmentation with UFO/CORK Hannes Frederic Sowa
  2013-10-27 14:37 ` Hannes Frederic Sowa
@ 2013-10-27 16:29 ` Hannes Frederic Sowa
  2013-10-29  4:16   ` David Miller
  1 sibling, 1 reply; 4+ messages in thread
From: Hannes Frederic Sowa @ 2013-10-27 16:29 UTC (permalink / raw)
  To: netdev

UFO as well as UDP_CORK do not respect IP_PMTUDISC_DO and
IP_PMTUDISC_PROBE well enough.

UFO enabled packet delivery just appends all frags to the cork and hands
it over to the network card. So we just deliver non-DF udp fragments
(DF-flag may get overwritten by hardware or virtual UFO enabled
interface).

UDP_CORK does enqueue the data until the cork is disengaged. At this
point it sets the correct IP_DF and local_df flags and hands it over to
ip_fragment which in this case will generate an icmp error which gets
appended to the error socket queue. This is not reflected in the syscall
error (of course, if UFO is enabled this also won't happen).

Improve this by checking the pmtudisc flags before appending data to the
socket and if we still can fit all data in one packet when IP_PMTUDISC_DO
or IP_PMTUDISC_PROBE is set, only then proceed.

We use (mtu-fragheaderlen) to check for the maximum length because we
ensure not to generate a fragment and non-fragmented data does not need
to have its length aligned on 64 bit boundaries. Also the passed in
ip_options are already aligned correctly.

Maybe, we can relax some other checks around ip_fragment. This needs
more research.

Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
---
v2:
 Switch from maxfraglen to mtu for length check as outlined in the commit
 message.

 net/ipv4/ip_output.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 8fbac7d..51be64e 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -810,7 +810,7 @@ static int __ip_append_data(struct sock *sk,
 	int copy;
 	int err;
 	int offset = 0;
-	unsigned int maxfraglen, fragheaderlen;
+	unsigned int maxfraglen, fragheaderlen, maxnonfragsize;
 	int csummode = CHECKSUM_NONE;
 	struct rtable *rt = (struct rtable *)cork->dst;
 
@@ -823,8 +823,10 @@ static int __ip_append_data(struct sock *sk,
 
 	fragheaderlen = sizeof(struct iphdr) + (opt ? opt->optlen : 0);
 	maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen;
+	maxnonfragsize = (inet->pmtudisc >= IP_PMTUDISC_DO) ?
+			 mtu : 0xFFFF;
 
-	if (cork->length + length > 0xFFFF - fragheaderlen) {
+	if (cork->length + length > maxnonfragsize - fragheaderlen) {
 		ip_local_error(sk, EMSGSIZE, fl4->daddr, inet->inet_dport,
 			       mtu-exthdrlen);
 		return -EMSGSIZE;
@@ -1122,7 +1124,7 @@ ssize_t	ip_append_page(struct sock *sk, struct flowi4 *fl4, struct page *page,
 	int mtu;
 	int len;
 	int err;
-	unsigned int maxfraglen, fragheaderlen, fraggap;
+	unsigned int maxfraglen, fragheaderlen, fraggap, maxnonfragsize;
 
 	if (inet->hdrincl)
 		return -EPERM;
@@ -1146,8 +1148,10 @@ ssize_t	ip_append_page(struct sock *sk, struct flowi4 *fl4, struct page *page,
 
 	fragheaderlen = sizeof(struct iphdr) + (opt ? opt->optlen : 0);
 	maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen;
+	maxnonfragsize = (inet->pmtudisc >= IP_PMTUDISC_DO) ?
+			 mtu : 0xFFFF;
 
-	if (cork->length + size > 0xFFFF - fragheaderlen) {
+	if (cork->length + size > maxnonfragsize - fragheaderlen) {
 		ip_local_error(sk, EMSGSIZE, fl4->daddr, inet->inet_dport, mtu);
 		return -EMSGSIZE;
 	}
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH net-next v2] ipv4: fix DO and PROBE pmtu mode regarding local fragmentation with UFO/CORK
  2013-10-27 16:29 ` [PATCH net-next v2] " Hannes Frederic Sowa
@ 2013-10-29  4:16   ` David Miller
  0 siblings, 0 replies; 4+ messages in thread
From: David Miller @ 2013-10-29  4:16 UTC (permalink / raw)
  To: hannes; +Cc: netdev

From: Hannes Frederic Sowa <hannes@stressinduktion.org>
Date: Sun, 27 Oct 2013 17:29:11 +0100

> UFO as well as UDP_CORK do not respect IP_PMTUDISC_DO and
> IP_PMTUDISC_PROBE well enough.
> 
> UFO enabled packet delivery just appends all frags to the cork and hands
> it over to the network card. So we just deliver non-DF udp fragments
> (DF-flag may get overwritten by hardware or virtual UFO enabled
> interface).
> 
> UDP_CORK does enqueue the data until the cork is disengaged. At this
> point it sets the correct IP_DF and local_df flags and hands it over to
> ip_fragment which in this case will generate an icmp error which gets
> appended to the error socket queue. This is not reflected in the syscall
> error (of course, if UFO is enabled this also won't happen).
> 
> Improve this by checking the pmtudisc flags before appending data to the
> socket and if we still can fit all data in one packet when IP_PMTUDISC_DO
> or IP_PMTUDISC_PROBE is set, only then proceed.
> 
> We use (mtu-fragheaderlen) to check for the maximum length because we
> ensure not to generate a fragment and non-fragmented data does not need
> to have its length aligned on 64 bit boundaries. Also the passed in
> ip_options are already aligned correctly.
> 
> Maybe, we can relax some other checks around ip_fragment. This needs
> more research.
> 
> Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
> ---
> v2:
>  Switch from maxfraglen to mtu for length check as outlined in the commit
>  message.

Looks good, applied.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2013-10-29  4:16 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-10-25 19:40 [PATCH net-next] ipv4: fix DO and PROBE pmtu mode regarding local fragmentation with UFO/CORK Hannes Frederic Sowa
2013-10-27 14:37 ` Hannes Frederic Sowa
2013-10-27 16:29 ` [PATCH net-next v2] " Hannes Frederic Sowa
2013-10-29  4:16   ` David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).