Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FRR]: Patch for kernel level graceful restart. #3621

Merged
merged 3 commits into from
Oct 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
227 changes: 227 additions & 0 deletions src/sonic-frr/patch/0008-zebra-kernel-level-graceful-restart.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@

zebra: Add kernel level graceful restart

<Initial Code from Praveen Chaudhary>

Add the a `--graceful_restart X` flag to zebra start that
now creates a timer that pops in X seconds and will go
through and remove all routes that are older than startup.

If graceful_restart is not specified then we will just pop
a timer that cleans everything up immediately.

Signed-off-by: Praveen Chaudhary <[email protected]>
Signed-off-by: Donald Sharp <[email protected]>

diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst
index f38db9d24..40d894929 100644
--- a/doc/user/zebra.rst
+++ b/doc/user/zebra.rst
@@ -23,9 +23,12 @@ Besides the common invocation options (:ref:`common-invocation-options`), the
Runs in batch mode. *zebra* parses configuration file and terminates
immediately.

-.. option:: -k, --keep_kernel
+.. option:: -K TIME, --graceful_restart TIME

- When zebra starts up, don't delete old self inserted routes.
+ If this option is specified, the graceful restart time is TIME seconds.
+ Zebra, when started, will read in routes. Those routes that Zebra
+ identifies that it was the originator of will be swept in TIME seconds.
+ If no time is specified then we will sweep those routes immediately.

.. option:: -r, --retain

diff --git a/zebra/main.c b/zebra/main.c
index 184e798bd..3d1d156ad 100644
--- a/zebra/main.c
+++ b/zebra/main.c
@@ -74,8 +74,7 @@ int retain_mode = 0;
/* Allow non-quagga entities to delete quagga routes */
int allow_delete = 0;

-/* Don't delete kernel route. */
-int keep_kernel_mode = 0;
+int graceful_restart;

bool v6_rr_semantics = false;

@@ -89,12 +88,12 @@ uint32_t nl_rcvbufsize = 4194304;
struct option longopts[] = {
{"batch", no_argument, NULL, 'b'},
{"allow_delete", no_argument, NULL, 'a'},
- {"keep_kernel", no_argument, NULL, 'k'},
{"socket", required_argument, NULL, 'z'},
{"ecmp", required_argument, NULL, 'e'},
{"label_socket", no_argument, NULL, 'l'},
{"retain", no_argument, NULL, 'r'},
{"vrfdefaultname", required_argument, NULL, 'o'},
+ {"graceful_restart", required_argument, NULL, 'K'},
#ifdef HAVE_NETLINK
{"vrfwnetns", no_argument, NULL, 'n'},
{"nl-bufsize", required_argument, NULL, 's'},
@@ -264,13 +263,14 @@ int main(int argc, char **argv)
char *netlink_fuzzing = NULL;
#endif /* HANDLE_NETLINK_FUZZING */

+ graceful_restart = 0;
vrf_configure_backend(VRF_BACKEND_VRF_LITE);
logicalrouter_configure_backend(LOGICALROUTER_BACKEND_NETNS);

frr_preinit(&zebra_di, argc, argv);

frr_opt_add(
- "bakz:e:l:o:r"
+ "baz:e:l:o:rK:"
#ifdef HAVE_NETLINK
"s:n"
#endif
@@ -282,24 +282,24 @@ int main(int argc, char **argv)
#endif /* HANDLE_NETLINK_FUZZING */
,
longopts,
- " -b, --batch Runs in batch mode\n"
- " -a, --allow_delete Allow other processes to delete zebra routes\n"
- " -z, --socket Set path of zebra socket\n"
- " -e, --ecmp Specify ECMP to use.\n"
- " -l, --label_socket Socket to external label manager\n"
- " -k, --keep_kernel Don't delete old routes which were installed by zebra.\n"
- " -r, --retain When program terminates, retain added route by zebra.\n"
- " -o, --vrfdefaultname Set default VRF name.\n"
+ " -b, --batch Runs in batch mode\n"
+ " -a, --allow_delete Allow other processes to delete zebra routes\n"
+ " -z, --socket Set path of zebra socket\n"
+ " -e, --ecmp Specify ECMP to use.\n"
+ " -l, --label_socket Socket to external label manager\n"
+ " -r, --retain When program terminates, retain added route by zebra.\n"
+ " -o, --vrfdefaultname Set default VRF name.\n"
+ " -K, --graceful_restart Graceful restart at the kernel level, timer in seconds for expiration\n"
#ifdef HAVE_NETLINK
- " -n, --vrfwnetns Use NetNS as VRF backend\n"
- " -s, --nl-bufsize Set netlink receive buffer size\n"
- " --v6-rr-semantics Use v6 RR semantics\n"
+ " -n, --vrfwnetns Use NetNS as VRF backend\n"
+ " -s, --nl-bufsize Set netlink receive buffer size\n"
+ " --v6-rr-semantics Use v6 RR semantics\n"
#endif /* HAVE_NETLINK */
#if defined(HANDLE_ZAPI_FUZZING)
- " -c <file> Bypass normal startup and use this file for testing of zapi\n"
+ " -c <file> Bypass normal startup and use this file for testing of zapi\n"
#endif /* HANDLE_ZAPI_FUZZING */
#if defined(HANDLE_NETLINK_FUZZING)
- " -w <file> Bypass normal startup and use this file for testing of netlink input\n"
+ " -w <file> Bypass normal startup and use this file for testing of netlink input\n"
#endif /* HANDLE_NETLINK_FUZZING */
);

@@ -318,9 +318,6 @@ int main(int argc, char **argv)
case 'a':
allow_delete = 1;
break;
- case 'k':
- keep_kernel_mode = 1;
- break;
case 'e':
multipath_num = atoi(optarg);
if (multipath_num > MULTIPATH_NUM
@@ -350,6 +347,9 @@ int main(int argc, char **argv)
case 'r':
retain_mode = 1;
break;
+ case 'K':
+ graceful_restart = atoi(optarg);
+ break;
#ifdef HAVE_NETLINK
case 's':
nl_rcvbufsize = atoi(optarg);
@@ -437,9 +437,9 @@ int main(int argc, char **argv)
* will be equal to the current getpid(). To know about such routes,
* we have to have route_read() called before.
*/
- if (!keep_kernel_mode)
- rib_sweep_route();
-
+ zrouter.startup_time = monotime(NULL);
+ thread_add_timer(zrouter.master, rib_sweep_route,
+ NULL, graceful_restart, NULL);
/* Needed for BSD routing socket. */
pid = getpid();

diff --git a/zebra/rib.h b/zebra/rib.h
index 9fe42aef3..69850f3a0 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -351,7 +351,7 @@ extern struct route_entry *rib_lookup_ipv4(struct prefix_ipv4 *p,
extern void rib_update(vrf_id_t vrf_id, rib_update_event_t event);
extern void rib_update_table(struct route_table *table,
rib_update_event_t event);
-extern void rib_sweep_route(void);
+extern int rib_sweep_route(struct thread *t);
extern void rib_sweep_table(struct route_table *table);
extern void rib_close_table(struct route_table *table);
extern void rib_init(void);
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 555127b09..b6afcdc8c 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -3145,6 +3145,7 @@ void rib_sweep_table(struct route_table *table)

for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) {
RNODE_FOREACH_RE_SAFE (rn, re, next) {
+
if (IS_ZEBRA_DEBUG_RIB)
route_entry_dump(&rn->p, NULL, re);

@@ -3154,6 +3155,14 @@ void rib_sweep_table(struct route_table *table)
if (!CHECK_FLAG(re->flags, ZEBRA_FLAG_SELFROUTE))
continue;

+ /*
+ * If routes are older than startup_time then
+ * we know we read them in from the kernel.
+ * As such we can safely remove them.
+ */
+ if (zrouter.startup_time < re->uptime)
+ continue;
+
/*
* So we are starting up and have received
* routes from the kernel that we have installed
@@ -3183,7 +3192,7 @@ void rib_sweep_table(struct route_table *table)
}

/* Sweep all RIB tables. */
-void rib_sweep_route(void)
+int rib_sweep_route(struct thread *t)
{
struct vrf *vrf;
struct zebra_vrf *zvrf;
@@ -3197,6 +3206,8 @@ void rib_sweep_route(void)
}

zebra_router_sweep_route();
+
+ return 0;
}

/* Remove specific by protocol routes from 'table'. */
diff --git a/zebra/zebra_router.h b/zebra/zebra_router.h
index b316b91d0..b2e92bad0 100644
--- a/zebra/zebra_router.h
+++ b/zebra/zebra_router.h
@@ -110,8 +110,15 @@ struct zebra_router {
* The EVPN instance, if any
*/
struct zebra_vrf *evpn_vrf;
+
+ /*
+ * Time for when we sweep the rib from old routes
+ */
+ time_t startup_time;
};

+#define GRACEFUL_RESTART_TIME 60
+
extern struct zebra_router zrouter;

extern void zebra_router_init(void);
1 change: 1 addition & 0 deletions src/sonic-frr/patch/series
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
0005-Support-VRF.patch
0006-changes-for-making-snmp-socket-non-blocking.patch
0007-prevent-dead-fd-poll-data-port-fix-from-frr.patch
0008-zebra-kernel-level-graceful-restart.patch