diff options
Diffstat (limited to 'lib/zclient.c')
| -rw-r--r-- | lib/zclient.c | 116 |
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) |
