mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-10 16:42:44 +00:00
zebra: Refactor nexthop reading from zapi messages
Take the zebra code that reads nexthops and combine it into one function so that when we add zapi messages to send/receive nexthops we can take advantage of this function. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
parent
224b3c8a79
commit
f70da2a390
293
zebra/zapi_msg.c
293
zebra/zapi_msg.c
@ -1578,23 +1578,145 @@ done:
|
|||||||
return nexthop;
|
return nexthop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool zapi_read_nexthops(struct zserv *client, struct zapi_route *api,
|
||||||
|
struct route_entry *re,
|
||||||
|
struct nexthop_group **png,
|
||||||
|
struct nhg_backup_info **pbnhg)
|
||||||
|
{
|
||||||
|
struct nexthop_group *ng = NULL;
|
||||||
|
struct nhg_backup_info *bnhg = NULL;
|
||||||
|
uint16_t nexthop_num, i;;
|
||||||
|
struct zapi_nexthop *nhops;
|
||||||
|
struct nexthop *last_nh = NULL;
|
||||||
|
|
||||||
|
assert(!(png && pbnhg));
|
||||||
|
|
||||||
|
if (png) {
|
||||||
|
*png = ng = nexthop_group_new();
|
||||||
|
nexthop_num = api->nexthop_num;
|
||||||
|
nhops = api->nexthops;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pbnhg && api->backup_nexthop_num > 0) {
|
||||||
|
if (IS_ZEBRA_DEBUG_RECV)
|
||||||
|
zlog_debug("%s: adding %d backup nexthops",
|
||||||
|
__func__, api->backup_nexthop_num);
|
||||||
|
|
||||||
|
nexthop_num = api->backup_nexthop_num;
|
||||||
|
*pbnhg = bnhg = zebra_nhg_backup_alloc();
|
||||||
|
nhops = api->backup_nexthops;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TBD should _all_ of the nexthop add operations use
|
||||||
|
* api_nh->vrf_id instead of re->vrf_id ? I only changed
|
||||||
|
* for cases NEXTHOP_TYPE_IPV4 and NEXTHOP_TYPE_IPV6.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < nexthop_num; i++) {
|
||||||
|
struct nexthop *nexthop;
|
||||||
|
enum lsp_types_t label_type;
|
||||||
|
char nhbuf[NEXTHOP_STRLEN];
|
||||||
|
char labelbuf[MPLS_LABEL_STRLEN];
|
||||||
|
struct zapi_nexthop *api_nh = &nhops[i];
|
||||||
|
|
||||||
|
/* Convert zapi nexthop */
|
||||||
|
nexthop = nexthop_from_zapi(re, api_nh, api);
|
||||||
|
if (!nexthop) {
|
||||||
|
flog_warn(
|
||||||
|
EC_ZEBRA_NEXTHOP_CREATION_FAILED,
|
||||||
|
"%s: Nexthops Specified: %u(%u) but we failed to properly create one",
|
||||||
|
__func__, nexthop_num, i);
|
||||||
|
if (ng)
|
||||||
|
nexthop_group_delete(&ng);
|
||||||
|
if (bnhg)
|
||||||
|
zebra_nhg_backup_free(&bnhg);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bnhg && CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP)) {
|
||||||
|
if (IS_ZEBRA_DEBUG_RECV) {
|
||||||
|
nexthop2str(nexthop, nhbuf, sizeof(nhbuf));
|
||||||
|
zlog_debug("%s: backup nh %s with BACKUP flag!",
|
||||||
|
__func__, nhbuf);
|
||||||
|
}
|
||||||
|
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP);
|
||||||
|
nexthop->backup_num = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CHECK_FLAG(api->message, ZAPI_MESSAGE_SRTE)) {
|
||||||
|
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_SRTE);
|
||||||
|
nexthop->srte_color = api_nh->srte_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MPLS labels for BGP-LU or Segment Routing */
|
||||||
|
if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_LABEL)
|
||||||
|
&& api_nh->type != NEXTHOP_TYPE_IFINDEX
|
||||||
|
&& api_nh->type != NEXTHOP_TYPE_BLACKHOLE
|
||||||
|
&& api_nh->label_num > 0) {
|
||||||
|
|
||||||
|
label_type = lsp_type_from_re_type(client->proto);
|
||||||
|
nexthop_add_labels(nexthop, label_type,
|
||||||
|
api_nh->label_num,
|
||||||
|
&api_nh->labels[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IS_ZEBRA_DEBUG_RECV) {
|
||||||
|
labelbuf[0] = '\0';
|
||||||
|
nhbuf[0] = '\0';
|
||||||
|
|
||||||
|
nexthop2str(nexthop, nhbuf, sizeof(nhbuf));
|
||||||
|
|
||||||
|
if (nexthop->nh_label &&
|
||||||
|
nexthop->nh_label->num_labels > 0) {
|
||||||
|
mpls_label2str(nexthop->nh_label->num_labels,
|
||||||
|
nexthop->nh_label->label,
|
||||||
|
labelbuf, sizeof(labelbuf),
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
|
zlog_debug("%s: nh=%s, vrf_id=%d %s",
|
||||||
|
__func__, nhbuf, api_nh->vrf_id, labelbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (png) {
|
||||||
|
/* Add new nexthop to temporary list. This list is
|
||||||
|
* canonicalized - sorted - so that it can be hashed later
|
||||||
|
* in route processing. We expect that the sender has sent
|
||||||
|
* the list sorted, and the zapi client api attempts to enforce
|
||||||
|
* that, so this should be inexpensive - but it is necessary
|
||||||
|
* to support shared nexthop-groups.
|
||||||
|
*/
|
||||||
|
nexthop_group_add_sorted(ng, nexthop);
|
||||||
|
}
|
||||||
|
if (bnhg) {
|
||||||
|
/* Note that the order of the backup nexthops is significant,
|
||||||
|
* so we don't sort this list as we do the primary nexthops,
|
||||||
|
* we just append.
|
||||||
|
*/
|
||||||
|
if (last_nh)
|
||||||
|
NEXTHOP_APPEND(last_nh, nexthop);
|
||||||
|
else
|
||||||
|
bnhg->nhe->nhg.nexthop = nexthop;
|
||||||
|
|
||||||
|
last_nh = nexthop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static void zread_route_add(ZAPI_HANDLER_ARGS)
|
static void zread_route_add(ZAPI_HANDLER_ARGS)
|
||||||
{
|
{
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
struct zapi_route api;
|
struct zapi_route api;
|
||||||
struct zapi_nexthop *api_nh;
|
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
struct prefix_ipv6 *src_p = NULL;
|
struct prefix_ipv6 *src_p = NULL;
|
||||||
struct route_entry *re;
|
struct route_entry *re;
|
||||||
struct nexthop *nexthop = NULL, *last_nh;
|
|
||||||
struct nexthop_group *ng = NULL;
|
struct nexthop_group *ng = NULL;
|
||||||
struct nhg_backup_info *bnhg = NULL;
|
struct nhg_backup_info *bnhg = NULL;
|
||||||
int i, ret;
|
int ret;
|
||||||
vrf_id_t vrf_id;
|
vrf_id_t vrf_id;
|
||||||
struct nhg_hash_entry nhe;
|
struct nhg_hash_entry nhe;
|
||||||
enum lsp_types_t label_type;
|
|
||||||
char nhbuf[NEXTHOP_STRLEN];
|
|
||||||
char labelbuf[MPLS_LABEL_STRLEN];
|
|
||||||
|
|
||||||
s = msg;
|
s = msg;
|
||||||
if (zapi_route_decode(s, &api) < 0) {
|
if (zapi_route_decode(s, &api) < 0) {
|
||||||
@ -1611,7 +1733,8 @@ static void zread_route_add(ZAPI_HANDLER_ARGS)
|
|||||||
|
|
||||||
prefix2str(&api.prefix, buf_prefix, sizeof(buf_prefix));
|
prefix2str(&api.prefix, buf_prefix, sizeof(buf_prefix));
|
||||||
zlog_debug("%s: p=(%u:%u)%s, msg flags=0x%x, flags=0x%x",
|
zlog_debug("%s: p=(%u:%u)%s, msg flags=0x%x, flags=0x%x",
|
||||||
__func__, vrf_id, api.tableid, buf_prefix, (int)api.message, api.flags);
|
__func__, vrf_id, api.tableid, buf_prefix,
|
||||||
|
(int)api.message, api.flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate new route. */
|
/* Allocate new route. */
|
||||||
@ -1647,158 +1770,10 @@ static void zread_route_add(ZAPI_HANDLER_ARGS)
|
|||||||
zebra_route_string(client->proto), &api.prefix);
|
zebra_route_string(client->proto), &api.prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use temporary list of nexthops */
|
if (!zapi_read_nexthops(client, &api, re, &ng, NULL) ||
|
||||||
ng = nexthop_group_new();
|
!zapi_read_nexthops(client, &api, re, NULL, &bnhg)) {
|
||||||
|
XFREE(MTYPE_RE, re);
|
||||||
/*
|
return;
|
||||||
* TBD should _all_ of the nexthop add operations use
|
|
||||||
* api_nh->vrf_id instead of re->vrf_id ? I only changed
|
|
||||||
* for cases NEXTHOP_TYPE_IPV4 and NEXTHOP_TYPE_IPV6.
|
|
||||||
*/
|
|
||||||
for (i = 0; i < api.nexthop_num; i++) {
|
|
||||||
api_nh = &api.nexthops[i];
|
|
||||||
|
|
||||||
/* Convert zapi nexthop */
|
|
||||||
nexthop = nexthop_from_zapi(re, api_nh, &api);
|
|
||||||
if (!nexthop) {
|
|
||||||
flog_warn(
|
|
||||||
EC_ZEBRA_NEXTHOP_CREATION_FAILED,
|
|
||||||
"%s: Nexthops Specified: %d but we failed to properly create one",
|
|
||||||
__func__, api.nexthop_num);
|
|
||||||
nexthop_group_delete(&ng);
|
|
||||||
XFREE(MTYPE_RE, re);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRTE)) {
|
|
||||||
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_SRTE);
|
|
||||||
nexthop->srte_color = api_nh->srte_color;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* MPLS labels for BGP-LU or Segment Routing */
|
|
||||||
if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_LABEL)
|
|
||||||
&& api_nh->type != NEXTHOP_TYPE_IFINDEX
|
|
||||||
&& api_nh->type != NEXTHOP_TYPE_BLACKHOLE
|
|
||||||
&& api_nh->label_num > 0) {
|
|
||||||
|
|
||||||
label_type = lsp_type_from_re_type(client->proto);
|
|
||||||
nexthop_add_labels(nexthop, label_type,
|
|
||||||
api_nh->label_num,
|
|
||||||
&api_nh->labels[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_RECV) {
|
|
||||||
labelbuf[0] = '\0';
|
|
||||||
nhbuf[0] = '\0';
|
|
||||||
|
|
||||||
nexthop2str(nexthop, nhbuf, sizeof(nhbuf));
|
|
||||||
|
|
||||||
if (nexthop->nh_label &&
|
|
||||||
nexthop->nh_label->num_labels > 0) {
|
|
||||||
mpls_label2str(nexthop->nh_label->num_labels,
|
|
||||||
nexthop->nh_label->label,
|
|
||||||
labelbuf, sizeof(labelbuf),
|
|
||||||
false);
|
|
||||||
}
|
|
||||||
|
|
||||||
zlog_debug("%s: nh=%s, vrf_id=%d %s",
|
|
||||||
__func__, nhbuf, api_nh->vrf_id, labelbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add new nexthop to temporary list. This list is
|
|
||||||
* canonicalized - sorted - so that it can be hashed later
|
|
||||||
* in route processing. We expect that the sender has sent
|
|
||||||
* the list sorted, and the zapi client api attempts to enforce
|
|
||||||
* that, so this should be inexpensive - but it is necessary
|
|
||||||
* to support shared nexthop-groups.
|
|
||||||
*/
|
|
||||||
nexthop_group_add_sorted(ng, nexthop);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate temporary list of backup nexthops, if necessary */
|
|
||||||
if (api.backup_nexthop_num > 0) {
|
|
||||||
if (IS_ZEBRA_DEBUG_RECV)
|
|
||||||
zlog_debug("%s: adding %d backup nexthops",
|
|
||||||
__func__, api.backup_nexthop_num);
|
|
||||||
|
|
||||||
bnhg = zebra_nhg_backup_alloc();
|
|
||||||
nexthop = NULL;
|
|
||||||
last_nh = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy backup nexthops also, if present */
|
|
||||||
for (i = 0; i < api.backup_nexthop_num; i++) {
|
|
||||||
api_nh = &api.backup_nexthops[i];
|
|
||||||
|
|
||||||
/* Convert zapi backup nexthop */
|
|
||||||
nexthop = nexthop_from_zapi(re, api_nh, &api);
|
|
||||||
if (!nexthop) {
|
|
||||||
flog_warn(
|
|
||||||
EC_ZEBRA_NEXTHOP_CREATION_FAILED,
|
|
||||||
"%s: Backup Nexthops Specified: %d but we failed to properly create one",
|
|
||||||
__func__, api.backup_nexthop_num);
|
|
||||||
nexthop_group_delete(&ng);
|
|
||||||
zebra_nhg_backup_free(&bnhg);
|
|
||||||
XFREE(MTYPE_RE, re);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Backup nexthops can't have backups; that's not valid. */
|
|
||||||
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP)) {
|
|
||||||
if (IS_ZEBRA_DEBUG_RECV) {
|
|
||||||
nexthop2str(nexthop, nhbuf, sizeof(nhbuf));
|
|
||||||
zlog_debug("%s: backup nh %s with BACKUP flag!",
|
|
||||||
__func__, nhbuf);
|
|
||||||
}
|
|
||||||
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP);
|
|
||||||
nexthop->backup_num = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRTE)) {
|
|
||||||
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_SRTE);
|
|
||||||
nexthop->srte_color = api_nh->srte_color;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* MPLS labels for BGP-LU or Segment Routing */
|
|
||||||
if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_LABEL)
|
|
||||||
&& api_nh->type != NEXTHOP_TYPE_IFINDEX
|
|
||||||
&& api_nh->type != NEXTHOP_TYPE_BLACKHOLE
|
|
||||||
&& api_nh->label_num > 0) {
|
|
||||||
|
|
||||||
label_type = lsp_type_from_re_type(client->proto);
|
|
||||||
nexthop_add_labels(nexthop, label_type,
|
|
||||||
api_nh->label_num,
|
|
||||||
&api_nh->labels[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_RECV) {
|
|
||||||
labelbuf[0] = '\0';
|
|
||||||
nhbuf[0] = '\0';
|
|
||||||
|
|
||||||
nexthop2str(nexthop, nhbuf, sizeof(nhbuf));
|
|
||||||
|
|
||||||
if (nexthop->nh_label &&
|
|
||||||
nexthop->nh_label->num_labels > 0) {
|
|
||||||
mpls_label2str(nexthop->nh_label->num_labels,
|
|
||||||
nexthop->nh_label->label,
|
|
||||||
labelbuf, sizeof(labelbuf),
|
|
||||||
false);
|
|
||||||
}
|
|
||||||
|
|
||||||
zlog_debug("%s: backup nh=%s, vrf_id=%d %s",
|
|
||||||
__func__, nhbuf, api_nh->vrf_id, labelbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Note that the order of the backup nexthops is significant,
|
|
||||||
* so we don't sort this list as we do the primary nexthops,
|
|
||||||
* we just append.
|
|
||||||
*/
|
|
||||||
if (last_nh)
|
|
||||||
NEXTHOP_APPEND(last_nh, nexthop);
|
|
||||||
else
|
|
||||||
bnhg->nhe->nhg.nexthop = nexthop;
|
|
||||||
|
|
||||||
last_nh = nexthop;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE))
|
if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE))
|
||||||
|
Loading…
Reference in New Issue
Block a user