Skip to content

Commit 8f623a1

Browse files
committed
Merge tag 'batadv-net-for-davem-20200918' of git://git.open-mesh.org/linux-merge
Simon Wunderlich says: ==================== Here are some batman-adv bugfixes: - fix wrong type use in backbone_gw hash, by Linus Luessing - disable TT re-routing for multicast packets, by Linus Luessing - Add missing include for in_interrupt(), by Sven Eckelmann - fix BLA/multicast issues for packets sent via unicast, by Linus Luessing (3 patches) ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents a128592 + 2369e82 commit 8f623a1

File tree

6 files changed

+179
-46
lines changed

6 files changed

+179
-46
lines changed

net/batman-adv/bridge_loop_avoidance.c

Lines changed: 117 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <linux/lockdep.h>
2626
#include <linux/netdevice.h>
2727
#include <linux/netlink.h>
28+
#include <linux/preempt.h>
2829
#include <linux/rculist.h>
2930
#include <linux/rcupdate.h>
3031
#include <linux/seq_file.h>
@@ -83,11 +84,12 @@ static inline u32 batadv_choose_claim(const void *data, u32 size)
8384
*/
8485
static inline u32 batadv_choose_backbone_gw(const void *data, u32 size)
8586
{
86-
const struct batadv_bla_claim *claim = (struct batadv_bla_claim *)data;
87+
const struct batadv_bla_backbone_gw *gw;
8788
u32 hash = 0;
8889

89-
hash = jhash(&claim->addr, sizeof(claim->addr), hash);
90-
hash = jhash(&claim->vid, sizeof(claim->vid), hash);
90+
gw = (struct batadv_bla_backbone_gw *)data;
91+
hash = jhash(&gw->orig, sizeof(gw->orig), hash);
92+
hash = jhash(&gw->vid, sizeof(gw->vid), hash);
9193

9294
return hash % size;
9395
}
@@ -1579,13 +1581,16 @@ int batadv_bla_init(struct batadv_priv *bat_priv)
15791581
}
15801582

15811583
/**
1582-
* batadv_bla_check_bcast_duplist() - Check if a frame is in the broadcast dup.
1584+
* batadv_bla_check_duplist() - Check if a frame is in the broadcast dup.
15831585
* @bat_priv: the bat priv with all the soft interface information
1584-
* @skb: contains the bcast_packet to be checked
1586+
* @skb: contains the multicast packet to be checked
1587+
* @payload_ptr: pointer to position inside the head buffer of the skb
1588+
* marking the start of the data to be CRC'ed
1589+
* @orig: originator mac address, NULL if unknown
15851590
*
1586-
* check if it is on our broadcast list. Another gateway might
1587-
* have sent the same packet because it is connected to the same backbone,
1588-
* so we have to remove this duplicate.
1591+
* Check if it is on our broadcast list. Another gateway might have sent the
1592+
* same packet because it is connected to the same backbone, so we have to
1593+
* remove this duplicate.
15891594
*
15901595
* This is performed by checking the CRC, which will tell us
15911596
* with a good chance that it is the same packet. If it is furthermore
@@ -1594,19 +1599,17 @@ int batadv_bla_init(struct batadv_priv *bat_priv)
15941599
*
15951600
* Return: true if a packet is in the duplicate list, false otherwise.
15961601
*/
1597-
bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
1598-
struct sk_buff *skb)
1602+
static bool batadv_bla_check_duplist(struct batadv_priv *bat_priv,
1603+
struct sk_buff *skb, u8 *payload_ptr,
1604+
const u8 *orig)
15991605
{
1600-
int i, curr;
1601-
__be32 crc;
1602-
struct batadv_bcast_packet *bcast_packet;
16031606
struct batadv_bcast_duplist_entry *entry;
16041607
bool ret = false;
1605-
1606-
bcast_packet = (struct batadv_bcast_packet *)skb->data;
1608+
int i, curr;
1609+
__be32 crc;
16071610

16081611
/* calculate the crc ... */
1609-
crc = batadv_skb_crc32(skb, (u8 *)(bcast_packet + 1));
1612+
crc = batadv_skb_crc32(skb, payload_ptr);
16101613

16111614
spin_lock_bh(&bat_priv->bla.bcast_duplist_lock);
16121615

@@ -1625,8 +1628,21 @@ bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
16251628
if (entry->crc != crc)
16261629
continue;
16271630

1628-
if (batadv_compare_eth(entry->orig, bcast_packet->orig))
1629-
continue;
1631+
/* are the originators both known and not anonymous? */
1632+
if (orig && !is_zero_ether_addr(orig) &&
1633+
!is_zero_ether_addr(entry->orig)) {
1634+
/* If known, check if the new frame came from
1635+
* the same originator:
1636+
* We are safe to take identical frames from the
1637+
* same orig, if known, as multiplications in
1638+
* the mesh are detected via the (orig, seqno) pair.
1639+
* So we can be a bit more liberal here and allow
1640+
* identical frames from the same orig which the source
1641+
* host might have sent multiple times on purpose.
1642+
*/
1643+
if (batadv_compare_eth(entry->orig, orig))
1644+
continue;
1645+
}
16301646

16311647
/* this entry seems to match: same crc, not too old,
16321648
* and from another gw. therefore return true to forbid it.
@@ -1642,7 +1658,14 @@ bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
16421658
entry = &bat_priv->bla.bcast_duplist[curr];
16431659
entry->crc = crc;
16441660
entry->entrytime = jiffies;
1645-
ether_addr_copy(entry->orig, bcast_packet->orig);
1661+
1662+
/* known originator */
1663+
if (orig)
1664+
ether_addr_copy(entry->orig, orig);
1665+
/* anonymous originator */
1666+
else
1667+
eth_zero_addr(entry->orig);
1668+
16461669
bat_priv->bla.bcast_duplist_curr = curr;
16471670

16481671
out:
@@ -1651,6 +1674,48 @@ bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
16511674
return ret;
16521675
}
16531676

1677+
/**
1678+
* batadv_bla_check_ucast_duplist() - Check if a frame is in the broadcast dup.
1679+
* @bat_priv: the bat priv with all the soft interface information
1680+
* @skb: contains the multicast packet to be checked, decapsulated from a
1681+
* unicast_packet
1682+
*
1683+
* Check if it is on our broadcast list. Another gateway might have sent the
1684+
* same packet because it is connected to the same backbone, so we have to
1685+
* remove this duplicate.
1686+
*
1687+
* Return: true if a packet is in the duplicate list, false otherwise.
1688+
*/
1689+
static bool batadv_bla_check_ucast_duplist(struct batadv_priv *bat_priv,
1690+
struct sk_buff *skb)
1691+
{
1692+
return batadv_bla_check_duplist(bat_priv, skb, (u8 *)skb->data, NULL);
1693+
}
1694+
1695+
/**
1696+
* batadv_bla_check_bcast_duplist() - Check if a frame is in the broadcast dup.
1697+
* @bat_priv: the bat priv with all the soft interface information
1698+
* @skb: contains the bcast_packet to be checked
1699+
*
1700+
* Check if it is on our broadcast list. Another gateway might have sent the
1701+
* same packet because it is connected to the same backbone, so we have to
1702+
* remove this duplicate.
1703+
*
1704+
* Return: true if a packet is in the duplicate list, false otherwise.
1705+
*/
1706+
bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
1707+
struct sk_buff *skb)
1708+
{
1709+
struct batadv_bcast_packet *bcast_packet;
1710+
u8 *payload_ptr;
1711+
1712+
bcast_packet = (struct batadv_bcast_packet *)skb->data;
1713+
payload_ptr = (u8 *)(bcast_packet + 1);
1714+
1715+
return batadv_bla_check_duplist(bat_priv, skb, payload_ptr,
1716+
bcast_packet->orig);
1717+
}
1718+
16541719
/**
16551720
* batadv_bla_is_backbone_gw_orig() - Check if the originator is a gateway for
16561721
* the VLAN identified by vid.
@@ -1812,7 +1877,7 @@ batadv_bla_loopdetect_check(struct batadv_priv *bat_priv, struct sk_buff *skb,
18121877
* @bat_priv: the bat priv with all the soft interface information
18131878
* @skb: the frame to be checked
18141879
* @vid: the VLAN ID of the frame
1815-
* @is_bcast: the packet came in a broadcast packet type.
1880+
* @packet_type: the batman packet type this frame came in
18161881
*
18171882
* batadv_bla_rx avoidance checks if:
18181883
* * we have to race for a claim
@@ -1824,7 +1889,7 @@ batadv_bla_loopdetect_check(struct batadv_priv *bat_priv, struct sk_buff *skb,
18241889
* further process the skb.
18251890
*/
18261891
bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
1827-
unsigned short vid, bool is_bcast)
1892+
unsigned short vid, int packet_type)
18281893
{
18291894
struct batadv_bla_backbone_gw *backbone_gw;
18301895
struct ethhdr *ethhdr;
@@ -1846,9 +1911,32 @@ bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
18461911
goto handled;
18471912

18481913
if (unlikely(atomic_read(&bat_priv->bla.num_requests)))
1849-
/* don't allow broadcasts while requests are in flight */
1850-
if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast)
1851-
goto handled;
1914+
/* don't allow multicast packets while requests are in flight */
1915+
if (is_multicast_ether_addr(ethhdr->h_dest))
1916+
/* Both broadcast flooding or multicast-via-unicasts
1917+
* delivery might send to multiple backbone gateways
1918+
* sharing the same LAN and therefore need to coordinate
1919+
* which backbone gateway forwards into the LAN,
1920+
* by claiming the payload source address.
1921+
*
1922+
* Broadcast flooding and multicast-via-unicasts
1923+
* delivery use the following two batman packet types.
1924+
* Note: explicitly exclude BATADV_UNICAST_4ADDR,
1925+
* as the DHCP gateway feature will send explicitly
1926+
* to only one BLA gateway, so the claiming process
1927+
* should be avoided there.
1928+
*/
1929+
if (packet_type == BATADV_BCAST ||
1930+
packet_type == BATADV_UNICAST)
1931+
goto handled;
1932+
1933+
/* potential duplicates from foreign BLA backbone gateways via
1934+
* multicast-in-unicast packets
1935+
*/
1936+
if (is_multicast_ether_addr(ethhdr->h_dest) &&
1937+
packet_type == BATADV_UNICAST &&
1938+
batadv_bla_check_ucast_duplist(bat_priv, skb))
1939+
goto handled;
18521940

18531941
ether_addr_copy(search_claim.addr, ethhdr->h_source);
18541942
search_claim.vid = vid;
@@ -1883,13 +1971,14 @@ bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
18831971
goto allow;
18841972
}
18851973

1886-
/* if it is a broadcast ... */
1887-
if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast) {
1974+
/* if it is a multicast ... */
1975+
if (is_multicast_ether_addr(ethhdr->h_dest) &&
1976+
(packet_type == BATADV_BCAST || packet_type == BATADV_UNICAST)) {
18881977
/* ... drop it. the responsible gateway is in charge.
18891978
*
1890-
* We need to check is_bcast because with the gateway
1979+
* We need to check packet type because with the gateway
18911980
* feature, broadcasts (like DHCP requests) may be sent
1892-
* using a unicast packet type.
1981+
* using a unicast 4 address packet type. See comment above.
18931982
*/
18941983
goto handled;
18951984
} else {

net/batman-adv/bridge_loop_avoidance.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ static inline bool batadv_bla_is_loopdetect_mac(const uint8_t *mac)
3535

3636
#ifdef CONFIG_BATMAN_ADV_BLA
3737
bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
38-
unsigned short vid, bool is_bcast);
38+
unsigned short vid, int packet_type);
3939
bool batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb,
4040
unsigned short vid);
4141
bool batadv_bla_is_backbone_gw(struct sk_buff *skb,
@@ -66,7 +66,7 @@ bool batadv_bla_check_claim(struct batadv_priv *bat_priv, u8 *addr,
6666

6767
static inline bool batadv_bla_rx(struct batadv_priv *bat_priv,
6868
struct sk_buff *skb, unsigned short vid,
69-
bool is_bcast)
69+
int packet_type)
7070
{
7171
return false;
7272
}

net/batman-adv/multicast.c

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#include <uapi/linux/batadv_packet.h>
5252
#include <uapi/linux/batman_adv.h>
5353

54+
#include "bridge_loop_avoidance.h"
5455
#include "hard-interface.h"
5556
#include "hash.h"
5657
#include "log.h"
@@ -1434,6 +1435,35 @@ batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
14341435
return BATADV_FORW_ALL;
14351436
}
14361437

1438+
/**
1439+
* batadv_mcast_forw_send_orig() - send a multicast packet to an originator
1440+
* @bat_priv: the bat priv with all the soft interface information
1441+
* @skb: the multicast packet to send
1442+
* @vid: the vlan identifier
1443+
* @orig_node: the originator to send the packet to
1444+
*
1445+
* Return: NET_XMIT_DROP in case of error or NET_XMIT_SUCCESS otherwise.
1446+
*/
1447+
int batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv,
1448+
struct sk_buff *skb,
1449+
unsigned short vid,
1450+
struct batadv_orig_node *orig_node)
1451+
{
1452+
/* Avoid sending multicast-in-unicast packets to other BLA
1453+
* gateways - they already got the frame from the LAN side
1454+
* we share with them.
1455+
* TODO: Refactor to take BLA into account earlier, to avoid
1456+
* reducing the mcast_fanout count.
1457+
*/
1458+
if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig, vid)) {
1459+
dev_kfree_skb(skb);
1460+
return NET_XMIT_SUCCESS;
1461+
}
1462+
1463+
return batadv_send_skb_unicast(bat_priv, skb, BATADV_UNICAST, 0,
1464+
orig_node, vid);
1465+
}
1466+
14371467
/**
14381468
* batadv_mcast_forw_tt() - forwards a packet to multicast listeners
14391469
* @bat_priv: the bat priv with all the soft interface information
@@ -1471,8 +1501,8 @@ batadv_mcast_forw_tt(struct batadv_priv *bat_priv, struct sk_buff *skb,
14711501
break;
14721502
}
14731503

1474-
batadv_send_skb_unicast(bat_priv, newskb, BATADV_UNICAST, 0,
1475-
orig_entry->orig_node, vid);
1504+
batadv_mcast_forw_send_orig(bat_priv, newskb, vid,
1505+
orig_entry->orig_node);
14761506
}
14771507
rcu_read_unlock();
14781508

@@ -1513,8 +1543,7 @@ batadv_mcast_forw_want_all_ipv4(struct batadv_priv *bat_priv,
15131543
break;
15141544
}
15151545

1516-
batadv_send_skb_unicast(bat_priv, newskb, BATADV_UNICAST, 0,
1517-
orig_node, vid);
1546+
batadv_mcast_forw_send_orig(bat_priv, newskb, vid, orig_node);
15181547
}
15191548
rcu_read_unlock();
15201549
return ret;
@@ -1551,8 +1580,7 @@ batadv_mcast_forw_want_all_ipv6(struct batadv_priv *bat_priv,
15511580
break;
15521581
}
15531582

1554-
batadv_send_skb_unicast(bat_priv, newskb, BATADV_UNICAST, 0,
1555-
orig_node, vid);
1583+
batadv_mcast_forw_send_orig(bat_priv, newskb, vid, orig_node);
15561584
}
15571585
rcu_read_unlock();
15581586
return ret;
@@ -1618,8 +1646,7 @@ batadv_mcast_forw_want_all_rtr4(struct batadv_priv *bat_priv,
16181646
break;
16191647
}
16201648

1621-
batadv_send_skb_unicast(bat_priv, newskb, BATADV_UNICAST, 0,
1622-
orig_node, vid);
1649+
batadv_mcast_forw_send_orig(bat_priv, newskb, vid, orig_node);
16231650
}
16241651
rcu_read_unlock();
16251652
return ret;
@@ -1656,8 +1683,7 @@ batadv_mcast_forw_want_all_rtr6(struct batadv_priv *bat_priv,
16561683
break;
16571684
}
16581685

1659-
batadv_send_skb_unicast(bat_priv, newskb, BATADV_UNICAST, 0,
1660-
orig_node, vid);
1686+
batadv_mcast_forw_send_orig(bat_priv, newskb, vid, orig_node);
16611687
}
16621688
rcu_read_unlock();
16631689
return ret;

net/batman-adv/multicast.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ enum batadv_forw_mode
4646
batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
4747
struct batadv_orig_node **mcast_single_orig);
4848

49+
int batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv,
50+
struct sk_buff *skb,
51+
unsigned short vid,
52+
struct batadv_orig_node *orig_node);
53+
4954
int batadv_mcast_forw_send(struct batadv_priv *bat_priv, struct sk_buff *skb,
5055
unsigned short vid);
5156

@@ -71,6 +76,16 @@ batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
7176
return BATADV_FORW_ALL;
7277
}
7378

79+
static inline int
80+
batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv,
81+
struct sk_buff *skb,
82+
unsigned short vid,
83+
struct batadv_orig_node *orig_node)
84+
{
85+
kfree_skb(skb);
86+
return NET_XMIT_DROP;
87+
}
88+
7489
static inline int
7590
batadv_mcast_forw_send(struct batadv_priv *bat_priv, struct sk_buff *skb,
7691
unsigned short vid)

net/batman-adv/routing.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -826,6 +826,10 @@ static bool batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
826826
vid = batadv_get_vid(skb, hdr_len);
827827
ethhdr = (struct ethhdr *)(skb->data + hdr_len);
828828

829+
/* do not reroute multicast frames in a unicast header */
830+
if (is_multicast_ether_addr(ethhdr->h_dest))
831+
return true;
832+
829833
/* check if the destination client was served by this node and it is now
830834
* roaming. In this case, it means that the node has got a ROAM_ADV
831835
* message and that it knows the new destination in the mesh to re-route

0 commit comments

Comments
 (0)