Bug #216 » 0001-batman-adv-lock-crc-access-in-bridge-loop-avoidance.patch
bridge_loop_avoidance.c | ||
---|---|---|
}
|
||
/* all claims gone, intialize CRC */
|
||
spin_lock_bh(&backbone_gw->crc_lock);
|
||
backbone_gw->crc = BATADV_BLA_CRC_INIT;
|
||
spin_unlock_bh(&backbone_gw->crc_lock);
|
||
}
|
||
/**
|
||
... | ... | |
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);
|
||
... | ... | |
__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,
|
||
... | ... | |
"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:
|
||
... | ... | |
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);
|
||
... | ... | |
unsigned short vid)
|
||
{
|
||
struct batadv_bla_backbone_gw *backbone_gw;
|
||
uint16_t crc;
|
||
uint16_t backbone_crc, crc;
|
||
if (memcmp(an_addr, batadv_announce_mac, 4) != 0)
|
||
return 0;
|
||
... | ... | |
"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 {
|
||
... | ... | |
struct batadv_bla_claim *claim;
|
||
struct batadv_hard_iface *primary_if;
|
||
struct hlist_head *head;
|
||
uint16_t backbone_crc;
|
||
uint32_t i;
|
||
bool is_own;
|
||
uint8_t *primary_addr;
|
||
... | ... | |
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_lock_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();
|
||
}
|
||
... | ... | |
struct hlist_head *head;
|
||
int secs, msecs;
|
||
uint32_t i;
|
||
uint16_t backbone_crc;
|
||
bool is_own;
|
||
uint8_t *primary_addr;
|
||
... | ... | |
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();
|
||
}
|
types.h | ||
---|---|---|
* backbone gateway - no bcast traffic is formwared until the situation was
|
||
* resolved
|
||
* @crc: crc16 checksum over all claims
|
||
* @crc_lock: lock protecting crc
|
||
* @refcount: number of contexts the object is used
|
||
* @rcu: struct used for freeing in an RCU-safe manner
|
||
*/
|
||
... | ... | |
atomic_t wait_periods;
|
||
atomic_t request_sent;
|
||
uint16_t crc;
|
||
spinlock_t crc_lock;
|
||
atomic_t refcount;
|
||
struct rcu_head rcu;
|
||
};
|