/*
 * 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;

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 */);
}

/* 
 * 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;
      
  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 */
      vlib_process_signal_event (vm, dhcp_client_process_node.index, 
                                 EVENT_DHCP_CLIENT_WAKEUP, c - dcm->clients);
      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)
        {
          void (*fp)(u32, u32, u8 *, u8, u8, u8 *, u8 *, u8 *) = c->event_callback;

          dhcp_client_acquire_address (dcm, c);

          /*
           * 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,
	      };

	      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,
					FIB_PROTOCOL_IP4,
					&nh,
					c->sw_if_index,
					~0,
					1,
					NULL, // no label stack
					FIB_ROUTE_PATH_FLAG_NONE);
	    }

          /*
           * 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 */
        }

      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;

  /* 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 ? 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);
}

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)
    {
      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,
				      FIB_PROTOCOL_IP4,
				      &nh,
				      c->sw_if_index,
				      ~0,
				      1,
				      FIB_ROUTE_PATH_FLAG_NONE);
	}

      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;
      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:
          pool_foreach (c, dcm->clients,
          ({
            timeout = dhcp_client_sm (now, timeout, 
                                          (uword)(c - dcm->clients));
          }));
          if (pool_elts (dcm->clients) == 0)
            timeout = 100.0;
          break;
        }

      vec_reset_length (event_data);
    }

  /* NOTREACHED */
  return 0;
}

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,
};

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;
    }

  pool_foreach (c, dcm->clients, 
  ({
    vlib_cli_output (vm, "%U", format_dhcp_client, dcm, c, verbose);
  }));
  
  return 0;
}

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,
};


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_1s =
  {
      .fp_len = 32,
      .fp_addr.ip4.as_u32 = 0xffffffff,
      .fp_proto = FIB_PROTOCOL_IP4,
  };
  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;
      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);

      /* this add is ref counted by FIB so we can add for each itf */
      fib_table_entry_special_add(fib_table_get_index_for_sw_if_index(
				      FIB_PROTOCOL_IP4,
				      c->sw_if_index),
				  &all_1s,
				  FIB_SOURCE_DHCP,
				  FIB_ENTRY_FLAG_LOCAL);

     /*
       * enable the interface to RX IPv4 packets
       * this is also ref counted
       */
      ip4_sw_interface_enable_disable (c->sw_if_index, 1);

      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]);

      fib_table_entry_special_remove(fib_table_get_index_for_sw_if_index(
					 FIB_PROTOCOL_IP4,
					 c->sw_if_index),
				     &all_1s,
				     FIB_SOURCE_DHCP);

      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,
				      FIB_PROTOCOL_IP4,
				      &nh,
				      c->sw_if_index,
				      ~0,
				      1,
				      FIB_ROUTE_PATH_FLAG_NONE);
      }
      dhcp_client_release_address (dcm, c);
      ip4_sw_interface_enable_disable (c->sw_if_index, 0);

      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,
                    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;
  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;
  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
        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);

  /* 
   * 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;
}

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,
};

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);
