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, 139 .path =
"set sr encaps source",
140 .short_help =
"set sr encaps source addr <ip6_addr>",
167 if (!
unformat (input,
"%d", &hop_limit))
169 if (hop_limit <= 0 || hop_limit > 255)
177 .path =
"set sr encaps hop-limit",
178 .short_help =
"set sr encaps hop-limit <value>",
196 ip6_address_t *addrp, *this_address;
197 u32 header_length = 0;
205 header_length +=
vec_len (sl) *
sizeof (ip6_address_t);
212 clib_host_to_net_u32 (0 | ((6 & 0xF) << 28));
222 iph->
protocol = IP_PROTOCOL_IPV6_ROUTE;
228 (
vec_len (sl) *
sizeof (ip6_address_t))) / 8) - 1;
235 sizeof (ip6_address_t));
255 ip6_address_t *addrp, *this_address;
256 u32 header_length = 0;
261 header_length += (
vec_len (sl) + 1) *
sizeof (ip6_address_t);
270 ((
vec_len (sl) + 1) *
sizeof (ip6_address_t))) / 8) - 1;
277 sizeof (ip6_address_t));
294 ip6_address_t *addrp, *this_address;
295 u32 header_length = 0;
300 header_length +=
vec_len (sl) *
sizeof (ip6_address_t);
309 (
vec_len (sl) *
sizeof (ip6_address_t))) / 8) - 1;
316 sizeof (ip6_address_t));
346 clib_memset (segment_list, 0,
sizeof (*segment_list));
451 .ip6 = sr_policy->
bsid,
554 .ip6 = sr_policy->
bsid,
628 u16 plugin,
void *ls_plugin_mem)
656 (fib_table != (
u32) ~ 0 ? fib_table : 0));
669 sr_policy->
type = behavior;
670 sr_policy->
fib_table = (fib_table != (
u32) ~ 0 ? fib_table : 0);
675 sr_policy->
plugin = plugin;
684 create_sl (sr_policy, segments, weight, is_encap);
691 "SRv6 steering of IP6 prefixes through BSIDs");
694 "SRv6 steering of IP4 prefixes through BSIDs");
742 .ip6 = sr_policy->
bsid,
823 u8 operation, ip6_address_t * segments,
u32 sl_index,
829 u32 *sl_index_iterate;
859 else if (operation == 2)
867 if (*sl_index_iterate == sl_index)
870 if (*sl_index_iterate != sl_index)
889 else if (operation == 3)
893 if (*sl_index_iterate == sl_index)
896 if (*sl_index_iterate != sl_index)
922 char is_del = 0, is_add = 0, is_mod = 0;
924 ip6_address_t bsid, next_address;
925 u32 sr_policy_index = (
u32) ~ 0, sl_index = (
u32) ~ 0;
927 ip6_address_t *segments = 0, *this_seg;
932 void *ls_plugin_mem = 0;
936 if (!is_add && !is_mod && !is_del &&
unformat (input,
"add"))
938 else if (!is_add && !is_mod && !is_del &&
unformat (input,
"del"))
940 else if (!is_add && !is_mod && !is_del &&
unformat (input,
"mod"))
945 else if (!is_add && !policy_set
946 &&
unformat (input,
"index %d", &sr_policy_index))
948 else if (
unformat (input,
"weight %d", &weight));
956 else if (
unformat (input,
"add sl"))
958 else if (
unformat (input,
"del sl index %d", &sl_index))
960 else if (
unformat (input,
"mod sl index %d", &sl_index))
962 else if (fib_table == (
u32) ~ 0
963 &&
unformat (input,
"fib-table %d", &fib_table));
966 else if (
unformat (input,
"insert"))
970 else if (!behavior &&
unformat (input,
"behavior"))
978 vec_add1 (vec_plugins, plugin);
985 (input,
"%U", (*plugin_it)->ls_unformat, &ls_plugin_mem))
987 behavior = (*plugin_it)->sr_policy_function_number;
1001 if (!is_add && !is_mod && !is_del)
1009 if (behavior &&
vec_len (segments) == 0)
1021 behavior, ls_plugin_mem);
1032 if (operation != 1 && sl_index == (
u32) ~ 0)
1034 if (operation == 1 &&
vec_len (segments) == 0)
1036 if (operation == 3 && weight == (
u32) ~ 0)
1040 sr_policy_index, fib_table, operation, segments,
1055 "There is already a FIB entry for the BindingSID address.\n" 1056 "The SR policy could not be created.");
1061 "The selected SR policy only contains ONE segment list. " 1062 "Please remove the SR policy instead");
1065 "Could not delete the segment list. " 1066 "It is not associated with that SR policy.");
1069 "Could not modify the segment list. " 1070 "The given SL is not associated with such SR policy.");
1079 .path =
"sr policy",
1080 .short_help =
"sr policy [add||del||mod] [bsid 2001::1||index 5] " 1081 "next A:: next B:: next C:: (weight 1) (fib-table 2) (encap|insert)",
1083 "Manipulation of SR policies.\n" 1084 "A Segment Routing policy may contain several SID lists. Each SID list has\n" 1085 "an associated weight (default 1), which will result in wECMP (uECMP).\n" 1086 "Segment Routing policies might be of type encapsulation or srh insertion\n" 1087 "Each SR policy will be associated with a unique BindingSID.\n" 1088 "A BindingSID is a locally allocated SegmentID. For every packet that arrives\n" 1089 "with IPv6_DA:BSID such traffic will be steered into the SR policy.\n" 1090 "The add command will create a SR policy with its first segment list (sl)\n" 1091 "The mod command allows you to add, remove, or modify the existing segment lists\n" 1092 "within an SR policy.\n" 1093 "The del command allows you to delete a SR policy along with all its associated\n" 1111 ip6_address_t *
addr;
1119 {vec_add1 (vec_policies, sr_policy); } );
1124 sr_policy = vec_policies[
i];
1129 (sr_policy->
is_encap ?
"Encapsulation" :
1141 s =
format (s,
"\t[%u].- ", *sl_index);
1148 s =
format (s,
"\b\b > ");
1159 .path =
"show sr policies",
1160 .short_help =
"show sr policies",
1178 (s,
"SR-policy-rewrite: src %U dst %U",
1211 u32 n_left_from, next_index, *from, *to_next;
1218 int encap_pkts = 0, bsid_pkts = 0;
1220 while (n_left_from > 0)
1227 while (n_left_from >= 8 && n_left_to_next >= 4)
1229 u32 bi0, bi1, bi2, bi3;
1231 u32 next0, next1, next2, next3;
1232 next0 = next1 = next2 = next3 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
1234 ip6_header_t *ip0_encap, *ip1_encap, *ip2_encap, *ip3_encap;
1258 to_next[0] = bi0 = from[0];
1259 to_next[1] = bi1 = from[1];
1260 to_next[2] = bi2 = from[2];
1261 to_next[3] = bi3 = from[3];
1265 n_left_to_next -= 4;
1330 sizeof (tr->
src.as_u8));
1332 sizeof (tr->
dst.as_u8));
1340 sizeof (tr->
src.as_u8));
1342 sizeof (tr->
dst.as_u8));
1350 sizeof (tr->
src.as_u8));
1352 sizeof (tr->
dst.as_u8));
1360 sizeof (tr->
src.as_u8));
1362 sizeof (tr->
dst.as_u8));
1368 n_left_to_next, bi0, bi1, bi2, bi3,
1369 next0, next1, next2, next3);
1373 while (n_left_from > 0 && n_left_to_next > 0)
1379 u32 next0 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
1386 n_left_to_next -= 1;
1411 sizeof (tr->
src.as_u8));
1413 sizeof (tr->
dst.as_u8));
1418 n_left_to_next, bi0, next0);
1426 SR_POLICY_REWRITE_ERROR_COUNTER_TOTAL,
1429 SR_POLICY_REWRITE_ERROR_COUNTER_BSID,
1438 .name =
"sr-pl-rewrite-encaps",
1439 .vector_size =
sizeof (
u32),
1446 #define _(s,n) [SR_POLICY_REWRITE_NEXT_##s] = n, 1467 ip0_encap->
ttl -= 1;
1468 checksum0 = ip0_encap->
checksum + clib_host_to_net_u16 (0x0100);
1469 checksum0 += checksum0 >= 0xffff;
1476 clib_host_to_net_u32 (0 | ((6 & 0xF) << 28) |
1477 ((ip0_encap->
tos & 0xFF) << 20));
1478 if (ip0->
protocol == IP_PROTOCOL_IPV6_ROUTE)
1480 sr0 = (
void *) (ip0 + 1);
1481 sr0->
protocol = IP_PROTOCOL_IP_IN_IP;
1484 ip0->
protocol = IP_PROTOCOL_IP_IN_IP;
1495 u32 n_left_from, next_index, *from, *to_next;
1502 int encap_pkts = 0, bsid_pkts = 0;
1504 while (n_left_from > 0)
1511 while (n_left_from >= 8 && n_left_to_next >= 4)
1513 u32 bi0, bi1, bi2, bi3;
1515 u32 next0, next1, next2, next3;
1516 next0 = next1 = next2 = next3 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
1518 ip4_header_t *ip0_encap, *ip1_encap, *ip2_encap, *ip3_encap;
1542 to_next[0] = bi0 = from[0];
1543 to_next[1] = bi1 = from[1];
1544 to_next[2] = bi2 = from[2];
1545 to_next[3] = bi3 = from[3];
1549 n_left_to_next -= 4;
1613 sizeof (tr->
src.as_u8));
1615 sizeof (tr->
dst.as_u8));
1623 sizeof (tr->
src.as_u8));
1625 sizeof (tr->
dst.as_u8));
1633 sizeof (tr->
src.as_u8));
1635 sizeof (tr->
dst.as_u8));
1643 sizeof (tr->
src.as_u8));
1645 sizeof (tr->
dst.as_u8));
1651 n_left_to_next, bi0, bi1, bi2, bi3,
1652 next0, next1, next2, next3);
1656 while (n_left_from > 0 && n_left_to_next > 0)
1663 u32 next0 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
1670 n_left_to_next -= 1;
1695 sizeof (tr->
src.as_u8));
1697 sizeof (tr->
dst.as_u8));
1702 n_left_to_next, bi0, next0);
1710 SR_POLICY_REWRITE_ERROR_COUNTER_TOTAL,
1713 SR_POLICY_REWRITE_ERROR_COUNTER_BSID,
1722 .name =
"sr-pl-rewrite-encaps-v4",
1723 .vector_size =
sizeof (
u32),
1730 #define _(s,n) [SR_POLICY_REWRITE_NEXT_##s] = n, 1751 return (*((
u64 *) m) & 0xffffffffffff);
1759 uword is_ip, eh_size;
1763 eh_type = clib_net_to_host_u16 (eh->
type);
1766 is_ip = (eh_type == ETHERNET_TYPE_IP4 || eh_type == ETHERNET_TYPE_IP6);
1789 u32 n_left_from, next_index, *from, *to_next;
1796 int encap_pkts = 0, bsid_pkts = 0;
1798 while (n_left_from > 0)
1805 while (n_left_from >= 8 && n_left_to_next >= 4)
1807 u32 bi0, bi1, bi2, bi3;
1809 u32 next0, next1, next2, next3;
1810 next0 = next1 = next2 = next3 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
1838 to_next[0] = bi0 = from[0];
1839 to_next[1] = bi1 = from[1];
1840 to_next[2] = bi2 = from[2];
1841 to_next[3] = bi3 = from[3];
1845 n_left_to_next -= 4;
1967 if (ip0->
protocol == IP_PROTOCOL_IPV6_ROUTE)
1969 sr0 = (
void *) (ip0 + 1);
1975 if (ip1->
protocol == IP_PROTOCOL_IPV6_ROUTE)
1977 sr1 = (
void *) (ip1 + 1);
1983 if (ip2->
protocol == IP_PROTOCOL_IPV6_ROUTE)
1985 sr2 = (
void *) (ip2 + 1);
1991 if (ip3->
protocol == IP_PROTOCOL_IPV6_ROUTE)
1993 sr3 = (
void *) (ip3 + 1);
2009 sizeof (tr->
src.as_u8));
2011 sizeof (tr->
dst.as_u8));
2019 sizeof (tr->
src.as_u8));
2021 sizeof (tr->
dst.as_u8));
2029 sizeof (tr->
src.as_u8));
2031 sizeof (tr->
dst.as_u8));
2039 sizeof (tr->
src.as_u8));
2041 sizeof (tr->
dst.as_u8));
2047 n_left_to_next, bi0, bi1, bi2, bi3,
2048 next0, next1, next2, next3);
2052 while (n_left_from > 0 && n_left_to_next > 0)
2061 u32 next0 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
2068 n_left_to_next -= 1;
2105 if (ip0->
protocol == IP_PROTOCOL_IPV6_ROUTE)
2107 sr0 = (
void *) (ip0 + 1);
2119 sizeof (tr->
src.as_u8));
2121 sizeof (tr->
dst.as_u8));
2126 n_left_to_next, bi0, next0);
2134 SR_POLICY_REWRITE_ERROR_COUNTER_TOTAL,
2137 SR_POLICY_REWRITE_ERROR_COUNTER_BSID,
2146 .name =
"sr-pl-rewrite-encaps-l2",
2147 .vector_size =
sizeof (
u32),
2154 #define _(s,n) [SR_POLICY_REWRITE_NEXT_##s] = n, 2169 u32 n_left_from, next_index, *from, *to_next;
2176 int insert_pkts = 0, bsid_pkts = 0;
2178 while (n_left_from > 0)
2185 while (n_left_from >= 8 && n_left_to_next >= 4)
2187 u32 bi0, bi1, bi2, bi3;
2189 u32 next0, next1, next2, next3;
2190 next0 = next1 = next2 = next3 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
2194 u16 new_l0, new_l1, new_l2, new_l3;
2217 to_next[0] = bi0 = from[0];
2218 to_next[1] = bi1 = from[1];
2219 to_next[2] = bi2 = from[2];
2220 to_next[3] = bi3 = from[3];
2224 n_left_to_next -= 4;
2257 if (ip0->
protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS)
2264 if (ip1->
protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS)
2271 if (ip2->
protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS)
2278 if (ip3->
protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS)
2286 (
void *) sr0 - (
void *) ip0);
2288 (
void *) sr1 - (
void *) ip1);
2290 (
void *) sr2 - (
void *) ip2);
2292 (
void *) sr3 - (
void *) ip3);
2313 ip0->hop_limit -= 1;
2314 ip1->hop_limit -= 1;
2315 ip2->hop_limit -= 1;
2316 ip3->hop_limit -= 1;
2319 clib_net_to_host_u16 (ip0->payload_length) +
2322 clib_net_to_host_u16 (ip1->payload_length) +
2325 clib_net_to_host_u16 (ip2->payload_length) +
2328 clib_net_to_host_u16 (ip3->payload_length) +
2331 ip0->payload_length = clib_host_to_net_u16 (new_l0);
2332 ip1->payload_length = clib_host_to_net_u16 (new_l1);
2333 ip2->payload_length = clib_host_to_net_u16 (new_l2);
2334 ip3->payload_length = clib_host_to_net_u16 (new_l3);
2341 sr0->
segments->as_u64[0] = ip0->dst_address.as_u64[0];
2342 sr0->
segments->as_u64[1] = ip0->dst_address.as_u64[1];
2343 sr1->
segments->as_u64[0] = ip1->dst_address.as_u64[0];
2344 sr1->
segments->as_u64[1] = ip1->dst_address.as_u64[1];
2345 sr2->
segments->as_u64[0] = ip2->dst_address.as_u64[0];
2346 sr2->
segments->as_u64[1] = ip2->dst_address.as_u64[1];
2347 sr3->
segments->as_u64[0] = ip3->dst_address.as_u64[0];
2348 sr3->
segments->as_u64[1] = ip3->dst_address.as_u64[1];
2350 ip0->dst_address.as_u64[0] =
2352 ip0->dst_address.as_u64[1] =
2354 ip1->dst_address.as_u64[0] =
2356 ip1->dst_address.as_u64[1] =
2358 ip2->dst_address.as_u64[0] =
2360 ip2->dst_address.as_u64[1] =
2362 ip3->dst_address.as_u64[0] =
2364 ip3->dst_address.as_u64[1] =
2367 ip6_ext_header_t *ip_ext;
2368 if (ip0 + 1 == (
void *) sr0)
2371 ip0->protocol = IP_PROTOCOL_IPV6_ROUTE;
2375 ip_ext = (
void *) (ip0 + 1);
2377 ip_ext->next_hdr = IP_PROTOCOL_IPV6_ROUTE;
2380 if (ip1 + 1 == (
void *) sr1)
2383 ip1->protocol = IP_PROTOCOL_IPV6_ROUTE;
2387 ip_ext = (
void *) (ip2 + 1);
2389 ip_ext->next_hdr = IP_PROTOCOL_IPV6_ROUTE;
2392 if (ip2 + 1 == (
void *) sr2)
2395 ip2->protocol = IP_PROTOCOL_IPV6_ROUTE;
2399 ip_ext = (
void *) (ip2 + 1);
2401 ip_ext->next_hdr = IP_PROTOCOL_IPV6_ROUTE;
2404 if (ip3 + 1 == (
void *) sr3)
2407 ip3->protocol = IP_PROTOCOL_IPV6_ROUTE;
2411 ip_ext = (
void *) (ip3 + 1);
2413 ip_ext->next_hdr = IP_PROTOCOL_IPV6_ROUTE;
2425 sizeof (tr->
src.as_u8));
2427 sizeof (tr->
dst.as_u8));
2435 sizeof (tr->
src.as_u8));
2437 sizeof (tr->
dst.as_u8));
2445 sizeof (tr->
src.as_u8));
2447 sizeof (tr->
dst.as_u8));
2455 sizeof (tr->
src.as_u8));
2457 sizeof (tr->
dst.as_u8));
2462 n_left_to_next, bi0, bi1, bi2, bi3,
2463 next0, next1, next2, next3);
2467 while (n_left_from > 0 && n_left_to_next > 0)
2474 u32 next0 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
2482 n_left_to_next -= 1;
2493 if (ip0->
protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS)
2501 (
void *) sr0 - (
void *) ip0);
2508 ip0->hop_limit -= 1;
2510 clib_net_to_host_u16 (ip0->payload_length) +
2512 ip0->payload_length = clib_host_to_net_u16 (new_l0);
2515 sr0->
segments->as_u64[0] = ip0->dst_address.as_u64[0];
2516 sr0->
segments->as_u64[1] = ip0->dst_address.as_u64[1];
2518 ip0->dst_address.as_u64[0] =
2520 ip0->dst_address.as_u64[1] =
2523 if (ip0 + 1 == (
void *) sr0)
2526 ip0->protocol = IP_PROTOCOL_IPV6_ROUTE;
2530 ip6_ext_header_t *ip_ext = (
void *) (ip0 + 1);
2532 ip_ext->next_hdr = IP_PROTOCOL_IPV6_ROUTE;
2541 sizeof (tr->
src.as_u8));
2543 sizeof (tr->
dst.as_u8));
2549 n_left_to_next, bi0, next0);
2557 SR_POLICY_REWRITE_ERROR_COUNTER_TOTAL,
2560 SR_POLICY_REWRITE_ERROR_COUNTER_BSID,
2568 .name =
"sr-pl-rewrite-insert",
2569 .vector_size =
sizeof (
u32),
2576 #define _(s,n) [SR_POLICY_REWRITE_NEXT_##s] = n, 2591 u32 n_left_from, next_index, *from, *to_next;
2598 int insert_pkts = 0, bsid_pkts = 0;
2600 while (n_left_from > 0)
2607 while (n_left_from >= 8 && n_left_to_next >= 4)
2609 u32 bi0, bi1, bi2, bi3;
2611 u32 next0, next1, next2, next3;
2612 next0 = next1 = next2 = next3 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
2616 u16 new_l0, new_l1, new_l2, new_l3;
2639 to_next[0] = bi0 = from[0];
2640 to_next[1] = bi1 = from[1];
2641 to_next[2] = bi2 = from[2];
2642 to_next[3] = bi3 = from[3];
2646 n_left_to_next -= 4;
2679 if (ip0->
protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS)
2686 if (ip1->
protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS)
2693 if (ip2->
protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS)
2700 if (ip3->
protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS)
2708 (
u8 *) ip0, (
void *) sr0 - (
void *) ip0);
2710 (
u8 *) ip1, (
void *) sr1 - (
void *) ip1);
2712 (
u8 *) ip2, (
void *) sr2 - (
void *) ip2);
2714 (
u8 *) ip3, (
void *) sr3 - (
void *) ip3);
2735 ip0->hop_limit -= 1;
2736 ip1->hop_limit -= 1;
2737 ip2->hop_limit -= 1;
2738 ip3->hop_limit -= 1;
2741 clib_net_to_host_u16 (ip0->payload_length) +
2744 clib_net_to_host_u16 (ip1->payload_length) +
2747 clib_net_to_host_u16 (ip2->payload_length) +
2750 clib_net_to_host_u16 (ip3->payload_length) +
2753 ip0->payload_length = clib_host_to_net_u16 (new_l0);
2754 ip1->payload_length = clib_host_to_net_u16 (new_l1);
2755 ip2->payload_length = clib_host_to_net_u16 (new_l2);
2756 ip3->payload_length = clib_host_to_net_u16 (new_l3);
2763 ip0->dst_address.as_u64[0] =
2765 ip0->dst_address.as_u64[1] =
2767 ip1->dst_address.as_u64[0] =
2769 ip1->dst_address.as_u64[1] =
2771 ip2->dst_address.as_u64[0] =
2773 ip2->dst_address.as_u64[1] =
2775 ip3->dst_address.as_u64[0] =
2777 ip3->dst_address.as_u64[1] =
2780 ip6_ext_header_t *ip_ext;
2781 if (ip0 + 1 == (
void *) sr0)
2784 ip0->protocol = IP_PROTOCOL_IPV6_ROUTE;
2788 ip_ext = (
void *) (ip0 + 1);
2790 ip_ext->next_hdr = IP_PROTOCOL_IPV6_ROUTE;
2793 if (ip1 + 1 == (
void *) sr1)
2796 ip1->protocol = IP_PROTOCOL_IPV6_ROUTE;
2800 ip_ext = (
void *) (ip2 + 1);
2802 ip_ext->next_hdr = IP_PROTOCOL_IPV6_ROUTE;
2805 if (ip2 + 1 == (
void *) sr2)
2808 ip2->protocol = IP_PROTOCOL_IPV6_ROUTE;
2812 ip_ext = (
void *) (ip2 + 1);
2814 ip_ext->next_hdr = IP_PROTOCOL_IPV6_ROUTE;
2817 if (ip3 + 1 == (
void *) sr3)
2820 ip3->protocol = IP_PROTOCOL_IPV6_ROUTE;
2824 ip_ext = (
void *) (ip3 + 1);
2826 ip_ext->next_hdr = IP_PROTOCOL_IPV6_ROUTE;
2838 sizeof (tr->
src.as_u8));
2840 sizeof (tr->
dst.as_u8));
2848 sizeof (tr->
src.as_u8));
2850 sizeof (tr->
dst.as_u8));
2858 sizeof (tr->
src.as_u8));
2860 sizeof (tr->
dst.as_u8));
2868 sizeof (tr->
src.as_u8));
2870 sizeof (tr->
dst.as_u8));
2875 n_left_to_next, bi0, bi1, bi2, bi3,
2876 next0, next1, next2, next3);
2880 while (n_left_from > 0 && n_left_to_next > 0)
2887 u32 next0 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
2895 n_left_to_next -= 1;
2906 if (ip0->
protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS)
2914 (
u8 *) ip0, (
void *) sr0 - (
void *) ip0);
2921 ip0->hop_limit -= 1;
2923 clib_net_to_host_u16 (ip0->payload_length) +
2925 ip0->payload_length = clib_host_to_net_u16 (new_l0);
2929 ip0->dst_address.as_u64[0] =
2931 ip0->dst_address.as_u64[1] =
2934 if (ip0 + 1 == (
void *) sr0)
2937 ip0->protocol = IP_PROTOCOL_IPV6_ROUTE;
2941 ip6_ext_header_t *ip_ext = (
void *) (ip0 + 1);
2943 ip_ext->next_hdr = IP_PROTOCOL_IPV6_ROUTE;
2952 sizeof (tr->
src.as_u8));
2954 sizeof (tr->
dst.as_u8));
2960 n_left_to_next, bi0, next0);
2968 SR_POLICY_REWRITE_ERROR_COUNTER_TOTAL,
2971 SR_POLICY_REWRITE_ERROR_COUNTER_BSID,
2979 .name =
"sr-pl-rewrite-b-insert",
2980 .vector_size =
sizeof (
u32),
2987 #define _(s,n) [SR_POLICY_REWRITE_NEXT_##s] = n, 3003 ip6_address_t *new_dst0;
3006 goto error_bsid_encaps;
3013 new_dst0 = (ip6_address_t *) (sr0->
segments);
3022 *next0 = SR_POLICY_REWRITE_NEXT_ERROR;
3023 b0->
error = node->
errors[SR_POLICY_REWRITE_ERROR_BSID_ZERO];
3034 u32 n_left_from, next_index, *from, *to_next;
3041 int encap_pkts = 0, bsid_pkts = 0;
3043 while (n_left_from > 0)
3050 while (n_left_from >= 8 && n_left_to_next >= 4)
3052 u32 bi0, bi1, bi2, bi3;
3054 u32 next0, next1, next2, next3;
3055 next0 = next1 = next2 = next3 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
3057 ip6_header_t *ip0_encap, *ip1_encap, *ip2_encap, *ip3_encap;
3082 to_next[0] = bi0 = from[0];
3083 to_next[1] = bi1 = from[1];
3084 to_next[2] = bi2 = from[2];
3085 to_next[3] = bi3 = from[3];
3089 n_left_to_next -= 4;
3171 sizeof (tr->
src.as_u8));
3173 sizeof (tr->
dst.as_u8));
3181 sizeof (tr->
src.as_u8));
3183 sizeof (tr->
dst.as_u8));
3191 sizeof (tr->
src.as_u8));
3193 sizeof (tr->
dst.as_u8));
3201 sizeof (tr->
src.as_u8));
3203 sizeof (tr->
dst.as_u8));
3209 n_left_to_next, bi0, bi1, bi2, bi3,
3210 next0, next1, next2, next3);
3214 while (n_left_from > 0 && n_left_to_next > 0)
3221 u32 next0 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
3228 n_left_to_next -= 1;
3257 sizeof (tr->
src.as_u8));
3259 sizeof (tr->
dst.as_u8));
3264 n_left_to_next, bi0, next0);
3272 SR_POLICY_REWRITE_ERROR_COUNTER_TOTAL,
3275 SR_POLICY_REWRITE_ERROR_COUNTER_BSID,
3284 .name =
"sr-pl-rewrite-b-encaps",
3285 .vector_size =
sizeof (
u32),
3292 #define _(s,n) [SR_POLICY_REWRITE_NEXT_##s] = n, 3363 vlib_cli_output (vm,
"SR Policy behaviors:\n-----------------------\n\n");
3367 ({ vec_add1 (plugins_vec, plugin); }));
3371 for (i = 0; i <
vec_len (plugins_vec); i++)
3373 plugin = plugins_vec[
i];
3383 .path =
"show sr policy behaviors",
3384 .short_help =
"show sr policy behaviors",
3394 ip6_address_t *
addr;
3399 s =
format (s,
"SR: Segment List index:[%d]", index);
3400 s =
format (s,
"\n\tSegments:");
3409 s =
format (s,
"\b\b > - ");
3422 "sr-pl-rewrite-encaps",
3427 "sr-pl-rewrite-encaps-v4",
3437 "sr-pl-rewrite-insert",
3446 "sr-pl-rewrite-b-insert",
3455 "sr-pl-rewrite-b-encaps",
3474 sizeof (ip6_address_t));
u8 * params_str
Behavior parameters (i.e.
#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.
static clib_error_t * show_sr_policy_behaviors_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
CLI function to 'show' all available SR LocalSID behaviors.
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.
#define IP_PROTOCOL_IP6_ETHERNET
int sr_policy_add(ip6_address_t *bsid, ip6_address_t *segments, u32 weight, u8 behavior, u32 fib_table, u8 is_encap, u16 plugin, void *ls_plugin_mem)
Create a new SR policy.
uword * policy_plugin_functions_by_key
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.
format_function_t * ls_format
LocalSID format function.
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.
sr_p_plugin_callback_t * removal
Function within plugin that will be called before localsid removal.
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)
unsigned char params_str[32]
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.
dpo_type_t dpo
DPO type registration.
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.
#define hash_set_mem(h, key, value)
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
unsigned char keyword_str[32]
static u8 * format_sr_segment_list_dpo(u8 *s, va_list *args)
vlib_error_t * errors
Vector of errors for this node.
int sr_policy_register_function(vlib_main_t *vm, u8 *fn_name, u8 *keyword_str, u8 *def_str, u8 *params_str, u8 prefix_length, dpo_type_t *dpo, format_function_t *ls_format, unformat_function_t *ls_unformat, sr_p_plugin_callback_t *creation_fn, sr_p_plugin_callback_t *removal_fn)
SR Policy plugin registry.
#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.
void sr_set_hop_limit(u8 hop_limit)
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.
u16 sr_policy_function_number
SR Policy plugin function.
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.
#define clib_memcpy(d, s, n)
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[]
vl_api_interface_index_t sw_if_index
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_policy_fn_registration_t * policy_plugin_functions
SR Segment List (SID list)
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Aggregate type for a prefix.
#define clib_error_return(e, args...)
sr_p_plugin_callback_t * creation
Function within plugin that will be called after localsid creation.
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.
SR Policy behavior registration.
dpo_type_t dpo_register_new_type(const dpo_vft_t *vft, const char *const *const *nodes)
Create and register a new DPO type.
static void * ip6_ext_header_find(vlib_main_t *vm, vlib_buffer_t *b, ip6_header_t *ip6_header, u8 header_type, ip6_ext_header_t **prev_ext_header)
int sr_policy_del(ip6_address_t *bsid, u32 index)
Delete a SR policy.
#define SR_POLICY_TYPE_DEFAULT
vl_api_fib_path_type_t type
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
unsigned char def_str[64]
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.
static u8 sr_pr_encaps_hop_limit
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
unformat_function_t * ls_unformat
LocalSID unformat function.
static clib_error_t * set_sr_hop_limit_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
#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)
sll srl srl sll sra u16x4 i
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
u8 * function_name
Function name.
vlib_main_t vlib_node_runtime_t * node
clib_error_t * sr_policy_rewrite_init(vlib_main_t *vm)
SR Policy Rewrite initialization.
#define VLIB_CLI_COMMAND(x,...)
u8 * def_str
Behavior definition (i.e.
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.
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
manual_print typedef address
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)
#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.
int() sr_p_plugin_callback_t(ip6_sr_policy_t *sr)
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.
#define hash_get_mem(h, key)
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[]
u16 flags
Copy of main node flags.
static dpo_type_t sr_pr_bsid_encaps_dpo_type
#define VLIB_NODE_FLAG_TRACE
u8 sr_get_hop_limit(void)
#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.
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.
u8 * keyword_str
Behavior keyword (i.e.
static uword pool_elts(void *v)
Number of active elements in a pool.