diff options
| author | Donald Sharp <sharpd@cumulusnetworks.com> | 2019-02-08 15:01:41 -0500 |
|---|---|---|
| committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2019-03-27 16:19:28 -0400 |
| commit | 3cdba47a82b21daf90816bcd31fe4ab005367079 (patch) | |
| tree | 80c1efaa22c950821e9298ace592ad98db18cd4d /zebra/rt_socket.c | |
| parent | 7a230a9d0cd2ecf2183f0e679deb52c00e80a172 (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.c | 54 |
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; } |
