From 42998828c9bfa419ff3d9c68fd50cd148e24d4e4 Mon Sep 17 00:00:00 2001 From: Pablo Camarillo Date: Thu, 13 Jul 2017 09:41:32 +0200 Subject: SR-MPLS: binary API and automated steering Change-Id: Iacfbaaa91ea8bd92790dec9fce567063bdbc5d64 Signed-off-by: Pablo Camarillo --- src/vnet/srmpls/sr_mpls_policy.c | 549 ++++++++++++++++++++++++++++++--------- 1 file changed, 430 insertions(+), 119 deletions(-) (limited to 'src/vnet/srmpls/sr_mpls_policy.c') diff --git a/src/vnet/srmpls/sr_mpls_policy.c b/src/vnet/srmpls/sr_mpls_policy.c index db4ad2a7f1b..d75f2d1e22f 100755 --- a/src/vnet/srmpls/sr_mpls_policy.c +++ b/src/vnet/srmpls/sr_mpls_policy.c @@ -1,18 +1,17 @@ /* * sr_mpls_policy.c: SR-MPLS policies * - * Copyright (c) 2016 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: + * Copyright (c) 2016 Cisco and/or its affiliates. Licensed under the Apache + * License, Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at: * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. */ /** @@ -26,17 +25,19 @@ * An SR policy has associated a BindingSID. * In case any packet arrives with MPLS_label == BindingSID then the SR policy * associated to such bindingSID will be applied to such packet. + * Also, a BSID can be associated with a (Next-Hop, Color) * */ #include #include -#include +#include #include #include #include #include #include +#include #include #include @@ -92,15 +93,15 @@ create_sl (mpls_sr_policy_t * sr_policy, mpls_label_t * sl, u32 weight) mpls_eos_bit_t eos; FOR_EACH_MPLS_EOS_BIT (eos) { - /* *INDENT-OFF* */ - fib_prefix_t pfx = { - .fp_len = 21, - .fp_proto = FIB_PROTOCOL_MPLS, - .fp_label = sr_policy->bsid, - .fp_eos = eos, - .fp_payload_proto = DPO_PROTO_MPLS, - }; - /* *INDENT-ON* */ + /* *INDENT-OFF* */ + fib_prefix_t pfx = { + .fp_len = 21, + .fp_proto = FIB_PROTOCOL_MPLS, + .fp_label = sr_policy->bsid, + .fp_eos = eos, + .fp_payload_proto = DPO_PROTO_MPLS, + }; + /* *INDENT-ON* */ fib_table_entry_path_add2 (0, &pfx, @@ -116,11 +117,11 @@ create_sl (mpls_sr_policy_t * sr_policy, mpls_label_t * sl, u32 weight) } /******************************* SR rewrite API *******************************/ -/* Three functions for handling sr policies: - * -> sr_mpls_policy_add - * -> sr_mpls_policy_del - * -> sr_mpls_policy_mod - * All of them are API. CLI function on sr_policy_command_fn */ +/* + * Three functions for handling sr policies: -> sr_mpls_policy_add -> + * sr_mpls_policy_del -> sr_mpls_policy_mod All of them are API. CLI function + * on sr_policy_command_fn + */ /** * @brief Create a new SR policy @@ -141,6 +142,9 @@ sr_mpls_policy_add (mpls_label_t bsid, mpls_label_t * segments, mpls_sr_policy_t *sr_policy = 0; uword *p; + if (!sm->sr_policies_index_hash) + sm->sr_policies_index_hash = hash_create (0, sizeof (mpls_label_t)); + /* Search for existing keys (BSID) */ p = hash_get (sm->sr_policies_index_hash, bsid); if (p) @@ -148,12 +152,14 @@ sr_mpls_policy_add (mpls_label_t bsid, mpls_label_t * segments, /* Add SR policy that already exists; complain */ return -12; } - /* Add an SR policy object */ pool_get (sm->sr_policies, sr_policy); memset (sr_policy, 0, sizeof (*sr_policy)); sr_policy->bsid = bsid; sr_policy->type = behavior; + sr_policy->endpoint_type = 0; + ip6_address_set_zero (&sr_policy->endpoint.ip6); + sr_policy->color = (u32) ~ 0; /* Copy the key */ hash_set (sm->sr_policies_index_hash, bsid, sr_policy - sm->sr_policies); @@ -173,7 +179,7 @@ sr_mpls_policy_add (mpls_label_t bsid, mpls_label_t * segments, * @return 0 if correct, else error */ int -sr_mpls_policy_del (mpls_label_t bsid, u32 index) +sr_mpls_policy_del (mpls_label_t bsid) { mpls_sr_main_t *sm = &sr_mpls_main; mpls_sr_policy_t *sr_policy = 0; @@ -182,20 +188,14 @@ sr_mpls_policy_del (mpls_label_t bsid, u32 index) u32 *sl_index; uword *p; - if (bsid) - { - p = hash_get (sm->sr_policies_index_hash, bsid); - if (p) - sr_policy = pool_elt_at_index (sm->sr_policies, p[0]); - else - return -1; - } + if (!sm->sr_policies_index_hash) + sm->sr_policies_index_hash = hash_create (0, sizeof (mpls_label_t)); + + p = hash_get (sm->sr_policies_index_hash, bsid); + if (p) + sr_policy = pool_elt_at_index (sm->sr_policies, p[0]); else - { - sr_policy = pool_elt_at_index (sm->sr_policies, index); - if (!sr_policy) - return -1; - } + return -1; /* Clean SID Lists */ vec_foreach (sl_index, sr_policy->segments_lists) @@ -211,21 +211,24 @@ sr_mpls_policy_del (mpls_label_t bsid, u32 index) .frp_local_label = segment_list->segments[0], }; + vec_add (path.frp_label_stack, segment_list + 1, + vec_len (segment_list) - 1); + fib_route_path_t *paths = NULL; vec_add1 (paths, path); /* remove each of the MPLS routes */ FOR_EACH_MPLS_EOS_BIT (eos) { - /* *INDENT-OFF* */ - fib_prefix_t pfx = { - .fp_len = 21, - .fp_proto = FIB_PROTOCOL_MPLS, - .fp_label = sr_policy->bsid, - .fp_eos = eos, - .fp_payload_proto = DPO_PROTO_MPLS, - }; - /* *INDENT-ON* */ + /* *INDENT-OFF* */ + fib_prefix_t pfx = { + .fp_len = 21, + .fp_proto = FIB_PROTOCOL_MPLS, + .fp_label = sr_policy->bsid, + .fp_eos = eos, + .fp_payload_proto = DPO_PROTO_MPLS, + }; + /* *INDENT-ON* */ fib_table_entry_path_remove2 (0, &pfx, FIB_SOURCE_SR, paths); } @@ -234,6 +237,12 @@ sr_mpls_policy_del (mpls_label_t bsid, u32 index) pool_put_index (sm->sid_lists, *sl_index); } + /* If there is still traces of TE, make sure locks are released */ + if (sr_policy->endpoint_type != 0 && sr_policy->color != (u32) ~ 0) + { + sr_mpls_policy_assign_endpoint_color (bsid, NULL, 0, (u32) ~ 0); + } + /* Remove SR policy entry */ hash_unset (sm->sr_policies_index_hash, sr_policy->bsid); pool_put (sm->sr_policies, sr_policy); @@ -249,17 +258,16 @@ sr_mpls_policy_del (mpls_label_t bsid, u32 index) * Segment List from the SR Policy. * * @param bsid is the bindingSID of the SR Policy - * @param index is the index of the SR policy * @param fib_table is the VRF where to install the FIB entry for the BSID * @param operation is the operation to perform (among the top ones) * @param segments is a vector of IPv6 address composing the segment list * @param sl_index is the index of the Segment List to modify/delete * @param weight is the weight of the sid list. optional. * - * @return 0 if correct, else error + * @return 0 ok, >0 index of SL, <0 error */ int -sr_mpls_policy_mod (mpls_label_t bsid, u32 index, u8 operation, +sr_mpls_policy_mod (mpls_label_t bsid, u8 operation, mpls_label_t * segments, u32 sl_index, u32 weight) { mpls_sr_main_t *sm = &sr_mpls_main; @@ -268,34 +276,32 @@ sr_mpls_policy_mod (mpls_label_t bsid, u32 index, u8 operation, u32 *sl_index_iterate; uword *p; - if (bsid) - { - p = hash_get (sm->sr_policies_index_hash, bsid); - if (p) - sr_policy = pool_elt_at_index (sm->sr_policies, p[0]); - else - return -1; - } + if (!sm->sr_policies_index_hash) + sm->sr_policies_index_hash = hash_create (0, sizeof (mpls_label_t)); + + p = hash_get (sm->sr_policies_index_hash, bsid); + if (p) + sr_policy = pool_elt_at_index (sm->sr_policies, p[0]); else - { - sr_policy = pool_elt_at_index (sm->sr_policies, index); - if (!sr_policy) - return -1; - } + return -1; - if (operation == 1) /* Add SR List to an existing SR policy */ - { + if (operation == 1) + { /* Add SR List to an existing SR policy */ /* Create the new SL */ segment_list = create_sl (sr_policy, segments, weight); - + return segment_list - sm->sid_lists; } - else if (operation == 2) /* Delete SR List from an existing SR policy */ - { + else if (operation == 2) + { /* Delete SR List from an existing SR + * policy */ /* Check that currently there are more than one SID list */ if (vec_len (sr_policy->segments_lists) == 1) return -21; - /* Check that the SR list does exist and is assigned to the sr policy */ + /* + * Check that the SR list does exist and is assigned to the + * sr policy + */ vec_foreach (sl_index_iterate, sr_policy->segments_lists) if (*sl_index_iterate == sl_index) break; @@ -316,20 +322,23 @@ sr_mpls_policy_mod (mpls_label_t bsid, u32 index, u8 operation, .frp_local_label = segment_list->segments[0], }; + vec_add (path.frp_label_stack, segment_list + 1, + vec_len (segment_list) - 1); + fib_route_path_t *paths = NULL; vec_add1 (paths, path); FOR_EACH_MPLS_EOS_BIT (eos) { - /* *INDENT-OFF* */ - fib_prefix_t pfx = { - .fp_len = 21, - .fp_proto = FIB_PROTOCOL_MPLS, - .fp_label = sr_policy->bsid, - .fp_eos = eos, - .fp_payload_proto = DPO_PROTO_MPLS, - }; - /* *INDENT-ON* */ + /* *INDENT-OFF* */ + fib_prefix_t pfx = { + .fp_len = 21, + .fp_proto = FIB_PROTOCOL_MPLS, + .fp_label = sr_policy->bsid, + .fp_eos = eos, + .fp_payload_proto = DPO_PROTO_MPLS, + }; + /* *INDENT-ON* */ fib_table_entry_path_remove2 (0, &pfx, FIB_SOURCE_SR, paths); } @@ -340,8 +349,9 @@ sr_mpls_policy_mod (mpls_label_t bsid, u32 index, u8 operation, vec_del1 (sr_policy->segments_lists, sl_index_iterate - sr_policy->segments_lists); } - else if (operation == 3) /* Modify the weight of an existing SR List */ - { + else if (operation == 3) + { /* Modify the weight of an existing + * SR List */ /* Find the corresponding SL */ vec_foreach (sl_index_iterate, sr_policy->segments_lists) if (*sl_index_iterate == sl_index) @@ -352,10 +362,67 @@ sr_mpls_policy_mod (mpls_label_t bsid, u32 index, u8 operation, /* Change the weight */ segment_list = pool_elt_at_index (sm->sid_lists, sl_index); - segment_list->weight = weight; /* Update LB */ - //FIXME + mpls_eos_bit_t eos; + fib_route_path_t path = { + .frp_proto = DPO_PROTO_MPLS, + .frp_sw_if_index = ~0, + .frp_fib_index = 0, + .frp_weight = segment_list->weight, + .frp_flags = FIB_ROUTE_PATH_FLAG_NONE, + .frp_local_label = segment_list->segments[0], + }; + + vec_add (path.frp_label_stack, segment_list + 1, + vec_len (segment_list) - 1); + + fib_route_path_t *paths = NULL; + vec_add1 (paths, path); + + FOR_EACH_MPLS_EOS_BIT (eos) + { + /* *INDENT-OFF* */ + fib_prefix_t pfx = { + .fp_len = 21, + .fp_proto = FIB_PROTOCOL_MPLS, + .fp_label = sr_policy->bsid, + .fp_eos = eos, + .fp_payload_proto = DPO_PROTO_MPLS, + }; + /* *INDENT-ON* */ + + fib_table_entry_path_remove2 (0, &pfx, FIB_SOURCE_SR, paths); + } + + segment_list->weight = weight; + + path.frp_weight = segment_list->weight; + + vec_free (paths); + paths = NULL; + vec_add1 (paths, path); + + FOR_EACH_MPLS_EOS_BIT (eos) + { + /* *INDENT-OFF* */ + fib_prefix_t pfx = { + .fp_len = 21, + .fp_proto = FIB_PROTOCOL_MPLS, + .fp_label = sr_policy->bsid, + .fp_eos = eos, + .fp_payload_proto = DPO_PROTO_MPLS, + }; + /* *INDENT-ON* */ + + fib_table_entry_path_add2 (0, + &pfx, + FIB_SOURCE_SR, + (sr_policy->type == + SR_POLICY_TYPE_DEFAULT ? + FIB_ENTRY_FLAG_NONE : + FIB_ENTRY_FLAG_MULTICAST), paths); + } } return 0; } @@ -371,7 +438,7 @@ sr_mpls_policy_command_fn (vlib_main_t * vm, unformat_input_t * input, char is_del = 0, is_add = 0, is_mod = 0; char policy_set = 0; mpls_label_t bsid, next_label; - u32 sr_policy_index = (u32) ~ 0, sl_index = (u32) ~ 0; + u32 sl_index = (u32) ~ 0; u32 weight = (u32) ~ 0; mpls_label_t *segments = 0; u8 operation = 0; @@ -389,13 +456,9 @@ sr_mpls_policy_command_fn (vlib_main_t * vm, unformat_input_t * input, && unformat (input, "bsid %U", unformat_mpls_unicast_label, &bsid)) policy_set = 1; - else if (!is_add && !policy_set - && unformat (input, "index %d", &sr_policy_index)) - policy_set = 1; else if (unformat (input, "weight %d", &weight)); - else - if (unformat - (input, "next %U", unformat_mpls_unicast_label, &next_label)) + else if (unformat + (input, "next %U", unformat_mpls_unicast_label, &next_label)) { vec_add (segments, &next_label, 1); } @@ -427,9 +490,7 @@ sr_mpls_policy_command_fn (vlib_main_t * vm, unformat_input_t * input, SR_POLICY_TYPE_DEFAULT), weight); } else if (is_del) - rv = - sr_mpls_policy_del ((sr_policy_index != (u32) ~ 0 ? (u32) ~ 0 : bsid), - sr_policy_index); + rv = sr_mpls_policy_del (bsid); else if (is_mod) { if (!operation) @@ -440,12 +501,8 @@ sr_mpls_policy_command_fn (vlib_main_t * vm, unformat_input_t * input, return clib_error_return (0, "No Segment List specified"); if (operation == 3 && weight == (u32) ~ 0) return clib_error_return (0, "No new weight for the SL specified"); - rv = - sr_mpls_policy_mod ((sr_policy_index != (u32) ~ 0 ? (u32) ~ 0 : bsid), - sr_policy_index, operation, segments, - sl_index, weight); + rv = sr_mpls_policy_mod (bsid, operation, segments, sl_index, weight); } - switch (rv) { case 0: @@ -464,6 +521,10 @@ sr_mpls_policy_command_fn (vlib_main_t * vm, unformat_input_t * input, return clib_error_return (0, "Could not delete the segment list. " "It is not associated with that SR policy."); + case -23: + return clib_error_return (0, + "Could not delete the segment list. " + "It is not associated with that SR policy."); case -32: return clib_error_return (0, "Could not modify the segment list. " @@ -475,12 +536,13 @@ sr_mpls_policy_command_fn (vlib_main_t * vm, unformat_input_t * input, } /* *INDENT-OFF* */ -VLIB_CLI_COMMAND (sr_mpls_policy_command, static) = { - .path = "sr mpls policy", - .short_help = "sr mpls policy [add||del||mod] bsid 2999 " - "next 10 next 20 next 30 (weight 1) (spray)", - .long_help = "TBD.\n", - .function = sr_mpls_policy_command_fn, +VLIB_CLI_COMMAND(sr_mpls_policy_command, static)= +{ + .path = "sr mpls policy", + .short_help = "sr mpls policy [add||del||mod] bsid 2999 " + "next 10 next 20 next 30 (weight 1) (spray)", + .long_help = "TBD.\n", + .function = sr_mpls_policy_command_fn, }; /* *INDENT-ON* */ @@ -502,9 +564,11 @@ show_sr_mpls_policies_command_fn (vlib_main_t * vm, unformat_input_t * input, vlib_cli_output (vm, "SR MPLS policies:"); - /* *INDENT-OFF* */ - pool_foreach (sr_policy, sm->sr_policies, {vec_add1 (vec_policies, sr_policy); } ); - /* *INDENT-ON* */ + /* *INDENT-OFF* */ + pool_foreach(sr_policy, sm->sr_policies, { + vec_add1(vec_policies, sr_policy); + }); + /* *INDENT-ON* */ vec_foreach_index (i, vec_policies) { @@ -512,6 +576,21 @@ show_sr_mpls_policies_command_fn (vlib_main_t * vm, unformat_input_t * input, vlib_cli_output (vm, "[%u].-\tBSID: %U", (u32) (sr_policy - sm->sr_policies), format_mpls_unicast_label, sr_policy->bsid); + switch (sr_policy->endpoint_type) + { + case SR_STEER_IPV6: + vlib_cli_output (vm, "\tEndpoint: %U", format_ip6_address, + &sr_policy->endpoint.ip6); + vlib_cli_output (vm, "\tColor: %u", sr_policy->color); + break; + case SR_STEER_IPV4: + vlib_cli_output (vm, "\tEndpoint: %U", format_ip4_address, + &sr_policy->endpoint.ip4); + vlib_cli_output (vm, "\tColor: %u", sr_policy->color); + break; + default: + vlib_cli_output (vm, "\tTE disabled"); + } vlib_cli_output (vm, "\tType: %s", (sr_policy->type == SR_POLICY_TYPE_DEFAULT ? "Default" : "Spray")); @@ -536,10 +615,244 @@ show_sr_mpls_policies_command_fn (vlib_main_t * vm, unformat_input_t * input, } /* *INDENT-OFF* */ -VLIB_CLI_COMMAND (show_sr_mpls_policies_command, static) = { - .path = "show sr mpls policies", - .short_help = "show sr mpls policies", - .function = show_sr_mpls_policies_command_fn, +VLIB_CLI_COMMAND(show_sr_mpls_policies_command, static)= +{ + .path = "show sr mpls policies", + .short_help = "show sr mpls policies", + .function = show_sr_mpls_policies_command_fn, +}; +/* *INDENT-ON* */ + +/** + * @brief Update the Endpoint,Color tuple of an SR policy + * + * @param bsid is the bindingSID of the SR Policy + * @param endpoint represents the IP46 of the endpoint + * @param color represents the color (u32) + * + * To reset to NULL use ~0 as parameters. + * + * @return 0 if correct, else error + */ +int +sr_mpls_policy_assign_endpoint_color (mpls_label_t bsid, + ip46_address_t * endpoint, + u8 endpoint_type, u32 color) +{ + mpls_sr_main_t *sm = &sr_mpls_main; + mpls_sr_policy_t *sr_policy = 0; + uword *endpoint_table, *p, *old_value; + + ip46_address_t any; + any.as_u64[0] = any.as_u64[1] = (u64) ~ 0; + + if (!sm->sr_policies_index_hash) + sm->sr_policies_index_hash = hash_create (0, sizeof (mpls_label_t)); + + p = hash_get (sm->sr_policies_index_hash, bsid); + if (p) + sr_policy = pool_elt_at_index (sm->sr_policies, p[0]); + else + return -1; + + /* If previous Endpoint, color existed, remove (NH,C) and (ANY,C) */ + if (sr_policy->endpoint_type) + { + endpoint_table = + mhash_get (&sm->sr_policies_c2e2eclabel_hash, &sr_policy->color); + if (!endpoint_table) + return -2; + old_value = + mhash_get ((mhash_t *) endpoint_table, &sr_policy->endpoint); + + fib_prefix_t pfx = { 0 }; + pfx.fp_proto = FIB_PROTOCOL_MPLS; + pfx.fp_len = 21; + pfx.fp_label = (u32) * old_value; + + mpls_eos_bit_t eos; + FOR_EACH_MPLS_EOS_BIT (eos) + { + pfx.fp_eos = eos; + fib_table_entry_path_remove (sm->fib_table_EC, + &pfx, + FIB_SOURCE_SR, + DPO_PROTO_MPLS, + NULL, + ~0, 0, 1, FIB_ROUTE_PATH_FLAG_NONE); + } + + old_value = mhash_get ((mhash_t *) endpoint_table, &any); + pfx.fp_label = (u32) * old_value; + + FOR_EACH_MPLS_EOS_BIT (eos) + { + pfx.fp_eos = eos; + fib_table_entry_path_remove (sm->fib_table_EC, + &pfx, + FIB_SOURCE_SR, + DPO_PROTO_MPLS, + NULL, + ~0, 0, 1, FIB_ROUTE_PATH_FLAG_NONE); + } + + /* Release the lock on (NH, Color) and (ANY, Color) */ + internal_label_unlock (sr_policy->endpoint, sr_policy->color); + internal_label_unlock (any, sr_policy->color); + + /* Reset the values on the SR policy */ + sr_policy->endpoint_type = 0; + sr_policy->endpoint.as_u64[0] = sr_policy->endpoint.as_u64[1] = + (u64) ~ 0; + sr_policy->color = (u32) ~ 0; + } + + if (endpoint_type) + { + sr_policy->endpoint_type = endpoint_type; + sr_policy->endpoint.as_u64[0] = endpoint->as_u64[0]; + sr_policy->endpoint.as_u64[1] = endpoint->as_u64[1]; + sr_policy->color = color; + + u32 label = find_or_create_internal_label (*endpoint, color); + internal_label_lock (*endpoint, sr_policy->color); + + /* If FIB doesnt exist, create them */ + if (sm->fib_table_EC == (u32) ~ 0) + { + sm->fib_table_EC = fib_table_create_and_lock (FIB_PROTOCOL_MPLS, + FIB_SOURCE_SR, + "SR-MPLS Traffic Engineering (NextHop,Color)"); + + fib_table_flush (sm->fib_table_EC, FIB_PROTOCOL_MPLS, + FIB_SOURCE_SPECIAL); + } + + fib_prefix_t pfx = { 0 }; + pfx.fp_proto = FIB_PROTOCOL_MPLS; + pfx.fp_len = 21; + + fib_route_path_t path = { + .frp_proto = DPO_PROTO_MPLS, + .frp_sw_if_index = ~0, + .frp_fib_index = 0, + .frp_weight = 1, + .frp_flags = FIB_ROUTE_PATH_FLAG_NONE, + .frp_label_stack = 0 + }; + path.frp_local_label = sr_policy->bsid; + + //Add the entry to ANY,Color + u32 any_label = find_or_create_internal_label (any, color); + internal_label_lock (any, sr_policy->color); + + pfx.fp_eos = MPLS_EOS; + path.frp_eos = MPLS_EOS; + + fib_route_path_t *paths = NULL; + vec_add1 (paths, path); + + pfx.fp_label = label; + fib_table_entry_update (sm->fib_table_EC, + &pfx, + FIB_SOURCE_SR, + FIB_ENTRY_FLAG_LOOSE_URPF_EXEMPT, paths); + + pfx.fp_label = any_label; + fib_table_entry_update (sm->fib_table_EC, + &pfx, + FIB_SOURCE_SR, + FIB_ENTRY_FLAG_LOOSE_URPF_EXEMPT, paths); + + vec_add1 (path.frp_label_stack, MPLS_IETF_IMPLICIT_NULL_LABEL); + pfx.fp_eos = MPLS_NON_EOS; + path.frp_eos = MPLS_NON_EOS; + + paths = NULL; + vec_add1 (paths, path); + + pfx.fp_label = label; + fib_table_entry_update (sm->fib_table_EC, + &pfx, + FIB_SOURCE_SR, + FIB_ENTRY_FLAG_LOOSE_URPF_EXEMPT, paths); + + pfx.fp_label = any_label; + fib_table_entry_update (sm->fib_table_EC, + &pfx, + FIB_SOURCE_SR, + FIB_ENTRY_FLAG_LOOSE_URPF_EXEMPT, paths); + } + return 0; +} + +/** + * @brief CLI to modify the Endpoint,Color of an SR policy + */ +static clib_error_t * +cli_sr_mpls_policy_ec_command_fn (vlib_main_t * vm, unformat_input_t * input, + vlib_cli_command_t * cmd) +{ + ip46_address_t endpoint; + u32 color = (u32) ~ 0; + mpls_label_t bsid; + u8 endpoint_type = 0; + char clear = 0, color_set = 0, bsid_set = 0; + + memset (&endpoint, 0, sizeof (ip46_address_t)); + + int rv; + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) + { + if (!endpoint_type + && unformat (input, "endpoint %U", unformat_ip6_address, + &endpoint.ip6)) + endpoint_type = SR_STEER_IPV6; + else if (!endpoint_type + && unformat (input, "endpoint %U", unformat_ip4_address, + &endpoint.ip4)) + endpoint_type = SR_STEER_IPV4; + else if (!color_set && unformat (input, "color %u", &color)) + color_set = 1; + else if (!bsid_set + && unformat (input, "bsid %U", unformat_mpls_unicast_label, + &bsid)) + bsid_set = 1; + else if (!clear && unformat (input, "clear")) + clear = 1; + else + break; + } + + if (!bsid_set) + return clib_error_return (0, "No BSID specified"); + if (!endpoint_type && !clear) + return clib_error_return (0, "No Endpoint specified"); + if (!color_set && !clear) + return clib_error_return (0, "No Color set"); + + /* In case its a cleanup */ + if (clear) + { + ip6_address_set_zero (&endpoint.ip6); + color = (u32) ~ 0; + } + rv = + sr_mpls_policy_assign_endpoint_color (bsid, &endpoint, endpoint_type, + color); + + if (rv) + clib_error_return (0, "Error on Endpoint,Color"); + + return 0; +} + +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND(cli_sr_mpls_policy_ec_command, static)= +{ + .path = "sr mpls policy te", + .short_help = "sr mpls policy te bsid xxxxx endpoint x.x.x.x color 12341234", + .function = cli_sr_mpls_policy_ec_command_fn, }; /* *INDENT-ON* */ @@ -553,17 +866,15 @@ sr_mpls_policy_rewrite_init (vlib_main_t * vm) mpls_sr_main_t *sm = &sr_mpls_main; /* Init memory for sr policy keys (bsid <-> ip6_address_t) */ - sm->sr_policies_index_hash = hash_create (0, sizeof (mpls_label_t)); - + sm->sr_policies_index_hash = NULL; + sm->sr_policies_c2e2eclabel_hash.hash = NULL; return 0; } VLIB_INIT_FUNCTION (sr_mpls_policy_rewrite_init); /* -* fd.io coding-style-patch-verification: ON -* -* Local Variables: -* eval: (c-set-style "gnu") -* End: -*/ + * fd.io coding-style-patch-verification: ON + * + * Local Variables: eval: (c-set-style "gnu") End: + */ -- cgit 1.2.3-korg