diff options
author | Takeru Hayasaka <hayatake396@gmail.com> | 2022-10-28 04:26:05 +0900 |
---|---|---|
committer | Andrew Yourtchenko <ayourtch@gmail.com> | 2023-12-20 17:30:19 +0000 |
commit | 68ac244283b60cbaf6356ab732f1d31583bb3e7a (patch) | |
tree | eafd76834ecd0aaa77ac4f9a54629636489d5bfd /src/plugins/srv6-mobile | |
parent | 69f800fbfd559c8db21d064ceeca5f81fb1f0021 (diff) |
srv6-mobile: Implement SRv6 mobile API funcs
This merge request adds the feature to manipulate localsids and policies for SRv6 mobile via API.
Type: feature
Signed-off-by: Takeru Hayasaka <hayatake396@gmail.com>
Change-Id: Ibb46bf71ae1d9d4591ce2c8ccf66f520887dad70
Diffstat (limited to 'src/plugins/srv6-mobile')
-rw-r--r-- | src/plugins/srv6-mobile/CMakeLists.txt | 5 | ||||
-rw-r--r-- | src/plugins/srv6-mobile/gtp4_d.c | 44 | ||||
-rw-r--r-- | src/plugins/srv6-mobile/gtp4_dt.c | 38 | ||||
-rw-r--r-- | src/plugins/srv6-mobile/gtp4_e.c | 29 | ||||
-rw-r--r-- | src/plugins/srv6-mobile/gtp6_d.c | 36 | ||||
-rw-r--r-- | src/plugins/srv6-mobile/gtp6_d_di.c | 24 | ||||
-rw-r--r-- | src/plugins/srv6-mobile/gtp6_dt.c | 40 | ||||
-rw-r--r-- | src/plugins/srv6-mobile/gtp6_e.c | 22 | ||||
-rw-r--r-- | src/plugins/srv6-mobile/mobile.h | 22 | ||||
-rw-r--r-- | src/plugins/srv6-mobile/sr_mobile.api | 79 | ||||
-rw-r--r-- | src/plugins/srv6-mobile/sr_mobile_api.c | 339 | ||||
-rw-r--r-- | src/plugins/srv6-mobile/sr_mobile_api.h | 72 | ||||
-rw-r--r-- | src/plugins/srv6-mobile/sr_mobile_types.api | 24 |
13 files changed, 682 insertions, 92 deletions
diff --git a/src/plugins/srv6-mobile/CMakeLists.txt b/src/plugins/srv6-mobile/CMakeLists.txt index 5a9945c2e4f..a917c8ded82 100644 --- a/src/plugins/srv6-mobile/CMakeLists.txt +++ b/src/plugins/srv6-mobile/CMakeLists.txt @@ -21,6 +21,11 @@ add_vpp_plugin(srv6mobile gtp6_d_di.c gtp6_dt.c node.c + sr_mobile_api.c + + API_FILES + sr_mobile.api + sr_mobile_types.api INSTALL_HEADERS mobile.h diff --git a/src/plugins/srv6-mobile/gtp4_d.c b/src/plugins/srv6-mobile/gtp4_d.c index 269902429d3..d5a5a6a567a 100644 --- a/src/plugins/srv6-mobile/gtp4_d.c +++ b/src/plugins/srv6-mobile/gtp4_d.c @@ -105,11 +105,33 @@ clb_format_srv6_t_m_gtp4_d (u8 * s, va_list * args) return s; } +void +alloc_param_srv6_t_m_gtp4_d (void **plugin_mem_p, const void *v6src_prefix, + const u32 v6src_prefixlen, const void *sr_prefix, + const u32 sr_prefixlen, const u32 fib_index, + const u8 nhtype, const bool drop_in) +{ + srv6_end_gtp4_d_param_t *ls_mem; + ls_mem = clib_mem_alloc (sizeof *ls_mem); + clib_memset (ls_mem, 0, sizeof *ls_mem); + *plugin_mem_p = ls_mem; + + ls_mem->v6src_prefixlen = v6src_prefixlen; + memcpy (&ls_mem->v6src_prefix, v6src_prefix, sizeof (ip6_address_t)); + ls_mem->sr_prefixlen = sr_prefixlen; + memcpy (&ls_mem->sr_prefix, sr_prefix, sizeof (ip6_address_t)); + + ls_mem->nhtype = nhtype; + ls_mem->drop_in = drop_in; + ls_mem->fib_table = fib_index; + ls_mem->fib4_index = ip4_fib_index_from_table_id (fib_index); + ls_mem->fib6_index = ip6_fib_index_from_table_id (fib_index); +} + static uword clb_unformat_srv6_t_m_gtp4_d (unformat_input_t * input, va_list * args) { void **plugin_mem_p = va_arg (*args, void **); - srv6_end_gtp4_d_param_t *ls_mem; ip6_address_t sr_prefix; u32 sr_prefixlen; ip6_address_t v6src_prefix; @@ -172,23 +194,9 @@ clb_unformat_srv6_t_m_gtp4_d (unformat_input_t * input, va_list * args) return 0; } - ls_mem = clib_mem_alloc (sizeof *ls_mem); - clib_memset (ls_mem, 0, sizeof *ls_mem); - *plugin_mem_p = ls_mem; - - ls_mem->sr_prefix = sr_prefix; - ls_mem->sr_prefixlen = sr_prefixlen; - - ls_mem->v6src_prefix = v6src_prefix; - ls_mem->v6src_prefixlen = v6src_prefixlen; - - ls_mem->nhtype = nhtype; - - ls_mem->drop_in = drop_in; - - ls_mem->fib_table = fib_table; - ls_mem->fib4_index = ip4_fib_index_from_table_id (fib_table); - ls_mem->fib6_index = ip6_fib_index_from_table_id (fib_table); + alloc_param_srv6_t_m_gtp4_d (plugin_mem_p, &v6src_prefix, v6src_prefixlen, + &sr_prefix, sr_prefixlen, fib_table, nhtype, + drop_in); return 1; } diff --git a/src/plugins/srv6-mobile/gtp4_dt.c b/src/plugins/srv6-mobile/gtp4_dt.c index 1f6bab1d055..c4752b77557 100644 --- a/src/plugins/srv6-mobile/gtp4_dt.c +++ b/src/plugins/srv6-mobile/gtp4_dt.c @@ -90,11 +90,31 @@ clb_format_srv6_t_m_gtp4_dt (u8 * s, va_list * args) return s; } +void +alloc_param_srv6_t_m_gtp4_dt (void **plugin_mem_p, const u32 fib_index, + const u32 local_fib_index, const u8 type) +{ + srv6_t_gtp4_dt_param_t *ls_mem; + ls_mem = clib_mem_alloc (sizeof *ls_mem); + clib_memset (ls_mem, 0, sizeof *ls_mem); + *plugin_mem_p = ls_mem; + + ls_mem->fib4_index = fib_table_find (FIB_PROTOCOL_IP4, fib_index); + ls_mem->fib6_index = fib_table_find (FIB_PROTOCOL_IP6, fib_index); + + if (type == SRV6_GTP4_DT6 || type == SRV6_GTP4_DT46) + { + ls_mem->local_fib_index = + fib_table_find (FIB_PROTOCOL_IP6, local_fib_index); + } + + ls_mem->type = type; +} + static uword clb_unformat_srv6_t_m_gtp4_dt (unformat_input_t * input, va_list * args) { void **plugin_mem_p = va_arg (*args, void **); - srv6_t_gtp4_dt_param_t *ls_mem; u32 fib_index = 0; u32 local_fib_index = 0; u32 type; @@ -118,20 +138,8 @@ clb_unformat_srv6_t_m_gtp4_dt (unformat_input_t * input, va_list * args) return 0; } - ls_mem = clib_mem_alloc (sizeof *ls_mem); - clib_memset (ls_mem, 0, sizeof *ls_mem); - *plugin_mem_p = ls_mem; - - ls_mem->fib4_index = fib_table_find (FIB_PROTOCOL_IP4, fib_index); - ls_mem->fib6_index = fib_table_find (FIB_PROTOCOL_IP6, fib_index); - - if (type == SRV6_GTP4_DT6 || type == SRV6_GTP4_DT46) - { - ls_mem->local_fib_index = - fib_table_find (FIB_PROTOCOL_IP6, local_fib_index); - } - - ls_mem->type = type; + alloc_param_srv6_t_m_gtp4_dt (plugin_mem_p, fib_index, local_fib_index, + type); return 1; } diff --git a/src/plugins/srv6-mobile/gtp4_e.c b/src/plugins/srv6-mobile/gtp4_e.c index 8efb938cf72..828f924464d 100644 --- a/src/plugins/srv6-mobile/gtp4_e.c +++ b/src/plugins/srv6-mobile/gtp4_e.c @@ -80,11 +80,26 @@ clb_format_srv6_end_m_gtp4_e (u8 * s, va_list * args) return s; } +void +alloc_param_srv6_end_m_gtp4_e (void **plugin_mem_p, const void *v4src_addr, + const u32 v4src_position, const u32 fib_table) +{ + srv6_end_gtp4_e_param_t *ls_mem; + ls_mem = clib_mem_alloc (sizeof *ls_mem); + clib_memset (ls_mem, 0, sizeof *ls_mem); + *plugin_mem_p = ls_mem; + ls_mem->v4src_position = v4src_position; + memcpy (&ls_mem->v4src_addr, v4src_addr, sizeof (ip4_address_t)); + + ls_mem->fib_table = fib_table; + ls_mem->fib4_index = ip4_fib_index_from_table_id (fib_table); + ls_mem->fib6_index = ip6_fib_index_from_table_id (fib_table); +} + static uword clb_unformat_srv6_end_m_gtp4_e (unformat_input_t * input, va_list * args) { void **plugin_mem_p = va_arg (*args, void **); - srv6_end_gtp4_e_param_t *ls_mem; ip4_address_t v4src_addr; u32 v4src_position = 0; u32 fib_table; @@ -113,16 +128,8 @@ clb_unformat_srv6_end_m_gtp4_e (unformat_input_t * input, va_list * args) if (!config) return 0; - ls_mem = clib_mem_alloc (sizeof *ls_mem); - clib_memset (ls_mem, 0, sizeof *ls_mem); - *plugin_mem_p = ls_mem; - - ls_mem->v4src_position = v4src_position; - memcpy (&ls_mem->v4src_addr, &v4src_addr, sizeof (ip4_address_t)); - - ls_mem->fib_table = fib_table; - ls_mem->fib4_index = ip4_fib_index_from_table_id (fib_table); - ls_mem->fib6_index = ip6_fib_index_from_table_id (fib_table); + alloc_param_srv6_end_m_gtp4_e (plugin_mem_p, &v4src_addr, v4src_position, + fib_table); return 1; } diff --git a/src/plugins/srv6-mobile/gtp6_d.c b/src/plugins/srv6-mobile/gtp6_d.c index 79549276c2c..1f5b9ac0d0f 100644 --- a/src/plugins/srv6-mobile/gtp6_d.c +++ b/src/plugins/srv6-mobile/gtp6_d.c @@ -94,11 +94,29 @@ clb_format_srv6_end_m_gtp6_d (u8 * s, va_list * args) return s; } +void +alloc_param_srv6_end_m_gtp6_d (void **plugin_mem_p, const void *sr_prefix, + const u32 sr_prefixlen, const u8 nhtype, + const bool drop_in, const u32 fib_table) +{ + srv6_end_gtp6_d_param_t *ls_mem; + ls_mem = clib_mem_alloc (sizeof *ls_mem); + clib_memset (ls_mem, 0, sizeof *ls_mem); + *plugin_mem_p = ls_mem; + + ls_mem->sr_prefixlen = sr_prefixlen; + memcpy (&ls_mem->sr_prefix, sr_prefix, sizeof (ip6_address_t)); + ls_mem->nhtype = nhtype; + ls_mem->drop_in = drop_in; + ls_mem->fib_table = fib_table; + ls_mem->fib4_index = ip4_fib_index_from_table_id (fib_table); + ls_mem->fib6_index = ip6_fib_index_from_table_id (fib_table); +} + static uword clb_unformat_srv6_end_m_gtp6_d (unformat_input_t * input, va_list * args) { void **plugin_mem_p = va_arg (*args, void **); - srv6_end_gtp6_d_param_t *ls_mem; ip6_address_t sr_prefix; u32 sr_prefixlen; u8 nhtype = SRV6_NHTYPE_NONE; @@ -150,20 +168,8 @@ clb_unformat_srv6_end_m_gtp6_d (unformat_input_t * input, va_list * args) return 0; } - ls_mem = clib_mem_alloc (sizeof *ls_mem); - clib_memset (ls_mem, 0, sizeof *ls_mem); - *plugin_mem_p = ls_mem; - - ls_mem->sr_prefix = sr_prefix; - ls_mem->sr_prefixlen = sr_prefixlen; - - ls_mem->nhtype = nhtype; - - ls_mem->drop_in = drop_in; - - ls_mem->fib_table = fib_table; - ls_mem->fib4_index = ip4_fib_index_from_table_id (fib_table); - ls_mem->fib6_index = ip6_fib_index_from_table_id (fib_table); + alloc_param_srv6_end_m_gtp6_d (plugin_mem_p, &sr_prefix, sr_prefixlen, + nhtype, drop_in, fib_table); return 1; } diff --git a/src/plugins/srv6-mobile/gtp6_d_di.c b/src/plugins/srv6-mobile/gtp6_d_di.c index 601db26aa90..80c0dbcec7c 100644 --- a/src/plugins/srv6-mobile/gtp6_d_di.c +++ b/src/plugins/srv6-mobile/gtp6_d_di.c @@ -91,11 +91,24 @@ clb_format_srv6_end_m_gtp6_d_di (u8 * s, va_list * args) return s; } +void +alloc_param_srv6_end_m_gtp6_di (void **plugin_mem_p, const void *sr_prefix, + const u32 sr_prefixlen, const u8 nhtype) +{ + srv6_end_gtp6_d_param_t *ls_mem; + ls_mem = clib_mem_alloc (sizeof *ls_mem); + clib_memset (ls_mem, 0, sizeof *ls_mem); + *plugin_mem_p = ls_mem; + + ls_mem->sr_prefixlen = sr_prefixlen; + memcpy (&ls_mem->sr_prefix, sr_prefix, sizeof (ip6_address_t)); + ls_mem->nhtype = nhtype; +} + static uword clb_unformat_srv6_end_m_gtp6_d_di (unformat_input_t * input, va_list * args) { void **plugin_mem_p = va_arg (*args, void **); - srv6_end_gtp6_d_param_t *ls_mem; ip6_address_t sr_prefix; u32 sr_prefixlen = 0; u8 nhtype; @@ -125,13 +138,8 @@ clb_unformat_srv6_end_m_gtp6_d_di (unformat_input_t * input, va_list * args) return 0; } - ls_mem = clib_mem_alloc (sizeof *ls_mem); - clib_memset (ls_mem, 0, sizeof *ls_mem); - *plugin_mem_p = ls_mem; - - ls_mem->sr_prefix = sr_prefix; - ls_mem->sr_prefixlen = sr_prefixlen; - ls_mem->nhtype = nhtype; + alloc_param_srv6_end_m_gtp6_di (plugin_mem_p, &sr_prefix, sr_prefixlen, + nhtype); return 1; } diff --git a/src/plugins/srv6-mobile/gtp6_dt.c b/src/plugins/srv6-mobile/gtp6_dt.c index ba8de54bec9..5fc0918621d 100644 --- a/src/plugins/srv6-mobile/gtp6_dt.c +++ b/src/plugins/srv6-mobile/gtp6_dt.c @@ -84,11 +84,31 @@ clb_format_srv6_end_m_gtp6_dt (u8 * s, va_list * args) return s; } +void +alloc_param_srv6_end_m_gtp6_dt (void **plugin_mem_p, const u32 fib_index, + const u32 local_fib_index, const u32 type) +{ + srv6_end_gtp6_dt_param_t *ls_mem; + ls_mem = clib_mem_alloc (sizeof *ls_mem); + clib_memset (ls_mem, 0, sizeof *ls_mem); + *plugin_mem_p = ls_mem; + + ls_mem->fib4_index = fib_table_find (FIB_PROTOCOL_IP4, fib_index); + ls_mem->fib6_index = fib_table_find (FIB_PROTOCOL_IP6, fib_index); + + if (type == SRV6_GTP6_DT6 || type == SRV6_GTP6_DT46) + { + ls_mem->local_fib_index = + fib_table_find (FIB_PROTOCOL_IP6, local_fib_index); + } + + ls_mem->type = type; +} + static uword clb_unformat_srv6_end_m_gtp6_dt (unformat_input_t * input, va_list * args) { void **plugin_mem_p = va_arg (*args, void **); - srv6_end_gtp6_dt_param_t *ls_mem; u32 fib_index = 0; u32 local_fib_index = 0; u32 type; @@ -111,22 +131,8 @@ clb_unformat_srv6_end_m_gtp6_dt (unformat_input_t * input, va_list * args) { return 0; } - - ls_mem = clib_mem_alloc (sizeof *ls_mem); - clib_memset (ls_mem, 0, sizeof *ls_mem); - *plugin_mem_p = ls_mem; - - ls_mem->fib4_index = fib_table_find (FIB_PROTOCOL_IP4, fib_index); - ls_mem->fib6_index = fib_table_find (FIB_PROTOCOL_IP6, fib_index); - - if (type == SRV6_GTP6_DT6 || type == SRV6_GTP6_DT46) - { - ls_mem->local_fib_index = - fib_table_find (FIB_PROTOCOL_IP6, local_fib_index); - } - - ls_mem->type = type; - + alloc_param_srv6_end_m_gtp6_dt (plugin_mem_p, fib_index, local_fib_index, + type); return 1; } diff --git a/src/plugins/srv6-mobile/gtp6_e.c b/src/plugins/srv6-mobile/gtp6_e.c index feaaaf95419..49b1bd1a6d9 100644 --- a/src/plugins/srv6-mobile/gtp6_e.c +++ b/src/plugins/srv6-mobile/gtp6_e.c @@ -76,16 +76,10 @@ clb_format_srv6_end_m_gtp6_e (u8 * s, va_list * args) return s; } -static uword -clb_unformat_srv6_end_m_gtp6_e (unformat_input_t * input, va_list * args) +void +alloc_param_srv6_end_m_gtp6_e (void **plugin_mem_p, const u32 fib_table) { - void **plugin_mem_p = va_arg (*args, void **); srv6_end_gtp6_e_param_t *ls_mem; - u32 fib_table; - - if (!unformat (input, "end.m.gtp6.e fib-table %d", &fib_table)) - return 0; - ls_mem = clib_mem_alloc (sizeof *ls_mem); clib_memset (ls_mem, 0, sizeof *ls_mem); *plugin_mem_p = ls_mem; @@ -93,6 +87,18 @@ clb_unformat_srv6_end_m_gtp6_e (unformat_input_t * input, va_list * args) ls_mem->fib_table = fib_table; ls_mem->fib4_index = ip4_fib_index_from_table_id (fib_table); ls_mem->fib6_index = ip6_fib_index_from_table_id (fib_table); +} + +static uword +clb_unformat_srv6_end_m_gtp6_e (unformat_input_t *input, va_list *args) +{ + void **plugin_mem_p = va_arg (*args, void **); + u32 fib_table; + + if (!unformat (input, "end.m.gtp6.e fib-table %d", &fib_table)) + return 0; + + alloc_param_srv6_end_m_gtp6_e (plugin_mem_p, fib_table); return 1; } diff --git a/src/plugins/srv6-mobile/mobile.h b/src/plugins/srv6-mobile/mobile.h index 5f6064ff10b..921abc90db2 100644 --- a/src/plugins/srv6-mobile/mobile.h +++ b/src/plugins/srv6-mobile/mobile.h @@ -71,6 +71,28 @@ #define GTPU_IE_MAX_SIZ 256 #define SRH_TLV_USER_PLANE_CONTAINER 0x0a /* tentative */ +typedef enum mobile_policy_function_list +{ + SRV6_MOBILE_POLICY_UNKNOWN_FUNCTION = 0, + SRV6_MOBILE_POLICY_T_M_GTP4_D, + SRV6_MOBILE_POLICY_T_M_GTP4_DT4, + SRV6_MOBILE_POLICY_T_M_GTP4_DT6, + SRV6_MOBILE_POLICY_T_M_GTP4_DT46, + SRV6_MOBILE_POLICY_END_M_GTP6_D, +} mobile_policy_function_list_t; + +typedef enum mobile_localsid_function_list +{ + SRV6_MOBILE_LOCALSID_UNKNOWN_FUNCTION = 0, + SRV6_MOBILE_LOCALSID_END_M_GTP4_E, + SRV6_MOBILE_LOCALSID_END_M_GTP6_E, + SRV6_MOBILE_LOCALSID_END_M_GTP6_D, + SRV6_MOBILE_LOCALSID_END_M_GTP6_D_DI, + SRV6_MOBILE_LOCALSID_END_M_GTP6_D_DT4, + SRV6_MOBILE_LOCALSID_END_M_GTP6_D_DT6, + SRV6_MOBILE_LOCALSID_END_M_GTP6_D_DT46, +} mobile_localsid_function_list_t; + /* *INDENT-OFF* */ typedef struct { diff --git a/src/plugins/srv6-mobile/sr_mobile.api b/src/plugins/srv6-mobile/sr_mobile.api new file mode 100644 index 00000000000..1487085a695 --- /dev/null +++ b/src/plugins/srv6-mobile/sr_mobile.api @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2022 BBSakura Networks Inc 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 + * + * 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. + */ + +option version = "0.1.0"; + +import "vnet/interface_types.api"; +import "vnet/ip/ip_types.api"; +import "vnet/srv6/sr_types.api"; +import "vnet/srv6/sr.api"; +import "plugins/srv6-mobile/sr_mobile_types.api"; + +/** \brief IPv6 SR for Mobile LocalSID add/del request + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param is_del - Boolean of whether its a delete instruction + @param localsid_prefix - IPv6 address of the localsid + @param behavior - the behavior of the SR policy. + @param fib_table - FIB table in which we should install the localsid entry + @param local_fib_table - lookup and forward GTP-U packet based on outer IP destination address. optional + @param drop_in - that reconverts to GTPv1 mode. optional + @param nhtype - next-header type. optional. + @param sr_prefix - v6 src ip encoding prefix.optional. + @param v4src_position - bit position where IPv4 src address embedded. optional. +*/ +autoreply define sr_mobile_localsid_add_del +{ + u32 client_index; + u32 context; + bool is_del [default=false]; + vl_api_ip6_prefix_t localsid_prefix; + string behavior[64]; + u32 fib_table; + u32 local_fib_table; + bool drop_in; + vl_api_sr_mobile_nhtype_t nhtype; + vl_api_ip6_prefix_t sr_prefix; + vl_api_ip4_address_t v4src_addr; + u32 v4src_position; +}; + +/** \brief IPv6 SR for Mobile policy add + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param bsid - the bindingSID of the SR Policy + @param sr_prefix - v6 dst ip encoding prefix. optional + @param v6src_position - v6 src prefix. optional + @param behavior - the behavior of the SR policy. + @param fib_table - the VRF where to install the FIB entry for the BSID + @param encap_src is a encaps IPv6 source addr. optional + @param local_fib_table - lookup and forward GTP-U packet based on outer IP destination address. optional + @param drop_in - that reconverts to GTPv1 mode. optional + @param nhtype - next-header type. +*/ +autoreply define sr_mobile_policy_add +{ + u32 client_index; + u32 context; + vl_api_ip6_address_t bsid_addr; + vl_api_ip6_prefix_t sr_prefix; + vl_api_ip6_prefix_t v6src_prefix; + string behavior[64]; + u32 fib_table; + u32 local_fib_table; + vl_api_ip6_address_t encap_src; + bool drop_in; + vl_api_sr_mobile_nhtype_t nhtype; +}; diff --git a/src/plugins/srv6-mobile/sr_mobile_api.c b/src/plugins/srv6-mobile/sr_mobile_api.c new file mode 100644 index 00000000000..51199317a3b --- /dev/null +++ b/src/plugins/srv6-mobile/sr_mobile_api.c @@ -0,0 +1,339 @@ +/* + *------------------------------------------------------------------ + * sr_mobile_api.c - ipv6 segment routing for mobile u-plane api + * + * Copyright (c) 2022 BBSakura Networks Inc 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 + * + * 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. + *------------------------------------------------------------------ + */ + +#include <stdint.h> +#include <vnet/vnet.h> +#include <vnet/srv6/sr.h> +#include <vlibmemory/api.h> + +#include <vnet/interface.h> +#include <vnet/api_errno.h> +#include <vnet/feature/feature.h> +#include <vnet/fib/fib_table.h> +#include <vnet/ip/ip_types_api.h> + +#include <vnet/format_fns.h> +#include <vnet/srv6/sr.api_enum.h> +#include <vnet/srv6/sr.api_types.h> + +#include <srv6-mobile/mobile.h> +#include <srv6-mobile/sr_mobile.api_types.h> +#include <srv6-mobile/sr_mobile_types.api_types.h> +#include <srv6-mobile/sr_mobile.api_enum.h> + +#include <srv6-mobile/sr_mobile_api.h> + +u16 msg_id_base; +#define REPLY_MSG_ID_BASE msg_id_base +#include <vlibapi/api_helper_macros.h> + +static inline uint16_t +sr_plugin_localsid_fn_num_find_by (ip6_sr_main_t *sm, const char *keyword_str, + size_t keyword_len) +{ + sr_localsid_fn_registration_t *plugin = 0, **vec_plugins = 0; + sr_localsid_fn_registration_t **plugin_it = 0; + pool_foreach (plugin, sm->plugin_functions) + { + vec_add1 (vec_plugins, plugin); + } + + vec_foreach (plugin_it, vec_plugins) + { + if (!srv6_mobile_strcmp_with_size (keyword_str, keyword_len, + (char *) (*plugin_it)->keyword_str)) + { + return (*plugin_it)->sr_localsid_function_number; + } + } + return UINT16_MAX; +} + +static inline uint16_t +sr_plugin_policy_fn_num_find_by (ip6_sr_main_t *sm, const char *keyword_str, + size_t keyword_len) +{ + sr_policy_fn_registration_t *plugin = 0, **vec_plugins = 0; + sr_policy_fn_registration_t **plugin_it = 0; + pool_foreach (plugin, sm->policy_plugin_functions) + { + vec_add1 (vec_plugins, plugin); + } + + vec_foreach (plugin_it, vec_plugins) + { + if (!srv6_mobile_strcmp_with_size (keyword_str, keyword_len, + (char *) (*plugin_it)->keyword_str)) + { + return (*plugin_it)->sr_policy_function_number; + } + } + return UINT16_MAX; +} + +static void +vl_api_sr_mobile_localsid_add_del_t_handler ( + vl_api_sr_mobile_localsid_add_del_t *mp) +{ + ip6_sr_main_t *sm = &sr_main; + vl_api_sr_mobile_localsid_add_del_reply_t *rmp; + int rv = 0; + ip6_address_t localsid; + u16 localsid_prefix_len = 128; + void *ls_plugin_mem = 0; + u16 behavior = 0; + u32 dt_type; + size_t behavior_size = 0; + mobile_localsid_function_list_t kind_fn = + SRV6_MOBILE_LOCALSID_UNKNOWN_FUNCTION; + + mp->behavior[sizeof (mp->behavior) - 1] = '\0'; + behavior_size = sizeof (mp->behavior); + // search behavior index + if (mp->behavior[0]) + { + if (!srv6_mobile_strcmp_with_size ((char *) mp->behavior, behavior_size, + "end.m.gtp4.e")) + { + kind_fn = SRV6_MOBILE_LOCALSID_END_M_GTP4_E; + } + else if (!srv6_mobile_strcmp_with_size ((char *) mp->behavior, + behavior_size, "end.m.gtp6.e")) + { + kind_fn = SRV6_MOBILE_LOCALSID_END_M_GTP6_E; + } + else if (!srv6_mobile_strcmp_with_size ((char *) mp->behavior, + behavior_size, "end.m.gtp6.d")) + { + kind_fn = SRV6_MOBILE_LOCALSID_END_M_GTP6_D; + } + else if (!srv6_mobile_strcmp_with_size ( + (char *) mp->behavior, behavior_size, "end.m.gtp6.d.di")) + { + kind_fn = SRV6_MOBILE_LOCALSID_END_M_GTP6_D_DI; + } + else if (!srv6_mobile_strcmp_with_size ( + (char *) mp->behavior, behavior_size, "end.m.gtp6.d.dt4")) + { + kind_fn = SRV6_MOBILE_LOCALSID_END_M_GTP6_D_DT4; + dt_type = SRV6_GTP6_DT4; + } + else if (!srv6_mobile_strcmp_with_size ( + (char *) mp->behavior, behavior_size, "end.m.gtp6.d.dt6")) + { + kind_fn = SRV6_MOBILE_LOCALSID_END_M_GTP6_D_DT6; + dt_type = SRV6_GTP6_DT6; + } + else if (!srv6_mobile_strcmp_with_size ( + (char *) mp->behavior, behavior_size, "end.m.gtp6.d.dt46")) + { + kind_fn = SRV6_MOBILE_LOCALSID_END_M_GTP6_D_DT46; + dt_type = SRV6_GTP6_DT46; + } + else + { + return; + } + switch (kind_fn) + { + case SRV6_MOBILE_LOCALSID_END_M_GTP4_E: + alloc_param_srv6_end_m_gtp4_e (&ls_plugin_mem, &mp->v4src_addr, + ntohl (mp->v4src_position), + ntohl (mp->fib_table)); + break; + case SRV6_MOBILE_LOCALSID_END_M_GTP6_E: + alloc_param_srv6_end_m_gtp6_e (&ls_plugin_mem, + ntohl (mp->fib_table)); + break; + case SRV6_MOBILE_LOCALSID_END_M_GTP6_D: + alloc_param_srv6_end_m_gtp6_d ( + &ls_plugin_mem, &mp->sr_prefix.address, mp->sr_prefix.len, + (u8) ntohl (mp->nhtype), mp->drop_in, ntohl (mp->fib_table)); + break; + case SRV6_MOBILE_LOCALSID_END_M_GTP6_D_DI: + alloc_param_srv6_end_m_gtp6_di ( + &ls_plugin_mem, &mp->sr_prefix.address, mp->sr_prefix.len, + (u8) ntohl (mp->nhtype)); + break; + case SRV6_MOBILE_LOCALSID_END_M_GTP6_D_DT4: + case SRV6_MOBILE_LOCALSID_END_M_GTP6_D_DT6: + case SRV6_MOBILE_LOCALSID_END_M_GTP6_D_DT46: + alloc_param_srv6_end_m_gtp6_dt ( + &ls_plugin_mem, ntohl (mp->fib_table), ntohl (mp->local_fib_table), + dt_type); + break; + case SRV6_MOBILE_LOCALSID_UNKNOWN_FUNCTION: + default: + return; // error + } + behavior = sr_plugin_localsid_fn_num_find_by (sm, (char *) mp->behavior, + behavior_size); + if (behavior == UINT16_MAX) + return; + } + else + { + return; + } + ip6_address_decode (mp->localsid_prefix.address, &localsid); + localsid_prefix_len = mp->localsid_prefix.len; + + rv = sr_cli_localsid (mp->is_del, &localsid, localsid_prefix_len, + 0, // ignore end_psp + behavior, + 0, // ignore sw_if_index + 0, // ignore vlan_index + ntohl (mp->fib_table), + NULL, // ignore nh_addr + 0, // ignore usid_len + ls_plugin_mem); + + REPLY_MACRO (VL_API_SR_MOBILE_LOCALSID_ADD_DEL_REPLY); +} + +static void +vl_api_sr_mobile_policy_add_t_handler (vl_api_sr_mobile_policy_add_t *mp) +{ + ip6_sr_main_t *sm = &sr_main; + vl_api_sr_mobile_policy_add_reply_t *rmp; + ip6_address_t bsid_addr; + ip6_address_t encap_src; + void *ls_plugin_mem = 0; + u16 behavior = 0; + size_t behavior_size = 0; + + u32 dt_type; + mobile_policy_function_list_t kind_fn = SRV6_MOBILE_POLICY_UNKNOWN_FUNCTION; + + ip6_address_decode (mp->bsid_addr, &bsid_addr); + ip6_address_decode (mp->encap_src, &encap_src); + if (ip6_address_is_zero (&encap_src)) + { + encap_src = *sr_get_encaps_source (); + } + mp->behavior[sizeof (mp->behavior) - 1] = '\0'; + behavior_size = sizeof (mp->behavior); + + // search behavior index + if (mp->behavior[0]) + { + if (!srv6_mobile_strcmp_with_size ((char *) mp->behavior, behavior_size, + "t.m.gtp4.d")) + { + kind_fn = SRV6_MOBILE_POLICY_T_M_GTP4_D; + } + else if (!srv6_mobile_strcmp_with_size ((char *) mp->behavior, + behavior_size, "t.m.gtp4.dt4")) + { + kind_fn = SRV6_MOBILE_POLICY_T_M_GTP4_DT4; + dt_type = SRV6_GTP4_DT4; + } + else if (!srv6_mobile_strcmp_with_size ((char *) mp->behavior, + behavior_size, "t.m.gtp4.dt6")) + { + kind_fn = SRV6_MOBILE_POLICY_T_M_GTP4_DT6; + dt_type = SRV6_GTP4_DT6; + } + else if (!srv6_mobile_strcmp_with_size ((char *) mp->behavior, + behavior_size, "t.m.gtp4.dt46")) + { + kind_fn = SRV6_MOBILE_POLICY_T_M_GTP4_DT46; + dt_type = SRV6_GTP4_DT46; + } + else if (!srv6_mobile_strcmp_with_size ((char *) mp->behavior, + behavior_size, "end.m.gtp6.d")) + { + kind_fn = SRV6_MOBILE_POLICY_END_M_GTP6_D; + } + else + { + return; + } + + switch (kind_fn) + { + case SRV6_MOBILE_POLICY_T_M_GTP4_D: + alloc_param_srv6_t_m_gtp4_d ( + &ls_plugin_mem, &mp->v6src_prefix.address, mp->v6src_prefix.len, + &mp->sr_prefix.address, mp->sr_prefix.len, ntohl (mp->fib_table), + mp->nhtype, mp->drop_in); + break; + case SRV6_MOBILE_POLICY_END_M_GTP6_D: + alloc_param_srv6_end_m_gtp6_d ( + &ls_plugin_mem, &mp->sr_prefix.address, mp->sr_prefix.len, + mp->nhtype, mp->drop_in, ntohl (mp->fib_table)); + break; + case SRV6_MOBILE_POLICY_T_M_GTP4_DT4: + case SRV6_MOBILE_POLICY_T_M_GTP4_DT6: + case SRV6_MOBILE_POLICY_T_M_GTP4_DT46: + alloc_param_srv6_t_m_gtp4_dt (&ls_plugin_mem, ntohl (mp->fib_table), + ntohl (mp->local_fib_table), dt_type); + break; + case SRV6_MOBILE_POLICY_UNKNOWN_FUNCTION: + default: + return; // error + } + + behavior = sr_plugin_policy_fn_num_find_by (sm, (char *) mp->behavior, + behavior_size); + if (behavior == UINT16_MAX) + return; + } + else + { + return; + } + + int rv = 0; + ip6_address_t *segments = 0, *this_seg; + vec_add2 (segments, this_seg, 1); + clib_memset (this_seg, 0, sizeof (*this_seg)); + + rv = sr_policy_add (&bsid_addr, + segments, // ignore segments + &encap_src, + (u32) ~0, // ignore weight + SR_POLICY_TYPE_DEFAULT, // ignore type + (u32) ~0, // ignore fib_table + 1, // ignore is_encap, + behavior, ls_plugin_mem); + vec_free (segments); + REPLY_MACRO (VL_API_SR_MOBILE_POLICY_ADD_REPLY); +} + +#include <srv6-mobile/sr_mobile.api.c> +static clib_error_t * +sr_mobile_api_hookup (vlib_main_t *vm) +{ + /* + * Set up the (msg_name, crc, message-id) table + */ + REPLY_MSG_ID_BASE = setup_message_id_table (); + + return 0; +} + +VLIB_API_INIT_FUNCTION (sr_mobile_api_hookup); +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/src/plugins/srv6-mobile/sr_mobile_api.h b/src/plugins/srv6-mobile/sr_mobile_api.h new file mode 100644 index 00000000000..28979b1875c --- /dev/null +++ b/src/plugins/srv6-mobile/sr_mobile_api.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2022 BBSakura Networks Inc 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 + * + * 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. + */ + +/** + * @file + * @brief Segment Routing for mobile u-plane api + * + */ + +#ifndef included_sr_mobile_api_h +#define included_sr_mobile_api_h +#include <stdint.h> +#include <vnet/srv6/sr.h> +#include <vnet/ip/ip_types_api.h> + +#define srv6_mobile_strcmp_with_size(s1, s1len, s2) \ + ({ \ + int __indicator = 0; \ + strcmp_s_inline (s1, s1len, s2, &__indicator); \ + __indicator; \ + }) + +void alloc_param_srv6_end_m_gtp4_e (void **plugin_mem_p, + const void *v4src_addr, + const u32 v4src_position, + const u32 fib_table); + +void alloc_param_srv6_end_m_gtp6_e (void **plugin_mem_p, const u32 fib_table); + +void alloc_param_srv6_end_m_gtp6_d (void **plugin_mem_p, const void *sr_prefix, + const u32 sr_prefixlen, const u8 nhtype, + const bool drop_in, const u32 fib_table); + +void alloc_param_srv6_end_m_gtp6_di (void **plugin_mem_p, + const void *sr_prefix, + const u32 sr_prefixlen, const u8 nhtype); + +void alloc_param_srv6_end_m_gtp6_dt (void **plugin_mem_p, const u32 fib_index, + const u32 local_fib_index, + const u32 type); + +void alloc_param_srv6_t_m_gtp4_d (void **plugin_mem_p, + const void *v6src_prefix, + const u32 v6src_prefixlen, + const void *sr_prefix, + const u32 sr_prefixlen, const u32 fib_index, + const u8 nhtype, const bool drop_in); + +void alloc_param_srv6_t_m_gtp4_dt (void **plugin_mem_p, const u32 fib_index, + const u32 local_fib_index, const u8 type); + +#endif /* included_sr_mobile_api_h */ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/src/plugins/srv6-mobile/sr_mobile_types.api b/src/plugins/srv6-mobile/sr_mobile_types.api new file mode 100644 index 00000000000..f2dbe302d00 --- /dev/null +++ b/src/plugins/srv6-mobile/sr_mobile_types.api @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2022 BBSakura Networks Inc 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 + * + * 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. + */ + +option version = "0.1.0"; + +enum sr_mobile_nhtype : u8 +{ + SRV6_NHTYPE_API_NONE = 0, + SRV6_NHTYPE_API_IPV4 = 1, + SRV6_NHTYPE_API_IPV6 = 2, + SRV6_NHTYPE_API_NON_IP = 3, +};
\ No newline at end of file |