summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorbket <bket@cvs.openbsd.org>2018-07-27 06:20:02 +0000
committerbket <bket@cvs.openbsd.org>2018-07-27 06:20:02 +0000
commitce3c847135e3401f56f09269cf05166ae9253b89 (patch)
treec4a8c1d9c9d939f6350e2f8c64d556301c31ae1e /sbin
parent49027b41bed3f7919f1c246e55b14c1d31da7079 (diff)
Enable slaacd(8) to set MTU on an interface.
If a router advertisement message with the MTU option is received on an interface slaacd will set the specified MTU on that interface. Lots of help from florian@. Thank you! OK florian@
Diffstat (limited to 'sbin')
-rw-r--r--sbin/slaacd/engine.c37
-rw-r--r--sbin/slaacd/engine.h3
-rw-r--r--sbin/slaacd/slaacd.c14
3 files changed, 50 insertions, 4 deletions
diff --git a/sbin/slaacd/engine.c b/sbin/slaacd/engine.c
index 58c39fb5c4a..228e0576409 100644
--- a/sbin/slaacd/engine.c
+++ b/sbin/slaacd/engine.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: engine.c,v 1.29 2018/07/23 17:25:52 florian Exp $ */
+/* $OpenBSD: engine.c,v 1.30 2018/07/27 06:20:01 bket Exp $ */
/*
* Copyright (c) 2017 Florian Obser <florian@openbsd.org>
@@ -164,6 +164,7 @@ struct radv {
LIST_HEAD(, radv_rdns) rdns_servers;
uint32_t dnssl_lifetime;
LIST_HEAD(, radv_dnssl) dnssls;
+ uint32_t mtu;
};
struct address_proposal {
@@ -185,6 +186,7 @@ struct address_proposal {
uint32_t vltime;
uint32_t pltime;
uint8_t soiikey[SLAACD_SOIIKEY_LEN];
+ uint32_t mtu;
};
struct dfr_proposal {
@@ -215,6 +217,7 @@ struct slaacd_iface {
struct sockaddr_in6 ll_address;
uint8_t soiikey[SLAACD_SOIIKEY_LEN];
int link_state;
+ uint32_t cur_mtu;
LIST_HEAD(, radv) radvs;
LIST_HEAD(, address_proposal) addr_proposals;
LIST_HEAD(, dfr_proposal) dfr_proposals;
@@ -1193,6 +1196,7 @@ parse_ra(struct slaacd_iface *iface, struct imsg_ra *ra)
struct nd_opt_prefix_info *prf;
struct nd_opt_rdnss *rdnss;
struct nd_opt_dnssl *dnssl;
+ struct nd_opt_mtu *mtu;
struct in6_addr *in6;
int i;
char *nssl;
@@ -1294,10 +1298,24 @@ parse_ra(struct slaacd_iface *iface, struct imsg_ra *ra)
LIST_INSERT_HEAD(&radv->dnssls, ra_dnssl, entries);
break;
+ case ND_OPT_MTU:
+ if (nd_opt_hdr->nd_opt_len != 1) {
+ log_warnx("invalid ND_OPT_MTU: len != 1");
+ goto err;
+ }
+ mtu = (struct nd_opt_mtu*) nd_opt_hdr;
+ radv->mtu = ntohl(mtu->nd_opt_mtu_mtu);
+
+ /* path MTU cannot be less than IPV6_MMTU */
+ if (radv->mtu < IPV6_MMTU) {
+ radv->mtu = 0;
+ log_warnx("invalid advertised MTU");
+ }
+
+ break;
case ND_OPT_REDIRECTED_HEADER:
case ND_OPT_SOURCE_LINKADDR:
case ND_OPT_TARGET_LINKADDR:
- case ND_OPT_MTU:
case ND_OPT_ROUTE_INFO:
#if 0
log_debug("\tOption: %u (len: %u) not implemented",
@@ -1812,6 +1830,13 @@ void update_iface_ra(struct slaacd_iface *iface, struct radv *ra)
addr_proposal->vltime = TWO_HOURS;
addr_proposal->pltime = prefix->pltime;
+ if (ra->mtu == iface->cur_mtu)
+ addr_proposal->mtu = 0;
+ else {
+ addr_proposal->mtu = ra->mtu;
+ iface->cur_mtu = ra->mtu;
+ }
+
log_debug("%s, addr state: %s", __func__,
proposal_state_name[addr_proposal->state]);
@@ -1902,6 +1927,7 @@ configure_address(struct address_proposal *addr_proposal)
address.vltime = addr_proposal->vltime;
address.pltime = addr_proposal->pltime;
address.privacy = addr_proposal->privacy;
+ address.mtu = addr_proposal->mtu;
engine_imsg_compose_main(IMSG_CONFIGURE_ADDRESS, 0, &address,
sizeof(address));
@@ -1950,6 +1976,13 @@ gen_address_proposal(struct slaacd_iface *iface, struct radv *ra, struct
addr_proposal->pltime = prefix->pltime;
}
+ if (ra->mtu == iface->cur_mtu)
+ addr_proposal->mtu = 0;
+ else {
+ addr_proposal->mtu = ra->mtu;
+ iface->cur_mtu = ra->mtu;
+ }
+
gen_addr(iface, prefix, addr_proposal, privacy);
tv.tv_sec = 0;
diff --git a/sbin/slaacd/engine.h b/sbin/slaacd/engine.h
index e7f520f1fba..8a9dbb7af35 100644
--- a/sbin/slaacd/engine.h
+++ b/sbin/slaacd/engine.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: engine.h,v 1.1 2017/06/03 10:00:29 florian Exp $ */
+/* $OpenBSD: engine.h,v 1.2 2018/07/27 06:20:01 bket Exp $ */
/*
* Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
@@ -34,6 +34,7 @@ struct imsg_configure_address {
struct in6_addr mask;
uint32_t vltime;
uint32_t pltime;
+ uint32_t mtu;
int privacy;
};
diff --git a/sbin/slaacd/slaacd.c b/sbin/slaacd/slaacd.c
index 7afd9dc3ec7..344fc148537 100644
--- a/sbin/slaacd/slaacd.c
+++ b/sbin/slaacd/slaacd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: slaacd.c,v 1.27 2018/07/23 17:25:52 florian Exp $ */
+/* $OpenBSD: slaacd.c,v 1.28 2018/07/27 06:20:01 bket Exp $ */
/*
* Copyright (c) 2017 Florian Obser <florian@openbsd.org>
@@ -761,6 +761,18 @@ configure_interface(struct imsg_configure_address *address)
if (ioctl(ioctl_sock, SIOCAIFADDR_IN6, &in6_addreq) < 0)
fatal("SIOCAIFADDR_IN6");
+
+ if (address->mtu) {
+ struct ifreq ifr;
+
+ (void)strlcpy(ifr.ifr_name, in6_addreq.ifra_name,
+ sizeof(ifr.ifr_name));
+ ifr.ifr_mtu = address->mtu;
+ log_debug("Setting MTU to %d", ifr.ifr_mtu);
+
+ if (ioctl(ioctl_sock, SIOCSIFMTU, &ifr) < 0)
+ log_warn("failed to set MTU");
+ }
}
void