diff options
author | Keith Burns (alagalah) <alagalah@gmail.com> | 2016-03-25 09:38:50 -0700 |
---|---|---|
committer | Keith Burns <alagalah@gmail.com> | 2016-04-30 16:38:09 +0000 |
commit | 52fc44d61bcebb898dc19ab818ff60e617055694 (patch) | |
tree | 2a5155984329b766f74ed4ef42569b6279d871bf /vpp-api-test | |
parent | 6de2ff28fef27421f6b9a6c1f4ef53d1bd8c7c6e (diff) |
IP6 SR multicast replicator
- adds ability to name tunnel
- creates policy as a collection of tunnel names
- map ip6 multicast address to policy and replicate packet
- adds zero memcpy for invariant portion of packet
Change-Id: Icd2fe6a2cf65c09906e82ed1afbb0eae8df79452
Signed-off-by: Keith Burns (alagalah) <alagalah@gmail.com>
Diffstat (limited to 'vpp-api-test')
-rw-r--r-- | vpp-api-test/vat/api_format.c | 152 |
1 files changed, 150 insertions, 2 deletions
diff --git a/vpp-api-test/vat/api_format.c b/vpp-api-test/vat/api_format.c index bbb3e252c38..4a57d4cb018 100644 --- a/vpp-api-test/vat/api_format.c +++ b/vpp-api-test/vat/api_format.c @@ -2159,6 +2159,8 @@ _(sw_interface_ip6nd_ra_config_reply) \ _(set_arp_neighbor_limit_reply) \ _(l2_patch_add_del_reply) \ _(sr_tunnel_add_del_reply) \ +_(sr_policy_add_del_reply) \ +_(sr_multicast_map_add_del_reply) \ _(classify_add_del_session_reply) \ _(classify_set_interface_ip_table_reply) \ _(classify_set_interface_l2_tables_reply) \ @@ -2298,6 +2300,8 @@ _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY, \ _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply) \ _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply) \ _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply) \ +_(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply) \ +_(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply) \ _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply) \ _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply) \ _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY, \ @@ -5537,6 +5541,7 @@ static int api_trace_profile_del (vat_main_t *vam) S; W; return 0; } + static int api_sr_tunnel_add_del (vat_main_t * vam) { unformat_input_t * i = vam->input; @@ -5557,11 +5562,17 @@ static int api_sr_tunnel_add_del (vat_main_t * vam) ip6_address_t * tags = 0; ip6_address_t * this_tag; ip6_address_t next_address, tag; + u8 * name = 0; + u8 * policy_name = 0; while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) { if (unformat (i, "del")) is_del = 1; + else if (unformat (i, "name %s", &name)) + ; + else if (unformat (i, "policy %s", &policy_name)) + ; else if (unformat (i, "rx_fib_id %d", &rx_table_id)) ; else if (unformat (i, "tx_fib_id %d", &tx_table_id)) @@ -5650,6 +5661,8 @@ static int api_sr_tunnel_add_del (vat_main_t * vam) mp->outer_vrf_id = ntohl (rx_table_id); mp->inner_vrf_id = ntohl (tx_table_id); + memcpy (mp->name, name, vec_len(name)); + memcpy (mp->policy_name, policy_name, vec_len(policy_name)); vec_free (segments); vec_free (tags); @@ -5658,6 +5671,136 @@ static int api_sr_tunnel_add_del (vat_main_t * vam) /* NOTREACHED */ } +static int api_sr_policy_add_del (vat_main_t * vam) +{ + unformat_input_t * input = vam->input; + vl_api_sr_policy_add_del_t *mp; + f64 timeout; + int is_del = 0; + u8 * name = 0; + u8 * tunnel_name = 0; + u8 ** tunnel_names = 0; + + int name_set = 0 ; + int tunnel_set = 0; + int j = 0; + int tunnel_names_length = 1; // Init to 1 to offset the #tunnel_names counter byte + int tun_name_len = 0; // Different naming convention used as confusing these would be "bad" (TM) + + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (input, "del")) + is_del = 1; + else if (unformat (input, "name %s", &name)) + name_set = 1; + else if (unformat (input, "tunnel %s", &tunnel_name)) + { + if (tunnel_name) + { + vec_add1 (tunnel_names, tunnel_name); + /* For serializer: + - length = #bytes to store in serial vector + - +1 = byte to store that length + */ + tunnel_names_length += (vec_len (tunnel_name) + 1); + tunnel_set = 1; + tunnel_name = 0; + } + } + else + break; + } + + if (!name_set) + { + errmsg ("policy name required\n"); + return -99; + } + + if ((!tunnel_set) && (!is_del)) + { + errmsg ("tunnel name required\n"); + return -99; + } + + M2(SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length); + + + + mp->is_add = !is_del; + + memcpy (mp->name, name, vec_len(name)); + // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized + u8 * serial_orig = 0; + vec_validate (serial_orig, tunnel_names_length); + *serial_orig = vec_len(tunnel_names); // Store the number of tunnels as length in first byte of serialized vector + serial_orig += 1; // Move along one byte to store the length of first tunnel_name + + for (j=0; j < vec_len(tunnel_names); j++) + { + tun_name_len = vec_len (tunnel_names[j]); + *serial_orig = tun_name_len; // Store length of tunnel name in first byte of Length/Value pair + serial_orig += 1; // Move along one byte to store the actual tunnel name + memcpy (serial_orig, tunnel_names[j], tun_name_len); + serial_orig += tun_name_len; // Advance past the copy + } + memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length); // Regress serial_orig to head then copy fwd + + vec_free (tunnel_names); + vec_free (tunnel_name); + + S; W; + /* NOTREACHED */ +} + +static int api_sr_multicast_map_add_del (vat_main_t * vam) +{ + unformat_input_t * input = vam->input; + vl_api_sr_multicast_map_add_del_t *mp; + f64 timeout; + int is_del = 0; + ip6_address_t multicast_address; + u8 * policy_name = 0; + int multicast_address_set = 0; + + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (input, "del")) + is_del = 1; + else if (unformat (input, "address %U", unformat_ip6_address, &multicast_address)) + multicast_address_set = 1; + else if (unformat (input, "sr-policy %s", &policy_name)) + ; + else + break; + } + + if (!is_del && !policy_name) + { + errmsg ("sr-policy name required\n"); + return -99; + } + + + if (!multicast_address_set) + { + errmsg ("address required\n"); + return -99; + } + + M(SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del); + + mp->is_add = !is_del; + memcpy (mp->policy_name, policy_name, vec_len(policy_name)); + clib_memcpy (mp->multicast_address, &multicast_address, sizeof (mp->multicast_address)); + + + vec_free (policy_name); + + S; W; + /* NOTREACHED */ +} + #define foreach_ip4_proto_field \ _(src_address) \ @@ -10508,8 +10651,13 @@ _(mpls_ethernet_add_del_tunnel_2, \ "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n" \ "resolve-attempts <n> resolve-if-needed 0 | 1 [del]") \ _(sr_tunnel_add_del, \ - "src <ip6-addr> dst <ip6-addr>/<mw> (next <ip6-addr>)+\n" \ - " [tag <ip6-addr>]* [clean] [reroute]") \ + "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n" \ + "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n" \ + "[policy <policy_name>]") \ +_(sr_policy_add_del, \ + "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]") \ +_(sr_multicast_map_add_del, \ + "address [ip6 multicast address] sr-policy [policy name] [del]") \ _(classify_add_del_table, \ "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n" \ "[del] mask <mask-value>\n" \ |