forked from Mirror/frr
sharpd: include backup nh info with lsps
If present in a configured nexthop_group, include backup nexthop/nhlfe info with LSP zapi add/update messages. Signed-off-by: Mark Stapp <mjs@voltanet.io>
This commit is contained in:
parent
ae076fc276
commit
665edffd1e
|
@ -410,6 +410,8 @@ DEFPY(sharp_lsp_prefix_v4, sharp_lsp_prefix_v4_cmd,
|
||||||
"Instance\n")
|
"Instance\n")
|
||||||
{
|
{
|
||||||
struct nexthop_group_cmd *nhgc = NULL;
|
struct nexthop_group_cmd *nhgc = NULL;
|
||||||
|
struct nexthop_group_cmd *backup_nhgc = NULL;
|
||||||
|
struct nexthop_group *backup_nhg = NULL;
|
||||||
struct prefix p = {};
|
struct prefix p = {};
|
||||||
int type = 0;
|
int type = 0;
|
||||||
|
|
||||||
|
@ -441,9 +443,23 @@ DEFPY(sharp_lsp_prefix_v4, sharp_lsp_prefix_v4_cmd,
|
||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Use group's backup nexthop info if present */
|
||||||
|
if (nhgc->backup_list_name[0]) {
|
||||||
|
backup_nhgc = nhgc_find(nhgc->backup_list_name);
|
||||||
|
|
||||||
|
if (!backup_nhgc) {
|
||||||
|
vty_out(vty,
|
||||||
|
"%% Backup group %s not found for group %s\n",
|
||||||
|
nhgc->backup_list_name,
|
||||||
|
nhgname);
|
||||||
|
return CMD_WARNING;
|
||||||
|
}
|
||||||
|
backup_nhg = &(backup_nhgc->nhg);
|
||||||
|
}
|
||||||
|
|
||||||
if (sharp_install_lsps_helper(true, pfx->family > 0 ? &p : NULL,
|
if (sharp_install_lsps_helper(true, pfx->family > 0 ? &p : NULL,
|
||||||
type, instance, inlabel,
|
type, instance, inlabel,
|
||||||
&(nhgc->nhg)) == 0)
|
&(nhgc->nhg), backup_nhg) == 0)
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
else {
|
else {
|
||||||
vty_out(vty, "%% LSP install failed!\n");
|
vty_out(vty, "%% LSP install failed!\n");
|
||||||
|
@ -454,7 +470,7 @@ DEFPY(sharp_lsp_prefix_v4, sharp_lsp_prefix_v4_cmd,
|
||||||
DEFPY(sharp_remove_lsp_prefix_v4, sharp_remove_lsp_prefix_v4_cmd,
|
DEFPY(sharp_remove_lsp_prefix_v4, sharp_remove_lsp_prefix_v4_cmd,
|
||||||
"sharp remove lsp \
|
"sharp remove lsp \
|
||||||
(0-100000)$inlabel\
|
(0-100000)$inlabel\
|
||||||
nexthop-group NHGNAME$nhgname\
|
[nexthop-group NHGNAME$nhgname] \
|
||||||
[prefix A.B.C.D/M$pfx\
|
[prefix A.B.C.D/M$pfx\
|
||||||
" FRR_IP_REDIST_STR_SHARPD "$type_str [instance (0-255)$instance]]",
|
" FRR_IP_REDIST_STR_SHARPD "$type_str [instance (0-255)$instance]]",
|
||||||
"Sharp Routing Protocol\n"
|
"Sharp Routing Protocol\n"
|
||||||
|
@ -472,6 +488,7 @@ DEFPY(sharp_remove_lsp_prefix_v4, sharp_remove_lsp_prefix_v4_cmd,
|
||||||
struct nexthop_group_cmd *nhgc = NULL;
|
struct nexthop_group_cmd *nhgc = NULL;
|
||||||
struct prefix p = {};
|
struct prefix p = {};
|
||||||
int type = 0;
|
int type = 0;
|
||||||
|
struct nexthop_group *nhg = NULL;
|
||||||
|
|
||||||
/* We're offered a v4 prefix */
|
/* We're offered a v4 prefix */
|
||||||
if (pfx->family > 0 && type_str) {
|
if (pfx->family > 0 && type_str) {
|
||||||
|
@ -489,6 +506,7 @@ DEFPY(sharp_remove_lsp_prefix_v4, sharp_remove_lsp_prefix_v4_cmd,
|
||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nhgname) {
|
||||||
nhgc = nhgc_find(nhgname);
|
nhgc = nhgc_find(nhgname);
|
||||||
if (!nhgc) {
|
if (!nhgc) {
|
||||||
vty_out(vty, "%% Nexthop-group '%s' does not exist\n",
|
vty_out(vty, "%% Nexthop-group '%s' does not exist\n",
|
||||||
|
@ -497,13 +515,15 @@ DEFPY(sharp_remove_lsp_prefix_v4, sharp_remove_lsp_prefix_v4_cmd,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nhgc->nhg.nexthop == NULL) {
|
if (nhgc->nhg.nexthop == NULL) {
|
||||||
vty_out(vty, "%% Nexthop-group '%s' is empty\n", nhgname);
|
vty_out(vty, "%% Nexthop-group '%s' is empty\n",
|
||||||
|
nhgname);
|
||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
}
|
}
|
||||||
|
nhg = &(nhgc->nhg);
|
||||||
|
}
|
||||||
|
|
||||||
if (sharp_install_lsps_helper(false, pfx->family > 0 ? &p : NULL,
|
if (sharp_install_lsps_helper(false, pfx->family > 0 ? &p : NULL,
|
||||||
type, instance, inlabel,
|
type, instance, inlabel, nhg, NULL) == 0)
|
||||||
&(nhgc->nhg)) == 0)
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
else {
|
else {
|
||||||
vty_out(vty, "%% LSP remove failed!\n");
|
vty_out(vty, "%% LSP remove failed!\n");
|
||||||
|
|
|
@ -89,7 +89,8 @@ static int sharp_ifp_down(struct interface *ifp)
|
||||||
|
|
||||||
int sharp_install_lsps_helper(bool install_p, const struct prefix *p,
|
int sharp_install_lsps_helper(bool install_p, const struct prefix *p,
|
||||||
uint8_t type, int instance, uint32_t in_label,
|
uint8_t type, int instance, uint32_t in_label,
|
||||||
const struct nexthop_group *nhg)
|
const struct nexthop_group *nhg,
|
||||||
|
const struct nexthop_group *backup_nhg)
|
||||||
{
|
{
|
||||||
struct zapi_labels zl = {};
|
struct zapi_labels zl = {};
|
||||||
struct zapi_nexthop *znh;
|
struct zapi_nexthop *znh;
|
||||||
|
@ -106,12 +107,15 @@ int sharp_install_lsps_helper(bool install_p, const struct prefix *p,
|
||||||
zl.route.instance = instance;
|
zl.route.instance = instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* List of nexthops is optional for delete */
|
||||||
i = 0;
|
i = 0;
|
||||||
|
if (nhg) {
|
||||||
for (ALL_NEXTHOPS_PTR(nhg, nh)) {
|
for (ALL_NEXTHOPS_PTR(nhg, nh)) {
|
||||||
znh = &zl.nexthops[i];
|
znh = &zl.nexthops[i];
|
||||||
|
|
||||||
/* Must have labels to be useful */
|
/* Must have labels to be useful */
|
||||||
if (nh->nh_label == NULL || nh->nh_label->num_labels == 0)
|
if (nh->nh_label == NULL ||
|
||||||
|
nh->nh_label->num_labels == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (nh->type == NEXTHOP_TYPE_IFINDEX ||
|
if (nh->type == NEXTHOP_TYPE_IFINDEX ||
|
||||||
|
@ -125,13 +129,46 @@ int sharp_install_lsps_helper(bool install_p, const struct prefix *p,
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Whoops - no nexthops isn't very useful */
|
/* Whoops - no nexthops isn't very useful for install */
|
||||||
if (i == 0)
|
if (i == 0 && install_p)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
zl.nexthop_num = i;
|
zl.nexthop_num = i;
|
||||||
|
|
||||||
|
/* Add optional backup nexthop info. Since these are used by index,
|
||||||
|
* we can't just skip over an invalid backup nexthop: we will
|
||||||
|
* invalidate the entire operation.
|
||||||
|
*/
|
||||||
|
if (backup_nhg != NULL) {
|
||||||
|
i = 0;
|
||||||
|
for (ALL_NEXTHOPS_PTR(backup_nhg, nh)) {
|
||||||
|
znh = &zl.backup_nexthops[i];
|
||||||
|
|
||||||
|
/* Must have labels to be useful */
|
||||||
|
if (nh->nh_label == NULL ||
|
||||||
|
nh->nh_label->num_labels == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (nh->type == NEXTHOP_TYPE_IFINDEX ||
|
||||||
|
nh->type == NEXTHOP_TYPE_BLACKHOLE)
|
||||||
|
/* Hmm - can't really deal with these types */
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ret = zapi_nexthop_from_nexthop(znh, nh);
|
||||||
|
if (ret < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i > 0)
|
||||||
|
SET_FLAG(zl.message, ZAPI_LABELS_HAS_BACKUPS);
|
||||||
|
|
||||||
|
zl.backup_nexthop_num = i;
|
||||||
|
}
|
||||||
|
|
||||||
if (install_p)
|
if (install_p)
|
||||||
ret = zebra_send_mpls_labels(zclient, ZEBRA_MPLS_LABELS_ADD,
|
ret = zebra_send_mpls_labels(zclient, ZEBRA_MPLS_LABELS_ADD,
|
||||||
&zl);
|
&zl);
|
||||||
|
|
|
@ -42,5 +42,7 @@ extern void sharp_remove_routes_helper(struct prefix *p, vrf_id_t vrf_id,
|
||||||
|
|
||||||
int sharp_install_lsps_helper(bool install_p, const struct prefix *p,
|
int sharp_install_lsps_helper(bool install_p, const struct prefix *p,
|
||||||
uint8_t type, int instance, uint32_t in_label,
|
uint8_t type, int instance, uint32_t in_label,
|
||||||
const struct nexthop_group *nhg);
|
const struct nexthop_group *nhg,
|
||||||
|
const struct nexthop_group *backup_nhg);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue