mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-07-05 17:42:21 +00:00
Merge pull request #3327 from adeg/feature/bgp-lu-auto-labels
bgpd, zebra: auto assign labels to regular labeled-unicast prefixes
This commit is contained in:
commit
96def26e5a
135
bgpd/bgp_label.c
135
bgpd/bgp_label.c
@ -120,20 +120,141 @@ mpls_label_t bgp_adv_label(struct bgp_node *rn, struct bgp_path_info *pi,
|
|||||||
return rn->local_label;
|
return rn->local_label;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bgp_reg_dereg_for_label(struct bgp_node *rn, struct bgp_path_info *pi,
|
/**
|
||||||
int reg)
|
* This is passed as the callback function to bgp_labelpool.c:bgp_lp_get()
|
||||||
|
* by bgp_reg_dereg_for_label() when a label needs to be obtained from
|
||||||
|
* label pool.
|
||||||
|
* Note that it will reject the allocated label if a label index is found,
|
||||||
|
* because the label index supposes predictable labels
|
||||||
|
*/
|
||||||
|
int bgp_reg_for_label_callback(mpls_label_t new_label, void *labelid,
|
||||||
|
bool allocated)
|
||||||
{
|
{
|
||||||
|
struct bgp_path_info *pi = (struct bgp_path_info *)labelid;
|
||||||
|
struct bgp_node *rn = (struct bgp_node *)pi->net;
|
||||||
|
char addr[PREFIX_STRLEN];
|
||||||
|
|
||||||
|
prefix2str(&rn->p, addr, PREFIX_STRLEN);
|
||||||
|
|
||||||
|
if (BGP_DEBUG(labelpool, LABELPOOL))
|
||||||
|
zlog_debug("%s: FEC %s label=%u, allocated=%d", __func__, addr,
|
||||||
|
new_label, allocated);
|
||||||
|
|
||||||
|
if (!allocated) {
|
||||||
|
/*
|
||||||
|
* previously-allocated label is now invalid
|
||||||
|
*/
|
||||||
|
if (pi->attr->label_index == MPLS_INVALID_LABEL_INDEX
|
||||||
|
&& pi->attr->label != MPLS_LABEL_NONE
|
||||||
|
&& CHECK_FLAG(rn->flags, BGP_NODE_REGISTERED_FOR_LABEL)) {
|
||||||
|
bgp_unregister_for_label(rn);
|
||||||
|
label_ntop(MPLS_LABEL_IMPLICIT_NULL, 1,
|
||||||
|
&rn->local_label);
|
||||||
|
bgp_set_valid_label(&rn->local_label);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* label index is assigned, this should be handled by SR-related code,
|
||||||
|
* so retry FEC registration and then reject label allocation for
|
||||||
|
* it to be released to label pool
|
||||||
|
*/
|
||||||
|
if (pi->attr->label_index != MPLS_INVALID_LABEL_INDEX) {
|
||||||
|
flog_err(
|
||||||
|
EC_BGP_LABEL,
|
||||||
|
"%s: FEC %s Rejecting allocated label %u as Label Index is %u",
|
||||||
|
__func__, addr, new_label, pi->attr->label_index);
|
||||||
|
|
||||||
|
bgp_register_for_label(pi->net, pi);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pi->attr->label != MPLS_INVALID_LABEL) {
|
||||||
|
if (new_label == pi->attr->label) {
|
||||||
|
/* already have same label, accept but do nothing */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* Shouldn't happen: different label allocation */
|
||||||
|
flog_err(EC_BGP_LABEL,
|
||||||
|
"%s: %s had label %u but got new assignment %u",
|
||||||
|
__func__, addr, pi->attr->label, new_label);
|
||||||
|
/* continue means use new one */
|
||||||
|
}
|
||||||
|
|
||||||
|
label_ntop(new_label, 1, &rn->local_label);
|
||||||
|
bgp_set_valid_label(&rn->local_label);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get back to registering the FEC
|
||||||
|
*/
|
||||||
|
bgp_register_for_label(pi->net, pi);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bgp_reg_dereg_for_label(struct bgp_node *rn, struct bgp_path_info *pi,
|
||||||
|
bool reg)
|
||||||
|
{
|
||||||
|
bool with_label_index = false;
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
struct prefix *p;
|
struct prefix *p;
|
||||||
|
mpls_label_t *local_label;
|
||||||
int command;
|
int command;
|
||||||
uint16_t flags = 0;
|
uint16_t flags = 0;
|
||||||
size_t flags_pos = 0;
|
size_t flags_pos = 0;
|
||||||
|
char addr[PREFIX_STRLEN];
|
||||||
|
|
||||||
|
p = &(rn->p);
|
||||||
|
local_label = &(rn->local_label);
|
||||||
|
/* this prevents the loop when we're called by
|
||||||
|
* bgp_reg_for_label_callback()
|
||||||
|
*/
|
||||||
|
bool have_label_to_reg = bgp_is_valid_label(local_label)
|
||||||
|
&& label_pton(local_label) != MPLS_LABEL_IMPLICIT_NULL;
|
||||||
|
|
||||||
|
if (reg) {
|
||||||
|
assert(pi);
|
||||||
|
/*
|
||||||
|
* Determine if we will let zebra should derive label from
|
||||||
|
* label index instead of bgpd requesting from label pool
|
||||||
|
*/
|
||||||
|
if (CHECK_FLAG(pi->attr->flag,
|
||||||
|
ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID))
|
||||||
|
&& pi->attr->label_index != BGP_INVALID_LABEL_INDEX) {
|
||||||
|
with_label_index = true;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* If no label index was provided -- assume any label
|
||||||
|
* from label pool will do. This means that label index
|
||||||
|
* always takes precedence over auto-assigned labels.
|
||||||
|
*/
|
||||||
|
if (!have_label_to_reg) {
|
||||||
|
if (BGP_DEBUG(labelpool, LABELPOOL)) {
|
||||||
|
prefix2str(p, addr, PREFIX_STRLEN);
|
||||||
|
zlog_debug("%s: Requesting label from LP for %s",
|
||||||
|
__func__, addr);
|
||||||
|
}
|
||||||
|
/* bgp_reg_for_label_callback() will call back
|
||||||
|
* __func__ when it gets a label from the pool.
|
||||||
|
* This means we'll never register FECs without
|
||||||
|
* valid labels.
|
||||||
|
*/
|
||||||
|
bgp_lp_get(LP_TYPE_BGP_LU, pi,
|
||||||
|
bgp_reg_for_label_callback);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Check socket. */
|
/* Check socket. */
|
||||||
if (!zclient || zclient->sock < 0)
|
if (!zclient || zclient->sock < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
p = &(rn->p);
|
/* If the route node has a local_label assigned or the
|
||||||
|
* path node has an MPLS SR label index allowing zebra to
|
||||||
|
* derive the label, proceed with registration. */
|
||||||
s = zclient->obuf;
|
s = zclient->obuf;
|
||||||
stream_reset(s);
|
stream_reset(s);
|
||||||
command = (reg) ? ZEBRA_FEC_REGISTER : ZEBRA_FEC_UNREGISTER;
|
command = (reg) ? ZEBRA_FEC_REGISTER : ZEBRA_FEC_UNREGISTER;
|
||||||
@ -143,13 +264,13 @@ void bgp_reg_dereg_for_label(struct bgp_node *rn, struct bgp_path_info *pi,
|
|||||||
stream_putw(s, PREFIX_FAMILY(p));
|
stream_putw(s, PREFIX_FAMILY(p));
|
||||||
stream_put_prefix(s, p);
|
stream_put_prefix(s, p);
|
||||||
if (reg) {
|
if (reg) {
|
||||||
assert(pi);
|
if (have_label_to_reg) {
|
||||||
if (pi->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID)) {
|
flags |= ZEBRA_FEC_REGISTER_LABEL;
|
||||||
if (pi->attr->label_index != BGP_INVALID_LABEL_INDEX) {
|
stream_putl(s, label_pton(local_label));
|
||||||
|
} else if (with_label_index) {
|
||||||
flags |= ZEBRA_FEC_REGISTER_LABEL_INDEX;
|
flags |= ZEBRA_FEC_REGISTER_LABEL_INDEX;
|
||||||
stream_putl(s, pi->attr->label_index);
|
stream_putl(s, pi->attr->label_index);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
SET_FLAG(rn->flags, BGP_NODE_REGISTERED_FOR_LABEL);
|
SET_FLAG(rn->flags, BGP_NODE_REGISTERED_FOR_LABEL);
|
||||||
} else
|
} else
|
||||||
UNSET_FLAG(rn->flags, BGP_NODE_REGISTERED_FOR_LABEL);
|
UNSET_FLAG(rn->flags, BGP_NODE_REGISTERED_FOR_LABEL);
|
||||||
|
@ -30,8 +30,10 @@ struct bgp_node;
|
|||||||
struct bgp_path_info;
|
struct bgp_path_info;
|
||||||
struct peer;
|
struct peer;
|
||||||
|
|
||||||
|
extern int bgp_reg_for_label_callback(mpls_label_t new_label, void *labelid,
|
||||||
|
bool allocated);
|
||||||
extern void bgp_reg_dereg_for_label(struct bgp_node *rn,
|
extern void bgp_reg_dereg_for_label(struct bgp_node *rn,
|
||||||
struct bgp_path_info *pi, int reg);
|
struct bgp_path_info *pi, bool reg);
|
||||||
extern int bgp_parse_fec_update(void);
|
extern int bgp_parse_fec_update(void);
|
||||||
extern mpls_label_t bgp_adv_label(struct bgp_node *rn, struct bgp_path_info *pi,
|
extern mpls_label_t bgp_adv_label(struct bgp_node *rn, struct bgp_path_info *pi,
|
||||||
struct peer *to, afi_t afi, safi_t safi);
|
struct peer *to, afi_t afi, safi_t safi);
|
||||||
@ -87,12 +89,12 @@ static inline void bgp_unset_valid_label(mpls_label_t *label)
|
|||||||
static inline void bgp_register_for_label(struct bgp_node *rn,
|
static inline void bgp_register_for_label(struct bgp_node *rn,
|
||||||
struct bgp_path_info *pi)
|
struct bgp_path_info *pi)
|
||||||
{
|
{
|
||||||
bgp_reg_dereg_for_label(rn, pi, 1);
|
bgp_reg_dereg_for_label(rn, pi, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void bgp_unregister_for_label(struct bgp_node *rn)
|
static inline void bgp_unregister_for_label(struct bgp_node *rn)
|
||||||
{
|
{
|
||||||
bgp_reg_dereg_for_label(rn, NULL, 0);
|
bgp_reg_dereg_for_label(rn, NULL, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Label stream to value */
|
/* Label stream to value */
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
* Types used in bgp_lp_get for debug tracking; add more as needed
|
* Types used in bgp_lp_get for debug tracking; add more as needed
|
||||||
*/
|
*/
|
||||||
#define LP_TYPE_VRF 0x00000001
|
#define LP_TYPE_VRF 0x00000001
|
||||||
|
#define LP_TYPE_BGP_LU 0x00000002
|
||||||
|
|
||||||
struct labelpool {
|
struct labelpool {
|
||||||
struct skiplist *ledger; /* all requests */
|
struct skiplist *ledger; /* all requests */
|
||||||
|
@ -2265,20 +2265,26 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn,
|
|||||||
|
|
||||||
/* Do we need to allocate or free labels?
|
/* Do we need to allocate or free labels?
|
||||||
* Right now, since we only deal with per-prefix labels, it is not
|
* Right now, since we only deal with per-prefix labels, it is not
|
||||||
* necessary to do this upon changes to best path except if the label
|
* necessary to do this upon changes to best path. Exceptions:
|
||||||
* index changes
|
* - label index has changed -> recalculate resulting label
|
||||||
|
* - path_info sub_type changed -> switch to/from implicit-null
|
||||||
|
* - no valid label (due to removed static label binding) -> get new one
|
||||||
*/
|
*/
|
||||||
if (bgp->allocate_mpls_labels[afi][safi]) {
|
if (bgp->allocate_mpls_labels[afi][safi]) {
|
||||||
if (new_select) {
|
if (new_select) {
|
||||||
if (!old_select
|
if (!old_select
|
||||||
|| bgp_label_index_differs(new_select, old_select)
|
|| bgp_label_index_differs(new_select, old_select)
|
||||||
|| new_select->sub_type != old_select->sub_type) {
|
|| new_select->sub_type != old_select->sub_type
|
||||||
|
|| !bgp_is_valid_label(&rn->local_label)) {
|
||||||
|
/* Enforced penultimate hop popping:
|
||||||
|
* implicit-null for local routes, aggregate
|
||||||
|
* and redistributed routes
|
||||||
|
*/
|
||||||
if (new_select->sub_type == BGP_ROUTE_STATIC
|
if (new_select->sub_type == BGP_ROUTE_STATIC
|
||||||
&& new_select->attr->flag
|
|| new_select->sub_type
|
||||||
& ATTR_FLAG_BIT(
|
== BGP_ROUTE_AGGREGATE
|
||||||
BGP_ATTR_PREFIX_SID)
|
|| new_select->sub_type
|
||||||
&& new_select->attr->label_index
|
== BGP_ROUTE_REDISTRIBUTE) {
|
||||||
!= BGP_INVALID_LABEL_INDEX) {
|
|
||||||
if (CHECK_FLAG(
|
if (CHECK_FLAG(
|
||||||
rn->flags,
|
rn->flags,
|
||||||
BGP_NODE_REGISTERED_FOR_LABEL))
|
BGP_NODE_REGISTERED_FOR_LABEL))
|
||||||
|
@ -58,6 +58,10 @@
|
|||||||
#define ZEBRA_IPTABLES_FORWARD 0
|
#define ZEBRA_IPTABLES_FORWARD 0
|
||||||
#define ZEBRA_IPTABLES_DROP 1
|
#define ZEBRA_IPTABLES_DROP 1
|
||||||
|
|
||||||
|
/* Zebra FEC register command flags. */
|
||||||
|
#define ZEBRA_FEC_REGISTER_LABEL 0x1
|
||||||
|
#define ZEBRA_FEC_REGISTER_LABEL_INDEX 0x2
|
||||||
|
|
||||||
extern struct sockaddr_storage zclient_addr;
|
extern struct sockaddr_storage zclient_addr;
|
||||||
extern socklen_t zclient_addr_len;
|
extern socklen_t zclient_addr_len;
|
||||||
|
|
||||||
|
@ -452,9 +452,6 @@ extern const char *zserv_command_string(unsigned int command);
|
|||||||
*/
|
*/
|
||||||
#define ZEBRA_FLAG_ONLINK 0x80
|
#define ZEBRA_FLAG_ONLINK 0x80
|
||||||
|
|
||||||
/* Zebra FEC flags. */
|
|
||||||
#define ZEBRA_FEC_REGISTER_LABEL_INDEX 0x1
|
|
||||||
|
|
||||||
#ifndef INADDR_LOOPBACK
|
#ifndef INADDR_LOOPBACK
|
||||||
#define INADDR_LOOPBACK 0x7f000001 /* Internet address 127.0.0.1. */
|
#define INADDR_LOOPBACK 0x7f000001 /* Internet address 127.0.0.1. */
|
||||||
#endif
|
#endif
|
||||||
|
@ -1187,6 +1187,7 @@ static void zread_fec_register(ZAPI_HANDLER_ARGS)
|
|||||||
unsigned short l = 0;
|
unsigned short l = 0;
|
||||||
struct prefix p;
|
struct prefix p;
|
||||||
uint16_t flags;
|
uint16_t flags;
|
||||||
|
uint32_t label = MPLS_INVALID_LABEL;
|
||||||
uint32_t label_index = MPLS_INVALID_LABEL_INDEX;
|
uint32_t label_index = MPLS_INVALID_LABEL_INDEX;
|
||||||
|
|
||||||
s = msg;
|
s = msg;
|
||||||
@ -1229,12 +1230,15 @@ static void zread_fec_register(ZAPI_HANDLER_ARGS)
|
|||||||
l += 5;
|
l += 5;
|
||||||
STREAM_GET(&p.u.prefix, s, PSIZE(p.prefixlen));
|
STREAM_GET(&p.u.prefix, s, PSIZE(p.prefixlen));
|
||||||
l += PSIZE(p.prefixlen);
|
l += PSIZE(p.prefixlen);
|
||||||
if (flags & ZEBRA_FEC_REGISTER_LABEL_INDEX) {
|
if (flags & ZEBRA_FEC_REGISTER_LABEL) {
|
||||||
|
STREAM_GETL(s, label);
|
||||||
|
l += 4;
|
||||||
|
} else if (flags & ZEBRA_FEC_REGISTER_LABEL_INDEX) {
|
||||||
STREAM_GETL(s, label_index);
|
STREAM_GETL(s, label_index);
|
||||||
l += 4;
|
l += 4;
|
||||||
} else
|
}
|
||||||
label_index = MPLS_INVALID_LABEL_INDEX;
|
|
||||||
zebra_mpls_fec_register(zvrf, &p, label_index, client);
|
zebra_mpls_fec_register(zvrf, &p, label, label_index, client);
|
||||||
}
|
}
|
||||||
|
|
||||||
stream_failure:
|
stream_failure:
|
||||||
|
@ -85,6 +85,12 @@ static struct log_ref ferr_zebra_err[] = {
|
|||||||
.description = "A client requested a label binding for a new FEC, but Zebra was unable to add the FEC to its internal table.",
|
.description = "A client requested a label binding for a new FEC, but Zebra was unable to add the FEC to its internal table.",
|
||||||
.suggestion = "Notify a developer.",
|
.suggestion = "Notify a developer.",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.code = EC_ZEBRA_FEC_LABEL_INDEX_LABEL_CONFLICT,
|
||||||
|
.title = "Refused to add FEC for MPLS client with both label index and label specified",
|
||||||
|
.description = "A client requested a label binding for a new FEC specifying a label index and a label at the same time.",
|
||||||
|
.suggestion = "Notify a developer.",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.code = EC_ZEBRA_FEC_RM_FAILED,
|
.code = EC_ZEBRA_FEC_RM_FAILED,
|
||||||
.title = "Failed to remove FEC for MPLS client",
|
.title = "Failed to remove FEC for MPLS client",
|
||||||
|
@ -37,6 +37,7 @@ enum zebra_log_refs {
|
|||||||
EC_ZEBRA_DP_INVALID_RC,
|
EC_ZEBRA_DP_INVALID_RC,
|
||||||
EC_ZEBRA_WQ_NONEXISTENT,
|
EC_ZEBRA_WQ_NONEXISTENT,
|
||||||
EC_ZEBRA_FEC_ADD_FAILED,
|
EC_ZEBRA_FEC_ADD_FAILED,
|
||||||
|
EC_ZEBRA_FEC_LABEL_INDEX_LABEL_CONFLICT,
|
||||||
EC_ZEBRA_FEC_RM_FAILED,
|
EC_ZEBRA_FEC_RM_FAILED,
|
||||||
EC_ZEBRA_IRDP_LEN_MISMATCH,
|
EC_ZEBRA_IRDP_LEN_MISMATCH,
|
||||||
EC_ZEBRA_RNH_UNKNOWN_FAMILY,
|
EC_ZEBRA_RNH_UNKNOWN_FAMILY,
|
||||||
|
@ -1813,17 +1813,22 @@ int zebra_mpls_lsp_uninstall(struct zebra_vrf *zvrf, struct route_node *rn,
|
|||||||
* NOTE: If there is a manually configured label binding, that is used.
|
* NOTE: If there is a manually configured label binding, that is used.
|
||||||
* Otherwise, if a label index is specified, it means we have to allocate the
|
* Otherwise, if a label index is specified, it means we have to allocate the
|
||||||
* label from a locally configured label block (SRGB), if one exists and index
|
* label from a locally configured label block (SRGB), if one exists and index
|
||||||
* is acceptable.
|
* is acceptable. If no label index then just register the specified label.
|
||||||
|
* NOTE2: Either label or label_index is expected to be set to MPLS_INVALID_*
|
||||||
|
* by the calling function. Register requests with both will be rejected.
|
||||||
*/
|
*/
|
||||||
int zebra_mpls_fec_register(struct zebra_vrf *zvrf, struct prefix *p,
|
int zebra_mpls_fec_register(struct zebra_vrf *zvrf, struct prefix *p,
|
||||||
uint32_t label_index, struct zserv *client)
|
uint32_t label, uint32_t label_index,
|
||||||
|
struct zserv *client)
|
||||||
{
|
{
|
||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
zebra_fec_t *fec;
|
zebra_fec_t *fec;
|
||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
int new_client;
|
bool new_client;
|
||||||
int label_change = 0;
|
bool label_change = false;
|
||||||
uint32_t old_label;
|
uint32_t old_label;
|
||||||
|
bool have_label_index = (label_index != MPLS_INVALID_LABEL_INDEX);
|
||||||
|
bool is_configured_fec = false; /* indicate statically configured FEC */
|
||||||
|
|
||||||
table = zvrf->fec_table[family2afi(PREFIX_FAMILY(p))];
|
table = zvrf->fec_table[family2afi(PREFIX_FAMILY(p))];
|
||||||
if (!table)
|
if (!table)
|
||||||
@ -1832,12 +1837,20 @@ int zebra_mpls_fec_register(struct zebra_vrf *zvrf, struct prefix *p,
|
|||||||
if (IS_ZEBRA_DEBUG_MPLS)
|
if (IS_ZEBRA_DEBUG_MPLS)
|
||||||
prefix2str(p, buf, BUFSIZ);
|
prefix2str(p, buf, BUFSIZ);
|
||||||
|
|
||||||
|
if (label != MPLS_INVALID_LABEL && have_label_index) {
|
||||||
|
flog_err(
|
||||||
|
EC_ZEBRA_FEC_LABEL_INDEX_LABEL_CONFLICT,
|
||||||
|
"Rejecting FEC register for %s with both label %u and Label Index %u specified, client %s",
|
||||||
|
buf, label, label_index,
|
||||||
|
zebra_route_string(client->proto));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Locate FEC */
|
/* Locate FEC */
|
||||||
fec = fec_find(table, p);
|
fec = fec_find(table, p);
|
||||||
if (!fec) {
|
if (!fec) {
|
||||||
fec = fec_add(table, p, MPLS_INVALID_LABEL, 0, label_index);
|
fec = fec_add(table, p, label, 0, label_index);
|
||||||
if (!fec) {
|
if (!fec) {
|
||||||
prefix2str(p, buf, BUFSIZ);
|
|
||||||
flog_err(
|
flog_err(
|
||||||
EC_ZEBRA_FEC_ADD_FAILED,
|
EC_ZEBRA_FEC_ADD_FAILED,
|
||||||
"Failed to add FEC %s upon register, client %s",
|
"Failed to add FEC %s upon register, client %s",
|
||||||
@ -1846,16 +1859,19 @@ int zebra_mpls_fec_register(struct zebra_vrf *zvrf, struct prefix *p,
|
|||||||
}
|
}
|
||||||
|
|
||||||
old_label = MPLS_INVALID_LABEL;
|
old_label = MPLS_INVALID_LABEL;
|
||||||
new_client = 1;
|
new_client = true;
|
||||||
} else {
|
} else {
|
||||||
|
/* Check if the FEC has been statically defined in the config */
|
||||||
|
is_configured_fec = fec->flags & FEC_FLAG_CONFIGURED;
|
||||||
/* Client may register same FEC with different label index. */
|
/* Client may register same FEC with different label index. */
|
||||||
new_client =
|
new_client =
|
||||||
(listnode_lookup(fec->client_list, client) == NULL);
|
(listnode_lookup(fec->client_list, client) == NULL);
|
||||||
if (!new_client && fec->label_index == label_index)
|
if (!new_client && fec->label_index == label_index
|
||||||
|
&& fec->label == label)
|
||||||
/* Duplicate register */
|
/* Duplicate register */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Save current label, update label index */
|
/* Save current label, update the FEC */
|
||||||
old_label = fec->label;
|
old_label = fec->label;
|
||||||
fec->label_index = label_index;
|
fec->label_index = label_index;
|
||||||
}
|
}
|
||||||
@ -1864,21 +1880,29 @@ int zebra_mpls_fec_register(struct zebra_vrf *zvrf, struct prefix *p,
|
|||||||
listnode_add(fec->client_list, client);
|
listnode_add(fec->client_list, client);
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_MPLS)
|
if (IS_ZEBRA_DEBUG_MPLS)
|
||||||
zlog_debug("FEC %s Label Index %u %s by client %s", buf,
|
zlog_debug("FEC %s label%s %u %s by client %s%s", buf,
|
||||||
label_index, new_client ? "registered" : "updated",
|
have_label_index ? " index" : "",
|
||||||
zebra_route_string(client->proto));
|
have_label_index ? label_index : label,
|
||||||
|
new_client ? "registered" : "updated",
|
||||||
|
zebra_route_string(client->proto),
|
||||||
|
is_configured_fec
|
||||||
|
? ", but using statically configured label"
|
||||||
|
: "");
|
||||||
|
|
||||||
/* If not a configured FEC, derive the local label (from label index)
|
/* If not a statically configured FEC, derive the local label
|
||||||
* or reset it.
|
* from label index or use the provided label
|
||||||
*/
|
*/
|
||||||
if (!(fec->flags & FEC_FLAG_CONFIGURED)) {
|
if (!is_configured_fec) {
|
||||||
|
if (have_label_index)
|
||||||
fec_derive_label_from_index(zvrf, fec);
|
fec_derive_label_from_index(zvrf, fec);
|
||||||
|
else
|
||||||
|
fec->label = label;
|
||||||
|
|
||||||
/* If no label change, exit. */
|
/* If no label change, exit. */
|
||||||
if (fec->label == old_label)
|
if (fec->label == old_label)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
label_change = 1;
|
label_change = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If new client or label change, update client and install or uninstall
|
/* If new client or label change, update client and install or uninstall
|
||||||
@ -2106,8 +2130,8 @@ int zebra_mpls_static_fec_del(struct zebra_vrf *zvrf, struct prefix *p)
|
|||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_MPLS) {
|
if (IS_ZEBRA_DEBUG_MPLS) {
|
||||||
prefix2str(p, buf, BUFSIZ);
|
prefix2str(p, buf, BUFSIZ);
|
||||||
zlog_debug("Delete fec %s label index %u", buf,
|
zlog_debug("Delete fec %s label %u label index %u", buf,
|
||||||
fec->label_index);
|
fec->label, fec->label_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
old_label = fec->label;
|
old_label = fec->label;
|
||||||
|
@ -191,16 +191,9 @@ int zebra_mpls_lsp_install(struct zebra_vrf *zvrf, struct route_node *rn,
|
|||||||
int zebra_mpls_lsp_uninstall(struct zebra_vrf *zvrf, struct route_node *rn,
|
int zebra_mpls_lsp_uninstall(struct zebra_vrf *zvrf, struct route_node *rn,
|
||||||
struct route_entry *re);
|
struct route_entry *re);
|
||||||
|
|
||||||
/*
|
|
||||||
* Registration from a client for the label binding for a FEC. If a binding
|
|
||||||
* already exists, it is informed to the client.
|
|
||||||
* NOTE: If there is a manually configured label binding, that is used.
|
|
||||||
* Otherwise, if aa label index is specified, it means we have to allocate the
|
|
||||||
* label from a locally configured label block (SRGB), if one exists and index
|
|
||||||
* is acceptable.
|
|
||||||
*/
|
|
||||||
int zebra_mpls_fec_register(struct zebra_vrf *zvrf, struct prefix *p,
|
int zebra_mpls_fec_register(struct zebra_vrf *zvrf, struct prefix *p,
|
||||||
uint32_t label_index, struct zserv *client);
|
uint32_t label, uint32_t label_index,
|
||||||
|
struct zserv *client);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Deregistration from a client for the label binding for a FEC. The FEC
|
* Deregistration from a client for the label binding for a FEC. The FEC
|
||||||
|
Loading…
Reference in New Issue
Block a user