lib: add backup nexthops to zapi routes

Add backup nexthop info to zapi route messages.

Signed-off-by: Mark Stapp <mjs@voltanet.io>
This commit is contained in:
Mark Stapp 2019-11-11 15:50:30 -05:00
parent defd2ea4a1
commit 018c648864
3 changed files with 96 additions and 3 deletions

View File

@ -948,6 +948,10 @@ int zapi_nexthop_encode(struct stream *s, const struct zapi_nexthop *api_nh,
stream_put(s, &(api_nh->rmac),
sizeof(struct ethaddr));
/* Index of backup nexthop */
if (CHECK_FLAG(nh_flags, ZAPI_NEXTHOP_FLAG_HAS_BACKUP))
stream_putc(s, api_nh->backup_idx);
done:
return ret;
}
@ -1007,6 +1011,10 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api)
return -1;
}
/* We canonicalize the nexthops by sorting them; this allows
* zebra to resolve the list of nexthops to a nexthop-group
* more efficiently.
*/
zapi_nexthop_group_sort(api->nexthops, api->nexthop_num);
stream_putw(s, api->nexthop_num);
@ -1033,6 +1041,50 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api)
}
}
/* Backup nexthops */
if (CHECK_FLAG(api->message, ZAPI_MESSAGE_BACKUP_NEXTHOPS)) {
/* limit the number of nexthops if necessary */
if (api->backup_nexthop_num > MULTIPATH_NUM) {
char buf[PREFIX2STR_BUFFER];
prefix2str(&api->prefix, buf, sizeof(buf));
flog_err(
EC_LIB_ZAPI_ENCODE,
"%s: prefix %s: can't encode %u backup nexthops (maximum is %u)",
__func__, buf, api->backup_nexthop_num,
MULTIPATH_NUM);
return -1;
}
/* Note that we do not sort the list of backup nexthops -
* this list is treated as an array and indexed by each
* primary nexthop that is associated with a backup.
*/
stream_putw(s, api->backup_nexthop_num);
for (i = 0; i < api->backup_nexthop_num; i++) {
api_nh = &api->backup_nexthops[i];
/* MPLS labels for BGP-LU or Segment Routing */
if (api_nh->label_num > MPLS_MAX_LABELS) {
char buf[PREFIX2STR_BUFFER];
prefix2str(&api->prefix, buf, sizeof(buf));
flog_err(EC_LIB_ZAPI_ENCODE,
"%s: prefix %s: backup: can't encode %u labels (maximum is %u)",
__func__, buf,
api_nh->label_num,
MPLS_MAX_LABELS);
return -1;
}
if (zapi_nexthop_encode(s, api_nh, api->flags) != 0)
return -1;
}
}
/* Attributes. */
if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
stream_putc(s, api->distance);
@ -1108,6 +1160,10 @@ static int zapi_nexthop_decode(struct stream *s, struct zapi_nexthop *api_nh,
STREAM_GET(&(api_nh->rmac), s,
sizeof(struct ethaddr));
/* Backup nexthop index */
if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_HAS_BACKUP))
STREAM_GETC(s, api_nh->backup_idx);
/* Success */
ret = 0;
@ -1214,6 +1270,24 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api)
}
}
/* Backup nexthops. */
if (CHECK_FLAG(api->message, ZAPI_MESSAGE_BACKUP_NEXTHOPS)) {
STREAM_GETW(s, api->backup_nexthop_num);
if (api->backup_nexthop_num > MULTIPATH_NUM) {
flog_err(EC_LIB_ZAPI_ENCODE,
"%s: invalid number of backup nexthops (%u)",
__func__, api->backup_nexthop_num);
return -1;
}
for (i = 0; i < api->backup_nexthop_num; i++) {
api_nh = &api->backup_nexthops[i];
if (zapi_nexthop_decode(s, api_nh, api->flags) != 0)
return -1;
}
}
/* Attributes. */
if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
STREAM_GETC(s, api->distance);
@ -1424,6 +1498,11 @@ int zapi_nexthop_from_nexthop(struct zapi_nexthop *znh,
znh->gate = nh->gate;
if (nh->nh_label && (nh->nh_label->num_labels > 0)) {
/* Validate */
if (nh->nh_label->num_labels > MPLS_MAX_LABELS)
return -1;
for (i = 0; i < nh->nh_label->num_labels; i++)
znh->labels[i] = nh->nh_label->label[i];

View File

@ -341,6 +341,9 @@ struct zclient {
#define ZAPI_MESSAGE_TAG 0x08
#define ZAPI_MESSAGE_MTU 0x10
#define ZAPI_MESSAGE_SRCPFX 0x20
/* Backup nexthops are present */
#define ZAPI_MESSAGE_BACKUP_NEXTHOPS 0x40
/*
* This should only be used by a DAEMON that needs to communicate
* the table being used is not in the VRF. You must pass the
@ -377,14 +380,21 @@ struct zapi_nexthop {
struct ethaddr rmac;
uint32_t weight;
/* Index of backup nexthop */
uint8_t backup_idx;
};
/*
* ZAPI nexthop flags values
* ZAPI nexthop flags values - we're encoding a single octet
* initially, so ensure that the on-the-wire encoding continues
* to match the number of valid flags.
*/
#define ZAPI_NEXTHOP_FLAG_ONLINK 0x01
#define ZAPI_NEXTHOP_FLAG_LABEL 0x02
#define ZAPI_NEXTHOP_FLAG_WEIGHT 0x04
#define ZAPI_NEXTHOP_FLAG_HAS_BACKUP 0x08 /* Nexthop has a backup */
/*
* Some of these data structures do not map easily to
@ -448,6 +458,10 @@ struct zapi_route {
uint16_t nexthop_num;
struct zapi_nexthop nexthops[MULTIPATH_NUM];
/* Support backup routes for IP FRR, TI-LFA, traffic engineering */
uint16_t backup_nexthop_num;
struct zapi_nexthop backup_nexthops[MULTIPATH_NUM];
uint8_t distance;
uint32_t metric;

View File

@ -1440,8 +1440,8 @@ static void zread_route_add(ZAPI_HANDLER_ARGS)
char buf_prefix[PREFIX_STRLEN];
prefix2str(&api.prefix, buf_prefix, sizeof(buf_prefix));
zlog_debug("%s: p=%s, flags=0x%x",
__func__, buf_prefix, api.flags);
zlog_debug("%s: p=%s, msg flags=0x%x, flags=0x%x",
__func__, buf_prefix, (int)api.message, api.flags);
}
/* Allocate new route. */