On 6/9/17 8:22 AM, Donald Sharp wrote: > @@ -988,7 +988,16 @@ static void ipmr_cache_resolve(struct net *net, struct > mr_table *mrt, > > rtnl_unicast(skb, net, NETLINK_CB(skb).portid); > } else { > - ip_mr_forward(net, mrt, skb, c, 0); > + struct net_device *dev = skb->dev; > + > + if (netif_is_l3_master(dev)) { > + dev = __dev_get_by_index(net, > IPCB(skb)->iif); > + if (!dev) { > + kfree_skb(skb); > + continue; > + } > + } > + ip_mr_forward(net, mrt, dev, skb, c, 0); > } > } > }
What about changing ipmr_cache_unresolved to take the dev it looked up already and then have ipmr_cache_unresolved reset skb->dev to it (and reset skb->skb_iff to dev->ifindex) when queuing to the unresolved list? Since this path does not have a local delivery, resetting the skb->dev will be fine and it avoids this second lookup using IPCB(skb)->iif: @@ -1073,7 +1073,7 @@ static int ipmr_cache_report(struct mr_table *mrt, /* Queue a packet for resolution. It gets locked cache entry! */ static int ipmr_cache_unresolved(struct mr_table *mrt, vifi_t vifi, - struct sk_buff *skb) + struct sk_buff *skb, struct net_device *dev) { const struct iphdr *iph = ip_hdr(skb); struct mfc_cache *c; @@ -1130,6 +1130,10 @@ static int ipmr_cache_unresolved(struct mr_table *mrt, vifi_t vifi, kfree_skb(skb); err = -ENOBUFS; } else { + if (dev) { + skb->dev = dev; + skb->skb_iif = dev->ifindex; + } skb_queue_tail(&c->mfc_un.unres.unresolved, skb); err = 0; } Combined with Thomas' earlier change this check in ip_mr_forward becomes: diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 9374b99c7c17..1393a4d18a9a 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -1853,13 +1853,7 @@ static void ip_mr_forward(struct net *net, struct mr_table *mrt, } /* Wrong interface: drop packet and (maybe) send PIM assert. */ - if (mrt->vif_table[vif].dev != skb->dev) { - struct net_device *mdev; - - mdev = l3mdev_master_dev_rcu(mrt->vif_table[vif].dev); - if (mdev == skb->dev) - goto forward; - + if (mrt->vif_table[vif].dev != dev) { if (rt_is_output_route(skb_rtable(skb))) { /* It is our own packet, looped back. * Very complicated situation...