diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/command.h | 2 | ||||
| -rw-r--r-- | lib/ipaddr.h | 14 | ||||
| -rw-r--r-- | lib/log.c | 3 | ||||
| -rw-r--r-- | lib/mpls.h | 1 | ||||
| -rw-r--r-- | lib/nexthop.c | 6 | ||||
| -rw-r--r-- | lib/nexthop.h | 4 | ||||
| -rw-r--r-- | lib/privs.h | 1 | ||||
| -rw-r--r-- | lib/route_types.txt | 1 | ||||
| -rw-r--r-- | lib/routemap.c | 62 | ||||
| -rw-r--r-- | lib/routemap.h | 16 | ||||
| -rw-r--r-- | lib/srte.h | 56 | ||||
| -rw-r--r-- | lib/stream.c | 58 | ||||
| -rw-r--r-- | lib/stream.h | 8 | ||||
| -rw-r--r-- | lib/subdir.am | 1 | ||||
| -rw-r--r-- | lib/zclient.c | 137 | ||||
| -rw-r--r-- | lib/zclient.h | 43 |
16 files changed, 397 insertions, 16 deletions
diff --git a/lib/command.h b/lib/command.h index a7a2eaf868..e20bfe3318 100644 --- a/lib/command.h +++ b/lib/command.h @@ -367,6 +367,8 @@ struct cmd_node { #define SHOW_STR "Show running system information\n" #define IP_STR "IP information\n" #define IPV6_STR "IPv6 information\n" +#define SRTE_STR "SR-TE information\n" +#define SRTE_COLOR_STR "SR-TE Color information\n" #define NO_STR "Negate a command or set its defaults\n" #define REDIST_STR "Redistribute information from another routing protocol\n" #define CLEAR_STR "Reset functions\n" diff --git a/lib/ipaddr.h b/lib/ipaddr.h index aa5b4a3217..730c7ce130 100644 --- a/lib/ipaddr.h +++ b/lib/ipaddr.h @@ -25,6 +25,8 @@ #include <zebra.h> +#include "lib/log.h" + #ifdef __cplusplus extern "C" { #endif @@ -59,6 +61,18 @@ struct ipaddr { #define IPADDRSZ(p) \ (IS_IPADDR_V4((p)) ? sizeof(struct in_addr) : sizeof(struct in6_addr)) +static inline int ipaddr_family(const struct ipaddr *ip) +{ + switch (ip->ipa_type) { + case IPADDR_V4: + return AF_INET; + case IPADDR_V6: + return AF_INET6; + default: + return AF_UNSPEC; + } +} + static inline int str2ipaddr(const char *str, struct ipaddr *ip) { int ret; @@ -384,6 +384,9 @@ static const struct zebra_desc_table command_types[] = { DESC_ENTRY(ZEBRA_MPLS_LABELS_ADD), DESC_ENTRY(ZEBRA_MPLS_LABELS_DELETE), DESC_ENTRY(ZEBRA_MPLS_LABELS_REPLACE), + DESC_ENTRY(ZEBRA_SR_POLICY_SET), + DESC_ENTRY(ZEBRA_SR_POLICY_DELETE), + DESC_ENTRY(ZEBRA_SR_POLICY_NOTIFY_STATUS), DESC_ENTRY(ZEBRA_IPMR_ROUTE_STATS), DESC_ENTRY(ZEBRA_LABEL_MANAGER_CONNECT), DESC_ENTRY(ZEBRA_LABEL_MANAGER_CONNECT_ASYNC), diff --git a/lib/mpls.h b/lib/mpls.h index 126dbf753d..8922a36664 100644 --- a/lib/mpls.h +++ b/lib/mpls.h @@ -129,6 +129,7 @@ enum lsp_types_t { ZEBRA_LSP_OSPF_SR = 4,/* OSPF Segment Routing LSP. */ ZEBRA_LSP_ISIS_SR = 5,/* IS-IS Segment Routing LSP. */ ZEBRA_LSP_SHARP = 6, /* Identifier for test protocol */ + ZEBRA_LSP_SRTE = 7, /* SR-TE LSP */ }; /* Functions for basic label operations. */ diff --git a/lib/nexthop.c b/lib/nexthop.c index 28d96a539c..0ea72d03e1 100644 --- a/lib/nexthop.c +++ b/lib/nexthop.c @@ -152,6 +152,11 @@ static int _nexthop_cmp_no_labels(const struct nexthop *next1, break; } + if (next1->srte_color < next2->srte_color) + return -1; + if (next1->srte_color > next2->srte_color) + return 1; + ret = _nexthop_source_cmp(next1, next2); if (ret != 0) goto done; @@ -643,6 +648,7 @@ void nexthop_copy_no_recurse(struct nexthop *copy, if (copy->backup_num > 0) memcpy(copy->backup_idx, nexthop->backup_idx, copy->backup_num); + copy->srte_color = nexthop->srte_color; memcpy(©->gate, &nexthop->gate, sizeof(nexthop->gate)); memcpy(©->src, &nexthop->src, sizeof(nexthop->src)); memcpy(©->rmap_src, &nexthop->rmap_src, sizeof(nexthop->rmap_src)); diff --git a/lib/nexthop.h b/lib/nexthop.h index ed40cc7eed..cadcea1f41 100644 --- a/lib/nexthop.h +++ b/lib/nexthop.h @@ -98,6 +98,7 @@ struct nexthop { */ #define NEXTHOP_FLAG_RNH_FILTERED (1 << 5) /* rmap filtered, used by rnh */ #define NEXTHOP_FLAG_HAS_BACKUP (1 << 6) /* Backup nexthop index is set */ +#define NEXTHOP_FLAG_SRTE (1 << 7) /* SR-TE color used for BGP traffic */ #define NEXTHOP_IS_ACTIVE(flags) \ (CHECK_FLAG(flags, NEXTHOP_FLAG_ACTIVE) \ @@ -141,6 +142,9 @@ struct nexthop { union { vni_t vni; } nh_encap; + + /* SR-TE color used for matching SR-TE policies */ + uint32_t srte_color; }; /* Utility to append one nexthop to another. */ diff --git a/lib/privs.h b/lib/privs.h index db5707d675..18ba8e8888 100644 --- a/lib/privs.h +++ b/lib/privs.h @@ -24,6 +24,7 @@ #define _ZEBRA_PRIVS_H #include <pthread.h> +#include <stdint.h> #include "lib/queue.h" #ifdef __cplusplus diff --git a/lib/route_types.txt b/lib/route_types.txt index 71d0a46449..b549c11cfc 100644 --- a/lib/route_types.txt +++ b/lib/route_types.txt @@ -85,6 +85,7 @@ ZEBRA_ROUTE_BFD, bfd, bfdd, '-', 0, 0, 0, "BFD" ZEBRA_ROUTE_OPENFABRIC, openfabric, fabricd, 'f', 1, 1, 1, "OpenFabric" ZEBRA_ROUTE_VRRP, vrrp, vrrpd, '-', 0, 0, 0, "VRRP" ZEBRA_ROUTE_NHG, nhg, none, '-', 0, 0, 0, "Nexthop Group" +ZEBRA_ROUTE_SRTE, srte, none, '-', 0, 0, 0, "SR-TE" ZEBRA_ROUTE_ALL, wildcard, none, '-', 0, 0, 0, "-" diff --git a/lib/routemap.c b/lib/routemap.c index df9a6a33ea..fb70860024 100644 --- a/lib/routemap.c +++ b/lib/routemap.c @@ -263,6 +263,24 @@ void route_map_no_match_tag_hook(int (*func)( rmap_match_set_hook.no_match_tag = func; } +/* set sr-te color */ +void route_map_set_srte_color_hook(int (*func)(struct vty *vty, + struct route_map_index *index, + const char *command, + const char *arg)) +{ + rmap_match_set_hook.set_srte_color = func; +} + +/* no set sr-te color */ +void route_map_no_set_srte_color_hook(int (*func)(struct vty *vty, + struct route_map_index *index, + const char *command, + const char *arg)) +{ + rmap_match_set_hook.no_set_srte_color = func; +} + /* set ip nexthop */ void route_map_set_ip_nexthop_hook(int (*func)(struct vty *vty, struct route_map_index *index, @@ -2613,6 +2631,47 @@ static unsigned int route_map_dep_data_hash_make_key(const void *p) return string_hash_make(dep_data->rname); } +DEFUN (set_srte_color, + set_srte_color_cmd, + "set sr-te color [(1-4294967295)]", + SET_STR + SRTE_STR + SRTE_COLOR_STR + "Color of the SR-TE Policies to match with\n") +{ + VTY_DECLVAR_CONTEXT(route_map_index, index); + int idx = 0; + char *arg = argv_find(argv, argc, "(1-4294967295)", &idx) + ? argv[idx]->arg + : NULL; + + if (rmap_match_set_hook.set_srte_color) + return rmap_match_set_hook.set_srte_color(vty, index, + "sr-te color", arg); + return CMD_SUCCESS; +} + +DEFUN (no_set_srte_color, + no_set_srte_color_cmd, + "no set sr-te color [(1-4294967295)]", + NO_STR + SET_STR + SRTE_STR + SRTE_COLOR_STR + "Color of the SR-TE Policies to match with\n") +{ + VTY_DECLVAR_CONTEXT(route_map_index, index); + int idx = 0; + char *arg = argv_find(argv, argc, "(1-4294967295)", &idx) + ? argv[idx]->arg + : NULL; + + if (rmap_match_set_hook.no_set_srte_color) + return rmap_match_set_hook.no_set_srte_color( + vty, index, "sr-te color", arg); + return CMD_SUCCESS; +} + static void *route_map_dep_hash_alloc(void *p) { char *dep_name = (char *)p; @@ -3237,5 +3296,8 @@ void route_map_init(void) install_element(RMAP_NODE, &routemap_optimization_cmd); install_element(RMAP_NODE, &no_routemap_optimization_cmd); + install_element(RMAP_NODE, &set_srte_color_cmd); + install_element(RMAP_NODE, &no_set_srte_color_cmd); + install_element(ENABLE_NODE, &show_route_map_pfx_tbl_cmd); } diff --git a/lib/routemap.h b/lib/routemap.h index 62195b8349..64da4b87ef 100644 --- a/lib/routemap.h +++ b/lib/routemap.h @@ -424,6 +424,14 @@ extern void route_map_match_tag_hook(int (*func)( extern void route_map_no_match_tag_hook(int (*func)( struct vty *vty, struct route_map_index *index, const char *command, const char *arg, route_map_event_t type)); +/* set sr-te color */ +extern void route_map_set_srte_color_hook( + int (*func)(struct vty *vty, struct route_map_index *index, + const char *command, const char *arg)); +/* no set sr-te color */ +extern void route_map_no_set_srte_color_hook( + int (*func)(struct vty *vty, struct route_map_index *index, + const char *command, const char *arg)); /* set ip nexthop */ extern void route_map_set_ip_nexthop_hook( int (*func)(struct vty *vty, struct route_map_index *index, @@ -606,6 +614,14 @@ struct route_map_match_set_hooks { const char *command, const char *arg, route_map_event_t type); + /* set sr-te color */ + int (*set_srte_color)(struct vty *vty, struct route_map_index *index, + const char *command, const char *arg); + + /* no set sr-te color */ + int (*no_set_srte_color)(struct vty *vty, struct route_map_index *index, + const char *command, const char *arg); + /* set ip nexthop */ int (*set_ip_nexthop)(struct vty *vty, struct route_map_index *index, const char *command, const char *arg); diff --git a/lib/srte.h b/lib/srte.h new file mode 100644 index 0000000000..d468c1cac9 --- /dev/null +++ b/lib/srte.h @@ -0,0 +1,56 @@ +/* + * SR-TE definitions + * Copyright 2020 NetDef Inc. + * Sascha Kattelmann + * + * This file is part of GNU Zebra. + * + * GNU Zebra is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * GNU Zebra is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _FRR_SRTE_H +#define _FRR_SRTE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define SRTE_POLICY_NAME_MAX_LENGTH 64 + +enum zebra_sr_policy_status { + ZEBRA_SR_POLICY_UP = 0, + ZEBRA_SR_POLICY_DOWN, +}; + +static inline int sr_policy_compare(const struct ipaddr *a_endpoint, + const struct ipaddr *b_endpoint, + uint32_t a_color, uint32_t b_color) +{ + int ret; + + ret = ipaddr_cmp(a_endpoint, b_endpoint); + if (ret < 0) + return -1; + if (ret > 0) + return 1; + + return a_color - b_color; +} + +#ifdef __cplusplus +} +#endif + +#endif /* _FRR_SRTE_H */ diff --git a/lib/stream.c b/lib/stream.c index d3afebbf13..768114e69b 100644 --- a/lib/stream.c +++ b/lib/stream.c @@ -586,6 +586,43 @@ uint32_t stream_get_ipv4(struct stream *s) return l; } +bool stream_get_ipaddr(struct stream *s, struct ipaddr *ip) +{ + uint16_t ipa_len; + + STREAM_VERIFY_SANE(s); + + /* Get address type. */ + if (STREAM_READABLE(s) < sizeof(uint16_t)) { + STREAM_BOUND_WARN2(s, "get ipaddr"); + return false; + } + ip->ipa_type = stream_getw(s); + + /* Get address value. */ + switch (ip->ipa_type) { + case IPADDR_V4: + ipa_len = IPV4_MAX_BYTELEN; + break; + case IPADDR_V6: + ipa_len = IPV6_MAX_BYTELEN; + break; + default: + flog_err(EC_LIB_DEVELOPMENT, + "%s: unknown ip address-family: %u", __func__, + ip->ipa_type); + return false; + } + if (STREAM_READABLE(s) < ipa_len) { + STREAM_BOUND_WARN2(s, "get ipaddr"); + return false; + } + memcpy(&ip->ip, s->data + s->getp, ipa_len); + s->getp += ipa_len; + + return true; +} + float stream_getf(struct stream *s) { union { @@ -852,6 +889,27 @@ int stream_put_in_addr(struct stream *s, const struct in_addr *addr) return sizeof(uint32_t); } +bool stream_put_ipaddr(struct stream *s, struct ipaddr *ip) +{ + stream_putw(s, ip->ipa_type); + + switch (ip->ipa_type) { + case IPADDR_V4: + stream_put_in_addr(s, &ip->ipaddr_v4); + break; + case IPADDR_V6: + stream_write(s, (uint8_t *)&ip->ipaddr_v6, 16); + break; + default: + flog_err(EC_LIB_DEVELOPMENT, + "%s: unknown ip address-family: %u", __func__, + ip->ipa_type); + return false; + } + + return true; +} + /* Put in_addr at location in the stream. */ int stream_put_in_addr_at(struct stream *s, size_t putp, const struct in_addr *addr) diff --git a/lib/stream.h b/lib/stream.h index 245f35db51..1250b6944d 100644 --- a/lib/stream.h +++ b/lib/stream.h @@ -189,6 +189,7 @@ extern int stream_putq(struct stream *, uint64_t); extern int stream_putq_at(struct stream *, size_t, uint64_t); extern int stream_put_ipv4(struct stream *, uint32_t); extern int stream_put_in_addr(struct stream *s, const struct in_addr *addr); +extern bool stream_put_ipaddr(struct stream *s, struct ipaddr *ip); extern int stream_put_in_addr_at(struct stream *s, size_t putp, const struct in_addr *addr); extern int stream_put_in6_addr_at(struct stream *s, size_t putp, @@ -219,6 +220,7 @@ extern uint64_t stream_getq(struct stream *); extern uint64_t stream_getq_from(struct stream *, size_t); bool stream_getq2(struct stream *s, uint64_t *q); extern uint32_t stream_get_ipv4(struct stream *); +extern bool stream_get_ipaddr(struct stream *s, struct ipaddr *ip); /* IEEE-754 floats */ extern float stream_getf(struct stream *); @@ -439,6 +441,12 @@ static inline const uint8_t *ptr_get_be32(const uint8_t *ptr, uint32_t *out) (P) = _pval; \ } while (0) +#define STREAM_GET_IPADDR(S, P) \ + do { \ + if (!stream_get_ipaddr((S), (P))) \ + goto stream_failure; \ + } while (0) + #define STREAM_GET(P, STR, SIZE) \ do { \ if (!stream_get2((P), (STR), (SIZE))) \ diff --git a/lib/subdir.am b/lib/subdir.am index 34ad30f968..1feaa56d13 100644 --- a/lib/subdir.am +++ b/lib/subdir.am @@ -242,6 +242,7 @@ pkginclude_HEADERS += \ lib/sockunion.h \ lib/spf_backoff.h \ lib/srcdest_table.h \ + lib/srte.h \ lib/stream.h \ lib/systemd.h \ lib/table.h \ diff --git a/lib/zclient.c b/lib/zclient.c index eb62350f4f..da9a7087fc 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -39,6 +39,7 @@ #include "pbr.h" #include "nexthop_group.h" #include "lib_errors.h" +#include "srte.h" DEFINE_MTYPE_STATIC(LIB, ZCLIENT, "Zclient") DEFINE_MTYPE_STATIC(LIB, REDIST_INST, "Redistribution instance IDs") @@ -886,7 +887,7 @@ static void zapi_nexthop_group_sort(struct zapi_nexthop *nh_grp, * Encode a single zapi nexthop */ int zapi_nexthop_encode(struct stream *s, const struct zapi_nexthop *api_nh, - uint32_t api_flags) + uint32_t api_flags, uint32_t api_message) { int i, ret = 0; int nh_flags = api_nh->flags; @@ -950,6 +951,10 @@ int zapi_nexthop_encode(struct stream *s, const struct zapi_nexthop *api_nh, stream_put(s, &(api_nh->rmac), sizeof(struct ethaddr)); + /* Color for Segment Routing TE. */ + if (CHECK_FLAG(api_message, ZAPI_MESSAGE_SRTE)) + stream_putl(s, api_nh->srte_color); + /* Index of backup nexthop */ if (CHECK_FLAG(nh_flags, ZAPI_NEXTHOP_FLAG_HAS_BACKUP)) { /* Validate backup count */ @@ -986,7 +991,7 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api) stream_putw(s, api->instance); stream_putl(s, api->flags); - stream_putc(s, api->message); + stream_putl(s, api->message); if (api->safi < SAFI_UNICAST || api->safi >= SAFI_MAX) { flog_err(EC_LIB_ZAPI_ENCODE, @@ -1047,7 +1052,9 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api) return -1; } - if (zapi_nexthop_encode(s, api_nh, api->flags) != 0) + if (zapi_nexthop_encode(s, api_nh, api->flags, + api->message) + != 0) return -1; } } @@ -1091,7 +1098,9 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api) return -1; } - if (zapi_nexthop_encode(s, api_nh, api->flags) != 0) + if (zapi_nexthop_encode(s, api_nh, api->flags, + api->message) + != 0) return -1; } } @@ -1118,7 +1127,7 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api) * Decode a single zapi nexthop object */ static int zapi_nexthop_decode(struct stream *s, struct zapi_nexthop *api_nh, - uint32_t api_flags) + uint32_t api_flags, uint32_t api_message) { int i, ret = -1; @@ -1171,6 +1180,10 @@ static int zapi_nexthop_decode(struct stream *s, struct zapi_nexthop *api_nh, STREAM_GET(&(api_nh->rmac), s, sizeof(struct ethaddr)); + /* Color for Segment Routing TE. */ + if (CHECK_FLAG(api_message, ZAPI_MESSAGE_SRTE)) + STREAM_GETL(s, api_nh->srte_color); + /* Backup nexthop index */ if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_HAS_BACKUP)) { STREAM_GETC(s, api_nh->backup_num); @@ -1208,7 +1221,7 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api) STREAM_GETW(s, api->instance); STREAM_GETL(s, api->flags); - STREAM_GETC(s, api->message); + STREAM_GETL(s, api->message); STREAM_GETC(s, api->safi); if (api->safi < SAFI_UNICAST || api->safi >= SAFI_MAX) { flog_err(EC_LIB_ZAPI_ENCODE, @@ -1283,7 +1296,9 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api) for (i = 0; i < api->nexthop_num; i++) { api_nh = &api->nexthops[i]; - if (zapi_nexthop_decode(s, api_nh, api->flags) != 0) + if (zapi_nexthop_decode(s, api_nh, api->flags, + api->message) + != 0) return -1; } } @@ -1301,7 +1316,9 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api) for (i = 0; i < api->backup_nexthop_num; i++) { api_nh = &api->backup_nexthops[i]; - if (zapi_nexthop_decode(s, api_nh, api->flags) != 0) + if (zapi_nexthop_decode(s, api_nh, api->flags, + api->message) + != 0) return -1; } } @@ -1488,6 +1505,7 @@ struct nexthop *nexthop_from_zapi_nexthop(const struct zapi_nexthop *znh) n->vrf_id = znh->vrf_id; n->ifindex = znh->ifindex; n->gate = znh->gate; + n->srte_color = znh->srte_color; /* * This function currently handles labels @@ -1605,6 +1623,7 @@ bool zapi_nexthop_update_decode(struct stream *s, struct zapi_route *nhr) memset(nhr, 0, sizeof(*nhr)); + STREAM_GETL(s, nhr->message); STREAM_GETW(s, nhr->prefix.family); STREAM_GETC(s, nhr->prefix.prefixlen); switch (nhr->prefix.family) { @@ -1617,6 +1636,8 @@ bool zapi_nexthop_update_decode(struct stream *s, struct zapi_route *nhr) default: break; } + if (CHECK_FLAG(nhr->message, ZAPI_MESSAGE_SRTE)) + STREAM_GETL(s, nhr->srte_color); STREAM_GETC(s, nhr->type); STREAM_GETW(s, nhr->instance); @@ -1625,7 +1646,7 @@ bool zapi_nexthop_update_decode(struct stream *s, struct zapi_route *nhr) STREAM_GETC(s, nhr->nexthop_num); for (i = 0; i < nhr->nexthop_num; i++) { - if (zapi_nexthop_decode(s, &(nhr->nexthops[i]), 0) != 0) + if (zapi_nexthop_decode(s, &(nhr->nexthops[i]), 0, 0) != 0) return -1; } @@ -2821,6 +2842,92 @@ int tm_release_table_chunk(struct zclient *zclient, uint32_t start, return zclient_send_message(zclient); } +int zebra_send_sr_policy(struct zclient *zclient, int cmd, + struct zapi_sr_policy *zp) +{ + if (zapi_sr_policy_encode(zclient->obuf, cmd, zp) < 0) + return -1; + return zclient_send_message(zclient); +} + +int zapi_sr_policy_encode(struct stream *s, int cmd, struct zapi_sr_policy *zp) +{ + struct zapi_srte_tunnel *zt = &zp->segment_list; + + stream_reset(s); + + zclient_create_header(s, cmd, VRF_DEFAULT); + stream_putl(s, zp->color); + stream_put_ipaddr(s, &zp->endpoint); + stream_write(s, &zp->name, SRTE_POLICY_NAME_MAX_LENGTH); + + stream_putc(s, zt->type); + stream_putl(s, zt->local_label); + + if (zt->label_num > MPLS_MAX_LABELS) { + flog_err(EC_LIB_ZAPI_ENCODE, + "%s: label %u: can't encode %u labels (maximum is %u)", + __func__, zt->local_label, zt->label_num, + MPLS_MAX_LABELS); + return -1; + } + stream_putw(s, zt->label_num); + + for (int i = 0; i < zt->label_num; i++) + stream_putl(s, zt->labels[i]); + + /* Put length at the first point of the stream. */ + stream_putw_at(s, 0, stream_get_endp(s)); + + return 0; +} + +int zapi_sr_policy_decode(struct stream *s, struct zapi_sr_policy *zp) +{ + memset(zp, 0, sizeof(*zp)); + + struct zapi_srte_tunnel *zt = &zp->segment_list; + + STREAM_GETL(s, zp->color); + STREAM_GET_IPADDR(s, &zp->endpoint); + STREAM_GET(&zp->name, s, SRTE_POLICY_NAME_MAX_LENGTH); + + /* segment list of active candidate path */ + STREAM_GETC(s, zt->type); + STREAM_GETL(s, zt->local_label); + STREAM_GETW(s, zt->label_num); + if (zt->label_num > MPLS_MAX_LABELS) { + flog_err(EC_LIB_ZAPI_ENCODE, + "%s: label %u: can't decode %u labels (maximum is %u)", + __func__, zt->local_label, zt->label_num, + MPLS_MAX_LABELS); + return -1; + } + for (int i = 0; i < zt->label_num; i++) + STREAM_GETL(s, zt->labels[i]); + + return 0; + +stream_failure: + return -1; +} + +int zapi_sr_policy_notify_status_decode(struct stream *s, + struct zapi_sr_policy *zp) +{ + memset(zp, 0, sizeof(*zp)); + + STREAM_GETL(s, zp->color); + STREAM_GET_IPADDR(s, &zp->endpoint); + STREAM_GET(&zp->name, s, SRTE_POLICY_NAME_MAX_LENGTH); + STREAM_GETL(s, zp->status); + + return 0; + +stream_failure: + return -1; +} + int zebra_send_mpls_labels(struct zclient *zclient, int cmd, struct zapi_labels *zl) { @@ -2860,7 +2967,7 @@ int zapi_labels_encode(struct stream *s, int cmd, struct zapi_labels *zl) for (int i = 0; i < zl->nexthop_num; i++) { znh = &zl->nexthops[i]; - if (zapi_nexthop_encode(s, znh, 0) < 0) + if (zapi_nexthop_encode(s, znh, 0, 0) < 0) return -1; } @@ -2879,7 +2986,7 @@ int zapi_labels_encode(struct stream *s, int cmd, struct zapi_labels *zl) for (int i = 0; i < zl->backup_nexthop_num; i++) { znh = &zl->backup_nexthops[i]; - if (zapi_nexthop_encode(s, znh, 0) < 0) + if (zapi_nexthop_encode(s, znh, 0, 0) < 0) return -1; } @@ -2955,7 +3062,7 @@ int zapi_labels_decode(struct stream *s, struct zapi_labels *zl) for (int i = 0; i < zl->nexthop_num; i++) { znh = &zl->nexthops[i]; - if (zapi_nexthop_decode(s, znh, 0) < 0) + if (zapi_nexthop_decode(s, znh, 0, 0) < 0) return -1; } @@ -2976,7 +3083,7 @@ int zapi_labels_decode(struct stream *s, struct zapi_labels *zl) for (int i = 0; i < zl->backup_nexthop_num; i++) { znh = &zl->backup_nexthops[i]; - if (zapi_nexthop_decode(s, znh, 0) < 0) + if (zapi_nexthop_decode(s, znh, 0, 0) < 0) return -1; } } @@ -3643,6 +3750,10 @@ static int zclient_read(struct thread *thread) (*zclient->opaque_unregister_handler)(command, zclient, length, vrf_id); break; + case ZEBRA_SR_POLICY_NOTIFY_STATUS: + if (zclient->sr_policy_notify_status) + (*zclient->sr_policy_notify_status)(command, zclient, + length, vrf_id); default: break; } diff --git a/lib/zclient.h b/lib/zclient.h index da06239d01..bcd8954dde 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -37,6 +37,7 @@ #include "pw.h" #include "mlag.h" +#include "srte.h" #ifdef __cplusplus extern "C" { @@ -89,6 +90,8 @@ enum zserv_client_capabilities { /* Macro to check if there GR enabled. */ #define ZEBRA_CLIENT_GR_ENABLED(X) (X == ZEBRA_CLIENT_GR_CAPABILITIES) +#define ZEBRA_SR_POLICY_NAME_MAX_LENGTH 100 + extern struct sockaddr_storage zclient_addr; extern socklen_t zclient_addr_len; @@ -143,6 +146,9 @@ typedef enum { ZEBRA_MPLS_LABELS_ADD, ZEBRA_MPLS_LABELS_DELETE, ZEBRA_MPLS_LABELS_REPLACE, + ZEBRA_SR_POLICY_SET, + ZEBRA_SR_POLICY_DELETE, + ZEBRA_SR_POLICY_NOTIFY_STATUS, ZEBRA_IPMR_ROUTE_STATS, ZEBRA_LABEL_MANAGER_CONNECT, ZEBRA_LABEL_MANAGER_CONNECT_ASYNC, @@ -351,6 +357,7 @@ struct zclient { int (*opaque_msg_handler)(ZAPI_CALLBACK_ARGS); int (*opaque_register_handler)(ZAPI_CALLBACK_ARGS); int (*opaque_unregister_handler)(ZAPI_CALLBACK_ARGS); + int (*sr_policy_notify_status)(ZAPI_CALLBACK_ARGS); }; /* Zebra API message flag. */ @@ -368,7 +375,8 @@ struct zclient { * the table being used is not in the VRF. You must pass the * default vrf, else this will be ignored. */ -#define ZAPI_MESSAGE_TABLEID 0x80 +#define ZAPI_MESSAGE_TABLEID 0x0080 +#define ZAPI_MESSAGE_SRTE 0x0100 #define ZSERV_VERSION 6 /* Zserv protocol message header */ @@ -403,6 +411,9 @@ struct zapi_nexthop { /* Backup nexthops, for IP-FRR, TI-LFA, etc */ uint8_t backup_num; uint8_t backup_idx[NEXTHOP_MAX_BACKUPS]; + + /* SR-TE color. */ + uint32_t srte_color; }; /* @@ -465,7 +476,7 @@ struct zapi_route { #define ZEBRA_FLAG_RR_USE_DISTANCE 0x40 /* The older XXX_MESSAGE flags live here */ - uint8_t message; + uint32_t message; /* * This is an enum but we are going to treat it as a uint8_t @@ -494,6 +505,9 @@ struct zapi_route { vrf_id_t vrf_id; uint32_t tableid; + + /* SR-TE color (used for nexthop updates only). */ + uint32_t srte_color; }; struct zapi_labels { @@ -516,6 +530,21 @@ struct zapi_labels { struct zapi_nexthop backup_nexthops[MULTIPATH_NUM]; }; +struct zapi_srte_tunnel { + enum lsp_types_t type; + mpls_label_t local_label; + uint8_t label_num; + mpls_label_t labels[MPLS_MAX_LABELS]; +}; + +struct zapi_sr_policy { + uint32_t color; + struct ipaddr endpoint; + char name[SRTE_POLICY_NAME_MAX_LENGTH]; + struct zapi_srte_tunnel segment_list; + int status; +}; + struct zapi_pw { char ifname[IF_NAMESIZE]; ifindex_t ifindex; @@ -775,6 +804,14 @@ 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_sr_policy(struct zclient *zclient, int cmd, + struct zapi_sr_policy *zp); +extern int zapi_sr_policy_encode(struct stream *s, int cmd, + struct zapi_sr_policy *zp); +extern int zapi_sr_policy_decode(struct stream *s, struct zapi_sr_policy *zp); +extern int zapi_sr_policy_notify_status_decode(struct stream *s, + struct zapi_sr_policy *zp); + 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, @@ -791,7 +828,7 @@ extern int zclient_send_rnh(struct zclient *zclient, int command, const struct prefix *p, bool exact_match, vrf_id_t vrf_id); int zapi_nexthop_encode(struct stream *s, const struct zapi_nexthop *api_nh, - uint32_t api_flags); + uint32_t api_flags, uint32_t api_message); extern int zapi_route_encode(uint8_t, struct stream *, struct zapi_route *); extern int zapi_route_decode(struct stream *, struct zapi_route *); bool zapi_route_notify_decode(struct stream *s, struct prefix *p, |
