sr: support define src ipv6 per encap policy
Can to define src ip of outer IPv6 Hdr for each encap policy. Along with that, I decided to develop it as API version V2. This is useful in the SRv6 MUP case. For example, it will be possible to handle multiple UPF destinations. Type: feature Change-Id: I44ff7b54e8868619069621ab53e194e2c7a17435 Signed-off-by: Takeru Hayasaka <hayatake396@gmail.com>
This commit is contained in:

committed by
Damjan Marion

parent
7550dd268f
commit
c4c205b091
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
option version = "2.0.0";
|
||||
option version = "2.1.0";
|
||||
|
||||
import "vnet/interface_types.api";
|
||||
import "vnet/ip/ip_types.api";
|
||||
@ -109,6 +109,65 @@ autoreply define sr_policy_mod
|
||||
vl_api_srv6_sid_list_t sids;
|
||||
};
|
||||
|
||||
enum sr_policy_type : u8
|
||||
{
|
||||
SR_API_POLICY_TYPE_DEFAULT = 0,
|
||||
SR_API_POLICY_TYPE_SPRAY = 1,
|
||||
SR_API_POLICY_TYPE_TEF = 2,
|
||||
};
|
||||
|
||||
/** \brief IPv6 SR policy add
|
||||
@param client_index - opaque cookie to identify the sender
|
||||
@param context - sender context, to match reply w/ request
|
||||
@param bsid is the bindingSID of the SR Policy
|
||||
@param weight is the weight of the sid list. optional.
|
||||
@param is_encap is the behavior of the SR policy. (0.SRH insert // 1.Encapsulation)
|
||||
@param type is the SR policy param. (0.Default // 1.Spray // 2.Tef)
|
||||
@param fib_table is the VRF where to install the FIB entry for the BSID
|
||||
@param sids is a srv6_sid_list object
|
||||
@param encap_src is a encaps IPv6 source addr. optional.
|
||||
*/
|
||||
autoreply define sr_policy_add_v2
|
||||
{
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
vl_api_ip6_address_t bsid_addr;
|
||||
u32 weight;
|
||||
bool is_encap;
|
||||
vl_api_sr_policy_type_t type [default=0x0];
|
||||
u32 fib_table;
|
||||
vl_api_srv6_sid_list_t sids;
|
||||
vl_api_ip6_address_t encap_src;
|
||||
option status="in_progress";
|
||||
};
|
||||
|
||||
/** \brief IPv6 SR policy modification
|
||||
@param client_index - opaque cookie to identify the sender
|
||||
@param context - sender context, to match reply w/ request
|
||||
@param bsid is the bindingSID of the SR Policy
|
||||
@param sr_policy_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 sl_index is the index of the Segment List to modify/delete
|
||||
@param weight is the weight of the sid list. optional.
|
||||
@param sids is a srv6_sid_list object
|
||||
@param encap_src is a encaps IPv6 source addr. optional.
|
||||
*/
|
||||
autoreply define sr_policy_mod_v2
|
||||
{
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
vl_api_ip6_address_t bsid_addr;
|
||||
u32 sr_policy_index;
|
||||
u32 fib_table;
|
||||
vl_api_sr_policy_op_t operation;
|
||||
u32 sl_index;
|
||||
u32 weight;
|
||||
vl_api_srv6_sid_list_t sids;
|
||||
vl_api_ip6_address_t encap_src;
|
||||
option status="in_progress";
|
||||
};
|
||||
|
||||
/** \brief IPv6 SR policy deletion
|
||||
@param client_index - opaque cookie to identify the sender
|
||||
@param context - sender context, to match reply w/ request
|
||||
@ -248,6 +307,29 @@ define sr_policies_details
|
||||
vl_api_srv6_sid_list_t sid_lists[num_sid_lists];
|
||||
};
|
||||
|
||||
/** \brief Dump the list of SR policies v2
|
||||
@param client_index - opaque cookie to identify the sender
|
||||
@param context - sender context, to match reply w/ request
|
||||
*/
|
||||
define sr_policies_v2_dump
|
||||
{
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
};
|
||||
|
||||
define sr_policies_v2_details
|
||||
{
|
||||
u32 context;
|
||||
vl_api_ip6_address_t bsid;
|
||||
vl_api_ip6_address_t encap_src;
|
||||
vl_api_sr_policy_type_t type;
|
||||
bool is_encap;
|
||||
u32 fib_table;
|
||||
u8 num_sid_lists;
|
||||
vl_api_srv6_sid_list_t sid_lists[num_sid_lists];
|
||||
option in_progress;
|
||||
};
|
||||
|
||||
/** \brief Dump the list of SR policies along with actual segment list index on VPP
|
||||
@param client_index - opaque cookie to identify the sender
|
||||
@param context - sender context, to match reply w/ request
|
||||
|
@ -112,6 +112,8 @@ typedef struct
|
||||
|
||||
u8 is_encap; /**< Mode (0 is SRH insert, 1 Encaps) */
|
||||
|
||||
ip6_address_t encap_src;
|
||||
|
||||
u16 plugin;
|
||||
void *plugin_mem;
|
||||
} ip6_sr_policy_t;
|
||||
@ -345,11 +347,12 @@ sr_policy_register_function (vlib_main_t * vm, u8 * fn_name,
|
||||
sr_p_plugin_callback_t * removal_fn);
|
||||
|
||||
extern int sr_policy_add (ip6_address_t *bsid, ip6_address_t *segments,
|
||||
u32 weight, u8 type, u32 fib_table, u8 is_encap,
|
||||
u16 plugin, void *plugin_mem);
|
||||
extern int sr_policy_mod (ip6_address_t * bsid, u32 index, u32 fib_table,
|
||||
u8 operation, ip6_address_t * segments,
|
||||
u32 sl_index, u32 weight);
|
||||
ip6_address_t *encap_src, u32 weight, u8 type,
|
||||
u32 fib_table, u8 is_encap, u16 plugin,
|
||||
void *plugin_mem);
|
||||
extern int sr_policy_mod (ip6_address_t *bsid, u32 index, u32 fib_table,
|
||||
u8 operation, ip6_address_t *segments,
|
||||
ip6_address_t *encap_src, u32 sl_index, u32 weight);
|
||||
extern int sr_policy_del (ip6_address_t * bsid, u32 index);
|
||||
|
||||
extern int
|
||||
|
@ -82,17 +82,16 @@ vl_api_sr_policy_add_t_handler (vl_api_sr_policy_add_t * mp)
|
||||
|
||||
ip6_address_decode (mp->bsid_addr, &bsid_addr);
|
||||
|
||||
/*
|
||||
* sr_policy_add (ip6_address_t *bsid, ip6_address_t *segments,
|
||||
* u32 weight, u8 behavior, u32 fib_table, u8 is_encap,
|
||||
* u16 behavior, void *plugin_mem)
|
||||
*/
|
||||
/*
|
||||
* sr_policy_add (ip6_address_t *bsid, ip6_address_t *segments,
|
||||
* ip6_address_t *encap_src,
|
||||
* u32 weight, u8 behavior, u32 fib_table, u8 is_encap,
|
||||
* u16 behavior, void *plugin_mem)
|
||||
*/
|
||||
int rv = 0;
|
||||
rv = sr_policy_add (&bsid_addr,
|
||||
segments,
|
||||
ntohl (mp->sids.weight),
|
||||
mp->is_spray, ntohl (mp->fib_table), mp->is_encap, 0,
|
||||
NULL);
|
||||
rv =
|
||||
sr_policy_add (&bsid_addr, segments, NULL, ntohl (mp->sids.weight),
|
||||
mp->is_spray, ntohl (mp->fib_table), mp->is_encap, 0, NULL);
|
||||
vec_free (segments);
|
||||
|
||||
REPLY_MACRO (VL_API_SR_POLICY_ADD_REPLY);
|
||||
@ -115,18 +114,93 @@ vl_api_sr_policy_mod_t_handler (vl_api_sr_policy_mod_t * mp)
|
||||
ip6_address_decode (mp->bsid_addr, &bsid_addr);
|
||||
|
||||
int rv = 0;
|
||||
/*
|
||||
* int
|
||||
* sr_policy_mod(ip6_address_t *bsid, u32 index, u32 fib_table,
|
||||
* u8 operation, ip6_address_t *segments, u32 sl_index,
|
||||
* u32 weight, u8 is_encap)
|
||||
*/
|
||||
rv = sr_policy_mod (&bsid_addr,
|
||||
ntohl (mp->sr_policy_index),
|
||||
ntohl (mp->fib_table),
|
||||
mp->operation,
|
||||
segments, ntohl (mp->sl_index),
|
||||
ntohl (mp->sids.weight));
|
||||
/*
|
||||
* int
|
||||
* sr_policy_mod(ip6_address_t *bsid, u32 index, u32 fib_table,
|
||||
* u8 operation, ip6_address_t *segments,
|
||||
* ip6_address_t *encap_src, u32 sl_index,
|
||||
* u32 weight, u8 is_encap)
|
||||
*/
|
||||
rv = sr_policy_mod (&bsid_addr, ntohl (mp->sr_policy_index),
|
||||
ntohl (mp->fib_table), mp->operation, segments, NULL,
|
||||
ntohl (mp->sl_index), ntohl (mp->sids.weight));
|
||||
vec_free (segments);
|
||||
|
||||
REPLY_MACRO (VL_API_SR_POLICY_MOD_REPLY);
|
||||
}
|
||||
|
||||
static void
|
||||
vl_api_sr_policy_add_v2_t_handler (vl_api_sr_policy_add_v2_t *mp)
|
||||
{
|
||||
vl_api_sr_policy_add_v2_reply_t *rmp;
|
||||
ip6_address_t *segments = 0, *seg;
|
||||
ip6_address_t bsid_addr;
|
||||
ip6_address_t encap_src;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < mp->sids.num_sids; i++)
|
||||
{
|
||||
vec_add2 (segments, seg, 1);
|
||||
ip6_address_decode (mp->sids.sids[i], seg);
|
||||
}
|
||||
|
||||
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 ();
|
||||
}
|
||||
/*
|
||||
* sr_policy_add (ip6_address_t *bsid, ip6_address_t *segments,
|
||||
* ip6_address_t *encap_src,
|
||||
* u32 weight, u8 behavior, u32 fib_table, u8 is_encap,
|
||||
* u16 behavior, void *plugin_mem)
|
||||
*/
|
||||
int rv = 0;
|
||||
rv =
|
||||
sr_policy_add (&bsid_addr, segments, &encap_src, ntohl (mp->sids.weight),
|
||||
mp->type, ntohl (mp->fib_table), mp->is_encap, 0, NULL);
|
||||
vec_free (segments);
|
||||
|
||||
REPLY_MACRO (VL_API_SR_POLICY_ADD_REPLY);
|
||||
}
|
||||
|
||||
static void
|
||||
vl_api_sr_policy_mod_v2_t_handler (vl_api_sr_policy_mod_v2_t *mp)
|
||||
{
|
||||
vl_api_sr_policy_mod_v2_reply_t *rmp;
|
||||
ip6_address_t *segments = 0, *seg;
|
||||
ip6_address_t bsid_addr;
|
||||
ip6_address_t encap_src;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < mp->sids.num_sids; i++)
|
||||
{
|
||||
vec_add2 (segments, seg, 1);
|
||||
ip6_address_decode (mp->sids.sids[i], seg);
|
||||
}
|
||||
|
||||
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 ();
|
||||
}
|
||||
|
||||
int rv = 0;
|
||||
/*
|
||||
* int
|
||||
* sr_policy_mod(ip6_address_t *bsid, u32 index, u32 fib_table,
|
||||
* u8 operation, ip6_address_t *segments,
|
||||
* ip6_address_t *encap_src, u32 sl_index,
|
||||
* u32 weight, u8 is_encap)
|
||||
*/
|
||||
rv =
|
||||
sr_policy_mod (&bsid_addr, ntohl (mp->sr_policy_index),
|
||||
ntohl (mp->fib_table), mp->operation, segments, &encap_src,
|
||||
ntohl (mp->sl_index), ntohl (mp->sids.weight));
|
||||
vec_free (segments);
|
||||
|
||||
REPLY_MACRO (VL_API_SR_POLICY_MOD_REPLY);
|
||||
@ -387,7 +461,68 @@ vl_api_sr_policies_dump_t_handler (vl_api_sr_policies_dump_t * mp)
|
||||
/* *INDENT-ON* */
|
||||
}
|
||||
|
||||
static void
|
||||
send_sr_policies_v2_details (ip6_sr_policy_t *t, vl_api_registration_t *reg,
|
||||
u32 context)
|
||||
{
|
||||
vl_api_sr_policies_v2_details_t *rmp;
|
||||
ip6_sr_main_t *sm = &sr_main;
|
||||
|
||||
u32 *sl_index, slidx = 0;
|
||||
ip6_sr_sl_t *segment_list = 0;
|
||||
ip6_address_t *segment;
|
||||
vl_api_srv6_sid_list_t *api_sid_list;
|
||||
|
||||
rmp = vl_msg_api_alloc (sizeof (*rmp) + vec_len (t->segments_lists) *
|
||||
sizeof (vl_api_srv6_sid_list_t));
|
||||
clib_memset (rmp, 0,
|
||||
(sizeof (*rmp) + vec_len (t->segments_lists) *
|
||||
sizeof (vl_api_srv6_sid_list_t)));
|
||||
|
||||
rmp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_SR_POLICIES_V2_DETAILS);
|
||||
ip6_address_encode (&t->bsid, rmp->bsid);
|
||||
ip6_address_encode (&t->encap_src, rmp->encap_src);
|
||||
rmp->is_encap = t->is_encap;
|
||||
rmp->type = t->type;
|
||||
rmp->fib_table = htonl (t->fib_table);
|
||||
rmp->num_sid_lists = vec_len (t->segments_lists);
|
||||
|
||||
/* Fill in all the segments lists */
|
||||
vec_foreach (sl_index, t->segments_lists)
|
||||
{
|
||||
segment_list = pool_elt_at_index (sm->sid_lists, *sl_index);
|
||||
|
||||
api_sid_list = &rmp->sid_lists[sl_index - t->segments_lists];
|
||||
|
||||
api_sid_list->num_sids = vec_len (segment_list->segments);
|
||||
api_sid_list->weight = htonl (segment_list->weight);
|
||||
slidx = 0;
|
||||
vec_foreach (segment, segment_list->segments)
|
||||
{
|
||||
ip6_address_encode (segment, api_sid_list->sids[slidx++]);
|
||||
}
|
||||
}
|
||||
|
||||
rmp->context = context;
|
||||
vl_api_send_msg (reg, (u8 *) rmp);
|
||||
}
|
||||
|
||||
static void
|
||||
vl_api_sr_policies_v2_dump_t_handler (vl_api_sr_policies_v2_dump_t *mp)
|
||||
{
|
||||
vl_api_registration_t *reg;
|
||||
ip6_sr_main_t *sm = &sr_main;
|
||||
ip6_sr_policy_t *t;
|
||||
|
||||
reg = vl_api_client_index_to_registration (mp->client_index);
|
||||
if (!reg)
|
||||
return;
|
||||
|
||||
pool_foreach (t, sm->sr_policies)
|
||||
{
|
||||
send_sr_policies_v2_details (t, reg, mp->context);
|
||||
}
|
||||
}
|
||||
|
||||
static void send_sr_policies_details_with_sl_index
|
||||
(ip6_sr_policy_t * t, vl_api_registration_t * reg, u32 context)
|
||||
|
@ -193,11 +193,12 @@ VLIB_CLI_COMMAND (set_sr_hop_limit_command, static) = {
|
||||
* @brief SR rewrite string computation for IPv6 encapsulation (inline)
|
||||
*
|
||||
* @param sl is a vector of IPv6 addresses composing the Segment List
|
||||
* @param src_v6addr is a encaps IPv6 source addr
|
||||
*
|
||||
* @return precomputed rewrite string for encapsulation
|
||||
*/
|
||||
static inline u8 *
|
||||
compute_rewrite_encaps (ip6_address_t *sl, u8 type)
|
||||
compute_rewrite_encaps (ip6_address_t *sl, ip6_address_t *src_v6addr, u8 type)
|
||||
{
|
||||
ip6_header_t *iph;
|
||||
ip6_sr_header_t *srh;
|
||||
@ -225,8 +226,8 @@ compute_rewrite_encaps (ip6_address_t *sl, u8 type)
|
||||
iph = (ip6_header_t *) rs;
|
||||
iph->ip_version_traffic_class_and_flow_label =
|
||||
clib_host_to_net_u32 (0 | ((6 & 0xF) << 28));
|
||||
iph->src_address.as_u64[0] = sr_pr_encaps_src.as_u64[0];
|
||||
iph->src_address.as_u64[1] = sr_pr_encaps_src.as_u64[1];
|
||||
iph->src_address.as_u64[0] = src_v6addr->as_u64[0];
|
||||
iph->src_address.as_u64[1] = src_v6addr->as_u64[1];
|
||||
iph->payload_length = header_length - IPv6_DEFAULT_HEADER_LENGTH;
|
||||
iph->protocol = IP_PROTOCOL_IPV6;
|
||||
iph->hop_limit = sr_pr_encaps_hop_limit;
|
||||
@ -370,18 +371,20 @@ compute_rewrite_bsid (ip6_address_t * sl)
|
||||
*
|
||||
* @param sr_policy is the SR policy where the SL will be added
|
||||
* @param sl is a vector of IPv6 addresses composing the Segment List
|
||||
* @param encap_src is a encaps IPv6 source addr. optional.
|
||||
* @param weight is the weight of the SegmentList (for load-balancing purposes)
|
||||
* @param is_encap represents the mode (SRH insertion vs Encapsulation)
|
||||
*
|
||||
* @return pointer to the just created segment list
|
||||
*/
|
||||
static inline ip6_sr_sl_t *
|
||||
create_sl (ip6_sr_policy_t * sr_policy, ip6_address_t * sl, u32 weight,
|
||||
u8 is_encap)
|
||||
create_sl (ip6_sr_policy_t *sr_policy, ip6_address_t *sl,
|
||||
ip6_address_t *encap_src, u32 weight, u8 is_encap)
|
||||
{
|
||||
ip6_sr_main_t *sm = &sr_main;
|
||||
ip6_sr_sl_t *segment_list;
|
||||
sr_policy_fn_registration_t *plugin = 0;
|
||||
ip6_address_t encap_srcv6 = sr_pr_encaps_src;
|
||||
|
||||
pool_get (sm->sid_lists, segment_list);
|
||||
clib_memset (segment_list, 0, sizeof (*segment_list));
|
||||
@ -400,8 +403,14 @@ create_sl (ip6_sr_policy_t * sr_policy, ip6_address_t * sl, u32 weight,
|
||||
|
||||
if (is_encap)
|
||||
{
|
||||
segment_list->rewrite = compute_rewrite_encaps (sl, sr_policy->type);
|
||||
if (encap_src)
|
||||
{
|
||||
clib_memcpy_fast (&encap_srcv6, encap_src, sizeof (ip6_address_t));
|
||||
}
|
||||
segment_list->rewrite =
|
||||
compute_rewrite_encaps (sl, &encap_srcv6, sr_policy->type);
|
||||
segment_list->rewrite_bsid = segment_list->rewrite;
|
||||
sr_policy->encap_src = encap_srcv6;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -660,17 +669,19 @@ update_replicate (ip6_sr_policy_t * sr_policy)
|
||||
*
|
||||
* @param bsid is the bindingSID of the SR Policy
|
||||
* @param segments is a vector of IPv6 address composing the segment list
|
||||
* @param encap_src is a encaps IPv6 source addr. optional.
|
||||
* @param weight is the weight of the sid list. optional.
|
||||
* @param behavior is the behavior of the SR policy. (default//spray)
|
||||
* @param fib_table is the VRF where to install the FIB entry for the BSID
|
||||
* @param is_encap (bool) whether SR policy should behave as Encap/SRH Insertion
|
||||
* @param is_encap (bool) whether SR policy should behave as Encap/SRH
|
||||
* Insertion
|
||||
*
|
||||
* @return 0 if correct, else error
|
||||
*/
|
||||
int
|
||||
sr_policy_add (ip6_address_t *bsid, ip6_address_t *segments, u32 weight,
|
||||
u8 type, u32 fib_table, u8 is_encap, u16 plugin,
|
||||
void *ls_plugin_mem)
|
||||
sr_policy_add (ip6_address_t *bsid, ip6_address_t *segments,
|
||||
ip6_address_t *encap_src, u32 weight, u8 type, u32 fib_table,
|
||||
u8 is_encap, u16 plugin, void *ls_plugin_mem)
|
||||
{
|
||||
ip6_sr_main_t *sm = &sr_main;
|
||||
ip6_sr_policy_t *sr_policy = 0;
|
||||
@ -726,7 +737,7 @@ sr_policy_add (ip6_address_t *bsid, ip6_address_t *segments, u32 weight,
|
||||
NULL);
|
||||
|
||||
/* Create a segment list and add the index to the SR policy */
|
||||
create_sl (sr_policy, segments, weight, is_encap);
|
||||
create_sl (sr_policy, segments, encap_src, weight, is_encap);
|
||||
|
||||
/* If FIB doesnt exist, create them */
|
||||
if (sm->fib_table_ip6 == (u32) ~ 0)
|
||||
@ -856,6 +867,7 @@ sr_policy_del (ip6_address_t * bsid, u32 index)
|
||||
* @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 encap_src is a encaps IPv6 source addr. optional.
|
||||
* @param sl_index is the index of the Segment List to modify/delete
|
||||
* @param weight is the weight of the sid list. optional.
|
||||
* @param is_encap Mode. Encapsulation or SRH insertion.
|
||||
@ -863,8 +875,8 @@ sr_policy_del (ip6_address_t * bsid, u32 index)
|
||||
* @return 0 if correct, else error
|
||||
*/
|
||||
int
|
||||
sr_policy_mod (ip6_address_t * bsid, u32 index, u32 fib_table,
|
||||
u8 operation, ip6_address_t * segments, u32 sl_index,
|
||||
sr_policy_mod (ip6_address_t *bsid, u32 index, u32 fib_table, u8 operation,
|
||||
ip6_address_t *segments, ip6_address_t *encap_src, u32 sl_index,
|
||||
u32 weight)
|
||||
{
|
||||
ip6_sr_main_t *sm = &sr_main;
|
||||
@ -889,8 +901,8 @@ sr_policy_mod (ip6_address_t * bsid, u32 index, u32 fib_table,
|
||||
if (operation == 1) /* Add SR List to an existing SR policy */
|
||||
{
|
||||
/* Create the new SL */
|
||||
segment_list =
|
||||
create_sl (sr_policy, segments, weight, sr_policy->is_encap);
|
||||
segment_list = create_sl (sr_policy, segments, encap_src, weight,
|
||||
sr_policy->is_encap);
|
||||
|
||||
/* Create a new LB DPO */
|
||||
if (sr_policy->type == SR_POLICY_TYPE_DEFAULT)
|
||||
@ -963,7 +975,7 @@ sr_policy_command_fn (vlib_main_t * vm, unformat_input_t * input,
|
||||
int rv = -1;
|
||||
char is_del = 0, is_add = 0, is_mod = 0;
|
||||
char policy_set = 0;
|
||||
ip6_address_t bsid, next_address;
|
||||
ip6_address_t bsid, next_address, src_v6addr;
|
||||
u32 sr_policy_index = (u32) ~ 0, sl_index = (u32) ~ 0;
|
||||
u32 weight = (u32) ~ 0, fib_table = (u32) ~ 0;
|
||||
ip6_address_t *segments = 0, *this_seg;
|
||||
@ -972,6 +984,7 @@ sr_policy_command_fn (vlib_main_t * vm, unformat_input_t * input,
|
||||
u8 type = SR_POLICY_TYPE_DEFAULT;
|
||||
u16 behavior = 0;
|
||||
void *ls_plugin_mem = 0;
|
||||
ip6_address_t *encap_src = 0;
|
||||
|
||||
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
|
||||
{
|
||||
@ -995,6 +1008,10 @@ sr_policy_command_fn (vlib_main_t * vm, unformat_input_t * input,
|
||||
clib_memcpy_fast (this_seg->as_u8, next_address.as_u8,
|
||||
sizeof (*this_seg));
|
||||
}
|
||||
else if (unformat (input, "v6src %U", unformat_ip6_address, &src_v6addr))
|
||||
{
|
||||
encap_src = &src_v6addr;
|
||||
}
|
||||
else if (unformat (input, "add sl"))
|
||||
operation = 1;
|
||||
else if (unformat (input, "del sl index %d", &sl_index))
|
||||
@ -1059,8 +1076,8 @@ sr_policy_command_fn (vlib_main_t * vm, unformat_input_t * input,
|
||||
if (vec_len (segments) == 0)
|
||||
return clib_error_return (0, "No Segment List specified");
|
||||
|
||||
rv = sr_policy_add (&bsid, segments, weight, type, fib_table, is_encap,
|
||||
behavior, ls_plugin_mem);
|
||||
rv = sr_policy_add (&bsid, segments, encap_src, weight, type, fib_table,
|
||||
is_encap, behavior, ls_plugin_mem);
|
||||
|
||||
vec_free (segments);
|
||||
}
|
||||
@ -1078,9 +1095,9 @@ sr_policy_command_fn (vlib_main_t * vm, unformat_input_t * input,
|
||||
if (operation == 3 && weight == (u32) ~ 0)
|
||||
return clib_error_return (0, "No new weight for the SL specified");
|
||||
|
||||
rv = sr_policy_mod ((sr_policy_index != (u32) ~ 0 ? NULL : &bsid),
|
||||
rv = sr_policy_mod ((sr_policy_index != (u32) ~0 ? NULL : &bsid),
|
||||
sr_policy_index, fib_table, operation, segments,
|
||||
sl_index, weight);
|
||||
encap_src, sl_index, weight);
|
||||
|
||||
if (segments)
|
||||
vec_free (segments);
|
||||
@ -1170,6 +1187,11 @@ show_sr_policies_command_fn (vlib_main_t * vm, unformat_input_t * input,
|
||||
vlib_cli_output (vm, "\tBehavior: %s",
|
||||
(sr_policy->is_encap ? "Encapsulation" :
|
||||
"SRH insertion"));
|
||||
if (sr_policy->is_encap)
|
||||
{
|
||||
vlib_cli_output (vm, "\tEncapSrcIP: %U", format_ip6_address,
|
||||
&sr_policy->encap_src);
|
||||
}
|
||||
switch (sr_policy->type)
|
||||
{
|
||||
case SR_POLICY_TYPE_SPRAY:
|
||||
|
@ -79,6 +79,18 @@ api_sr_policy_add (vat_main_t *vam)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
api_sr_policy_mod_v2 (vat_main_t *vam)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
api_sr_policy_add_v2 (vat_main_t *vam)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
api_sr_localsids_dump (vat_main_t *vam)
|
||||
{
|
||||
@ -91,6 +103,12 @@ api_sr_policies_dump (vat_main_t *vam)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
api_sr_policies_v2_dump (vat_main_t *vam)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
api_sr_policies_with_sl_index_dump (vat_main_t *vam)
|
||||
{
|
||||
@ -108,6 +126,11 @@ vl_api_sr_policies_details_t_handler (vl_api_sr_policies_details_t *mp)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
vl_api_sr_policies_v2_details_t_handler (vl_api_sr_policies_v2_details_t *mp)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
vl_api_sr_localsids_details_t_handler (vl_api_sr_localsids_details_t *mp)
|
||||
{
|
||||
|
@ -10,6 +10,7 @@ from vpp_srv6 import (
|
||||
SRv6LocalSIDBehaviors,
|
||||
VppSRv6LocalSID,
|
||||
VppSRv6Policy,
|
||||
VppSRv6PolicyV2,
|
||||
SRv6PolicyType,
|
||||
VppSRv6Steering,
|
||||
SRv6PolicySteeringTypes,
|
||||
@ -248,6 +249,121 @@ class TestSRv6(VppTestCase):
|
||||
# cleanup interfaces
|
||||
self.teardown_interfaces()
|
||||
|
||||
def test_SRv6_T_Encaps_with_v6src(self):
|
||||
"""Test SRv6 Transit.Encaps behavior for IPv6 and select multiple src v6addr case."""
|
||||
# send traffic to one destination interface
|
||||
# source and destination are IPv6 only
|
||||
self.setup_interfaces(ipv6=[True, True])
|
||||
|
||||
# configure FIB entries
|
||||
route = VppIpRoute(
|
||||
self, "a4::", 64, [VppRoutePath(self.pg1.remote_ip6, self.pg1.sw_if_index)]
|
||||
)
|
||||
route.add_vpp_config()
|
||||
|
||||
# configure encaps IPv6 source address
|
||||
# needs to be done before SR Policy config
|
||||
# TODO: API?
|
||||
self.vapi.cli("set sr encaps source addr a3::")
|
||||
|
||||
bsid = "a3::9999:1"
|
||||
other_src_ip = "b1::"
|
||||
# configure SRv6 Policy
|
||||
# Note: segment list order: first -> last
|
||||
sr_policy = VppSRv6PolicyV2(
|
||||
self,
|
||||
bsid=bsid,
|
||||
is_encap=1,
|
||||
sr_type=SRv6PolicyType.SR_POLICY_TYPE_DEFAULT,
|
||||
weight=1,
|
||||
fib_table=0,
|
||||
segments=["a4::", "a5::", "a6::c7"],
|
||||
encap_src=other_src_ip,
|
||||
source=other_src_ip,
|
||||
)
|
||||
sr_policy.add_vpp_config()
|
||||
self.sr_policy = sr_policy
|
||||
|
||||
# log the sr policies
|
||||
self.logger.info(self.vapi.cli("show sr policies"))
|
||||
|
||||
# steer IPv6 traffic to a7::/64 into SRv6 Policy
|
||||
# use the bsid of the above self.sr_policy
|
||||
pol_steering = VppSRv6Steering(
|
||||
self,
|
||||
bsid=self.sr_policy.bsid,
|
||||
prefix="a7::",
|
||||
mask_width=64,
|
||||
traffic_type=SRv6PolicySteeringTypes.SR_STEER_IPV6,
|
||||
sr_policy_index=0,
|
||||
table_id=0,
|
||||
sw_if_index=0,
|
||||
)
|
||||
pol_steering.add_vpp_config()
|
||||
|
||||
# log the sr steering policies
|
||||
self.logger.info(self.vapi.cli("show sr steering-policies"))
|
||||
|
||||
# create packets
|
||||
count = len(self.pg_packet_sizes)
|
||||
dst_inner = "a7::1234"
|
||||
pkts = []
|
||||
|
||||
# create IPv6 packets without SRH
|
||||
packet_header = self.create_packet_header_IPv6(dst_inner)
|
||||
# create traffic stream pg0->pg1
|
||||
pkts.extend(
|
||||
self.create_stream(
|
||||
self.pg0, self.pg1, packet_header, self.pg_packet_sizes, count
|
||||
)
|
||||
)
|
||||
|
||||
# create IPv6 packets with SRH
|
||||
# packets with segments-left 1, active segment a7::
|
||||
packet_header = self.create_packet_header_IPv6_SRH(
|
||||
sidlist=["a8::", "a7::", "a6::"], segleft=1
|
||||
)
|
||||
# create traffic stream pg0->pg1
|
||||
pkts.extend(
|
||||
self.create_stream(
|
||||
self.pg0, self.pg1, packet_header, self.pg_packet_sizes, count
|
||||
)
|
||||
)
|
||||
|
||||
# create IPv6 packets with SRH and IPv6
|
||||
# packets with segments-left 1, active segment a7::
|
||||
packet_header = self.create_packet_header_IPv6_SRH_IPv6(
|
||||
dst_inner, sidlist=["a8::", "a7::", "a6::"], segleft=1
|
||||
)
|
||||
# create traffic stream pg0->pg1
|
||||
pkts.extend(
|
||||
self.create_stream(
|
||||
self.pg0, self.pg1, packet_header, self.pg_packet_sizes, count
|
||||
)
|
||||
)
|
||||
|
||||
# send packets and verify received packets
|
||||
self.send_and_verify_pkts(
|
||||
self.pg0, pkts, self.pg1, self.compare_rx_tx_packet_T_Encaps
|
||||
)
|
||||
|
||||
# log the localsid counters
|
||||
self.logger.info(self.vapi.cli("show sr localsid"))
|
||||
|
||||
# remove SR steering
|
||||
pol_steering.remove_vpp_config()
|
||||
self.logger.info(self.vapi.cli("show sr steering-policies"))
|
||||
|
||||
# remove SR Policies
|
||||
self.sr_policy.remove_vpp_config()
|
||||
self.logger.info(self.vapi.cli("show sr policies"))
|
||||
|
||||
# remove FIB entries
|
||||
# done by tearDown
|
||||
|
||||
# cleanup interfaces
|
||||
self.teardown_interfaces()
|
||||
|
||||
@unittest.skipUnless(0, "PC to fix")
|
||||
def test_SRv6_T_Insert(self):
|
||||
"""Test SRv6 Transit.Insert behavior (IPv6 only)."""
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
from vpp_object import VppObject
|
||||
from socket import inet_pton, inet_ntop, AF_INET, AF_INET6
|
||||
import copy
|
||||
|
||||
|
||||
class SRv6LocalSIDBehaviors:
|
||||
@ -28,6 +29,7 @@ class SRv6PolicyType:
|
||||
# from src/vnet/srv6/sr.h
|
||||
SR_POLICY_TYPE_DEFAULT = 0
|
||||
SR_POLICY_TYPE_SPRAY = 1
|
||||
SR_POLICY_TYPE_TEF = 2
|
||||
|
||||
|
||||
class SRv6PolicySteeringTypes:
|
||||
@ -148,6 +150,79 @@ class VppSRv6Policy(VppObject):
|
||||
)
|
||||
|
||||
|
||||
class VppSRv6PolicyV2(VppObject):
|
||||
"""
|
||||
SRv6 Policy
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
test,
|
||||
bsid,
|
||||
is_encap,
|
||||
sr_type,
|
||||
weight,
|
||||
fib_table,
|
||||
segments,
|
||||
encap_src,
|
||||
source,
|
||||
):
|
||||
self._test = test
|
||||
self.bsid = bsid
|
||||
self.is_encap = is_encap
|
||||
self.sr_type = sr_type
|
||||
self.weight = weight
|
||||
self.fib_table = fib_table
|
||||
self.segments = segments
|
||||
self.encap_src = encap_src
|
||||
self.n_segments = len(segments)
|
||||
|
||||
# source not passed to API
|
||||
# self.source = inet_pton(AF_INET6, source)
|
||||
self.source = source
|
||||
self._configured = False
|
||||
|
||||
def add_vpp_config(self):
|
||||
self._test.vapi.sr_policy_add_v2(
|
||||
bsid_addr=self.bsid,
|
||||
weight=self.weight,
|
||||
is_encap=self.is_encap,
|
||||
type=self.sr_type,
|
||||
fib_table=self.fib_table,
|
||||
encap_src=self.encap_src,
|
||||
sids={
|
||||
"num_sids": self.n_segments,
|
||||
"sids": self._get_fixed_segments(),
|
||||
"weight": 1,
|
||||
},
|
||||
)
|
||||
self._configured = True
|
||||
|
||||
def remove_vpp_config(self):
|
||||
self._test.vapi.sr_policy_del(self.bsid)
|
||||
self._configured = False
|
||||
|
||||
def query_vpp_config(self):
|
||||
# no API to query SR Policies
|
||||
# use _configured flag for now
|
||||
return self._configured
|
||||
|
||||
def object_id(self):
|
||||
return "%d;%s-><%s>;%d" % (
|
||||
self.sr_type,
|
||||
self.bsid,
|
||||
",".join(self.segments),
|
||||
self.is_encap,
|
||||
)
|
||||
|
||||
def _get_fixed_segments(self):
|
||||
segs = copy.copy(self.segments)
|
||||
# note: array expect size is 16
|
||||
for _ in range(16 - self.n_segments):
|
||||
segs.append("")
|
||||
return segs
|
||||
|
||||
|
||||
class VppSRv6Steering(VppObject):
|
||||
"""
|
||||
SRv6 Steering
|
||||
@ -177,7 +252,7 @@ class VppSRv6Steering(VppObject):
|
||||
def add_vpp_config(self):
|
||||
self._test.vapi.sr_steering_add_del(
|
||||
is_del=0,
|
||||
bsid=self.bsid,
|
||||
bsid_addr=self.bsid,
|
||||
sr_policy_index=self.sr_policy_index,
|
||||
table_id=self.table_id,
|
||||
prefix={"address": self.prefix, "len": self.mask_width},
|
||||
@ -189,7 +264,7 @@ class VppSRv6Steering(VppObject):
|
||||
def remove_vpp_config(self):
|
||||
self._test.vapi.sr_steering_add_del(
|
||||
is_del=1,
|
||||
bsid=self.bsid,
|
||||
bsid_addr=self.bsid,
|
||||
sr_policy_index=self.sr_policy_index,
|
||||
table_id=self.table_id,
|
||||
prefix={"address": self.prefix, "len": self.mask_width},
|
||||
|
Reference in New Issue
Block a user