forked from sonic-net/sonic-buildimage
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow shorthand delete of all nexthops in multipath IPv6 routes (#111)
* Adding support for shorthand delete of all nexthops in multipath IPv6 route delete since FRR fills only prefix information for deleting IPv6 multipath route. This was already supported by IPv4 but missing for IPv6. This commit brings shorthand delete of IPv6 multipath routes. Backporting changes from newer linux kernel https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/net/ipv6/route.c?h=v4.14.144&id=0ae8133586ad1c9be894411aaf8b17bb58c8efe5
- Loading branch information
1 parent
feb42b0
commit 886d46f
Showing
2 changed files
with
141 additions
and
0 deletions.
There are no files selected for viewing
140 changes: 140 additions & 0 deletions
140
patch/0001-net-ipv6-Allow-shorthand-delete-of-all-nexthops-in-m.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
From 055d25a3f712c2fcb16a171786e487739953d471 Mon Sep 17 00:00:00 2001 | ||
From: Preetham Singh <[email protected]> | ||
Date: Wed, 18 Sep 2019 02:54:13 -0700 | ||
Subject: [PATCH] net: ipv6: Allow shorthand delete of all | ||
nexthops in multipath route | ||
|
||
This was already supported by IPv4 but missing for IPv6. This commit | ||
brings shorthand delete of IPv6 multipath routes in kernel. | ||
|
||
Successive delete of multi-path routes(32 paths) was not clearing all routes in kernel though frr was sending RTM_DELROUTE when last nexthop was getting deleted. Reason being For IPv6 delete route in kernel, expects all nhops to be sent. On counter part, IPv4 route delete in kernel does NOT expect all nhops to be sent. FRR currently doesnt send any nhops when operation is RTM_DELROUTE for both IPv4 & IPv6. | ||
|
||
back porting below changes from newer version of kernel | ||
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/net/ipv6/route.c?h=v4.14.144&id=0ae8133586ad1c9be894411aaf8b17bb58c8efe5 | ||
|
||
After importing above patch, there were no stale IPv6 routes in kernel. | ||
|
||
Signed-off-by: Preetham Singh <[email protected]> | ||
--- | ||
include/net/ip6_fib.h | 4 ++- | ||
net/ipv6/route.c | 67 +++++++++++++++++++++++++++++++++++++++++-- | ||
2 files changed, 68 insertions(+), 3 deletions(-) | ||
|
||
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h | ||
index a6bcb18..82ef4ba 100644 | ||
--- a/include/net/ip6_fib.h | ||
+++ b/include/net/ip6_fib.h | ||
@@ -37,7 +37,9 @@ struct fib6_config { | ||
int fc_ifindex; | ||
u32 fc_flags; | ||
u32 fc_protocol; | ||
- u32 fc_type; /* only 8 bits are used */ | ||
+ u16 fc_type; /* only 8 bits are used */ | ||
+ u16 fc_delete_all_nh : 1, | ||
+ __unused : 15; | ||
|
||
struct in6_addr fc_dst; | ||
struct in6_addr fc_src; | ||
diff --git a/net/ipv6/route.c b/net/ipv6/route.c | ||
index 7dcd34f..9743662 100644 | ||
--- a/net/ipv6/route.c | ||
+++ b/net/ipv6/route.c | ||
@@ -98,6 +98,12 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, | ||
struct sk_buff *skb); | ||
static void rt6_dst_from_metrics_check(struct rt6_info *rt); | ||
static int rt6_score_route(struct rt6_info *rt, int oif, int strict); | ||
+static size_t rt6_nlmsg_size(struct rt6_info *rt); | ||
+static int rt6_fill_node(struct net *net, | ||
+ struct sk_buff *skb, struct rt6_info *rt, | ||
+ struct in6_addr *dst, struct in6_addr *src, | ||
+ int iif, int type, u32 portid, u32 seq, | ||
+ int prefix, int nowait, unsigned int flags); | ||
|
||
#ifdef CONFIG_IPV6_ROUTE_INFO | ||
static struct rt6_info *rt6_add_route_info(struct net *net, | ||
@@ -2183,6 +2189,57 @@ int ip6_del_rt(struct rt6_info *rt) | ||
return __ip6_del_rt(rt, &info); | ||
} | ||
|
||
+static int __ip6_del_rt_siblings(struct rt6_info *rt, struct fib6_config *cfg) | ||
+{ | ||
+ struct nl_info *info = &cfg->fc_nlinfo; | ||
+ struct net *net = info->nl_net; | ||
+ struct sk_buff *skb = NULL; | ||
+ struct fib6_table *table; | ||
+ int err = -ENOENT; | ||
+ | ||
+ if (rt == net->ipv6.ip6_null_entry) | ||
+ goto out_put; | ||
+ table = rt->rt6i_table; | ||
+ write_lock_bh(&table->tb6_lock); | ||
+ | ||
+ if (rt->rt6i_nsiblings && cfg->fc_delete_all_nh) { | ||
+ struct rt6_info *sibling, *next_sibling; | ||
+ | ||
+ /* prefer to send a single notification with all hops */ | ||
+ skb = nlmsg_new(rt6_nlmsg_size(rt), gfp_any()); | ||
+ if (skb) { | ||
+ u32 seq = info->nlh ? info->nlh->nlmsg_seq : 0; | ||
+ | ||
+ if (rt6_fill_node(net, skb, rt, | ||
+ NULL, NULL, 0, RTM_DELROUTE, | ||
+ info->portid, seq, 0, 0, 0) < 0) { | ||
+ kfree_skb(skb); | ||
+ skb = NULL; | ||
+ } | ||
+ } | ||
+ | ||
+ list_for_each_entry_safe(sibling, next_sibling, | ||
+ &rt->rt6i_siblings, | ||
+ rt6i_siblings) { | ||
+ err = fib6_del(sibling, info); | ||
+ if (err) | ||
+ goto out_unlock; | ||
+ } | ||
+ } | ||
+ | ||
+ err = fib6_del(rt, info); | ||
+out_unlock: | ||
+ write_unlock_bh(&table->tb6_lock); | ||
+out_put: | ||
+ ip6_rt_put(rt); | ||
+ | ||
+ if (skb) { | ||
+ rtnl_notify(skb, net, info->portid, RTNLGRP_IPV6_ROUTE, | ||
+ info->nlh, gfp_any()); | ||
+ } | ||
+ return err; | ||
+} | ||
+ | ||
static int ip6_route_del(struct fib6_config *cfg) | ||
{ | ||
struct fib6_table *table; | ||
@@ -2219,7 +2276,11 @@ static int ip6_route_del(struct fib6_config *cfg) | ||
dst_hold(&rt->dst); | ||
read_unlock_bh(&table->tb6_lock); | ||
|
||
- return __ip6_del_rt(rt, &cfg->fc_nlinfo); | ||
+ /* if gateway was specified only delete the one hop */ | ||
+ if (cfg->fc_flags & RTF_GATEWAY) | ||
+ return __ip6_del_rt(rt, &cfg->fc_nlinfo); | ||
+ | ||
+ return __ip6_del_rt_siblings(rt, cfg); | ||
} | ||
} | ||
read_unlock_bh(&table->tb6_lock); | ||
@@ -3167,8 +3228,10 @@ static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh) | ||
|
||
if (cfg.fc_mp) | ||
return ip6_route_multipath_del(&cfg); | ||
- else | ||
+ else { | ||
+ cfg.fc_delete_all_nh = 1; | ||
return ip6_route_del(&cfg); | ||
+ } | ||
} | ||
|
||
static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh) | ||
-- | ||
2.18.0 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters