mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-06 18:04:03 +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),
|
stream_put(s, &(api_nh->rmac),
|
||||||
sizeof(struct ethaddr));
|
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:
|
done:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1007,6 +1011,10 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api)
|
|||||||
return -1;
|
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);
|
zapi_nexthop_group_sort(api->nexthops, api->nexthop_num);
|
||||||
|
|
||||||
stream_putw(s, 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. */
|
/* Attributes. */
|
||||||
if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
|
if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
|
||||||
stream_putc(s, api->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,
|
STREAM_GET(&(api_nh->rmac), s,
|
||||||
sizeof(struct ethaddr));
|
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 */
|
/* Success */
|
||||||
ret = 0;
|
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. */
|
/* Attributes. */
|
||||||
if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
|
if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
|
||||||
STREAM_GETC(s, api->distance);
|
STREAM_GETC(s, api->distance);
|
||||||
@ -1424,6 +1498,11 @@ int zapi_nexthop_from_nexthop(struct zapi_nexthop *znh,
|
|||||||
znh->gate = nh->gate;
|
znh->gate = nh->gate;
|
||||||
|
|
||||||
if (nh->nh_label && (nh->nh_label->num_labels > 0)) {
|
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++)
|
for (i = 0; i < nh->nh_label->num_labels; i++)
|
||||||
znh->labels[i] = nh->nh_label->label[i];
|
znh->labels[i] = nh->nh_label->label[i];
|
||||||
|
|
||||||
|
@ -341,6 +341,9 @@ struct zclient {
|
|||||||
#define ZAPI_MESSAGE_TAG 0x08
|
#define ZAPI_MESSAGE_TAG 0x08
|
||||||
#define ZAPI_MESSAGE_MTU 0x10
|
#define ZAPI_MESSAGE_MTU 0x10
|
||||||
#define ZAPI_MESSAGE_SRCPFX 0x20
|
#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
|
* 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
|
* the table being used is not in the VRF. You must pass the
|
||||||
@ -377,14 +380,21 @@ struct zapi_nexthop {
|
|||||||
struct ethaddr rmac;
|
struct ethaddr rmac;
|
||||||
|
|
||||||
uint32_t weight;
|
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_ONLINK 0x01
|
||||||
#define ZAPI_NEXTHOP_FLAG_LABEL 0x02
|
#define ZAPI_NEXTHOP_FLAG_LABEL 0x02
|
||||||
#define ZAPI_NEXTHOP_FLAG_WEIGHT 0x04
|
#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
|
* Some of these data structures do not map easily to
|
||||||
@ -448,6 +458,10 @@ struct zapi_route {
|
|||||||
uint16_t nexthop_num;
|
uint16_t nexthop_num;
|
||||||
struct zapi_nexthop nexthops[MULTIPATH_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;
|
uint8_t distance;
|
||||||
|
|
||||||
uint32_t metric;
|
uint32_t metric;
|
||||||
|
@ -1440,8 +1440,8 @@ static void zread_route_add(ZAPI_HANDLER_ARGS)
|
|||||||
char buf_prefix[PREFIX_STRLEN];
|
char buf_prefix[PREFIX_STRLEN];
|
||||||
|
|
||||||
prefix2str(&api.prefix, buf_prefix, sizeof(buf_prefix));
|
prefix2str(&api.prefix, buf_prefix, sizeof(buf_prefix));
|
||||||
zlog_debug("%s: p=%s, flags=0x%x",
|
zlog_debug("%s: p=%s, msg flags=0x%x, flags=0x%x",
|
||||||
__func__, buf_prefix, api.flags);
|
__func__, buf_prefix, (int)api.message, api.flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate new route. */
|
/* Allocate new route. */
|
||||||
|
Loading…
Reference in New Issue
Block a user