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;
|
||
|
};
|
||