diff options
Diffstat (limited to 'net/batman-adv/bridge_loop_avoidance.c')
-rw-r--r-- | net/batman-adv/bridge_loop_avoidance.c | 55 |
1 files changed, 50 insertions, 5 deletions
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 191a70290dca..d5d71ac96c8a 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c | |||
@@ -260,7 +260,9 @@ batadv_bla_del_backbone_claims(struct batadv_bla_backbone_gw *backbone_gw) | |||
260 | } | 260 | } |
261 | 261 | ||
262 | /* all claims gone, initialize CRC */ | 262 | /* all claims gone, initialize CRC */ |
263 | spin_lock_bh(&backbone_gw->crc_lock); | ||
263 | backbone_gw->crc = BATADV_BLA_CRC_INIT; | 264 | backbone_gw->crc = BATADV_BLA_CRC_INIT; |
265 | spin_unlock_bh(&backbone_gw->crc_lock); | ||
264 | } | 266 | } |
265 | 267 | ||
266 | /** | 268 | /** |
@@ -408,6 +410,7 @@ batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, u8 *orig, | |||
408 | entry->lasttime = jiffies; | 410 | entry->lasttime = jiffies; |
409 | entry->crc = BATADV_BLA_CRC_INIT; | 411 | entry->crc = BATADV_BLA_CRC_INIT; |
410 | entry->bat_priv = bat_priv; | 412 | entry->bat_priv = bat_priv; |
413 | spin_lock_init(&entry->crc_lock); | ||
411 | atomic_set(&entry->request_sent, 0); | 414 | atomic_set(&entry->request_sent, 0); |
412 | atomic_set(&entry->wait_periods, 0); | 415 | atomic_set(&entry->wait_periods, 0); |
413 | ether_addr_copy(entry->orig, orig); | 416 | ether_addr_copy(entry->orig, orig); |
@@ -557,7 +560,9 @@ static void batadv_bla_send_announce(struct batadv_priv *bat_priv, | |||
557 | __be16 crc; | 560 | __be16 crc; |
558 | 561 | ||
559 | memcpy(mac, batadv_announce_mac, 4); | 562 | memcpy(mac, batadv_announce_mac, 4); |
563 | spin_lock_bh(&backbone_gw->crc_lock); | ||
560 | crc = htons(backbone_gw->crc); | 564 | crc = htons(backbone_gw->crc); |
565 | spin_unlock_bh(&backbone_gw->crc_lock); | ||
561 | memcpy(&mac[4], &crc, 2); | 566 | memcpy(&mac[4], &crc, 2); |
562 | 567 | ||
563 | batadv_bla_send_claim(bat_priv, mac, backbone_gw->vid, | 568 | 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, | |||
618 | "bla_add_claim(): changing ownership for %pM, vid %d\n", | 623 | "bla_add_claim(): changing ownership for %pM, vid %d\n", |
619 | mac, BATADV_PRINT_VID(vid)); | 624 | mac, BATADV_PRINT_VID(vid)); |
620 | 625 | ||
626 | spin_lock_bh(&claim->backbone_gw->crc_lock); | ||
621 | claim->backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN); | 627 | claim->backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN); |
628 | spin_unlock_bh(&claim->backbone_gw->crc_lock); | ||
622 | batadv_backbone_gw_free_ref(claim->backbone_gw); | 629 | batadv_backbone_gw_free_ref(claim->backbone_gw); |
623 | } | 630 | } |
624 | /* set (new) backbone gw */ | 631 | /* set (new) backbone gw */ |
625 | atomic_inc(&backbone_gw->refcount); | 632 | atomic_inc(&backbone_gw->refcount); |
626 | claim->backbone_gw = backbone_gw; | 633 | claim->backbone_gw = backbone_gw; |
627 | 634 | ||
635 | spin_lock_bh(&backbone_gw->crc_lock); | ||
628 | backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN); | 636 | backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN); |
637 | spin_unlock_bh(&backbone_gw->crc_lock); | ||
629 | backbone_gw->lasttime = jiffies; | 638 | backbone_gw->lasttime = jiffies; |
630 | 639 | ||
631 | claim_free_ref: | 640 | claim_free_ref: |
@@ -653,7 +662,9 @@ static void batadv_bla_del_claim(struct batadv_priv *bat_priv, | |||
653 | batadv_choose_claim, claim); | 662 | batadv_choose_claim, claim); |
654 | batadv_claim_free_ref(claim); /* reference from the hash is gone */ | 663 | batadv_claim_free_ref(claim); /* reference from the hash is gone */ |
655 | 664 | ||
665 | spin_lock_bh(&claim->backbone_gw->crc_lock); | ||
656 | claim->backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN); | 666 | claim->backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN); |
667 | spin_unlock_bh(&claim->backbone_gw->crc_lock); | ||
657 | 668 | ||
658 | /* don't need the reference from hash_find() anymore */ | 669 | /* don't need the reference from hash_find() anymore */ |
659 | batadv_claim_free_ref(claim); | 670 | batadv_claim_free_ref(claim); |
@@ -664,7 +675,7 @@ static int batadv_handle_announce(struct batadv_priv *bat_priv, u8 *an_addr, | |||
664 | u8 *backbone_addr, unsigned short vid) | 675 | u8 *backbone_addr, unsigned short vid) |
665 | { | 676 | { |
666 | struct batadv_bla_backbone_gw *backbone_gw; | 677 | struct batadv_bla_backbone_gw *backbone_gw; |
667 | u16 crc; | 678 | u16 backbone_crc, crc; |
668 | 679 | ||
669 | if (memcmp(an_addr, batadv_announce_mac, 4) != 0) | 680 | if (memcmp(an_addr, batadv_announce_mac, 4) != 0) |
670 | return 0; | 681 | return 0; |
@@ -683,12 +694,16 @@ static int batadv_handle_announce(struct batadv_priv *bat_priv, u8 *an_addr, | |||
683 | "handle_announce(): ANNOUNCE vid %d (sent by %pM)... CRC = %#.4x\n", | 694 | "handle_announce(): ANNOUNCE vid %d (sent by %pM)... CRC = %#.4x\n", |
684 | BATADV_PRINT_VID(vid), backbone_gw->orig, crc); | 695 | BATADV_PRINT_VID(vid), backbone_gw->orig, crc); |
685 | 696 | ||
686 | if (backbone_gw->crc != crc) { | 697 | spin_lock_bh(&backbone_gw->crc_lock); |
698 | backbone_crc = backbone_gw->crc; | ||
699 | spin_unlock_bh(&backbone_gw->crc_lock); | ||
700 | |||
701 | if (backbone_crc != crc) { | ||
687 | batadv_dbg(BATADV_DBG_BLA, backbone_gw->bat_priv, | 702 | batadv_dbg(BATADV_DBG_BLA, backbone_gw->bat_priv, |
688 | "handle_announce(): CRC FAILED for %pM/%d (my = %#.4x, sent = %#.4x)\n", | 703 | "handle_announce(): CRC FAILED for %pM/%d (my = %#.4x, sent = %#.4x)\n", |
689 | backbone_gw->orig, | 704 | backbone_gw->orig, |
690 | BATADV_PRINT_VID(backbone_gw->vid), | 705 | BATADV_PRINT_VID(backbone_gw->vid), |
691 | backbone_gw->crc, crc); | 706 | backbone_crc, crc); |
692 | 707 | ||
693 | batadv_bla_send_request(backbone_gw); | 708 | batadv_bla_send_request(backbone_gw); |
694 | } else { | 709 | } else { |
@@ -1153,6 +1168,26 @@ void batadv_bla_update_orig_address(struct batadv_priv *bat_priv, | |||
1153 | } | 1168 | } |
1154 | } | 1169 | } |
1155 | 1170 | ||
1171 | /** | ||
1172 | * batadv_bla_status_update - purge bla interfaces if necessary | ||
1173 | * @net_dev: the soft interface net device | ||
1174 | */ | ||
1175 | void batadv_bla_status_update(struct net_device *net_dev) | ||
1176 | { | ||
1177 | struct batadv_priv *bat_priv = netdev_priv(net_dev); | ||
1178 | struct batadv_hard_iface *primary_if; | ||
1179 | |||
1180 | primary_if = batadv_primary_if_get_selected(bat_priv); | ||
1181 | if (!primary_if) | ||
1182 | return; | ||
1183 | |||
1184 | /* this function already purges everything when bla is disabled, | ||
1185 | * so just call that one. | ||
1186 | */ | ||
1187 | batadv_bla_update_orig_address(bat_priv, primary_if, primary_if); | ||
1188 | batadv_hardif_free_ref(primary_if); | ||
1189 | } | ||
1190 | |||
1156 | /* periodic work to do: | 1191 | /* periodic work to do: |
1157 | * * purge structures when they are too old | 1192 | * * purge structures when they are too old |
1158 | * * send announcements | 1193 | * * send announcements |
@@ -1647,6 +1682,7 @@ int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset) | |||
1647 | struct batadv_bla_claim *claim; | 1682 | struct batadv_bla_claim *claim; |
1648 | struct batadv_hard_iface *primary_if; | 1683 | struct batadv_hard_iface *primary_if; |
1649 | struct hlist_head *head; | 1684 | struct hlist_head *head; |
1685 | u16 backbone_crc; | ||
1650 | u32 i; | 1686 | u32 i; |
1651 | bool is_own; | 1687 | bool is_own; |
1652 | u8 *primary_addr; | 1688 | u8 *primary_addr; |
@@ -1669,11 +1705,15 @@ int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset) | |||
1669 | hlist_for_each_entry_rcu(claim, head, hash_entry) { | 1705 | hlist_for_each_entry_rcu(claim, head, hash_entry) { |
1670 | is_own = batadv_compare_eth(claim->backbone_gw->orig, | 1706 | is_own = batadv_compare_eth(claim->backbone_gw->orig, |
1671 | primary_addr); | 1707 | primary_addr); |
1708 | |||
1709 | spin_lock_bh(&claim->backbone_gw->crc_lock); | ||
1710 | backbone_crc = claim->backbone_gw->crc; | ||
1711 | spin_unlock_bh(&claim->backbone_gw->crc_lock); | ||
1672 | seq_printf(seq, " * %pM on %5d by %pM [%c] (%#.4x)\n", | 1712 | seq_printf(seq, " * %pM on %5d by %pM [%c] (%#.4x)\n", |
1673 | claim->addr, BATADV_PRINT_VID(claim->vid), | 1713 | claim->addr, BATADV_PRINT_VID(claim->vid), |
1674 | claim->backbone_gw->orig, | 1714 | claim->backbone_gw->orig, |
1675 | (is_own ? 'x' : ' '), | 1715 | (is_own ? 'x' : ' '), |
1676 | claim->backbone_gw->crc); | 1716 | backbone_crc); |
1677 | } | 1717 | } |
1678 | rcu_read_unlock(); | 1718 | rcu_read_unlock(); |
1679 | } | 1719 | } |
@@ -1692,6 +1732,7 @@ int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset) | |||
1692 | struct batadv_hard_iface *primary_if; | 1732 | struct batadv_hard_iface *primary_if; |
1693 | struct hlist_head *head; | 1733 | struct hlist_head *head; |
1694 | int secs, msecs; | 1734 | int secs, msecs; |
1735 | u16 backbone_crc; | ||
1695 | u32 i; | 1736 | u32 i; |
1696 | bool is_own; | 1737 | bool is_own; |
1697 | u8 *primary_addr; | 1738 | u8 *primary_addr; |
@@ -1722,10 +1763,14 @@ int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset) | |||
1722 | if (is_own) | 1763 | if (is_own) |
1723 | continue; | 1764 | continue; |
1724 | 1765 | ||
1766 | spin_lock_bh(&backbone_gw->crc_lock); | ||
1767 | backbone_crc = backbone_gw->crc; | ||
1768 | spin_unlock_bh(&backbone_gw->crc_lock); | ||
1769 | |||
1725 | seq_printf(seq, " * %pM on %5d %4i.%03is (%#.4x)\n", | 1770 | seq_printf(seq, " * %pM on %5d %4i.%03is (%#.4x)\n", |
1726 | backbone_gw->orig, | 1771 | backbone_gw->orig, |
1727 | BATADV_PRINT_VID(backbone_gw->vid), secs, | 1772 | BATADV_PRINT_VID(backbone_gw->vid), secs, |
1728 | msecs, backbone_gw->crc); | 1773 | msecs, backbone_crc); |
1729 | } | 1774 | } |
1730 | rcu_read_unlock(); | 1775 | rcu_read_unlock(); |
1731 | } | 1776 | } |