From f8527e5b20043db706b2bedd3cca305b4814d932 Mon Sep 17 00:00:00 2001
From: Naresh Kumar Mehta <[email protected]>
Date: Mon, 4 Apr 2016 19:07:54 +0530
Subject: [PATCH] linux-system: Set MTU while adding interfaces to bridge

1. This change fixes the mtu setting for bridge
   When setting the mtu of a bridge, the value need be set to the interfaces
   adding to the bridge, otherwise, it will use the least mtu of all of the
   interface to bridge's mtu. This change will set the bridge's mtu to the
   added interfaces.

2. This change also fixes the MTU settings for VLANed interfaces
   While setting MTU, set MTU to master iterface first & then set it for VLANed
   interface. This fixes ticket #20393

Signed-off-by: Zhu Ken <[email protected]>
Signed-off-by: Naresh Kumar Mehta <[email protected]>
---
 system-dummy.c |    5 +++++
 system-linux.c |   45 ++++++++++++++++++++++++++++++++++++++++-----
 system.h       |    2 ++
 3 files changed, 47 insertions(+), 5 deletions(-)

diff --git a/system-dummy.c b/system-dummy.c
index 9c734ea..0b36132 100644
--- a/system-dummy.c
+++ b/system-dummy.c
@@ -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;
diff --git a/system-linux.c b/system-linux.c
index 351a994..f79180c 100644
--- a/system-linux.c
+++ b/system-linux.c
@@ -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);
 
diff --git a/system.h b/system.h
index d5cb4e3..7d583ad 100644
--- a/system.h
+++ b/system.h
@@ -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
-- 
1.7.9.5
_______________________________________________
openwrt-devel mailing list
[email protected]
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel

Reply via email to