*** linux-3.4.91/net/ipv4/route.c.orig 2014-05-18 05:26:09.000000000 -0700 --- linux-3.4.91/net/ipv4/route.c 2014-07-22 17:20:03.156032862 -0700 *************** *** 2008,2031 **** --- 2008,2033 ---- return dst_alloc(&ipv4_dst_ops, dev, 1, -1, DST_HOST | (nopolicy ? DST_NOPOLICY : 0) | (noxfrm ? DST_NOXFRM : 0)); } /* called in rcu_read_lock() section */ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, u8 tos, struct net_device *dev, int our) { unsigned int hash; struct rtable *rth; + struct neighbour *n; + char lladdr[8]; __be32 spec_dst; struct in_device *in_dev = __in_dev_get_rcu(dev); u32 itag = 0; int err; /* Primary sanity checks. */ if (in_dev == NULL) return -EINVAL; if (ipv4_is_multicast(saddr) || ipv4_is_lbcast(saddr) || ipv4_is_loopback(saddr) || skb->protocol != htons(ETH_P_IP)) *************** *** 2072,2095 **** --- 2074,2101 ---- rth->dst.input= ip_local_deliver; rth->rt_flags |= RTCF_LOCAL; } #ifdef CONFIG_IP_MROUTE if (!ipv4_is_local_multicast(daddr) && IN_DEV_MFORWARD(in_dev)) rth->dst.input = ip_mr_input; #endif RT_CACHE_STAT_INC(in_slow_mc); hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev))); rth = rt_intern_hash(hash, rth, skb, dev->ifindex); + if (dev_parse_header(skb, lladdr) > 0) { + n = __neigh_lookup(&arp_tbl, &saddr, dev, 1); + neigh_update(n, lladdr, NUD_REACHABLE, 0); + } return IS_ERR(rth) ? PTR_ERR(rth) : 0; e_nobufs: return -ENOBUFS; e_inval: return -EINVAL; e_err: return err; } static void ip_handle_martian_source(struct net_device *dev,