@@ -260,6 +260,11 @@ int system_add_ip_tunnel(const char *name, struct blob_attr *attr)
return 0;
}
+int system_update_ipv4_mtu(struct device *dev, int mtu)
+{
+ return 0;
+}
+
int system_update_ipv6_mtu(struct device *dev, int mtu)
{
return 0;
@@ -636,6 +636,12 @@ int system_bridge_addif(struct device *bridge, struct device *dev)
char *oldbr;
int ret = 0;
+ if (bridge->settings.flags & DEV_OPT_MTU) {
+ system_update_ipv4_mtu(dev, bridge->settings.mtu);
+ }
+ if (bridge->settings.flags & DEV_OPT_MTU6) {
+ system_update_ipv6_mtu(dev, bridge->settings.mtu6);
+ }
oldbr = system_get_bridge(dev->ifname, dev_buf, sizeof(dev_buf));
if (!oldbr || strcmp(oldbr, bridge->ifname) != 0)
ret = system_bridge_if(bridge->ifname, dev, SIOCBRADDIF, NULL);
@@ -1163,10 +1169,9 @@ system_if_get_settings(struct device *dev, struct device_settings *s)
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name));
- if (ioctl(sock_ioctl, SIOCGIFMTU, &ifr) == 0) {
- s->mtu = ifr.ifr_mtu;
+ s->mtu = system_update_ipv4_mtu(dev, 0);
+ if (s->mtu > 0)
s->flags |= DEV_OPT_MTU;
- }
s->mtu6 = system_update_ipv6_mtu(dev, 0);
if (s->mtu6 > 0)
@@ -1274,8 +1279,7 @@ system_if_apply_settings(struct device *dev, struct device_settings *s, unsigned
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name));
if (s->flags & DEV_OPT_MTU & apply_mask) {
- ifr.ifr_mtu = s->mtu;
- if (ioctl(sock_ioctl, SIOCSIFMTU, &ifr) < 0)
+ if (system_update_ipv4_mtu(dev, s->mtu) < 0)
s->flags &= ~DEV_OPT_MTU;
}
if (s->flags & DEV_OPT_MTU6 & apply_mask) {
@@ -2416,10 +2420,41 @@ int system_del_ip_tunnel(const char *name, struct blob_attr *attr)
return __system_del_ip_tunnel(name, tb);
}
+int system_update_ipv4_mtu(struct device *dev, int mtu)
+{
+ int ret = -1;
+ struct ifreq ifr;
+
+ if(!dev)
+ return ret;
+
+ memset(&ifr, 0, sizeof(ifr));
+ ifr.ifr_addr.sa_family = AF_INET;
+ strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name));
+
+ if (!mtu) {
+ ret = ioctl(sock_ioctl, SIOCGIFMTU, &ifr);
+ if (ret == 0)
+ ret = ifr.ifr_mtu;
+ } else {
+ struct device * parent = system_if_get_parent(dev);
+ if (parent)
+ system_update_ipv4_mtu(parent, mtu);
+
+ ifr.ifr_mtu = mtu;
+ ret = ioctl(sock_ioctl, SIOCSIFMTU, &ifr);
+ }
+ return (ret == 0)?mtu:ret;
+}
+
int system_update_ipv6_mtu(struct device *dev, int mtu)
{
int ret = -1;
char buf[64];
+
+ if(!dev)
+ return ret;
+
snprintf(buf, sizeof(buf), "/proc/sys/net/ipv6/conf/%s/mtu",
dev->ifname);
@@ -163,6 +163,8 @@ time_t system_get_rtime(void);
void system_fd_set_cloexec(int fd);
+int system_update_ipv4_mtu(struct device *device, int mtu);
+
int system_update_ipv6_mtu(struct device *device, int mtu);
#endif