Fix VPP-1487 DHCP client does not support option 6-domain server

Change-Id: I36ad1ef2a53af3d3f3a6348bc189b17e9e4e21bd
Signed-off-by: jackiechen1985 <xiaobo.chen@tieto.com>
diff --git a/src/vat/api_format.c b/src/vat/api_format.c
index d2c125d..fb0f3fd 100644
--- a/src/vat/api_format.c
+++ b/src/vat/api_format.c
@@ -2697,13 +2697,22 @@
 static void
 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
 {
-  errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
-	  "router_addr %U host_mac %U",
-	  ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
-	  mp->lease.hostname,
-	  format_ip4_address, &mp->lease.host_address,
-	  format_ip4_address, &mp->lease.router_address,
-	  format_ethernet_address, mp->lease.host_mac);
+  u8 *s, i;
+
+  s = format (s, "DHCP compl event: pid %d %s hostname %s host_addr %U "
+	      "host_mac %U router_addr %U",
+	      ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
+	      mp->lease.hostname,
+	      format_ip4_address, mp->lease.host_address,
+	      format_ethernet_address, mp->lease.host_mac,
+	      format_ip4_address, mp->lease.router_address);
+
+  for (i = 0; i < mp->lease.count; i++)
+    s =
+      format (s, " domain_server_addr %U", format_ip4_address,
+	      mp->lease.domain_server[i].address);
+
+  errmsg ((char *) s);
 }
 
 static void vl_api_dhcp_compl_event_t_handler_json
diff --git a/src/vnet/dhcp/client.c b/src/vnet/dhcp/client.c
index aac3ad3..1d53521 100644
--- a/src/vnet/dhcp/client.c
+++ b/src/vnet/dhcp/client.c
@@ -248,7 +248,14 @@
 	    c->router_address.as_u32 = router_address;
 	  }
 	  break;
-
+	case 6:		/* domain server address */
+	  {
+	    vec_free (c->domain_server_address);
+	    vec_validate (c->domain_server_address,
+			  o->length / sizeof (ip4_address_t) - 1);
+	    clib_memcpy (c->domain_server_address, o->data, o->length);
+	  }
+	  break;
 	case 12:		/* hostname */
 	  {
 	    /* Replace the existing hostname if necessary */
@@ -315,6 +322,7 @@
 	  c->router_address.as_u32 = 0;
 	  c->lease_renewal_interval = 0;
 	  c->dhcp_server.as_u32 = 0;
+	  vec_free (c->domain_server_address);
 	  break;
 	}
 
@@ -814,17 +822,26 @@
   dhcp_client_main_t *dcm = va_arg (*va, dhcp_client_main_t *);
   dhcp_client_t *c = va_arg (*va, dhcp_client_t *);
   int verbose = va_arg (*va, int);
+  ip4_address_t *addr;
 
   s = format (s, "[%d] %U state %U ", c - dcm->clients,
 	      format_vnet_sw_if_index_name, dcm->vnet_main, c->sw_if_index,
 	      format_dhcp_client_state, c->state);
 
   if (c->leased_address.as_u32)
-    s = format (s, "addr %U/%d gw %U\n",
-		format_ip4_address, &c->leased_address,
-		c->subnet_mask_width, format_ip4_address, &c->router_address);
+    {
+      s = format (s, "addr %U/%d gw %U\n",
+		  format_ip4_address, &c->leased_address,
+		  c->subnet_mask_width, format_ip4_address,
+		  &c->router_address);
+
+      vec_foreach (addr, c->domain_server_address)
+	s = format (s, "dns %U ", format_ip4_address, addr);
+    }
   else
-    s = format (s, "no address\n");
+    {
+      s = format (s, "no address\n");
+    }
 
   if (verbose)
     {
@@ -962,6 +979,7 @@
 	}
       dhcp_client_release_address (dcm, c);
 
+      vec_free (c->domain_server_address);
       vec_free (c->option_55_data);
       vec_free (c->hostname);
       vec_free (c->client_identifier);
diff --git a/src/vnet/dhcp/client.h b/src/vnet/dhcp/client.h
index 72cbf66..2b5341d 100644
--- a/src/vnet/dhcp/client.h
+++ b/src/vnet/dhcp/client.h
@@ -64,6 +64,7 @@
   ip4_address_t dhcp_server;
   u32 subnet_mask_width;	/* option 1 */
   ip4_address_t router_address;	/* option 3 */
+  ip4_address_t *domain_server_address;	/* option 6 */
   u32 lease_renewal_interval;	/* option 51 */
   u32 lease_lifetime;		/* option 59 */
 
diff --git a/src/vnet/dhcp/dhcp.api b/src/vnet/dhcp/dhcp.api
index ac1e685..033c7a3 100644
--- a/src/vnet/dhcp/dhcp.api
+++ b/src/vnet/dhcp/dhcp.api
@@ -96,6 +96,14 @@
   vl_api_dhcp_client_t client;
 };
 
+/** \brief Struct representing domain server
+    @param address - IP address
+*/
+typeonly manual_print manual_endian define domain_server
+{
+  u8 address[16];
+};
+
 /** \brief Data learned by the client during the DHCP process
     @param sw_if_index - the interface on which the client is configured
     @param state - the state of the lease (see dhcp_client_state_t)
@@ -115,6 +123,8 @@
   u8 host_address[16];
   u8 router_address[16];
   u8 host_mac[6];
+  u8 count;
+  vl_api_domain_server_t domain_server[count];
 };
 
 /** \brief Tell client about a DHCP completion event
diff --git a/src/vnet/dhcp/dhcp_api.c b/src/vnet/dhcp/dhcp_api.c
index c96c3e1..d71ffe9 100644
--- a/src/vnet/dhcp/dhcp_api.c
+++ b/src/vnet/dhcp/dhcp_api.c
@@ -218,6 +218,7 @@
 			  const dhcp_client_t * client)
 {
   size_t len;
+  u8 i;
 
   lease->is_ipv6 = 0;		// only support IPv6 clients
   lease->sw_if_index = ntohl (client->sw_if_index);
@@ -227,8 +228,16 @@
   lease->hostname[len] = 0;
 
   lease->mask_width = client->subnet_mask_width;
-  clib_memcpy (&lease->host_address[0], (u8 *) & client->leased_address, 4);
-  clib_memcpy (&lease->router_address[0], (u8 *) & client->router_address, 4);
+  clib_memcpy (&lease->host_address[0], (u8 *) & client->leased_address,
+	       sizeof (ip4_address_t));
+  clib_memcpy (&lease->router_address[0], (u8 *) & client->router_address,
+	       sizeof (ip4_address_t));
+
+  lease->count = vec_len (client->domain_server_address);
+  for (i = 0; i < lease->count; i++)
+    clib_memcpy (&lease->domain_server[i].address,
+		 (u8 *) & client->domain_server_address[i],
+		 sizeof (ip4_address_t));
 
   if (NULL != client->l2_rewrite)
     clib_memcpy (&lease->host_mac[0], client->l2_rewrite + 6, 6);