Hi Matteo,

(1) Can you send patches like this via Github pull requests?
(2) I'd prefer for `offsets` to be a parameter rather than a global
(for multithread safety). If you can't do this I will sometime.

Eddie


On Thu, Nov 14, 2013 at 1:31 PM, Matteo Croce <mat...@openwrt.org> wrote:
> Scan the radiotap header once per packet thus reducing
> the parser complexity from O(n^2) to O(n)
> ---
>  elements/wifi/radiotapdecap.cc | 37 ++++++++++++++++---------------------
>  1 file changed, 16 insertions(+), 21 deletions(-)
>
> diff --git a/elements/wifi/radiotapdecap.cc b/elements/wifi/radiotapdecap.cc
> index e30f84d..ab91788 100644
> --- a/elements/wifi/radiotapdecap.cc
> +++ b/elements/wifi/radiotapdecap.cc
> @@ -50,6 +50,8 @@ static const int 
> radiotap_elem_to_bytes[NUM_RADIOTAP_ELEMENTS] =
>          1, /* IEEE80211_RADIOTAP_DATA_RETRIES */
>         };
>
> +static u_int8_t *offsets[NUM_RADIOTAP_ELEMENTS];
> +
>  static int rt_el_present(struct ieee80211_radiotap_header *th, u_int32_t 
> element)
>  {
>         if (element > NUM_RADIOTAP_ELEMENTS)
> @@ -61,6 +63,8 @@ static int rt_check_header(struct ieee80211_radiotap_header 
> *th, int len)
>  {
>         int bytes = 0;
>         int x = 0;
> +       u_int8_t *ptr = (u_int8_t *)(th + 1);
> +
>         if (th->it_version != 0) {
>                 return 0;
>         }
> @@ -70,8 +74,10 @@ static int rt_check_header(struct 
> ieee80211_radiotap_header *th, int len)
>         }
>
>         for (x = 0; x < NUM_RADIOTAP_ELEMENTS; x++) {
> -               if (rt_el_present(th, x))
> +               if (rt_el_present(th, x)) {
> +                   offsets[x] = ptr + bytes;
>                     bytes += radiotap_elem_to_bytes[x];
> +               }
>         }
>
>         if (le16_to_cpu(th->it_len) < sizeof(struct 
> ieee80211_radiotap_header) + bytes) {
> @@ -85,17 +91,6 @@ static int rt_check_header(struct 
> ieee80211_radiotap_header *th, int len)
>         return 1;
>  }
>
> -static u_int8_t *rt_el_offset(struct ieee80211_radiotap_header *th, 
> u_int32_t element) {
> -       unsigned int x = 0;
> -       u_int8_t *offset = ((u_int8_t *) th) + 
> sizeof(ieee80211_radiotap_header);
> -       for (x = 0; x < NUM_RADIOTAP_ELEMENTS && x < element; x++) {
> -               if (rt_el_present(th, x))
> -                       offset += radiotap_elem_to_bytes[x];
> -       }
> -
> -       return offset;
> -}
> -
>  RadiotapDecap::RadiotapDecap()
>  {
>  }
> @@ -121,7 +116,7 @@ RadiotapDecap::simple_action(Packet *p)
>                 ceh->magic = WIFI_EXTRA_MAGIC;
>
>                 if (rt_el_present(th, IEEE80211_RADIOTAP_FLAGS)) {
> -                       u_int8_t flags = *((u_int8_t *) rt_el_offset(th, 
> IEEE80211_RADIOTAP_FLAGS));
> +                       u_int8_t flags = *offsets[IEEE80211_RADIOTAP_FLAGS];
>                         if (flags & IEEE80211_RADIOTAP_F_DATAPAD) {
>                                 ceh->pad = 1;
>                         }
> @@ -131,36 +126,36 @@ RadiotapDecap::simple_action(Packet *p)
>                 }
>
>                 if (rt_el_present(th, IEEE80211_RADIOTAP_RATE)) {
> -                       ceh->rate = *((u_int8_t *) rt_el_offset(th, 
> IEEE80211_RADIOTAP_RATE));
> +                       ceh->rate = *offsets[IEEE80211_RADIOTAP_RATE];
>                 }
>
>                 if (rt_el_present(th, IEEE80211_RADIOTAP_DBM_ANTSIGNAL))
> -                       ceh->rssi = *((u_int8_t *) rt_el_offset(th, 
> IEEE80211_RADIOTAP_DBM_ANTSIGNAL));
> +                       ceh->rssi = 
> *offsets[IEEE80211_RADIOTAP_DBM_ANTSIGNAL];
>
>                 if (rt_el_present(th, IEEE80211_RADIOTAP_DBM_ANTNOISE))
> -                       ceh->silence = *((u_int8_t *) rt_el_offset(th, 
> IEEE80211_RADIOTAP_DBM_ANTNOISE));
> +                       ceh->silence = 
> *offsets[IEEE80211_RADIOTAP_DBM_ANTNOISE];
>
>                 if (rt_el_present(th, IEEE80211_RADIOTAP_DB_ANTSIGNAL))
> -                       ceh->rssi = *((u_int8_t *) rt_el_offset(th, 
> IEEE80211_RADIOTAP_DB_ANTSIGNAL));
> +                       ceh->rssi = *offsets[IEEE80211_RADIOTAP_DB_ANTSIGNAL];
>
>                 if (rt_el_present(th, IEEE80211_RADIOTAP_DB_ANTNOISE))
> -                       ceh->silence = *((u_int8_t *) rt_el_offset(th, 
> IEEE80211_RADIOTAP_DB_ANTNOISE));
> +                       ceh->silence = 
> *offsets[IEEE80211_RADIOTAP_DB_ANTNOISE];
>
>                 if (rt_el_present(th, IEEE80211_RADIOTAP_RX_FLAGS)) {
> -                       u_int16_t flags = le16_to_cpu(*((u_int16_t *) 
> rt_el_offset(th, IEEE80211_RADIOTAP_RX_FLAGS)));
> +                       u_int16_t flags = le16_to_cpu(*((u_int16_t *) 
> offsets[IEEE80211_RADIOTAP_RX_FLAGS]));
>                         if (flags & IEEE80211_RADIOTAP_F_RX_BADFCS)
>                                 ceh->flags |= WIFI_EXTRA_RX_ERR;
>                 }
>
>                 if (rt_el_present(th, IEEE80211_RADIOTAP_TX_FLAGS)) {
> -                       u_int16_t flags = le16_to_cpu(*((u_int16_t *) 
> rt_el_offset(th, IEEE80211_RADIOTAP_TX_FLAGS)));
> +                       u_int16_t flags = le16_to_cpu(*((u_int16_t *) 
> offsets[IEEE80211_RADIOTAP_TX_FLAGS]));
>                         ceh->flags |= WIFI_EXTRA_TX;
>                         if (flags & IEEE80211_RADIOTAP_F_TX_FAIL)
>                                 ceh->flags |= WIFI_EXTRA_TX_FAIL;
>                 }
>
>                 if (rt_el_present(th, IEEE80211_RADIOTAP_DATA_RETRIES))
> -                       ceh->retries = *((u_int8_t *) rt_el_offset(th, 
> IEEE80211_RADIOTAP_DATA_RETRIES));
> +                       ceh->retries = 
> *offsets[IEEE80211_RADIOTAP_DATA_RETRIES];
>
>                 p->pull(le16_to_cpu(th->it_len));
>                 p->set_mac_header(p->data());  // reset mac-header pointer
> --
> 1.8.3.2
>
> _______________________________________________
> click mailing list
> click@amsterdam.lcs.mit.edu
> https://amsterdam.lcs.mit.edu/mailman/listinfo/click
_______________________________________________
click mailing list
click@amsterdam.lcs.mit.edu
https://amsterdam.lcs.mit.edu/mailman/listinfo/click

Reply via email to