summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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)