static vlib_node_registration_t dhcp_client_process_node;
#define DHCP_DBG(...) \
- vlib_log_debug (dhcp_logger, __VA_ARGS__);
+ vlib_log_debug (dhcp_logger, __VA_ARGS__)
#define DHCP_INFO(...) \
- vlib_log_notice (dhcp_logger, __VA_ARGS__);
+ vlib_log_notice (dhcp_logger, __VA_ARGS__)
#define foreach_dhcp_sent_packet_stat \
_(DISCOVER, "DHCP discover packets sent") \
s =
format (s, "\n retry-count:%d, next-xmt:%.2f", c->retry_count,
c->next_transmit);
- s =
- format (s, "\n adjacencies:[unicast:%d broadcast:%d]", c->ai_ucast,
- c->ai_bcast);
+ s = format (s, "\n broadcast adjacency:%d", c->ai_bcast);
}
return s;
}
.ip4 = c->learned.router_address,
};
- /* *INDENT-OFF* */
fib_table_entry_path_add (
fib_table_get_index_for_sw_if_index (
FIB_PROTOCOL_IP4,
&nh, c->sw_if_index,
~0, 1, NULL, // no label stack
FIB_ROUTE_PATH_FLAG_NONE);
- /* *INDENT-ON* */
- }
- if (c->learned.dhcp_server.as_u32)
- {
- ip46_address_t dst = {
- .ip4 = c->learned.dhcp_server,
- };
- c->ai_ucast = adj_nbr_add_or_lock (FIB_PROTOCOL_IP4,
- VNET_LINK_IP4, &dst,
- c->sw_if_index);
}
}
clib_memcpy (&c->installed, &c->learned, sizeof (c->installed));
DPO_PROTO_IP4, &nh, c->sw_if_index, ~0,
1, FIB_ROUTE_PATH_FLAG_NONE);
}
- adj_unlock (c->ai_ucast);
- c->ai_ucast = ADJ_INDEX_INVALID;
}
clib_memset (&c->installed, 0, sizeof (c->installed));
c->addresses_installed = 0;
if (c->event_callback)
c->event_callback (c->client_index, c);
- DHCP_INFO ("update: %U", format_dhcp_client, dcm, c);
+ DHCP_INFO ("update: %U", format_dhcp_client, dcm, c, 1 /* verbose */ );
}
static void
dhcp_client_reset (dhcp_client_main_t * dcm, dhcp_client_t * c)
{
+ vlib_worker_thread_barrier_sync (dcm->vlib_main);
if (c->client_detect_feature_enabled == 1)
{
vnet_feature_enable_disable ("ip4-unicast",
c->sw_if_index, 0, 0, 0);
c->client_detect_feature_enabled = 0;
}
-
dhcp_client_release_address (dcm, c);
+ vlib_worker_thread_barrier_release (dcm->vlib_main);
+
clib_memset (&c->learned, 0, sizeof (c->installed));
c->state = DHCP_DISCOVER;
c->next_transmit = vlib_time_now (dcm->vlib_main);
udp_header_t * udp, dhcp_header_t * dhcp)
{
dhcp_client_main_t *dcm = &dhcp_client_main;
- vlib_main_t *vm = dcm->vlib_main;
+ vlib_main_t *vm = vlib_get_main ();
dhcp_client_t *c;
uword *p;
- f64 now = vlib_time_now (dcm->vlib_main);
+ f64 now = vlib_time_now (vm);
u8 dhcp_message_type = 0;
dhcp_option_t *o;
DHCP_INFO ("send: type:%U bcast:%d %U",
format_dhcp_packet_type, type,
- is_broadcast, format_dhcp_client, dcm, c);
+ is_broadcast, format_dhcp_client, dcm, c, 1 /* verbose */ );
/* Interface(s) down? */
if ((hw->flags & VNET_HW_INTERFACE_FLAG_LINK_UP) == 0)
/* Build a dhcpv4 pkt from whole cloth */
b = vlib_get_buffer (vm, bi);
- VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b);
ASSERT (b->current_data == 0);
vnet_buffer (b)->sw_if_index[VLIB_RX] = c->sw_if_index;
b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
- if (ADJ_INDEX_INVALID == c->ai_ucast)
- is_broadcast = 1;
-
if (is_broadcast)
{
node_index = ip4_rewrite_node.index;
vnet_buffer (b)->ip.adj_index[VLIB_TX] = c->ai_bcast;
}
else
- {
- ip_adjacency_t *adj = adj_get (c->ai_ucast);
-
- if (IP_LOOKUP_NEXT_ARP == adj->lookup_next_index)
- node_index = ip4_arp_node.index;
- else
- node_index = ip4_rewrite_node.index;
- vnet_buffer (b)->ip.adj_index[VLIB_TX] = c->ai_ucast;
- }
+ node_index = dcm->ip4_lookup_node_index;
/* Enqueue the packet right now */
f = vlib_get_frame_to_node (vm, node_index);
* State machine "DISCOVER" state. Send a dhcp discover packet,
* eventually back off the retry rate.
*/
- DHCP_INFO ("enter discover: %U", format_dhcp_client, dcm, c);
-
/*
* In order to accept any OFFER, whether broadcasted or unicasted, we
* need to configure the dhcp-client-detect feature as an input feature
*/
if (c->client_detect_feature_enabled == 0)
{
+ vlib_worker_thread_barrier_sync (dcm->vlib_main);
vnet_feature_enable_disable ("ip4-unicast",
"ip4-dhcp-client-detect",
c->sw_if_index, 1 /* enable */ , 0, 0);
+ vlib_worker_thread_barrier_release (dcm->vlib_main);
c->client_detect_feature_enabled = 1;
}
* State machine "REQUEST" state. Send a dhcp request packet,
* eventually drop back to the discover state.
*/
- DHCP_INFO ("enter request: %U", format_dhcp_client, dcm, c);
+ DHCP_INFO ("enter request: %U", format_dhcp_client, dcm, c,
+ 1 /*verbose */ );
send_dhcp_pkt (dcm, c, DHCP_PACKET_REQUEST, 1 /* is_broadcast */ );
*/
if (c->client_detect_feature_enabled == 0)
{
+ vlib_worker_thread_barrier_sync (dcm->vlib_main);
vnet_feature_enable_disable ("ip4-unicast",
"ip4-dhcp-client-detect",
c->sw_if_index, 1 /* enable */ , 0, 0);
+ vlib_worker_thread_barrier_release (dcm->vlib_main);
c->client_detect_feature_enabled = 1;
}
*/
if (now > c->lease_expires)
{
- DHCP_INFO ("lease expired: %U", format_dhcp_client, dcm, c);
+ DHCP_INFO ("lease expired: %U", format_dhcp_client, dcm, c,
+ 1 /*verbose */ );
/* reset all data for the client. do not send any more messages
* since the objects to do so have been lost */
return 1;
}
- DHCP_INFO ("enter bound: %U", format_dhcp_client, dcm, c);
+ DHCP_INFO ("enter bound: %U", format_dhcp_client, dcm, c, 1 /* verbose */ );
send_dhcp_pkt (dcm, c, DHCP_PACKET_REQUEST, 0 /* is_broadcast */ );
c->retry_count++;
/* Time for us to do something with this client? */
if (now < c->next_transmit)
- return timeout;
+ return c->next_transmit;
+
+ DHCP_INFO ("sm active session %d", c - dcm->clients);
again:
switch (c->state)
break;
}
- if (c->next_transmit < now + timeout)
- return c->next_transmit - now;
-
- return timeout;
+ return c->next_transmit;
}
static uword
dhcp_client_process (vlib_main_t * vm,
vlib_node_runtime_t * rt, vlib_frame_t * f)
{
- f64 timeout = 100.0;
+ f64 timeout = 1000.0;
+ f64 next_expire_time, this_next_expire_time;
f64 now;
uword event_type;
uword *event_data = 0;
{
case EVENT_DHCP_CLIENT_WAKEUP:
for (i = 0; i < vec_len (event_data); i++)
- timeout = dhcp_client_sm (now, timeout, event_data[i]);
- break;
+ (void) dhcp_client_sm (now, timeout, event_data[i]);
+ /* FALLTHROUGH */
case ~0:
- /* *INDENT-OFF* */
- DHCP_INFO ("timeout");
- 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;
+ if (pool_elts (dcm->clients))
+ {
+ next_expire_time = 1e70;
+ pool_foreach (c, dcm->clients)
+ {
+ this_next_expire_time = dhcp_client_sm
+ (now, timeout, (uword) (c - dcm->clients));
+ next_expire_time = this_next_expire_time < next_expire_time ?
+ this_next_expire_time : next_expire_time;
+ }
+ if (next_expire_time > now)
+ timeout = next_expire_time - now;
+ else
+ {
+ clib_warning ("BUG");
+ timeout = 1.13;
+ }
+ }
+ else
+ timeout = 1000.0;
break;
}
return 0;
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (dhcp_client_process_node,static) = {
.function = dhcp_client_process,
.type = VLIB_NODE_TYPE_PROCESS,
.n_errors = ARRAY_LEN(dhcp_client_process_stat_strings),
.error_strings = dhcp_client_process_stat_strings,
};
-/* *INDENT-ON* */
static clib_error_t *
show_dhcp_client_command_fn (vlib_main_t * vm,
return 0;
}
- /* *INDENT-OFF* */
- pool_foreach (c, dcm->clients,
- ({
+ 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
c->client_identifier = a->client_identifier;
c->set_broadcast_flag = a->set_broadcast_flag;
c->dscp = a->dscp;
- c->ai_ucast = ADJ_INDEX_INVALID;
c->ai_bcast = adj_nbr_add_or_lock (FIB_PROTOCOL_IP4,
VNET_LINK_IP4,
&ADJ_BCAST_ADDR, c->sw_if_index);
vlib_process_signal_event (vm, dhcp_client_process_node.index,
EVENT_DHCP_CLIENT_WAKEUP, c - dcm->clients);
- DHCP_INFO ("create: %U", format_dhcp_client, dcm, c);
+ DHCP_INFO ("create: %U", format_dhcp_client, dcm, c, 1 /* verbose */ );
}
else
{
vec_free (a->option_55_data);
if (is_add)
- clib_warning ("dhcp client already enabled on intf_idx %d",
- sw_if_index);
+ DHCP_INFO ("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);
+ DHCP_INFO ("not enabled on on intf_idx %d", sw_if_index);
break;
default:
- clib_warning ("dhcp_client_add_del returned %d", rv);
+ DHCP_INFO ("dhcp_client_add_del returned %d", rv);
}
return rv;
dhcp_client_main_t *dcm = &dhcp_client_main;
dhcp_client_t *c;
- /* *INDENT-OFF* */
- pool_foreach (c, dcm->clients,
- ({
+ pool_foreach (c, dcm->clients)
+ {
if (!cb(c, ctx))
break;
- }));
- /* *INDENT-ON* */
+ }
}
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;
+ vlib_node_t *ip4_lookup_node;
+
+ ip4_lookup_node = vlib_get_node_by_name (vm, (u8 *) "ip4-lookup");
+
+ /* Should never happen... */
+ if (ip4_lookup_node == 0)
+ return clib_error_return (0, "ip4-lookup node not found");
+ dcm->ip4_lookup_node_index = ip4_lookup_node->index;
dcm->vlib_main = vm;
dcm->vnet_main = vnet_get_main ();
dcm->seed = (u32) clib_cpu_time_now ();
dhcp_logger = vlib_log_register_class ("dhcp", "client");
+ DHCP_DBG ("plugin initialized");
return 0;
}