/* Note: This is temporal. We don't know whether to follow this path or
take the ip address of a loopback interface or even the OIF */
+void
+sr_set_source (ip6_address_t * address)
+{
+ clib_memcpy (&sr_pr_encaps_src, address, sizeof (sr_pr_encaps_src));
+}
+
static clib_error_t *
set_sr_src_command_fn (vlib_main_t * vm, unformat_input_t * input,
vlib_cli_command_t * cmd)
iph->protocol = IP_PROTOCOL_IPV6;
iph->hop_limit = IPv6_DEFAULT_HOP_LIMIT;
- srh = (ip6_sr_header_t *) (iph + 1);
- iph->protocol = IP_PROTOCOL_IPV6_ROUTE;
- srh->protocol = IP_PROTOCOL_IPV6;
- srh->type = ROUTING_HEADER_TYPE_SR;
- srh->segments_left = vec_len (sl) - 1;
- srh->first_segment = vec_len (sl) - 1;
- srh->length = ((sizeof (ip6_sr_header_t) +
- (vec_len (sl) * sizeof (ip6_address_t))) / 8) - 1;
- srh->flags = 0x00;
- srh->reserved = 0x00;
- addrp = srh->segments + vec_len (sl) - 1;
- vec_foreach (this_address, sl)
- {
- clib_memcpy (addrp->as_u8, this_address->as_u8, sizeof (ip6_address_t));
- addrp--;
- }
+ if (vec_len (sl) > 1)
+ {
+ srh = (ip6_sr_header_t *) (iph + 1);
+ iph->protocol = IP_PROTOCOL_IPV6_ROUTE;
+ srh->protocol = IP_PROTOCOL_IPV6;
+ srh->type = ROUTING_HEADER_TYPE_SR;
+ srh->segments_left = vec_len (sl) - 1;
+ srh->first_segment = vec_len (sl) - 1;
+ srh->length = ((sizeof (ip6_sr_header_t) +
+ (vec_len (sl) * sizeof (ip6_address_t))) / 8) - 1;
+ srh->flags = 0x00;
+ srh->reserved = 0x00;
+ addrp = srh->segments + vec_len (sl) - 1;
+ vec_foreach (this_address, sl)
+ {
+ clib_memcpy (addrp->as_u8, this_address->as_u8,
+ sizeof (ip6_address_t));
+ addrp--;
+ }
+ }
iph->dst_address.as_u64[0] = sl->as_u64[0];
iph->dst_address.as_u64[1] = sl->as_u64[1];
return rs;
ip6_sr_sl_t *segment_list;
pool_get (sm->sid_lists, segment_list);
- memset (segment_list, 0, sizeof (*segment_list));
+ clib_memset (segment_list, 0, sizeof (*segment_list));
vec_add1 (sr_policy->segments_lists, segment_list - sm->sid_lists);
/* Add FIB entry for BSID */
fhc = fib_table_get_flow_hash_config (sr_policy->fib_table,
- dpo_proto_to_fib (DPO_PROTO_IP6));
+ FIB_PROTOCOL_IP6);
dpo_set (&sr_policy->bsid_dpo, DPO_LOAD_BALANCE, DPO_PROTO_IP6,
load_balance_create (0, DPO_PROTO_IP6, fhc));
/* Add an SR policy object */
pool_get (sm->sr_policies, sr_policy);
- memset (sr_policy, 0, sizeof (*sr_policy));
+ clib_memset (sr_policy, 0, sizeof (*sr_policy));
clib_memcpy (&sr_policy->bsid, bsid, sizeof (ip6_address_t));
sr_policy->type = behavior;
sr_policy->fib_table = (fib_table != (u32) ~ 0 ? fib_table : 0); //Is default FIB 0 ?
if (sm->fib_table_ip6 == (u32) ~ 0)
{
sm->fib_table_ip6 = fib_table_create_and_lock (FIB_PROTOCOL_IP6,
+ FIB_SOURCE_SR,
"SRv6 steering of IP6 prefixes through BSIDs");
sm->fib_table_ip4 = fib_table_create_and_lock (FIB_PROTOCOL_IP6,
+ FIB_SOURCE_SR,
"SRv6 steering of IP4 prefixes through BSIDs");
}
segment_list = pool_elt_at_index (sm->sid_lists, *sl_index);
vec_free (segment_list->segments);
vec_free (segment_list->rewrite);
- vec_free (segment_list->rewrite_bsid);
+ if (!sr_policy->is_encap)
+ vec_free (segment_list->rewrite_bsid);
pool_put_index (sm->sid_lists, *sl_index);
}
/* If FIB empty unlock it */
if (!pool_elts (sm->sr_policies) && !pool_elts (sm->steer_policies))
{
- fib_table_unlock (sm->fib_table_ip6, FIB_PROTOCOL_IP6);
- fib_table_unlock (sm->fib_table_ip4, FIB_PROTOCOL_IP6);
+ fib_table_unlock (sm->fib_table_ip6, FIB_PROTOCOL_IP6, FIB_SOURCE_SR);
+ fib_table_unlock (sm->fib_table_ip4, FIB_PROTOCOL_IP6, FIB_SOURCE_SR);
sm->fib_table_ip6 = (u32) ~ 0;
sm->fib_table_ip4 = (u32) ~ 0;
}
segment_list = pool_elt_at_index (sm->sid_lists, sl_index);
vec_free (segment_list->segments);
vec_free (segment_list->rewrite);
- vec_free (segment_list->rewrite_bsid);
+ if (!sr_policy->is_encap)
+ vec_free (segment_list->rewrite_bsid);
pool_put_index (sm->sid_lists, sl_index);
vec_del1 (sr_policy->segments_lists,
sl_index_iterate - sr_policy->segments_lists);
rv = sr_policy_add (&bsid, segments, weight,
(is_spray ? SR_POLICY_TYPE_SPRAY :
SR_POLICY_TYPE_DEFAULT), fib_table, is_encap);
+ vec_free (segments);
}
else if (is_del)
rv = sr_policy_del ((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);
+ vec_free (segments);
}
switch (rv)
ip0->ip_version_traffic_class_and_flow_label =
clib_host_to_net_u32 (0 | ((6 & 0xF) << 28) |
((ip0_encap->tos & 0xFF) << 20));
- sr0 = (void *) (ip0 + 1);
- sr0->protocol = IP_PROTOCOL_IP_IN_IP;
+ if (ip0->protocol == IP_PROTOCOL_IPV6_ROUTE)
+ {
+ sr0 = (void *) (ip0 + 1);
+ sr0->protocol = IP_PROTOCOL_IP_IN_IP;
+ }
+ else
+ ip0->protocol = IP_PROTOCOL_IP_IN_IP;
}
/**
ip3->payload_length =
clib_host_to_net_u16 (b3->current_length - sizeof (ip6_header_t));
- sr0 = (void *) (ip0 + 1);
- sr1 = (void *) (ip1 + 1);
- sr2 = (void *) (ip2 + 1);
- sr3 = (void *) (ip3 + 1);
+ if (ip0->protocol == IP_PROTOCOL_IPV6_ROUTE)
+ {
+ sr0 = (void *) (ip0 + 1);
+ sr0->protocol = IP_PROTOCOL_IP6_NONXT;
+ }
+ else
+ ip0->protocol = IP_PROTOCOL_IP6_NONXT;
- sr0->protocol = sr1->protocol = sr2->protocol = sr3->protocol =
- IP_PROTOCOL_IP6_NONXT;
+ if (ip1->protocol == IP_PROTOCOL_IPV6_ROUTE)
+ {
+ sr1 = (void *) (ip1 + 1);
+ sr1->protocol = IP_PROTOCOL_IP6_NONXT;
+ }
+ else
+ ip1->protocol = IP_PROTOCOL_IP6_NONXT;
+
+ if (ip2->protocol == IP_PROTOCOL_IPV6_ROUTE)
+ {
+ sr2 = (void *) (ip2 + 1);
+ sr2->protocol = IP_PROTOCOL_IP6_NONXT;
+ }
+ else
+ ip2->protocol = IP_PROTOCOL_IP6_NONXT;
+
+ if (ip3->protocol == IP_PROTOCOL_IPV6_ROUTE)
+ {
+ sr3 = (void *) (ip3 + 1);
+ sr3->protocol = IP_PROTOCOL_IP6_NONXT;
+ }
+ else
+ ip3->protocol = IP_PROTOCOL_IP6_NONXT;
/* Which Traffic class and flow label do I set ? */
//ip0->ip_version_traffic_class_and_flow_label = clib_host_to_net_u32(0|((6&0xF)<<28)|((ip0_encap->tos&0xFF)<<20));
ip0->payload_length =
clib_host_to_net_u16 (b0->current_length - sizeof (ip6_header_t));
- sr0 = (void *) (ip0 + 1);
- sr0->protocol = IP_PROTOCOL_IP6_NONXT;
+ if (ip0->protocol == IP_PROTOCOL_IPV6_ROUTE)
+ {
+ sr0 = (void *) (ip0 + 1);
+ sr0->protocol = IP_PROTOCOL_IP6_NONXT;
+ }
+ else
+ ip0->protocol = IP_PROTOCOL_IP6_NONXT;
if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE) &&
PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))