Import dhcpcd-5.1.4

Changes from dhcpcd-5.1.3 include:
 * dhcpcd logs even in quiet mode.
 * Sleep for 1/100th of a second to give time for kernel to send RELEASE.
 * -S option now works.
 * Only warn about using CSR on bind.
This commit is contained in:
roy 2009-12-23 08:30:06 +00:00
parent 07dad0134f
commit 5f8a05b17d
9 changed files with 170 additions and 37 deletions

View File

@ -222,6 +222,7 @@ bind_interface(void *arg)
add_timeout_sec(lease->rebindtime, start_rebind, iface);
add_timeout_sec(lease->leasetime, start_expire, iface);
}
ifo->options &= ~ DHCPCD_CSR_WARNED;
configure(iface);
daemonise();
state->state = DHS_BOUND;

View File

@ -547,7 +547,8 @@ get_routes(const struct interface *iface)
return nrt;
}
return get_option_routes(iface->name, iface->state->new);
return get_option_routes(iface->state->new,
iface->name, &iface->state->options->options);
}
static struct rt *

View File

@ -28,7 +28,7 @@
#define CONFIG_H
#define PACKAGE "dhcpcd"
#define VERSION "5.1.3"
#define VERSION "5.1.4"
#ifndef CONFIG
# define CONFIG SYSCONFDIR "/" PACKAGE ".conf"

View File

@ -70,7 +70,7 @@ static const struct dhcp_opt const dhcp_opts[] = {
{ 1, IPV4 | REQUEST, "subnet_mask" },
/* RFC 3442 states that the CSR has to come before all other
* routes. For completeness, we also specify static routes,
* then routers. */
* then routers. */
{ 121, RFC3442, "classless_static_routes" },
{ 249, RFC3442, "ms_classless_static_routes" },
{ 33, IPV4 | ARRAY | REQUEST, "static_routes" },
@ -701,7 +701,8 @@ route_netmask(uint32_t ip_in)
* If we have a CSR then we only use that.
* Otherwise we add static routes and then routers. */
struct rt *
get_option_routes(const char *ifname, const struct dhcp_message *dhcp)
get_option_routes(const struct dhcp_message *dhcp,
const char *ifname, int *opts)
{
const uint8_t *p;
const uint8_t *e;
@ -716,9 +717,11 @@ get_option_routes(const char *ifname, const struct dhcp_message *dhcp)
p = get_option(dhcp, DHO_MSCSR, &len, NULL);
if (p) {
routes = decode_rfc3442_rt(len, p);
if (routes) {
syslog(LOG_DEBUG, "%s: using Classless Static Routes (RFC3442)",
ifname);
if (routes && !(*opts & DHCPCD_CSR_WARNED)) {
syslog(LOG_DEBUG,
"%s: using Classless Static Routes (RFC3442)",
ifname);
*opts |= DHCPCD_CSR_WARNED;
return routes;
}
}
@ -787,12 +790,12 @@ encode_rfc1035(const char *src, uint8_t *dst)
return p - dst;
}
#define PUTADDR(_type, _val) \
{ \
*p++ = _type; \
*p++ = 4; \
memcpy(p, &_val.s_addr, 4); \
p += 4; \
#define PUTADDR(_type, _val) \
{ \
*p++ = _type; \
*p++ = 4; \
memcpy(p, &_val.s_addr, 4); \
p += 4; \
}
int
@ -1137,7 +1140,7 @@ print_string(char *s, ssize_t len, int dl, const uint8_t *data)
case '\'': /* FALLTHROUGH */
case '$': /* FALLTHROUGH */
case '`': /* FALLTHROUGH */
case '\\': /* FALLTHROUGH */
case '\\':
if (s) {
if (len < 3) {
errno = ENOBUFS;
@ -1392,4 +1395,6 @@ get_lease(struct dhcp_lease *lease, const struct dhcp_message *dhcp)
lease->renewaltime = 0;
if (get_option_uint32(&lease->rebindtime, dhcp, DHO_REBINDTIME) != 0)
lease->rebindtime = 0;
if (get_option_addr(&lease->server, dhcp, DHO_SERVERID) != 0)
lease->server.s_addr = INADDR_ANY;
}

View File

@ -184,7 +184,7 @@ int get_option_uint8(uint8_t *, const struct dhcp_message *, uint8_t);
#define is_bootp(m) (m && \
!IN_LINKLOCAL(htonl((m)->yiaddr)) && \
get_option_uint8(NULL, m, DHO_MESSAGETYPE) == -1)
struct rt *get_option_routes(const char *, const struct dhcp_message *);
struct rt *get_option_routes(const struct dhcp_message *, const char *, int *);
ssize_t configure_env(char **, const char *, const struct dhcp_message *,
const struct if_options *);

View File

@ -0,0 +1,86 @@
# Sample dhcpcd hook for ypbind
# This script is only suitable for the Linux version.
# Distributions may want to just have their command here instead of this
if [ -x /etc/rc.d/ypbind ]; then
ypbind_restart_cmd="/etc/rc.d/ypbind restart"
ypbind_stop_cmd="/etc/rc.d/ypbind stop"
elif [ -x /usr/local/etc/rc.d/ypbind ]; then
ypbind_restart_cmd="/usr/local/etc/rc.d/ypbind restart"
ypbind_stop_cmd="/usr/local/etc/rc.d/ypbind stop"
fi
ypbind_dir="$state_dir/ypbind"
best_domain()
{
local i=
for i in $interfaces; do
if [ -e "$ypbind_dir/$i" ]; then
cat "$ypbind_dir/$i"
fi
done
return 1
}
make_yp_binding()
{
[ -d "$ypbind_dir" ] || mkdir -p "$ypbind_dir"
echo "$new_nis_domain" >"$ypbind_dir/$interface"
local nd="$(best_domain)"
local cf=/var/yp/binding/"$new_nis_domain".ypservers
if [ -n "$new_nis_servers" ]; then
local ncf="$cf.$interface" x=
rm -f "$ncf"
for x in $new_nis_servers; do
echo "$x" >>"$ncf"
done
change_file "$cf" "$ncf"
else
# Because this is not an if .. fi then we can use $? below
[ -e "$cf" ] && rm "$cf"
fi
if [ $? = 0 -o "$nd" != "$(domainname)" ]; then
domainname "$nd"
if [ -n "$ypbind_restart_cmd" ]; then
eval $ypbind_restart_cmd
fi
fi
}
restore_yp_binding()
{
rm -f "$ypbind_dir/$interface"
local nd="$(best_domain)"
# We need to stop ypbind if there is no best domain
# otherwise it will just stall as we cannot set domainname
# to blank :/
if [ -z "$nd" ]; then
if [ -n "$ypbind_stop_cmd" ]; then
eval $ypbind_stop_cmd
fi
elif [ "$nd" != "$(domainname)" ]; then
domainname "$nd"
if [ -n "$ypbind_restart_cmd" ]; then
eval $ypbind_restart_cmd
fi
fi
}
case "$reason" in
PREINIT)
rm -f "$ypbind_dir/$interface"
;;
TEST)
;;
*)
if [ -n "$new_nis_domain" ]; then
make_yp_binding
elif [ -n "$old_nis_domain" ]; then
restore_yp_binding
fi
;;
esac

View File

@ -72,6 +72,11 @@ const char copyright[] = "Copyright (c) 2006-2009 Roy Marples";
/* We should define a maximum for the NAK exponential backoff */
#define NAKOFF_MAX 60
/* Wait N nanoseconds between sending a RELEASE and dropping the address.
* This gives the kernel enough time to actually send it. */
#define RELEASE_DELAY_S 0
#define RELEASE_DELAY_NS 10000000
int options = 0;
int pidfd = -1;
struct interface *ifaces = NULL;
@ -518,10 +523,9 @@ handle_dhcp(struct interface *iface, struct dhcp_message **dhcpp)
{
lease->frominfo = 0;
lease->addr.s_addr = dhcp->yiaddr;
lease->server.s_addr = INADDR_ANY;
if (type != 0)
get_option_addr(&lease->server,
dhcp, DHO_SERVERID);
if (type == 0 ||
get_option_addr(&lease->server, dhcp, DHO_SERVERID) != 0)
lease->server.s_addr = INADDR_ANY;
log_dhcp(LOG_INFO, "offered", iface, dhcp);
free(state->offer);
state->offer = dhcp;
@ -572,9 +576,10 @@ handle_dhcp(struct interface *iface, struct dhcp_message **dhcpp)
state->offer = dhcp;
*dhcpp = NULL;
}
lease->frominfo = 0;
lease->frominfo = 0;
delete_timeout(NULL, iface);
/* We now have an offer, so close the DHCP sockets.
* This allows us to safely ARP when broken DHCP servers send an ACK
* follows by an invalid NAK. */
@ -704,13 +709,20 @@ open_sockets(struct interface *iface)
static void
send_release(struct interface *iface)
{
struct timespec ts;
if (iface->state->lease.addr.s_addr &&
!IN_LINKLOCAL(htonl(iface->state->lease.addr.s_addr)))
{
syslog(LOG_INFO, "%s: releasing lease of %s",
iface->name, inet_ntoa(iface->state->lease.addr));
open_sockets(iface);
iface->state->xid = arc4random();
send_message(iface, DHCP_RELEASE, NULL);
/* Give the packet a chance to go before dropping the ip */
ts.tv_sec = RELEASE_DELAY_S;
ts.tv_nsec = RELEASE_DELAY_NS;
nanosleep(&ts, NULL);
drop_config(iface, "RELEASE");
}
unlink(iface->leasefile);
@ -1630,7 +1642,7 @@ main(int argc, char **argv)
if (options & DHCPCD_DEBUG)
setlogmask(LOG_UPTO(LOG_DEBUG));
else if (options & DHCPCD_QUIET)
setlogmask(LOG_UPTO(LOG_WARNING));
close(STDERR_FILENO);
if (!(options & DHCPCD_TEST)) {
/* If we have any other args, we should run as a single dhcpcd
@ -1805,16 +1817,38 @@ main(int argc, char **argv)
if (iface->carrier != LINK_DOWN)
opt = 1;
}
if (opt == 0 &&
options & DHCPCD_LINK &&
!(options & DHCPCD_WAITIP))
{
syslog(LOG_WARNING, "no interfaces have a carrier");
daemonise();
} else if (options & DHCPCD_DAEMONISE && ifo->timeout > 0) {
if (options & DHCPCD_IPV4LL)
options |= DHCPCD_TIMEOUT_IPV4LL;
add_timeout_sec(ifo->timeout, handle_exit_timeout, NULL);
if (!(options & DHCPCD_BACKGROUND)) {
/* If we don't have a carrier, we may have to wait for a second
* before one becomes available if we brought an interface up. */
if (opt == 0 &&
options & DHCPCD_LINK &&
options & DHCPCD_WAITUP &&
!(options & DHCPCD_WAITIP))
{
ts.tv_sec = 1;
ts.tv_nsec = 0;
nanosleep(&ts, NULL);
for (iface = ifaces; iface; iface = iface->next) {
handle_carrier(iface->name);
if (iface->carrier != LINK_DOWN) {
opt = 1;
break;
}
}
}
if (opt == 0 &&
options & DHCPCD_LINK &&
!(options & DHCPCD_WAITIP))
{
syslog(LOG_WARNING, "no interfaces have a carrier");
daemonise();
} else if (options & DHCPCD_DAEMONISE && ifo->timeout > 0) {
if (options & DHCPCD_IPV4LL)
options |= DHCPCD_TIMEOUT_IPV4LL;
add_timeout_sec(ifo->timeout, handle_exit_timeout, NULL);
}
}
free_options(ifo);

View File

@ -37,7 +37,7 @@
/* Don't set any optional arguments here so we retain POSIX
* compatibility with getopt */
#define IF_OPTS "bc:de:f:gh:i:kl:m:no:pqr:s:t:u:v:wxy:z:ABC:DEF:GI:KLN:O:Q:TVW:X:Z:"
#define IF_OPTS "bc:de:f:gh:i:kl:m:no:pqr:s:t:u:v:wxy:z:ABC:DEF:GI:KLN:O:Q:S:TVW:X:Z:"
#define DEFAULT_TIMEOUT 30
#define DEFAULT_REBOOT 10
@ -72,6 +72,8 @@
#define DHCPCD_VENDORRAW (1 << 23)
#define DHCPCD_TIMEOUT_IPV4LL (1 << 24)
#define DHCPCD_WAITIP (1 << 25)
#define DHCPCD_WAITUP (1 << 26)
#define DHCPCD_CSR_WARNED (1 << 27)
extern const struct option cf_options[];

View File

@ -100,7 +100,6 @@ inet_cidrtoaddr(int cidr, struct in_addr *addr)
addr->s_addr = 0;
if (ocets > 0) {
memset(&addr->s_addr, 255, (size_t)ocets - 1);
memset((unsigned char *)&addr->s_addr + (ocets - 1),
(256 - (1 << (32 - cidr) % 8)), 1);
}
@ -389,12 +388,17 @@ discover_interfaces(int argc, char * const *argv)
continue;
/* Bring the interface up if not already */
if (!(ifp->flags & IFF_UP) &&
if (!(ifp->flags & IFF_UP)
#ifdef SIOCGIFMEDIA
carrier_status(ifp) != -1 &&
&& carrier_status(ifp) != -1
#endif
up_interface(ifp) != 0)
syslog(LOG_ERR, "%s: up_interface: %m", ifp->name);
)
{
if (up_interface(ifp) == 0)
options |= DHCPCD_WAITUP;
else
syslog(LOG_ERR, "%s: up_interface: %m", ifp->name);
}
/* Don't allow loopback unless explicit */
if (ifp->flags & IFF_LOOPBACK) {