summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Dedecker <dedeckeh@gmail.com>2014-03-10 16:27:51 +0100
committerFelix Fietkau <nbd@openwrt.org>2014-03-11 10:22:57 +0100
commit02021e2069d0ee315b0ff263b6c010bef63b879c (patch)
tree73d096226852fa43cd41963a6d93627a3171d18f
parent8aabd47c6f4fefc8fbd70c34a738f7c26956d8cd (diff)
downloadnetifd-02021e2069d0ee315b0ff263b6c010bef63b879c.tar.gz
netifd: Fix bridge MTU setting when a bridge member is added
Reapply bridge mtu setting as adding a bridge member will override the bridge mtu in the kernel Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
-rw-r--r--bridge.c11
-rw-r--r--device.c2
-rw-r--r--interface.c2
-rw-r--r--system-dummy.c2
-rw-r--r--system-linux.c15
-rw-r--r--system.h4
6 files changed, 23 insertions, 13 deletions
diff --git a/bridge.c b/bridge.c
index 7bd1cf0..147fe0a 100644
--- a/bridge.c
+++ b/bridge.c
@@ -233,8 +233,15 @@ bridge_member_cb(struct device_user *dev, enum device_event ev)
if (bst->n_present == 1)
device_set_present(&bst->dev, true);
- if (bst->dev.active)
- bridge_enable_member(bm);
+ if (bst->dev.active && !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);
+ }
break;
case DEV_EVENT_REMOVE:
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 12682dc..7cec649 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..1ad861a 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);