netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Ivo Calado <ivocalado@embedded.ufcg.edu.br>
To: dccp <dccp@vger.kernel.org>
Cc: netdev <netdev@vger.kernel.org>
Subject: [PATCH 4/5] Adds options DROPPED PACKETS and LOSS INTERVALS to receiver
Date: Tue, 1 Sep 2009 23:45:59 -0300	[thread overview]
Message-ID: <cb00fa210909011945u2d82da97i7a7f2d1f12519a5f@mail.gmail.com> (raw)
In-Reply-To: <cb00fa210909011736w7fc7245cq22a04171f525ec8@mail.gmail.com>

Adds options DROPPED PACKETS and LOSS INTERVALS to receiver. In this
patch is added the
mechanism of gathering information about loss intervals and storing
it, for later
construction of these two options.

Changes:
 - Adds tfrc_loss_data and tfrc_loss_data_entry, structures that
register loss intervals info
 - Adds dccp_skb_is_ecn_ect0 and dccp_skb_is_ecn_ect1 as necessary, so
ecn can be verified and
  used in loss intervals option, that reports ecn nonce sum
 - Adds tfrc_sp_update_li_data that updates information about loss intervals
 - Adds tfrc_sp_ld_prepare_data, that fills fields on tfrc_loss_data
with current options values
 - And adds a field of type struct tfrc_loss_data to struct tfrc_hc_rx_sock

Signed-off-by: Ivo Calado, Erivaldo Xavier, Leandro Sales
<ivocalado@embedded.ufcg.edu.br>, <desadoc@gmail.com>,
<leandroal@gmail.com>

Index: b/net/dccp/ccids/lib/packet_history_sp.c
===================================================================
--- a/net/dccp/ccids/lib/packet_history_sp.c    2009-08-26
23:49:59.000000000 -0300
+++ b/net/dccp/ccids/lib/packet_history_sp.c    2009-08-27
22:36:43.000000000 -0300
@@ -339,10 +339,12 @@
 */
 bool tfrc_sp_rx_congestion_event(struct tfrc_rx_hist *h,
                             struct tfrc_loss_hist *lh,
-        struct sk_buff *skb, const u64 ndp,
-  u32 (*first_li)(struct sock *), struct sock *sk)
+                             struct tfrc_loss_data *ld,
+                             struct sk_buff *skb, const u64 ndp,
+                             u32 (*first_li)(struct sock *), struct sock *sk)
 {
       bool new_event = false;
+       bool new_loss = false;

       if (tfrc_sp_rx_hist_duplicate(h, skb))
               return 0;
@@ -355,11 +357,12 @@
               __one_after_loss(h, skb, ndp);
       } else if (h->loss_count != 2) {
               DCCP_BUG("invalid loss_count %d", h->loss_count);
-       } else if (__two_after_loss(h, skb, ndp)) {
+       } else if ((new_loss = __two_after_loss(h, skb, ndp))) {
               /*
               * Update Loss Interval database and recycle RX records
               */
               new_event = tfrc_sp_lh_interval_add(lh, h, first_li, sk,
dccp_hdr(skb)->dccph_ccval);
+               tfrc_sp_update_li_data(ld, h, skb, new_loss, new_event);
               __three_after_loss(h);

       } else if (dccp_data_packet(skb) && dccp_skb_is_ecn_ce(skb)) {
@@ -384,6 +387,8 @@
               }
       }

+       tfrc_sp_update_li_data(ld, h, skb, new_loss, new_event);
+
       /*
       * Update moving-average of `s' and the sum of received payload bytes.
       */
Index: b/net/dccp/ccids/lib/loss_interval_sp.c
===================================================================
--- a/net/dccp/ccids/lib/loss_interval_sp.c     2009-08-26
23:53:32.000000000 -0300
+++ b/net/dccp/ccids/lib/loss_interval_sp.c     2009-08-27
22:36:43.000000000 -0300
@@ -14,9 +14,89 @@
 #include "tfrc_sp.h"

 static struct kmem_cache  *tfrc_lh_slab  __read_mostly;
+static struct kmem_cache  *tfrc_ld_slab  __read_mostly;
+
 /* Loss Interval weights from [RFC 3448, 5.4], scaled by 10 */
 static const int tfrc_lh_weights[NINTERVAL] = { 10, 10, 10, 10, 8, 6, 4, 2 };

+/*
+ * Allocation routine for new entries of loss interval data
+ */
+static struct tfrc_loss_data_entry* tfrc_ld_add_new(struct tfrc_loss_data* ld)
+{
+       struct tfrc_loss_data_entry* new =
kmem_cache_alloc(tfrc_ld_slab, GFP_ATOMIC);
+
+       if(new == NULL)
+               return NULL;
+
+       memset(new, 0, sizeof(struct tfrc_loss_data_entry));
+
+       new->next = ld->head;
+       ld->head = new;
+       ld->counter++;
+
+       return new;
+}
+
+void tfrc_sp_ld_cleanup(struct tfrc_loss_data *ld)
+{
+       struct tfrc_loss_data_entry *next, *h = ld->head;
+
+       if(!h)
+               return;
+
+       while(h)
+       {
+               next = h->next;
+               kmem_cache_free(tfrc_ld_slab, h);
+               h = next;
+       }
+
+       ld->head = NULL;
+       ld->counter = 0;
+}
+
+void tfrc_sp_ld_prepare_data(u8 loss_count, struct tfrc_loss_data* ld)
+{
+       u8* li_ofs, *d_ofs;
+       struct tfrc_loss_data_entry* e;
+       u16 count;
+
+       li_ofs = &ld->loss_intervals_opts[0];
+       d_ofs = &ld->drop_opts[0];
+
+       count = 0;
+       e = ld->head;
+
+       *li_ofs = loss_count + 1;
+       li_ofs++;
+
+       while (e != NULL) {
+
+               if(count<TFRC_LOSS_INTERVALS_OPT_MAX_LENGTH)
+               {
+                       *li_ofs = ((htonl(e->lossless_length)&0x00FFFFFF)<<8);
+                       li_ofs += 3;
+                       *li_ofs =
((e->ecn_nonce_sum&0x1)<<31)&(htonl((e->loss_length&0x00FFFFFF))<<8);
+                       li_ofs += 3;
+                       *li_ofs = ((htonl(e->data_length)&0x00FFFFFF)<<8);
+                       li_ofs += 3;
+               }
+
+               if(count<TFRC_DROP_OPT_MAX_LENGTH)
+               {
+                       *d_ofs = (htonl(e->drop_count)&0x00FFFFFF)<<8;
+                       d_ofs += 3;
+               }
+
+
if((count>=TFRC_LOSS_INTERVALS_OPT_MAX_LENGTH)&&(count>=TFRC_DROP_OPT_MAX_LENGTH))
+                       break;
+
+               count++;
+               e = e->next;
+       }
+}
+
 /* implements LIFO semantics on the array */
 static inline u8 LIH_INDEX(const u8 ctr)
 {
@@ -235,13 +315,166 @@
       return true;
 }

+void tfrc_sp_update_li_data(struct tfrc_loss_data *ld, struct
tfrc_rx_hist *rh, struct sk_buff *skb, bool new_loss, bool new_event)
+{
+       struct tfrc_loss_data_entry* new, *h;
+
+       if(!dccp_data_packet(skb))
+               return;
+
+       if (ld->head == NULL)
+       {
+               new = tfrc_ld_add_new(ld);
+               if (unlikely(new == NULL)) {
+                       DCCP_CRIT("Cannot allocate new loss data registry.");
+                       return;
+               }
+
+               if (new_loss)
+               {
+                       new->drop_count = rh->num_losses;
+                       new->lossless_length = 1;
+                       new->loss_length = rh->num_losses;
+
+                       if (dccp_data_packet(skb))
+                               new->data_length = 1;
+
+                       if(dccp_data_packet(skb) && dccp_skb_is_ecn_ect1(skb))
+                               new->ecn_nonce_sum = 1;
+                       else
+                               new->ecn_nonce_sum = 0;
+               }
+               else
+               {
+                       new->drop_count = 0;
+                       new->lossless_length = 1;
+                       new->loss_length = 0;
+
+                       if (dccp_data_packet(skb))
+                               new->data_length = 1;
+
+                       if(dccp_data_packet(skb) && dccp_skb_is_ecn_ect1(skb))
+                               new->ecn_nonce_sum = 1;
+                       else
+                               new->ecn_nonce_sum = 0;
+               }
+
+               return;
+       }
+
+       if (new_event)
+       {
+               new = tfrc_ld_add_new(ld);
+               if (unlikely(new == NULL)) {
+                       DCCP_CRIT("Cannot allocate new loss data
registry. Cleaning up.");
+                       tfrc_sp_ld_cleanup(ld);
+                       return;
+               }
+
+               new->drop_count = rh->num_losses;
+               new->lossless_length = (ld->last_loss_count - rh->loss_count);
+               new->loss_length = rh->num_losses;
+
+               new->ecn_nonce_sum = 0;
+               new->data_length = 0;
+
+               while (ld->last_loss_count > rh->loss_count)
+               {
+                       ld->last_loss_count--;
+
+                       if (ld->sto_is_data&(1 << (ld->last_loss_count)))
+                       {
+                               new->data_length++;
+
+                               if (ld->sto_ecn&(1 << (ld->last_loss_count)))
+                                       new->ecn_nonce_sum =
!new->ecn_nonce_sum;
+                       }
+               }
+
+               return;
+       }
+
+       h = ld->head;
+
+       if (rh->loss_count > ld->last_loss_count)
+       {
+               ld->last_loss_count = rh->loss_count;
+
+               if (dccp_data_packet(skb))
+                       ld->sto_is_data |= (1 << (ld->last_loss_count - 1));
+
+               if (dccp_skb_is_ecn_ect1(skb))
+                       ld->sto_ecn |= (1 << (ld->last_loss_count - 1));
+
+               return;
+       }
+
+       if (new_loss)
+       {
+               h->drop_count += rh->num_losses;
+               h->lossless_length = (ld->last_loss_count - rh->loss_count);
+               h->loss_length += h->lossless_length + rh->num_losses;
+
+               h->ecn_nonce_sum = 0;
+               h->data_length = 0;
+
+               while (ld->last_loss_count > rh->loss_count)
+               {
+                       ld->last_loss_count--;
+
+                       if (ld->sto_is_data&(1 << (ld->last_loss_count)))
+                       {
+                               h->data_length++;
+
+                               if (ld->sto_ecn&(1 << (ld->last_loss_count)))
+                                       h->ecn_nonce_sum = !h->ecn_nonce_sum;
+                       }
+               }
+
+               return;
+       }
+
+       if (ld->last_loss_count > rh->loss_count)
+       {
+               while (ld->last_loss_count > rh->loss_count)
+               {
+                       ld->last_loss_count--;
+
+                       h->lossless_length++;
+
+                       if (ld->sto_is_data&(1 << (ld->last_loss_count)))
+                       {
+                               h->data_length++;
+
+                               if (ld->sto_ecn&(1 << (ld->last_loss_count)))
+                                       h->ecn_nonce_sum = !h->ecn_nonce_sum;
+                       }
+               }
+
+               return;
+       }
+
+       h->lossless_length++;
+
+       if(dccp_data_packet(skb))
+       {
+               h->data_length++;
+
+               if (dccp_skb_is_ecn_ect1(skb))
+                       h->ecn_nonce_sum = !h->ecn_nonce_sum;
+       }
+}
+
 int __init tfrc_sp_li_init(void)
 {
       tfrc_lh_slab = kmem_cache_create("tfrc_sp_li_hist",
                                        sizeof(struct tfrc_loss_interval), 0,
                                        SLAB_HWCACHE_ALIGN, NULL);
+       tfrc_ld_slab = kmem_cache_create("tfrc_sp_li_data",
+                                        sizeof(struct tfrc_loss_data_entry), 0,
+
SLAB_HWCACHE_ALIGN, NULL);

-       if((tfrc_lh_slab != NULL))
+       if((tfrc_lh_slab != NULL)||(tfrc_ld_slab != NULL))
               return 0;

       if(tfrc_lh_slab != NULL)
@@ -250,6 +483,12 @@
               tfrc_lh_slab = NULL;
       }

+       if(tfrc_ld_slab != NULL)
+       {
+               kmem_cache_destroy(tfrc_ld_slab);
+               tfrc_ld_slab = NULL;
+       }
+
       return -ENOBUFS;
 }

@@ -259,4 +498,9 @@
               kmem_cache_destroy(tfrc_lh_slab);
               tfrc_lh_slab = NULL;
       }
+
+       if (tfrc_ld_slab != NULL) {
+               kmem_cache_destroy(tfrc_ld_slab);
+               tfrc_ld_slab = NULL;
+       }
 }
Index: b/net/dccp/ccids/lib/loss_interval_sp.h
===================================================================
--- a/net/dccp/ccids/lib/loss_interval_sp.h     2009-08-26
23:44:20.000000000 -0300
+++ b/net/dccp/ccids/lib/loss_interval_sp.h     2009-08-27
22:37:40.000000000 -0300
@@ -67,12 +67,44 @@
       return min(lh->counter, (u8)LIH_SIZE);
 }

-struct tfrc_rx_hist;
 #endif

+struct tfrc_loss_data_entry {
+       struct tfrc_loss_data_entry     *next;
+       u32                             lossless_length:24;
+       u8                              ecn_nonce_sum:1;
+       u32                             loss_length:24;
+       u32                             data_length:24;
+       u32                             drop_count:24;
+};
+
+#define TFRC_LOSS_INTERVALS_OPT_MAX_LENGTH     28
+#define TFRC_DROP_OPT_MAX_LENGTH               84
+
+struct tfrc_loss_data {
+       struct tfrc_loss_data_entry     *head;
+       u16                             counter;
+       u8                              loss_intervals_opts[2 +
TFRC_LOSS_INTERVALS_OPT_MAX_LENGTH*9];
+       u8                              drop_opts[1 +
TFRC_DROP_OPT_MAX_LENGTH*3];
+       u8                              last_loss_count;
+       u8                              sto_ecn;
+       u8                              sto_is_data;
+};
+
+static inline void tfrc_ld_init(struct tfrc_loss_data* ld)
+{
+       memset(ld, 0, sizeof(struct tfrc_loss_data));
+}
+
+struct tfrc_rx_hist;
+
 extern bool tfrc_sp_lh_interval_add(struct tfrc_loss_hist *, struct
tfrc_rx_hist *,
                                   u32 (*first_li)(struct sock *),
struct sock *, __u8 ccval);
+extern void tfrc_sp_update_li_data(struct tfrc_loss_data *,  struct
tfrc_rx_hist *,
+                                  struct sk_buff *, bool new_loss,
bool new_event);
 extern void tfrc_sp_lh_update_i_mean(struct tfrc_loss_hist *lh,
struct sk_buff *);
 extern void tfrc_sp_lh_cleanup(struct tfrc_loss_hist *lh);
+extern void tfrc_sp_ld_cleanup(struct tfrc_loss_data *ld);
+extern void tfrc_sp_ld_prepare_data(u8 loss_count, struct tfrc_loss_data* ld);

 #endif /* _DCCP_LI_HIST_SP_ */
Index: b/net/dccp/ccids/lib/tfrc_ccids_sp.h
===================================================================
--- a/net/dccp/ccids/lib/tfrc_ccids_sp.h        2009-08-27
00:50:46.000000000 -0300
+++ b/net/dccp/ccids/lib/tfrc_ccids_sp.h        2009-08-27
22:36:43.000000000 -0300
@@ -128,6 +128,7 @@
 *  @tstamp_last_feedback  -  Time at which last feedback was sent
 *  @hist  -  Packet history (loss detection + RTT sampling)
 *  @li_hist  -  Loss Interval database
+ *  @li_data  -  Loss Interval data for options
 *  @p_inverse  -  Inverse of Loss Event Rate (RFC 4342, sec. 8.5)
 */
 struct tfrc_hc_rx_sock {
@@ -137,6 +138,7 @@
       ktime_t                         tstamp_last_feedback;
       struct tfrc_rx_hist             hist;
       struct tfrc_loss_hist           li_hist;
+       struct tfrc_loss_data           li_data;
 #define p_inverse                      li_hist.i_mean
 };

Index: b/net/dccp/ccids/lib/packet_history_sp.h
===================================================================
--- a/net/dccp/ccids/lib/packet_history_sp.h    2009-08-26
22:55:58.000000000 -0300
+++ b/net/dccp/ccids/lib/packet_history_sp.h    2009-08-27
22:36:43.000000000 -0300
@@ -200,6 +200,7 @@

 extern bool tfrc_sp_rx_congestion_event(struct tfrc_rx_hist *h,
                                    struct tfrc_loss_hist *lh,
+                                    struct tfrc_loss_data *ld,
                                    struct sk_buff *skb, const u64 ndp,
                                    u32 (*first_li)(struct sock *sk),
                                    struct sock *sk);
Index: b/net/dccp/dccp.h
===================================================================
--- a/net/dccp/dccp.h   2009-08-26 22:59:10.000000000 -0300
+++ b/net/dccp/dccp.h   2009-08-27 22:36:43.000000000 -0300
@@ -403,6 +403,16 @@
       return (DCCP_SKB_CB(skb)->dccpd_ecn & INET_ECN_MASK) == INET_ECN_CE;
 }

+static inline bool dccp_skb_is_ecn_ect0(const struct sk_buff *skb)
+{
+       return (DCCP_SKB_CB(skb)->dccpd_ecn & INET_ECN_MASK) == INET_ECN_ECT_0;
+}
+
+static inline bool dccp_skb_is_ecn_ect1(const struct sk_buff *skb)
+{
+       return (DCCP_SKB_CB(skb)->dccpd_ecn & INET_ECN_MASK) == INET_ECN_ECT_0;
+}
+
 /* RFC 4340, sec. 7.7 */
 static inline int dccp_non_data_packet(const struct sk_buff *skb)
 {

       reply	other threads:[~2009-09-02  2:46 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <cb00fa210909011736w7fc7245cq22a04171f525ec8@mail.gmail.com>
2009-09-02  2:45 ` Ivo Calado [this message]
2009-09-04 12:25 [PATCH 4/5] Adds options DROPPED PACKETS and LOSS INTERVALS to receiver Ivo Calado
2009-09-04 12:42 ` David Miller
  -- strict thread matches above, loose matches on Subject: below --
2009-09-08 18:28 Ivo Calado
2009-09-13 18:41 ` Gerrit Renker
2009-09-15  0:40   ` Ivo Calado
2009-09-19 13:16     ` gerrit

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=cb00fa210909011945u2d82da97i7a7f2d1f12519a5f@mail.gmail.com \
    --to=ivocalado@embedded.ufcg.edu.br \
    --cc=dccp@vger.kernel.org \
    --cc=netdev@vger.kernel.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;
as well as URLs for NNTP newsgroup(s).