diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -736,23 +736,19 @@ } ia = NULL; } - /* RFC 3927 2.7: Do not forward datagrams for 169.254.0.0/16. */ - if (IN_LINKLOCAL(ntohl(ip->ip_dst.s_addr))) { - IPSTAT_INC(ips_cantforward); - m_freem(m); - return; - } if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) { if (V_ip_mrouter) { /* * If we are acting as a multicast router, all - * incoming multicast packets are passed to the - * kernel-level multicast forwarding function. + * incoming multicast packets without link-local + * source addresses are passed to the kernel-level + * multicast forwarding function. * The packet is returned (relatively) intact; if * ip_mforward() returns a non-zero value, the packet * must be discarded, else it may be accepted below. */ - if (ip_mforward && ip_mforward(ip, ifp, m, 0) != 0) { + if (!IN_LINKLOCAL(ntohl(ip->ip_src.s_addr)) && + ip_mforward && ip_mforward(ip, ifp, m, 0) != 0) { IPSTAT_INC(ips_cantforward); m_freem(m); return; @@ -779,6 +775,14 @@ if (ip->ip_dst.s_addr == INADDR_ANY) goto ours; + /* RFC 3927 2.7: Do not forward datagrams for 169.254.0.0/16. */ + if (IN_LINKLOCAL(ntohl(ip->ip_src.s_addr)) || + IN_LINKLOCAL(ntohl(ip->ip_dst.s_addr))) { + IPSTAT_INC(ips_cantforward); + m_freem(m); + return; + } + /* * Not for us; forward if possible and desirable. */