mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-15 09:20:25 +00:00
zebra: convert LSP nhlfe lists to use typesafe lists
Convert the embedded lists of nhlfes and snhlfes in zebra LSPs and SLSPs to use typesafe dlists. Signed-off-by: Mark Stapp <mjs@voltanet.io>
This commit is contained in:
parent
55add95cd7
commit
ee70f62979
@ -3504,6 +3504,7 @@ enum zebra_dplane_result kernel_neigh_update_ctx(struct zebra_dplane_ctx *ctx)
|
|||||||
int netlink_mpls_multipath(int cmd, struct zebra_dplane_ctx *ctx)
|
int netlink_mpls_multipath(int cmd, struct zebra_dplane_ctx *ctx)
|
||||||
{
|
{
|
||||||
mpls_lse_t lse;
|
mpls_lse_t lse;
|
||||||
|
const struct nhlfe_list_head *head;
|
||||||
const zebra_nhlfe_t *nhlfe;
|
const zebra_nhlfe_t *nhlfe;
|
||||||
struct nexthop *nexthop = NULL;
|
struct nexthop *nexthop = NULL;
|
||||||
unsigned int nexthop_num;
|
unsigned int nexthop_num;
|
||||||
@ -3524,7 +3525,8 @@ int netlink_mpls_multipath(int cmd, struct zebra_dplane_ctx *ctx)
|
|||||||
* or multipath case.
|
* or multipath case.
|
||||||
*/
|
*/
|
||||||
nexthop_num = 0;
|
nexthop_num = 0;
|
||||||
for (nhlfe = dplane_ctx_get_nhlfe(ctx); nhlfe; nhlfe = nhlfe->next) {
|
head = dplane_ctx_get_nhlfe_list(ctx);
|
||||||
|
frr_each(nhlfe_list_const, head, nhlfe) {
|
||||||
nexthop = nhlfe->nexthop;
|
nexthop = nhlfe->nexthop;
|
||||||
if (!nexthop)
|
if (!nexthop)
|
||||||
continue;
|
continue;
|
||||||
@ -3579,8 +3581,7 @@ int netlink_mpls_multipath(int cmd, struct zebra_dplane_ctx *ctx)
|
|||||||
routedesc);
|
routedesc);
|
||||||
|
|
||||||
nexthop_num = 0;
|
nexthop_num = 0;
|
||||||
for (nhlfe = dplane_ctx_get_nhlfe(ctx);
|
frr_each(nhlfe_list_const, head, nhlfe) {
|
||||||
nhlfe; nhlfe = nhlfe->next) {
|
|
||||||
nexthop = nhlfe->nexthop;
|
nexthop = nhlfe->nexthop;
|
||||||
if (!nexthop)
|
if (!nexthop)
|
||||||
continue;
|
continue;
|
||||||
@ -3618,8 +3619,7 @@ int netlink_mpls_multipath(int cmd, struct zebra_dplane_ctx *ctx)
|
|||||||
routedesc);
|
routedesc);
|
||||||
|
|
||||||
nexthop_num = 0;
|
nexthop_num = 0;
|
||||||
for (nhlfe = dplane_ctx_get_nhlfe(ctx);
|
frr_each(nhlfe_list_const, head, nhlfe) {
|
||||||
nhlfe; nhlfe = nhlfe->next) {
|
|
||||||
nexthop = nhlfe->nexthop;
|
nexthop = nhlfe->nexthop;
|
||||||
if (!nexthop)
|
if (!nexthop)
|
||||||
continue;
|
continue;
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include "zebra/zebra_router.h"
|
#include "zebra/zebra_router.h"
|
||||||
#include "zebra/zebra_dplane.h"
|
#include "zebra/zebra_dplane.h"
|
||||||
#include "zebra/zebra_vxlan_private.h"
|
#include "zebra/zebra_vxlan_private.h"
|
||||||
|
#include "zebra/zebra_mpls.h"
|
||||||
#include "zebra/rt.h"
|
#include "zebra/rt.h"
|
||||||
#include "zebra/debug.h"
|
#include "zebra/debug.h"
|
||||||
|
|
||||||
@ -510,19 +511,16 @@ static void dplane_ctx_free_internal(struct zebra_dplane_ctx *ctx)
|
|||||||
case DPLANE_OP_LSP_DELETE:
|
case DPLANE_OP_LSP_DELETE:
|
||||||
case DPLANE_OP_LSP_NOTIFY:
|
case DPLANE_OP_LSP_NOTIFY:
|
||||||
{
|
{
|
||||||
zebra_nhlfe_t *nhlfe, *next;
|
zebra_nhlfe_t *nhlfe;
|
||||||
|
|
||||||
/* Free allocated NHLFEs */
|
/* Free allocated NHLFEs */
|
||||||
for (nhlfe = ctx->u.lsp.nhlfe_list; nhlfe; nhlfe = next) {
|
frr_each_safe(nhlfe_list, &ctx->u.lsp.nhlfe_list, nhlfe)
|
||||||
next = nhlfe->next;
|
|
||||||
|
|
||||||
zebra_mpls_nhlfe_del(nhlfe);
|
zebra_mpls_nhlfe_del(nhlfe);
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear pointers in lsp struct, in case we're cacheing
|
/* Clear pointers in lsp struct, in case we're cacheing
|
||||||
* free context structs.
|
* free context structs.
|
||||||
*/
|
*/
|
||||||
ctx->u.lsp.nhlfe_list = NULL;
|
nhlfe_list_init(&ctx->u.lsp.nhlfe_list);
|
||||||
ctx->u.lsp.best_nhlfe = NULL;
|
ctx->u.lsp.best_nhlfe = NULL;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -1217,11 +1215,11 @@ void dplane_ctx_set_lsp_flags(struct zebra_dplane_ctx *ctx,
|
|||||||
ctx->u.lsp.flags = flags;
|
ctx->u.lsp.flags = flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
const zebra_nhlfe_t *dplane_ctx_get_nhlfe(const struct zebra_dplane_ctx *ctx)
|
const struct nhlfe_list_head *dplane_ctx_get_nhlfe_list(
|
||||||
|
const struct zebra_dplane_ctx *ctx)
|
||||||
{
|
{
|
||||||
DPLANE_CTX_VALID(ctx);
|
DPLANE_CTX_VALID(ctx);
|
||||||
|
return &(ctx->u.lsp.nhlfe_list);
|
||||||
return ctx->u.lsp.nhlfe_list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
zebra_nhlfe_t *dplane_ctx_add_nhlfe(struct zebra_dplane_ctx *ctx,
|
zebra_nhlfe_t *dplane_ctx_add_nhlfe(struct zebra_dplane_ctx *ctx,
|
||||||
@ -1230,7 +1228,7 @@ zebra_nhlfe_t *dplane_ctx_add_nhlfe(struct zebra_dplane_ctx *ctx,
|
|||||||
union g_addr *gate,
|
union g_addr *gate,
|
||||||
ifindex_t ifindex,
|
ifindex_t ifindex,
|
||||||
uint8_t num_labels,
|
uint8_t num_labels,
|
||||||
mpls_label_t out_labels[])
|
mpls_label_t *out_labels)
|
||||||
{
|
{
|
||||||
zebra_nhlfe_t *nhlfe;
|
zebra_nhlfe_t *nhlfe;
|
||||||
|
|
||||||
@ -1729,13 +1727,14 @@ static int dplane_ctx_lsp_init(struct zebra_dplane_ctx *ctx,
|
|||||||
|
|
||||||
memset(&ctx->u.lsp, 0, sizeof(ctx->u.lsp));
|
memset(&ctx->u.lsp, 0, sizeof(ctx->u.lsp));
|
||||||
|
|
||||||
|
nhlfe_list_init(&(ctx->u.lsp.nhlfe_list));
|
||||||
ctx->u.lsp.ile = lsp->ile;
|
ctx->u.lsp.ile = lsp->ile;
|
||||||
ctx->u.lsp.addr_family = lsp->addr_family;
|
ctx->u.lsp.addr_family = lsp->addr_family;
|
||||||
ctx->u.lsp.num_ecmp = lsp->num_ecmp;
|
ctx->u.lsp.num_ecmp = lsp->num_ecmp;
|
||||||
ctx->u.lsp.flags = lsp->flags;
|
ctx->u.lsp.flags = lsp->flags;
|
||||||
|
|
||||||
/* Copy source LSP's nhlfes, and capture 'best' nhlfe */
|
/* Copy source LSP's nhlfes, and capture 'best' nhlfe */
|
||||||
for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) {
|
frr_each(nhlfe_list, &lsp->nhlfe_list, nhlfe) {
|
||||||
/* Not sure if this is meaningful... */
|
/* Not sure if this is meaningful... */
|
||||||
if (nhlfe->nexthop == NULL)
|
if (nhlfe->nexthop == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
@ -310,14 +310,15 @@ void dplane_ctx_set_addr_family(struct zebra_dplane_ctx *ctx,
|
|||||||
uint32_t dplane_ctx_get_lsp_flags(const struct zebra_dplane_ctx *ctx);
|
uint32_t dplane_ctx_get_lsp_flags(const struct zebra_dplane_ctx *ctx);
|
||||||
void dplane_ctx_set_lsp_flags(struct zebra_dplane_ctx *ctx,
|
void dplane_ctx_set_lsp_flags(struct zebra_dplane_ctx *ctx,
|
||||||
uint32_t flags);
|
uint32_t flags);
|
||||||
const zebra_nhlfe_t *dplane_ctx_get_nhlfe(const struct zebra_dplane_ctx *ctx);
|
const struct nhlfe_list_head *dplane_ctx_get_nhlfe_list(
|
||||||
|
const struct zebra_dplane_ctx *ctx);
|
||||||
zebra_nhlfe_t *dplane_ctx_add_nhlfe(struct zebra_dplane_ctx *ctx,
|
zebra_nhlfe_t *dplane_ctx_add_nhlfe(struct zebra_dplane_ctx *ctx,
|
||||||
enum lsp_types_t lsp_type,
|
enum lsp_types_t lsp_type,
|
||||||
enum nexthop_types_t nh_type,
|
enum nexthop_types_t nh_type,
|
||||||
union g_addr *gate,
|
union g_addr *gate,
|
||||||
ifindex_t ifindex,
|
ifindex_t ifindex,
|
||||||
uint8_t num_labels,
|
uint8_t num_labels,
|
||||||
mpls_label_t out_labels[]);
|
mpls_label_t *out_labels);
|
||||||
|
|
||||||
const zebra_nhlfe_t *dplane_ctx_get_best_nhlfe(
|
const zebra_nhlfe_t *dplane_ctx_get_best_nhlfe(
|
||||||
const struct zebra_dplane_ctx *ctx);
|
const struct zebra_dplane_ctx *ctx);
|
||||||
|
@ -99,7 +99,8 @@ 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(zebra_nhlfe_t *nhlfe, char *buf, int size);
|
||||||
static int nhlfe_nhop_match(zebra_nhlfe_t *nhlfe, enum nexthop_types_t gtype,
|
static int nhlfe_nhop_match(zebra_nhlfe_t *nhlfe, enum nexthop_types_t gtype,
|
||||||
const union g_addr *gate, ifindex_t ifindex);
|
const union g_addr *gate, ifindex_t ifindex);
|
||||||
static zebra_nhlfe_t *nhlfe_find(zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
|
static zebra_nhlfe_t *nhlfe_find(struct nhlfe_list_head *list,
|
||||||
|
enum lsp_types_t lsp_type,
|
||||||
enum nexthop_types_t gtype,
|
enum nexthop_types_t gtype,
|
||||||
const union g_addr *gate, ifindex_t ifindex);
|
const union g_addr *gate, ifindex_t ifindex);
|
||||||
static zebra_nhlfe_t *nhlfe_add(zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
|
static zebra_nhlfe_t *nhlfe_add(zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
|
||||||
@ -132,6 +133,8 @@ static void mpls_lsp_uninstall_all_type(struct hash_bucket *bucket, void *ctxt);
|
|||||||
static void mpls_ftn_uninstall_all(struct zebra_vrf *zvrf,
|
static void mpls_ftn_uninstall_all(struct zebra_vrf *zvrf,
|
||||||
int afi, enum lsp_types_t lsp_type);
|
int afi, enum lsp_types_t lsp_type);
|
||||||
|
|
||||||
|
/* List implementations - declare internal linkage */
|
||||||
|
DECLARE_DLIST(snhlfe_list, struct zebra_snhlfe_t_, list);
|
||||||
|
|
||||||
/* Static functions */
|
/* Static functions */
|
||||||
|
|
||||||
@ -143,7 +146,7 @@ static void clear_nhlfe_installed(zebra_lsp_t *lsp)
|
|||||||
zebra_nhlfe_t *nhlfe;
|
zebra_nhlfe_t *nhlfe;
|
||||||
struct nexthop *nexthop;
|
struct nexthop *nexthop;
|
||||||
|
|
||||||
for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) {
|
frr_each_safe(nhlfe_list, &lsp->nhlfe_list, nhlfe) {
|
||||||
nexthop = nhlfe->nexthop;
|
nexthop = nhlfe->nexthop;
|
||||||
if (!nexthop)
|
if (!nexthop)
|
||||||
continue;
|
continue;
|
||||||
@ -196,7 +199,8 @@ static int lsp_install(struct zebra_vrf *zvrf, mpls_label_t label,
|
|||||||
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
|
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
nhlfe = nhlfe_find(lsp, lsp_type, nexthop->type, &nexthop->gate,
|
nhlfe = nhlfe_find(&lsp->nhlfe_list, lsp_type,
|
||||||
|
nexthop->type, &nexthop->gate,
|
||||||
nexthop->ifindex);
|
nexthop->ifindex);
|
||||||
if (nhlfe) {
|
if (nhlfe) {
|
||||||
/* Clear deleted flag (in case it was set) */
|
/* Clear deleted flag (in case it was set) */
|
||||||
@ -251,7 +255,7 @@ static int lsp_install(struct zebra_vrf *zvrf, mpls_label_t label,
|
|||||||
if (added || changed) {
|
if (added || changed) {
|
||||||
if (lsp_processq_add(lsp))
|
if (lsp_processq_add(lsp))
|
||||||
return -1;
|
return -1;
|
||||||
} else if (!lsp->nhlfe_list
|
} else if ((nhlfe_list_first(&lsp->nhlfe_list) == NULL)
|
||||||
&& !CHECK_FLAG(lsp->flags, LSP_FLAG_SCHEDULED))
|
&& !CHECK_FLAG(lsp->flags, LSP_FLAG_SCHEDULED))
|
||||||
lsp_free(lsp_table, &lsp);
|
lsp_free(lsp_table, &lsp);
|
||||||
|
|
||||||
@ -267,7 +271,7 @@ static int lsp_uninstall(struct zebra_vrf *zvrf, mpls_label_t label)
|
|||||||
struct hash *lsp_table;
|
struct hash *lsp_table;
|
||||||
zebra_ile_t tmp_ile;
|
zebra_ile_t tmp_ile;
|
||||||
zebra_lsp_t *lsp;
|
zebra_lsp_t *lsp;
|
||||||
zebra_nhlfe_t *nhlfe, *nhlfe_next;
|
zebra_nhlfe_t *nhlfe;
|
||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
|
|
||||||
/* Lookup table. */
|
/* Lookup table. */
|
||||||
@ -278,12 +282,11 @@ static int lsp_uninstall(struct zebra_vrf *zvrf, mpls_label_t label)
|
|||||||
/* If entry is not present, exit. */
|
/* If entry is not present, exit. */
|
||||||
tmp_ile.in_label = label;
|
tmp_ile.in_label = label;
|
||||||
lsp = hash_lookup(lsp_table, &tmp_ile);
|
lsp = hash_lookup(lsp_table, &tmp_ile);
|
||||||
if (!lsp || !lsp->nhlfe_list)
|
if (!lsp || (nhlfe_list_first(&lsp->nhlfe_list) == NULL))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Mark NHLFEs for delete or directly delete, as appropriate. */
|
/* Mark NHLFEs for delete or directly delete, as appropriate. */
|
||||||
for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe_next) {
|
frr_each_safe(nhlfe_list, &lsp->nhlfe_list, nhlfe) {
|
||||||
nhlfe_next = nhlfe->next;
|
|
||||||
|
|
||||||
/* Skip static NHLFEs */
|
/* Skip static NHLFEs */
|
||||||
if (nhlfe->type == ZEBRA_LSP_STATIC)
|
if (nhlfe->type == ZEBRA_LSP_STATIC)
|
||||||
@ -308,7 +311,7 @@ static int lsp_uninstall(struct zebra_vrf *zvrf, mpls_label_t label)
|
|||||||
if (CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED)) {
|
if (CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED)) {
|
||||||
if (lsp_processq_add(lsp))
|
if (lsp_processq_add(lsp))
|
||||||
return -1;
|
return -1;
|
||||||
} else if (!lsp->nhlfe_list
|
} else if ((nhlfe_list_first(&lsp->nhlfe_list) == NULL)
|
||||||
&& !CHECK_FLAG(lsp->flags, LSP_FLAG_SCHEDULED))
|
&& !CHECK_FLAG(lsp->flags, LSP_FLAG_SCHEDULED))
|
||||||
lsp_free(lsp_table, &lsp);
|
lsp_free(lsp_table, &lsp);
|
||||||
|
|
||||||
@ -784,7 +787,7 @@ static void lsp_select_best_nhlfe(zebra_lsp_t *lsp)
|
|||||||
* only
|
* only
|
||||||
* concerned with non-deleted NHLFEs.
|
* concerned with non-deleted NHLFEs.
|
||||||
*/
|
*/
|
||||||
for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) {
|
frr_each_safe(nhlfe_list, &lsp->nhlfe_list, nhlfe) {
|
||||||
/* Clear selection flags. */
|
/* Clear selection flags. */
|
||||||
UNSET_FLAG(nhlfe->flags,
|
UNSET_FLAG(nhlfe->flags,
|
||||||
(NHLFE_FLAG_SELECTED | NHLFE_FLAG_MULTIPATH));
|
(NHLFE_FLAG_SELECTED | NHLFE_FLAG_MULTIPATH));
|
||||||
@ -809,7 +812,7 @@ static void lsp_select_best_nhlfe(zebra_lsp_t *lsp)
|
|||||||
* new (uninstalled) NHLFE has been selected, an installed entry that is
|
* new (uninstalled) NHLFE has been selected, an installed entry that is
|
||||||
* still selected has a change or an installed entry is to be removed.
|
* still selected has a change or an installed entry is to be removed.
|
||||||
*/
|
*/
|
||||||
for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) {
|
frr_each(nhlfe_list, &lsp->nhlfe_list, nhlfe) {
|
||||||
int nh_chg, nh_sel, nh_inst;
|
int nh_chg, nh_sel, nh_inst;
|
||||||
|
|
||||||
nexthop = nhlfe->nexthop;
|
nexthop = nhlfe->nexthop;
|
||||||
@ -967,8 +970,7 @@ static wq_item_status lsp_process(struct work_queue *wq, void *data)
|
|||||||
* Any NHLFE that was installed but is not
|
* Any NHLFE that was installed but is not
|
||||||
* selected now needs to have its flags updated.
|
* selected now needs to have its flags updated.
|
||||||
*/
|
*/
|
||||||
for (nhlfe = lsp->nhlfe_list; nhlfe;
|
frr_each_safe(nhlfe_list, &lsp->nhlfe_list, nhlfe) {
|
||||||
nhlfe = nhlfe->next) {
|
|
||||||
nexthop = nhlfe->nexthop;
|
nexthop = nhlfe->nexthop;
|
||||||
if (!nexthop)
|
if (!nexthop)
|
||||||
continue;
|
continue;
|
||||||
@ -1012,7 +1014,7 @@ static void lsp_processq_del(struct work_queue *wq, void *data)
|
|||||||
struct zebra_vrf *zvrf;
|
struct zebra_vrf *zvrf;
|
||||||
zebra_lsp_t *lsp;
|
zebra_lsp_t *lsp;
|
||||||
struct hash *lsp_table;
|
struct hash *lsp_table;
|
||||||
zebra_nhlfe_t *nhlfe, *nhlfe_next;
|
zebra_nhlfe_t *nhlfe;
|
||||||
|
|
||||||
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
||||||
assert(zvrf);
|
assert(zvrf);
|
||||||
@ -1031,13 +1033,12 @@ static void lsp_processq_del(struct work_queue *wq, void *data)
|
|||||||
*/
|
*/
|
||||||
UNSET_FLAG(lsp->flags, LSP_FLAG_SCHEDULED);
|
UNSET_FLAG(lsp->flags, LSP_FLAG_SCHEDULED);
|
||||||
|
|
||||||
for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe_next) {
|
frr_each_safe(nhlfe_list, &lsp->nhlfe_list, nhlfe) {
|
||||||
nhlfe_next = nhlfe->next;
|
|
||||||
if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_DELETED))
|
if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_DELETED))
|
||||||
nhlfe_del(nhlfe);
|
nhlfe_del(nhlfe);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!lsp->nhlfe_list)
|
if (nhlfe_list_first(&lsp->nhlfe_list) == NULL)
|
||||||
lsp_free(lsp_table, &lsp);
|
lsp_free(lsp_table, &lsp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1080,6 +1081,7 @@ static void *lsp_alloc(void *p)
|
|||||||
|
|
||||||
lsp = XCALLOC(MTYPE_LSP, sizeof(zebra_lsp_t));
|
lsp = XCALLOC(MTYPE_LSP, sizeof(zebra_lsp_t));
|
||||||
lsp->ile = *ile;
|
lsp->ile = *ile;
|
||||||
|
nhlfe_list_init(&lsp->nhlfe_list);
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_MPLS)
|
if (IS_ZEBRA_DEBUG_MPLS)
|
||||||
zlog_debug("Alloc LSP in-label %u", lsp->ile.in_label);
|
zlog_debug("Alloc LSP in-label %u", lsp->ile.in_label);
|
||||||
@ -1094,7 +1096,7 @@ static void *lsp_alloc(void *p)
|
|||||||
static void lsp_free(struct hash *lsp_table, zebra_lsp_t **plsp)
|
static void lsp_free(struct hash *lsp_table, zebra_lsp_t **plsp)
|
||||||
{
|
{
|
||||||
zebra_lsp_t *lsp;
|
zebra_lsp_t *lsp;
|
||||||
zebra_nhlfe_t *nhlfe, *nhlfe_next;
|
zebra_nhlfe_t *nhlfe;
|
||||||
|
|
||||||
if (plsp == NULL || *plsp == NULL)
|
if (plsp == NULL || *plsp == NULL)
|
||||||
return;
|
return;
|
||||||
@ -1106,11 +1108,8 @@ static void lsp_free(struct hash *lsp_table, zebra_lsp_t **plsp)
|
|||||||
lsp->ile.in_label, lsp->flags);
|
lsp->ile.in_label, lsp->flags);
|
||||||
|
|
||||||
/* Free nhlfes, if any. */
|
/* Free nhlfes, if any. */
|
||||||
for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe_next) {
|
frr_each_safe(nhlfe_list, &lsp->nhlfe_list, nhlfe)
|
||||||
nhlfe_next = nhlfe->next;
|
|
||||||
|
|
||||||
nhlfe_del(nhlfe);
|
nhlfe_del(nhlfe);
|
||||||
}
|
|
||||||
|
|
||||||
hash_release(lsp_table, &lsp->ile);
|
hash_release(lsp_table, &lsp->ile);
|
||||||
XFREE(MTYPE_LSP, lsp);
|
XFREE(MTYPE_LSP, lsp);
|
||||||
@ -1190,16 +1189,14 @@ static int nhlfe_nhop_match(zebra_nhlfe_t *nhlfe, enum nexthop_types_t gtype,
|
|||||||
/*
|
/*
|
||||||
* Locate NHLFE that matches with passed info.
|
* Locate NHLFE that matches with passed info.
|
||||||
*/
|
*/
|
||||||
static zebra_nhlfe_t *nhlfe_find(zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
|
static zebra_nhlfe_t *nhlfe_find(struct nhlfe_list_head *list,
|
||||||
|
enum lsp_types_t lsp_type,
|
||||||
enum nexthop_types_t gtype,
|
enum nexthop_types_t gtype,
|
||||||
const union g_addr *gate, ifindex_t ifindex)
|
const union g_addr *gate, ifindex_t ifindex)
|
||||||
{
|
{
|
||||||
zebra_nhlfe_t *nhlfe;
|
zebra_nhlfe_t *nhlfe;
|
||||||
|
|
||||||
if (!lsp)
|
frr_each_safe(nhlfe_list, list, nhlfe) {
|
||||||
return NULL;
|
|
||||||
|
|
||||||
for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) {
|
|
||||||
if (nhlfe->type != lsp_type)
|
if (nhlfe->type != lsp_type)
|
||||||
continue;
|
continue;
|
||||||
if (!nhlfe_nhop_match(nhlfe, gtype, gate, ifindex))
|
if (!nhlfe_nhop_match(nhlfe, gtype, gate, ifindex))
|
||||||
@ -1210,13 +1207,21 @@ static zebra_nhlfe_t *nhlfe_find(zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add NHLFE. Base entry must have been created and duplicate
|
* Enqueue nhlfe to lsp - at the head of the list
|
||||||
* check done.
|
|
||||||
*/
|
*/
|
||||||
static zebra_nhlfe_t *nhlfe_add(zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
|
static void nhlfe_enqueue(zebra_lsp_t *lsp, zebra_nhlfe_t *nhlfe)
|
||||||
|
{
|
||||||
|
nhlfe_list_add_head(&lsp->nhlfe_list, nhlfe);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate and init new NHLFE.
|
||||||
|
*/
|
||||||
|
static zebra_nhlfe_t *nhlfe_ctor(zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
|
||||||
enum nexthop_types_t gtype,
|
enum nexthop_types_t gtype,
|
||||||
const union g_addr *gate, ifindex_t ifindex,
|
const union g_addr *gate,
|
||||||
uint8_t num_labels, mpls_label_t labels[])
|
ifindex_t ifindex, uint8_t num_labels,
|
||||||
|
mpls_label_t *labels)
|
||||||
{
|
{
|
||||||
zebra_nhlfe_t *nhlfe;
|
zebra_nhlfe_t *nhlfe;
|
||||||
struct nexthop *nexthop;
|
struct nexthop *nexthop;
|
||||||
@ -1260,12 +1265,32 @@ static zebra_nhlfe_t *nhlfe_add(zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
|
|||||||
XFREE(MTYPE_NHLFE, nhlfe);
|
XFREE(MTYPE_NHLFE, nhlfe);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
nhlfe->nexthop = nexthop;
|
nhlfe->nexthop = nexthop;
|
||||||
if (lsp->nhlfe_list)
|
|
||||||
lsp->nhlfe_list->prev = nhlfe;
|
return nhlfe;
|
||||||
nhlfe->next = lsp->nhlfe_list;
|
}
|
||||||
lsp->nhlfe_list = nhlfe;
|
|
||||||
|
/*
|
||||||
|
* Add NHLFE. Base entry must have been created and duplicate
|
||||||
|
* check done.
|
||||||
|
*/
|
||||||
|
static zebra_nhlfe_t *nhlfe_add(zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
|
||||||
|
enum nexthop_types_t gtype,
|
||||||
|
const union g_addr *gate, ifindex_t ifindex,
|
||||||
|
uint8_t num_labels, mpls_label_t *labels)
|
||||||
|
{
|
||||||
|
zebra_nhlfe_t *nhlfe;
|
||||||
|
|
||||||
|
if (!lsp)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Allocate new object */
|
||||||
|
nhlfe = nhlfe_ctor(lsp, lsp_type, gtype, gate, ifindex, num_labels,
|
||||||
|
labels);
|
||||||
|
|
||||||
|
/* Enqueue to LSP */
|
||||||
|
if (nhlfe)
|
||||||
|
nhlfe_enqueue(lsp, nhlfe);
|
||||||
|
|
||||||
return nhlfe;
|
return nhlfe;
|
||||||
}
|
}
|
||||||
@ -1288,17 +1313,12 @@ static int nhlfe_del(zebra_nhlfe_t *nhlfe)
|
|||||||
if (nhlfe->nexthop)
|
if (nhlfe->nexthop)
|
||||||
nexthop_free(nhlfe->nexthop);
|
nexthop_free(nhlfe->nexthop);
|
||||||
|
|
||||||
/* Unlink from LSP */
|
|
||||||
if (nhlfe->next)
|
|
||||||
nhlfe->next->prev = nhlfe->prev;
|
|
||||||
if (nhlfe->prev)
|
|
||||||
nhlfe->prev->next = nhlfe->next;
|
|
||||||
else
|
|
||||||
lsp->nhlfe_list = nhlfe->next;
|
|
||||||
|
|
||||||
if (nhlfe == lsp->best_nhlfe)
|
if (nhlfe == lsp->best_nhlfe)
|
||||||
lsp->best_nhlfe = NULL;
|
lsp->best_nhlfe = NULL;
|
||||||
|
|
||||||
|
/* Unlink from LSP */
|
||||||
|
nhlfe_list_del(&lsp->nhlfe_list, nhlfe);
|
||||||
|
|
||||||
XFREE(MTYPE_NHLFE, nhlfe);
|
XFREE(MTYPE_NHLFE, nhlfe);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1316,14 +1336,12 @@ static void nhlfe_out_label_update(zebra_nhlfe_t *nhlfe,
|
|||||||
static int mpls_lsp_uninstall_all(struct hash *lsp_table, zebra_lsp_t *lsp,
|
static int mpls_lsp_uninstall_all(struct hash *lsp_table, zebra_lsp_t *lsp,
|
||||||
enum lsp_types_t type)
|
enum lsp_types_t type)
|
||||||
{
|
{
|
||||||
zebra_nhlfe_t *nhlfe, *nhlfe_next;
|
zebra_nhlfe_t *nhlfe;
|
||||||
int schedule_lsp = 0;
|
int schedule_lsp = 0;
|
||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
|
|
||||||
/* Mark NHLFEs for delete or directly delete, as appropriate. */
|
/* Mark NHLFEs for delete or directly delete, as appropriate. */
|
||||||
for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe_next) {
|
frr_each_safe(nhlfe_list, &lsp->nhlfe_list, nhlfe) {
|
||||||
nhlfe_next = nhlfe->next;
|
|
||||||
|
|
||||||
/* Skip non-static NHLFEs */
|
/* Skip non-static NHLFEs */
|
||||||
if (nhlfe->type != type)
|
if (nhlfe->type != type)
|
||||||
continue;
|
continue;
|
||||||
@ -1348,7 +1366,7 @@ static int mpls_lsp_uninstall_all(struct hash *lsp_table, zebra_lsp_t *lsp,
|
|||||||
if (schedule_lsp) {
|
if (schedule_lsp) {
|
||||||
if (lsp_processq_add(lsp))
|
if (lsp_processq_add(lsp))
|
||||||
return -1;
|
return -1;
|
||||||
} else if (!lsp->nhlfe_list
|
} else if ((nhlfe_list_first(&lsp->nhlfe_list) == NULL)
|
||||||
&& !CHECK_FLAG(lsp->flags, LSP_FLAG_SCHEDULED))
|
&& !CHECK_FLAG(lsp->flags, LSP_FLAG_SCHEDULED))
|
||||||
lsp_free(lsp_table, &lsp);
|
lsp_free(lsp_table, &lsp);
|
||||||
|
|
||||||
@ -1374,7 +1392,7 @@ static int mpls_static_lsp_uninstall_all(struct zebra_vrf *zvrf,
|
|||||||
/* If entry is not present, exit. */
|
/* If entry is not present, exit. */
|
||||||
tmp_ile.in_label = in_label;
|
tmp_ile.in_label = in_label;
|
||||||
lsp = hash_lookup(lsp_table, &tmp_ile);
|
lsp = hash_lookup(lsp_table, &tmp_ile);
|
||||||
if (!lsp || !lsp->nhlfe_list)
|
if (!lsp || (nhlfe_list_first(&lsp->nhlfe_list) == NULL))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return mpls_lsp_uninstall_all(lsp_table, lsp, ZEBRA_LSP_STATIC);
|
return mpls_lsp_uninstall_all(lsp_table, lsp, ZEBRA_LSP_STATIC);
|
||||||
@ -1475,7 +1493,7 @@ static void lsp_print(zebra_lsp_t *lsp, void *ctxt)
|
|||||||
CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED) ? " (installed)"
|
CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED) ? " (installed)"
|
||||||
: "");
|
: "");
|
||||||
|
|
||||||
for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next)
|
frr_each(nhlfe_list, &lsp->nhlfe_list, nhlfe)
|
||||||
nhlfe_print(nhlfe, vty);
|
nhlfe_print(nhlfe, vty);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1493,7 +1511,7 @@ static json_object *lsp_json(zebra_lsp_t *lsp)
|
|||||||
if (CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED))
|
if (CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED))
|
||||||
json_object_boolean_true_add(json, "installed");
|
json_object_boolean_true_add(json, "installed");
|
||||||
|
|
||||||
for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next)
|
frr_each(nhlfe_list, &lsp->nhlfe_list, nhlfe)
|
||||||
json_object_array_add(json_nhlfe_list, nhlfe_json(nhlfe));
|
json_object_array_add(json_nhlfe_list, nhlfe_json(nhlfe));
|
||||||
|
|
||||||
json_object_object_add(json, "nexthops", json_nhlfe_list);
|
json_object_object_add(json, "nexthops", json_nhlfe_list);
|
||||||
@ -1541,6 +1559,8 @@ static void *slsp_alloc(void *p)
|
|||||||
|
|
||||||
slsp = XCALLOC(MTYPE_SLSP, sizeof(zebra_slsp_t));
|
slsp = XCALLOC(MTYPE_SLSP, sizeof(zebra_slsp_t));
|
||||||
slsp->ile = *ile;
|
slsp->ile = *ile;
|
||||||
|
snhlfe_list_init(&slsp->snhlfe_list);
|
||||||
|
|
||||||
return ((void *)slsp);
|
return ((void *)slsp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1600,7 +1620,7 @@ static zebra_snhlfe_t *snhlfe_find(zebra_slsp_t *slsp,
|
|||||||
if (!slsp)
|
if (!slsp)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for (snhlfe = slsp->snhlfe_list; snhlfe; snhlfe = snhlfe->next) {
|
frr_each_safe(snhlfe_list, &slsp->snhlfe_list, snhlfe) {
|
||||||
if (!snhlfe_match(snhlfe, gtype, gate, ifindex))
|
if (!snhlfe_match(snhlfe, gtype, gate, ifindex))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1642,10 +1662,7 @@ static zebra_snhlfe_t *snhlfe_add(zebra_slsp_t *slsp,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (slsp->snhlfe_list)
|
snhlfe_list_add_head(&slsp->snhlfe_list, snhlfe);
|
||||||
slsp->snhlfe_list->prev = snhlfe;
|
|
||||||
snhlfe->next = slsp->snhlfe_list;
|
|
||||||
slsp->snhlfe_list = snhlfe;
|
|
||||||
|
|
||||||
return snhlfe;
|
return snhlfe;
|
||||||
}
|
}
|
||||||
@ -1664,14 +1681,8 @@ static int snhlfe_del(zebra_snhlfe_t *snhlfe)
|
|||||||
if (!slsp)
|
if (!slsp)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (snhlfe->next)
|
snhlfe_list_del(&slsp->snhlfe_list, snhlfe);
|
||||||
snhlfe->next->prev = snhlfe->prev;
|
|
||||||
if (snhlfe->prev)
|
|
||||||
snhlfe->prev->next = snhlfe->next;
|
|
||||||
else
|
|
||||||
slsp->snhlfe_list = snhlfe->next;
|
|
||||||
|
|
||||||
snhlfe->prev = snhlfe->next = NULL;
|
|
||||||
XFREE(MTYPE_SNHLFE_IFNAME, snhlfe->ifname);
|
XFREE(MTYPE_SNHLFE_IFNAME, snhlfe->ifname);
|
||||||
XFREE(MTYPE_SNHLFE, snhlfe);
|
XFREE(MTYPE_SNHLFE, snhlfe);
|
||||||
|
|
||||||
@ -1683,13 +1694,12 @@ static int snhlfe_del(zebra_snhlfe_t *snhlfe)
|
|||||||
*/
|
*/
|
||||||
static int snhlfe_del_all(zebra_slsp_t *slsp)
|
static int snhlfe_del_all(zebra_slsp_t *slsp)
|
||||||
{
|
{
|
||||||
zebra_snhlfe_t *snhlfe, *snhlfe_next;
|
zebra_snhlfe_t *snhlfe;
|
||||||
|
|
||||||
if (!slsp)
|
if (!slsp)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
for (snhlfe = slsp->snhlfe_list; snhlfe; snhlfe = snhlfe_next) {
|
frr_each_safe(snhlfe_list, &slsp->snhlfe_list, snhlfe) {
|
||||||
snhlfe_next = snhlfe->next;
|
|
||||||
snhlfe_del(snhlfe);
|
snhlfe_del(snhlfe);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1793,8 +1803,7 @@ void zebra_mpls_lsp_dplane_result(struct zebra_dplane_ctx *ctx)
|
|||||||
if (status == ZEBRA_DPLANE_REQUEST_SUCCESS) {
|
if (status == ZEBRA_DPLANE_REQUEST_SUCCESS) {
|
||||||
/* Update zebra object */
|
/* Update zebra object */
|
||||||
SET_FLAG(lsp->flags, LSP_FLAG_INSTALLED);
|
SET_FLAG(lsp->flags, LSP_FLAG_INSTALLED);
|
||||||
for (nhlfe = lsp->nhlfe_list; nhlfe;
|
frr_each(nhlfe_list, &lsp->nhlfe_list, nhlfe) {
|
||||||
nhlfe = nhlfe->next) {
|
|
||||||
nexthop = nhlfe->nexthop;
|
nexthop = nhlfe->nexthop;
|
||||||
if (!nexthop)
|
if (!nexthop)
|
||||||
continue;
|
continue;
|
||||||
@ -1837,6 +1846,7 @@ void zebra_mpls_process_dplane_notify(struct zebra_dplane_ctx *ctx)
|
|||||||
struct hash *lsp_table;
|
struct hash *lsp_table;
|
||||||
zebra_lsp_t *lsp;
|
zebra_lsp_t *lsp;
|
||||||
zebra_nhlfe_t *nhlfe;
|
zebra_nhlfe_t *nhlfe;
|
||||||
|
const struct nhlfe_list_head *head;
|
||||||
const zebra_nhlfe_t *ctx_nhlfe;
|
const zebra_nhlfe_t *ctx_nhlfe;
|
||||||
struct nexthop *nexthop;
|
struct nexthop *nexthop;
|
||||||
const struct nexthop *ctx_nexthop;
|
const struct nexthop *ctx_nexthop;
|
||||||
@ -1872,7 +1882,8 @@ void zebra_mpls_process_dplane_notify(struct zebra_dplane_ctx *ctx)
|
|||||||
* the existing state of the LSP objects available before making
|
* the existing state of the LSP objects available before making
|
||||||
* any changes.
|
* any changes.
|
||||||
*/
|
*/
|
||||||
for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) {
|
head = dplane_ctx_get_nhlfe_list(ctx);
|
||||||
|
frr_each_safe(nhlfe_list, &lsp->nhlfe_list, nhlfe) {
|
||||||
char buf[NEXTHOP_STRLEN];
|
char buf[NEXTHOP_STRLEN];
|
||||||
|
|
||||||
nexthop = nhlfe->nexthop;
|
nexthop = nhlfe->nexthop;
|
||||||
@ -1883,9 +1894,7 @@ void zebra_mpls_process_dplane_notify(struct zebra_dplane_ctx *ctx)
|
|||||||
start_count++;
|
start_count++;
|
||||||
|
|
||||||
ctx_nexthop = NULL;
|
ctx_nexthop = NULL;
|
||||||
for (ctx_nhlfe = dplane_ctx_get_nhlfe(ctx);
|
frr_each(nhlfe_list_const, head, ctx_nhlfe) {
|
||||||
ctx_nhlfe; ctx_nhlfe = ctx_nhlfe->next) {
|
|
||||||
|
|
||||||
ctx_nexthop = ctx_nhlfe->nexthop;
|
ctx_nexthop = ctx_nhlfe->nexthop;
|
||||||
if (!ctx_nexthop)
|
if (!ctx_nexthop)
|
||||||
continue;
|
continue;
|
||||||
@ -1960,7 +1969,7 @@ void zebra_mpls_process_dplane_notify(struct zebra_dplane_ctx *ctx)
|
|||||||
* Now we take a second pass and bring the zebra
|
* Now we take a second pass and bring the zebra
|
||||||
* nexthop state into sync with the forwarding-plane state.
|
* nexthop state into sync with the forwarding-plane state.
|
||||||
*/
|
*/
|
||||||
for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) {
|
frr_each_safe(nhlfe_list, &lsp->nhlfe_list, nhlfe) {
|
||||||
char buf[NEXTHOP_STRLEN];
|
char buf[NEXTHOP_STRLEN];
|
||||||
|
|
||||||
nexthop = nhlfe->nexthop;
|
nexthop = nhlfe->nexthop;
|
||||||
@ -1968,9 +1977,7 @@ void zebra_mpls_process_dplane_notify(struct zebra_dplane_ctx *ctx)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
ctx_nexthop = NULL;
|
ctx_nexthop = NULL;
|
||||||
for (ctx_nhlfe = dplane_ctx_get_nhlfe(ctx);
|
frr_each(nhlfe_list_const, head, ctx_nhlfe) {
|
||||||
ctx_nhlfe; ctx_nhlfe = ctx_nhlfe->next) {
|
|
||||||
|
|
||||||
ctx_nexthop = ctx_nhlfe->nexthop;
|
ctx_nexthop = ctx_nhlfe->nexthop;
|
||||||
if (!ctx_nexthop)
|
if (!ctx_nexthop)
|
||||||
continue;
|
continue;
|
||||||
@ -2765,7 +2772,7 @@ int mpls_lsp_install(struct zebra_vrf *zvrf, enum lsp_types_t type,
|
|||||||
if (!lsp)
|
if (!lsp)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
nhlfe = nhlfe_find(lsp, type, gtype, gate, ifindex);
|
nhlfe = nhlfe_find(&lsp->nhlfe_list, type, gtype, gate, ifindex);
|
||||||
if (nhlfe) {
|
if (nhlfe) {
|
||||||
struct nexthop *nh = nhlfe->nexthop;
|
struct nexthop *nh = nhlfe->nexthop;
|
||||||
|
|
||||||
@ -2861,7 +2868,7 @@ int mpls_lsp_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type,
|
|||||||
lsp = hash_lookup(lsp_table, &tmp_ile);
|
lsp = hash_lookup(lsp_table, &tmp_ile);
|
||||||
if (!lsp)
|
if (!lsp)
|
||||||
return 0;
|
return 0;
|
||||||
nhlfe = nhlfe_find(lsp, type, gtype, gate, ifindex);
|
nhlfe = nhlfe_find(&lsp->nhlfe_list, type, gtype, gate, ifindex);
|
||||||
if (!nhlfe)
|
if (!nhlfe)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -2881,7 +2888,7 @@ int mpls_lsp_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type,
|
|||||||
nhlfe_del(nhlfe);
|
nhlfe_del(nhlfe);
|
||||||
|
|
||||||
/* Free LSP entry if no other NHLFEs and not scheduled. */
|
/* Free LSP entry if no other NHLFEs and not scheduled. */
|
||||||
if (!lsp->nhlfe_list
|
if ((nhlfe_list_first(&lsp->nhlfe_list) == NULL)
|
||||||
&& !CHECK_FLAG(lsp->flags, LSP_FLAG_SCHEDULED))
|
&& !CHECK_FLAG(lsp->flags, LSP_FLAG_SCHEDULED))
|
||||||
lsp_free(lsp_table, &lsp);
|
lsp_free(lsp_table, &lsp);
|
||||||
|
|
||||||
@ -2921,7 +2928,7 @@ static void mpls_lsp_uninstall_all_type(struct hash_bucket *bucket, void *ctxt)
|
|||||||
struct hash *lsp_table;
|
struct hash *lsp_table;
|
||||||
|
|
||||||
lsp = (zebra_lsp_t *)bucket->data;
|
lsp = (zebra_lsp_t *)bucket->data;
|
||||||
if (!lsp->nhlfe_list)
|
if (nhlfe_list_first(&lsp->nhlfe_list) == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lsp_table = args->lsp_table;
|
lsp_table = args->lsp_table;
|
||||||
@ -3014,15 +3021,17 @@ int zebra_mpls_lsp_label_consistent(struct zebra_vrf *zvrf,
|
|||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* If not only NHLFE, cannot allow label change. */
|
/* If not only NHLFE, cannot allow label change. */
|
||||||
if (snhlfe != slsp->snhlfe_list || snhlfe->next)
|
if (snhlfe != snhlfe_list_first(&slsp->snhlfe_list) ||
|
||||||
|
snhlfe_list_next(&slsp->snhlfe_list, snhlfe) != NULL)
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
/* If other NHLFEs exist, label operation must match. */
|
/* If other NHLFEs exist, label operation must match. */
|
||||||
if (slsp->snhlfe_list) {
|
snhlfe = snhlfe_list_first(&slsp->snhlfe_list);
|
||||||
|
if (snhlfe != NULL) {
|
||||||
int cur_op, new_op;
|
int cur_op, new_op;
|
||||||
|
|
||||||
cur_op = (slsp->snhlfe_list->out_label
|
cur_op = (snhlfe->out_label ==
|
||||||
== MPLS_LABEL_IMPLICIT_NULL);
|
MPLS_LABEL_IMPLICIT_NULL);
|
||||||
new_op = (out_label == MPLS_LABEL_IMPLICIT_NULL);
|
new_op = (out_label == MPLS_LABEL_IMPLICIT_NULL);
|
||||||
if (cur_op != new_op)
|
if (cur_op != new_op)
|
||||||
return 0;
|
return 0;
|
||||||
@ -3159,7 +3168,7 @@ int zebra_mpls_static_lsp_del(struct zebra_vrf *zvrf, mpls_label_t in_label,
|
|||||||
|
|
||||||
/* Remove entire static LSP entry if no NHLFE - valid in either case
|
/* Remove entire static LSP entry if no NHLFE - valid in either case
|
||||||
* above. */
|
* above. */
|
||||||
if (!slsp->snhlfe_list) {
|
if (snhlfe_list_first(&slsp->snhlfe_list) == NULL) {
|
||||||
slsp = hash_release(slsp_table, &tmp_ile);
|
slsp = hash_release(slsp_table, &tmp_ile);
|
||||||
XFREE(MTYPE_SLSP, slsp);
|
XFREE(MTYPE_SLSP, slsp);
|
||||||
}
|
}
|
||||||
@ -3247,8 +3256,7 @@ void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf,
|
|||||||
ttable_rowseps(tt, 0, BOTTOM, true, '-');
|
ttable_rowseps(tt, 0, BOTTOM, true, '-');
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(lsp_list, node, lsp)) {
|
for (ALL_LIST_ELEMENTS_RO(lsp_list, node, lsp)) {
|
||||||
for (nhlfe = lsp->nhlfe_list; nhlfe;
|
frr_each_safe(nhlfe_list, &lsp->nhlfe_list, nhlfe) {
|
||||||
nhlfe = nhlfe->next) {
|
|
||||||
struct nexthop *nexthop;
|
struct nexthop *nexthop;
|
||||||
const char *out_label_str;
|
const char *out_label_str;
|
||||||
char nh_buf[NEXTHOP_STRLEN];
|
char nh_buf[NEXTHOP_STRLEN];
|
||||||
@ -3320,8 +3328,7 @@ int zebra_mpls_write_lsp_config(struct vty *vty, struct zebra_vrf *zvrf)
|
|||||||
hash_get_sorted_list(zvrf->slsp_table, slsp_cmp);
|
hash_get_sorted_list(zvrf->slsp_table, slsp_cmp);
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(slsp_list, node, slsp)) {
|
for (ALL_LIST_ELEMENTS_RO(slsp_list, node, slsp)) {
|
||||||
for (snhlfe = slsp->snhlfe_list; snhlfe;
|
frr_each(snhlfe_list, &slsp->snhlfe_list, snhlfe) {
|
||||||
snhlfe = snhlfe->next) {
|
|
||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
char lstr[30];
|
char lstr[30];
|
||||||
|
|
||||||
|
@ -55,6 +55,10 @@ typedef struct zebra_nhlfe_t_ zebra_nhlfe_t;
|
|||||||
typedef struct zebra_lsp_t_ zebra_lsp_t;
|
typedef struct zebra_lsp_t_ zebra_lsp_t;
|
||||||
typedef struct zebra_fec_t_ zebra_fec_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
|
* (Outgoing) nexthop label forwarding entry configuration
|
||||||
*/
|
*/
|
||||||
@ -71,9 +75,8 @@ struct zebra_snhlfe_t_ {
|
|||||||
/* Backpointer to base entry. */
|
/* Backpointer to base entry. */
|
||||||
zebra_slsp_t *slsp;
|
zebra_slsp_t *slsp;
|
||||||
|
|
||||||
/* Pointers to more outgoing information for same in-label */
|
/* Linkage for LSPs' lists */
|
||||||
zebra_snhlfe_t *next;
|
struct snhlfe_list_item list;
|
||||||
zebra_snhlfe_t *prev;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -97,9 +100,10 @@ struct zebra_nhlfe_t_ {
|
|||||||
#define NHLFE_FLAG_DELETED (1 << 3)
|
#define NHLFE_FLAG_DELETED (1 << 3)
|
||||||
#define NHLFE_FLAG_INSTALLED (1 << 4)
|
#define NHLFE_FLAG_INSTALLED (1 << 4)
|
||||||
|
|
||||||
zebra_nhlfe_t *next;
|
|
||||||
zebra_nhlfe_t *prev;
|
|
||||||
uint8_t distance;
|
uint8_t distance;
|
||||||
|
|
||||||
|
/* Linkage for LSPs' lists */
|
||||||
|
struct nhlfe_list_item list;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -117,7 +121,7 @@ struct zebra_slsp_t_ {
|
|||||||
zebra_ile_t ile;
|
zebra_ile_t ile;
|
||||||
|
|
||||||
/* List of outgoing nexthop static configuration */
|
/* List of outgoing nexthop static configuration */
|
||||||
zebra_snhlfe_t *snhlfe_list;
|
struct snhlfe_list_head snhlfe_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -127,8 +131,9 @@ struct zebra_lsp_t_ {
|
|||||||
/* Incoming label */
|
/* Incoming label */
|
||||||
zebra_ile_t ile;
|
zebra_ile_t ile;
|
||||||
|
|
||||||
/* List of NHLFE, pointer to best and num equal-cost. */
|
/* List of NHLFEs, pointer to best, and num equal-cost. */
|
||||||
zebra_nhlfe_t *nhlfe_list;
|
struct nhlfe_list_head nhlfe_list;
|
||||||
|
|
||||||
zebra_nhlfe_t *best_nhlfe;
|
zebra_nhlfe_t *best_nhlfe;
|
||||||
uint32_t num_ecmp;
|
uint32_t num_ecmp;
|
||||||
|
|
||||||
@ -164,6 +169,9 @@ struct zebra_fec_t_ {
|
|||||||
struct list *client_list;
|
struct list *client_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Declare typesafe list apis/macros */
|
||||||
|
DECLARE_DLIST(nhlfe_list, struct zebra_nhlfe_t_, list);
|
||||||
|
|
||||||
/* Function declarations. */
|
/* Function declarations. */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -239,8 +239,9 @@ static int kernel_send_rtmsg_v6(int action, mpls_label_t in_label,
|
|||||||
|
|
||||||
static int kernel_lsp_cmd(struct zebra_dplane_ctx *ctx)
|
static int kernel_lsp_cmd(struct zebra_dplane_ctx *ctx)
|
||||||
{
|
{
|
||||||
|
const struct nhlfe_list_head *head;
|
||||||
const zebra_nhlfe_t *nhlfe;
|
const zebra_nhlfe_t *nhlfe;
|
||||||
struct nexthop *nexthop = NULL;
|
const struct nexthop *nexthop = NULL;
|
||||||
unsigned int nexthop_num = 0;
|
unsigned int nexthop_num = 0;
|
||||||
int action;
|
int action;
|
||||||
|
|
||||||
@ -258,7 +259,8 @@ static int kernel_lsp_cmd(struct zebra_dplane_ctx *ctx)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (nhlfe = dplane_ctx_get_nhlfe(ctx); nhlfe; nhlfe = nhlfe->next) {
|
head = dplane_ctx_get_nhlfe_list(ctx);
|
||||||
|
frr_each(nhlfe_list_const, head, nhlfe) {
|
||||||
nexthop = nhlfe->nexthop;
|
nexthop = nhlfe->nexthop;
|
||||||
if (!nexthop)
|
if (!nexthop)
|
||||||
continue;
|
continue;
|
||||||
|
Loading…
Reference in New Issue
Block a user