Skip to content

Commit

Permalink
net: introduce a new function dst_dev_put()
Browse files Browse the repository at this point in the history
This function should be called when removing routes from fib tree after
the dst gc is no longer in use.
We first mark DST_OBSOLETE_DEAD on this dst to make sure next
dst_ops->check() fails and returns NULL.
Secondly, as we no longer keep the gc_list, we need to properly
release dst->dev right at the moment when the dst is removed from
the fib/fib6 tree.
It does the following:
1. change dst->input and output pointers to dst_discard/dst_dscard_out to
   discard all packets
2. replace dst->dev with loopback interface

Signed-off-by: Wei Wang <[email protected]>
Acked-by: Martin KaFai Lau <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
tracywwnj authored and davem330 committed Jun 18, 2017
1 parent 5f56f40 commit 4a6ce2b
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 0 deletions.
1 change: 1 addition & 0 deletions include/net/dst.h
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,7 @@ void dst_init(struct dst_entry *dst, struct dst_ops *ops,
unsigned short flags);
void __dst_free(struct dst_entry *dst);
struct dst_entry *dst_destroy(struct dst_entry *dst);
void dst_dev_put(struct dst_entry *dst);

static inline void dst_free(struct dst_entry *dst)
{
Expand Down
24 changes: 24 additions & 0 deletions net/core/dst.c
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,30 @@ static void dst_destroy_rcu(struct rcu_head *head)
__dst_free(dst);
}

/* Operations to mark dst as DEAD and clean up the net device referenced
* by dst:
* 1. put the dst under loopback interface and discard all tx/rx packets
* on this route.
* 2. release the net_device
* This function should be called when removing routes from the fib tree
* in preparation for a NETDEV_DOWN/NETDEV_UNREGISTER event and also to
* make the next dst_ops->check() fail.
*/
void dst_dev_put(struct dst_entry *dst)
{
struct net_device *dev = dst->dev;

dst->obsolete = DST_OBSOLETE_DEAD;
if (dst->ops->ifdown)
dst->ops->ifdown(dst, dev, true);
dst->input = dst_discard;
dst->output = dst_discard_out;
dst->dev = dev_net(dst->dev)->loopback_dev;
dev_hold(dst->dev);
dev_put(dev);
}
EXPORT_SYMBOL(dst_dev_put);

void dst_release(struct dst_entry *dst)
{
if (dst) {
Expand Down

0 comments on commit 4a6ce2b

Please sign in to comment.