summaryrefslogtreecommitdiff
path: root/zebra/rt_socket.c
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2019-02-08 15:01:41 -0500
committerDonald Sharp <sharpd@cumulusnetworks.com>2019-03-27 16:19:28 -0400
commit3cdba47a82b21daf90816bcd31fe4ab005367079 (patch)
tree80c1efaa22c950821e9298ace592ad98db18cd4d /zebra/rt_socket.c
parent7a230a9d0cd2ecf2183f0e679deb52c00e80a172 (diff)
zebra: Modify code so that dplane is responsible for indicating success/fail of install
We have several route types KERNEL and CONNECT that are handled via special case in the code. This was causing a lot of work keeping the two different classes of route types as special(SYSTEM OR NOT). Put the dplane in charge of the code that sets the bits for signalling route install/failure. This greatly simplifies the code calling path and makes all route types be handled exactly the same. Additionaly code that we want to run post data plane install can just work as per normal then, instead of having to know we need to run it when we have a special type of route. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com.
Diffstat (limited to 'zebra/rt_socket.c')
-rw-r--r--zebra/rt_socket.c54
1 files changed, 38 insertions, 16 deletions
diff --git a/zebra/rt_socket.c b/zebra/rt_socket.c
index f25259f300..8d8bdd0a6d 100644
--- a/zebra/rt_socket.c
+++ b/zebra/rt_socket.c
@@ -304,33 +304,41 @@ static int kernel_rtm(int cmd, const struct prefix *p,
enum zebra_dplane_result kernel_route_update(struct zebra_dplane_ctx *ctx)
{
enum zebra_dplane_result res = ZEBRA_DPLANE_REQUEST_SUCCESS;
+ uint32_t type, old_type;
if (dplane_ctx_get_src(ctx) != NULL) {
zlog_err("route add: IPv6 sourcedest routes unsupported!");
return ZEBRA_DPLANE_REQUEST_FAILURE;
}
+ type = dplane_ctx_get_type(ctx);
+ old_type = dplane_ctx_get_old_type(ctx);
+
frr_elevate_privs(&zserv_privs) {
- if (dplane_ctx_get_op(ctx) == DPLANE_OP_ROUTE_DELETE)
- kernel_rtm(RTM_DELETE, dplane_ctx_get_dest(ctx),
- dplane_ctx_get_ng(ctx),
- dplane_ctx_get_metric(ctx));
- else if (dplane_ctx_get_op(ctx) == DPLANE_OP_ROUTE_INSTALL)
- kernel_rtm(RTM_ADD, dplane_ctx_get_dest(ctx),
- dplane_ctx_get_ng(ctx),
- dplane_ctx_get_metric(ctx));
- else if (dplane_ctx_get_op(ctx) == DPLANE_OP_ROUTE_UPDATE) {
+ if (dplane_ctx_get_op(ctx) == DPLANE_OP_ROUTE_DELETE) {
+ if (!RSYSTEM_ROUTE(type))
+ kernel_rtm(RTM_DELETE, dplane_ctx_get_dest(ctx),
+ dplane_ctx_get_ng(ctx),
+ dplane_ctx_get_metric(ctx));
+ } else if (dplane_ctx_get_op(ctx) == DPLANE_OP_ROUTE_INSTALL) {
+ if (!RSYSTEM_ROUTE(type))
+ kernel_rtm(RTM_ADD, dplane_ctx_get_dest(ctx),
+ dplane_ctx_get_ng(ctx),
+ dplane_ctx_get_metric(ctx));
+ } else if (dplane_ctx_get_op(ctx) == DPLANE_OP_ROUTE_UPDATE) {
/* Must do delete and add separately -
* no update available
*/
- kernel_rtm(RTM_DELETE, dplane_ctx_get_dest(ctx),
- dplane_ctx_get_old_ng(ctx),
- dplane_ctx_get_old_metric(ctx));
-
- kernel_rtm(RTM_ADD, dplane_ctx_get_dest(ctx),
- dplane_ctx_get_ng(ctx),
- dplane_ctx_get_metric(ctx));
+ if (!RSYSTEM_ROUTE(old_type))
+ kernel_rtm(RTM_DELETE, dplane_ctx_get_dest(ctx),
+ dplane_ctx_get_old_ng(ctx),
+ dplane_ctx_get_old_metric(ctx));
+
+ if (!RSYSTEM_ROUTE(type))
+ kernel_rtm(RTM_ADD, dplane_ctx_get_dest(ctx),
+ dplane_ctx_get_ng(ctx),
+ dplane_ctx_get_metric(ctx));
} else {
zlog_err("Invalid routing socket update op %s (%u)",
dplane_op2str(dplane_ctx_get_op(ctx)),
@@ -339,6 +347,20 @@ enum zebra_dplane_result kernel_route_update(struct zebra_dplane_ctx *ctx)
}
} /* Elevated privs */
+ if (RSYSTEM_ROUTE(type)
+ && dplane_ctx_get_op(ctx) != DPLANE_OP_ROUTE_DELETE) {
+ struct nexthop *nexthop;
+
+ for (ALL_NEXTHOPS_PTR(dplane_ctx_get_ng(ctx), nexthop)) {
+ if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
+ continue;
+
+ if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) {
+ SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
+ }
+ }
+ }
+
return res;
}