]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/zebra_mpls.c
*: style for EC replacements
[mirror_frr.git] / zebra / zebra_mpls.c
index 3cc1848ee3c15350cf8c5f124ba8afd0bb866d45..c19aeb626068a4dcb5e7029f1864eb6a6bfd6e1a 100644 (file)
 
 #include "zebra/rib.h"
 #include "zebra/rt.h"
+#include "zebra/interface.h"
 #include "zebra/zserv.h"
 #include "zebra/redistribute.h"
 #include "zebra/debug.h"
 #include "zebra/zebra_memory.h"
 #include "zebra/zebra_vrf.h"
 #include "zebra/zebra_mpls.h"
+#include "zebra/zebra_errors.h"
 
 DEFINE_MTYPE_STATIC(ZEBRA, LSP, "MPLS LSP object")
 DEFINE_MTYPE_STATIC(ZEBRA, FEC, "MPLS FEC object")
@@ -463,7 +465,7 @@ static int fec_send(zebra_fec_t *fec, struct zserv *client)
        stream_put_prefix(s, &rn->p);
        stream_putl(s, fec->label);
        stream_putw_at(s, 0, stream_get_endp(s));
-       return zebra_server_send_message(client, s);
+       return zserv_send_message(client, s);
 }
 
 /*
@@ -549,8 +551,6 @@ static zebra_fec_t *fec_add(struct route_table *table, struct prefix *p,
 
        if (!fec) {
                fec = XCALLOC(MTYPE_FEC, sizeof(zebra_fec_t));
-               if (!fec)
-                       return NULL;
 
                rn->info = fec;
                fec->rn = rn;
@@ -704,6 +704,7 @@ static int nhlfe_nexthop_active(zebra_nhlfe_t *nhlfe)
 {
        struct nexthop *nexthop;
        struct interface *ifp;
+       struct zebra_ns *zns;
 
        nexthop = nhlfe->nexthop;
        if (!nexthop) // unexpected
@@ -721,7 +722,8 @@ static int nhlfe_nexthop_active(zebra_nhlfe_t *nhlfe)
                 * which will not be in the default
                 * VRF.  So let's look in all of them
                 */
-               ifp = if_lookup_by_index(nexthop->ifindex, VRF_UNKNOWN);
+               zns = zebra_ns_lookup(NS_DEFAULT);
+               ifp = if_lookup_by_index_per_ns(zns, nexthop->ifindex);
                if (ifp && if_is_operative(ifp))
                        SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
                else
@@ -860,7 +862,7 @@ static void lsp_uninstall_from_kernel(struct hash_backet *backet, void *ctxt)
 
        lsp = (zebra_lsp_t *)backet->data;
        if (CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED))
-               kernel_del_lsp(lsp);
+               (void)kernel_del_lsp(lsp);
 }
 
 /*
@@ -914,17 +916,35 @@ static wq_item_status lsp_process(struct work_queue *wq, void *data)
                if (newbest) {
 
                        UNSET_FLAG(lsp->flags, LSP_FLAG_CHANGED);
-                       kernel_add_lsp(lsp);
-
-                       zvrf->lsp_installs++;
+                       switch (kernel_add_lsp(lsp)) {
+                       case DP_REQUEST_QUEUED:
+                               flog_err(
+                                       EC_ZEBRA_DP_INVALID_RC,
+                                       "No current DataPlane interfaces can return this, please fix");
+                               break;
+                       case DP_REQUEST_FAILURE:
+                               break;
+                       case DP_REQUEST_SUCCESS:
+                               zvrf->lsp_installs++;
+                               break;
+                       }
                }
        } else {
                /* Installed, may need an update and/or delete. */
                if (!newbest) {
 
-                       kernel_del_lsp(lsp);
-
-                       zvrf->lsp_removals++;
+                       switch (kernel_del_lsp(lsp)) {
+                       case DP_REQUEST_QUEUED:
+                               flog_err(
+                                       EC_ZEBRA_DP_INVALID_RC,
+                                       "No current DataPlane interfaces can return this, please fix");
+                               break;
+                       case DP_REQUEST_FAILURE:
+                               break;
+                       case DP_REQUEST_SUCCESS:
+                               zvrf->lsp_removals++;
+                               break;
+                       }
                } else if (CHECK_FLAG(lsp->flags, LSP_FLAG_CHANGED)) {
                        zebra_nhlfe_t *nhlfe;
                        struct nexthop *nexthop;
@@ -953,9 +973,18 @@ static wq_item_status lsp_process(struct work_queue *wq, void *data)
                                }
                        }
 
-                       kernel_upd_lsp(lsp);
-
-                       zvrf->lsp_installs++;
+                       switch (kernel_upd_lsp(lsp)) {
+                       case DP_REQUEST_QUEUED:
+                               flog_err(
+                                       EC_ZEBRA_DP_INVALID_RC,
+                                       "No current DataPlane interfaces can return this, please fix");
+                               break;
+                       case DP_REQUEST_FAILURE:
+                               break;
+                       case DP_REQUEST_SUCCESS:
+                               zvrf->lsp_installs++;
+                               break;
+                       }
                }
        }
 
@@ -1026,7 +1055,8 @@ static int lsp_processq_add(zebra_lsp_t *lsp)
                return 0;
 
        if (zebrad.lsp_process_q == NULL) {
-               zlog_err("%s: work_queue does not exist!", __func__);
+               flog_err(EC_ZEBRA_WQ_NONEXISTENT,
+                        "%s: work_queue does not exist!", __func__);
                return -1;
        }
 
@@ -1157,8 +1187,6 @@ static zebra_nhlfe_t *nhlfe_add(zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
                return NULL;
 
        nhlfe = XCALLOC(MTYPE_NHLFE, sizeof(zebra_nhlfe_t));
-       if (!nhlfe)
-               return NULL;
 
        nhlfe->lsp = lsp;
        nhlfe->type = lsp_type;
@@ -1670,7 +1698,8 @@ static int mpls_processq_init(struct zebra_t *zebra)
 {
        zebra->lsp_process_q = work_queue_new(zebra->master, "LSP processing");
        if (!zebra->lsp_process_q) {
-               zlog_err("%s: could not initialise work queue!", __func__);
+               flog_err(EC_ZEBRA_WQ_NONEXISTENT,
+                        "%s: could not initialise work queue!", __func__);
                return -1;
        }
 
@@ -1687,7 +1716,7 @@ static int mpls_processq_init(struct zebra_t *zebra)
 
 /* Public functions */
 
-void kernel_lsp_pass_fail(zebra_lsp_t *lsp, enum southbound_results res)
+void kernel_lsp_pass_fail(zebra_lsp_t *lsp, enum dp_results res)
 {
        struct nexthop *nexthop;
        zebra_nhlfe_t *nhlfe;
@@ -1696,12 +1725,13 @@ void kernel_lsp_pass_fail(zebra_lsp_t *lsp, enum southbound_results res)
                return;
 
        switch (res) {
-       case SOUTHBOUND_INSTALL_FAILURE:
+       case DP_INSTALL_FAILURE:
                UNSET_FLAG(lsp->flags, LSP_FLAG_INSTALLED);
                clear_nhlfe_installed(lsp);
-               zlog_warn("LSP Install Failure: %u", lsp->ile.in_label);
+               flog_warn(EC_ZEBRA_LSP_INSTALL_FAILURE,
+                         "LSP Install Failure: %u", lsp->ile.in_label);
                break;
-       case SOUTHBOUND_INSTALL_SUCCESS:
+       case DP_INSTALL_SUCCESS:
                SET_FLAG(lsp->flags, LSP_FLAG_INSTALLED);
                for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) {
                        nexthop = nhlfe->nexthop;
@@ -1712,93 +1742,17 @@ void kernel_lsp_pass_fail(zebra_lsp_t *lsp, enum southbound_results res)
                        SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
                }
                break;
-       case SOUTHBOUND_DELETE_SUCCESS:
+       case DP_DELETE_SUCCESS:
                UNSET_FLAG(lsp->flags, LSP_FLAG_INSTALLED);
                clear_nhlfe_installed(lsp);
                break;
-       case SOUTHBOUND_DELETE_FAILURE:
-               zlog_warn("LSP Deletion Failure: %u", lsp->ile.in_label);
+       case DP_DELETE_FAILURE:
+               flog_warn(EC_ZEBRA_LSP_DELETE_FAILURE,
+                         "LSP Deletion Failure: %u", lsp->ile.in_label);
                break;
        }
 }
 
-/*
- * String to label conversion, labels separated by '/'.
- *
- * @param label_str labels separated by /
- * @param num_labels number of labels; zero if conversion was unsuccessful
- * @param labels preallocated mpls_label_t array of size MPLS_MAX_LABELS; only
- *               modified if the conversion succeeded
- * @return  0 on success
- *         -1 if the string could not be parsed as integers
- *         -2 if a label was inside the reserved range (0-15)
- *         -3 if the number of labels given exceeds MPLS_MAX_LABELS
- */
-int mpls_str2label(const char *label_str, uint8_t *num_labels,
-                  mpls_label_t *labels)
-{
-       char *ostr;                       // copy of label string (start)
-       char *lstr;                       // copy of label string
-       char *nump;                       // pointer to next segment
-       char *endp;                       // end pointer
-       int i;                            // for iterating label_str
-       int rc;                           // return code
-       mpls_label_t pl[MPLS_MAX_LABELS]; // parsed labels
-
-       /* labels to zero until we have a successful parse */
-       ostr = lstr = XSTRDUP(MTYPE_TMP, label_str);
-       *num_labels = 0;
-       rc = 0;
-
-       for (i = 0; i < MPLS_MAX_LABELS && lstr && !rc; i++) {
-               nump = strsep(&lstr, "/");
-               pl[i] = strtoul(nump, &endp, 10);
-
-               /* format check */
-               if (*endp != '\0')
-                       rc = -1;
-               /* validity check */
-               else if (!IS_MPLS_UNRESERVED_LABEL(pl[i]))
-                       rc = -2;
-       }
-
-       /* excess labels */
-       if (!rc && i == MPLS_MAX_LABELS && lstr)
-               rc = -3;
-
-       if (!rc) {
-               *num_labels = i;
-               memcpy(labels, pl, *num_labels * sizeof(mpls_label_t));
-       }
-
-       XFREE(MTYPE_TMP, ostr);
-
-       return rc;
-}
-
-/*
- * Label to string conversion, labels in string separated by '/'.
- */
-char *mpls_label2str(uint8_t num_labels, mpls_label_t *labels, char *buf,
-                    int len, int pretty)
-{
-       char label_buf[BUFSIZ];
-       int i;
-
-       buf[0] = '\0';
-       for (i = 0; i < num_labels; i++) {
-               if (i != 0)
-                       strlcat(buf, "/", len);
-               if (pretty)
-                       label2str(labels[i], label_buf, sizeof(label_buf));
-               else
-                       snprintf(label_buf, sizeof(label_buf), "%u", labels[i]);
-               strlcat(buf, label_buf, len);
-       }
-
-       return buf;
-}
-
 /*
  * Install dynamic LSP entry.
  */
@@ -1882,7 +1836,8 @@ int zebra_mpls_fec_register(struct zebra_vrf *zvrf, struct prefix *p,
                fec = fec_add(table, p, MPLS_INVALID_LABEL, 0, label_index);
                if (!fec) {
                        prefix2str(p, buf, BUFSIZ);
-                       zlog_err(
+                       flog_err(
+                               EC_ZEBRA_FEC_ADD_FAILED,
                                "Failed to add FEC %s upon register, client %s",
                                buf, zebra_route_string(client->proto));
                        return -1;
@@ -1962,7 +1917,8 @@ int zebra_mpls_fec_unregister(struct zebra_vrf *zvrf, struct prefix *p,
        fec = fec_find(table, p);
        if (!fec) {
                prefix2str(p, buf, BUFSIZ);
-               zlog_err("Failed to find FEC %s upon unregister, client %s",
+               flog_err(EC_ZEBRA_FEC_RM_FAILED,
+                        "Failed to find FEC %s upon unregister, client %s",
                         buf, zebra_route_string(client->proto));
                return -1;
        }
@@ -1990,9 +1946,9 @@ int zebra_mpls_fec_unregister(struct zebra_vrf *zvrf, struct prefix *p,
 /*
  * Cleanup any FECs registered by this client.
  */
-int zebra_mpls_cleanup_fecs_for_client(struct zebra_vrf *zvrf,
-                                      struct zserv *client)
+static int zebra_mpls_cleanup_fecs_for_client(struct zserv *client)
 {
+       struct zebra_vrf *zvrf = vrf_info_lookup(VRF_DEFAULT);
        struct route_node *rn;
        zebra_fec_t *fec;
        struct listnode *node;
@@ -2093,7 +2049,8 @@ int zebra_mpls_static_fec_add(struct zebra_vrf *zvrf, struct prefix *p,
                              MPLS_INVALID_LABEL_INDEX);
                if (!fec) {
                        prefix2str(p, buf, BUFSIZ);
-                       zlog_err("Failed to add FEC %s upon config", buf);
+                       flog_err(EC_ZEBRA_FEC_ADD_FAILED,
+                                "Failed to add FEC %s upon config", buf);
                        return -1;
                }
 
@@ -2140,7 +2097,8 @@ int zebra_mpls_static_fec_del(struct zebra_vrf *zvrf, struct prefix *p)
        fec = fec_find(table, p);
        if (!fec) {
                prefix2str(p, buf, BUFSIZ);
-               zlog_err("Failed to find FEC %s upon delete", buf);
+               flog_err(EC_ZEBRA_FEC_RM_FAILED,
+                        "Failed to find FEC %s upon delete", buf);
                return -1;
        }
 
@@ -2490,7 +2448,7 @@ void mpls_ldp_lsp_uninstall_all(struct hash_backet *backet, void *ctxt)
        struct hash *lsp_table;
 
        lsp = (zebra_lsp_t *)backet->data;
-       if (!lsp || !lsp->nhlfe_list)
+       if (!lsp->nhlfe_list)
                return;
 
        lsp_table = ctxt;
@@ -2742,7 +2700,7 @@ void zebra_mpls_lsp_schedule(struct zebra_vrf *zvrf)
  * (VTY command handler).
  */
 void zebra_mpls_print_lsp(struct vty *vty, struct zebra_vrf *zvrf,
-                         mpls_label_t label, uint8_t use_json)
+                         mpls_label_t label, bool use_json)
 {
        struct hash *lsp_table;
        zebra_lsp_t *lsp;
@@ -2773,7 +2731,7 @@ void zebra_mpls_print_lsp(struct vty *vty, struct zebra_vrf *zvrf,
  * Display MPLS label forwarding table (VTY command handler).
  */
 void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf,
-                               uint8_t use_json)
+                               bool use_json)
 {
        char buf[BUFSIZ];
        json_object *json = NULL;
@@ -2808,10 +2766,13 @@ void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf,
 
                                switch (nexthop->type) {
                                case NEXTHOP_TYPE_IFINDEX: {
+                                       struct zebra_ns *zns;
                                        struct interface *ifp;
 
-                                       ifp = if_lookup_by_index(
-                                               nexthop->ifindex, VRF_UNKNOWN);
+                                       zns = zebra_ns_lookup(NS_DEFAULT);
+                                       ifp = if_lookup_by_index_per_ns(
+                                                       zns,
+                                                       nexthop->ifindex);
                                        vty_out(vty, "%15s", ifp->name);
                                        break;
                                }
@@ -2986,10 +2947,13 @@ void zebra_mpls_init(void)
        mpls_enabled = 0;
 
        if (mpls_kernel_init() < 0) {
-               zlog_warn("Disabling MPLS support (no kernel support)");
+               flog_warn(EC_ZEBRA_MPLS_SUPPORT_DISABLED,
+                         "Disabling MPLS support (no kernel support)");
                return;
        }
 
        if (!mpls_processq_init(&zebrad))
                mpls_enabled = 1;
+
+       hook_register(zserv_client_close, zebra_mpls_cleanup_fecs_for_client);
 }