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);