Author: adrian
Date: Sun Mar  4 05:49:39 2012
New Revision: 232479
URL: http://svn.freebsd.org/changeset/base/232479

Log:
  * Added IEEE80211_ACTION_CAT_MESH in ieee80211.h as specified amendment spec;
  * Moved old categories as specified by D4.0 to be action fields of MESH 
category
    as specified in amendment spec;
  * Modified functions to use MESH category and its action fields:
    + ieee80211_send_action_register
    + ieee80211_send_action
    + ieee80211_recv_action_register
    +ieee80211_recv_action;
  * Modified ieee80211_hwmp_init and hwmp_send_action so they uses correct
    action fields as specified in amendment spec;
  * Modified ieee80211_parse_action so that it verifies MESH frames.
  * Change Mesh Link Metric to use one information element as amendment spec.
    Draft 4.0 defined two different information elements for request and 
response.
  
  Submitted by: montha...@gmail.com

Modified:
  head/sys/net80211/ieee80211.h
  head/sys/net80211/ieee80211_action.c
  head/sys/net80211/ieee80211_hwmp.c
  head/sys/net80211/ieee80211_input.c
  head/sys/net80211/ieee80211_mesh.c
  head/sys/net80211/ieee80211_mesh.h

Modified: head/sys/net80211/ieee80211.h
==============================================================================
--- head/sys/net80211/ieee80211.h       Sun Mar  4 05:19:55 2012        
(r232478)
+++ head/sys/net80211/ieee80211.h       Sun Mar  4 05:49:39 2012        
(r232479)
@@ -325,6 +325,7 @@ struct ieee80211_action {
 #define        IEEE80211_ACTION_CAT_DLS        2       /* DLS */
 #define        IEEE80211_ACTION_CAT_BA         3       /* BA */
 #define        IEEE80211_ACTION_CAT_HT         7       /* HT */
+#define        IEEE80211_ACTION_CAT_MESH       13      /* Mesh */
 #define        IEEE80211_ACTION_CAT_VENDOR     127     /* Vendor Specific */
 
 #define        IEEE80211_ACTION_HT_TXCHWIDTH   0       /* recommended xmit 
chan width*/

Modified: head/sys/net80211/ieee80211_action.c
==============================================================================
--- head/sys/net80211/ieee80211_action.c        Sun Mar  4 05:19:55 2012        
(r232478)
+++ head/sys/net80211/ieee80211_action.c        Sun Mar  4 05:49:39 2012        
(r232479)
@@ -99,16 +99,20 @@ ieee80211_send_action_register(int cat, 
                        break;
                meshpl_send_action[act] = f;
                return 0;
-       case IEEE80211_ACTION_CAT_MESHLMETRIC:
-               if (act >= N(meshlm_send_action))
-                       break;
-               meshlm_send_action[act] = f;
-               return 0;
-       case IEEE80211_ACTION_CAT_MESHPATH:
-               if (act >= N(hwmp_send_action))
-                       break;
-               hwmp_send_action[act] = f;
-               return 0;
+       case IEEE80211_ACTION_CAT_MESH:
+               switch (act) {
+               case IEEE80211_ACTION_MESH_LMETRIC:
+                       if (act >= N(meshlm_send_action))
+                               break;
+                       meshlm_send_action[act] = f;
+                       return 0;
+               case IEEE80211_ACTION_MESH_HWMP:
+                       if (act >= N(hwmp_send_action))
+                               break;
+                       hwmp_send_action[act] = f;
+                       return 0;
+               }
+               break;
        case IEEE80211_ACTION_CAT_VENDOR:
                if (act >= N(vendor_send_action))
                        break;
@@ -144,13 +148,17 @@ ieee80211_send_action(struct ieee80211_n
                if (act < N(meshpl_send_action))
                        f = meshpl_send_action[act];
                break;
-       case IEEE80211_ACTION_CAT_MESHLMETRIC:
-               if (act < N(meshlm_send_action))
-                       f = meshlm_send_action[act];
-               break;
-       case IEEE80211_ACTION_CAT_MESHPATH:
-               if (act < N(hwmp_send_action))
-                       f = hwmp_send_action[act];
+       case IEEE80211_ACTION_CAT_MESH:
+               switch (act) {
+               case IEEE80211_ACTION_MESH_LMETRIC:
+                       if (act < N(meshlm_send_action))
+                               f = meshlm_send_action[act];
+                       break;
+               case IEEE80211_ACTION_MESH_HWMP:
+                       if (act < N(hwmp_send_action))
+                               f = hwmp_send_action[act];
+                       break;
+               }
                break;
        case IEEE80211_ACTION_CAT_VENDOR:
                if (act < N(vendor_send_action))
@@ -212,16 +220,20 @@ ieee80211_recv_action_register(int cat, 
                        break;
                meshpl_recv_action[act] = f;
                return 0;
-       case IEEE80211_ACTION_CAT_MESHLMETRIC:
-               if (act >= N(meshlm_recv_action))
-                       break;
-               meshlm_recv_action[act] = f;
-               return 0;
-       case IEEE80211_ACTION_CAT_MESHPATH:
-               if (act >= N(hwmp_recv_action))
-                       break;
-               hwmp_recv_action[act] = f;
-               return 0;
+       case IEEE80211_ACTION_CAT_MESH:
+               switch (act) {
+               case IEEE80211_ACTION_MESH_LMETRIC:
+                       if (act >= N(meshlm_recv_action))
+                               break;
+                       meshlm_recv_action[act] = f;
+                       return 0;
+               case IEEE80211_ACTION_MESH_HWMP:
+                       if (act >= N(hwmp_recv_action))
+                               break;
+                       hwmp_recv_action[act] = f;
+                       return 0;
+               }
+               break;
        case IEEE80211_ACTION_CAT_VENDOR:
                if (act >= N(vendor_recv_action))
                        break;
@@ -261,13 +273,17 @@ ieee80211_recv_action(struct ieee80211_n
                if (ia->ia_action < N(meshpl_recv_action))
                        f = meshpl_recv_action[ia->ia_action];
                break;
-       case IEEE80211_ACTION_CAT_MESHLMETRIC:
-               if (ia->ia_action < N(meshlm_recv_action))
-                       f = meshlm_recv_action[ia->ia_action];
-               break;
-       case IEEE80211_ACTION_CAT_MESHPATH:
-               if (ia->ia_action < N(hwmp_recv_action))
-                       f = hwmp_recv_action[ia->ia_action];
+       case IEEE80211_ACTION_CAT_MESH:
+               switch (ia->ia_action) {
+               case IEEE80211_ACTION_MESH_LMETRIC:
+                       if (ia->ia_action < N(meshlm_recv_action))
+                               f = meshlm_recv_action[ia->ia_action];
+                       break;
+               case IEEE80211_ACTION_MESH_HWMP:
+                       if (ia->ia_action < N(hwmp_recv_action))
+                               f = hwmp_recv_action[ia->ia_action];
+                       break;
+               }
                break;
        case IEEE80211_ACTION_CAT_VENDOR:
                if (ia->ia_action < N(vendor_recv_action))

Modified: head/sys/net80211/ieee80211_hwmp.c
==============================================================================
--- head/sys/net80211/ieee80211_hwmp.c  Sun Mar  4 05:19:55 2012        
(r232478)
+++ head/sys/net80211/ieee80211_hwmp.c  Sun Mar  4 05:49:39 2012        
(r232479)
@@ -220,8 +220,8 @@ ieee80211_hwmp_init(void)
        /*
         * Register action frame handler.
         */
-       ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESHPATH,
-           IEEE80211_ACTION_MESHPATH_SEL, hwmp_recv_action_meshpath);
+       ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESH,
+           IEEE80211_ACTION_MESH_HWMP, hwmp_recv_action_meshpath);
 
        /* NB: default is 5 secs per spec */
        mesh_proto_hwmp.mpp_inact = msecs_to_ticks(5*1000);
@@ -434,8 +434,8 @@ hwmp_send_action(struct ieee80211_node *
                vap->iv_stats.is_tx_nobuf++;
                return ENOMEM;
        }
-       *frm++ = IEEE80211_ACTION_CAT_MESHPATH;
-       *frm++ = IEEE80211_ACTION_MESHPATH_SEL;
+       *frm++ = IEEE80211_ACTION_CAT_MESH;
+       *frm++ = IEEE80211_ACTION_MESH_HWMP;
        switch (*ie) {
        case IEEE80211_ELEMID_MESHPREQ:
                frm = hwmp_add_meshpreq(frm,

Modified: head/sys/net80211/ieee80211_input.c
==============================================================================
--- head/sys/net80211/ieee80211_input.c Sun Mar  4 05:19:55 2012        
(r232478)
+++ head/sys/net80211/ieee80211_input.c Sun Mar  4 05:49:39 2012        
(r232479)
@@ -760,6 +760,37 @@ ieee80211_parse_action(struct ieee80211_
                        break;
                }
                break;
+       case IEEE80211_ACTION_CAT_MESH:
+               switch (ia->ia_action) {
+               case IEEE80211_ACTION_MESH_LMETRIC:
+                       /*
+                        * XXX: verification is true only if we are using
+                        * Airtime link metric (default)
+                        */
+                       IEEE80211_VERIFY_LENGTH(efrm - frm,
+                           sizeof(struct ieee80211_meshlmetric_ie),
+                           return EINVAL);
+                       break;
+               case IEEE80211_ACTION_MESH_HWMP:
+                       /* verify something */
+                       break;
+               case IEEE80211_ACTION_MESH_GANN:
+               case IEEE80211_ACTION_MESH_CC:
+               case IEEE80211_ACTION_MESH_MCCA_SREQ:
+               case IEEE80211_ACTION_MESH_MCCA_SREP:
+               case IEEE80211_ACTION_MESH_MCCA_AREQ:
+               case IEEE80211_ACTION_MESH_MCCA_ADVER:
+               case IEEE80211_ACTION_MESH_MCCA_TRDOWN:
+               case IEEE80211_ACTION_MESH_TBTT_REQ:
+               case IEEE80211_ACTION_MESH_TBTT_RES:
+                       /* reject these early on, not implemented */
+                       IEEE80211_DISCARD(vap,
+                           IEEE80211_MSG_ELEMID | IEEE80211_MSG_INPUT,
+                           wh, NULL, "not implemented yet, act=0x%02X",
+                           ia->ia_action);
+                       return EINVAL;
+               }
+               break;
        }
        return 0;
 }

Modified: head/sys/net80211/ieee80211_mesh.c
==============================================================================
--- head/sys/net80211/ieee80211_mesh.c  Sun Mar  4 05:19:55 2012        
(r232478)
+++ head/sys/net80211/ieee80211_mesh.c  Sun Mar  4 05:49:39 2012        
(r232479)
@@ -122,14 +122,12 @@ static const uint8_t broadcastaddr[IEEE8
 static ieee80211_recv_action_func mesh_recv_action_meshpeering_open;
 static ieee80211_recv_action_func mesh_recv_action_meshpeering_confirm;
 static ieee80211_recv_action_func mesh_recv_action_meshpeering_close;
-static ieee80211_recv_action_func mesh_recv_action_meshlmetric_req;
-static ieee80211_recv_action_func mesh_recv_action_meshlmetric_rep;
+static ieee80211_recv_action_func mesh_recv_action_meshlmetric;
 
 static ieee80211_send_action_func mesh_send_action_meshpeering_open;
 static ieee80211_send_action_func mesh_send_action_meshpeering_confirm;
 static ieee80211_send_action_func mesh_send_action_meshpeering_close;
-static ieee80211_send_action_func mesh_send_action_meshlink_request;
-static ieee80211_send_action_func mesh_send_action_meshlink_reply;
+static ieee80211_send_action_func mesh_send_action_meshlmetric;
 
 static const struct ieee80211_mesh_proto_metric mesh_metric_airtime = {
        .mpm_descr      = "AIRTIME",
@@ -437,10 +435,8 @@ ieee80211_mesh_init(void)
        ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESHPEERING,
            IEEE80211_ACTION_MESHPEERING_CLOSE,
            mesh_recv_action_meshpeering_close);
-       ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESHLMETRIC,
-           IEEE80211_ACTION_MESHLMETRIC_REQ, mesh_recv_action_meshlmetric_req);
-       ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESHLMETRIC,
-           IEEE80211_ACTION_MESHLMETRIC_REP, mesh_recv_action_meshlmetric_rep);
+       ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESH,
+           IEEE80211_ACTION_MESH_LMETRIC, mesh_recv_action_meshlmetric);
 
        ieee80211_send_action_register(IEEE80211_ACTION_CAT_MESHPEERING,
            IEEE80211_ACTION_MESHPEERING_OPEN,
@@ -451,12 +447,9 @@ ieee80211_mesh_init(void)
        ieee80211_send_action_register(IEEE80211_ACTION_CAT_MESHPEERING,
            IEEE80211_ACTION_MESHPEERING_CLOSE,
            mesh_send_action_meshpeering_close);
-       ieee80211_send_action_register(IEEE80211_ACTION_CAT_MESHLMETRIC,
-           IEEE80211_ACTION_MESHLMETRIC_REQ,
-           mesh_send_action_meshlink_request);
-       ieee80211_send_action_register(IEEE80211_ACTION_CAT_MESHLMETRIC,
-           IEEE80211_ACTION_MESHLMETRIC_REP,
-           mesh_send_action_meshlink_reply);
+       ieee80211_send_action_register(IEEE80211_ACTION_CAT_MESH,
+           IEEE80211_ACTION_MESH_LMETRIC,
+           mesh_send_action_meshlmetric);
 
        /*
         * Register Airtime Link Metric.
@@ -1861,25 +1854,24 @@ mesh_recv_action_meshpeering_close(struc
  * Link Metric handling.
  */
 static int
-mesh_recv_action_meshlmetric_req(struct ieee80211_node *ni,
-       const struct ieee80211_frame *wh,
-       const uint8_t *frm, const uint8_t *efrm)
-{
-       uint32_t metric;
-
-       metric = mesh_airtime_calc(ni);
-       ieee80211_send_action(ni,
-           IEEE80211_ACTION_CAT_MESHLMETRIC,
-           IEEE80211_ACTION_MESHLMETRIC_REP,
-           &metric);
-       return 0;
-}
-
-static int
-mesh_recv_action_meshlmetric_rep(struct ieee80211_node *ni,
+mesh_recv_action_meshlmetric(struct ieee80211_node *ni,
        const struct ieee80211_frame *wh,
        const uint8_t *frm, const uint8_t *efrm)
 {
+       const struct ieee80211_meshlmetric_ie *ie =
+           (const struct ieee80211_meshlmetric_ie *)
+           (frm+2); /* action + code */
+       struct ieee80211_meshlmetric_ie lm_rep;
+       
+       if (ie->lm_flags & IEEE80211_MESH_LMETRIC_FLAGS_REQ) {
+               lm_rep.lm_flags = 0;
+               lm_rep.lm_metric = mesh_airtime_calc(ni);
+               ieee80211_send_action(ni,
+                   IEEE80211_ACTION_CAT_MESH,
+                   IEEE80211_ACTION_MESH_LMETRIC,
+                   &lm_rep);
+       }
+       /* XXX: else do nothing for now */
        return 0;
 }
 
@@ -2091,56 +2083,23 @@ mesh_send_action_meshpeering_close(struc
 }
 
 static int
-mesh_send_action_meshlink_request(struct ieee80211_node *ni,
+mesh_send_action_meshlmetric(struct ieee80211_node *ni,
        int category, int action, void *arg0)
 {
        struct ieee80211vap *vap = ni->ni_vap;
        struct ieee80211com *ic = ni->ni_ic;
+       struct ieee80211_meshlmetric_ie *ie = arg0;
        struct mbuf *m;
        uint8_t *frm;
 
-       IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, ni,
-           "%s", "send LINK METRIC REQUEST action");
-
-       IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE,
-           "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", __func__, __LINE__,
-           ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1);
-       ieee80211_ref_node(ni);
-
-       m = ieee80211_getmgtframe(&frm,
-           ic->ic_headroom + sizeof(struct ieee80211_frame),
-           sizeof(uint16_t)    /* action+category */
-       );
-       if (m != NULL) {
-               /*
-                * mesh link metric request
-                *   [1] category
-                *   [1] action
-                */
-               *frm++ = category;
-               *frm++ = action;
-               m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *);
-               return mesh_send_action(ni, m);
+       if (ie->lm_flags & IEEE80211_MESH_LMETRIC_FLAGS_REQ) {
+               IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH,
+                   ni, "%s", "send LINK METRIC REQUEST action");
        } else {
-               vap->iv_stats.is_tx_nobuf++;
-               ieee80211_free_node(ni);
-               return ENOMEM;
+               IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH,
+                   ni, "send LINK METRIC REPLY action: metric 0x%x",
+                   ie->lm_metric);
        }
-}
-
-static int
-mesh_send_action_meshlink_reply(struct ieee80211_node *ni,
-       int category, int action, void *args0)
-{
-       struct ieee80211vap *vap = ni->ni_vap;
-       struct ieee80211com *ic = ni->ni_ic;
-       uint32_t *metric = args0;
-       struct mbuf *m;
-       uint8_t *frm;
-
-       IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, ni,
-           "send LINK METRIC REPLY action: metric 0x%x", *metric);
-
        IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE,
            "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", __func__, __LINE__,
            ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1);
@@ -2148,19 +2107,20 @@ mesh_send_action_meshlink_reply(struct i
 
        m = ieee80211_getmgtframe(&frm,
            ic->ic_headroom + sizeof(struct ieee80211_frame),
-           sizeof(uint16_t)    /* action+category */
-           + sizeof(struct ieee80211_meshlmetric_ie)
+           sizeof(uint16_t) +  /* action+category */
+           sizeof(struct ieee80211_meshlmetric_ie)
        );
        if (m != NULL) {
                /*
-                * mesh link metric reply
+                * mesh link metric
                 *   [1] category
                 *   [1] action
                 *   [tlv] mesh link metric
                 */
                *frm++ = category;
                *frm++ = action;
-               frm = ieee80211_add_meshlmetric(frm, *metric);
+               frm = ieee80211_add_meshlmetric(frm,
+                   ie->lm_flags, ie->lm_metric);
                m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *);
                return mesh_send_action(ni, m);
        } else {
@@ -2505,10 +2465,11 @@ mesh_airtime_calc(struct ieee80211_node 
  * Add a Mesh Link Metric report IE to a frame.
  */
 uint8_t *
-ieee80211_add_meshlmetric(uint8_t *frm, uint32_t metric)
+ieee80211_add_meshlmetric(uint8_t *frm, uint8_t flags, uint32_t metric)
 {
        *frm++ = IEEE80211_ELEMID_MESHLINK;
-       *frm++ = 4;
+       *frm++ = 5;
+       *frm++ = flags;
        ADDWORD(frm, metric);
        return frm;
 }

Modified: head/sys/net80211/ieee80211_mesh.h
==============================================================================
--- head/sys/net80211/ieee80211_mesh.h  Sun Mar  4 05:19:55 2012        
(r232478)
+++ head/sys/net80211/ieee80211_mesh.h  Sun Mar  4 05:49:39 2012        
(r232479)
@@ -119,8 +119,14 @@ struct ieee80211_meshid_ie {
 
 /* Link Metric Report */
 struct ieee80211_meshlmetric_ie {
-       uint8_t         lm_ie;  /* IEEE80211_ELEMID_MESHLINK */
+       uint8_t         lm_ie;  /* IEEE80211_ACTION_MESH_LMETRIC */
        uint8_t         lm_len;
+       uint8_t         lm_flags;
+#define        IEEE80211_MESH_LMETRIC_FLAGS_REQ        0x01    /* Request */
+       /*
+        * XXX: this field should be variable in size and depend on
+        * the active active path selection metric identifier
+        */
        uint32_t        lm_metric;
 #define        IEEE80211_MESHLMETRIC_INITIALVAL        0
 } __packed;
@@ -307,8 +313,7 @@ struct ieee80211_meshpuc_ie {
  * 802.11s Action Frames
  */
 #define        IEEE80211_ACTION_CAT_MESHPEERING        30      /* XXX Linux */
-#define        IEEE80211_ACTION_CAT_MESHLMETRIC        13
-#define        IEEE80211_ACTION_CAT_MESHPATH           32      /* XXX Linux */
+/* XXX: these need to be looked into */
 #define        IEEE80211_ACTION_CAT_INTERWORK          15
 #define        IEEE80211_ACTION_CAT_RESOURCE           16
 #define        IEEE80211_ACTION_CAT_PROXY              17
@@ -324,20 +329,21 @@ enum {
 };
 
 /*
- * Mesh Path Selection Action code.
+ * Mesh Action code.
  */
 enum {
-       IEEE80211_ACTION_MESHPATH_SEL   = 0,
-       /* 1-255 reserved */
-};
-
-/*
- * Mesh Link Metric Action codes.
- */
-enum {
-       IEEE80211_ACTION_MESHLMETRIC_REQ = 0,   /* Link Metric Request */
-       IEEE80211_ACTION_MESHLMETRIC_REP = 1,   /* Link Metric Report */
-       /* 2-255 reserved */
+       IEEE80211_ACTION_MESH_LMETRIC   = 0,    /* Mesh Link Metric Report */
+       IEEE80211_ACTION_MESH_HWMP      = 1,    /* HWMP Mesh Path Selection */
+       IEEE80211_ACTION_MESH_GANN      = 2,    /* Gate Announcement */
+       IEEE80211_ACTION_MESH_CC        = 3,    /* Congestion Control */
+       IEEE80211_ACTION_MESH_MCCA_SREQ = 4,    /* MCCA Setup Request */
+       IEEE80211_ACTION_MESH_MCCA_SREP = 5,    /* MCCA Setup Reply */
+       IEEE80211_ACTION_MESH_MCCA_AREQ = 6,    /* MCCA Advertisement Req. */
+       IEEE80211_ACTION_MESH_MCCA_ADVER =7,    /* MCCA Advertisement */
+       IEEE80211_ACTION_MESH_MCCA_TRDOWN = 8,  /* MCCA Teardown */
+       IEEE80211_ACTION_MESH_TBTT_REQ  = 9,    /* TBTT Adjustment Request */
+       IEEE80211_ACTION_MESH_TBTT_RES  = 10,   /* TBTT Adjustment Response */
+       /* 11-255 reserved */
 };
 
 /*
@@ -496,7 +502,7 @@ uint8_t *   ieee80211_add_meshid(uint8_t *
 uint8_t *      ieee80211_add_meshconf(uint8_t *, struct ieee80211vap *);
 uint8_t *      ieee80211_add_meshpeer(uint8_t *, uint8_t, uint16_t, uint16_t,
                    uint16_t);
-uint8_t *      ieee80211_add_meshlmetric(uint8_t *, uint32_t);
+uint8_t *      ieee80211_add_meshlmetric(uint8_t *, uint8_t, uint32_t);
 
 void           ieee80211_mesh_node_init(struct ieee80211vap *,
                    struct ieee80211_node *);
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to