diff --git a/ldpd/ldp_zebra.c b/ldpd/ldp_zebra.c index be94a7e2bd..5582b95c83 100644 --- a/ldpd/ldp_zebra.c +++ b/ldpd/ldp_zebra.c @@ -121,25 +121,48 @@ ldp_zebra_send_mpls_labels(int cmd, struct kroute *kr) (cmd == ZEBRA_MPLS_LABELS_ADD) ? "add" : "delete"); zl.type = ZEBRA_LSP_LDP; - zl.prefix.family = kr->af; - zl.prefix.prefixlen = kr->prefixlen; + zl.local_label = kr->local_label; + + /* Set prefix. */ + SET_FLAG(zl.message, ZAPI_LABELS_FTN); + zl.route.prefix.family = kr->af; switch (kr->af) { case AF_INET: - zl.prefix.u.prefix4 = kr->prefix.v4; - zl.nexthop.ipv4 = kr->nexthop.v4; + zl.route.prefix.u.prefix4 = kr->prefix.v4; break; case AF_INET6: - zl.prefix.u.prefix6 = kr->prefix.v6; - zl.nexthop.ipv6 = kr->nexthop.v6; + zl.route.prefix.u.prefix6 = kr->prefix.v6; break; default: - fatalx("kr_change: unknown af"); + fatalx("ldp_zebra_send_mpls_labels: unknown af"); } - zl.ifindex = kr->ifindex; - zl.route_type = kr->route_type; - zl.route_instance = kr->route_instance; - zl.local_label = kr->local_label; - zl.remote_label = kr->remote_label; + zl.route.prefix.prefixlen = kr->prefixlen; + zl.route.type = kr->route_type; + zl.route.instance = kr->route_instance; + + /* Set nexthop. */ + switch (kr->af) { + case AF_INET: + zl.nexthop.family = AF_INET; + zl.nexthop.address.ipv4 = kr->nexthop.v4; + if (kr->ifindex) + zl.nexthop.type = NEXTHOP_TYPE_IPV4_IFINDEX; + else + zl.nexthop.type = NEXTHOP_TYPE_IPV4; + break; + case AF_INET6: + zl.nexthop.family = AF_INET6; + zl.nexthop.address.ipv6 = kr->nexthop.v6; + if (kr->ifindex) + zl.nexthop.type = NEXTHOP_TYPE_IPV6_IFINDEX; + else + zl.nexthop.type = NEXTHOP_TYPE_IPV6; + break; + default: + break; + } + zl.nexthop.ifindex = kr->ifindex; + zl.nexthop.label = kr->remote_label; return zebra_send_mpls_labels(zclient, cmd, &zl); } diff --git a/lib/zclient.c b/lib/zclient.c index 3e2c0b24d7..a82484e42d 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -2464,25 +2464,31 @@ 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->message); stream_putc(s, zl->type); - stream_putw(s, zl->prefix.family); - stream_put_prefix(s, &zl->prefix); - switch (zl->prefix.family) { + stream_putl(s, zl->local_label); + + if (CHECK_FLAG(zl->message, ZAPI_LABELS_FTN)) { + stream_putw(s, zl->route.prefix.family); + stream_put_prefix(s, &zl->route.prefix); + stream_putc(s, zl->route.type); + stream_putw(s, zl->route.instance); + } + + stream_putc(s, zl->nexthop.type); + stream_putw(s, zl->nexthop.family); + switch (zl->nexthop.family) { case AF_INET: - stream_put_in_addr(s, &zl->nexthop.ipv4); + stream_put_in_addr(s, &zl->nexthop.address.ipv4); break; case AF_INET6: - stream_write(s, (uint8_t *)&zl->nexthop.ipv6, 16); + stream_write(s, (uint8_t *)&zl->nexthop.address.ipv6, 16); break; default: - flog_err(EC_LIB_ZAPI_ENCODE, "%s: unknown af", __func__); - return -1; + break; } - stream_putl(s, zl->ifindex); - stream_putc(s, zl->route_type); - stream_putw(s, zl->route_instance); - stream_putl(s, zl->local_label); - stream_putl(s, zl->remote_label); + stream_putl(s, zl->nexthop.ifindex); + stream_putl(s, zl->nexthop.label); /* Put length at the first point of the stream. */ stream_putw_at(s, 0, stream_get_endp(s)); @@ -2492,47 +2498,67 @@ int zapi_labels_encode(struct stream *s, int cmd, struct zapi_labels *zl) 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->message); STREAM_GETC(s, zl->type); - STREAM_GETW(s, zl->prefix.family); - STREAM_GETC(s, zl->prefix.prefixlen); - psize = PSIZE(zl->prefix.prefixlen); + STREAM_GETL(s, zl->local_label); - 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); + if (CHECK_FLAG(zl->message, ZAPI_LABELS_FTN)) { + size_t psize; + + STREAM_GETW(s, zl->route.prefix.family); + STREAM_GETC(s, zl->route.prefix.prefixlen); + + psize = PSIZE(zl->route.prefix.prefixlen); + switch (zl->route.prefix.family) { + case AF_INET: + if (zl->route.prefix.prefixlen > IPV4_MAX_BITLEN) { + zlog_debug( + "%s: Specified prefix length %d is greater than a v4 address can support", + __PRETTY_FUNCTION__, + zl->route.prefix.prefixlen); + return -1; + } + STREAM_GET(&zl->route.prefix.u.prefix4.s_addr, s, + psize); + break; + case AF_INET6: + if (zl->route.prefix.prefixlen > IPV6_MAX_BITLEN) { + zlog_debug( + "%s: Specified prefix length %d is greater than a v6 address can support", + __PRETTY_FUNCTION__, + zl->route.prefix.prefixlen); + return -1; + } + STREAM_GET(&zl->route.prefix.u.prefix6, s, psize); + break; + default: + flog_err(EC_LIB_ZAPI_ENCODE, + "%s: Specified family %u is not v4 or v6", + __PRETTY_FUNCTION__, zl->route.prefix.family); return -1; } - STREAM_GET(&zl->prefix.u.prefix4.s_addr, s, psize); - STREAM_GET(&zl->nexthop.ipv4.s_addr, s, IPV4_MAX_BYTELEN); + + STREAM_GETC(s, zl->route.type); + STREAM_GETW(s, zl->route.instance); + } + + STREAM_GETC(s, zl->nexthop.type); + STREAM_GETW(s, zl->nexthop.family); + switch (zl->nexthop.family) { + case AF_INET: + STREAM_GET(&zl->nexthop.address.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); + STREAM_GET(&zl->nexthop.address.ipv6, s, 16); break; default: - zlog_debug("%s: Specified AF %d is not supported for this call", - __PRETTY_FUNCTION__, zl->prefix.family); - return -1; + break; } - STREAM_GETL(s, zl->ifindex); - STREAM_GETC(s, zl->route_type); - STREAM_GETW(s, zl->route_instance); - STREAM_GETL(s, zl->local_label); - STREAM_GETL(s, zl->remote_label); + STREAM_GETL(s, zl->nexthop.ifindex); + STREAM_GETL(s, zl->nexthop.label); return 0; stream_failure: diff --git a/lib/zclient.h b/lib/zclient.h index a3238a9161..e0da1cbe32 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -396,14 +396,22 @@ struct zapi_route { }; struct zapi_labels { + uint8_t message; +#define ZAPI_LABELS_FTN 0x01 enum lsp_types_t type; - struct prefix prefix; - union g_addr nexthop; - ifindex_t ifindex; - uint8_t route_type; - unsigned short route_instance; mpls_label_t local_label; - mpls_label_t remote_label; + struct { + struct prefix prefix; + uint8_t type; + unsigned short instance; + } route; + struct { + enum nexthop_types_t type; + int family; + union g_addr address; + ifindex_t ifindex; + mpls_label_t label; + } nexthop; }; struct zapi_pw { diff --git a/ospfd/ospf_sr.c b/ospfd/ospf_sr.c index 70a4d93958..2d06ae77fc 100644 --- a/ospfd/ospf_sr.c +++ b/ospfd/ospf_sr.c @@ -618,15 +618,20 @@ static int ospf_zebra_send_mpls_labels(int cmd, struct sr_nhlfe nhlfe) nhlfe.prefv4.prefixlen, nhlfe.ifindex); zl.type = ZEBRA_LSP_OSPF_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.route_type = ZEBRA_ROUTE_OSPF; - zl.route_instance = 0; zl.local_label = nhlfe.label_in; - zl.remote_label = nhlfe.label_out; + + SET_FLAG(zl.message, ZAPI_LABELS_FTN); + zl.route.prefix.family = nhlfe.prefv4.family; + zl.route.prefix.prefixlen = nhlfe.prefv4.prefixlen; + zl.route.prefix.u.prefix4 = nhlfe.prefv4.prefix; + zl.route.type = ZEBRA_ROUTE_OSPF; + zl.route.instance = 0; + + zl.nexthop.type = NEXTHOP_TYPE_IPV4_IFINDEX; + zl.nexthop.family = AF_INET; + zl.nexthop.address.ipv4 = nhlfe.nexthop; + zl.nexthop.ifindex = nhlfe.ifindex; + zl.nexthop.label = nhlfe.label_out; return zebra_send_mpls_labels(zclient, cmd, &zl); } diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 15ff4a8b97..fa2ce019c5 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -1753,7 +1753,6 @@ static void zread_mpls_labels(ZAPI_HANDLER_ARGS) { struct stream *s; struct zapi_labels zl; - enum nexthop_types_t gtype; /* Get input stream. */ s = msg; @@ -1764,38 +1763,27 @@ static void zread_mpls_labels(ZAPI_HANDLER_ARGS) return; } - switch (zl.prefix.family) { - case AF_INET: - if (zl.ifindex) - gtype = NEXTHOP_TYPE_IPV4_IFINDEX; - else - gtype = NEXTHOP_TYPE_IPV4; - break; - case AF_INET6: - if (zl.ifindex) - gtype = NEXTHOP_TYPE_IPV6_IFINDEX; - else - gtype = NEXTHOP_TYPE_IPV6; - break; - default: - return; - } - if (!mpls_enabled) return; if (hdr->command == ZEBRA_MPLS_LABELS_ADD) { - 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.route_type, - zl.route_instance, zl.remote_label); + mpls_lsp_install(zvrf, zl.type, zl.local_label, + zl.nexthop.label, zl.nexthop.type, + &zl.nexthop.address, zl.nexthop.ifindex); + if (CHECK_FLAG(zl.message, ZAPI_LABELS_FTN)) + mpls_ftn_update(1, zvrf, zl.type, &zl.route.prefix, + zl.nexthop.type, &zl.nexthop.address, + zl.nexthop.ifindex, zl.route.type, + zl.route.instance, zl.nexthop.label); } else if (hdr->command == ZEBRA_MPLS_LABELS_DELETE) { - 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.route_type, - zl.route_instance, zl.remote_label); + mpls_lsp_uninstall(zvrf, zl.type, zl.local_label, + zl.nexthop.type, &zl.nexthop.address, + zl.nexthop.ifindex); + if (CHECK_FLAG(zl.message, ZAPI_LABELS_FTN)) + mpls_ftn_update(0, zvrf, zl.type, &zl.route.prefix, + zl.nexthop.type, &zl.nexthop.address, + zl.nexthop.ifindex, zl.route.type, + zl.route.instance, zl.nexthop.label); } }