mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-27 20:33:20 +00:00
Merge pull request #5892 from qlyoung/fix-zclient-many
assorted lib / zclient fixes
This commit is contained in:
commit
1b0f1cb4d7
30
lib/if.c
30
lib/if.c
@ -582,23 +582,39 @@ struct interface *if_get_by_ifindex(ifindex_t ifindex, vrf_id_t vrf_id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void if_set_index(struct interface *ifp, ifindex_t ifindex)
|
||||
int if_set_index(struct interface *ifp, ifindex_t ifindex)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
|
||||
if (ifp->ifindex == ifindex)
|
||||
return 0;
|
||||
|
||||
vrf = vrf_get(ifp->vrf_id, NULL);
|
||||
assert(vrf);
|
||||
|
||||
if (ifp->ifindex == ifindex)
|
||||
return;
|
||||
/*
|
||||
* If there is already an interface with this ifindex, we will collide
|
||||
* on insertion, so don't even try.
|
||||
*/
|
||||
if (if_lookup_by_ifindex(ifindex, ifp->vrf_id))
|
||||
return -1;
|
||||
|
||||
if (ifp->ifindex != IFINDEX_INTERNAL)
|
||||
IFINDEX_RB_REMOVE(vrf, ifp);
|
||||
|
||||
ifp->ifindex = ifindex;
|
||||
|
||||
if (ifp->ifindex != IFINDEX_INTERNAL)
|
||||
IFINDEX_RB_INSERT(vrf, ifp)
|
||||
if (ifp->ifindex != IFINDEX_INTERNAL) {
|
||||
/*
|
||||
* This should never happen, since we checked if there was
|
||||
* already an interface with the desired ifindex at the top of
|
||||
* the function. Nevertheless.
|
||||
*/
|
||||
if (IFINDEX_RB_INSERT(vrf, ifp))
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void if_set_name(struct interface *ifp, const char *name)
|
||||
@ -1249,8 +1265,6 @@ struct if_link_params *if_link_params_get(struct interface *ifp)
|
||||
|
||||
struct if_link_params *iflp =
|
||||
XCALLOC(MTYPE_IF_LINK_PARAMS, sizeof(struct if_link_params));
|
||||
if (iflp == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Set TE metric equal to standard metric */
|
||||
iflp->te_metric = ifp->metric;
|
||||
@ -1278,8 +1292,6 @@ struct if_link_params *if_link_params_get(struct interface *ifp)
|
||||
|
||||
void if_link_params_free(struct interface *ifp)
|
||||
{
|
||||
if (ifp->link_params == NULL)
|
||||
return;
|
||||
XFREE(MTYPE_IF_LINK_PARAMS, ifp->link_params);
|
||||
}
|
||||
|
||||
|
75
lib/if.h
75
lib/if.h
@ -308,33 +308,58 @@ RB_HEAD(if_index_head, interface);
|
||||
RB_PROTOTYPE(if_index_head, interface, index_entry, if_cmp_index_func)
|
||||
DECLARE_QOBJ_TYPE(interface)
|
||||
|
||||
#define IFNAME_RB_INSERT(vrf, ifp) \
|
||||
if (RB_INSERT(if_name_head, &vrf->ifaces_by_name, (ifp))) \
|
||||
flog_err(EC_LIB_INTERFACE, \
|
||||
"%s(%s): corruption detected -- interface with this " \
|
||||
"name exists already in VRF %u!", \
|
||||
__func__, (ifp)->name, (ifp)->vrf_id);
|
||||
#define IFNAME_RB_INSERT(vrf, ifp) \
|
||||
({ \
|
||||
struct interface *_iz = \
|
||||
RB_INSERT(if_name_head, &vrf->ifaces_by_name, (ifp)); \
|
||||
if (_iz) \
|
||||
flog_err( \
|
||||
EC_LIB_INTERFACE, \
|
||||
"%s(%s): corruption detected -- interface with this " \
|
||||
"name exists already in VRF %u!", \
|
||||
__func__, (ifp)->name, (ifp)->vrf_id); \
|
||||
_iz; \
|
||||
})
|
||||
|
||||
#define IFNAME_RB_REMOVE(vrf, ifp) \
|
||||
if (RB_REMOVE(if_name_head, &vrf->ifaces_by_name, (ifp)) == NULL) \
|
||||
flog_err(EC_LIB_INTERFACE, \
|
||||
"%s(%s): corruption detected -- interface with this " \
|
||||
"name doesn't exist in VRF %u!", \
|
||||
__func__, (ifp)->name, (ifp)->vrf_id);
|
||||
#define IFNAME_RB_REMOVE(vrf, ifp) \
|
||||
({ \
|
||||
struct interface *_iz = \
|
||||
RB_REMOVE(if_name_head, &vrf->ifaces_by_name, (ifp)); \
|
||||
if (_iz == NULL) \
|
||||
flog_err( \
|
||||
EC_LIB_INTERFACE, \
|
||||
"%s(%s): corruption detected -- interface with this " \
|
||||
"name doesn't exist in VRF %u!", \
|
||||
__func__, (ifp)->name, (ifp)->vrf_id); \
|
||||
_iz; \
|
||||
})
|
||||
|
||||
#define IFINDEX_RB_INSERT(vrf, ifp) \
|
||||
if (RB_INSERT(if_index_head, &vrf->ifaces_by_index, (ifp))) \
|
||||
flog_err(EC_LIB_INTERFACE, \
|
||||
"%s(%u): corruption detected -- interface with this " \
|
||||
"ifindex exists already in VRF %u!", \
|
||||
__func__, (ifp)->ifindex, (ifp)->vrf_id);
|
||||
|
||||
#define IFINDEX_RB_REMOVE(vrf, ifp) \
|
||||
if (RB_REMOVE(if_index_head, &vrf->ifaces_by_index, (ifp)) == NULL) \
|
||||
flog_err(EC_LIB_INTERFACE, \
|
||||
"%s(%u): corruption detected -- interface with this " \
|
||||
"ifindex doesn't exist in VRF %u!", \
|
||||
__func__, (ifp)->ifindex, (ifp)->vrf_id);
|
||||
#define IFINDEX_RB_INSERT(vrf, ifp) \
|
||||
({ \
|
||||
struct interface *_iz = RB_INSERT( \
|
||||
if_index_head, &vrf->ifaces_by_index, (ifp)); \
|
||||
if (_iz) \
|
||||
flog_err( \
|
||||
EC_LIB_INTERFACE, \
|
||||
"%s(%u): corruption detected -- interface with this " \
|
||||
"ifindex exists already in VRF %u!", \
|
||||
__func__, (ifp)->ifindex, (ifp)->vrf_id); \
|
||||
_iz; \
|
||||
})
|
||||
|
||||
#define IFINDEX_RB_REMOVE(vrf, ifp) \
|
||||
({ \
|
||||
struct interface *_iz = RB_REMOVE( \
|
||||
if_index_head, &vrf->ifaces_by_index, (ifp)); \
|
||||
if (_iz == NULL) \
|
||||
flog_err( \
|
||||
EC_LIB_INTERFACE, \
|
||||
"%s(%u): corruption detected -- interface with this " \
|
||||
"ifindex doesn't exist in VRF %u!", \
|
||||
__func__, (ifp)->ifindex, (ifp)->vrf_id); \
|
||||
_iz; \
|
||||
})
|
||||
|
||||
#define FOR_ALL_INTERFACES(vrf, ifp) \
|
||||
if (vrf) \
|
||||
@ -502,7 +527,7 @@ extern struct interface *if_get_by_name(const char *ifname, vrf_id_t vrf_id);
|
||||
extern struct interface *if_get_by_ifindex(ifindex_t ifindex, vrf_id_t vrf_id);
|
||||
|
||||
/* Sets the index and adds to index list */
|
||||
extern void if_set_index(struct interface *ifp, ifindex_t ifindex);
|
||||
extern int if_set_index(struct interface *ifp, ifindex_t ifindex);
|
||||
/* Sets the name and adds to name list */
|
||||
extern void if_set_name(struct interface *ifp, const char *name);
|
||||
|
||||
|
21
lib/stream.c
21
lib/stream.c
@ -543,6 +543,27 @@ uint64_t stream_getq(struct stream *s)
|
||||
return q;
|
||||
}
|
||||
|
||||
bool stream_getq2(struct stream *s, uint64_t *q)
|
||||
{
|
||||
STREAM_VERIFY_SANE(s);
|
||||
|
||||
if (STREAM_READABLE(s) < sizeof(uint64_t)) {
|
||||
STREAM_BOUND_WARN2(s, "get uint64");
|
||||
return false;
|
||||
}
|
||||
|
||||
*q = ((uint64_t)s->data[s->getp++]) << 56;
|
||||
*q |= ((uint64_t)s->data[s->getp++]) << 48;
|
||||
*q |= ((uint64_t)s->data[s->getp++]) << 40;
|
||||
*q |= ((uint64_t)s->data[s->getp++]) << 32;
|
||||
*q |= ((uint64_t)s->data[s->getp++]) << 24;
|
||||
*q |= ((uint64_t)s->data[s->getp++]) << 16;
|
||||
*q |= ((uint64_t)s->data[s->getp++]) << 8;
|
||||
*q |= ((uint64_t)s->data[s->getp++]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Get next long word from the stream. */
|
||||
uint32_t stream_get_ipv4(struct stream *s)
|
||||
{
|
||||
|
20
lib/stream.h
20
lib/stream.h
@ -215,6 +215,7 @@ extern bool stream_getl2(struct stream *s, uint32_t *l);
|
||||
extern uint32_t stream_getl_from(struct stream *, size_t);
|
||||
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 *);
|
||||
|
||||
/* IEEE-754 floats */
|
||||
@ -402,6 +403,25 @@ static inline const uint8_t *ptr_get_be32(const uint8_t *ptr, uint32_t *out)
|
||||
(P) = _pval; \
|
||||
} while (0)
|
||||
|
||||
#define STREAM_GETF(S, P) \
|
||||
do { \
|
||||
union { \
|
||||
float r; \
|
||||
uint32_t d; \
|
||||
} _pval; \
|
||||
if (stream_getl2((S), &_pval.d)) \
|
||||
goto stream_failure; \
|
||||
(P) = _pval.r; \
|
||||
} while (0)
|
||||
|
||||
#define STREAM_GETQ(S, P) \
|
||||
do { \
|
||||
uint64_t _pval; \
|
||||
if (!stream_getq2((S), &_pval)) \
|
||||
goto stream_failure; \
|
||||
(P) = _pval; \
|
||||
} while (0)
|
||||
|
||||
#define STREAM_GET(P, STR, SIZE) \
|
||||
do { \
|
||||
if (!stream_get2((P), (STR), (SIZE))) \
|
||||
|
16
lib/vrf.c
16
lib/vrf.c
@ -593,10 +593,22 @@ int vrf_get_backend(void)
|
||||
return vrf_backend;
|
||||
}
|
||||
|
||||
void vrf_configure_backend(int vrf_backend_netns)
|
||||
int vrf_configure_backend(enum vrf_backend_type backend)
|
||||
{
|
||||
vrf_backend = vrf_backend_netns;
|
||||
/* Work around issue in old gcc */
|
||||
switch (backend) {
|
||||
case VRF_BACKEND_UNKNOWN:
|
||||
case VRF_BACKEND_NETNS:
|
||||
case VRF_BACKEND_VRF_LITE:
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
vrf_backend = backend;
|
||||
vrf_backend_configured = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vrf_handler_create(struct vty *vty, const char *vrfname,
|
||||
|
15
lib/vrf.h
15
lib/vrf.h
@ -101,9 +101,12 @@ RB_PROTOTYPE(vrf_name_head, vrf, name_entry, vrf_name_compare)
|
||||
DECLARE_QOBJ_TYPE(vrf)
|
||||
|
||||
/* Allow VRF with netns as backend */
|
||||
#define VRF_BACKEND_VRF_LITE 0
|
||||
#define VRF_BACKEND_NETNS 1
|
||||
#define VRF_BACKEND_UNKNOWN 2
|
||||
enum vrf_backend_type {
|
||||
VRF_BACKEND_VRF_LITE,
|
||||
VRF_BACKEND_NETNS,
|
||||
VRF_BACKEND_UNKNOWN,
|
||||
VRF_BACKEND_MAX,
|
||||
};
|
||||
|
||||
extern struct vrf_id_head vrfs_by_id;
|
||||
extern struct vrf_name_head vrfs_by_name;
|
||||
@ -292,10 +295,10 @@ extern void vrf_install_commands(void);
|
||||
* VRF utilities
|
||||
*/
|
||||
|
||||
/* API for configuring VRF backend
|
||||
* should be called from zebra only
|
||||
/*
|
||||
* API for configuring VRF backend
|
||||
*/
|
||||
extern void vrf_configure_backend(int vrf_backend_netns);
|
||||
extern int vrf_configure_backend(enum vrf_backend_type backend);
|
||||
extern int vrf_get_backend(void);
|
||||
extern int vrf_is_backend_netns(void);
|
||||
|
||||
|
230
lib/zclient.c
230
lib/zclient.c
@ -1635,33 +1635,34 @@ int zebra_redistribute_default_send(int command, struct zclient *zclient,
|
||||
}
|
||||
|
||||
/* Get prefix in ZServ format; family should be filled in on prefix */
|
||||
static void zclient_stream_get_prefix(struct stream *s, struct prefix *p)
|
||||
static int zclient_stream_get_prefix(struct stream *s, struct prefix *p)
|
||||
{
|
||||
size_t plen = prefix_blen(p);
|
||||
uint8_t c;
|
||||
p->prefixlen = 0;
|
||||
|
||||
if (plen == 0)
|
||||
return;
|
||||
return -1;
|
||||
|
||||
stream_get(&p->u.prefix, s, plen);
|
||||
STREAM_GET(&p->u.prefix, s, plen);
|
||||
STREAM_GETC(s, c);
|
||||
p->prefixlen = MIN(plen * 8, c);
|
||||
|
||||
return 0;
|
||||
stream_failure:
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Router-id update from zebra daemon. */
|
||||
void zebra_router_id_update_read(struct stream *s, struct prefix *rid)
|
||||
int zebra_router_id_update_read(struct stream *s, struct prefix *rid)
|
||||
{
|
||||
/* Fetch interface address. */
|
||||
STREAM_GETC(s, rid->family);
|
||||
|
||||
zclient_stream_get_prefix(s, rid);
|
||||
return zclient_stream_get_prefix(s, rid);
|
||||
|
||||
stream_failure:
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Interface addition from zebra daemon. */
|
||||
@ -1710,24 +1711,36 @@ stream_failure:
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
static void zclient_vrf_add(struct zclient *zclient, vrf_id_t vrf_id)
|
||||
static int zclient_vrf_add(struct zclient *zclient, vrf_id_t vrf_id)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
char vrfname_tmp[VRF_NAMSIZ];
|
||||
char vrfname_tmp[VRF_NAMSIZ + 1] = {};
|
||||
struct vrf_data data;
|
||||
|
||||
stream_get(&data, zclient->ibuf, sizeof(struct vrf_data));
|
||||
STREAM_GET(&data, zclient->ibuf, sizeof(struct vrf_data));
|
||||
/* Read interface name. */
|
||||
stream_get(vrfname_tmp, zclient->ibuf, VRF_NAMSIZ);
|
||||
STREAM_GET(vrfname_tmp, zclient->ibuf, VRF_NAMSIZ);
|
||||
|
||||
/* Lookup/create vrf by vrf_id. */
|
||||
if (strlen(vrfname_tmp) == 0)
|
||||
goto stream_failure;
|
||||
|
||||
/* Lookup/create vrf by name, then vrf_id. */
|
||||
vrf = vrf_get(vrf_id, vrfname_tmp);
|
||||
|
||||
/* If there's already a VRF with this name, don't create vrf */
|
||||
if (!vrf)
|
||||
return 0;
|
||||
|
||||
vrf->data.l.table_id = data.l.table_id;
|
||||
memcpy(vrf->data.l.netns_name, data.l.netns_name, NS_NAMSIZ);
|
||||
/* overwrite default vrf */
|
||||
if (vrf_id == VRF_DEFAULT)
|
||||
vrf_set_default_name(vrfname_tmp, false);
|
||||
vrf_enable(vrf);
|
||||
|
||||
return 0;
|
||||
stream_failure:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void zclient_vrf_delete(struct zclient *zclient, vrf_id_t vrf_id)
|
||||
@ -1748,21 +1761,32 @@ static void zclient_vrf_delete(struct zclient *zclient, vrf_id_t vrf_id)
|
||||
vrf_delete(vrf);
|
||||
}
|
||||
|
||||
static void zclient_interface_add(struct zclient *zclient, vrf_id_t vrf_id)
|
||||
static int zclient_interface_add(struct zclient *zclient, vrf_id_t vrf_id)
|
||||
{
|
||||
struct interface *ifp;
|
||||
char ifname_tmp[INTERFACE_NAMSIZ];
|
||||
char ifname_tmp[INTERFACE_NAMSIZ + 1] = {};
|
||||
struct stream *s = zclient->ibuf;
|
||||
|
||||
/* Read interface name. */
|
||||
stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
|
||||
STREAM_GET(ifname_tmp, s, INTERFACE_NAMSIZ);
|
||||
|
||||
/* Lookup/create interface by name. */
|
||||
if (!vrf_get(vrf_id, NULL)) {
|
||||
zlog_debug(
|
||||
"Rx'd interface add from Zebra, but VRF %u does not exist",
|
||||
vrf_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ifp = if_get_by_name(ifname_tmp, vrf_id);
|
||||
|
||||
zebra_interface_if_set_value(s, ifp);
|
||||
|
||||
if_new_via_zapi(ifp);
|
||||
|
||||
return 0;
|
||||
stream_failure:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1774,10 +1798,10 @@ static void zclient_interface_add(struct zclient *zclient, vrf_id_t vrf_id)
|
||||
struct interface *zebra_interface_state_read(struct stream *s, vrf_id_t vrf_id)
|
||||
{
|
||||
struct interface *ifp;
|
||||
char ifname_tmp[INTERFACE_NAMSIZ];
|
||||
char ifname_tmp[INTERFACE_NAMSIZ + 1] = {};
|
||||
|
||||
/* Read interface name. */
|
||||
stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
|
||||
STREAM_GET(ifname_tmp, s, INTERFACE_NAMSIZ);
|
||||
|
||||
/* Lookup this by interface index. */
|
||||
ifp = if_lookup_by_name(ifname_tmp, vrf_id);
|
||||
@ -1791,6 +1815,8 @@ struct interface *zebra_interface_state_read(struct stream *s, vrf_id_t vrf_id)
|
||||
zebra_interface_if_set_value(s, ifp);
|
||||
|
||||
return ifp;
|
||||
stream_failure:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void zclient_interface_delete(struct zclient *zclient, vrf_id_t vrf_id)
|
||||
@ -1844,21 +1870,23 @@ static void zclient_handle_error(ZAPI_CALLBACK_ARGS)
|
||||
(*zclient->handle_error)(error);
|
||||
}
|
||||
|
||||
static void link_params_set_value(struct stream *s, struct if_link_params *iflp)
|
||||
static int link_params_set_value(struct stream *s, struct if_link_params *iflp)
|
||||
{
|
||||
|
||||
if (iflp == NULL)
|
||||
return;
|
||||
return -1;
|
||||
|
||||
iflp->lp_status = stream_getl(s);
|
||||
iflp->te_metric = stream_getl(s);
|
||||
iflp->max_bw = stream_getf(s);
|
||||
iflp->max_rsv_bw = stream_getf(s);
|
||||
uint32_t bwclassnum = stream_getl(s);
|
||||
uint32_t bwclassnum;
|
||||
|
||||
STREAM_GETL(s, iflp->lp_status);
|
||||
STREAM_GETL(s, iflp->te_metric);
|
||||
STREAM_GETF(s, iflp->max_bw);
|
||||
STREAM_GETF(s, iflp->max_rsv_bw);
|
||||
STREAM_GETL(s, bwclassnum);
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = 0; i < bwclassnum && i < MAX_CLASS_TYPE; i++)
|
||||
iflp->unrsv_bw[i] = stream_getf(s);
|
||||
STREAM_GETF(s, iflp->unrsv_bw[i]);
|
||||
if (i < bwclassnum)
|
||||
flog_err(
|
||||
EC_LIB_ZAPI_MISSMATCH,
|
||||
@ -1866,19 +1894,23 @@ static void link_params_set_value(struct stream *s, struct if_link_params *iflp)
|
||||
" - outdated library?",
|
||||
__func__, bwclassnum, MAX_CLASS_TYPE);
|
||||
}
|
||||
iflp->admin_grp = stream_getl(s);
|
||||
iflp->rmt_as = stream_getl(s);
|
||||
STREAM_GETL(s, iflp->admin_grp);
|
||||
STREAM_GETL(s, iflp->rmt_as);
|
||||
iflp->rmt_ip.s_addr = stream_get_ipv4(s);
|
||||
|
||||
iflp->av_delay = stream_getl(s);
|
||||
iflp->min_delay = stream_getl(s);
|
||||
iflp->max_delay = stream_getl(s);
|
||||
iflp->delay_var = stream_getl(s);
|
||||
STREAM_GETL(s, iflp->av_delay);
|
||||
STREAM_GETL(s, iflp->min_delay);
|
||||
STREAM_GETL(s, iflp->max_delay);
|
||||
STREAM_GETL(s, iflp->delay_var);
|
||||
|
||||
iflp->pkt_loss = stream_getf(s);
|
||||
iflp->res_bw = stream_getf(s);
|
||||
iflp->ava_bw = stream_getf(s);
|
||||
iflp->use_bw = stream_getf(s);
|
||||
STREAM_GETF(s, iflp->pkt_loss);
|
||||
STREAM_GETF(s, iflp->res_bw);
|
||||
STREAM_GETF(s, iflp->ava_bw);
|
||||
STREAM_GETF(s, iflp->use_bw);
|
||||
|
||||
return 0;
|
||||
stream_failure:
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct interface *zebra_interface_link_params_read(struct stream *s,
|
||||
@ -1887,9 +1919,7 @@ struct interface *zebra_interface_link_params_read(struct stream *s,
|
||||
struct if_link_params *iflp;
|
||||
ifindex_t ifindex;
|
||||
|
||||
assert(s);
|
||||
|
||||
ifindex = stream_getl(s);
|
||||
STREAM_GETL(s, ifindex);
|
||||
|
||||
struct interface *ifp = if_lookup_by_index(ifindex, vrf_id);
|
||||
|
||||
@ -1903,36 +1933,41 @@ struct interface *zebra_interface_link_params_read(struct stream *s,
|
||||
if ((iflp = if_link_params_get(ifp)) == NULL)
|
||||
return NULL;
|
||||
|
||||
link_params_set_value(s, iflp);
|
||||
if (link_params_set_value(s, iflp) != 0)
|
||||
goto stream_failure;
|
||||
|
||||
return ifp;
|
||||
|
||||
stream_failure:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void zebra_interface_if_set_value(struct stream *s,
|
||||
struct interface *ifp)
|
||||
{
|
||||
uint8_t link_params_status = 0;
|
||||
ifindex_t old_ifindex;
|
||||
ifindex_t old_ifindex, new_ifindex;
|
||||
|
||||
old_ifindex = ifp->ifindex;
|
||||
/* Read interface's index. */
|
||||
if_set_index(ifp, stream_getl(s));
|
||||
ifp->status = stream_getc(s);
|
||||
STREAM_GETL(s, new_ifindex);
|
||||
if_set_index(ifp, new_ifindex);
|
||||
STREAM_GETC(s, ifp->status);
|
||||
|
||||
/* Read interface's value. */
|
||||
ifp->flags = stream_getq(s);
|
||||
ifp->ptm_enable = stream_getc(s);
|
||||
ifp->ptm_status = stream_getc(s);
|
||||
ifp->metric = stream_getl(s);
|
||||
ifp->speed = stream_getl(s);
|
||||
ifp->mtu = stream_getl(s);
|
||||
ifp->mtu6 = stream_getl(s);
|
||||
ifp->bandwidth = stream_getl(s);
|
||||
ifp->link_ifindex = stream_getl(s);
|
||||
ifp->ll_type = stream_getl(s);
|
||||
ifp->hw_addr_len = stream_getl(s);
|
||||
STREAM_GETQ(s, ifp->flags);
|
||||
STREAM_GETC(s, ifp->ptm_enable);
|
||||
STREAM_GETC(s, ifp->ptm_status);
|
||||
STREAM_GETL(s, ifp->metric);
|
||||
STREAM_GETL(s, ifp->speed);
|
||||
STREAM_GETL(s, ifp->mtu);
|
||||
STREAM_GETL(s, ifp->mtu6);
|
||||
STREAM_GETL(s, ifp->bandwidth);
|
||||
STREAM_GETL(s, ifp->link_ifindex);
|
||||
STREAM_GETL(s, ifp->ll_type);
|
||||
STREAM_GETL(s, ifp->hw_addr_len);
|
||||
if (ifp->hw_addr_len)
|
||||
stream_get(ifp->hw_addr, s,
|
||||
STREAM_GET(ifp->hw_addr, s,
|
||||
MIN(ifp->hw_addr_len, INTERFACE_HWADDR_MAX));
|
||||
|
||||
/* Read Traffic Engineering status */
|
||||
@ -1944,6 +1979,11 @@ static void zebra_interface_if_set_value(struct stream *s,
|
||||
}
|
||||
|
||||
nexthop_group_interface_state_change(ifp, old_ifindex);
|
||||
|
||||
return;
|
||||
stream_failure:
|
||||
zlog_err("Could not parse interface values; aborting");
|
||||
assert(!"Failed to parse interface values");
|
||||
}
|
||||
|
||||
size_t zebra_interface_link_params_write(struct stream *s,
|
||||
@ -2042,7 +2082,7 @@ struct connected *zebra_interface_address_read(int type, struct stream *s,
|
||||
memset(&d, 0, sizeof(d));
|
||||
|
||||
/* Get interface index. */
|
||||
ifindex = stream_getl(s);
|
||||
STREAM_GETL(s, ifindex);
|
||||
|
||||
/* Lookup index. */
|
||||
ifp = if_lookup_by_index(ifindex, vrf_id);
|
||||
@ -2055,16 +2095,18 @@ struct connected *zebra_interface_address_read(int type, struct stream *s,
|
||||
}
|
||||
|
||||
/* Fetch flag. */
|
||||
ifc_flags = stream_getc(s);
|
||||
STREAM_GETC(s, ifc_flags);
|
||||
|
||||
/* Fetch interface address. */
|
||||
d.family = p.family = stream_getc(s);
|
||||
STREAM_GETC(s, d.family);
|
||||
p.family = d.family;
|
||||
plen = prefix_blen(&d);
|
||||
|
||||
zclient_stream_get_prefix(s, &p);
|
||||
if (zclient_stream_get_prefix(s, &p) != 0)
|
||||
goto stream_failure;
|
||||
|
||||
/* Fetch destination address. */
|
||||
stream_get(&d.u.prefix, s, plen);
|
||||
STREAM_GET(&d.u.prefix, s, plen);
|
||||
|
||||
/* N.B. NULL destination pointers are encoded as all zeroes */
|
||||
dp = memconstant(&d.u.prefix, 0, plen) ? NULL : &d;
|
||||
@ -2100,6 +2142,9 @@ struct connected *zebra_interface_address_read(int type, struct stream *s,
|
||||
}
|
||||
|
||||
return ifc;
|
||||
|
||||
stream_failure:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2135,7 +2180,7 @@ zebra_interface_nbr_address_read(int type, struct stream *s, vrf_id_t vrf_id)
|
||||
struct nbr_connected *ifc;
|
||||
|
||||
/* Get interface index. */
|
||||
ifindex = stream_getl(s);
|
||||
STREAM_GETL(s, ifindex);
|
||||
|
||||
/* Lookup index. */
|
||||
ifp = if_lookup_by_index(ifindex, vrf_id);
|
||||
@ -2148,9 +2193,9 @@ zebra_interface_nbr_address_read(int type, struct stream *s, vrf_id_t vrf_id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p.family = stream_getc(s);
|
||||
stream_get(&p.u.prefix, s, prefix_blen(&p));
|
||||
p.prefixlen = stream_getc(s);
|
||||
STREAM_GETC(s, p.family);
|
||||
STREAM_GET(&p.u.prefix, s, prefix_blen(&p));
|
||||
STREAM_GETC(s, p.prefixlen);
|
||||
|
||||
if (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD) {
|
||||
/* Currently only supporting P2P links, so any new RA source
|
||||
@ -2174,18 +2219,21 @@ zebra_interface_nbr_address_read(int type, struct stream *s, vrf_id_t vrf_id)
|
||||
}
|
||||
|
||||
return ifc;
|
||||
|
||||
stream_failure:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct interface *zebra_interface_vrf_update_read(struct stream *s,
|
||||
vrf_id_t vrf_id,
|
||||
vrf_id_t *new_vrf_id)
|
||||
{
|
||||
char ifname[INTERFACE_NAMSIZ];
|
||||
char ifname[INTERFACE_NAMSIZ + 1] = {};
|
||||
struct interface *ifp;
|
||||
vrf_id_t new_id;
|
||||
|
||||
/* Read interface name. */
|
||||
stream_get(ifname, s, INTERFACE_NAMSIZ);
|
||||
STREAM_GET(ifname, s, INTERFACE_NAMSIZ);
|
||||
|
||||
/* Lookup interface. */
|
||||
ifp = if_lookup_by_name(ifname, vrf_id);
|
||||
@ -2197,10 +2245,13 @@ struct interface *zebra_interface_vrf_update_read(struct stream *s,
|
||||
}
|
||||
|
||||
/* Fetch new VRF Id. */
|
||||
new_id = stream_getl(s);
|
||||
STREAM_GETL(s, new_id);
|
||||
|
||||
*new_vrf_id = new_id;
|
||||
return ifp;
|
||||
|
||||
stream_failure:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* filter unwanted messages until the expected one arrives */
|
||||
@ -2309,8 +2360,11 @@ int lm_label_manager_connect(struct zclient *zclient, int async)
|
||||
s = zclient->ibuf;
|
||||
|
||||
/* read instance and proto */
|
||||
uint8_t proto = stream_getc(s);
|
||||
uint16_t instance = stream_getw(s);
|
||||
uint8_t proto;
|
||||
uint16_t instance;
|
||||
|
||||
STREAM_GETC(s, proto);
|
||||
STREAM_GETW(s, instance);
|
||||
|
||||
/* sanity */
|
||||
if (proto != zclient->redist_default)
|
||||
@ -2325,11 +2379,14 @@ int lm_label_manager_connect(struct zclient *zclient, int async)
|
||||
instance, zclient->instance);
|
||||
|
||||
/* result code */
|
||||
result = stream_getc(s);
|
||||
STREAM_GETC(s, result);
|
||||
if (zclient_debug)
|
||||
zlog_debug("LM connect-response received, result %u", result);
|
||||
|
||||
return (int)result;
|
||||
|
||||
stream_failure:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2437,8 +2494,11 @@ int lm_get_label_chunk(struct zclient *zclient, uint8_t keep, uint32_t base,
|
||||
s = zclient->ibuf;
|
||||
|
||||
/* read proto and instance */
|
||||
uint8_t proto = stream_getc(s);
|
||||
uint16_t instance = stream_getw(s);
|
||||
uint8_t proto;
|
||||
uint8_t instance;
|
||||
|
||||
STREAM_GETC(s, proto);
|
||||
STREAM_GETW(s, instance);
|
||||
|
||||
/* sanities */
|
||||
if (proto != zclient->redist_default)
|
||||
@ -2460,10 +2520,10 @@ int lm_get_label_chunk(struct zclient *zclient, uint8_t keep, uint32_t base,
|
||||
}
|
||||
|
||||
/* keep */
|
||||
response_keep = stream_getc(s);
|
||||
STREAM_GETC(s, response_keep);
|
||||
/* start and end labels */
|
||||
*start = stream_getl(s);
|
||||
*end = stream_getl(s);
|
||||
STREAM_GETL(s, *start);
|
||||
STREAM_GETL(s, *end);
|
||||
|
||||
/* not owning this response */
|
||||
if (keep != response_keep) {
|
||||
@ -2485,6 +2545,9 @@ int lm_get_label_chunk(struct zclient *zclient, uint8_t keep, uint32_t base,
|
||||
response_keep);
|
||||
|
||||
return 0;
|
||||
|
||||
stream_failure:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2874,7 +2937,7 @@ int zebra_send_pw(struct zclient *zclient, int command, struct zapi_pw *pw)
|
||||
/*
|
||||
* Receive PW status update from Zebra and send it to LDE process.
|
||||
*/
|
||||
void zebra_read_pw_status_update(ZAPI_CALLBACK_ARGS, struct zapi_pw_status *pw)
|
||||
int zebra_read_pw_status_update(ZAPI_CALLBACK_ARGS, struct zapi_pw_status *pw)
|
||||
{
|
||||
struct stream *s;
|
||||
|
||||
@ -2883,8 +2946,12 @@ void zebra_read_pw_status_update(ZAPI_CALLBACK_ARGS, struct zapi_pw_status *pw)
|
||||
|
||||
/* Get data. */
|
||||
stream_get(pw->ifname, s, IF_NAMESIZE);
|
||||
pw->ifindex = stream_getl(s);
|
||||
pw->status = stream_getl(s);
|
||||
STREAM_GETL(s, pw->ifindex);
|
||||
STREAM_GETL(s, pw->status);
|
||||
|
||||
return 0;
|
||||
stream_failure:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void zclient_capability_decode(ZAPI_CALLBACK_ARGS)
|
||||
@ -2895,7 +2962,14 @@ static void zclient_capability_decode(ZAPI_CALLBACK_ARGS)
|
||||
uint8_t mpls_enabled;
|
||||
|
||||
STREAM_GETL(s, vrf_backend);
|
||||
vrf_configure_backend(vrf_backend);
|
||||
|
||||
if (vrf_backend < 0 || vrf_configure_backend(vrf_backend)) {
|
||||
flog_err(EC_LIB_ZAPI_ENCODE,
|
||||
"%s: Garbage VRF backend type: %d\n", __func__,
|
||||
vrf_backend);
|
||||
goto stream_failure;
|
||||
}
|
||||
|
||||
|
||||
memset(&cap, 0, sizeof(cap));
|
||||
STREAM_GETC(s, mpls_enabled);
|
||||
|
@ -723,7 +723,7 @@ zebra_interface_nbr_address_read(int, struct stream *, vrf_id_t);
|
||||
extern struct interface *zebra_interface_vrf_update_read(struct stream *s,
|
||||
vrf_id_t vrf_id,
|
||||
vrf_id_t *new_vrf_id);
|
||||
extern void zebra_router_id_update_read(struct stream *s, struct prefix *rid);
|
||||
extern int zebra_router_id_update_read(struct stream *s, struct prefix *rid);
|
||||
|
||||
extern struct interface *zebra_interface_link_params_read(struct stream *s,
|
||||
vrf_id_t vrf_id);
|
||||
@ -752,7 +752,8 @@ 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);
|
||||
extern int zebra_read_pw_status_update(ZAPI_CALLBACK_ARGS,
|
||||
struct zapi_pw_status *pw);
|
||||
|
||||
extern int zclient_route_send(uint8_t, struct zclient *, struct zapi_route *);
|
||||
extern int zclient_send_rnh(struct zclient *zclient, int command,
|
||||
|
Loading…
Reference in New Issue
Block a user