]> git.puffer.fish Git - mirror/frr.git/commitdiff
ldpd: make allowing broken-lsps to be installed with pop operation configurable 8577/head
authorlynne <lynne@voltanet.io>
Tue, 27 Apr 2021 16:21:54 +0000 (12:21 -0400)
committerlynne <lynne@voltanet.io>
Mon, 3 May 2021 13:02:36 +0000 (09:02 -0400)
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>
ldpd/lde.c
ldpd/lde.h
ldpd/ldp_vty.h
ldpd/ldp_vty_cmds.c
ldpd/ldp_vty_conf.c
ldpd/ldp_zebra.c
ldpd/ldpd.c
ldpd/ldpd.h

index 02dcec750b195c1532ed1a22f55cbe53baa29aeb..724e83adb29b4ae476034785b4e6f1fd448f4691 100644 (file)
@@ -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)
 {
index e09be01ece58ac4ba9fe4d7b396a478a86b93f0d..dee6f3fcb9831e51e847844b1db89a8e70b15f23 100644 (file)
@@ -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 *);
index 882874f1be49179eff0a0f9a985a35857933c617..d788fa0687a28ee1c88951469d2ff78555503b31 100644 (file)
@@ -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);
index 1f102f86fa89fb9594ec2b31ce576a6fab4bdf0e..b65ebf6f559e0a867930aefda8110bf376ff6d35 100644 (file)
@@ -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);
index 6e925d1410444290e9b182873278689f78cd6e28..b35d3dfa00793e6d5e2b9bafa0a8049d3d892417 100644 (file)
@@ -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)
 {
index fd51625bbd389b481c1853a4857ab07c1a680446..2d90412d173418e931fcf0969dedfe82b060369d 100644 (file)
@@ -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;
 
index d69a4dcd3c5ade83093b3241c41584a17abb9aa8..800b954d65253769e009a5bb5873443eb405f46f 100644 (file)
@@ -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();
 
index cb7ac85d967c88ff90271e2a826e226c58b9df19..616c390e50b0e6e1c14dd4ffdc46c0269f73eba0 100644 (file)
@@ -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;