From: Andreas Langer <an.langer@gmx.de>
To: b.a.t.m.a.n@lists.open-mesh.org
Subject: Re: [B.A.T.M.A.N.] [PATCH 2/2] batman-adv: layer2 unicast packet fragmentation
Date: Tue, 6 Jul 2010 20:06:27 +0200 [thread overview]
Message-ID: <20100706200627.67717415@rechenknecht> (raw)
In-Reply-To: <20100706170737.GA18453@lunn.ch>
Hi Andrew, answers see below
> > +struct frag_packet_list_entry *search_frag_packet(struct list_head *head,
> > + struct unicast_frag_packet *up) {
> > +
> > + struct frag_packet_list_entry *tfp;
> > + struct unicast_frag_packet *tmp_up = NULL;
> > +
> > + list_for_each_entry(tfp, head, list) {
> > +
> > + if (!tfp->skb)
> > + continue;
> > +
> > + if (tfp->seqno == ntohs(up->seqno))
> > + goto mov_tail;
>
> Please could you explain this last bit? If we have received a
> retransmit we move it to the tail of the list?
If we receive a packet with the same seqno we move the list entry to the tail then return null.
tmp_frag_entry =
search_frag_packet(&orig_node->frag_list,
unicast_packet);
if (!tmp_frag_entry) {
create_frag_entry(&orig_node->frag_list, skb);
In routing.c it creates now a new entry, create_frag_entry takes the last list entry. So the old
packet with the same seqno will be now overwritten. I hope it is clear, do you see any problems with
this ?
> > +
> > + tmp_up = (struct unicast_frag_packet *) tfp->skb->data;
> > +
> > + if (up->flags & UNI_FRAG_HEAD) {
> > +
> > + if (tfp->seqno == ntohs(up->seqno)+1) {
> > + if (tmp_up->flags & UNI_FRAG_HEAD)
> > + goto mov_tail;
> > + else
> > + goto ret_tfp;
> > + }
> > + } else {
> > +
> > + if (tfp->seqno == ntohs(up->seqno)-1) {
> > + if (tmp_up->flags & UNI_FRAG_HEAD)
> > + goto ret_tfp;
> > + else
> > + goto mov_tail;
> > + }
> > + }
>
> How about simplifying this loop a little. Not tested, probably broken,
> but i hope expresses the idea:
>
> if (up->flags & UNI_FRAG_HEAD) {
> search_seqno = ntohs(up->seqno)+1
> } else {
> search_seqno = ntohs(up->seqno)-1
> }
>
> list_for_each_entry(tfp, head, list) {
> if (!tfp->skb)
> continue;
>
> /* Found the other fragment? */
> if (tfp->seqno == search_seqno)
> /* Head and a tail? */
> if ((tmp_up->flags & UNI_FRAG_HEAD) !=
> (tfp->flags & UNI_FRAG_HEAD)
> return tfp;
> } else {
> /* Two heads or tails. Move to tail of list so it will
> get recycled */
> list_move_tail(&tfp->list, head);
> return NULL;
> }
> }
> return NULL;
>
> Moving the ntohs() out of the loop should save a few cycles and it is
> hopefully a little bit more readable.
Thanks for the hint, it is more comprehensible.
>
> > + }
> > + goto ret_null;
> > +
> > +ret_tfp:
> > + return tfp;
> > +mov_tail:
> > + list_move_tail(&tfp->list, head);
> > +ret_null:
> > + return NULL;
>
> Assuming you don't like my re-write, could we remove ret_tfp and
> ret_null. I don't think they aid the understandability of the
> code. They are just return statements.
I like your re-write.
> > +}
> > +
> > +void frag_list_free(struct list_head *head)
> > +{
> > +
> > + struct frag_packet_list_entry *pf, *tmp_pf;
> > +
> > + if (!list_empty(head)) {
> > +
> > + list_for_each_entry_safe(pf, tmp_pf, head, list) {
> > + if (pf->skb)
> > + kfree_skb(pf->skb);
>
> kfree_skb() is happy to take a NULL pointer. So there is no need to do
> the comparison here. It will get repeated inside kfree_skb(). This
> happens in a few places.
Thanks for the hint.
> > + list_del(&pf->list);
> > + kfree(pf);
> > + }
> > + }
> > + return;
>
>
> > +int recv_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if)
> > +{
> > + struct unicast_packet *unicast_packet;
> > + struct ethhdr *ethhdr;
> > + int hdr_size = sizeof(struct unicast_packet);
> > +
> > + /* drop packet if it has not necessary minimum size */
> > + if (skb_headlen(skb) < hdr_size)
> > + return NET_RX_DROP;
> > +
> > + ethhdr = (struct ethhdr *) skb_mac_header(skb);
> > +
> > + /* packet with unicast indication but broadcast recipient */
> > + if (is_bcast(ethhdr->h_dest))
> > + return NET_RX_DROP;
> > +
> > + /* packet with broadcast sender address */
> > + if (is_bcast(ethhdr->h_source))
> > + return NET_RX_DROP;
> > +
> > + /* not for me */
> > + if (!is_my_mac(ethhdr->h_dest))
> > + return NET_RX_DROP;
> > +
> > + unicast_packet = (struct unicast_packet *) skb->data;
> > +
> > + /* packet for me */
> > + if (is_my_mac(unicast_packet->dest)) {
> > + interface_rx(skb, hdr_size);
> > + return NET_RX_SUCCESS;
> > + }
> > +
> > + return route_unicast_packet(skb, recv_if, hdr_size);
> > +}
> > +
> > +int recv_ucast_frag_packet(struct sk_buff *skb, struct batman_if *recv_if)
> > +{
> > + struct unicast_frag_packet *unicast_packet;
> > + struct orig_node *orig_node;
> > + struct ethhdr *ethhdr;
> > + struct frag_packet_list_entry *tmp_frag_entry;
> > + int hdr_size = sizeof(struct unicast_frag_packet);
> > + unsigned long flags;
> > +
> > + /* drop packet if it has not necessary minimum size */
> > + if (skb_headlen(skb) < hdr_size)
> > + return NET_RX_DROP;
> > +
> > + ethhdr = (struct ethhdr *) skb_mac_header(skb);
> > +
> > + /* packet with unicast indication but broadcast recipient */
> > + if (is_bcast(ethhdr->h_dest))
> > + return NET_RX_DROP;
> > +
> > + /* packet with broadcast sender address */
> > + if (is_bcast(ethhdr->h_source))
> > + return NET_RX_DROP;
> > +
> > + /* not for me */
> > + if (!is_my_mac(ethhdr->h_dest))
> > + return NET_RX_DROP;
> > +
>
> There is some code here which is identical to
> recv_unicast_packet(). Could it be refactored into a helper function?
Yes it could, i already thought about it.
>
> Andrew
Thanks again, i will send a new patch.
regards,
Andreas
next prev parent reply other threads:[~2010-07-06 18:06 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-07-06 15:58 [B.A.T.M.A.N.] batman adv unicast fragmentation (version 4) Andreas Langer
2010-07-06 15:59 ` [B.A.T.M.A.N.] [PATCH 1/2] batctl: layer2 unicast packet fragmentation Andreas Langer
2010-07-06 15:59 ` [B.A.T.M.A.N.] [PATCH 2/2] batman-adv: " Andreas Langer
2010-07-06 17:07 ` Andrew Lunn
2010-07-06 18:06 ` Andreas Langer [this message]
2010-07-06 17:39 ` Antonio Quartulli
2010-07-06 18:17 ` Andreas Langer
2010-07-06 18:57 ` Andrew Lunn
2010-07-06 19:13 ` Sven Eckelmann
2010-07-06 19:50 ` Marek Lindner
2010-07-07 10:40 ` Marek Lindner
-- strict thread matches above, loose matches on Subject: below --
2010-07-07 17:30 [B.A.T.M.A.N.] batman adv unicast fragmentation (version 5) Andreas Langer
2010-07-07 17:32 ` [B.A.T.M.A.N.] [PATCH 2/2] batman-adv: layer2 unicast packet fragmentation Andreas Langer
2010-07-09 14:51 ` Sven Eckelmann
2010-07-05 21:42 [B.A.T.M.A.N.] batman adv unicast fragmentation (version 3) Andreas Langer
2010-07-05 21:44 ` [B.A.T.M.A.N.] [PATCH 2/2] batman-adv: layer2 unicast packet fragmentation Andreas Langer
2010-06-30 18:58 [B.A.T.M.A.N.] batman adv unicast fragmentation Andreas Langer
2010-06-30 19:00 ` [B.A.T.M.A.N.] [PATCH 2/2] batman-adv: layer2 unicast packet fragmentation Andreas Langer
2010-07-05 0:37 ` Sven Eckelmann
2010-07-05 12:53 ` Sven Eckelmann
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=20100706200627.67717415@rechenknecht \
--to=an.langer@gmx.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