summaryrefslogtreecommitdiff
path: root/lib/zclient.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/zclient.c')
-rw-r--r--lib/zclient.c116
1 files changed, 83 insertions, 33 deletions
diff --git a/lib/zclient.c b/lib/zclient.c
index b879326d71..a01da77669 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -173,10 +173,10 @@ void zclient_stop(struct zclient *zclient)
redist_del_instance(
&zclient->mi_redist[afi][zclient->redist_default],
zclient->instance);
- }
- vrf_bitmap_free(zclient->default_information);
- zclient->default_information = VRF_BITMAP_NULL;
+ vrf_bitmap_free(zclient->default_information[afi]);
+ zclient->default_information[afi] = VRF_BITMAP_NULL;
+ }
}
void zclient_reset(struct zclient *zclient)
@@ -447,7 +447,7 @@ void zclient_send_reg_requests(struct zclient *zclient, vrf_id_t vrf_id)
}
/* Resend all redistribute request. */
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
+ for (afi = AFI_IP; afi < AFI_MAX; afi++) {
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
if (i != zclient->redist_default
&& vrf_bitmap_check(zclient->redist[afi][i],
@@ -456,10 +456,12 @@ void zclient_send_reg_requests(struct zclient *zclient, vrf_id_t vrf_id)
zclient, afi, i, 0,
vrf_id);
- /* If default information is needed. */
- if (vrf_bitmap_check(zclient->default_information, VRF_DEFAULT))
- zebra_message_send(zclient, ZEBRA_REDISTRIBUTE_DEFAULT_ADD,
- vrf_id);
+ /* If default information is needed. */
+ if (vrf_bitmap_check(zclient->default_information[afi], vrf_id))
+ zebra_redistribute_default_send(
+ ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient, afi,
+ vrf_id);
+ }
}
/* Send unregister requests to zebra daemon for the information in a VRF. */
@@ -512,7 +514,7 @@ void zclient_send_dereg_requests(struct zclient *zclient, vrf_id_t vrf_id)
}
/* Flush all redistribute request. */
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
+ for (afi = AFI_IP; afi < AFI_MAX; afi++) {
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
if (i != zclient->redist_default
&& vrf_bitmap_check(zclient->redist[afi][i],
@@ -521,10 +523,12 @@ void zclient_send_dereg_requests(struct zclient *zclient, vrf_id_t vrf_id)
ZEBRA_REDISTRIBUTE_DELETE, zclient, afi,
i, 0, vrf_id);
- /* If default information is needed. */
- if (vrf_bitmap_check(zclient->default_information, VRF_DEFAULT))
- zebra_message_send(zclient, ZEBRA_REDISTRIBUTE_DEFAULT_DELETE,
- vrf_id);
+ /* If default information is needed. */
+ if (vrf_bitmap_check(zclient->default_information[afi], vrf_id))
+ zebra_redistribute_default_send(
+ ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient, afi,
+ vrf_id);
+ }
}
/* Send request to zebra daemon to start or stop RA. */
@@ -620,12 +624,13 @@ void zclient_init(struct zclient *zclient, int redist_default,
zclient->redist_default = redist_default;
zclient->instance = instance;
/* Pending: make afi(s) an arg. */
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
+ for (afi = AFI_IP; afi < AFI_MAX; afi++) {
redist_add_instance(&zclient->mi_redist[afi][redist_default],
instance);
- /* Set default-information redistribute to zero. */
- zclient->default_information = vrf_bitmap_init();
+ /* Set default-information redistribute to zero. */
+ zclient->default_information[afi] = vrf_bitmap_init();
+ }
if (zclient_debug)
zlog_debug("zclient_start is called");
@@ -749,10 +754,24 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api)
stream_reset(s);
zclient_create_header(s, cmd, api->vrf_id);
+ if (api->type >= ZEBRA_ROUTE_MAX) {
+ flog_err(EC_LIB_ZAPI_ENCODE,
+ "%s: Specified route type (%u) is not a legal value\n",
+ __PRETTY_FUNCTION__, api->type);
+ return -1;
+ }
stream_putc(s, api->type);
+
stream_putw(s, api->instance);
stream_putl(s, api->flags);
stream_putc(s, api->message);
+
+ if (api->safi < SAFI_UNICAST || api->safi >= SAFI_MAX) {
+ flog_err(EC_LIB_ZAPI_ENCODE,
+ "%s: Specified route SAFI (%u) is not a legal value\n",
+ __PRETTY_FUNCTION__, api->safi);
+ return -1;
+ }
stream_putc(s, api->safi);
/* Put prefix information. */
@@ -788,6 +807,7 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api)
stream_putl(s, api_nh->vrf_id);
stream_putc(s, api_nh->type);
+ stream_putc(s, api_nh->onlink);
switch (api_nh->type) {
case NEXTHOP_TYPE_BLACKHOLE:
stream_putc(s, api_nh->bh_type);
@@ -868,7 +888,7 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api)
/* Type, flags, message. */
STREAM_GETC(s, api->type);
- if (api->type > ZEBRA_ROUTE_MAX) {
+ if (api->type >= ZEBRA_ROUTE_MAX) {
flog_err(EC_LIB_ZAPI_ENCODE,
"%s: Specified route type: %d is not a legal value\n",
__PRETTY_FUNCTION__, api->type);
@@ -879,6 +899,12 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api)
STREAM_GETL(s, api->flags);
STREAM_GETC(s, api->message);
STREAM_GETC(s, api->safi);
+ if (api->safi < SAFI_UNICAST || api->safi >= SAFI_MAX) {
+ flog_err(EC_LIB_ZAPI_ENCODE,
+ "%s: Specified route SAFI (%u) is not a legal value\n",
+ __PRETTY_FUNCTION__, api->safi);
+ return -1;
+ }
/* Prefix. */
STREAM_GETC(s, api->prefix.family);
@@ -948,6 +974,7 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api)
STREAM_GETL(s, api_nh->vrf_id);
STREAM_GETC(s, api_nh->type);
+ STREAM_GETC(s, api_nh->onlink);
switch (api_nh->type) {
case NEXTHOP_TYPE_BLACKHOLE:
STREAM_GETC(s, api_nh->bh_type);
@@ -1280,6 +1307,22 @@ int zebra_redistribute_send(int command, struct zclient *zclient, afi_t afi,
return zclient_send_message(zclient);
}
+int zebra_redistribute_default_send(int command, struct zclient *zclient,
+ afi_t afi, vrf_id_t vrf_id)
+{
+ struct stream *s;
+
+ s = zclient->obuf;
+ stream_reset(s);
+
+ zclient_create_header(s, command, vrf_id);
+ stream_putc(s, afi);
+
+ stream_putw_at(s, 0, stream_get_endp(s));
+
+ return zclient_send_message(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)
{
@@ -1370,7 +1413,7 @@ static void zclient_vrf_add(struct zclient *zclient, vrf_id_t vrf_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);
+ vrf_set_default_name(vrfname_tmp, false);
vrf_enable(vrf);
}
@@ -1474,7 +1517,8 @@ static void link_params_set_value(struct stream *s, struct if_link_params *iflp)
iflp->use_bw = stream_getf(s);
}
-struct interface *zebra_interface_link_params_read(struct stream *s)
+struct interface *zebra_interface_link_params_read(struct stream *s,
+ vrf_id_t vrf_id)
{
struct if_link_params *iflp;
ifindex_t ifindex;
@@ -1483,7 +1527,7 @@ struct interface *zebra_interface_link_params_read(struct stream *s)
ifindex = stream_getl(s);
- struct interface *ifp = if_lookup_by_index(ifindex, VRF_DEFAULT);
+ struct interface *ifp = if_lookup_by_index(ifindex, vrf_id);
if (ifp == NULL) {
flog_err(EC_LIB_ZAPI_ENCODE,
@@ -1770,19 +1814,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;
}
@@ -2349,12 +2393,17 @@ static void zclient_capability_decode(int command, struct zclient *zclient,
{
struct zclient_capabilities cap;
struct stream *s = zclient->ibuf;
+ int vrf_backend;
uint8_t mpls_enabled;
+ STREAM_GETL(s, vrf_backend);
+ vrf_configure_backend(vrf_backend);
+
memset(&cap, 0, sizeof(cap));
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);
@@ -2559,7 +2608,7 @@ static int zclient_read(struct thread *thread)
case ZEBRA_INTERFACE_LINK_PARAMS:
if (zclient->interface_link_params)
(*zclient->interface_link_params)(command, zclient,
- length);
+ length, vrf_id);
break;
case ZEBRA_FEC_UPDATE:
if (zclient_debug)
@@ -2708,21 +2757,22 @@ void zclient_redistribute(int command, struct zclient *zclient, afi_t afi,
void zclient_redistribute_default(int command, struct zclient *zclient,
- vrf_id_t vrf_id)
+ afi_t afi, vrf_id_t vrf_id)
{
if (command == ZEBRA_REDISTRIBUTE_DEFAULT_ADD) {
- if (vrf_bitmap_check(zclient->default_information, vrf_id))
+ if (vrf_bitmap_check(zclient->default_information[afi], vrf_id))
return;
- vrf_bitmap_set(zclient->default_information, vrf_id);
+ vrf_bitmap_set(zclient->default_information[afi], vrf_id);
} else {
- if (!vrf_bitmap_check(zclient->default_information, vrf_id))
+ if (!vrf_bitmap_check(zclient->default_information[afi],
+ vrf_id))
return;
- vrf_bitmap_unset(zclient->default_information, vrf_id);
+ vrf_bitmap_unset(zclient->default_information[afi], vrf_id);
}
if (zclient->sock > 0)
- zebra_message_send(zclient, command, vrf_id);
+ zebra_redistribute_default_send(command, zclient, afi, vrf_id);
}
static void zclient_event(enum event event, struct zclient *zclient)