ip: Router ID included in flow hash
[vpp.git] / src / plugins / cnat / cnat_api.c
index 2049d44..c215caa 100644 (file)
@@ -43,28 +43,44 @@ static u32 cnat_base_msg_id;
 
 #include <vlibapi/api_helper_macros.h>
 
-static void
+static int
 cnat_endpoint_decode (const vl_api_cnat_endpoint_t * in,
                      cnat_endpoint_t * out)
 {
-  ip_address_decode2 (&in->addr, &out->ce_ip);
+  int rv = 0;
   out->ce_port = clib_net_to_host_u16 (in->port);
+  out->ce_sw_if_index = clib_net_to_host_u32 (in->sw_if_index);
+  out->ce_flags = 0;
+  if (out->ce_sw_if_index == INDEX_INVALID)
+    ip_address_decode2 (&in->addr, &out->ce_ip);
+  else
+    rv = ip_address_family_decode (in->if_af, &out->ce_ip.version);
+  return rv;
 }
 
-static void
+static int
 cnat_endpoint_tuple_decode (const vl_api_cnat_endpoint_tuple_t * in,
                            cnat_endpoint_tuple_t * out)
 {
-  cnat_endpoint_decode (&in->src_ep, &out->src_ep);
-  cnat_endpoint_decode (&in->dst_ep, &out->dst_ep);
+  int rv = 0;
+  rv = cnat_endpoint_decode (&in->src_ep, &out->src_ep);
+  if (rv)
+    return rv;
+  rv = cnat_endpoint_decode (&in->dst_ep, &out->dst_ep);
+  return rv;
 }
 
 static void
 cnat_endpoint_encode (const cnat_endpoint_t * in,
                      vl_api_cnat_endpoint_t * out)
 {
-  ip_address_encode2 (&in->ce_ip, &out->addr);
   out->port = clib_net_to_host_u16 (in->ce_port);
+  out->sw_if_index = clib_net_to_host_u32 (in->ce_sw_if_index);
+  out->if_af = ip_address_family_encode (in->ce_ip.version);
+  if (in->ce_flags & CNAT_EP_FLAG_RESOLVED)
+    ip_address_encode2 (&in->ce_ip, &out->addr);
+  else
+    clib_memset ((void *) &in->ce_ip, 0, sizeof (in->ce_ip));
 }
 
 static void
@@ -78,21 +94,27 @@ vl_api_cnat_translation_update_t_handler (vl_api_cnat_translation_update_t
   u32 id = ~0;
   u8 flags;
   int rv = 0;
-  u8 pi;
+  u32 pi, n_paths;
 
   rv = ip_proto_decode (mp->translation.ip_proto, &ip_proto);
 
   if (rv)
     goto done;
 
-  vec_validate (paths, mp->translation.n_paths - 1);
+  n_paths = clib_net_to_host_u32 (mp->translation.n_paths);
+  vec_validate (paths, n_paths - 1);
 
-  for (pi = 0; pi < mp->translation.n_paths; pi++)
+  for (pi = 0; pi < n_paths; pi++)
     {
       path = &paths[pi];
-      cnat_endpoint_tuple_decode (&mp->translation.paths[pi], path);
+      rv = cnat_endpoint_tuple_decode (&mp->translation.paths[pi], path);
+      if (rv)
+       goto done;
     }
-  cnat_endpoint_decode (&mp->translation.vip, &vip);
+
+  rv = cnat_endpoint_decode (&mp->translation.vip, &vip);
+  if (rv)
+    goto done;
 
   flags = mp->translation.flags;
   if (!mp->translation.is_real_ip)
@@ -136,7 +158,7 @@ cnat_translation_send_details (u32 cti, void *args)
   vl_api_cnat_endpoint_tuple_t *path;
   size_t msg_size;
   cnat_translation_t *ct;
-  u8 n_paths;
+  u32 n_paths;
 
   ctx = args;
   ct = cnat_translation_get (cti);
@@ -148,8 +170,8 @@ cnat_translation_send_details (u32 cti, void *args)
 
   /* fill in the message */
   mp->context = ctx->context;
-  mp->translation.n_paths = n_paths;
-  mp->translation.id = htonl (cti);
+  mp->translation.n_paths = clib_host_to_net_u32 (n_paths);
+  mp->translation.id = clib_host_to_net_u32 (cti);
   cnat_endpoint_encode (&ct->ct_vip, &mp->translation.vip);
   mp->translation.ip_proto = ip_proto_encode (ct->ct_proto);
 
@@ -206,6 +228,8 @@ cnat_session_send_details (const cnat_session_t * session, void *args)
   /* fill in the message */
   mp->context = ctx->context;
 
+  ep.ce_sw_if_index = INDEX_INVALID;
+  ep.ce_flags = CNAT_EP_FLAG_RESOLVED;
   ip_address2_from_46 (&session->value.cs_ip[VLIB_TX], session->key.cs_af,
                       &ep.ce_ip);
   ep.ce_port = clib_host_to_net_u16 (session->value.cs_port[VLIB_TX]);
@@ -258,17 +282,37 @@ vl_api_cnat_session_purge_t_handler (vl_api_cnat_session_purge_t * mp)
   REPLY_MACRO (VL_API_CNAT_SESSION_PURGE_REPLY);
 }
 
+static void
+vl_api_cnat_get_snat_addresses_t_handler (vl_api_cnat_get_snat_addresses_t
+                                         * mp)
+{
+  vl_api_cnat_get_snat_addresses_reply_t *rmp;
+  int rv = 0;
+
+  /* *INDENT-OFF* */
+  REPLY_MACRO2 (VL_API_CNAT_GET_SNAT_ADDRESSES_REPLY,
+  ({
+    ip6_address_encode (&ip_addr_v6(&cnat_main.snat_ip6.ce_ip), rmp->snat_ip6);
+    ip4_address_encode (&ip_addr_v4(&cnat_main.snat_ip4.ce_ip), rmp->snat_ip4);
+    rmp->sw_if_index = clib_host_to_net_u32 (cnat_main.snat_ip6.ce_sw_if_index);
+  }));
+  /* *INDENT-ON* */
+}
+
 static void
 vl_api_cnat_set_snat_addresses_t_handler (vl_api_cnat_set_snat_addresses_t
                                          * mp)
 {
   vl_api_cnat_set_snat_addresses_reply_t *rmp;
+  u32 sw_if_index = clib_net_to_host_u32 (mp->sw_if_index);
+  ip4_address_t ip4;
+  ip6_address_t ip6;
   int rv = 0;
 
-  cnat_lazy_init ();
+  ip4_address_decode (mp->snat_ip4, &ip4);
+  ip6_address_decode (mp->snat_ip6, &ip6);
 
-  ip4_address_decode (mp->snat_ip4, &cnat_main.snat_ip4);
-  ip6_address_decode (mp->snat_ip6, &cnat_main.snat_ip6);
+  cnat_set_snat (&ip4, &ip6, sw_if_index);
 
   REPLY_MACRO (VL_API_CNAT_SET_SNAT_ADDRESSES_REPLY);
 }