]> git.puffer.fish Git - matthieu/frr.git/commitdiff
lib: introduce encode/decode functions for the MPLS zapi messages
authorRenato Westphal <renato@opensourcerouting.org>
Thu, 8 Aug 2019 00:06:03 +0000 (21:06 -0300)
committerRenato Westphal <renato@opensourcerouting.org>
Sat, 7 Sep 2019 00:06:11 +0000 (21:06 -0300)
Do this for the following reasons:
* Improve modularity of the code by separating the decoding of the
  ZAPI messages from their processing;
* Create an API that is easier to use by the client daemons.

Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
ldpd/ldp_zebra.c
lib/zclient.c
lib/zclient.h
ospfd/ospf_sr.c
zebra/zapi_msg.c

index 35a7d944d30c66d9dc77e55d87acbe851bc9c56c..04e21e8026bd7d5e86e7109d3f455cc23fb28448 100644 (file)
@@ -37,7 +37,7 @@
 static void     ifp2kif(struct interface *, struct kif *);
 static void     ifc2kaddr(struct interface *, struct connected *,
                    struct kaddr *);
-static int      zebra_send_mpls_labels(int, struct kroute *);
+static int      ldp_zebra_send_mpls_labels(int, struct kroute *);
 static int      ldp_router_id_update(ZAPI_CALLBACK_ARGS);
 static int      ldp_interface_add(ZAPI_CALLBACK_ARGS);
 static int      ldp_interface_delete(ZAPI_CALLBACK_ARGS);
@@ -106,9 +106,9 @@ pw2zpw(struct l2vpn_pw *pw, struct zapi_pw *zpw)
 }
 
 static int
-zebra_send_mpls_labels(int cmd, struct kroute *kr)
+ldp_zebra_send_mpls_labels(int cmd, struct kroute *kr)
 {
-       struct stream           *s;
+       struct zapi_labels zl = {};
 
        if (kr->local_label < MPLS_LABEL_RESERVED_MAX ||
            kr->remote_label == NO_LABEL)
@@ -120,48 +120,39 @@ zebra_send_mpls_labels(int cmd, struct kroute *kr)
            log_label(kr->local_label), log_label(kr->remote_label),
            (cmd == ZEBRA_MPLS_LABELS_ADD) ? "add" : "delete");
 
-       /* Reset stream. */
-       s = zclient->obuf;
-       stream_reset(s);
-
-       zclient_create_header(s, cmd, VRF_DEFAULT);
-       stream_putc(s, ZEBRA_LSP_LDP);
-       stream_putl(s, kr->af);
+       zl.type = ZEBRA_LSP_LDP;
+       zl.prefix.family = kr->af;
+       zl.prefix.prefixlen = kr->prefixlen;
        switch (kr->af) {
        case AF_INET:
-               stream_put_in_addr(s, &kr->prefix.v4);
-               stream_putc(s, kr->prefixlen);
-               stream_put_in_addr(s, &kr->nexthop.v4);
+               zl.prefix.u.prefix4 = kr->prefix.v4;
+               zl.nexthop.ipv4 = kr->nexthop.v4;
                break;
        case AF_INET6:
-               stream_write(s, (uint8_t *)&kr->prefix.v6, 16);
-               stream_putc(s, kr->prefixlen);
-               stream_write(s, (uint8_t *)&kr->nexthop.v6, 16);
+               zl.prefix.u.prefix6 = kr->prefix.v6;
+               zl.nexthop.ipv6 = kr->nexthop.v6;
                break;
        default:
                fatalx("kr_change: unknown af");
        }
-       stream_putl(s, kr->ifindex);
-       stream_putc(s, kr->priority);
-       stream_putl(s, kr->local_label);
-       stream_putl(s, kr->remote_label);
-
-       /* Put length at the first point of the stream. */
-       stream_putw_at(s, 0, stream_get_endp(s));
+       zl.ifindex = kr->ifindex;
+       zl.distance = kr->priority;
+       zl.local_label = kr->local_label;
+       zl.remote_label = kr->remote_label;
 
-       return (zclient_send_message(zclient));
+       return zebra_send_mpls_labels(zclient, cmd, &zl);
 }
 
 int
 kr_change(struct kroute *kr)
 {
-       return (zebra_send_mpls_labels(ZEBRA_MPLS_LABELS_ADD, kr));
+       return (ldp_zebra_send_mpls_labels(ZEBRA_MPLS_LABELS_ADD, kr));
 }
 
 int
 kr_delete(struct kroute *kr)
 {
-       return (zebra_send_mpls_labels(ZEBRA_MPLS_LABELS_DELETE, kr));
+       return (ldp_zebra_send_mpls_labels(ZEBRA_MPLS_LABELS_DELETE, kr));
 }
 
 int
index f809704f8679b195c13a9a4d2cbd2f5f1242979e..81f0b81f62b3c40c1b37aae736df8a4ee41c8f19 100644 (file)
@@ -2451,6 +2451,91 @@ int tm_release_table_chunk(struct zclient *zclient, uint32_t start,
        return zclient_send_message(zclient);
 }
 
+int zebra_send_mpls_labels(struct zclient *zclient, int cmd,
+                          struct zapi_labels *zl)
+{
+       if (zapi_labels_encode(zclient->obuf, cmd, zl) < 0)
+               return -1;
+       return zclient_send_message(zclient);
+}
+
+int zapi_labels_encode(struct stream *s, int cmd, struct zapi_labels *zl)
+{
+       stream_reset(s);
+
+       zclient_create_header(s, cmd, VRF_DEFAULT);
+       stream_putc(s, zl->type);
+       stream_putw(s, zl->prefix.family);
+       stream_put_prefix(s, &zl->prefix);
+       switch (zl->prefix.family) {
+       case AF_INET:
+               stream_put_in_addr(s, &zl->nexthop.ipv4);
+               break;
+       case AF_INET6:
+               stream_write(s, (uint8_t *)&zl->nexthop.ipv6, 16);
+               break;
+       default:
+               flog_err(EC_LIB_ZAPI_ENCODE, "%s: unknown af", __func__);
+               return -1;
+       }
+       stream_putl(s, zl->ifindex);
+       stream_putc(s, zl->distance);
+       stream_putl(s, zl->local_label);
+       stream_putl(s, zl->remote_label);
+
+       /* Put length at the first point of the stream. */
+       stream_putw_at(s, 0, stream_get_endp(s));
+
+       return 0;
+}
+
+int zapi_labels_decode(struct stream *s, struct zapi_labels *zl)
+{
+       size_t psize;
+
+       memset(zl, 0, sizeof(*zl));
+
+       /* Get data. */
+       STREAM_GETC(s, zl->type);
+       STREAM_GETW(s, zl->prefix.family);
+       STREAM_GETC(s, zl->prefix.prefixlen);
+       psize = PSIZE(zl->prefix.prefixlen);
+
+       switch (zl->prefix.family) {
+       case AF_INET:
+               if (zl->prefix.prefixlen > IPV4_MAX_BITLEN) {
+                       zlog_debug(
+                               "%s: Specified prefix length %d is greater than a v4 address can support",
+                               __PRETTY_FUNCTION__, zl->prefix.prefixlen);
+                       return -1;
+               }
+               STREAM_GET(&zl->prefix.u.prefix4.s_addr, s, psize);
+               STREAM_GET(&zl->nexthop.ipv4.s_addr, s, IPV4_MAX_BYTELEN);
+               break;
+       case AF_INET6:
+               if (zl->prefix.prefixlen > IPV6_MAX_BITLEN) {
+                       zlog_debug(
+                               "%s: Specified prefix length %d is greater than a v6 address can support",
+                               __PRETTY_FUNCTION__, zl->prefix.prefixlen);
+                       return -1;
+               }
+               STREAM_GET(&zl->prefix.u.prefix6, s, psize);
+               STREAM_GET(&zl->nexthop.ipv6, s, 16);
+               break;
+       default:
+               zlog_debug("%s: Specified AF %d is not supported for this call",
+                          __PRETTY_FUNCTION__, zl->prefix.family);
+               return -1;
+       }
+       STREAM_GETL(s, zl->ifindex);
+       STREAM_GETC(s, zl->distance);
+       STREAM_GETL(s, zl->local_label);
+       STREAM_GETL(s, zl->remote_label);
+
+       return 0;
+stream_failure:
+       return -1;
+}
 
 int zebra_send_pw(struct zclient *zclient, int command, struct zapi_pw *pw)
 {
index 81e454d1924ec4791e505edd8376c3e5de382f53..e665635a8a332326fa159be2c70c827a42c20f2e 100644 (file)
@@ -395,6 +395,16 @@ struct zapi_route {
        uint32_t tableid;
 };
 
+struct zapi_labels {
+       enum lsp_types_t type;
+       struct prefix prefix;
+       union g_addr nexthop;
+       ifindex_t ifindex;
+       uint8_t distance;
+       mpls_label_t local_label;
+       mpls_label_t remote_label;
+};
+
 struct zapi_pw {
        char ifname[IF_NAMESIZE];
        ifindex_t ifindex;
@@ -625,6 +635,12 @@ extern int tm_get_table_chunk(struct zclient *zclient, uint32_t chunk_size,
 extern int tm_release_table_chunk(struct zclient *zclient, uint32_t start,
                                  uint32_t end);
 
+extern int zebra_send_mpls_labels(struct zclient *zclient, int cmd,
+                                 struct zapi_labels *zl);
+extern int zapi_labels_encode(struct stream *s, int cmd,
+                             struct zapi_labels *zl);
+extern int zapi_labels_decode(struct stream *s, struct zapi_labels *zl);
+
 extern int zebra_send_pw(struct zclient *zclient, int command,
                         struct zapi_pw *pw);
 extern void zebra_read_pw_status_update(ZAPI_CALLBACK_ARGS, struct zapi_pw_status *pw);
index 6947393a6086b1983cfa0b3a77f7cadec4b91487..a361d17817b2d6a95cd5db16d31364e82e4dc679 100644 (file)
@@ -608,26 +608,7 @@ static int compute_prefix_nhlfe(struct sr_prefix *srp)
 /* Send MPLS Label entry to Zebra for installation or deletion */
 static int ospf_zebra_send_mpls_labels(int cmd, struct sr_nhlfe nhlfe)
 {
-       struct stream *s;
-
-       /* Reset stream. */
-       s = zclient->obuf;
-       stream_reset(s);
-
-       zclient_create_header(s, cmd, VRF_DEFAULT);
-       stream_putc(s, ZEBRA_LSP_SR);
-       /* OSPF Segment Routing currently support only IPv4 */
-       stream_putl(s, nhlfe.prefv4.family);
-       stream_put_in_addr(s, &nhlfe.prefv4.prefix);
-       stream_putc(s, nhlfe.prefv4.prefixlen);
-       stream_put_in_addr(s, &nhlfe.nexthop);
-       stream_putl(s, nhlfe.ifindex);
-       stream_putc(s, OSPF_SR_PRIORITY_DEFAULT);
-       stream_putl(s, nhlfe.label_in);
-       stream_putl(s, nhlfe.label_out);
-
-       /* Put length at the first point of the stream. */
-       stream_putw_at(s, 0, stream_get_endp(s));
+       struct zapi_labels zl = {};
 
        if (IS_DEBUG_OSPF_SR)
                zlog_debug("    |-  %s LSP %u/%u for %s/%u via %u",
@@ -636,7 +617,17 @@ static int ospf_zebra_send_mpls_labels(int cmd, struct sr_nhlfe nhlfe)
                           inet_ntoa(nhlfe.prefv4.prefix),
                           nhlfe.prefv4.prefixlen, nhlfe.ifindex);
 
-       return zclient_send_message(zclient);
+       zl.type = ZEBRA_LSP_SR;
+       zl.prefix.family = nhlfe.prefv4.family;
+       zl.prefix.prefixlen = nhlfe.prefv4.prefixlen;
+       zl.prefix.u.prefix4 = nhlfe.prefv4.prefix;
+       zl.nexthop.ipv4 = nhlfe.nexthop;
+       zl.ifindex = nhlfe.ifindex;
+       zl.distance = OSPF_SR_PRIORITY_DEFAULT;
+       zl.local_label = nhlfe.label_in;
+       zl.remote_label = nhlfe.label_out;
+
+       return zebra_send_mpls_labels(zclient, cmd, &zl);
 }
 
 /* Request zebra to install/remove FEC in FIB */
index fa6a2f62ec00318cbe329ff207214e44b0d5daee..6915d84c0d2ac7ff2b696dddd8d4eeb3db0c35bd 100644 (file)
@@ -1752,62 +1752,27 @@ static void zread_vrf_unregister(ZAPI_HANDLER_ARGS)
 static void zread_mpls_labels(ZAPI_HANDLER_ARGS)
 {
        struct stream *s;
-       enum lsp_types_t type;
-       struct prefix prefix;
+       struct zapi_labels zl;
        enum nexthop_types_t gtype;
-       union g_addr gate;
-       ifindex_t ifindex;
-       mpls_label_t in_label, out_label;
-       uint8_t distance;
 
        /* Get input stream.  */
        s = msg;
-
-       /* Get data. */
-       STREAM_GETC(s, type);
-       STREAM_GETL(s, prefix.family);
-       switch (prefix.family) {
-       case AF_INET:
-               STREAM_GET(&prefix.u.prefix4.s_addr, s, IPV4_MAX_BYTELEN);
-               STREAM_GETC(s, prefix.prefixlen);
-               if (prefix.prefixlen > IPV4_MAX_BITLEN) {
-                       zlog_debug(
-                               "%s: Specified prefix length %d is greater than a v4 address can support",
-                               __PRETTY_FUNCTION__, prefix.prefixlen);
-                       return;
-               }
-               STREAM_GET(&gate.ipv4.s_addr, s, IPV4_MAX_BYTELEN);
-               break;
-       case AF_INET6:
-               STREAM_GET(&prefix.u.prefix6, s, 16);
-               STREAM_GETC(s, prefix.prefixlen);
-               if (prefix.prefixlen > IPV6_MAX_BITLEN) {
-                       zlog_debug(
-                               "%s: Specified prefix length %d is greater than a v6 address can support",
-                               __PRETTY_FUNCTION__, prefix.prefixlen);
-                       return;
-               }
-               STREAM_GET(&gate.ipv6, s, 16);
-               break;
-       default:
-               zlog_debug("%s: Specified AF %d is not supported for this call",
-                          __PRETTY_FUNCTION__, prefix.family);
+       if (zapi_labels_decode(s, &zl) < 0) {
+               if (IS_ZEBRA_DEBUG_RECV)
+                       zlog_debug("%s: Unable to decode zapi_labels sent",
+                                  __PRETTY_FUNCTION__);
                return;
        }
-       STREAM_GETL(s, ifindex);
-       STREAM_GETC(s, distance);
-       STREAM_GETL(s, in_label);
-       STREAM_GETL(s, out_label);
 
-       switch (prefix.family) {
+       switch (zl.prefix.family) {
        case AF_INET:
-               if (ifindex)
+               if (zl.ifindex)
                        gtype = NEXTHOP_TYPE_IPV4_IFINDEX;
                else
                        gtype = NEXTHOP_TYPE_IPV4;
                break;
        case AF_INET6:
-               if (ifindex)
+               if (zl.ifindex)
                        gtype = NEXTHOP_TYPE_IPV6_IFINDEX;
                else
                        gtype = NEXTHOP_TYPE_IPV6;
@@ -1820,17 +1785,18 @@ static void zread_mpls_labels(ZAPI_HANDLER_ARGS)
                return;
 
        if (hdr->command == ZEBRA_MPLS_LABELS_ADD) {
-               mpls_lsp_install(zvrf, type, in_label, out_label, gtype, &gate,
-                                ifindex);
-               mpls_ftn_update(1, zvrf, type, &prefix, gtype, &gate, ifindex,
-                               distance, out_label);
+               mpls_lsp_install(zvrf, zl.type, zl.local_label, zl.remote_label,
+                                gtype, &zl.nexthop, zl.ifindex);
+               mpls_ftn_update(1, zvrf, zl.type, &zl.prefix, gtype,
+                               &zl.nexthop, zl.ifindex, zl.distance,
+                               zl.remote_label);
        } else if (hdr->command == ZEBRA_MPLS_LABELS_DELETE) {
-               mpls_lsp_uninstall(zvrf, type, in_label, gtype, &gate, ifindex);
-               mpls_ftn_update(0, zvrf, type, &prefix, gtype, &gate, ifindex,
-                               distance, out_label);
+               mpls_lsp_uninstall(zvrf, zl.type, zl.local_label, gtype,
+                                  &zl.nexthop, zl.ifindex);
+               mpls_ftn_update(0, zvrf, zl.type, &zl.prefix, gtype,
+                               &zl.nexthop, zl.ifindex, zl.distance,
+                               zl.remote_label);
        }
-stream_failure:
-       return;
 }
 
 /* Send response to a table manager connect request to client */