aboutsummaryrefslogtreecommitdiffstats
path: root/vpp
diff options
context:
space:
mode:
authorKeith Burns (alagalah) <alagalah@gmail.com>2016-03-25 09:38:50 -0700
committerKeith Burns <alagalah@gmail.com>2016-04-30 16:38:09 +0000
commit52fc44d61bcebb898dc19ab818ff60e617055694 (patch)
tree2a5155984329b766f74ed4ef42569b6279d871bf /vpp
parent6de2ff28fef27421f6b9a6c1f4ef53d1bd8c7c6e (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')
-rw-r--r--vpp/api/api.c117
-rw-r--r--vpp/api/custom_dump.c73
-rw-r--r--vpp/api/vpe.api52
3 files changed, 239 insertions, 3 deletions
diff --git a/vpp/api/api.c b/vpp/api/api.c
index eaae51a5eac..41f57602550 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 cd17328edb4..6ae8c76dd82 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 88b6070083d..9d0f6b7f469 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