The following commit has been merged in the master branch: commit f36f4a86e66e7bdfbf4da53e3122157d12e48cbe Merge: 1aee9b47eab62668ded02ed09f6f12c0d67e3c8a c7029f97552c4dd7bca88b0d9cda39e69bf7d600 Author: Marek Lindner lindner_marek@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_ */