Fix af_packet issues:
[vpp.git] / src / vnet / dhcp / client.c
index dbcb2a5..b89b8f2 100644 (file)
@@ -100,12 +100,12 @@ 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;
 
   /* disable the feature */
   vnet_feature_enable_disable ("ip4-unicast",
                               "ip4-dhcp-client-detect",
                               c->sw_if_index, 0 /* disable */ , 0, 0);
+  c->client_detect_feature_enabled = 0;
 
   /* if renewing the lease, the address and route have already been added */
   if (c->state == DHCP_BOUND)
@@ -146,12 +146,8 @@ dhcp_client_addr_callback (dhcp_client_t * c)
   /*
    * 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 */
+  if (c->event_callback)
+    c->event_callback (c->client_index, c);
 }
 
 /*
@@ -220,6 +216,7 @@ dhcp_client_for_us (u32 bi, vlib_buffer_t * b,
          {
            u32 lease_time_in_seconds =
              clib_host_to_net_u32 (o->data_as_u32[0]);
+           // for debug: lease_time_in_seconds = 20; /*$$$$*/
            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 */
@@ -251,7 +248,14 @@ dhcp_client_for_us (u32 bi, vlib_buffer_t * b,
            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 */
@@ -307,6 +311,7 @@ dhcp_client_for_us (u32 bi, vlib_buffer_t * b,
                                           "ip4-dhcp-client-detect",
                                           c->sw_if_index, 1 /* enable */ ,
                                           0, 0);
+             c->client_detect_feature_enabled = 1;
            }
          /* Wipe out any memory of the address we had... */
          c->state = DHCP_DISCOVER;
@@ -317,6 +322,7 @@ dhcp_client_for_us (u32 bi, vlib_buffer_t * b,
          c->router_address.as_u32 = 0;
          c->lease_renewal_interval = 0;
          c->dhcp_server.as_u32 = 0;
+         vec_free (c->domain_server_address);
          break;
        }
 
@@ -424,7 +430,7 @@ send_dhcp_pkt (dhcp_client_main_t * dcm, dhcp_client_t * c,
   dhcp = (dhcp_header_t *) (udp + 1);
 
   /* $$$ optimize, maybe */
-  memset (ip, 0, sizeof (*ip) + sizeof (*udp) + sizeof (*dhcp));
+  clib_memset (ip, 0, sizeof (*ip) + sizeof (*udp) + sizeof (*dhcp));
 
   ip->ip_version_and_header_length = 0x45;
   ip->ttl = 128;
@@ -577,6 +583,15 @@ 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.
    */
+
+  if (c->client_detect_feature_enabled == 0)
+    {
+      vnet_feature_enable_disable ("ip4-unicast",
+                                  "ip4-dhcp-client-detect",
+                                  c->sw_if_index, 1 /* enable */ , 0, 0);
+      c->client_detect_feature_enabled = 1;
+    }
+
   send_dhcp_pkt (dcm, c, DHCP_PACKET_DISCOVER, 1 /* is_broadcast */ );
 
   c->retry_count++;
@@ -623,10 +638,13 @@ dhcp_bound_state (dhcp_client_main_t * dcm, dhcp_client_t * c, f64 now)
    * DHCP address. Turn it back on again on first renew attempt.
    * Otherwise, if the DHCP server replies we'll never see it.
    */
-  if (!c->retry_count)
-    vnet_feature_enable_disable ("ip4-unicast",
-                                "ip4-dhcp-client-detect",
-                                c->sw_if_index, 1 /* enable */ , 0, 0);
+  if (c->client_detect_feature_enabled == 0)
+    {
+      vnet_feature_enable_disable ("ip4-unicast",
+                                  "ip4-dhcp-client-detect",
+                                  c->sw_if_index, 1 /* enable */ , 0, 0);
+      c->client_detect_feature_enabled = 1;
+    }
 
   send_dhcp_pkt (dcm, c, DHCP_PACKET_REQUEST, 0 /* is_broadcast */ );
 
@@ -804,17 +822,27 @@ 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);
+  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",
+                 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);
+      vec_add1 (s, '\n');
+    }
   else
-    s = format (s, "no address\n");
+    {
+      s = format (s, "no address\n");
+    }
 
   if (verbose)
     {
@@ -897,8 +925,9 @@ dhcp_client_add_del (dhcp_client_add_del_args_t * a)
 
   if (a->is_add)
     {
+      dhcp_maybe_register_udp_ports (DHCP_PORT_REG_CLIENT);
       pool_get (dcm->clients, c);
-      memset (c, 0, sizeof (*c));
+      clib_memset (c, 0, sizeof (*c));
       c->state = DHCP_DISCOVER;
       c->sw_if_index = a->sw_if_index;
       c->client_index = a->client_index;
@@ -928,6 +957,7 @@ dhcp_client_add_del (dhcp_client_add_del_args_t * a)
       vnet_feature_enable_disable ("ip4-unicast",
                                   "ip4-dhcp-client-detect",
                                   c->sw_if_index, 1 /* enable */ , 0, 0);
+      c->client_detect_feature_enabled = 1;
 
       vlib_process_signal_event (vm, dhcp_client_process_node.index,
                                 EVENT_DHCP_CLIENT_WAKEUP, c - dcm->clients);
@@ -950,6 +980,7 @@ dhcp_client_add_del (dhcp_client_add_del_args_t * a)
        }
       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);
@@ -961,18 +992,19 @@ dhcp_client_add_del (dhcp_client_add_del_args_t * a)
 }
 
 int
-dhcp_client_config (vlib_main_t * vm,
+dhcp_client_config (u32 is_add,
+                   u32 client_index,
+                   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_event_cb_t event_callback,
+                   u8 set_broadcast_flag, u32 pid)
 {
   dhcp_client_add_del_args_t _a, *a = &_a;
   int rv;
 
-  memset (a, 0, sizeof (*a));
+  clib_memset (a, 0, sizeof (*a));
   a->is_add = is_add;
   a->sw_if_index = sw_if_index;
   a->client_index = client_index;
@@ -1045,6 +1077,22 @@ dhcp_client_config (vlib_main_t * vm,
   return rv;
 }
 
+void
+dhcp_client_walk (dhcp_client_walk_cb_t cb, void *ctx)
+{
+  dhcp_client_main_t *dcm = &dhcp_client_main;
+  dhcp_client_t *c;
+
+  /* *INDENT-OFF* */
+  pool_foreach (c, dcm->clients,
+  ({
+    if (!cb(c, ctx))
+      break;
+  }));
+  /* *INDENT-ON* */
+
+}
+
 static clib_error_t *
 dhcp_client_set_command_fn (vlib_main_t * vm,
                            unformat_input_t * input,
@@ -1078,7 +1126,7 @@ dhcp_client_set_command_fn (vlib_main_t * vm,
   if (sw_if_index_set == 0)
     return clib_error_return (0, "interface not specified");
 
-  memset (a, 0, sizeof (*a));
+  clib_memset (a, 0, sizeof (*a));
   a->is_add = is_add;
   a->sw_if_index = sw_if_index;
   a->hostname = hostname;