Skip to content

Commit 886d46f

Browse files
preetham-singhlguohan
authored andcommitted
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
1 parent feb42b0 commit 886d46f

2 files changed

Lines changed: 141 additions & 0 deletions

File tree

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
From 055d25a3f712c2fcb16a171786e487739953d471 Mon Sep 17 00:00:00 2001
2+
From: Preetham Singh <[email protected]>
3+
Date: Wed, 18 Sep 2019 02:54:13 -0700
4+
Subject: [PATCH] net: ipv6: Allow shorthand delete of all
5+
nexthops in multipath route
6+
7+
This was already supported by IPv4 but missing for IPv6. This commit
8+
brings shorthand delete of IPv6 multipath routes in kernel.
9+
10+
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.
11+
12+
back porting below changes from newer version of kernel
13+
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/net/ipv6/route.c?h=v4.14.144&id=0ae8133586ad1c9be894411aaf8b17bb58c8efe5
14+
15+
After importing above patch, there were no stale IPv6 routes in kernel.
16+
17+
Signed-off-by: Preetham Singh <[email protected]>
18+
---
19+
include/net/ip6_fib.h | 4 ++-
20+
net/ipv6/route.c | 67 +++++++++++++++++++++++++++++++++++++++++--
21+
2 files changed, 68 insertions(+), 3 deletions(-)
22+
23+
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
24+
index a6bcb18..82ef4ba 100644
25+
--- a/include/net/ip6_fib.h
26+
+++ b/include/net/ip6_fib.h
27+
@@ -37,7 +37,9 @@ struct fib6_config {
28+
int fc_ifindex;
29+
u32 fc_flags;
30+
u32 fc_protocol;
31+
- u32 fc_type; /* only 8 bits are used */
32+
+ u16 fc_type; /* only 8 bits are used */
33+
+ u16 fc_delete_all_nh : 1,
34+
+ __unused : 15;
35+
36+
struct in6_addr fc_dst;
37+
struct in6_addr fc_src;
38+
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
39+
index 7dcd34f..9743662 100644
40+
--- a/net/ipv6/route.c
41+
+++ b/net/ipv6/route.c
42+
@@ -98,6 +98,12 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk,
43+
struct sk_buff *skb);
44+
static void rt6_dst_from_metrics_check(struct rt6_info *rt);
45+
static int rt6_score_route(struct rt6_info *rt, int oif, int strict);
46+
+static size_t rt6_nlmsg_size(struct rt6_info *rt);
47+
+static int rt6_fill_node(struct net *net,
48+
+ struct sk_buff *skb, struct rt6_info *rt,
49+
+ struct in6_addr *dst, struct in6_addr *src,
50+
+ int iif, int type, u32 portid, u32 seq,
51+
+ int prefix, int nowait, unsigned int flags);
52+
53+
#ifdef CONFIG_IPV6_ROUTE_INFO
54+
static struct rt6_info *rt6_add_route_info(struct net *net,
55+
@@ -2183,6 +2189,57 @@ int ip6_del_rt(struct rt6_info *rt)
56+
return __ip6_del_rt(rt, &info);
57+
}
58+
59+
+static int __ip6_del_rt_siblings(struct rt6_info *rt, struct fib6_config *cfg)
60+
+{
61+
+ struct nl_info *info = &cfg->fc_nlinfo;
62+
+ struct net *net = info->nl_net;
63+
+ struct sk_buff *skb = NULL;
64+
+ struct fib6_table *table;
65+
+ int err = -ENOENT;
66+
+
67+
+ if (rt == net->ipv6.ip6_null_entry)
68+
+ goto out_put;
69+
+ table = rt->rt6i_table;
70+
+ write_lock_bh(&table->tb6_lock);
71+
+
72+
+ if (rt->rt6i_nsiblings && cfg->fc_delete_all_nh) {
73+
+ struct rt6_info *sibling, *next_sibling;
74+
+
75+
+ /* prefer to send a single notification with all hops */
76+
+ skb = nlmsg_new(rt6_nlmsg_size(rt), gfp_any());
77+
+ if (skb) {
78+
+ u32 seq = info->nlh ? info->nlh->nlmsg_seq : 0;
79+
+
80+
+ if (rt6_fill_node(net, skb, rt,
81+
+ NULL, NULL, 0, RTM_DELROUTE,
82+
+ info->portid, seq, 0, 0, 0) < 0) {
83+
+ kfree_skb(skb);
84+
+ skb = NULL;
85+
+ }
86+
+ }
87+
+
88+
+ list_for_each_entry_safe(sibling, next_sibling,
89+
+ &rt->rt6i_siblings,
90+
+ rt6i_siblings) {
91+
+ err = fib6_del(sibling, info);
92+
+ if (err)
93+
+ goto out_unlock;
94+
+ }
95+
+ }
96+
+
97+
+ err = fib6_del(rt, info);
98+
+out_unlock:
99+
+ write_unlock_bh(&table->tb6_lock);
100+
+out_put:
101+
+ ip6_rt_put(rt);
102+
+
103+
+ if (skb) {
104+
+ rtnl_notify(skb, net, info->portid, RTNLGRP_IPV6_ROUTE,
105+
+ info->nlh, gfp_any());
106+
+ }
107+
+ return err;
108+
+}
109+
+
110+
static int ip6_route_del(struct fib6_config *cfg)
111+
{
112+
struct fib6_table *table;
113+
@@ -2219,7 +2276,11 @@ static int ip6_route_del(struct fib6_config *cfg)
114+
dst_hold(&rt->dst);
115+
read_unlock_bh(&table->tb6_lock);
116+
117+
- return __ip6_del_rt(rt, &cfg->fc_nlinfo);
118+
+ /* if gateway was specified only delete the one hop */
119+
+ if (cfg->fc_flags & RTF_GATEWAY)
120+
+ return __ip6_del_rt(rt, &cfg->fc_nlinfo);
121+
+
122+
+ return __ip6_del_rt_siblings(rt, cfg);
123+
}
124+
}
125+
read_unlock_bh(&table->tb6_lock);
126+
@@ -3167,8 +3228,10 @@ static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh)
127+
128+
if (cfg.fc_mp)
129+
return ip6_route_multipath_del(&cfg);
130+
- else
131+
+ else {
132+
+ cfg.fc_delete_all_nh = 1;
133+
return ip6_route_del(&cfg);
134+
+ }
135+
}
136+
137+
static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh)
138+
--
139+
2.18.0
140+

patch/series

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ mellanox-backport-introduce-tc-sample-action.patch
8989
kernel-enable-psample-and-act_sample-drivers.patch
9090
0000-net-Fix-netdev-adjacency-tracking.patch
9191
0000-net-ipv6-ll-anycast-mcast-routes-on-dev.patch
92+
0001-net-ipv6-Allow-shorthand-delete-of-all-nexthops-in-m.patch
9293
#
9394
# This series applies on GIT commit 1451b36b2b0d62178e42f648d8a18131af18f7d8
9495
# Tkernel-sched-core-fix-cgroup-fork-race.patch

0 commit comments

Comments
 (0)