Subject: kern/34908: Forwarding multicast packets changes source port in udp header
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: None <tbeadle@nexthop.com>
List: netbsd-bugs
Date: 10/25/2006 14:45:00
>Number: 34908
>Category: kern
>Synopsis: Forwarding multicast packets changes source port in udp header
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Oct 25 14:45:00 +0000 2006
>Originator: Tommy Beadle
>Release: 3.0
>Organization:
Nexthop.com
>Environment:
NetBSD rack3-boxb 3.0 NetBSD 3.0 (NEXTHOP-PIM-2) #2: Tue Oct 24 11:25:51 EDT 2006 root@labtest:/usr/src/sys/arch/i386/compile/NEXTHOP-PIM-2 i386
>Description:
Assume multicast routing is enabled and the multicast forwarding cache has been populated so an S,G entry exists with an iif and oiflist.
When a udp packet arrives for that S,G, the source port in the udp header is changed to an incorrect value and the checksum becomes invalid.
>How-To-Repeat:
Given the following topology:
+--+ +--+ +--+
S -----|RP|-------|P1|-----|P2|----- R
N2 +--+ N1 +--+ N3 +--+ N4
Configure RP as a PIM-SM rendezvous point and P2 with IGMP running on N4. PIM-SM is running on N1, N2, and N3. Start a multicast receiver for group G on R so that P2 joins to the RP tree. Start sending data from S to G. When the data is forwarded from RP, the udp source port has been corrupted (and the checksum is invalid).
It appears that in_delayed_chksum was getting called and was writing a checksum in to the first 2 bytes of the packet after the IP header, which is the UDP source port in the case of a udp packet.
This only happens when the outgoing interface has UDP4CSUM as a capability listed in ifconfig but has that capability disabled. If either the capability is not present or if it is present and enabled, then the corruption does not occur.
>Fix:
--- netinet/ip_mroute.c.old 2005-02-26 17:45:12.000000000 -0500
+++ netinet/ip_mroute.c 2006-10-20 11:39:55.000000000 -0400
@@ -1418,6 +1418,11 @@
int s;
vifi_t vifi;
+ /*
+ * Clear any in-bound checksum flags for this packet.
+ */
+ m->m_pkthdr.csum_flags = 0;
+
if (mrtdebug & DEBUG_FORWARD)
log(LOG_DEBUG, "ip_mforward: src %x, dst %x, ifp %p\n",
ntohl(ip->ip_src.s_addr), ntohl(ip->ip_dst.s_addr), ifp);