diff options
| author | carlsonj <none@none> | 2007-04-25 11:54:45 -0700 | 
|---|---|---|
| committer | carlsonj <none@none> | 2007-04-25 11:54:45 -0700 | 
| commit | cfb9c9abdc2696bc174bb10a3a28552dc917b98f (patch) | |
| tree | 66f98c1f0a916d6eacc66a9141e1153208695386 /usr/src | |
| parent | 8cb045d062db356cee4eaacd954f772ab314f6f3 (diff) | |
| download | illumos-joyent-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
Diffstat (limited to 'usr/src')
| -rw-r--r-- | usr/src/cmd/cmd-inet/sbin/dhcpagent/agent.c | 15 | ||||
| -rw-r--r-- | usr/src/cmd/cmd-inet/sbin/dhcpagent/bound.c | 13 | ||||
| -rw-r--r-- | usr/src/cmd/cmd-inet/sbin/dhcpagent/inform.c | 9 | ||||
| -rw-r--r-- | usr/src/cmd/cmd-inet/sbin/dhcpagent/init_reboot.c | 6 | ||||
| -rw-r--r-- | usr/src/cmd/cmd-inet/sbin/dhcpagent/interface.c | 16 | ||||
| -rw-r--r-- | usr/src/cmd/cmd-inet/sbin/dhcpagent/release.c | 18 | ||||
| -rw-r--r-- | usr/src/cmd/cmd-inet/sbin/dhcpagent/request.c | 10 | ||||
| -rw-r--r-- | usr/src/cmd/cmd-inet/sbin/dhcpagent/select.c | 33 | ||||
| -rw-r--r-- | usr/src/cmd/cmd-inet/sbin/dhcpagent/states.c | 47 | ||||
| -rw-r--r-- | usr/src/cmd/cmd-inet/sbin/dhcpagent/states.h | 73 | ||||
| -rw-r--r-- | usr/src/cmd/cmd-inet/sbin/dhcpagent/util.c | 18 | ||||
| -rw-r--r-- | usr/src/cmd/cmd-inet/sbin/dhcpagent/util.h | 4 | ||||
| -rw-r--r-- | usr/src/cmd/cmd-inet/usr.lib/in.ndpd/main.c | 7 | ||||
| -rw-r--r-- | usr/src/lib/libdhcpagent/common/dhcpagent_ipc.c | 32 | ||||
| -rw-r--r-- | usr/src/lib/libdhcpagent/common/dhcpagent_ipc.h | 2 | ||||
| -rw-r--r-- | usr/src/lib/libdhcpagent/common/dhcpagent_util.c | 32 | 
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) | 
