From: Marek Lindner <lindner_marek@yahoo.de>
To: The list for a Better Approach To Mobile Ad-hoc Networking
<b.a.t.m.a.n@lists.open-mesh.org>
Subject: Re: [B.A.T.M.A.N.] [PATCH 2/3] batman-adv: Receive fragmented packets and merge
Date: Wed, 24 Apr 2013 03:17:26 +0800 [thread overview]
Message-ID: <201304240317.27196.lindner_marek@yahoo.de> (raw)
In-Reply-To: <1366474654-26361-3-git-send-email-martin@hundeboll.net>
On Sunday, April 21, 2013 00:17:33 Martin Hundebøll wrote:
> @@ -0,0 +1,372 @@
> +/* Copyright (C) 2012 B.A.T.M.A.N. contributors:
The copyright year could be updated.
> +/**
> + * batadv_frag_clear_list() - Delete entries in the fragment buffer list.
> + * @head: head of list with entries.
> + *
> + * Frees fragments in the passed hlist. Should be called with appropriate
> lock. + */
The kernel doc should not contain "()" following the function name and no
capital letter after the hyphen. You do this multiple times ..
> +static void batadv_frag_clear_list(struct hlist_head *head)
> +{
> + struct batadv_frag_list_entry *entry;
> + struct hlist_node *node, *node_tmp;
> +
> + hlist_for_each_safe(node, node_tmp, head) {
> + entry = hlist_entry(node, struct batadv_frag_list_entry, list);
> + hlist_del(node);
> + kfree_skb(entry->skb);
> + kfree(entry);
> + }
> +}
Why not hlist_for_each_entry_safe() ?
> +/**
> + * batadv_frag_clear_orig() - Free fragments associated to an orig.
> + * @orig_node: Originator to free fragments from.
> + */
> +void batadv_frag_clear_orig(struct batadv_orig_node *orig_node)
> +{
> + uint8_t i;
> +
> + for (i = 0; i < BATADV_FRAG_BUFFER_COUNT; i++) {
> + spin_lock_bh(&orig_node->fragments[i].lock);
> + batadv_frag_clear_list(&orig_node->fragments[i].head);
> + orig_node->fragments[i].size = 0;
> + spin_unlock_bh(&orig_node->fragments[i].lock);
> + }
> +}
> +
> +/**
> + * batadv_frag_check_orig() - Free timed out fragments from an orig.
> + * @orig_node: originator to check fragments from.
> + *
> + * Check timestamp of every hlist in fragment table and delete all entries
> if + * timed out.
> + */
> +void batadv_frag_check_orig(struct batadv_orig_node *orig_node)
> +{
> + struct batadv_frag_table_entry *frags;
> + uint8_t i;
> +
> + for (i = 0; i < BATADV_FRAG_BUFFER_COUNT; i++) {
> + frags = &orig_node->fragments[i];
> + spin_lock_bh(&frags->lock);
> +
> + if (!hlist_empty(&frags->head) &&
> + batadv_has_timed_out(frags->timestamp, BATADV_FRAG_TIMEOUT))
> + batadv_frag_clear_list(&frags->head);
> +
> + spin_unlock_bh(&frags->lock);
> + }
> +}
batadv_frag_clear_orig() and batadv_frag_check_orig() nearly do the same thing
except for the timestamp check. Would it be feasible to merge these functions
into one ?
> +/**
> + * batadv_frag_size_limit() - Maximum possible size of fragmented packet.
> + */
Kernel doc mentioning the return value ?
> +static inline int batadv_frag_size_limit(void)
No need to explicitely "inline" the function. The compiler will do this for
us.
> +/**
> + * batadv_frag_init_list() - Check and prepare fragment buffer for new
> fragment.
How about we call individual slices of the large packet "fragments" and the
list of fragments we buffer "fragment chain" for the sake of clarity ?
> +/**
> + * batadv_frag_insert_packet() - Insert a fragment into an fragment
> buffer.
Same here. The "an" is a typo.
> + struct batadv_frag_list_entry *new = NULL, *curr = NULL;
> + struct batadv_frag_packet *packet;
There seems to be no apparent reason to initialize new and curr ?!
The naming of the three variables "new", "curr" and "packet" make this
function hard to read. I understand you try to avoid confusion between the
different types. Do you feel comfortable with "frag_entry_new",
"frag_entry_curr" and "frag_packet" ?
> +/**
> + * batadv_frag_merge_packets() - Merge a list of fragments.
> + * @head: head if list with fragments.
> + * @skb: Packet with total size of skb after merging.
> + *
> + * Expands the first skb in the list and copies the content of the
> remaining + * skb's into the expanded one. After doing so, it clears the
> list. + *
> + * Returns NULL on error.
> + */
Returns the merged skb or NULL on error.
> + /* Make room for the rest of the fragments. */
> + if (pskb_expand_head(skb_out, 0, size - skb->len, GFP_ATOMIC) < 0) {
> + kfree_skb(skb_out);
> + goto free;
> + }
If pskb_expand_head() really fails this function will lead to a crash because
skb_out points to undefined memory.
Btw, is pskb_expand_head() enough to handle all cases ? Did you try this with
a large (4000 bytes or more) packet ?
> diff --git a/fragmentation.h b/fragmentation.h
> new file mode 100644
> index 0000000..16d1a62
> --- /dev/null
> +++ b/fragmentation.h
> @@ -0,0 +1,31 @@
> +/* Copyright (C) 2012 B.A.T.M.A.N. contributors:
Copyright year ...
> #define BATADV_GW_THRESHOLD 50
> +#define BATADV_FRAG_BUFFER_COUNT 8
> +#define BATADV_FRAG_MAX_FRAGMENTS 16
> +#define BATADV_FRAG_MAX_FRAG_SIZE 1400
> +#define BATADV_FRAG_TIMEOUT 10000
Some comments explaining the meaning of these defines would be nice.
> +/**
> + * struct batadv_frag_packet - Network structure for fragments.
> + * @header: Common batman-adv header with type, compatibility version, and
> ttl. + * @dest: Final destination used when routing fragments.
> + * @orig: Originator of the fragment used when merging the packet.
> + * @no: Fragment number within this sequence.
> + * @reserved: Unused
> + * @seqno: Sequence identification.
> + * @total_size: Size of the merged packet.
> + */
> +struct batadv_frag_packet {
> + struct batadv_header header;
> + uint8_t dest[ETH_ALEN];
> + uint8_t orig[ETH_ALEN];
> + uint8_t no:4;
> + uint8_t reserved:4;
> + __be16 seqno;
> + __be16 total_size;
> +} __packed;
If you moved the no/reserved byte between header and dest the packet would be
properly aligned. Furthermore, the bitfield requires manual endianess
"support" (as we recently learned). You might want to check the tvlv patches
as reference.
Last but not least, Simon proposed patches to route unicast packets without
knowing their type. This requires the dest field to be in the right place.
That is one of the reasons for the BUILD_BUG_ON() macro. You removed the old
one but forgot to add the new fragment check.
> +int batadv_recv_frag_packet(struct sk_buff *skb,
> + struct batadv_hard_iface *recv_if)
> +{
> + struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
> + struct batadv_orig_node *orig_node_src = NULL;
> + struct batadv_frag_packet *packet;
Same nitpick here: packet isn't that clear - frag_packet would be better.
>@@ -178,6 +206,7 @@ struct batadv_orig_node {
> spinlock_t in_coding_list_lock; /* Protects in_coding_list */
> spinlock_t out_coding_list_lock; /* Protects out_coding_list */
> #endif
>+ struct batadv_frag_table_entry fragments[BATADV_FRAG_BUFFER_COUNT];
> };
Kernel doc ?
> @@ -307,6 +336,10 @@ enum batadv_counters {
> BATADV_CNT_MGMT_TX_BYTES,
> BATADV_CNT_MGMT_RX,
> BATADV_CNT_MGMT_RX_BYTES,
> + BATADV_CNT_FRAG_RX,
> + BATADV_CNT_FRAG_RX_BYTES,
> + BATADV_CNT_FRAG_FWD,
> + BATADV_CNT_FRAG_FWD_BYTES,
> BATADV_CNT_TT_REQUEST_TX,
> BATADV_CNT_TT_REQUEST_RX,
> BATADV_CNT_TT_RESPONSE_TX,
Kernel doc ?
Cheers,
Marek
next prev parent reply other threads:[~2013-04-23 19:17 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-04-20 16:17 [B.A.T.M.A.N.] [PATCH 0/3] Fragmentation version 2 Martin Hundebøll
2013-04-20 16:17 ` [B.A.T.M.A.N.] [PATCH 1/3] batman-adv: Remove old fragmentation code Martin Hundebøll
2013-04-23 17:32 ` Marek Lindner
2013-04-20 16:17 ` [B.A.T.M.A.N.] [PATCH 2/3] batman-adv: Receive fragmented packets and merge Martin Hundebøll
2013-04-23 19:17 ` Marek Lindner [this message]
2013-04-23 19:30 ` Antonio Quartulli
2013-04-23 19:43 ` Marek Lindner
2013-04-23 19:47 ` Antonio Quartulli
2013-04-20 16:17 ` [B.A.T.M.A.N.] [PATCH 3/3] batman-adv: Fragment and send skbs larger than mtu Martin Hundebøll
2013-04-23 19:35 ` Marek Lindner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=201304240317.27196.lindner_marek@yahoo.de \
--to=lindner_marek@yahoo.de \
--cc=b.a.t.m.a.n@lists.open-mesh.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox