Skip to content

Commit 4b2b606

Browse files
liuhangbinPaolo Abeni
authored andcommitted
ipv4/fib: send notify when delete source address routes
After deleting an interface address in fib_del_ifaddr(), the function scans the fib_info list for stray entries and calls fib_flush() and fib_table_flush(). Then the stray entries will be deleted silently and no RTM_DELROUTE notification will be sent. This lack of notification can make routing daemons, or monitor like `ip monitor route` miss the routing changes. e.g. + ip link add dummy1 type dummy + ip link add dummy2 type dummy + ip link set dummy1 up + ip link set dummy2 up + ip addr add 192.168.5.5/24 dev dummy1 + ip route add 7.7.7.0/24 dev dummy2 src 192.168.5.5 + ip -4 route 7.7.7.0/24 dev dummy2 scope link src 192.168.5.5 192.168.5.0/24 dev dummy1 proto kernel scope link src 192.168.5.5 + ip monitor route + ip addr del 192.168.5.5/24 dev dummy1 Deleted 192.168.5.0/24 dev dummy1 proto kernel scope link src 192.168.5.5 Deleted broadcast 192.168.5.255 dev dummy1 table local proto kernel scope link src 192.168.5.5 Deleted local 192.168.5.5 dev dummy1 table local proto kernel scope host src 192.168.5.5 As Ido reminded, fib_table_flush() isn't only called when an address is deleted, but also when an interface is deleted or put down. The lack of notification in these cases is deliberate. And commit 7c6bb7d ("net/ipv6: Add knob to skip DELROUTE message on device down") introduced a sysctl to make IPv6 behave like IPv4 in this regard. So we can't send the route delete notify blindly in fib_table_flush(). To fix this issue, let's add a new flag in "struct fib_info" to track the deleted prefer source address routes, and only send notify for them. After update: + ip monitor route + ip addr del 192.168.5.5/24 dev dummy1 Deleted 192.168.5.0/24 dev dummy1 proto kernel scope link src 192.168.5.5 Deleted broadcast 192.168.5.255 dev dummy1 table local proto kernel scope link src 192.168.5.5 Deleted local 192.168.5.5 dev dummy1 table local proto kernel scope host src 192.168.5.5 Deleted 7.7.7.0/24 dev dummy2 scope link src 192.168.5.5 Suggested-by: Thomas Haller <[email protected]> Signed-off-by: Hangbin Liu <[email protected]> Acked-by: Nicolas Dichtel <[email protected]> Reviewed-by: David Ahern <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
1 parent 6a70e5c commit 4b2b606

File tree

3 files changed

+6
-0
lines changed

3 files changed

+6
-0
lines changed

include/net/ip_fib.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ struct fib_info {
154154
int fib_nhs;
155155
bool fib_nh_is_v6;
156156
bool nh_updated;
157+
bool pfsrc_removed;
157158
struct nexthop *nh;
158159
struct rcu_head rcu;
159160
struct fib_nh fib_nh[];

net/ipv4/fib_semantics.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1887,6 +1887,7 @@ int fib_sync_down_addr(struct net_device *dev, __be32 local)
18871887
continue;
18881888
if (fi->fib_prefsrc == local) {
18891889
fi->fib_flags |= RTNH_F_DEAD;
1890+
fi->pfsrc_removed = true;
18901891
ret++;
18911892
}
18921893
}

net/ipv4/fib_trie.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2027,6 +2027,7 @@ void fib_table_flush_external(struct fib_table *tb)
20272027
int fib_table_flush(struct net *net, struct fib_table *tb, bool flush_all)
20282028
{
20292029
struct trie *t = (struct trie *)tb->tb_data;
2030+
struct nl_info info = { .nl_net = net };
20302031
struct key_vector *pn = t->kv;
20312032
unsigned long cindex = 1;
20322033
struct hlist_node *tmp;
@@ -2089,6 +2090,9 @@ int fib_table_flush(struct net *net, struct fib_table *tb, bool flush_all)
20892090

20902091
fib_notify_alias_delete(net, n->key, &n->leaf, fa,
20912092
NULL);
2093+
if (fi->pfsrc_removed)
2094+
rtmsg_fib(RTM_DELROUTE, htonl(n->key), fa,
2095+
KEYLENGTH - fa->fa_slen, tb->tb_id, &info, 0);
20922096
hlist_del_rcu(&fa->fa_list);
20932097
fib_release_info(fa->fa_info);
20942098
alias_free_mem_rcu(fa);

0 commit comments

Comments
 (0)