Apply the bridge MTU setting after a bridge memeber as the kernel
overrides the bridge MTU setting with the bridge member MTU
setting

Signed-off-by: Hans Dedecker <dedec...@gmail.com>
---
 bridge.c       |   13 +++++++++++--
 device.c       |    2 +-
 interface.c    |    2 +-
 system-dummy.c |    2 +-
 system-linux.c |   15 +++++++++------
 system.h       |    4 ++--
 6 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/bridge.c b/bridge.c
index 4ef0d7e..bbb1d47 100644
--- a/bridge.c
+++ b/bridge.c
@@ -231,8 +231,17 @@ bridge_member_cb(struct device_user *dev, enum 
device_event ev)
                bm->present = true;
                bst->n_present++;
 
-               if (bst->dev.active)
-                       bridge_enable_member(bm);
+               if (bst->dev.active) {
+                       if (!bridge_enable_member(bm)) {
+                               /*
+                                * Adding a bridge member can overwrite the 
bridge mtu
+                                * in the kernel, apply the bridge settings in 
case the
+                                * bridge mtu is set
+                                */
+                               system_if_apply_settings(&bst->dev, 
&bst->dev.settings,
+                                                               DEV_OPT_MTU);
+                       }
+               }
                else if (bst->n_present == 1)
                        device_set_present(&bst->dev, true);
 
diff --git a/device.c b/device.c
index 6a770ac..2fb68d7 100644
--- a/device.c
+++ b/device.c
@@ -623,7 +623,7 @@ device_create(const char *name, const struct device_type 
*type,
                odev->current_config = true;
                change = device_set_config(odev, type, config);
                if (odev->external) {
-                       system_if_apply_settings(odev, &odev->settings);
+                       system_if_apply_settings(odev, &odev->settings, 
odev->settings.flags);
                        change = DEV_CONFIG_APPLIED;
                }
                switch (change) {
diff --git a/interface.c b/interface.c
index f0fd43f..43ba773 100644
--- a/interface.c
+++ b/interface.c
@@ -839,7 +839,7 @@ interface_handle_link(struct interface *iface, const char 
*name, bool add)
                if (iface->device_config)
                        device_set_config(dev, &simple_device_type, 
iface->config);
 
-               system_if_apply_settings(dev, &dev->settings);
+               system_if_apply_settings(dev, &dev->settings, 
dev->settings.flags);
                ret = interface_add_link(iface, dev);
        } else {
                ret = interface_remove_link(iface, dev);
diff --git a/system-dummy.c b/system-dummy.c
index c8379ff..3ab22b0 100644
--- a/system-dummy.c
+++ b/system-dummy.c
@@ -120,7 +120,7 @@ system_if_dump_stats(struct device *dev, struct blob_buf *b)
 }
 
 void
-system_if_apply_settings(struct device *dev, struct device_settings *s)
+system_if_apply_settings(struct device *dev, struct device_settings *s, 
unsigned int apply_mask)
 {
 }
 
diff --git a/system-linux.c b/system-linux.c
index f0cea34..d2429a9 100644
--- a/system-linux.c
+++ b/system-linux.c
@@ -798,23 +798,26 @@ system_if_get_settings(struct device *dev, struct 
device_settings *s)
 }
 
 void
-system_if_apply_settings(struct device *dev, struct device_settings *s)
+system_if_apply_settings(struct device *dev, struct device_settings *s, 
unsigned int apply_mask)
 {
        struct ifreq ifr;
 
+       if (!apply_mask)
+               return;
+
        memset(&ifr, 0, sizeof(ifr));
        strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name));
-       if (s->flags & DEV_OPT_MTU) {
+       if (s->flags & DEV_OPT_MTU & apply_mask) {
                ifr.ifr_mtu = s->mtu;
                if (ioctl(sock_ioctl, SIOCSIFMTU, &ifr) < 0)
                        s->flags &= ~DEV_OPT_MTU;
        }
-       if (s->flags & DEV_OPT_TXQUEUELEN) {
+       if (s->flags & DEV_OPT_TXQUEUELEN & apply_mask) {
                ifr.ifr_qlen = s->txqueuelen;
                if (ioctl(sock_ioctl, SIOCSIFTXQLEN, &ifr) < 0)
                        s->flags &= ~DEV_OPT_TXQUEUELEN;
        }
-       if ((s->flags & DEV_OPT_MACADDR) && !dev->external) {
+       if ((s->flags & DEV_OPT_MACADDR & apply_mask) && !dev->external) {
                ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
                memcpy(&ifr.ifr_hwaddr.sa_data, s->macaddr, sizeof(s->macaddr));
                if (ioctl(sock_ioctl, SIOCSIFHWADDR, &ifr) < 0)
@@ -825,7 +828,7 @@ system_if_apply_settings(struct device *dev, struct 
device_settings *s)
 int system_if_up(struct device *dev)
 {
        system_if_get_settings(dev, &dev->orig_settings);
-       system_if_apply_settings(dev, &dev->settings);
+       system_if_apply_settings(dev, &dev->settings, dev->settings.flags);
        device_set_ifindex(dev, system_if_resolve(dev));
        return system_if_flags(dev->ifname, IFF_UP, 0);
 }
@@ -834,7 +837,7 @@ int system_if_down(struct device *dev)
 {
        int ret = system_if_flags(dev->ifname, 0, IFF_UP);
        dev->orig_settings.flags &= dev->settings.flags;
-       system_if_apply_settings(dev, &dev->orig_settings);
+       system_if_apply_settings(dev, &dev->orig_settings, 
dev->orig_settings.flags);
        return ret;
 }
 
diff --git a/system.h b/system.h
index ff83a1c..bcc928d 100644
--- a/system.h
+++ b/system.h
@@ -104,8 +104,8 @@ int system_if_dump_info(struct device *dev, struct blob_buf 
*b);
 int system_if_dump_stats(struct device *dev, struct blob_buf *b);
 struct device *system_if_get_parent(struct device *dev);
 bool system_if_force_external(const char *ifname);
-void system_if_apply_settings(struct device *dev, struct device_settings *s);
-
+void system_if_apply_settings(struct device *dev, struct device_settings *s,
+                               unsigned int apply_mask);
 
 int system_add_address(struct device *dev, struct device_addr *addr);
 int system_del_address(struct device *dev, struct device_addr *addr);
-- 
1.7.1
_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel

Reply via email to