summaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorNicolas Dichtel <nicolas.dichtel@6wind.com>2014-09-01 16:07:29 +0200
committerDavid S. Miller <davem@davemloft.net>2014-09-02 12:57:04 -0700
commitba9989069f4e426b1e0ed7018eacc9e1ba607095 (patch)
treea31001f42e367eac32e74c69ab2d48e571a14645 /net/core
parent90c325e3bfe14ef360de6650fa2a2e92685e5cee (diff)
downloadop-kernel-dev-ba9989069f4e426b1e0ed7018eacc9e1ba607095.zip
op-kernel-dev-ba9989069f4e426b1e0ed7018eacc9e1ba607095.tar.gz
rtnl/do_setlink(): notify when a netdev is modified
Depending on which parameters were updated, the changes were not propagated via the notifier chain and netlink. The new flag has been set only when the change did not cause a call to the notifier chain and/or to the netlink notification functions. Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/rtnetlink.c35
1 files changed, 21 insertions, 14 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 7d84db3..a688268 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1482,6 +1482,8 @@ static int do_set_master(struct net_device *dev, int ifindex)
}
#define DO_SETLINK_MODIFIED 0x01
+/* notify flag means notify + modified. */
+#define DO_SETLINK_NOTIFY 0x03
static int do_setlink(const struct sk_buff *skb,
struct net_device *dev, struct ifinfomsg *ifm,
struct nlattr **tb, char *ifname, int status)
@@ -1532,7 +1534,7 @@ static int do_setlink(const struct sk_buff *skb,
if (err < 0)
goto errout;
- status |= DO_SETLINK_MODIFIED;
+ status |= DO_SETLINK_NOTIFY;
}
if (tb[IFLA_ADDRESS]) {
@@ -1564,7 +1566,7 @@ static int do_setlink(const struct sk_buff *skb,
if (tb[IFLA_GROUP]) {
dev_set_group(dev, nla_get_u32(tb[IFLA_GROUP]));
- status |= DO_SETLINK_MODIFIED;
+ status |= DO_SETLINK_NOTIFY;
}
/*
@@ -1584,7 +1586,7 @@ static int do_setlink(const struct sk_buff *skb,
nla_len(tb[IFLA_IFALIAS]));
if (err < 0)
goto errout;
- status |= DO_SETLINK_MODIFIED;
+ status |= DO_SETLINK_NOTIFY;
}
if (tb[IFLA_BROADCAST]) {
@@ -1616,7 +1618,7 @@ static int do_setlink(const struct sk_buff *skb,
unsigned long value = nla_get_u32(tb[IFLA_TXQLEN]);
if (dev->tx_queue_len ^ value)
- status |= DO_SETLINK_MODIFIED;
+ status |= DO_SETLINK_NOTIFY;
dev->tx_queue_len = value;
}
@@ -1629,7 +1631,7 @@ static int do_setlink(const struct sk_buff *skb,
write_lock_bh(&dev_base_lock);
if (dev->link_mode ^ value)
- status |= DO_SETLINK_MODIFIED;
+ status |= DO_SETLINK_NOTIFY;
dev->link_mode = value;
write_unlock_bh(&dev_base_lock);
}
@@ -1645,7 +1647,7 @@ static int do_setlink(const struct sk_buff *skb,
err = do_setvfinfo(dev, attr);
if (err < 0)
goto errout;
- status |= DO_SETLINK_MODIFIED;
+ status |= DO_SETLINK_NOTIFY;
}
}
err = 0;
@@ -1675,7 +1677,7 @@ static int do_setlink(const struct sk_buff *skb,
err = ops->ndo_set_vf_port(dev, vf, port);
if (err < 0)
goto errout;
- status |= DO_SETLINK_MODIFIED;
+ status |= DO_SETLINK_NOTIFY;
}
}
err = 0;
@@ -1693,7 +1695,7 @@ static int do_setlink(const struct sk_buff *skb,
err = ops->ndo_set_vf_port(dev, PORT_SELF_VF, port);
if (err < 0)
goto errout;
- status |= DO_SETLINK_MODIFIED;
+ status |= DO_SETLINK_NOTIFY;
}
if (tb[IFLA_AF_SPEC]) {
@@ -1710,15 +1712,20 @@ static int do_setlink(const struct sk_buff *skb,
if (err < 0)
goto errout;
- status |= DO_SETLINK_MODIFIED;
+ status |= DO_SETLINK_NOTIFY;
}
}
err = 0;
errout:
- if (err < 0 && status & DO_SETLINK_MODIFIED)
- net_warn_ratelimited("A link change request failed with some changes committed already. Interface %s may have been left with an inconsistent configuration, please check.\n",
- dev->name);
+ if (status & DO_SETLINK_MODIFIED) {
+ if (status & DO_SETLINK_NOTIFY)
+ netdev_state_change(dev);
+
+ if (err < 0)
+ net_warn_ratelimited("A link change request failed with some changes committed already. Interface %s may have been left with an inconsistent configuration, please check.\n",
+ dev->name);
+ }
return err;
}
@@ -2015,7 +2022,7 @@ replay:
err = ops->changelink(dev, tb, data);
if (err < 0)
return err;
- status |= DO_SETLINK_MODIFIED;
+ status |= DO_SETLINK_NOTIFY;
}
if (linkinfo[IFLA_INFO_SLAVE_DATA]) {
@@ -2026,7 +2033,7 @@ replay:
tb, slave_data);
if (err < 0)
return err;
- status |= DO_SETLINK_MODIFIED;
+ status |= DO_SETLINK_NOTIFY;
}
return do_setlink(skb, dev, ifm, tb, ifname, status);
OpenPOWER on IntegriCloud