summaryrefslogtreecommitdiffstats
path: root/ldpd
diff options
context:
space:
mode:
authorlynne <lynne@voltanet.io>2021-04-27 18:21:54 +0200
committerlynne <lynne@voltanet.io>2021-05-03 15:02:36 +0200
commitff5279ba48f2ff388e2345e118732e5b27f5a791 (patch)
tree359bcf5c82ba0e548c36ec9f7371a79271dd71e4 /ldpd
parentMerge pull request #8566 from rubensfig/isis_metricstyle (diff)
downloadfrr-ff5279ba48f2ff388e2345e118732e5b27f5a791.tar.xz
frr-ff5279ba48f2ff388e2345e118732e5b27f5a791.zip
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>
Diffstat (limited to 'ldpd')
-rw-r--r--ldpd/lde.c24
-rw-r--r--ldpd/lde.h1
-rw-r--r--ldpd/ldp_vty.h1
-rw-r--r--ldpd/ldp_vty_cmds.c11
-rw-r--r--ldpd/ldp_vty_conf.c16
-rw-r--r--ldpd/ldp_zebra.c9
-rw-r--r--ldpd/ldpd.c10
-rw-r--r--ldpd/ldpd.h2
8 files changed, 71 insertions, 3 deletions
diff --git a/ldpd/lde.c b/ldpd/lde.c
index 02dcec750..724e83adb 100644
--- a/ldpd/lde.c
+++ b/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)
{
diff --git a/ldpd/lde.h b/ldpd/lde.h
index e09be01ec..dee6f3fcb 100644
--- a/ldpd/lde.h
+++ b/ldpd/lde.h
@@ -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 *);
diff --git a/ldpd/ldp_vty.h b/ldpd/ldp_vty.h
index 882874f1b..d788fa068 100644
--- a/ldpd/ldp_vty.h
+++ b/ldpd/ldp_vty.h
@@ -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);
diff --git a/ldpd/ldp_vty_cmds.c b/ldpd/ldp_vty_cmds.c
index 1f102f86f..b65ebf6f5 100644
--- a/ldpd/ldp_vty_cmds.c
+++ b/ldpd/ldp_vty_cmds.c
@@ -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);
diff --git a/ldpd/ldp_vty_conf.c b/ldpd/ldp_vty_conf.c
index 6e925d141..b35d3dfa0 100644
--- a/ldpd/ldp_vty_conf.c
+++ b/ldpd/ldp_vty_conf.c
@@ -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",
@@ -1040,6 +1043,19 @@ int ldp_vty_wait_for_sync_interval(struct vty *vty, const char *negate,
}
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)
{
if (negate)
diff --git a/ldpd/ldp_zebra.c b/ldpd/ldp_zebra.c
index fd51625bb..2d90412d1 100644
--- a/ldpd/ldp_zebra.c
+++ b/ldpd/ldp_zebra.c
@@ -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;
diff --git a/ldpd/ldpd.c b/ldpd/ldpd.c
index d69a4dcd3..800b954d6 100644
--- a/ldpd/ldpd.c
+++ b/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();
diff --git a/ldpd/ldpd.h b/ldpd/ldpd.h
index cb7ac85d9..616c390e5 100644
--- a/ldpd/ldpd.h
+++ b/ldpd/ldpd.h
@@ -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;