]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/zebra_mpls.c
bgpd, zebra: auto assign labels from label pool to regular prefixes in BGP labeled...
[mirror_frr.git] / zebra / zebra_mpls.c
index c19aeb626068a4dcb5e7029f1864eb6a6bfd6e1a..c0764cd4b8c6090226be791dac19a3d0af8ff7dc 100644 (file)
@@ -79,7 +79,7 @@ static zebra_fec_t *fec_add(struct route_table *table, struct prefix *p,
 static int fec_del(zebra_fec_t *fec);
 
 static unsigned int label_hash(void *p);
-static int label_cmp(const void *p1, const void *p2);
+static bool label_cmp(const void *p1, const void *p2);
 static int nhlfe_nexthop_active_ipv4(zebra_nhlfe_t *nhlfe,
                                     struct nexthop *nexthop);
 static int nhlfe_nexthop_active_ipv6(zebra_nhlfe_t *nhlfe,
@@ -572,7 +572,7 @@ static zebra_fec_t *fec_add(struct route_table *table, struct prefix *p,
  */
 static int fec_del(zebra_fec_t *fec)
 {
-       list_delete_and_null(&fec->client_list);
+       list_delete(&fec->client_list);
        fec->rn->info = NULL;
        route_unlock_node(fec->rn);
        XFREE(MTYPE_FEC, fec);
@@ -592,7 +592,7 @@ static unsigned int label_hash(void *p)
 /*
  * Compare 2 LSP hash entries based on in-label.
  */
-static int label_cmp(const void *p1, const void *p2)
+static bool label_cmp(const void *p1, const void *p2)
 {
        const zebra_ile_t *ile1 = p1;
        const zebra_ile_t *ile2 = p2;
@@ -917,14 +917,14 @@ static wq_item_status lsp_process(struct work_queue *wq, void *data)
 
                        UNSET_FLAG(lsp->flags, LSP_FLAG_CHANGED);
                        switch (kernel_add_lsp(lsp)) {
-                       case DP_REQUEST_QUEUED:
+                       case ZEBRA_DPLANE_REQUEST_QUEUED:
                                flog_err(
                                        EC_ZEBRA_DP_INVALID_RC,
                                        "No current DataPlane interfaces can return this, please fix");
                                break;
-                       case DP_REQUEST_FAILURE:
+                       case ZEBRA_DPLANE_REQUEST_FAILURE:
                                break;
-                       case DP_REQUEST_SUCCESS:
+                       case ZEBRA_DPLANE_REQUEST_SUCCESS:
                                zvrf->lsp_installs++;
                                break;
                        }
@@ -934,14 +934,14 @@ static wq_item_status lsp_process(struct work_queue *wq, void *data)
                if (!newbest) {
 
                        switch (kernel_del_lsp(lsp)) {
-                       case DP_REQUEST_QUEUED:
+                       case ZEBRA_DPLANE_REQUEST_QUEUED:
                                flog_err(
                                        EC_ZEBRA_DP_INVALID_RC,
                                        "No current DataPlane interfaces can return this, please fix");
                                break;
-                       case DP_REQUEST_FAILURE:
+                       case ZEBRA_DPLANE_REQUEST_FAILURE:
                                break;
-                       case DP_REQUEST_SUCCESS:
+                       case ZEBRA_DPLANE_REQUEST_SUCCESS:
                                zvrf->lsp_removals++;
                                break;
                        }
@@ -974,14 +974,14 @@ static wq_item_status lsp_process(struct work_queue *wq, void *data)
                        }
 
                        switch (kernel_upd_lsp(lsp)) {
-                       case DP_REQUEST_QUEUED:
+                       case ZEBRA_DPLANE_REQUEST_QUEUED:
                                flog_err(
                                        EC_ZEBRA_DP_INVALID_RC,
                                        "No current DataPlane interfaces can return this, please fix");
                                break;
-                       case DP_REQUEST_FAILURE:
+                       case ZEBRA_DPLANE_REQUEST_FAILURE:
                                break;
-                       case DP_REQUEST_SUCCESS:
+                       case ZEBRA_DPLANE_REQUEST_SUCCESS:
                                zvrf->lsp_installs++;
                                break;
                        }
@@ -1716,7 +1716,7 @@ static int mpls_processq_init(struct zebra_t *zebra)
 
 /* Public functions */
 
-void kernel_lsp_pass_fail(zebra_lsp_t *lsp, enum dp_results res)
+void kernel_lsp_pass_fail(zebra_lsp_t *lsp, enum zebra_dplane_status res)
 {
        struct nexthop *nexthop;
        zebra_nhlfe_t *nhlfe;
@@ -1725,13 +1725,13 @@ void kernel_lsp_pass_fail(zebra_lsp_t *lsp, enum dp_results res)
                return;
 
        switch (res) {
-       case DP_INSTALL_FAILURE:
+       case ZEBRA_DPLANE_INSTALL_FAILURE:
                UNSET_FLAG(lsp->flags, LSP_FLAG_INSTALLED);
                clear_nhlfe_installed(lsp);
                flog_warn(EC_ZEBRA_LSP_INSTALL_FAILURE,
                          "LSP Install Failure: %u", lsp->ile.in_label);
                break;
-       case DP_INSTALL_SUCCESS:
+       case ZEBRA_DPLANE_INSTALL_SUCCESS:
                SET_FLAG(lsp->flags, LSP_FLAG_INSTALLED);
                for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) {
                        nexthop = nhlfe->nexthop;
@@ -1742,14 +1742,16 @@ void kernel_lsp_pass_fail(zebra_lsp_t *lsp, enum dp_results res)
                        SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
                }
                break;
-       case DP_DELETE_SUCCESS:
+       case ZEBRA_DPLANE_DELETE_SUCCESS:
                UNSET_FLAG(lsp->flags, LSP_FLAG_INSTALLED);
                clear_nhlfe_installed(lsp);
                break;
-       case DP_DELETE_FAILURE:
+       case ZEBRA_DPLANE_DELETE_FAILURE:
                flog_warn(EC_ZEBRA_LSP_DELETE_FAILURE,
                          "LSP Deletion Failure: %u", lsp->ile.in_label);
                break;
+       case ZEBRA_DPLANE_STATUS_NONE:
+               break;
        }
 }
 
@@ -1811,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.
  * 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
- * 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,
-                           uint32_t label_index, struct zserv *client)
+                           uint32_t label, uint32_t label_index,
+                           struct zserv *client)
 {
        struct route_table *table;
        zebra_fec_t *fec;
        char buf[BUFSIZ];
-       int new_client;
-       int label_change = 0;
+       bool new_client;
+       bool label_change = false;
        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))];
        if (!table)
@@ -1830,12 +1837,20 @@ int zebra_mpls_fec_register(struct zebra_vrf *zvrf, struct prefix *p,
        if (IS_ZEBRA_DEBUG_MPLS)
                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 */
        fec = fec_find(table, p);
        if (!fec) {
-               fec = fec_add(table, p, MPLS_INVALID_LABEL, 0, label_index);
+               fec = fec_add(table, p, label, 0, label_index);
                if (!fec) {
-                       prefix2str(p, buf, BUFSIZ);
                        flog_err(
                                EC_ZEBRA_FEC_ADD_FAILED,
                                "Failed to add FEC %s upon register, client %s",
@@ -1844,16 +1859,19 @@ int zebra_mpls_fec_register(struct zebra_vrf *zvrf, struct prefix *p,
                }
 
                old_label = MPLS_INVALID_LABEL;
-               new_client = 1;
+               new_client = true;
        } 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. */
                new_client =
                        (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 */
                        return 0;
 
-               /* Save current label, update label index */
+               /* Save current label, update the FEC */
                old_label = fec->label;
                fec->label_index = label_index;
        }
@@ -1862,21 +1880,29 @@ int zebra_mpls_fec_register(struct zebra_vrf *zvrf, struct prefix *p,
                listnode_add(fec->client_list, client);
 
        if (IS_ZEBRA_DEBUG_MPLS)
-               zlog_debug("FEC %s Label Index %u %s by client %s", buf,
-                          label_index, new_client ? "registered" : "updated",
-                          zebra_route_string(client->proto));
-
-       /* If not a configured FEC, derive the local label (from label index)
-        * or reset it.
+               zlog_debug("FEC %s label%s %u %s by client %s%s", buf,
+                          have_label_index ? " index" : "",
+                          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 statically configured FEC, derive the local label
+        * from label index or use the provided label
         */
-       if (!(fec->flags & FEC_FLAG_CONFIGURED)) {
-               fec_derive_label_from_index(zvrf, fec);
+       if (!is_configured_fec) {
+               if (have_label_index)
+                       fec_derive_label_from_index(zvrf, fec);
+               else
+                       fec->label = label;
 
                /* If no label change, exit. */
                if (fec->label == old_label)
                        return 0;
 
-               label_change = 1;
+               label_change = true;
        }
 
        /* If new client or label change, update client and install or uninstall
@@ -2104,8 +2130,8 @@ int zebra_mpls_static_fec_del(struct zebra_vrf *zvrf, struct prefix *p)
 
        if (IS_ZEBRA_DEBUG_MPLS) {
                prefix2str(p, buf, BUFSIZ);
-               zlog_debug("Delete fec %s label index %u", buf,
-                          fec->label_index);
+               zlog_debug("Delete fec %s label %u label index %u", buf,
+                          fec->label, fec->label_index);
        }
 
        old_label = fec->label;
@@ -2808,7 +2834,7 @@ void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf,
                vty_out(vty, "\n");
        }
 
-       list_delete_and_null(&lsp_list);
+       list_delete(&lsp_list);
 }
 
 /*
@@ -2847,7 +2873,7 @@ int zebra_mpls_write_lsp_config(struct vty *vty, struct zebra_vrf *zvrf)
                }
        }
 
-       list_delete_and_null(&slsp_list);
+       list_delete(&slsp_list);
        return (zvrf->slsp_table->count ? 1 : 0);
 }