]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - include/net/bonding.h
Merge branch 'upstream' of git://git.infradead.org/users/pcmoore/audit
[karo-tx-linux.git] / include / net / bonding.h
index c1740a2794a37bce9dc9d48739a766a93ff4f743..ee6c52053aa324800f82baf4cbe2674f47d56399 100644 (file)
@@ -165,7 +165,8 @@ struct slave {
        u8     backup:1,   /* indicates backup slave. Value corresponds with
                              BOND_STATE_ACTIVE and BOND_STATE_BACKUP */
               inactive:1, /* indicates inactive slave */
-              should_notify:1; /* indicateds whether the state changed */
+              should_notify:1, /* indicates whether the state changed */
+              should_notify_link:1; /* indicates whether the link changed */
        u8     duplex;
        u32    original_mtu;
        u32    link_failure_count;
@@ -246,6 +247,7 @@ struct bonding {
        ((struct slave *) rtnl_dereference(dev->rx_handler_data))
 
 void bond_queue_slave_event(struct slave *slave);
+void bond_lower_state_changed(struct slave *slave);
 
 struct bond_vlan_tag {
        __be16          vlan_proto;
@@ -327,6 +329,7 @@ static inline void bond_set_active_slave(struct slave *slave)
        if (slave->backup) {
                slave->backup = 0;
                bond_queue_slave_event(slave);
+               bond_lower_state_changed(slave);
                rtmsg_ifinfo(RTM_NEWLINK, slave->dev, 0, GFP_ATOMIC);
        }
 }
@@ -336,6 +339,7 @@ static inline void bond_set_backup_slave(struct slave *slave)
        if (!slave->backup) {
                slave->backup = 1;
                bond_queue_slave_event(slave);
+               bond_lower_state_changed(slave);
                rtmsg_ifinfo(RTM_NEWLINK, slave->dev, 0, GFP_ATOMIC);
        }
 }
@@ -348,6 +352,7 @@ static inline void bond_set_slave_state(struct slave *slave,
 
        slave->backup = slave_state;
        if (notify) {
+               bond_lower_state_changed(slave);
                rtmsg_ifinfo(RTM_NEWLINK, slave->dev, 0, GFP_ATOMIC);
                bond_queue_slave_event(slave);
                slave->should_notify = 0;
@@ -379,6 +384,7 @@ static inline void bond_slave_state_notify(struct bonding *bond)
 
        bond_for_each_slave(bond, tmp, iter) {
                if (tmp->should_notify) {
+                       bond_lower_state_changed(tmp);
                        rtmsg_ifinfo(RTM_NEWLINK, tmp->dev, 0, GFP_ATOMIC);
                        tmp->should_notify = 0;
                }
@@ -504,10 +510,37 @@ static inline bool bond_is_slave_inactive(struct slave *slave)
        return slave->inactive;
 }
 
-static inline void bond_set_slave_link_state(struct slave *slave, int state)
+static inline void bond_set_slave_link_state(struct slave *slave, int state,
+                                            bool notify)
 {
+       if (slave->link == state)
+               return;
+
        slave->link = state;
-       bond_queue_slave_event(slave);
+       if (notify) {
+               bond_queue_slave_event(slave);
+               bond_lower_state_changed(slave);
+               slave->should_notify_link = 0;
+       } else {
+               if (slave->should_notify_link)
+                       slave->should_notify_link = 0;
+               else
+                       slave->should_notify_link = 1;
+       }
+}
+
+static inline void bond_slave_link_notify(struct bonding *bond)
+{
+       struct list_head *iter;
+       struct slave *tmp;
+
+       bond_for_each_slave(bond, tmp, iter) {
+               if (tmp->should_notify_link) {
+                       bond_queue_slave_event(tmp);
+                       bond_lower_state_changed(tmp);
+                       tmp->should_notify_link = 0;
+               }
+       }
 }
 
 static inline __be32 bond_confirm_addr(struct net_device *dev, __be32 dst, __be32 local)