Skip to content

Commit

Permalink
arp: allow to invalidate specific ARP entries
Browse files Browse the repository at this point in the history
IPv4 over firewire needs to be able to remove ARP entries
from the ARP cache that belong to nodes that are removed, because
IPv4 over firewire uses ARP packets for private information
about nodes.

This information becomes invalid as soon as node drops
off the bus and when it reconnects, its only possible
to start talking to it after it responded to an ARP packet.
But ARP cache prevents such packets from being sent.

Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Maxim Levitsky authored and David S. Miller committed Jan 11, 2011
1 parent bfe0d02 commit 545ecdc
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 11 deletions.
1 change: 1 addition & 0 deletions include/net/arp.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@ extern struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
const unsigned char *src_hw,
const unsigned char *target_hw);
extern void arp_xmit(struct sk_buff *skb);
int arp_invalidate(struct net_device *dev, __be32 ip);

#endif /* _ARP_H */
29 changes: 18 additions & 11 deletions net/ipv4/arp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1143,6 +1143,23 @@ static int arp_req_get(struct arpreq *r, struct net_device *dev)
return err;
}

int arp_invalidate(struct net_device *dev, __be32 ip)
{
struct neighbour *neigh = neigh_lookup(&arp_tbl, &ip, dev);
int err = -ENXIO;

if (neigh) {
if (neigh->nud_state & ~NUD_NOARP)
err = neigh_update(neigh, NULL, NUD_FAILED,
NEIGH_UPDATE_F_OVERRIDE|
NEIGH_UPDATE_F_ADMIN);
neigh_release(neigh);
}

return err;
}
EXPORT_SYMBOL(arp_invalidate);

static int arp_req_delete_public(struct net *net, struct arpreq *r,
struct net_device *dev)
{
Expand All @@ -1163,7 +1180,6 @@ static int arp_req_delete(struct net *net, struct arpreq *r,
{
int err;
__be32 ip;
struct neighbour *neigh;

if (r->arp_flags & ATF_PUBL)
return arp_req_delete_public(net, r, dev);
Expand All @@ -1181,16 +1197,7 @@ static int arp_req_delete(struct net *net, struct arpreq *r,
if (!dev)
return -EINVAL;
}
err = -ENXIO;
neigh = neigh_lookup(&arp_tbl, &ip, dev);
if (neigh) {
if (neigh->nud_state & ~NUD_NOARP)
err = neigh_update(neigh, NULL, NUD_FAILED,
NEIGH_UPDATE_F_OVERRIDE|
NEIGH_UPDATE_F_ADMIN);
neigh_release(neigh);
}
return err;
return arp_invalidate(dev, ip);
}

/*
Expand Down

0 comments on commit 545ecdc

Please sign in to comment.