From eeb5fb3a50079e1af6e655694c6ff99ec2f9d070 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ignas=20Ba=C4=8Dius?= Date: Thu, 3 Oct 2019 17:15:38 +0300 Subject: [PATCH] sr: add "set sr encaps hop-limit" command MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Default hop-limit for the encapsulating IPv6 header is a compile-time constant. Add ability to specify custom hop-limit, in order to avoid packets being dropped with "hop limit exceeded in transit" response in certain network configurations. Type: feature Signed-off-by: Ignas Bačius Change-Id: I77f2b35c987cfd31801dc2744d31fb3c1984158f --- src/plugins/srv6-as/as.c | 2 +- src/vnet/srv6/sr.api | 12 ++++++++++++ src/vnet/srv6/sr.h | 3 +++ src/vnet/srv6/sr_api.c | 15 ++++++++++++++ src/vnet/srv6/sr_policy.md | 4 ++++ src/vnet/srv6/sr_policy_rewrite.c | 41 ++++++++++++++++++++++++++++++++++++++- 6 files changed, 75 insertions(+), 2 deletions(-) diff --git a/src/plugins/srv6-as/as.c b/src/plugins/srv6-as/as.c index 3a476044d60..99e68511f32 100644 --- a/src/plugins/srv6-as/as.c +++ b/src/plugins/srv6-as/as.c @@ -64,7 +64,7 @@ prepare_rewrite (ip6_address_t src_addr, ip6_address_t * sid_list, iph->src_address = src_addr; iph->dst_address = sid_list[0]; iph->payload_length = sr_hdr_len; - iph->hop_limit = IPv6_DEFAULT_HOP_LIMIT; + iph->hop_limit = sr_get_hop_limit (); if (num_sids > 1) { diff --git a/src/vnet/srv6/sr.api b/src/vnet/srv6/sr.api index e989ffe2f16..1d696b0c897 100644 --- a/src/vnet/srv6/sr.api +++ b/src/vnet/srv6/sr.api @@ -137,6 +137,18 @@ autoreply define sr_set_encap_source u8 encaps_source[16]; }; +/** \brief IPv6 SR Set SRv6 encapsulation hop-limit + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param hop_limit is the hop-limit value to set +*/ +autoreply define sr_set_encap_hop_limit +{ + u32 client_index; + u32 context; + u8 hop_limit; +}; + /** \brief IPv6 SR steering add/del @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request diff --git a/src/vnet/srv6/sr.h b/src/vnet/srv6/sr.h index 9ca0348cb87..2e2d43978bf 100755 --- a/src/vnet/srv6/sr.h +++ b/src/vnet/srv6/sr.h @@ -278,6 +278,9 @@ sr_steering_policy (int is_del, ip6_address_t * bsid, u32 sr_policy_index, extern void sr_set_source (ip6_address_t * address); +extern void sr_set_hop_limit (u8 hop_limit); +extern u8 sr_get_hop_limit (void); + /** * @brief SR rewrite string computation for SRH insertion (inline) * diff --git a/src/vnet/srv6/sr_api.c b/src/vnet/srv6/sr_api.c index 32eff2ef5e5..f3738da668d 100644 --- a/src/vnet/srv6/sr_api.c +++ b/src/vnet/srv6/sr_api.c @@ -50,6 +50,7 @@ _(SR_POLICY_MOD, sr_policy_mod) \ _(SR_POLICY_DEL, sr_policy_del) \ _(SR_STEERING_ADD_DEL, sr_steering_add_del) \ _(SR_SET_ENCAP_SOURCE, sr_set_encap_source) \ +_(SR_SET_ENCAP_HOP_LIMIT, sr_set_encap_hop_limit) \ _(SR_LOCALSIDS_DUMP, sr_localsids_dump) \ _(SR_POLICIES_DUMP, sr_policies_dump) \ _(SR_STEERING_POL_DUMP, sr_steering_pol_dump) @@ -178,6 +179,20 @@ vl_api_sr_set_encap_source_t_handler (vl_api_sr_set_encap_source_t * mp) REPLY_MACRO (VL_API_SR_SET_ENCAP_SOURCE_REPLY); } +static void +vl_api_sr_set_encap_hop_limit_t_handler (vl_api_sr_set_encap_hop_limit_t * mp) +{ + vl_api_sr_set_encap_hop_limit_reply_t *rmp; + int rv = 0; + + if (mp->hop_limit == 0) + rv = VNET_API_ERROR_INVALID_VALUE; + else + sr_set_hop_limit (mp->hop_limit); + + REPLY_MACRO (VL_API_SR_SET_ENCAP_HOP_LIMIT_REPLY); +} + static void vl_api_sr_steering_add_del_t_handler (vl_api_sr_steering_add_del_t * mp) { diff --git a/src/vnet/srv6/sr_policy.md b/src/vnet/srv6/sr_policy.md index 521b84616c0..2a7eb4c9870 100644 --- a/src/vnet/srv6/sr_policy.md +++ b/src/vnet/srv6/sr_policy.md @@ -54,3 +54,7 @@ Spray policies are used for removing multicast state from a network core domain, In case the user decides to create an SR policy an IPv6 Source Address must be specified for the encapsulated traffic. In order to do so the user might use the following command: set sr encaps source addr XXXX::YYYY + +Default hop-limit for the encapsulating IPv6 header is 64. It is possible to specify custom hop-limit value from 1 to 255 using this command: + + set sr encaps hop-limit N diff --git a/src/vnet/srv6/sr_policy_rewrite.c b/src/vnet/srv6/sr_policy_rewrite.c index feac151665a..8d11da67ddf 100755 --- a/src/vnet/srv6/sr_policy_rewrite.c +++ b/src/vnet/srv6/sr_policy_rewrite.c @@ -107,6 +107,7 @@ static dpo_type_t sr_pr_bsid_insert_dpo_type; * @brief IPv6 SA for encapsulated packets */ static ip6_address_t sr_pr_encaps_src; +static u8 sr_pr_encaps_hop_limit = IPv6_DEFAULT_HOP_LIMIT; /******************* SR rewrite set encaps IPv6 source addr *******************/ /* Note: This is temporal. We don't know whether to follow this path or @@ -141,6 +142,44 @@ VLIB_CLI_COMMAND (set_sr_src_command, static) = { }; /* *INDENT-ON* */ +/******************** SR rewrite set encaps IPv6 hop-limit ********************/ + +void +sr_set_hop_limit (u8 hop_limit) +{ + sr_pr_encaps_hop_limit = hop_limit; +} + +u8 +sr_get_hop_limit (void) +{ + return sr_pr_encaps_hop_limit; +} + +static clib_error_t * +set_sr_hop_limit_command_fn (vlib_main_t * vm, unformat_input_t * input, + vlib_cli_command_t * cmd) +{ + int hop_limit = sr_get_hop_limit (); + + if (unformat_check_input (input) == UNFORMAT_END_OF_INPUT) + return clib_error_return (0, "No value specified"); + if (!unformat (input, "%d", &hop_limit)) + return clib_error_return (0, "Invalid value"); + if (hop_limit <= 0 || hop_limit > 255) + return clib_error_return (0, "Value out of range [1-255]"); + sr_pr_encaps_hop_limit = (u8) hop_limit; + return 0; +} + +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND (set_sr_hop_limit_command, static) = { + .path = "set sr encaps hop-limit", + .short_help = "set sr encaps hop-limit ", + .function = set_sr_hop_limit_command_fn, +}; +/* *INDENT-ON* */ + /*********************** SR rewrite string computation ************************/ /** * @brief SR rewrite string computation for IPv6 encapsulation (inline) @@ -175,7 +214,7 @@ compute_rewrite_encaps (ip6_address_t * sl) iph->src_address.as_u64[1] = sr_pr_encaps_src.as_u64[1]; iph->payload_length = header_length - IPv6_DEFAULT_HEADER_LENGTH; iph->protocol = IP_PROTOCOL_IPV6; - iph->hop_limit = IPv6_DEFAULT_HOP_LIMIT; + iph->hop_limit = sr_pr_encaps_hop_limit; if (vec_len (sl) > 1) { -- 2.16.6