]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/zebra_mpls.c
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / zebra / zebra_mpls.c
index 8fe5dd9d278aaa945aba02c7829219522f03df68..d25505839c2a15f19b155dfe0f04bc90c7dbfc93 100644 (file)
@@ -1,21 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /* Zebra MPLS code
  * Copyright (C) 2013 Cumulus Networks, Inc.
- *
- * This file is part of GNU Zebra.
- *
- * GNU Zebra is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * GNU Zebra is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; see the file COPYING; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include <zebra.h>
@@ -53,7 +38,7 @@ DEFINE_MTYPE_STATIC(ZEBRA, LSP, "MPLS LSP object");
 DEFINE_MTYPE_STATIC(ZEBRA, FEC, "MPLS FEC object");
 DEFINE_MTYPE_STATIC(ZEBRA, NHLFE, "MPLS nexthop object");
 
-int mpls_enabled;
+bool mpls_enabled;
 bool mpls_pw_reach_strict; /* Strict reachability checking */
 
 /* static function declarations */
@@ -492,7 +477,7 @@ static void fec_print(struct zebra_fec *fec, struct vty *vty)
 
        rn = fec->rn;
        vty_out(vty, "%pRN\n", rn);
-       vty_out(vty, "  Label: %s", label2str(fec->label, buf, BUFSIZ));
+       vty_out(vty, "  Label: %s", label2str(fec->label, 0, buf, BUFSIZ));
        if (fec->label_index != MPLS_INVALID_LABEL_INDEX)
                vty_out(vty, ", Label Index: %u", fec->label_index);
        vty_out(vty, "\n");
@@ -1035,15 +1020,12 @@ static void lsp_processq_del(struct work_queue *wq, void *data)
        struct zebra_lsp *lsp;
        struct hash *lsp_table;
        struct zebra_nhlfe *nhlfe;
-       bool in_shutdown = false;
 
        /* If zebra is shutting down, don't delete any structs,
         * just ignore this callback. The LSPs will be cleaned up
         * during the shutdown processing.
         */
-       in_shutdown = atomic_load_explicit(&zrouter.in_shutdown,
-                                          memory_order_relaxed);
-       if (in_shutdown)
+       if (zebra_router_in_shutdown())
                return;
 
        zvrf = vrf_info_lookup(VRF_DEFAULT);
@@ -1142,6 +1124,21 @@ static void lsp_check_free(struct hash *lsp_table, struct zebra_lsp **plsp)
                lsp_free(lsp_table, plsp);
 }
 
+static void lsp_free_nhlfe(struct zebra_lsp *lsp)
+{
+       struct zebra_nhlfe *nhlfe;
+
+       while ((nhlfe = nhlfe_list_first(&lsp->nhlfe_list))) {
+               nhlfe_list_del(&lsp->nhlfe_list, nhlfe);
+               nhlfe_free(nhlfe);
+       }
+
+       while ((nhlfe = nhlfe_list_first(&lsp->backup_nhlfe_list))) {
+               nhlfe_list_del(&lsp->backup_nhlfe_list, nhlfe);
+               nhlfe_free(nhlfe);
+       }
+}
+
 /*
  * Dtor for an LSP: remove from ile hash, release any internal allocations,
  * free LSP object.
@@ -1149,7 +1146,6 @@ static void lsp_check_free(struct hash *lsp_table, struct zebra_lsp **plsp)
 static void lsp_free(struct hash *lsp_table, struct zebra_lsp **plsp)
 {
        struct zebra_lsp *lsp;
-       struct zebra_nhlfe *nhlfe;
 
        if (plsp == NULL || *plsp == NULL)
                return;
@@ -1160,13 +1156,7 @@ static void lsp_free(struct hash *lsp_table, struct zebra_lsp **plsp)
                zlog_debug("Free LSP in-label %u flags 0x%x",
                           lsp->ile.in_label, lsp->flags);
 
-       /* Free nhlfes, if any. */
-       frr_each_safe(nhlfe_list, &lsp->nhlfe_list, nhlfe)
-               nhlfe_del(nhlfe);
-
-       /* Free backup nhlfes, if any. */
-       frr_each_safe(nhlfe_list, &lsp->backup_nhlfe_list, nhlfe)
-               nhlfe_del(nhlfe);
+       lsp_free_nhlfe(lsp);
 
        hash_release(lsp_table, &lsp->ile);
        XFREE(MTYPE_LSP, lsp);
@@ -1592,8 +1582,8 @@ static void nhlfe_print(struct zebra_nhlfe *nhlfe, struct vty *vty,
        vty_out(vty, " type: %s remote label: %s distance: %d\n",
                nhlfe_type2str(nhlfe->type),
                mpls_label2str(nexthop->nh_label->num_labels,
-                              nexthop->nh_label->label,
-                              buf, sizeof(buf), 0),
+                              nexthop->nh_label->label, buf, sizeof(buf),
+                              nexthop->nh_label_type, 0),
                nhlfe->distance);
 
        if (indent)
@@ -1743,23 +1733,15 @@ static int lsp_cmp(const struct zebra_lsp *lsp1, const struct zebra_lsp *lsp2)
 /*
  * Initialize work queue for processing changed LSPs.
  */
-static int mpls_processq_init(void)
+static void mpls_processq_init(void)
 {
        zrouter.lsp_process_q = work_queue_new(zrouter.master, "LSP processing");
-       if (!zrouter.lsp_process_q) {
-               flog_err(EC_ZEBRA_WQ_NONEXISTENT,
-                        "%s: could not initialise work queue!", __func__);
-               return -1;
-       }
 
        zrouter.lsp_process_q->spec.workfunc = &lsp_process;
        zrouter.lsp_process_q->spec.del_item_data = &lsp_processq_del;
-       zrouter.lsp_process_q->spec.errorfunc = NULL;
        zrouter.lsp_process_q->spec.completion_func = &lsp_processq_complete;
        zrouter.lsp_process_q->spec.max_retries = 0;
        zrouter.lsp_process_q->spec.hold = 10;
-
-       return 0;
 }
 
 
@@ -1851,7 +1833,57 @@ void zebra_mpls_lsp_dplane_result(struct zebra_dplane_ctx *ctx)
                                             ZEBRA_SR_POLICY_LABEL_REMOVED);
                break;
 
-       default:
+       case DPLANE_OP_LSP_NOTIFY:
+       case DPLANE_OP_NONE:
+       case DPLANE_OP_ROUTE_INSTALL:
+       case DPLANE_OP_ROUTE_UPDATE:
+       case DPLANE_OP_ROUTE_DELETE:
+       case DPLANE_OP_ROUTE_NOTIFY:
+       case DPLANE_OP_NH_INSTALL:
+       case DPLANE_OP_NH_UPDATE:
+       case DPLANE_OP_NH_DELETE:
+       case DPLANE_OP_PW_INSTALL:
+       case DPLANE_OP_PW_UNINSTALL:
+       case DPLANE_OP_SYS_ROUTE_ADD:
+       case DPLANE_OP_SYS_ROUTE_DELETE:
+       case DPLANE_OP_ADDR_INSTALL:
+       case DPLANE_OP_ADDR_UNINSTALL:
+       case DPLANE_OP_MAC_INSTALL:
+       case DPLANE_OP_MAC_DELETE:
+       case DPLANE_OP_NEIGH_INSTALL:
+       case DPLANE_OP_NEIGH_UPDATE:
+       case DPLANE_OP_NEIGH_DELETE:
+       case DPLANE_OP_VTEP_ADD:
+       case DPLANE_OP_VTEP_DELETE:
+       case DPLANE_OP_RULE_ADD:
+       case DPLANE_OP_RULE_DELETE:
+       case DPLANE_OP_RULE_UPDATE:
+       case DPLANE_OP_NEIGH_DISCOVER:
+       case DPLANE_OP_BR_PORT_UPDATE:
+       case DPLANE_OP_IPTABLE_ADD:
+       case DPLANE_OP_IPTABLE_DELETE:
+       case DPLANE_OP_IPSET_ADD:
+       case DPLANE_OP_IPSET_DELETE:
+       case DPLANE_OP_IPSET_ENTRY_ADD:
+       case DPLANE_OP_IPSET_ENTRY_DELETE:
+       case DPLANE_OP_NEIGH_IP_INSTALL:
+       case DPLANE_OP_NEIGH_IP_DELETE:
+       case DPLANE_OP_NEIGH_TABLE_UPDATE:
+       case DPLANE_OP_GRE_SET:
+       case DPLANE_OP_INTF_ADDR_ADD:
+       case DPLANE_OP_INTF_ADDR_DEL:
+       case DPLANE_OP_INTF_NETCONFIG:
+       case DPLANE_OP_INTF_INSTALL:
+       case DPLANE_OP_INTF_UPDATE:
+       case DPLANE_OP_INTF_DELETE:
+       case DPLANE_OP_TC_QDISC_INSTALL:
+       case DPLANE_OP_TC_QDISC_UNINSTALL:
+       case DPLANE_OP_TC_CLASS_ADD:
+       case DPLANE_OP_TC_CLASS_DELETE:
+       case DPLANE_OP_TC_CLASS_UPDATE:
+       case DPLANE_OP_TC_FILTER_ADD:
+       case DPLANE_OP_TC_FILTER_DELETE:
+       case DPLANE_OP_TC_FILTER_UPDATE:
                break;
 
        } /* Switch */
@@ -2672,7 +2704,7 @@ int zebra_mpls_write_fec_config(struct vty *vty, struct zebra_vrf *zvrf)
 
                        write = 1;
                        vty_out(vty, "mpls label bind %pFX %s\n", &rn->p,
-                               label2str(fec->label, lstr, BUFSIZ));
+                               label2str(fec->label, 0, lstr, BUFSIZ));
                }
        }
 
@@ -2749,9 +2781,9 @@ static bool ftn_update_nexthop(bool add_p, struct nexthop *nexthop,
        return true;
 }
 
-int mpls_ftn_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type,
-                      struct prefix *prefix, uint8_t route_type,
-                      unsigned short route_instance)
+void zebra_mpls_ftn_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type,
+                             struct prefix *prefix, uint8_t route_type,
+                             uint8_t route_instance)
 {
        struct route_table *table;
        struct route_node *rn;
@@ -2763,7 +2795,7 @@ int mpls_ftn_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type,
        /* Lookup table.  */
        table = zebra_vrf_table(afi, SAFI_UNICAST, zvrf_id(zvrf));
        if (!table)
-               return -1;
+               return;
 
        /* Lookup existing route */
        rn = route_node_get(table, prefix);
@@ -2774,7 +2806,7 @@ int mpls_ftn_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type,
                        break;
        }
        if (re == NULL)
-               return -1;
+               return;
 
        /*
         * Nexthops are now shared by multiple routes, so we have to make
@@ -2803,8 +2835,6 @@ int mpls_ftn_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type,
        zebra_nhg_free(new_nhe);
 
        rib_queue_add(rn);
-
-       return 0;
 }
 
 /*
@@ -2886,8 +2916,8 @@ static bool ftn_update_znh(bool add_p, enum lsp_types_t type,
  * There are several changes that need to be made, in several zebra
  * data structures, so we want to do all the work required at once.
  */
-int mpls_zapi_labels_process(bool add_p, struct zebra_vrf *zvrf,
-                            const struct zapi_labels *zl)
+void zebra_mpls_zapi_labels_process(bool add_p, struct zebra_vrf *zvrf,
+                                   const struct zapi_labels *zl)
 {
        int i, counter, ret = 0;
        char buf[NEXTHOP_STRLEN];
@@ -2908,7 +2938,7 @@ int mpls_zapi_labels_process(bool add_p, struct zebra_vrf *zvrf,
                /* Lookup table. */
                lsp_table = zvrf->lsp_table;
                if (!lsp_table)
-                       return -1;
+                       return;
 
                /* Find or create LSP object */
                tmp_ile.in_label = zl->local_label;
@@ -3072,8 +3102,6 @@ znh_done:
 
        if (new_nhe)
                zebra_nhg_free(new_nhe);
-
-       return ret;
 }
 
 /*
@@ -3121,10 +3149,10 @@ lsp_add_nhlfe(struct zebra_lsp *lsp, enum lsp_types_t type,
 
                        nhlfe2str(nhlfe, buf, sizeof(buf));
                        mpls_label2str(num_out_labels, out_labels, buf2,
-                                      sizeof(buf2), 0);
+                                      sizeof(buf2), 0, 0);
                        mpls_label2str(nh->nh_label->num_labels,
                                       nh->nh_label->label, buf3, sizeof(buf3),
-                                      0);
+                                      nh->nh_label_type, 0);
 
                        zlog_debug("LSP in-label %u type %d %snexthop %s out-label(s) changed to %s (old %s)",
                                   lsp->ile.in_label, type, backup_str, buf,
@@ -3152,7 +3180,7 @@ lsp_add_nhlfe(struct zebra_lsp *lsp, enum lsp_types_t type,
 
                        nhlfe2str(nhlfe, buf, sizeof(buf));
                        mpls_label2str(num_out_labels, out_labels, buf2,
-                                      sizeof(buf2), 0);
+                                      sizeof(buf2), 0, 0);
 
                        zlog_debug("Add LSP in-label %u type %d %snexthop %s out-label(s) %s",
                                   lsp->ile.in_label, type, backup_str, buf,
@@ -3669,6 +3697,7 @@ int zebra_mpls_static_lsp_del(struct zebra_vrf *zvrf, mpls_label_t in_label,
         */
        if (nhlfe_list_first(&lsp->nhlfe_list) == NULL) {
                lsp = hash_release(slsp_table, &tmp_ile);
+               lsp_free_nhlfe(lsp);
                XFREE(MTYPE_LSP, lsp);
        }
 
@@ -3734,10 +3763,10 @@ void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf,
                json = json_object_new_object();
 
                for (ALL_LIST_ELEMENTS_RO(lsp_list, node, lsp))
-                       json_object_object_add(
-                               json, label2str(lsp->ile.in_label, buf,
-                                               sizeof(buf)),
-                               lsp_json(lsp));
+                       json_object_object_add(json,
+                                              label2str(lsp->ile.in_label, 0,
+                                                        buf, sizeof(buf)),
+                                              lsp_json(lsp));
 
                vty_json(vty, json);
        } else {
@@ -3789,7 +3818,8 @@ void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf,
                                        out_label_str = mpls_label2str(
                                                nexthop->nh_label->num_labels,
                                                &nexthop->nh_label->label[0],
-                                               buf, sizeof(buf), 1);
+                                               buf, sizeof(buf),
+                                               nexthop->nh_label_type, 1);
                                else
                                        out_label_str = "-";
 
@@ -4009,6 +4039,8 @@ static void lsp_table_free(void *p)
 {
        struct zebra_lsp *lsp = p;
 
+       lsp_free_nhlfe(lsp);
+
        XFREE(MTYPE_LSP, lsp);
 }
 
@@ -4053,12 +4085,23 @@ void zebra_mpls_init_tables(struct zebra_vrf *zvrf)
        zvrf->mpls_srgb.end_label = MPLS_DEFAULT_MAX_SRGB_LABEL;
 }
 
+void zebra_mpls_turned_on(void)
+{
+       if (!mpls_enabled) {
+               mpls_processq_init();
+               mpls_enabled = true;
+       }
+
+       hook_register(zserv_client_close, zebra_mpls_cleanup_fecs_for_client);
+       hook_register(zserv_client_close, zebra_mpls_cleanup_zclient_labels);
+}
+
 /*
  * Global MPLS initialization.
  */
 void zebra_mpls_init(void)
 {
-       mpls_enabled = 0;
+       mpls_enabled = false;
        mpls_pw_reach_strict = false;
 
        if (mpls_kernel_init() < 0) {
@@ -4067,9 +4110,5 @@ void zebra_mpls_init(void)
                return;
        }
 
-       if (!mpls_processq_init())
-               mpls_enabled = 1;
-
-       hook_register(zserv_client_close, zebra_mpls_cleanup_fecs_for_client);
-       hook_register(zserv_client_close, zebra_mpls_cleanup_zclient_labels);
+       zebra_mpls_turned_on();
 }