Merge tag 'hsi-for-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-hsi
[deliverable/linux.git] / net / batman-adv / bridge_loop_avoidance.c
index 191a70290dca2ae15af2ec31845c3b4ed8dad37c..d5d71ac96c8a7c400d90d30d1851f49dc76db95c 100644 (file)
@@ -260,7 +260,9 @@ batadv_bla_del_backbone_claims(struct batadv_bla_backbone_gw *backbone_gw)
        }
 
        /* all claims gone, initialize CRC */
+       spin_lock_bh(&backbone_gw->crc_lock);
        backbone_gw->crc = BATADV_BLA_CRC_INIT;
+       spin_unlock_bh(&backbone_gw->crc_lock);
 }
 
 /**
@@ -408,6 +410,7 @@ batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, u8 *orig,
        entry->lasttime = jiffies;
        entry->crc = BATADV_BLA_CRC_INIT;
        entry->bat_priv = bat_priv;
+       spin_lock_init(&entry->crc_lock);
        atomic_set(&entry->request_sent, 0);
        atomic_set(&entry->wait_periods, 0);
        ether_addr_copy(entry->orig, orig);
@@ -557,7 +560,9 @@ static void batadv_bla_send_announce(struct batadv_priv *bat_priv,
        __be16 crc;
 
        memcpy(mac, batadv_announce_mac, 4);
+       spin_lock_bh(&backbone_gw->crc_lock);
        crc = htons(backbone_gw->crc);
+       spin_unlock_bh(&backbone_gw->crc_lock);
        memcpy(&mac[4], &crc, 2);
 
        batadv_bla_send_claim(bat_priv, mac, backbone_gw->vid,
@@ -618,14 +623,18 @@ static void batadv_bla_add_claim(struct batadv_priv *bat_priv,
                           "bla_add_claim(): changing ownership for %pM, vid %d\n",
                           mac, BATADV_PRINT_VID(vid));
 
+               spin_lock_bh(&claim->backbone_gw->crc_lock);
                claim->backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN);
+               spin_unlock_bh(&claim->backbone_gw->crc_lock);
                batadv_backbone_gw_free_ref(claim->backbone_gw);
        }
        /* set (new) backbone gw */
        atomic_inc(&backbone_gw->refcount);
        claim->backbone_gw = backbone_gw;
 
+       spin_lock_bh(&backbone_gw->crc_lock);
        backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN);
+       spin_unlock_bh(&backbone_gw->crc_lock);
        backbone_gw->lasttime = jiffies;
 
 claim_free_ref:
@@ -653,7 +662,9 @@ static void batadv_bla_del_claim(struct batadv_priv *bat_priv,
                           batadv_choose_claim, claim);
        batadv_claim_free_ref(claim); /* reference from the hash is gone */
 
+       spin_lock_bh(&claim->backbone_gw->crc_lock);
        claim->backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN);
+       spin_unlock_bh(&claim->backbone_gw->crc_lock);
 
        /* don't need the reference from hash_find() anymore */
        batadv_claim_free_ref(claim);
@@ -664,7 +675,7 @@ static int batadv_handle_announce(struct batadv_priv *bat_priv, u8 *an_addr,
                                  u8 *backbone_addr, unsigned short vid)
 {
        struct batadv_bla_backbone_gw *backbone_gw;
-       u16 crc;
+       u16 backbone_crc, crc;
 
        if (memcmp(an_addr, batadv_announce_mac, 4) != 0)
                return 0;
@@ -683,12 +694,16 @@ static int batadv_handle_announce(struct batadv_priv *bat_priv, u8 *an_addr,
                   "handle_announce(): ANNOUNCE vid %d (sent by %pM)... CRC = %#.4x\n",
                   BATADV_PRINT_VID(vid), backbone_gw->orig, crc);
 
-       if (backbone_gw->crc != crc) {
+       spin_lock_bh(&backbone_gw->crc_lock);
+       backbone_crc = backbone_gw->crc;
+       spin_unlock_bh(&backbone_gw->crc_lock);
+
+       if (backbone_crc != crc) {
                batadv_dbg(BATADV_DBG_BLA, backbone_gw->bat_priv,
                           "handle_announce(): CRC FAILED for %pM/%d (my = %#.4x, sent = %#.4x)\n",
                           backbone_gw->orig,
                           BATADV_PRINT_VID(backbone_gw->vid),
-                          backbone_gw->crc, crc);
+                          backbone_crc, crc);
 
                batadv_bla_send_request(backbone_gw);
        } else {
@@ -1153,6 +1168,26 @@ void batadv_bla_update_orig_address(struct batadv_priv *bat_priv,
        }
 }
 
+/**
+ * batadv_bla_status_update - purge bla interfaces if necessary
+ * @net_dev: the soft interface net device
+ */
+void batadv_bla_status_update(struct net_device *net_dev)
+{
+       struct batadv_priv *bat_priv = netdev_priv(net_dev);
+       struct batadv_hard_iface *primary_if;
+
+       primary_if = batadv_primary_if_get_selected(bat_priv);
+       if (!primary_if)
+               return;
+
+       /* this function already purges everything when bla is disabled,
+        * so just call that one.
+        */
+       batadv_bla_update_orig_address(bat_priv, primary_if, primary_if);
+       batadv_hardif_free_ref(primary_if);
+}
+
 /* periodic work to do:
  *  * purge structures when they are too old
  *  * send announcements
@@ -1647,6 +1682,7 @@ int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset)
        struct batadv_bla_claim *claim;
        struct batadv_hard_iface *primary_if;
        struct hlist_head *head;
+       u16 backbone_crc;
        u32 i;
        bool is_own;
        u8 *primary_addr;
@@ -1669,11 +1705,15 @@ int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset)
                hlist_for_each_entry_rcu(claim, head, hash_entry) {
                        is_own = batadv_compare_eth(claim->backbone_gw->orig,
                                                    primary_addr);
+
+                       spin_lock_bh(&claim->backbone_gw->crc_lock);
+                       backbone_crc = claim->backbone_gw->crc;
+                       spin_unlock_bh(&claim->backbone_gw->crc_lock);
                        seq_printf(seq, " * %pM on %5d by %pM [%c] (%#.4x)\n",
                                   claim->addr, BATADV_PRINT_VID(claim->vid),
                                   claim->backbone_gw->orig,
                                   (is_own ? 'x' : ' '),
-                                  claim->backbone_gw->crc);
+                                  backbone_crc);
                }
                rcu_read_unlock();
        }
@@ -1692,6 +1732,7 @@ int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset)
        struct batadv_hard_iface *primary_if;
        struct hlist_head *head;
        int secs, msecs;
+       u16 backbone_crc;
        u32 i;
        bool is_own;
        u8 *primary_addr;
@@ -1722,10 +1763,14 @@ int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset)
                        if (is_own)
                                continue;
 
+                       spin_lock_bh(&backbone_gw->crc_lock);
+                       backbone_crc = backbone_gw->crc;
+                       spin_unlock_bh(&backbone_gw->crc_lock);
+
                        seq_printf(seq, " * %pM on %5d %4i.%03is (%#.4x)\n",
                                   backbone_gw->orig,
                                   BATADV_PRINT_VID(backbone_gw->vid), secs,
-                                  msecs, backbone_gw->crc);
+                                  msecs, backbone_crc);
                }
                rcu_read_unlock();
        }
This page took 0.02709 seconds and 5 git commands to generate.