diff -NurpP --minimal a/net/ipv4/arp.c b/net/ipv4/arp.c --- a/net/ipv4/arp.c 2005-03-01 16:35:25.000000000 +0100 +++ b/net/ipv4/arp.c 2005-03-04 01:38:12.000000000 +0100 @@ -125,6 +125,7 @@ struct neigh_table *clip_tbl_hook; #include #include +#include /* * Interface to generic neighbour cache. @@ -472,20 +473,26 @@ static int arp_set_predefined(int addr_h int arp_find(unsigned char *haddr, struct sk_buff *skb) { - struct net_device *dev = skb->dev; + struct vnet *vn = vnet_get(skb->nfvnet); + struct net_device *dev = vn ? vn->vndev : skb->dev; u32 paddr; struct neighbour *n; + int ret = 0; + + vxdprintk(VXD_CBIT(ngnet, 1), + "arp_find: skb(%p, #%u) dev(%s, #%u)", + skb, skb->nfxid, dev->name, dev->nfxid); if (!skb->dst) { printk(KERN_DEBUG "arp_find is called with dst==NULL\n"); - kfree_skb(skb); - return 1; + ret = 1; + goto free_skb; } paddr = ((struct rtable*)skb->dst)->rt_gateway; if (arp_set_predefined(inet_addr_type(paddr, dev->nfxid), haddr, paddr, dev)) - return 0; + goto done; n = __neigh_lookup(&arp_tbl, &paddr, dev, 1); @@ -496,12 +503,19 @@ int arp_find(unsigned char *haddr, struc memcpy(haddr, n->ha, dev->addr_len); read_unlock_bh(&n->lock); neigh_release(n); - return 0; + } else { + neigh_release(n); + ret = 1; } - neigh_release(n); - } else - kfree_skb(skb); - return 1; + goto done; + } + +free_skb: + kfree_skb(skb); +done: + if (vn) + vnet_put(vn); + return ret; } /* END OF OBSOLETE FUNCTIONS */