From: Steven Barth Date: Wed, 24 Jun 2015 11:02:37 +0000 (+0200) Subject: Add mtu6 option to override IPv6 MTU X-Git-Url: https://git.archive.openwrt.org/?p=project%2Fnetifd.git;a=commitdiff_plain;h=5b29ffda0099c3bcb8d17a728e1e89dc21a2e68d Add mtu6 option to override IPv6 MTU Signed-off-by: Steven Barth --- diff --git a/bridge.c b/bridge.c index 9da5314..4a0cbe9 100644 --- a/bridge.c +++ b/bridge.c @@ -299,7 +299,7 @@ bridge_member_cb(struct device_user *dev, enum device_event ev) * bridge mtu is set */ system_if_apply_settings(&bst->dev, &bst->dev.settings, - DEV_OPT_MTU); + DEV_OPT_MTU | DEV_OPT_MTU6); } break; diff --git a/device.c b/device.c index dd2823d..1265c86 100644 --- a/device.c +++ b/device.c @@ -34,6 +34,7 @@ static bool default_ps = true; static const struct blobmsg_policy dev_attrs[__DEV_ATTR_MAX] = { [DEV_ATTR_TYPE] = { .name = "type", .type = BLOBMSG_TYPE_STRING }, [DEV_ATTR_MTU] = { .name = "mtu", .type = BLOBMSG_TYPE_INT32 }, + [DEV_ATTR_MTU6] = { .name = "mtu6", .type = BLOBMSG_TYPE_INT32 }, [DEV_ATTR_MACADDR] = { .name = "macaddr", .type = BLOBMSG_TYPE_STRING }, [DEV_ATTR_TXQUEUELEN] = { .name = "txqueuelen", .type = BLOBMSG_TYPE_INT32 }, [DEV_ATTR_ENABLED] = { .name = "enabled", .type = BLOBMSG_TYPE_BOOL }, @@ -154,6 +155,7 @@ device_merge_settings(struct device *dev, struct device_settings *n) memset(n, 0, sizeof(*n)); n->mtu = s->flags & DEV_OPT_MTU ? s->mtu : os->mtu; + n->mtu6 = s->flags & DEV_OPT_MTU6 ? s->mtu6 : os->mtu6; n->txqueuelen = s->flags & DEV_OPT_TXQUEUELEN ? s->txqueuelen : os->txqueuelen; memcpy(n->macaddr, @@ -189,6 +191,11 @@ device_init_settings(struct device *dev, struct blob_attr **tb) s->flags |= DEV_OPT_MTU; } + if ((cur = tb[DEV_ATTR_MTU6])) { + s->mtu6 = blobmsg_get_u32(cur); + s->flags |= DEV_OPT_MTU6; + } + if ((cur = tb[DEV_ATTR_TXQUEUELEN])) { s->txqueuelen = blobmsg_get_u32(cur); s->flags |= DEV_OPT_TXQUEUELEN; @@ -843,6 +850,8 @@ device_dump_status(struct blob_buf *b, struct device *dev) device_merge_settings(dev, &st); if (st.flags & DEV_OPT_MTU) blobmsg_add_u32(b, "mtu", st.mtu); + if (st.flags & DEV_OPT_MTU6) + blobmsg_add_u32(b, "mtu6", st.mtu6); if (st.flags & DEV_OPT_MACADDR) blobmsg_add_string(b, "macaddr", format_macaddr(st.macaddr)); if (st.flags & DEV_OPT_TXQUEUELEN) diff --git a/device.h b/device.h index 3001f10..4d84d80 100644 --- a/device.h +++ b/device.h @@ -28,6 +28,7 @@ typedef int (*device_state_cb)(struct device *, bool up); enum { DEV_ATTR_TYPE, DEV_ATTR_MTU, + DEV_ATTR_MTU6, DEV_ATTR_MACADDR, DEV_ATTR_TXQUEUELEN, DEV_ATTR_ENABLED, @@ -80,6 +81,7 @@ enum { DEV_OPT_NEIGHREACHABLETIME = (1 << 9), DEV_OPT_RPS = (1 << 10), DEV_OPT_XPS = (1 << 11), + DEV_OPT_MTU6 = (1 << 12), }; /* events broadcasted to all users of a device */ @@ -123,6 +125,7 @@ struct device_user { struct device_settings { unsigned int flags; unsigned int mtu; + unsigned int mtu6; unsigned int txqueuelen; uint8_t macaddr[6]; bool ipv6; diff --git a/interface-ip.c b/interface-ip.c index aec3892..7f8a451 100644 --- a/interface-ip.c +++ b/interface-ip.c @@ -767,10 +767,11 @@ interface_set_prefix_address(struct device_prefix_assignment *assignment, route.metric = iface->metric; system_add_route(l3_downlink, &route); - if (uplink && uplink->l3_dev.dev) { - int mtu = system_update_ipv6_mtu( - uplink->l3_dev.dev, 0); - if (mtu > 0) + if (uplink && uplink->l3_dev.dev && !(l3_downlink->settings.flags & DEV_OPT_MTU6)) { + int mtu = system_update_ipv6_mtu(uplink->l3_dev.dev, 0); + int mtu_old = system_update_ipv6_mtu(l3_downlink, 0); + + if (mtu > 0 && mtu_old > mtu) system_update_ipv6_mtu(l3_downlink, mtu); } diff --git a/system-linux.c b/system-linux.c index 6dc9acd..b44eb76 100644 --- a/system-linux.c +++ b/system-linux.c @@ -1019,6 +1019,10 @@ system_if_get_settings(struct device *dev, struct device_settings *s) s->flags |= DEV_OPT_MTU; } + s->mtu6 = system_update_ipv6_mtu(dev, 0); + if (s->mtu6 > 0) + s->flags |= DEV_OPT_MTU6; + if (ioctl(sock_ioctl, SIOCGIFTXQLEN, &ifr) == 0) { s->txqueuelen = ifr.ifr_qlen; s->flags |= DEV_OPT_TXQUEUELEN; @@ -1114,6 +1118,9 @@ system_if_apply_settings(struct device *dev, struct device_settings *s, unsigned if (ioctl(sock_ioctl, SIOCSIFMTU, &ifr) < 0) s->flags &= ~DEV_OPT_MTU; } + if (s->flags & DEV_OPT_MTU6 & apply_mask) { + system_update_ipv6_mtu(dev, s->mtu6); + } if (s->flags & DEV_OPT_TXQUEUELEN & apply_mask) { ifr.ifr_qlen = s->txqueuelen; if (ioctl(sock_ioctl, SIOCSIFTXQLEN, &ifr) < 0) @@ -2163,19 +2170,18 @@ int system_update_ipv6_mtu(struct device *dev, int mtu) dev->ifname); int fd = open(buf, O_RDWR); - ssize_t len = read(fd, buf, sizeof(buf) - 1); - if (len < 0) - goto out; - buf[len] = 0; - ret = atoi(buf); + if (!mtu) { + ssize_t len = read(fd, buf, sizeof(buf) - 1); + if (len < 0) + goto out; - if (!mtu || ret <= mtu) - goto out; - - lseek(fd, 0, SEEK_SET); - if (write(fd, buf, snprintf(buf, sizeof(buf), "%i", mtu)) <= 0) - ret = -1; + buf[len] = 0; + ret = atoi(buf); + } else { + if (write(fd, buf, snprintf(buf, sizeof(buf), "%i", mtu)) > 0) + ret = mtu; + } out: close(fd);