mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-05 13:21:22 +00:00
zebra: remove 'static' lsp objects
Use the same lsp and nexthop/nhlfe objects for 'static' and dynamic LSPs; remove the 'static' objects and their supporting code. Signed-off-by: Mark Stapp <mjs@voltanet.io>
This commit is contained in:
parent
0405eff37a
commit
608a57c08b
@ -52,10 +52,7 @@
|
||||
|
||||
DEFINE_MTYPE_STATIC(ZEBRA, LSP, "MPLS LSP object")
|
||||
DEFINE_MTYPE_STATIC(ZEBRA, FEC, "MPLS FEC object")
|
||||
DEFINE_MTYPE_STATIC(ZEBRA, SLSP, "MPLS static LSP config")
|
||||
DEFINE_MTYPE_STATIC(ZEBRA, NHLFE, "MPLS nexthop object")
|
||||
DEFINE_MTYPE_STATIC(ZEBRA, SNHLFE, "MPLS static nexthop object")
|
||||
DEFINE_MTYPE_STATIC(ZEBRA, SNHLFE_IFNAME, "MPLS static nexthop ifname")
|
||||
|
||||
int mpls_enabled;
|
||||
|
||||
@ -101,7 +98,8 @@ static void lsp_check_free(struct hash *lsp_table, zebra_lsp_t **plsp);
|
||||
/* Free lsp; sets caller's pointer to NULL */
|
||||
static void lsp_free(struct hash *lsp_table, zebra_lsp_t **plsp);
|
||||
|
||||
static char *nhlfe2str(zebra_nhlfe_t *nhlfe, char *buf, int size);
|
||||
static char *nhlfe2str(const zebra_nhlfe_t *nhlfe, char *buf, int size);
|
||||
static char *nhlfe_config_str(const zebra_nhlfe_t *nhlfe, char *buf, int size);
|
||||
static int nhlfe_nhop_match(zebra_nhlfe_t *nhlfe, enum nexthop_types_t gtype,
|
||||
const union g_addr *gate, ifindex_t ifindex);
|
||||
static zebra_nhlfe_t *nhlfe_find(struct nhlfe_list_head *list,
|
||||
@ -124,19 +122,6 @@ static int mpls_static_lsp_uninstall_all(struct zebra_vrf *zvrf,
|
||||
static void nhlfe_print(zebra_nhlfe_t *nhlfe, struct vty *vty,
|
||||
const char *indent);
|
||||
static void lsp_print(struct vty *vty, zebra_lsp_t *lsp);
|
||||
static void *slsp_alloc(void *p);
|
||||
static int snhlfe_match(zebra_snhlfe_t *snhlfe, enum nexthop_types_t gtype,
|
||||
const union g_addr *gate, ifindex_t ifindex);
|
||||
static zebra_snhlfe_t *snhlfe_find(zebra_slsp_t *slsp,
|
||||
enum nexthop_types_t gtype,
|
||||
const union g_addr *gate, ifindex_t ifindex);
|
||||
static zebra_snhlfe_t *snhlfe_add(zebra_slsp_t *slsp,
|
||||
enum nexthop_types_t gtype,
|
||||
const union g_addr *gate, ifindex_t ifindex,
|
||||
mpls_label_t out_label);
|
||||
static int snhlfe_del(zebra_snhlfe_t *snhlfe);
|
||||
static int snhlfe_del_all(zebra_slsp_t *slsp);
|
||||
static char *snhlfe2str(zebra_snhlfe_t *snhlfe, char *buf, int size);
|
||||
static void mpls_lsp_uninstall_all_type(struct hash_bucket *bucket, void *ctxt);
|
||||
static void mpls_ftn_uninstall_all(struct zebra_vrf *zvrf,
|
||||
int afi, enum lsp_types_t lsp_type);
|
||||
@ -145,9 +130,6 @@ static int lsp_znh_install(zebra_lsp_t *lsp, enum lsp_types_t type,
|
||||
static int lsp_backup_znh_install(zebra_lsp_t *lsp, enum lsp_types_t type,
|
||||
const struct zapi_nexthop *znh);
|
||||
|
||||
/* List implementations - declare internal linkage */
|
||||
DECLARE_DLIST(snhlfe_list, struct zebra_snhlfe_t_, list);
|
||||
|
||||
/* Static functions */
|
||||
|
||||
/*
|
||||
@ -1173,9 +1155,9 @@ static void lsp_free(struct hash *lsp_table, zebra_lsp_t **plsp)
|
||||
/*
|
||||
* Create printable string for NHLFE entry.
|
||||
*/
|
||||
static char *nhlfe2str(zebra_nhlfe_t *nhlfe, char *buf, int size)
|
||||
static char *nhlfe2str(const zebra_nhlfe_t *nhlfe, char *buf, int size)
|
||||
{
|
||||
struct nexthop *nexthop;
|
||||
const struct nexthop *nexthop;
|
||||
|
||||
buf[0] = '\0';
|
||||
nexthop = nhlfe->nexthop;
|
||||
@ -1414,7 +1396,7 @@ static int mpls_lsp_uninstall_all(struct hash *lsp_table, zebra_lsp_t *lsp,
|
||||
continue;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_MPLS) {
|
||||
nhlfe2str(nhlfe, buf, BUFSIZ);
|
||||
nhlfe2str(nhlfe, buf, sizeof(buf));
|
||||
zlog_debug(
|
||||
"Del LSP in-label %u type %d nexthop %s flags 0x%x",
|
||||
lsp->ile.in_label, type, buf, nhlfe->flags);
|
||||
@ -1435,7 +1417,7 @@ static int mpls_lsp_uninstall_all(struct hash *lsp_table, zebra_lsp_t *lsp,
|
||||
continue;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_MPLS) {
|
||||
nhlfe2str(nhlfe, buf, BUFSIZ);
|
||||
nhlfe2str(nhlfe, buf, sizeof(buf));
|
||||
zlog_debug(
|
||||
"Del backup LSP in-label %u type %d nexthop %s flags 0x%x",
|
||||
lsp->ile.in_label, type, buf, nhlfe->flags);
|
||||
@ -1710,188 +1692,6 @@ static int lsp_cmp(const zebra_lsp_t *lsp1, const zebra_lsp_t *lsp2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback to allocate static LSP.
|
||||
*/
|
||||
static void *slsp_alloc(void *p)
|
||||
{
|
||||
const zebra_ile_t *ile = p;
|
||||
zebra_slsp_t *slsp;
|
||||
|
||||
slsp = XCALLOC(MTYPE_SLSP, sizeof(zebra_slsp_t));
|
||||
slsp->ile = *ile;
|
||||
snhlfe_list_init(&slsp->snhlfe_list);
|
||||
|
||||
return ((void *)slsp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare two static LSPs based on their label values.
|
||||
*/
|
||||
static int slsp_cmp(const zebra_slsp_t *slsp1, const zebra_slsp_t *slsp2)
|
||||
{
|
||||
if (slsp1->ile.in_label < slsp2->ile.in_label)
|
||||
return -1;
|
||||
|
||||
if (slsp1->ile.in_label > slsp2->ile.in_label)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if static NHLFE matches with search info passed.
|
||||
*/
|
||||
static int snhlfe_match(zebra_snhlfe_t *snhlfe, enum nexthop_types_t gtype,
|
||||
const union g_addr *gate, ifindex_t ifindex)
|
||||
{
|
||||
int cmp = 1;
|
||||
|
||||
if (snhlfe->gtype != gtype)
|
||||
return 1;
|
||||
|
||||
switch (snhlfe->gtype) {
|
||||
case NEXTHOP_TYPE_IPV4:
|
||||
cmp = memcmp(&(snhlfe->gate.ipv4), &(gate->ipv4),
|
||||
sizeof(struct in_addr));
|
||||
break;
|
||||
case NEXTHOP_TYPE_IPV6:
|
||||
case NEXTHOP_TYPE_IPV6_IFINDEX:
|
||||
cmp = memcmp(&(snhlfe->gate.ipv6), &(gate->ipv6),
|
||||
sizeof(struct in6_addr));
|
||||
if (!cmp && snhlfe->gtype == NEXTHOP_TYPE_IPV6_IFINDEX)
|
||||
cmp = !(snhlfe->ifindex == ifindex);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return cmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Locate static NHLFE that matches with passed info.
|
||||
*/
|
||||
static zebra_snhlfe_t *snhlfe_find(zebra_slsp_t *slsp,
|
||||
enum nexthop_types_t gtype,
|
||||
const union g_addr *gate, ifindex_t ifindex)
|
||||
{
|
||||
zebra_snhlfe_t *snhlfe;
|
||||
|
||||
if (!slsp)
|
||||
return NULL;
|
||||
|
||||
frr_each_safe(snhlfe_list, &slsp->snhlfe_list, snhlfe) {
|
||||
if (!snhlfe_match(snhlfe, gtype, gate, ifindex))
|
||||
break;
|
||||
}
|
||||
|
||||
return snhlfe;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Add static NHLFE. Base LSP config entry must have been created
|
||||
* and duplicate check done.
|
||||
*/
|
||||
static zebra_snhlfe_t *snhlfe_add(zebra_slsp_t *slsp,
|
||||
enum nexthop_types_t gtype,
|
||||
const union g_addr *gate, ifindex_t ifindex,
|
||||
mpls_label_t out_label)
|
||||
{
|
||||
zebra_snhlfe_t *snhlfe;
|
||||
|
||||
if (!slsp)
|
||||
return NULL;
|
||||
|
||||
snhlfe = XCALLOC(MTYPE_SNHLFE, sizeof(zebra_snhlfe_t));
|
||||
snhlfe->slsp = slsp;
|
||||
snhlfe->out_label = out_label;
|
||||
snhlfe->gtype = gtype;
|
||||
switch (gtype) {
|
||||
case NEXTHOP_TYPE_IPV4:
|
||||
snhlfe->gate.ipv4 = gate->ipv4;
|
||||
break;
|
||||
case NEXTHOP_TYPE_IPV6:
|
||||
case NEXTHOP_TYPE_IPV6_IFINDEX:
|
||||
snhlfe->gate.ipv6 = gate->ipv6;
|
||||
if (ifindex)
|
||||
snhlfe->ifindex = ifindex;
|
||||
break;
|
||||
default:
|
||||
XFREE(MTYPE_SNHLFE, snhlfe);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
snhlfe_list_add_head(&slsp->snhlfe_list, snhlfe);
|
||||
|
||||
return snhlfe;
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete static NHLFE. Entry must be present on list.
|
||||
*/
|
||||
static int snhlfe_del(zebra_snhlfe_t *snhlfe)
|
||||
{
|
||||
zebra_slsp_t *slsp;
|
||||
|
||||
if (!snhlfe)
|
||||
return -1;
|
||||
|
||||
slsp = snhlfe->slsp;
|
||||
if (!slsp)
|
||||
return -1;
|
||||
|
||||
snhlfe_list_del(&slsp->snhlfe_list, snhlfe);
|
||||
|
||||
XFREE(MTYPE_SNHLFE_IFNAME, snhlfe->ifname);
|
||||
XFREE(MTYPE_SNHLFE, snhlfe);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete all static NHLFE entries for this LSP (in label).
|
||||
*/
|
||||
static int snhlfe_del_all(zebra_slsp_t *slsp)
|
||||
{
|
||||
zebra_snhlfe_t *snhlfe;
|
||||
|
||||
if (!slsp)
|
||||
return -1;
|
||||
|
||||
frr_each_safe(snhlfe_list, &slsp->snhlfe_list, snhlfe) {
|
||||
snhlfe_del(snhlfe);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create printable string for NHLFE configuration.
|
||||
*/
|
||||
static char *snhlfe2str(zebra_snhlfe_t *snhlfe, char *buf, int size)
|
||||
{
|
||||
buf[0] = '\0';
|
||||
switch (snhlfe->gtype) {
|
||||
case NEXTHOP_TYPE_IPV4:
|
||||
inet_ntop(AF_INET, &snhlfe->gate.ipv4, buf, size);
|
||||
break;
|
||||
case NEXTHOP_TYPE_IPV6:
|
||||
case NEXTHOP_TYPE_IPV6_IFINDEX:
|
||||
inet_ntop(AF_INET6, &snhlfe->gate.ipv6, buf, size);
|
||||
if (snhlfe->ifindex)
|
||||
strlcat(buf,
|
||||
ifindex2ifname(snhlfe->ifindex, VRF_DEFAULT),
|
||||
size);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize work queue for processing changed LSPs.
|
||||
*/
|
||||
@ -3633,8 +3433,9 @@ int zebra_mpls_lsp_label_consistent(struct zebra_vrf *zvrf,
|
||||
{
|
||||
struct hash *slsp_table;
|
||||
zebra_ile_t tmp_ile;
|
||||
zebra_slsp_t *slsp;
|
||||
zebra_snhlfe_t *snhlfe;
|
||||
zebra_lsp_t *lsp;
|
||||
zebra_nhlfe_t *nhlfe;
|
||||
const struct nexthop *nh;
|
||||
|
||||
/* Lookup table. */
|
||||
slsp_table = zvrf->slsp_table;
|
||||
@ -3643,26 +3444,37 @@ int zebra_mpls_lsp_label_consistent(struct zebra_vrf *zvrf,
|
||||
|
||||
/* If entry is not present, exit. */
|
||||
tmp_ile.in_label = in_label;
|
||||
slsp = hash_lookup(slsp_table, &tmp_ile);
|
||||
if (!slsp)
|
||||
lsp = hash_lookup(slsp_table, &tmp_ile);
|
||||
if (!lsp)
|
||||
return 1;
|
||||
|
||||
snhlfe = snhlfe_find(slsp, gtype, gate, ifindex);
|
||||
if (snhlfe) {
|
||||
if (snhlfe->out_label == out_label)
|
||||
nhlfe = nhlfe_find(&lsp->nhlfe_list, ZEBRA_LSP_STATIC,
|
||||
gtype, gate, ifindex);
|
||||
if (nhlfe) {
|
||||
nh = nhlfe->nexthop;
|
||||
|
||||
if (nh == NULL || nh->nh_label == NULL)
|
||||
return 0;
|
||||
|
||||
if (nh->nh_label->label[0] == out_label)
|
||||
return 1;
|
||||
|
||||
/* If not only NHLFE, cannot allow label change. */
|
||||
if (snhlfe != snhlfe_list_first(&slsp->snhlfe_list) ||
|
||||
snhlfe_list_next(&slsp->snhlfe_list, snhlfe) != NULL)
|
||||
if (nhlfe != nhlfe_list_first(&lsp->nhlfe_list) ||
|
||||
nhlfe_list_next(&lsp->nhlfe_list, nhlfe) != NULL)
|
||||
return 0;
|
||||
} else {
|
||||
/* If other NHLFEs exist, label operation must match. */
|
||||
snhlfe = snhlfe_list_first(&slsp->snhlfe_list);
|
||||
if (snhlfe != NULL) {
|
||||
nhlfe = nhlfe_list_first(&lsp->nhlfe_list);
|
||||
if (nhlfe != NULL) {
|
||||
int cur_op, new_op;
|
||||
|
||||
cur_op = (snhlfe->out_label ==
|
||||
nh = nhlfe->nexthop;
|
||||
|
||||
if (nh == NULL || nh->nh_label == NULL)
|
||||
return 0;
|
||||
|
||||
cur_op = (nh->nh_label->label[0] ==
|
||||
MPLS_LABEL_IMPLICIT_NULL);
|
||||
new_op = (out_label == MPLS_LABEL_IMPLICIT_NULL);
|
||||
if (cur_op != new_op)
|
||||
@ -3689,8 +3501,8 @@ int zebra_mpls_static_lsp_add(struct zebra_vrf *zvrf, mpls_label_t in_label,
|
||||
{
|
||||
struct hash *slsp_table;
|
||||
zebra_ile_t tmp_ile;
|
||||
zebra_slsp_t *slsp;
|
||||
zebra_snhlfe_t *snhlfe;
|
||||
zebra_lsp_t *lsp;
|
||||
zebra_nhlfe_t *nhlfe;
|
||||
char buf[BUFSIZ];
|
||||
|
||||
/* Lookup table. */
|
||||
@ -3700,31 +3512,47 @@ int zebra_mpls_static_lsp_add(struct zebra_vrf *zvrf, mpls_label_t in_label,
|
||||
|
||||
/* Find or create LSP. */
|
||||
tmp_ile.in_label = in_label;
|
||||
slsp = hash_get(slsp_table, &tmp_ile, slsp_alloc);
|
||||
if (!slsp)
|
||||
lsp = hash_get(slsp_table, &tmp_ile, lsp_alloc);
|
||||
if (!lsp)
|
||||
return -1;
|
||||
|
||||
snhlfe = snhlfe_find(slsp, gtype, gate, ifindex);
|
||||
if (snhlfe) {
|
||||
if (snhlfe->out_label == out_label)
|
||||
nhlfe = nhlfe_find(&lsp->nhlfe_list, ZEBRA_LSP_STATIC, gtype, gate,
|
||||
ifindex);
|
||||
if (nhlfe) {
|
||||
struct nexthop *nh = nhlfe->nexthop;
|
||||
|
||||
assert(nh);
|
||||
assert(nh->nh_label);
|
||||
|
||||
/* Compare existing nexthop */
|
||||
if (nh->nh_label->num_labels == 1 &&
|
||||
nh->nh_label->label[0] == out_label)
|
||||
/* No change */
|
||||
return 0;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_MPLS) {
|
||||
snhlfe2str(snhlfe, buf, sizeof(buf));
|
||||
nhlfe2str(nhlfe, buf, sizeof(buf));
|
||||
zlog_debug(
|
||||
"Upd static LSP in-label %u nexthop %s out-label %u (old %u)",
|
||||
in_label, buf, out_label, snhlfe->out_label);
|
||||
in_label, buf, out_label,
|
||||
nh->nh_label->label[0]);
|
||||
}
|
||||
snhlfe->out_label = out_label;
|
||||
if (nh->nh_label->num_labels == 1)
|
||||
nh->nh_label->label[0] = out_label;
|
||||
else {
|
||||
nexthop_del_labels(nh);
|
||||
nexthop_add_labels(nh, ZEBRA_LSP_STATIC, 1, &out_label);
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Add static LSP entry to this nexthop */
|
||||
snhlfe = snhlfe_add(slsp, gtype, gate, ifindex, out_label);
|
||||
if (!snhlfe)
|
||||
nhlfe = nhlfe_add(lsp, ZEBRA_LSP_STATIC, gtype, gate,
|
||||
ifindex, 1, &out_label, false /*backup*/);
|
||||
if (!nhlfe)
|
||||
return -1;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_MPLS) {
|
||||
snhlfe2str(snhlfe, buf, sizeof(buf));
|
||||
nhlfe2str(nhlfe, buf, sizeof(buf));
|
||||
zlog_debug(
|
||||
"Add static LSP in-label %u nexthop %s out-label %u",
|
||||
in_label, buf, out_label);
|
||||
@ -3752,8 +3580,8 @@ int zebra_mpls_static_lsp_del(struct zebra_vrf *zvrf, mpls_label_t in_label,
|
||||
{
|
||||
struct hash *slsp_table;
|
||||
zebra_ile_t tmp_ile;
|
||||
zebra_slsp_t *slsp;
|
||||
zebra_snhlfe_t *snhlfe;
|
||||
zebra_lsp_t *lsp;
|
||||
zebra_nhlfe_t *nhlfe;
|
||||
|
||||
/* Lookup table. */
|
||||
slsp_table = zvrf->slsp_table;
|
||||
@ -3762,8 +3590,8 @@ int zebra_mpls_static_lsp_del(struct zebra_vrf *zvrf, mpls_label_t in_label,
|
||||
|
||||
/* If entry is not present, exit. */
|
||||
tmp_ile.in_label = in_label;
|
||||
slsp = hash_lookup(slsp_table, &tmp_ile);
|
||||
if (!slsp)
|
||||
lsp = hash_lookup(slsp_table, &tmp_ile);
|
||||
if (!lsp)
|
||||
return 0;
|
||||
|
||||
/* Is it delete of entire LSP or a specific NHLFE? */
|
||||
@ -3775,16 +3603,19 @@ int zebra_mpls_static_lsp_del(struct zebra_vrf *zvrf, mpls_label_t in_label,
|
||||
mpls_static_lsp_uninstall_all(zvrf, in_label);
|
||||
|
||||
/* Delete all static NHLFEs */
|
||||
snhlfe_del_all(slsp);
|
||||
frr_each_safe(nhlfe_list, &lsp->nhlfe_list, nhlfe) {
|
||||
nhlfe_del(nhlfe);
|
||||
}
|
||||
} else {
|
||||
/* Find specific NHLFE, exit if not found. */
|
||||
snhlfe = snhlfe_find(slsp, gtype, gate, ifindex);
|
||||
if (!snhlfe)
|
||||
nhlfe = nhlfe_find(&lsp->nhlfe_list, ZEBRA_LSP_STATIC,
|
||||
gtype, gate, ifindex);
|
||||
if (!nhlfe)
|
||||
return 0;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_MPLS) {
|
||||
char buf[BUFSIZ];
|
||||
snhlfe2str(snhlfe, buf, BUFSIZ);
|
||||
nhlfe2str(nhlfe, buf, sizeof(buf));
|
||||
zlog_debug("Del static LSP in-label %u nexthop %s",
|
||||
in_label, buf);
|
||||
}
|
||||
@ -3794,14 +3625,15 @@ int zebra_mpls_static_lsp_del(struct zebra_vrf *zvrf, mpls_label_t in_label,
|
||||
gate, ifindex, false);
|
||||
|
||||
/* Delete static LSP NHLFE */
|
||||
snhlfe_del(snhlfe);
|
||||
nhlfe_del(nhlfe);
|
||||
}
|
||||
|
||||
/* Remove entire static LSP entry if no NHLFE - valid in either case
|
||||
* above. */
|
||||
if (snhlfe_list_first(&slsp->snhlfe_list) == NULL) {
|
||||
slsp = hash_release(slsp_table, &tmp_ile);
|
||||
XFREE(MTYPE_SLSP, slsp);
|
||||
* above.
|
||||
*/
|
||||
if (nhlfe_list_first(&lsp->nhlfe_list) == NULL) {
|
||||
lsp = hash_release(slsp_table, &tmp_ile);
|
||||
XFREE(MTYPE_LSP, lsp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -3948,24 +3780,59 @@ void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf,
|
||||
list_delete(&lsp_list);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create printable string for static LSP configuration.
|
||||
*/
|
||||
static char *nhlfe_config_str(const zebra_nhlfe_t *nhlfe, char *buf, int size)
|
||||
{
|
||||
const struct nexthop *nh;
|
||||
|
||||
nh = nhlfe->nexthop;
|
||||
|
||||
buf[0] = '\0';
|
||||
switch (nh->type) {
|
||||
case NEXTHOP_TYPE_IPV4:
|
||||
inet_ntop(AF_INET, &nh->gate.ipv4, buf, size);
|
||||
break;
|
||||
case NEXTHOP_TYPE_IPV6:
|
||||
case NEXTHOP_TYPE_IPV6_IFINDEX:
|
||||
inet_ntop(AF_INET6, &nh->gate.ipv6, buf, size);
|
||||
if (nh->ifindex)
|
||||
strlcat(buf,
|
||||
ifindex2ifname(nh->ifindex, VRF_DEFAULT),
|
||||
size);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* Display MPLS LSP configuration of all static LSPs (VTY command handler).
|
||||
*/
|
||||
int zebra_mpls_write_lsp_config(struct vty *vty, struct zebra_vrf *zvrf)
|
||||
{
|
||||
zebra_slsp_t *slsp;
|
||||
zebra_snhlfe_t *snhlfe;
|
||||
zebra_lsp_t *lsp;
|
||||
zebra_nhlfe_t *nhlfe;
|
||||
struct nexthop *nh;
|
||||
struct listnode *node;
|
||||
struct list *slsp_list =
|
||||
hash_get_sorted_list(zvrf->slsp_table, slsp_cmp);
|
||||
hash_get_sorted_list(zvrf->slsp_table, lsp_cmp);
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(slsp_list, node, slsp)) {
|
||||
frr_each(snhlfe_list, &slsp->snhlfe_list, snhlfe) {
|
||||
for (ALL_LIST_ELEMENTS_RO(slsp_list, node, lsp)) {
|
||||
frr_each(nhlfe_list, &lsp->nhlfe_list, nhlfe) {
|
||||
char buf[BUFSIZ];
|
||||
char lstr[30];
|
||||
|
||||
snhlfe2str(snhlfe, buf, sizeof(buf));
|
||||
switch (snhlfe->out_label) {
|
||||
nh = nhlfe->nexthop;
|
||||
if (nh == NULL || nh->nh_label == NULL)
|
||||
continue;
|
||||
|
||||
nhlfe_config_str(nhlfe, buf, sizeof(buf));
|
||||
|
||||
switch (nh->nh_label->label[0]) {
|
||||
case MPLS_LABEL_IPV4_EXPLICIT_NULL:
|
||||
case MPLS_LABEL_IPV6_EXPLICIT_NULL:
|
||||
strlcpy(lstr, "explicit-null", sizeof(lstr));
|
||||
@ -3975,11 +3842,11 @@ int zebra_mpls_write_lsp_config(struct vty *vty, struct zebra_vrf *zvrf)
|
||||
break;
|
||||
default:
|
||||
snprintf(lstr, sizeof(lstr), "%u",
|
||||
snhlfe->out_label);
|
||||
nh->nh_label->label[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
vty_out(vty, "mpls lsp %u %s %s\n", slsp->ile.in_label,
|
||||
vty_out(vty, "mpls lsp %u %s %s\n", lsp->ile.in_label,
|
||||
buf, lstr);
|
||||
}
|
||||
}
|
||||
|
@ -50,36 +50,13 @@ extern "C" {
|
||||
/* Typedefs */
|
||||
|
||||
typedef struct zebra_ile_t_ zebra_ile_t;
|
||||
typedef struct zebra_snhlfe_t_ zebra_snhlfe_t;
|
||||
typedef struct zebra_slsp_t_ zebra_slsp_t;
|
||||
typedef struct zebra_nhlfe_t_ zebra_nhlfe_t;
|
||||
typedef struct zebra_lsp_t_ zebra_lsp_t;
|
||||
typedef struct zebra_fec_t_ zebra_fec_t;
|
||||
|
||||
/* Declare LSP nexthop list types */
|
||||
PREDECL_DLIST(snhlfe_list);
|
||||
PREDECL_DLIST(nhlfe_list);
|
||||
|
||||
/*
|
||||
* (Outgoing) nexthop label forwarding entry configuration
|
||||
*/
|
||||
struct zebra_snhlfe_t_ {
|
||||
/* Nexthop information */
|
||||
enum nexthop_types_t gtype;
|
||||
union g_addr gate;
|
||||
char *ifname;
|
||||
ifindex_t ifindex;
|
||||
|
||||
/* Out label. */
|
||||
mpls_label_t out_label;
|
||||
|
||||
/* Backpointer to base entry. */
|
||||
zebra_slsp_t *slsp;
|
||||
|
||||
/* Linkage for LSPs' lists */
|
||||
struct snhlfe_list_item list;
|
||||
};
|
||||
|
||||
/*
|
||||
* (Outgoing) nexthop label forwarding entry
|
||||
*/
|
||||
@ -115,17 +92,6 @@ struct zebra_ile_t_ {
|
||||
mpls_label_t in_label;
|
||||
};
|
||||
|
||||
/*
|
||||
* Label swap entry static configuration.
|
||||
*/
|
||||
struct zebra_slsp_t_ {
|
||||
/* Incoming label */
|
||||
zebra_ile_t ile;
|
||||
|
||||
/* List of outgoing nexthop static configuration */
|
||||
struct snhlfe_list_head snhlfe_list;
|
||||
};
|
||||
|
||||
/*
|
||||
* Label swap entry (ile -> list of nhlfes)
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user