summaryrefslogtreecommitdiff
path: root/net/batman-adv
diff options
context:
space:
mode:
Diffstat (limited to 'net/batman-adv')
-rw-r--r--net/batman-adv/aggregation.c54
-rw-r--r--net/batman-adv/aggregation.h9
-rw-r--r--net/batman-adv/bat_debugfs.c15
-rw-r--r--net/batman-adv/bat_sysfs.c45
-rw-r--r--net/batman-adv/bitarray.c6
-rw-r--r--net/batman-adv/bitarray.h6
-rw-r--r--net/batman-adv/gateway_client.c80
-rw-r--r--net/batman-adv/gateway_common.c19
-rw-r--r--net/batman-adv/hard-interface.c134
-rw-r--r--net/batman-adv/hard-interface.h38
-rw-r--r--net/batman-adv/hash.c7
-rw-r--r--net/batman-adv/hash.h6
-rw-r--r--net/batman-adv/icmp_socket.c23
-rw-r--r--net/batman-adv/main.c24
-rw-r--r--net/batman-adv/main.h87
-rw-r--r--net/batman-adv/originator.c66
-rw-r--r--net/batman-adv/originator.h14
-rw-r--r--net/batman-adv/packet.h52
-rw-r--r--net/batman-adv/ring_buffer.c4
-rw-r--r--net/batman-adv/ring_buffer.h2
-rw-r--r--net/batman-adv/routing.c249
-rw-r--r--net/batman-adv/routing.h14
-rw-r--r--net/batman-adv/send.c95
-rw-r--r--net/batman-adv/send.h14
-rw-r--r--net/batman-adv/soft-interface.c504
-rw-r--r--net/batman-adv/soft-interface.h4
-rw-r--r--net/batman-adv/translation-table.c496
-rw-r--r--net/batman-adv/translation-table.h33
-rw-r--r--net/batman-adv/types.h59
-rw-r--r--net/batman-adv/unicast.c48
-rw-r--r--net/batman-adv/unicast.h8
-rw-r--r--net/batman-adv/vis.c146
32 files changed, 1343 insertions, 1018 deletions
diff --git a/net/batman-adv/aggregation.c b/net/batman-adv/aggregation.c
index af45d6b2031f..4080970ade7d 100644
--- a/net/batman-adv/aggregation.c
+++ b/net/batman-adv/aggregation.c
@@ -23,20 +23,21 @@
#include "aggregation.h"
#include "send.h"
#include "routing.h"
+#include "hard-interface.h"
-/* calculate the size of the hna information for a given packet */
-static int hna_len(struct batman_packet *batman_packet)
+/* calculate the size of the tt information for a given packet */
+static int tt_len(const struct batman_packet *batman_packet)
{
- return batman_packet->num_hna * ETH_ALEN;
+ return batman_packet->num_tt * ETH_ALEN;
}
/* return true if new_packet can be aggregated with forw_packet */
-static bool can_aggregate_with(struct batman_packet *new_batman_packet,
+static bool can_aggregate_with(const struct batman_packet *new_batman_packet,
int packet_len,
unsigned long send_time,
bool directlink,
- struct hard_iface *if_incoming,
- struct forw_packet *forw_packet)
+ const struct hard_iface *if_incoming,
+ const struct forw_packet *forw_packet)
{
struct batman_packet *batman_packet =
(struct batman_packet *)forw_packet->skb->data;
@@ -95,10 +96,10 @@ static bool can_aggregate_with(struct batman_packet *new_batman_packet,
return false;
}
-#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0)
/* create a new aggregated packet and add this packet to it */
-static void new_aggregated_packet(unsigned char *packet_buff, int packet_len,
- unsigned long send_time, bool direct_link,
+static void new_aggregated_packet(const unsigned char *packet_buff,
+ int packet_len, unsigned long send_time,
+ bool direct_link,
struct hard_iface *if_incoming,
int own_packet)
{
@@ -106,20 +107,23 @@ static void new_aggregated_packet(unsigned char *packet_buff, int packet_len,
struct forw_packet *forw_packet_aggr;
unsigned char *skb_buff;
+ if (!atomic_inc_not_zero(&if_incoming->refcount))
+ return;
+
/* own packet should always be scheduled */
if (!own_packet) {
if (!atomic_dec_not_zero(&bat_priv->batman_queue_left)) {
bat_dbg(DBG_BATMAN, bat_priv,
"batman packet queue full\n");
- return;
+ goto out;
}
}
- forw_packet_aggr = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC);
+ forw_packet_aggr = kmalloc(sizeof(*forw_packet_aggr), GFP_ATOMIC);
if (!forw_packet_aggr) {
if (!own_packet)
atomic_inc(&bat_priv->batman_queue_left);
- return;
+ goto out;
}
if ((atomic_read(&bat_priv->aggregated_ogms)) &&
@@ -134,7 +138,7 @@ static void new_aggregated_packet(unsigned char *packet_buff, int packet_len,
if (!own_packet)
atomic_inc(&bat_priv->batman_queue_left);
kfree(forw_packet_aggr);
- return;
+ goto out;
}
skb_reserve(forw_packet_aggr->skb, sizeof(struct ethhdr));
@@ -147,7 +151,7 @@ static void new_aggregated_packet(unsigned char *packet_buff, int packet_len,
forw_packet_aggr->own = own_packet;
forw_packet_aggr->if_incoming = if_incoming;
forw_packet_aggr->num_packets = 0;
- forw_packet_aggr->direct_link_flags = 0;
+ forw_packet_aggr->direct_link_flags = NO_FLAGS;
forw_packet_aggr->send_time = send_time;
/* save packet direct link flag status */
@@ -165,12 +169,15 @@ static void new_aggregated_packet(unsigned char *packet_buff, int packet_len,
queue_delayed_work(bat_event_workqueue,
&forw_packet_aggr->delayed_work,
send_time - jiffies);
+
+ return;
+out:
+ hardif_free_ref(if_incoming);
}
/* aggregate a new packet into the existing aggregation */
static void aggregate(struct forw_packet *forw_packet_aggr,
- unsigned char *packet_buff,
- int packet_len,
+ const unsigned char *packet_buff, int packet_len,
bool direct_link)
{
unsigned char *skb_buff;
@@ -246,12 +253,13 @@ void add_bat_packet_to_list(struct bat_priv *bat_priv,
}
/* unpack the aggregated packets and process them one by one */
-void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff,
- int packet_len, struct hard_iface *if_incoming)
+void receive_aggr_bat_packet(const struct ethhdr *ethhdr,
+ unsigned char *packet_buff, int packet_len,
+ struct hard_iface *if_incoming)
{
struct batman_packet *batman_packet;
int buff_pos = 0;
- unsigned char *hna_buff;
+ unsigned char *tt_buff;
batman_packet = (struct batman_packet *)packet_buff;
@@ -260,14 +268,14 @@ void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff,
orig_interval. */
batman_packet->seqno = ntohl(batman_packet->seqno);
- hna_buff = packet_buff + buff_pos + BAT_PACKET_LEN;
+ tt_buff = packet_buff + buff_pos + BAT_PACKET_LEN;
receive_bat_packet(ethhdr, batman_packet,
- hna_buff, hna_len(batman_packet),
+ tt_buff, tt_len(batman_packet),
if_incoming);
- buff_pos += BAT_PACKET_LEN + hna_len(batman_packet);
+ buff_pos += BAT_PACKET_LEN + tt_len(batman_packet);
batman_packet = (struct batman_packet *)
(packet_buff + buff_pos);
} while (aggregated_packet(buff_pos, packet_len,
- batman_packet->num_hna));
+ batman_packet->num_tt));
}
diff --git a/net/batman-adv/aggregation.h b/net/batman-adv/aggregation.h
index 062204289d1f..fedeb8d0e13f 100644
--- a/net/batman-adv/aggregation.h
+++ b/net/batman-adv/aggregation.h
@@ -25,9 +25,9 @@
#include "main.h"
/* is there another aggregated packet here? */
-static inline int aggregated_packet(int buff_pos, int packet_len, int num_hna)
+static inline int aggregated_packet(int buff_pos, int packet_len, int num_tt)
{
- int next_buff_pos = buff_pos + BAT_PACKET_LEN + (num_hna * ETH_ALEN);
+ int next_buff_pos = buff_pos + BAT_PACKET_LEN + (num_tt * ETH_ALEN);
return (next_buff_pos <= packet_len) &&
(next_buff_pos <= MAX_AGGREGATION_BYTES);
@@ -37,7 +37,8 @@ void add_bat_packet_to_list(struct bat_priv *bat_priv,
unsigned char *packet_buff, int packet_len,
struct hard_iface *if_incoming, char own_packet,
unsigned long send_time);
-void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff,
- int packet_len, struct hard_iface *if_incoming);
+void receive_aggr_bat_packet(const struct ethhdr *ethhdr,
+ unsigned char *packet_buff, int packet_len,
+ struct hard_iface *if_incoming);
#endif /* _NET_BATMAN_ADV_AGGREGATION_H_ */
diff --git a/net/batman-adv/bat_debugfs.c b/net/batman-adv/bat_debugfs.c
index 0e9d43509935..d0af9bf69e46 100644
--- a/net/batman-adv/bat_debugfs.c
+++ b/net/batman-adv/bat_debugfs.c
@@ -50,7 +50,8 @@ static void emit_log_char(struct debug_log *debug_log, char c)
debug_log->log_start = debug_log->log_end - log_buff_len;
}
-static int fdebug_log(struct debug_log *debug_log, char *fmt, ...)
+__printf(2, 3)
+static int fdebug_log(struct debug_log *debug_log, const char *fmt, ...)
{
va_list args;
static char debug_log_buf[256];
@@ -74,14 +75,14 @@ static int fdebug_log(struct debug_log *debug_log, char *fmt, ...)
return 0;
}
-int debug_log(struct bat_priv *bat_priv, char *fmt, ...)
+int debug_log(struct bat_priv *bat_priv, const char *fmt, ...)
{
va_list args;
char tmp_log_buf[256];
va_start(args, fmt);
vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args);
- fdebug_log(bat_priv->debug_log, "[%10u] %s",
+ fdebug_log(bat_priv->debug_log, "[%10lu] %s",
(jiffies / HZ), tmp_log_buf);
va_end(args);
@@ -114,7 +115,7 @@ static ssize_t log_read(struct file *file, char __user *buf,
!(debug_log->log_end - debug_log->log_start))
return -EAGAIN;
- if ((!buf) || (count < 0))
+ if (!buf)
return -EINVAL;
if (count == 0)
@@ -184,7 +185,7 @@ static int debug_log_setup(struct bat_priv *bat_priv)
if (!bat_priv->debug_dir)
goto err;
- bat_priv->debug_log = kzalloc(sizeof(struct debug_log), GFP_ATOMIC);
+ bat_priv->debug_log = kzalloc(sizeof(*bat_priv->debug_log), GFP_ATOMIC);
if (!bat_priv->debug_log)
goto err;
@@ -241,13 +242,13 @@ static int softif_neigh_open(struct inode *inode, struct file *file)
static int transtable_global_open(struct inode *inode, struct file *file)
{
struct net_device *net_dev = (struct net_device *)inode->i_private;
- return single_open(file, hna_global_seq_print_text, net_dev);
+ return single_open(file, tt_global_seq_print_text, net_dev);
}
static int transtable_local_open(struct inode *inode, struct file *file)
{
struct net_device *net_dev = (struct net_device *)inode->i_private;
- return single_open(file, hna_local_seq_print_text, net_dev);
+ return single_open(file, tt_local_seq_print_text, net_dev);
}
static int vis_data_open(struct inode *inode, struct file *file)
diff --git a/net/batman-adv/bat_sysfs.c b/net/batman-adv/bat_sysfs.c
index e449bf6353e0..924d5773da21 100644
--- a/net/batman-adv/bat_sysfs.c
+++ b/net/batman-adv/bat_sysfs.c
@@ -28,9 +28,17 @@
#include "gateway_client.h"
#include "vis.h"
-#define to_dev(obj) container_of(obj, struct device, kobj)
-#define kobj_to_netdev(obj) to_net_dev(to_dev(obj->parent))
-#define kobj_to_batpriv(obj) netdev_priv(kobj_to_netdev(obj))
+static struct net_device *kobj_to_netdev(struct kobject *obj)
+{
+ struct device *dev = container_of(obj->parent, struct device, kobj);
+ return to_net_dev(dev);
+}
+
+static struct bat_priv *kobj_to_batpriv(struct kobject *obj)
+{
+ struct net_device *net_dev = kobj_to_netdev(obj);
+ return netdev_priv(net_dev);
+}
/* Use this, if you have customized show and store functions */
#define BAT_ATTR(_name, _mode, _show, _store) \
@@ -96,7 +104,7 @@ ssize_t show_##_name(struct kobject *kobj, struct attribute *attr, \
static int store_bool_attr(char *buff, size_t count,
struct net_device *net_dev,
- char *attr_name, atomic_t *attr)
+ const char *attr_name, atomic_t *attr)
{
int enabled = -1;
@@ -138,16 +146,15 @@ static inline ssize_t __store_bool_attr(char *buff, size_t count,
{
int ret;
- ret = store_bool_attr(buff, count, net_dev, (char *)attr->name,
- attr_store);
+ ret = store_bool_attr(buff, count, net_dev, attr->name, attr_store);
if (post_func && ret)
post_func(net_dev);
return ret;
}
-static int store_uint_attr(char *buff, size_t count,
- struct net_device *net_dev, char *attr_name,
+static int store_uint_attr(const char *buff, size_t count,
+ struct net_device *net_dev, const char *attr_name,
unsigned int min, unsigned int max, atomic_t *attr)
{
unsigned long uint_val;
@@ -183,15 +190,15 @@ static int store_uint_attr(char *buff, size_t count,
return count;
}
-static inline ssize_t __store_uint_attr(char *buff, size_t count,
+static inline ssize_t __store_uint_attr(const char *buff, size_t count,
int min, int max,
void (*post_func)(struct net_device *),
- struct attribute *attr,
+ const struct attribute *attr,
atomic_t *attr_store, struct net_device *net_dev)
{
int ret;
- ret = store_uint_attr(buff, count, net_dev, (char *)attr->name,
+ ret = store_uint_attr(buff, count, net_dev, attr->name,
min, max, attr_store);
if (post_func && ret)
post_func(net_dev);
@@ -488,22 +495,24 @@ static ssize_t store_mesh_iface(struct kobject *kobj, struct attribute *attr,
(strncmp(hard_iface->soft_iface->name, buff, IFNAMSIZ) == 0))
goto out;
+ if (!rtnl_trylock()) {
+ ret = -ERESTARTSYS;
+ goto out;
+ }
+
if (status_tmp == IF_NOT_IN_USE) {
- rtnl_lock();
hardif_disable_interface(hard_iface);
- rtnl_unlock();
- goto out;
+ goto unlock;
}
/* if the interface already is in use */
- if (hard_iface->if_status != IF_NOT_IN_USE) {
- rtnl_lock();
+ if (hard_iface->if_status != IF_NOT_IN_USE)
hardif_disable_interface(hard_iface);
- rtnl_unlock();
- }
ret = hardif_enable_interface(hard_iface, buff);
+unlock:
+ rtnl_unlock();
out:
hardif_free_ref(hard_iface);
return ret;
diff --git a/net/batman-adv/bitarray.c b/net/batman-adv/bitarray.c
index ad2ca925b3e0..700ee4f7a945 100644
--- a/net/batman-adv/bitarray.c
+++ b/net/batman-adv/bitarray.c
@@ -26,7 +26,7 @@
/* returns true if the corresponding bit in the given seq_bits indicates true
* and curr_seqno is within range of last_seqno */
-uint8_t get_bit_status(unsigned long *seq_bits, uint32_t last_seqno,
+uint8_t get_bit_status(const unsigned long *seq_bits, uint32_t last_seqno,
uint32_t curr_seqno)
{
int32_t diff, word_offset, word_num;
@@ -130,7 +130,7 @@ static void bit_reset_window(unsigned long *seq_bits)
char bit_get_packet(void *priv, unsigned long *seq_bits,
int32_t seq_num_diff, int8_t set_mark)
{
- struct bat_priv *bat_priv = (struct bat_priv *)priv;
+ struct bat_priv *bat_priv = priv;
/* sequence number is slightly older. We already got a sequence number
* higher than this one, so we just mark it. */
@@ -190,7 +190,7 @@ char bit_get_packet(void *priv, unsigned long *seq_bits,
/* count the hamming weight, how many good packets did we receive? just count
* the 1's.
*/
-int bit_packet_count(unsigned long *seq_bits)
+int bit_packet_count(const unsigned long *seq_bits)
{
int i, hamming = 0;
diff --git a/net/batman-adv/bitarray.h b/net/batman-adv/bitarray.h
index 769c246d1fc1..e32eb2ddd2d2 100644
--- a/net/batman-adv/bitarray.h
+++ b/net/batman-adv/bitarray.h
@@ -26,8 +26,8 @@
/* returns true if the corresponding bit in the given seq_bits indicates true
* and curr_seqno is within range of last_seqno */
-uint8_t get_bit_status(unsigned long *seq_bits, uint32_t last_seqno,
- uint32_t curr_seqno);
+uint8_t get_bit_status(const unsigned long *seq_bits, uint32_t last_seqno,
+ uint32_t curr_seqno);
/* turn corresponding bit on, so we can remember that we got the packet */
void bit_mark(unsigned long *seq_bits, int32_t n);
@@ -39,6 +39,6 @@ char bit_get_packet(void *priv, unsigned long *seq_bits,
int32_t seq_num_diff, int8_t set_mark);
/* count the hamming weight, how many good packets did we receive? */
-int bit_packet_count(unsigned long *seq_bits);
+int bit_packet_count(const unsigned long *seq_bits);
#endif /* _NET_BATMAN_ADV_BITARRAY_H_ */
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c
index 2acd7a666bda..24aee561f3d8 100644
--- a/net/batman-adv/gateway_client.c
+++ b/net/batman-adv/gateway_client.c
@@ -29,18 +29,10 @@
#include <linux/udp.h>
#include <linux/if_vlan.h>
-static void gw_node_free_rcu(struct rcu_head *rcu)
-{
- struct gw_node *gw_node;
-
- gw_node = container_of(rcu, struct gw_node, rcu);
- kfree(gw_node);
-}
-
static void gw_node_free_ref(struct gw_node *gw_node)
{
if (atomic_dec_and_test(&gw_node->refcount))
- call_rcu(&gw_node->rcu, gw_node_free_rcu);
+ kfree_rcu(gw_node, rcu);
}
static struct gw_node *gw_get_selected_gw_node(struct bat_priv *bat_priv)
@@ -94,7 +86,7 @@ static void gw_select(struct bat_priv *bat_priv, struct gw_node *new_gw_node)
if (new_gw_node && !atomic_inc_not_zero(&new_gw_node->refcount))
new_gw_node = NULL;
- curr_gw_node = bat_priv->curr_gw;
+ curr_gw_node = rcu_dereference_protected(bat_priv->curr_gw, 1);
rcu_assign_pointer(bat_priv->curr_gw, new_gw_node);
if (curr_gw_node)
@@ -127,7 +119,7 @@ void gw_election(struct bat_priv *bat_priv)
return;
curr_gw = gw_get_selected_gw_node(bat_priv);
- if (!curr_gw)
+ if (curr_gw)
goto out;
rcu_read_lock();
@@ -281,11 +273,10 @@ static void gw_node_add(struct bat_priv *bat_priv,
struct gw_node *gw_node;
int down, up;
- gw_node = kmalloc(sizeof(struct gw_node), GFP_ATOMIC);
+ gw_node = kzalloc(sizeof(*gw_node), GFP_ATOMIC);
if (!gw_node)
return;
- memset(gw_node, 0, sizeof(struct gw_node));
INIT_HLIST_NODE(&gw_node->list);
gw_node->orig_node = orig_node;
atomic_set(&gw_node->refcount, 1);
@@ -310,9 +301,13 @@ void gw_node_update(struct bat_priv *bat_priv,
struct hlist_node *node;
struct gw_node *gw_node, *curr_gw;
+ /**
+ * Note: We don't need a NULL check here, since curr_gw never gets
+ * dereferenced. If curr_gw is NULL we also should not exit as we may
+ * have this gateway in our list (duplication check!) even though we
+ * have no currently selected gateway.
+ */
curr_gw = gw_get_selected_gw_node(bat_priv);
- if (!curr_gw)
- goto out;
rcu_read_lock();
hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) {
@@ -327,7 +322,7 @@ void gw_node_update(struct bat_priv *bat_priv,
gw_node->deleted = 0;
- if (new_gwflags == 0) {
+ if (new_gwflags == NO_FLAGS) {
gw_node->deleted = jiffies;
bat_dbg(DBG_BATMAN, bat_priv,
"Gateway %pM removed from gateway list\n",
@@ -340,7 +335,7 @@ void gw_node_update(struct bat_priv *bat_priv,
goto unlock;
}
- if (new_gwflags == 0)
+ if (new_gwflags == NO_FLAGS)
goto unlock;
gw_node_add(bat_priv, orig_node, new_gwflags);
@@ -350,14 +345,14 @@ deselect:
gw_deselect(bat_priv);
unlock:
rcu_read_unlock();
-out:
+
if (curr_gw)
gw_node_free_ref(curr_gw);
}
void gw_node_delete(struct bat_priv *bat_priv, struct orig_node *orig_node)
{
- return gw_node_update(bat_priv, orig_node, 0);
+ gw_node_update(bat_priv, orig_node, 0);
}
void gw_node_purge(struct bat_priv *bat_priv)
@@ -398,8 +393,8 @@ void gw_node_purge(struct bat_priv *bat_priv)
/**
* fails if orig_node has no router
*/
-static int _write_buffer_text(struct bat_priv *bat_priv,
- struct seq_file *seq, struct gw_node *gw_node)
+static int _write_buffer_text(struct bat_priv *bat_priv, struct seq_file *seq,
+ const struct gw_node *gw_node)
{
struct gw_node *curr_gw;
struct neigh_node *router;
@@ -435,30 +430,32 @@ int gw_client_seq_print_text(struct seq_file *seq, void *offset)
{
struct net_device *net_dev = (struct net_device *)seq->private;
struct bat_priv *bat_priv = netdev_priv(net_dev);
+ struct hard_iface *primary_if;
struct gw_node *gw_node;
struct hlist_node *node;
- int gw_count = 0;
+ int gw_count = 0, ret = 0;
- if (!bat_priv->primary_if) {
-
- return seq_printf(seq, "BATMAN mesh %s disabled - please "
- "specify interfaces to enable it\n",
- net_dev->name);
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if) {
+ ret = seq_printf(seq, "BATMAN mesh %s disabled - please "
+ "specify interfaces to enable it\n",
+ net_dev->name);
+ goto out;
}
- if (bat_priv->primary_if->if_status != IF_ACTIVE) {
-
- return seq_printf(seq, "BATMAN mesh %s disabled - "
- "primary interface not active\n",
- net_dev->name);
+ if (primary_if->if_status != IF_ACTIVE) {
+ ret = seq_printf(seq, "BATMAN mesh %s disabled - "
+ "primary interface not active\n",
+ net_dev->name);
+ goto out;
}
seq_printf(seq, " %-12s (%s/%i) %17s [%10s]: gw_class ... "
"[B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%pM (%s)]\n",
"Gateway", "#", TQ_MAX_VALUE, "Nexthop",
"outgoingIF", SOURCE_VERSION, REVISION_VERSION_STR,
- bat_priv->primary_if->net_dev->name,
- bat_priv->primary_if->net_dev->dev_addr, net_dev->name);
+ primary_if->net_dev->name,
+ primary_if->net_dev->dev_addr, net_dev->name);
rcu_read_lock();
hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) {
@@ -476,7 +473,10 @@ int gw_client_seq_print_text(struct seq_file *seq, void *offset)
if (gw_count == 0)
seq_printf(seq, "No gateways in range ...\n");
- return 0;
+out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
+ return ret;
}
int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb)
@@ -508,7 +508,7 @@ int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb)
/* check for ip header */
switch (ntohs(ethhdr->h_proto)) {
case ETH_P_IP:
- if (!pskb_may_pull(skb, header_len + sizeof(struct iphdr)))
+ if (!pskb_may_pull(skb, header_len + sizeof(*iphdr)))
return 0;
iphdr = (struct iphdr *)(skb->data + header_len);
header_len += iphdr->ihl * 4;
@@ -519,10 +519,10 @@ int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb)
break;
case ETH_P_IPV6:
- if (!pskb_may_pull(skb, header_len + sizeof(struct ipv6hdr)))
+ if (!pskb_may_pull(skb, header_len + sizeof(*ipv6hdr)))
return 0;
ipv6hdr = (struct ipv6hdr *)(skb->data + header_len);
- header_len += sizeof(struct ipv6hdr);
+ header_len += sizeof(*ipv6hdr);
/* check for udp header */
if (ipv6hdr->nexthdr != IPPROTO_UDP)
@@ -533,10 +533,10 @@ int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb)
return 0;
}
- if (!pskb_may_pull(skb, header_len + sizeof(struct udphdr)))
+ if (!pskb_may_pull(skb, header_len + sizeof(*udphdr)))
return 0;
udphdr = (struct udphdr *)(skb->data + header_len);
- header_len += sizeof(struct udphdr);
+ header_len += sizeof(*udphdr);
/* check for bootp port */
if ((ntohs(ethhdr->h_proto) == ETH_P_IP) &&
diff --git a/net/batman-adv/gateway_common.c b/net/batman-adv/gateway_common.c
index 50d3a59a3d73..e74307be8e0c 100644
--- a/net/batman-adv/gateway_common.c
+++ b/net/batman-adv/gateway_common.c
@@ -76,10 +76,11 @@ void gw_bandwidth_to_kbit(uint8_t gw_srv_class, int *down, int *up)
}
static bool parse_gw_bandwidth(struct net_device *net_dev, char *buff,
- long *up, long *down)
+ int *up, int *down)
{
int ret, multi = 1;
char *slash_ptr, *tmp_ptr;
+ long ldown, lup;
slash_ptr = strchr(buff, '/');
if (slash_ptr)
@@ -96,7 +97,7 @@ static bool parse_gw_bandwidth(struct net_device *net_dev, char *buff,
*tmp_ptr = '\0';
}
- ret = strict_strtoul(buff, 10, down);
+ ret = strict_strtol(buff, 10, &ldown);
if (ret) {
bat_err(net_dev,
"Download speed of gateway mode invalid: %s\n",
@@ -104,7 +105,7 @@ static bool parse_gw_bandwidth(struct net_device *net_dev, char *buff,
return false;
}
- *down *= multi;
+ *down = ldown * multi;
/* we also got some upload info */
if (slash_ptr) {
@@ -121,7 +122,7 @@ static bool parse_gw_bandwidth(struct net_device *net_dev, char *buff,
*tmp_ptr = '\0';
}
- ret = strict_strtoul(slash_ptr + 1, 10, up);
+ ret = strict_strtol(slash_ptr + 1, 10, &lup);
if (ret) {
bat_err(net_dev,
"Upload speed of gateway mode invalid: "
@@ -129,7 +130,7 @@ static bool parse_gw_bandwidth(struct net_device *net_dev, char *buff,
return false;
}
- *up *= multi;
+ *up = lup * multi;
}
return true;
@@ -138,7 +139,8 @@ static bool parse_gw_bandwidth(struct net_device *net_dev, char *buff,
ssize_t gw_bandwidth_set(struct net_device *net_dev, char *buff, size_t count)
{
struct bat_priv *bat_priv = netdev_priv(net_dev);
- long gw_bandwidth_tmp = 0, up = 0, down = 0;
+ long gw_bandwidth_tmp = 0;
+ int up = 0, down = 0;
bool ret;
ret = parse_gw_bandwidth(net_dev, buff, &up, &down);
@@ -158,12 +160,11 @@ ssize_t gw_bandwidth_set(struct net_device *net_dev, char *buff, size_t count)
* speeds, hence we need to calculate it back to show the number
* that is going to be propagated
**/
- gw_bandwidth_to_kbit((uint8_t)gw_bandwidth_tmp,
- (int *)&down, (int *)&up);
+ gw_bandwidth_to_kbit((uint8_t)gw_bandwidth_tmp, &down, &up);
gw_deselect(bat_priv);
bat_info(net_dev, "Changing gateway bandwidth from: '%i' to: '%ld' "
- "(propagating: %ld%s/%ld%s)\n",
+ "(propagating: %d%s/%d%s)\n",
atomic_read(&bat_priv->gw_bandwidth), gw_bandwidth_tmp,
(down > 2048 ? down / 1024 : down),
(down > 2048 ? "MBit" : "KBit"),
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index b3058e46ee6b..abb490106f3b 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -31,9 +31,6 @@
#include <linux/if_arp.h>
-/* protect update critical side of hardif_list - but not the content */
-static DEFINE_SPINLOCK(hardif_list_lock);
-
static int batman_skb_recv(struct sk_buff *skb,
struct net_device *dev,
@@ -49,7 +46,7 @@ void hardif_free_rcu(struct rcu_head *rcu)
kfree(hard_iface);
}
-struct hard_iface *hardif_get_by_netdev(struct net_device *net_dev)
+struct hard_iface *hardif_get_by_netdev(const struct net_device *net_dev)
{
struct hard_iface *hard_iface;
@@ -67,7 +64,7 @@ out:
return hard_iface;
}
-static int is_valid_iface(struct net_device *net_dev)
+static int is_valid_iface(const struct net_device *net_dev)
{
if (net_dev->flags & IFF_LOOPBACK)
return 0;
@@ -89,7 +86,7 @@ static int is_valid_iface(struct net_device *net_dev)
return 1;
}
-static struct hard_iface *hardif_get_active(struct net_device *soft_iface)
+static struct hard_iface *hardif_get_active(const struct net_device *soft_iface)
{
struct hard_iface *hard_iface;
@@ -110,50 +107,60 @@ out:
return hard_iface;
}
-static void update_primary_addr(struct bat_priv *bat_priv)
+static void primary_if_update_addr(struct bat_priv *bat_priv)
{
struct vis_packet *vis_packet;
+ struct hard_iface *primary_if;
+
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
+ goto out;
vis_packet = (struct vis_packet *)
bat_priv->my_vis_info->skb_packet->data;
- memcpy(vis_packet->vis_orig,
- bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+ memcpy(vis_packet->vis_orig, primary_if->net_dev->dev_addr, ETH_ALEN);
memcpy(vis_packet->sender_orig,
- bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+ primary_if->net_dev->dev_addr, ETH_ALEN);
+
+out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
}
-static void set_primary_if(struct bat_priv *bat_priv,
- struct hard_iface *hard_iface)
+static void primary_if_select(struct bat_priv *bat_priv,
+ struct hard_iface *new_hard_iface)
{
+ struct hard_iface *curr_hard_iface;
struct batman_packet *batman_packet;
- struct hard_iface *old_if;
- if (hard_iface && !atomic_inc_not_zero(&hard_iface->refcount))
- hard_iface = NULL;
+ ASSERT_RTNL();
+
+ if (new_hard_iface && !atomic_inc_not_zero(&new_hard_iface->refcount))
+ new_hard_iface = NULL;
- old_if = bat_priv->primary_if;
- bat_priv->primary_if = hard_iface;
+ curr_hard_iface = rcu_dereference_protected(bat_priv->primary_if, 1);
+ rcu_assign_pointer(bat_priv->primary_if, new_hard_iface);
- if (old_if)
- hardif_free_ref(old_if);
+ if (curr_hard_iface)
+ hardif_free_ref(curr_hard_iface);
- if (!bat_priv->primary_if)
+ if (!new_hard_iface)
return;
- batman_packet = (struct batman_packet *)(hard_iface->packet_buff);
+ batman_packet = (struct batman_packet *)(new_hard_iface->packet_buff);
batman_packet->flags = PRIMARIES_FIRST_HOP;
batman_packet->ttl = TTL;
- update_primary_addr(bat_priv);
+ primary_if_update_addr(bat_priv);
/***
- * hacky trick to make sure that we send the HNA information via
+ * hacky trick to make sure that we send the TT information via
* our new primary interface
*/
- atomic_set(&bat_priv->hna_local_changed, 1);
+ atomic_set(&bat_priv->tt_local_changed, 1);
}
-static bool hardif_is_iface_up(struct hard_iface *hard_iface)
+static bool hardif_is_iface_up(const struct hard_iface *hard_iface)
{
if (hard_iface->net_dev->flags & IFF_UP)
return true;
@@ -169,9 +176,9 @@ static void update_mac_addresses(struct hard_iface *hard_iface)
hard_iface->net_dev->dev_addr, ETH_ALEN);
}
-static void check_known_mac_addr(struct net_device *net_dev)
+static void check_known_mac_addr(const struct net_device *net_dev)
{
- struct hard_iface *hard_iface;
+ const struct hard_iface *hard_iface;
rcu_read_lock();
list_for_each_entry_rcu(hard_iface, &hardif_list, list) {
@@ -197,8 +204,8 @@ static void check_known_mac_addr(struct net_device *net_dev)
int hardif_min_mtu(struct net_device *soft_iface)
{
- struct bat_priv *bat_priv = netdev_priv(soft_iface);
- struct hard_iface *hard_iface;
+ const struct bat_priv *bat_priv = netdev_priv(soft_iface);
+ const struct hard_iface *hard_iface;
/* allow big frames if all devices are capable to do so
* (have MTU > 1500 + BAT_HEADER_LEN) */
int min_mtu = ETH_DATA_LEN;
@@ -236,9 +243,10 @@ void update_min_mtu(struct net_device *soft_iface)
static void hardif_activate_interface(struct hard_iface *hard_iface)
{
struct bat_priv *bat_priv;
+ struct hard_iface *primary_if = NULL;
if (hard_iface->if_status != IF_INACTIVE)
- return;
+ goto out;
bat_priv = netdev_priv(hard_iface->soft_iface);
@@ -249,14 +257,18 @@ static void hardif_activate_interface(struct hard_iface *hard_iface)
* the first active interface becomes our primary interface or
* the next active interface after the old primay interface was removed
*/
- if (!bat_priv->primary_if)
- set_primary_if(bat_priv, hard_iface);
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
+ primary_if_select(bat_priv, hard_iface);
bat_info(hard_iface->soft_iface, "Interface activated: %s\n",
hard_iface->net_dev->name);
update_min_mtu(hard_iface->soft_iface);
- return;
+
+out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
}
static void hardif_deactivate_interface(struct hard_iface *hard_iface)
@@ -273,7 +285,8 @@ static void hardif_deactivate_interface(struct hard_iface *hard_iface)
update_min_mtu(hard_iface->soft_iface);
}
-int hardif_enable_interface(struct hard_iface *hard_iface, char *iface_name)
+int hardif_enable_interface(struct hard_iface *hard_iface,
+ const char *iface_name)
{
struct bat_priv *bat_priv;
struct batman_packet *batman_packet;
@@ -324,10 +337,10 @@ int hardif_enable_interface(struct hard_iface *hard_iface, char *iface_name)
batman_packet = (struct batman_packet *)(hard_iface->packet_buff);
batman_packet->packet_type = BAT_PACKET;
batman_packet->version = COMPAT_VERSION;
- batman_packet->flags = 0;
+ batman_packet->flags = NO_FLAGS;
batman_packet->ttl = 2;
batman_packet->tq = TQ_MAX_VALUE;
- batman_packet->num_hna = 0;
+ batman_packet->num_tt = 0;
hard_iface->if_num = bat_priv->num_ifaces;
bat_priv->num_ifaces++;
@@ -386,12 +399,13 @@ err:
void hardif_disable_interface(struct hard_iface *hard_iface)
{
struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
+ struct hard_iface *primary_if = NULL;
if (hard_iface->if_status == IF_ACTIVE)
hardif_deactivate_interface(hard_iface);
if (hard_iface->if_status != IF_INACTIVE)
- return;
+ goto out;
bat_info(hard_iface->soft_iface, "Removing interface: %s\n",
hard_iface->net_dev->name);
@@ -400,11 +414,12 @@ void hardif_disable_interface(struct hard_iface *hard_iface)
bat_priv->num_ifaces--;
orig_hash_del_if(hard_iface, bat_priv->num_ifaces);
- if (hard_iface == bat_priv->primary_if) {
+ primary_if = primary_if_get_selected(bat_priv);
+ if (hard_iface == primary_if) {
struct hard_iface *new_if;
new_if = hardif_get_active(hard_iface->soft_iface);
- set_primary_if(bat_priv, new_if);
+ primary_if_select(bat_priv, new_if);
if (new_if)
hardif_free_ref(new_if);
@@ -425,6 +440,10 @@ void hardif_disable_interface(struct hard_iface *hard_iface)
hard_iface->soft_iface = NULL;
hardif_free_ref(hard_iface);
+
+out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
}
static struct hard_iface *hardif_add_interface(struct net_device *net_dev)
@@ -432,13 +451,15 @@ static struct hard_iface *hardif_add_interface(struct net_device *net_dev)
struct hard_iface *hard_iface;
int ret;
+ ASSERT_RTNL();
+
ret = is_valid_iface(net_dev);
if (ret != 1)
goto out;
dev_hold(net_dev);
- hard_iface = kmalloc(sizeof(struct hard_iface), GFP_ATOMIC);
+ hard_iface = kmalloc(sizeof(*hard_iface), GFP_ATOMIC);
if (!hard_iface) {
pr_err("Can't add interface (%s): out of memory\n",
net_dev->name);
@@ -458,10 +479,7 @@ static struct hard_iface *hardif_add_interface(struct net_device *net_dev)
atomic_set(&hard_iface->refcount, 2);
check_known_mac_addr(hard_iface->net_dev);
-
- spin_lock(&hardif_list_lock);
list_add_tail_rcu(&hard_iface->list, &hardif_list);
- spin_unlock(&hardif_list_lock);
return hard_iface;
@@ -475,6 +493,8 @@ out:
static void hardif_remove_interface(struct hard_iface *hard_iface)
{
+ ASSERT_RTNL();
+
/* first deactivate interface */
if (hard_iface->if_status != IF_NOT_IN_USE)
hardif_disable_interface(hard_iface);
@@ -490,20 +510,11 @@ static void hardif_remove_interface(struct hard_iface *hard_iface)
void hardif_remove_interfaces(void)
{
struct hard_iface *hard_iface, *hard_iface_tmp;
- struct list_head if_queue;
-
- INIT_LIST_HEAD(&if_queue);
- spin_lock(&hardif_list_lock);
+ rtnl_lock();
list_for_each_entry_safe(hard_iface, hard_iface_tmp,
&hardif_list, list) {
list_del_rcu(&hard_iface->list);
- list_add_tail(&hard_iface->list, &if_queue);
- }
- spin_unlock(&hardif_list_lock);
-
- rtnl_lock();
- list_for_each_entry_safe(hard_iface, hard_iface_tmp, &if_queue, list) {
hardif_remove_interface(hard_iface);
}
rtnl_unlock();
@@ -512,8 +523,9 @@ void hardif_remove_interfaces(void)
static int hard_if_event(struct notifier_block *this,
unsigned long event, void *ptr)
{
- struct net_device *net_dev = (struct net_device *)ptr;
+ struct net_device *net_dev = ptr;
struct hard_iface *hard_iface = hardif_get_by_netdev(net_dev);
+ struct hard_iface *primary_if = NULL;
struct bat_priv *bat_priv;
if (!hard_iface && event == NETDEV_REGISTER)
@@ -531,9 +543,7 @@ static int hard_if_event(struct notifier_block *this,
hardif_deactivate_interface(hard_iface);
break;
case NETDEV_UNREGISTER:
- spin_lock(&hardif_list_lock);
list_del_rcu(&hard_iface->list);
- spin_unlock(&hardif_list_lock);
hardif_remove_interface(hard_iface);
break;
@@ -549,16 +559,22 @@ static int hard_if_event(struct notifier_block *this,
update_mac_addresses(hard_iface);
bat_priv = netdev_priv(hard_iface->soft_iface);
- if (hard_iface == bat_priv->primary_if)
- update_primary_addr(bat_priv);
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
+ goto hardif_put;
+
+ if (hard_iface == primary_if)
+ primary_if_update_addr(bat_priv);
break;
default:
break;
- };
+ }
hardif_put:
hardif_free_ref(hard_iface);
out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
return NOTIFY_DONE;
}
diff --git a/net/batman-adv/hard-interface.h b/net/batman-adv/hard-interface.h
index a9ddf36e51c8..442eacbc9e3a 100644
--- a/net/batman-adv/hard-interface.h
+++ b/net/batman-adv/hard-interface.h
@@ -22,17 +22,21 @@
#ifndef _NET_BATMAN_ADV_HARD_INTERFACE_H_
#define _NET_BATMAN_ADV_HARD_INTERFACE_H_
-#define IF_NOT_IN_USE 0
-#define IF_TO_BE_REMOVED 1
-#define IF_INACTIVE 2
-#define IF_ACTIVE 3
-#define IF_TO_BE_ACTIVATED 4
-#define IF_I_WANT_YOU 5
+enum hard_if_state {
+ IF_NOT_IN_USE,
+ IF_TO_BE_REMOVED,
+ IF_INACTIVE,
+ IF_ACTIVE,
+ IF_TO_BE_ACTIVATED,
+ IF_I_WANT_YOU
+};
extern struct notifier_block hard_if_notifier;
-struct hard_iface *hardif_get_by_netdev(struct net_device *net_dev);
-int hardif_enable_interface(struct hard_iface *hard_iface, char *iface_name);
+struct hard_iface*
+hardif_get_by_netdev(const struct net_device *net_dev);
+int hardif_enable_interface(struct hard_iface *hard_iface,
+ const char *iface_name);
void hardif_disable_interface(struct hard_iface *hard_iface);
void hardif_remove_interfaces(void);
int hardif_min_mtu(struct net_device *soft_iface);
@@ -45,4 +49,22 @@ static inline void hardif_free_ref(struct hard_iface *hard_iface)
call_rcu(&hard_iface->rcu, hardif_free_rcu);
}
+static inline struct hard_iface *primary_if_get_selected(
+ struct bat_priv *bat_priv)
+{
+ struct hard_iface *hard_iface;
+
+ rcu_read_lock();
+ hard_iface = rcu_dereference(bat_priv->primary_if);
+ if (!hard_iface)
+ goto out;
+
+ if (!atomic_inc_not_zero(&hard_iface->refcount))
+ hard_iface = NULL;
+
+out:
+ rcu_read_unlock();
+ return hard_iface;
+}
+
#endif /* _NET_BATMAN_ADV_HARD_INTERFACE_H_ */
diff --git a/net/batman-adv/hash.c b/net/batman-adv/hash.c
index c5213d8f2cca..2a172505f513 100644
--- a/net/batman-adv/hash.c
+++ b/net/batman-adv/hash.c
@@ -46,15 +46,16 @@ struct hashtable_t *hash_new(int size)
{
struct hashtable_t *hash;
- hash = kmalloc(sizeof(struct hashtable_t), GFP_ATOMIC);
+ hash = kmalloc(sizeof(*hash), GFP_ATOMIC);
if (!hash)
return NULL;
- hash->table = kmalloc(sizeof(struct element_t *) * size, GFP_ATOMIC);
+ hash->table = kmalloc(sizeof(*hash->table) * size, GFP_ATOMIC);
if (!hash->table)
goto free_hash;
- hash->list_locks = kmalloc(sizeof(spinlock_t) * size, GFP_ATOMIC);
+ hash->list_locks = kmalloc(sizeof(*hash->list_locks) * size,
+ GFP_ATOMIC);
if (!hash->list_locks)
goto free_table;
diff --git a/net/batman-adv/hash.h b/net/batman-adv/hash.h
index 434822b27473..dd5c9fd7a905 100644
--- a/net/batman-adv/hash.h
+++ b/net/batman-adv/hash.h
@@ -28,12 +28,12 @@
* compare 2 element datas for their keys,
* return 0 if same and not 0 if not
* same */
-typedef int (*hashdata_compare_cb)(struct hlist_node *, void *);
+typedef int (*hashdata_compare_cb)(const struct hlist_node *, const void *);
/* the hashfunction, should return an index
* based on the key in the data of the first
* argument and the size the second */
-typedef int (*hashdata_choose_cb)(void *, int);
+typedef int (*hashdata_choose_cb)(const void *, int);
typedef void (*hashdata_free_cb)(struct hlist_node *, void *);
struct hashtable_t {
@@ -80,7 +80,7 @@ static inline void hash_delete(struct hashtable_t *hash,
static inline int hash_add(struct hashtable_t *hash,
hashdata_compare_cb compare,
hashdata_choose_cb choose,
- void *data, struct hlist_node *data_node)
+ const void *data, struct hlist_node *data_node)
{
int index;
struct hlist_head *head;
diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c
index 49079c254476..ac3520e057c0 100644
--- a/net/batman-adv/icmp_socket.c
+++ b/net/batman-adv/icmp_socket.c
@@ -46,7 +46,7 @@ static int bat_socket_open(struct inode *inode, struct file *file)
nonseekable_open(inode, file);
- socket_client = kmalloc(sizeof(struct socket_client), GFP_KERNEL);
+ socket_client = kmalloc(sizeof(*socket_client), GFP_KERNEL);
if (!socket_client)
return -ENOMEM;
@@ -153,6 +153,7 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
{
struct socket_client *socket_client = file->private_data;
struct bat_priv *bat_priv = socket_client->bat_priv;
+ struct hard_iface *primary_if = NULL;
struct sk_buff *skb;
struct icmp_packet_rr *icmp_packet;
@@ -167,15 +168,21 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
return -EINVAL;
}
- if (!bat_priv->primary_if)
- return -EFAULT;
+ primary_if = primary_if_get_selected(bat_priv);
+
+ if (!primary_if) {
+ len = -EFAULT;
+ goto out;
+ }
if (len >= sizeof(struct icmp_packet_rr))
packet_len = sizeof(struct icmp_packet_rr);
skb = dev_alloc_skb(packet_len + sizeof(struct ethhdr));
- if (!skb)
- return -ENOMEM;
+ if (!skb) {
+ len = -ENOMEM;
+ goto out;
+ }
skb_reserve(skb, sizeof(struct ethhdr));
icmp_packet = (struct icmp_packet_rr *)skb_put(skb, packet_len);
@@ -233,7 +240,7 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
goto dst_unreach;
memcpy(icmp_packet->orig,
- bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+ primary_if->net_dev->dev_addr, ETH_ALEN);
if (packet_len == sizeof(struct icmp_packet_rr))
memcpy(icmp_packet->rr,
@@ -248,6 +255,8 @@ dst_unreach:
free_skb:
kfree_skb(skb);
out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
if (neigh_node)
neigh_node_free_ref(neigh_node);
if (orig_node)
@@ -301,7 +310,7 @@ static void bat_socket_add_packet(struct socket_client *socket_client,
{
struct socket_packet *socket_packet;
- socket_packet = kmalloc(sizeof(struct socket_packet), GFP_ATOMIC);
+ socket_packet = kmalloc(sizeof(*socket_packet), GFP_ATOMIC);
if (!socket_packet)
return;
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index 709b33bbdf43..2d6445e171d6 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -33,6 +33,9 @@
#include "vis.h"
#include "hash.h"
+
+/* List manipulations on hardif_list have to be rtnl_lock()'ed,
+ * list traversals just rcu-locked */
struct list_head hardif_list;
unsigned char broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
@@ -81,28 +84,29 @@ int mesh_init(struct net_device *soft_iface)
spin_lock_init(&bat_priv->forw_bat_list_lock);
spin_lock_init(&bat_priv->forw_bcast_list_lock);
- spin_lock_init(&bat_priv->hna_lhash_lock);
- spin_lock_init(&bat_priv->hna_ghash_lock);
+ spin_lock_init(&bat_priv->tt_lhash_lock);
+ spin_lock_init(&bat_priv->tt_ghash_lock);
spin_lock_init(&bat_priv->gw_list_lock);
spin_lock_init(&bat_priv->vis_hash_lock);
spin_lock_init(&bat_priv->vis_list_lock);
spin_lock_init(&bat_priv->softif_neigh_lock);
+ spin_lock_init(&bat_priv->softif_neigh_vid_lock);
INIT_HLIST_HEAD(&bat_priv->forw_bat_list);
INIT_HLIST_HEAD(&bat_priv->forw_bcast_list);
INIT_HLIST_HEAD(&bat_priv->gw_list);
- INIT_HLIST_HEAD(&bat_priv->softif_neigh_list);
+ INIT_HLIST_HEAD(&bat_priv->softif_neigh_vids);
if (originator_init(bat_priv) < 1)
goto err;
- if (hna_local_init(bat_priv) < 1)
+ if (tt_local_init(bat_priv) < 1)
goto err;
- if (hna_global_init(bat_priv) < 1)
+ if (tt_global_init(bat_priv) < 1)
goto err;
- hna_local_add(soft_iface, soft_iface->dev_addr);
+ tt_local_add(soft_iface, soft_iface->dev_addr);
if (vis_init(bat_priv) < 1)
goto err;
@@ -133,8 +137,8 @@ void mesh_free(struct net_device *soft_iface)
gw_node_purge(bat_priv);
originator_free(bat_priv);
- hna_local_free(bat_priv);
- hna_global_free(bat_priv);
+ tt_local_free(bat_priv);
+ tt_global_free(bat_priv);
softif_neigh_purge(bat_priv);
@@ -151,9 +155,9 @@ void dec_module_count(void)
module_put(THIS_MODULE);
}
-int is_my_mac(uint8_t *addr)
+int is_my_mac(const uint8_t *addr)
{
- struct hard_iface *hard_iface;
+ const struct hard_iface *hard_iface;
rcu_read_lock();
list_for_each_entry_rcu(hard_iface, &hardif_list, list) {
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index dc248697de71..ed488cbae80f 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -34,46 +34,51 @@
#define TQ_MAX_VALUE 255
#define JITTER 20
-#define TTL 50 /* Time To Live of broadcast messages */
-#define PURGE_TIMEOUT 200 /* purge originators after time in seconds if no
- * valid packet comes in -> TODO: check
- * influence on TQ_LOCAL_WINDOW_SIZE */
-#define LOCAL_HNA_TIMEOUT 3600 /* in seconds */
+ /* Time To Live of broadcast messages */
+#define TTL 50
-#define TQ_LOCAL_WINDOW_SIZE 64 /* sliding packet range of received originator
- * messages in squence numbers (should be a
- * multiple of our word size) */
+/* purge originators after time in seconds if no valid packet comes in
+ * -> TODO: check influence on TQ_LOCAL_WINDOW_SIZE */
+#define PURGE_TIMEOUT 200
+#define TT_LOCAL_TIMEOUT 3600 /* in seconds */
+
+/* sliding packet range of received originator messages in squence numbers
+ * (should be a multiple of our word size) */
+#define TQ_LOCAL_WINDOW_SIZE 64
#define TQ_GLOBAL_WINDOW_SIZE 5
#define TQ_LOCAL_BIDRECT_SEND_MINIMUM 1
#define TQ_LOCAL_BIDRECT_RECV_MINIMUM 1
#define TQ_TOTAL_BIDRECT_LIMIT 1
+#define NO_FLAGS 0
+
#define NUM_WORDS (TQ_LOCAL_WINDOW_SIZE / WORD_BIT_SIZE)
#define LOG_BUF_LEN 8192 /* has to be a power of 2 */
#define VIS_INTERVAL 5000 /* 5 seconds */
-/* how much worse secondary interfaces may be to
- * to be considered as bonding candidates */
-
+/* how much worse secondary interfaces may be to be considered as bonding
+ * candidates */
#define BONDING_TQ_THRESHOLD 50
-#define MAX_AGGREGATION_BYTES 512 /* should not be bigger than 512 bytes or
- * change the size of
- * forw_packet->direct_link_flags */
+/* should not be bigger than 512 bytes or change the size of
+ * forw_packet->direct_link_flags */
+#define MAX_AGGREGATION_BYTES 512
#define MAX_AGGREGATION_MS 100
#define SOFTIF_NEIGH_TIMEOUT 180000 /* 3 minutes */
+/* don't reset again within 30 seconds */
#define RESET_PROTECTION_MS 30000
#define EXPECTED_SEQNO_RANGE 65536
-/* don't reset again within 30 seconds */
-#define MESH_INACTIVE 0
-#define MESH_ACTIVE 1
-#define MESH_DEACTIVATING 2
+enum mesh_state {
+ MESH_INACTIVE,
+ MESH_ACTIVE,
+ MESH_DEACTIVATING
+};
#define BCAST_QUEUE_LEN 256
#define BATMAN_QUEUE_LEN 256
@@ -84,13 +89,15 @@
#ifdef pr_fmt
#undef pr_fmt
#endif
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt /* Append 'batman-adv: ' before
- * kernel messages */
+/* Append 'batman-adv: ' before kernel messages */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#define DBG_BATMAN 1 /* all messages related to routing / flooding /
- * broadcasting / etc */
-#define DBG_ROUTES 2 /* route or hna added / changed / deleted */
-#define DBG_ALL 3
+/* all messages related to routing / flooding / broadcasting / etc */
+enum dbg_level {
+ DBG_BATMAN = 1 << 0,
+ DBG_ROUTES = 1 << 1, /* route added / changed / deleted */
+ DBG_ALL = 3
+};
/*
@@ -131,10 +138,10 @@ int mesh_init(struct net_device *soft_iface);
void mesh_free(struct net_device *soft_iface);
void inc_module_count(void);
void dec_module_count(void);
-int is_my_mac(uint8_t *addr);
+int is_my_mac(const uint8_t *addr);
#ifdef CONFIG_BATMAN_ADV_DEBUG
-int debug_log(struct bat_priv *bat_priv, char *fmt, ...);
+int debug_log(struct bat_priv *bat_priv, const char *fmt, ...) __printf(2, 3);
#define bat_dbg(type, bat_priv, fmt, arg...) \
do { \
@@ -143,9 +150,10 @@ int debug_log(struct bat_priv *bat_priv, char *fmt, ...);
} \
while (0)
#else /* !CONFIG_BATMAN_ADV_DEBUG */
+__printf(3, 4)
static inline void bat_dbg(char type __always_unused,
struct bat_priv *bat_priv __always_unused,
- char *fmt __always_unused, ...)
+ const char *fmt __always_unused, ...)
{
}
#endif
@@ -170,9 +178,32 @@ static inline void bat_dbg(char type __always_unused,
*
* note: can't use compare_ether_addr() as it requires aligned memory
*/
-static inline int compare_eth(void *data1, void *data2)
+
+static inline int compare_eth(const void *data1, const void *data2)
{
return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0);
}
+
+#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0)
+
+/* Returns the smallest signed integer in two's complement with the sizeof x */
+#define smallest_signed_int(x) (1u << (7u + 8u * (sizeof(x) - 1u)))
+
+/* Checks if a sequence number x is a predecessor/successor of y.
+ * they handle overflows/underflows and can correctly check for a
+ * predecessor/successor unless the variable sequence number has grown by
+ * more then 2**(bitwidth(x)-1)-1.
+ * This means that for a uint8_t with the maximum value 255, it would think:
+ * - when adding nothing - it is neither a predecessor nor a successor
+ * - before adding more than 127 to the starting value - it is a predecessor,
+ * - when adding 128 - it is neither a predecessor nor a successor,
+ * - after adding more than 127 to the starting value - it is a successor */
+#define seq_before(x, y) ({typeof(x) _d1 = (x); \
+ typeof(y) _d2 = (y); \
+ typeof(x) _dummy = (_d1 - _d2); \
+ (void) (&_d1 == &_d2); \
+ _dummy > smallest_signed_int(_dummy); })
+#define seq_after(x, y) seq_before(y, x)
+
#endif /* _NET_BATMAN_ADV_MAIN_H_ */
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index 5b8fe32043da..a6c35d4e332b 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -19,8 +19,6 @@
*
*/
-/* increase the reference counter for this originator */
-
#include "main.h"
#include "originator.h"
#include "hash.h"
@@ -56,18 +54,10 @@ err:
return 0;
}
-static void neigh_node_free_rcu(struct rcu_head *rcu)
-{
- struct neigh_node *neigh_node;
-
- neigh_node = container_of(rcu, struct neigh_node, rcu);
- kfree(neigh_node);
-}
-
void neigh_node_free_ref(struct neigh_node *neigh_node)
{
if (atomic_dec_and_test(&neigh_node->refcount))
- call_rcu(&neigh_node->rcu, neigh_node_free_rcu);
+ kfree_rcu(neigh_node, rcu);
}
/* increases the refcounter of a found router */
@@ -87,7 +77,7 @@ struct neigh_node *orig_node_get_router(struct orig_node *orig_node)
struct neigh_node *create_neighbor(struct orig_node *orig_node,
struct orig_node *orig_neigh_node,
- uint8_t *neigh,
+ const uint8_t *neigh,
struct hard_iface *if_incoming)
{
struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
@@ -96,7 +86,7 @@ struct neigh_node *create_neighbor(struct orig_node *orig_node,
bat_dbg(DBG_BATMAN, bat_priv,
"Creating new last-hop neighbor of originator\n");
- neigh_node = kzalloc(sizeof(struct neigh_node), GFP_ATOMIC);
+ neigh_node = kzalloc(sizeof(*neigh_node), GFP_ATOMIC);
if (!neigh_node)
return NULL;
@@ -144,7 +134,7 @@ static void orig_node_free_rcu(struct rcu_head *rcu)
spin_unlock_bh(&orig_node->neigh_list_lock);
frag_list_free(&orig_node->frag_list);
- hna_global_del_orig(orig_node->bat_priv, orig_node,
+ tt_global_del_orig(orig_node->bat_priv, orig_node,
"originator timed out");
kfree(orig_node->bcast_own);
@@ -193,7 +183,7 @@ void originator_free(struct bat_priv *bat_priv)
/* this function finds or creates an originator entry for the given
* address if it does not exits */
-struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr)
+struct orig_node *get_orig_node(struct bat_priv *bat_priv, const uint8_t *addr)
{
struct orig_node *orig_node;
int size;
@@ -206,7 +196,7 @@ struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr)
bat_dbg(DBG_BATMAN, bat_priv,
"Creating new originator: %pM\n", addr);
- orig_node = kzalloc(sizeof(struct orig_node), GFP_ATOMIC);
+ orig_node = kzalloc(sizeof(*orig_node), GFP_ATOMIC);
if (!orig_node)
return NULL;
@@ -222,7 +212,7 @@ struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr)
orig_node->bat_priv = bat_priv;
memcpy(orig_node->orig, addr, ETH_ALEN);
orig_node->router = NULL;
- orig_node->hna_buff = NULL;
+ orig_node->tt_buff = NULL;
orig_node->bcast_seqno_reset = jiffies - 1
- msecs_to_jiffies(RESET_PROTECTION_MS);
orig_node->batman_seqno_reset = jiffies - 1
@@ -333,8 +323,8 @@ static bool purge_orig_node(struct bat_priv *bat_priv,
&best_neigh_node)) {
update_routes(bat_priv, orig_node,
best_neigh_node,
- orig_node->hna_buff,
- orig_node->hna_buff_len);
+ orig_node->tt_buff,
+ orig_node->tt_buff_len);
}
}
@@ -405,29 +395,34 @@ int orig_seq_print_text(struct seq_file *seq, void *offset)
struct hashtable_t *hash = bat_priv->orig_hash;
struct hlist_node *node, *node_tmp;
struct hlist_head *head;
+ struct hard_iface *primary_if;
struct orig_node *orig_node;
struct neigh_node *neigh_node, *neigh_node_tmp;
int batman_count = 0;
int last_seen_secs;
int last_seen_msecs;
- int i;
+ int i, ret = 0;
- if ((!bat_priv->primary_if) ||
- (bat_priv->primary_if->if_status != IF_ACTIVE)) {
- if (!bat_priv->primary_if)
- return seq_printf(seq, "BATMAN mesh %s disabled - "
- "please specify interfaces to enable it\n",
- net_dev->name);
+ primary_if = primary_if_get_selected(bat_priv);
- return seq_printf(seq, "BATMAN mesh %s "
- "disabled - primary interface not active\n",
- net_dev->name);
+ if (!primary_if) {
+ ret = seq_printf(seq, "BATMAN mesh %s disabled - "
+ "please specify interfaces to enable it\n",
+ net_dev->name);
+ goto out;
+ }
+
+ if (primary_if->if_status != IF_ACTIVE) {
+ ret = seq_printf(seq, "BATMAN mesh %s "
+ "disabled - primary interface not active\n",
+ net_dev->name);
+ goto out;
}
seq_printf(seq, "[B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%pM (%s)]\n",
SOURCE_VERSION, REVISION_VERSION_STR,
- bat_priv->primary_if->net_dev->name,
- bat_priv->primary_if->net_dev->dev_addr, net_dev->name);
+ primary_if->net_dev->name,
+ primary_if->net_dev->dev_addr, net_dev->name);
seq_printf(seq, " %-15s %s (%s/%i) %17s [%10s]: %20s ...\n",
"Originator", "last-seen", "#", TQ_MAX_VALUE, "Nexthop",
"outgoingIF", "Potential nexthops");
@@ -474,7 +469,10 @@ next:
if (batman_count == 0)
seq_printf(seq, "No batman nodes in range ...\n");
- return 0;
+out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
+ return ret;
}
static int orig_node_add_if(struct orig_node *orig_node, int max_if_num)
@@ -561,7 +559,7 @@ static int orig_node_del_if(struct orig_node *orig_node,
memcpy(data_ptr, orig_node->bcast_own, del_if_num * chunk_size);
/* copy second part */
- memcpy(data_ptr + del_if_num * chunk_size,
+ memcpy((char *)data_ptr + del_if_num * chunk_size,
orig_node->bcast_own + ((del_if_num + 1) * chunk_size),
(max_if_num - del_if_num) * chunk_size);
@@ -581,7 +579,7 @@ free_bcast_own:
memcpy(data_ptr, orig_node->bcast_own_sum,
del_if_num * sizeof(uint8_t));
- memcpy(data_ptr + del_if_num * sizeof(uint8_t),
+ memcpy((char *)data_ptr + del_if_num * sizeof(uint8_t),
orig_node->bcast_own_sum + ((del_if_num + 1) * sizeof(uint8_t)),
(max_if_num - del_if_num) * sizeof(uint8_t));
diff --git a/net/batman-adv/originator.h b/net/batman-adv/originator.h
index e1d641f27aa9..8e307af7aa0d 100644
--- a/net/batman-adv/originator.h
+++ b/net/batman-adv/originator.h
@@ -28,10 +28,10 @@ int originator_init(struct bat_priv *bat_priv);
void originator_free(struct bat_priv *bat_priv);
void purge_orig_ref(struct bat_priv *bat_priv);
void orig_node_free_ref(struct orig_node *orig_node);
-struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr);
+struct orig_node *get_orig_node(struct bat_priv *bat_priv, const uint8_t *addr);
struct neigh_node *create_neighbor(struct orig_node *orig_node,
struct orig_node *orig_neigh_node,
- uint8_t *neigh,
+ const uint8_t *neigh,
struct hard_iface *if_incoming);
void neigh_node_free_ref(struct neigh_node *neigh_node);
struct neigh_node *orig_node_get_router(struct orig_node *orig_node);
@@ -41,18 +41,18 @@ int orig_hash_del_if(struct hard_iface *hard_iface, int max_if_num);
/* returns 1 if they are the same originator */
-static inline int compare_orig(struct hlist_node *node, void *data2)
+static inline int compare_orig(const struct hlist_node *node, const void *data2)
{
- void *data1 = container_of(node, struct orig_node, hash_entry);
+ const void *data1 = container_of(node, struct orig_node, hash_entry);
return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0);
}
/* hashfunction to choose an entry in a hash table of given size */
/* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */
-static inline int choose_orig(void *data, int32_t size)
+static inline int choose_orig(const void *data, int32_t size)
{
- unsigned char *key = data;
+ const unsigned char *key = data;
uint32_t hash = 0;
size_t i;
@@ -70,7 +70,7 @@ static inline int choose_orig(void *data, int32_t size)
}
static inline struct orig_node *orig_hash_find(struct bat_priv *bat_priv,
- void *data)
+ const void *data)
{
struct hashtable_t *hash = bat_priv->orig_hash;
struct hlist_head *head;
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h
index e7571879af3f..9f77086a5461 100644
--- a/net/batman-adv/packet.h
+++ b/net/batman-adv/packet.h
@@ -24,33 +24,44 @@
#define ETH_P_BATMAN 0x4305 /* unofficial/not registered Ethertype */
-#define BAT_PACKET 0x01
-#define BAT_ICMP 0x02
-#define BAT_UNICAST 0x03
-#define BAT_BCAST 0x04
-#define BAT_VIS 0x05
-#define BAT_UNICAST_FRAG 0x06
+enum bat_packettype {
+ BAT_PACKET = 0x01,
+ BAT_ICMP = 0x02,
+ BAT_UNICAST = 0x03,
+ BAT_BCAST = 0x04,
+ BAT_VIS = 0x05,
+ BAT_UNICAST_FRAG = 0x06
+};
/* this file is included by batctl which needs these defines */
#define COMPAT_VERSION 12
-#define DIRECTLINK 0x40
-#define VIS_SERVER 0x20
-#define PRIMARIES_FIRST_HOP 0x10
+
+enum batman_flags {
+ PRIMARIES_FIRST_HOP = 1 << 4,
+ VIS_SERVER = 1 << 5,
+ DIRECTLINK = 1 << 6
+};
/* ICMP message types */
-#define ECHO_REPLY 0
-#define DESTINATION_UNREACHABLE 3
-#define ECHO_REQUEST 8
-#define TTL_EXCEEDED 11
-#define PARAMETER_PROBLEM 12
+enum icmp_packettype {
+ ECHO_REPLY = 0,
+ DESTINATION_UNREACHABLE = 3,
+ ECHO_REQUEST = 8,
+ TTL_EXCEEDED = 11,
+ PARAMETER_PROBLEM = 12
+};
/* vis defines */
-#define VIS_TYPE_SERVER_SYNC 0
-#define VIS_TYPE_CLIENT_UPDATE 1
+enum vis_packettype {
+ VIS_TYPE_SERVER_SYNC = 0,
+ VIS_TYPE_CLIENT_UPDATE = 1
+};
/* fragmentation defines */
-#define UNI_FRAG_HEAD 0x01
-#define UNI_FRAG_LARGETAIL 0x02
+enum unicast_frag_flags {
+ UNI_FRAG_HEAD = 1 << 0,
+ UNI_FRAG_LARGETAIL = 1 << 1
+};
struct batman_packet {
uint8_t packet_type;
@@ -61,7 +72,7 @@ struct batman_packet {
uint8_t orig[6];
uint8_t prev_sender[6];
uint8_t ttl;
- uint8_t num_hna;
+ uint8_t num_tt;
uint8_t gw_flags; /* flags related to gateway class */
uint8_t align;
} __packed;
@@ -128,8 +139,7 @@ struct vis_packet {
uint8_t entries; /* number of entries behind this struct */
uint32_t seqno; /* sequence number */
uint8_t ttl; /* TTL */
- uint8_t vis_orig[6]; /* originator that informs about its
- * neighbors */
+ uint8_t vis_orig[6]; /* originator that announces its neighbors */
uint8_t target_orig[6]; /* who should receive this packet */
uint8_t sender_orig[6]; /* who sent or rebroadcasted this packet */
} __packed;
diff --git a/net/batman-adv/ring_buffer.c b/net/batman-adv/ring_buffer.c
index 5bb6a619afee..f1ccfa76ce8a 100644
--- a/net/batman-adv/ring_buffer.c
+++ b/net/batman-adv/ring_buffer.c
@@ -28,9 +28,9 @@ void ring_buffer_set(uint8_t lq_recv[], uint8_t *lq_index, uint8_t value)
*lq_index = (*lq_index + 1) % TQ_GLOBAL_WINDOW_SIZE;
}
-uint8_t ring_buffer_avg(uint8_t lq_recv[])
+uint8_t ring_buffer_avg(const uint8_t lq_recv[])
{
- uint8_t *ptr;
+ const uint8_t *ptr;
uint16_t count = 0, i = 0, sum = 0;
ptr = lq_recv;
diff --git a/net/batman-adv/ring_buffer.h b/net/batman-adv/ring_buffer.h
index 0395b2741864..7cdfe62b657c 100644
--- a/net/batman-adv/ring_buffer.h
+++ b/net/batman-adv/ring_buffer.h
@@ -23,6 +23,6 @@
#define _NET_BATMAN_ADV_RING_BUFFER_H_
void ring_buffer_set(uint8_t lq_recv[], uint8_t *lq_index, uint8_t value);
-uint8_t ring_buffer_avg(uint8_t lq_recv[]);
+uint8_t ring_buffer_avg(const uint8_t lq_recv[]);
#endif /* _NET_BATMAN_ADV_RING_BUFFER_H_ */
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index f6c642246972..934f1f2f86c6 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -64,28 +64,27 @@ void slide_own_bcast_window(struct hard_iface *hard_iface)
}
}
-static void update_HNA(struct bat_priv *bat_priv, struct orig_node *orig_node,
- unsigned char *hna_buff, int hna_buff_len)
+static void update_TT(struct bat_priv *bat_priv, struct orig_node *orig_node,
+ const unsigned char *tt_buff, int tt_buff_len)
{
- if ((hna_buff_len != orig_node->hna_buff_len) ||
- ((hna_buff_len > 0) &&
- (orig_node->hna_buff_len > 0) &&
- (memcmp(orig_node->hna_buff, hna_buff, hna_buff_len) != 0))) {
-
- if (orig_node->hna_buff_len > 0)
- hna_global_del_orig(bat_priv, orig_node,
- "originator changed hna");
-
- if ((hna_buff_len > 0) && (hna_buff))
- hna_global_add_orig(bat_priv, orig_node,
- hna_buff, hna_buff_len);
+ if ((tt_buff_len != orig_node->tt_buff_len) ||
+ ((tt_buff_len > 0) &&
+ (orig_node->tt_buff_len > 0) &&
+ (memcmp(orig_node->tt_buff, tt_buff, tt_buff_len) != 0))) {
+
+ if (orig_node->tt_buff_len > 0)
+ tt_global_del_orig(bat_priv, orig_node,
+ "originator changed tt");
+
+ if ((tt_buff_len > 0) && (tt_buff))
+ tt_global_add_orig(bat_priv, orig_node,
+ tt_buff, tt_buff_len);
}
}
-static void update_route(struct bat_priv *bat_priv,
- struct orig_node *orig_node,
+static void update_route(struct bat_priv *bat_priv, struct orig_node *orig_node,
struct neigh_node *neigh_node,
- unsigned char *hna_buff, int hna_buff_len)
+ const unsigned char *tt_buff, int tt_buff_len)
{
struct neigh_node *curr_router;
@@ -96,7 +95,7 @@ static void update_route(struct bat_priv *bat_priv,
bat_dbg(DBG_ROUTES, bat_priv, "Deleting route towards: %pM\n",
orig_node->orig);
- hna_global_del_orig(bat_priv, orig_node,
+ tt_global_del_orig(bat_priv, orig_node,
"originator timed out");
/* route added */
@@ -105,11 +104,11 @@ static void update_route(struct bat_priv *bat_priv,
bat_dbg(DBG_ROUTES, bat_priv,
"Adding route towards: %pM (via %pM)\n",
orig_node->orig, neigh_node->addr);
- hna_global_add_orig(bat_priv, orig_node,
- hna_buff, hna_buff_len);
+ tt_global_add_orig(bat_priv, orig_node,
+ tt_buff, tt_buff_len);
/* route changed */
- } else {
+ } else if (neigh_node && curr_router) {
bat_dbg(DBG_ROUTES, bat_priv,
"Changing route towards: %pM "
"(now via %pM - was via %pM)\n",
@@ -133,10 +132,9 @@ static void update_route(struct bat_priv *bat_priv,
neigh_node_free_ref(curr_router);
}
-
void update_routes(struct bat_priv *bat_priv, struct orig_node *orig_node,
- struct neigh_node *neigh_node, unsigned char *hna_buff,
- int hna_buff_len)
+ struct neigh_node *neigh_node, const unsigned char *tt_buff,
+ int tt_buff_len)
{
struct neigh_node *router = NULL;
@@ -147,10 +145,10 @@ void update_routes(struct bat_priv *bat_priv, struct orig_node *orig_node,
if (router != neigh_node)
update_route(bat_priv, orig_node, neigh_node,
- hna_buff, hna_buff_len);
- /* may be just HNA changed */
+ tt_buff, tt_buff_len);
+ /* may be just TT changed */
else
- update_HNA(bat_priv, orig_node, hna_buff, hna_buff_len);
+ update_TT(bat_priv, orig_node, tt_buff, tt_buff_len);
out:
if (router)
@@ -169,65 +167,41 @@ static int is_bidirectional_neigh(struct orig_node *orig_node,
uint8_t orig_eq_count, neigh_rq_count, tq_own;
int tq_asym_penalty, ret = 0;
- if (orig_node == orig_neigh_node) {
- rcu_read_lock();
- hlist_for_each_entry_rcu(tmp_neigh_node, node,
- &orig_node->neigh_list, list) {
-
- if (!compare_eth(tmp_neigh_node->addr,
- orig_neigh_node->orig))
- continue;
-
- if (tmp_neigh_node->if_incoming != if_incoming)
- continue;
-
- if (!atomic_inc_not_zero(&tmp_neigh_node->refcount))
- continue;
-
- neigh_node = tmp_neigh_node;
- }
- rcu_read_unlock();
+ /* find corresponding one hop neighbor */
+ rcu_read_lock();
+ hlist_for_each_entry_rcu(tmp_neigh_node, node,
+ &orig_neigh_node->neigh_list, list) {
- if (!neigh_node)
- neigh_node = create_neighbor(orig_node,
- orig_neigh_node,
- orig_neigh_node->orig,
- if_incoming);
- if (!neigh_node)
- goto out;
+ if (!compare_eth(tmp_neigh_node->addr, orig_neigh_node->orig))
+ continue;
- neigh_node->last_valid = jiffies;
- } else {
- /* find packet count of corresponding one hop neighbor */
- rcu_read_lock();
- hlist_for_each_entry_rcu(tmp_neigh_node, node,
- &orig_neigh_node->neigh_list, list) {
+ if (tmp_neigh_node->if_incoming != if_incoming)
+ continue;
- if (!compare_eth(tmp_neigh_node->addr,
- orig_neigh_node->orig))
- continue;
+ if (!atomic_inc_not_zero(&tmp_neigh_node->refcount))
+ continue;
- if (tmp_neigh_node->if_incoming != if_incoming)
- continue;
+ neigh_node = tmp_neigh_node;
+ break;
+ }
+ rcu_read_unlock();
- if (!atomic_inc_not_zero(&tmp_neigh_node->refcount))
- continue;
+ if (!neigh_node)
+ neigh_node = create_neighbor(orig_neigh_node,
+ orig_neigh_node,
+ orig_neigh_node->orig,
+ if_incoming);
- neigh_node = tmp_neigh_node;
- }
- rcu_read_unlock();
+ if (!neigh_node)
+ goto out;
- if (!neigh_node)
- neigh_node = create_neighbor(orig_neigh_node,
- orig_neigh_node,
- orig_neigh_node->orig,
- if_incoming);
- if (!neigh_node)
- goto out;
- }
+ /* if orig_node is direct neighbour update neigh_node last_valid */
+ if (orig_node == orig_neigh_node)
+ neigh_node->last_valid = jiffies;
orig_node->last_valid = jiffies;
+ /* find packet count of corresponding one hop neighbor */
spin_lock_bh(&orig_node->ogm_cnt_lock);
orig_eq_count = orig_neigh_node->bcast_own_sum[if_incoming->if_num];
neigh_rq_count = neigh_node->real_packet_count;
@@ -372,9 +346,9 @@ out:
}
/* copy primary address for bonding */
-static void bonding_save_primary(struct orig_node *orig_node,
+static void bonding_save_primary(const struct orig_node *orig_node,
struct orig_node *orig_neigh_node,
- struct batman_packet *batman_packet)
+ const struct batman_packet *batman_packet)
{
if (!(batman_packet->flags & PRIMARIES_FIRST_HOP))
return;
@@ -382,19 +356,18 @@ static void bonding_save_primary(struct orig_node *orig_node,
memcpy(orig_neigh_node->primary_addr, orig_node->orig, ETH_ALEN);
}
-static void update_orig(struct bat_priv *bat_priv,
- struct orig_node *orig_node,
- struct ethhdr *ethhdr,
- struct batman_packet *batman_packet,
+static void update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node,
+ const struct ethhdr *ethhdr,
+ const struct batman_packet *batman_packet,
struct hard_iface *if_incoming,
- unsigned char *hna_buff, int hna_buff_len,
+ const unsigned char *tt_buff, int tt_buff_len,
char is_duplicate)
{
struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
struct neigh_node *router = NULL;
struct orig_node *orig_node_tmp;
struct hlist_node *node;
- int tmp_hna_buff_len;
+ int tmp_tt_buff_len;
uint8_t bcast_own_sum_orig, bcast_own_sum_neigh;
bat_dbg(DBG_BATMAN, bat_priv, "update_originator(): "
@@ -459,18 +432,18 @@ static void update_orig(struct bat_priv *bat_priv,
bonding_candidate_add(orig_node, neigh_node);
- tmp_hna_buff_len = (hna_buff_len > batman_packet->num_hna * ETH_ALEN ?
- batman_packet->num_hna * ETH_ALEN : hna_buff_len);
+ tmp_tt_buff_len = (tt_buff_len > batman_packet->num_tt * ETH_ALEN ?
+ batman_packet->num_tt * ETH_ALEN : tt_buff_len);
/* if this neighbor already is our next hop there is nothing
* to change */
router = orig_node_get_router(orig_node);
if (router == neigh_node)
- goto update_hna;
+ goto update_tt;
/* if this neighbor does not offer a better TQ we won't consider it */
if (router && (router->tq_avg > neigh_node->tq_avg))
- goto update_hna;
+ goto update_tt;
/* if the TQ is the same and the link not more symetric we
* won't consider it either */
@@ -488,16 +461,16 @@ static void update_orig(struct bat_priv *bat_priv,
spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock);
if (bcast_own_sum_orig >= bcast_own_sum_neigh)
- goto update_hna;
+ goto update_tt;
}
update_routes(bat_priv, orig_node, neigh_node,
- hna_buff, tmp_hna_buff_len);
+ tt_buff, tmp_tt_buff_len);
goto update_gw;
-update_hna:
+update_tt:
update_routes(bat_priv, orig_node, router,
- hna_buff, tmp_hna_buff_len);
+ tt_buff, tmp_tt_buff_len);
update_gw:
if (orig_node->gw_flags != batman_packet->gw_flags)
@@ -555,9 +528,9 @@ static int window_protected(struct bat_priv *bat_priv,
* -1 the packet is old and has been received while the seqno window
* was protected. Caller should drop it.
*/
-static char count_real_packets(struct ethhdr *ethhdr,
- struct batman_packet *batman_packet,
- struct hard_iface *if_incoming)
+static char count_real_packets(const struct ethhdr *ethhdr,
+ const struct batman_packet *batman_packet,
+ const struct hard_iface *if_incoming)
{
struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
struct orig_node *orig_node;
@@ -619,9 +592,9 @@ out:
return ret;
}
-void receive_bat_packet(struct ethhdr *ethhdr,
+void receive_bat_packet(const struct ethhdr *ethhdr,
struct batman_packet *batman_packet,
- unsigned char *hna_buff, int hna_buff_len,
+ const unsigned char *tt_buff, int tt_buff_len,
struct hard_iface *if_incoming)
{
struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
@@ -688,7 +661,7 @@ void receive_bat_packet(struct ethhdr *ethhdr,
hard_iface->net_dev->dev_addr))
is_my_oldorig = 1;
- if (compare_eth(ethhdr->h_source, broadcast_addr))
+ if (is_broadcast_ether_addr(ethhdr->h_source))
is_broadcast = 1;
}
rcu_read_unlock();
@@ -725,17 +698,16 @@ void receive_bat_packet(struct ethhdr *ethhdr,
/* neighbor has to indicate direct link and it has to
* come via the corresponding interface */
- /* if received seqno equals last send seqno save new
- * seqno for bidirectional check */
+ /* save packet seqno for bidirectional check */
if (has_directlink_flag &&
compare_eth(if_incoming->net_dev->dev_addr,
- batman_packet->orig) &&
- (batman_packet->seqno - if_incoming_seqno + 2 == 0)) {
+ batman_packet->orig)) {
offset = if_incoming->if_num * NUM_WORDS;
spin_lock_bh(&orig_neigh_node->ogm_cnt_lock);
word = &(orig_neigh_node->bcast_own[offset]);
- bit_mark(word, 0);
+ bit_mark(word,
+ if_incoming_seqno - batman_packet->seqno - 2);
orig_neigh_node->bcast_own_sum[if_incoming->if_num] =
bit_packet_count(word);
spin_unlock_bh(&orig_neigh_node->ogm_cnt_lock);
@@ -818,14 +790,14 @@ void receive_bat_packet(struct ethhdr *ethhdr,
((orig_node->last_real_seqno == batman_packet->seqno) &&
(orig_node->last_ttl - 3 <= batman_packet->ttl))))
update_orig(bat_priv, orig_node, ethhdr, batman_packet,
- if_incoming, hna_buff, hna_buff_len, is_duplicate);
+ if_incoming, tt_buff, tt_buff_len, is_duplicate);
/* is single hop (direct) neighbor */
if (is_single_hop_neigh) {
/* mark direct link on incoming interface */
schedule_forward_packet(orig_node, ethhdr, batman_packet,
- 1, hna_buff_len, if_incoming);
+ 1, tt_buff_len, if_incoming);
bat_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: "
"rebroadcast neighbor packet with direct link flag\n");
@@ -848,7 +820,7 @@ void receive_bat_packet(struct ethhdr *ethhdr,
bat_dbg(DBG_BATMAN, bat_priv,
"Forwarding packet: rebroadcast originator packet\n");
schedule_forward_packet(orig_node, ethhdr, batman_packet,
- 0, hna_buff_len, if_incoming);
+ 0, tt_buff_len, if_incoming);
out_neigh:
if ((orig_neigh_node) && (!is_single_hop_neigh))
@@ -904,6 +876,7 @@ int recv_bat_packet(struct sk_buff *skb, struct hard_iface *hard_iface)
static int recv_my_icmp_packet(struct bat_priv *bat_priv,
struct sk_buff *skb, size_t icmp_len)
{
+ struct hard_iface *primary_if = NULL;
struct orig_node *orig_node = NULL;
struct neigh_node *router = NULL;
struct icmp_packet_rr *icmp_packet;
@@ -917,7 +890,8 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv,
goto out;
}
- if (!bat_priv->primary_if)
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
goto out;
/* answer echo request (ping) */
@@ -937,8 +911,7 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv,
icmp_packet = (struct icmp_packet_rr *)skb->data;
memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
- memcpy(icmp_packet->orig,
- bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+ memcpy(icmp_packet->orig, primary_if->net_dev->dev_addr, ETH_ALEN);
icmp_packet->msg_type = ECHO_REPLY;
icmp_packet->ttl = TTL;
@@ -946,6 +919,8 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv,
ret = NET_RX_SUCCESS;
out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
if (router)
neigh_node_free_ref(router);
if (orig_node)
@@ -956,6 +931,7 @@ out:
static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv,
struct sk_buff *skb)
{
+ struct hard_iface *primary_if = NULL;
struct orig_node *orig_node = NULL;
struct neigh_node *router = NULL;
struct icmp_packet *icmp_packet;
@@ -971,7 +947,8 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv,
goto out;
}
- if (!bat_priv->primary_if)
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
goto out;
/* get routing information */
@@ -990,8 +967,7 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv,
icmp_packet = (struct icmp_packet *)skb->data;
memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
- memcpy(icmp_packet->orig,
- bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+ memcpy(icmp_packet->orig, primary_if->net_dev->dev_addr, ETH_ALEN);
icmp_packet->msg_type = TTL_EXCEEDED;
icmp_packet->ttl = TTL;
@@ -999,6 +975,8 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv,
ret = NET_RX_SUCCESS;
out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
if (router)
neigh_node_free_ref(router);
if (orig_node)
@@ -1095,7 +1073,7 @@ out:
* This method rotates the bonding list and increases the
* returned router's refcount. */
static struct neigh_node *find_bond_router(struct orig_node *primary_orig,
- struct hard_iface *recv_if)
+ const struct hard_iface *recv_if)
{
struct neigh_node *tmp_neigh_node;
struct neigh_node *router = NULL, *first_candidate = NULL;
@@ -1146,7 +1124,7 @@ out:
*
* Increases the returned router's refcount */
static struct neigh_node *find_ifalter_router(struct orig_node *primary_orig,
- struct hard_iface *recv_if)
+ const struct hard_iface *recv_if)
{
struct neigh_node *tmp_neigh_node;
struct neigh_node *router = NULL, *first_candidate = NULL;
@@ -1194,7 +1172,7 @@ static struct neigh_node *find_ifalter_router(struct orig_node *primary_orig,
* refcount.*/
struct neigh_node *find_router(struct bat_priv *bat_priv,
struct orig_node *orig_node,
- struct hard_iface *recv_if)
+ const struct hard_iface *recv_if)
{
struct orig_node *primary_orig_node;
struct orig_node *router_orig;
@@ -1207,7 +1185,7 @@ struct neigh_node *find_router(struct bat_priv *bat_priv,
router = orig_node_get_router(orig_node);
if (!router)
- return NULL;
+ goto err;
/* without bonding, the first node should
* always choose the default router. */
@@ -1216,10 +1194,8 @@ struct neigh_node *find_router(struct bat_priv *bat_priv,
rcu_read_lock();
/* select default router to output */
router_orig = router->orig_node;
- if (!router_orig) {
- rcu_read_unlock();
- return NULL;
- }
+ if (!router_orig)
+ goto err_unlock;
if ((!recv_if) && (!bonding_enabled))
goto return_router;
@@ -1260,8 +1236,17 @@ struct neigh_node *find_router(struct bat_priv *bat_priv,
router = find_ifalter_router(primary_orig_node, recv_if);
return_router:
+ if (router && router->if_incoming->if_status != IF_ACTIVE)
+ goto err_unlock;
+
rcu_read_unlock();
return router;
+err_unlock:
+ rcu_read_unlock();
+err:
+ if (router)
+ neigh_node_free_ref(router);
+ return NULL;
}
static int check_unicast_packet(struct sk_buff *skb, int hdr_size)
@@ -1310,13 +1295,10 @@ int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
}
/* get routing information */
- rcu_read_lock();
orig_node = orig_hash_find(bat_priv, unicast_packet->dest);
if (!orig_node)
- goto unlock;
-
- rcu_read_unlock();
+ goto out;
/* find_router() increases neigh_nodes refcount if found. */
neigh_node = find_router(bat_priv, orig_node, recv_if);
@@ -1362,10 +1344,7 @@ int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
/* route it */
send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
ret = NET_RX_SUCCESS;
- goto out;
-unlock:
- rcu_read_unlock();
out:
if (neigh_node)
neigh_node_free_ref(neigh_node);
@@ -1377,7 +1356,7 @@ out:
int recv_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
{
struct unicast_packet *unicast_packet;
- int hdr_size = sizeof(struct unicast_packet);
+ int hdr_size = sizeof(*unicast_packet);
if (check_unicast_packet(skb, hdr_size) < 0)
return NET_RX_DROP;
@@ -1397,7 +1376,7 @@ int recv_ucast_frag_packet(struct sk_buff *skb, struct hard_iface *recv_if)
{
struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface);
struct unicast_frag_packet *unicast_packet;
- int hdr_size = sizeof(struct unicast_frag_packet);
+ int hdr_size = sizeof(*unicast_packet);
struct sk_buff *new_skb = NULL;
int ret;
@@ -1433,7 +1412,7 @@ int recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
struct orig_node *orig_node = NULL;
struct bcast_packet *bcast_packet;
struct ethhdr *ethhdr;
- int hdr_size = sizeof(struct bcast_packet);
+ int hdr_size = sizeof(*bcast_packet);
int ret = NET_RX_DROP;
int32_t seq_diff;
@@ -1464,13 +1443,10 @@ int recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
if (bcast_packet->ttl < 2)
goto out;
- rcu_read_lock();
orig_node = orig_hash_find(bat_priv, bcast_packet->orig);
if (!orig_node)
- goto rcu_unlock;
-
- rcu_read_unlock();
+ goto out;
spin_lock_bh(&orig_node->bcast_seqno_lock);
@@ -1501,9 +1477,6 @@ int recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
ret = NET_RX_SUCCESS;
goto out;
-rcu_unlock:
- rcu_read_unlock();
- goto out;
spin_unlock:
spin_unlock_bh(&orig_node->bcast_seqno_lock);
out:
@@ -1517,7 +1490,7 @@ int recv_vis_packet(struct sk_buff *skb, struct hard_iface *recv_if)
struct vis_packet *vis_packet;
struct ethhdr *ethhdr;
struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface);
- int hdr_size = sizeof(struct vis_packet);
+ int hdr_size = sizeof(*vis_packet);
/* keep skb linear */
if (skb_linearize(skb) < 0)
diff --git a/net/batman-adv/routing.h b/net/batman-adv/routing.h
index b5a064c88a4f..0ce03923ec05 100644
--- a/net/batman-adv/routing.h
+++ b/net/batman-adv/routing.h
@@ -23,13 +23,13 @@
#define _NET_BATMAN_ADV_ROUTING_H_
void slide_own_bcast_window(struct hard_iface *hard_iface);
-void receive_bat_packet(struct ethhdr *ethhdr,
- struct batman_packet *batman_packet,
- unsigned char *hna_buff, int hna_buff_len,
- struct hard_iface *if_incoming);
+void receive_bat_packet(const struct ethhdr *ethhdr,
+ struct batman_packet *batman_packet,
+ const unsigned char *tt_buff, int tt_buff_len,
+ struct hard_iface *if_incoming);
void update_routes(struct bat_priv *bat_priv, struct orig_node *orig_node,
- struct neigh_node *neigh_node, unsigned char *hna_buff,
- int hna_buff_len);
+ struct neigh_node *neigh_node, const unsigned char *tt_buff,
+ int tt_buff_len);
int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if);
int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if);
int recv_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if);
@@ -39,7 +39,7 @@ int recv_vis_packet(struct sk_buff *skb, struct hard_iface *recv_if);
int recv_bat_packet(struct sk_buff *skb, struct hard_iface *recv_if);
struct neigh_node *find_router(struct bat_priv *bat_priv,
struct orig_node *orig_node,
- struct hard_iface *recv_if);
+ const struct hard_iface *recv_if);
void bonding_candidate_del(struct orig_node *orig_node,
struct neigh_node *neigh_node);
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index e78670c3c4b7..a1b8c3173a3f 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -33,14 +33,14 @@
static void send_outstanding_bcast_packet(struct work_struct *work);
/* apply hop penalty for a normal link */
-static uint8_t hop_penalty(const uint8_t tq, struct bat_priv *bat_priv)
+static uint8_t hop_penalty(uint8_t tq, const struct bat_priv *bat_priv)
{
int hop_penalty = atomic_read(&bat_priv->hop_penalty);
return (tq * (TQ_MAX_VALUE - hop_penalty)) / (TQ_MAX_VALUE);
}
/* when do we schedule our own packet to be sent */
-static unsigned long own_send_time(struct bat_priv *bat_priv)
+static unsigned long own_send_time(const struct bat_priv *bat_priv)
{
return jiffies + msecs_to_jiffies(
atomic_read(&bat_priv->orig_interval) -
@@ -55,9 +55,8 @@ static unsigned long forward_send_time(void)
/* send out an already prepared packet to the given address via the
* specified batman interface */
-int send_skb_packet(struct sk_buff *skb,
- struct hard_iface *hard_iface,
- uint8_t *dst_addr)
+int send_skb_packet(struct sk_buff *skb, struct hard_iface *hard_iface,
+ const uint8_t *dst_addr)
{
struct ethhdr *ethhdr;
@@ -74,7 +73,7 @@ int send_skb_packet(struct sk_buff *skb,
}
/* push to the ethernet header. */
- if (my_skb_head_push(skb, sizeof(struct ethhdr)) < 0)
+ if (my_skb_head_push(skb, sizeof(*ethhdr)) < 0)
goto send_skb_err;
skb_reset_mac_header(skb);
@@ -121,7 +120,7 @@ static void send_packet_to_if(struct forw_packet *forw_packet,
/* adjust all flags and log packets */
while (aggregated_packet(buff_pos,
forw_packet->packet_len,
- batman_packet->num_hna)) {
+ batman_packet->num_tt)) {
/* we might have aggregated direct link packets with an
* ordinary base packet */
@@ -145,8 +144,8 @@ static void send_packet_to_if(struct forw_packet *forw_packet,
hard_iface->net_dev->name,
hard_iface->net_dev->dev_addr);
- buff_pos += sizeof(struct batman_packet) +
- (batman_packet->num_hna * ETH_ALEN);
+ buff_pos += sizeof(*batman_packet) +
+ (batman_packet->num_tt * ETH_ALEN);
packet_num++;
batman_packet = (struct batman_packet *)
(forw_packet->skb->data + buff_pos);
@@ -221,19 +220,18 @@ static void rebuild_batman_packet(struct bat_priv *bat_priv,
unsigned char *new_buff;
struct batman_packet *batman_packet;
- new_len = sizeof(struct batman_packet) +
- (bat_priv->num_local_hna * ETH_ALEN);
+ new_len = sizeof(*batman_packet) + (bat_priv->num_local_tt * ETH_ALEN);
new_buff = kmalloc(new_len, GFP_ATOMIC);
/* keep old buffer if kmalloc should fail */
if (new_buff) {
memcpy(new_buff, hard_iface->packet_buff,
- sizeof(struct batman_packet));
+ sizeof(*batman_packet));
batman_packet = (struct batman_packet *)new_buff;
- batman_packet->num_hna = hna_local_fill_buffer(bat_priv,
- new_buff + sizeof(struct batman_packet),
- new_len - sizeof(struct batman_packet));
+ batman_packet->num_tt = tt_local_fill_buffer(bat_priv,
+ new_buff + sizeof(*batman_packet),
+ new_len - sizeof(*batman_packet));
kfree(hard_iface->packet_buff);
hard_iface->packet_buff = new_buff;
@@ -244,6 +242,7 @@ static void rebuild_batman_packet(struct bat_priv *bat_priv,
void schedule_own_packet(struct hard_iface *hard_iface)
{
struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
+ struct hard_iface *primary_if;
unsigned long send_time;
struct batman_packet *batman_packet;
int vis_server;
@@ -253,6 +252,7 @@ void schedule_own_packet(struct hard_iface *hard_iface)
return;
vis_server = atomic_read(&bat_priv->vis_mode);
+ primary_if = primary_if_get_selected(bat_priv);
/**
* the interface gets activated here to avoid race conditions between
@@ -264,9 +264,9 @@ void schedule_own_packet(struct hard_iface *hard_iface)
if (hard_iface->if_status == IF_TO_BE_ACTIVATED)
hard_iface->if_status = IF_ACTIVE;
- /* if local hna has changed and interface is a primary interface */
- if ((atomic_read(&bat_priv->hna_local_changed)) &&
- (hard_iface == bat_priv->primary_if))
+ /* if local tt has changed and interface is a primary interface */
+ if ((atomic_read(&bat_priv->tt_local_changed)) &&
+ (hard_iface == primary_if))
rebuild_batman_packet(bat_priv, hard_iface);
/**
@@ -284,12 +284,12 @@ void schedule_own_packet(struct hard_iface *hard_iface)
else
batman_packet->flags &= ~VIS_SERVER;
- if ((hard_iface == bat_priv->primary_if) &&
+ if ((hard_iface == primary_if) &&
(atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER))
batman_packet->gw_flags =
(uint8_t)atomic_read(&bat_priv->gw_bandwidth);
else
- batman_packet->gw_flags = 0;
+ batman_packet->gw_flags = NO_FLAGS;
atomic_inc(&hard_iface->seqno);
@@ -299,12 +299,15 @@ void schedule_own_packet(struct hard_iface *hard_iface)
hard_iface->packet_buff,
hard_iface->packet_len,
hard_iface, 1, send_time);
+
+ if (primary_if)
+ hardif_free_ref(primary_if);
}
void schedule_forward_packet(struct orig_node *orig_node,
- struct ethhdr *ethhdr,
+ const struct ethhdr *ethhdr,
struct batman_packet *batman_packet,
- uint8_t directlink, int hna_buff_len,
+ uint8_t directlink, int tt_buff_len,
struct hard_iface *if_incoming)
{
struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
@@ -364,7 +367,7 @@ void schedule_forward_packet(struct orig_node *orig_node,
send_time = forward_send_time();
add_bat_packet_to_list(bat_priv,
(unsigned char *)batman_packet,
- sizeof(struct batman_packet) + hna_buff_len,
+ sizeof(*batman_packet) + tt_buff_len,
if_incoming, 0, send_time);
}
@@ -372,6 +375,8 @@ static void forw_packet_free(struct forw_packet *forw_packet)
{
if (forw_packet->skb)
kfree_skb(forw_packet->skb);
+ if (forw_packet->if_incoming)
+ hardif_free_ref(forw_packet->if_incoming);
kfree(forw_packet);
}
@@ -393,7 +398,6 @@ static void _add_bcast_packet_to_list(struct bat_priv *bat_priv,
send_time);
}
-#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0)
/* add a broadcast packet to the queue and setup timers. broadcast packets
* are sent multiple times to increase probability for beeing received.
*
@@ -402,36 +406,40 @@ static void _add_bcast_packet_to_list(struct bat_priv *bat_priv,
*
* The skb is not consumed, so the caller should make sure that the
* skb is freed. */
-int add_bcast_packet_to_list(struct bat_priv *bat_priv, struct sk_buff *skb)
+int add_bcast_packet_to_list(struct bat_priv *bat_priv,
+ const struct sk_buff *skb)
{
+ struct hard_iface *primary_if = NULL;
struct forw_packet *forw_packet;
struct bcast_packet *bcast_packet;
+ struct sk_buff *newskb;
if (!atomic_dec_not_zero(&bat_priv->bcast_queue_left)) {
bat_dbg(DBG_BATMAN, bat_priv, "bcast packet queue full\n");
goto out;
}
- if (!bat_priv->primary_if)
- goto out;
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
+ goto out_and_inc;
- forw_packet = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC);
+ forw_packet = kmalloc(sizeof(*forw_packet), GFP_ATOMIC);
if (!forw_packet)
goto out_and_inc;
- skb = skb_copy(skb, GFP_ATOMIC);
- if (!skb)
+ newskb = skb_copy(skb, GFP_ATOMIC);
+ if (!newskb)
goto packet_free;
/* as we have a copy now, it is safe to decrease the TTL */
- bcast_packet = (struct bcast_packet *)skb->data;
+ bcast_packet = (struct bcast_packet *)newskb->data;
bcast_packet->ttl--;
- skb_reset_mac_header(skb);
+ skb_reset_mac_header(newskb);
- forw_packet->skb = skb;
- forw_packet->if_incoming = bat_priv->primary_if;
+ forw_packet->skb = newskb;
+ forw_packet->if_incoming = primary_if;
/* how often did we send the bcast packet ? */
forw_packet->num_packets = 0;
@@ -444,6 +452,8 @@ packet_free:
out_and_inc:
atomic_inc(&bat_priv->bcast_queue_left);
out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
return NETDEV_TX_BUSY;
}
@@ -527,10 +537,11 @@ out:
}
void purge_outstanding_packets(struct bat_priv *bat_priv,
- struct hard_iface *hard_iface)
+ const struct hard_iface *hard_iface)
{
struct forw_packet *forw_packet;
struct hlist_node *tmp_node, *safe_tmp_node;
+ bool pending;
if (hard_iface)
bat_dbg(DBG_BATMAN, bat_priv,
@@ -559,8 +570,13 @@ void purge_outstanding_packets(struct bat_priv *bat_priv,
* send_outstanding_bcast_packet() will lock the list to
* delete the item from the list
*/
- cancel_delayed_work_sync(&forw_packet->delayed_work);
+ pending = cancel_delayed_work_sync(&forw_packet->delayed_work);
spin_lock_bh(&bat_priv->forw_bcast_list_lock);
+
+ if (pending) {
+ hlist_del(&forw_packet->list);
+ forw_packet_free(forw_packet);
+ }
}
spin_unlock_bh(&bat_priv->forw_bcast_list_lock);
@@ -583,8 +599,13 @@ void purge_outstanding_packets(struct bat_priv *bat_priv,
* send_outstanding_bat_packet() will lock the list to
* delete the item from the list
*/
- cancel_delayed_work_sync(&forw_packet->delayed_work);
+ pending = cancel_delayed_work_sync(&forw_packet->delayed_work);
spin_lock_bh(&bat_priv->forw_bat_list_lock);
+
+ if (pending) {
+ hlist_del(&forw_packet->list);
+ forw_packet_free(forw_packet);
+ }
}
spin_unlock_bh(&bat_priv->forw_bat_list_lock);
}
diff --git a/net/batman-adv/send.h b/net/batman-adv/send.h
index 7b2ff19c05e7..eceab870024d 100644
--- a/net/batman-adv/send.h
+++ b/net/batman-adv/send.h
@@ -22,18 +22,18 @@
#ifndef _NET_BATMAN_ADV_SEND_H_
#define _NET_BATMAN_ADV_SEND_H_
-int send_skb_packet(struct sk_buff *skb,
- struct hard_iface *hard_iface,
- uint8_t *dst_addr);
+int send_skb_packet(struct sk_buff *skb, struct hard_iface *hard_iface,
+ const uint8_t *dst_addr);
void schedule_own_packet(struct hard_iface *hard_iface);
void schedule_forward_packet(struct orig_node *orig_node,
- struct ethhdr *ethhdr,
+ const struct ethhdr *ethhdr,
struct batman_packet *batman_packet,
- uint8_t directlink, int hna_buff_len,
+ uint8_t directlink, int tt_buff_len,
struct hard_iface *if_outgoing);
-int add_bcast_packet_to_list(struct bat_priv *bat_priv, struct sk_buff *skb);
+int add_bcast_packet_to_list(struct bat_priv *bat_priv,
+ const struct sk_buff *skb);
void send_outstanding_bat_packet(struct work_struct *work);
void purge_outstanding_packets(struct bat_priv *bat_priv,
- struct hard_iface *hard_iface);
+ const struct hard_iface *hard_iface);
#endif /* _NET_BATMAN_ADV_SEND_H_ */
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index 1f6f756bc584..b8d3f248efdc 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -43,8 +43,6 @@ static void bat_get_drvinfo(struct net_device *dev,
static u32 bat_get_msglevel(struct net_device *dev);
static void bat_set_msglevel(struct net_device *dev, u32 value);
static u32 bat_get_link(struct net_device *dev);
-static u32 bat_get_rx_csum(struct net_device *dev);
-static int bat_set_rx_csum(struct net_device *dev, u32 data);
static const struct ethtool_ops bat_ethtool_ops = {
.get_settings = bat_get_settings,
@@ -52,8 +50,6 @@ static const struct ethtool_ops bat_ethtool_ops = {
.get_msglevel = bat_get_msglevel,
.set_msglevel = bat_set_msglevel,
.get_link = bat_get_link,
- .get_rx_csum = bat_get_rx_csum,
- .set_rx_csum = bat_set_rx_csum
};
int my_skb_head_push(struct sk_buff *skb, unsigned int len)
@@ -76,169 +72,371 @@ int my_skb_head_push(struct sk_buff *skb, unsigned int len)
return 0;
}
-static void softif_neigh_free_rcu(struct rcu_head *rcu)
-{
- struct softif_neigh *softif_neigh;
-
- softif_neigh = container_of(rcu, struct softif_neigh, rcu);
- kfree(softif_neigh);
-}
-
static void softif_neigh_free_ref(struct softif_neigh *softif_neigh)
{
if (atomic_dec_and_test(&softif_neigh->refcount))
- call_rcu(&softif_neigh->rcu, softif_neigh_free_rcu);
+ kfree_rcu(softif_neigh, rcu);
}
-static struct softif_neigh *softif_neigh_get_selected(struct bat_priv *bat_priv)
+static void softif_neigh_vid_free_rcu(struct rcu_head *rcu)
{
- struct softif_neigh *neigh;
-
- rcu_read_lock();
- neigh = rcu_dereference(bat_priv->softif_neigh);
-
- if (neigh && !atomic_inc_not_zero(&neigh->refcount))
- neigh = NULL;
-
- rcu_read_unlock();
- return neigh;
-}
+ struct softif_neigh_vid *softif_neigh_vid;
+ struct softif_neigh *softif_neigh;
+ struct hlist_node *node, *node_tmp;
+ struct bat_priv *bat_priv;
-static void softif_neigh_select(struct bat_priv *bat_priv,
- struct softif_neigh *new_neigh)
-{
- struct softif_neigh *curr_neigh;
+ softif_neigh_vid = container_of(rcu, struct softif_neigh_vid, rcu);
+ bat_priv = softif_neigh_vid->bat_priv;
spin_lock_bh(&bat_priv->softif_neigh_lock);
-
- if (new_neigh && !atomic_inc_not_zero(&new_neigh->refcount))
- new_neigh = NULL;
-
- curr_neigh = bat_priv->softif_neigh;
- rcu_assign_pointer(bat_priv->softif_neigh, new_neigh);
-
- if (curr_neigh)
- softif_neigh_free_ref(curr_neigh);
-
+ hlist_for_each_entry_safe(softif_neigh, node, node_tmp,
+ &softif_neigh_vid->softif_neigh_list, list) {
+ hlist_del_rcu(&softif_neigh->list);
+ softif_neigh_free_ref(softif_neigh);
+ }
spin_unlock_bh(&bat_priv->softif_neigh_lock);
+
+ kfree(softif_neigh_vid);
}
-static void softif_neigh_deselect(struct bat_priv *bat_priv)
+static void softif_neigh_vid_free_ref(struct softif_neigh_vid *softif_neigh_vid)
{
- softif_neigh_select(bat_priv, NULL);
+ if (atomic_dec_and_test(&softif_neigh_vid->refcount))
+ call_rcu(&softif_neigh_vid->rcu, softif_neigh_vid_free_rcu);
}
-void softif_neigh_purge(struct bat_priv *bat_priv)
+static struct softif_neigh_vid *softif_neigh_vid_get(struct bat_priv *bat_priv,
+ short vid)
{
- struct softif_neigh *softif_neigh, *curr_softif_neigh;
- struct hlist_node *node, *node_tmp;
- char do_deselect = 0;
-
- curr_softif_neigh = softif_neigh_get_selected(bat_priv);
-
- spin_lock_bh(&bat_priv->softif_neigh_lock);
-
- hlist_for_each_entry_safe(softif_neigh, node, node_tmp,
- &bat_priv->softif_neigh_list, list) {
+ struct softif_neigh_vid *softif_neigh_vid;
+ struct hlist_node *node;
- if ((!time_after(jiffies, softif_neigh->last_seen +
- msecs_to_jiffies(SOFTIF_NEIGH_TIMEOUT))) &&
- (atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE))
+ rcu_read_lock();
+ hlist_for_each_entry_rcu(softif_neigh_vid, node,
+ &bat_priv->softif_neigh_vids, list) {
+ if (softif_neigh_vid->vid != vid)
continue;
- if (curr_softif_neigh == softif_neigh) {
- bat_dbg(DBG_ROUTES, bat_priv,
- "Current mesh exit point '%pM' vanished "
- "(vid: %d).\n",
- softif_neigh->addr, softif_neigh->vid);
- do_deselect = 1;
- }
+ if (!atomic_inc_not_zero(&softif_neigh_vid->refcount))
+ continue;
- hlist_del_rcu(&softif_neigh->list);
- softif_neigh_free_ref(softif_neigh);
+ goto out;
}
- spin_unlock_bh(&bat_priv->softif_neigh_lock);
+ softif_neigh_vid = kzalloc(sizeof(*softif_neigh_vid), GFP_ATOMIC);
+ if (!softif_neigh_vid)
+ goto out;
- /* soft_neigh_deselect() needs to acquire the softif_neigh_lock */
- if (do_deselect)
- softif_neigh_deselect(bat_priv);
+ softif_neigh_vid->vid = vid;
+ softif_neigh_vid->bat_priv = bat_priv;
- if (curr_softif_neigh)
- softif_neigh_free_ref(curr_softif_neigh);
+ /* initialize with 2 - caller decrements counter by one */
+ atomic_set(&softif_neigh_vid->refcount, 2);
+ INIT_HLIST_HEAD(&softif_neigh_vid->softif_neigh_list);
+ INIT_HLIST_NODE(&softif_neigh_vid->list);
+ spin_lock_bh(&bat_priv->softif_neigh_vid_lock);
+ hlist_add_head_rcu(&softif_neigh_vid->list,
+ &bat_priv->softif_neigh_vids);
+ spin_unlock_bh(&bat_priv->softif_neigh_vid_lock);
+
+out:
+ rcu_read_unlock();
+ return softif_neigh_vid;
}
static struct softif_neigh *softif_neigh_get(struct bat_priv *bat_priv,
- uint8_t *addr, short vid)
+ const uint8_t *addr, short vid)
{
- struct softif_neigh *softif_neigh;
+ struct softif_neigh_vid *softif_neigh_vid;
+ struct softif_neigh *softif_neigh = NULL;
struct hlist_node *node;
+ softif_neigh_vid = softif_neigh_vid_get(bat_priv, vid);
+ if (!softif_neigh_vid)
+ goto out;
+
rcu_read_lock();
hlist_for_each_entry_rcu(softif_neigh, node,
- &bat_priv->softif_neigh_list, list) {
+ &softif_neigh_vid->softif_neigh_list,
+ list) {
if (!compare_eth(softif_neigh->addr, addr))
continue;
- if (softif_neigh->vid != vid)
- continue;
-
if (!atomic_inc_not_zero(&softif_neigh->refcount))
continue;
softif_neigh->last_seen = jiffies;
- goto out;
+ goto unlock;
}
- softif_neigh = kzalloc(sizeof(struct softif_neigh), GFP_ATOMIC);
+ softif_neigh = kzalloc(sizeof(*softif_neigh), GFP_ATOMIC);
if (!softif_neigh)
- goto out;
+ goto unlock;
memcpy(softif_neigh->addr, addr, ETH_ALEN);
- softif_neigh->vid = vid;
softif_neigh->last_seen = jiffies;
/* initialize with 2 - caller decrements counter by one */
atomic_set(&softif_neigh->refcount, 2);
INIT_HLIST_NODE(&softif_neigh->list);
spin_lock_bh(&bat_priv->softif_neigh_lock);
- hlist_add_head_rcu(&softif_neigh->list, &bat_priv->softif_neigh_list);
+ hlist_add_head_rcu(&softif_neigh->list,
+ &softif_neigh_vid->softif_neigh_list);
spin_unlock_bh(&bat_priv->softif_neigh_lock);
+unlock:
+ rcu_read_unlock();
out:
+ if (softif_neigh_vid)
+ softif_neigh_vid_free_ref(softif_neigh_vid);
+ return softif_neigh;
+}
+
+static struct softif_neigh *softif_neigh_get_selected(
+ struct softif_neigh_vid *softif_neigh_vid)
+{
+ struct softif_neigh *softif_neigh;
+
+ rcu_read_lock();
+ softif_neigh = rcu_dereference(softif_neigh_vid->softif_neigh);
+
+ if (softif_neigh && !atomic_inc_not_zero(&softif_neigh->refcount))
+ softif_neigh = NULL;
+
rcu_read_unlock();
return softif_neigh;
}
+static struct softif_neigh *softif_neigh_vid_get_selected(
+ struct bat_priv *bat_priv,
+ short vid)
+{
+ struct softif_neigh_vid *softif_neigh_vid;
+ struct softif_neigh *softif_neigh = NULL;
+
+ softif_neigh_vid = softif_neigh_vid_get(bat_priv, vid);
+ if (!softif_neigh_vid)
+ goto out;
+
+ softif_neigh = softif_neigh_get_selected(softif_neigh_vid);
+out:
+ if (softif_neigh_vid)
+ softif_neigh_vid_free_ref(softif_neigh_vid);
+ return softif_neigh;
+}
+
+static void softif_neigh_vid_select(struct bat_priv *bat_priv,
+ struct softif_neigh *new_neigh,
+ short vid)
+{
+ struct softif_neigh_vid *softif_neigh_vid;
+ struct softif_neigh *curr_neigh;
+
+ softif_neigh_vid = softif_neigh_vid_get(bat_priv, vid);
+ if (!softif_neigh_vid)
+ goto out;
+
+ spin_lock_bh(&bat_priv->softif_neigh_lock);
+
+ if (new_neigh && !atomic_inc_not_zero(&new_neigh->refcount))
+ new_neigh = NULL;
+
+ curr_neigh = rcu_dereference_protected(softif_neigh_vid->softif_neigh,
+ 1);
+ rcu_assign_pointer(softif_neigh_vid->softif_neigh, new_neigh);
+
+ if ((curr_neigh) && (!new_neigh))
+ bat_dbg(DBG_ROUTES, bat_priv,
+ "Removing mesh exit point on vid: %d (prev: %pM).\n",
+ vid, curr_neigh->addr);
+ else if ((curr_neigh) && (new_neigh))
+ bat_dbg(DBG_ROUTES, bat_priv,
+ "Changing mesh exit point on vid: %d from %pM "
+ "to %pM.\n", vid, curr_neigh->addr, new_neigh->addr);
+ else if ((!curr_neigh) && (new_neigh))
+ bat_dbg(DBG_ROUTES, bat_priv,
+ "Setting mesh exit point on vid: %d to %pM.\n",
+ vid, new_neigh->addr);
+
+ if (curr_neigh)
+ softif_neigh_free_ref(curr_neigh);
+
+ spin_unlock_bh(&bat_priv->softif_neigh_lock);
+
+out:
+ if (softif_neigh_vid)
+ softif_neigh_vid_free_ref(softif_neigh_vid);
+}
+
+static void softif_neigh_vid_deselect(struct bat_priv *bat_priv,
+ struct softif_neigh_vid *softif_neigh_vid)
+{
+ struct softif_neigh *curr_neigh;
+ struct softif_neigh *softif_neigh = NULL, *softif_neigh_tmp;
+ struct hard_iface *primary_if = NULL;
+ struct hlist_node *node;
+
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
+ goto out;
+
+ /* find new softif_neigh immediately to avoid temporary loops */
+ rcu_read_lock();
+ curr_neigh = rcu_dereference(softif_neigh_vid->softif_neigh);
+
+ hlist_for_each_entry_rcu(softif_neigh_tmp, node,
+ &softif_neigh_vid->softif_neigh_list,
+ list) {
+ if (softif_neigh_tmp == curr_neigh)
+ continue;
+
+ /* we got a neighbor but its mac is 'bigger' than ours */
+ if (memcmp(primary_if->net_dev->dev_addr,
+ softif_neigh_tmp->addr, ETH_ALEN) < 0)
+ continue;
+
+ if (!atomic_inc_not_zero(&softif_neigh_tmp->refcount))
+ continue;
+
+ softif_neigh = softif_neigh_tmp;
+ goto unlock;
+ }
+
+unlock:
+ rcu_read_unlock();
+out:
+ softif_neigh_vid_select(bat_priv, softif_neigh, softif_neigh_vid->vid);
+
+ if (primary_if)
+ hardif_free_ref(primary_if);
+ if (softif_neigh)
+ softif_neigh_free_ref(softif_neigh);
+}
+
int softif_neigh_seq_print_text(struct seq_file *seq, void *offset)
{
struct net_device *net_dev = (struct net_device *)seq->private;
struct bat_priv *bat_priv = netdev_priv(net_dev);
+ struct softif_neigh_vid *softif_neigh_vid;
struct softif_neigh *softif_neigh;
- struct hlist_node *node;
+ struct hard_iface *primary_if;
+ struct hlist_node *node, *node_tmp;
struct softif_neigh *curr_softif_neigh;
+ int ret = 0, last_seen_secs, last_seen_msecs;
- if (!bat_priv->primary_if) {
- return seq_printf(seq, "BATMAN mesh %s disabled - "
- "please specify interfaces to enable it\n",
- net_dev->name);
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if) {
+ ret = seq_printf(seq, "BATMAN mesh %s disabled - "
+ "please specify interfaces to enable it\n",
+ net_dev->name);
+ goto out;
+ }
+
+ if (primary_if->if_status != IF_ACTIVE) {
+ ret = seq_printf(seq, "BATMAN mesh %s "
+ "disabled - primary interface not active\n",
+ net_dev->name);
+ goto out;
}
seq_printf(seq, "Softif neighbor list (%s)\n", net_dev->name);
- curr_softif_neigh = softif_neigh_get_selected(bat_priv);
rcu_read_lock();
- hlist_for_each_entry_rcu(softif_neigh, node,
- &bat_priv->softif_neigh_list, list)
- seq_printf(seq, "%s %pM (vid: %d)\n",
- curr_softif_neigh == softif_neigh
- ? "=>" : " ", softif_neigh->addr,
- softif_neigh->vid);
+ hlist_for_each_entry_rcu(softif_neigh_vid, node,
+ &bat_priv->softif_neigh_vids, list) {
+ seq_printf(seq, " %-15s %s on vid: %d\n",
+ "Originator", "last-seen", softif_neigh_vid->vid);
+
+ curr_softif_neigh = softif_neigh_get_selected(softif_neigh_vid);
+
+ hlist_for_each_entry_rcu(softif_neigh, node_tmp,
+ &softif_neigh_vid->softif_neigh_list,
+ list) {
+ last_seen_secs = jiffies_to_msecs(jiffies -
+ softif_neigh->last_seen) / 1000;
+ last_seen_msecs = jiffies_to_msecs(jiffies -
+ softif_neigh->last_seen) % 1000;
+ seq_printf(seq, "%s %pM %3i.%03is\n",
+ curr_softif_neigh == softif_neigh
+ ? "=>" : " ", softif_neigh->addr,
+ last_seen_secs, last_seen_msecs);
+ }
+
+ if (curr_softif_neigh)
+ softif_neigh_free_ref(curr_softif_neigh);
+
+ seq_printf(seq, "\n");
+ }
rcu_read_unlock();
- if (curr_softif_neigh)
- softif_neigh_free_ref(curr_softif_neigh);
- return 0;
+out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
+ return ret;
+}
+
+void softif_neigh_purge(struct bat_priv *bat_priv)
+{
+ struct softif_neigh *softif_neigh, *curr_softif_neigh;
+ struct softif_neigh_vid *softif_neigh_vid;
+ struct hlist_node *node, *node_tmp, *node_tmp2;
+ char do_deselect;
+
+ rcu_read_lock();
+ hlist_for_each_entry_rcu(softif_neigh_vid, node,
+ &bat_priv->softif_neigh_vids, list) {
+ if (!atomic_inc_not_zero(&softif_neigh_vid->refcount))
+ continue;
+
+ curr_softif_neigh = softif_neigh_get_selected(softif_neigh_vid);
+ do_deselect = 0;
+
+ spin_lock_bh(&bat_priv->softif_neigh_lock);
+ hlist_for_each_entry_safe(softif_neigh, node_tmp, node_tmp2,
+ &softif_neigh_vid->softif_neigh_list,
+ list) {
+ if ((!time_after(jiffies, softif_neigh->last_seen +
+ msecs_to_jiffies(SOFTIF_NEIGH_TIMEOUT))) &&
+ (atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE))
+ continue;
+
+ if (curr_softif_neigh == softif_neigh) {
+ bat_dbg(DBG_ROUTES, bat_priv,
+ "Current mesh exit point on vid: %d "
+ "'%pM' vanished.\n",
+ softif_neigh_vid->vid,
+ softif_neigh->addr);
+ do_deselect = 1;
+ }
+
+ hlist_del_rcu(&softif_neigh->list);
+ softif_neigh_free_ref(softif_neigh);
+ }
+ spin_unlock_bh(&bat_priv->softif_neigh_lock);
+
+ /* soft_neigh_vid_deselect() needs to acquire the
+ * softif_neigh_lock */
+ if (do_deselect)
+ softif_neigh_vid_deselect(bat_priv, softif_neigh_vid);
+
+ if (curr_softif_neigh)
+ softif_neigh_free_ref(curr_softif_neigh);
+
+ softif_neigh_vid_free_ref(softif_neigh_vid);
+ }
+ rcu_read_unlock();
+
+ spin_lock_bh(&bat_priv->softif_neigh_vid_lock);
+ hlist_for_each_entry_safe(softif_neigh_vid, node, node_tmp,
+ &bat_priv->softif_neigh_vids, list) {
+ if (!hlist_empty(&softif_neigh_vid->softif_neigh_list))
+ continue;
+
+ hlist_del_rcu(&softif_neigh_vid->list);
+ softif_neigh_vid_free_ref(softif_neigh_vid);
+ }
+ spin_unlock_bh(&bat_priv->softif_neigh_vid_lock);
+
}
static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev,
@@ -247,7 +445,8 @@ static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev,
struct bat_priv *bat_priv = netdev_priv(dev);
struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
struct batman_packet *batman_packet;
- struct softif_neigh *softif_neigh;
+ struct softif_neigh *softif_neigh = NULL;
+ struct hard_iface *primary_if = NULL;
struct softif_neigh *curr_softif_neigh = NULL;
if (ntohs(ethhdr->h_proto) == ETH_P_8021Q)
@@ -257,65 +456,52 @@ static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev,
batman_packet = (struct batman_packet *)(skb->data + ETH_HLEN);
if (batman_packet->version != COMPAT_VERSION)
- goto err;
+ goto out;
if (batman_packet->packet_type != BAT_PACKET)
- goto err;
+ goto out;
if (!(batman_packet->flags & PRIMARIES_FIRST_HOP))
- goto err;
+ goto out;
if (is_my_mac(batman_packet->orig))
- goto err;
+ goto out;
softif_neigh = softif_neigh_get(bat_priv, batman_packet->orig, vid);
-
if (!softif_neigh)
- goto err;
+ goto out;
- curr_softif_neigh = softif_neigh_get_selected(bat_priv);
+ curr_softif_neigh = softif_neigh_vid_get_selected(bat_priv, vid);
if (curr_softif_neigh == softif_neigh)
goto out;
- /* we got a neighbor but its mac is 'bigger' than ours */
- if (memcmp(bat_priv->primary_if->net_dev->dev_addr,
- softif_neigh->addr, ETH_ALEN) < 0)
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
goto out;
- /* switch to new 'smallest neighbor' */
- if ((curr_softif_neigh) &&
- (memcmp(softif_neigh->addr, curr_softif_neigh->addr,
- ETH_ALEN) < 0)) {
- bat_dbg(DBG_ROUTES, bat_priv,
- "Changing mesh exit point from %pM (vid: %d) "
- "to %pM (vid: %d).\n",
- curr_softif_neigh->addr,
- curr_softif_neigh->vid,
- softif_neigh->addr, softif_neigh->vid);
-
- softif_neigh_select(bat_priv, softif_neigh);
+ /* we got a neighbor but its mac is 'bigger' than ours */
+ if (memcmp(primary_if->net_dev->dev_addr,
+ softif_neigh->addr, ETH_ALEN) < 0)
goto out;
- }
/* close own batX device and use softif_neigh as exit node */
- if ((!curr_softif_neigh) &&
- (memcmp(softif_neigh->addr,
- bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN) < 0)) {
- bat_dbg(DBG_ROUTES, bat_priv,
- "Setting mesh exit point to %pM (vid: %d).\n",
- softif_neigh->addr, softif_neigh->vid);
-
- softif_neigh_select(bat_priv, softif_neigh);
+ if (!curr_softif_neigh) {
+ softif_neigh_vid_select(bat_priv, softif_neigh, vid);
goto out;
}
+ /* switch to new 'smallest neighbor' */
+ if (memcmp(softif_neigh->addr, curr_softif_neigh->addr, ETH_ALEN) < 0)
+ softif_neigh_vid_select(bat_priv, softif_neigh, vid);
+
out:
- softif_neigh_free_ref(softif_neigh);
-err:
kfree_skb(skb);
+ if (softif_neigh)
+ softif_neigh_free_ref(softif_neigh);
if (curr_softif_neigh)
softif_neigh_free_ref(curr_softif_neigh);
-
+ if (primary_if)
+ hardif_free_ref(primary_if);
return;
}
@@ -345,11 +531,11 @@ static int interface_set_mac_addr(struct net_device *dev, void *p)
if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;
- /* only modify hna-table if it has been initialised before */
+ /* only modify transtable if it has been initialised before */
if (atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE) {
- hna_local_remove(bat_priv, dev->dev_addr,
+ tt_local_remove(bat_priv, dev->dev_addr,
"mac address changed");
- hna_local_add(dev, addr->sa_data);
+ tt_local_add(dev, addr->sa_data);
}
memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
@@ -371,6 +557,7 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
{
struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
struct bat_priv *bat_priv = netdev_priv(soft_iface);
+ struct hard_iface *primary_if = NULL;
struct bcast_packet *bcast_packet;
struct vlan_ethhdr *vhdr;
struct softif_neigh *curr_softif_neigh = NULL;
@@ -401,12 +588,12 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
* if we have a another chosen mesh exit node in range
* it will transport the packets to the mesh
*/
- curr_softif_neigh = softif_neigh_get_selected(bat_priv);
- if ((curr_softif_neigh) && (curr_softif_neigh->vid == vid))
+ curr_softif_neigh = softif_neigh_vid_get_selected(bat_priv, vid);
+ if (curr_softif_neigh)
goto dropped;
/* TODO: check this for locks */
- hna_local_add(soft_iface, ethhdr->h_source);
+ tt_local_add(soft_iface, ethhdr->h_source);
if (is_multicast_ether_addr(ethhdr->h_dest)) {
ret = gw_is_target(bat_priv, skb);
@@ -420,10 +607,11 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
/* ethernet packet should be broadcasted */
if (do_bcast) {
- if (!bat_priv->primary_if)
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
goto dropped;
- if (my_skb_head_push(skb, sizeof(struct bcast_packet)) < 0)
+ if (my_skb_head_push(skb, sizeof(*bcast_packet)) < 0)
goto dropped;
bcast_packet = (struct bcast_packet *)skb->data;
@@ -436,7 +624,7 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
/* hw address of first interface is the orig mac because only
* this mac is known throughout the mesh */
memcpy(bcast_packet->orig,
- bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+ primary_if->net_dev->dev_addr, ETH_ALEN);
/* set broadcast sequence number */
bcast_packet->seqno =
@@ -466,6 +654,8 @@ dropped_freed:
end:
if (curr_softif_neigh)
softif_neigh_free_ref(curr_softif_neigh);
+ if (primary_if)
+ hardif_free_ref(primary_if);
return NETDEV_TX_OK;
}
@@ -507,8 +697,8 @@ void interface_rx(struct net_device *soft_iface,
* if we have a another chosen mesh exit node in range
* it will transport the packets to the non-mesh network
*/
- curr_softif_neigh = softif_neigh_get_selected(bat_priv);
- if (curr_softif_neigh && (curr_softif_neigh->vid == vid)) {
+ curr_softif_neigh = softif_neigh_vid_get_selected(bat_priv, vid);
+ if (curr_softif_neigh) {
skb_push(skb, hdr_size);
unicast_packet = (struct unicast_packet *)skb->data;
@@ -591,8 +781,8 @@ static void interface_setup(struct net_device *dev)
* have not been initialized yet
*/
dev->mtu = ETH_DATA_LEN;
- dev->hard_header_len = BAT_HEADER_LEN; /* reserve more space in the
- * skbuff for our header */
+ /* reserve more space in the skbuff for our header */
+ dev->hard_header_len = BAT_HEADER_LEN;
/* generate random address */
random_ether_addr(dev_addr);
@@ -600,24 +790,23 @@ static void interface_setup(struct net_device *dev)
SET_ETHTOOL_OPS(dev, &bat_ethtool_ops);
- memset(priv, 0, sizeof(struct bat_priv));
+ memset(priv, 0, sizeof(*priv));
}
-struct net_device *softif_create(char *name)
+struct net_device *softif_create(const char *name)
{
struct net_device *soft_iface;
struct bat_priv *bat_priv;
int ret;
- soft_iface = alloc_netdev(sizeof(struct bat_priv) , name,
- interface_setup);
+ soft_iface = alloc_netdev(sizeof(*bat_priv), name, interface_setup);
if (!soft_iface) {
pr_err("Unable to allocate the batman interface: %s\n", name);
goto out;
}
- ret = register_netdev(soft_iface);
+ ret = register_netdevice(soft_iface);
if (ret < 0) {
pr_err("Unable to register the batman interface '%s': %i\n",
name, ret);
@@ -641,11 +830,10 @@ struct net_device *softif_create(char *name)
atomic_set(&bat_priv->mesh_state, MESH_INACTIVE);
atomic_set(&bat_priv->bcast_seqno, 1);
- atomic_set(&bat_priv->hna_local_changed, 0);
+ atomic_set(&bat_priv->tt_local_changed, 0);
bat_priv->primary_if = NULL;
bat_priv->num_ifaces = 0;
- bat_priv->softif_neigh = NULL;
ret = sysfs_add_meshif(soft_iface);
if (ret < 0)
@@ -683,7 +871,7 @@ void softif_destroy(struct net_device *soft_iface)
unregister_netdevice(soft_iface);
}
-int softif_is_valid(struct net_device *net_dev)
+int softif_is_valid(const struct net_device *net_dev)
{
#ifdef HAVE_NET_DEVICE_OPS
if (net_dev->netdev_ops->ndo_start_xmit == interface_tx)
@@ -701,7 +889,7 @@ static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
cmd->supported = 0;
cmd->advertising = 0;
- cmd->speed = SPEED_10;
+ ethtool_cmd_speed_set(cmd, SPEED_10);
cmd->duplex = DUPLEX_FULL;
cmd->port = PORT_TP;
cmd->phy_address = 0;
@@ -735,13 +923,3 @@ static u32 bat_get_link(struct net_device *dev)
{
return 1;
}
-
-static u32 bat_get_rx_csum(struct net_device *dev)
-{
- return 0;
-}
-
-static int bat_set_rx_csum(struct net_device *dev, u32 data)
-{
- return -EOPNOTSUPP;
-}
diff --git a/net/batman-adv/soft-interface.h b/net/batman-adv/soft-interface.h
index 4789b6f2a0b3..c24906dd1d6a 100644
--- a/net/batman-adv/soft-interface.h
+++ b/net/batman-adv/soft-interface.h
@@ -29,8 +29,8 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface);
void interface_rx(struct net_device *soft_iface,
struct sk_buff *skb, struct hard_iface *recv_if,
int hdr_size);
-struct net_device *softif_create(char *name);
+struct net_device *softif_create(const char *name);
void softif_destroy(struct net_device *soft_iface);
-int softif_is_valid(struct net_device *net_dev);
+int softif_is_valid(const struct net_device *net_dev);
#endif /* _NET_BATMAN_ADV_SOFT_INTERFACE_H_ */
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 8d15b48d1692..561f76968d5e 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -22,43 +22,46 @@
#include "main.h"
#include "translation-table.h"
#include "soft-interface.h"
+#include "hard-interface.h"
#include "hash.h"
#include "originator.h"
-static void hna_local_purge(struct work_struct *work);
-static void _hna_global_del_orig(struct bat_priv *bat_priv,
- struct hna_global_entry *hna_global_entry,
- char *message);
+static void tt_local_purge(struct work_struct *work);
+static void _tt_global_del_orig(struct bat_priv *bat_priv,
+ struct tt_global_entry *tt_global_entry,
+ const char *message);
/* returns 1 if they are the same mac addr */
-static int compare_lhna(struct hlist_node *node, void *data2)
+static int compare_ltt(const struct hlist_node *node, const void *data2)
{
- void *data1 = container_of(node, struct hna_local_entry, hash_entry);
+ const void *data1 = container_of(node, struct tt_local_entry,
+ hash_entry);
return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0);
}
/* returns 1 if they are the same mac addr */
-static int compare_ghna(struct hlist_node *node, void *data2)
+static int compare_gtt(const struct hlist_node *node, const void *data2)
{
- void *data1 = container_of(node, struct hna_global_entry, hash_entry);
+ const void *data1 = container_of(node, struct tt_global_entry,
+ hash_entry);
return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0);
}
-static void hna_local_start_timer(struct bat_priv *bat_priv)
+static void tt_local_start_timer(struct bat_priv *bat_priv)
{
- INIT_DELAYED_WORK(&bat_priv->hna_work, hna_local_purge);
- queue_delayed_work(bat_event_workqueue, &bat_priv->hna_work, 10 * HZ);
+ INIT_DELAYED_WORK(&bat_priv->tt_work, tt_local_purge);
+ queue_delayed_work(bat_event_workqueue, &bat_priv->tt_work, 10 * HZ);
}
-static struct hna_local_entry *hna_local_hash_find(struct bat_priv *bat_priv,
- void *data)
+static struct tt_local_entry *tt_local_hash_find(struct bat_priv *bat_priv,
+ const void *data)
{
- struct hashtable_t *hash = bat_priv->hna_local_hash;
+ struct hashtable_t *hash = bat_priv->tt_local_hash;
struct hlist_head *head;
struct hlist_node *node;
- struct hna_local_entry *hna_local_entry, *hna_local_entry_tmp = NULL;
+ struct tt_local_entry *tt_local_entry, *tt_local_entry_tmp = NULL;
int index;
if (!hash)
@@ -68,26 +71,26 @@ static struct hna_local_entry *hna_local_hash_find(struct bat_priv *bat_priv,
head = &hash->table[index];
rcu_read_lock();
- hlist_for_each_entry_rcu(hna_local_entry, node, head, hash_entry) {
- if (!compare_eth(hna_local_entry, data))
+ hlist_for_each_entry_rcu(tt_local_entry, node, head, hash_entry) {
+ if (!compare_eth(tt_local_entry, data))
continue;
- hna_local_entry_tmp = hna_local_entry;
+ tt_local_entry_tmp = tt_local_entry;
break;
}
rcu_read_unlock();
- return hna_local_entry_tmp;
+ return tt_local_entry_tmp;
}
-static struct hna_global_entry *hna_global_hash_find(struct bat_priv *bat_priv,
- void *data)
+static struct tt_global_entry *tt_global_hash_find(struct bat_priv *bat_priv,
+ const void *data)
{
- struct hashtable_t *hash = bat_priv->hna_global_hash;
+ struct hashtable_t *hash = bat_priv->tt_global_hash;
struct hlist_head *head;
struct hlist_node *node;
- struct hna_global_entry *hna_global_entry;
- struct hna_global_entry *hna_global_entry_tmp = NULL;
+ struct tt_global_entry *tt_global_entry;
+ struct tt_global_entry *tt_global_entry_tmp = NULL;
int index;
if (!hash)
@@ -97,125 +100,125 @@ static struct hna_global_entry *hna_global_hash_find(struct bat_priv *bat_priv,
head = &hash->table[index];
rcu_read_lock();
- hlist_for_each_entry_rcu(hna_global_entry, node, head, hash_entry) {
- if (!compare_eth(hna_global_entry, data))
+ hlist_for_each_entry_rcu(tt_global_entry, node, head, hash_entry) {
+ if (!compare_eth(tt_global_entry, data))
continue;
- hna_global_entry_tmp = hna_global_entry;
+ tt_global_entry_tmp = tt_global_entry;
break;
}
rcu_read_unlock();
- return hna_global_entry_tmp;
+ return tt_global_entry_tmp;
}
-int hna_local_init(struct bat_priv *bat_priv)
+int tt_local_init(struct bat_priv *bat_priv)
{
- if (bat_priv->hna_local_hash)
+ if (bat_priv->tt_local_hash)
return 1;
- bat_priv->hna_local_hash = hash_new(1024);
+ bat_priv->tt_local_hash = hash_new(1024);
- if (!bat_priv->hna_local_hash)
+ if (!bat_priv->tt_local_hash)
return 0;
- atomic_set(&bat_priv->hna_local_changed, 0);
- hna_local_start_timer(bat_priv);
+ atomic_set(&bat_priv->tt_local_changed, 0);
+ tt_local_start_timer(bat_priv);
return 1;
}
-void hna_local_add(struct net_device *soft_iface, uint8_t *addr)
+void tt_local_add(struct net_device *soft_iface, const uint8_t *addr)
{
struct bat_priv *bat_priv = netdev_priv(soft_iface);
- struct hna_local_entry *hna_local_entry;
- struct hna_global_entry *hna_global_entry;
+ struct tt_local_entry *tt_local_entry;
+ struct tt_global_entry *tt_global_entry;
int required_bytes;
- spin_lock_bh(&bat_priv->hna_lhash_lock);
- hna_local_entry = hna_local_hash_find(bat_priv, addr);
- spin_unlock_bh(&bat_priv->hna_lhash_lock);
+ spin_lock_bh(&bat_priv->tt_lhash_lock);
+ tt_local_entry = tt_local_hash_find(bat_priv, addr);
+ spin_unlock_bh(&bat_priv->tt_lhash_lock);
- if (hna_local_entry) {
- hna_local_entry->last_seen = jiffies;
+ if (tt_local_entry) {
+ tt_local_entry->last_seen = jiffies;
return;
}
/* only announce as many hosts as possible in the batman-packet and
- space in batman_packet->num_hna That also should give a limit to
+ space in batman_packet->num_tt That also should give a limit to
MAC-flooding. */
- required_bytes = (bat_priv->num_local_hna + 1) * ETH_ALEN;
+ required_bytes = (bat_priv->num_local_tt + 1) * ETH_ALEN;
required_bytes += BAT_PACKET_LEN;
if ((required_bytes > ETH_DATA_LEN) ||
(atomic_read(&bat_priv->aggregated_ogms) &&
required_bytes > MAX_AGGREGATION_BYTES) ||
- (bat_priv->num_local_hna + 1 > 255)) {
+ (bat_priv->num_local_tt + 1 > 255)) {
bat_dbg(DBG_ROUTES, bat_priv,
- "Can't add new local hna entry (%pM): "
- "number of local hna entries exceeds packet size\n",
+ "Can't add new local tt entry (%pM): "
+ "number of local tt entries exceeds packet size\n",
addr);
return;
}
bat_dbg(DBG_ROUTES, bat_priv,
- "Creating new local hna entry: %pM\n", addr);
+ "Creating new local tt entry: %pM\n", addr);
- hna_local_entry = kmalloc(sizeof(struct hna_local_entry), GFP_ATOMIC);
- if (!hna_local_entry)
+ tt_local_entry = kmalloc(sizeof(*tt_local_entry), GFP_ATOMIC);
+ if (!tt_local_entry)
return;
- memcpy(hna_local_entry->addr, addr, ETH_ALEN);
- hna_local_entry->last_seen = jiffies;
+ memcpy(tt_local_entry->addr, addr, ETH_ALEN);
+ tt_local_entry->last_seen = jiffies;
/* the batman interface mac address should never be purged */
if (compare_eth(addr, soft_iface->dev_addr))
- hna_local_entry->never_purge = 1;
+ tt_local_entry->never_purge = 1;
else
- hna_local_entry->never_purge = 0;
+ tt_local_entry->never_purge = 0;
- spin_lock_bh(&bat_priv->hna_lhash_lock);
+ spin_lock_bh(&bat_priv->tt_lhash_lock);
- hash_add(bat_priv->hna_local_hash, compare_lhna, choose_orig,
- hna_local_entry, &hna_local_entry->hash_entry);
- bat_priv->num_local_hna++;
- atomic_set(&bat_priv->hna_local_changed, 1);
+ hash_add(bat_priv->tt_local_hash, compare_ltt, choose_orig,
+ tt_local_entry, &tt_local_entry->hash_entry);
+ bat_priv->num_local_tt++;
+ atomic_set(&bat_priv->tt_local_changed, 1);
- spin_unlock_bh(&bat_priv->hna_lhash_lock);
+ spin_unlock_bh(&bat_priv->tt_lhash_lock);
/* remove address from global hash if present */
- spin_lock_bh(&bat_priv->hna_ghash_lock);
+ spin_lock_bh(&bat_priv->tt_ghash_lock);
- hna_global_entry = hna_global_hash_find(bat_priv, addr);
+ tt_global_entry = tt_global_hash_find(bat_priv, addr);
- if (hna_global_entry)
- _hna_global_del_orig(bat_priv, hna_global_entry,
- "local hna received");
+ if (tt_global_entry)
+ _tt_global_del_orig(bat_priv, tt_global_entry,
+ "local tt received");
- spin_unlock_bh(&bat_priv->hna_ghash_lock);
+ spin_unlock_bh(&bat_priv->tt_ghash_lock);
}
-int hna_local_fill_buffer(struct bat_priv *bat_priv,
+int tt_local_fill_buffer(struct bat_priv *bat_priv,
unsigned char *buff, int buff_len)
{
- struct hashtable_t *hash = bat_priv->hna_local_hash;
- struct hna_local_entry *hna_local_entry;
+ struct hashtable_t *hash = bat_priv->tt_local_hash;
+ struct tt_local_entry *tt_local_entry;
struct hlist_node *node;
struct hlist_head *head;
int i, count = 0;
- spin_lock_bh(&bat_priv->hna_lhash_lock);
+ spin_lock_bh(&bat_priv->tt_lhash_lock);
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
rcu_read_lock();
- hlist_for_each_entry_rcu(hna_local_entry, node,
+ hlist_for_each_entry_rcu(tt_local_entry, node,
head, hash_entry) {
if (buff_len < (count + 1) * ETH_ALEN)
break;
- memcpy(buff + (count * ETH_ALEN), hna_local_entry->addr,
+ memcpy(buff + (count * ETH_ALEN), tt_local_entry->addr,
ETH_ALEN);
count++;
@@ -223,37 +226,47 @@ int hna_local_fill_buffer(struct bat_priv *bat_priv,
rcu_read_unlock();
}
- /* if we did not get all new local hnas see you next time ;-) */
- if (count == bat_priv->num_local_hna)
- atomic_set(&bat_priv->hna_local_changed, 0);
+ /* if we did not get all new local tts see you next time ;-) */
+ if (count == bat_priv->num_local_tt)
+ atomic_set(&bat_priv->tt_local_changed, 0);
- spin_unlock_bh(&bat_priv->hna_lhash_lock);
+ spin_unlock_bh(&bat_priv->tt_lhash_lock);
return count;
}
-int hna_local_seq_print_text(struct seq_file *seq, void *offset)
+int tt_local_seq_print_text(struct seq_file *seq, void *offset)
{
struct net_device *net_dev = (struct net_device *)seq->private;
struct bat_priv *bat_priv = netdev_priv(net_dev);
- struct hashtable_t *hash = bat_priv->hna_local_hash;
- struct hna_local_entry *hna_local_entry;
+ struct hashtable_t *hash = bat_priv->tt_local_hash;
+ struct tt_local_entry *tt_local_entry;
+ struct hard_iface *primary_if;
struct hlist_node *node;
struct hlist_head *head;
size_t buf_size, pos;
char *buff;
- int i;
+ int i, ret = 0;
- if (!bat_priv->primary_if) {
- return seq_printf(seq, "BATMAN mesh %s disabled - "
- "please specify interfaces to enable it\n",
- net_dev->name);
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if) {
+ ret = seq_printf(seq, "BATMAN mesh %s disabled - "
+ "please specify interfaces to enable it\n",
+ net_dev->name);
+ goto out;
+ }
+
+ if (primary_if->if_status != IF_ACTIVE) {
+ ret = seq_printf(seq, "BATMAN mesh %s disabled - "
+ "primary interface not active\n",
+ net_dev->name);
+ goto out;
}
seq_printf(seq, "Locally retrieved addresses (from %s) "
- "announced via HNA:\n",
+ "announced via TT:\n",
net_dev->name);
- spin_lock_bh(&bat_priv->hna_lhash_lock);
+ spin_lock_bh(&bat_priv->tt_lhash_lock);
buf_size = 1;
/* Estimate length for: " * xx:xx:xx:xx:xx:xx\n" */
@@ -268,8 +281,9 @@ int hna_local_seq_print_text(struct seq_file *seq, void *offset)
buff = kmalloc(buf_size, GFP_ATOMIC);
if (!buff) {
- spin_unlock_bh(&bat_priv->hna_lhash_lock);
- return -ENOMEM;
+ spin_unlock_bh(&bat_priv->tt_lhash_lock);
+ ret = -ENOMEM;
+ goto out;
}
buff[0] = '\0';
@@ -279,211 +293,224 @@ int hna_local_seq_print_text(struct seq_file *seq, void *offset)
head = &hash->table[i];
rcu_read_lock();
- hlist_for_each_entry_rcu(hna_local_entry, node,
+ hlist_for_each_entry_rcu(tt_local_entry, node,
head, hash_entry) {
pos += snprintf(buff + pos, 22, " * %pM\n",
- hna_local_entry->addr);
+ tt_local_entry->addr);
}
rcu_read_unlock();
}
- spin_unlock_bh(&bat_priv->hna_lhash_lock);
+ spin_unlock_bh(&bat_priv->tt_lhash_lock);
seq_printf(seq, "%s", buff);
kfree(buff);
- return 0;
+out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
+ return ret;
}
-static void _hna_local_del(struct hlist_node *node, void *arg)
+static void _tt_local_del(struct hlist_node *node, void *arg)
{
- struct bat_priv *bat_priv = (struct bat_priv *)arg;
- void *data = container_of(node, struct hna_local_entry, hash_entry);
+ struct bat_priv *bat_priv = arg;
+ void *data = container_of(node, struct tt_local_entry, hash_entry);
kfree(data);
- bat_priv->num_local_hna--;
- atomic_set(&bat_priv->hna_local_changed, 1);
+ bat_priv->num_local_tt--;
+ atomic_set(&bat_priv->tt_local_changed, 1);
}
-static void hna_local_del(struct bat_priv *bat_priv,
- struct hna_local_entry *hna_local_entry,
- char *message)
+static void tt_local_del(struct bat_priv *bat_priv,
+ struct tt_local_entry *tt_local_entry,
+ const char *message)
{
- bat_dbg(DBG_ROUTES, bat_priv, "Deleting local hna entry (%pM): %s\n",
- hna_local_entry->addr, message);
+ bat_dbg(DBG_ROUTES, bat_priv, "Deleting local tt entry (%pM): %s\n",
+ tt_local_entry->addr, message);
- hash_remove(bat_priv->hna_local_hash, compare_lhna, choose_orig,
- hna_local_entry->addr);
- _hna_local_del(&hna_local_entry->hash_entry, bat_priv);
+ hash_remove(bat_priv->tt_local_hash, compare_ltt, choose_orig,
+ tt_local_entry->addr);
+ _tt_local_del(&tt_local_entry->hash_entry, bat_priv);
}
-void hna_local_remove(struct bat_priv *bat_priv,
- uint8_t *addr, char *message)
+void tt_local_remove(struct bat_priv *bat_priv,
+ const uint8_t *addr, const char *message)
{
- struct hna_local_entry *hna_local_entry;
+ struct tt_local_entry *tt_local_entry;
- spin_lock_bh(&bat_priv->hna_lhash_lock);
+ spin_lock_bh(&bat_priv->tt_lhash_lock);
- hna_local_entry = hna_local_hash_find(bat_priv, addr);
+ tt_local_entry = tt_local_hash_find(bat_priv, addr);
- if (hna_local_entry)
- hna_local_del(bat_priv, hna_local_entry, message);
+ if (tt_local_entry)
+ tt_local_del(bat_priv, tt_local_entry, message);
- spin_unlock_bh(&bat_priv->hna_lhash_lock);
+ spin_unlock_bh(&bat_priv->tt_lhash_lock);
}
-static void hna_local_purge(struct work_struct *work)
+static void tt_local_purge(struct work_struct *work)
{
struct delayed_work *delayed_work =
container_of(work, struct delayed_work, work);
struct bat_priv *bat_priv =
- container_of(delayed_work, struct bat_priv, hna_work);
- struct hashtable_t *hash = bat_priv->hna_local_hash;
- struct hna_local_entry *hna_local_entry;
+ container_of(delayed_work, struct bat_priv, tt_work);
+ struct hashtable_t *hash = bat_priv->tt_local_hash;
+ struct tt_local_entry *tt_local_entry;
struct hlist_node *node, *node_tmp;
struct hlist_head *head;
unsigned long timeout;
int i;
- spin_lock_bh(&bat_priv->hna_lhash_lock);
+ spin_lock_bh(&bat_priv->tt_lhash_lock);
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
- hlist_for_each_entry_safe(hna_local_entry, node, node_tmp,
+ hlist_for_each_entry_safe(tt_local_entry, node, node_tmp,
head, hash_entry) {
- if (hna_local_entry->never_purge)
+ if (tt_local_entry->never_purge)
continue;
- timeout = hna_local_entry->last_seen;
- timeout += LOCAL_HNA_TIMEOUT * HZ;
+ timeout = tt_local_entry->last_seen;
+ timeout += TT_LOCAL_TIMEOUT * HZ;
if (time_before(jiffies, timeout))
continue;
- hna_local_del(bat_priv, hna_local_entry,
+ tt_local_del(bat_priv, tt_local_entry,
"address timed out");
}
}
- spin_unlock_bh(&bat_priv->hna_lhash_lock);
- hna_local_start_timer(bat_priv);
+ spin_unlock_bh(&bat_priv->tt_lhash_lock);
+ tt_local_start_timer(bat_priv);
}
-void hna_local_free(struct bat_priv *bat_priv)
+void tt_local_free(struct bat_priv *bat_priv)
{
- if (!bat_priv->hna_local_hash)
+ if (!bat_priv->tt_local_hash)
return;
- cancel_delayed_work_sync(&bat_priv->hna_work);
- hash_delete(bat_priv->hna_local_hash, _hna_local_del, bat_priv);
- bat_priv->hna_local_hash = NULL;
+ cancel_delayed_work_sync(&bat_priv->tt_work);
+ hash_delete(bat_priv->tt_local_hash, _tt_local_del, bat_priv);
+ bat_priv->tt_local_hash = NULL;
}
-int hna_global_init(struct bat_priv *bat_priv)
+int tt_global_init(struct bat_priv *bat_priv)
{
- if (bat_priv->hna_global_hash)
+ if (bat_priv->tt_global_hash)
return 1;
- bat_priv->hna_global_hash = hash_new(1024);
+ bat_priv->tt_global_hash = hash_new(1024);
- if (!bat_priv->hna_global_hash)
+ if (!bat_priv->tt_global_hash)
return 0;
return 1;
}
-void hna_global_add_orig(struct bat_priv *bat_priv,
+void tt_global_add_orig(struct bat_priv *bat_priv,
struct orig_node *orig_node,
- unsigned char *hna_buff, int hna_buff_len)
+ const unsigned char *tt_buff, int tt_buff_len)
{
- struct hna_global_entry *hna_global_entry;
- struct hna_local_entry *hna_local_entry;
- int hna_buff_count = 0;
- unsigned char *hna_ptr;
+ struct tt_global_entry *tt_global_entry;
+ struct tt_local_entry *tt_local_entry;
+ int tt_buff_count = 0;
+ const unsigned char *tt_ptr;
- while ((hna_buff_count + 1) * ETH_ALEN <= hna_buff_len) {
- spin_lock_bh(&bat_priv->hna_ghash_lock);
+ while ((tt_buff_count + 1) * ETH_ALEN <= tt_buff_len) {
+ spin_lock_bh(&bat_priv->tt_ghash_lock);
- hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN);
- hna_global_entry = hna_global_hash_find(bat_priv, hna_ptr);
+ tt_ptr = tt_buff + (tt_buff_count * ETH_ALEN);
+ tt_global_entry = tt_global_hash_find(bat_priv, tt_ptr);
- if (!hna_global_entry) {
- spin_unlock_bh(&bat_priv->hna_ghash_lock);
+ if (!tt_global_entry) {
+ spin_unlock_bh(&bat_priv->tt_ghash_lock);
- hna_global_entry =
- kmalloc(sizeof(struct hna_global_entry),
- GFP_ATOMIC);
+ tt_global_entry = kmalloc(sizeof(*tt_global_entry),
+ GFP_ATOMIC);
- if (!hna_global_entry)
+ if (!tt_global_entry)
break;
- memcpy(hna_global_entry->addr, hna_ptr, ETH_ALEN);
+ memcpy(tt_global_entry->addr, tt_ptr, ETH_ALEN);
bat_dbg(DBG_ROUTES, bat_priv,
- "Creating new global hna entry: "
+ "Creating new global tt entry: "
"%pM (via %pM)\n",
- hna_global_entry->addr, orig_node->orig);
+ tt_global_entry->addr, orig_node->orig);
- spin_lock_bh(&bat_priv->hna_ghash_lock);
- hash_add(bat_priv->hna_global_hash, compare_ghna,
- choose_orig, hna_global_entry,
- &hna_global_entry->hash_entry);
+ spin_lock_bh(&bat_priv->tt_ghash_lock);
+ hash_add(bat_priv->tt_global_hash, compare_gtt,
+ choose_orig, tt_global_entry,
+ &tt_global_entry->hash_entry);
}
- hna_global_entry->orig_node = orig_node;
- spin_unlock_bh(&bat_priv->hna_ghash_lock);
+ tt_global_entry->orig_node = orig_node;
+ spin_unlock_bh(&bat_priv->tt_ghash_lock);
/* remove address from local hash if present */
- spin_lock_bh(&bat_priv->hna_lhash_lock);
+ spin_lock_bh(&bat_priv->tt_lhash_lock);
- hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN);
- hna_local_entry = hna_local_hash_find(bat_priv, hna_ptr);
+ tt_ptr = tt_buff + (tt_buff_count * ETH_ALEN);
+ tt_local_entry = tt_local_hash_find(bat_priv, tt_ptr);
- if (hna_local_entry)
- hna_local_del(bat_priv, hna_local_entry,
- "global hna received");
+ if (tt_local_entry)
+ tt_local_del(bat_priv, tt_local_entry,
+ "global tt received");
- spin_unlock_bh(&bat_priv->hna_lhash_lock);
+ spin_unlock_bh(&bat_priv->tt_lhash_lock);
- hna_buff_count++;
+ tt_buff_count++;
}
/* initialize, and overwrite if malloc succeeds */
- orig_node->hna_buff = NULL;
- orig_node->hna_buff_len = 0;
-
- if (hna_buff_len > 0) {
- orig_node->hna_buff = kmalloc(hna_buff_len, GFP_ATOMIC);
- if (orig_node->hna_buff) {
- memcpy(orig_node->hna_buff, hna_buff, hna_buff_len);
- orig_node->hna_buff_len = hna_buff_len;
+ orig_node->tt_buff = NULL;
+ orig_node->tt_buff_len = 0;
+
+ if (tt_buff_len > 0) {
+ orig_node->tt_buff = kmalloc(tt_buff_len, GFP_ATOMIC);
+ if (orig_node->tt_buff) {
+ memcpy(orig_node->tt_buff, tt_buff, tt_buff_len);
+ orig_node->tt_buff_len = tt_buff_len;
}
}
}
-int hna_global_seq_print_text(struct seq_file *seq, void *offset)
+int tt_global_seq_print_text(struct seq_file *seq, void *offset)
{
struct net_device *net_dev = (struct net_device *)seq->private;
struct bat_priv *bat_priv = netdev_priv(net_dev);
- struct hashtable_t *hash = bat_priv->hna_global_hash;
- struct hna_global_entry *hna_global_entry;
+ struct hashtable_t *hash = bat_priv->tt_global_hash;
+ struct tt_global_entry *tt_global_entry;
+ struct hard_iface *primary_if;
struct hlist_node *node;
struct hlist_head *head;
size_t buf_size, pos;
char *buff;
- int i;
+ int i, ret = 0;
- if (!bat_priv->primary_if) {
- return seq_printf(seq, "BATMAN mesh %s disabled - "
- "please specify interfaces to enable it\n",
- net_dev->name);
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if) {
+ ret = seq_printf(seq, "BATMAN mesh %s disabled - please "
+ "specify interfaces to enable it\n",
+ net_dev->name);
+ goto out;
}
- seq_printf(seq, "Globally announced HNAs received via the mesh %s\n",
+ if (primary_if->if_status != IF_ACTIVE) {
+ ret = seq_printf(seq, "BATMAN mesh %s disabled - "
+ "primary interface not active\n",
+ net_dev->name);
+ goto out;
+ }
+
+ seq_printf(seq,
+ "Globally announced TT entries received via the mesh %s\n",
net_dev->name);
- spin_lock_bh(&bat_priv->hna_ghash_lock);
+ spin_lock_bh(&bat_priv->tt_ghash_lock);
buf_size = 1;
/* Estimate length for: " * xx:xx:xx:xx:xx:xx via xx:xx:xx:xx:xx:xx\n"*/
@@ -498,8 +525,9 @@ int hna_global_seq_print_text(struct seq_file *seq, void *offset)
buff = kmalloc(buf_size, GFP_ATOMIC);
if (!buff) {
- spin_unlock_bh(&bat_priv->hna_ghash_lock);
- return -ENOMEM;
+ spin_unlock_bh(&bat_priv->tt_ghash_lock);
+ ret = -ENOMEM;
+ goto out;
}
buff[0] = '\0';
pos = 0;
@@ -508,101 +536,105 @@ int hna_global_seq_print_text(struct seq_file *seq, void *offset)
head = &hash->table[i];
rcu_read_lock();
- hlist_for_each_entry_rcu(hna_global_entry, node,
+ hlist_for_each_entry_rcu(tt_global_entry, node,
head, hash_entry) {
pos += snprintf(buff + pos, 44,
" * %pM via %pM\n",
- hna_global_entry->addr,
- hna_global_entry->orig_node->orig);
+ tt_global_entry->addr,
+ tt_global_entry->orig_node->orig);
}
rcu_read_unlock();
}
- spin_unlock_bh(&bat_priv->hna_ghash_lock);
+ spin_unlock_bh(&bat_priv->tt_ghash_lock);
seq_printf(seq, "%s", buff);
kfree(buff);
- return 0;
+out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
+ return ret;
}
-static void _hna_global_del_orig(struct bat_priv *bat_priv,
- struct hna_global_entry *hna_global_entry,
- char *message)
+static void _tt_global_del_orig(struct bat_priv *bat_priv,
+ struct tt_global_entry *tt_global_entry,
+ const char *message)
{
bat_dbg(DBG_ROUTES, bat_priv,
- "Deleting global hna entry %pM (via %pM): %s\n",
- hna_global_entry->addr, hna_global_entry->orig_node->orig,
+ "Deleting global tt entry %pM (via %pM): %s\n",
+ tt_global_entry->addr, tt_global_entry->orig_node->orig,
message);
- hash_remove(bat_priv->hna_global_hash, compare_ghna, choose_orig,
- hna_global_entry->addr);
- kfree(hna_global_entry);
+ hash_remove(bat_priv->tt_global_hash, compare_gtt, choose_orig,
+ tt_global_entry->addr);
+ kfree(tt_global_entry);
}
-void hna_global_del_orig(struct bat_priv *bat_priv,
- struct orig_node *orig_node, char *message)
+void tt_global_del_orig(struct bat_priv *bat_priv,
+ struct orig_node *orig_node, const char *message)
{
- struct hna_global_entry *hna_global_entry;
- int hna_buff_count = 0;
- unsigned char *hna_ptr;
+ struct tt_global_entry *tt_global_entry;
+ int tt_buff_count = 0;
+ unsigned char *tt_ptr;
- if (orig_node->hna_buff_len == 0)
+ if (orig_node->tt_buff_len == 0)
return;
- spin_lock_bh(&bat_priv->hna_ghash_lock);
+ spin_lock_bh(&bat_priv->tt_ghash_lock);
- while ((hna_buff_count + 1) * ETH_ALEN <= orig_node->hna_buff_len) {
- hna_ptr = orig_node->hna_buff + (hna_buff_count * ETH_ALEN);
- hna_global_entry = hna_global_hash_find(bat_priv, hna_ptr);
+ while ((tt_buff_count + 1) * ETH_ALEN <= orig_node->tt_buff_len) {
+ tt_ptr = orig_node->tt_buff + (tt_buff_count * ETH_ALEN);
+ tt_global_entry = tt_global_hash_find(bat_priv, tt_ptr);
- if ((hna_global_entry) &&
- (hna_global_entry->orig_node == orig_node))
- _hna_global_del_orig(bat_priv, hna_global_entry,
+ if ((tt_global_entry) &&
+ (tt_global_entry->orig_node == orig_node))
+ _tt_global_del_orig(bat_priv, tt_global_entry,
message);
- hna_buff_count++;
+ tt_buff_count++;
}
- spin_unlock_bh(&bat_priv->hna_ghash_lock);
+ spin_unlock_bh(&bat_priv->tt_ghash_lock);
- orig_node->hna_buff_len = 0;
- kfree(orig_node->hna_buff);
- orig_node->hna_buff = NULL;
+ orig_node->tt_buff_len = 0;
+ kfree(orig_node->tt_buff);
+ orig_node->tt_buff = NULL;
}
-static void hna_global_del(struct hlist_node *node, void *arg)
+static void tt_global_del(struct hlist_node *node, void *arg)
{
- void *data = container_of(node, struct hna_global_entry, hash_entry);
+ void *data = container_of(node, struct tt_global_entry, hash_entry);
kfree(data);
}
-void hna_global_free(struct bat_priv *bat_priv)
+void tt_global_free(struct bat_priv *bat_priv)
{
- if (!bat_priv->hna_global_hash)
+ if (!bat_priv->tt_global_hash)
return;
- hash_delete(bat_priv->hna_global_hash, hna_global_del, NULL);
- bat_priv->hna_global_hash = NULL;
+ hash_delete(bat_priv->tt_global_hash, tt_global_del, NULL);
+ bat_priv->tt_global_hash = NULL;
}
-struct orig_node *transtable_search(struct bat_priv *bat_priv, uint8_t *addr)
+struct orig_node *transtable_search(struct bat_priv *bat_priv,
+ const uint8_t *addr)
{
- struct hna_global_entry *hna_global_entry;
+ struct tt_global_entry *tt_global_entry;
struct orig_node *orig_node = NULL;
- spin_lock_bh(&bat_priv->hna_ghash_lock);
- hna_global_entry = hna_global_hash_find(bat_priv, addr);
+ spin_lock_bh(&bat_priv->tt_ghash_lock);
+ tt_global_entry = tt_global_hash_find(bat_priv, addr);
- if (!hna_global_entry)
+ if (!tt_global_entry)
goto out;
- if (!atomic_inc_not_zero(&hna_global_entry->orig_node->refcount))
+ if (!atomic_inc_not_zero(&tt_global_entry->orig_node->refcount))
goto out;
- orig_node = hna_global_entry->orig_node;
+ orig_node = tt_global_entry->orig_node;
out:
- spin_unlock_bh(&bat_priv->hna_ghash_lock);
+ spin_unlock_bh(&bat_priv->tt_ghash_lock);
return orig_node;
}
diff --git a/net/batman-adv/translation-table.h b/net/batman-adv/translation-table.h
index f19931ca1457..0f2b9905cfc4 100644
--- a/net/batman-adv/translation-table.h
+++ b/net/batman-adv/translation-table.h
@@ -22,22 +22,23 @@
#ifndef _NET_BATMAN_ADV_TRANSLATION_TABLE_H_
#define _NET_BATMAN_ADV_TRANSLATION_TABLE_H_
-int hna_local_init(struct bat_priv *bat_priv);
-void hna_local_add(struct net_device *soft_iface, uint8_t *addr);
-void hna_local_remove(struct bat_priv *bat_priv,
- uint8_t *addr, char *message);
-int hna_local_fill_buffer(struct bat_priv *bat_priv,
+int tt_local_init(struct bat_priv *bat_priv);
+void tt_local_add(struct net_device *soft_iface, const uint8_t *addr);
+void tt_local_remove(struct bat_priv *bat_priv,
+ const uint8_t *addr, const char *message);
+int tt_local_fill_buffer(struct bat_priv *bat_priv,
unsigned char *buff, int buff_len);
-int hna_local_seq_print_text(struct seq_file *seq, void *offset);
-void hna_local_free(struct bat_priv *bat_priv);
-int hna_global_init(struct bat_priv *bat_priv);
-void hna_global_add_orig(struct bat_priv *bat_priv,
- struct orig_node *orig_node,
- unsigned char *hna_buff, int hna_buff_len);
-int hna_global_seq_print_text(struct seq_file *seq, void *offset);
-void hna_global_del_orig(struct bat_priv *bat_priv,
- struct orig_node *orig_node, char *message);
-void hna_global_free(struct bat_priv *bat_priv);
-struct orig_node *transtable_search(struct bat_priv *bat_priv, uint8_t *addr);
+int tt_local_seq_print_text(struct seq_file *seq, void *offset);
+void tt_local_free(struct bat_priv *bat_priv);
+int tt_global_init(struct bat_priv *bat_priv);
+void tt_global_add_orig(struct bat_priv *bat_priv,
+ struct orig_node *orig_node,
+ const unsigned char *tt_buff, int tt_buff_len);
+int tt_global_seq_print_text(struct seq_file *seq, void *offset);
+void tt_global_del_orig(struct bat_priv *bat_priv,
+ struct orig_node *orig_node, const char *message);
+void tt_global_free(struct bat_priv *bat_priv);
+struct orig_node *transtable_search(struct bat_priv *bat_priv,
+ const uint8_t *addr);
#endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 75123b1ae0de..65b32223d104 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -75,8 +75,8 @@ struct orig_node {
unsigned long batman_seqno_reset;
uint8_t gw_flags;
uint8_t flags;
- unsigned char *hna_buff;
- int16_t hna_buff_len;
+ unsigned char *tt_buff;
+ int16_t tt_buff_len;
uint32_t last_real_seqno;
uint8_t last_ttl;
unsigned long bcast_bits[NUM_WORDS];
@@ -89,11 +89,11 @@ struct orig_node {
struct hlist_node hash_entry;
struct bat_priv *bat_priv;
unsigned long last_frag_packet;
- spinlock_t ogm_cnt_lock; /* protects: bcast_own, bcast_own_sum,
- * neigh_node->real_bits,
- * neigh_node->real_packet_count */
- spinlock_t bcast_seqno_lock; /* protects bcast_bits,
- * last_bcast_seqno */
+ /* ogm_cnt_lock protects: bcast_own, bcast_own_sum,
+ * neigh_node->real_bits, neigh_node->real_packet_count */
+ spinlock_t ogm_cnt_lock;
+ /* bcast_seqno_lock protects bcast_bits, last_bcast_seqno */
+ spinlock_t bcast_seqno_lock;
atomic_t bond_candidates;
struct list_head bond_list;
};
@@ -146,34 +146,34 @@ struct bat_priv {
atomic_t bcast_queue_left;
atomic_t batman_queue_left;
char num_ifaces;
- struct hlist_head softif_neigh_list;
- struct softif_neigh __rcu *softif_neigh;
struct debug_log *debug_log;
- struct hard_iface *primary_if;
struct kobject *mesh_obj;
struct dentry *debug_dir;
struct hlist_head forw_bat_list;
struct hlist_head forw_bcast_list;
struct hlist_head gw_list;
+ struct hlist_head softif_neigh_vids;
struct list_head vis_send_list;
struct hashtable_t *orig_hash;
- struct hashtable_t *hna_local_hash;
- struct hashtable_t *hna_global_hash;
+ struct hashtable_t *tt_local_hash;
+ struct hashtable_t *tt_global_hash;
struct hashtable_t *vis_hash;
spinlock_t forw_bat_list_lock; /* protects forw_bat_list */
spinlock_t forw_bcast_list_lock; /* protects */
- spinlock_t hna_lhash_lock; /* protects hna_local_hash */
- spinlock_t hna_ghash_lock; /* protects hna_global_hash */
+ spinlock_t tt_lhash_lock; /* protects tt_local_hash */
+ spinlock_t tt_ghash_lock; /* protects tt_global_hash */
spinlock_t gw_list_lock; /* protects gw_list and curr_gw */
spinlock_t vis_hash_lock; /* protects vis_hash */
spinlock_t vis_list_lock; /* protects vis_info::recv_list */
spinlock_t softif_neigh_lock; /* protects soft-interface neigh list */
- int16_t num_local_hna;
- atomic_t hna_local_changed;
- struct delayed_work hna_work;
+ spinlock_t softif_neigh_vid_lock; /* protects soft-interface vid list */
+ int16_t num_local_tt;
+ atomic_t tt_local_changed;
+ struct delayed_work tt_work;
struct delayed_work orig_work;
struct delayed_work vis_work;
struct gw_node __rcu *curr_gw; /* rcu protected pointer */
+ struct hard_iface __rcu *primary_if; /* rcu protected pointer */
struct vis_info *my_vis_info;
};
@@ -192,14 +192,14 @@ struct socket_packet {
struct icmp_packet_rr icmp_packet;
};
-struct hna_local_entry {
+struct tt_local_entry {
uint8_t addr[ETH_ALEN];
unsigned long last_seen;
char never_purge;
struct hlist_node hash_entry;
};
-struct hna_global_entry {
+struct tt_global_entry {
uint8_t addr[ETH_ALEN];
struct orig_node *orig_node;
struct hlist_node hash_entry;
@@ -246,10 +246,10 @@ struct frag_packet_list_entry {
};
struct vis_info {
- unsigned long first_seen;
- struct list_head recv_list;
- /* list of server-neighbors we received a vis-packet
- * from. we should not reply to them. */
+ unsigned long first_seen;
+ /* list of server-neighbors we received a vis-packet
+ * from. we should not reply to them. */
+ struct list_head recv_list;
struct list_head send_list;
struct kref refcount;
struct hlist_node hash_entry;
@@ -262,7 +262,7 @@ struct vis_info {
struct vis_info_entry {
uint8_t src[ETH_ALEN];
uint8_t dest[ETH_ALEN];
- uint8_t quality; /* quality = 0 means HNA */
+ uint8_t quality; /* quality = 0 client */
} __packed;
struct recvlist_node {
@@ -270,11 +270,20 @@ struct recvlist_node {
uint8_t mac[ETH_ALEN];
};
+struct softif_neigh_vid {
+ struct hlist_node list;
+ struct bat_priv *bat_priv;
+ short vid;
+ atomic_t refcount;
+ struct softif_neigh __rcu *softif_neigh;
+ struct rcu_head rcu;
+ struct hlist_head softif_neigh_list;
+};
+
struct softif_neigh {
struct hlist_node list;
uint8_t addr[ETH_ALEN];
unsigned long last_seen;
- short vid;
atomic_t refcount;
struct rcu_head rcu;
};
diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c
index d46acc815138..6eabf42f8822 100644
--- a/net/batman-adv/unicast.c
+++ b/net/batman-adv/unicast.c
@@ -39,8 +39,8 @@ static struct sk_buff *frag_merge_packet(struct list_head *head,
(struct unicast_frag_packet *)skb->data;
struct sk_buff *tmp_skb;
struct unicast_packet *unicast_packet;
- int hdr_len = sizeof(struct unicast_packet);
- int uni_diff = sizeof(struct unicast_frag_packet) - hdr_len;
+ int hdr_len = sizeof(*unicast_packet);
+ int uni_diff = sizeof(*up) - hdr_len;
/* set skb to the first part and tmp_skb to the second part */
if (up->flags & UNI_FRAG_HEAD) {
@@ -53,7 +53,7 @@ static struct sk_buff *frag_merge_packet(struct list_head *head,
if (skb_linearize(skb) < 0 || skb_linearize(tmp_skb) < 0)
goto err;
- skb_pull(tmp_skb, sizeof(struct unicast_frag_packet));
+ skb_pull(tmp_skb, sizeof(*up));
if (pskb_expand_head(skb, 0, tmp_skb->len, GFP_ATOMIC) < 0)
goto err;
@@ -99,8 +99,7 @@ static int frag_create_buffer(struct list_head *head)
struct frag_packet_list_entry *tfp;
for (i = 0; i < FRAG_BUFFER_SIZE; i++) {
- tfp = kmalloc(sizeof(struct frag_packet_list_entry),
- GFP_ATOMIC);
+ tfp = kmalloc(sizeof(*tfp), GFP_ATOMIC);
if (!tfp) {
frag_list_free(head);
return -ENOMEM;
@@ -115,7 +114,7 @@ static int frag_create_buffer(struct list_head *head)
}
static struct frag_packet_list_entry *frag_search_packet(struct list_head *head,
- struct unicast_frag_packet *up)
+ const struct unicast_frag_packet *up)
{
struct frag_packet_list_entry *tfp;
struct unicast_frag_packet *tmp_up = NULL;
@@ -218,18 +217,20 @@ out:
}
int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv,
- struct hard_iface *hard_iface, uint8_t dstaddr[])
+ struct hard_iface *hard_iface, const uint8_t dstaddr[])
{
struct unicast_packet tmp_uc, *unicast_packet;
+ struct hard_iface *primary_if;
struct sk_buff *frag_skb;
struct unicast_frag_packet *frag1, *frag2;
- int uc_hdr_len = sizeof(struct unicast_packet);
- int ucf_hdr_len = sizeof(struct unicast_frag_packet);
+ int uc_hdr_len = sizeof(*unicast_packet);
+ int ucf_hdr_len = sizeof(*frag1);
int data_len = skb->len - uc_hdr_len;
- int large_tail = 0;
+ int large_tail = 0, ret = NET_RX_DROP;
uint16_t seqno;
- if (!bat_priv->primary_if)
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
goto dropped;
frag_skb = dev_alloc_skb(data_len - (data_len / 2) + ucf_hdr_len);
@@ -248,14 +249,14 @@ int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv,
frag1 = (struct unicast_frag_packet *)skb->data;
frag2 = (struct unicast_frag_packet *)frag_skb->data;
- memcpy(frag1, &tmp_uc, sizeof(struct unicast_packet));
+ memcpy(frag1, &tmp_uc, sizeof(tmp_uc));
frag1->ttl--;
frag1->version = COMPAT_VERSION;
frag1->packet_type = BAT_UNICAST_FRAG;
- memcpy(frag1->orig, bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
- memcpy(frag2, frag1, sizeof(struct unicast_frag_packet));
+ memcpy(frag1->orig, primary_if->net_dev->dev_addr, ETH_ALEN);
+ memcpy(frag2, frag1, sizeof(*frag2));
if (data_len & 1)
large_tail = UNI_FRAG_LARGETAIL;
@@ -269,13 +270,17 @@ int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv,
send_skb_packet(skb, hard_iface, dstaddr);
send_skb_packet(frag_skb, hard_iface, dstaddr);
- return NET_RX_SUCCESS;
+ ret = NET_RX_SUCCESS;
+ goto out;
drop_frag:
kfree_skb(frag_skb);
dropped:
kfree_skb(skb);
- return NET_RX_DROP;
+out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
+ return ret;
}
int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv)
@@ -289,12 +294,12 @@ int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv)
/* get routing information */
if (is_multicast_ether_addr(ethhdr->h_dest)) {
- orig_node = (struct orig_node *)gw_get_selected_orig(bat_priv);
+ orig_node = gw_get_selected_orig(bat_priv);
if (orig_node)
goto find_router;
}
- /* check for hna host - increases orig_node refcount */
+ /* check for tt host - increases orig_node refcount */
orig_node = transtable_search(bat_priv, ethhdr->h_dest);
find_router:
@@ -308,10 +313,7 @@ find_router:
if (!neigh_node)
goto out;
- if (neigh_node->if_incoming->if_status != IF_ACTIVE)
- goto out;
-
- if (my_skb_head_push(skb, sizeof(struct unicast_packet)) < 0)
+ if (my_skb_head_push(skb, sizeof(*unicast_packet)) < 0)
goto out;
unicast_packet = (struct unicast_packet *)skb->data;
@@ -325,7 +327,7 @@ find_router:
memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN);
if (atomic_read(&bat_priv->fragmentation) &&
- data_len + sizeof(struct unicast_packet) >
+ data_len + sizeof(*unicast_packet) >
neigh_node->if_incoming->net_dev->mtu) {
/* send frag skb decreases ttl */
unicast_packet->ttl++;
diff --git a/net/batman-adv/unicast.h b/net/batman-adv/unicast.h
index 16ad7a9242b5..62f54b954625 100644
--- a/net/batman-adv/unicast.h
+++ b/net/batman-adv/unicast.h
@@ -32,11 +32,11 @@ int frag_reassemble_skb(struct sk_buff *skb, struct bat_priv *bat_priv,
void frag_list_free(struct list_head *head);
int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv);
int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv,
- struct hard_iface *hard_iface, uint8_t dstaddr[]);
+ struct hard_iface *hard_iface, const uint8_t dstaddr[]);
-static inline int frag_can_reassemble(struct sk_buff *skb, int mtu)
+static inline int frag_can_reassemble(const struct sk_buff *skb, int mtu)
{
- struct unicast_frag_packet *unicast_packet;
+ const struct unicast_frag_packet *unicast_packet;
int uneven_correction = 0;
unsigned int merged_size;
@@ -49,7 +49,7 @@ static inline int frag_can_reassemble(struct sk_buff *skb, int mtu)
uneven_correction = -1;
}
- merged_size = (skb->len - sizeof(struct unicast_frag_packet)) * 2;
+ merged_size = (skb->len - sizeof(*unicast_packet)) * 2;
merged_size += sizeof(struct unicast_packet) + uneven_correction;
return merged_size <= mtu;
diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c
index d4cc4f5399f4..355c6e590b0c 100644
--- a/net/batman-adv/vis.c
+++ b/net/batman-adv/vis.c
@@ -30,22 +30,6 @@
#define MAX_VIS_PACKET_SIZE 1000
-/* Returns the smallest signed integer in two's complement with the sizeof x */
-#define smallest_signed_int(x) (1u << (7u + 8u * (sizeof(x) - 1u)))
-
-/* Checks if a sequence number x is a predecessor/successor of y.
- * they handle overflows/underflows and can correctly check for a
- * predecessor/successor unless the variable sequence number has grown by
- * more then 2**(bitwidth(x)-1)-1.
- * This means that for a uint8_t with the maximum value 255, it would think:
- * - when adding nothing - it is neither a predecessor nor a successor
- * - before adding more than 127 to the starting value - it is a predecessor,
- * - when adding 128 - it is neither a predecessor nor a successor,
- * - after adding more than 127 to the starting value - it is a successor */
-#define seq_before(x, y) ({typeof(x) _dummy = (x - y); \
- _dummy > smallest_signed_int(_dummy); })
-#define seq_after(x, y) seq_before(y, x)
-
static void start_vis_timer(struct bat_priv *bat_priv);
/* free the info */
@@ -68,10 +52,10 @@ static void free_info(struct kref *ref)
}
/* Compare two vis packets, used by the hashing algorithm */
-static int vis_info_cmp(struct hlist_node *node, void *data2)
+static int vis_info_cmp(const struct hlist_node *node, const void *data2)
{
- struct vis_info *d1, *d2;
- struct vis_packet *p1, *p2;
+ const struct vis_info *d1, *d2;
+ const struct vis_packet *p1, *p2;
d1 = container_of(node, struct vis_info, hash_entry);
d2 = data2;
@@ -82,11 +66,11 @@ static int vis_info_cmp(struct hlist_node *node, void *data2)
/* hash function to choose an entry in a hash table of given size */
/* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */
-static int vis_info_choose(void *data, int size)
+static int vis_info_choose(const void *data, int size)
{
- struct vis_info *vis_info = data;
- struct vis_packet *packet;
- unsigned char *key;
+ const struct vis_info *vis_info = data;
+ const struct vis_packet *packet;
+ const unsigned char *key;
uint32_t hash = 0;
size_t i;
@@ -106,7 +90,7 @@ static int vis_info_choose(void *data, int size)
}
static struct vis_info *vis_hash_find(struct bat_priv *bat_priv,
- void *data)
+ const void *data)
{
struct hashtable_t *hash = bat_priv->vis_hash;
struct hlist_head *head;
@@ -143,7 +127,7 @@ static void vis_data_insert_interface(const uint8_t *interface,
struct hlist_node *pos;
hlist_for_each_entry(entry, pos, if_list, list) {
- if (compare_eth(entry->addr, (void *)interface))
+ if (compare_eth(entry->addr, interface))
return;
}
@@ -156,7 +140,8 @@ static void vis_data_insert_interface(const uint8_t *interface,
hlist_add_head(&entry->list, if_list);
}
-static ssize_t vis_data_read_prim_sec(char *buff, struct hlist_head *if_list)
+static ssize_t vis_data_read_prim_sec(char *buff,
+ const struct hlist_head *if_list)
{
struct if_list_entry *entry;
struct hlist_node *pos;
@@ -189,12 +174,13 @@ static size_t vis_data_count_prim_sec(struct hlist_head *if_list)
}
/* read an entry */
-static ssize_t vis_data_read_entry(char *buff, struct vis_info_entry *entry,
- uint8_t *src, bool primary)
+static ssize_t vis_data_read_entry(char *buff,
+ const struct vis_info_entry *entry,
+ const uint8_t *src, bool primary)
{
/* maximal length: max(4+17+2, 3+17+1+3+2) == 26 */
if (primary && entry->quality == 0)
- return sprintf(buff, "HNA %pM, ", entry->dest);
+ return sprintf(buff, "TT %pM, ", entry->dest);
else if (compare_eth(entry->src, src))
return sprintf(buff, "TQ %pM %d, ", entry->dest,
entry->quality);
@@ -204,6 +190,7 @@ static ssize_t vis_data_read_entry(char *buff, struct vis_info_entry *entry,
int vis_seq_print_text(struct seq_file *seq, void *offset)
{
+ struct hard_iface *primary_if;
struct hlist_node *node;
struct hlist_head *head;
struct vis_info *info;
@@ -215,15 +202,18 @@ int vis_seq_print_text(struct seq_file *seq, void *offset)
HLIST_HEAD(vis_if_list);
struct if_list_entry *entry;
struct hlist_node *pos, *n;
- int i, j;
+ int i, j, ret = 0;
int vis_server = atomic_read(&bat_priv->vis_mode);
size_t buff_pos, buf_size;
char *buff;
int compare;
- if ((!bat_priv->primary_if) ||
- (vis_server == VIS_TYPE_CLIENT_UPDATE))
- return 0;
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
+ goto out;
+
+ if (vis_server == VIS_TYPE_CLIENT_UPDATE)
+ goto out;
buf_size = 1;
/* Estimate length */
@@ -235,7 +225,7 @@ int vis_seq_print_text(struct seq_file *seq, void *offset)
hlist_for_each_entry_rcu(info, node, head, hash_entry) {
packet = (struct vis_packet *)info->skb_packet->data;
entries = (struct vis_info_entry *)
- ((char *)packet + sizeof(struct vis_packet));
+ ((char *)packet + sizeof(*packet));
for (j = 0; j < packet->entries; j++) {
if (entries[j].quality == 0)
@@ -270,7 +260,8 @@ int vis_seq_print_text(struct seq_file *seq, void *offset)
buff = kmalloc(buf_size, GFP_ATOMIC);
if (!buff) {
spin_unlock_bh(&bat_priv->vis_hash_lock);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto out;
}
buff[0] = '\0';
buff_pos = 0;
@@ -282,7 +273,7 @@ int vis_seq_print_text(struct seq_file *seq, void *offset)
hlist_for_each_entry_rcu(info, node, head, hash_entry) {
packet = (struct vis_packet *)info->skb_packet->data;
entries = (struct vis_info_entry *)
- ((char *)packet + sizeof(struct vis_packet));
+ ((char *)packet + sizeof(*packet));
for (j = 0; j < packet->entries; j++) {
if (entries[j].quality == 0)
@@ -328,7 +319,10 @@ int vis_seq_print_text(struct seq_file *seq, void *offset)
seq_printf(seq, "%s", buff);
kfree(buff);
- return 0;
+out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
+ return ret;
}
/* add the info packet to the send list, if it was not
@@ -353,11 +347,11 @@ static void send_list_del(struct vis_info *info)
/* tries to add one entry to the receive list. */
static void recv_list_add(struct bat_priv *bat_priv,
- struct list_head *recv_list, char *mac)
+ struct list_head *recv_list, const char *mac)
{
struct recvlist_node *entry;
- entry = kmalloc(sizeof(struct recvlist_node), GFP_ATOMIC);
+ entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
if (!entry)
return;
@@ -369,9 +363,9 @@ static void recv_list_add(struct bat_priv *bat_priv,
/* returns 1 if this mac is in the recv_list */
static int recv_list_is_in(struct bat_priv *bat_priv,
- struct list_head *recv_list, char *mac)
+ const struct list_head *recv_list, const char *mac)
{
- struct recvlist_node *entry;
+ const struct recvlist_node *entry;
spin_lock_bh(&bat_priv->vis_list_lock);
list_for_each_entry(entry, recv_list, list) {
@@ -404,11 +398,11 @@ static struct vis_info *add_packet(struct bat_priv *bat_priv,
return NULL;
/* see if the packet is already in vis_hash */
- search_elem.skb_packet = dev_alloc_skb(sizeof(struct vis_packet));
+ search_elem.skb_packet = dev_alloc_skb(sizeof(*search_packet));
if (!search_elem.skb_packet)
return NULL;
search_packet = (struct vis_packet *)skb_put(search_elem.skb_packet,
- sizeof(struct vis_packet));
+ sizeof(*search_packet));
memcpy(search_packet->vis_orig, vis_packet->vis_orig, ETH_ALEN);
old_info = vis_hash_find(bat_priv, &search_elem);
@@ -434,27 +428,26 @@ static struct vis_info *add_packet(struct bat_priv *bat_priv,
kref_put(&old_info->refcount, free_info);
}
- info = kmalloc(sizeof(struct vis_info), GFP_ATOMIC);
+ info = kmalloc(sizeof(*info), GFP_ATOMIC);
if (!info)
return NULL;
- info->skb_packet = dev_alloc_skb(sizeof(struct vis_packet) +
- vis_info_len + sizeof(struct ethhdr));
+ info->skb_packet = dev_alloc_skb(sizeof(*packet) + vis_info_len +
+ sizeof(struct ethhdr));
if (!info->skb_packet) {
kfree(info);
return NULL;
}
skb_reserve(info->skb_packet, sizeof(struct ethhdr));
- packet = (struct vis_packet *)skb_put(info->skb_packet,
- sizeof(struct vis_packet) +
- vis_info_len);
+ packet = (struct vis_packet *)skb_put(info->skb_packet, sizeof(*packet)
+ + vis_info_len);
kref_init(&info->refcount);
INIT_LIST_HEAD(&info->send_list);
INIT_LIST_HEAD(&info->recv_list);
info->first_seen = jiffies;
info->bat_priv = bat_priv;
- memcpy(packet, vis_packet, sizeof(struct vis_packet) + vis_info_len);
+ memcpy(packet, vis_packet, sizeof(*packet) + vis_info_len);
/* initialize and add new packet. */
*is_new = 1;
@@ -591,9 +584,9 @@ static int find_best_vis_server(struct bat_priv *bat_priv,
}
/* Return true if the vis packet is full. */
-static bool vis_packet_full(struct vis_info *info)
+static bool vis_packet_full(const struct vis_info *info)
{
- struct vis_packet *packet;
+ const struct vis_packet *packet;
packet = (struct vis_packet *)info->skb_packet->data;
if (MAX_VIS_PACKET_SIZE / sizeof(struct vis_info_entry)
@@ -611,10 +604,10 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
struct hlist_head *head;
struct orig_node *orig_node;
struct neigh_node *router;
- struct vis_info *info = (struct vis_info *)bat_priv->my_vis_info;
+ struct vis_info *info = bat_priv->my_vis_info;
struct vis_packet *packet = (struct vis_packet *)info->skb_packet->data;
struct vis_info_entry *entry;
- struct hna_local_entry *hna_local_entry;
+ struct tt_local_entry *tt_local_entry;
int best_tq = -1, i;
info->first_seen = jiffies;
@@ -624,7 +617,7 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
packet->ttl = TTL;
packet->seqno = htonl(ntohl(packet->seqno) + 1);
packet->entries = 0;
- skb_trim(info->skb_packet, sizeof(struct vis_packet));
+ skb_trim(info->skb_packet, sizeof(*packet));
if (packet->vis_type == VIS_TYPE_CLIENT_UPDATE) {
best_tq = find_best_vis_server(bat_priv, info);
@@ -670,29 +663,29 @@ next:
rcu_read_unlock();
}
- hash = bat_priv->hna_local_hash;
+ hash = bat_priv->tt_local_hash;
- spin_lock_bh(&bat_priv->hna_lhash_lock);
+ spin_lock_bh(&bat_priv->tt_lhash_lock);
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
- hlist_for_each_entry(hna_local_entry, node, head, hash_entry) {
+ hlist_for_each_entry(tt_local_entry, node, head, hash_entry) {
entry = (struct vis_info_entry *)
skb_put(info->skb_packet,
sizeof(*entry));
memset(entry->src, 0, ETH_ALEN);
- memcpy(entry->dest, hna_local_entry->addr, ETH_ALEN);
- entry->quality = 0; /* 0 means HNA */
+ memcpy(entry->dest, tt_local_entry->addr, ETH_ALEN);
+ entry->quality = 0; /* 0 means TT */
packet->entries++;
if (vis_packet_full(info)) {
- spin_unlock_bh(&bat_priv->hna_lhash_lock);
+ spin_unlock_bh(&bat_priv->tt_lhash_lock);
return 0;
}
}
}
- spin_unlock_bh(&bat_priv->hna_lhash_lock);
+ spin_unlock_bh(&bat_priv->tt_lhash_lock);
return 0;
unlock:
@@ -815,16 +808,20 @@ out:
/* only send one vis packet. called from send_vis_packets() */
static void send_vis_packet(struct bat_priv *bat_priv, struct vis_info *info)
{
+ struct hard_iface *primary_if;
struct vis_packet *packet;
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
+ goto out;
+
packet = (struct vis_packet *)info->skb_packet->data;
if (packet->ttl < 2) {
pr_debug("Error - can't send vis packet: ttl exceeded\n");
- return;
+ goto out;
}
- memcpy(packet->sender_orig, bat_priv->primary_if->net_dev->dev_addr,
- ETH_ALEN);
+ memcpy(packet->sender_orig, primary_if->net_dev->dev_addr, ETH_ALEN);
packet->ttl--;
if (is_broadcast_ether_addr(packet->target_orig))
@@ -832,6 +829,10 @@ static void send_vis_packet(struct bat_priv *bat_priv, struct vis_info *info)
else
unicast_vis_packet(bat_priv, info);
packet->ttl++; /* restore TTL */
+
+out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
}
/* called from timer; send (and maybe generate) vis packet. */
@@ -858,8 +859,7 @@ static void send_vis_packets(struct work_struct *work)
kref_get(&info->refcount);
spin_unlock_bh(&bat_priv->vis_hash_lock);
- if (bat_priv->primary_if)
- send_vis_packet(bat_priv, info);
+ send_vis_packet(bat_priv, info);
spin_lock_bh(&bat_priv->vis_hash_lock);
send_list_del(info);
@@ -893,17 +893,15 @@ int vis_init(struct bat_priv *bat_priv)
goto err;
}
- bat_priv->my_vis_info->skb_packet = dev_alloc_skb(
- sizeof(struct vis_packet) +
- MAX_VIS_PACKET_SIZE +
- sizeof(struct ethhdr));
+ bat_priv->my_vis_info->skb_packet = dev_alloc_skb(sizeof(*packet) +
+ MAX_VIS_PACKET_SIZE +
+ sizeof(struct ethhdr));
if (!bat_priv->my_vis_info->skb_packet)
goto free_info;
skb_reserve(bat_priv->my_vis_info->skb_packet, sizeof(struct ethhdr));
- packet = (struct vis_packet *)skb_put(
- bat_priv->my_vis_info->skb_packet,
- sizeof(struct vis_packet));
+ packet = (struct vis_packet *)skb_put(bat_priv->my_vis_info->skb_packet,
+ sizeof(*packet));
/* prefill the vis info */
bat_priv->my_vis_info->first_seen = jiffies -