From: Mark Stapp Date: Fri, 17 Aug 2018 19:25:24 +0000 (-0400) Subject: zebra: update routing socket path X-Git-Tag: frr-7.1-dev~233^2~9 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=01ce7cbac1895e8308e6c213336a28b4176ef354;p=matthieu%2Ffrr.git zebra: update routing socket path Update route-socket path for route updates using the async dplane module. Signed-off-by: Mark Stapp --- diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index 8df5a37640..d236d488d4 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -48,6 +48,7 @@ #include "zebra/kernel_socket.h" #include "zebra/rib.h" #include "zebra/zebra_errors.h" +#include "zebra/zebra_ptm.h" extern struct zebra_privs_t zserv_privs; diff --git a/zebra/rt_socket.c b/zebra/rt_socket.c index eddb0ebfb3..99c4474e69 100644 --- a/zebra/rt_socket.c +++ b/zebra/rt_socket.c @@ -91,7 +91,7 @@ static int kernel_rtm_add_labels(struct mpls_label_stack *nh_label, /* Interface between zebra message and rtm message. */ static int kernel_rtm_ipv4(int cmd, const struct prefix *p, - struct route_entry *re) + const struct nexthop_group *ng, uint32_t metric) { struct sockaddr_in *mask = NULL; @@ -126,7 +126,7 @@ static int kernel_rtm_ipv4(int cmd, const struct prefix *p, #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ /* Make gateway. */ - for (ALL_NEXTHOPS(re->ng, nexthop)) { + for (ALL_NEXTHOPS_PTR(ng, nexthop)) { if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) continue; @@ -139,8 +139,7 @@ static int kernel_rtm_ipv4(int cmd, const struct prefix *p, * other than ADD and DELETE? */ if ((cmd == RTM_ADD && NEXTHOP_IS_ACTIVE(nexthop->flags)) - || (cmd == RTM_DELETE - && CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))) { + || (cmd == RTM_DELETE)) { if (nexthop->type == NEXTHOP_TYPE_IPV4 || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX) { sin_gate.sin_addr = nexthop->gate.ipv4; @@ -181,14 +180,13 @@ static int kernel_rtm_ipv4(int cmd, const struct prefix *p, (union sockunion *)mask, gate ? (union sockunion *)&sin_gate : NULL, - smplsp, ifindex, bh_type, re->metric); + smplsp, ifindex, bh_type, metric); if (IS_ZEBRA_DEBUG_RIB) { if (!gate) { zlog_debug( - "%s: %s: attention! gate not found for re %p", - __func__, prefix_buf, re); - route_entry_dump(p, NULL, re); + "%s: %s: attention! gate not found for re", + __func__, prefix_buf); } else inet_ntop(AF_INET, &sin_gate.sin_addr, gate_buf, INET_ADDRSTRLEN); @@ -247,8 +245,9 @@ static int kernel_rtm_ipv4(int cmd, const struct prefix *p, /* If there was no useful nexthop, then complain. */ if (nexthop_num == 0) { if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug("%s: No useful nexthops were found in RIB entry %p", - __func__, re); + zlog_debug("%s: No useful nexthops were found in RIB prefix %s", + __func__, prefix2str(p, prefix_buf, + sizeof(prefix_buf))); return 1; } @@ -281,7 +280,7 @@ static int sin6_masklen(struct in6_addr mask) /* Interface between zebra message and rtm message. */ static int kernel_rtm_ipv6(int cmd, const struct prefix *p, - struct route_entry *re) + const struct nexthop_group *ng, uint32_t metric) { struct sockaddr_in6 *mask; struct sockaddr_in6 sin_dest, sin_mask, sin_gate; @@ -312,7 +311,7 @@ static int kernel_rtm_ipv6(int cmd, const struct prefix *p, #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ /* Make gateway. */ - for (ALL_NEXTHOPS(re->ng, nexthop)) { + for (ALL_NEXTHOPS_PTR(ng, nexthop)) { if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) continue; @@ -367,7 +366,7 @@ static int kernel_rtm_ipv6(int cmd, const struct prefix *p, error = rtm_write(cmd, (union sockunion *)&sin_dest, (union sockunion *)mask, gate ? (union sockunion *)&sin_gate : NULL, - smplsp, ifindex, bh_type, re->metric); + smplsp, ifindex, bh_type, metric); (void)error; nexthop_num++; @@ -383,17 +382,65 @@ static int kernel_rtm_ipv6(int cmd, const struct prefix *p, return 0; /*XXX*/ } -static int kernel_rtm(int cmd, const struct prefix *p, struct route_entry *re) +static int kernel_rtm(int cmd, const struct prefix *p, + const struct nexthop_group *ng, uint32_t metric) { switch (PREFIX_FAMILY(p)) { case AF_INET: - return kernel_rtm_ipv4(cmd, p, re); + return kernel_rtm_ipv4(cmd, p, ng, metric); case AF_INET6: - return kernel_rtm_ipv6(cmd, p, re); + return kernel_rtm_ipv6(cmd, p, ng, metric); } return 0; } +/* + * Update or delete a prefix from the kernel, + * using info from a dataplane context struct. + */ +enum zebra_dplane_result kernel_route_update(dplane_ctx_h ctx) +{ + enum zebra_dplane_result res = ZEBRA_DPLANE_REQUEST_SUCCESS; + + if (dplane_ctx_get_src(ctx) != NULL) { + zlog_err("route add: IPv6 sourcedest routes unsupported!"); + res = ZEBRA_DPLANE_REQUEST_FAILURE; + goto done; + } + + if (zserv_privs.change(ZPRIVS_RAISE)) + zlog_err("Can't raise privileges"); + + 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) { + /* + * 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)); + } else { + zlog_err("Invalid routing socket update op %u", + dplane_ctx_get_op(ctx)); + res = ZEBRA_DPLANE_REQUEST_FAILURE; + } + + if (zserv_privs.change(ZPRIVS_LOWER)) + zlog_err("Can't lower privileges"); + +done: + + return res; +} + enum zebra_dplane_result kernel_route_rib(struct route_node *rn, const struct prefix *p, const struct prefix *src_p, @@ -409,13 +456,11 @@ enum zebra_dplane_result kernel_route_rib(struct route_node *rn, } frr_elevate_privs(&zserv_privs) { - if (old) - route |= kernel_rtm(RTM_DELETE, p, old); - + route |= kernel_rtm(RTM_DELETE, p, + &old->ng, old->metric); if (new) - route |= kernel_rtm(RTM_ADD, p, new); - + route |= kernel_rtm(RTM_ADD, p, &new->ng, new->metric); } if (new) { @@ -433,11 +478,6 @@ enum zebra_dplane_result kernel_route_rib(struct route_node *rn, return ZEBRA_DPLANE_REQUEST_SUCCESS; } -enum zebra_dplane_result kernel_route_update(dplane_ctx_h ctx) -{ - return ZEBRA_DPLANE_REQUEST_FAILURE; -} - int kernel_neigh_update(int add, int ifindex, uint32_t addr, char *lla, int llalen, ns_id_t ns_id) { diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index 5e3aa6a4e9..4f54b3440b 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -90,6 +90,7 @@ struct zebra_dplane_ctx_s { route_tag_t zd_tag; route_tag_t zd_old_tag; uint32_t zd_metric; + uint32_t zd_old_metric; uint16_t zd_instance; uint16_t zd_old_instance; @@ -105,6 +106,9 @@ struct zebra_dplane_ctx_s { /* Nexthops */ struct nexthop_group zd_ng; + /* "Previous" nexthops, used only in route update case without netlink */ + struct nexthop_group zd_old_ng; + /* TODO -- use fixed array of nexthops, to avoid mallocs? */ /* Embedded list linkage */ @@ -212,6 +216,10 @@ static void dplane_ctx_free(dplane_ctx_h *pctx) nexthops_free((*pctx)->zd_ng.nexthop); } + if ((*pctx)->zd_old_ng.nexthop) { + nexthops_free((*pctx)->zd_old_ng.nexthop); + } + /* Clear validation value */ (*pctx)->zd_magic = 0; @@ -406,6 +414,13 @@ uint32_t dplane_ctx_get_metric(const dplane_ctx_h ctx) return ctx->zd_metric; } +uint32_t dplane_ctx_get_old_metric(const dplane_ctx_h ctx) +{ + DPLANE_CTX_VALID(ctx); + + return ctx->zd_old_metric; +} + uint32_t dplane_ctx_get_mtu(const dplane_ctx_h ctx) { DPLANE_CTX_VALID(ctx); @@ -441,6 +456,13 @@ const struct nexthop_group *dplane_ctx_get_ng(const dplane_ctx_h ctx) return &(ctx->zd_ng); } +const struct nexthop_group *dplane_ctx_get_old_ng(const dplane_ctx_h ctx) +{ + DPLANE_CTX_VALID(ctx); + + return &(ctx->zd_old_ng); +} + const struct zebra_dplane_info *dplane_ctx_get_ns(const dplane_ctx_h ctx) { DPLANE_CTX_VALID(ctx); @@ -488,6 +510,7 @@ static int dplane_ctx_route_init(dplane_ctx_h ctx, ctx->zd_table_id = re->table; ctx->zd_metric = re->metric; + ctx->zd_old_metric = re->metric; ctx->zd_vrf_id = re->vrf_id; ctx->zd_mtu = re->mtu; ctx->zd_nexthop_mtu = re->nexthop_mtu; @@ -616,6 +639,13 @@ dplane_route_update_internal(struct route_node *rn, ctx->zd_old_type = old_re->type; ctx->zd_old_instance = old_re->instance; ctx->zd_old_distance = old_re->distance; + ctx->zd_old_metric = old_re->metric; + +#ifndef HAVE_NETLINK + /* Capture previous re's nexthops too for bsd, sigh */ + copy_nexthops(&(ctx->zd_old_ng.nexthop), + old_re->ng.nexthop, NULL); +#endif /* !HAVE_NETLINK */ } /* Enqueue context for processing */ diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h index 49c98879fe..88e671e615 100644 --- a/zebra/zebra_dplane.h +++ b/zebra/zebra_dplane.h @@ -159,6 +159,7 @@ route_tag_t dplane_ctx_get_old_tag(const dplane_ctx_h ctx); uint16_t dplane_ctx_get_instance(const dplane_ctx_h ctx); uint16_t dplane_ctx_get_old_instance(const dplane_ctx_h ctx); uint32_t dplane_ctx_get_metric(const dplane_ctx_h ctx); +uint32_t dplane_ctx_get_old_metric(const dplane_ctx_h ctx); uint32_t dplane_ctx_get_mtu(const dplane_ctx_h ctx); uint32_t dplane_ctx_get_nh_mtu(const dplane_ctx_h ctx); uint8_t dplane_ctx_get_distance(const dplane_ctx_h ctx); @@ -166,6 +167,7 @@ uint8_t dplane_ctx_get_old_distance(const dplane_ctx_h ctx); const struct nexthop_group *dplane_ctx_get_ng(const dplane_ctx_h ctx); const struct zebra_dplane_info *dplane_ctx_get_ns(const dplane_ctx_h ctx); +const struct nexthop_group *dplane_ctx_get_old_ng(const dplane_ctx_h ctx); /* * Enqueue route change operations for the dataplane.