netfilter: nf_ct_dccp: add missing DCCP protocol changes in event cache
[safe/jmp/linux-2.6] / net / mac80211 / mesh.h
index d565b3f..d891d7d 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/types.h>
 #include <linux/jhash.h>
+#include <asm/unaligned.h>
 #include "ieee80211_i.h"
 
 
  *
  *
  *
- * @MESH_PATH_ACTIVE: the mesh path is can be used for forwarding
- * @MESH_PATH_RESOLVED: the discovery process is running for this mesh path
+ * @MESH_PATH_ACTIVE: the mesh path can be used for forwarding
+ * @MESH_PATH_RESOLVING: the discovery process is running for this mesh path
  * @MESH_PATH_DSN_VALID: the mesh path contains a valid destination sequence
  *     number
  * @MESH_PATH_FIXED: the mesh path has been manually set and should not be
  *     modified
  * @MESH_PATH_RESOLVED: the mesh path can has been resolved
- * @MESH_PATH_DELETE: the mesh path is scheduled to be deleted
  *
- * MESH_PATH_RESOLVED and MESH_PATH_DELETE are used by the mesh path timer to
+ * MESH_PATH_RESOLVED is used by the mesh path timer to
  * decide when to stop or cancel the mesh path discovery.
  */
 enum mesh_path_flags {
@@ -41,14 +41,13 @@ enum mesh_path_flags {
        MESH_PATH_DSN_VALID =   BIT(2),
        MESH_PATH_FIXED =       BIT(3),
        MESH_PATH_RESOLVED =    BIT(4),
-       MESH_PATH_DELETE =      BIT(5),
 };
 
 /**
  * struct mesh_path - mac80211 mesh path structure
  *
  * @dst: mesh path destination mac address
- * @dev: mesh path device
+ * @sdata: mesh subif
  * @next_hop: mesh neighbor to which frames for this destination will be
  *     forwarded
  * @timer: mesh path discovery timer
@@ -65,13 +64,15 @@ enum mesh_path_flags {
  * @state_lock: mesh pat state lock
  *
  *
- * The combination of dst and dev is unique in the mesh path table. A reference
- * to the next_hop sta will be kept and in case this sta is removed, the
- * mesh_path structure must be also removed or substitued in a rcu safe way
+ * The combination of dst and sdata is unique in the mesh path table. Since the
+ * next_hop STA is only protected by RCU as well, deleting the STA must also
+ * remove/substitute the mesh_path structure and wait until that is no longer
+ * reachable before destroying the STA completely.
  */
 struct mesh_path {
        u8 dst[ETH_ALEN];
-       struct net_device *dev;
+       u8 mpp[ETH_ALEN];       /* used for MPP or MAP */
+       struct ieee80211_sub_if_data *sdata;
        struct sta_info *next_hop;
        struct timer_list timer;
        struct sk_buff_head frame_queue;
@@ -109,7 +110,7 @@ struct mesh_table {
        __u32 hash_rnd;                 /* Used for hash generation */
        atomic_t entries;               /* Up to MAX_MESH_NEIGHBOURS */
        void (*free_node) (struct hlist_node *p, bool free_leafs);
-       void (*copy_node) (struct hlist_node *p, struct mesh_table *newtbl);
+       int (*copy_node) (struct hlist_node *p, struct mesh_table *newtbl);
        int size_order;
        int mean_chain_len;
 };
@@ -140,13 +141,10 @@ struct rmc_entry {
 
 struct mesh_rmc {
        struct rmc_entry bucket[RMC_BUCKETS];
-       u8 idx_mask;
+       u32 idx_mask;
 };
 
 
-/* Mesh IEs constants */
-#define MESH_CFG_LEN           19
-
 /*
  * MESH_CFG_COMP_LEN Includes:
  *     - Active path selection protocol ID.
@@ -156,7 +154,7 @@ struct mesh_rmc {
  * Does not include mesh capabilities, which may vary across nodes in the same
  * mesh
  */
-#define MESH_CFG_CMP_LEN       17
+#define MESH_CFG_CMP_LEN       (IEEE80211_MESH_CONFIG_LEN - 2)
 
 /* Default values, timeouts in ms */
 #define MESH_TTL               5
@@ -198,79 +196,90 @@ struct mesh_rmc {
 
 /* Public interfaces */
 /* Various */
-u8 mesh_id_hash(u8 *mesh_id, int mesh_id_len);
 int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr);
 int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
                struct ieee80211_sub_if_data *sdata);
 int mesh_rmc_check(u8 *addr, struct ieee80211s_hdr *mesh_hdr,
-               struct net_device *dev);
-bool mesh_matches_local(struct ieee802_11_elems *ie, struct net_device *dev);
-void mesh_ids_set_default(struct ieee80211_if_sta *sta);
-void mesh_mgmt_ies_add(struct sk_buff *skb, struct net_device *dev);
-void mesh_rmc_free(struct net_device *dev);
-int mesh_rmc_init(struct net_device *dev);
+               struct ieee80211_sub_if_data *sdata);
+bool mesh_matches_local(struct ieee802_11_elems *ie,
+               struct ieee80211_sub_if_data *sdata);
+void mesh_ids_set_default(struct ieee80211_if_mesh *mesh);
+void mesh_mgmt_ies_add(struct sk_buff *skb,
+               struct ieee80211_sub_if_data *sdata);
+void mesh_rmc_free(struct ieee80211_sub_if_data *sdata);
+int mesh_rmc_init(struct ieee80211_sub_if_data *sdata);
 void ieee80211s_init(void);
 void ieee80211s_stop(void);
 void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata);
+ieee80211_rx_result
+ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
+                      struct ieee80211_rx_status *rx_status);
+void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata);
+void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata);
 
 /* Mesh paths */
-int mesh_nexthop_lookup(u8 *next_hop, struct sk_buff *skb,
-               struct net_device *dev);
-void mesh_path_start_discovery(struct net_device *dev);
-struct mesh_path *mesh_path_lookup(u8 *dst, struct net_device *dev);
-struct mesh_path *mesh_path_lookup_by_idx(int idx, struct net_device *dev);
+int mesh_nexthop_lookup(struct sk_buff *skb,
+               struct ieee80211_sub_if_data *sdata);
+void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata);
+struct mesh_path *mesh_path_lookup(u8 *dst,
+               struct ieee80211_sub_if_data *sdata);
+struct mesh_path *mpp_path_lookup(u8 *dst,
+                                 struct ieee80211_sub_if_data *sdata);
+int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata);
+struct mesh_path *mesh_path_lookup_by_idx(int idx,
+               struct ieee80211_sub_if_data *sdata);
 void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop);
-void mesh_path_expire(struct net_device *dev);
-void mesh_path_flush(struct net_device *dev);
-void mesh_rx_path_sel_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
-               size_t len);
-int mesh_path_add(u8 *dst, struct net_device *dev);
+void mesh_path_expire(struct ieee80211_sub_if_data *sdata);
+void mesh_path_flush(struct ieee80211_sub_if_data *sdata);
+void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata,
+               struct ieee80211_mgmt *mgmt, size_t len);
+int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata);
 /* Mesh plinks */
-void mesh_neighbour_update(u8 *hw_addr, u64 rates, struct net_device *dev,
-               bool add);
-bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie,
-                             struct net_device *dev);
-void mesh_accept_plinks_update(struct net_device *dev);
-struct sta_info *mesh_plink_add(u8 *hw_addr, u64 rates, struct net_device *dev);
+void mesh_neighbour_update(u8 *hw_addr, u32 rates,
+               struct ieee80211_sub_if_data *sdata, bool add);
+bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie);
+void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata);
 void mesh_plink_broken(struct sta_info *sta);
 void mesh_plink_deactivate(struct sta_info *sta);
 int mesh_plink_open(struct sta_info *sta);
-int mesh_plink_close(struct sta_info *sta);
 void mesh_plink_block(struct sta_info *sta);
-void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
-                        size_t len, struct ieee80211_rx_status *rx_status);
+void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
+                        struct ieee80211_mgmt *mgmt, size_t len,
+                        struct ieee80211_rx_status *rx_status);
 
 /* Private interfaces */
 /* Mesh tables */
 struct mesh_table *mesh_table_alloc(int size_order);
 void mesh_table_free(struct mesh_table *tbl, bool free_leafs);
 struct mesh_table *mesh_table_grow(struct mesh_table *tbl);
-u32 mesh_table_hash(u8 *addr, struct net_device *dev, struct mesh_table *tbl);
+u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata,
+               struct mesh_table *tbl);
 /* Mesh paths */
 int mesh_path_error_tx(u8 *dest, __le32 dest_dsn, u8 *ra,
-               struct net_device *dev);
+               struct ieee80211_sub_if_data *sdata);
 void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta);
 void mesh_path_flush_pending(struct mesh_path *mpath);
 void mesh_path_tx_pending(struct mesh_path *mpath);
 int mesh_pathtbl_init(void);
 void mesh_pathtbl_unregister(void);
-int mesh_path_del(u8 *addr, struct net_device *dev);
+int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata);
 void mesh_path_timer(unsigned long data);
 void mesh_path_flush_by_nexthop(struct sta_info *sta);
-void mesh_path_discard_frame(struct sk_buff *skb, struct net_device *dev);
+void mesh_path_discard_frame(struct sk_buff *skb,
+               struct ieee80211_sub_if_data *sdata);
 
 #ifdef CONFIG_MAC80211_MESH
 extern int mesh_allocated;
 
 static inline int mesh_plink_free_count(struct ieee80211_sub_if_data *sdata)
 {
-       return sdata->u.sta.mshcfg.dot11MeshMaxPeerLinks -
-              atomic_read(&sdata->u.sta.mshstats.estab_plinks);
+       return sdata->u.mesh.mshcfg.dot11MeshMaxPeerLinks -
+              atomic_read(&sdata->u.mesh.mshstats.estab_plinks);
 }
 
 static inline bool mesh_plink_availables(struct ieee80211_sub_if_data *sdata)
 {
-       return (min(mesh_plink_free_count(sdata),
+       return (min_t(long, mesh_plink_free_count(sdata),
                   MESH_MAX_PLINKS - sdata->local->num_sta)) > 0;
 }
 
@@ -283,10 +292,12 @@ static inline void mesh_path_activate(struct mesh_path *mpath)
        for (i = 0; i <= x->hash_mask; i++) \
                hlist_for_each_entry_rcu(node, p, &x->hash_buckets[i], list)
 
+void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local);
+
 #else
 #define mesh_allocated 0
+static inline void
+ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) {}
 #endif
 
-#define MESH_PREQ(skb) (skb->cb + 30)
-
 #endif /* IEEE80211S_H */