multicast IP datagram forwarding bug and fix (fwd)

2 messages, 2 authors, 2003-08-04 · open the first message on its own page

multicast IP datagram forwarding bug and fix (fwd)

From: Pekka Savola <hidden>
Date: 2003-08-04 06:06:04

I didn't see followups to this, so I'm re-sending to the list just in case 
it got dropped in the cracks..

-- 
Pekka Savola                 "You each name yourselves king, yet the
Netcore Oy                    kingdom bleeds."
Systems. Networks. Security. -- George R.R. Martin: A Clash of Kings
---------- Forwarded message ----------
Date: Mon, 28 Jul 2003 13:20:31 -0400
From: "Weng, Wending" <redacted>
To: netdev@oss.sgi.com
Subject: multicast IP datagram forwarding bug and fix
Hi,

   LINUX doesn't forward multicast IP datagram if it has option(s), there is is a bug in the module ipmr.c, function
ipmr_forward_finish, below is the current version of this function:

static inline int ipmr_forward_finish(struct sk_buff *skb)
{
        struct dst_entry *dst = skb->dst;

        if (skb->len <= dst->pmtu)
                return dst->output(skb);
        else
                return ip_fragment(skb, dst->output);
}

it forgets to recalculate the checksum in case the option is modified.

The following code works properly:

static inline int ipmr_forward_finish(struct sk_buff *skb)
{
        struct dst_entry *dst = skb->dst;

        ip_forward_options (skb); /* this line recalculates checksum if needed. */

        if (skb->len <= dst->pmtu)
                return dst->output(skb);
        else
                return ip_fragment(skb, dst->output);
}

Wending Weng

Re: multicast IP datagram forwarding bug and fix (fwd)

From: David S. Miller <hidden>
Date: 2003-08-04 06:05:52

On Mon, 4 Aug 2003 09:06:04 +0300 (EEST)
Pekka Savola [off-list ref] wrote:
I didn't see followups to this, so I'm re-sending to the list just in case 
it got dropped in the cracks..
I've already checked in a correct fix for this problem from Alexey:

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.1584.2.13 -> 1.1584.2.14
#	     net/ipv4/ipmr.c	1.27    -> 1.28   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/08/02	kuznet@ms2.inr.ac.ru	1.1584.2.14
# [IPV4]: IP options were not updated while forwarding multicasts.
# --------------------------------------------
#
diff -Nru a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
--- a/net/ipv4/ipmr.c	Sun Aug  3 23:07:44 2003
+++ b/net/ipv4/ipmr.c	Sun Aug  3 23:07:44 2003
@@ -1100,6 +1100,7 @@
 
 	skb->h.ipiph = skb->nh.iph;
 	skb->nh.iph = iph;
+	memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
 #ifdef CONFIG_NETFILTER
 	nf_conntrack_put(skb->nfct);
 	skb->nfct = NULL;
@@ -1108,12 +1109,14 @@
 
 static inline int ipmr_forward_finish(struct sk_buff *skb)
 {
-	struct dst_entry *dst = skb->dst;
+	struct ip_options * opt	= &(IPCB(skb)->opt);
 
-	if (skb->len <= dst_pmtu(dst))
-		return dst_output(skb);
-	else
-		return ip_fragment(skb, dst_output);
+	IP_INC_STATS_BH(IpForwDatagrams);
+
+	if (unlikely(opt->optlen))
+		ip_forward_options(skb);
+
+	return dst_output(skb);
 }
 
 /*
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help