The following commit has been merged in the master branch:
commit f36f4a86e66e7bdfbf4da53e3122157d12e48cbe
Merge: 1aee9b47eab62668ded02ed09f6f12c0d67e3c8a c7029f97552c4dd7bca88b0d9cda39e69bf7d600
Author: Marek Lindner <lindner_marek(a)yahoo.de>
Date: Wed Apr 25 19:52:49 2012 +0800
Merge branch 'next'
diff --combined distributed-arp-table.c
index a2d3821,6935be9..76e23f1
--- a/distributed-arp-table.c
+++ b/distributed-arp-table.c
@@@ -37,7 -37,8 +37,8 @@@
#ifdef CONFIG_BATMAN_ADV_DEBUG
static void bat_dbg_arp(struct bat_priv *bat_priv, struct sk_buff *skb,
- uint16_t type, int hdr_size, char *msg) {
+ uint16_t type, int hdr_size, char *msg)
+ {
struct unicast_4addr_packet *unicast_4addr_packet;
if (msg)
@@@ -51,7 -52,8 +52,8 @@@
return;
/* if the AP packet is encapsulated in a batman packet, let's print some
- * debug messages */
+ * debug messages
+ */
unicast_4addr_packet = (struct unicast_4addr_packet *)skb->data;
switch (unicast_4addr_packet->u.header.packet_type) {
@@@ -94,7 -96,10 +96,10 @@@
#else
- #define bat_dbg_arp(...)
+ static void bat_dbg_arp(struct bat_priv *bat_priv, struct sk_buff *skb,
+ uint16_t type, int hdr_size, char *msg)
+ {
+ }
#endif /* CONFIG_BATMAN_ADV_DEBUG */
@@@ -118,11 -123,13 +123,13 @@@ static bool is_orig_node_eligible(struc
if (tmp_max > last_max)
goto out;
/* check if during this iteration we have already found an originator
- * with a closer dht address */
+ * with a closer dht address
+ */
if (tmp_max < max)
goto out;
/* this is an hash collision with the temporary selected node. Choose
- * the one with the lowest address */
+ * the one with the lowest address
+ */
if ((tmp_max == max) &&
(compare_eth(candidate->orig, max_orig_node->orig) > 0))
goto out;
@@@ -133,7 -140,8 +140,8 @@@ out
}
/* selects the next candidate by populating cands[select] and modifies last_max
- * accordingly */
+ * accordingly
+ */
static void choose_next_candidate(struct bat_priv *bat_priv,
struct dht_candidate *cands, int select,
dat_addr_t ip_key, dat_addr_t *last_max)
@@@ -146,11 -154,13 +154,13 @@@
int i;
/* if no node is eligible as candidate, we will leave the candidate as
- * NOT_FOUND */
+ * NOT_FOUND
+ */
cands[select].type = DHT_CANDIDATE_NOT_FOUND;
/* iterate over the originator list and find the node with closest
- * dht_address which has not been selected yet */
+ * dht_address which has not been selected yet
+ */
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
@@@ -190,7 -200,8 +200,8 @@@
* closest values (from the LEFT, with wrap around if needed) then the hash
* value of the key. ip_dst is the key.
*
- * return an array of size DHT_CANDIDATES_NUM */
+ * return an array of size DHT_CANDIDATES_NUM
+ */
static struct dht_candidate *dht_select_candidates(struct bat_priv *bat_priv,
uint32_t ip_dst)
{
@@@ -222,7 -233,8 +233,8 @@@
* and is sent as unicast packet to each of the selected candidate.
*
* If the packet is successfully sent to at least one candidate, then this
- * function returns true */
+ * function returns true
+ */
static bool dht_send_data(struct bat_priv *bat_priv, struct sk_buff *skb,
uint32_t ip, int packet_subtype)
{
@@@ -269,7 -281,8 +281,8 @@@ out
/* Update the neighbour entry corresponding to the IP passed as parameter with
* the hw address hw. If the neighbour entry doesn't exists, then it will be
- * created */
+ * created
+ */
static void arp_neigh_update(struct bat_priv *bat_priv, uint32_t ip,
uint8_t *hw)
{
@@@ -293,7 -306,8 +306,8 @@@ out
}
/* Returns arphdr->ar_op if the skb contains a valid ARP packet, otherwise
- * returns 0 */
+ * returns 0
+ */
static uint16_t arp_get_type(struct bat_priv *bat_priv, struct sk_buff *skb,
int hdr_size)
{
@@@ -347,7 -361,8 +361,8 @@@ out
/* return true if the message has been sent to the dht candidates, false
* otherwise. In case of true the message has to be enqueued to permit the
- * fallback */
+ * fallback
+ */
bool dat_snoop_outgoing_arp_request(struct bat_priv *bat_priv,
struct sk_buff *skb)
{
@@@ -361,7 -376,8 +376,8 @@@
type = arp_get_type(bat_priv, skb, 0);
/* If we get an ARP_REQUEST we have to send the unicast message to the
- * selected DHT candidates */
+ * selected DHT candidates
+ */
if (type != ARPOP_REQUEST)
goto out;
@@@ -395,11 -411,9 +411,11 @@@
netif_rx(skb_new);
bat_dbg(DBG_DAT, bat_priv, "ARP request replied locally\n");
- } else
+ } else {
/* Send the request on the DHT */
+ inc_counter(bat_priv, BAT_CNT_DAT_REQUEST_TX);
ret = dht_send_data(bat_priv, skb, ip_dst, BAT_P_DAT_DHT_GET);
+ }
out:
if (n)
neigh_release(n);
@@@ -411,7 -425,8 +427,8 @@@
/* This function is meant to be invoked for an ARP request which is coming into
* the bat0 interfaces from the mesh network. It will check for the needed data
* into the local table. If found, an ARP reply is sent immediately, otherwise
- * the caller has to deliver the ARP request to the upper layer */
+ * the caller has to deliver the ARP request to the upper layer
+ */
bool dat_snoop_incoming_arp_request(struct bat_priv *bat_priv,
struct sk_buff *skb, int hdr_size)
{
@@@ -452,8 -467,6 +469,8 @@@
if (!skb_new)
goto out;
+ inc_counter(bat_priv, BAT_CNT_DAT_REPLY_TX);
+
unicast_4addr_send_skb(skb_new, bat_priv, BAT_P_DAT_CACHE_REPLY);
ret = true;
@@@ -469,7 -482,8 +486,8 @@@ out
/* This function is meant to be invoked on an ARP reply packet going into the
* soft interface. The related neighbour entry has to be updated and the DHT has
- * to be populated as well */
+ * to be populated as well
+ */
bool dat_snoop_outgoing_arp_reply(struct bat_priv *bat_priv,
struct sk_buff *skb)
{
@@@ -492,10 -506,9 +510,11 @@@
arp_neigh_update(bat_priv, ip_src, hw_src);
arp_neigh_update(bat_priv, ip_dst, hw_dst);
+ inc_counter(bat_priv, BAT_CNT_DAT_REPLY_TX);
+
/* Send the ARP reply to the candidates for both the IP addresses we
- * fetched from the ARP reply */
+ * fetched from the ARP reply
+ */
dht_send_data(bat_priv, skb, ip_src, BAT_P_DAT_DHT_PUT);
dht_send_data(bat_priv, skb, ip_dst, BAT_P_DAT_DHT_PUT);
ret = true;
@@@ -504,7 -517,8 +523,8 @@@ out
}
/* This function has to be invoked on an ARP reply coming into the soft
- * interface from the mesh network. The local table has to be updated */
+ * interface from the mesh network. The local table has to be updated
+ */
bool dat_snoop_incoming_arp_reply(struct bat_priv *bat_priv,
struct sk_buff *skb, int hdr_size)
{
@@@ -526,12 -540,14 +546,14 @@@
ip_dst = ARP_IP_DST(skb, hdr_size);
/* Update our internal cache with both the IP addresses we fetched from
- * the ARP reply */
+ * the ARP reply
+ */
arp_neigh_update(bat_priv, ip_src, hw_src);
arp_neigh_update(bat_priv, ip_dst, hw_dst);
/* if this REPLY is directed to a client of mine, let's deliver the
- * packet to the interface */
+ * packet to the interface
+ */
ret = !is_my_client(bat_priv, hw_dst);
out:
/* if ret == false packet has to be delivered to the interface */
@@@ -544,7 -560,8 +566,8 @@@ bool dat_drop_broadcast_packet(struct b
struct neighbour *n;
/* If this packet is an ARP_REQUEST and we already have the information
- * that it is going to ask, we can drop the packet */
+ * that it is going to ask, we can drop the packet
+ */
if (!forw_packet->num_packets &&
(ARPOP_REQUEST == arp_get_type(bat_priv, forw_packet->skb,
sizeof(struct bcast_packet)))) {
@@@ -578,7 -595,8 +601,8 @@@ void arp_change_timeout(struct net_devi
}
/* Introduce a delay in the ARP state-machine transactions. Entries
- * will be kept in the ARP table for the default time multiplied by 4 */
+ * will be kept in the ARP table for the default time multiplied by 4
+ */
in_dev->arp_parms->base_reachable_time *= ARP_TIMEOUT_FACTOR;
in_dev->arp_parms->gc_staletime *= ARP_TIMEOUT_FACTOR;
in_dev->arp_parms->reachable_time *= ARP_TIMEOUT_FACTOR;
diff --combined main.c
index 25c2e2b,9137aa0..79dd604
--- a/main.c
+++ b/main.c
@@@ -40,7 -40,7 +40,7 @@@
* list traversals just rcu-locked */
struct list_head hardif_list;
static int (*recv_packet_handler[256])(struct sk_buff *, struct hard_iface *);
-char bat_routing_algo[20] = "BATMAN IV";
+char bat_routing_algo[20] = "BATMAN_IV";
static struct hlist_head bat_algo_list;
unsigned char broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
@@@ -153,8 -153,6 +153,8 @@@ void mesh_free(struct net_device *soft_
bla_free(bat_priv);
+ free_percpu(bat_priv->bat_counters);
+
atomic_set(&bat_priv->mesh_state, MESH_INACTIVE);
}
@@@ -193,7 -191,8 +193,8 @@@ static int recv_unhandled_packet(struc
}
/* incoming packets with the batman ethertype received on any active hard
- * interface */
+ * interface
+ */
int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *ptype, struct net_device *orig_dev)
{
@@@ -240,7 -239,8 +241,8 @@@
}
/* all receive handlers return whether they received or reused
- * the supplied skb. if not, we have to free the skb. */
+ * the supplied skb. if not, we have to free the skb.
+ */
idx = batman_ogm_packet->header.packet_type;
ret = (*recv_packet_handler[idx])(skb, hard_iface);
@@@ -249,7 -249,8 +251,8 @@@
/* return NET_RX_SUCCESS in any case as we
* most probably dropped the packet for
- * routing-logical reasons. */
+ * routing-logical reasons.
+ */
return NET_RX_SUCCESS;
err_free:
@@@ -380,19 -381,14 +383,19 @@@ int bat_algo_seq_print_text(struct seq_
static int param_set_ra(const char *val, const struct kernel_param *kp)
{
struct bat_algo_ops *bat_algo_ops;
+ char *algo_name = (char *)val;
+ size_t name_len = strlen(algo_name);
+
+ if (algo_name[name_len - 1] == '\n')
+ algo_name[name_len - 1] = '\0';
- bat_algo_ops = bat_algo_get((char *)val);
+ bat_algo_ops = bat_algo_get(algo_name);
if (!bat_algo_ops) {
- pr_err("Routing algorithm '%s' is not supported\n", val);
+ pr_err("Routing algorithm '%s' is not supported\n", algo_name);
return -EINVAL;
}
- return param_set_copystring(val, kp);
+ return param_set_copystring(algo_name, kp);
}
static const struct kernel_param_ops param_ops_ra = {
diff --combined main.h
index 9dc7971,97d0258..c893c25
--- a/main.h
+++ b/main.h
@@@ -72,7 -72,8 +72,8 @@@
/* numbers of originator to contact for any PUT/GET DHT operation */
#define DHT_CANDIDATES_NUM 3
/* Factor which default ARP timeout values of the soft_iface table are
- * multiplied by */
+ * multiplied by
+ */
#define ARP_TIMEOUT_FACTOR 4
#define LOG_BUF_LEN 8192 /* has to be a power of 2 */
@@@ -150,7 -151,6 +151,7 @@@ enum dbg_level
#include <linux/kthread.h> /* kernel threads */
#include <linux/pkt_sched.h> /* schedule types */
#include <linux/workqueue.h> /* workqueue */
+#include <linux/percpu.h>
#include <linux/slab.h>
#include <net/sock.h> /* struct sock */
#include <linux/jiffies.h>
@@@ -260,30 -260,4 +261,30 @@@ static inline bool has_timed_out(unsign
_dummy > smallest_signed_int(_dummy); })
#define seq_after(x, y) seq_before(y, x)
+/* Stop preemption on local cpu while incrementing the counter */
+static inline void add_counter(struct bat_priv *bat_priv, size_t idx,
+ size_t count)
+{
+ int cpu = get_cpu();
+ per_cpu_ptr(bat_priv->bat_counters, cpu)[idx] += count;
+ put_cpu();
+}
+
+#define inc_counter(b, i) add_counter(b, i, 1)
+
+/* Sum and return the cpu-local counters for index 'idx' */
+static inline uint64_t sum_counter(struct bat_priv *bat_priv, size_t idx)
+{
+ uint64_t *counters;
+ int cpu;
+ int sum = 0;
+
+ for_each_possible_cpu(cpu) {
+ counters = per_cpu_ptr(bat_priv->bat_counters, cpu);
+ sum += counters[idx];
+ }
+
+ return sum;
+}
+
#endif /* _NET_BATMAN_ADV_MAIN_H_ */
--
batman-adv