diff options
Diffstat (limited to 'usr/src/cmd/cmd-inet/sbin/dhcpagent')
-rw-r--r-- | usr/src/cmd/cmd-inet/sbin/dhcpagent/Makefile | 1 | ||||
-rw-r--r-- | usr/src/cmd/cmd-inet/sbin/dhcpagent/bound.c | 25 | ||||
-rw-r--r-- | usr/src/cmd/cmd-inet/sbin/dhcpagent/defaults.c | 4 | ||||
-rw-r--r-- | usr/src/cmd/cmd-inet/sbin/dhcpagent/defaults.h | 4 | ||||
-rw-r--r-- | usr/src/cmd/cmd-inet/sbin/dhcpagent/dhcpagent.dfl | 6 | ||||
-rw-r--r-- | usr/src/cmd/cmd-inet/sbin/dhcpagent/interface.c | 36 | ||||
-rw-r--r-- | usr/src/cmd/cmd-inet/sbin/dhcpagent/interface.h | 4 |
7 files changed, 74 insertions, 6 deletions
diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/Makefile b/usr/src/cmd/cmd-inet/sbin/dhcpagent/Makefile index b52683dee2..550c2aa118 100644 --- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/Makefile +++ b/usr/src/cmd/cmd-inet/sbin/dhcpagent/Makefile @@ -34,6 +34,7 @@ OBJS = adopt.o agent.o async.o bound.o class_id.o defaults.o inform.o \ request.o script_handler.o select.o states.o util.o include ../../../Makefile.cmd +include ../../../Makefile.ctf SRCS = $(OBJS:%.o=%.c) POFILES = $(OBJS:%.o=%.po) diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/bound.c b/usr/src/cmd/cmd-inet/sbin/dhcpagent/bound.c index 0e5d496af2..8fc093f684 100644 --- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/bound.c +++ b/usr/src/cmd/cmd-inet/sbin/dhcpagent/bound.c @@ -455,13 +455,15 @@ void dhcp_bound_complete(dhcp_smach_t *dsmp) { PKT_LIST *ack = dsmp->dsm_ack; + DHCP_OPT *mtu; DHCP_OPT *routes; DHCP_OPT *router_list; int i; DHCPSTATE oldstate; dhcp_lif_t *lif; boolean_t ignore_routes = B_FALSE, ignore_router_list = B_FALSE; - boolean_t manage_classless_routes; + boolean_t ignore_mtu = B_FALSE; + boolean_t manage_classless_routes, manage_mtu; /* * Do bound state entry processing only if running IPv4. There's no @@ -484,6 +486,7 @@ dhcp_bound_complete(dhcp_smach_t *dsmp) manage_classless_routes = df_get_bool(dsmp->dsm_name, dsmp->dsm_isv6, DF_CLASSLESS_ROUTES); + manage_mtu = df_get_bool(dsmp->dsm_name, dsmp->dsm_isv6, DF_SET_MTU); /* * Check to see if the default route or classless routes options appear @@ -491,6 +494,9 @@ dhcp_bound_complete(dhcp_smach_t *dsmp) */ for (i = 0; i < dsmp->dsm_pillen; i++) { switch (dsmp->dsm_pil[i]) { + case CD_MTU: + ignore_mtu = B_TRUE; + break; case CD_ROUTER: ignore_router_list = B_TRUE; break; @@ -501,8 +507,23 @@ dhcp_bound_complete(dhcp_smach_t *dsmp) } /* - * XXX Set interface MTU... + * If the server provides a valid MTU option, and the operator has not + * disabled MTU management, configure the MTU on the interface now. + * The SIOCSLIFMTU ioctl does not work for IPv4 logicals. */ + if (manage_mtu && !ignore_mtu && strchr(lif->lif_name, ':') == NULL && + (mtu = ack->opts[CD_MTU]) != NULL && + mtu->len == sizeof (uint16_t)) { + uint16_t mtuval; + + (void) memcpy(&mtuval, mtu->value, sizeof (mtuval)); + mtuval = ntohs(mtuval); + + if (!set_lif_mtu(lif, mtuval)) { + dhcpmsg(MSG_ERR, "dhcp_bound_complete: could not set " + "interface MTU to %u", (uint_t)mtuval); + } + } /* * XXX Get classless routes... diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/defaults.c b/usr/src/cmd/cmd-inet/sbin/dhcpagent/defaults.c index 634438be1a..34e502778e 100644 --- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/defaults.c +++ b/usr/src/cmd/cmd-inet/sbin/dhcpagent/defaults.c @@ -46,9 +46,8 @@ struct dhcp_default { }; /* - * note: keep in the same order as tunable parameter constants in defaults.h + * NOTE: Keep in the same order as tunable parameter constants in defaults.h */ - static struct dhcp_default defaults[] = { { "RELEASE_ON_SIGTERM", "0", 0, 0 }, { "IGNORE_FAILED_ARP", "1", 0, -1 }, @@ -66,6 +65,7 @@ static struct dhcp_default defaults[] = { { "DNS_DOMAINNAME", NULL, 0, 0 }, { "ADOPT_DOMAINNAME", "0", 0, 0 }, { "CLASSLESS_ROUTES", "1", 0, 0 }, + { "SET_MTU", "1", 0, 0 } }; diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/defaults.h b/usr/src/cmd/cmd-inet/sbin/dhcpagent/defaults.h index b2aec7fcea..537f3551f2 100644 --- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/defaults.h +++ b/usr/src/cmd/cmd-inet/sbin/dhcpagent/defaults.h @@ -40,9 +40,8 @@ extern "C" { #endif /* - * tunable parameters -- keep in the same order as defaults[] in defaults.c + * Tunable parameters -- keep in the same order as defaults[] in defaults.c */ - enum { DF_RELEASE_ON_SIGTERM, /* send RELEASE on each if upon SIGTERM */ _UNUSED_DF_IGNORE_FAILED_ARP, @@ -60,6 +59,7 @@ enum { DF_DNS_DOMAINNAME, /* static domain name if not in --reqhost */ DF_ADOPT_DOMAINNAME, /* adopt DHCP domain if not in --reqhost */ DF_CLASSLESS_ROUTES, /* manage additional routes (option 121) */ + DF_SET_MTU /* set interface MTU (option 26) */ }; #define DHCP_AGENT_DEFAULTS "/etc/default/dhcpagent" diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/dhcpagent.dfl b/usr/src/cmd/cmd-inet/sbin/dhcpagent/dhcpagent.dfl index e457264c4d..edee460623 100644 --- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/dhcpagent.dfl +++ b/usr/src/cmd/cmd-inet/sbin/dhcpagent/dhcpagent.dfl @@ -23,6 +23,7 @@ # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # Copyright (c) 2016-2017, Chris Fraire <cfraire@me.com>. +# Copyright 2019, Joyent, Inc. # # @@ -167,6 +168,11 @@ # # CLASSLESS_ROUTES=no +# XXX By default, the DHCP agent will set the MTU of the link if the MTU option +# (26) is provided by the server. To prevent this, uncomment the following +# line. +# +# SET_MTU=no # By default, a parameter request list requesting a subnet mask (1), router # (3), DNS server (6), hostname (12), DNS domain (15), MTU (26), broadcast diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/interface.c b/usr/src/cmd/cmd-inet/sbin/dhcpagent/interface.c index fd18717259..3e4a2dd285 100644 --- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/interface.c +++ b/usr/src/cmd/cmd-inet/sbin/dhcpagent/interface.c @@ -438,6 +438,7 @@ insert_lif(dhcp_pif_t *pif, const char *lname, int *error) lif->lif_max = 1024; else lif->lif_max = lifr.lifr_mtu; + lif->lif_mtu_orig = lif->lif_mtu = lif->lif_max; if (ioctl(fd, SIOCGLIFADDR, &lifr) == -1) { if (errno == ENXIO) @@ -1227,6 +1228,41 @@ clear_lif_dhcp(dhcp_lif_t *lif) (void) ioctl(fd, SIOCSLIFFLAGS, &lifr); } +boolean_t +set_lif_mtu(dhcp_lif_t *lif, uint_t mtu) +{ + struct lifreq lifr; + int fd = lif->lif_pif->pif_isv6 ? v6_sock_fd : v4_sock_fd; + + if (lif->lif_mtu == mtu) { + /* + * We set the MTU to this value already. + */ + return (B_TRUE); + } + + (void) memset(&lifr, 0, sizeof (lifr)); + (void) strlcpy(lifr.lifr_name, lif->lif_name, LIFNAMSIZ); + lifr.lifr_mtu = mtu; + + if (ioctl(fd, SIOCSLIFMTU, &lifr) == -1) { + return (B_FALSE); + } + + lif->lif_mtu = mtu; + return (B_TRUE); +} + +boolean_t +clear_lif_mtu(dhcp_lif_t *lif) +{ + if (lif->lif_mtu == lif->lif_mtu_orig) { + return (B_TRUE); + } + + return (set_lif_mtu(lif, lif->lif_mtu_orig)); +} + /* * set_lif_deprecated(): Set the "deprecated" flag to tell users that this * address will be going away. As the interface is diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/interface.h b/usr/src/cmd/cmd-inet/sbin/dhcpagent/interface.h index 446adfb36f..d164adf3a9 100644 --- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/interface.h +++ b/usr/src/cmd/cmd-inet/sbin/dhcpagent/interface.h @@ -76,6 +76,8 @@ struct dhcp_lif_s { dhcp_smach_t *lif_smachs; /* pointer to list of state machines */ dhcp_lease_t *lif_lease; /* backpointer to lease holding LIF */ uint64_t lif_flags; /* Interface flags (IFF_*) */ + uint_t lif_mtu; /* Interface MTU */ + uint_t lif_mtu_orig; /* Original interface MTU */ int lif_sock_ip_fd; /* Bound to addr.BOOTPC for src addr */ iu_event_id_t lif_packet_id; /* event packet id */ uint_t lif_max; /* maximum IP message size */ @@ -183,6 +185,8 @@ dhcp_lif_t *attach_lif(const char *, boolean_t, int *); int set_lif_dhcp(dhcp_lif_t *); void set_lif_deprecated(dhcp_lif_t *); boolean_t clear_lif_deprecated(dhcp_lif_t *); +boolean_t set_lif_mtu(dhcp_lif_t *, uint_t); +boolean_t clear_lif_mtu(dhcp_lif_t *); boolean_t open_ip_lif(dhcp_lif_t *, in_addr_t, boolean_t); void close_ip_lif(dhcp_lif_t *); void lif_mark_decline(dhcp_lif_t *, const char *); |