mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-03 02:22:48 +00:00
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:
parent
defd2ea4a1
commit
018c648864
@ -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];
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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. */
|
||||
|
Loading…
Reference in New Issue
Block a user