]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: update routing socket path
authorMark Stapp <mjs@voltanet.io>
Fri, 17 Aug 2018 19:25:24 +0000 (15:25 -0400)
committerMark Stapp <mjs@voltanet.io>
Thu, 25 Oct 2018 12:56:52 +0000 (08:56 -0400)
Update route-socket path for route updates using the async
dplane module.

Signed-off-by: Mark Stapp <mjs@voltanet.io>
zebra/kernel_socket.c
zebra/rt_socket.c
zebra/zebra_dplane.c
zebra/zebra_dplane.h

index 8df5a37640674abcff43818c88de686bbd756cbe..d236d488d456f290c7ad7c77618debdc3731b0af 100644 (file)
@@ -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;
 
index eddb0ebfb3b29318893b4a71df05949383b4a2f8..99c4474e6911a4840038f5cd1bdf92161a1c58b5 100644 (file)
@@ -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)
 {
index 5e3aa6a4e9e05d93c62205626af7b16f9ba10f9b..4f54b3440b7f4fd967c740034b6ffb9f7c10317a 100644 (file)
@@ -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 */
index 49c98879fe855ce1f8acdbaa91bcd0839fedb024..88e671e6152b72fc2c4157cbb1b8b8b233741802 100644 (file)
@@ -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.