+struct roam_adv_packet {
+ uint8_t packet_type;
+ uint8_t version;
+ uint8_t dst[6];
+ uint8_t ttl;
+ uint8_t src[6];
+ uint8_t client[6];
+} __packed;
+
Maybe put ttl at the end, to help with alignment?
+ tt_global_add(bat_priv, orig_node,
roam_adv_packet->client,
+ atomic_read(&orig_node->last_ttvn) + 1, true);
+
+ /* Roaming phase starts: I have a new information but the ttvn has been
+ * incremented yet. This flag will make me check all the incoming
+ * packets for the correct destination. */
The grammar in that comment could be better:
/* Roaming phase starts: I have new information but the ttvn has not
* been incremented yet. This flag will make me check all the incoming
* packets for the correct destination. */
+void send_roam_adv(struct bat_priv *bat_priv, uint8_t *client,
+ struct orig_node *orig_node)
+{
+ struct neigh_node *neigh_node;
+ struct sk_buff *skb;
+ struct roam_adv_packet *roam_adv_packet;
+ struct tt_roam_node *tt_roam_node;
+ bool found = false;
+ int ret = 1;
+
+ spin_lock_bh(&bat_priv->tt_roam_list_lock);
+ /* The new tt_req will be issued only if I'm not waiting for a
+ * reply from the same orig_node yet */
+ list_for_each_entry(tt_roam_node, &bat_priv->tt_roam_list, list) {
+ if (!compare_eth(tt_roam_node->addr, client))
+ continue;
+
+ if (is_out_of_time(tt_roam_node->first_time,
+ ROAMING_MAX_TIME * 1000))
+ continue;
+
+ if (!atomic_dec_not_zero(&tt_roam_node->counter))
+ /* Sorry, you roamed too many times! */
+ goto unlock;
+
+ found = true;
+ break;
+ }
+
+ if (!found) {
+ tt_roam_node = kmalloc(sizeof(struct tt_roam_node), GFP_ATOMIC);
+ if (!tt_roam_node)
+ goto unlock;
+
+ tt_roam_node->first_time = jiffies;
+ atomic_set(&tt_roam_node->counter, ROAMING_MAX_COUNT - 1);
+ memcpy(tt_roam_node->addr, client, ETH_ALEN);
+
+ list_add(&tt_roam_node->list, &bat_priv->tt_roam_list);
+ }
+ spin_unlock_bh(&bat_priv->tt_roam_list_lock);
+
+ skb = dev_alloc_skb(sizeof(struct roam_adv_packet) + ETH_HLEN);
+ if (!skb)
+ goto free_skb;
If the allocation fails, go free it ?
+
+ skb_reserve(skb, ETH_HLEN);
+
+ roam_adv_packet = (struct roam_adv_packet *)skb_put(skb,
+ sizeof(struct roam_adv_packet));
+
+ roam_adv_packet->packet_type = BAT_ROAM_ADV;
+ roam_adv_packet->version = COMPAT_VERSION;
+ roam_adv_packet->ttl = TTL;
+ memcpy(roam_adv_packet->src,
+ bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+ memcpy(roam_adv_packet->dst, orig_node->orig, ETH_ALEN);
+ memcpy(roam_adv_packet->client, client, ETH_ALEN);
+
+ neigh_node = find_router(bat_priv, orig_node, NULL);
+ if (!neigh_node)
+ goto free_skb;
+
+ if (neigh_node->if_incoming->if_status != IF_ACTIVE)
+ goto free_neigh;
+
+ bat_dbg(DBG_ROUTES, bat_priv,
+ "Sending ROAMING_ADV to %pM (client %pM) via %pM\n",
+ orig_node->orig, client, neigh_node->addr);
+
+ send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
+ ret = 0;
+
+free_neigh:
+ if (neigh_node)
+ neigh_node_free_ref(neigh_node);
+free_skb:
+ if (ret)
+ kfree_skb(skb);
+ return;
+unlock:
+ spin_unlock_bh(&bat_priv->tt_roam_list_lock);
}
All these different goto's makes me think of BASIC. How about breaking
this function up into a number of functions.
1) find an existing tt_roam_node
2) Create a new tt_roam_node
3) Allocate and fill in the roam_adv_packet.
4) Find the neigh_node and send the packet.
You then end up with something like
void send_roam_adv(struct bat_priv *bat_priv, uint8_t *client,
struct orig_node *orig_node)
{
spin_lock_bh(&bat_priv->tt_roam_list_lock);
tt_roam_node = find_tt_roam_node(client);
if (!tt_roam_node) {
tt_roam_node = new_tt_roam_node(client, bat_priv);
}
spin_unlock_bh(&bat_priv->tt_roam_list_lock);
if (tt_roam_node)
roam_pkt = build_roam_pkt(bat_priv, orig_node, client);
if (roan_pkt)
send_roam_pkt(roam_pkt, orig_node, client);
}
No goto's and easier to understand. It also makes it clear that
tt_roam_node is not actually used while sending the packet, so maybe
it does not belong inside send_roam_adv()?
+ bool tt_poss_change; /* this flag is needed to
detect an ongoing
+ * roaming event. If it is true, it means that
+ * in the last OGM interval I sent a Roaming_adv,
+ * so I have to check every packet going to it
+ * whether the destination is still a client of
+ * its or not, it will be reset as soon as I'll
+ * receive a new TTVN from it */
+
Too many it/its. I have a hard time understanding what it is.
So, mostly comments about the comments and style issues.
Andrew