From mboxrd@z Thu Jan 1 00:00:00 1970 From: Kristian Evensen Subject: [PATCH net-next] fib_trie: Send RTM_DELROUTE when link goes down Date: Thu, 17 Oct 2013 13:13:15 +0200 Message-ID: <1382008395-9869-1-git-send-email-kristian.evensen@gmail.com> Cc: Kristian Evensen To: netdev@vger.kernel.org Return-path: Received: from mail-lb0-f175.google.com ([209.85.217.175]:62940 "EHLO mail-lb0-f175.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751299Ab3JQLNa (ORCPT ); Thu, 17 Oct 2013 07:13:30 -0400 Received: by mail-lb0-f175.google.com with SMTP id y6so1764583lbh.34 for ; Thu, 17 Oct 2013 04:13:28 -0700 (PDT) Sender: netdev-owner@vger.kernel.org List-ID: From: Kristian Evensen When a link is set as down using for example "ip link set dev X down", routes are deleted, but RTM_DELROUTE messages are not sent to RTNLGRP_IPV4_ROUTE. This patch makes trie_flush_list() send a RTM_DELROUTE for each route that is removed, and makes rtnelink route deletion behavior consistent across commands. The parameter lists for trie_flush_list() and trie_flush_leaf() are expanded to include required information otherwise unavailable in trie_flush_list(). One use case that is simplified by this patch is IPv4 WAN connection monitoring. Instead of listening for and handling both RTM_*ROUTE and RTM_*LINK-messages, it is sufficient to handle RTM_*ROUTE. Signed-off-by: Kristian Evensen --- net/ipv4/fib_trie.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index ec9a9ef..acd5b3b 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -1698,15 +1698,23 @@ int fib_table_delete(struct fib_table *tb, struct fib_config *cfg) return 0; } -static int trie_flush_list(struct list_head *head) +static int trie_flush_list(struct list_head *head, u32 tb_id, t_key key, + int plen) { struct fib_alias *fa, *fa_node; int found = 0; + struct nl_info cfg; + + memset(&cfg, 0, sizeof(cfg)); list_for_each_entry_safe(fa, fa_node, head, fa_list) { struct fib_info *fi = fa->fa_info; if (fi && (fi->fib_flags & RTNH_F_DEAD)) { + cfg.nl_net = fi->fib_net; + rtmsg_fib(RTM_DELROUTE, htonl(key), fa, plen, tb_id, + &cfg, 0); + list_del_rcu(&fa->fa_list); fib_release_info(fa->fa_info); alias_free_mem_rcu(fa); @@ -1716,7 +1724,7 @@ static int trie_flush_list(struct list_head *head) return found; } -static int trie_flush_leaf(struct leaf *l) +static int trie_flush_leaf(struct leaf *l, u32 tb_id) { int found = 0; struct hlist_head *lih = &l->list; @@ -1724,7 +1732,7 @@ static int trie_flush_leaf(struct leaf *l) struct leaf_info *li = NULL; hlist_for_each_entry_safe(li, tmp, lih, hlist) { - found += trie_flush_list(&li->falh); + found += trie_flush_list(&li->falh, tb_id, l->key, li->plen); if (list_empty(&li->falh)) { hlist_del_rcu(&li->hlist); @@ -1813,7 +1821,7 @@ int fib_table_flush(struct fib_table *tb) int found = 0; for (l = trie_firstleaf(t); l; l = trie_nextleaf(l)) { - found += trie_flush_leaf(l); + found += trie_flush_leaf(l, tb->tb_id); if (ll && hlist_empty(&ll->list)) trie_leaf_remove(t, ll); -- 1.8.1.2