vcl: add api to set lcl ip

Type: feature

Change-Id: I40169fbbe8a20670dd612c341b6c78b5c925bf74
Signed-off-by: Florin Coras <fcoras@cisco.com>
diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c
index 72ec4f4..10cf17a 100644
--- a/src/vcl/vppcom.c
+++ b/src/vcl/vppcom.c
@@ -235,6 +235,7 @@
   mp->is_ip4 = s->transport.is_ip4;
   mp->parent_handle = s->parent_handle;
   clib_memcpy_fast (&mp->ip, &s->transport.rmt_ip, sizeof (mp->ip));
+  clib_memcpy_fast (&mp->lcl_ip, &s->transport.lcl_ip, sizeof (mp->lcl_ip));
   mp->port = s->transport.rmt_port;
   mp->proto = s->session_type;
   app_send_ctrl_evt_to_vpp (mq, app_evt);
@@ -1537,6 +1538,25 @@
   return vcl_session_handle (client_session);
 }
 
+static void
+vcl_ip_copy_from_ep (ip46_address_t * ip, vppcom_endpt_t * ep)
+{
+  if (ep->is_ip4)
+    clib_memcpy_fast (&ip->ip4, ep->ip, sizeof (ip4_address_t));
+  else
+    clib_memcpy_fast (&ip->ip6, ep->ip, sizeof (ip6_address_t));
+}
+
+void
+vcl_ip_copy_to_ep (ip46_address_t * ip, vppcom_endpt_t * ep, u8 is_ip4)
+{
+  ep->is_ip4 = is_ip4;
+  if (is_ip4)
+    clib_memcpy_fast (ep->ip, &ip->ip4, sizeof (ip4_address_t));
+  else
+    clib_memcpy_fast (ep->ip, &ip->ip6, sizeof (ip6_address_t));
+}
+
 int
 vppcom_session_connect (uint32_t session_handle, vppcom_endpt_t * server_ep)
 {
@@ -1572,12 +1592,7 @@
     }
 
   session->transport.is_ip4 = server_ep->is_ip4;
-  if (session->transport.is_ip4)
-    clib_memcpy_fast (&session->transport.rmt_ip.ip4, server_ep->ip,
-		      sizeof (ip4_address_t));
-  else
-    clib_memcpy_fast (&session->transport.rmt_ip.ip6, server_ep->ip,
-		      sizeof (ip6_address_t));
+  vcl_ip_copy_from_ep (&session->transport.rmt_ip, server_ep);
   session->transport.rmt_port = server_ep->port;
   session->parent_handle = VCL_INVALID_SESSION_HANDLE;
 
@@ -2928,6 +2943,24 @@
 	rv = VPPCOM_EINVAL;
       break;
 
+    case VPPCOM_ATTR_SET_LCL_ADDR:
+      if (PREDICT_TRUE (buffer && buflen &&
+			(*buflen >= sizeof (*ep)) && ep->ip))
+	{
+	  session->transport.is_ip4 = ep->is_ip4;
+	  session->transport.lcl_port = ep->port;
+	  vcl_ip_copy_from_ep (&session->transport.lcl_ip, ep);
+	  *buflen = sizeof (*ep);
+	  VDBG (1, "VPPCOM_ATTR_SET_LCL_ADDR: sh %u, is_ip4 = %u, addr = %U"
+		" port %d", session_handle, ep->is_ip4, format_ip46_address,
+		&session->transport.lcl_ip,
+		ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
+		clib_net_to_host_u16 (ep->port));
+	}
+      else
+	rv = VPPCOM_EINVAL;
+      break;
+
     case VPPCOM_ATTR_GET_LIBC_EPFD:
       rv = session->libc_epfd;
       VDBG (2, "VPPCOM_ATTR_GET_LIBC_EPFD: libc_epfd %d", rv);
diff --git a/src/vcl/vppcom.h b/src/vcl/vppcom.h
index 6281509..6261303 100644
--- a/src/vcl/vppcom.h
+++ b/src/vcl/vppcom.h
@@ -137,6 +137,7 @@
   VPPCOM_ATTR_GET_FLAGS,
   VPPCOM_ATTR_SET_FLAGS,
   VPPCOM_ATTR_GET_LCL_ADDR,
+  VPPCOM_ATTR_SET_LCL_ADDR,
   VPPCOM_ATTR_GET_PEER_ADDR,
   VPPCOM_ATTR_GET_LIBC_EPFD,
   VPPCOM_ATTR_SET_LIBC_EPFD,
diff --git a/src/vnet/session/application_interface.h b/src/vnet/session/application_interface.h
index d907287..609a20a 100644
--- a/src/vnet/session/application_interface.h
+++ b/src/vnet/session/application_interface.h
@@ -371,6 +371,7 @@
   u8 proto;
   u8 is_ip4;
   ip46_address_t ip;
+  ip46_address_t lcl_ip;
   u8 hostname_len;
   u8 hostname[16];
   u64 parent_handle;
diff --git a/src/vnet/session/session_node.c b/src/vnet/session/session_node.c
index c15d2be..4f0251b 100644
--- a/src/vnet/session/session_node.c
+++ b/src/vnet/session/session_node.c
@@ -111,6 +111,7 @@
   a->sep.port = mp->port;
   a->sep.transport_proto = mp->proto;
   a->sep.peer.fib_index = mp->vrf;
+  clib_memcpy_fast (&a->sep.peer.ip, &mp->lcl_ip, sizeof (mp->lcl_ip));
   a->sep.peer.sw_if_index = ENDPOINT_INVALID_INDEX;
   a->sep_ext.parent_handle = mp->parent_handle;
   a->sep_ext.ckpair_index = mp->ckpair_index;
diff --git a/src/vnet/session/session_types.h b/src/vnet/session/session_types.h
index c2bb4dd..2b56584 100644
--- a/src/vnet/session/session_types.h
+++ b/src/vnet/session/session_types.h
@@ -21,7 +21,7 @@
 
 #define SESSION_INVALID_INDEX ((u32)~0)
 #define SESSION_INVALID_HANDLE ((u64)~0)
-#define SESSION_CTRL_MSG_MAX_SIZE 68
+#define SESSION_CTRL_MSG_MAX_SIZE 84
 
 #define foreach_session_endpoint_fields				\
   foreach_transport_endpoint_cfg_fields				\