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, 145 .path =
"set sr encaps source",
146 .short_help =
"set sr encaps source addr <ip6_addr>",
173 if (!
unformat (input,
"%d", &hop_limit))
175 if (hop_limit <= 0 || hop_limit > 255)
183 .path =
"set sr encaps hop-limit",
184 .short_help =
"set sr encaps hop-limit <value>",
202 ip6_address_t *addrp, *this_address;
203 u32 header_length = 0;
211 header_length +=
vec_len (sl) *
sizeof (ip6_address_t);
218 clib_host_to_net_u32 (0 | ((6 & 0xF) << 28));
228 iph->
protocol = IP_PROTOCOL_IPV6_ROUTE;
234 (
vec_len (sl) *
sizeof (ip6_address_t))) / 8) - 1;
241 sizeof (ip6_address_t));
261 ip6_address_t *addrp, *this_address;
262 u32 header_length = 0;
267 header_length += (
vec_len (sl) + 1) *
sizeof (ip6_address_t);
276 ((
vec_len (sl) + 1) *
sizeof (ip6_address_t))) / 8) - 1;
283 sizeof (ip6_address_t));
300 ip6_address_t *addrp, *this_address;
301 u32 header_length = 0;
306 header_length +=
vec_len (sl) *
sizeof (ip6_address_t);
315 (
vec_len (sl) *
sizeof (ip6_address_t))) / 8) - 1;
322 sizeof (ip6_address_t));
352 clib_memset (segment_list, 0,
sizeof (*segment_list));
457 .ip6 = sr_policy->
bsid,
560 .ip6 = sr_policy->
bsid,
634 u16 plugin,
void *ls_plugin_mem)
662 (fib_table != (
u32) ~ 0 ? fib_table : 0));
675 sr_policy->
type = behavior;
676 sr_policy->
fib_table = (fib_table != (
u32) ~ 0 ? fib_table : 0);
681 sr_policy->
plugin = plugin;
690 create_sl (sr_policy, segments, weight, is_encap);
697 "SRv6 steering of IP6 prefixes through BSIDs");
700 "SRv6 steering of IP4 prefixes through BSIDs");
748 .ip6 = sr_policy->
bsid,
835 u32 *sl_index_iterate;
865 else if (operation == 2)
873 if (*sl_index_iterate == sl_index)
876 if (*sl_index_iterate != sl_index)
895 else if (operation == 3)
899 if (*sl_index_iterate == sl_index)
902 if (*sl_index_iterate != sl_index)
928 char is_del = 0, is_add = 0, is_mod = 0;
930 ip6_address_t bsid, next_address;
933 ip6_address_t *segments = 0, *this_seg;
938 void *ls_plugin_mem = 0;
942 if (!is_add && !is_mod && !is_del &&
unformat (input,
"add"))
944 else if (!is_add && !is_mod && !is_del &&
unformat (input,
"del"))
946 else if (!is_add && !is_mod && !is_del &&
unformat (input,
"mod"))
951 else if (!is_add && !policy_set
952 &&
unformat (input,
"index %d", &sr_policy_index))
954 else if (
unformat (input,
"weight %d", &weight));
962 else if (
unformat (input,
"add sl"))
968 else if (fib_table == (
u32) ~ 0
969 &&
unformat (input,
"fib-table %d", &fib_table));
972 else if (
unformat (input,
"insert"))
976 else if (!behavior &&
unformat (input,
"behavior"))
991 (input,
"%U", (*plugin_it)->ls_unformat, &ls_plugin_mem))
993 behavior = (*plugin_it)->sr_policy_function_number;
1007 if (!is_add && !is_mod && !is_del)
1015 if (behavior &&
vec_len (segments) == 0)
1027 behavior, ls_plugin_mem);
1040 if (operation == 1 &&
vec_len (segments) == 0)
1042 if (operation == 3 && weight == (
u32) ~ 0)
1046 sr_policy_index, fib_table, operation, segments,
1061 "There is already a FIB entry for the BindingSID address.\n" 1062 "The SR policy could not be created.");
1067 "The selected SR policy only contains ONE segment list. " 1068 "Please remove the SR policy instead");
1071 "Could not delete the segment list. " 1072 "It is not associated with that SR policy.");
1075 "Could not modify the segment list. " 1076 "The given SL is not associated with such SR policy.");
1085 .path =
"sr policy",
1086 .short_help =
"sr policy [add||del||mod] [bsid 2001::1||index 5] " 1087 "next A:: next B:: next C:: (weight 1) (fib-table 2) (encap|insert)",
1089 "Manipulation of SR policies.\n" 1090 "A Segment Routing policy may contain several SID lists. Each SID list has\n" 1091 "an associated weight (default 1), which will result in wECMP (uECMP).\n" 1092 "Segment Routing policies might be of type encapsulation or srh insertion\n" 1093 "Each SR policy will be associated with a unique BindingSID.\n" 1094 "A BindingSID is a locally allocated SegmentID. For every packet that arrives\n" 1095 "with IPv6_DA:BSID such traffic will be steered into the SR policy.\n" 1096 "The add command will create a SR policy with its first segment list (sl)\n" 1097 "The mod command allows you to add, remove, or modify the existing segment lists\n" 1098 "within an SR policy.\n" 1099 "The del command allows you to delete a SR policy along with all its associated\n" 1117 ip6_address_t *
addr;
1125 {
vec_add1 (vec_policies, sr_policy); }
1130 sr_policy = vec_policies[
i];
1135 (sr_policy->
is_encap ?
"Encapsulation" :
1147 s =
format (s,
"\t[%u].- ", *sl_index);
1154 s =
format (s,
"\b\b > ");
1165 .path =
"show sr policies",
1166 .short_help =
"show sr policies",
1186 .path =
"show sr encaps source addr",
1187 .short_help =
"show sr encaps source addr",
1207 .path =
"show sr encaps hop-limit",
1208 .short_help =
"show sr encaps hop-limit",
1226 (s,
"SR-policy-rewrite: src %U dst %U",
1259 u32 n_left_from, next_index, *from, *to_next;
1266 int encap_pkts = 0, bsid_pkts = 0;
1268 while (n_left_from > 0)
1275 while (n_left_from >= 8 && n_left_to_next >= 4)
1277 u32 bi0, bi1, bi2, bi3;
1279 u32 next0, next1, next2, next3;
1280 next0 = next1 = next2 = next3 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
1282 ip6_header_t *ip0_encap, *ip1_encap, *ip2_encap, *ip3_encap;
1306 to_next[0] = bi0 = from[0];
1307 to_next[1] = bi1 = from[1];
1308 to_next[2] = bi2 = from[2];
1309 to_next[3] = bi3 = from[3];
1313 n_left_to_next -= 4;
1378 sizeof (tr->
src.as_u8));
1380 sizeof (tr->
dst.as_u8));
1388 sizeof (tr->
src.as_u8));
1390 sizeof (tr->
dst.as_u8));
1398 sizeof (tr->
src.as_u8));
1400 sizeof (tr->
dst.as_u8));
1408 sizeof (tr->
src.as_u8));
1410 sizeof (tr->
dst.as_u8));
1416 n_left_to_next, bi0, bi1, bi2, bi3,
1417 next0, next1, next2, next3);
1421 while (n_left_from > 0 && n_left_to_next > 0)
1427 u32 next0 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
1434 n_left_to_next -= 1;
1459 sizeof (tr->
src.as_u8));
1461 sizeof (tr->
dst.as_u8));
1466 n_left_to_next, bi0, next0);
1474 SR_POLICY_REWRITE_ERROR_COUNTER_TOTAL,
1477 SR_POLICY_REWRITE_ERROR_COUNTER_BSID,
1486 .name =
"sr-pl-rewrite-encaps",
1487 .vector_size =
sizeof (
u32),
1494 #define _(s,n) [SR_POLICY_REWRITE_NEXT_##s] = n, 1515 ip0_encap->
ttl -= 1;
1516 checksum0 = ip0_encap->
checksum + clib_host_to_net_u16 (0x0100);
1517 checksum0 += checksum0 >= 0xffff;
1524 clib_host_to_net_u32 (0 | ((6 & 0xF) << 28) |
1525 ((ip0_encap->
tos & 0xFF) << 20));
1526 if (ip0->
protocol == IP_PROTOCOL_IPV6_ROUTE)
1528 sr0 = (
void *) (ip0 + 1);
1529 sr0->
protocol = IP_PROTOCOL_IP_IN_IP;
1532 ip0->
protocol = IP_PROTOCOL_IP_IN_IP;
1543 u32 n_left_from, next_index, *from, *to_next;
1550 int encap_pkts = 0, bsid_pkts = 0;
1552 while (n_left_from > 0)
1559 while (n_left_from >= 8 && n_left_to_next >= 4)
1561 u32 bi0, bi1, bi2, bi3;
1563 u32 next0, next1, next2, next3;
1564 next0 = next1 = next2 = next3 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
1566 ip4_header_t *ip0_encap, *ip1_encap, *ip2_encap, *ip3_encap;
1590 to_next[0] = bi0 = from[0];
1591 to_next[1] = bi1 = from[1];
1592 to_next[2] = bi2 = from[2];
1593 to_next[3] = bi3 = from[3];
1597 n_left_to_next -= 4;
1661 sizeof (tr->
src.as_u8));
1663 sizeof (tr->
dst.as_u8));
1671 sizeof (tr->
src.as_u8));
1673 sizeof (tr->
dst.as_u8));
1681 sizeof (tr->
src.as_u8));
1683 sizeof (tr->
dst.as_u8));
1691 sizeof (tr->
src.as_u8));
1693 sizeof (tr->
dst.as_u8));
1699 n_left_to_next, bi0, bi1, bi2, bi3,
1700 next0, next1, next2, next3);
1704 while (n_left_from > 0 && n_left_to_next > 0)
1711 u32 next0 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
1718 n_left_to_next -= 1;
1743 sizeof (tr->
src.as_u8));
1745 sizeof (tr->
dst.as_u8));
1750 n_left_to_next, bi0, next0);
1758 SR_POLICY_REWRITE_ERROR_COUNTER_TOTAL,
1761 SR_POLICY_REWRITE_ERROR_COUNTER_BSID,
1770 .name =
"sr-pl-rewrite-encaps-v4",
1771 .vector_size =
sizeof (
u32),
1778 #define _(s,n) [SR_POLICY_REWRITE_NEXT_##s] = n, 1799 return (*((
u64 *) m) & 0xffffffffffff);
1807 uword is_ip, eh_size;
1811 eh_type = clib_net_to_host_u16 (eh->
type);
1814 is_ip = (eh_type == ETHERNET_TYPE_IP4 || eh_type == ETHERNET_TYPE_IP6);
1837 u32 n_left_from, next_index, *from, *to_next;
1844 int encap_pkts = 0, bsid_pkts = 0;
1846 while (n_left_from > 0)
1853 while (n_left_from >= 8 && n_left_to_next >= 4)
1855 u32 bi0, bi1, bi2, bi3;
1857 u32 next0, next1, next2, next3;
1858 next0 = next1 = next2 = next3 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
1886 to_next[0] = bi0 = from[0];
1887 to_next[1] = bi1 = from[1];
1888 to_next[2] = bi2 = from[2];
1889 to_next[3] = bi3 = from[3];
1893 n_left_to_next -= 4;
2015 if (ip0->
protocol == IP_PROTOCOL_IPV6_ROUTE)
2017 sr0 = (
void *) (ip0 + 1);
2023 if (ip1->
protocol == IP_PROTOCOL_IPV6_ROUTE)
2025 sr1 = (
void *) (ip1 + 1);
2031 if (ip2->
protocol == IP_PROTOCOL_IPV6_ROUTE)
2033 sr2 = (
void *) (ip2 + 1);
2039 if (ip3->
protocol == IP_PROTOCOL_IPV6_ROUTE)
2041 sr3 = (
void *) (ip3 + 1);
2057 sizeof (tr->
src.as_u8));
2059 sizeof (tr->
dst.as_u8));
2067 sizeof (tr->
src.as_u8));
2069 sizeof (tr->
dst.as_u8));
2077 sizeof (tr->
src.as_u8));
2079 sizeof (tr->
dst.as_u8));
2087 sizeof (tr->
src.as_u8));
2089 sizeof (tr->
dst.as_u8));
2095 n_left_to_next, bi0, bi1, bi2, bi3,
2096 next0, next1, next2, next3);
2100 while (n_left_from > 0 && n_left_to_next > 0)
2109 u32 next0 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
2116 n_left_to_next -= 1;
2153 if (ip0->
protocol == IP_PROTOCOL_IPV6_ROUTE)
2155 sr0 = (
void *) (ip0 + 1);
2167 sizeof (tr->
src.as_u8));
2169 sizeof (tr->
dst.as_u8));
2174 n_left_to_next, bi0, next0);
2182 SR_POLICY_REWRITE_ERROR_COUNTER_TOTAL,
2185 SR_POLICY_REWRITE_ERROR_COUNTER_BSID,
2194 .name =
"sr-pl-rewrite-encaps-l2",
2195 .vector_size =
sizeof (
u32),
2202 #define _(s,n) [SR_POLICY_REWRITE_NEXT_##s] = n, 2217 u32 n_left_from, next_index, *from, *to_next;
2224 int insert_pkts = 0, bsid_pkts = 0;
2226 while (n_left_from > 0)
2233 while (n_left_from >= 8 && n_left_to_next >= 4)
2235 u32 bi0, bi1, bi2, bi3;
2237 u32 next0, next1, next2, next3;
2238 next0 = next1 = next2 = next3 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
2242 u16 new_l0, new_l1, new_l2, new_l3;
2265 to_next[0] = bi0 = from[0];
2266 to_next[1] = bi1 = from[1];
2267 to_next[2] = bi2 = from[2];
2268 to_next[3] = bi3 = from[3];
2272 n_left_to_next -= 4;
2305 if (ip0->
protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS)
2312 if (ip1->
protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS)
2319 if (ip2->
protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS)
2326 if (ip3->
protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS)
2334 (
void *) sr0 - (
void *) ip0);
2336 (
void *) sr1 - (
void *) ip1);
2338 (
void *) sr2 - (
void *) ip2);
2340 (
void *) sr3 - (
void *) ip3);
2361 ip0->hop_limit -= 1;
2362 ip1->hop_limit -= 1;
2363 ip2->hop_limit -= 1;
2364 ip3->hop_limit -= 1;
2367 clib_net_to_host_u16 (ip0->payload_length) +
2370 clib_net_to_host_u16 (ip1->payload_length) +
2373 clib_net_to_host_u16 (ip2->payload_length) +
2376 clib_net_to_host_u16 (ip3->payload_length) +
2379 ip0->payload_length = clib_host_to_net_u16 (new_l0);
2380 ip1->payload_length = clib_host_to_net_u16 (new_l1);
2381 ip2->payload_length = clib_host_to_net_u16 (new_l2);
2382 ip3->payload_length = clib_host_to_net_u16 (new_l3);
2389 sr0->
segments->as_u64[0] = ip0->dst_address.as_u64[0];
2390 sr0->
segments->as_u64[1] = ip0->dst_address.as_u64[1];
2391 sr1->
segments->as_u64[0] = ip1->dst_address.as_u64[0];
2392 sr1->
segments->as_u64[1] = ip1->dst_address.as_u64[1];
2393 sr2->
segments->as_u64[0] = ip2->dst_address.as_u64[0];
2394 sr2->
segments->as_u64[1] = ip2->dst_address.as_u64[1];
2395 sr3->
segments->as_u64[0] = ip3->dst_address.as_u64[0];
2396 sr3->
segments->as_u64[1] = ip3->dst_address.as_u64[1];
2398 ip0->dst_address.as_u64[0] =
2400 ip0->dst_address.as_u64[1] =
2402 ip1->dst_address.as_u64[0] =
2404 ip1->dst_address.as_u64[1] =
2406 ip2->dst_address.as_u64[0] =
2408 ip2->dst_address.as_u64[1] =
2410 ip3->dst_address.as_u64[0] =
2412 ip3->dst_address.as_u64[1] =
2415 ip6_ext_header_t *ip_ext;
2416 if (ip0 + 1 == (
void *) sr0)
2419 ip0->protocol = IP_PROTOCOL_IPV6_ROUTE;
2423 ip_ext = (
void *) (ip0 + 1);
2425 ip_ext->next_hdr = IP_PROTOCOL_IPV6_ROUTE;
2428 if (ip1 + 1 == (
void *) sr1)
2431 ip1->protocol = IP_PROTOCOL_IPV6_ROUTE;
2435 ip_ext = (
void *) (ip2 + 1);
2437 ip_ext->next_hdr = IP_PROTOCOL_IPV6_ROUTE;
2440 if (ip2 + 1 == (
void *) sr2)
2443 ip2->protocol = IP_PROTOCOL_IPV6_ROUTE;
2447 ip_ext = (
void *) (ip2 + 1);
2449 ip_ext->next_hdr = IP_PROTOCOL_IPV6_ROUTE;
2452 if (ip3 + 1 == (
void *) sr3)
2455 ip3->protocol = IP_PROTOCOL_IPV6_ROUTE;
2459 ip_ext = (
void *) (ip3 + 1);
2461 ip_ext->next_hdr = IP_PROTOCOL_IPV6_ROUTE;
2473 sizeof (tr->
src.as_u8));
2475 sizeof (tr->
dst.as_u8));
2483 sizeof (tr->
src.as_u8));
2485 sizeof (tr->
dst.as_u8));
2493 sizeof (tr->
src.as_u8));
2495 sizeof (tr->
dst.as_u8));
2503 sizeof (tr->
src.as_u8));
2505 sizeof (tr->
dst.as_u8));
2510 n_left_to_next, bi0, bi1, bi2, bi3,
2511 next0, next1, next2, next3);
2515 while (n_left_from > 0 && n_left_to_next > 0)
2522 u32 next0 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
2530 n_left_to_next -= 1;
2541 if (ip0->
protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS)
2549 (
void *) sr0 - (
void *) ip0);
2556 ip0->hop_limit -= 1;
2558 clib_net_to_host_u16 (ip0->payload_length) +
2560 ip0->payload_length = clib_host_to_net_u16 (new_l0);
2563 sr0->
segments->as_u64[0] = ip0->dst_address.as_u64[0];
2564 sr0->
segments->as_u64[1] = ip0->dst_address.as_u64[1];
2566 ip0->dst_address.as_u64[0] =
2568 ip0->dst_address.as_u64[1] =
2571 if (ip0 + 1 == (
void *) sr0)
2574 ip0->protocol = IP_PROTOCOL_IPV6_ROUTE;
2578 ip6_ext_header_t *ip_ext = (
void *) (ip0 + 1);
2580 ip_ext->next_hdr = IP_PROTOCOL_IPV6_ROUTE;
2589 sizeof (tr->
src.as_u8));
2591 sizeof (tr->
dst.as_u8));
2597 n_left_to_next, bi0, next0);
2605 SR_POLICY_REWRITE_ERROR_COUNTER_TOTAL,
2608 SR_POLICY_REWRITE_ERROR_COUNTER_BSID,
2616 .name =
"sr-pl-rewrite-insert",
2617 .vector_size =
sizeof (
u32),
2624 #define _(s,n) [SR_POLICY_REWRITE_NEXT_##s] = n, 2639 u32 n_left_from, next_index, *from, *to_next;
2646 int insert_pkts = 0, bsid_pkts = 0;
2648 while (n_left_from > 0)
2655 while (n_left_from >= 8 && n_left_to_next >= 4)
2657 u32 bi0, bi1, bi2, bi3;
2659 u32 next0, next1, next2, next3;
2660 next0 = next1 = next2 = next3 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
2664 u16 new_l0, new_l1, new_l2, new_l3;
2687 to_next[0] = bi0 = from[0];
2688 to_next[1] = bi1 = from[1];
2689 to_next[2] = bi2 = from[2];
2690 to_next[3] = bi3 = from[3];
2694 n_left_to_next -= 4;
2727 if (ip0->
protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS)
2734 if (ip1->
protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS)
2741 if (ip2->
protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS)
2748 if (ip3->
protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS)
2756 (
u8 *) ip0, (
void *) sr0 - (
void *) ip0);
2758 (
u8 *) ip1, (
void *) sr1 - (
void *) ip1);
2760 (
u8 *) ip2, (
void *) sr2 - (
void *) ip2);
2762 (
u8 *) ip3, (
void *) sr3 - (
void *) ip3);
2783 ip0->hop_limit -= 1;
2784 ip1->hop_limit -= 1;
2785 ip2->hop_limit -= 1;
2786 ip3->hop_limit -= 1;
2789 clib_net_to_host_u16 (ip0->payload_length) +
2792 clib_net_to_host_u16 (ip1->payload_length) +
2795 clib_net_to_host_u16 (ip2->payload_length) +
2798 clib_net_to_host_u16 (ip3->payload_length) +
2801 ip0->payload_length = clib_host_to_net_u16 (new_l0);
2802 ip1->payload_length = clib_host_to_net_u16 (new_l1);
2803 ip2->payload_length = clib_host_to_net_u16 (new_l2);
2804 ip3->payload_length = clib_host_to_net_u16 (new_l3);
2811 ip0->dst_address.as_u64[0] =
2813 ip0->dst_address.as_u64[1] =
2815 ip1->dst_address.as_u64[0] =
2817 ip1->dst_address.as_u64[1] =
2819 ip2->dst_address.as_u64[0] =
2821 ip2->dst_address.as_u64[1] =
2823 ip3->dst_address.as_u64[0] =
2825 ip3->dst_address.as_u64[1] =
2828 ip6_ext_header_t *ip_ext;
2829 if (ip0 + 1 == (
void *) sr0)
2832 ip0->protocol = IP_PROTOCOL_IPV6_ROUTE;
2836 ip_ext = (
void *) (ip0 + 1);
2838 ip_ext->next_hdr = IP_PROTOCOL_IPV6_ROUTE;
2841 if (ip1 + 1 == (
void *) sr1)
2844 ip1->protocol = IP_PROTOCOL_IPV6_ROUTE;
2848 ip_ext = (
void *) (ip2 + 1);
2850 ip_ext->next_hdr = IP_PROTOCOL_IPV6_ROUTE;
2853 if (ip2 + 1 == (
void *) sr2)
2856 ip2->protocol = IP_PROTOCOL_IPV6_ROUTE;
2860 ip_ext = (
void *) (ip2 + 1);
2862 ip_ext->next_hdr = IP_PROTOCOL_IPV6_ROUTE;
2865 if (ip3 + 1 == (
void *) sr3)
2868 ip3->protocol = IP_PROTOCOL_IPV6_ROUTE;
2872 ip_ext = (
void *) (ip3 + 1);
2874 ip_ext->next_hdr = IP_PROTOCOL_IPV6_ROUTE;
2886 sizeof (tr->
src.as_u8));
2888 sizeof (tr->
dst.as_u8));
2896 sizeof (tr->
src.as_u8));
2898 sizeof (tr->
dst.as_u8));
2906 sizeof (tr->
src.as_u8));
2908 sizeof (tr->
dst.as_u8));
2916 sizeof (tr->
src.as_u8));
2918 sizeof (tr->
dst.as_u8));
2923 n_left_to_next, bi0, bi1, bi2, bi3,
2924 next0, next1, next2, next3);
2928 while (n_left_from > 0 && n_left_to_next > 0)
2935 u32 next0 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
2943 n_left_to_next -= 1;
2954 if (ip0->
protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS)
2962 (
u8 *) ip0, (
void *) sr0 - (
void *) ip0);
2969 ip0->hop_limit -= 1;
2971 clib_net_to_host_u16 (ip0->payload_length) +
2973 ip0->payload_length = clib_host_to_net_u16 (new_l0);
2977 ip0->dst_address.as_u64[0] =
2979 ip0->dst_address.as_u64[1] =
2982 if (ip0 + 1 == (
void *) sr0)
2985 ip0->protocol = IP_PROTOCOL_IPV6_ROUTE;
2989 ip6_ext_header_t *ip_ext = (
void *) (ip0 + 1);
2991 ip_ext->next_hdr = IP_PROTOCOL_IPV6_ROUTE;
3000 sizeof (tr->
src.as_u8));
3002 sizeof (tr->
dst.as_u8));
3008 n_left_to_next, bi0, next0);
3016 SR_POLICY_REWRITE_ERROR_COUNTER_TOTAL,
3019 SR_POLICY_REWRITE_ERROR_COUNTER_BSID,
3027 .name =
"sr-pl-rewrite-b-insert",
3028 .vector_size =
sizeof (
u32),
3035 #define _(s,n) [SR_POLICY_REWRITE_NEXT_##s] = n, 3051 ip6_address_t *new_dst0;
3054 goto error_bsid_encaps;
3061 new_dst0 = (ip6_address_t *) (sr0->
segments);
3070 *next0 = SR_POLICY_REWRITE_NEXT_ERROR;
3071 b0->
error = node->
errors[SR_POLICY_REWRITE_ERROR_BSID_ZERO];
3082 u32 n_left_from, next_index, *from, *to_next;
3089 int encap_pkts = 0, bsid_pkts = 0;
3091 while (n_left_from > 0)
3098 while (n_left_from >= 8 && n_left_to_next >= 4)
3100 u32 bi0, bi1, bi2, bi3;
3102 u32 next0, next1, next2, next3;
3103 next0 = next1 = next2 = next3 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
3105 ip6_header_t *ip0_encap, *ip1_encap, *ip2_encap, *ip3_encap;
3130 to_next[0] = bi0 = from[0];
3131 to_next[1] = bi1 = from[1];
3132 to_next[2] = bi2 = from[2];
3133 to_next[3] = bi3 = from[3];
3137 n_left_to_next -= 4;
3219 sizeof (tr->
src.as_u8));
3221 sizeof (tr->
dst.as_u8));
3229 sizeof (tr->
src.as_u8));
3231 sizeof (tr->
dst.as_u8));
3239 sizeof (tr->
src.as_u8));
3241 sizeof (tr->
dst.as_u8));
3249 sizeof (tr->
src.as_u8));
3251 sizeof (tr->
dst.as_u8));
3257 n_left_to_next, bi0, bi1, bi2, bi3,
3258 next0, next1, next2, next3);
3262 while (n_left_from > 0 && n_left_to_next > 0)
3269 u32 next0 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
3276 n_left_to_next -= 1;
3305 sizeof (tr->
src.as_u8));
3307 sizeof (tr->
dst.as_u8));
3312 n_left_to_next, bi0, next0);
3320 SR_POLICY_REWRITE_ERROR_COUNTER_TOTAL,
3323 SR_POLICY_REWRITE_ERROR_COUNTER_BSID,
3332 .name =
"sr-pl-rewrite-b-encaps",
3333 .vector_size =
sizeof (
u32),
3340 #define _(s,n) [SR_POLICY_REWRITE_NEXT_##s] = n, 3411 vlib_cli_output (vm,
"SR Policy behaviors:\n-----------------------\n\n");
3415 {
vec_add1 (plugins_vec, plugin); }
3419 for (i = 0; i <
vec_len (plugins_vec); i++)
3421 plugin = plugins_vec[
i];
3431 .path =
"show sr policy behaviors",
3432 .short_help =
"show sr policy behaviors",
3442 ip6_address_t *
addr;
3447 s =
format (s,
"SR: Segment List index:[%d]", index);
3448 s =
format (s,
"\n\tSegments:");
3457 s =
format (s,
"\b\b > - ");
3470 "sr-pl-rewrite-encaps",
3475 "sr-pl-rewrite-encaps-v4",
3485 "sr-pl-rewrite-insert",
3494 "sr-pl-rewrite-b-insert",
3503 "sr-pl-rewrite-b-encaps",
3522 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.
#define pool_foreach(VAR, POOL)
Iterate through pool.
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)
static u32 ip4_compute_flow_hash(const ip4_header_t *ip, flow_hash_config_t flow_hash_config)
#define clib_memcpy_fast(a, b, c)
unsigned char params_str[32]
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() ...
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_policy_fn_registration_t * policy_plugin_functions
SR Segment List (SID list)
description fragment has unexpected format
#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.
#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 IP_FLOW_HASH_DEFAULT
Default: 5-tuple without the "reverse" bit.
#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)
__clib_export void mhash_init(mhash_t *h, uword n_value_bytes, uword n_key_bytes)
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...
#define hash_mix64(a0, b0, c0)
#define CLIB_PREFETCH(addr, size, type)
static clib_error_t * show_sr_encaps_source_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
CLI to display onscreen the SR encaps source addr.
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
ip6_address_t * sr_get_encaps_source()
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
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.
#define SR_SEGMENT_LIST_WEIGHT_DEFAULT
mhash_t sr_policies_index_hash
static u32 ip6_compute_flow_hash(const ip6_header_t *ip, flow_hash_config_t flow_hash_config)
__clib_export uword mhash_unset(mhash_t *h, void *key, uword *old_value)
#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.
static clib_error_t * show_sr_encaps_hop_limit_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
CLI to display onscreen the hop-limit value used for SRv6 encapsulation.
u32 flow_hash_config_t
A flow hash configuration is a mask of the flow hash options.
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.
void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
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)
vl_api_interface_index_t sw_if_index
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.