back to topotato report
topotato coverage report
Current view: top level - zebra - zebra_mpls_vty.c (source / functions) Hit Total Coverage
Test: aggregated run ( view descriptions ) Lines: 15 181 8.3 %
Date: 2023-02-24 14:41:08 Functions: 1 16 6.2 %

          Line data    Source code
       1             : /* Zebra MPLS VTY functions
       2             :  * Copyright (C) 2002 Kunihiro Ishiguro
       3             :  *
       4             :  * This file is part of GNU Zebra.
       5             :  *
       6             :  * GNU Zebra is free software; you can redistribute it and/or modify it
       7             :  * under the terms of the GNU General Public License as published by the
       8             :  * Free Software Foundation; either version 2, or (at your option) any
       9             :  * later version.
      10             :  *
      11             :  * GNU Zebra is distributed in the hope that it will be useful, but
      12             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14             :  * General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU General Public License along
      17             :  * with this program; see the file COPYING; if not, write to the Free Software
      18             :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
      19             :  */
      20             : 
      21             : #include <zebra.h>
      22             : 
      23             : #include "memory.h"
      24             : #include "if.h"
      25             : #include "prefix.h"
      26             : #include "command.h"
      27             : #include "table.h"
      28             : #include "rib.h"
      29             : #include "nexthop.h"
      30             : #include "vrf.h"
      31             : #include "mpls.h"
      32             : #include "lib/json.h"
      33             : 
      34             : #include "zebra/zserv.h"
      35             : #include "zebra/zebra_vrf.h"
      36             : #include "zebra/zebra_mpls.h"
      37             : #include "zebra/zebra_rnh.h"
      38             : #include "zebra/redistribute.h"
      39             : #include "zebra/zebra_routemap.h"
      40             : 
      41           0 : static int zebra_mpls_transit_lsp(struct vty *vty, int add_cmd,
      42             :                                   const char *inlabel_str, const char *gate_str,
      43             :                                   const char *outlabel_str,
      44             :                                   const char *flag_str)
      45             : {
      46           0 :         struct zebra_vrf *zvrf;
      47           0 :         int ret;
      48           0 :         enum nexthop_types_t gtype;
      49           0 :         union g_addr gate;
      50           0 :         mpls_label_t label;
      51           0 :         mpls_label_t in_label, out_label;
      52             : 
      53           0 :         if (!mpls_enabled) {
      54           0 :                 vty_out(vty,
      55             :                         "%% MPLS not turned on in kernel, ignoring command\n");
      56           0 :                 return CMD_WARNING_CONFIG_FAILED;
      57             :         }
      58             : 
      59           0 :         zvrf = vrf_info_lookup(VRF_DEFAULT);
      60           0 :         if (!zvrf) {
      61           0 :                 vty_out(vty, "%% Default VRF does not exist\n");
      62           0 :                 return CMD_WARNING_CONFIG_FAILED;
      63             :         }
      64             : 
      65           0 :         if (!inlabel_str) {
      66           0 :                 vty_out(vty, "%% No Label Information\n");
      67           0 :                 return CMD_WARNING_CONFIG_FAILED;
      68             :         }
      69             : 
      70           0 :         out_label = MPLS_LABEL_IMPLICIT_NULL; /* as initialization */
      71           0 :         label = atoi(inlabel_str);
      72           0 :         if (!IS_MPLS_UNRESERVED_LABEL(label)) {
      73           0 :                 vty_out(vty, "%% Invalid label\n");
      74           0 :                 return CMD_WARNING_CONFIG_FAILED;
      75             :         }
      76             : 
      77           0 :         if (add_cmd) {
      78           0 :                 if (!gate_str) {
      79           0 :                         vty_out(vty, "%% No Nexthop Information\n");
      80           0 :                         return CMD_WARNING_CONFIG_FAILED;
      81             :                 }
      82           0 :                 if (!outlabel_str) {
      83           0 :                         vty_out(vty, "%% No Outgoing label Information\n");
      84           0 :                         return CMD_WARNING_CONFIG_FAILED;
      85             :                 }
      86             :         }
      87             : 
      88           0 :         in_label = label;
      89           0 :         gtype = NEXTHOP_TYPE_BLACKHOLE; /* as initialization */
      90             : 
      91           0 :         if (gate_str) {
      92             :                 /* Gateway is a IPv4 or IPv6 nexthop. */
      93           0 :                 ret = inet_pton(AF_INET6, gate_str, &gate.ipv6);
      94           0 :                 if (ret == 1)
      95             :                         gtype = NEXTHOP_TYPE_IPV6;
      96             :                 else {
      97           0 :                         ret = inet_pton(AF_INET, gate_str, &gate.ipv4);
      98           0 :                         if (ret == 1)
      99             :                                 gtype = NEXTHOP_TYPE_IPV4;
     100             :                         else {
     101           0 :                                 vty_out(vty, "%% Invalid nexthop\n");
     102           0 :                                 return CMD_WARNING_CONFIG_FAILED;
     103             :                         }
     104             :                 }
     105             :         }
     106             : 
     107           0 :         if (outlabel_str) {
     108           0 :                 if (outlabel_str[0] == 'i')
     109             :                         out_label = MPLS_LABEL_IMPLICIT_NULL;
     110           0 :                 else if (outlabel_str[0] == 'e' && gtype == NEXTHOP_TYPE_IPV4)
     111             :                         out_label = MPLS_LABEL_IPV4_EXPLICIT_NULL;
     112           0 :                 else if (outlabel_str[0] == 'e' && gtype == NEXTHOP_TYPE_IPV6)
     113             :                         out_label = MPLS_LABEL_IPV6_EXPLICIT_NULL;
     114             :                 else
     115           0 :                         out_label = atoi(outlabel_str);
     116             :         }
     117             : 
     118           0 :         if (add_cmd) {
     119             : #if defined(HAVE_CUMULUS)
     120             :                 /* Check that label value is consistent. */
     121             :                 if (!zebra_mpls_lsp_label_consistent(zvrf, in_label, out_label,
     122             :                                                      gtype, &gate, 0)) {
     123             :                         vty_out(vty, "%% Label value not consistent\n");
     124             :                         return CMD_WARNING_CONFIG_FAILED;
     125             :                 }
     126             : #endif /* HAVE_CUMULUS */
     127             : 
     128           0 :                 ret = zebra_mpls_static_lsp_add(zvrf, in_label, out_label,
     129             :                                                 gtype, &gate, 0);
     130             :         } else
     131           0 :                 ret = zebra_mpls_static_lsp_del(zvrf, in_label, gtype, &gate,
     132             :                                                 0);
     133             : 
     134           0 :         if (ret != 0) {
     135           0 :                 vty_out(vty, "%% LSP cannot be %s\n",
     136             :                         add_cmd ? "added" : "deleted");
     137           0 :                 return CMD_WARNING_CONFIG_FAILED;
     138             :         }
     139             : 
     140             :         return CMD_SUCCESS;
     141             : }
     142             : 
     143           0 : DEFUN (mpls_transit_lsp,
     144             :        mpls_transit_lsp_cmd,
     145             :        "mpls lsp (16-1048575) <A.B.C.D|X:X::X:X> <(16-1048575)|explicit-null|implicit-null>",
     146             :        MPLS_STR
     147             :        "Establish label switched path\n"
     148             :        "Incoming MPLS label\n"
     149             :        "IPv4 gateway address\n"
     150             :        "IPv6 gateway address\n"
     151             :        "Outgoing MPLS label\n"
     152             :        "Use Explicit-Null label\n"
     153             :        "Use Implicit-Null label\n")
     154             : {
     155           0 :         return zebra_mpls_transit_lsp(vty, 1, argv[2]->arg, argv[3]->arg,
     156           0 :                                       argv[4]->arg, NULL);
     157             : }
     158             : 
     159           0 : DEFUN (no_mpls_transit_lsp,
     160             :        no_mpls_transit_lsp_cmd,
     161             :        "no mpls lsp (16-1048575) <A.B.C.D|X:X::X:X>",
     162             :        NO_STR
     163             :        MPLS_STR
     164             :        "Establish label switched path\n"
     165             :        "Incoming MPLS label\n"
     166             :        "IPv4 gateway address\n"
     167             :        "IPv6 gateway address\n")
     168             : {
     169           0 :         return zebra_mpls_transit_lsp(vty, 0, argv[3]->arg, argv[4]->arg, NULL,
     170             :                                       NULL);
     171             : }
     172             : 
     173             : ALIAS(no_mpls_transit_lsp, no_mpls_transit_lsp_out_label_cmd,
     174             :       "no mpls lsp (16-1048575) <A.B.C.D|X:X::X:X> <(16-1048575)|explicit-null|implicit-null>",
     175             :       NO_STR MPLS_STR
     176             :       "Establish label switched path\n"
     177             :       "Incoming MPLS label\n"
     178             :       "IPv4 gateway address\n"
     179             :       "IPv6 gateway address\n"
     180             :       "Outgoing MPLS label\n"
     181             :       "Use Explicit-Null label\n"
     182             :       "Use Implicit-Null label\n")
     183             : 
     184           0 : DEFUN (no_mpls_transit_lsp_all,
     185             :        no_mpls_transit_lsp_all_cmd,
     186             :        "no mpls lsp (16-1048575)",
     187             :        NO_STR
     188             :        MPLS_STR
     189             :        "Establish label switched path\n"
     190             :        "Incoming MPLS label\n")
     191             : {
     192           0 :         return zebra_mpls_transit_lsp(vty, 0, argv[3]->arg, NULL, NULL, NULL);
     193             : }
     194             : 
     195           0 : static int zebra_mpls_bind(struct vty *vty, int add_cmd, const char *prefix,
     196             :                            const char *label_str)
     197             : {
     198           0 :         struct zebra_vrf *zvrf;
     199           0 :         struct prefix p;
     200           0 :         uint32_t label;
     201           0 :         int ret;
     202             : 
     203           0 :         zvrf = vrf_info_lookup(VRF_DEFAULT);
     204           0 :         if (!zvrf) {
     205           0 :                 vty_out(vty, "%% Default VRF does not exist\n");
     206           0 :                 return CMD_WARNING_CONFIG_FAILED;
     207             :         }
     208             : 
     209           0 :         memset(&p, 0, sizeof(p));
     210           0 :         ret = str2prefix(prefix, &p);
     211           0 :         if (ret <= 0) {
     212           0 :                 vty_out(vty, "%% Malformed address\n");
     213           0 :                 return CMD_WARNING_CONFIG_FAILED;
     214             :         }
     215             : 
     216           0 :         if (add_cmd) {
     217           0 :                 if (!label_str) {
     218           0 :                         vty_out(vty, "%% No label binding specified\n");
     219           0 :                         return CMD_WARNING_CONFIG_FAILED;
     220             :                 }
     221             : 
     222           0 :                 if (!strcmp(label_str, "implicit-null"))
     223             :                         label = MPLS_LABEL_IMPLICIT_NULL;
     224           0 :                 else if (!strcmp(label_str, "explicit-null")) {
     225           0 :                         if (p.family == AF_INET)
     226             :                                 label = MPLS_LABEL_IPV4_EXPLICIT_NULL;
     227             :                         else
     228           0 :                                 label = MPLS_LABEL_IPV6_EXPLICIT_NULL;
     229             :                 } else {
     230           0 :                         label = atoi(label_str);
     231           0 :                         if (!IS_MPLS_UNRESERVED_LABEL(label)) {
     232           0 :                                 vty_out(vty, "%% Invalid label\n");
     233           0 :                                 return CMD_WARNING_CONFIG_FAILED;
     234             :                         }
     235           0 :                         if (zebra_mpls_label_already_bound(zvrf, label)) {
     236           0 :                                 vty_out(vty,
     237             :                                         "%% Label already bound to a FEC\n");
     238           0 :                                 return CMD_WARNING_CONFIG_FAILED;
     239             :                         }
     240             :                 }
     241             : 
     242           0 :                 ret = zebra_mpls_static_fec_add(zvrf, &p, label);
     243             :         } else
     244           0 :                 ret = zebra_mpls_static_fec_del(zvrf, &p);
     245             : 
     246           0 :         if (ret) {
     247           0 :                 vty_out(vty, "%% FEC to label binding cannot be %s\n",
     248             :                         add_cmd ? "added" : "deleted");
     249           0 :                 return CMD_WARNING_CONFIG_FAILED;
     250             :         }
     251             : 
     252             :         return CMD_SUCCESS;
     253             : }
     254             : 
     255           0 : DEFUN (mpls_label_bind,
     256             :        mpls_label_bind_cmd,
     257             :        "mpls label bind <A.B.C.D/M|X:X::X:X/M> <(16-1048575)|implicit-null|explicit-null>",
     258             :        MPLS_STR
     259             :        "Label configuration\n"
     260             :        "Establish FEC to label binding\n"
     261             :        "IPv4 prefix\n"
     262             :        "IPv6 prefix\n"
     263             :        "MPLS Label to bind\n"
     264             :        "Use Implicit-Null Label\n"
     265             :        "Use Explicit-Null Label\n")
     266             : {
     267           0 :         return zebra_mpls_bind(vty, 1, argv[3]->arg, argv[4]->arg);
     268             : }
     269             : 
     270           0 : DEFUN (no_mpls_label_bind,
     271             :        no_mpls_label_bind_cmd,
     272             :        "no mpls label bind <A.B.C.D/M|X:X::X:X/M> [<(16-1048575)|implicit-null>]",
     273             :        NO_STR
     274             :        MPLS_STR
     275             :        "Label configuration\n"
     276             :        "Establish FEC to label binding\n"
     277             :        "IPv4 prefix\n"
     278             :        "IPv6 prefix\n"
     279             :        "MPLS Label to bind\n"
     280             :        "Use Implicit-Null Label\n")
     281             : {
     282           0 :         return zebra_mpls_bind(vty, 0, argv[4]->arg, NULL);
     283             : }
     284             : 
     285             : /* MPLS LSP configuration write function. */
     286           0 : static int zebra_mpls_config(struct vty *vty)
     287             : {
     288           0 :         int write = 0;
     289           0 :         struct zebra_vrf *zvrf;
     290             : 
     291           0 :         zvrf = vrf_info_lookup(VRF_DEFAULT);
     292           0 :         if (!zvrf)
     293             :                 return 0;
     294             : 
     295           0 :         write += zebra_mpls_write_lsp_config(vty, zvrf);
     296           0 :         write += zebra_mpls_write_fec_config(vty, zvrf);
     297           0 :         write += zebra_mpls_write_label_block_config(vty, zvrf);
     298           0 :         return write;
     299             : }
     300             : 
     301           0 : DEFUN (show_mpls_fec,
     302             :        show_mpls_fec_cmd,
     303             :        "show mpls fec [<A.B.C.D/M|X:X::X:X/M>]",
     304             :        SHOW_STR
     305             :        MPLS_STR
     306             :        "MPLS FEC table\n"
     307             :        "FEC to display information about\n"
     308             :        "FEC to display information about\n")
     309             : {
     310           0 :         struct zebra_vrf *zvrf;
     311           0 :         struct prefix p;
     312           0 :         int ret;
     313             : 
     314           0 :         zvrf = vrf_info_lookup(VRF_DEFAULT);
     315           0 :         if (!zvrf)
     316             :                 return 0;
     317             : 
     318           0 :         if (argc == 3)
     319           0 :                 zebra_mpls_print_fec_table(vty, zvrf);
     320             :         else {
     321           0 :                 memset(&p, 0, sizeof(struct prefix));
     322           0 :                 ret = str2prefix(argv[3]->arg, &p);
     323           0 :                 if (ret <= 0) {
     324           0 :                         vty_out(vty, "%% Malformed address\n");
     325           0 :                         return CMD_WARNING;
     326             :                 }
     327           0 :                 zebra_mpls_print_fec(vty, zvrf, &p);
     328             :         }
     329             : 
     330             :         return CMD_SUCCESS;
     331             : }
     332             : 
     333           0 : DEFUN (show_mpls_table,
     334             :        show_mpls_table_cmd,
     335             :        "show mpls table [json]",
     336             :        SHOW_STR
     337             :        MPLS_STR
     338             :        "MPLS table\n"
     339             :        JSON_STR)
     340             : {
     341           0 :         struct zebra_vrf *zvrf;
     342           0 :         bool uj = use_json(argc, argv);
     343             : 
     344           0 :         zvrf = vrf_info_lookup(VRF_DEFAULT);
     345           0 :         zebra_mpls_print_lsp_table(vty, zvrf, uj);
     346           0 :         return CMD_SUCCESS;
     347             : }
     348             : 
     349           0 : DEFUN (show_mpls_table_lsp,
     350             :        show_mpls_table_lsp_cmd,
     351             :        "show mpls table (16-1048575) [json]",
     352             :        SHOW_STR
     353             :        MPLS_STR
     354             :        "MPLS table\n"
     355             :        "LSP to display information about\n"
     356             :        JSON_STR)
     357             : {
     358           0 :         uint32_t label;
     359           0 :         struct zebra_vrf *zvrf;
     360           0 :         bool uj = use_json(argc, argv);
     361             : 
     362           0 :         zvrf = vrf_info_lookup(VRF_DEFAULT);
     363           0 :         label = atoi(argv[3]->arg);
     364           0 :         zebra_mpls_print_lsp(vty, zvrf, label, uj);
     365           0 :         return CMD_SUCCESS;
     366             : }
     367             : 
     368           0 : DEFUN (show_mpls_status,
     369             :        show_mpls_status_cmd,
     370             :        "show mpls status",
     371             :        SHOW_STR
     372             :        "MPLS information\n"
     373             :        "MPLS status\n")
     374             : {
     375           0 :         vty_out(vty, "MPLS support enabled: %s\n",
     376           0 :                 (mpls_enabled) ? "yes"
     377             :                                : "no (mpls kernel extensions not detected)");
     378           0 :         return CMD_SUCCESS;
     379             : }
     380             : 
     381           0 : static int zebra_mpls_global_block(struct vty *vty, int add_cmd,
     382             :                                    const char *start_label_str,
     383             :                                    const char *end_label_str)
     384             : {
     385           0 :         int ret;
     386           0 :         uint32_t start_label;
     387           0 :         uint32_t end_label;
     388           0 :         struct zebra_vrf *zvrf;
     389             : 
     390           0 :         zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
     391           0 :         if (!zvrf) {
     392           0 :                 vty_out(vty, "%% Default VRF does not exist\n");
     393           0 :                 return CMD_WARNING_CONFIG_FAILED;
     394             :         }
     395             : 
     396           0 :         if (add_cmd) {
     397           0 :                 if (!start_label_str || !end_label_str) {
     398           0 :                         vty_out(vty, "%% Labels not specified\n");
     399           0 :                         return CMD_WARNING_CONFIG_FAILED;
     400             :                 }
     401             : 
     402           0 :                 start_label = atoi(start_label_str);
     403           0 :                 end_label = atoi(end_label_str);
     404           0 :                 if (!IS_MPLS_UNRESERVED_LABEL(start_label)
     405           0 :                     || !IS_MPLS_UNRESERVED_LABEL(end_label)) {
     406           0 :                         vty_out(vty, "%% Invalid label\n");
     407           0 :                         return CMD_WARNING_CONFIG_FAILED;
     408             :                 }
     409           0 :                 if (end_label < start_label) {
     410           0 :                         vty_out(vty, "%% End label is less than Start label\n");
     411           0 :                         return CMD_WARNING_CONFIG_FAILED;
     412             :                 }
     413             : 
     414           0 :                 ret = zebra_mpls_label_block_add(zvrf, start_label, end_label);
     415             :         } else
     416           0 :                 ret = zebra_mpls_label_block_del(zvrf);
     417             : 
     418           0 :         if (ret) {
     419           0 :                 vty_out(vty, "%% Global label block could not be %s\n",
     420             :                         add_cmd ? "added" : "deleted");
     421           0 :                 return CMD_WARNING_CONFIG_FAILED;
     422             :         }
     423             : 
     424             :         return CMD_SUCCESS;
     425             : }
     426             : 
     427           0 : DEFUN (mpls_label_global_block,
     428             :        mpls_label_global_block_cmd,
     429             :        "mpls label global-block (16-1048575) (16-1048575)",
     430             :        MPLS_STR
     431             :        "Label configuration\n"
     432             :        "Configure global label block\n"
     433             :        "Start label\n"
     434             :        "End label\n")
     435             : {
     436           0 :         return zebra_mpls_global_block(vty, 1, argv[3]->arg, argv[4]->arg);
     437             : }
     438             : 
     439           0 : DEFUN (no_mpls_label_global_block,
     440             :        no_mpls_label_global_block_cmd,
     441             :        "no mpls label global-block [(16-1048575) (16-1048575)]",
     442             :        NO_STR
     443             :        MPLS_STR
     444             :        "Label configuration\n"
     445             :        "Configure global label block\n"
     446             :        "Start label\n"
     447             :        "End label\n")
     448             : {
     449           0 :         return zebra_mpls_global_block(vty, 0, NULL, NULL);
     450             : }
     451             : 
     452             : static int zebra_mpls_config(struct vty *vty);
     453             : /* MPLS node for MPLS LSP. */
     454             : static struct cmd_node mpls_node = {
     455             :         .name = "mpls",
     456             :         .node = MPLS_NODE,
     457             :         .prompt = "",
     458             :         .config_write = zebra_mpls_config,
     459             : };
     460             : 
     461             : /* MPLS VTY.  */
     462          79 : void zebra_mpls_vty_init(void)
     463             : {
     464          79 :         install_element(VIEW_NODE, &show_mpls_status_cmd);
     465             : 
     466          79 :         install_node(&mpls_node);
     467             : 
     468          79 :         install_element(CONFIG_NODE, &mpls_transit_lsp_cmd);
     469          79 :         install_element(CONFIG_NODE, &no_mpls_transit_lsp_cmd);
     470          79 :         install_element(CONFIG_NODE, &no_mpls_transit_lsp_out_label_cmd);
     471          79 :         install_element(CONFIG_NODE, &no_mpls_transit_lsp_all_cmd);
     472             : 
     473          79 :         install_element(CONFIG_NODE, &mpls_label_bind_cmd);
     474          79 :         install_element(CONFIG_NODE, &no_mpls_label_bind_cmd);
     475             : 
     476          79 :         install_element(CONFIG_NODE, &mpls_label_global_block_cmd);
     477          79 :         install_element(CONFIG_NODE, &no_mpls_label_global_block_cmd);
     478             : 
     479          79 :         install_element(VIEW_NODE, &show_mpls_table_cmd);
     480          79 :         install_element(VIEW_NODE, &show_mpls_table_lsp_cmd);
     481          79 :         install_element(VIEW_NODE, &show_mpls_fec_cmd);
     482          79 : }

Generated by: LCOV version v1.16-topotato