diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 3114893c9d..0c29254f3f 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -4220,7 +4220,8 @@ bgp_static_update_safi (struct bgp *bgp, struct prefix *p, route should be installed as valid. */ static int bgp_static_set (struct vty *vty, const char *ip_str, - afi_t afi, safi_t safi, const char *rmap, int backdoor) + afi_t afi, safi_t safi, const char *rmap, int backdoor, + u_int32_t label_index) { VTY_DECLVAR_CONTEXT(bgp, bgp); int ret; @@ -4253,6 +4254,13 @@ bgp_static_set (struct vty *vty, const char *ip_str, /* Configuration change. */ bgp_static = rn->info; + /* Label index cannot be changed. */ + if (bgp_static->label_index != label_index) + { + vty_out (vty, "%% Label index cannot be changed%s", VTY_NEWLINE); + return CMD_WARNING; + } + /* Check previous routes are installed into BGP. */ if (bgp_static->valid && bgp_static->backdoor != backdoor) need_update = 1; @@ -4284,6 +4292,7 @@ bgp_static_set (struct vty *vty, const char *ip_str, bgp_static->valid = 0; bgp_static->igpmetric = 0; bgp_static->igpnexthop.s_addr = 0; + bgp_static->label_index = label_index; if (rmap) { @@ -4810,7 +4819,8 @@ DEFUN (bgp_network, { int idx_ipv4_prefixlen = 1; return bgp_static_set (vty, argv[idx_ipv4_prefixlen]->arg, - AFI_IP, bgp_node_safi (vty), NULL, 0); + AFI_IP, bgp_node_safi (vty), NULL, 0, + BGP_INVALID_LABEL_INDEX); } DEFUN (bgp_network_route_map, @@ -4824,7 +4834,8 @@ DEFUN (bgp_network_route_map, int idx_ipv4_prefixlen = 1; int idx_word = 3; return bgp_static_set (vty, argv[idx_ipv4_prefixlen]->arg, - AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0); + AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0, + BGP_INVALID_LABEL_INDEX); } DEFUN (bgp_network_backdoor, @@ -4836,7 +4847,7 @@ DEFUN (bgp_network_backdoor, { int idx_ipv4_prefixlen = 1; return bgp_static_set (vty, argv[idx_ipv4_prefixlen]->arg, AFI_IP, SAFI_UNICAST, - NULL, 1); + NULL, 1, BGP_INVALID_LABEL_INDEX); } DEFUN (bgp_network_mask, @@ -4860,7 +4871,7 @@ DEFUN (bgp_network_mask, } return bgp_static_set (vty, prefix_str, - AFI_IP, bgp_node_safi (vty), NULL, 0); + AFI_IP, bgp_node_safi (vty), NULL, 0, BGP_INVALID_LABEL_INDEX); } DEFUN (bgp_network_mask_route_map, @@ -4887,7 +4898,7 @@ DEFUN (bgp_network_mask_route_map, } return bgp_static_set (vty, prefix_str, - AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0); + AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0, BGP_INVALID_LABEL_INDEX); } DEFUN (bgp_network_mask_backdoor, @@ -4912,7 +4923,8 @@ DEFUN (bgp_network_mask_backdoor, } return bgp_static_set (vty, prefix_str, AFI_IP, SAFI_UNICAST, - NULL, 1); + NULL, 1, + BGP_INVALID_LABEL_INDEX); } DEFUN (bgp_network_mask_natural, @@ -4933,7 +4945,8 @@ DEFUN (bgp_network_mask_natural, } return bgp_static_set (vty, prefix_str, - AFI_IP, bgp_node_safi (vty), NULL, 0); + AFI_IP, bgp_node_safi (vty), NULL, 0, + BGP_INVALID_LABEL_INDEX); } DEFUN (bgp_network_mask_natural_route_map, @@ -4957,7 +4970,8 @@ DEFUN (bgp_network_mask_natural_route_map, } return bgp_static_set (vty, prefix_str, - AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0); + AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0, + BGP_INVALID_LABEL_INDEX); } DEFUN (bgp_network_mask_natural_backdoor, @@ -4979,7 +4993,39 @@ DEFUN (bgp_network_mask_natural_backdoor, } return bgp_static_set (vty, prefix_str, AFI_IP, SAFI_UNICAST, - NULL, 1); + NULL, 1, BGP_INVALID_LABEL_INDEX); +} + +DEFUN (bgp_network_label_index, + bgp_network_label_index_cmd, + "network A.B.C.D/M label-index (0-4294967294)", + "Specify a network to announce via BGP\n" + "IP prefix /, e.g., 35.0.0.0/8\n" + "Label index to associate with the prefix\n" + "Label index value\n") +{ + u_int32_t label_index; + + VTY_GET_INTEGER ("label-index", label_index, argv[3]->arg); + return bgp_static_set (vty, argv[1]->arg, + AFI_IP, bgp_node_safi (vty), NULL, 0, label_index); +} + +DEFUN (bgp_network_label_index_route_map, + bgp_network_label_index_route_map_cmd, + "network A.B.C.D/M label-index (0-4294967294) route-map WORD", + "Specify a network to announce via BGP\n" + "IP prefix\n" + "Label index to associate with the prefix\n" + "Label index value\n" + "Route-map to modify the attributes\n" + "Name of the route map\n") +{ + u_int32_t label_index; + + VTY_GET_INTEGER ("label-index", label_index, argv[3]->arg); + return bgp_static_set (vty, argv[1]->arg, + AFI_IP, bgp_node_safi (vty), argv[5]->arg, 0, label_index); } DEFUN (no_bgp_network, @@ -5050,6 +5096,26 @@ DEFUN (no_bgp_network_mask_natural, bgp_node_safi (vty)); } +ALIAS (no_bgp_network, + no_bgp_network_label_index_cmd, + "no network A.B.C.D/M label-index (0-4294967294)", + NO_STR + "Specify a network to announce via BGP\n" + "IP prefix /, e.g., 35.0.0.0/8\n" + "Label index to associate with the prefix\n" + "Label index value\n") + +ALIAS (no_bgp_network, + no_bgp_network_label_index_route_map_cmd, + "no network A.B.C.D/M label-index (0-4294967294)route-map WORD", + NO_STR + "Specify a network to announce via BGP\n" + "IP prefix\n" + "Label index to associate with the prefix\n" + "Label index value\n" + "Route-map to modify the attributes\n" + "Name of the route map\n") + DEFUN (ipv6_bgp_network, ipv6_bgp_network_cmd, "network X:X::X:X/M", @@ -5058,7 +5124,8 @@ DEFUN (ipv6_bgp_network, { int idx_ipv6_prefixlen = 1; return bgp_static_set (vty, argv[idx_ipv6_prefixlen]->arg, AFI_IP6, bgp_node_safi(vty), - NULL, 0); + NULL, 0, + BGP_INVALID_LABEL_INDEX); } DEFUN (ipv6_bgp_network_route_map, @@ -5072,7 +5139,40 @@ DEFUN (ipv6_bgp_network_route_map, int idx_ipv6_prefixlen = 1; int idx_word = 3; return bgp_static_set (vty, argv[idx_ipv6_prefixlen]->arg, AFI_IP6, - bgp_node_safi (vty), argv[idx_word]->arg, 0); + bgp_node_safi (vty), argv[idx_word]->arg, 0, + BGP_INVALID_LABEL_INDEX); +} + +DEFUN (ipv6_bgp_network_label_index, + ipv6_bgp_network_label_index_cmd, + "network X:X::X:X/M label-index (0-4294967294)", + "Specify a network to announce via BGP\n" + "IPv6 prefix /\n" + "Label index to associate with the prefix\n" + "Label index value\n") +{ + u_int32_t label_index; + + VTY_GET_INTEGER ("label-index", label_index, argv[3]->arg); + return bgp_static_set (vty, argv[1]->arg, + AFI_IP6, bgp_node_safi (vty), NULL, 0, label_index); +} + +DEFUN (ipv6_bgp_network_label_index_route_map, + ipv6_bgp_network_label_index_route_map_cmd, + "network X:X::X:X/M label-index (0-4294967294) route-map WORD", + "Specify a network to announce via BGP\n" + "IPv6 prefix\n" + "Label index to associate with the prefix\n" + "Label index value\n" + "Route-map to modify the attributes\n" + "Name of the route map\n") +{ + u_int32_t label_index; + + VTY_GET_INTEGER ("label-index", label_index, argv[3]->arg); + return bgp_static_set (vty, argv[1]->arg, + AFI_IP6, bgp_node_safi (vty), argv[5]->arg, 0, label_index); } DEFUN (no_ipv6_bgp_network, @@ -5088,6 +5188,26 @@ DEFUN (no_ipv6_bgp_network, return bgp_static_unset (vty, argv[idx_ipv6_prefixlen]->arg, AFI_IP6, bgp_node_safi(vty)); } +ALIAS (no_ipv6_bgp_network, + no_ipv6_bgp_network_label_index_cmd, + "no network X:X::X:X/M label-index (0-4294967294)", + NO_STR + "Specify a network to announce via BGP\n" + "IPv6 prefix /\n" + "Label index to associate with the prefix\n" + "Label index value\n") + +ALIAS (no_ipv6_bgp_network, + no_ipv6_bgp_network_label_index_route_map_cmd, + "no network X:X::X:X/M label-index (0-4294967294) route-map WORD", + NO_STR + "Specify a network to announce via BGP\n" + "IPv6 prefix\n" + "Label index to associate with the prefix\n" + "Label index value\n" + "Route-map to modify the attributes\n" + "Name of the route map\n") + /* Aggreagete address: advertise-map Set condition to advertise attribute @@ -10621,6 +10741,9 @@ bgp_config_write_network (struct vty *vty, struct bgp *bgp, p->prefixlen); } + if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) + vty_out (vty, " label-index %u", bgp_static->label_index); + if (bgp_static->rmap.name) vty_out (vty, " route-map %s", bgp_static->rmap.name); else @@ -10747,6 +10870,8 @@ bgp_route_init (void) install_element (BGP_IPV4_NODE, &bgp_network_route_map_cmd); install_element (BGP_IPV4_NODE, &bgp_network_mask_route_map_cmd); install_element (BGP_IPV4_NODE, &bgp_network_mask_natural_route_map_cmd); + install_element (BGP_IPV4_NODE, &no_bgp_network_label_index_cmd); + install_element (BGP_IPV4_NODE, &no_bgp_network_label_index_route_map_cmd); install_element (BGP_IPV4_NODE, &no_bgp_table_map_cmd); install_element (BGP_IPV4_NODE, &no_bgp_network_cmd); install_element (BGP_IPV4_NODE, &no_bgp_network_mask_cmd); @@ -10782,6 +10907,8 @@ bgp_route_init (void) install_element (BGP_IPV4L_NODE, &bgp_network_route_map_cmd); install_element (BGP_IPV4L_NODE, &bgp_network_mask_route_map_cmd); install_element (BGP_IPV4L_NODE, &bgp_network_mask_natural_route_map_cmd); + install_element (BGP_IPV4L_NODE, &bgp_network_label_index_cmd); + install_element (BGP_IPV4L_NODE, &bgp_network_label_index_route_map_cmd); install_element (BGP_IPV4L_NODE, &no_bgp_table_map_cmd); install_element (BGP_IPV4L_NODE, &no_bgp_network_cmd); install_element (BGP_IPV4L_NODE, &no_bgp_network_mask_cmd); @@ -10820,6 +10947,10 @@ bgp_route_init (void) install_element (BGP_IPV6_NODE, &ipv6_bgp_network_route_map_cmd); install_element (BGP_IPV6_NODE, &no_bgp_table_map_cmd); install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_cmd); + install_element (BGP_IPV6_NODE, &ipv6_bgp_network_label_index_cmd); + install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_label_index_cmd); + install_element (BGP_IPV6_NODE, &ipv6_bgp_network_label_index_route_map_cmd); + install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_label_index_route_map_cmd); install_element (BGP_IPV6_NODE, &ipv6_aggregate_address_cmd); install_element (BGP_IPV6_NODE, &no_ipv6_aggregate_address_cmd); diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 69b8ea8a55..35994d4f76 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -180,6 +180,10 @@ struct bgp_static /* Backdoor configuration. */ int backdoor; + /* Label index configuration; applies to LU prefixes. */ + u_int32_t label_index; +#define BGP_INVALID_LABEL_INDEX 0xFFFFFFFF + /* Import check status. */ u_char valid; diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index f13a3f4f0a..85ce147d25 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -2735,6 +2735,45 @@ zebra_mpls_write_lsp_config (struct vty *vty, struct zebra_vrf *zvrf) return (zvrf->slsp_table->count ? 1 : 0); } +/* + * Add/update global label block. + */ +int +zebra_mpls_label_block_add (struct zebra_vrf *zvrf, u_int32_t start_label, + u_int32_t end_label) +{ + zvrf->mpls_srgb.start_label = start_label; + zvrf->mpls_srgb.end_label = end_label; + return 0; +} + +/* + * Delete global label block. + */ +int +zebra_mpls_label_block_del (struct zebra_vrf *zvrf) +{ + zvrf->mpls_srgb.start_label = 0; + zvrf->mpls_srgb.end_label = 0; + return 0; +} + +/* + * Display MPLS global label block configuration (VTY command handler). + */ +int +zebra_mpls_write_label_block_config (struct vty *vty, struct zebra_vrf *zvrf) +{ + if (zvrf->mpls_srgb.start_label == 0) + return 0; + + vty_out(vty, "mpls label global-block %u %u%s", + zvrf->mpls_srgb.start_label, zvrf->mpls_srgb.end_label, + VTY_NEWLINE); + + return 1; +} + /* * Called upon process exiting, need to delete LSP forwarding * entries from the kernel. @@ -2764,6 +2803,8 @@ zebra_mpls_init_tables (struct zebra_vrf *zvrf) zvrf->fec_table[AFI_IP] = route_table_init(); zvrf->fec_table[AFI_IP6] = route_table_init(); zvrf->mpls_flags = 0; + zvrf->mpls_srgb.start_label = 0; + zvrf->mpls_srgb.end_label = 0; } /* diff --git a/zebra/zebra_mpls.h b/zebra/zebra_mpls.h index f9d58a46e8..f8e95fa100 100644 --- a/zebra/zebra_mpls.h +++ b/zebra/zebra_mpls.h @@ -183,6 +183,25 @@ char * mpls_label2str (u_int8_t num_labels, mpls_label_t *labels, char *buf, int len); +/* + * Add/update global label block. + */ +int +zebra_mpls_label_block_add (struct zebra_vrf *zvrf, u_int32_t start_label, + u_int32_t end_label); + +/* + * Delete global label block. + */ +int +zebra_mpls_label_block_del (struct zebra_vrf *vrf); + +/* + * Display MPLS global label block configuration (VTY command handler). + */ +int +zebra_mpls_write_label_block_config (struct vty *vty, struct zebra_vrf *vrf); + /* * Install dynamic LSP entry. */ diff --git a/zebra/zebra_mpls_null.c b/zebra/zebra_mpls_null.c index d6f99b5178..12176c024e 100644 --- a/zebra/zebra_mpls_null.c +++ b/zebra/zebra_mpls_null.c @@ -44,6 +44,25 @@ mpls_str2label (const char *label_str, u_int8_t *num_labels, return 0; } +int +zebra_mpls_label_block_add (struct zebra_vrf *vrf, u_int32_t start_label, + u_int32_t end_label) +{ + return 0; +} + +int +zebra_mpls_label_block_del (struct zebra_vrf *zvrf) +{ + return 0; +} + +int +zebra_mpls_write_label_block_config (struct vty *vty, struct zebra_vrf *zvrf) +{ + return 0; +} + int zebra_mpls_lsp_install (struct zebra_vrf *zvrf, struct route_node *rn, struct rib *rib) { diff --git a/zebra/zebra_mpls_vty.c b/zebra/zebra_mpls_vty.c index 8d8025682a..f46037487e 100644 --- a/zebra/zebra_mpls_vty.c +++ b/zebra/zebra_mpls_vty.c @@ -873,6 +873,7 @@ zebra_mpls_config (struct vty *vty) write += zebra_mpls_write_lsp_config(vty, zvrf); write += zebra_mpls_write_fec_config(vty, zvrf); + write += zebra_mpls_write_label_block_config (vty, zvrf); return write; } @@ -957,6 +958,85 @@ DEFUN (show_mpls_status, return CMD_SUCCESS; } +static int +zebra_mpls_global_block (struct vty *vty, int add_cmd, + const char *start_label_str, const char *end_label_str) +{ + int ret; + u_int32_t start_label; + u_int32_t end_label; + struct zebra_vrf *zvrf; + + zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT); + if (!zvrf) + { + vty_out (vty, "%% Default VRF does not exist%s", VTY_NEWLINE); + return CMD_WARNING; + } + + if (add_cmd) + { + if (!start_label_str || !end_label_str) + { + vty_out (vty, "%% Labels not specified%s", VTY_NEWLINE); + return CMD_WARNING; + } + + start_label = atoi(start_label_str); + end_label = atoi(end_label_str); + if (!IS_MPLS_UNRESERVED_LABEL(start_label) || + !IS_MPLS_UNRESERVED_LABEL(end_label)) + { + vty_out (vty, "%% Invalid label%s", VTY_NEWLINE); + return CMD_WARNING; + } + if (end_label < start_label) + { + vty_out (vty, "%% End label is less than Start label%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + ret = zebra_mpls_label_block_add (zvrf, start_label, end_label); + } + else + ret = zebra_mpls_label_block_del (zvrf); + + if (ret) + { + vty_out (vty, "%% Global label block could not be %s%s", + add_cmd ? "added" : "deleted", VTY_NEWLINE); + return CMD_WARNING; + } + + return CMD_SUCCESS; +} + +DEFUN (mpls_label_global_block, + mpls_label_global_block_cmd, + "mpls label global-block (16-1048575) (16-1048575)", + MPLS_STR + "Label configuration\n" + "Configure global label block\n" + "Start label\n" + "End label\n") +{ + return zebra_mpls_global_block (vty, 1, argv[3]->arg, argv[4]->arg); +} + +DEFUN (no_mpls_label_global_block, + no_mpls_label_global_block_cmd, + "no mpls label global-block [(16-1048575) (16-1048575)]", + NO_STR + MPLS_STR + "Label configuration\n" + "Configure global label block\n" + "Start label\n" + "End label\n") +{ + return zebra_mpls_global_block (vty, 0, NULL, NULL); +} + /* MPLS node for MPLS LSP. */ static struct cmd_node mpls_node = { MPLS_NODE, "", 1 }; @@ -1009,6 +1089,9 @@ zebra_mpls_vty_init (void) install_element (CONFIG_NODE, &mpls_label_bind_cmd); install_element (CONFIG_NODE, &no_mpls_label_bind_cmd); + install_element (CONFIG_NODE, &mpls_label_global_block_cmd); + install_element (CONFIG_NODE, &no_mpls_label_global_block_cmd); + install_element (VIEW_NODE, &show_mpls_table_cmd); install_element (VIEW_NODE, &show_mpls_table_lsp_cmd); install_element (VIEW_NODE, &show_mpls_fec_cmd); diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h index 8333ca27d7..74c2a52171 100644 --- a/zebra/zebra_vrf.h +++ b/zebra/zebra_vrf.h @@ -25,6 +25,13 @@ #include +/* MPLS (Segment Routing) global block */ +typedef struct mpls_srgb_t_ +{ + u_int32_t start_label; + u_int32_t end_label; +} mpls_srgb_t; + /* Routing table instance. */ struct zebra_vrf { @@ -82,6 +89,9 @@ struct zebra_vrf /* MPLS FEC binding table */ struct route_table *fec_table[AFI_MAX]; + /* MPLS Segment Routing Global block */ + mpls_srgb_t mpls_srgb; + /* MPLS processing flags */ u_int16_t mpls_flags; #define MPLS_FLAG_SCHEDULE_LSPS (1 << 0)