Merge pull request #7258 from mjstapp/zebra_remove_slsp

zebra: remove 'static' lsp objects
This commit is contained in:
Donald Sharp 2020-10-13 15:51:18 -04:00 committed by GitHub
commit 82b4a8bf2c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 120 additions and 287 deletions

View File

@ -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);
}
}

View File

@ -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)
*/