diff options
-rw-r--r-- | src/libsystemd-network/sd-icmp6-nd.c | 27 | ||||
-rw-r--r-- | src/systemd/sd-icmp6-nd.h | 2 |
2 files changed, 29 insertions, 0 deletions
diff --git a/src/libsystemd-network/sd-icmp6-nd.c b/src/libsystemd-network/sd-icmp6-nd.c index 85b8ff93c5..8b567e3a5c 100644 --- a/src/libsystemd-network/sd-icmp6-nd.c +++ b/src/libsystemd-network/sd-icmp6-nd.c @@ -237,6 +237,18 @@ int sd_icmp6_nd_new(sd_icmp6_nd **ret) { return 0; } +int sd_icmp6_ra_get_mtu(sd_icmp6_nd *nd, uint32_t *mtu) { + assert_return(nd, -EINVAL); + assert_return(mtu, -EINVAL); + + if (nd->mtu == 0) + return -ENOMSG; + + *mtu = nd->mtu; + + return 0; +} + static int icmp6_ra_parse(sd_icmp6_nd *nd, struct nd_router_advert *ra, ssize_t len) { void *opt; @@ -256,11 +268,26 @@ static int icmp6_ra_parse(sd_icmp6_nd *nd, struct nd_router_advert *ra, opt_hdr = opt; while (len != 0 && len >= opt_hdr->nd_opt_len * ICMP6_OPT_LEN_UNITS) { + struct nd_opt_mtu *opt_mtu; + uint32_t mtu; if (opt_hdr->nd_opt_len == 0) return -ENOMSG; switch (opt_hdr->nd_opt_type) { + case ND_OPT_MTU: + opt_mtu = opt; + + mtu = be32toh(opt_mtu->nd_opt_mtu_mtu); + + if (mtu != nd->mtu) { + nd->mtu = MAX(mtu, IP6_MIN_MTU); + + log_icmp6_nd(nd, "Router Advertisement link MTU %d using %d", + mtu, nd->mtu); + } + + break; } diff --git a/src/systemd/sd-icmp6-nd.h b/src/systemd/sd-icmp6-nd.h index 73f91aad1b..73ebccfedd 100644 --- a/src/systemd/sd-icmp6-nd.h +++ b/src/systemd/sd-icmp6-nd.h @@ -51,6 +51,8 @@ sd_icmp6_nd *sd_icmp6_nd_ref(sd_icmp6_nd *nd); sd_icmp6_nd *sd_icmp6_nd_unref(sd_icmp6_nd *nd); int sd_icmp6_nd_new(sd_icmp6_nd **ret); +int sd_icmp6_ra_get_mtu(sd_icmp6_nd *nd, uint32_t *mtu); + int sd_icmp6_nd_stop(sd_icmp6_nd *nd); int sd_icmp6_router_solicitation_start(sd_icmp6_nd *nd); |