forked from Mirror/frr
ldpd: make allowing broken-lsps to be installed with pop operation configurable
If LDP is miss configured in a setup and the router has LSPs with no remote label, this code installs the LSP with a pop instruction of the top-level label so the packet can be forwarded using IP. This is a best-effort attempt to deliver labeled IP packets to their final destination instead of dropping them. If this config is turned off the code will only install LSPs that have a valid remote label. Signed-off-by: Lynne Morrison <lynne@voltanet.io>
This commit is contained in:
parent
adf1bb9f0c
commit
ff5279ba48
24
ldpd/lde.c
24
ldpd/lde.c
|
@ -1630,6 +1630,30 @@ lde_nbr_addr_update(struct lde_nbr *ln, struct lde_addr *lde_addr, int removed)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
lde_allow_broken_lsp_update(int new_config)
|
||||
{
|
||||
struct fec_node *fn;
|
||||
struct fec_nh *fnh;
|
||||
struct fec *f;
|
||||
|
||||
RB_FOREACH(f, fec_tree, &ft) {
|
||||
fn = (struct fec_node *)f;
|
||||
|
||||
LIST_FOREACH(fnh, &fn->nexthops, entry) {
|
||||
/* allow-broken-lsp config is changing so
|
||||
* we need to reprogram labeled routes to
|
||||
* have proper top-level label
|
||||
*/
|
||||
if (!(new_config & F_LDPD_ALLOW_BROKEN_LSP))
|
||||
lde_send_delete_klabel(fn, fnh);
|
||||
|
||||
if (fn->local_label != NO_LABEL)
|
||||
lde_send_change_klabel(fn, fnh);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static __inline int
|
||||
lde_map_compare(const struct lde_map *a, const struct lde_map *b)
|
||||
{
|
||||
|
|
|
@ -200,6 +200,7 @@ void lde_route_update_release(struct iface *, int);
|
|||
void lde_route_update_release_all(int);
|
||||
struct lde_addr *lde_address_find(struct lde_nbr *, int,
|
||||
union ldpd_addr *);
|
||||
void lde_allow_broken_lsp_update(int new_config);
|
||||
|
||||
/* lde_lib.c */
|
||||
void fec_init(struct fec_tree *);
|
||||
|
|
|
@ -34,6 +34,7 @@ extern struct cmd_node ldp_debug_node;
|
|||
union ldpd_addr;
|
||||
int ldp_get_address(const char *, int *, union ldpd_addr *);
|
||||
int ldp_vty_mpls_ldp (struct vty *, const char *);
|
||||
int ldp_vty_allow_broken_lsp(struct vty *, const char *);
|
||||
int ldp_vty_address_family (struct vty *, const char *, const char *);
|
||||
int ldp_vty_disc_holdtime(struct vty *, const char *, enum hello_type, long);
|
||||
int ldp_vty_disc_interval(struct vty *, const char *, enum hello_type, long);
|
||||
|
|
|
@ -241,6 +241,16 @@ DEFPY (ldp_wait_for_sync,
|
|||
|
||||
}
|
||||
|
||||
DEFPY (ldp_allow_broken_lsps,
|
||||
ldp_allow_broken_lsps_cmd,
|
||||
"[no] install allow-broken-lsps",
|
||||
NO_STR
|
||||
"install lsps\n"
|
||||
"if no remote-label install with imp-null")
|
||||
{
|
||||
return (ldp_vty_allow_broken_lsp(vty, no));
|
||||
}
|
||||
|
||||
DEFPY (ldp_discovery_targeted_hello_accept,
|
||||
ldp_discovery_targeted_hello_accept_cmd,
|
||||
"[no] discovery targeted-hello accept [from <(1-199)|(1300-2699)|WORD>$from_acl]",
|
||||
|
@ -844,6 +854,7 @@ ldp_vty_init (void)
|
|||
install_element(LDP_NODE, &ldp_router_id_cmd);
|
||||
install_element(LDP_NODE, &ldp_ordered_control_cmd);
|
||||
install_element(LDP_NODE, &ldp_wait_for_sync_cmd);
|
||||
install_element(LDP_NODE, &ldp_allow_broken_lsps_cmd);
|
||||
|
||||
install_element(LDP_IPV4_NODE, &ldp_discovery_link_holdtime_cmd);
|
||||
install_element(LDP_IPV4_NODE, &ldp_discovery_targeted_holdtime_cmd);
|
||||
|
|
|
@ -290,6 +290,9 @@ ldp_config_write(struct vty *vty)
|
|||
vty_out (vty, " wait-for-sync %u\n",
|
||||
ldpd_conf->wait_for_sync_interval);
|
||||
|
||||
if (ldpd_conf->flags & F_LDPD_ALLOW_BROKEN_LSP)
|
||||
vty_out(vty, " install allow-broken-lsp\n");
|
||||
|
||||
RB_FOREACH(nbrp, nbrp_head, &ldpd_conf->nbrp_tree) {
|
||||
if (nbrp->flags & F_NBRP_KEEPALIVE)
|
||||
vty_out (vty, " neighbor %pI4 session holdtime %u\n",
|
||||
|
@ -1039,6 +1042,19 @@ int ldp_vty_wait_for_sync_interval(struct vty *vty, const char *negate,
|
|||
return (CMD_SUCCESS);
|
||||
}
|
||||
|
||||
int
|
||||
ldp_vty_allow_broken_lsp(struct vty *vty, const char *negate)
|
||||
{
|
||||
if (negate)
|
||||
vty_conf->flags &= ~F_LDPD_ALLOW_BROKEN_LSP;
|
||||
else
|
||||
vty_conf->flags |= F_LDPD_ALLOW_BROKEN_LSP;
|
||||
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
|
||||
return (CMD_SUCCESS);
|
||||
}
|
||||
|
||||
int
|
||||
ldp_vty_ds_cisco_interop(struct vty *vty, const char * negate)
|
||||
{
|
||||
|
|
|
@ -246,12 +246,17 @@ ldp_zebra_send_mpls_labels(int cmd, struct kroute *kr)
|
|||
zl.route.instance = kr->route_instance;
|
||||
}
|
||||
|
||||
/*
|
||||
* For broken LSPs, instruct the forwarding plane to pop the top-level
|
||||
/* If allow-broken-lsps is enabled then if an lsp is received with
|
||||
* no remote label, instruct the forwarding plane to pop the top-level
|
||||
* label and forward packets normally. This is a best-effort attempt
|
||||
* to deliver labeled IP packets to their final destination (instead of
|
||||
* dropping them).
|
||||
*/
|
||||
if (kr->remote_label == NO_LABEL
|
||||
&& !(ldpd_conf->flags & F_LDPD_ALLOW_BROKEN_LSP)
|
||||
&& cmd == ZEBRA_MPLS_LABELS_ADD)
|
||||
return 0;
|
||||
|
||||
if (kr->remote_label == NO_LABEL)
|
||||
kr->remote_label = MPLS_LABEL_IMPLICIT_NULL;
|
||||
|
||||
|
|
10
ldpd/ldpd.c
10
ldpd/ldpd.c
|
@ -1365,6 +1365,16 @@ merge_global(struct ldpd_conf *conf, struct ldpd_conf *xconf)
|
|||
ldpe_reset_ds_nbrs();
|
||||
}
|
||||
|
||||
/*
|
||||
* Configuration of allow-broken-lsp requires reprograming all
|
||||
* labeled routes
|
||||
*/
|
||||
if ((conf->flags & F_LDPD_ALLOW_BROKEN_LSP) !=
|
||||
(xconf->flags & F_LDPD_ALLOW_BROKEN_LSP)) {
|
||||
if (ldpd_process == PROC_LDE_ENGINE)
|
||||
lde_allow_broken_lsp_update(xconf->flags);
|
||||
}
|
||||
|
||||
if (ldpd_process == PROC_LDP_ENGINE)
|
||||
ldpe_set_config_change_time();
|
||||
|
||||
|
|
|
@ -590,7 +590,7 @@ DECLARE_QOBJ_TYPE(ldpd_conf);
|
|||
#define F_LDPD_DS_CISCO_INTEROP 0x0002
|
||||
#define F_LDPD_ENABLED 0x0004
|
||||
#define F_LDPD_ORDERED_CONTROL 0x0008
|
||||
|
||||
#define F_LDPD_ALLOW_BROKEN_LSP 0x0010
|
||||
|
||||
struct ldpd_af_global {
|
||||
struct thread *disc_ev;
|
||||
|
|
Loading…
Reference in a new issue