63 #define foreach_sr_policy_rewrite_next \ 64 _(IP6_LOOKUP, "ip6-lookup") \ 65 _(ERROR, "error-drop") 69 #define _(s,n) SR_POLICY_REWRITE_NEXT_##s, 76 #define foreach_sr_policy_rewrite_error \ 77 _(INTERNAL_ERROR, "Segment Routing undefined error") \ 78 _(BSID_ZERO, "BSID with SL = 0") \ 79 _(COUNTER_TOTAL, "SR steered IPv6 packets") \ 80 _(COUNTER_ENCAP, "SR: Encaps packets") \ 81 _(COUNTER_INSERT, "SR: SRH inserted packets") \ 82 _(COUNTER_BSID, "SR: BindingSID steered packets") 86 #define _(sym,str) SR_POLICY_REWRITE_ERROR_##sym, 93 #define _(sym,string) string, 138 .path =
"set sr encaps source",
139 .short_help =
"set sr encaps source addr <ip6_addr>",
158 u32 header_length = 0;
173 clib_host_to_net_u32 (0 | ((6 & 0xF) << 28));
183 iph->
protocol = IP_PROTOCOL_IPV6_ROUTE;
217 u32 header_length = 0;
256 u32 header_length = 0;
306 clib_memset (segment_list, 0,
sizeof (*segment_list));
376 .ip6 = sr_policy->
bsid,
481 .ip6 = sr_policy->
bsid,
554 u32 weight,
u8 behavior,
u32 fib_table,
u8 is_encap)
582 (fib_table != (
u32) ~ 0 ? fib_table : 0));
595 sr_policy->
type = behavior;
596 sr_policy->
fib_table = (fib_table != (
u32) ~ 0 ? fib_table : 0);
604 create_sl (sr_policy, segments, weight, is_encap);
611 "SRv6 steering of IP6 prefixes through BSIDs");
614 "SRv6 steering of IP4 prefixes through BSIDs");
662 .ip6 = sr_policy->
bsid,
736 u32 *sl_index_iterate;
766 else if (operation == 2)
774 if (*sl_index_iterate == sl_index)
777 if (*sl_index_iterate != sl_index)
796 else if (operation == 3)
800 if (*sl_index_iterate == sl_index)
803 if (*sl_index_iterate != sl_index)
808 segment_list->
weight = weight;
828 char is_del = 0,
is_add = 0, is_mod = 0;
831 u32 sr_policy_index = (
u32) ~ 0, sl_index = (
u32) ~ 0;
832 u32 weight = (
u32) ~ 0, fib_table = (
u32) ~ 0;
842 else if (!
is_add && !is_mod && !is_del &&
unformat (input,
"del"))
844 else if (!
is_add && !is_mod && !is_del &&
unformat (input,
"mod"))
849 else if (!
is_add && !policy_set
850 &&
unformat (input,
"index %d", &sr_policy_index))
852 else if (
unformat (input,
"weight %d", &weight));
860 else if (
unformat (input,
"add sl"))
862 else if (
unformat (input,
"del sl index %d", &sl_index))
864 else if (
unformat (input,
"mod sl index %d", &sl_index))
866 else if (fib_table == (
u32) ~ 0
867 &&
unformat (input,
"fib-table %d", &fib_table));
870 else if (
unformat (input,
"insert"))
878 if (!
is_add && !is_mod && !is_del)
900 if (operation != 1 && sl_index == (
u32) ~ 0)
902 if (operation == 1 &&
vec_len (segments) == 0)
904 if (operation == 3 && weight == (
u32) ~ 0)
907 sr_policy_index, fib_table, operation, segments,
920 "There is already a FIB entry for the BindingSID address.\n" 921 "The SR policy could not be created.");
926 "The selected SR policy only contains ONE segment list. " 927 "Please remove the SR policy instead");
930 "Could not delete the segment list. " 931 "It is not associated with that SR policy.");
934 "Could not modify the segment list. " 935 "The given SL is not associated with such SR policy.");
945 .short_help =
"sr policy [add||del||mod] [bsid 2001::1||index 5] " 946 "next A:: next B:: next C:: (weight 1) (fib-table 2) (encap|insert)",
948 "Manipulation of SR policies.\n" 949 "A Segment Routing policy may contain several SID lists. Each SID list has\n" 950 "an associated weight (default 1), which will result in wECMP (uECMP).\n" 951 "Segment Routing policies might be of type encapsulation or srh insertion\n" 952 "Each SR policy will be associated with a unique BindingSID.\n" 953 "A BindingSID is a locally allocated SegmentID. For every packet that arrives\n" 954 "with IPv6_DA:BSID such traffic will be steered into the SR policy.\n" 955 "The add command will create a SR policy with its first segment list (sl)\n" 956 "The mod command allows you to add, remove, or modify the existing segment lists\n" 957 "within an SR policy.\n" 958 "The del command allows you to delete a SR policy along with all its associated\n" 984 {vec_add1 (vec_policies, sr_policy); } );
989 sr_policy = vec_policies[
i];
994 (sr_policy->
is_encap ?
"Encapsulation" :
1006 s =
format (s,
"\t[%u].- ", *sl_index);
1013 s =
format (s,
"\b\b > ");
1024 .path =
"show sr policies",
1025 .short_help =
"show sr policies",
1043 (s,
"SR-policy-rewrite: src %U dst %U",
1076 u32 n_left_from, next_index, *from, *to_next;
1083 int encap_pkts = 0, bsid_pkts = 0;
1085 while (n_left_from > 0)
1092 while (n_left_from >= 8 && n_left_to_next >= 4)
1094 u32 bi0, bi1, bi2, bi3;
1096 u32 next0, next1, next2, next3;
1097 next0 = next1 = next2 = next3 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
1099 ip6_header_t *ip0_encap, *ip1_encap, *ip2_encap, *ip3_encap;
1123 to_next[0] = bi0 = from[0];
1124 to_next[1] = bi1 = from[1];
1125 to_next[2] = bi2 = from[2];
1126 to_next[3] = bi3 = from[3];
1130 n_left_to_next -= 4;
1233 n_left_to_next, bi0, bi1, bi2, bi3,
1234 next0, next1, next2, next3);
1238 while (n_left_from > 0 && n_left_to_next > 0)
1244 u32 next0 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
1251 n_left_to_next -= 1;
1283 n_left_to_next, bi0, next0);
1291 SR_POLICY_REWRITE_ERROR_COUNTER_TOTAL,
1294 SR_POLICY_REWRITE_ERROR_COUNTER_BSID,
1303 .name =
"sr-pl-rewrite-encaps",
1304 .vector_size =
sizeof (
u32),
1311 #define _(s,n) [SR_POLICY_REWRITE_NEXT_##s] = n, 1332 ip0_encap->
ttl -= 1;
1333 checksum0 = ip0_encap->
checksum + clib_host_to_net_u16 (0x0100);
1334 checksum0 += checksum0 >= 0xffff;
1341 clib_host_to_net_u32 (0 | ((6 & 0xF) << 28) |
1342 ((ip0_encap->
tos & 0xFF) << 20));
1343 if (ip0->
protocol == IP_PROTOCOL_IPV6_ROUTE)
1345 sr0 = (
void *) (ip0 + 1);
1346 sr0->
protocol = IP_PROTOCOL_IP_IN_IP;
1349 ip0->
protocol = IP_PROTOCOL_IP_IN_IP;
1360 u32 n_left_from, next_index, *from, *to_next;
1367 int encap_pkts = 0, bsid_pkts = 0;
1369 while (n_left_from > 0)
1376 while (n_left_from >= 8 && n_left_to_next >= 4)
1378 u32 bi0, bi1, bi2, bi3;
1380 u32 next0, next1, next2, next3;
1381 next0 = next1 = next2 = next3 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
1383 ip4_header_t *ip0_encap, *ip1_encap, *ip2_encap, *ip3_encap;
1407 to_next[0] = bi0 = from[0];
1408 to_next[1] = bi1 = from[1];
1409 to_next[2] = bi2 = from[2];
1410 to_next[3] = bi3 = from[3];
1414 n_left_to_next -= 4;
1516 n_left_to_next, bi0, bi1, bi2, bi3,
1517 next0, next1, next2, next3);
1521 while (n_left_from > 0 && n_left_to_next > 0)
1528 u32 next0 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
1535 n_left_to_next -= 1;
1567 n_left_to_next, bi0, next0);
1575 SR_POLICY_REWRITE_ERROR_COUNTER_TOTAL,
1578 SR_POLICY_REWRITE_ERROR_COUNTER_BSID,
1587 .name =
"sr-pl-rewrite-encaps-v4",
1588 .vector_size =
sizeof (
u32),
1595 #define _(s,n) [SR_POLICY_REWRITE_NEXT_##s] = n, 1616 return (*((
u64 *) m) & 0xffffffffffff);
1624 uword is_ip, eh_size;
1628 eh_type = clib_net_to_host_u16 (eh->
type);
1631 is_ip = (eh_type == ETHERNET_TYPE_IP4 || eh_type == ETHERNET_TYPE_IP6);
1654 u32 n_left_from, next_index, *from, *to_next;
1661 int encap_pkts = 0, bsid_pkts = 0;
1663 while (n_left_from > 0)
1670 while (n_left_from >= 8 && n_left_to_next >= 4)
1672 u32 bi0, bi1, bi2, bi3;
1674 u32 next0, next1, next2, next3;
1675 next0 = next1 = next2 = next3 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
1703 to_next[0] = bi0 = from[0];
1704 to_next[1] = bi1 = from[1];
1705 to_next[2] = bi2 = from[2];
1706 to_next[3] = bi3 = from[3];
1710 n_left_to_next -= 4;
1832 if (ip0->
protocol == IP_PROTOCOL_IPV6_ROUTE)
1834 sr0 = (
void *) (ip0 + 1);
1835 sr0->
protocol = IP_PROTOCOL_IP6_NONXT;
1838 ip0->
protocol = IP_PROTOCOL_IP6_NONXT;
1840 if (ip1->
protocol == IP_PROTOCOL_IPV6_ROUTE)
1842 sr1 = (
void *) (ip1 + 1);
1843 sr1->
protocol = IP_PROTOCOL_IP6_NONXT;
1846 ip1->
protocol = IP_PROTOCOL_IP6_NONXT;
1848 if (ip2->
protocol == IP_PROTOCOL_IPV6_ROUTE)
1850 sr2 = (
void *) (ip2 + 1);
1851 sr2->
protocol = IP_PROTOCOL_IP6_NONXT;
1854 ip2->
protocol = IP_PROTOCOL_IP6_NONXT;
1856 if (ip3->
protocol == IP_PROTOCOL_IPV6_ROUTE)
1858 sr3 = (
void *) (ip3 + 1);
1859 sr3->
protocol = IP_PROTOCOL_IP6_NONXT;
1862 ip3->
protocol = IP_PROTOCOL_IP6_NONXT;
1912 n_left_to_next, bi0, bi1, bi2, bi3,
1913 next0, next1, next2, next3);
1917 while (n_left_from > 0 && n_left_to_next > 0)
1926 u32 next0 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
1933 n_left_to_next -= 1;
1970 if (ip0->
protocol == IP_PROTOCOL_IPV6_ROUTE)
1972 sr0 = (
void *) (ip0 + 1);
1973 sr0->
protocol = IP_PROTOCOL_IP6_NONXT;
1976 ip0->
protocol = IP_PROTOCOL_IP6_NONXT;
1991 n_left_to_next, bi0, next0);
1999 SR_POLICY_REWRITE_ERROR_COUNTER_TOTAL,
2002 SR_POLICY_REWRITE_ERROR_COUNTER_BSID,
2011 .name =
"sr-pl-rewrite-encaps-l2",
2012 .vector_size =
sizeof (
u32),
2019 #define _(s,n) [SR_POLICY_REWRITE_NEXT_##s] = n, 2034 u32 n_left_from, next_index, *from, *to_next;
2041 int insert_pkts = 0, bsid_pkts = 0;
2043 while (n_left_from > 0)
2050 while (n_left_from >= 8 && n_left_to_next >= 4)
2052 u32 bi0, bi1, bi2, bi3;
2054 u32 next0, next1, next2, next3;
2055 next0 = next1 = next2 = next3 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
2059 u16 new_l0, new_l1, new_l2, new_l3;
2082 to_next[0] = bi0 = from[0];
2083 to_next[1] = bi1 = from[1];
2084 to_next[2] = bi2 = from[2];
2085 to_next[3] = bi3 = from[3];
2089 n_left_to_next -= 4;
2122 if (ip0->
protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS)
2129 if (ip1->
protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS)
2136 if (ip2->
protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS)
2143 if (ip3->
protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS)
2151 (
void *) sr0 - (
void *) ip0);
2153 (
void *) sr1 - (
void *) ip1);
2155 (
void *) sr2 - (
void *) ip2);
2157 (
void *) sr3 - (
void *) ip3);
2178 ip0->hop_limit -= 1;
2179 ip1->hop_limit -= 1;
2180 ip2->hop_limit -= 1;
2181 ip3->hop_limit -= 1;
2184 clib_net_to_host_u16 (ip0->payload_length) +
2187 clib_net_to_host_u16 (ip1->payload_length) +
2190 clib_net_to_host_u16 (ip2->payload_length) +
2193 clib_net_to_host_u16 (ip3->payload_length) +
2196 ip0->payload_length = clib_host_to_net_u16 (new_l0);
2197 ip1->payload_length = clib_host_to_net_u16 (new_l1);
2198 ip2->payload_length = clib_host_to_net_u16 (new_l2);
2199 ip3->payload_length = clib_host_to_net_u16 (new_l3);
2215 ip0->dst_address.as_u64[0] =
2217 ip0->dst_address.as_u64[1] =
2219 ip1->dst_address.as_u64[0] =
2221 ip1->dst_address.as_u64[1] =
2223 ip2->dst_address.as_u64[0] =
2225 ip2->dst_address.as_u64[1] =
2227 ip3->dst_address.as_u64[0] =
2229 ip3->dst_address.as_u64[1] =
2232 ip6_ext_header_t *ip_ext;
2233 if (ip0 + 1 == (
void *) sr0)
2236 ip0->protocol = IP_PROTOCOL_IPV6_ROUTE;
2240 ip_ext = (
void *) (ip0 + 1);
2242 ip_ext->next_hdr = IP_PROTOCOL_IPV6_ROUTE;
2245 if (ip1 + 1 == (
void *) sr1)
2248 ip1->protocol = IP_PROTOCOL_IPV6_ROUTE;
2252 ip_ext = (
void *) (ip2 + 1);
2254 ip_ext->next_hdr = IP_PROTOCOL_IPV6_ROUTE;
2257 if (ip2 + 1 == (
void *) sr2)
2260 ip2->protocol = IP_PROTOCOL_IPV6_ROUTE;
2264 ip_ext = (
void *) (ip2 + 1);
2266 ip_ext->next_hdr = IP_PROTOCOL_IPV6_ROUTE;
2269 if (ip3 + 1 == (
void *) sr3)
2272 ip3->protocol = IP_PROTOCOL_IPV6_ROUTE;
2276 ip_ext = (
void *) (ip3 + 1);
2278 ip_ext->next_hdr = IP_PROTOCOL_IPV6_ROUTE;
2327 n_left_to_next, bi0, bi1, bi2, bi3,
2328 next0, next1, next2, next3);
2332 while (n_left_from > 0 && n_left_to_next > 0)
2339 u32 next0 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
2347 n_left_to_next -= 1;
2358 if (ip0->
protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS)
2366 (
void *) sr0 - (
void *) ip0);
2373 ip0->hop_limit -= 1;
2375 clib_net_to_host_u16 (ip0->payload_length) +
2377 ip0->payload_length = clib_host_to_net_u16 (new_l0);
2383 ip0->dst_address.as_u64[0] =
2385 ip0->dst_address.as_u64[1] =
2388 if (ip0 + 1 == (
void *) sr0)
2391 ip0->protocol = IP_PROTOCOL_IPV6_ROUTE;
2395 ip6_ext_header_t *ip_ext = (
void *) (ip0 + 1);
2397 ip_ext->next_hdr = IP_PROTOCOL_IPV6_ROUTE;
2414 n_left_to_next, bi0, next0);
2422 SR_POLICY_REWRITE_ERROR_COUNTER_TOTAL,
2425 SR_POLICY_REWRITE_ERROR_COUNTER_BSID,
2433 .name =
"sr-pl-rewrite-insert",
2434 .vector_size =
sizeof (
u32),
2441 #define _(s,n) [SR_POLICY_REWRITE_NEXT_##s] = n, 2456 u32 n_left_from, next_index, *from, *to_next;
2463 int insert_pkts = 0, bsid_pkts = 0;
2465 while (n_left_from > 0)
2472 while (n_left_from >= 8 && n_left_to_next >= 4)
2474 u32 bi0, bi1, bi2, bi3;
2476 u32 next0, next1, next2, next3;
2477 next0 = next1 = next2 = next3 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
2481 u16 new_l0, new_l1, new_l2, new_l3;
2504 to_next[0] = bi0 = from[0];
2505 to_next[1] = bi1 = from[1];
2506 to_next[2] = bi2 = from[2];
2507 to_next[3] = bi3 = from[3];
2511 n_left_to_next -= 4;
2544 if (ip0->
protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS)
2551 if (ip1->
protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS)
2558 if (ip2->
protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS)
2565 if (ip3->
protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS)
2573 (
u8 *) ip0, (
void *) sr0 - (
void *) ip0);
2575 (
u8 *) ip1, (
void *) sr1 - (
void *) ip1);
2577 (
u8 *) ip2, (
void *) sr2 - (
void *) ip2);
2579 (
u8 *) ip3, (
void *) sr3 - (
void *) ip3);
2600 ip0->hop_limit -= 1;
2601 ip1->hop_limit -= 1;
2602 ip2->hop_limit -= 1;
2603 ip3->hop_limit -= 1;
2606 clib_net_to_host_u16 (ip0->payload_length) +
2609 clib_net_to_host_u16 (ip1->payload_length) +
2612 clib_net_to_host_u16 (ip2->payload_length) +
2615 clib_net_to_host_u16 (ip3->payload_length) +
2618 ip0->payload_length = clib_host_to_net_u16 (new_l0);
2619 ip1->payload_length = clib_host_to_net_u16 (new_l1);
2620 ip2->payload_length = clib_host_to_net_u16 (new_l2);
2621 ip3->payload_length = clib_host_to_net_u16 (new_l3);
2628 ip0->dst_address.as_u64[0] =
2630 ip0->dst_address.as_u64[1] =
2632 ip1->dst_address.as_u64[0] =
2634 ip1->dst_address.as_u64[1] =
2636 ip2->dst_address.as_u64[0] =
2638 ip2->dst_address.as_u64[1] =
2640 ip3->dst_address.as_u64[0] =
2642 ip3->dst_address.as_u64[1] =
2645 ip6_ext_header_t *ip_ext;
2646 if (ip0 + 1 == (
void *) sr0)
2649 ip0->protocol = IP_PROTOCOL_IPV6_ROUTE;
2653 ip_ext = (
void *) (ip0 + 1);
2655 ip_ext->next_hdr = IP_PROTOCOL_IPV6_ROUTE;
2658 if (ip1 + 1 == (
void *) sr1)
2661 ip1->protocol = IP_PROTOCOL_IPV6_ROUTE;
2665 ip_ext = (
void *) (ip2 + 1);
2667 ip_ext->next_hdr = IP_PROTOCOL_IPV6_ROUTE;
2670 if (ip2 + 1 == (
void *) sr2)
2673 ip2->protocol = IP_PROTOCOL_IPV6_ROUTE;
2677 ip_ext = (
void *) (ip2 + 1);
2679 ip_ext->next_hdr = IP_PROTOCOL_IPV6_ROUTE;
2682 if (ip3 + 1 == (
void *) sr3)
2685 ip3->protocol = IP_PROTOCOL_IPV6_ROUTE;
2689 ip_ext = (
void *) (ip3 + 1);
2691 ip_ext->next_hdr = IP_PROTOCOL_IPV6_ROUTE;
2740 n_left_to_next, bi0, bi1, bi2, bi3,
2741 next0, next1, next2, next3);
2745 while (n_left_from > 0 && n_left_to_next > 0)
2752 u32 next0 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
2760 n_left_to_next -= 1;
2771 if (ip0->
protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS)
2779 (
u8 *) ip0, (
void *) sr0 - (
void *) ip0);
2786 ip0->hop_limit -= 1;
2788 clib_net_to_host_u16 (ip0->payload_length) +
2790 ip0->payload_length = clib_host_to_net_u16 (new_l0);
2794 ip0->dst_address.as_u64[0] =
2796 ip0->dst_address.as_u64[1] =
2799 if (ip0 + 1 == (
void *) sr0)
2802 ip0->protocol = IP_PROTOCOL_IPV6_ROUTE;
2806 ip6_ext_header_t *ip_ext = (
void *) (ip0 + 1);
2808 ip_ext->next_hdr = IP_PROTOCOL_IPV6_ROUTE;
2825 n_left_to_next, bi0, next0);
2833 SR_POLICY_REWRITE_ERROR_COUNTER_TOTAL,
2836 SR_POLICY_REWRITE_ERROR_COUNTER_BSID,
2844 .name =
"sr-pl-rewrite-b-insert",
2845 .vector_size =
sizeof (
u32),
2852 #define _(s,n) [SR_POLICY_REWRITE_NEXT_##s] = n, 2871 goto error_bsid_encaps;
2887 *next0 = SR_POLICY_REWRITE_NEXT_ERROR;
2888 b0->
error = node->
errors[SR_POLICY_REWRITE_ERROR_BSID_ZERO];
2899 u32 n_left_from, next_index, *from, *to_next;
2906 int encap_pkts = 0, bsid_pkts = 0;
2908 while (n_left_from > 0)
2915 while (n_left_from >= 8 && n_left_to_next >= 4)
2917 u32 bi0, bi1, bi2, bi3;
2919 u32 next0, next1, next2, next3;
2920 next0 = next1 = next2 = next3 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
2922 ip6_header_t *ip0_encap, *ip1_encap, *ip2_encap, *ip3_encap;
2924 ip6_ext_header_t *prev0, *prev1, *prev2, *prev3;
2948 to_next[0] = bi0 = from[0];
2949 to_next[1] = bi1 = from[1];
2950 to_next[2] = bi2 = from[2];
2951 to_next[3] = bi3 = from[3];
2955 n_left_to_next -= 4;
2989 IP_PROTOCOL_IPV6_ROUTE);
2991 IP_PROTOCOL_IPV6_ROUTE);
2993 IP_PROTOCOL_IPV6_ROUTE);
2995 IP_PROTOCOL_IPV6_ROUTE);
3071 n_left_to_next, bi0, bi1, bi2, bi3,
3072 next0, next1, next2, next3);
3076 while (n_left_from > 0 && n_left_to_next > 0)
3081 ip6_ext_header_t *prev0;
3084 u32 next0 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
3091 n_left_to_next -= 1;
3102 IP_PROTOCOL_IPV6_ROUTE);
3126 n_left_to_next, bi0, next0);
3134 SR_POLICY_REWRITE_ERROR_COUNTER_TOTAL,
3137 SR_POLICY_REWRITE_ERROR_COUNTER_BSID,
3146 .name =
"sr-pl-rewrite-b-encaps",
3147 .vector_size =
sizeof (
u32),
3154 #define _(s,n) [SR_POLICY_REWRITE_NEXT_##s] = n, 3171 s =
format (s,
"SR: Segment List index:[%d]", index);
3172 s =
format (s,
"\n\tSegments:");
3181 s =
format (s,
"\b\b > - ");
3194 "sr-pl-rewrite-encaps",
3199 "sr-pl-rewrite-encaps-v4",
3209 "sr-pl-rewrite-insert",
3218 "sr-pl-rewrite-b-insert",
3227 "sr-pl-rewrite-b-encaps",
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
static clib_error_t * sr_policy_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
CLI for 'sr policies' command family.
static u8 * compute_rewrite_insert(ip6_address_t *sl)
SR rewrite string computation for SRH insertion (inline)
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
fib_protocol_t fp_proto
protocol type
dpo_lock_fn_t dv_lock
A reference counting lock function.
u8 type
Type (default is 0)
#define vec_foreach_index(var, v)
Iterate over vector indices.
fib_node_index_t path_index
The index of the FIB path.
#define foreach_sr_policy_rewrite_error
A virtual function table regisitered for a DPO type.
static uword sr_policy_rewrite_b_insert(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Graph node for applying a SR policy into a packet.
fib_node_index_t fib_table_lookup_exact_match(u32 fib_index, const fib_prefix_t *prefix)
Perfom an exact match in the non-forwarding table.
dpo_id_t path_dpo
ID of the Data-path object.
static uword sr_policy_rewrite_b_encaps(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Graph node for applying a SR policy BSID - Encapsulation.
void sr_dpo_unlock(dpo_id_t *dpo)
no-op unlock function.
static const char *const sr_pr_encaps_ip4_nodes[]
static int dpo_id_is_valid(const dpo_id_t *dpoi)
Return true if the DPO object is valid, i.e.
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
vlib_node_registration_t sr_policy_rewrite_b_encaps_node
(constructor) VLIB_REGISTER_NODE (sr_policy_rewrite_b_encaps_node)
#define clib_memcpy_fast(a, b, c)
static u32 ip4_compute_flow_hash(const ip4_header_t *ip, flow_hash_config_t flow_hash_config)
uword mhash_unset(mhash_t *h, void *key, uword *old_value)
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
#define ethernet_buffer_header_size(b)
Determine the size of the Ethernet headers of the current frame in the buffer.
int sr_policy_mod(ip6_address_t *bsid, u32 index, u32 fib_table, u8 operation, ip6_address_t *segments, u32 sl_index, u32 weight)
Modify an existing SR policy.
dpo_id_t ip4_dpo
DPO for Encaps IPv6.
#define VLIB_BUFFER_PRE_DATA_SIZE
static uword sr_policy_rewrite_insert(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Graph node for applying a SR policy into a packet.
u16 current_length
Nbytes between current data and the end of this buffer.
ip6_address_t * segments
SIDs (key)
static u8 * compute_rewrite_bsid(ip6_address_t *sl)
SR rewrite string computation for SRH insertion with BSID (inline)
u32 index_t
A Data-Path Object is an object that represents actions that are applied to packets are they are swit...
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
#define vlib_validate_buffer_enqueue_x4(vm, node, next_index, to_next, n_left_to_next, bi0, bi1, bi2, bi3, next0, next1, next2, next3)
Finish enqueueing four buffers forward in the graph.
static clib_error_t * set_sr_src_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
static ip6_sr_sl_t * create_sl(ip6_sr_policy_t *sr_policy, ip6_address_t *sl, u32 weight, u8 is_encap)
Creates a Segment List and adds it to an SR policy.
static const char *const *const sr_pr_bsid_encaps_nodes[DPO_PROTO_NUM]
#define IPv6_DEFAULT_HEADER_LENGTH
u32 l2_sr_policy_rewrite_index
#define ROUTING_HEADER_TYPE_SR
static u8 * format_sr_segment_list_dpo(u8 *s, va_list *args)
vlib_error_t * errors
Vector of errors for this node.
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
ip6_sr_steering_policy_t * steer_policies
static_always_inline void encaps_processing_v6(vlib_node_runtime_t *node, vlib_buffer_t *b0, ip6_header_t *ip0, ip6_header_t *ip0_encap)
IPv6 encapsulation processing as per RFC2473.
vlib_node_registration_t sr_policy_rewrite_encaps_v4_node
(constructor) VLIB_REGISTER_NODE (sr_policy_rewrite_encaps_v4_node)
u8 * rewrite_bsid
Precomputed rewrite header for bindingSID.
vlib_node_registration_t sr_policy_rewrite_encaps_l2_node
(constructor) VLIB_REGISTER_NODE (sr_policy_rewrite_encaps_l2_node)
static uword sr_policy_rewrite_encaps_l2(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Graph node for applying a SR policy into a L2 frame.
flow_hash_config_t fib_table_get_flow_hash_config(u32 fib_index, fib_protocol_t proto)
Get the flow hash configured used by the table.
index_t load_balance_create(u32 n_buckets, dpo_proto_t lb_proto, flow_hash_config_t fhc)
dpo_id_t ip6_dpo
DPO for Encaps/Insert IPv6.
u32 * sw_iface_sr_policies
vlib_node_registration_t sr_policy_rewrite_encaps_node
(constructor) VLIB_REGISTER_NODE (sr_policy_rewrite_encaps_node)
#define static_always_inline
enum dpo_type_t_ dpo_type_t
Common types of data-path objects New types can be dynamically added using dpo_register_new_type() ...
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
static const char *const sr_pr_insert_ip6_nodes[]
static u32 l2_flow_hash(vlib_buffer_t *b0)
#define VLIB_INIT_FUNCTION(x)
void fib_table_entry_special_remove(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source)
Remove a 'special' entry from the FIB.
SR Segment List (SID list)
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Aggregrate type for a prefix.
#define clib_error_return(e, args...)
void load_balance_multipath_update(const dpo_id_t *dpo, const load_balance_path_t *raw_nhs, load_balance_flags_t flags)
static uword sr_policy_rewrite_encaps(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Graph node for applying a SR policy into an IPv6 packet.
static const char *const *const sr_pr_encaps_nodes[DPO_PROTO_NUM]
static u64 mac_to_u64(u8 *m)
u32 fib_table_find(fib_protocol_t proto, u32 table_id)
Get the index of the FIB for a Table-ID.
dpo_type_t dpo_register_new_type(const dpo_vft_t *vft, const char *const *const *nodes)
Create and register a new DPO type.
int sr_policy_del(ip6_address_t *bsid, u32 index)
Delete a SR policy.
#define SR_POLICY_TYPE_DEFAULT
vlib_error_t error
Error code for buffers to be enqueued to error handler.
static void update_replicate(ip6_sr_policy_t *sr_policy)
Updates the Replicate DPO after an SR Policy change.
vlib_node_registration_t sr_policy_rewrite_b_insert_node
(constructor) VLIB_REGISTER_NODE (sr_policy_rewrite_b_insert_node)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
vlib_node_registration_t sr_policy_rewrite_insert_node
(constructor) VLIB_REGISTER_NODE (sr_policy_rewrite_insert_node)
static const char *const sr_pr_bsid_insert_ip6_nodes[]
void sr_set_source(ip6_address_t *address)
static dpo_type_t sr_pr_bsid_insert_dpo_type
static u8 * compute_rewrite_encaps(ip6_address_t *sl)
SR rewrite string computation for IPv6 encapsulation (inline)
load-balancing over a choice of [un]equal cost paths
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
static u32 ip6_compute_flow_hash(const ip6_header_t *ip, flow_hash_config_t flow_hash_config)
#define pool_put(P, E)
Free an object E in pool P.
#define vec_dup(V)
Return copy of vector (no header, no alignment)
void sr_dpo_lock(dpo_id_t *dpo)
no-op lock function.
#define vec_del1(v, i)
Delete the element at index I.
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Finish enqueueing one buffer forward in the graph.
static uword mhash_set(mhash_t *h, void *key, uword new_value, uword *old_value)
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Get pointer to next frame vector data by (vlib_node_runtime_t, next_index).
void fib_table_unlock(u32 fib_index, fib_protocol_t proto, fib_source_t source)
Take a reference counting lock on the table.
u8 is_encap
Mode (0 is SRH insert, 1 Encaps)
static uword sr_policy_rewrite_encaps_v4(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Graph node for applying a SR policy into an IPv4 packet.
u32 weight
SID list weight (wECMP / UCMP)
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
sr_policy_rewrite_error_t
#define ip6_ext_header_len(p)
The fine-grained event logger allows lightweight, thread-safe event logging at minimum cost...
void replicate_multipath_update(const dpo_id_t *dpo, load_balance_path_t *next_hops)
#define VLIB_REGISTER_NODE(x,...)
fib_node_index_t fib_table_entry_special_dpo_update(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags, const dpo_id_t *dpo)
Update a 'special' entry to the FIB that links to the DPO passed A special entry is an entry that the...
void mhash_init(mhash_t *h, uword n_value_bytes, uword n_key_bytes)
#define hash_mix64(a0, b0, c0)
#define CLIB_PREFETCH(addr, size, type)
static const char *const sr_pr_bsid_encaps_ip6_nodes[]
#define vec_free(V)
Free vector's memory (no header).
static_always_inline void end_bsid_encaps_srh_processing(vlib_node_runtime_t *node, vlib_buffer_t *b0, ip6_header_t *ip0, ip6_sr_header_t *sr0, u32 *next0)
Function BSID encapsulation.
static u8 * format_sr_policy_rewrite_trace(u8 *s, va_list *args)
Trace for the SR Policy Rewrite graph node.
u32 * segments_lists
SID lists indexes (vector)
u32 fib_node_index_t
A typedef of a node index.
dpo_id_t bsid_dpo
DPO for Encaps/Insert for BSID.
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Release pointer to next frame vector data.
void dpo_set(dpo_id_t *dpo, dpo_type_t type, dpo_proto_t proto, index_t index)
Set/create a DPO ID The DPO will be locked.
index_t replicate_create(u32 n_buckets, dpo_proto_t rep_proto)
#define foreach_sr_policy_rewrite_next
clib_error_t * sr_policy_rewrite_init(vlib_main_t *vm)
SR Policy Rewrite initialization.
#define VLIB_CLI_COMMAND(x,...)
static const char *const *const sr_pr_bsid_insert_nodes[DPO_PROTO_NUM]
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
#define pool_put_index(p, i)
Free pool element with given index.
static uword * mhash_get(mhash_t *h, const void *key)
static const char *const *const sr_pr_insert_nodes[DPO_PROTO_NUM]
#define SR_POLICY_TYPE_SPRAY
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
#define IP_FLOW_HASH_DEFAULT
Default: 5-tuple without the "reverse" bit.
static dpo_type_t sr_pr_encaps_dpo_type
Dynamically added SR SL DPO type.
static_always_inline void encaps_processing_v4(vlib_node_runtime_t *node, vlib_buffer_t *b0, ip6_header_t *ip0, ip4_header_t *ip0_encap)
IPv4 encapsulation processing as per RFC2473.
u32 flow_hash_config_t
A flow hash configuration is a mask of the flow hash options.
#define SR_SEGMENT_LIST_WEIGHT_DEFAULT
mhash_t sr_policies_index_hash
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
int sr_policy_add(ip6_address_t *bsid, ip6_address_t *segments, u32 weight, u8 behavior, u32 fib_table, u8 is_encap)
Create a new SR policy.
#define FIB_NODE_INDEX_INVALID
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
ip6_sr_policy_t * sr_policies
u32 path_weight
weight for the path.
u8 * rewrite
Precomputed rewrite header.
VLIB buffer representation.
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
dpo_id_t bsid_dpo
SR Policy specific DPO - BSID.
static dpo_type_t sr_pr_insert_dpo_type
One path from an [EU]CMP set that the client wants to add to a load-balance object.
static char * sr_policy_rewrite_error_strings[]
Segment Routing data structures definitions.
Segment Routing main datastructure.
dpo_id_t ip6_dpo
SR Policy specific DPO - IPv4.
void dpo_reset(dpo_id_t *dpo)
reset a DPO ID The DPO will be unlocked.
#define vec_foreach(var, vec)
Vector iterator.
static const char *const sr_pr_encaps_ip6_nodes[]
#define ip6_ext_header_find_t(i, p, m, t)
u16 flags
Copy of main node flags.
static dpo_type_t sr_pr_bsid_encaps_dpo_type
#define VLIB_NODE_FLAG_TRACE
#define CLIB_CACHE_LINE_BYTES
#define IPv6_DEFAULT_HOP_LIMIT
u32 fib_table_create_and_lock(fib_protocol_t proto, fib_source_t src, const char *const fmt,...)
Create a new table with no table ID.
dpo_id_t ip4_dpo
SR Policy specific DPO - IPv6.
static ip6_address_t sr_pr_encaps_src
IPv6 SA for encapsulated packets.
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
static void update_lb(ip6_sr_policy_t *sr_policy)
Updates the Load Balancer after an SR Policy change.
ip6_address_t bsid
BindingSID (key)
static u32 ip_flow_hash(void *data)
static clib_error_t * show_sr_policies_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
CLI to display onscreen all the SR policies.
static uword pool_elts(void *v)
Number of active elements in a pool.