[<prev] [next>] [day] [month] [year] [list]
Message-ID: <15f4f9a9d98540819ac6976daaa8ae48@wizdom.nu>
Date: Wed, 14 Apr 2021 09:50:03 +0000
From: Sietse van Zanen <sietse@...dom.nu>
To: "netdev@...r.kernel.org" <netdev@...r.kernel.org>
Subject: FW: IGMP messages leading to MRT_NOCACHE upcalls
Hi,
IGMP packets are eligible to be forwarded by the kernel, leading to MRT_NOCACHE upcalls to userspace. I decided to check into this, because there was a notable difference in multicast mrt between FreeBSD (which "arguably" has the better network stack) and Linux using the exact same user space daemon on the exact same network.
I decided to quickly patch ipmr.c to log what is eligible to be forwarded (in ip_mr_input()):
if (ip_hdr(skb)->ttl <= 1 || (ntohl(ip_hdr(skb)->daddr) & IGMP_LOCAL_GROUP_MASK)
== IGMP_LOCAL_GROUP) {
pr_err("ipmr: packet from 0x%x with ttl %u to 0x%x proto %d\n", ntohl(ip_hdr(skb)->saddr), ip_hdr(skb)->ttl, ntohl(ip_hdr(skb)->daddr), ip_hdr(skb)->protocol);
}
And surely:
[ 4621.488211] ipmr: packet from 0xc0a80190 with ttl 1 to 0xeffffffa proto 17
[ 4621.514365] ipmr: packet from 0xa001464 with ttl 1 to 0xeffffffa proto 17
[ 4621.692470] ipmr: packet from 0xc0a80190 with ttl 1 to 0xeffffffa proto 17
[ 4621.767651] ipmr: packet from 0xc0a80190 with ttl 1 to 0xeffffffa proto 17
[ 4625.497651] ipmr: packet from 0xc0a8018f with ttl 1 to 0xeffffffa proto 2
[ 4626.021713] ipmr: packet from 0xc0a8018f with ttl 1 to 0xe1004701 proto 2
[ 4650.288509] ipmr: packet from 0xa001401 with ttl 1 to 0xe1004701 proto 2
[ 4651.288419] ipmr: packet from 0xa001401 with ttl 1 to 0xe1004701 proto 2
Looking at the FreeBSD source code (from sys/netinet/ip_mroute.c X_ip_mforward()), here these packets are rightly and correctly discarded even before an mrt cache lookup is made.
/*
* Don't forward a packet with time-to-live of zero or one,
* or a packet destined to a local-only group.
*/
if (ip->ip_ttl <= 1 || IN_LOCAL_GROUP(ntohl(ip->ip_dst.s_addr))) {
MFC_UNLOCK();
VIF_UNLOCK();
return 0;
The following comment in ipmr.c also makes absolutely no sense to me:
/* IGMPv1 (and broken IGMPv2 implementations sort of
* Cisco IOS <= 11.2(8)) do not put router alert
* option to IGMP packets destined to routable
* groups. It is very bad, because it means
* that we can forward NO IGMP messages.
IGMP messages, as per rfc1112, rfc2236 and rfc3376 are sent with ttl of 1 and hence must not be forwarded. IGMP pertains to the local network only, and will be seriously broken if routed. Also multicast forwarding rules clearly specify that packets should only be forwarded if their ttl is greater than the interface threshold, which is impossible for packets with ttl of 1.
Network trace shows that these packets are not actually forwarded, only marked as eligible in ip_mr_input().
The following questions therefor deserve an answer:
1. Why are packets with a ttl of 1 eligible to be forwarded and not immediately discarded?
2. Why are IGMP packets eligible to be forwarded?
3. Why are IGMP packets resulting in MRT_NOCACHE upcalls at all?
Userspace daemon is already receiving the IGMP packets themselves and has no way for discerning the resulting upcalls leading to routes being incorrectly added.
4. Would it not be better (or would it break stuff) if these packets will be discarded on earliest convenience in ip_mr_input(), as FreeBSD does:
if (ip_hdr(skb)->ttl <= 1 || (ntohl(ip_hdr(skb)->daddr) & IGMP_LOCAL_GROUP_MASK)
== IGMP_LOCAL_GROUP) {
goto don't_forward;
}
Powered by blists - more mailing lists