diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/distribute.c | 155 | ||||
| -rw-r--r-- | lib/distribute.h | 36 | ||||
| -rw-r--r-- | lib/mlag.c | 41 | ||||
| -rw-r--r-- | lib/mlag.h | 32 | ||||
| -rw-r--r-- | lib/northbound_cli.c | 13 | ||||
| -rw-r--r-- | lib/northbound_cli.h | 2 | ||||
| -rw-r--r-- | lib/subdir.am | 2 | ||||
| -rw-r--r-- | lib/vrf.c | 2 | ||||
| -rw-r--r-- | lib/zclient.c | 13 | ||||
| -rw-r--r-- | lib/zclient.h | 3 |
10 files changed, 217 insertions, 82 deletions
diff --git a/lib/distribute.c b/lib/distribute.c index 9697916332..3a6b775bc8 100644 --- a/lib/distribute.c +++ b/lib/distribute.c @@ -27,16 +27,12 @@ #include "distribute.h" #include "memory.h" +DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE_CTX, "Distribute ctx") DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE, "Distribute list") DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE_IFNAME, "Dist-list ifname") DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE_NAME, "Dist-list name") -/* Hash of distribute list. */ -struct hash *disthash; - -/* Hook functions. */ -void (*distribute_add_hook)(struct distribute *); -void (*distribute_delete_hook)(struct distribute *); +struct list *dist_ctx_list; static struct distribute *distribute_new(void) { @@ -62,7 +58,8 @@ static void distribute_free(struct distribute *dist) XFREE(MTYPE_DISTRIBUTE, dist); } -static void distribute_free_if_empty(struct distribute *dist) +static void distribute_free_if_empty(struct distribute_ctx *ctx, + struct distribute *dist) { int i; @@ -70,12 +67,13 @@ static void distribute_free_if_empty(struct distribute *dist) if (dist->list[i] != NULL || dist->prefix[i] != NULL) return; - hash_release(disthash, dist); + hash_release(ctx->disthash, dist); distribute_free(dist); } /* Lookup interface's distribute list. */ -struct distribute *distribute_lookup(const char *ifname) +struct distribute *distribute_lookup(struct distribute_ctx *ctx, + const char *ifname) { struct distribute key; struct distribute *dist; @@ -83,7 +81,7 @@ struct distribute *distribute_lookup(const char *ifname) /* temporary reference */ key.ifname = (ifname) ? XSTRDUP(MTYPE_DISTRIBUTE_IFNAME, ifname) : NULL; - dist = hash_lookup(disthash, &key); + dist = hash_lookup(ctx->disthash, &key); if (key.ifname) XFREE(MTYPE_DISTRIBUTE_IFNAME, key.ifname); @@ -91,14 +89,18 @@ struct distribute *distribute_lookup(const char *ifname) return dist; } -void distribute_list_add_hook(void (*func)(struct distribute *)) +void distribute_list_add_hook(struct distribute_ctx *ctx, + void (*func)(struct distribute_ctx *ctx, + struct distribute *)) { - distribute_add_hook = func; + ctx->distribute_add_hook = func; } -void distribute_list_delete_hook(void (*func)(struct distribute *)) +void distribute_list_delete_hook(struct distribute_ctx *ctx, + void (*func)(struct distribute_ctx *ctx, + struct distribute *)) { - distribute_delete_hook = func; + ctx->distribute_delete_hook = func; } static void *distribute_hash_alloc(struct distribute *arg) @@ -114,7 +116,8 @@ static void *distribute_hash_alloc(struct distribute *arg) } /* Make new distribute list and push into hash. */ -static struct distribute *distribute_get(const char *ifname) +static struct distribute *distribute_get(struct distribute_ctx *ctx, + const char *ifname) { struct distribute key; struct distribute *ret; @@ -122,7 +125,7 @@ static struct distribute *distribute_get(const char *ifname) /* temporary reference */ key.ifname = (ifname) ? XSTRDUP(MTYPE_DISTRIBUTE_IFNAME, ifname) : NULL; - ret = hash_get(disthash, &key, + ret = hash_get(ctx->disthash, &key, (void *(*)(void *))distribute_hash_alloc); if (key.ifname) @@ -152,29 +155,32 @@ static bool distribute_cmp(const struct distribute *dist1, } /* Set access-list name to the distribute list. */ -static void distribute_list_set(const char *ifname, enum distribute_type type, +static void distribute_list_set(struct distribute_ctx *ctx, + const char *ifname, enum distribute_type type, const char *alist_name) { struct distribute *dist; - dist = distribute_get(ifname); + dist = distribute_get(ctx, ifname); if (dist->list[type]) XFREE(MTYPE_DISTRIBUTE_NAME, dist->list[type]); dist->list[type] = XSTRDUP(MTYPE_DISTRIBUTE_NAME, alist_name); /* Apply this distribute-list to the interface. */ - (*distribute_add_hook)(dist); + (ctx->distribute_add_hook)(ctx, dist); } /* Unset distribute-list. If matched distribute-list exist then return 1. */ -static int distribute_list_unset(const char *ifname, enum distribute_type type, +static int distribute_list_unset(struct distribute_ctx *ctx, + const char *ifname, + enum distribute_type type, const char *alist_name) { struct distribute *dist; - dist = distribute_lookup(ifname); + dist = distribute_lookup(ctx, ifname); if (!dist) return 0; @@ -187,39 +193,41 @@ static int distribute_list_unset(const char *ifname, enum distribute_type type, dist->list[type] = NULL; /* Apply this distribute-list to the interface. */ - (*distribute_delete_hook)(dist); + (ctx->distribute_delete_hook)(ctx, dist); /* If all dist are NULL, then free distribute list. */ - distribute_free_if_empty(dist); + distribute_free_if_empty(ctx, dist); return 1; } /* Set access-list name to the distribute list. */ -static void distribute_list_prefix_set(const char *ifname, +static void distribute_list_prefix_set(struct distribute_ctx *ctx, + const char *ifname, enum distribute_type type, const char *plist_name) { struct distribute *dist; - dist = distribute_get(ifname); + dist = distribute_get(ctx, ifname); if (dist->prefix[type]) XFREE(MTYPE_DISTRIBUTE_NAME, dist->prefix[type]); dist->prefix[type] = XSTRDUP(MTYPE_DISTRIBUTE_NAME, plist_name); /* Apply this distribute-list to the interface. */ - (*distribute_add_hook)(dist); + (ctx->distribute_add_hook)(ctx, dist); } /* Unset distribute-list. If matched distribute-list exist then return 1. */ -static int distribute_list_prefix_unset(const char *ifname, +static int distribute_list_prefix_unset(struct distribute_ctx *ctx, + const char *ifname, enum distribute_type type, const char *plist_name) { struct distribute *dist; - dist = distribute_lookup(ifname); + dist = distribute_lookup(ctx, ifname); if (!dist) return 0; @@ -232,10 +240,10 @@ static int distribute_list_prefix_unset(const char *ifname, dist->prefix[type] = NULL; /* Apply this distribute-list to the interface. */ - (*distribute_delete_hook)(dist); + (ctx->distribute_delete_hook)(ctx, dist); /* If all dist are NULL, then free distribute list. */ - distribute_free_if_empty(dist); + distribute_free_if_empty(ctx, dist); return 1; } @@ -250,15 +258,17 @@ DEFUN (distribute_list, "Interface name\n") { int prefix = (argv[1]->type == WORD_TKN) ? 1 : 0; - /* Check of distribute list type. */ enum distribute_type type = argv[2 + prefix]->arg[0] == 'i' ? DISTRIBUTE_V4_IN : DISTRIBUTE_V4_OUT; /* Set appropriate function call */ - void (*distfn)(const char *, enum distribute_type, const char *) = + void (*distfn)(struct distribute_ctx *, const char *, + enum distribute_type, const char *) = prefix ? &distribute_list_prefix_set : &distribute_list_set; + struct distribute_ctx *ctx = + (struct distribute_ctx *)listnode_head(dist_ctx_list); /* if interface is present, get name */ const char *ifname = NULL; @@ -266,7 +276,7 @@ DEFUN (distribute_list, ifname = argv[argc - 1]->arg; /* Get interface name corresponding distribute list. */ - distfn(ifname, type, argv[1 + prefix]->arg); + distfn(ctx, ifname, type, argv[1 + prefix]->arg); return CMD_SUCCESS; } @@ -283,15 +293,16 @@ DEFUN (ipv6_distribute_list, "Interface name\n") { int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0; - /* Check of distribute list type. */ enum distribute_type type = argv[3 + prefix]->arg[0] == 'i' ? DISTRIBUTE_V6_IN : DISTRIBUTE_V6_OUT; /* Set appropriate function call */ - void (*distfn)(const char *, enum distribute_type, const char *) = + void (*distfn)(struct distribute_ctx *, const char *, + enum distribute_type, const char *) = prefix ? &distribute_list_prefix_set : &distribute_list_set; + struct distribute_ctx *ctx = listnode_head(dist_ctx_list); /* if interface is present, get name */ const char *ifname = NULL; @@ -299,7 +310,7 @@ DEFUN (ipv6_distribute_list, ifname = argv[argc - 1]->arg; /* Get interface name corresponding distribute list. */ - distfn(ifname, type, argv[2 + prefix]->arg); + distfn(ctx, ifname, type, argv[2 + prefix]->arg); return CMD_SUCCESS; } @@ -316,7 +327,6 @@ DEFUN (no_distribute_list, "Interface name\n") { int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0; - int idx_alname = 2 + prefix; int idx_disttype = idx_alname + 1; enum distribute_type type = @@ -324,16 +334,17 @@ DEFUN (no_distribute_list, DISTRIBUTE_V4_IN : DISTRIBUTE_V4_OUT; /* Set appropriate function call */ - int (*distfn)(const char *, enum distribute_type, - const char *) = + int (*distfn)(struct distribute_ctx *, const char *, + enum distribute_type, const char *) = prefix ? &distribute_list_prefix_unset : &distribute_list_unset; + struct distribute_ctx *ctx = listnode_head(dist_ctx_list); /* if interface is present, get name */ const char *ifname = NULL; if (argv[argc - 1]->type == VARIABLE_TKN) ifname = argv[argc - 1]->arg; /* Get interface name corresponding distribute list. */ - int ret = distfn(ifname, type, argv[2 + prefix]->arg); + int ret = distfn(ctx, ifname, type, argv[2 + prefix]->arg); if (!ret) { vty_out(vty, "distribute list doesn't exist\n"); @@ -355,16 +366,17 @@ DEFUN (no_ipv6_distribute_list, "Interface name\n") { int prefix = (argv[3]->type == WORD_TKN) ? 1 : 0; - int idx_alname = 3 + prefix; int idx_disttype = idx_alname + 1; enum distribute_type type = argv[idx_disttype]->arg[0] == 'i' ? DISTRIBUTE_V6_IN : DISTRIBUTE_V6_OUT; + struct distribute_ctx *ctx = listnode_head(dist_ctx_list); /* Set appropriate function call */ - int (*distfn)(const char *, enum distribute_type, const char *) = + int (*distfn)(struct distribute_ctx *, const char *, + enum distribute_type, const char *) = prefix ? &distribute_list_prefix_unset : &distribute_list_unset; /* if interface is present, get name */ @@ -373,7 +385,7 @@ DEFUN (no_ipv6_distribute_list, if (argv[argc - 1]->type == VARIABLE_TKN) ifname = argv[argc - 1]->arg; /* Get interface name corresponding distribute list. */ - int ret = distfn(ifname, type, argv[3 + prefix]->arg); + int ret = distfn(ctx, ifname, type, argv[3 + prefix]->arg); if (!ret) { vty_out(vty, "distribute list doesn't exist\n"); @@ -393,7 +405,7 @@ static int distribute_print(struct vty *vty, char *tab[], int is_prefix, return has_print; } -int config_show_distribute(struct vty *vty) +int config_show_distribute(struct vty *vty, struct distribute_ctx *dist_ctxt) { unsigned int i; int has_print = 0; @@ -401,7 +413,7 @@ int config_show_distribute(struct vty *vty) struct distribute *dist; /* Output filter configuration. */ - dist = distribute_lookup(NULL); + dist = distribute_lookup(dist_ctxt, NULL); vty_out(vty, " Outgoing update filter list for all interface is"); has_print = 0; if (dist) { @@ -419,8 +431,8 @@ int config_show_distribute(struct vty *vty) else vty_out(vty, " not set\n"); - for (i = 0; i < disthash->size; i++) - for (mp = disthash->index[i]; mp; mp = mp->next) { + for (i = 0; i < dist_ctxt->disthash->size; i++) + for (mp = dist_ctxt->disthash->index[i]; mp; mp = mp->next) { dist = mp->data; if (dist->ifname) { vty_out(vty, " %s filtered by", @@ -447,7 +459,7 @@ int config_show_distribute(struct vty *vty) /* Input filter configuration. */ - dist = distribute_lookup(NULL); + dist = distribute_lookup(dist_ctxt, NULL); vty_out(vty, " Incoming update filter list for all interface is"); has_print = 0; if (dist) { @@ -465,8 +477,8 @@ int config_show_distribute(struct vty *vty) else vty_out(vty, " not set\n"); - for (i = 0; i < disthash->size; i++) - for (mp = disthash->index[i]; mp; mp = mp->next) { + for (i = 0; i < dist_ctxt->disthash->size; i++) + for (mp = dist_ctxt->disthash->index[i]; mp; mp = mp->next) { dist = mp->data; if (dist->ifname) { vty_out(vty, " %s filtered by", @@ -494,7 +506,8 @@ int config_show_distribute(struct vty *vty) } /* Configuration write function. */ -int config_write_distribute(struct vty *vty) +int config_write_distribute(struct vty *vty, + struct distribute_ctx *dist_ctxt) { unsigned int i; int j; @@ -502,8 +515,8 @@ int config_write_distribute(struct vty *vty) struct hash_backet *mp; int write = 0; - for (i = 0; i < disthash->size; i++) - for (mp = disthash->index[i]; mp; mp = mp->next) { + for (i = 0; i < dist_ctxt->disthash->size; i++) + for (mp = dist_ctxt->disthash->index[i]; mp; mp = mp->next) { struct distribute *dist; dist = mp->data; @@ -543,19 +556,38 @@ int config_write_distribute(struct vty *vty) return write; } -/* Clear all distribute list. */ -void distribute_list_reset() +void distribute_list_delete(struct distribute_ctx **ctx) { - hash_clean(disthash, (void (*)(void *))distribute_free); + if ((*ctx)->disthash) { + hash_clean((*ctx)->disthash, (void (*)(void *))distribute_free); + } + if (!dist_ctx_list) + dist_ctx_list = list_new(); + listnode_delete(dist_ctx_list, *ctx); + if (list_isempty(dist_ctx_list)) + list_delete(&dist_ctx_list); + XFREE(MTYPE_DISTRIBUTE_CTX, (*ctx)); } -/* Initialize distribute list related hash. */ -void distribute_list_init(int node) +/* Initialize distribute list container */ +struct distribute_ctx *distribute_list_ctx_create(struct vrf *vrf) { - disthash = hash_create( + struct distribute_ctx *ctx; + + ctx = XCALLOC(MTYPE_DISTRIBUTE_CTX, sizeof(struct distribute_ctx)); + ctx->vrf = vrf; + ctx->disthash = hash_create( distribute_hash_make, (bool (*)(const void *, const void *))distribute_cmp, NULL); + if (!dist_ctx_list) + dist_ctx_list = list_new(); + listnode_add(dist_ctx_list, ctx); + return ctx; +} +/* Initialize distribute list vty commands */ +void distribute_list_init(int node) +{ /* vtysh command-extraction doesn't grok install_element(node, ) */ if (node == RIP_NODE) { install_element(RIP_NODE, &distribute_list_cmd); @@ -563,10 +595,7 @@ void distribute_list_init(int node) } else if (node == RIPNG_NODE) { install_element(RIPNG_NODE, &distribute_list_cmd); install_element(RIPNG_NODE, &no_distribute_list_cmd); - } - - /* install v6 */ - if (node == RIPNG_NODE) { + /* install v6 */ install_element(RIPNG_NODE, &ipv6_distribute_list_cmd); install_element(RIPNG_NODE, &no_ipv6_distribute_list_cmd); } diff --git a/lib/distribute.h b/lib/distribute.h index 35c5e0d6b6..44c699b38a 100644 --- a/lib/distribute.h +++ b/lib/distribute.h @@ -45,14 +45,36 @@ struct distribute { char *prefix[DISTRIBUTE_MAX]; }; +struct distribute_ctx { + /* Hash of distribute list. */ + struct hash *disthash; + + /* Hook functions. */ + void (*distribute_add_hook)(struct distribute_ctx *ctx, + struct distribute *dist); + void (*distribute_delete_hook)(struct distribute_ctx *ctx, + struct distribute *dist); + + /* vrf information */ + struct vrf *vrf; +}; + /* Prototypes for distribute-list. */ -extern void distribute_list_init(int); -extern void distribute_list_reset(void); -extern void distribute_list_add_hook(void (*)(struct distribute *)); -extern void distribute_list_delete_hook(void (*)(struct distribute *)); -extern struct distribute *distribute_lookup(const char *); -extern int config_write_distribute(struct vty *); -extern int config_show_distribute(struct vty *); +extern void distribute_list_init(int node); +extern struct distribute_ctx *distribute_list_ctx_create(struct vrf *vrf); +extern void distribute_list_delete(struct distribute_ctx **ctx); +extern void distribute_list_add_hook(struct distribute_ctx *ctx, + void (*)(struct distribute_ctx *ctx, + struct distribute *)); +extern void distribute_list_delete_hook(struct distribute_ctx *ctx, + void (*)(struct distribute_ctx *ctx, + struct distribute *)); +extern struct distribute *distribute_lookup(struct distribute_ctx *ctx, + const char *ifname); +extern int config_write_distribute(struct vty *vty, + struct distribute_ctx *ctx); +extern int config_show_distribute(struct vty *vty, + struct distribute_ctx *ctx); extern enum filter_type distribute_apply_in(struct interface *, struct prefix *); diff --git a/lib/mlag.c b/lib/mlag.c new file mode 100644 index 0000000000..acdc662924 --- /dev/null +++ b/lib/mlag.c @@ -0,0 +1,41 @@ +/* mlag generic code. + * Copyright (C) 2018 Cumulus Networks, Inc. + * Donald Sharp + * + * This file is part of FRR. + * + * FRR 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. + * + * FRR 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 FRR; see the file COPYING. If not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ +#include <zebra.h> + +#include <mlag.h> + +char *mlag_role2str(enum mlag_role role, char *buf, size_t size) +{ + switch (role) { + case MLAG_ROLE_NONE: + snprintf(buf, size, "NONE"); + break; + case MLAG_ROLE_PRIMARY: + snprintf(buf, size, "PRIMARY"); + break; + case MLAG_ROLE_SECONDARY: + snprintf(buf, size, "SECONDARY"); + break; + } + + return buf; +} diff --git a/lib/mlag.h b/lib/mlag.h new file mode 100644 index 0000000000..73725ca3fd --- /dev/null +++ b/lib/mlag.h @@ -0,0 +1,32 @@ +/* mlag header. + * Copyright (C) 2018 Cumulus Networks, Inc. + * Donald Sharp + * + * This file is part of FRR. + * + * FRR 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. + * + * FRR 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 FRR; see the file COPYING. If not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ +#ifndef __MLAG_H__ +#define __MLAG_H__ + +enum mlag_role { + MLAG_ROLE_NONE, + MLAG_ROLE_PRIMARY, + MLAG_ROLE_SECONDARY +}; + +extern char *mlag_role2str(enum mlag_role role, char *buf, size_t size); +#endif diff --git a/lib/northbound_cli.c b/lib/northbound_cli.c index acde0ead02..2b024ace93 100644 --- a/lib/northbound_cli.c +++ b/lib/northbound_cli.c @@ -79,8 +79,7 @@ void nb_cli_enqueue_change(struct vty *vty, const char *xpath, int nb_cli_apply_changes(struct vty *vty, const char *xpath_base_fmt, ...) { struct nb_config *candidate_transitory; - char xpath_base[XPATH_MAXLEN]; - va_list ap; + char xpath_base[XPATH_MAXLEN] = {}; bool error = false; int ret; @@ -94,9 +93,13 @@ int nb_cli_apply_changes(struct vty *vty, const char *xpath_base_fmt, ...) candidate_transitory = nb_config_dup(vty->candidate_config); /* Parse the base XPath format string. */ - va_start(ap, xpath_base_fmt); - vsnprintf(xpath_base, sizeof(xpath_base), xpath_base_fmt, ap); - va_end(ap); + if (xpath_base_fmt) { + va_list ap; + + va_start(ap, xpath_base_fmt); + vsnprintf(xpath_base, sizeof(xpath_base), xpath_base_fmt, ap); + va_end(ap); + } /* Edit candidate configuration. */ for (size_t i = 0; i < vty->num_cfg_changes; i++) { diff --git a/lib/northbound_cli.h b/lib/northbound_cli.h index 362a4bc325..884f250941 100644 --- a/lib/northbound_cli.h +++ b/lib/northbound_cli.h @@ -60,7 +60,7 @@ extern void nb_cli_enqueue_change(struct vty *vty, const char *xpath, * * xpath_base_fmt * Prepend the given XPath (absolute or relative) to all enqueued - * configuration changes. + * configuration changes. This is an optional parameter. * * Returns: * CMD_SUCCESS on success, CMD_WARNING_CONFIG_FAILED otherwise. diff --git a/lib/subdir.am b/lib/subdir.am index 43b39100cb..ccbe13bca6 100644 --- a/lib/subdir.am +++ b/lib/subdir.am @@ -44,6 +44,7 @@ lib_libfrr_la_SOURCES = \ lib/md5.c \ lib/memory.c \ lib/memory_vty.c \ + lib/mlag.c \ lib/module.c \ lib/mpls.c \ lib/network.c \ @@ -134,6 +135,7 @@ pkginclude_HEADERS += \ lib/bitfield.h \ lib/buffer.h \ lib/checksum.h \ + lib/mlag.h \ lib/command.h \ lib/command_graph.h \ lib/command_match.h \ @@ -330,6 +330,8 @@ vrf_id_t vrf_name_to_id(const char *name) vrf_id_t vrf_id = VRF_DEFAULT; // Pending: need a way to return invalid // id/ routine not used. + if (!name) + return vrf_id; vrf = vrf_lookup_by_name(name); if (vrf) vrf_id = vrf->vrf_id; diff --git a/lib/zclient.c b/lib/zclient.c index beb3ca4f34..1c40750db0 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -1770,19 +1770,19 @@ struct interface *zebra_interface_vrf_update_read(struct stream *s, vrf_id_t vrf_id, vrf_id_t *new_vrf_id) { - unsigned int ifindex; + char ifname[INTERFACE_NAMSIZ]; struct interface *ifp; vrf_id_t new_id; - /* Get interface index. */ - ifindex = stream_getl(s); + /* Read interface name. */ + stream_get(ifname, s, INTERFACE_NAMSIZ); /* Lookup interface. */ - ifp = if_lookup_by_index(ifindex, vrf_id); + ifp = if_lookup_by_name(ifname, vrf_id); if (ifp == NULL) { flog_err(EC_LIB_ZAPI_ENCODE, - "INTERFACE_VRF_UPDATE: Cannot find IF %u in VRF %d", - ifindex, vrf_id); + "INTERFACE_VRF_UPDATE: Cannot find IF %s in VRF %d", + ifname, vrf_id); return NULL; } @@ -2355,6 +2355,7 @@ static void zclient_capability_decode(int command, struct zclient *zclient, STREAM_GETC(s, mpls_enabled); cap.mpls_enabled = !!mpls_enabled; STREAM_GETL(s, cap.ecmp); + STREAM_GETC(s, cap.role); if (zclient->zebra_capabilities) (*zclient->zebra_capabilities)(&cap); diff --git a/lib/zclient.h b/lib/zclient.h index 8fe711f310..831cccfb7e 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -36,6 +36,8 @@ /* For union pw_protocol_fields */ #include "pw.h" +#include "mlag.h" + /* For input/output buffer to zebra. */ #define ZEBRA_MAX_PACKET_SIZ 16384 @@ -171,6 +173,7 @@ struct redist_proto { struct zclient_capabilities { uint32_t ecmp; bool mpls_enabled; + enum mlag_role role; }; /* Structure for the zebra client. */ |
