save and restore previous device settings when overriding them via config
authorFelix Fietkau <nbd@openwrt.org>
Sun, 22 Jan 2012 18:00:04 +0000 (19:00 +0100)
committerFelix Fietkau <nbd@openwrt.org>
Sun, 22 Jan 2012 18:00:04 +0000 (19:00 +0100)
device.h
system-linux.c

index 12176ce7175ed77c3d46d035f2e923a6143840b0..2b7fb13c3568e74e415e41042ec4c88127d7b9ec 100644 (file)
--- a/device.h
+++ b/device.h
@@ -112,6 +112,7 @@ struct device {
 
        struct device_user parent;
 
+       struct device_settings orig_settings;
        struct device_settings settings;
 };
 
index 0ff2b3b344d742c0beb457a4bbd11c1e6ae53974..4fa0ead507ded0046cace9412f51c761abe810a8 100644 (file)
@@ -569,6 +569,30 @@ int system_vlan_del(struct device *dev)
        return system_vlan(dev, -1);
 }
 
+static void
+system_if_get_settings(struct device *dev, struct device_settings *s)
+{
+       struct ifreq ifr;
+
+       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->flags |= DEV_OPT_MTU;
+       }
+
+       if (ioctl(sock_ioctl, SIOCGIFTXQLEN, &ifr) == 0) {
+               s->txqueuelen = ifr.ifr_qlen;
+               s->flags |= DEV_OPT_TXQUEUELEN;
+       }
+
+       if (ioctl(sock_ioctl, SIOCGIFHWADDR, &ifr) == 0) {
+               memcpy(s->macaddr, &ifr.ifr_hwaddr, sizeof(s->macaddr));
+               s->flags |= DEV_OPT_MACADDR;
+       }
+}
+
 static void
 system_if_apply_settings(struct device *dev, struct device_settings *s)
 {
@@ -592,6 +616,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);
        dev->ifindex = system_if_resolve(dev);
        return system_if_flags(dev->ifname, IFF_UP, 0);
@@ -599,7 +624,9 @@ int system_if_up(struct device *dev)
 
 int system_if_down(struct device *dev)
 {
-       return system_if_flags(dev->ifname, 0, IFF_UP);
+       int ret = system_if_flags(dev->ifname, 0, IFF_UP);
+       system_if_apply_settings(dev, &dev->orig_settings);
+       return ret;
 }
 
 int system_if_check(struct device *dev)