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) -----BEGIN PGP SIGNATURE----- iQJKBAABCgA0FiEE1ilQI7G+y+fdhnrfoSvjmEKSnqEFAl9ks7UWHHN3QHNpbW9u d3VuZGVybGljaC5kZQAKCRChK+OYQpKeoePDEACQyp9GN3N2VvqfwZI8GQUPuFTY L7JjyzIDAL9B2zx25YGicznKmnjnIuM37kX9YEWWc+PPJTrc0d3CV/jEzqwIFxBo 2stdB+x7idVgxI2drmOsFou5fxNknMxduW1CxQmr/V9c2PAkF/qkiZYLdHjSddVN WwMVnmWIP95cfkBZ1TsmxUdAh/vftjBGF0InbveX5ETsuPCXOVnApokwg6PqYGA8 fZ0YorZx5h16JIlhuv8//yNb12w677AuC2ze1MXfFU165Xh8A4seUTLtFUZ7muTj 0i5Bjc+yKzKUYjXOy6lIu6vWS3ogsvDedNTIWVcJ4K6hmniz6gzQggSBtiN8qt+O jwp8m3Rcci9gZo4UfBlOclJic2ywI6SecUFYxEdjHtGdl3vHzitp/tgVkTTjbI+v vCXThn1iC7g5TrheroYpWfdFOyChL5i3RmfE4ypOGNeND6ZcSYBrmAI1JbsPcEv4 07qF5o61NReNWspCXMKjOjRNEiTeV3/lNOjIdzTCFajC208hyKptEZK7CH9FZPqr d3QHzr/xDce5kzVk2xiH/LTXcpZT4BjuKbCIaobsjuQCn3i2D4LGeE4L5Ek/WIX8 yW4G8hXW2AgXeReGIn96WhCPLm8NtviAsmN9DFvN0tBmMQmbpyYFPzzGdtCGId00 S87ikl+G+OD+Q/BCMA== =JjK9 -----END PGP SIGNATURE----- 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>
This commit is contained in:
commit
8f623a10c3
@ -25,6 +25,7 @@
|
|||||||
#include <linux/lockdep.h>
|
#include <linux/lockdep.h>
|
||||||
#include <linux/netdevice.h>
|
#include <linux/netdevice.h>
|
||||||
#include <linux/netlink.h>
|
#include <linux/netlink.h>
|
||||||
|
#include <linux/preempt.h>
|
||||||
#include <linux/rculist.h>
|
#include <linux/rculist.h>
|
||||||
#include <linux/rcupdate.h>
|
#include <linux/rcupdate.h>
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
@ -83,11 +84,12 @@ static inline u32 batadv_choose_claim(const void *data, u32 size)
|
|||||||
*/
|
*/
|
||||||
static inline u32 batadv_choose_backbone_gw(const void *data, u32 size)
|
static inline u32 batadv_choose_backbone_gw(const void *data, u32 size)
|
||||||
{
|
{
|
||||||
const struct batadv_bla_claim *claim = (struct batadv_bla_claim *)data;
|
const struct batadv_bla_backbone_gw *gw;
|
||||||
u32 hash = 0;
|
u32 hash = 0;
|
||||||
|
|
||||||
hash = jhash(&claim->addr, sizeof(claim->addr), hash);
|
gw = (struct batadv_bla_backbone_gw *)data;
|
||||||
hash = jhash(&claim->vid, sizeof(claim->vid), hash);
|
hash = jhash(&gw->orig, sizeof(gw->orig), hash);
|
||||||
|
hash = jhash(&gw->vid, sizeof(gw->vid), hash);
|
||||||
|
|
||||||
return hash % size;
|
return hash % size;
|
||||||
}
|
}
|
||||||
@ -1579,13 +1581,16 @@ int batadv_bla_init(struct batadv_priv *bat_priv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* batadv_bla_check_bcast_duplist() - Check if a frame is in the broadcast dup.
|
* batadv_bla_check_duplist() - Check if a frame is in the broadcast dup.
|
||||||
* @bat_priv: the bat priv with all the soft interface information
|
* @bat_priv: the bat priv with all the soft interface information
|
||||||
* @skb: contains the bcast_packet to be checked
|
* @skb: contains the multicast packet to be checked
|
||||||
|
* @payload_ptr: pointer to position inside the head buffer of the skb
|
||||||
|
* marking the start of the data to be CRC'ed
|
||||||
|
* @orig: originator mac address, NULL if unknown
|
||||||
*
|
*
|
||||||
* check if it is on our broadcast list. Another gateway might
|
* Check if it is on our broadcast list. Another gateway might have sent the
|
||||||
* have sent the same packet because it is connected to the same backbone,
|
* same packet because it is connected to the same backbone, so we have to
|
||||||
* so we have to remove this duplicate.
|
* remove this duplicate.
|
||||||
*
|
*
|
||||||
* This is performed by checking the CRC, which will tell us
|
* This is performed by checking the CRC, which will tell us
|
||||||
* with a good chance that it is the same packet. If it is furthermore
|
* 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)
|
|||||||
*
|
*
|
||||||
* Return: true if a packet is in the duplicate list, false otherwise.
|
* Return: true if a packet is in the duplicate list, false otherwise.
|
||||||
*/
|
*/
|
||||||
bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
|
static bool batadv_bla_check_duplist(struct batadv_priv *bat_priv,
|
||||||
struct sk_buff *skb)
|
struct sk_buff *skb, u8 *payload_ptr,
|
||||||
|
const u8 *orig)
|
||||||
{
|
{
|
||||||
int i, curr;
|
|
||||||
__be32 crc;
|
|
||||||
struct batadv_bcast_packet *bcast_packet;
|
|
||||||
struct batadv_bcast_duplist_entry *entry;
|
struct batadv_bcast_duplist_entry *entry;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
int i, curr;
|
||||||
bcast_packet = (struct batadv_bcast_packet *)skb->data;
|
__be32 crc;
|
||||||
|
|
||||||
/* calculate the crc ... */
|
/* calculate the crc ... */
|
||||||
crc = batadv_skb_crc32(skb, (u8 *)(bcast_packet + 1));
|
crc = batadv_skb_crc32(skb, payload_ptr);
|
||||||
|
|
||||||
spin_lock_bh(&bat_priv->bla.bcast_duplist_lock);
|
spin_lock_bh(&bat_priv->bla.bcast_duplist_lock);
|
||||||
|
|
||||||
@ -1625,8 +1628,21 @@ bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
|
|||||||
if (entry->crc != crc)
|
if (entry->crc != crc)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (batadv_compare_eth(entry->orig, bcast_packet->orig))
|
/* are the originators both known and not anonymous? */
|
||||||
continue;
|
if (orig && !is_zero_ether_addr(orig) &&
|
||||||
|
!is_zero_ether_addr(entry->orig)) {
|
||||||
|
/* If known, check if the new frame came from
|
||||||
|
* the same originator:
|
||||||
|
* We are safe to take identical frames from the
|
||||||
|
* same orig, if known, as multiplications in
|
||||||
|
* the mesh are detected via the (orig, seqno) pair.
|
||||||
|
* So we can be a bit more liberal here and allow
|
||||||
|
* identical frames from the same orig which the source
|
||||||
|
* host might have sent multiple times on purpose.
|
||||||
|
*/
|
||||||
|
if (batadv_compare_eth(entry->orig, orig))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* this entry seems to match: same crc, not too old,
|
/* this entry seems to match: same crc, not too old,
|
||||||
* and from another gw. therefore return true to forbid it.
|
* 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,
|
|||||||
entry = &bat_priv->bla.bcast_duplist[curr];
|
entry = &bat_priv->bla.bcast_duplist[curr];
|
||||||
entry->crc = crc;
|
entry->crc = crc;
|
||||||
entry->entrytime = jiffies;
|
entry->entrytime = jiffies;
|
||||||
ether_addr_copy(entry->orig, bcast_packet->orig);
|
|
||||||
|
/* known originator */
|
||||||
|
if (orig)
|
||||||
|
ether_addr_copy(entry->orig, orig);
|
||||||
|
/* anonymous originator */
|
||||||
|
else
|
||||||
|
eth_zero_addr(entry->orig);
|
||||||
|
|
||||||
bat_priv->bla.bcast_duplist_curr = curr;
|
bat_priv->bla.bcast_duplist_curr = curr;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@ -1651,6 +1674,48 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* batadv_bla_check_ucast_duplist() - Check if a frame is in the broadcast dup.
|
||||||
|
* @bat_priv: the bat priv with all the soft interface information
|
||||||
|
* @skb: contains the multicast packet to be checked, decapsulated from a
|
||||||
|
* unicast_packet
|
||||||
|
*
|
||||||
|
* Check if it is on our broadcast list. Another gateway might have sent the
|
||||||
|
* same packet because it is connected to the same backbone, so we have to
|
||||||
|
* remove this duplicate.
|
||||||
|
*
|
||||||
|
* Return: true if a packet is in the duplicate list, false otherwise.
|
||||||
|
*/
|
||||||
|
static bool batadv_bla_check_ucast_duplist(struct batadv_priv *bat_priv,
|
||||||
|
struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
return batadv_bla_check_duplist(bat_priv, skb, (u8 *)skb->data, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* batadv_bla_check_bcast_duplist() - Check if a frame is in the broadcast dup.
|
||||||
|
* @bat_priv: the bat priv with all the soft interface information
|
||||||
|
* @skb: contains the bcast_packet to be checked
|
||||||
|
*
|
||||||
|
* Check if it is on our broadcast list. Another gateway might have sent the
|
||||||
|
* same packet because it is connected to the same backbone, so we have to
|
||||||
|
* remove this duplicate.
|
||||||
|
*
|
||||||
|
* Return: true if a packet is in the duplicate list, false otherwise.
|
||||||
|
*/
|
||||||
|
bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
|
||||||
|
struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
struct batadv_bcast_packet *bcast_packet;
|
||||||
|
u8 *payload_ptr;
|
||||||
|
|
||||||
|
bcast_packet = (struct batadv_bcast_packet *)skb->data;
|
||||||
|
payload_ptr = (u8 *)(bcast_packet + 1);
|
||||||
|
|
||||||
|
return batadv_bla_check_duplist(bat_priv, skb, payload_ptr,
|
||||||
|
bcast_packet->orig);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* batadv_bla_is_backbone_gw_orig() - Check if the originator is a gateway for
|
* batadv_bla_is_backbone_gw_orig() - Check if the originator is a gateway for
|
||||||
* the VLAN identified by vid.
|
* the VLAN identified by vid.
|
||||||
@ -1812,7 +1877,7 @@ batadv_bla_loopdetect_check(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
|||||||
* @bat_priv: the bat priv with all the soft interface information
|
* @bat_priv: the bat priv with all the soft interface information
|
||||||
* @skb: the frame to be checked
|
* @skb: the frame to be checked
|
||||||
* @vid: the VLAN ID of the frame
|
* @vid: the VLAN ID of the frame
|
||||||
* @is_bcast: the packet came in a broadcast packet type.
|
* @packet_type: the batman packet type this frame came in
|
||||||
*
|
*
|
||||||
* batadv_bla_rx avoidance checks if:
|
* batadv_bla_rx avoidance checks if:
|
||||||
* * we have to race for a claim
|
* * we have to race for a claim
|
||||||
@ -1824,7 +1889,7 @@ batadv_bla_loopdetect_check(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
|||||||
* further process the skb.
|
* further process the skb.
|
||||||
*/
|
*/
|
||||||
bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||||
unsigned short vid, bool is_bcast)
|
unsigned short vid, int packet_type)
|
||||||
{
|
{
|
||||||
struct batadv_bla_backbone_gw *backbone_gw;
|
struct batadv_bla_backbone_gw *backbone_gw;
|
||||||
struct ethhdr *ethhdr;
|
struct ethhdr *ethhdr;
|
||||||
@ -1846,9 +1911,32 @@ bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
|||||||
goto handled;
|
goto handled;
|
||||||
|
|
||||||
if (unlikely(atomic_read(&bat_priv->bla.num_requests)))
|
if (unlikely(atomic_read(&bat_priv->bla.num_requests)))
|
||||||
/* don't allow broadcasts while requests are in flight */
|
/* don't allow multicast packets while requests are in flight */
|
||||||
if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast)
|
if (is_multicast_ether_addr(ethhdr->h_dest))
|
||||||
goto handled;
|
/* Both broadcast flooding or multicast-via-unicasts
|
||||||
|
* delivery might send to multiple backbone gateways
|
||||||
|
* sharing the same LAN and therefore need to coordinate
|
||||||
|
* which backbone gateway forwards into the LAN,
|
||||||
|
* by claiming the payload source address.
|
||||||
|
*
|
||||||
|
* Broadcast flooding and multicast-via-unicasts
|
||||||
|
* delivery use the following two batman packet types.
|
||||||
|
* Note: explicitly exclude BATADV_UNICAST_4ADDR,
|
||||||
|
* as the DHCP gateway feature will send explicitly
|
||||||
|
* to only one BLA gateway, so the claiming process
|
||||||
|
* should be avoided there.
|
||||||
|
*/
|
||||||
|
if (packet_type == BATADV_BCAST ||
|
||||||
|
packet_type == BATADV_UNICAST)
|
||||||
|
goto handled;
|
||||||
|
|
||||||
|
/* potential duplicates from foreign BLA backbone gateways via
|
||||||
|
* multicast-in-unicast packets
|
||||||
|
*/
|
||||||
|
if (is_multicast_ether_addr(ethhdr->h_dest) &&
|
||||||
|
packet_type == BATADV_UNICAST &&
|
||||||
|
batadv_bla_check_ucast_duplist(bat_priv, skb))
|
||||||
|
goto handled;
|
||||||
|
|
||||||
ether_addr_copy(search_claim.addr, ethhdr->h_source);
|
ether_addr_copy(search_claim.addr, ethhdr->h_source);
|
||||||
search_claim.vid = vid;
|
search_claim.vid = vid;
|
||||||
@ -1883,13 +1971,14 @@ bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
|||||||
goto allow;
|
goto allow;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if it is a broadcast ... */
|
/* if it is a multicast ... */
|
||||||
if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast) {
|
if (is_multicast_ether_addr(ethhdr->h_dest) &&
|
||||||
|
(packet_type == BATADV_BCAST || packet_type == BATADV_UNICAST)) {
|
||||||
/* ... drop it. the responsible gateway is in charge.
|
/* ... drop it. the responsible gateway is in charge.
|
||||||
*
|
*
|
||||||
* We need to check is_bcast because with the gateway
|
* We need to check packet type because with the gateway
|
||||||
* feature, broadcasts (like DHCP requests) may be sent
|
* feature, broadcasts (like DHCP requests) may be sent
|
||||||
* using a unicast packet type.
|
* using a unicast 4 address packet type. See comment above.
|
||||||
*/
|
*/
|
||||||
goto handled;
|
goto handled;
|
||||||
} else {
|
} else {
|
||||||
|
@ -35,7 +35,7 @@ static inline bool batadv_bla_is_loopdetect_mac(const uint8_t *mac)
|
|||||||
|
|
||||||
#ifdef CONFIG_BATMAN_ADV_BLA
|
#ifdef CONFIG_BATMAN_ADV_BLA
|
||||||
bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||||
unsigned short vid, bool is_bcast);
|
unsigned short vid, int packet_type);
|
||||||
bool batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
bool batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||||
unsigned short vid);
|
unsigned short vid);
|
||||||
bool batadv_bla_is_backbone_gw(struct sk_buff *skb,
|
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,
|
|||||||
|
|
||||||
static inline bool batadv_bla_rx(struct batadv_priv *bat_priv,
|
static inline bool batadv_bla_rx(struct batadv_priv *bat_priv,
|
||||||
struct sk_buff *skb, unsigned short vid,
|
struct sk_buff *skb, unsigned short vid,
|
||||||
bool is_bcast)
|
int packet_type)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,7 @@
|
|||||||
#include <uapi/linux/batadv_packet.h>
|
#include <uapi/linux/batadv_packet.h>
|
||||||
#include <uapi/linux/batman_adv.h>
|
#include <uapi/linux/batman_adv.h>
|
||||||
|
|
||||||
|
#include "bridge_loop_avoidance.h"
|
||||||
#include "hard-interface.h"
|
#include "hard-interface.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
@ -1434,6 +1435,35 @@ batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
|||||||
return BATADV_FORW_ALL;
|
return BATADV_FORW_ALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* batadv_mcast_forw_send_orig() - send a multicast packet to an originator
|
||||||
|
* @bat_priv: the bat priv with all the soft interface information
|
||||||
|
* @skb: the multicast packet to send
|
||||||
|
* @vid: the vlan identifier
|
||||||
|
* @orig_node: the originator to send the packet to
|
||||||
|
*
|
||||||
|
* Return: NET_XMIT_DROP in case of error or NET_XMIT_SUCCESS otherwise.
|
||||||
|
*/
|
||||||
|
int batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv,
|
||||||
|
struct sk_buff *skb,
|
||||||
|
unsigned short vid,
|
||||||
|
struct batadv_orig_node *orig_node)
|
||||||
|
{
|
||||||
|
/* Avoid sending multicast-in-unicast packets to other BLA
|
||||||
|
* gateways - they already got the frame from the LAN side
|
||||||
|
* we share with them.
|
||||||
|
* TODO: Refactor to take BLA into account earlier, to avoid
|
||||||
|
* reducing the mcast_fanout count.
|
||||||
|
*/
|
||||||
|
if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig, vid)) {
|
||||||
|
dev_kfree_skb(skb);
|
||||||
|
return NET_XMIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return batadv_send_skb_unicast(bat_priv, skb, BATADV_UNICAST, 0,
|
||||||
|
orig_node, vid);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* batadv_mcast_forw_tt() - forwards a packet to multicast listeners
|
* batadv_mcast_forw_tt() - forwards a packet to multicast listeners
|
||||||
* @bat_priv: the bat priv with all the soft interface information
|
* @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,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
batadv_send_skb_unicast(bat_priv, newskb, BATADV_UNICAST, 0,
|
batadv_mcast_forw_send_orig(bat_priv, newskb, vid,
|
||||||
orig_entry->orig_node, vid);
|
orig_entry->orig_node);
|
||||||
}
|
}
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
||||||
@ -1513,8 +1543,7 @@ batadv_mcast_forw_want_all_ipv4(struct batadv_priv *bat_priv,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
batadv_send_skb_unicast(bat_priv, newskb, BATADV_UNICAST, 0,
|
batadv_mcast_forw_send_orig(bat_priv, newskb, vid, orig_node);
|
||||||
orig_node, vid);
|
|
||||||
}
|
}
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
return ret;
|
return ret;
|
||||||
@ -1551,8 +1580,7 @@ batadv_mcast_forw_want_all_ipv6(struct batadv_priv *bat_priv,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
batadv_send_skb_unicast(bat_priv, newskb, BATADV_UNICAST, 0,
|
batadv_mcast_forw_send_orig(bat_priv, newskb, vid, orig_node);
|
||||||
orig_node, vid);
|
|
||||||
}
|
}
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
return ret;
|
return ret;
|
||||||
@ -1618,8 +1646,7 @@ batadv_mcast_forw_want_all_rtr4(struct batadv_priv *bat_priv,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
batadv_send_skb_unicast(bat_priv, newskb, BATADV_UNICAST, 0,
|
batadv_mcast_forw_send_orig(bat_priv, newskb, vid, orig_node);
|
||||||
orig_node, vid);
|
|
||||||
}
|
}
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
return ret;
|
return ret;
|
||||||
@ -1656,8 +1683,7 @@ batadv_mcast_forw_want_all_rtr6(struct batadv_priv *bat_priv,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
batadv_send_skb_unicast(bat_priv, newskb, BATADV_UNICAST, 0,
|
batadv_mcast_forw_send_orig(bat_priv, newskb, vid, orig_node);
|
||||||
orig_node, vid);
|
|
||||||
}
|
}
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -46,6 +46,11 @@ enum batadv_forw_mode
|
|||||||
batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||||
struct batadv_orig_node **mcast_single_orig);
|
struct batadv_orig_node **mcast_single_orig);
|
||||||
|
|
||||||
|
int batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv,
|
||||||
|
struct sk_buff *skb,
|
||||||
|
unsigned short vid,
|
||||||
|
struct batadv_orig_node *orig_node);
|
||||||
|
|
||||||
int batadv_mcast_forw_send(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
int batadv_mcast_forw_send(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||||
unsigned short vid);
|
unsigned short vid);
|
||||||
|
|
||||||
@ -71,6 +76,16 @@ batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
|||||||
return BATADV_FORW_ALL;
|
return BATADV_FORW_ALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv,
|
||||||
|
struct sk_buff *skb,
|
||||||
|
unsigned short vid,
|
||||||
|
struct batadv_orig_node *orig_node)
|
||||||
|
{
|
||||||
|
kfree_skb(skb);
|
||||||
|
return NET_XMIT_DROP;
|
||||||
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
batadv_mcast_forw_send(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
batadv_mcast_forw_send(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||||
unsigned short vid)
|
unsigned short vid)
|
||||||
|
@ -826,6 +826,10 @@ static bool batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
|
|||||||
vid = batadv_get_vid(skb, hdr_len);
|
vid = batadv_get_vid(skb, hdr_len);
|
||||||
ethhdr = (struct ethhdr *)(skb->data + hdr_len);
|
ethhdr = (struct ethhdr *)(skb->data + hdr_len);
|
||||||
|
|
||||||
|
/* do not reroute multicast frames in a unicast header */
|
||||||
|
if (is_multicast_ether_addr(ethhdr->h_dest))
|
||||||
|
return true;
|
||||||
|
|
||||||
/* check if the destination client was served by this node and it is now
|
/* check if the destination client was served by this node and it is now
|
||||||
* roaming. In this case, it means that the node has got a ROAM_ADV
|
* roaming. In this case, it means that the node has got a ROAM_ADV
|
||||||
* message and that it knows the new destination in the mesh to re-route
|
* message and that it knows the new destination in the mesh to re-route
|
||||||
|
@ -364,9 +364,8 @@ send:
|
|||||||
goto dropped;
|
goto dropped;
|
||||||
ret = batadv_send_skb_via_gw(bat_priv, skb, vid);
|
ret = batadv_send_skb_via_gw(bat_priv, skb, vid);
|
||||||
} else if (mcast_single_orig) {
|
} else if (mcast_single_orig) {
|
||||||
ret = batadv_send_skb_unicast(bat_priv, skb,
|
ret = batadv_mcast_forw_send_orig(bat_priv, skb, vid,
|
||||||
BATADV_UNICAST, 0,
|
mcast_single_orig);
|
||||||
mcast_single_orig, vid);
|
|
||||||
} else if (forw_mode == BATADV_FORW_SOME) {
|
} else if (forw_mode == BATADV_FORW_SOME) {
|
||||||
ret = batadv_mcast_forw_send(bat_priv, skb, vid);
|
ret = batadv_mcast_forw_send(bat_priv, skb, vid);
|
||||||
} else {
|
} else {
|
||||||
@ -425,10 +424,10 @@ void batadv_interface_rx(struct net_device *soft_iface,
|
|||||||
struct vlan_ethhdr *vhdr;
|
struct vlan_ethhdr *vhdr;
|
||||||
struct ethhdr *ethhdr;
|
struct ethhdr *ethhdr;
|
||||||
unsigned short vid;
|
unsigned short vid;
|
||||||
bool is_bcast;
|
int packet_type;
|
||||||
|
|
||||||
batadv_bcast_packet = (struct batadv_bcast_packet *)skb->data;
|
batadv_bcast_packet = (struct batadv_bcast_packet *)skb->data;
|
||||||
is_bcast = (batadv_bcast_packet->packet_type == BATADV_BCAST);
|
packet_type = batadv_bcast_packet->packet_type;
|
||||||
|
|
||||||
skb_pull_rcsum(skb, hdr_size);
|
skb_pull_rcsum(skb, hdr_size);
|
||||||
skb_reset_mac_header(skb);
|
skb_reset_mac_header(skb);
|
||||||
@ -471,7 +470,7 @@ void batadv_interface_rx(struct net_device *soft_iface,
|
|||||||
/* Let the bridge loop avoidance check the packet. If will
|
/* Let the bridge loop avoidance check the packet. If will
|
||||||
* not handle it, we can safely push it up.
|
* not handle it, we can safely push it up.
|
||||||
*/
|
*/
|
||||||
if (batadv_bla_rx(bat_priv, skb, vid, is_bcast))
|
if (batadv_bla_rx(bat_priv, skb, vid, packet_type))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (orig_node)
|
if (orig_node)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user