/*
 * Copyright (c) 2015 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <vlib/vlib.h>
#include <vnet/dhcp/client.h>
#include <vnet/dhcp/dhcp_proxy.h>
#include <vnet/fib/fib_table.h>

dhcp_client_main_t dhcp_client_main;
static u8 *format_dhcp_client_state (u8 * s, va_list * va);
static vlib_node_registration_t dhcp_client_process_node;

#define foreach_dhcp_client_process_stat        \
_(DISCOVER, "DHCP discover packets sent")       \
_(OFFER, "DHCP offer packets sent")             \
_(REQUEST, "DHCP request packets sent")         \
_(ACK, "DHCP ack packets sent")

typedef enum
{
#define _(sym,str) DHCP_STAT_##sym,
  foreach_dhcp_client_process_stat
#undef _
    DHCP_STAT_UNKNOWN,
  DHCP_STAT_N_STAT,
} sample_error_t;

static char *dhcp_client_process_stat_strings[] = {
#define _(sym,string) string,
  foreach_dhcp_client_process_stat
#undef _
    "DHCP unknown packets sent",
};


static void
dhcp_client_acquire_address (dhcp_client_main_t * dcm, dhcp_client_t * c)
{
  /*
   * Install any/all info gleaned from dhcp, right here
   */
  ip4_add_del_interface_address (dcm->vlib_main, c->sw_if_index,
				 (void *) &c->leased_address,
				 c->subnet_mask_width, 0 /*is_del */ );
}

static void
dhcp_client_release_address (dhcp_client_main_t * dcm, dhcp_client_t * c)
{
  /*
   * Remove any/all info gleaned from dhcp, right here. Caller(s)
   * have not wiped out the info yet.
   */

  ip4_add_del_interface_address (dcm->vlib_main, c->sw_if_index,
				 (void *) &c->leased_address,
				 c->subnet_mask_width, 1 /*is_del */ );
}

static void
set_l2_rewrite (dhcp_client_main_t * dcm, dhcp_client_t * c)
{
  /* Acquire the L2 rewrite string for the indicated sw_if_index */
  c->l2_rewrite = vnet_build_rewrite_for_sw_interface (dcm->vnet_main,
						       c->sw_if_index,
						       VNET_LINK_IP4,
						       0 /* broadcast */ );
}

void vl_api_rpc_call_main_thread (void *fp, u8 * data, u32 data_length);

static void
dhcp_client_proc_callback (uword * client_index)
{
  vlib_main_t *vm = vlib_get_main ();
  ASSERT (vlib_get_thread_index () == 0);
  vlib_process_signal_event (vm, dhcp_client_process_node.index,
			     EVENT_DHCP_CLIENT_WAKEUP, *client_index);
}

static void
dhcp_client_addr_callback (dhcp_client_t * c)
{
  dhcp_client_main_t *dcm = &dhcp_client_main;
  void (*fp) (u32, u32, u8 *, u8, u8, u8 *, u8 *, u8 *) = c->event_callback;

  /* add the advertised subnet and disable the feature */
  dhcp_client_acquire_address (dcm, c);
  vnet_feature_enable_disable ("ip4-unicast",
			       "ip4-dhcp-client-detect",
			       c->sw_if_index, 0, 0, 0);

  /*
   * Configure default IP route:
   */
  if (c->router_address.as_u32)
    {
      fib_prefix_t all_0s = {
	.fp_len = 0,
	.fp_addr.ip4.as_u32 = 0x0,
	.fp_proto = FIB_PROTOCOL_IP4,
      };
      ip46_address_t nh = {
	.ip4 = c->router_address,
      };

      /* *INDENT-OFF* */
      fib_table_entry_path_add (
	fib_table_get_index_for_sw_if_index (
	  FIB_PROTOCOL_IP4,
	  c->sw_if_index),
	  &all_0s,
	  FIB_SOURCE_DHCP,
	  FIB_ENTRY_FLAG_NONE,
          DPO_PROTO_IP4,
          &nh, c->sw_if_index,
          ~0, 1, NULL,	// no label stack
          FIB_ROUTE_PATH_FLAG_NONE);
      /* *INDENT-ON* */
    }

  /*
   * Call the user's event callback to report DHCP information
   */
  if (fp)
    (*fp) (c->client_index,	/* clinet index */
	   c->pid, c->hostname, c->subnet_mask_width, 0,	/* is_ipv6 */
	   (u8 *) & c->leased_address,	/* host IP address */
	   (u8 *) & c->router_address,	/* router IP address */
	   (u8 *) (c->l2_rewrite + 6));	/* host MAC address */
}

/*
 * dhcp_client_for_us - server-to-client callback.
 * Called from proxy_node.c:dhcp_proxy_to_client_input().
 * This function first decides that the packet in question is
 * actually for the dhcp client code in case we're also acting as
 * a dhcp proxy. Ay caramba, what a folly!
 */
int
dhcp_client_for_us (u32 bi, vlib_buffer_t * b,
		    ip4_header_t * ip,
		    udp_header_t * udp, dhcp_header_t * dhcp)
{
  dhcp_client_main_t *dcm = &dhcp_client_main;
  vlib_main_t *vm = dcm->vlib_main;
  dhcp_client_t *c;
  uword *p;
  f64 now = vlib_time_now (dcm->vlib_main);
  u8 dhcp_message_type = 0;
  dhcp_option_t *o;

  /*
   * Doing dhcp client on this interface?
   * Presumably we will always receive dhcp clnt for-us pkts on
   * the interface that's asking for an address.
   */
  p = hash_get (dcm->client_by_sw_if_index,
		vnet_buffer (b)->sw_if_index[VLIB_RX]);
  if (p == 0)
    return 0;			/* no */

  c = pool_elt_at_index (dcm->clients, p[0]);

  /* Mixing dhcp relay and dhcp proxy? DGMS... */
  if (c->state == DHCP_BOUND && c->retry_count == 0)
    return 0;

  /* parse through the packet, learn what we can */
  if (dhcp->your_ip_address.as_u32)
    c->leased_address.as_u32 = dhcp->your_ip_address.as_u32;

  c->dhcp_server.as_u32 = dhcp->server_ip_address.as_u32;

  o = (dhcp_option_t *) dhcp->options;

  while (o->option != 0xFF /* end of options */  &&
	 (u8 *) o < (b->data + b->current_data + b->current_length))
    {
      switch (o->option)
	{
	case 53:		/* dhcp message type */
	  dhcp_message_type = o->data[0];
	  break;

	case 51:		/* lease time */
	  {
	    u32 lease_time_in_seconds =
	      clib_host_to_net_u32 (o->data_as_u32[0]);
	    c->lease_expires = now + (f64) lease_time_in_seconds;
	    c->lease_lifetime = lease_time_in_seconds;
	    /* Set a sensible default, in case we don't get opt 58 */
	    c->lease_renewal_interval = lease_time_in_seconds / 2;
	  }
	  break;

	case 58:		/* lease renew time in seconds */
	  {
	    u32 lease_renew_time_in_seconds =
	      clib_host_to_net_u32 (o->data_as_u32[0]);
	    c->lease_renewal_interval = lease_renew_time_in_seconds;
	  }
	  break;

	case 54:		/* dhcp server address */
	  c->dhcp_server.as_u32 = o->data_as_u32[0];
	  break;

	case 1:		/* subnet mask */
	  {
	    u32 subnet_mask = clib_host_to_net_u32 (o->data_as_u32[0]);
	    c->subnet_mask_width = count_set_bits (subnet_mask);
	  }
	  break;
	case 3:		/* router address */
	  {
	    u32 router_address = o->data_as_u32[0];
	    c->router_address.as_u32 = router_address;
	  }
	  break;

	case 12:		/* hostname */
	  {
	    /* Replace the existing hostname if necessary */
	    vec_free (c->hostname);
	    vec_validate (c->hostname, o->length - 1);
	    clib_memcpy (c->hostname, o->data, o->length);
	  }
	  break;

	  /* $$$$ Your message in this space, parse more options */
	default:
	  break;
	}

      o = (dhcp_option_t *) (((uword) o) + (o->length + 2));
    }

  switch (c->state)
    {
    case DHCP_DISCOVER:
      if (dhcp_message_type != DHCP_PACKET_OFFER)
	{
	  clib_warning ("sw_if_index %d state %U message type %d",
			c->sw_if_index, format_dhcp_client_state,
			c->state, dhcp_message_type);
	  c->next_transmit = now + 5.0;
	  break;
	}

      /* Received an offer, go send a request */
      c->state = DHCP_REQUEST;
      c->retry_count = 0;
      c->next_transmit = 0;	/* send right now... */
      /* Poke the client process, which will send the request */
      uword client_id = c - dcm->clients;
      vl_api_rpc_call_main_thread (dhcp_client_proc_callback,
				   (u8 *) & client_id, sizeof (uword));
      break;

    case DHCP_BOUND:
    case DHCP_REQUEST:
      if (dhcp_message_type != DHCP_PACKET_ACK)
	{
	  clib_warning ("sw_if_index %d state %U message type %d",
			c->sw_if_index, format_dhcp_client_state,
			c->state, dhcp_message_type);
	  c->next_transmit = now + 5.0;
	  break;
	}
      /* OK, we own the address (etc), add to the routing table(s) */
      if (c->state == DHCP_REQUEST)
	vl_api_rpc_call_main_thread (dhcp_client_addr_callback,
				     (u8 *) c, sizeof (*c));

      c->state = DHCP_BOUND;
      c->retry_count = 0;
      c->next_transmit = now + (f64) c->lease_renewal_interval;
      c->lease_expires = now + (f64) c->lease_lifetime;
      break;

    default:
      clib_warning ("client %d bogus state %d", c - dcm->clients, c->state);
      break;
    }

  /* drop the pkt, return 1 */
  vlib_buffer_free (vm, &bi, 1);
  return 1;
}

static void
send_dhcp_pkt (dhcp_client_main_t * dcm, dhcp_client_t * c,
	       dhcp_packet_type_t type, int is_broadcast)
{
  vlib_main_t *vm = dcm->vlib_main;
  vnet_main_t *vnm = dcm->vnet_main;
  vnet_hw_interface_t *hw = vnet_get_sup_hw_interface (vnm, c->sw_if_index);
  vnet_sw_interface_t *sup_sw
    = vnet_get_sup_sw_interface (vnm, c->sw_if_index);
  vnet_sw_interface_t *sw = vnet_get_sw_interface (vnm, c->sw_if_index);
  vlib_buffer_t *b;
  u32 bi;
  ip4_header_t *ip;
  udp_header_t *udp;
  dhcp_header_t *dhcp;
  u32 *to_next;
  vlib_frame_t *f;
  dhcp_option_t *o;
  u16 udp_length, ip_length;
  u32 counter_index;

  /* Interface(s) down? */
  if ((hw->flags & VNET_HW_INTERFACE_FLAG_LINK_UP) == 0)
    return;
  if ((sup_sw->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) == 0)
    return;
  if ((sw->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) == 0)
    return;

  if (vlib_buffer_alloc (vm, &bi, 1) != 1)
    {
      clib_warning ("buffer allocation failure");
      c->next_transmit = 0;
      return;
    }

  /* Build a dhcpv4 pkt from whole cloth */
  b = vlib_get_buffer (vm, bi);

  ASSERT (b->current_data == 0);

  vnet_buffer (b)->sw_if_index[VLIB_RX] = c->sw_if_index;
  if (is_broadcast)
    {
      f = vlib_get_frame_to_node (vm, hw->output_node_index);
      vnet_buffer (b)->sw_if_index[VLIB_TX] = c->sw_if_index;
      clib_memcpy (b->data, c->l2_rewrite, vec_len (c->l2_rewrite));
      ip = (void *)
	(((u8 *) vlib_buffer_get_current (b)) + vec_len (c->l2_rewrite));
    }
  else
    {
      f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
      vnet_buffer (b)->sw_if_index[VLIB_TX] = ~0;	/* use interface VRF */
      ip = vlib_buffer_get_current (b);
    }

  /* Enqueue the packet right now */
  to_next = vlib_frame_vector_args (f);
  to_next[0] = bi;
  f->n_vectors = 1;

  if (is_broadcast)
    vlib_put_frame_to_node (vm, hw->output_node_index, f);
  else
    vlib_put_frame_to_node (vm, ip4_lookup_node.index, f);

  udp = (udp_header_t *) (ip + 1);
  dhcp = (dhcp_header_t *) (udp + 1);

  /* $$$ optimize, maybe */
  memset (ip, 0, sizeof (*ip) + sizeof (*udp) + sizeof (*dhcp));

  ip->ip_version_and_header_length = 0x45;
  ip->ttl = 128;
  ip->protocol = IP_PROTOCOL_UDP;

  if (is_broadcast)
    {
      /* src = 0.0.0.0, dst = 255.255.255.255 */
      ip->dst_address.as_u32 = ~0;
    }
  else
    {
      /* Renewing an active lease, plain old ip4 src/dst */
      ip->src_address.as_u32 = c->leased_address.as_u32;
      ip->dst_address.as_u32 = c->dhcp_server.as_u32;
    }

  udp->src_port = clib_host_to_net_u16 (UDP_DST_PORT_dhcp_to_client);
  udp->dst_port = clib_host_to_net_u16 (UDP_DST_PORT_dhcp_to_server);

  /* Send the interface MAC address */
  clib_memcpy (dhcp->client_hardware_address, c->l2_rewrite + 6, 6);

  /* Lease renewal, set up client_ip_address */
  if (is_broadcast == 0)
    dhcp->client_ip_address.as_u32 = c->leased_address.as_u32;

  dhcp->opcode = 1;		/* request, all we send */
  dhcp->hardware_type = 1;	/* ethernet */
  dhcp->hardware_address_length = 6;
  dhcp->transaction_identifier = c->transaction_id;
  dhcp->flags =
    clib_host_to_net_u16 (is_broadcast && c->set_broadcast_flag ?
			  DHCP_FLAG_BROADCAST : 0);
  dhcp->magic_cookie.as_u32 = DHCP_MAGIC;

  o = (dhcp_option_t *) dhcp->options;

  /* Send option 53, the DHCP message type */
  o->option = DHCP_PACKET_OPTION_MSG_TYPE;
  o->length = 1;
  o->data[0] = type;
  o = (dhcp_option_t *) (((uword) o) + (o->length + 2));

  /* Send option 57, max msg length */
  if (0 /* not needed, apparently */ )
    {
      o->option = 57;
      o->length = 2;
      {
	u16 *o2 = (u16 *) o->data;
	*o2 = clib_host_to_net_u16 (1152);
	o = (dhcp_option_t *) (((uword) o) + (o->length + 2));
      }
    }

  /*
   * If server ip address is available with non-zero value,
   * option 54 (DHCP Server Identifier) is sent.
   */
  if (c->dhcp_server.as_u32)
    {
      o->option = 54;
      o->length = 4;
      clib_memcpy (o->data, &c->dhcp_server.as_u32, 4);
      o = (dhcp_option_t *) (((uword) o) + (o->length + 2));
    }

  /* send option 50, requested IP address */
  if (c->leased_address.as_u32)
    {
      o->option = 50;
      o->length = 4;
      clib_memcpy (o->data, &c->leased_address.as_u32, 4);
      o = (dhcp_option_t *) (((uword) o) + (o->length + 2));
    }

  /* send option 12, host name */
  if (vec_len (c->hostname))
    {
      o->option = 12;
      o->length = vec_len (c->hostname);
      clib_memcpy (o->data, c->hostname, vec_len (c->hostname));
      o = (dhcp_option_t *) (((uword) o) + (o->length + 2));
    }

  /* send option 61, client_id */
  if (vec_len (c->client_identifier))
    {
      o->option = 61;
      o->length = vec_len (c->client_identifier);
      clib_memcpy (o->data, c->client_identifier,
		   vec_len (c->client_identifier));
      o = (dhcp_option_t *) (((uword) o) + (o->length + 2));
    }

  /* $$ maybe send the client s/w version if anyone cares */

  /*
   * send option 55, parameter request list
   * The current list - see below, matches the Linux dhcp client's list
   * Any specific dhcp server config and/or dhcp server may or may
   * not yield specific options.
   */
  o->option = 55;
  o->length = vec_len (c->option_55_data);
  clib_memcpy (o->data, c->option_55_data, vec_len (c->option_55_data));
  o = (dhcp_option_t *) (((uword) o) + (o->length + 2));

  /* End of list */
  o->option = 0xff;
  o->length = 0;
  o++;

  b->current_length = ((u8 *) o) - b->data;

  /* fix ip length, checksum and udp length */
  ip_length = vlib_buffer_length_in_chain (vm, b);
  if (is_broadcast)
    ip_length -= vec_len (c->l2_rewrite);

  ip->length = clib_host_to_net_u16 (ip_length);
  ip->checksum = ip4_header_checksum (ip);

  udp_length = ip_length - (sizeof (*ip));
  udp->length = clib_host_to_net_u16 (udp_length);

  switch (type)
    {
#define _(a,b) case DHCP_PACKET_##a: {counter_index = DHCP_STAT_##a; break;}
      foreach_dhcp_client_process_stat
#undef _
    default:
      counter_index = DHCP_STAT_UNKNOWN;
      break;
    }

  vlib_node_increment_counter (vm, dhcp_client_process_node.index,
			       counter_index, 1);
}

static int
dhcp_discover_state (dhcp_client_main_t * dcm, dhcp_client_t * c, f64 now)
{
  /*
   * State machine "DISCOVER" state. Send a dhcp discover packet,
   * eventually back off the retry rate.
   */
  send_dhcp_pkt (dcm, c, DHCP_PACKET_DISCOVER, 1 /* is_broadcast */ );

  c->retry_count++;
  if (c->retry_count > 10)
    c->next_transmit = now + 5.0;
  else
    c->next_transmit = now + 1.0;
  return 0;
}

static int
dhcp_request_state (dhcp_client_main_t * dcm, dhcp_client_t * c, f64 now)
{
  /*
   * State machine "REQUEST" state. Send a dhcp request packet,
   * eventually drop back to the discover state.
   */
  send_dhcp_pkt (dcm, c, DHCP_PACKET_REQUEST, 1 /* is_broadcast */ );

  c->retry_count++;
  if (c->retry_count > 7 /* lucky you */ )
    {
      c->state = DHCP_DISCOVER;
      c->next_transmit = now;
      c->retry_count = 0;
      return 1;
    }
  c->next_transmit = now + 1.0;
  return 0;
}

static int
dhcp_bound_state (dhcp_client_main_t * dcm, dhcp_client_t * c, f64 now)
{
  /*
   * State machine "BOUND" state. Send a dhcp request packet,
   * eventually, when the lease expires, forget the dhcp data
   * and go back to the stone age.
   */
  send_dhcp_pkt (dcm, c, DHCP_PACKET_REQUEST, 0 /* is_broadcast */ );

  c->retry_count++;
  if (c->retry_count > 10)
    c->next_transmit = now + 5.0;
  else
    c->next_transmit = now + 1.0;

  if (now > c->lease_expires)
    {
      /* Remove the default route */
      if (c->router_address.as_u32)
	{
	  fib_prefix_t all_0s = {
	    .fp_len = 0,
	    .fp_addr.ip4.as_u32 = 0x0,
	    .fp_proto = FIB_PROTOCOL_IP4,
	  };
	  ip46_address_t nh = {
	    .ip4 = c->router_address,
	  };

	  fib_table_entry_path_remove (fib_table_get_index_for_sw_if_index
				       (FIB_PROTOCOL_IP4, c->sw_if_index),
				       &all_0s, FIB_SOURCE_DHCP,
				       DPO_PROTO_IP4, &nh, c->sw_if_index, ~0,
				       1, FIB_ROUTE_PATH_FLAG_NONE);
	}
      /* Remove the interface address */
      dhcp_client_release_address (dcm, c);
      c->state = DHCP_DISCOVER;
      c->next_transmit = now;
      c->retry_count = 0;
      /* Wipe out any memory of the address we had... */
      c->leased_address.as_u32 = 0;
      c->subnet_mask_width = 0;
      c->router_address.as_u32 = 0;
      c->lease_renewal_interval = 0;
      c->dhcp_server.as_u32 = 0;
      /*
       * We disable the client detect feature when we bind a
       * DHCP address. Turn it back on again here.
       * Otherwise, if the DHCP server replies after an outage,
       * we'll never see it.
       */
      vnet_feature_enable_disable ("ip4-unicast",
				   "ip4-dhcp-client-detect",
				   c->sw_if_index, 1, 0, 0);
      return 1;
    }
  return 0;
}

static f64
dhcp_client_sm (f64 now, f64 timeout, uword pool_index)
{
  dhcp_client_main_t *dcm = &dhcp_client_main;
  dhcp_client_t *c;

  /* deleted, pooched, yadda yadda yadda */
  if (pool_is_free_index (dcm->clients, pool_index))
    return timeout;

  c = pool_elt_at_index (dcm->clients, pool_index);

  /* Time for us to do something with this client? */
  if (now < c->next_transmit)
    return timeout;

again:
  switch (c->state)
    {
    case DHCP_DISCOVER:	/* send a discover */
      if (dhcp_discover_state (dcm, c, now))
	goto again;
      break;

    case DHCP_REQUEST:		/* send a request */
      if (dhcp_request_state (dcm, c, now))
	goto again;
      break;

    case DHCP_BOUND:		/* bound, renew needed? */
      if (dhcp_bound_state (dcm, c, now))
	goto again;
      break;

    default:
      clib_warning ("dhcp client %d bogus state %d",
		    c - dcm->clients, c->state);
      break;
    }

  if (c->next_transmit < now + timeout)
    return c->next_transmit - now;

  return timeout;
}

static uword
dhcp_client_process (vlib_main_t * vm,
		     vlib_node_runtime_t * rt, vlib_frame_t * f)
{
  f64 timeout = 100.0;
  f64 now;
  uword event_type;
  uword *event_data = 0;
  dhcp_client_main_t *dcm = &dhcp_client_main;
  dhcp_client_t *c;
  int i;

  while (1)
    {
      vlib_process_wait_for_event_or_clock (vm, timeout);

      event_type = vlib_process_get_events (vm, &event_data);

      now = vlib_time_now (vm);

      switch (event_type)
	{
	case EVENT_DHCP_CLIENT_WAKEUP:
	  for (i = 0; i < vec_len (event_data); i++)
	    timeout = dhcp_client_sm (now, timeout, event_data[i]);
	  break;

	case ~0:
          /* *INDENT-OFF* */
	  pool_foreach (c, dcm->clients,
          ({
            timeout = dhcp_client_sm (now, timeout,
                                      (uword) (c - dcm->clients));
          }));
          /* *INDENT-ON* */
	  if (pool_elts (dcm->clients) == 0)
	    timeout = 100.0;
	  break;
	}

      vec_reset_length (event_data);
    }

  /* NOTREACHED */
  return 0;
}

/* *INDENT-OFF* */
VLIB_REGISTER_NODE (dhcp_client_process_node,static) = {
    .function = dhcp_client_process,
    .type = VLIB_NODE_TYPE_PROCESS,
    .name = "dhcp-client-process",
    .process_log2_n_stack_bytes = 16,
    .n_errors = ARRAY_LEN(dhcp_client_process_stat_strings),
    .error_strings = dhcp_client_process_stat_strings,
};
/* *INDENT-ON* */

static u8 *
format_dhcp_client_state (u8 * s, va_list * va)
{
  dhcp_client_state_t state = va_arg (*va, dhcp_client_state_t);
  char *str = "BOGUS!";

  switch (state)
    {
#define _(a)                                    \
    case a:                                     \
      str = #a;                                 \
        break;
      foreach_dhcp_client_state;
#undef _
    default:
      break;
    }

  s = format (s, "%s", str);
  return s;
}

static u8 *
format_dhcp_client (u8 * s, va_list * va)
{
  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);

  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);
  else
    s = format (s, "no address\n");

  if (verbose)
    {
      s = format (s, "retry count %d, next xmt %.2f",
		  c->retry_count, c->next_transmit);
    }
  return s;
}

static clib_error_t *
show_dhcp_client_command_fn (vlib_main_t * vm,
			     unformat_input_t * input,
			     vlib_cli_command_t * cmd)
{
  dhcp_client_main_t *dcm = &dhcp_client_main;
  dhcp_client_t *c;
  int verbose = 0;
  u32 sw_if_index = ~0;
  uword *p;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "intfc %U",
		    unformat_vnet_sw_interface, dcm->vnet_main, &sw_if_index))
	;
      else if (unformat (input, "verbose"))
	verbose = 1;
      else
	break;
    }

  if (sw_if_index != ~0)
    {
      p = hash_get (dcm->client_by_sw_if_index, sw_if_index);
      if (p == 0)
	return clib_error_return (0, "dhcp client not configured");
      c = pool_elt_at_index (dcm->clients, p[0]);
      vlib_cli_output (vm, "%U", format_dhcp_client, dcm, c, verbose);
      return 0;
    }

  /* *INDENT-OFF* */
  pool_foreach (c, dcm->clients,
  ({
    vlib_cli_output (vm, "%U",
                     format_dhcp_client, dcm,
                     c, verbose);
  }));
  /* *INDENT-ON* */

  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_dhcp_client_command, static) = {
  .path = "show dhcp client",
  .short_help = "show dhcp client [intfc <intfc>][verbose]",
  .function = show_dhcp_client_command_fn,
};
/* *INDENT-ON* */


int
dhcp_client_add_del (dhcp_client_add_del_args_t * a)
{
  dhcp_client_main_t *dcm = &dhcp_client_main;
  vlib_main_t *vm = dcm->vlib_main;
  dhcp_client_t *c;
  uword *p;
  fib_prefix_t all_0s = {
    .fp_len = 0,
    .fp_addr.ip4.as_u32 = 0x0,
    .fp_proto = FIB_PROTOCOL_IP4,
  };

  p = hash_get (dcm->client_by_sw_if_index, a->sw_if_index);

  if ((p && a->is_add) || (!p && a->is_add == 0))
    return VNET_API_ERROR_INVALID_VALUE;

  if (a->is_add)
    {
      pool_get (dcm->clients, c);
      memset (c, 0, sizeof (*c));
      c->state = DHCP_DISCOVER;
      c->sw_if_index = a->sw_if_index;
      c->client_index = a->client_index;
      c->pid = a->pid;
      c->event_callback = a->event_callback;
      c->option_55_data = a->option_55_data;
      c->hostname = a->hostname;
      c->client_identifier = a->client_identifier;
      c->set_broadcast_flag = a->set_broadcast_flag;
      do
	{
	  c->transaction_id = random_u32 (&dcm->seed);
	}
      while (c->transaction_id == 0);
      set_l2_rewrite (dcm, c);
      hash_set (dcm->client_by_sw_if_index, a->sw_if_index, c - dcm->clients);

      /*
       * In order to accept any OFFER, whether broadcasted or unicasted, we
       * need to configure the dhcp-client-detect feature as an input feature
       * so the DHCP OFFER is sent to the ip4-local node. Without this a
       * broadcasted OFFER hits the 255.255.255.255/32 address and a unicast
       * hits 0.0.0.0/0 both of which default to drop and the latter may forward
       * of box - not what we want. Nor to we want to change these route for
       * all interfaces in this table
       */
      vnet_feature_enable_disable ("ip4-unicast",
				   "ip4-dhcp-client-detect",
				   c->sw_if_index, 1, 0, 0);

      vlib_process_signal_event (vm, dhcp_client_process_node.index,
				 EVENT_DHCP_CLIENT_WAKEUP, c - dcm->clients);
    }
  else
    {
      c = pool_elt_at_index (dcm->clients, p[0]);

      if (c->router_address.as_u32)
	{
	  ip46_address_t nh = {
	    .ip4 = c->router_address,
	  };

	  fib_table_entry_path_remove (fib_table_get_index_for_sw_if_index
				       (FIB_PROTOCOL_IP4, c->sw_if_index),
				       &all_0s, FIB_SOURCE_DHCP,
				       DPO_PROTO_IP4, &nh, c->sw_if_index, ~0,
				       1, FIB_ROUTE_PATH_FLAG_NONE);
	}
      dhcp_client_release_address (dcm, c);

      vec_free (c->option_55_data);
      vec_free (c->hostname);
      vec_free (c->client_identifier);
      vec_free (c->l2_rewrite);
      hash_unset (dcm->client_by_sw_if_index, c->sw_if_index);
      pool_put (dcm->clients, c);
    }
  return 0;
}

int
dhcp_client_config (vlib_main_t * vm,
		    u32 sw_if_index,
		    u8 * hostname,
		    u8 * client_id,
		    u32 is_add,
		    u32 client_index,
		    void *event_callback, u8 set_broadcast_flag, u32 pid)
{
  dhcp_client_add_del_args_t _a, *a = &_a;
  int rv;

  memset (a, 0, sizeof (*a));
  a->is_add = is_add;
  a->sw_if_index = sw_if_index;
  a->client_index = client_index;
  a->pid = pid;
  a->event_callback = event_callback;
  a->set_broadcast_flag = set_broadcast_flag;
  vec_validate (a->hostname, strlen ((char *) hostname) - 1);
  strncpy ((char *) a->hostname, (char *) hostname, vec_len (a->hostname));
  vec_validate (a->client_identifier, strlen ((char *) client_id) - 1);
  strncpy ((char *) a->client_identifier, (char *) client_id,
	   vec_len (a->client_identifier));

  /*
   * Option 55 request list. These data precisely match
   * the Ubuntu dhcp client. YMMV.
   */

  /* Subnet Mask */
  vec_add1 (a->option_55_data, 1);
  /* Broadcast address */
  vec_add1 (a->option_55_data, 28);
  /* time offset */
  vec_add1 (a->option_55_data, 2);
  /* Router */
  vec_add1 (a->option_55_data, 3);
  /* Domain Name */
  vec_add1 (a->option_55_data, 15);
  /* DNS */
  vec_add1 (a->option_55_data, 6);
  /* Domain search */
  vec_add1 (a->option_55_data, 119);
  /* Host name */
  vec_add1 (a->option_55_data, 12);
  /* NetBIOS name server */
  vec_add1 (a->option_55_data, 44);
  /* NetBIOS Scope */
  vec_add1 (a->option_55_data, 47);
  /* MTU */
  vec_add1 (a->option_55_data, 26);
  /* Classless static route */
  vec_add1 (a->option_55_data, 121);
  /* NTP servers */
  vec_add1 (a->option_55_data, 42);

  rv = dhcp_client_add_del (a);

  switch (rv)
    {
    case 0:
      break;

    case VNET_API_ERROR_INVALID_VALUE:

      vec_free (a->hostname);
      vec_free (a->client_identifier);
      vec_free (a->option_55_data);

      if (is_add)
	clib_warning ("dhcp client already enabled on intf_idx %d",
		      sw_if_index);
      else
	clib_warning ("dhcp client not enabled on on intf_idx %d",
		      sw_if_index);
      break;

    default:
      clib_warning ("dhcp_client_add_del returned %d", rv);
    }

  return rv;
}

static clib_error_t *
dhcp_client_set_command_fn (vlib_main_t * vm,
			    unformat_input_t * input,
			    vlib_cli_command_t * cmd)
{

  dhcp_client_main_t *dcm = &dhcp_client_main;
  u32 sw_if_index;
  u8 *hostname = 0;
  u8 sw_if_index_set = 0;
  u8 set_broadcast_flag = 1;
  int is_add = 1;
  dhcp_client_add_del_args_t _a, *a = &_a;
  int rv;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "intfc %U",
		    unformat_vnet_sw_interface, dcm->vnet_main, &sw_if_index))
	sw_if_index_set = 1;
      else if (unformat (input, "hostname %v", &hostname))
	;
      else if (unformat (input, "del"))
	is_add = 0;
      else if (unformat (input, "broadcast", &set_broadcast_flag))
	is_add = 0;
      else
	break;
    }

  if (sw_if_index_set == 0)
    return clib_error_return (0, "interface not specified");

  memset (a, 0, sizeof (*a));
  a->is_add = is_add;
  a->sw_if_index = sw_if_index;
  a->hostname = hostname;
  a->client_identifier = format (0, "vpe 1.0%c", 0);
  a->set_broadcast_flag = set_broadcast_flag;

  /*
   * Option 55 request list. These data precisely match
   * the Ubuntu dhcp client. YMMV.
   */

  /* Subnet Mask */
  vec_add1 (a->option_55_data, 1);
  /* Broadcast address */
  vec_add1 (a->option_55_data, 28);
  /* time offset */
  vec_add1 (a->option_55_data, 2);
  /* Router */
  vec_add1 (a->option_55_data, 3);
  /* Domain Name */
  vec_add1 (a->option_55_data, 15);
  /* DNS */
  vec_add1 (a->option_55_data, 6);
  /* Domain search */
  vec_add1 (a->option_55_data, 119);
  /* Host name */
  vec_add1 (a->option_55_data, 12);
  /* NetBIOS name server */
  vec_add1 (a->option_55_data, 44);
  /* NetBIOS Scope */
  vec_add1 (a->option_55_data, 47);
  /* MTU */
  vec_add1 (a->option_55_data, 26);
  /* Classless static route */
  vec_add1 (a->option_55_data, 121);
  /* NTP servers */
  vec_add1 (a->option_55_data, 42);

  rv = dhcp_client_add_del (a);

  switch (rv)
    {
    case 0:
      break;

    case VNET_API_ERROR_INVALID_VALUE:

      vec_free (a->hostname);
      vec_free (a->client_identifier);
      vec_free (a->option_55_data);
      if (is_add)
	return clib_error_return (0, "dhcp client already enabled on %U",
				  format_vnet_sw_if_index_name,
				  dcm->vnet_main, sw_if_index);
      else
	return clib_error_return (0, "dhcp client not enabled on %U",
				  format_vnet_sw_if_index_name,
				  dcm->vnet_main, sw_if_index);
      break;

    default:
      vlib_cli_output (vm, "dhcp_client_add_del returned %d", rv);
    }

  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (dhcp_client_set_command, static) = {
  .path = "set dhcp client",
  .short_help = "set dhcp client [del] intfc <interface> [hostname <name>]",
  .function = dhcp_client_set_command_fn,
};
/* *INDENT-ON* */

static clib_error_t *
dhcp_client_init (vlib_main_t * vm)
{
  dhcp_client_main_t *dcm = &dhcp_client_main;

  dcm->vlib_main = vm;
  dcm->vnet_main = vnet_get_main ();
  dcm->seed = 0xdeaddabe;
  return 0;
}

VLIB_INIT_FUNCTION (dhcp_client_init);

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
