Commit 0e43182c authored by David S. Miller's avatar David S. Miller

Merge branch 'batman-adv/next' of git://git.open-mesh.org/linux-merge

parents 131ea667 a943cac1
...@@ -22,6 +22,14 @@ Description: ...@@ -22,6 +22,14 @@ Description:
mesh will be fragmented or silently discarded if the mesh will be fragmented or silently discarded if the
packet size exceeds the outgoing interface MTU. packet size exceeds the outgoing interface MTU.
What: /sys/class/net/<mesh_iface>/mesh/ap_isolation
Date: May 2011
Contact: Antonio Quartulli <ordex@autistici.org>
Description:
Indicates whether the data traffic going from a
wireless client to another wireless client will be
silently dropped.
What: /sys/class/net/<mesh_iface>/mesh/gw_bandwidth What: /sys/class/net/<mesh_iface>/mesh/gw_bandwidth
Date: October 2010 Date: October 2010
Contact: Marek Lindner <lindner_marek@yahoo.de> Contact: Marek Lindner <lindner_marek@yahoo.de>
......
...@@ -28,8 +28,7 @@ ...@@ -28,8 +28,7 @@
static inline int aggregated_packet(int buff_pos, int packet_len, static inline int aggregated_packet(int buff_pos, int packet_len,
int tt_num_changes) int tt_num_changes)
{ {
int next_buff_pos = buff_pos + BAT_PACKET_LEN + (tt_num_changes * int next_buff_pos = buff_pos + BAT_PACKET_LEN + tt_len(tt_num_changes);
sizeof(struct tt_change));
return (next_buff_pos <= packet_len) && return (next_buff_pos <= packet_len) &&
(next_buff_pos <= MAX_AGGREGATION_BYTES); (next_buff_pos <= MAX_AGGREGATION_BYTES);
......
...@@ -380,6 +380,7 @@ static ssize_t store_gw_bwidth(struct kobject *kobj, struct attribute *attr, ...@@ -380,6 +380,7 @@ static ssize_t store_gw_bwidth(struct kobject *kobj, struct attribute *attr,
BAT_ATTR_BOOL(aggregated_ogms, S_IRUGO | S_IWUSR, NULL); BAT_ATTR_BOOL(aggregated_ogms, S_IRUGO | S_IWUSR, NULL);
BAT_ATTR_BOOL(bonding, S_IRUGO | S_IWUSR, NULL); BAT_ATTR_BOOL(bonding, S_IRUGO | S_IWUSR, NULL);
BAT_ATTR_BOOL(fragmentation, S_IRUGO | S_IWUSR, update_min_mtu); BAT_ATTR_BOOL(fragmentation, S_IRUGO | S_IWUSR, update_min_mtu);
BAT_ATTR_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL);
static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode); static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode);
static BAT_ATTR(gw_mode, S_IRUGO | S_IWUSR, show_gw_mode, store_gw_mode); static BAT_ATTR(gw_mode, S_IRUGO | S_IWUSR, show_gw_mode, store_gw_mode);
BAT_ATTR_UINT(orig_interval, S_IRUGO | S_IWUSR, 2 * JITTER, INT_MAX, NULL); BAT_ATTR_UINT(orig_interval, S_IRUGO | S_IWUSR, 2 * JITTER, INT_MAX, NULL);
...@@ -396,6 +397,7 @@ static struct bat_attribute *mesh_attrs[] = { ...@@ -396,6 +397,7 @@ static struct bat_attribute *mesh_attrs[] = {
&bat_attr_aggregated_ogms, &bat_attr_aggregated_ogms,
&bat_attr_bonding, &bat_attr_bonding,
&bat_attr_fragmentation, &bat_attr_fragmentation,
&bat_attr_ap_isolation,
&bat_attr_vis_mode, &bat_attr_vis_mode,
&bat_attr_gw_mode, &bat_attr_gw_mode,
&bat_attr_orig_interval, &bat_attr_orig_interval,
......
...@@ -97,12 +97,12 @@ static void bit_shift(unsigned long *seq_bits, int32_t n) ...@@ -97,12 +97,12 @@ static void bit_shift(unsigned long *seq_bits, int32_t n)
(seq_bits[i - word_num - 1] >> (seq_bits[i - word_num - 1] >>
(WORD_BIT_SIZE-word_offset)); (WORD_BIT_SIZE-word_offset));
/* and the upper part of the right half and shift it left to /* and the upper part of the right half and shift it left to
* it's position */ * its position */
/* for our example that would be: word[0] = 9800 + 0076 = /* for our example that would be: word[0] = 9800 + 0076 =
* 9876 */ * 9876 */
} }
/* now for our last word, i==word_num, we only have the it's "left" /* now for our last word, i==word_num, we only have its "left" half.
* half. that's the 1000 word in our example.*/ * that's the 1000 word in our example.*/
seq_bits[i] = (seq_bits[i - word_num] << word_offset); seq_bits[i] = (seq_bits[i - word_num] << word_offset);
......
...@@ -532,14 +532,14 @@ static bool is_type_dhcprequest(struct sk_buff *skb, int header_len) ...@@ -532,14 +532,14 @@ static bool is_type_dhcprequest(struct sk_buff *skb, int header_len)
pkt_len -= header_len + DHCP_OPTIONS_OFFSET + 1; pkt_len -= header_len + DHCP_OPTIONS_OFFSET + 1;
/* Access the dhcp option lists. Each entry is made up by: /* Access the dhcp option lists. Each entry is made up by:
* - octect 1: option type * - octet 1: option type
* - octect 2: option data len (only if type != 255 and 0) * - octet 2: option data len (only if type != 255 and 0)
* - octect 3: option data */ * - octet 3: option data */
while (*p != 255 && !ret) { while (*p != 255 && !ret) {
/* p now points to the first octect: option type */ /* p now points to the first octet: option type */
if (*p == 53) { if (*p == 53) {
/* type 53 is the message type option. /* type 53 is the message type option.
* Jump the len octect and go to the data octect */ * Jump the len octet and go to the data octet */
if (pkt_len < 2) if (pkt_len < 2)
goto out; goto out;
p += 2; p += 2;
......
...@@ -249,7 +249,7 @@ static void hardif_activate_interface(struct hard_iface *hard_iface) ...@@ -249,7 +249,7 @@ static void hardif_activate_interface(struct hard_iface *hard_iface)
/** /**
* the first active interface becomes our primary interface or * the first active interface becomes our primary interface or
* the next active interface after the old primay interface was removed * the next active interface after the old primary interface was removed
*/ */
primary_if = primary_if_get_selected(bat_priv); primary_if = primary_if_get_selected(bat_priv);
if (!primary_if) if (!primary_if)
...@@ -573,7 +573,7 @@ static int hard_if_event(struct notifier_block *this, ...@@ -573,7 +573,7 @@ static int hard_if_event(struct notifier_block *this,
return NOTIFY_DONE; return NOTIFY_DONE;
} }
/* receive a packet with the batman ethertype coming on a hard /* incoming packets with the batman ethertype received on any active hard
* interface */ * interface */
static int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, static int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *ptype, struct packet_type *ptype,
...@@ -681,6 +681,36 @@ static int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, ...@@ -681,6 +681,36 @@ static int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
return NET_RX_DROP; return NET_RX_DROP;
} }
/* This function returns true if the interface represented by ifindex is a
* 802.11 wireless device */
bool is_wifi_iface(int ifindex)
{
struct net_device *net_device = NULL;
bool ret = false;
if (ifindex == NULL_IFINDEX)
goto out;
net_device = dev_get_by_index(&init_net, ifindex);
if (!net_device)
goto out;
#ifdef CONFIG_WIRELESS_EXT
/* pre-cfg80211 drivers have to implement WEXT, so it is possible to
* check for wireless_handlers != NULL */
if (net_device->wireless_handlers)
ret = true;
else
#endif
/* cfg80211 drivers have to set ieee80211_ptr */
if (net_device->ieee80211_ptr)
ret = true;
out:
if (net_device)
dev_put(net_device);
return ret;
}
struct notifier_block hard_if_notifier = { struct notifier_block hard_if_notifier = {
.notifier_call = hard_if_event, .notifier_call = hard_if_event,
}; };
...@@ -42,6 +42,7 @@ void hardif_remove_interfaces(void); ...@@ -42,6 +42,7 @@ void hardif_remove_interfaces(void);
int hardif_min_mtu(struct net_device *soft_iface); int hardif_min_mtu(struct net_device *soft_iface);
void update_min_mtu(struct net_device *soft_iface); void update_min_mtu(struct net_device *soft_iface);
void hardif_free_rcu(struct rcu_head *rcu); void hardif_free_rcu(struct rcu_head *rcu);
bool is_wifi_iface(int ifindex);
static inline void hardif_free_ref(struct hard_iface *hard_iface) static inline void hardif_free_ref(struct hard_iface *hard_iface)
{ {
......
...@@ -76,19 +76,30 @@ static inline void hash_delete(struct hashtable_t *hash, ...@@ -76,19 +76,30 @@ static inline void hash_delete(struct hashtable_t *hash,
hash_destroy(hash); hash_destroy(hash);
} }
/* adds data to the hashtable. returns 0 on success, -1 on error */ /**
* hash_add - adds data to the hashtable
* @hash: storage hash table
* @compare: callback to determine if 2 hash elements are identical
* @choose: callback calculating the hash index
* @data: data passed to the aforementioned callbacks as argument
* @data_node: to be added element
*
* Returns 0 on success, 1 if the element already is in the hash
* and -1 on error.
*/
static inline int hash_add(struct hashtable_t *hash, static inline int hash_add(struct hashtable_t *hash,
hashdata_compare_cb compare, hashdata_compare_cb compare,
hashdata_choose_cb choose, hashdata_choose_cb choose,
const void *data, struct hlist_node *data_node) const void *data, struct hlist_node *data_node)
{ {
int index; int index, ret = -1;
struct hlist_head *head; struct hlist_head *head;
struct hlist_node *node; struct hlist_node *node;
spinlock_t *list_lock; /* spinlock to protect write access */ spinlock_t *list_lock; /* spinlock to protect write access */
if (!hash) if (!hash)
goto err; goto out;
index = choose(data, hash->size); index = choose(data, hash->size);
head = &hash->table[index]; head = &hash->table[index];
...@@ -99,6 +110,7 @@ static inline int hash_add(struct hashtable_t *hash, ...@@ -99,6 +110,7 @@ static inline int hash_add(struct hashtable_t *hash,
if (!compare(node, data)) if (!compare(node, data))
continue; continue;
ret = 1;
goto err_unlock; goto err_unlock;
} }
rcu_read_unlock(); rcu_read_unlock();
...@@ -108,12 +120,13 @@ static inline int hash_add(struct hashtable_t *hash, ...@@ -108,12 +120,13 @@ static inline int hash_add(struct hashtable_t *hash,
hlist_add_head_rcu(data_node, head); hlist_add_head_rcu(data_node, head);
spin_unlock_bh(list_lock); spin_unlock_bh(list_lock);
return 0; ret = 0;
goto out;
err_unlock: err_unlock:
rcu_read_unlock(); rcu_read_unlock();
err: out:
return -1; return ret;
} }
/* removes data from hash, if found. returns pointer do data on success, so you /* removes data from hash, if found. returns pointer do data on success, so you
......
...@@ -107,7 +107,7 @@ int mesh_init(struct net_device *soft_iface) ...@@ -107,7 +107,7 @@ int mesh_init(struct net_device *soft_iface)
if (tt_init(bat_priv) < 1) if (tt_init(bat_priv) < 1)
goto err; goto err;
tt_local_add(soft_iface, soft_iface->dev_addr); tt_local_add(soft_iface, soft_iface->dev_addr, NULL_IFINDEX);
if (vis_init(bat_priv) < 1) if (vis_init(bat_priv) < 1)
goto err; goto err;
......
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
#define PURGE_TIMEOUT 200 #define PURGE_TIMEOUT 200
#define TT_LOCAL_TIMEOUT 3600 /* in seconds */ #define TT_LOCAL_TIMEOUT 3600 /* in seconds */
#define TT_CLIENT_ROAM_TIMEOUT 600 #define TT_CLIENT_ROAM_TIMEOUT 600
/* sliding packet range of received originator messages in squence numbers /* sliding packet range of received originator messages in sequence numbers
* (should be a multiple of our word size) */ * (should be a multiple of our word size) */
#define TQ_LOCAL_WINDOW_SIZE 64 #define TQ_LOCAL_WINDOW_SIZE 64
#define TT_REQUEST_TIMEOUT 3 /* seconds we have to keep pending tt_req */ #define TT_REQUEST_TIMEOUT 3 /* seconds we have to keep pending tt_req */
...@@ -62,6 +62,8 @@ ...@@ -62,6 +62,8 @@
#define NO_FLAGS 0 #define NO_FLAGS 0
#define NULL_IFINDEX 0 /* dummy ifindex used to avoid iface checks */
#define NUM_WORDS (TQ_LOCAL_WINDOW_SIZE / WORD_BIT_SIZE) #define NUM_WORDS (TQ_LOCAL_WINDOW_SIZE / WORD_BIT_SIZE)
#define LOG_BUF_LEN 8192 /* has to be a power of 2 */ #define LOG_BUF_LEN 8192 /* has to be a power of 2 */
...@@ -133,7 +135,7 @@ enum dbg_level { ...@@ -133,7 +135,7 @@ enum dbg_level {
#include <linux/mutex.h> /* mutex */ #include <linux/mutex.h> /* mutex */
#include <linux/module.h> /* needed by all modules */ #include <linux/module.h> /* needed by all modules */
#include <linux/netdevice.h> /* netdevice */ #include <linux/netdevice.h> /* netdevice */
#include <linux/etherdevice.h> /* ethernet address classifaction */ #include <linux/etherdevice.h> /* ethernet address classification */
#include <linux/if_ether.h> /* ethernet header */ #include <linux/if_ether.h> /* ethernet header */
#include <linux/poll.h> /* poll_table */ #include <linux/poll.h> /* poll_table */
#include <linux/kthread.h> /* kernel threads */ #include <linux/kthread.h> /* kernel threads */
......
...@@ -252,7 +252,7 @@ struct orig_node *get_orig_node(struct bat_priv *bat_priv, const uint8_t *addr) ...@@ -252,7 +252,7 @@ struct orig_node *get_orig_node(struct bat_priv *bat_priv, const uint8_t *addr)
hash_added = hash_add(bat_priv->orig_hash, compare_orig, hash_added = hash_add(bat_priv->orig_hash, compare_orig,
choose_orig, orig_node, &orig_node->hash_entry); choose_orig, orig_node, &orig_node->hash_entry);
if (hash_added < 0) if (hash_added != 0)
goto free_bcast_own_sum; goto free_bcast_own_sum;
return orig_node; return orig_node;
......
...@@ -84,6 +84,7 @@ enum tt_query_flags { ...@@ -84,6 +84,7 @@ enum tt_query_flags {
enum tt_client_flags { enum tt_client_flags {
TT_CLIENT_DEL = 1 << 0, TT_CLIENT_DEL = 1 << 0,
TT_CLIENT_ROAM = 1 << 1, TT_CLIENT_ROAM = 1 << 1,
TT_CLIENT_WIFI = 1 << 2,
TT_CLIENT_NOPURGE = 1 << 8, TT_CLIENT_NOPURGE = 1 << 8,
TT_CLIENT_NEW = 1 << 9, TT_CLIENT_NEW = 1 << 9,
TT_CLIENT_PENDING = 1 << 10 TT_CLIENT_PENDING = 1 << 10
......
...@@ -64,66 +64,6 @@ void slide_own_bcast_window(struct hard_iface *hard_iface) ...@@ -64,66 +64,6 @@ void slide_own_bcast_window(struct hard_iface *hard_iface)
} }
} }
static void update_transtable(struct bat_priv *bat_priv,
struct orig_node *orig_node,
const unsigned char *tt_buff,
uint8_t tt_num_changes, uint8_t ttvn,
uint16_t tt_crc)
{
uint8_t orig_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
bool full_table = true;
/* the ttvn increased by one -> we can apply the attached changes */
if (ttvn - orig_ttvn == 1) {
/* the OGM could not contain the changes because they were too
* many to fit in one frame or because they have already been
* sent TT_OGM_APPEND_MAX times. In this case send a tt
* request */
if (!tt_num_changes) {
full_table = false;
goto request_table;
}
tt_update_changes(bat_priv, orig_node, tt_num_changes, ttvn,
(struct tt_change *)tt_buff);
/* Even if we received the crc into the OGM, we prefer
* to recompute it to spot any possible inconsistency
* in the global table */
orig_node->tt_crc = tt_global_crc(bat_priv, orig_node);
/* The ttvn alone is not enough to guarantee consistency
* because a single value could repesent different states
* (due to the wrap around). Thus a node has to check whether
* the resulting table (after applying the changes) is still
* consistent or not. E.g. a node could disconnect while its
* ttvn is X and reconnect on ttvn = X + TTVN_MAX: in this case
* checking the CRC value is mandatory to detect the
* inconsistency */
if (orig_node->tt_crc != tt_crc)
goto request_table;
/* Roaming phase is over: tables are in sync again. I can
* unset the flag */
orig_node->tt_poss_change = false;
} else {
/* if we missed more than one change or our tables are not
* in sync anymore -> request fresh tt data */
if (ttvn != orig_ttvn || orig_node->tt_crc != tt_crc) {
request_table:
bat_dbg(DBG_TT, bat_priv, "TT inconsistency for %pM. "
"Need to retrieve the correct information "
"(ttvn: %u last_ttvn: %u crc: %u last_crc: "
"%u num_changes: %u)\n", orig_node->orig, ttvn,
orig_ttvn, tt_crc, orig_node->tt_crc,
tt_num_changes);
send_tt_request(bat_priv, orig_node, ttvn, tt_crc,
full_table);
return;
}
}
}
static void update_route(struct bat_priv *bat_priv, static void update_route(struct bat_priv *bat_priv,
struct orig_node *orig_node, struct orig_node *orig_node,
struct neigh_node *neigh_node) struct neigh_node *neigh_node)
...@@ -228,7 +168,7 @@ static int is_bidirectional_neigh(struct orig_node *orig_node, ...@@ -228,7 +168,7 @@ static int is_bidirectional_neigh(struct orig_node *orig_node,
if (!neigh_node) if (!neigh_node)
goto out; goto out;
/* if orig_node is direct neighbour update neigh_node last_valid */ /* if orig_node is direct neighbor update neigh_node last_valid */
if (orig_node == orig_neigh_node) if (orig_node == orig_neigh_node)
neigh_node->last_valid = jiffies; neigh_node->last_valid = jiffies;
...@@ -473,7 +413,7 @@ static void update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node, ...@@ -473,7 +413,7 @@ static void update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node,
if (router && (router->tq_avg > neigh_node->tq_avg)) if (router && (router->tq_avg > neigh_node->tq_avg))
goto update_tt; goto update_tt;
/* if the TQ is the same and the link not more symetric we /* if the TQ is the same and the link not more symmetric we
* won't consider it either */ * won't consider it either */
if (router && (neigh_node->tq_avg == router->tq_avg)) { if (router && (neigh_node->tq_avg == router->tq_avg)) {
orig_node_tmp = router->orig_node; orig_node_tmp = router->orig_node;
...@@ -500,10 +440,9 @@ static void update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node, ...@@ -500,10 +440,9 @@ static void update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node,
if (((batman_packet->orig != ethhdr->h_source) && if (((batman_packet->orig != ethhdr->h_source) &&
(batman_packet->ttl > 2)) || (batman_packet->ttl > 2)) ||
(batman_packet->flags & PRIMARIES_FIRST_HOP)) (batman_packet->flags & PRIMARIES_FIRST_HOP))
update_transtable(bat_priv, orig_node, tt_buff, tt_update_orig(bat_priv, orig_node, tt_buff,
batman_packet->tt_num_changes, batman_packet->tt_num_changes,
batman_packet->ttvn, batman_packet->ttvn, batman_packet->tt_crc);
batman_packet->tt_crc);
if (orig_node->gw_flags != batman_packet->gw_flags) if (orig_node->gw_flags != batman_packet->gw_flags)
gw_node_update(bat_priv, orig_node, batman_packet->gw_flags); gw_node_update(bat_priv, orig_node, batman_packet->gw_flags);
...@@ -1243,7 +1182,7 @@ int recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if) ...@@ -1243,7 +1182,7 @@ int recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if)
} }
break; break;
case TT_RESPONSE: case TT_RESPONSE:
/* packet needs to be linearised to access the TT changes */ /* packet needs to be linearized to access the TT changes */
if (skb_linearize(skb) < 0) if (skb_linearize(skb) < 0)
goto out; goto out;
...@@ -1300,7 +1239,7 @@ int recv_roam_adv(struct sk_buff *skb, struct hard_iface *recv_if) ...@@ -1300,7 +1239,7 @@ int recv_roam_adv(struct sk_buff *skb, struct hard_iface *recv_if)
roam_adv_packet->client); roam_adv_packet->client);
tt_global_add(bat_priv, orig_node, roam_adv_packet->client, tt_global_add(bat_priv, orig_node, roam_adv_packet->client,
atomic_read(&orig_node->last_ttvn) + 1, true); atomic_read(&orig_node->last_ttvn) + 1, true, false);
/* Roaming phase starts: I have new information but the ttvn has not /* Roaming phase starts: I have new information but the ttvn has not
* been incremented yet. This flag will make me check all the incoming * been incremented yet. This flag will make me check all the incoming
...@@ -1536,7 +1475,7 @@ static int check_unicast_ttvn(struct bat_priv *bat_priv, ...@@ -1536,7 +1475,7 @@ static int check_unicast_ttvn(struct bat_priv *bat_priv,
ethhdr = (struct ethhdr *)(skb->data + ethhdr = (struct ethhdr *)(skb->data +
sizeof(struct unicast_packet)); sizeof(struct unicast_packet));
orig_node = transtable_search(bat_priv, ethhdr->h_dest); orig_node = transtable_search(bat_priv, NULL, ethhdr->h_dest);
if (!orig_node) { if (!orig_node) {
if (!is_my_client(bat_priv, ethhdr->h_dest)) if (!is_my_client(bat_priv, ethhdr->h_dest))
......
...@@ -135,7 +135,7 @@ static void send_packet_to_if(struct forw_packet *forw_packet, ...@@ -135,7 +135,7 @@ static void send_packet_to_if(struct forw_packet *forw_packet,
"Forwarding")); "Forwarding"));
bat_dbg(DBG_BATMAN, bat_priv, bat_dbg(DBG_BATMAN, bat_priv,
"%s %spacket (originator %pM, seqno %d, TQ %d, TTL %d," "%s %spacket (originator %pM, seqno %d, TQ %d, TTL %d,"
" IDF %s, hvn %d) on interface %s [%pM]\n", " IDF %s, ttvn %d) on interface %s [%pM]\n",
fwd_str, (packet_num > 0 ? "aggregated " : ""), fwd_str, (packet_num > 0 ? "aggregated " : ""),
batman_packet->orig, ntohl(batman_packet->seqno), batman_packet->orig, ntohl(batman_packet->seqno),
batman_packet->tq, batman_packet->ttl, batman_packet->tq, batman_packet->ttl,
...@@ -313,7 +313,7 @@ void schedule_own_packet(struct hard_iface *hard_iface) ...@@ -313,7 +313,7 @@ void schedule_own_packet(struct hard_iface *hard_iface)
prepare_packet_buffer(bat_priv, hard_iface); prepare_packet_buffer(bat_priv, hard_iface);
} }
/* if the changes have been sent enough times */ /* if the changes have been sent often enough */
if (!atomic_dec_not_zero(&bat_priv->tt_ogm_append_cnt)) if (!atomic_dec_not_zero(&bat_priv->tt_ogm_append_cnt))
reset_packet_buffer(bat_priv, hard_iface); reset_packet_buffer(bat_priv, hard_iface);
} }
...@@ -454,7 +454,7 @@ static void _add_bcast_packet_to_list(struct bat_priv *bat_priv, ...@@ -454,7 +454,7 @@ static void _add_bcast_packet_to_list(struct bat_priv *bat_priv,
} }
/* add a broadcast packet to the queue and setup timers. broadcast packets /* add a broadcast packet to the queue and setup timers. broadcast packets
* are sent multiple times to increase probability for beeing received. * are sent multiple times to increase probability for being received.
* *
* This function returns NETDEV_TX_OK on success and NETDEV_TX_BUSY on * This function returns NETDEV_TX_OK on success and NETDEV_TX_BUSY on
* errors. * errors.
...@@ -612,7 +612,7 @@ void purge_outstanding_packets(struct bat_priv *bat_priv, ...@@ -612,7 +612,7 @@ void purge_outstanding_packets(struct bat_priv *bat_priv,
&bat_priv->forw_bcast_list, list) { &bat_priv->forw_bcast_list, list) {
/** /**
* if purge_outstanding_packets() was called with an argmument * if purge_outstanding_packets() was called with an argument
* we delete only packets belonging to the given interface * we delete only packets belonging to the given interface
*/ */
if ((hard_iface) && if ((hard_iface) &&
...@@ -641,7 +641,7 @@ void purge_outstanding_packets(struct bat_priv *bat_priv, ...@@ -641,7 +641,7 @@ void purge_outstanding_packets(struct bat_priv *bat_priv,
&bat_priv->forw_bat_list, list) { &bat_priv->forw_bat_list, list) {
/** /**
* if purge_outstanding_packets() was called with an argmument * if purge_outstanding_packets() was called with an argument
* we delete only packets belonging to the given interface * we delete only packets belonging to the given interface
*/ */
if ((hard_iface) && if ((hard_iface) &&
......
...@@ -532,11 +532,11 @@ static int interface_set_mac_addr(struct net_device *dev, void *p) ...@@ -532,11 +532,11 @@ static int 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;
/* only modify transtable if it has been initialised before */ /* only modify transtable if it has been initialized before */
if (atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE) { if (atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE) {
tt_local_remove(bat_priv, dev->dev_addr, tt_local_remove(bat_priv, dev->dev_addr,
"mac address changed", false); "mac address changed", false);
tt_local_add(dev, addr->sa_data); tt_local_add(dev, addr->sa_data, NULL_IFINDEX);
} }
memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
...@@ -595,9 +595,10 @@ static int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) ...@@ -595,9 +595,10 @@ static int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
goto dropped; goto dropped;
/* Register the client MAC in the transtable */ /* Register the client MAC in the transtable */
tt_local_add(soft_iface, ethhdr->h_source); tt_local_add(soft_iface, ethhdr->h_source, skb->skb_iif);
orig_node = transtable_search(bat_priv, ethhdr->h_dest); orig_node = transtable_search(bat_priv, ethhdr->h_source,
ethhdr->h_dest);
if (is_multicast_ether_addr(ethhdr->h_dest) || if (is_multicast_ether_addr(ethhdr->h_dest) ||
(orig_node && orig_node->gw_flags)) { (orig_node && orig_node->gw_flags)) {
ret = gw_is_target(bat_priv, skb, orig_node); ret = gw_is_target(bat_priv, skb, orig_node);
...@@ -739,6 +740,9 @@ void interface_rx(struct net_device *soft_iface, ...@@ -739,6 +740,9 @@ void interface_rx(struct net_device *soft_iface,
soft_iface->last_rx = jiffies; soft_iface->last_rx = jiffies;
if (is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest))
goto dropped;
netif_rx(skb); netif_rx(skb);
goto out; goto out;
...@@ -812,6 +816,7 @@ struct net_device *softif_create(const char *name) ...@@ -812,6 +816,7 @@ struct net_device *softif_create(const char *name)
atomic_set(&bat_priv->aggregated_ogms, 1); atomic_set(&bat_priv->aggregated_ogms, 1);
atomic_set(&bat_priv->bonding, 0); atomic_set(&bat_priv->bonding, 0);
atomic_set(&bat_priv->ap_isolation, 0);
atomic_set(&bat_priv->vis_mode, VIS_TYPE_CLIENT_UPDATE); atomic_set(&bat_priv->vis_mode, VIS_TYPE_CLIENT_UPDATE);
atomic_set(&bat_priv->gw_mode, GW_MODE_OFF); atomic_set(&bat_priv->gw_mode, GW_MODE_OFF);
atomic_set(&bat_priv->gw_sel_class, 20); atomic_set(&bat_priv->gw_sel_class, 20);
......
This diff is collapsed.
...@@ -26,15 +26,16 @@ int tt_len(int changes_num); ...@@ -26,15 +26,16 @@ int tt_len(int changes_num);
int tt_changes_fill_buffer(struct bat_priv *bat_priv, int tt_changes_fill_buffer(struct bat_priv *bat_priv,
unsigned char *buff, int buff_len); unsigned char *buff, int buff_len);
int tt_init(struct bat_priv *bat_priv); int tt_init(struct bat_priv *bat_priv);
void tt_local_add(struct net_device *soft_iface, const uint8_t *addr); void tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
int ifindex);
void tt_local_remove(struct bat_priv *bat_priv, void tt_local_remove(struct bat_priv *bat_priv,
const uint8_t *addr, const char *message, bool roaming); const uint8_t *addr, const char *message, bool roaming);
int tt_local_seq_print_text(struct seq_file *seq, void *offset); int tt_local_seq_print_text(struct seq_file *seq, void *offset);
void tt_global_add_orig(struct bat_priv *bat_priv, struct orig_node *orig_node, void tt_global_add_orig(struct bat_priv *bat_priv, struct orig_node *orig_node,
const unsigned char *tt_buff, int tt_buff_len); const unsigned char *tt_buff, int tt_buff_len);
int tt_global_add(struct bat_priv *bat_priv, int tt_global_add(struct bat_priv *bat_priv, struct orig_node *orig_node,
struct orig_node *orig_node, const unsigned char *addr, const unsigned char *addr, uint8_t ttvn, bool roaming,
uint8_t ttvn, bool roaming); bool wifi);
int tt_global_seq_print_text(struct seq_file *seq, void *offset); int tt_global_seq_print_text(struct seq_file *seq, void *offset);
void tt_global_del_orig(struct bat_priv *bat_priv, void tt_global_del_orig(struct bat_priv *bat_priv,
struct orig_node *orig_node, const char *message); struct orig_node *orig_node, const char *message);
...@@ -42,25 +43,23 @@ void tt_global_del(struct bat_priv *bat_priv, ...@@ -42,25 +43,23 @@ void tt_global_del(struct bat_priv *bat_priv,
struct orig_node *orig_node, const unsigned char *addr, struct orig_node *orig_node, const unsigned char *addr,
const char *message, bool roaming); const char *message, bool roaming);
struct orig_node *transtable_search(struct bat_priv *bat_priv, struct orig_node *transtable_search(struct bat_priv *bat_priv,
const uint8_t *addr); const uint8_t *src, const uint8_t *addr);
void tt_save_orig_buffer(struct bat_priv *bat_priv, struct orig_node *orig_node, void tt_save_orig_buffer(struct bat_priv *bat_priv, struct orig_node *orig_node,
const unsigned char *tt_buff, uint8_t tt_num_changes); const unsigned char *tt_buff, uint8_t tt_num_changes);
uint16_t tt_local_crc(struct bat_priv *bat_priv); uint16_t tt_local_crc(struct bat_priv *bat_priv);
uint16_t tt_global_crc(struct bat_priv *bat_priv, struct orig_node *orig_node); uint16_t tt_global_crc(struct bat_priv *bat_priv, struct orig_node *orig_node);
void tt_free(struct bat_priv *bat_priv); void tt_free(struct bat_priv *bat_priv);
int send_tt_request(struct bat_priv *bat_priv,
struct orig_node *dst_orig_node, uint8_t hvn,
uint16_t tt_crc, bool full_table);
bool send_tt_response(struct bat_priv *bat_priv, bool send_tt_response(struct bat_priv *bat_priv,
struct tt_query_packet *tt_request); struct tt_query_packet *tt_request);
void tt_update_changes(struct bat_priv *bat_priv, struct orig_node *orig_node,
uint16_t tt_num_changes, uint8_t ttvn,
struct tt_change *tt_change);
bool is_my_client(struct bat_priv *bat_priv, const uint8_t *addr); bool is_my_client(struct bat_priv *bat_priv, const uint8_t *addr);
void handle_tt_response(struct bat_priv *bat_priv, void handle_tt_response(struct bat_priv *bat_priv,
struct tt_query_packet *tt_response); struct tt_query_packet *tt_response);
void send_roam_adv(struct bat_priv *bat_priv, uint8_t *client, void send_roam_adv(struct bat_priv *bat_priv, uint8_t *client,
struct orig_node *orig_node); struct orig_node *orig_node);
void tt_commit_changes(struct bat_priv *bat_priv); void tt_commit_changes(struct bat_priv *bat_priv);
bool is_ap_isolated(struct bat_priv *bat_priv, uint8_t *src, uint8_t *dst);
void tt_update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node,
const unsigned char *tt_buff, uint8_t tt_num_changes,
uint8_t ttvn, uint16_t tt_crc);
#endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */ #endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */
...@@ -57,7 +57,7 @@ struct hard_iface { ...@@ -57,7 +57,7 @@ struct hard_iface {
* @batman_seqno_reset: time when the batman seqno window was reset * @batman_seqno_reset: time when the batman seqno window was reset
* @gw_flags: flags related to gateway class * @gw_flags: flags related to gateway class
* @flags: for now only VIS_SERVER flag * @flags: for now only VIS_SERVER flag
* @last_real_seqno: last and best known squence number * @last_real_seqno: last and best known sequence number
* @last_ttl: ttl of last received packet * @last_ttl: ttl of last received packet
* @last_bcast_seqno: last broadcast sequence number received by this host * @last_bcast_seqno: last broadcast sequence number received by this host
* *
...@@ -146,6 +146,7 @@ struct bat_priv { ...@@ -146,6 +146,7 @@ struct bat_priv {
atomic_t aggregated_ogms; /* boolean */ atomic_t aggregated_ogms; /* boolean */
atomic_t bonding; /* boolean */ atomic_t bonding; /* boolean */
atomic_t fragmentation; /* boolean */ atomic_t fragmentation; /* boolean */
atomic_t ap_isolation; /* boolean */
atomic_t vis_mode; /* VIS_TYPE_* */ atomic_t vis_mode; /* VIS_TYPE_* */
atomic_t gw_mode; /* GW_MODE_* */ atomic_t gw_mode; /* GW_MODE_* */
atomic_t gw_sel_class; /* uint */ atomic_t gw_sel_class; /* uint */
...@@ -156,7 +157,7 @@ struct bat_priv { ...@@ -156,7 +157,7 @@ struct bat_priv {
atomic_t bcast_seqno; atomic_t bcast_seqno;
atomic_t bcast_queue_left; atomic_t bcast_queue_left;
atomic_t batman_queue_left; atomic_t batman_queue_left;
atomic_t ttvn; /* tranlation table version number */ atomic_t ttvn; /* translation table version number */
atomic_t tt_ogm_append_cnt; atomic_t tt_ogm_append_cnt;
atomic_t tt_local_changes; /* changes registered in a OGM interval */ atomic_t tt_local_changes; /* changes registered in a OGM interval */
/* The tt_poss_change flag is used to detect an ongoing roaming phase. /* The tt_poss_change flag is used to detect an ongoing roaming phase.
......
...@@ -299,8 +299,10 @@ int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv) ...@@ -299,8 +299,10 @@ int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv)
goto find_router; goto find_router;
} }
/* check for tt host - increases orig_node refcount */ /* check for tt host - increases orig_node refcount.
orig_node = transtable_search(bat_priv, ethhdr->h_dest); * returns NULL in case of AP isolation */
orig_node = transtable_search(bat_priv, ethhdr->h_source,
ethhdr->h_dest);
find_router: find_router:
/** /**
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#include "packet.h" #include "packet.h"
#define FRAG_TIMEOUT 10000 /* purge frag list entrys after time in ms */ #define FRAG_TIMEOUT 10000 /* purge frag list entries after time in ms */
#define FRAG_BUFFER_SIZE 6 /* number of list elements in buffer */ #define FRAG_BUFFER_SIZE 6 /* number of list elements in buffer */
int frag_reassemble_skb(struct sk_buff *skb, struct bat_priv *bat_priv, int frag_reassemble_skb(struct sk_buff *skb, struct bat_priv *bat_priv,
......
...@@ -131,7 +131,7 @@ static void vis_data_insert_interface(const uint8_t *interface, ...@@ -131,7 +131,7 @@ static void vis_data_insert_interface(const uint8_t *interface,
return; return;
} }
/* its a new address, add it to the list */ /* it's a new address, add it to the list */
entry = kmalloc(sizeof(*entry), GFP_ATOMIC); entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
if (!entry) if (!entry)
return; return;
...@@ -465,7 +465,7 @@ static struct vis_info *add_packet(struct bat_priv *bat_priv, ...@@ -465,7 +465,7 @@ static struct vis_info *add_packet(struct bat_priv *bat_priv,
/* try to add it */ /* try to add it */
hash_added = hash_add(bat_priv->vis_hash, vis_info_cmp, vis_info_choose, hash_added = hash_add(bat_priv->vis_hash, vis_info_cmp, vis_info_choose,
info, &info->hash_entry); info, &info->hash_entry);
if (hash_added < 0) { if (hash_added != 0) {
/* did not work (for some reason) */ /* did not work (for some reason) */
kref_put(&info->refcount, free_info); kref_put(&info->refcount, free_info);
info = NULL; info = NULL;
...@@ -920,7 +920,7 @@ int vis_init(struct bat_priv *bat_priv) ...@@ -920,7 +920,7 @@ int vis_init(struct bat_priv *bat_priv)
hash_added = hash_add(bat_priv->vis_hash, vis_info_cmp, vis_info_choose, hash_added = hash_add(bat_priv->vis_hash, vis_info_cmp, vis_info_choose,
bat_priv->my_vis_info, bat_priv->my_vis_info,
&bat_priv->my_vis_info->hash_entry); &bat_priv->my_vis_info->hash_entry);
if (hash_added < 0) { if (hash_added != 0) {
pr_err("Can't add own vis packet into hash\n"); pr_err("Can't add own vis packet into hash\n");
/* not in hash, need to remove it manually. */ /* not in hash, need to remove it manually. */
kref_put(&bat_priv->my_vis_info->refcount, free_info); kref_put(&bat_priv->my_vis_info->refcount, free_info);
......
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