From 9844732361b13b768973bb4cc479fbfd0ce7f1af Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 18 Jun 2012 17:29:53 +0200 Subject: [PATCH] --- yaml --- r: 314315 b: refs/heads/master c: fd7462de461949e36d70f5b0bc17b98c5a00729c h: refs/heads/master i: 314313: 8c9e487c86cc91a924518bc0eab1e6a5130ca775 314311: 29f67bd3d1f4486e3a485bb129e1c237ae624250 v: v3 --- [refs] | 2 +- trunk/Documentation/networking/batman-adv.txt | 5 - trunk/net/batman-adv/bat_debugfs.c | 11 +- trunk/net/batman-adv/bat_iv_ogm.c | 63 +++---- trunk/net/batman-adv/bat_sysfs.c | 4 +- trunk/net/batman-adv/bridge_loop_avoidance.c | 27 +-- trunk/net/batman-adv/gateway_common.c | 3 - trunk/net/batman-adv/hard-interface.c | 4 +- trunk/net/batman-adv/hash.c | 9 - trunk/net/batman-adv/hash.h | 19 +- trunk/net/batman-adv/icmp_socket.c | 4 +- trunk/net/batman-adv/main.c | 42 ++--- trunk/net/batman-adv/main.h | 29 +-- trunk/net/batman-adv/originator.c | 18 +- trunk/net/batman-adv/packet.h | 18 +- trunk/net/batman-adv/routing.c | 23 +-- trunk/net/batman-adv/send.c | 74 +++++++- trunk/net/batman-adv/soft-interface.c | 66 +------ trunk/net/batman-adv/translation-table.c | 168 ++++-------------- trunk/net/batman-adv/translation-table.h | 7 +- trunk/net/batman-adv/types.h | 22 +-- trunk/net/batman-adv/vis.c | 29 ++- trunk/net/netfilter/nf_conntrack_netlink.c | 13 +- 23 files changed, 229 insertions(+), 431 deletions(-) diff --git a/[refs] b/[refs] index 4c7a987b7c7a..8a299fa7ee01 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: f032537fef3bc6db5905a63f7d1f5af5a136b500 +refs/heads/master: fd7462de461949e36d70f5b0bc17b98c5a00729c diff --git a/trunk/Documentation/networking/batman-adv.txt b/trunk/Documentation/networking/batman-adv.txt index 8f3ae4a6147e..75a592365af9 100644 --- a/trunk/Documentation/networking/batman-adv.txt +++ b/trunk/Documentation/networking/batman-adv.txt @@ -211,11 +211,6 @@ The debug output can be changed at runtime using the file will enable debug messages for when routes change. -Counters for different types of packets entering and leaving the -batman-adv module are available through ethtool: - -# ethtool --statistics bat0 - BATCTL ------ diff --git a/trunk/net/batman-adv/bat_debugfs.c b/trunk/net/batman-adv/bat_debugfs.c index db8273c26989..3b588f86d770 100644 --- a/trunk/net/batman-adv/bat_debugfs.c +++ b/trunk/net/batman-adv/bat_debugfs.c @@ -195,13 +195,13 @@ static int debug_log_setup(struct bat_priv *bat_priv) d = debugfs_create_file("log", S_IFREG | S_IRUSR, bat_priv->debug_dir, bat_priv, &log_fops); - if (!d) + if (d) goto err; return 0; err: - return -ENOMEM; + return 1; } static void debug_log_cleanup(struct bat_priv *bat_priv) @@ -348,11 +348,8 @@ int debugfs_add_meshif(struct net_device *dev) if (!bat_priv->debug_dir) goto out; - if (bat_socket_setup(bat_priv) < 0) - goto rem_attr; - - if (debug_log_setup(bat_priv) < 0) - goto rem_attr; + bat_socket_setup(bat_priv); + debug_log_setup(bat_priv); for (bat_debug = mesh_debuginfos; *bat_debug; ++bat_debug) { file = debugfs_create_file(((*bat_debug)->attr).name, diff --git a/trunk/net/batman-adv/bat_iv_ogm.c b/trunk/net/batman-adv/bat_iv_ogm.c index 6e0859f4a6a9..dc53798ebb47 100644 --- a/trunk/net/batman-adv/bat_iv_ogm.c +++ b/trunk/net/batman-adv/bat_iv_ogm.c @@ -34,12 +34,11 @@ static struct neigh_node *bat_iv_ogm_neigh_new(struct hard_iface *hard_iface, const uint8_t *neigh_addr, struct orig_node *orig_node, struct orig_node *orig_neigh, - __be32 seqno) + uint32_t seqno) { struct neigh_node *neigh_node; - neigh_node = batadv_neigh_node_new(hard_iface, neigh_addr, - ntohl(seqno)); + neigh_node = batadv_neigh_node_new(hard_iface, neigh_addr, seqno); if (!neigh_node) goto out; @@ -60,7 +59,7 @@ static int bat_iv_ogm_iface_enable(struct hard_iface *hard_iface) { struct batman_ogm_packet *batman_ogm_packet; uint32_t random_seqno; - int res = -ENOMEM; + int res = -1; /* randomize initial seqno to avoid collision */ get_random_bytes(&random_seqno, sizeof(random_seqno)); @@ -197,12 +196,8 @@ static void bat_iv_ogm_send_to_if(struct forw_packet *forw_packet, /* create clone because function is called more than once */ skb = skb_clone(forw_packet->skb, GFP_ATOMIC); - if (skb) { - batadv_inc_counter(bat_priv, BAT_CNT_MGMT_TX); - batadv_add_counter(bat_priv, BAT_CNT_MGMT_TX_BYTES, - skb->len + ETH_HLEN); + if (skb) send_skb_packet(skb, hard_iface, broadcast_addr); - } } /* send a batman ogm packet */ @@ -547,6 +542,9 @@ static void bat_iv_ogm_forward(struct orig_node *orig_node, "Forwarding packet: tq: %i, ttl: %i\n", batman_ogm_packet->tq, batman_ogm_packet->header.ttl); + batman_ogm_packet->seqno = htonl(batman_ogm_packet->seqno); + batman_ogm_packet->tt_crc = htons(batman_ogm_packet->tt_crc); + /* switch of primaries first hop flag when forwarding */ batman_ogm_packet->flags &= ~PRIMARIES_FIRST_HOP; if (is_single_hop_neigh) @@ -559,31 +557,26 @@ static void bat_iv_ogm_forward(struct orig_node *orig_node, if_incoming, 0, bat_iv_ogm_fwd_send_time()); } -static void bat_iv_ogm_schedule(struct hard_iface *hard_iface) +static void bat_iv_ogm_schedule(struct hard_iface *hard_iface, + int tt_num_changes) { struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface); struct batman_ogm_packet *batman_ogm_packet; struct hard_iface *primary_if; - int vis_server, tt_num_changes = 0; + int vis_server; vis_server = atomic_read(&bat_priv->vis_mode); primary_if = primary_if_get_selected(bat_priv); - if (hard_iface == primary_if) - tt_num_changes = batadv_tt_append_diff(bat_priv, - &hard_iface->packet_buff, - &hard_iface->packet_len, - BATMAN_OGM_HLEN); - batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff; /* change sequence number to network order */ batman_ogm_packet->seqno = htonl((uint32_t)atomic_read(&hard_iface->seqno)); - atomic_inc(&hard_iface->seqno); batman_ogm_packet->ttvn = atomic_read(&bat_priv->ttvn); - batman_ogm_packet->tt_crc = htons(bat_priv->tt_crc); + batman_ogm_packet->tt_crc = htons((uint16_t) + atomic_read(&bat_priv->tt_crc)); if (tt_num_changes >= 0) batman_ogm_packet->tt_num_changes = tt_num_changes; @@ -599,6 +592,8 @@ static void bat_iv_ogm_schedule(struct hard_iface *hard_iface) else batman_ogm_packet->gw_flags = NO_FLAGS; + atomic_inc(&hard_iface->seqno); + slide_own_bcast_window(hard_iface); bat_iv_ogm_queue_add(bat_priv, hard_iface->packet_buff, hard_iface->packet_len, hard_iface, 1, @@ -726,7 +721,7 @@ static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv, tt_update_orig(bat_priv, orig_node, tt_buff, batman_ogm_packet->tt_num_changes, batman_ogm_packet->ttvn, - ntohs(batman_ogm_packet->tt_crc)); + batman_ogm_packet->tt_crc); if (orig_node->gw_flags != batman_ogm_packet->gw_flags) gw_node_update(bat_priv, orig_node, @@ -873,14 +868,13 @@ static int bat_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, int32_t seq_diff; int need_update = 0; int set_mark, ret = -1; - uint32_t seqno = ntohl(batman_ogm_packet->seqno); orig_node = get_orig_node(bat_priv, batman_ogm_packet->orig); if (!orig_node) return 0; spin_lock_bh(&orig_node->ogm_cnt_lock); - seq_diff = seqno - orig_node->last_real_seqno; + seq_diff = batman_ogm_packet->seqno - orig_node->last_real_seqno; /* signalize caller that the packet is to be dropped. */ if (!hlist_empty(&orig_node->neigh_list) && @@ -894,7 +888,7 @@ static int bat_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, is_duplicate |= bat_test_bit(tmp_neigh_node->real_bits, orig_node->last_real_seqno, - seqno); + batman_ogm_packet->seqno); if (compare_eth(tmp_neigh_node->addr, ethhdr->h_source) && (tmp_neigh_node->if_incoming == if_incoming)) @@ -916,8 +910,8 @@ static int bat_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, if (need_update) { bat_dbg(DBG_BATMAN, bat_priv, "updating last_seqno: old %u, new %u\n", - orig_node->last_real_seqno, seqno); - orig_node->last_real_seqno = seqno; + orig_node->last_real_seqno, batman_ogm_packet->seqno); + orig_node->last_real_seqno = batman_ogm_packet->seqno; } ret = is_duplicate; @@ -973,8 +967,8 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, "Received BATMAN packet via NB: %pM, IF: %s [%pM] (from OG: %pM, via prev OG: %pM, seqno %u, ttvn %u, crc %u, changes %u, td %d, TTL %d, V %d, IDF %d)\n", ethhdr->h_source, if_incoming->net_dev->name, if_incoming->net_dev->dev_addr, batman_ogm_packet->orig, - batman_ogm_packet->prev_sender, ntohl(batman_ogm_packet->seqno), - batman_ogm_packet->ttvn, ntohs(batman_ogm_packet->tt_crc), + batman_ogm_packet->prev_sender, batman_ogm_packet->seqno, + batman_ogm_packet->ttvn, batman_ogm_packet->tt_crc, batman_ogm_packet->tt_num_changes, batman_ogm_packet->tq, batman_ogm_packet->header.ttl, batman_ogm_packet->header.version, has_directlink_flag); @@ -1045,7 +1039,7 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, word = &(orig_neigh_node->bcast_own[offset]); bat_set_bit(word, if_incoming_seqno - - ntohl(batman_ogm_packet->seqno) - 2); + batman_ogm_packet->seqno - 2); orig_neigh_node->bcast_own_sum[if_incoming->if_num] = bitmap_weight(word, TQ_LOCAL_WINDOW_SIZE); spin_unlock_bh(&orig_neigh_node->ogm_cnt_lock); @@ -1138,7 +1132,7 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, * seqno and similar ttl as the non-duplicate */ if (is_bidirectional && (!is_duplicate || - ((orig_node->last_real_seqno == ntohl(batman_ogm_packet->seqno)) && + ((orig_node->last_real_seqno == batman_ogm_packet->seqno) && (orig_node->last_ttl - 3 <= batman_ogm_packet->header.ttl)))) bat_iv_ogm_orig_update(bat_priv, orig_node, ethhdr, batman_ogm_packet, if_incoming, @@ -1210,10 +1204,6 @@ static int bat_iv_ogm_receive(struct sk_buff *skb, if (bat_priv->bat_algo_ops->bat_ogm_emit != bat_iv_ogm_emit) return NET_RX_DROP; - batadv_inc_counter(bat_priv, BAT_CNT_MGMT_RX); - batadv_add_counter(bat_priv, BAT_CNT_MGMT_RX_BYTES, - skb->len + ETH_HLEN); - packet_len = skb_headlen(skb); ethhdr = (struct ethhdr *)skb_mac_header(skb); packet_buff = skb->data; @@ -1221,6 +1211,11 @@ static int bat_iv_ogm_receive(struct sk_buff *skb, /* unpack the aggregated packets and process them one by one */ do { + /* network to host order for our 32bit seqno and the + orig_interval */ + batman_ogm_packet->seqno = ntohl(batman_ogm_packet->seqno); + batman_ogm_packet->tt_crc = ntohs(batman_ogm_packet->tt_crc); + tt_buff = packet_buff + buff_pos + BATMAN_OGM_HLEN; bat_iv_ogm_process(ethhdr, batman_ogm_packet, @@ -1239,7 +1234,7 @@ static int bat_iv_ogm_receive(struct sk_buff *skb, } static struct bat_algo_ops batman_iv __read_mostly = { - .name = "BATMAN_IV", + .name = "BATMAN IV", .bat_iface_enable = bat_iv_ogm_iface_enable, .bat_iface_disable = bat_iv_ogm_iface_disable, .bat_iface_update_mac = bat_iv_ogm_iface_update_mac, diff --git a/trunk/net/batman-adv/bat_sysfs.c b/trunk/net/batman-adv/bat_sysfs.c index dc1edbee63df..5bc7b66d32dc 100644 --- a/trunk/net/batman-adv/bat_sysfs.c +++ b/trunk/net/batman-adv/bat_sysfs.c @@ -445,7 +445,7 @@ BAT_ATTR_SIF_UINT(gw_sel_class, S_IRUGO | S_IWUSR, 1, TQ_MAX_VALUE, static BAT_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, show_gw_bwidth, store_gw_bwidth); #ifdef CONFIG_BATMAN_ADV_DEBUG -BAT_ATTR_SIF_UINT(log_level, S_IRUGO | S_IWUSR, 0, DBG_ALL, NULL); +BAT_ATTR_SIF_UINT(log_level, S_IRUGO | S_IWUSR, 0, 15, NULL); #endif static struct bat_attribute *mesh_attrs[] = { @@ -680,7 +680,7 @@ void sysfs_del_hardif(struct kobject **hardif_obj) int throw_uevent(struct bat_priv *bat_priv, enum uev_type type, enum uev_action action, const char *data) { - int ret = -ENOMEM; + int ret = -1; struct hard_iface *primary_if = NULL; struct kobject *bat_kobj; char *uevent_env[4] = { NULL, NULL, NULL, NULL }; diff --git a/trunk/net/batman-adv/bridge_loop_avoidance.c b/trunk/net/batman-adv/bridge_loop_avoidance.c index 314e37b272a7..8bf97515a77d 100644 --- a/trunk/net/batman-adv/bridge_loop_avoidance.c +++ b/trunk/net/batman-adv/bridge_loop_avoidance.c @@ -258,7 +258,7 @@ static void bla_send_claim(struct bat_priv *bat_priv, uint8_t *mac, struct net_device *soft_iface; uint8_t *hw_src; struct bla_claim_dst local_claim_dest; - __be32 zeroip = 0; + uint32_t zeroip = 0; primary_if = primary_if_get_selected(bat_priv); if (!primary_if) @@ -506,11 +506,11 @@ static void bla_send_announce(struct bat_priv *bat_priv, struct backbone_gw *backbone_gw) { uint8_t mac[ETH_ALEN]; - __be16 crc; + uint16_t crc; memcpy(mac, announce_mac, 4); crc = htons(backbone_gw->crc); - memcpy(&mac[4], &crc, 2); + memcpy(&mac[4], (uint8_t *)&crc, 2); bla_send_claim(bat_priv, mac, backbone_gw->vid, CLAIM_TYPE_ANNOUNCE); @@ -627,7 +627,7 @@ static int handle_announce(struct bat_priv *bat_priv, /* handle as ANNOUNCE frame */ backbone_gw->lasttime = jiffies; - crc = ntohs(*((__be16 *)(&an_addr[4]))); + crc = ntohs(*((uint16_t *)(&an_addr[4]))); bat_dbg(DBG_BLA, bat_priv, "handle_announce(): ANNOUNCE vid %d (sent by %pM)... CRC = %04x\n", @@ -1127,14 +1127,6 @@ static void bla_periodic_work(struct work_struct *work) bla_start_timer(bat_priv); } -/* The hash for claim and backbone hash receive the same key because they - * are getting initialized by hash_new with the same key. Reinitializing - * them with to different keys to allow nested locking without generating - * lockdep warnings - */ -static struct lock_class_key claim_hash_lock_class_key; -static struct lock_class_key backbone_hash_lock_class_key; - /* initialize all bla structures */ int bla_init(struct bat_priv *bat_priv) { @@ -1164,23 +1156,18 @@ int bla_init(struct bat_priv *bat_priv) bat_priv->bcast_duplist_curr = 0; if (bat_priv->claim_hash) - return 0; + return 1; bat_priv->claim_hash = hash_new(128); bat_priv->backbone_hash = hash_new(32); if (!bat_priv->claim_hash || !bat_priv->backbone_hash) - return -ENOMEM; - - batadv_hash_set_lock_class(bat_priv->claim_hash, - &claim_hash_lock_class_key); - batadv_hash_set_lock_class(bat_priv->backbone_hash, - &backbone_hash_lock_class_key); + return -1; bat_dbg(DBG_BLA, bat_priv, "bla hashes initialized\n"); bla_start_timer(bat_priv); - return 0; + return 1; } /** diff --git a/trunk/net/batman-adv/gateway_common.c b/trunk/net/batman-adv/gateway_common.c index 6e3b052b935d..ca57ac7d73b2 100644 --- a/trunk/net/batman-adv/gateway_common.c +++ b/trunk/net/batman-adv/gateway_common.c @@ -162,9 +162,6 @@ ssize_t gw_bandwidth_set(struct net_device *net_dev, char *buff, size_t count) **/ gw_bandwidth_to_kbit((uint8_t)gw_bandwidth_tmp, &down, &up); - if (atomic_read(&bat_priv->gw_bandwidth) == gw_bandwidth_tmp) - return count; - gw_deselect(bat_priv); bat_info(net_dev, "Changing gateway bandwidth from: '%i' to: '%ld' (propagating: %d%s/%d%s)\n", diff --git a/trunk/net/batman-adv/hard-interface.c b/trunk/net/batman-adv/hard-interface.c index ce78c6d645c6..dc334fa89847 100644 --- a/trunk/net/batman-adv/hard-interface.c +++ b/trunk/net/batman-adv/hard-interface.c @@ -306,8 +306,10 @@ int hardif_enable_interface(struct hard_iface *hard_iface, bat_priv = netdev_priv(hard_iface->soft_iface); ret = bat_priv->bat_algo_ops->bat_iface_enable(hard_iface); - if (ret < 0) + if (ret < 0) { + ret = -ENOMEM; goto err_dev; + } hard_iface->if_num = bat_priv->num_ifaces; bat_priv->num_ifaces++; diff --git a/trunk/net/batman-adv/hash.c b/trunk/net/batman-adv/hash.c index 5b2eabe7c4e0..117687bedf25 100644 --- a/trunk/net/batman-adv/hash.c +++ b/trunk/net/batman-adv/hash.c @@ -69,12 +69,3 @@ struct hashtable_t *hash_new(uint32_t size) kfree(hash); return NULL; } - -void batadv_hash_set_lock_class(struct hashtable_t *hash, - struct lock_class_key *key) -{ - uint32_t i; - - for (i = 0; i < hash->size; i++) - lockdep_set_class(&hash->list_locks[i], key); -} diff --git a/trunk/net/batman-adv/hash.h b/trunk/net/batman-adv/hash.h index 3d67ce49fc31..d4bd7862719b 100644 --- a/trunk/net/batman-adv/hash.h +++ b/trunk/net/batman-adv/hash.h @@ -45,10 +45,6 @@ struct hashtable_t { /* allocates and clears the hash */ struct hashtable_t *hash_new(uint32_t size); -/* set class key for all locks */ -void batadv_hash_set_lock_class(struct hashtable_t *hash, - struct lock_class_key *key); - /* free only the hashtable and the hash itself. */ void hash_destroy(struct hashtable_t *hash); @@ -110,23 +106,26 @@ static inline int hash_add(struct hashtable_t *hash, head = &hash->table[index]; list_lock = &hash->list_locks[index]; - spin_lock_bh(list_lock); - - hlist_for_each(node, head) { + rcu_read_lock(); + __hlist_for_each_rcu(node, head) { if (!compare(node, data)) continue; ret = 1; - goto unlock; + goto err_unlock; } + rcu_read_unlock(); /* no duplicate found in list, add new element */ + spin_lock_bh(list_lock); hlist_add_head_rcu(data_node, head); + spin_unlock_bh(list_lock); ret = 0; + goto out; -unlock: - spin_unlock_bh(list_lock); +err_unlock: + rcu_read_unlock(); out: return ret; } diff --git a/trunk/net/batman-adv/icmp_socket.c b/trunk/net/batman-adv/icmp_socket.c index d27db8192e93..2e98a57f3407 100644 --- a/trunk/net/batman-adv/icmp_socket.c +++ b/trunk/net/batman-adv/icmp_socket.c @@ -285,13 +285,13 @@ int bat_socket_setup(struct bat_priv *bat_priv) d = debugfs_create_file(ICMP_SOCKET, S_IFREG | S_IWUSR | S_IRUSR, bat_priv->debug_dir, bat_priv, &fops); - if (!d) + if (d) goto err; return 0; err: - return -ENOMEM; + return 1; } static void bat_socket_add_packet(struct socket_client *socket_client, diff --git a/trunk/net/batman-adv/main.c b/trunk/net/batman-adv/main.c index 46ba302d2d01..083a2993efe4 100644 --- a/trunk/net/batman-adv/main.c +++ b/trunk/net/batman-adv/main.c @@ -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}; @@ -92,7 +92,6 @@ static void __exit batman_exit(void) int mesh_init(struct net_device *soft_iface) { struct bat_priv *bat_priv = netdev_priv(soft_iface); - int ret; spin_lock_init(&bat_priv->forw_bat_list_lock); spin_lock_init(&bat_priv->forw_bcast_list_lock); @@ -111,32 +110,30 @@ int mesh_init(struct net_device *soft_iface) INIT_LIST_HEAD(&bat_priv->tt_req_list); INIT_LIST_HEAD(&bat_priv->tt_roam_list); - ret = originator_init(bat_priv); - if (ret < 0) + if (originator_init(bat_priv) < 1) goto err; - ret = tt_init(bat_priv); - if (ret < 0) + if (tt_init(bat_priv) < 1) goto err; tt_local_add(soft_iface, soft_iface->dev_addr, NULL_IFINDEX); - ret = vis_init(bat_priv); - if (ret < 0) + if (vis_init(bat_priv) < 1) goto err; - ret = bla_init(bat_priv); - if (ret < 0) + if (bla_init(bat_priv) < 1) goto err; atomic_set(&bat_priv->gw_reselect, 0); atomic_set(&bat_priv->mesh_state, MESH_ACTIVE); - - return 0; + goto end; err: mesh_free(soft_iface); - return ret; + return -1; + +end: + return 0; } void mesh_free(struct net_device *soft_iface) @@ -156,8 +153,6 @@ void mesh_free(struct net_device *soft_iface) bla_free(bat_priv); - free_percpu(bat_priv->bat_counters); - atomic_set(&bat_priv->mesh_state, MESH_INACTIVE); } @@ -322,13 +317,12 @@ static struct bat_algo_ops *bat_algo_get(char *name) int bat_algo_register(struct bat_algo_ops *bat_algo_ops) { struct bat_algo_ops *bat_algo_ops_tmp; - int ret; + int ret = -1; bat_algo_ops_tmp = bat_algo_get(bat_algo_ops->name); if (bat_algo_ops_tmp) { pr_info("Trying to register already registered routing algorithm: %s\n", bat_algo_ops->name); - ret = -EEXIST; goto out; } @@ -341,7 +335,6 @@ int bat_algo_register(struct bat_algo_ops *bat_algo_ops) !bat_algo_ops->bat_ogm_emit) { pr_info("Routing algo '%s' does not implement required ops\n", bat_algo_ops->name); - ret = -EINVAL; goto out; } @@ -356,7 +349,7 @@ int bat_algo_register(struct bat_algo_ops *bat_algo_ops) int bat_algo_select(struct bat_priv *bat_priv, char *name) { struct bat_algo_ops *bat_algo_ops; - int ret = -EINVAL; + int ret = -1; bat_algo_ops = bat_algo_get(name); if (!bat_algo_ops) @@ -386,19 +379,14 @@ int bat_algo_seq_print_text(struct seq_file *seq, void *offset) 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(algo_name); + bat_algo_ops = bat_algo_get((char *)val); if (!bat_algo_ops) { - pr_err("Routing algorithm '%s' is not supported\n", algo_name); + pr_err("Routing algorithm '%s' is not supported\n", val); return -EINVAL; } - return param_set_copystring(algo_name, kp); + return param_set_copystring(val, kp); } static const struct kernel_param_ops param_ops_ra = { diff --git a/trunk/net/batman-adv/main.h b/trunk/net/batman-adv/main.h index 6e0cbdc48321..f4a3ec003479 100644 --- a/trunk/net/batman-adv/main.h +++ b/trunk/net/batman-adv/main.h @@ -28,7 +28,7 @@ #define DRIVER_DEVICE "batman-adv" #ifndef SOURCE_VERSION -#define SOURCE_VERSION "2012.3.0" +#define SOURCE_VERSION "2012.2.0" #endif /* B.A.T.M.A.N. parameters */ @@ -138,7 +138,6 @@ enum dbg_level { #include /* kernel threads */ #include /* schedule types */ #include /* workqueue */ -#include #include #include /* struct sock */ #include @@ -243,30 +242,4 @@ static inline bool has_timed_out(unsigned long timestamp, unsigned int timeout) _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 batadv_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 batadv_inc_counter(b, i) batadv_add_counter(b, i, 1) - -/* Sum and return the cpu-local counters for index 'idx' */ -static inline uint64_t batadv_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_ */ diff --git a/trunk/net/batman-adv/originator.c b/trunk/net/batman-adv/originator.c index cf83c5422e9a..41147942ba53 100644 --- a/trunk/net/batman-adv/originator.c +++ b/trunk/net/batman-adv/originator.c @@ -50,7 +50,7 @@ static int compare_orig(const struct hlist_node *node, const void *data2) int originator_init(struct bat_priv *bat_priv) { if (bat_priv->orig_hash) - return 0; + return 1; bat_priv->orig_hash = hash_new(1024); @@ -58,10 +58,10 @@ int originator_init(struct bat_priv *bat_priv) goto err; start_purge_timer(bat_priv); - return 0; + return 1; err: - return -ENOMEM; + return 0; } void neigh_node_free_ref(struct neigh_node *neigh_node) @@ -488,7 +488,7 @@ static int orig_node_add_if(struct orig_node *orig_node, int max_if_num) data_ptr = kmalloc(max_if_num * sizeof(unsigned long) * NUM_WORDS, GFP_ATOMIC); if (!data_ptr) - return -ENOMEM; + return -1; memcpy(data_ptr, orig_node->bcast_own, (max_if_num - 1) * sizeof(unsigned long) * NUM_WORDS); @@ -497,7 +497,7 @@ static int orig_node_add_if(struct orig_node *orig_node, int max_if_num) data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC); if (!data_ptr) - return -ENOMEM; + return -1; memcpy(data_ptr, orig_node->bcast_own_sum, (max_if_num - 1) * sizeof(uint8_t)); @@ -528,7 +528,7 @@ int orig_hash_add_if(struct hard_iface *hard_iface, int max_if_num) ret = orig_node_add_if(orig_node, max_if_num); spin_unlock_bh(&orig_node->ogm_cnt_lock); - if (ret == -ENOMEM) + if (ret == -1) goto err; } rcu_read_unlock(); @@ -554,7 +554,7 @@ static int orig_node_del_if(struct orig_node *orig_node, chunk_size = sizeof(unsigned long) * NUM_WORDS; data_ptr = kmalloc(max_if_num * chunk_size, GFP_ATOMIC); if (!data_ptr) - return -ENOMEM; + return -1; /* copy first part */ memcpy(data_ptr, orig_node->bcast_own, del_if_num * chunk_size); @@ -573,7 +573,7 @@ static int orig_node_del_if(struct orig_node *orig_node, data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC); if (!data_ptr) - return -ENOMEM; + return -1; memcpy(data_ptr, orig_node->bcast_own_sum, del_if_num * sizeof(uint8_t)); @@ -612,7 +612,7 @@ int orig_hash_del_if(struct hard_iface *hard_iface, int max_if_num) hard_iface->if_num); spin_unlock_bh(&orig_node->ogm_cnt_lock); - if (ret == -ENOMEM) + if (ret == -1) goto err; } rcu_read_unlock(); diff --git a/trunk/net/batman-adv/packet.h b/trunk/net/batman-adv/packet.h index 033d99490e82..0ee1af770798 100644 --- a/trunk/net/batman-adv/packet.h +++ b/trunk/net/batman-adv/packet.h @@ -105,7 +105,7 @@ enum bla_claimframe { struct bla_claim_dst { uint8_t magic[3]; /* FF:43:05 */ uint8_t type; /* bla_claimframe */ - __be16 group; /* group id */ + uint16_t group; /* group id */ } __packed; struct batman_header { @@ -117,14 +117,14 @@ struct batman_header { struct batman_ogm_packet { struct batman_header header; uint8_t flags; /* 0x40: DIRECTLINK flag, 0x20 VIS_SERVER flag... */ - __be32 seqno; + uint32_t seqno; uint8_t orig[ETH_ALEN]; uint8_t prev_sender[ETH_ALEN]; uint8_t gw_flags; /* flags related to gateway class */ uint8_t tq; uint8_t tt_num_changes; uint8_t ttvn; /* translation table version number */ - __be16 tt_crc; + uint16_t tt_crc; } __packed; #define BATMAN_OGM_HLEN sizeof(struct batman_ogm_packet) @@ -134,7 +134,7 @@ struct icmp_packet { uint8_t msg_type; /* see ICMP message types above */ uint8_t dst[ETH_ALEN]; uint8_t orig[ETH_ALEN]; - __be16 seqno; + uint16_t seqno; uint8_t uid; uint8_t reserved; } __packed; @@ -148,7 +148,7 @@ struct icmp_packet_rr { uint8_t msg_type; /* see ICMP message types above */ uint8_t dst[ETH_ALEN]; uint8_t orig[ETH_ALEN]; - __be16 seqno; + uint16_t seqno; uint8_t uid; uint8_t rr_cur; uint8_t rr[BAT_RR_LEN][ETH_ALEN]; @@ -167,20 +167,20 @@ struct unicast_frag_packet { uint8_t flags; uint8_t align; uint8_t orig[ETH_ALEN]; - __be16 seqno; + uint16_t seqno; } __packed; struct bcast_packet { struct batman_header header; uint8_t reserved; - __be32 seqno; + uint32_t seqno; uint8_t orig[ETH_ALEN]; } __packed; struct vis_packet { struct batman_header header; uint8_t vis_type; /* which type of vis-participant sent this? */ - __be32 seqno; /* sequence number */ + uint32_t seqno; /* sequence number */ uint8_t entries; /* number of entries behind this struct */ uint8_t reserved; uint8_t vis_orig[ETH_ALEN]; /* originator reporting its neighbors */ @@ -206,7 +206,7 @@ struct tt_query_packet { * if TT_REQUEST: crc associated with the * ttvn * if TT_RESPONSE: table_size */ - __be16 tt_data; + uint16_t tt_data; } __packed; struct roam_adv_packet { diff --git a/trunk/net/batman-adv/routing.c b/trunk/net/batman-adv/routing.c index 9cfd23c6d64a..840e2c64a301 100644 --- a/trunk/net/batman-adv/routing.c +++ b/trunk/net/batman-adv/routing.c @@ -573,7 +573,7 @@ int recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if) { struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); struct tt_query_packet *tt_query; - uint16_t tt_size; + uint16_t tt_len; struct ethhdr *ethhdr; /* drop packet if it has not necessary minimum size */ @@ -596,10 +596,10 @@ int recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if) tt_query = (struct tt_query_packet *)skb->data; + tt_query->tt_data = ntohs(tt_query->tt_data); + switch (tt_query->flags & TT_QUERY_TYPE_MASK) { case TT_REQUEST: - batadv_inc_counter(bat_priv, BAT_CNT_TT_REQUEST_RX); - /* If we cannot provide an answer the tt_request is * forwarded */ if (!send_tt_response(bat_priv, tt_query)) { @@ -607,25 +607,22 @@ int recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if) "Routing TT_REQUEST to %pM [%c]\n", tt_query->dst, (tt_query->flags & TT_FULL_TABLE ? 'F' : '.')); + tt_query->tt_data = htons(tt_query->tt_data); return route_unicast_packet(skb, recv_if); } break; case TT_RESPONSE: - batadv_inc_counter(bat_priv, BAT_CNT_TT_RESPONSE_RX); - if (is_my_mac(tt_query->dst)) { /* packet needs to be linearized to access the TT * changes */ if (skb_linearize(skb) < 0) goto out; - /* skb_linearize() possibly changed skb->data */ - tt_query = (struct tt_query_packet *)skb->data; - tt_size = tt_len(ntohs(tt_query->tt_data)); + tt_len = tt_query->tt_data * sizeof(struct tt_change); /* Ensure we have all the claimed data */ if (unlikely(skb_headlen(skb) < - sizeof(struct tt_query_packet) + tt_size)) + sizeof(struct tt_query_packet) + tt_len)) goto out; handle_tt_response(bat_priv, tt_query); @@ -634,6 +631,7 @@ int recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if) "Routing TT_RESPONSE to %pM [%c]\n", tt_query->dst, (tt_query->flags & TT_FULL_TABLE ? 'F' : '.')); + tt_query->tt_data = htons(tt_query->tt_data); return route_unicast_packet(skb, recv_if); } break; @@ -665,8 +663,6 @@ int recv_roam_adv(struct sk_buff *skb, struct hard_iface *recv_if) if (is_broadcast_ether_addr(ethhdr->h_source)) goto out; - batadv_inc_counter(bat_priv, BAT_CNT_TT_ROAM_ADV_RX); - roam_adv_packet = (struct roam_adv_packet *)skb->data; if (!is_my_mac(roam_adv_packet->dst)) @@ -874,11 +870,6 @@ static int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if) /* decrement ttl */ unicast_packet->header.ttl--; - /* Update stats counter */ - batadv_inc_counter(bat_priv, BAT_CNT_FORWARD); - batadv_add_counter(bat_priv, BAT_CNT_FORWARD_BYTES, - skb->len + ETH_HLEN); - /* route it */ send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); ret = NET_RX_SUCCESS; diff --git a/trunk/net/batman-adv/send.c b/trunk/net/batman-adv/send.c index 79f8973810c0..f47299f22c68 100644 --- a/trunk/net/batman-adv/send.c +++ b/trunk/net/batman-adv/send.c @@ -77,9 +77,62 @@ int send_skb_packet(struct sk_buff *skb, struct hard_iface *hard_iface, return NET_XMIT_DROP; } +static void realloc_packet_buffer(struct hard_iface *hard_iface, + int new_len) +{ + unsigned char *new_buff; + + new_buff = kmalloc(new_len, GFP_ATOMIC); + + /* keep old buffer if kmalloc should fail */ + if (new_buff) { + memcpy(new_buff, hard_iface->packet_buff, + BATMAN_OGM_HLEN); + + kfree(hard_iface->packet_buff); + hard_iface->packet_buff = new_buff; + hard_iface->packet_len = new_len; + } +} + +/* when calling this function (hard_iface == primary_if) has to be true */ +static int prepare_packet_buffer(struct bat_priv *bat_priv, + struct hard_iface *hard_iface) +{ + int new_len; + + new_len = BATMAN_OGM_HLEN + + tt_len((uint8_t)atomic_read(&bat_priv->tt_local_changes)); + + /* if we have too many changes for one packet don't send any + * and wait for the tt table request which will be fragmented */ + if (new_len > hard_iface->soft_iface->mtu) + new_len = BATMAN_OGM_HLEN; + + realloc_packet_buffer(hard_iface, new_len); + + atomic_set(&bat_priv->tt_crc, tt_local_crc(bat_priv)); + + /* reset the sending counter */ + atomic_set(&bat_priv->tt_ogm_append_cnt, TT_OGM_APPEND_MAX); + + return tt_changes_fill_buffer(bat_priv, + hard_iface->packet_buff + BATMAN_OGM_HLEN, + hard_iface->packet_len - BATMAN_OGM_HLEN); +} + +static int reset_packet_buffer(struct bat_priv *bat_priv, + struct hard_iface *hard_iface) +{ + realloc_packet_buffer(hard_iface, BATMAN_OGM_HLEN); + return 0; +} + void schedule_bat_ogm(struct hard_iface *hard_iface) { struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface); + struct hard_iface *primary_if; + int tt_num_changes = -1; if ((hard_iface->if_status == IF_NOT_IN_USE) || (hard_iface->if_status == IF_TO_BE_REMOVED)) @@ -95,7 +148,26 @@ void schedule_bat_ogm(struct hard_iface *hard_iface) if (hard_iface->if_status == IF_TO_BE_ACTIVATED) hard_iface->if_status = IF_ACTIVE; - bat_priv->bat_algo_ops->bat_ogm_schedule(hard_iface); + primary_if = primary_if_get_selected(bat_priv); + + if (hard_iface == primary_if) { + /* if at least one change happened */ + if (atomic_read(&bat_priv->tt_local_changes) > 0) { + tt_commit_changes(bat_priv); + tt_num_changes = prepare_packet_buffer(bat_priv, + hard_iface); + } + + /* if the changes have been sent often enough */ + if (!atomic_dec_not_zero(&bat_priv->tt_ogm_append_cnt)) + tt_num_changes = reset_packet_buffer(bat_priv, + hard_iface); + } + + if (primary_if) + hardif_free_ref(primary_if); + + bat_priv->bat_algo_ops->bat_ogm_schedule(hard_iface, tt_num_changes); } static void forw_packet_free(struct forw_packet *forw_packet) diff --git a/trunk/net/batman-adv/soft-interface.c b/trunk/net/batman-adv/soft-interface.c index 304a7ba09e03..6e2530b02043 100644 --- a/trunk/net/batman-adv/soft-interface.c +++ b/trunk/net/batman-adv/soft-interface.c @@ -45,10 +45,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 void batadv_get_strings(struct net_device *dev, u32 stringset, u8 *data); -static void batadv_get_ethtool_stats(struct net_device *dev, - struct ethtool_stats *stats, u64 *data); -static int batadv_get_sset_count(struct net_device *dev, int stringset); static const struct ethtool_ops bat_ethtool_ops = { .get_settings = bat_get_settings, @@ -56,9 +52,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_strings = batadv_get_strings, - .get_ethtool_stats = batadv_get_ethtool_stats, - .get_sset_count = batadv_get_sset_count, }; int my_skb_head_push(struct sk_buff *skb, unsigned int len) @@ -406,18 +399,13 @@ struct net_device *softif_create(const char *name) bat_priv->primary_if = NULL; bat_priv->num_ifaces = 0; - bat_priv->bat_counters = __alloc_percpu(sizeof(uint64_t) * BAT_CNT_NUM, - __alignof__(uint64_t)); - if (!bat_priv->bat_counters) - goto unreg_soft_iface; - ret = bat_algo_select(bat_priv, bat_routing_algo); if (ret < 0) - goto free_bat_counters; + goto unreg_soft_iface; ret = sysfs_add_meshif(soft_iface); if (ret < 0) - goto free_bat_counters; + goto unreg_soft_iface; ret = debugfs_add_meshif(soft_iface); if (ret < 0) @@ -433,8 +421,6 @@ struct net_device *softif_create(const char *name) debugfs_del_meshif(soft_iface); unreg_sysfs: sysfs_del_meshif(soft_iface); -free_bat_counters: - free_percpu(bat_priv->bat_counters); unreg_soft_iface: unregister_netdevice(soft_iface); return NULL; @@ -500,51 +486,3 @@ static u32 bat_get_link(struct net_device *dev) { return 1; } - -/* Inspired by drivers/net/ethernet/dlink/sundance.c:1702 - * Declare each description string in struct.name[] to get fixed sized buffer - * and compile time checking for strings longer than ETH_GSTRING_LEN. - */ -static const struct { - const char name[ETH_GSTRING_LEN]; -} bat_counters_strings[] = { - { "forward" }, - { "forward_bytes" }, - { "mgmt_tx" }, - { "mgmt_tx_bytes" }, - { "mgmt_rx" }, - { "mgmt_rx_bytes" }, - { "tt_request_tx" }, - { "tt_request_rx" }, - { "tt_response_tx" }, - { "tt_response_rx" }, - { "tt_roam_adv_tx" }, - { "tt_roam_adv_rx" }, -}; - -static void batadv_get_strings(struct net_device *dev, uint32_t stringset, - uint8_t *data) -{ - if (stringset == ETH_SS_STATS) - memcpy(data, bat_counters_strings, - sizeof(bat_counters_strings)); -} - -static void batadv_get_ethtool_stats(struct net_device *dev, - struct ethtool_stats *stats, - uint64_t *data) -{ - struct bat_priv *bat_priv = netdev_priv(dev); - int i; - - for (i = 0; i < BAT_CNT_NUM; i++) - data[i] = batadv_sum_counter(bat_priv, i); -} - -static int batadv_get_sset_count(struct net_device *dev, int stringset) -{ - if (stringset == ETH_SS_STATS) - return BAT_CNT_NUM; - - return -EOPNOTSUPP; -} diff --git a/trunk/net/batman-adv/translation-table.c b/trunk/net/batman-adv/translation-table.c index a1a51cc9d88e..a66c2dcd1088 100644 --- a/trunk/net/batman-adv/translation-table.c +++ b/trunk/net/batman-adv/translation-table.c @@ -181,14 +181,14 @@ int tt_len(int changes_num) static int tt_local_init(struct bat_priv *bat_priv) { if (bat_priv->tt_local_hash) - return 0; + return 1; bat_priv->tt_local_hash = hash_new(1024); if (!bat_priv->tt_local_hash) - return -ENOMEM; + return 0; - return 0; + return 1; } void tt_local_add(struct net_device *soft_iface, const uint8_t *addr, @@ -275,64 +275,14 @@ void tt_local_add(struct net_device *soft_iface, const uint8_t *addr, tt_global_entry_free_ref(tt_global_entry); } -static void tt_realloc_packet_buff(unsigned char **packet_buff, - int *packet_buff_len, int min_packet_len, - int new_packet_len) -{ - unsigned char *new_buff; - - new_buff = kmalloc(new_packet_len, GFP_ATOMIC); - - /* keep old buffer if kmalloc should fail */ - if (new_buff) { - memcpy(new_buff, *packet_buff, min_packet_len); - kfree(*packet_buff); - *packet_buff = new_buff; - *packet_buff_len = new_packet_len; - } -} - -static void tt_prepare_packet_buff(struct bat_priv *bat_priv, - unsigned char **packet_buff, - int *packet_buff_len, int min_packet_len) -{ - struct hard_iface *primary_if; - int req_len; - - primary_if = primary_if_get_selected(bat_priv); - - req_len = min_packet_len; - req_len += tt_len(atomic_read(&bat_priv->tt_local_changes)); - - /* if we have too many changes for one packet don't send any - * and wait for the tt table request which will be fragmented - */ - if ((!primary_if) || (req_len > primary_if->soft_iface->mtu)) - req_len = min_packet_len; - - tt_realloc_packet_buff(packet_buff, packet_buff_len, - min_packet_len, req_len); - - if (primary_if) - hardif_free_ref(primary_if); -} - -static int tt_changes_fill_buff(struct bat_priv *bat_priv, - unsigned char **packet_buff, - int *packet_buff_len, int min_packet_len) +int tt_changes_fill_buffer(struct bat_priv *bat_priv, + unsigned char *buff, int buff_len) { + int count = 0, tot_changes = 0; struct tt_change_node *entry, *safe; - int count = 0, tot_changes = 0, new_len; - unsigned char *tt_buff; - - tt_prepare_packet_buff(bat_priv, packet_buff, - packet_buff_len, min_packet_len); - new_len = *packet_buff_len - min_packet_len; - tt_buff = *packet_buff + min_packet_len; - - if (new_len > 0) - tot_changes = new_len / tt_len(1); + if (buff_len > 0) + tot_changes = buff_len / tt_len(1); spin_lock_bh(&bat_priv->tt_changes_list_lock); atomic_set(&bat_priv->tt_local_changes, 0); @@ -340,7 +290,7 @@ static int tt_changes_fill_buff(struct bat_priv *bat_priv, list_for_each_entry_safe(entry, safe, &bat_priv->tt_changes_list, list) { if (count < tot_changes) { - memcpy(tt_buff + tt_len(count), + memcpy(buff + tt_len(count), &entry->change, sizeof(struct tt_change)); count++; } @@ -354,20 +304,22 @@ static int tt_changes_fill_buff(struct bat_priv *bat_priv, kfree(bat_priv->tt_buff); bat_priv->tt_buff_len = 0; bat_priv->tt_buff = NULL; - /* check whether this new OGM has no changes due to size problems */ - if (new_len > 0) { - /* if kmalloc() fails we will reply with the full table + /* We check whether this new OGM has no changes due to size + * problems */ + if (buff_len > 0) { + /** + * if kmalloc() fails we will reply with the full table * instead of providing the diff */ - bat_priv->tt_buff = kmalloc(new_len, GFP_ATOMIC); + bat_priv->tt_buff = kmalloc(buff_len, GFP_ATOMIC); if (bat_priv->tt_buff) { - memcpy(bat_priv->tt_buff, tt_buff, new_len); - bat_priv->tt_buff_len = new_len; + memcpy(bat_priv->tt_buff, buff, buff_len); + bat_priv->tt_buff_len = buff_len; } } spin_unlock_bh(&bat_priv->tt_buff_lock); - return count; + return tot_changes; } int tt_local_seq_print_text(struct seq_file *seq, void *offset) @@ -539,14 +491,14 @@ static void tt_local_table_free(struct bat_priv *bat_priv) static int tt_global_init(struct bat_priv *bat_priv) { if (bat_priv->tt_global_hash) - return 0; + return 1; bat_priv->tt_global_hash = hash_new(1024); if (!bat_priv->tt_global_hash) - return -ENOMEM; + return 0; - return 0; + return 1; } static void tt_changes_list_free(struct bat_priv *bat_priv) @@ -1153,7 +1105,7 @@ static uint16_t tt_global_crc(struct bat_priv *bat_priv, } /* Calculates the checksum of the local table */ -static uint16_t batadv_tt_local_crc(struct bat_priv *bat_priv) +uint16_t tt_local_crc(struct bat_priv *bat_priv) { uint16_t total = 0, total_one; struct hashtable_t *hash = bat_priv->tt_local_hash; @@ -1404,8 +1356,6 @@ static int send_tt_request(struct bat_priv *bat_priv, dst_orig_node->orig, neigh_node->addr, (full_table ? 'F' : '.')); - batadv_inc_counter(bat_priv, BAT_CNT_TT_REQUEST_TX); - send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); ret = 0; @@ -1466,7 +1416,7 @@ static bool send_other_tt_response(struct bat_priv *bat_priv, /* I don't have the requested data */ if (orig_ttvn != req_ttvn || - tt_request->tt_data != htons(req_dst_orig_node->tt_crc)) + tt_request->tt_data != req_dst_orig_node->tt_crc) goto out; /* If the full table has been explicitly requested */ @@ -1530,8 +1480,6 @@ static bool send_other_tt_response(struct bat_priv *bat_priv, res_dst_orig_node->orig, neigh_node->addr, req_dst_orig_node->orig, req_ttvn); - batadv_inc_counter(bat_priv, BAT_CNT_TT_RESPONSE_TX); - send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); ret = true; goto out; @@ -1648,8 +1596,6 @@ static bool send_my_tt_response(struct bat_priv *bat_priv, orig_node->orig, neigh_node->addr, (tt_response->flags & TT_FULL_TABLE ? 'F' : '.')); - batadv_inc_counter(bat_priv, BAT_CNT_TT_RESPONSE_TX); - send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); ret = true; goto out; @@ -1726,7 +1672,7 @@ static void tt_fill_gtable(struct bat_priv *bat_priv, _tt_update_changes(bat_priv, orig_node, (struct tt_change *)(tt_response + 1), - ntohs(tt_response->tt_data), tt_response->ttvn); + tt_response->tt_data, tt_response->ttvn); spin_lock_bh(&orig_node->tt_buff_lock); kfree(orig_node->tt_buff); @@ -1781,8 +1727,7 @@ void handle_tt_response(struct bat_priv *bat_priv, bat_dbg(DBG_TT, bat_priv, "Received TT_RESPONSE from %pM for ttvn %d t_size: %d [%c]\n", - tt_response->src, tt_response->ttvn, - ntohs(tt_response->tt_data), + tt_response->src, tt_response->ttvn, tt_response->tt_data, (tt_response->flags & TT_FULL_TABLE ? 'F' : '.')); /* we should have never asked a backbone gw */ @@ -1796,8 +1741,7 @@ void handle_tt_response(struct bat_priv *bat_priv, if (tt_response->flags & TT_FULL_TABLE) tt_fill_gtable(bat_priv, tt_response); else - tt_update_changes(bat_priv, orig_node, - ntohs(tt_response->tt_data), + tt_update_changes(bat_priv, orig_node, tt_response->tt_data, tt_response->ttvn, (struct tt_change *)(tt_response + 1)); @@ -1823,15 +1767,11 @@ void handle_tt_response(struct bat_priv *bat_priv, int tt_init(struct bat_priv *bat_priv) { - int ret; - - ret = tt_local_init(bat_priv); - if (ret < 0) - return ret; + if (!tt_local_init(bat_priv)) + return 0; - ret = tt_global_init(bat_priv); - if (ret < 0) - return ret; + if (!tt_global_init(bat_priv)) + return 0; tt_start_timer(bat_priv); @@ -1955,8 +1895,6 @@ static void send_roam_adv(struct bat_priv *bat_priv, uint8_t *client, "Sending ROAMING_ADV to %pM (client %pM) via %pM\n", orig_node->orig, client, neigh_node->addr); - batadv_inc_counter(bat_priv, BAT_CNT_TT_ROAM_ADV_TX); - send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); ret = 0; @@ -2073,56 +2011,20 @@ static void tt_local_purge_pending_clients(struct bat_priv *bat_priv) } -static int tt_commit_changes(struct bat_priv *bat_priv, - unsigned char **packet_buff, int *packet_buff_len, - int packet_min_len) +void tt_commit_changes(struct bat_priv *bat_priv) { - uint16_t changed_num = 0; - - if (atomic_read(&bat_priv->tt_local_changes) < 1) - return -ENOENT; - - changed_num = tt_set_flags(bat_priv->tt_local_hash, - TT_CLIENT_NEW, false); - - /* all reset entries have to be counted as local entries */ + uint16_t changed_num = tt_set_flags(bat_priv->tt_local_hash, + TT_CLIENT_NEW, false); + /* all the reset entries have now to be effectively counted as local + * entries */ atomic_add(changed_num, &bat_priv->num_local_tt); tt_local_purge_pending_clients(bat_priv); - bat_priv->tt_crc = batadv_tt_local_crc(bat_priv); /* Increment the TTVN only once per OGM interval */ atomic_inc(&bat_priv->ttvn); bat_dbg(DBG_TT, bat_priv, "Local changes committed, updating to ttvn %u\n", (uint8_t)atomic_read(&bat_priv->ttvn)); bat_priv->tt_poss_change = false; - - /* reset the sending counter */ - atomic_set(&bat_priv->tt_ogm_append_cnt, TT_OGM_APPEND_MAX); - - return tt_changes_fill_buff(bat_priv, packet_buff, - packet_buff_len, packet_min_len); -} - -/* when calling this function (hard_iface == primary_if) has to be true */ -int batadv_tt_append_diff(struct bat_priv *bat_priv, - unsigned char **packet_buff, int *packet_buff_len, - int packet_min_len) -{ - int tt_num_changes; - - /* if at least one change happened */ - tt_num_changes = tt_commit_changes(bat_priv, packet_buff, - packet_buff_len, packet_min_len); - - /* if the changes have been sent often enough */ - if ((tt_num_changes < 0) && - (!atomic_dec_not_zero(&bat_priv->tt_ogm_append_cnt))) { - tt_realloc_packet_buff(packet_buff, packet_buff_len, - packet_min_len, packet_min_len); - tt_num_changes = 0; - } - - return tt_num_changes; } bool is_ap_isolated(struct bat_priv *bat_priv, uint8_t *src, uint8_t *dst) diff --git a/trunk/net/batman-adv/translation-table.h b/trunk/net/batman-adv/translation-table.h index d6ea30f9b026..c43374dc364d 100644 --- a/trunk/net/batman-adv/translation-table.h +++ b/trunk/net/batman-adv/translation-table.h @@ -23,6 +23,8 @@ #define _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ int tt_len(int changes_num); +int tt_changes_fill_buffer(struct bat_priv *bat_priv, + unsigned char *buff, int buff_len); int tt_init(struct bat_priv *bat_priv); void tt_local_add(struct net_device *soft_iface, const uint8_t *addr, int ifindex); @@ -39,19 +41,18 @@ void tt_global_del_orig(struct bat_priv *bat_priv, struct orig_node *orig_node, const char *message); struct orig_node *transtable_search(struct bat_priv *bat_priv, const uint8_t *src, const uint8_t *addr); +uint16_t tt_local_crc(struct bat_priv *bat_priv); void tt_free(struct bat_priv *bat_priv); bool send_tt_response(struct bat_priv *bat_priv, struct tt_query_packet *tt_request); bool is_my_client(struct bat_priv *bat_priv, const uint8_t *addr); void handle_tt_response(struct bat_priv *bat_priv, struct tt_query_packet *tt_response); +void tt_commit_changes(struct bat_priv *bat_priv); bool is_ap_isolated(struct bat_priv *bat_priv, uint8_t *src, uint8_t *dst); void tt_update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node, const unsigned char *tt_buff, uint8_t tt_num_changes, uint8_t ttvn, uint16_t tt_crc); -int batadv_tt_append_diff(struct bat_priv *bat_priv, - unsigned char **packet_buff, int *packet_buff_len, - int packet_min_len); bool tt_global_client_is_roaming(struct bat_priv *bat_priv, uint8_t *addr); diff --git a/trunk/net/batman-adv/types.h b/trunk/net/batman-adv/types.h index bf71d525445a..61308e8016ff 100644 --- a/trunk/net/batman-adv/types.h +++ b/trunk/net/batman-adv/types.h @@ -148,26 +148,9 @@ struct bcast_duplist_entry { }; #endif -enum bat_counters { - BAT_CNT_FORWARD, - BAT_CNT_FORWARD_BYTES, - BAT_CNT_MGMT_TX, - BAT_CNT_MGMT_TX_BYTES, - BAT_CNT_MGMT_RX, - BAT_CNT_MGMT_RX_BYTES, - BAT_CNT_TT_REQUEST_TX, - BAT_CNT_TT_REQUEST_RX, - BAT_CNT_TT_RESPONSE_TX, - BAT_CNT_TT_RESPONSE_RX, - BAT_CNT_TT_ROAM_ADV_TX, - BAT_CNT_TT_ROAM_ADV_RX, - BAT_CNT_NUM, -}; - struct bat_priv { atomic_t mesh_state; struct net_device_stats stats; - uint64_t __percpu *bat_counters; /* Per cpu counters */ atomic_t aggregated_ogms; /* boolean */ atomic_t bonding; /* boolean */ atomic_t fragmentation; /* boolean */ @@ -227,7 +210,7 @@ struct bat_priv { spinlock_t vis_list_lock; /* protects vis_info::recv_list */ atomic_t num_local_tt; /* Checksum of the local table, recomputed before sending a new OGM */ - uint16_t tt_crc; + atomic_t tt_crc; unsigned char *tt_buff; int16_t tt_buff_len; spinlock_t tt_buff_lock; /* protects tt_buff */ @@ -405,7 +388,8 @@ struct bat_algo_ops { /* called when primary interface is selected / changed */ void (*bat_primary_iface_set)(struct hard_iface *hard_iface); /* prepare a new outgoing OGM for the send queue */ - void (*bat_ogm_schedule)(struct hard_iface *hard_iface); + void (*bat_ogm_schedule)(struct hard_iface *hard_iface, + int tt_num_changes); /* send scheduled OGM */ void (*bat_ogm_emit)(struct forw_packet *forw_packet); }; diff --git a/trunk/net/batman-adv/vis.c b/trunk/net/batman-adv/vis.c index 01d5da54143e..cec216fb77c7 100644 --- a/trunk/net/batman-adv/vis.c +++ b/trunk/net/batman-adv/vis.c @@ -207,6 +207,7 @@ int vis_seq_print_text(struct seq_file *seq, void *offset) int vis_server = atomic_read(&bat_priv->vis_mode); size_t buff_pos, buf_size; char *buff; + int compare; primary_if = primary_if_get_selected(bat_priv); if (!primary_if) @@ -227,18 +228,14 @@ int vis_seq_print_text(struct seq_file *seq, void *offset) entries = (struct vis_info_entry *) ((char *)packet + sizeof(*packet)); - vis_data_insert_interface(packet->vis_orig, - &vis_if_list, true); - for (j = 0; j < packet->entries; j++) { if (entries[j].quality == 0) continue; - if (compare_eth(entries[j].src, - packet->vis_orig)) - continue; + compare = + compare_eth(entries[j].src, packet->vis_orig); vis_data_insert_interface(entries[j].src, &vis_if_list, - false); + compare); } hlist_for_each_entry(entry, pos, &vis_if_list, list) { @@ -279,18 +276,14 @@ int vis_seq_print_text(struct seq_file *seq, void *offset) entries = (struct vis_info_entry *) ((char *)packet + sizeof(*packet)); - vis_data_insert_interface(packet->vis_orig, - &vis_if_list, true); - for (j = 0; j < packet->entries; j++) { if (entries[j].quality == 0) continue; - if (compare_eth(entries[j].src, - packet->vis_orig)) - continue; + compare = + compare_eth(entries[j].src, packet->vis_orig); vis_data_insert_interface(entries[j].src, &vis_if_list, - false); + compare); } hlist_for_each_entry(entry, pos, &vis_if_list, list) { @@ -633,7 +626,7 @@ static int generate_vis_packet(struct bat_priv *bat_priv) best_tq = find_best_vis_server(bat_priv, info); if (best_tq < 0) - return best_tq; + return -1; } for (i = 0; i < hash->size; i++) { @@ -885,7 +878,7 @@ int vis_init(struct bat_priv *bat_priv) int hash_added; if (bat_priv->vis_hash) - return 0; + return 1; spin_lock_bh(&bat_priv->vis_hash_lock); @@ -936,7 +929,7 @@ int vis_init(struct bat_priv *bat_priv) spin_unlock_bh(&bat_priv->vis_hash_lock); start_vis_timer(bat_priv); - return 0; + return 1; free_info: kfree(bat_priv->my_vis_info); @@ -944,7 +937,7 @@ int vis_init(struct bat_priv *bat_priv) err: spin_unlock_bh(&bat_priv->vis_hash_lock); vis_quit(bat_priv); - return -ENOMEM; + return 0; } /* Decrease the reference count on a hash item info */ diff --git a/trunk/net/netfilter/nf_conntrack_netlink.c b/trunk/net/netfilter/nf_conntrack_netlink.c index ae156dff4887..76271a1301a5 100644 --- a/trunk/net/netfilter/nf_conntrack_netlink.c +++ b/trunk/net/netfilter/nf_conntrack_netlink.c @@ -1224,19 +1224,12 @@ ctnetlink_change_helper(struct nf_conn *ct, const struct nlattr * const cda[]) if (helper->from_nlattr && helpinfo) helper->from_nlattr(helpinfo, ct); return 0; - } - if (help->helper) + } else return -EBUSY; - /* need to zero data of old helper */ - memset(help->data, 0, help->helper->data_len); - } else { - /* we cannot set a helper for an existing conntrack */ - return -EOPNOTSUPP; } - rcu_assign_pointer(help->helper, helper); - - return 0; + /* we cannot set a helper for an existing conntrack */ + return -EOPNOTSUPP; } static inline int