summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcarlsonj <none@none>2007-04-25 11:54:45 -0700
committercarlsonj <none@none>2007-04-25 11:54:45 -0700
commitcfb9c9abdc2696bc174bb10a3a28552dc917b98f (patch)
tree66f98c1f0a916d6eacc66a9141e1153208695386
parent8cb045d062db356cee4eaacd954f772ab314f6f3 (diff)
downloadillumos-gate-cfb9c9abdc2696bc174bb10a3a28552dc917b98f.tar.gz
6396937 dhcpagent: cannot write /etc/dhcp/e1000g0.dhc
6514851 in.ndpd "giving up" message needs work 6524645 clear_lif_dhcp is too cautious 6525108 inconsistent handling of lists due to fix for CR 6209214 6528047 dhcp inform messages are sent with zero source 6541139 dhcpagent can leave timers running on drop 6541633 dhcpagent's route clean-up mechanism can misfire, removing default route
-rw-r--r--usr/src/cmd/cmd-inet/sbin/dhcpagent/agent.c15
-rw-r--r--usr/src/cmd/cmd-inet/sbin/dhcpagent/bound.c13
-rw-r--r--usr/src/cmd/cmd-inet/sbin/dhcpagent/inform.c9
-rw-r--r--usr/src/cmd/cmd-inet/sbin/dhcpagent/init_reboot.c6
-rw-r--r--usr/src/cmd/cmd-inet/sbin/dhcpagent/interface.c16
-rw-r--r--usr/src/cmd/cmd-inet/sbin/dhcpagent/release.c18
-rw-r--r--usr/src/cmd/cmd-inet/sbin/dhcpagent/request.c10
-rw-r--r--usr/src/cmd/cmd-inet/sbin/dhcpagent/select.c33
-rw-r--r--usr/src/cmd/cmd-inet/sbin/dhcpagent/states.c47
-rw-r--r--usr/src/cmd/cmd-inet/sbin/dhcpagent/states.h73
-rw-r--r--usr/src/cmd/cmd-inet/sbin/dhcpagent/util.c18
-rw-r--r--usr/src/cmd/cmd-inet/sbin/dhcpagent/util.h4
-rw-r--r--usr/src/cmd/cmd-inet/usr.lib/in.ndpd/main.c7
-rw-r--r--usr/src/lib/libdhcpagent/common/dhcpagent_ipc.c32
-rw-r--r--usr/src/lib/libdhcpagent/common/dhcpagent_ipc.h2
-rw-r--r--usr/src/lib/libdhcpagent/common/dhcpagent_util.c32
16 files changed, 196 insertions, 139 deletions
diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/agent.c b/usr/src/cmd/cmd-inet/sbin/dhcpagent/agent.c
index 2e805874bb..aebf723f93 100644
--- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/agent.c
+++ b/usr/src/cmd/cmd-inet/sbin/dhcpagent/agent.c
@@ -941,17 +941,14 @@ load_option:
* going into SELECTING.
*/
- if (debug_level == 0 &&
- iu_schedule_timer_ms(tq, lrand48() % DHCP_SELECT_WAIT,
- dhcp_start, dsmp) != -1) {
- hold_smach(dsmp);
+ if (debug_level == 0 && set_start_timer(dsmp)) {
/* next destination: dhcp_start() */
break;
+ } else {
+ dhcp_selecting(dsmp);
+ /* next destination: dhcp_requesting() */
+ break;
}
-
- dhcp_selecting(dsmp);
- /* next destination: dhcp_requesting() */
- break;
}
case DHCP_STATUS: {
@@ -1147,6 +1144,8 @@ check_lif(dhcp_lif_t *lif, const struct ifa_msghdr *ifam, int msglen)
lif->lif_plumbed = B_FALSE;
dhcpmsg(MSG_INFO, "%s has been removed; abandoning",
lif->lif_name);
+ if (!isv6)
+ discard_default_routes(lif->lif_smachs);
} else {
dhcpmsg(MSG_ERR,
"unable to retrieve interface flags on %s",
diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/bound.c b/usr/src/cmd/cmd-inet/sbin/dhcpagent/bound.c
index 9fbbc6a287..3c9713666e 100644
--- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/bound.c
+++ b/usr/src/cmd/cmd-inet/sbin/dhcpagent/bound.c
@@ -327,6 +327,7 @@ dhcp_bound_complete(dhcp_smach_t *dsmp)
DHCP_OPT *router_list;
int i;
DHCPSTATE oldstate;
+ dhcp_lif_t *lif;
/*
* Do bound state entry processing only if running IPv4. There's no
@@ -344,13 +345,19 @@ dhcp_bound_complete(dhcp_smach_t *dsmp)
}
/*
- * add each provided router; we'll clean them up when the
+ * Add each provided router; we'll clean them up when the
* state machine goes away or when our lease expires.
+ *
+ * Note that we do not handle default routers on IPv4 logicals;
+ * see README for details.
*/
ack = dsmp->dsm_ack;
router_list = ack->opts[CD_ROUTER];
- if (router_list && (router_list->len % sizeof (ipaddr_t)) == 0) {
+ lif = dsmp->dsm_lif;
+ if (router_list != NULL &&
+ (router_list->len % sizeof (ipaddr_t)) == 0 &&
+ strchr(lif->lif_name, ':') == NULL) {
dsmp->dsm_nrouters = router_list->len / sizeof (ipaddr_t);
dsmp->dsm_routers = malloc(router_list->len);
@@ -366,7 +373,7 @@ dhcp_bound_complete(dhcp_smach_t *dsmp)
router_list->value + (i * sizeof (ipaddr_t)),
sizeof (ipaddr_t));
- if (!add_default_route(dsmp->dsm_name,
+ if (!add_default_route(lif->lif_pif->pif_index,
&dsmp->dsm_routers[i])) {
dhcpmsg(MSG_ERR, "configure_bound: cannot add "
"default router %s on %s", inet_ntoa(
diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/inform.c b/usr/src/cmd/cmd-inet/sbin/dhcpagent/inform.c
index e742e91649..f53944a006 100644
--- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/inform.c
+++ b/usr/src/cmd/cmd-inet/sbin/dhcpagent/inform.c
@@ -50,6 +50,9 @@ static boolean_t stop_informing(dhcp_smach_t *, unsigned int);
* output: void
* note: the INFORM cannot be sent successfully if the interface
* does not have an IP address (this is mostly an issue for IPv4).
+ * We switch into INFORM_SENT state before sending the packet so
+ * that the packet-sending subsystem uses regular sockets and sets
+ * the source address. (See set_smach_state.)
*/
void
@@ -57,7 +60,7 @@ dhcp_inform(dhcp_smach_t *dsmp)
{
dhcp_pkt_t *dpkt;
- if (!set_smach_state(dsmp, INIT))
+ if (!set_smach_state(dsmp, INFORM_SENT))
goto failed;
if (dsmp->dsm_isv6) {
@@ -101,14 +104,12 @@ dhcp_inform(dhcp_smach_t *dsmp)
}
}
- if (!set_smach_state(dsmp, INFORM_SENT))
- goto failed;
-
return;
failed:
dsmp->dsm_dflags |= DHCP_IF_FAILED;
ipc_action_finish(dsmp, DHCP_IPC_E_INT);
+ (void) set_smach_state(dsmp, INIT);
}
/*
diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/init_reboot.c b/usr/src/cmd/cmd-inet/sbin/dhcpagent/init_reboot.c
index 497a3e9d18..5afcad75ad 100644
--- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/init_reboot.c
+++ b/usr/src/cmd/cmd-inet/sbin/dhcpagent/init_reboot.c
@@ -29,7 +29,6 @@
#include <sys/types.h>
#include <stdio.h>
-#include <stdlib.h>
#include <limits.h>
#include <sys/socket.h>
#include <netinet/in.h>
@@ -191,10 +190,7 @@ dhcp_init_reboot_v6(dhcp_smach_t *dsmp)
return;
failure:
- if (iu_schedule_timer_ms(tq, lrand48() % DHCP_SELECT_WAIT, dhcp_start,
- dsmp) != -1)
- hold_smach(dsmp);
- else
+ if (!set_start_timer(dsmp))
dhcp_selecting(dsmp);
}
diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/interface.c b/usr/src/cmd/cmd-inet/sbin/dhcpagent/interface.c
index 4e1b8d892b..f5ed8b4a3e 100644
--- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/interface.c
+++ b/usr/src/cmd/cmd-inet/sbin/dhcpagent/interface.c
@@ -779,8 +779,11 @@ verify_lif(const dhcp_lif_t *lif)
fd = isv6 ? v6_sock_fd : v4_sock_fd;
if (ioctl(fd, SIOCGLIFFLAGS, &lifr) == -1) {
- dhcpmsg(MSG_ERR, "verify_lif: SIOCGLIFFLAGS failed on %s",
- lif->lif_name);
+ if (errno != ENXIO) {
+ dhcpmsg(MSG_ERR,
+ "verify_lif: SIOCGLIFFLAGS failed on %s",
+ lif->lif_name);
+ }
return (B_FALSE);
}
@@ -901,8 +904,10 @@ canonize_lif(dhcp_lif_t *lif)
fd = isv6 ? v6_sock_fd : v4_sock_fd;
if (ioctl(fd, SIOCGLIFFLAGS, &lifr) == -1) {
- dhcpmsg(MSG_ERR, "canonize_lif: can't get flags for %s",
- lif->lif_name);
+ if (errno != ENXIO) {
+ dhcpmsg(MSG_ERR, "canonize_lif: can't get flags for %s",
+ lif->lif_name);
+ }
return;
}
@@ -1223,9 +1228,6 @@ clear_lif_dhcp(dhcp_lif_t *lif)
(void) strlcpy(lifr.lifr_name, lif->lif_name, LIFNAMSIZ);
- if (!(lif->lif_flags & IFF_DHCPRUNNING))
- return;
-
if (ioctl(fd, SIOCGLIFFLAGS, &lifr) == -1)
return;
diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/release.c b/usr/src/cmd/cmd-inet/sbin/dhcpagent/release.c
index a841364f2f..28d4ec77f8 100644
--- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/release.c
+++ b/usr/src/cmd/cmd-inet/sbin/dhcpagent/release.c
@@ -36,6 +36,7 @@
#include <netinet/dhcp6.h>
#include <dhcpmsg.h>
#include <dhcp_hostconf.h>
+#include <dhcpagent_util.h>
#include "agent.h"
#include "packet.h"
@@ -237,18 +238,27 @@ dhcp_drop(dhcp_smach_t *dsmp, void *arg)
dsmp->dsm_name);
} else {
PKT_LIST *plp[2];
+ const char *hcfile;
+ hcfile = ifname_to_hostconf(dsmp->dsm_name,
+ dsmp->dsm_isv6);
plp[0] = dsmp->dsm_ack;
plp[1] = dsmp->dsm_orig_ack;
if (write_hostconf(dsmp->dsm_name, plp, 2,
monosec_to_time(dsmp->dsm_curstart_monosec),
- dsmp->dsm_isv6) == -1) {
+ dsmp->dsm_isv6) != -1) {
+ dhcpmsg(MSG_DEBUG, "wrote lease to %s", hcfile);
+ } else if (errno == EROFS) {
+ dhcpmsg(MSG_DEBUG, "%s is on a read-only file "
+ "system; not saving lease", hcfile);
+ } else {
dhcpmsg(MSG_ERR, "cannot write %s (reboot will "
- "not use cached configuration)",
- ifname_to_hostconf(dsmp->dsm_name,
- dsmp->dsm_isv6));
+ "not use cached configuration)", hcfile);
}
}
+ } else {
+ dhcpmsg(MSG_DEBUG, "%s in state %s; not saving lease",
+ dsmp->dsm_name, dhcp_state_to_string(dsmp->dsm_state));
}
deprecate_leases(dsmp);
finished_smach(dsmp, DHCP_IPC_SUCCESS);
diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/request.c b/usr/src/cmd/cmd-inet/sbin/dhcpagent/request.c
index 936965e703..685e4ac921 100644
--- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/request.c
+++ b/usr/src/cmd/cmd-inet/sbin/dhcpagent/request.c
@@ -608,8 +608,10 @@ static void
accept_v4_acknak(dhcp_smach_t *dsmp, PKT_LIST *plp)
{
if (*plp->opts[CD_DHCP_TYPE]->value == ACK) {
- if (plp->opts[CD_LEASE_TIME] == NULL ||
- plp->opts[CD_LEASE_TIME]->len != sizeof (lease_t)) {
+ if (dsmp->dsm_state != INFORM_SENT &&
+ dsmp->dsm_state != INFORMATION &&
+ (plp->opts[CD_LEASE_TIME] == NULL ||
+ plp->opts[CD_LEASE_TIME]->len != sizeof (lease_t))) {
dhcpmsg(MSG_WARNING, "accept_v4_acknak: ACK packet on "
"%s missing mandatory lease option, ignored",
dsmp->dsm_name);
@@ -1133,15 +1135,13 @@ dhcp_restart(dhcp_smach_t *dsmp)
*/
deprecate_leases(dsmp);
- if (iu_schedule_timer(tq, DHCP_RESTART_WAIT, dhcp_start, dsmp) == -1) {
+ if (!set_start_timer(dsmp)) {
dhcpmsg(MSG_ERROR, "dhcp_restart: cannot schedule dhcp_start, "
"reverting to INIT state on %s", dsmp->dsm_name);
(void) set_smach_state(dsmp, INIT);
dsmp->dsm_dflags |= DHCP_IF_FAILED;
ipc_action_finish(dsmp, DHCP_IPC_E_MEMORY);
- } else {
- hold_smach(dsmp);
}
}
diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/select.c b/usr/src/cmd/cmd-inet/sbin/dhcpagent/select.c
index 9dfead3df0..8f2771c14a 100644
--- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/select.c
+++ b/usr/src/cmd/cmd-inet/sbin/dhcpagent/select.c
@@ -29,6 +29,7 @@
#include <sys/types.h>
#include <stdio.h>
+#include <stdlib.h>
#include <strings.h>
#include <time.h>
#include <limits.h>
@@ -59,15 +60,39 @@ static stop_func_t stop_selecting;
*/
/* ARGSUSED */
-void
+static void
dhcp_start(iu_tq_t *tqp, void *arg)
{
dhcp_smach_t *dsmp = arg;
- release_smach(dsmp);
+ dsmp->dsm_start_timer = -1;
+ (void) set_smach_state(dsmp, INIT);
+ if (verify_smach(dsmp)) {
+ dhcpmsg(MSG_VERBOSE, "starting DHCP on %s", dsmp->dsm_name);
+ dhcp_selecting(dsmp);
+ }
+}
- dhcpmsg(MSG_VERBOSE, "starting DHCP on %s", dsmp->dsm_name);
- dhcp_selecting(dsmp);
+/*
+ * set_start_timer(): sets a random timer to start a DHCP state machine
+ *
+ * input: dhcp_smach_t *: the state machine on which to start DHCP
+ * output: boolean_t: B_TRUE if a timer is now running
+ */
+
+boolean_t
+set_start_timer(dhcp_smach_t *dsmp)
+{
+ if (dsmp->dsm_start_timer != -1)
+ return (B_TRUE);
+
+ dsmp->dsm_start_timer = iu_schedule_timer_ms(tq,
+ lrand48() % DHCP_SELECT_WAIT, dhcp_start, dsmp);
+ if (dsmp->dsm_start_timer == -1)
+ return (B_FALSE);
+
+ hold_smach(dsmp);
+ return (B_TRUE);
}
/*
diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/states.c b/usr/src/cmd/cmd-inet/sbin/dhcpagent/states.c
index ddf03f6c78..c26e6c07b2 100644
--- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/states.c
+++ b/usr/src/cmd/cmd-inet/sbin/dhcpagent/states.c
@@ -169,6 +169,7 @@ insert_smach(dhcp_lif_t *lif, int *error)
dsmp->dsm_script_pid = -1;
dsmp->dsm_script_helper_pid = -1;
dsmp->dsm_script_event_id = -1;
+ dsmp->dsm_start_timer = -1;
ipc_action_init(&dsmp->dsm_ia);
@@ -575,6 +576,8 @@ cancel_offer_timer(dhcp_smach_t *dsmp)
*
* input: dhcp_smach_t *: state machine to cancel
* output: none
+ * note: this function assumes that the iu timer functions are synchronous
+ * and thus don't require any protection or ordering on cancellation.
*/
static void
@@ -594,6 +597,11 @@ cancel_smach_timers(dhcp_smach_t *dsmp)
cancel_offer_timer(dsmp);
stop_pkt_retransmission(dsmp);
+ if (dsmp->dsm_start_timer != -1) {
+ (void) iu_cancel_timer(tq, dsmp->dsm_start_timer, NULL);
+ dsmp->dsm_start_timer = -1;
+ release_smach(dsmp);
+ }
}
/*
@@ -675,7 +683,8 @@ set_smach_state(dhcp_smach_t *dsmp, DHCPSTATE state)
* For IPv6, no such change is necessary.
*/
is_bound = (state == BOUND || state == REBINDING ||
- state == RENEWING || state == RELEASING);
+ state == RENEWING || state == RELEASING ||
+ state == INFORM_SENT || state == INFORMATION);
if (dsmp->dsm_using_dlpi && is_bound) {
if (!open_ip_lif(dsmp->dsm_lif))
return (B_FALSE);
@@ -1026,7 +1035,24 @@ smach_count(void)
}
/*
- * remove_default_routes(): removes a state machine's default routes
+ * discard_default_routes(): removes a state machine's default routes alone.
+ *
+ * input: dhcp_smach_t *: the state machine whose default routes need to be
+ * discarded
+ * output: void
+ */
+
+void
+discard_default_routes(dhcp_smach_t *dsmp)
+{
+ free(dsmp->dsm_routers);
+ dsmp->dsm_routers = NULL;
+ dsmp->dsm_nrouters = 0;
+}
+
+/*
+ * remove_default_routes(): removes a state machine's default routes from the
+ * kernel and from the state machine.
*
* input: dhcp_smach_t *: the state machine whose default routes need to be
* removed
@@ -1037,10 +1063,12 @@ void
remove_default_routes(dhcp_smach_t *dsmp)
{
int idx;
+ uint32_t ifindex;
if (dsmp->dsm_routers != NULL) {
+ ifindex = dsmp->dsm_lif->lif_pif->pif_index;
for (idx = dsmp->dsm_nrouters - 1; idx >= 0; idx--) {
- if (del_default_route(dsmp->dsm_name,
+ if (del_default_route(ifindex,
&dsmp->dsm_routers[idx])) {
dhcpmsg(MSG_DEBUG, "remove_default_routes: "
"removed %s from %s",
@@ -1053,9 +1081,7 @@ remove_default_routes(dhcp_smach_t *dsmp)
dsmp->dsm_name);
}
}
- free(dsmp->dsm_routers);
- dsmp->dsm_routers = NULL;
- dsmp->dsm_nrouters = 0;
+ discard_default_routes(dsmp);
}
}
@@ -1114,10 +1140,13 @@ void
refresh_smach(dhcp_smach_t *dsmp)
{
if (dsmp->dsm_state == BOUND || dsmp->dsm_state == RENEWING ||
- dsmp->dsm_state == REBINDING) {
- dhcpmsg(MSG_WARNING, "refreshing lease on %s", dsmp->dsm_name);
+ dsmp->dsm_state == REBINDING || dsmp->dsm_state == INFORMATION) {
+ dhcpmsg(MSG_WARNING, "refreshing state on %s", dsmp->dsm_name);
cancel_smach_timers(dsmp);
- dhcp_init_reboot(dsmp);
+ if (dsmp->dsm_state == INFORMATION)
+ dhcp_inform(dsmp);
+ else
+ dhcp_init_reboot(dsmp);
}
}
diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/states.h b/usr/src/cmd/cmd-inet/sbin/dhcpagent/states.h
index 768f5a86a4..02209ce243 100644
--- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/states.h
+++ b/usr/src/cmd/cmd-inet/sbin/dhcpagent/states.h
@@ -57,22 +57,22 @@ extern "C" {
* day allowed per interface, this will need to become a list.
*/
struct dhcp_smach_s {
- dhcp_smach_t *dsm_next; /* Note: must be first */
- dhcp_smach_t *dsm_prev;
+ dhcp_smach_t *dsm_next; /* Note: must be first */
+ dhcp_smach_t *dsm_prev;
/*
* The name of the state machine. This is currently just a pointer to
* the controlling LIF's name, but could be otherwise.
*/
- const char *dsm_name;
- dhcp_lif_t *dsm_lif; /* Controlling LIF */
- uint_t dsm_hold_count; /* reference count */
+ const char *dsm_name;
+ dhcp_lif_t *dsm_lif; /* Controlling LIF */
+ uint_t dsm_hold_count; /* reference count */
- dhcp_lease_t *dsm_leases; /* List of leases */
- uint_t dsm_lif_wait; /* LIFs waiting on DAD */
- uint_t dsm_lif_down; /* LIFs failed */
+ dhcp_lease_t *dsm_leases; /* List of leases */
+ uint_t dsm_lif_wait; /* LIFs waiting on DAD */
+ uint_t dsm_lif_down; /* LIFs failed */
- boolean_t dsm_using_dlpi;
+ boolean_t dsm_using_dlpi;
/*
* each state machine can have at most one pending asynchronous
@@ -85,8 +85,8 @@ struct dhcp_smach_s {
* to maintain them.
*/
- ipc_action_t dsm_ia;
- async_action_t dsm_async;
+ ipc_action_t dsm_ia;
+ async_action_t dsm_async;
uchar_t *dsm_cid; /* client id */
uchar_t dsm_cidlen; /* client id len */
@@ -95,7 +95,7 @@ struct dhcp_smach_s {
* current state of the machine
*/
- DHCPSTATE dsm_state;
+ DHCPSTATE dsm_state;
uint16_t dsm_dflags; /* DHCP_IF_* (shared with IPC) */
@@ -138,7 +138,7 @@ struct dhcp_smach_s {
* REQUEST can have the same pkt->secs.
*/
- uint16_t dsm_disc_secs;
+ uint16_t dsm_disc_secs;
/*
* this is a chain of packets which have been received on this
@@ -147,7 +147,7 @@ struct dhcp_smach_s {
* general, packets are put on this list through recv_pkt()
*/
- PKT_LIST *dsm_recv_pkt_list;
+ PKT_LIST *dsm_recv_pkt_list;
/*
* these three fields are initially zero, and get incremented
@@ -160,9 +160,9 @@ struct dhcp_smach_s {
* (if any other state).
*/
- uint32_t dsm_sent;
- uint32_t dsm_received;
- uint32_t dsm_bad_offers;
+ uint32_t dsm_sent;
+ uint32_t dsm_received;
+ uint32_t dsm_bad_offers;
/*
* dsm_send_pkt.pkt is dynamically allocated to be as big a
@@ -174,7 +174,7 @@ struct dhcp_smach_s {
* other functions.
*/
- dhcp_pkt_t dsm_send_pkt;
+ dhcp_pkt_t dsm_send_pkt;
union {
struct sockaddr_in v4;
struct sockaddr_in6 v6;
@@ -189,11 +189,11 @@ struct dhcp_smach_s {
* value, and dsm_send_timeout must be set to the IRT (initial
* retransmit timer) value by the sender.
*/
- uint_t dsm_send_timeout;
- uint_t dsm_send_tcenter;
- stop_func_t *dsm_send_stop_func;
- uint32_t dsm_packet_sent;
- iu_timer_id_t dsm_retrans_timer;
+ uint_t dsm_send_timeout;
+ uint_t dsm_send_tcenter;
+ stop_func_t *dsm_send_stop_func;
+ uint32_t dsm_packet_sent;
+ iu_timer_id_t dsm_retrans_timer;
/*
* The host name we've been asked to request is remembered
@@ -218,17 +218,19 @@ struct dhcp_smach_s {
* When the lease time actually begins (and thus becomes current),
* `dsm_curstart_monosec' is set to `dsm_newstart_monosec'.
*/
- hrtime_t dsm_neg_hrtime;
- monosec_t dsm_newstart_monosec;
- monosec_t dsm_curstart_monosec;
-
- int dsm_script_fd;
- pid_t dsm_script_pid;
- pid_t dsm_script_helper_pid;
- const char *dsm_script_event;
- iu_event_id_t dsm_script_event_id;
- void *dsm_callback_arg;
- script_callback_t *dsm_script_callback;
+ hrtime_t dsm_neg_hrtime;
+ monosec_t dsm_newstart_monosec;
+ monosec_t dsm_curstart_monosec;
+
+ int dsm_script_fd;
+ pid_t dsm_script_pid;
+ pid_t dsm_script_helper_pid;
+ const char *dsm_script_event;
+ iu_event_id_t dsm_script_event_id;
+ void *dsm_callback_arg;
+ script_callback_t *dsm_script_callback;
+
+ iu_timer_id_t dsm_start_timer;
};
#define dsm_isv6 dsm_lif->lif_pif->pif_isv6
@@ -277,7 +279,7 @@ void dhcp_renew(iu_tq_t *, void *);
void dhcp_requesting(iu_tq_t *, void *);
void dhcp_restart(dhcp_smach_t *);
void dhcp_selecting(dhcp_smach_t *);
-void dhcp_start(iu_tq_t *, void *);
+boolean_t set_start_timer(dhcp_smach_t *);
void send_declines(dhcp_smach_t *);
void send_v6_request(dhcp_smach_t *);
boolean_t save_server_id(dhcp_smach_t *, PKT_LIST *);
@@ -307,6 +309,7 @@ void nuke_smach_list(void);
boolean_t schedule_smach_timer(dhcp_smach_t *, int, uint32_t,
iu_tq_callback_t *);
void cancel_offer_timer(dhcp_smach_t *);
+void discard_default_routes(dhcp_smach_t *);
void remove_default_routes(dhcp_smach_t *);
/* Lease-related support functions in states.c */
diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/util.c b/usr/src/cmd/cmd-inet/sbin/dhcpagent/util.c
index 0c63ba8dcb..3d445dff96 100644
--- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/util.c
+++ b/usr/src/cmd/cmd-inet/sbin/dhcpagent/util.c
@@ -314,7 +314,7 @@ daemonize(void)
*/
static boolean_t
-update_default_route(const char *ifname, int type, struct in_addr *gateway_nbo,
+update_default_route(uint32_t ifindex, int type, struct in_addr *gateway_nbo,
int flags)
{
struct {
@@ -343,7 +343,7 @@ update_default_route(const char *ifname, int type, struct in_addr *gateway_nbo,
rtmsg.rm_mask.sin_addr.s_addr = htonl(0);
rtmsg.rm_ifp.sdl_family = AF_LINK;
- rtmsg.rm_ifp.sdl_index = if_nametoindex(ifname);
+ rtmsg.rm_ifp.sdl_index = ifindex;
return (write(rtsock_fd, &rtmsg, sizeof (rtmsg)) == sizeof (rtmsg));
}
@@ -357,12 +357,9 @@ update_default_route(const char *ifname, int type, struct in_addr *gateway_nbo,
*/
boolean_t
-add_default_route(const char *ifname, struct in_addr *gateway_nbo)
+add_default_route(uint32_t ifindex, struct in_addr *gateway_nbo)
{
- if (strchr(ifname, ':') != NULL) /* see README */
- return (B_TRUE);
-
- return (update_default_route(ifname, RTM_ADD, gateway_nbo, RTF_UP));
+ return (update_default_route(ifindex, RTM_ADD, gateway_nbo, RTF_UP));
}
/*
@@ -374,15 +371,12 @@ add_default_route(const char *ifname, struct in_addr *gateway_nbo)
*/
boolean_t
-del_default_route(const char *ifname, struct in_addr *gateway_nbo)
+del_default_route(uint32_t ifindex, struct in_addr *gateway_nbo)
{
- if (strchr(ifname, ':') != NULL)
- return (B_TRUE);
-
if (gateway_nbo->s_addr == htonl(INADDR_ANY)) /* no router */
return (B_TRUE);
- return (update_default_route(ifname, RTM_DELETE, gateway_nbo, 0));
+ return (update_default_route(ifindex, RTM_DELETE, gateway_nbo, 0));
}
/*
diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/util.h b/usr/src/cmd/cmd-inet/sbin/dhcpagent/util.h
index a426a0e601..ead7c513f9 100644
--- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/util.h
+++ b/usr/src/cmd/cmd-inet/sbin/dhcpagent/util.h
@@ -67,8 +67,8 @@ boolean_t cancel_timer(dhcp_timer_t *);
boolean_t schedule_timer(dhcp_timer_t *, iu_tq_callback_t *, void *);
/* miscellaneous */
-boolean_t add_default_route(const char *, struct in_addr *);
-boolean_t del_default_route(const char *, struct in_addr *);
+boolean_t add_default_route(uint32_t, struct in_addr *);
+boolean_t del_default_route(uint32_t, struct in_addr *);
int daemonize(void);
monosec_t monosec(void);
void print_server_msg(dhcp_smach_t *, const char *, uint_t);
diff --git a/usr/src/cmd/cmd-inet/usr.lib/in.ndpd/main.c b/usr/src/cmd/cmd-inet/usr.lib/in.ndpd/main.c
index d29ccc361e..27716cabce 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/in.ndpd/main.c
+++ b/usr/src/cmd/cmd-inet/usr.lib/in.ndpd/main.c
@@ -1090,8 +1090,11 @@ solicit_event(struct phyint *pi, enum solicit_events event, uint_t elapsed)
case INIT_SOLICIT:
solicit(&v6allrouters, pi);
if (--pi->pi_sol_count == 0) {
- logmsg(LOG_DEBUG, "solicit_event: giving up on %s\n",
- pi->pi_name);
+ if (debug & D_STATE) {
+ logmsg(LOG_DEBUG, "solicit_event: no routers "
+ "found on %s; assuming default flags\n",
+ pi->pi_name);
+ }
if (pi->pi_StatefulAddrConf) {
pi->pi_ra_flags |= ND_RA_FLAG_MANAGED |
ND_RA_FLAG_OTHER;
diff --git a/usr/src/lib/libdhcpagent/common/dhcpagent_ipc.c b/usr/src/lib/libdhcpagent/common/dhcpagent_ipc.c
index 8a3ec18060..0d5cc7f8ff 100644
--- a/usr/src/lib/libdhcpagent/common/dhcpagent_ipc.c
+++ b/usr/src/lib/libdhcpagent/common/dhcpagent_ipc.c
@@ -76,6 +76,12 @@ static int dhcp_ipc_timed_read(int, void *, unsigned int, int *);
static int getinfo_ifnames(const char *, dhcp_optnum_t *, DHCP_OPT **);
static char *get_ifnames(int, int);
+/* must be kept in sync with enum in dhcpagent_ipc.h */
+static const char *ipc_typestr[] = {
+ "drop", "extend", "ping", "release", "start", "status",
+ "inform", "get_tag"
+};
+
/*
* dhcp_ipc_alloc_request(): allocates a dhcp_ipc_request_t of the given type
* and interface, with a timeout of 0.
@@ -636,6 +642,25 @@ dhcp_ipc_strerror(int error)
}
/*
+ * dhcp_string_to_request(): maps a string into a request code
+ *
+ * input: const char *: the string to map
+ * output: dhcp_ipc_type_t: the request code, or -1 if unknown
+ */
+
+dhcp_ipc_type_t
+dhcp_string_to_request(const char *request)
+{
+ unsigned int i;
+
+ for (i = 0; i < DHCP_NIPC; i++)
+ if (strcmp(ipc_typestr[i], request) == 0)
+ return ((dhcp_ipc_type_t)i);
+
+ return ((dhcp_ipc_type_t)-1);
+}
+
+/*
* dhcp_ipc_type_to_string(): maps an ipc command code into a human-readable
* string
*
@@ -646,15 +671,10 @@ dhcp_ipc_strerror(int error)
const char *
dhcp_ipc_type_to_string(dhcp_ipc_type_t type)
{
- static const char *typestr[] = {
- "drop", "extend", "ping", "release", "start", "status",
- "inform", "get_tag"
- };
-
if (type < 0 || type >= DHCP_NIPC)
return ("unknown");
else
- return (typestr[(int)type]);
+ return (ipc_typestr[(int)type]);
}
/*
diff --git a/usr/src/lib/libdhcpagent/common/dhcpagent_ipc.h b/usr/src/lib/libdhcpagent/common/dhcpagent_ipc.h
index 91236a85bb..58f06c9d3f 100644
--- a/usr/src/lib/libdhcpagent/common/dhcpagent_ipc.h
+++ b/usr/src/lib/libdhcpagent/common/dhcpagent_ipc.h
@@ -85,7 +85,7 @@ typedef enum {
* code in dhcpagent relies on the numeric values of these
* requests -- but there's no sane reason to change them anyway.
*
- * If any commands are changed, added, or removed, see the typestr[]
+ * If any commands are changed, added, or removed, see the ipc_typestr[]
* array in dhcpagent_ipc.c.
*/
diff --git a/usr/src/lib/libdhcpagent/common/dhcpagent_util.c b/usr/src/lib/libdhcpagent/common/dhcpagent_util.c
index 61101bb66c..e6d95cd0d1 100644
--- a/usr/src/lib/libdhcpagent/common/dhcpagent_util.c
+++ b/usr/src/lib/libdhcpagent/common/dhcpagent_util.c
@@ -79,38 +79,6 @@ dhcp_state_to_string(DHCPSTATE state)
}
/*
- * dhcp_string_to_request(): maps a string into a request code
- *
- * input: const char *: the string to map
- * output: dhcp_ipc_type_t: the request code, or -1 if unknown
- */
-
-dhcp_ipc_type_t
-dhcp_string_to_request(const char *request)
-{
- static struct {
- const char *string;
- dhcp_ipc_type_t type;
- } types[] = {
- { "drop", DHCP_DROP },
- { "extend", DHCP_EXTEND },
- { "inform", DHCP_INFORM },
- { "ping", DHCP_PING },
- { "release", DHCP_RELEASE },
- { "start", DHCP_START },
- { "status", DHCP_STATUS }
- };
-
- unsigned int i;
-
- for (i = 0; i < (sizeof (types) / sizeof (*types)); i++)
- if (strcmp(types[i].string, request) == 0)
- return (types[i].type);
-
- return (-1);
-}
-
-/*
* dhcp_start_agent(): starts the agent if not already running
*
* input: int: number of seconds to wait for agent to start (-1 is forever)