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 | |
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')
-rw-r--r-- | vpp/api/api.c | 117 | ||||
-rw-r--r-- | vpp/api/custom_dump.c | 73 | ||||
-rw-r--r-- | vpp/api/vpe.api | 52 |
3 files changed, 239 insertions, 3 deletions
diff --git a/vpp/api/api.c b/vpp/api/api.c index eaae51a5..41f57602 100644 --- a/vpp/api/api.c +++ b/vpp/api/api.c @@ -42,6 +42,7 @@ #include <vppinfra/format.h> #include <vppinfra/error.h> +#include <vnet/api_errno.h> // alagalah TODO : committers please pay note, is this ok? #include <vnet/vnet.h> #include <vnet/l2/l2_input.h> #include <vnet/l2/l2_bd.h> @@ -329,7 +330,8 @@ _(LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface) \ _(LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump) \ _(LISP_LOCAL_EID_TABLE_DUMP, lisp_local_eid_table_dump) \ _(LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump) \ -_(LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump) +_(LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump) \ +_(SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del) #define QUOTE_(x) #x #define QUOTE(x) QUOTE_(x) @@ -3389,7 +3391,15 @@ static void vl_api_sr_tunnel_add_del_t_handler a->is_del = (mp->is_add == 0); a->rx_table_id = ntohl(mp->outer_vrf_id); a->tx_table_id = ntohl(mp->inner_vrf_id); - + + a->name = format(0, "%s", mp->name); + if (!(vec_len(a->name))) + a->name = 0; + + a->policy_name = format(0, "%s", mp->policy_name); + if (!(vec_len(a->policy_name))) + a->policy_name = 0; + /* Yank segments and tags out of the API message */ this_address = (ip6_address_t *)mp->segs_and_tags; for (i = 0; i < mp->n_segments; i++) { @@ -3414,6 +3424,96 @@ out: #endif } +static void vl_api_sr_policy_add_del_t_handler +(vl_api_sr_policy_add_del_t *mp) +{ +#if IPV6SR == 0 + clib_warning ("unimplemented"); +#else + ip6_sr_add_del_policy_args_t _a, *a=&_a; + int rv = 0; + vl_api_sr_policy_add_del_reply_t * rmp; + int i; + + memset (a, 0, sizeof (*a)); + a->is_del = (mp->is_add == 0); + + a->name = format(0, "%s", mp->name); + if (!(vec_len(a->name))) + { + rv = VNET_API_ERROR_NO_SUCH_NODE2; + goto out; + } + + if (!(mp->tunnel_names)) + { + rv = VNET_API_ERROR_NO_SUCH_NODE2; + goto out; + } + + // start deserializing tunnel_names + int num_tunnels = mp->tunnel_names[0]; //number of tunnels + u8 * deser_tun_names = mp->tunnel_names; + deser_tun_names += 1; //moving along + + u8 * tun_name = 0; + int tun_name_len = 0; + + for (i=0; i < num_tunnels; i++) + { + tun_name_len= *deser_tun_names; + deser_tun_names += 1; + vec_resize (tun_name, tun_name_len); + memcpy(tun_name, deser_tun_names, tun_name_len); + vec_add1 (a->tunnel_names, tun_name); + deser_tun_names += tun_name_len; + tun_name = 0; + } + + rv = ip6_sr_add_del_policy (a); + +out: + + REPLY_MACRO(VL_API_SR_POLICY_ADD_DEL_REPLY); +#endif +} + +static void vl_api_sr_multicast_map_add_del_t_handler +(vl_api_sr_multicast_map_add_del_t *mp) +{ +#if IPV6SR == 0 + clib_warning ("unimplemented"); +#else + ip6_sr_add_del_multicastmap_args_t _a, *a=&_a; + int rv = 0; + vl_api_sr_multicast_map_add_del_reply_t * rmp; + + memset (a, 0, sizeof (*a)); + a->is_del = (mp->is_add == 0); + + a->multicast_address = (ip6_address_t *)&mp->multicast_address; + a->policy_name = format(0, "%s", mp->policy_name); + + if (a->multicast_address == 0) + { + rv = -1 ; + goto out; + } + + if (!(a->policy_name)) + { + rv = -2 ; + goto out; + } + + rv = ip6_sr_add_del_multicastmap (a); + +out: + + REPLY_MACRO(VL_API_SR_MULTICAST_MAP_ADD_DEL_REPLY); +#endif +} + #define foreach_classify_add_del_table_field \ _(table_index) \ _(nbuckets) \ @@ -5827,6 +5927,19 @@ vpe_api_hookup (vlib_main_t *vm) vl_api_sr_tunnel_add_del_t_print, 256, 1); + + /* + * Manually register the sr policy add del msg, so we trace + * enough bytes to capture a typical tunnel name list + */ + vl_msg_api_set_handlers (VL_API_SR_POLICY_ADD_DEL, + "sr_policy_add_del", + vl_api_sr_policy_add_del_t_handler, + vl_noop_handler, + vl_api_sr_policy_add_del_t_endian, + vl_api_sr_policy_add_del_t_print, + 256, 1); + /* * Trace space for 8 MPLS encap labels, classifier mask+match */ diff --git a/vpp/api/custom_dump.c b/vpp/api/custom_dump.c index cd17328e..6ae8c76d 100644 --- a/vpp/api/custom_dump.c +++ b/vpp/api/custom_dump.c @@ -1014,6 +1014,9 @@ static void *vl_api_sr_tunnel_add_del_t_print s = format (0, "SCRIPT: sr_tunnel_add_del "); + if (mp->name) + s = format (s, "name %s ", mp->name); + s = format (s, "src %U dst %U/%d ", format_ip6_address, (ip6_address_t *) mp->src_address, format_ip6_address, @@ -1062,12 +1065,78 @@ static void *vl_api_sr_tunnel_add_del_t_print } } + if (mp->policy_name) + s = format (s, "policy_name %s ", mp->policy_name); + if (mp->is_add == 0) s = format (s, "del "); FINISH; } +static void *vl_api_sr_policy_add_del_t_print +(vl_api_sr_policy_add_del_t * mp, void *handle) +{ + u8 * s; + int i; + + s = format (0, "SCRIPT: sr_policy_add_del "); + + if (mp->name) + s = format (s, "name %s ", mp->name); + + + if (mp->tunnel_names) + { + // start deserializing tunnel_names + int num_tunnels = mp->tunnel_names[0]; //number of tunnels + u8 * deser_tun_names = mp->tunnel_names; + deser_tun_names += 1; //moving along + + u8 * tun_name = 0; + int tun_name_len = 0; + + for (i=0; i < num_tunnels; i++) + { + tun_name_len= *deser_tun_names; + deser_tun_names += 1; + vec_resize (tun_name, tun_name_len); + memcpy(tun_name, deser_tun_names, tun_name_len); + s = format (s, "tunnel %s ", tun_name); + deser_tun_names += tun_name_len; + tun_name = 0; + } + } + + if (mp->is_add == 0) + s = format (s, "del "); + + FINISH; +} + +static void *vl_api_sr_multicast_map_add_del_t_print +(vl_api_sr_multicast_map_add_del_t * mp, void *handle) +{ + + u8 * s = 0; + /* int i; */ + + s = format (0, "SCRIPT: sr_multicast_map_add_del "); + + if (mp->multicast_address) + s = format (s, "address %U ", format_ip6_address, &mp->multicast_address); + + if (mp->policy_name) + s = format (s, "sr-policy %s ", &mp->policy_name); + + + if (mp->is_add == 0) + s = format (s, "del "); + + FINISH; +} + + static void *vl_api_classify_add_del_table_t_print (vl_api_classify_add_del_table_t * mp, void *handle) { @@ -1808,6 +1877,8 @@ _(SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config) \ _(SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit) \ _(L2_PATCH_ADD_DEL, l2_patch_add_del) \ _(SR_TUNNEL_ADD_DEL, sr_tunnel_add_del) \ +_(SR_POLICY_ADD_DEL, sr_policy_add_del) \ +_(SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del) \ _(SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect) \ _(L2FIB_ADD_DEL, l2fib_add_del) \ _(L2_FLAGS, l2_flags) \ @@ -1816,7 +1887,7 @@ _(CLASSIFY_ADD_DEL_TABLE, classify_add_del_table) \ _(CLASSIFY_ADD_DEL_SESSION, classify_add_del_session) \ _(SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge) \ _(BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del) \ -_(BRIDGE_DOMAIN_DUMP, bridge_domain_dump) \ +_(BRIDGE_DOMAIN_DUMP, bridge_domain_dump) \ _(CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table) \ _(CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables) \ _(ADD_NODE_NEXT, add_node_next) \ diff --git a/vpp/api/vpe.api b/vpp/api/vpe.api index 88b60700..9d0f6b7f 100644 --- a/vpp/api/vpe.api +++ b/vpp/api/vpe.api @@ -1145,6 +1145,7 @@ define l2_patch_add_del_reply { @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request @param is_add - add the tunnel if non-zero, else delete it + @param name[] - tunnel name (len. 64) @param src_address[] - @param dst_address[] - @param dst_mask_width - @@ -1154,11 +1155,13 @@ define l2_patch_add_del_reply { @param n_segments - @param n_tags - @param segs_and_tags[] - + @param policy_name[] - name of policy to associate this tunnel to (len. 64) */ define sr_tunnel_add_del { u32 client_index; u32 context; u8 is_add; + u8 name[64]; u8 src_address[16]; u8 dst_address[16]; u8 dst_mask_width; @@ -1168,6 +1171,7 @@ define sr_tunnel_add_del { u8 n_segments; u8 n_tags; u8 segs_and_tags[0]; + u8 policy_name[64]; }; /** \brief IPv6 segment routing tunnel add / del response @@ -1179,6 +1183,54 @@ define sr_tunnel_add_del_reply { i32 retval; }; +/** \brief IPv6 segment routing policy add / del request + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param is_add - add the tunnel if non-zero, else delete it + @param name[] - policy name (len. 64) + @param tunnel_names[] - +*/ +define sr_policy_add_del { + u32 client_index; + u32 context; + u8 is_add; + u8 name[64]; + u8 tunnel_names[0]; +}; + +/** \brief IPv6 segment routing policy add / del response + @param context - sender context, to match reply w/ request + @param retval - return value for request +*/ +define sr_policy_add_del_reply { + u32 context; + i32 retval; +}; + +/** \brief IPv6 segment routing multicast map to policy add / del request + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param is_add - add the tunnel if non-zero, else delete it + @param multicast_address[] - IP6 multicast address + @param policy_name[] = policy name (len.64) +*/ +define sr_multicast_map_add_del { + u32 client_index; + u32 context; + u8 is_add; + u8 multicast_address[16]; + u8 policy_name[64]; +}; + +/** \brief IPv6 segment routing multicast map to policy add / del response + @param context - sender context, to match reply w/ request + @param retval - return value for request +*/ +define sr_multicast_map_add_del_reply { + u32 context; + i32 retval; +}; + /** \brief Interface set vpath request @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request |