Commit 860b4042 authored by David S. Miller's avatar David S. Miller

Merge tag 'batman-adv-for-davem' of git://git.open-mesh.org/linux-merge

Antonio Quartulli says:

====================
Included changes:
- use ether_addr_copy instead of memcpy when possible
- implement new multicast packet optimisation
- improve several kerneldoc sections
- minor code cleanups

here you have our patchset for net-next/linux-3.15.  They are 16
patches but most of them are just small cleanups and kerneldoc
improvements.

The only big change is the one from patch 8 to 13 by Linus Lüssing
that introduces a new multicast packets optimisation. This new
component aims to reduce the air overhead by sending multicast packets
as bat-unicast when only one destination exists or by dropping them
directly at the source if the multicast group is totally empty.

In patch 11 Linus introduces an atomic_t variable, that like others
that we already have is only object of write and read, thus making the
atomic characteristic totally useless.  Unfortunately this is part of
our sysfs framework, that helps the developer to introduce new knobs
by using few macros only. For this reason we decided to keep Linus'
new knob for now, but I'd like to let you know that we are in the
process of re-working such framework in order to convert all the
current (useless) atomic_t to boolean in one go.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 65025079 3f2532fc
...@@ -76,6 +76,15 @@ Description: ...@@ -76,6 +76,15 @@ Description:
is used to classify clients as "isolated" by the is used to classify clients as "isolated" by the
Extended Isolation feature. Extended Isolation feature.
What: /sys/class/net/<mesh_iface>/mesh/multicast_mode
Date: Feb 2014
Contact: Linus Lüssing <linus.luessing@web.de>
Description:
Indicates whether multicast optimizations are enabled
or disabled. If set to zero then all nodes in the
mesh are going to use classic flooding for any
multicast packet with no optimizations.
What: /sys/class/net/<mesh_iface>/mesh/network_coding What: /sys/class/net/<mesh_iface>/mesh/network_coding
Date: Nov 2012 Date: Nov 2012
Contact: Martin Hundeboll <martin@hundeboll.net> Contact: Martin Hundeboll <martin@hundeboll.net>
......
...@@ -50,6 +50,15 @@ config BATMAN_ADV_NC ...@@ -50,6 +50,15 @@ config BATMAN_ADV_NC
If you think that your network does not need this feature you If you think that your network does not need this feature you
can safely disable it and save some space. can safely disable it and save some space.
config BATMAN_ADV_MCAST
bool "Multicast optimisation"
depends on BATMAN_ADV
default n
help
This option enables the multicast optimisation which aims to
reduce the air overhead while improving the reliability of
multicast messages.
config BATMAN_ADV_DEBUG config BATMAN_ADV_DEBUG
bool "B.A.T.M.A.N. debugging" bool "B.A.T.M.A.N. debugging"
depends on BATMAN_ADV depends on BATMAN_ADV
......
...@@ -36,3 +36,4 @@ batman-adv-y += send.o ...@@ -36,3 +36,4 @@ batman-adv-y += send.o
batman-adv-y += soft-interface.o batman-adv-y += soft-interface.o
batman-adv-y += sysfs.o batman-adv-y += sysfs.o
batman-adv-y += translation-table.o batman-adv-y += translation-table.o
batman-adv-$(CONFIG_BATMAN_ADV_MCAST) += multicast.o
...@@ -347,10 +347,10 @@ static void batadv_iv_ogm_iface_update_mac(struct batadv_hard_iface *hard_iface) ...@@ -347,10 +347,10 @@ static void batadv_iv_ogm_iface_update_mac(struct batadv_hard_iface *hard_iface)
unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff; unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff;
batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff; batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
memcpy(batadv_ogm_packet->orig, ether_addr_copy(batadv_ogm_packet->orig,
hard_iface->net_dev->dev_addr, ETH_ALEN); hard_iface->net_dev->dev_addr);
memcpy(batadv_ogm_packet->prev_sender, ether_addr_copy(batadv_ogm_packet->prev_sender,
hard_iface->net_dev->dev_addr, ETH_ALEN); hard_iface->net_dev->dev_addr);
} }
static void static void
...@@ -830,7 +830,7 @@ static void batadv_iv_ogm_forward(struct batadv_orig_node *orig_node, ...@@ -830,7 +830,7 @@ static void batadv_iv_ogm_forward(struct batadv_orig_node *orig_node,
tvlv_len = ntohs(batadv_ogm_packet->tvlv_len); tvlv_len = ntohs(batadv_ogm_packet->tvlv_len);
batadv_ogm_packet->ttl--; batadv_ogm_packet->ttl--;
memcpy(batadv_ogm_packet->prev_sender, ethhdr->h_source, ETH_ALEN); ether_addr_copy(batadv_ogm_packet->prev_sender, ethhdr->h_source);
/* apply hop penalty */ /* apply hop penalty */
batadv_ogm_packet->tq = batadv_hop_penalty(batadv_ogm_packet->tq, batadv_ogm_packet->tq = batadv_hop_penalty(batadv_ogm_packet->tq,
......
...@@ -191,7 +191,7 @@ batadv_backbone_hash_find(struct batadv_priv *bat_priv, ...@@ -191,7 +191,7 @@ batadv_backbone_hash_find(struct batadv_priv *bat_priv,
if (!hash) if (!hash)
return NULL; return NULL;
memcpy(search_entry.orig, addr, ETH_ALEN); ether_addr_copy(search_entry.orig, addr);
search_entry.vid = vid; search_entry.vid = vid;
index = batadv_choose_backbone_gw(&search_entry, hash->size); index = batadv_choose_backbone_gw(&search_entry, hash->size);
...@@ -305,7 +305,7 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac, ...@@ -305,7 +305,7 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac,
/* normal claim frame /* normal claim frame
* set Ethernet SRC to the clients mac * set Ethernet SRC to the clients mac
*/ */
memcpy(ethhdr->h_source, mac, ETH_ALEN); ether_addr_copy(ethhdr->h_source, mac);
batadv_dbg(BATADV_DBG_BLA, bat_priv, batadv_dbg(BATADV_DBG_BLA, bat_priv,
"bla_send_claim(): CLAIM %pM on vid %d\n", mac, "bla_send_claim(): CLAIM %pM on vid %d\n", mac,
BATADV_PRINT_VID(vid)); BATADV_PRINT_VID(vid));
...@@ -314,7 +314,7 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac, ...@@ -314,7 +314,7 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac,
/* unclaim frame /* unclaim frame
* set HW SRC to the clients mac * set HW SRC to the clients mac
*/ */
memcpy(hw_src, mac, ETH_ALEN); ether_addr_copy(hw_src, mac);
batadv_dbg(BATADV_DBG_BLA, bat_priv, batadv_dbg(BATADV_DBG_BLA, bat_priv,
"bla_send_claim(): UNCLAIM %pM on vid %d\n", mac, "bla_send_claim(): UNCLAIM %pM on vid %d\n", mac,
BATADV_PRINT_VID(vid)); BATADV_PRINT_VID(vid));
...@@ -323,7 +323,7 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac, ...@@ -323,7 +323,7 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac,
/* announcement frame /* announcement frame
* set HW SRC to the special mac containg the crc * set HW SRC to the special mac containg the crc
*/ */
memcpy(hw_src, mac, ETH_ALEN); ether_addr_copy(hw_src, mac);
batadv_dbg(BATADV_DBG_BLA, bat_priv, batadv_dbg(BATADV_DBG_BLA, bat_priv,
"bla_send_claim(): ANNOUNCE of %pM on vid %d\n", "bla_send_claim(): ANNOUNCE of %pM on vid %d\n",
ethhdr->h_source, BATADV_PRINT_VID(vid)); ethhdr->h_source, BATADV_PRINT_VID(vid));
...@@ -333,8 +333,8 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac, ...@@ -333,8 +333,8 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac,
* set HW SRC and header destination to the receiving backbone * set HW SRC and header destination to the receiving backbone
* gws mac * gws mac
*/ */
memcpy(hw_src, mac, ETH_ALEN); ether_addr_copy(hw_src, mac);
memcpy(ethhdr->h_dest, mac, ETH_ALEN); ether_addr_copy(ethhdr->h_dest, mac);
batadv_dbg(BATADV_DBG_BLA, bat_priv, batadv_dbg(BATADV_DBG_BLA, bat_priv,
"bla_send_claim(): REQUEST of %pM to %pM on vid %d\n", "bla_send_claim(): REQUEST of %pM to %pM on vid %d\n",
ethhdr->h_source, ethhdr->h_dest, ethhdr->h_source, ethhdr->h_dest,
...@@ -395,7 +395,7 @@ batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, uint8_t *orig, ...@@ -395,7 +395,7 @@ batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, uint8_t *orig,
entry->bat_priv = bat_priv; entry->bat_priv = bat_priv;
atomic_set(&entry->request_sent, 0); atomic_set(&entry->request_sent, 0);
atomic_set(&entry->wait_periods, 0); atomic_set(&entry->wait_periods, 0);
memcpy(entry->orig, orig, ETH_ALEN); ether_addr_copy(entry->orig, orig);
/* one for the hash, one for returning */ /* one for the hash, one for returning */
atomic_set(&entry->refcount, 2); atomic_set(&entry->refcount, 2);
...@@ -563,7 +563,7 @@ static void batadv_bla_add_claim(struct batadv_priv *bat_priv, ...@@ -563,7 +563,7 @@ static void batadv_bla_add_claim(struct batadv_priv *bat_priv,
struct batadv_bla_claim search_claim; struct batadv_bla_claim search_claim;
int hash_added; int hash_added;
memcpy(search_claim.addr, mac, ETH_ALEN); ether_addr_copy(search_claim.addr, mac);
search_claim.vid = vid; search_claim.vid = vid;
claim = batadv_claim_hash_find(bat_priv, &search_claim); claim = batadv_claim_hash_find(bat_priv, &search_claim);
...@@ -573,7 +573,7 @@ static void batadv_bla_add_claim(struct batadv_priv *bat_priv, ...@@ -573,7 +573,7 @@ static void batadv_bla_add_claim(struct batadv_priv *bat_priv,
if (!claim) if (!claim)
return; return;
memcpy(claim->addr, mac, ETH_ALEN); ether_addr_copy(claim->addr, mac);
claim->vid = vid; claim->vid = vid;
claim->lasttime = jiffies; claim->lasttime = jiffies;
claim->backbone_gw = backbone_gw; claim->backbone_gw = backbone_gw;
...@@ -624,7 +624,7 @@ static void batadv_bla_del_claim(struct batadv_priv *bat_priv, ...@@ -624,7 +624,7 @@ static void batadv_bla_del_claim(struct batadv_priv *bat_priv,
{ {
struct batadv_bla_claim search_claim, *claim; struct batadv_bla_claim search_claim, *claim;
memcpy(search_claim.addr, mac, ETH_ALEN); ether_addr_copy(search_claim.addr, mac);
search_claim.vid = vid; search_claim.vid = vid;
claim = batadv_claim_hash_find(bat_priv, &search_claim); claim = batadv_claim_hash_find(bat_priv, &search_claim);
if (!claim) if (!claim)
...@@ -882,7 +882,7 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv, ...@@ -882,7 +882,7 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv,
proto = ethhdr->h_proto; proto = ethhdr->h_proto;
headlen = ETH_HLEN; headlen = ETH_HLEN;
if (vid & BATADV_VLAN_HAS_TAG) { if (vid & BATADV_VLAN_HAS_TAG) {
vhdr = (struct vlan_ethhdr *)ethhdr; vhdr = vlan_eth_hdr(skb);
proto = vhdr->h_vlan_encapsulated_proto; proto = vhdr->h_vlan_encapsulated_proto;
headlen += VLAN_HLEN; headlen += VLAN_HLEN;
} }
...@@ -1103,8 +1103,8 @@ void batadv_bla_update_orig_address(struct batadv_priv *bat_priv, ...@@ -1103,8 +1103,8 @@ void batadv_bla_update_orig_address(struct batadv_priv *bat_priv,
oldif->net_dev->dev_addr)) oldif->net_dev->dev_addr))
continue; continue;
memcpy(backbone_gw->orig, ether_addr_copy(backbone_gw->orig,
primary_if->net_dev->dev_addr, ETH_ALEN); primary_if->net_dev->dev_addr);
/* send an announce frame so others will ask for our /* send an announce frame so others will ask for our
* claims and update their tables. * claims and update their tables.
*/ */
...@@ -1310,7 +1310,7 @@ int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, ...@@ -1310,7 +1310,7 @@ int 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;
memcpy(entry->orig, bcast_packet->orig, ETH_ALEN); ether_addr_copy(entry->orig, bcast_packet->orig);
bat_priv->bla.bcast_duplist_curr = curr; bat_priv->bla.bcast_duplist_curr = curr;
out: out:
...@@ -1458,7 +1458,7 @@ int batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb, ...@@ -1458,7 +1458,7 @@ int batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast) if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast)
goto handled; goto handled;
memcpy(search_claim.addr, ethhdr->h_source, ETH_ALEN); ether_addr_copy(search_claim.addr, ethhdr->h_source);
search_claim.vid = vid; search_claim.vid = vid;
claim = batadv_claim_hash_find(bat_priv, &search_claim); claim = batadv_claim_hash_find(bat_priv, &search_claim);
...@@ -1547,9 +1547,6 @@ int batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb, ...@@ -1547,9 +1547,6 @@ int batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb,
if (!atomic_read(&bat_priv->bridge_loop_avoidance)) if (!atomic_read(&bat_priv->bridge_loop_avoidance))
goto allow; goto allow;
/* in VLAN case, the mac header might not be set. */
skb_reset_mac_header(skb);
if (batadv_bla_process_claim(bat_priv, primary_if, skb)) if (batadv_bla_process_claim(bat_priv, primary_if, skb))
goto handled; goto handled;
...@@ -1560,7 +1557,7 @@ int batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb, ...@@ -1560,7 +1557,7 @@ int batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb,
if (is_multicast_ether_addr(ethhdr->h_dest)) if (is_multicast_ether_addr(ethhdr->h_dest))
goto handled; goto handled;
memcpy(search_claim.addr, ethhdr->h_source, ETH_ALEN); ether_addr_copy(search_claim.addr, ethhdr->h_source);
search_claim.vid = vid; search_claim.vid = vid;
claim = batadv_claim_hash_find(bat_priv, &search_claim); claim = batadv_claim_hash_find(bat_priv, &search_claim);
......
...@@ -277,7 +277,7 @@ static void batadv_dat_entry_add(struct batadv_priv *bat_priv, __be32 ip, ...@@ -277,7 +277,7 @@ static void batadv_dat_entry_add(struct batadv_priv *bat_priv, __be32 ip,
/* if this entry is already known, just update it */ /* if this entry is already known, just update it */
if (dat_entry) { if (dat_entry) {
if (!batadv_compare_eth(dat_entry->mac_addr, mac_addr)) if (!batadv_compare_eth(dat_entry->mac_addr, mac_addr))
memcpy(dat_entry->mac_addr, mac_addr, ETH_ALEN); ether_addr_copy(dat_entry->mac_addr, mac_addr);
dat_entry->last_update = jiffies; dat_entry->last_update = jiffies;
batadv_dbg(BATADV_DBG_DAT, bat_priv, batadv_dbg(BATADV_DBG_DAT, bat_priv,
"Entry updated: %pI4 %pM (vid: %d)\n", "Entry updated: %pI4 %pM (vid: %d)\n",
...@@ -292,7 +292,7 @@ static void batadv_dat_entry_add(struct batadv_priv *bat_priv, __be32 ip, ...@@ -292,7 +292,7 @@ static void batadv_dat_entry_add(struct batadv_priv *bat_priv, __be32 ip,
dat_entry->ip = ip; dat_entry->ip = ip;
dat_entry->vid = vid; dat_entry->vid = vid;
memcpy(dat_entry->mac_addr, mac_addr, ETH_ALEN); ether_addr_copy(dat_entry->mac_addr, mac_addr);
dat_entry->last_update = jiffies; dat_entry->last_update = jiffies;
atomic_set(&dat_entry->refcount, 2); atomic_set(&dat_entry->refcount, 2);
...@@ -1027,6 +1027,11 @@ bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv, ...@@ -1027,6 +1027,11 @@ bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
if (!skb_new) if (!skb_new)
goto out; goto out;
/* the rest of the TX path assumes that the mac_header offset pointing
* to the inner Ethernet header has been set, therefore reset it now.
*/
skb_reset_mac_header(skb_new);
if (vid & BATADV_VLAN_HAS_TAG) if (vid & BATADV_VLAN_HAS_TAG)
skb_new = vlan_insert_tag(skb_new, htons(ETH_P_8021Q), skb_new = vlan_insert_tag(skb_new, htons(ETH_P_8021Q),
vid & VLAN_VID_MASK); vid & VLAN_VID_MASK);
......
...@@ -25,6 +25,9 @@ ...@@ -25,6 +25,9 @@
#include <linux/if_arp.h> #include <linux/if_arp.h>
/**
* BATADV_DAT_ADDR_MAX - maximum address value in the DHT space
*/
#define BATADV_DAT_ADDR_MAX ((batadv_dat_addr_t)~(batadv_dat_addr_t)0) #define BATADV_DAT_ADDR_MAX ((batadv_dat_addr_t)~(batadv_dat_addr_t)0)
void batadv_dat_status_update(struct net_device *net_dev); void batadv_dat_status_update(struct net_device *net_dev);
......
...@@ -449,8 +449,8 @@ bool batadv_frag_send_packet(struct sk_buff *skb, ...@@ -449,8 +449,8 @@ bool batadv_frag_send_packet(struct sk_buff *skb,
frag_header.reserved = 0; frag_header.reserved = 0;
frag_header.no = 0; frag_header.no = 0;
frag_header.total_size = htons(skb->len); frag_header.total_size = htons(skb->len);
memcpy(frag_header.orig, primary_if->net_dev->dev_addr, ETH_ALEN); ether_addr_copy(frag_header.orig, primary_if->net_dev->dev_addr);
memcpy(frag_header.dest, orig_node->orig, ETH_ALEN); ether_addr_copy(frag_header.dest, orig_node->orig);
/* Eat and send fragments from the tail of skb */ /* Eat and send fragments from the tail of skb */
while (skb->len > max_fragment_size) { while (skb->len > max_fragment_size) {
......
...@@ -678,7 +678,7 @@ batadv_gw_dhcp_recipient_get(struct sk_buff *skb, unsigned int *header_len, ...@@ -678,7 +678,7 @@ batadv_gw_dhcp_recipient_get(struct sk_buff *skb, unsigned int *header_len,
if (!pskb_may_pull(skb, *header_len + ETH_HLEN)) if (!pskb_may_pull(skb, *header_len + ETH_HLEN))
return BATADV_DHCP_NO; return BATADV_DHCP_NO;
ethhdr = (struct ethhdr *)skb->data; ethhdr = eth_hdr(skb);
proto = ethhdr->h_proto; proto = ethhdr->h_proto;
*header_len += ETH_HLEN; *header_len += ETH_HLEN;
...@@ -687,7 +687,7 @@ batadv_gw_dhcp_recipient_get(struct sk_buff *skb, unsigned int *header_len, ...@@ -687,7 +687,7 @@ batadv_gw_dhcp_recipient_get(struct sk_buff *skb, unsigned int *header_len,
if (!pskb_may_pull(skb, *header_len + VLAN_HLEN)) if (!pskb_may_pull(skb, *header_len + VLAN_HLEN))
return BATADV_DHCP_NO; return BATADV_DHCP_NO;
vhdr = (struct vlan_ethhdr *)skb->data; vhdr = vlan_eth_hdr(skb);
proto = vhdr->h_vlan_encapsulated_proto; proto = vhdr->h_vlan_encapsulated_proto;
*header_len += VLAN_HLEN; *header_len += VLAN_HLEN;
} }
...@@ -726,7 +726,7 @@ batadv_gw_dhcp_recipient_get(struct sk_buff *skb, unsigned int *header_len, ...@@ -726,7 +726,7 @@ batadv_gw_dhcp_recipient_get(struct sk_buff *skb, unsigned int *header_len,
return BATADV_DHCP_NO; return BATADV_DHCP_NO;
/* skb->data might have been reallocated by pskb_may_pull() */ /* skb->data might have been reallocated by pskb_may_pull() */
ethhdr = (struct ethhdr *)skb->data; ethhdr = eth_hdr(skb);
if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) if (ntohs(ethhdr->h_proto) == ETH_P_8021Q)
ethhdr = (struct ethhdr *)(skb->data + VLAN_HLEN); ethhdr = (struct ethhdr *)(skb->data + VLAN_HLEN);
...@@ -763,7 +763,7 @@ batadv_gw_dhcp_recipient_get(struct sk_buff *skb, unsigned int *header_len, ...@@ -763,7 +763,7 @@ batadv_gw_dhcp_recipient_get(struct sk_buff *skb, unsigned int *header_len,
if (*p != ETH_ALEN) if (*p != ETH_ALEN)
return BATADV_DHCP_NO; return BATADV_DHCP_NO;
memcpy(chaddr, skb->data + chaddr_offset, ETH_ALEN); ether_addr_copy(chaddr, skb->data + chaddr_offset);
} }
return ret; return ret;
......
...@@ -158,6 +158,7 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff, ...@@ -158,6 +158,7 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
struct batadv_orig_node *orig_node = NULL; struct batadv_orig_node *orig_node = NULL;
struct batadv_neigh_node *neigh_node = NULL; struct batadv_neigh_node *neigh_node = NULL;
size_t packet_len = sizeof(struct batadv_icmp_packet); size_t packet_len = sizeof(struct batadv_icmp_packet);
uint8_t *addr;
if (len < sizeof(struct batadv_icmp_header)) { if (len < sizeof(struct batadv_icmp_header)) {
batadv_dbg(BATADV_DBG_BATMAN, bat_priv, batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
...@@ -227,10 +228,10 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff, ...@@ -227,10 +228,10 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
goto dst_unreach; goto dst_unreach;
icmp_packet_rr = (struct batadv_icmp_packet_rr *)icmp_header; icmp_packet_rr = (struct batadv_icmp_packet_rr *)icmp_header;
if (packet_len == sizeof(*icmp_packet_rr)) if (packet_len == sizeof(*icmp_packet_rr)) {
memcpy(icmp_packet_rr->rr, addr = neigh_node->if_incoming->net_dev->dev_addr;
neigh_node->if_incoming->net_dev->dev_addr, ether_addr_copy(icmp_packet_rr->rr[0], addr);
ETH_ALEN); }
break; break;
default: default:
...@@ -250,7 +251,7 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff, ...@@ -250,7 +251,7 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
goto free_skb; goto free_skb;
} }
memcpy(icmp_header->orig, primary_if->net_dev->dev_addr, ETH_ALEN); ether_addr_copy(icmp_header->orig, primary_if->net_dev->dev_addr);
batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
goto out; goto out;
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "gateway_client.h" #include "gateway_client.h"
#include "bridge_loop_avoidance.h" #include "bridge_loop_avoidance.h"
#include "distributed-arp-table.h" #include "distributed-arp-table.h"
#include "multicast.h"
#include "gateway_common.h" #include "gateway_common.h"
#include "hash.h" #include "hash.h"
#include "bat_algo.h" #include "bat_algo.h"
...@@ -110,6 +111,9 @@ int batadv_mesh_init(struct net_device *soft_iface) ...@@ -110,6 +111,9 @@ int batadv_mesh_init(struct net_device *soft_iface)
spin_lock_init(&bat_priv->tt.last_changeset_lock); spin_lock_init(&bat_priv->tt.last_changeset_lock);
spin_lock_init(&bat_priv->tt.commit_lock); spin_lock_init(&bat_priv->tt.commit_lock);
spin_lock_init(&bat_priv->gw.list_lock); spin_lock_init(&bat_priv->gw.list_lock);
#ifdef CONFIG_BATMAN_ADV_MCAST
spin_lock_init(&bat_priv->mcast.want_lists_lock);
#endif
spin_lock_init(&bat_priv->tvlv.container_list_lock); spin_lock_init(&bat_priv->tvlv.container_list_lock);
spin_lock_init(&bat_priv->tvlv.handler_list_lock); spin_lock_init(&bat_priv->tvlv.handler_list_lock);
spin_lock_init(&bat_priv->softif_vlan_list_lock); spin_lock_init(&bat_priv->softif_vlan_list_lock);
...@@ -117,9 +121,17 @@ int batadv_mesh_init(struct net_device *soft_iface) ...@@ -117,9 +121,17 @@ int batadv_mesh_init(struct net_device *soft_iface)
INIT_HLIST_HEAD(&bat_priv->forw_bat_list); INIT_HLIST_HEAD(&bat_priv->forw_bat_list);
INIT_HLIST_HEAD(&bat_priv->forw_bcast_list); INIT_HLIST_HEAD(&bat_priv->forw_bcast_list);
INIT_HLIST_HEAD(&bat_priv->gw.list); INIT_HLIST_HEAD(&bat_priv->gw.list);
#ifdef CONFIG_BATMAN_ADV_MCAST
INIT_HLIST_HEAD(&bat_priv->mcast.want_all_unsnoopables_list);
INIT_HLIST_HEAD(&bat_priv->mcast.want_all_ipv4_list);
INIT_HLIST_HEAD(&bat_priv->mcast.want_all_ipv6_list);
#endif
INIT_LIST_HEAD(&bat_priv->tt.changes_list); INIT_LIST_HEAD(&bat_priv->tt.changes_list);
INIT_LIST_HEAD(&bat_priv->tt.req_list); INIT_LIST_HEAD(&bat_priv->tt.req_list);
INIT_LIST_HEAD(&bat_priv->tt.roam_list); INIT_LIST_HEAD(&bat_priv->tt.roam_list);
#ifdef CONFIG_BATMAN_ADV_MCAST
INIT_HLIST_HEAD(&bat_priv->mcast.mla_list);
#endif
INIT_HLIST_HEAD(&bat_priv->tvlv.container_list); INIT_HLIST_HEAD(&bat_priv->tvlv.container_list);
INIT_HLIST_HEAD(&bat_priv->tvlv.handler_list); INIT_HLIST_HEAD(&bat_priv->tvlv.handler_list);
INIT_HLIST_HEAD(&bat_priv->softif_vlan_list); INIT_HLIST_HEAD(&bat_priv->softif_vlan_list);
...@@ -145,6 +157,7 @@ int batadv_mesh_init(struct net_device *soft_iface) ...@@ -145,6 +157,7 @@ int batadv_mesh_init(struct net_device *soft_iface)
goto err; goto err;
batadv_gw_init(bat_priv); batadv_gw_init(bat_priv);
batadv_mcast_init(bat_priv);
atomic_set(&bat_priv->gw.reselect, 0); atomic_set(&bat_priv->gw.reselect, 0);
atomic_set(&bat_priv->mesh_state, BATADV_MESH_ACTIVE); atomic_set(&bat_priv->mesh_state, BATADV_MESH_ACTIVE);
...@@ -169,6 +182,8 @@ void batadv_mesh_free(struct net_device *soft_iface) ...@@ -169,6 +182,8 @@ void batadv_mesh_free(struct net_device *soft_iface)
batadv_dat_free(bat_priv); batadv_dat_free(bat_priv);
batadv_bla_free(bat_priv); batadv_bla_free(bat_priv);
batadv_mcast_free(bat_priv);
/* Free the TT and the originator tables only after having terminated /* Free the TT and the originator tables only after having terminated
* all the other depending components which may use these structures for * all the other depending components which may use these structures for
* their purposes. * their purposes.
...@@ -1133,8 +1148,8 @@ void batadv_tvlv_unicast_send(struct batadv_priv *bat_priv, uint8_t *src, ...@@ -1133,8 +1148,8 @@ void batadv_tvlv_unicast_send(struct batadv_priv *bat_priv, uint8_t *src,
unicast_tvlv_packet->reserved = 0; unicast_tvlv_packet->reserved = 0;
unicast_tvlv_packet->tvlv_len = htons(tvlv_len); unicast_tvlv_packet->tvlv_len = htons(tvlv_len);
unicast_tvlv_packet->align = 0; unicast_tvlv_packet->align = 0;
memcpy(unicast_tvlv_packet->src, src, ETH_ALEN); ether_addr_copy(unicast_tvlv_packet->src, src);
memcpy(unicast_tvlv_packet->dst, dst, ETH_ALEN); ether_addr_copy(unicast_tvlv_packet->dst, dst);
tvlv_buff = (unsigned char *)(unicast_tvlv_packet + 1); tvlv_buff = (unsigned char *)(unicast_tvlv_packet + 1);
tvlv_hdr = (struct batadv_tvlv_hdr *)tvlv_buff; tvlv_hdr = (struct batadv_tvlv_hdr *)tvlv_buff;
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#define BATADV_DRIVER_DEVICE "batman-adv" #define BATADV_DRIVER_DEVICE "batman-adv"
#ifndef BATADV_SOURCE_VERSION #ifndef BATADV_SOURCE_VERSION
#define BATADV_SOURCE_VERSION "2014.1.0" #define BATADV_SOURCE_VERSION "2014.2.0"
#endif #endif
/* B.A.T.M.A.N. parameters */ /* B.A.T.M.A.N. parameters */
...@@ -176,6 +176,8 @@ enum batadv_uev_type { ...@@ -176,6 +176,8 @@ enum batadv_uev_type {
#include <linux/percpu.h> #include <linux/percpu.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <net/sock.h> /* struct sock */ #include <net/sock.h> /* struct sock */
#include <net/addrconf.h> /* ipv6 address stuff */
#include <linux/ip.h>
#include <net/rtnetlink.h> #include <net/rtnetlink.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
......
This diff is collapsed.
/* Copyright (C) 2014 B.A.T.M.A.N. contributors:
*
* Linus Lüssing
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _NET_BATMAN_ADV_MULTICAST_H_
#define _NET_BATMAN_ADV_MULTICAST_H_
/**
* batadv_forw_mode - the way a packet should be forwarded as
* @BATADV_FORW_ALL: forward the packet to all nodes (currently via classic
* flooding)
* @BATADV_FORW_SINGLE: forward the packet to a single node (currently via the
* BATMAN unicast routing protocol)
* @BATADV_FORW_NONE: don't forward, drop it
*/
enum batadv_forw_mode {
BATADV_FORW_ALL,
BATADV_FORW_SINGLE,
BATADV_FORW_NONE,
};
#ifdef CONFIG_BATMAN_ADV_MCAST
void batadv_mcast_mla_update(struct batadv_priv *bat_priv);
enum batadv_forw_mode
batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
struct batadv_orig_node **mcast_single_orig);
void batadv_mcast_init(struct batadv_priv *bat_priv);
void batadv_mcast_free(struct batadv_priv *bat_priv);
void batadv_mcast_purge_orig(struct batadv_orig_node *orig_node);
#else
static inline void batadv_mcast_mla_update(struct batadv_priv *bat_priv)
{
return;
}
static inline enum batadv_forw_mode
batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
struct batadv_orig_node **mcast_single_orig)
{
return BATADV_FORW_ALL;
}
static inline int batadv_mcast_init(struct batadv_priv *bat_priv)
{
return 0;
}
static inline void batadv_mcast_free(struct batadv_priv *bat_priv)
{
return;
}
static inline void batadv_mcast_purge_orig(struct batadv_orig_node *orig_node)
{
return;
}
#endif /* CONFIG_BATMAN_ADV_MCAST */
#endif /* _NET_BATMAN_ADV_MULTICAST_H_ */
...@@ -819,7 +819,7 @@ static struct batadv_nc_node ...@@ -819,7 +819,7 @@ static struct batadv_nc_node
/* Initialize nc_node */ /* Initialize nc_node */
INIT_LIST_HEAD(&nc_node->list); INIT_LIST_HEAD(&nc_node->list);
memcpy(nc_node->addr, orig_node->orig, ETH_ALEN); ether_addr_copy(nc_node->addr, orig_node->orig);
nc_node->orig_node = orig_neigh_node; nc_node->orig_node = orig_neigh_node;
atomic_set(&nc_node->refcount, 2); atomic_set(&nc_node->refcount, 2);
...@@ -941,8 +941,8 @@ static struct batadv_nc_path *batadv_nc_get_path(struct batadv_priv *bat_priv, ...@@ -941,8 +941,8 @@ static struct batadv_nc_path *batadv_nc_get_path(struct batadv_priv *bat_priv,
spin_lock_init(&nc_path->packet_list_lock); spin_lock_init(&nc_path->packet_list_lock);
atomic_set(&nc_path->refcount, 2); atomic_set(&nc_path->refcount, 2);
nc_path->last_valid = jiffies; nc_path->last_valid = jiffies;
memcpy(nc_path->next_hop, dst, ETH_ALEN); ether_addr_copy(nc_path->next_hop, dst);
memcpy(nc_path->prev_hop, src, ETH_ALEN); ether_addr_copy(nc_path->prev_hop, src);
batadv_dbg(BATADV_DBG_NC, bat_priv, "Adding nc_path %pM -> %pM\n", batadv_dbg(BATADV_DBG_NC, bat_priv, "Adding nc_path %pM -> %pM\n",
nc_path->prev_hop, nc_path->prev_hop,
...@@ -1114,15 +1114,15 @@ static bool batadv_nc_code_packets(struct batadv_priv *bat_priv, ...@@ -1114,15 +1114,15 @@ static bool batadv_nc_code_packets(struct batadv_priv *bat_priv,
coded_packet->ttl = packet1->ttl; coded_packet->ttl = packet1->ttl;
/* Info about first unicast packet */ /* Info about first unicast packet */
memcpy(coded_packet->first_source, first_source, ETH_ALEN); ether_addr_copy(coded_packet->first_source, first_source);
memcpy(coded_packet->first_orig_dest, packet1->dest, ETH_ALEN); ether_addr_copy(coded_packet->first_orig_dest, packet1->dest);
coded_packet->first_crc = packet_id1; coded_packet->first_crc = packet_id1;
coded_packet->first_ttvn = packet1->ttvn; coded_packet->first_ttvn = packet1->ttvn;
/* Info about second unicast packet */ /* Info about second unicast packet */
memcpy(coded_packet->second_dest, second_dest, ETH_ALEN); ether_addr_copy(coded_packet->second_dest, second_dest);
memcpy(coded_packet->second_source, second_source, ETH_ALEN); ether_addr_copy(coded_packet->second_source, second_source);
memcpy(coded_packet->second_orig_dest, packet2->dest, ETH_ALEN); ether_addr_copy(coded_packet->second_orig_dest, packet2->dest);
coded_packet->second_crc = packet_id2; coded_packet->second_crc = packet_id2;
coded_packet->second_ttl = packet2->ttl; coded_packet->second_ttl = packet2->ttl;
coded_packet->second_ttvn = packet2->ttvn; coded_packet->second_ttvn = packet2->ttvn;
...@@ -1349,8 +1349,8 @@ static void batadv_nc_skb_store_before_coding(struct batadv_priv *bat_priv, ...@@ -1349,8 +1349,8 @@ static void batadv_nc_skb_store_before_coding(struct batadv_priv *bat_priv,
/* Set the mac header as if we actually sent the packet uncoded */ /* Set the mac header as if we actually sent the packet uncoded */
ethhdr = eth_hdr(skb); ethhdr = eth_hdr(skb);
memcpy(ethhdr->h_source, ethhdr->h_dest, ETH_ALEN); ether_addr_copy(ethhdr->h_source, ethhdr->h_dest);
memcpy(ethhdr->h_dest, eth_dst_new, ETH_ALEN); ether_addr_copy(ethhdr->h_dest, eth_dst_new);
/* Set data pointer to MAC header to mimic packets from our tx path */ /* Set data pointer to MAC header to mimic packets from our tx path */
skb_push(skb, ETH_HLEN); skb_push(skb, ETH_HLEN);
...@@ -1636,7 +1636,7 @@ batadv_nc_skb_decode_packet(struct batadv_priv *bat_priv, struct sk_buff *skb, ...@@ -1636,7 +1636,7 @@ batadv_nc_skb_decode_packet(struct batadv_priv *bat_priv, struct sk_buff *skb,
/* Reconstruct original mac header */ /* Reconstruct original mac header */
ethhdr = eth_hdr(skb); ethhdr = eth_hdr(skb);
memcpy(ethhdr, &ethhdr_tmp, sizeof(*ethhdr)); *ethhdr = ethhdr_tmp;
/* Select the correct unicast header information based on the location /* Select the correct unicast header information based on the location
* of our mac address in the coded_packet header * of our mac address in the coded_packet header
...@@ -1646,7 +1646,7 @@ batadv_nc_skb_decode_packet(struct batadv_priv *bat_priv, struct sk_buff *skb, ...@@ -1646,7 +1646,7 @@ batadv_nc_skb_decode_packet(struct batadv_priv *bat_priv, struct sk_buff *skb,
* so the Ethernet address must be copied to h_dest and * so the Ethernet address must be copied to h_dest and
* pkt_type changed from PACKET_OTHERHOST to PACKET_HOST * pkt_type changed from PACKET_OTHERHOST to PACKET_HOST
*/ */
memcpy(ethhdr->h_dest, coded_packet_tmp.second_dest, ETH_ALEN); ether_addr_copy(ethhdr->h_dest, coded_packet_tmp.second_dest);
skb->pkt_type = PACKET_HOST; skb->pkt_type = PACKET_HOST;
orig_dest = coded_packet_tmp.second_orig_dest; orig_dest = coded_packet_tmp.second_orig_dest;
...@@ -1682,7 +1682,7 @@ batadv_nc_skb_decode_packet(struct batadv_priv *bat_priv, struct sk_buff *skb, ...@@ -1682,7 +1682,7 @@ batadv_nc_skb_decode_packet(struct batadv_priv *bat_priv, struct sk_buff *skb,
unicast_packet->packet_type = BATADV_UNICAST; unicast_packet->packet_type = BATADV_UNICAST;
unicast_packet->version = BATADV_COMPAT_VERSION; unicast_packet->version = BATADV_COMPAT_VERSION;
unicast_packet->ttl = ttl; unicast_packet->ttl = ttl;
memcpy(unicast_packet->dest, orig_dest, ETH_ALEN); ether_addr_copy(unicast_packet->dest, orig_dest);
unicast_packet->ttvn = ttvn; unicast_packet->ttvn = ttvn;
batadv_nc_packet_free(nc_packet); batadv_nc_packet_free(nc_packet);
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "bridge_loop_avoidance.h" #include "bridge_loop_avoidance.h"
#include "network-coding.h" #include "network-coding.h"
#include "fragmentation.h" #include "fragmentation.h"
#include "multicast.h"
/* hash class keys */ /* hash class keys */
static struct lock_class_key batadv_orig_hash_lock_class_key; static struct lock_class_key batadv_orig_hash_lock_class_key;
...@@ -446,7 +447,7 @@ batadv_neigh_node_new(struct batadv_hard_iface *hard_iface, ...@@ -446,7 +447,7 @@ batadv_neigh_node_new(struct batadv_hard_iface *hard_iface,
INIT_HLIST_HEAD(&neigh_node->ifinfo_list); INIT_HLIST_HEAD(&neigh_node->ifinfo_list);
spin_lock_init(&neigh_node->ifinfo_lock); spin_lock_init(&neigh_node->ifinfo_lock);
memcpy(neigh_node->addr, neigh_addr, ETH_ALEN); ether_addr_copy(neigh_node->addr, neigh_addr);
neigh_node->if_incoming = hard_iface; neigh_node->if_incoming = hard_iface;
neigh_node->orig_node = orig_node; neigh_node->orig_node = orig_node;
...@@ -557,6 +558,8 @@ static void batadv_orig_node_free_rcu(struct rcu_head *rcu) ...@@ -557,6 +558,8 @@ static void batadv_orig_node_free_rcu(struct rcu_head *rcu)
} }
spin_unlock_bh(&orig_node->neigh_list_lock); spin_unlock_bh(&orig_node->neigh_list_lock);
batadv_mcast_purge_orig(orig_node);
/* Free nc_nodes */ /* Free nc_nodes */
batadv_nc_purge_orig(orig_node->bat_priv, orig_node, NULL); batadv_nc_purge_orig(orig_node->bat_priv, orig_node, NULL);
...@@ -664,15 +667,17 @@ struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv, ...@@ -664,15 +667,17 @@ struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv,
/* extra reference for return */ /* extra reference for return */
atomic_set(&orig_node->refcount, 2); atomic_set(&orig_node->refcount, 2);
orig_node->tt_initialised = false;
orig_node->bat_priv = bat_priv; orig_node->bat_priv = bat_priv;
memcpy(orig_node->orig, addr, ETH_ALEN); ether_addr_copy(orig_node->orig, addr);
batadv_dat_init_orig_node_addr(orig_node); batadv_dat_init_orig_node_addr(orig_node);
atomic_set(&orig_node->last_ttvn, 0); atomic_set(&orig_node->last_ttvn, 0);
orig_node->tt_buff = NULL; orig_node->tt_buff = NULL;
orig_node->tt_buff_len = 0; orig_node->tt_buff_len = 0;
reset_time = jiffies - 1 - msecs_to_jiffies(BATADV_RESET_PROTECTION_MS); reset_time = jiffies - 1 - msecs_to_jiffies(BATADV_RESET_PROTECTION_MS);
orig_node->bcast_seqno_reset = reset_time; orig_node->bcast_seqno_reset = reset_time;
#ifdef CONFIG_BATMAN_ADV_MCAST
orig_node->mcast_flags = BATADV_NO_FLAGS;
#endif
/* create a vlan object for the "untagged" LAN */ /* create a vlan object for the "untagged" LAN */
vlan = batadv_orig_node_vlan_new(orig_node, BATADV_NO_FLAGS); vlan = batadv_orig_node_vlan_new(orig_node, BATADV_NO_FLAGS);
......
...@@ -89,6 +89,19 @@ enum batadv_icmp_packettype { ...@@ -89,6 +89,19 @@ enum batadv_icmp_packettype {
BATADV_PARAMETER_PROBLEM = 12, BATADV_PARAMETER_PROBLEM = 12,
}; };
/**
* enum batadv_mcast_flags - flags for multicast capabilities and settings
* @BATADV_MCAST_WANT_ALL_UNSNOOPABLES: we want all packets destined for
* 224.0.0.0/24 or ff02::1
* @BATADV_MCAST_WANT_ALL_IPV4: we want all IPv4 multicast packets
* @BATADV_MCAST_WANT_ALL_IPV6: we want all IPv6 multicast packets
*/
enum batadv_mcast_flags {
BATADV_MCAST_WANT_ALL_UNSNOOPABLES = BIT(0),
BATADV_MCAST_WANT_ALL_IPV4 = BIT(1),
BATADV_MCAST_WANT_ALL_IPV6 = BIT(2),
};
/* tt data subtypes */ /* tt data subtypes */
#define BATADV_TT_DATA_TYPE_MASK 0x0F #define BATADV_TT_DATA_TYPE_MASK 0x0F
...@@ -106,10 +119,30 @@ enum batadv_tt_data_flags { ...@@ -106,10 +119,30 @@ enum batadv_tt_data_flags {
BATADV_TT_FULL_TABLE = BIT(4), BATADV_TT_FULL_TABLE = BIT(4),
}; };
/* BATADV_TT_CLIENT flags. /**
* Flags from BIT(0) to BIT(7) are sent on the wire, while flags from BIT(8) to * enum batadv_tt_client_flags - TT client specific flags
* BIT(15) are used for local computation only. * @BATADV_TT_CLIENT_DEL: the client has to be deleted from the table
* Flags from BIT(4) to BIT(7) are kept in sync with the rest of the network. * @BATADV_TT_CLIENT_ROAM: the client roamed to/from another node and the new
* update telling its new real location has not been received/sent yet
* @BATADV_TT_CLIENT_WIFI: this client is connected through a wifi interface.
* This information is used by the "AP Isolation" feature
* @BATADV_TT_CLIENT_ISOLA: this client is considered "isolated". This
* information is used by the Extended Isolation feature
* @BATADV_TT_CLIENT_NOPURGE: this client should never be removed from the table
* @BATADV_TT_CLIENT_NEW: this client has been added to the local table but has
* not been announced yet
* @BATADV_TT_CLIENT_PENDING: this client is marked for removal but it is kept
* in the table for one more originator interval for consistency purposes
* @BATADV_TT_CLIENT_TEMP: this global client has been detected to be part of
* the network but no nnode has already announced it
*
* Bits from 0 to 7 are called _remote flags_ because they are sent on the wire.
* Bits from 8 to 15 are called _local flags_ because they are used for local
* computations only.
*
* Bits from 4 to 7 - a subset of remote flags - are ensured to be in sync with
* the other nodes in the network. To achieve this goal these flags are included
* in the TT CRC computation.
*/ */
enum batadv_tt_client_flags { enum batadv_tt_client_flags {
BATADV_TT_CLIENT_DEL = BIT(0), BATADV_TT_CLIENT_DEL = BIT(0),
...@@ -145,6 +178,7 @@ enum batadv_bla_claimframe { ...@@ -145,6 +178,7 @@ enum batadv_bla_claimframe {
* @BATADV_TVLV_NC: network coding tvlv * @BATADV_TVLV_NC: network coding tvlv
* @BATADV_TVLV_TT: translation table tvlv * @BATADV_TVLV_TT: translation table tvlv
* @BATADV_TVLV_ROAM: roaming advertisement tvlv * @BATADV_TVLV_ROAM: roaming advertisement tvlv
* @BATADV_TVLV_MCAST: multicast capability tvlv
*/ */
enum batadv_tvlv_type { enum batadv_tvlv_type {
BATADV_TVLV_GW = 0x01, BATADV_TVLV_GW = 0x01,
...@@ -152,6 +186,7 @@ enum batadv_tvlv_type { ...@@ -152,6 +186,7 @@ enum batadv_tvlv_type {
BATADV_TVLV_NC = 0x03, BATADV_TVLV_NC = 0x03,
BATADV_TVLV_TT = 0x04, BATADV_TVLV_TT = 0x04,
BATADV_TVLV_ROAM = 0x05, BATADV_TVLV_ROAM = 0x05,
BATADV_TVLV_MCAST = 0x06,
}; };
#pragma pack(2) #pragma pack(2)
...@@ -504,4 +539,14 @@ struct batadv_tvlv_roam_adv { ...@@ -504,4 +539,14 @@ struct batadv_tvlv_roam_adv {
__be16 vid; __be16 vid;
}; };
/**
* struct batadv_tvlv_mcast_data - payload of a multicast tvlv
* @flags: multicast flags announced by the orig node
* @reserved: reserved field
*/
struct batadv_tvlv_mcast_data {
uint8_t flags;
uint8_t reserved[3];
};
#endif /* _NET_BATMAN_ADV_PACKET_H_ */ #endif /* _NET_BATMAN_ADV_PACKET_H_ */
...@@ -222,8 +222,8 @@ static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv, ...@@ -222,8 +222,8 @@ static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv,
icmph = (struct batadv_icmp_header *)skb->data; icmph = (struct batadv_icmp_header *)skb->data;
memcpy(icmph->dst, icmph->orig, ETH_ALEN); ether_addr_copy(icmph->dst, icmph->orig);
memcpy(icmph->orig, primary_if->net_dev->dev_addr, ETH_ALEN); ether_addr_copy(icmph->orig, primary_if->net_dev->dev_addr);
icmph->msg_type = BATADV_ECHO_REPLY; icmph->msg_type = BATADV_ECHO_REPLY;
icmph->ttl = BATADV_TTL; icmph->ttl = BATADV_TTL;
...@@ -276,9 +276,8 @@ static int batadv_recv_icmp_ttl_exceeded(struct batadv_priv *bat_priv, ...@@ -276,9 +276,8 @@ static int batadv_recv_icmp_ttl_exceeded(struct batadv_priv *bat_priv,
icmp_packet = (struct batadv_icmp_packet *)skb->data; icmp_packet = (struct batadv_icmp_packet *)skb->data;
memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); ether_addr_copy(icmp_packet->dst, icmp_packet->orig);
memcpy(icmp_packet->orig, primary_if->net_dev->dev_addr, ether_addr_copy(icmp_packet->orig, primary_if->net_dev->dev_addr);
ETH_ALEN);
icmp_packet->msg_type = BATADV_TTL_EXCEEDED; icmp_packet->msg_type = BATADV_TTL_EXCEEDED;
icmp_packet->ttl = BATADV_TTL; icmp_packet->ttl = BATADV_TTL;
...@@ -341,8 +340,8 @@ int batadv_recv_icmp_packet(struct sk_buff *skb, ...@@ -341,8 +340,8 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
if (icmp_packet_rr->rr_cur >= BATADV_RR_LEN) if (icmp_packet_rr->rr_cur >= BATADV_RR_LEN)
goto out; goto out;
memcpy(&(icmp_packet_rr->rr[icmp_packet_rr->rr_cur]), ether_addr_copy(icmp_packet_rr->rr[icmp_packet_rr->rr_cur],
ethhdr->h_dest, ETH_ALEN); ethhdr->h_dest);
icmp_packet_rr->rr_cur++; icmp_packet_rr->rr_cur++;
} }
...@@ -664,7 +663,7 @@ batadv_reroute_unicast_packet(struct batadv_priv *bat_priv, ...@@ -664,7 +663,7 @@ batadv_reroute_unicast_packet(struct batadv_priv *bat_priv,
} }
/* update the packet header */ /* update the packet header */
memcpy(unicast_packet->dest, orig_addr, ETH_ALEN); ether_addr_copy(unicast_packet->dest, orig_addr);
unicast_packet->ttvn = orig_ttvn; unicast_packet->ttvn = orig_ttvn;
ret = true; ret = true;
...@@ -774,7 +773,7 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, ...@@ -774,7 +773,7 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
if (!primary_if) if (!primary_if)
return 0; return 0;
memcpy(unicast_packet->dest, primary_if->net_dev->dev_addr, ETH_ALEN); ether_addr_copy(unicast_packet->dest, primary_if->net_dev->dev_addr);
batadv_hardif_free_ref(primary_if); batadv_hardif_free_ref(primary_if);
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "originator.h" #include "originator.h"
#include "network-coding.h" #include "network-coding.h"
#include "fragmentation.h" #include "fragmentation.h"
#include "multicast.h"
static void batadv_send_outstanding_bcast_packet(struct work_struct *work); static void batadv_send_outstanding_bcast_packet(struct work_struct *work);
...@@ -59,8 +60,8 @@ int batadv_send_skb_packet(struct sk_buff *skb, ...@@ -59,8 +60,8 @@ int batadv_send_skb_packet(struct sk_buff *skb,
skb_reset_mac_header(skb); skb_reset_mac_header(skb);
ethhdr = eth_hdr(skb); ethhdr = eth_hdr(skb);
memcpy(ethhdr->h_source, hard_iface->net_dev->dev_addr, ETH_ALEN); ether_addr_copy(ethhdr->h_source, hard_iface->net_dev->dev_addr);
memcpy(ethhdr->h_dest, dst_addr, ETH_ALEN); ether_addr_copy(ethhdr->h_dest, dst_addr);
ethhdr->h_proto = htons(ETH_P_BATMAN); ethhdr->h_proto = htons(ETH_P_BATMAN);
skb_set_network_header(skb, ETH_HLEN); skb_set_network_header(skb, ETH_HLEN);
...@@ -165,7 +166,7 @@ batadv_send_skb_push_fill_unicast(struct sk_buff *skb, int hdr_size, ...@@ -165,7 +166,7 @@ batadv_send_skb_push_fill_unicast(struct sk_buff *skb, int hdr_size,
/* set unicast ttl */ /* set unicast ttl */
unicast_packet->ttl = BATADV_TTL; unicast_packet->ttl = BATADV_TTL;
/* copy the destination for faster routing */ /* copy the destination for faster routing */
memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN); ether_addr_copy(unicast_packet->dest, orig_node->orig);
/* set the destination tt version number */ /* set the destination tt version number */
unicast_packet->ttvn = ttvn; unicast_packet->ttvn = ttvn;
...@@ -220,7 +221,7 @@ bool batadv_send_skb_prepare_unicast_4addr(struct batadv_priv *bat_priv, ...@@ -220,7 +221,7 @@ bool batadv_send_skb_prepare_unicast_4addr(struct batadv_priv *bat_priv,
uc_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data; uc_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data;
uc_4addr_packet->u.packet_type = BATADV_UNICAST_4ADDR; uc_4addr_packet->u.packet_type = BATADV_UNICAST_4ADDR;
memcpy(uc_4addr_packet->src, primary_if->net_dev->dev_addr, ETH_ALEN); ether_addr_copy(uc_4addr_packet->src, primary_if->net_dev->dev_addr);
uc_4addr_packet->subtype = packet_subtype; uc_4addr_packet->subtype = packet_subtype;
uc_4addr_packet->reserved = 0; uc_4addr_packet->reserved = 0;
...@@ -248,7 +249,7 @@ bool batadv_send_skb_prepare_unicast_4addr(struct batadv_priv *bat_priv, ...@@ -248,7 +249,7 @@ bool batadv_send_skb_prepare_unicast_4addr(struct batadv_priv *bat_priv,
* *
* Returns NET_XMIT_DROP in case of error or NET_XMIT_SUCCESS otherwise. * Returns NET_XMIT_DROP in case of error or NET_XMIT_SUCCESS otherwise.
*/ */
static int batadv_send_skb_unicast(struct batadv_priv *bat_priv, int batadv_send_skb_unicast(struct batadv_priv *bat_priv,
struct sk_buff *skb, int packet_type, struct sk_buff *skb, int packet_type,
int packet_subtype, int packet_subtype,
struct batadv_orig_node *orig_node, struct batadv_orig_node *orig_node,
...@@ -256,7 +257,7 @@ static int batadv_send_skb_unicast(struct batadv_priv *bat_priv, ...@@ -256,7 +257,7 @@ static int batadv_send_skb_unicast(struct batadv_priv *bat_priv,
{ {
struct ethhdr *ethhdr; struct ethhdr *ethhdr;
struct batadv_unicast_packet *unicast_packet; struct batadv_unicast_packet *unicast_packet;
int ret = NET_XMIT_DROP, hdr_size; int ret = NET_XMIT_DROP;
if (!orig_node) if (!orig_node)
goto out; goto out;
...@@ -265,16 +266,12 @@ static int batadv_send_skb_unicast(struct batadv_priv *bat_priv, ...@@ -265,16 +266,12 @@ static int batadv_send_skb_unicast(struct batadv_priv *bat_priv,
case BATADV_UNICAST: case BATADV_UNICAST:
if (!batadv_send_skb_prepare_unicast(skb, orig_node)) if (!batadv_send_skb_prepare_unicast(skb, orig_node))
goto out; goto out;
hdr_size = sizeof(*unicast_packet);
break; break;
case BATADV_UNICAST_4ADDR: case BATADV_UNICAST_4ADDR:
if (!batadv_send_skb_prepare_unicast_4addr(bat_priv, skb, if (!batadv_send_skb_prepare_unicast_4addr(bat_priv, skb,
orig_node, orig_node,
packet_subtype)) packet_subtype))
goto out; goto out;
hdr_size = sizeof(struct batadv_unicast_4addr_packet);
break; break;
default: default:
/* this function supports UNICAST and UNICAST_4ADDR only. It /* this function supports UNICAST and UNICAST_4ADDR only. It
...@@ -283,7 +280,10 @@ static int batadv_send_skb_unicast(struct batadv_priv *bat_priv, ...@@ -283,7 +280,10 @@ static int batadv_send_skb_unicast(struct batadv_priv *bat_priv,
goto out; goto out;
} }
ethhdr = (struct ethhdr *)(skb->data + hdr_size); /* skb->data might have been reallocated by
* batadv_send_skb_prepare_unicast{,_4addr}()
*/
ethhdr = eth_hdr(skb);
unicast_packet = (struct batadv_unicast_packet *)skb->data; unicast_packet = (struct batadv_unicast_packet *)skb->data;
/* inform the destination node that we are still missing a correct route /* inform the destination node that we are still missing a correct route
...@@ -312,6 +312,7 @@ static int batadv_send_skb_unicast(struct batadv_priv *bat_priv, ...@@ -312,6 +312,7 @@ static int batadv_send_skb_unicast(struct batadv_priv *bat_priv,
* @packet_type: the batman unicast packet type to use * @packet_type: the batman unicast packet type to use
* @packet_subtype: the unicast 4addr packet subtype (only relevant for unicast * @packet_subtype: the unicast 4addr packet subtype (only relevant for unicast
* 4addr packets) * 4addr packets)
* @dst_hint: can be used to override the destination contained in the skb
* @vid: the vid to be used to search the translation table * @vid: the vid to be used to search the translation table
* *
* Look up the recipient node for the destination address in the ethernet * Look up the recipient node for the destination address in the ethernet
......
...@@ -36,6 +36,11 @@ bool batadv_send_skb_prepare_unicast_4addr(struct batadv_priv *bat_priv, ...@@ -36,6 +36,11 @@ bool batadv_send_skb_prepare_unicast_4addr(struct batadv_priv *bat_priv,
struct sk_buff *skb, struct sk_buff *skb,
struct batadv_orig_node *orig_node, struct batadv_orig_node *orig_node,
int packet_subtype); int packet_subtype);
int batadv_send_skb_unicast(struct batadv_priv *bat_priv,
struct sk_buff *skb, int packet_type,
int packet_subtype,
struct batadv_orig_node *orig_node,
unsigned short vid);
int batadv_send_skb_via_tt_generic(struct batadv_priv *bat_priv, int batadv_send_skb_via_tt_generic(struct batadv_priv *bat_priv,
struct sk_buff *skb, int packet_type, struct sk_buff *skb, int packet_type,
int packet_subtype, uint8_t *dst_hint, int packet_subtype, uint8_t *dst_hint,
...@@ -47,6 +52,7 @@ int batadv_send_skb_via_gw(struct batadv_priv *bat_priv, struct sk_buff *skb, ...@@ -47,6 +52,7 @@ int batadv_send_skb_via_gw(struct batadv_priv *bat_priv, struct sk_buff *skb,
* batadv_send_skb_via_tt - send an skb via TT lookup * batadv_send_skb_via_tt - send an skb via TT lookup
* @bat_priv: the bat priv with all the soft interface information * @bat_priv: the bat priv with all the soft interface information
* @skb: the payload to send * @skb: the payload to send
* @dst_hint: can be used to override the destination contained in the skb
* @vid: the vid to be used to search the translation table * @vid: the vid to be used to search the translation table
* *
* Look up the recipient node for the destination address in the ethernet * Look up the recipient node for the destination address in the ethernet
...@@ -68,6 +74,7 @@ static inline int batadv_send_skb_via_tt(struct batadv_priv *bat_priv, ...@@ -68,6 +74,7 @@ static inline int batadv_send_skb_via_tt(struct batadv_priv *bat_priv,
* @bat_priv: the bat priv with all the soft interface information * @bat_priv: the bat priv with all the soft interface information
* @skb: the payload to send * @skb: the payload to send
* @packet_subtype: the unicast 4addr packet subtype to use * @packet_subtype: the unicast 4addr packet subtype to use
* @dst_hint: can be used to override the destination contained in the skb
* @vid: the vid to be used to search the translation table * @vid: the vid to be used to search the translation table
* *
* Look up the recipient node for the destination address in the ethernet * Look up the recipient node for the destination address in the ethernet
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <linux/ethtool.h> #include <linux/ethtool.h>
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include <linux/if_vlan.h> #include <linux/if_vlan.h>
#include "multicast.h"
#include "bridge_loop_avoidance.h" #include "bridge_loop_avoidance.h"
#include "network-coding.h" #include "network-coding.h"
...@@ -111,8 +112,8 @@ static int batadv_interface_set_mac_addr(struct net_device *dev, void *p) ...@@ -111,8 +112,8 @@ static int batadv_interface_set_mac_addr(struct net_device *dev, void *p)
if (!is_valid_ether_addr(addr->sa_data)) if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL; return -EADDRNOTAVAIL;
memcpy(old_addr, dev->dev_addr, ETH_ALEN); ether_addr_copy(old_addr, dev->dev_addr);
memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); ether_addr_copy(dev->dev_addr, addr->sa_data);
/* only modify transtable if it has been initialized before */ /* only modify transtable if it has been initialized before */
if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_ACTIVE) { if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_ACTIVE) {
...@@ -170,17 +171,19 @@ static int batadv_interface_tx(struct sk_buff *skb, ...@@ -170,17 +171,19 @@ static int batadv_interface_tx(struct sk_buff *skb,
unsigned short vid; unsigned short vid;
uint32_t seqno; uint32_t seqno;
int gw_mode; int gw_mode;
enum batadv_forw_mode forw_mode;
struct batadv_orig_node *mcast_single_orig = NULL;
if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
goto dropped; goto dropped;
soft_iface->trans_start = jiffies; soft_iface->trans_start = jiffies;
vid = batadv_get_vid(skb, 0); vid = batadv_get_vid(skb, 0);
ethhdr = (struct ethhdr *)skb->data; ethhdr = eth_hdr(skb);
switch (ntohs(ethhdr->h_proto)) { switch (ntohs(ethhdr->h_proto)) {
case ETH_P_8021Q: case ETH_P_8021Q:
vhdr = (struct vlan_ethhdr *)skb->data; vhdr = vlan_eth_hdr(skb);
if (vhdr->h_vlan_encapsulated_proto != ethertype) if (vhdr->h_vlan_encapsulated_proto != ethertype)
break; break;
...@@ -194,7 +197,7 @@ static int batadv_interface_tx(struct sk_buff *skb, ...@@ -194,7 +197,7 @@ static int batadv_interface_tx(struct sk_buff *skb,
goto dropped; goto dropped;
/* skb->data might have been reallocated by batadv_bla_tx() */ /* skb->data might have been reallocated by batadv_bla_tx() */
ethhdr = (struct ethhdr *)skb->data; ethhdr = eth_hdr(skb);
/* Register the client MAC in the transtable */ /* Register the client MAC in the transtable */
if (!is_multicast_ether_addr(ethhdr->h_source)) { if (!is_multicast_ether_addr(ethhdr->h_source)) {
...@@ -230,7 +233,7 @@ static int batadv_interface_tx(struct sk_buff *skb, ...@@ -230,7 +233,7 @@ static int batadv_interface_tx(struct sk_buff *skb,
/* skb->data may have been modified by /* skb->data may have been modified by
* batadv_gw_dhcp_recipient_get() * batadv_gw_dhcp_recipient_get()
*/ */
ethhdr = (struct ethhdr *)skb->data; ethhdr = eth_hdr(skb);
/* if gw_mode is on, broadcast any non-DHCP message. /* if gw_mode is on, broadcast any non-DHCP message.
* All the DHCP packets are going to be sent as unicast * All the DHCP packets are going to be sent as unicast
*/ */
...@@ -247,9 +250,19 @@ static int batadv_interface_tx(struct sk_buff *skb, ...@@ -247,9 +250,19 @@ static int batadv_interface_tx(struct sk_buff *skb,
* directed to a DHCP server * directed to a DHCP server
*/ */
goto dropped; goto dropped;
}
send: send:
if (do_bcast && !is_broadcast_ether_addr(ethhdr->h_dest)) {
forw_mode = batadv_mcast_forw_mode(bat_priv, skb,
&mcast_single_orig);
if (forw_mode == BATADV_FORW_NONE)
goto dropped;
if (forw_mode == BATADV_FORW_SINGLE)
do_bcast = false;
}
}
batadv_skb_set_priority(skb, 0); batadv_skb_set_priority(skb, 0);
/* ethernet packet should be broadcasted */ /* ethernet packet should be broadcasted */
...@@ -279,8 +292,8 @@ static int batadv_interface_tx(struct sk_buff *skb, ...@@ -279,8 +292,8 @@ static int batadv_interface_tx(struct sk_buff *skb,
/* hw address of first interface is the orig mac because only /* hw address of first interface is the orig mac because only
* this mac is known throughout the mesh * this mac is known throughout the mesh
*/ */
memcpy(bcast_packet->orig, ether_addr_copy(bcast_packet->orig,
primary_if->net_dev->dev_addr, ETH_ALEN); primary_if->net_dev->dev_addr);
/* set broadcast sequence number */ /* set broadcast sequence number */
seqno = atomic_inc_return(&bat_priv->bcast_seqno); seqno = atomic_inc_return(&bat_priv->bcast_seqno);
...@@ -301,6 +314,10 @@ static int batadv_interface_tx(struct sk_buff *skb, ...@@ -301,6 +314,10 @@ static int batadv_interface_tx(struct sk_buff *skb,
if (ret) if (ret)
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) {
ret = batadv_send_skb_unicast(bat_priv, skb,
BATADV_UNICAST, 0,
mcast_single_orig, vid);
} else { } else {
if (batadv_dat_snoop_outgoing_arp_request(bat_priv, if (batadv_dat_snoop_outgoing_arp_request(bat_priv,
skb)) skb))
...@@ -652,10 +669,7 @@ static void batadv_softif_destroy_finish(struct work_struct *work) ...@@ -652,10 +669,7 @@ static void batadv_softif_destroy_finish(struct work_struct *work)
} }
batadv_sysfs_del_meshif(soft_iface); batadv_sysfs_del_meshif(soft_iface);
unregister_netdev(soft_iface);
rtnl_lock();
unregister_netdevice(soft_iface);
rtnl_unlock();
} }
/** /**
...@@ -691,6 +705,14 @@ static int batadv_softif_init_late(struct net_device *dev) ...@@ -691,6 +705,14 @@ static int batadv_softif_init_late(struct net_device *dev)
#endif #endif
#ifdef CONFIG_BATMAN_ADV_DAT #ifdef CONFIG_BATMAN_ADV_DAT
atomic_set(&bat_priv->distributed_arp_table, 1); atomic_set(&bat_priv->distributed_arp_table, 1);
#endif
#ifdef CONFIG_BATMAN_ADV_MCAST
bat_priv->mcast.flags = BATADV_NO_FLAGS;
atomic_set(&bat_priv->multicast_mode, 1);
atomic_set(&bat_priv->mcast.num_disabled, 0);
atomic_set(&bat_priv->mcast.num_want_all_unsnoopables, 0);
atomic_set(&bat_priv->mcast.num_want_all_ipv4, 0);
atomic_set(&bat_priv->mcast.num_want_all_ipv6, 0);
#endif #endif
atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF); atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF);
atomic_set(&bat_priv->gw_sel_class, 20); atomic_set(&bat_priv->gw_sel_class, 20);
......
...@@ -539,6 +539,9 @@ BATADV_ATTR_SIF_UINT(gw_sel_class, S_IRUGO | S_IWUSR, 1, BATADV_TQ_MAX_VALUE, ...@@ -539,6 +539,9 @@ BATADV_ATTR_SIF_UINT(gw_sel_class, S_IRUGO | S_IWUSR, 1, BATADV_TQ_MAX_VALUE,
batadv_post_gw_reselect); batadv_post_gw_reselect);
static BATADV_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, batadv_show_gw_bwidth, static BATADV_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, batadv_show_gw_bwidth,
batadv_store_gw_bwidth); batadv_store_gw_bwidth);
#ifdef CONFIG_BATMAN_ADV_MCAST
BATADV_ATTR_SIF_BOOL(multicast_mode, S_IRUGO | S_IWUSR, NULL);
#endif
#ifdef CONFIG_BATMAN_ADV_DEBUG #ifdef CONFIG_BATMAN_ADV_DEBUG
BATADV_ATTR_SIF_UINT(log_level, S_IRUGO | S_IWUSR, 0, BATADV_DBG_ALL, NULL); BATADV_ATTR_SIF_UINT(log_level, S_IRUGO | S_IWUSR, 0, BATADV_DBG_ALL, NULL);
#endif #endif
...@@ -557,6 +560,9 @@ static struct batadv_attribute *batadv_mesh_attrs[] = { ...@@ -557,6 +560,9 @@ static struct batadv_attribute *batadv_mesh_attrs[] = {
#endif #endif
#ifdef CONFIG_BATMAN_ADV_DAT #ifdef CONFIG_BATMAN_ADV_DAT
&batadv_attr_distributed_arp_table, &batadv_attr_distributed_arp_table,
#endif
#ifdef CONFIG_BATMAN_ADV_MCAST
&batadv_attr_multicast_mode,
#endif #endif
&batadv_attr_fragmentation, &batadv_attr_fragmentation,
&batadv_attr_routing_algo, &batadv_attr_routing_algo,
......
This diff is collapsed.
...@@ -29,6 +29,8 @@ int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset); ...@@ -29,6 +29,8 @@ int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset);
void batadv_tt_global_del_orig(struct batadv_priv *bat_priv, void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node, struct batadv_orig_node *orig_node,
int32_t match_vid, const char *message); int32_t match_vid, const char *message);
int batadv_tt_global_hash_count(struct batadv_priv *bat_priv,
const uint8_t *addr, unsigned short vid);
struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv, struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv,
const uint8_t *src, const uint8_t *src,
const uint8_t *addr, const uint8_t *addr,
......
...@@ -24,8 +24,9 @@ ...@@ -24,8 +24,9 @@
#ifdef CONFIG_BATMAN_ADV_DAT #ifdef CONFIG_BATMAN_ADV_DAT
/* batadv_dat_addr_t is the type used for all DHT addresses. If it is changed, /**
* BATADV_DAT_ADDR_MAX is changed as well. * batadv_dat_addr_t - it is the type used for all DHT addresses. If it is
* changed, BATADV_DAT_ADDR_MAX is changed as well.
* *
* *Please be careful: batadv_dat_addr_t must be UNSIGNED* * *Please be careful: batadv_dat_addr_t must be UNSIGNED*
*/ */
...@@ -163,7 +164,7 @@ struct batadv_vlan_tt { ...@@ -163,7 +164,7 @@ struct batadv_vlan_tt {
}; };
/** /**
* batadv_orig_node_vlan - VLAN specific data per orig_node * struct batadv_orig_node_vlan - VLAN specific data per orig_node
* @vid: the VLAN identifier * @vid: the VLAN identifier
* @tt: VLAN specific TT attributes * @tt: VLAN specific TT attributes
* @list: list node for orig_node::vlan_list * @list: list node for orig_node::vlan_list
...@@ -204,14 +205,18 @@ struct batadv_orig_bat_iv { ...@@ -204,14 +205,18 @@ struct batadv_orig_bat_iv {
* @batadv_dat_addr_t: address of the orig node in the distributed hash * @batadv_dat_addr_t: address of the orig node in the distributed hash
* @last_seen: time when last packet from this node was received * @last_seen: time when last packet from this node was received
* @bcast_seqno_reset: time when the broadcast seqno window was reset * @bcast_seqno_reset: time when the broadcast seqno window was reset
* @mcast_flags: multicast flags announced by the orig node
* @mcast_want_all_unsnoop_node: a list node for the
* mcast.want_all_unsnoopables list
* @mcast_want_all_ipv4_node: a list node for the mcast.want_all_ipv4 list
* @mcast_want_all_ipv6_node: a list node for the mcast.want_all_ipv6 list
* @capabilities: announced capabilities of this originator * @capabilities: announced capabilities of this originator
* @capa_initialized: bitfield to remember whether a capability was initialized
* @last_ttvn: last seen translation table version number * @last_ttvn: last seen translation table version number
* @tt_buff: last tt changeset this node received from the orig node * @tt_buff: last tt changeset this node received from the orig node
* @tt_buff_len: length of the last tt changeset this node received from the * @tt_buff_len: length of the last tt changeset this node received from the
* orig node * orig node
* @tt_buff_lock: lock that protects tt_buff and tt_buff_len * @tt_buff_lock: lock that protects tt_buff and tt_buff_len
* @tt_initialised: bool keeping track of whether or not this node have received
* any translation table information from the orig node yet
* @tt_lock: prevents from updating the table while reading it. Table update is * @tt_lock: prevents from updating the table while reading it. Table update is
* made up by two operations (data structure update and metdata -CRC/TTVN- * made up by two operations (data structure update and metdata -CRC/TTVN-
* recalculation) and they have to be executed atomically in order to avoid * recalculation) and they have to be executed atomically in order to avoid
...@@ -247,12 +252,18 @@ struct batadv_orig_node { ...@@ -247,12 +252,18 @@ struct batadv_orig_node {
#endif #endif
unsigned long last_seen; unsigned long last_seen;
unsigned long bcast_seqno_reset; unsigned long bcast_seqno_reset;
#ifdef CONFIG_BATMAN_ADV_MCAST
uint8_t mcast_flags;
struct hlist_node mcast_want_all_unsnoopables_node;
struct hlist_node mcast_want_all_ipv4_node;
struct hlist_node mcast_want_all_ipv6_node;
#endif
uint8_t capabilities; uint8_t capabilities;
uint8_t capa_initialized;
atomic_t last_ttvn; atomic_t last_ttvn;
unsigned char *tt_buff; unsigned char *tt_buff;
int16_t tt_buff_len; int16_t tt_buff_len;
spinlock_t tt_buff_lock; /* protects tt_buff & tt_buff_len */ spinlock_t tt_buff_lock; /* protects tt_buff & tt_buff_len */
bool tt_initialised;
/* prevents from changing the table while reading it */ /* prevents from changing the table while reading it */
spinlock_t tt_lock; spinlock_t tt_lock;
DECLARE_BITMAP(bcast_bits, BATADV_TQ_LOCAL_WINDOW_SIZE); DECLARE_BITMAP(bcast_bits, BATADV_TQ_LOCAL_WINDOW_SIZE);
...@@ -282,10 +293,15 @@ struct batadv_orig_node { ...@@ -282,10 +293,15 @@ struct batadv_orig_node {
* enum batadv_orig_capabilities - orig node capabilities * enum batadv_orig_capabilities - orig node capabilities
* @BATADV_ORIG_CAPA_HAS_DAT: orig node has distributed arp table enabled * @BATADV_ORIG_CAPA_HAS_DAT: orig node has distributed arp table enabled
* @BATADV_ORIG_CAPA_HAS_NC: orig node has network coding enabled * @BATADV_ORIG_CAPA_HAS_NC: orig node has network coding enabled
* @BATADV_ORIG_CAPA_HAS_TT: orig node has tt capability
* @BATADV_ORIG_CAPA_HAS_MCAST: orig node has some multicast capability
* (= orig node announces a tvlv of type BATADV_TVLV_MCAST)
*/ */
enum batadv_orig_capabilities { enum batadv_orig_capabilities {
BATADV_ORIG_CAPA_HAS_DAT = BIT(0), BATADV_ORIG_CAPA_HAS_DAT = BIT(0),
BATADV_ORIG_CAPA_HAS_NC = BIT(1), BATADV_ORIG_CAPA_HAS_NC = BIT(1),
BATADV_ORIG_CAPA_HAS_TT = BIT(2),
BATADV_ORIG_CAPA_HAS_MCAST = BIT(3),
}; };
/** /**
...@@ -334,7 +350,7 @@ struct batadv_neigh_node { ...@@ -334,7 +350,7 @@ struct batadv_neigh_node {
}; };
/** /**
* struct batadv_neigh_node_bat_iv - neighbor information per outgoing * struct batadv_neigh_ifinfo_bat_iv - neighbor information per outgoing
* interface for BATMAN IV * interface for BATMAN IV
* @tq_recv: ring buffer of received TQ values from this neigh node * @tq_recv: ring buffer of received TQ values from this neigh node
* @tq_index: ring buffer index * @tq_index: ring buffer index
...@@ -544,7 +560,7 @@ struct batadv_priv_bla { ...@@ -544,7 +560,7 @@ struct batadv_priv_bla {
#endif #endif
/** /**
* struct batadv_debug_log - debug logging data * struct batadv_priv_debug_log - debug logging data
* @log_buff: buffer holding the logs (ring bufer) * @log_buff: buffer holding the logs (ring bufer)
* @log_start: index of next character to read * @log_start: index of next character to read
* @log_end: index of next character to write * @log_end: index of next character to write
...@@ -607,6 +623,39 @@ struct batadv_priv_dat { ...@@ -607,6 +623,39 @@ struct batadv_priv_dat {
}; };
#endif #endif
#ifdef CONFIG_BATMAN_ADV_MCAST
/**
* struct batadv_priv_mcast - per mesh interface mcast data
* @mla_list: list of multicast addresses we are currently announcing via TT
* @want_all_unsnoopables_list: a list of orig_nodes wanting all unsnoopable
* multicast traffic
* @want_all_ipv4_list: a list of orig_nodes wanting all IPv4 multicast traffic
* @want_all_ipv6_list: a list of orig_nodes wanting all IPv6 multicast traffic
* @flags: the flags we have last sent in our mcast tvlv
* @enabled: whether the multicast tvlv is currently enabled
* @num_disabled: number of nodes that have no mcast tvlv
* @num_want_all_unsnoopables: number of nodes wanting unsnoopable IP traffic
* @num_want_all_ipv4: counter for items in want_all_ipv4_list
* @num_want_all_ipv6: counter for items in want_all_ipv6_list
* @want_lists_lock: lock for protecting modifications to mcast want lists
* (traversals are rcu-locked)
*/
struct batadv_priv_mcast {
struct hlist_head mla_list;
struct hlist_head want_all_unsnoopables_list;
struct hlist_head want_all_ipv4_list;
struct hlist_head want_all_ipv6_list;
uint8_t flags;
bool enabled;
atomic_t num_disabled;
atomic_t num_want_all_unsnoopables;
atomic_t num_want_all_ipv4;
atomic_t num_want_all_ipv6;
/* protects want_all_{unsnoopables,ipv4,ipv6}_list */
spinlock_t want_lists_lock;
};
#endif
/** /**
* struct batadv_priv_nc - per mesh interface network coding private data * struct batadv_priv_nc - per mesh interface network coding private data
* @work: work queue callback item for cleanup * @work: work queue callback item for cleanup
...@@ -672,6 +721,8 @@ struct batadv_softif_vlan { ...@@ -672,6 +721,8 @@ struct batadv_softif_vlan {
* enabled * enabled
* @distributed_arp_table: bool indicating whether distributed ARP table is * @distributed_arp_table: bool indicating whether distributed ARP table is
* enabled * enabled
* @multicast_mode: Enable or disable multicast optimizations on this node's
* sender/originating side
* @gw_mode: gateway operation: off, client or server (see batadv_gw_modes) * @gw_mode: gateway operation: off, client or server (see batadv_gw_modes)
* @gw_sel_class: gateway selection class (applies if gw_mode client) * @gw_sel_class: gateway selection class (applies if gw_mode client)
* @orig_interval: OGM broadcast interval in milliseconds * @orig_interval: OGM broadcast interval in milliseconds
...@@ -702,6 +753,7 @@ struct batadv_softif_vlan { ...@@ -702,6 +753,7 @@ struct batadv_softif_vlan {
* @tt: translation table data * @tt: translation table data
* @tvlv: type-version-length-value data * @tvlv: type-version-length-value data
* @dat: distributed arp table data * @dat: distributed arp table data
* @mcast: multicast data
* @network_coding: bool indicating whether network coding is enabled * @network_coding: bool indicating whether network coding is enabled
* @batadv_priv_nc: network coding data * @batadv_priv_nc: network coding data
*/ */
...@@ -720,6 +772,9 @@ struct batadv_priv { ...@@ -720,6 +772,9 @@ struct batadv_priv {
#endif #endif
#ifdef CONFIG_BATMAN_ADV_DAT #ifdef CONFIG_BATMAN_ADV_DAT
atomic_t distributed_arp_table; atomic_t distributed_arp_table;
#endif
#ifdef CONFIG_BATMAN_ADV_MCAST
atomic_t multicast_mode;
#endif #endif
atomic_t gw_mode; atomic_t gw_mode;
atomic_t gw_sel_class; atomic_t gw_sel_class;
...@@ -759,6 +814,9 @@ struct batadv_priv { ...@@ -759,6 +814,9 @@ struct batadv_priv {
#ifdef CONFIG_BATMAN_ADV_DAT #ifdef CONFIG_BATMAN_ADV_DAT
struct batadv_priv_dat dat; struct batadv_priv_dat dat;
#endif #endif
#ifdef CONFIG_BATMAN_ADV_MCAST
struct batadv_priv_mcast mcast;
#endif
#ifdef CONFIG_BATMAN_ADV_NC #ifdef CONFIG_BATMAN_ADV_NC
atomic_t network_coding; atomic_t network_coding;
struct batadv_priv_nc nc; struct batadv_priv_nc nc;
...@@ -881,12 +939,14 @@ struct batadv_tt_local_entry { ...@@ -881,12 +939,14 @@ struct batadv_tt_local_entry {
* struct batadv_tt_global_entry - translation table global entry data * struct batadv_tt_global_entry - translation table global entry data
* @common: general translation table data * @common: general translation table data
* @orig_list: list of orig nodes announcing this non-mesh client * @orig_list: list of orig nodes announcing this non-mesh client
* @orig_list_count: number of items in the orig_list
* @list_lock: lock protecting orig_list * @list_lock: lock protecting orig_list
* @roam_at: time at which TT_GLOBAL_ROAM was set * @roam_at: time at which TT_GLOBAL_ROAM was set
*/ */
struct batadv_tt_global_entry { struct batadv_tt_global_entry {
struct batadv_tt_common_entry common; struct batadv_tt_common_entry common;
struct hlist_head orig_list; struct hlist_head orig_list;
atomic_t orig_list_count;
spinlock_t list_lock; /* protects orig_list */ spinlock_t list_lock; /* protects orig_list */
unsigned long roam_at; unsigned long roam_at;
}; };
...@@ -1004,8 +1064,8 @@ struct batadv_nc_packet { ...@@ -1004,8 +1064,8 @@ struct batadv_nc_packet {
}; };
/** /**
* batadv_skb_cb - control buffer structure used to store private data relevant * struct batadv_skb_cb - control buffer structure used to store private data
* to batman-adv in the skb->cb buffer in skbs. * relevant to batman-adv in the skb->cb buffer in skbs.
* @decoded: Marks a skb as decoded, which is checked when searching for coding * @decoded: Marks a skb as decoded, which is checked when searching for coding
* opportunities in network-coding.c * opportunities in network-coding.c
*/ */
...@@ -1115,6 +1175,16 @@ struct batadv_dat_entry { ...@@ -1115,6 +1175,16 @@ struct batadv_dat_entry {
struct rcu_head rcu; struct rcu_head rcu;
}; };
/**
* struct batadv_hw_addr - a list entry for a MAC address
* @list: list node for the linking of entries
* @addr: the MAC address of this list entry
*/
struct batadv_hw_addr {
struct hlist_node list;
unsigned char addr[ETH_ALEN];
};
/** /**
* struct batadv_dat_candidate - candidate destination for DAT operations * struct batadv_dat_candidate - candidate destination for DAT operations
* @type: the type of the selected candidate. It can one of the following: * @type: the type of the selected candidate. It can one of the following:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment