Netdev List
 help / color / mirror / Atom feed
* [PATCH] neighbour tables via rtnetlink v2
From: Thomas Graf @ 2005-05-24 17:02 UTC (permalink / raw)
  To: netdev

Setting of values is still untested due to missing userspace part but
reading of the configuration and the statistics works. Example libnl
output including full statistics:

arp_cache entries 2 reachable 26s 156msec retrans 1s
    thresh1 128 thresh2 512 thresh3 1024
    key-len 4 entry-size 152 last-flush 24m 19s 474msec
    hash-rand 0xC7089C95/0x00000003 gc 1 last-rand 4s 472msec
    refcnt 1 qlen 3 proxy-qlen 64 locktime 1s base-reachable 30s
    app-probes 0 ucast-probes 3 mcast-probes 3 gc-stale-time 1m
    probe-delay 5s anycast-delay 1s proxy-delay 800msec
    lookups 65 hits 62 failed 0 allocations 3 destroys 1
    hash-grows 1 forced-gc-runs 0 periodic-gc-runs 387
    rcv-unicast-probes 0 rcv-multicast-probes 0

and for device specific parameter sets:

arp_cache<eth0> reachable 22s 443msec retrans 1s
    refcnt 3 qlen 3 proxy-qlen 64 locktime 1s base-reachable 30s
    app-probes 0 ucast-probes 3 mcast-probes 3 gc-stale-time 1m
    probe-delay 5s anycast-delay 1s proxy-delay 800msec

I use msecs for all time values instead of user HZ and seconds
to allow for greater precision and less headache for userspace.

Attached are 3 patches, new netlink and rtnetlink shortcuts
for prettier message building and the actual new code.

[NETLINK] New message building macros

 NLMSG_NEW(skb, pid, sequence, type, length)
   Start a new netlink message, returns message header.
  
 NLMSG_NEW_ANSWER(skb, nlcb, type, length)
   Start a new netlink message as answer to a request,
   returns message header.

 NLMSG_END(skb, nlh)
   End a netlink message, fixes total message length,
   returns skb->len.

 NLMSG_CANCEL(skb, nlh)
   Cancel the building process and trim whole message
   from skb again, returns -1.

Signed-off-by: Thomas Graf <tgraf@suug.ch>

---
commit 7250be2b3e192904e66ce314a3d2d2e46bc8bce2
tree 4f7a765c06386f20a3a9b68eea4efd57e2b354ad
parent d1faeaeb95a05275cf0c5b51b88f2fa833434625
author Thomas Graf <tgraf@suug.ch> Tue, 24 May 2005 14:26:10 +0200
committer Thomas Graf <tgraf@suug.ch> Tue, 24 May 2005 14:26:10 +0200

 include/linux/netlink.h |   22 ++++++++++++++++++++--
 1 files changed, 20 insertions(+), 2 deletions(-)

Index: include/linux/netlink.h
===================================================================
--- c6f827347b3c6c28bc55a8eb1e62ea2659202cab/include/linux/netlink.h  (mode:100644)
+++ 4f7a765c06386f20a3a9b68eea4efd57e2b354ad/include/linux/netlink.h  (mode:100644)
@@ -170,9 +170,27 @@
 	return nlh;
 }
 
+#define NLMSG_END(skb, nlh) \
+({	(nlh)->nlmsg_len = (skb)->tail - (unsigned char *) (nlh); \
+	skb->len; })
+
+#define NLMSG_CANCEL(skb, nlh) \
+({	skb_trim((skb), (unsigned char *) (nlh) - (skb)->data); \
+	-1; })
+
 #define NLMSG_PUT(skb, pid, seq, type, len) \
-({ if (skb_tailroom(skb) < (int)NLMSG_SPACE(len)) goto nlmsg_failure; \
-   __nlmsg_put(skb, pid, seq, type, len); })
+({	if (skb_tailroom(skb) < (int)NLMSG_SPACE(len)) \
+		goto nlmsg_failure; \
+	__nlmsg_put(skb, pid, seq, type, len); })
+
+#define NLMSG_NEW(skb, pid, seq, type, len) \
+({	struct nlmsghdr *_hdr = NLMSG_PUT(skb, pid, seq, type, len); \
+	_hdr->nlmsg_flags = pid ? NLM_F_MULTI : 0; \
+	_hdr; })
+
+#define NLMSG_NEW_ANSWER(skb, cb, type, len) \
+	NLMSG_NEW(skb, NETLINK_CB((cb)->skb).pid, \
+		  (cb)->nlh->nlmsg_seq, type, len)
 
 extern int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
 			      struct nlmsghdr *nlh,


[RTNETLINK] Routing attribute related shortcuts

 RTA_GET_U(32|64)(tlv)
   Assumes tlv is a u32/u64 field and returns its value.

 RTA_GET_[M]SECS(tlv)
   Assumes tlv is a u64 and transports jiffies converted
   to seconds or milliseconds and returns its value.

 RTA_PUT_U(32|64)(skb, type, value)
   Appends %value as fixed u32/u64 to %skb as TLV %type.

 RTA_PUT_[M]SECS(skb, type, jiffies)
   Converts %jiffies to secs/msecs and appends it as u64
   to %skb as TLV %type.

 RTA_PUT_STRING(skb, type, string)
   Appends %NUL terminated %string to %skb as TLV %type.

 RTA_NEST(skb, type)
   Starts a nested TLV %type and returns the nesting handle.

 RTA_END_NEST(skb, nesting_handle)
   Finishes the nested TLV %nesting_handle, must be called
   symmetric to RTA_NEST().

Signed-off-by: Thomas Graf <tgraf@suug.ch>

---
commit edab564809178ad08753d8d620fc9b518898fd79
tree d3a4a96913f779af77cd3486cdeb701dc92efed0
parent 7250be2b3e192904e66ce314a3d2d2e46bc8bce2
author Thomas Graf <tgraf@suug.ch> Tue, 24 May 2005 18:47:38 +0200
committer Thomas Graf <tgraf@suug.ch> Tue, 24 May 2005 18:47:38 +0200

 include/linux/rtnetlink.h |   37 +++++++++++++++++++++++++++++++++++++
 1 files changed, 37 insertions(+)

Index: include/linux/rtnetlink.h
===================================================================
--- 4f7a765c06386f20a3a9b68eea4efd57e2b354ad/include/linux/rtnetlink.h  (mode:100644)
+++ d3a4a96913f779af77cd3486cdeb701dc92efed0/include/linux/rtnetlink.h  (mode:100644)
@@ -123,8 +123,20 @@
 #define RTA_DATA(rta)   ((void*)(((char*)(rta)) + RTA_LENGTH(0)))
 #define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0))
 
+#define RTA_GET_U32(rta) \
+({	if (!rta || RTA_PAYLOAD(rta) < sizeof(u32)) \
+		goto rtattr_failure; \
+	*(u32 *) RTA_DATA(rta); })
 
+#define RTA_GET_U64(rta) \
+({	u64 _tmp; \
+	if (!rta || RTA_PAYLOAD(rta) < sizeof(u64)) \
+		goto rtattr_failure; \
+	memcpy(&_tmp, RTA_DATA(rta), sizeof(_tmp)); \
+	_tmp; })
 
+#define RTA_GET_SECS(rta) ((unsigned long) RTA_GET_U64(rta) * HZ)
+#define RTA_GET_MSECS(rta) (msecs_to_jiffies((unsigned long) RTA_GET_U64(rta)))
 
 /******************************************************************************
  *		Definitions used in routing table administration.
@@ -789,6 +801,31 @@
 ({	if (unlikely(skb_tailroom(skb) < (int)(attrlen))) \
 		goto rtattr_failure; \
 	memcpy(skb_put(skb, RTA_ALIGN(attrlen)), data, attrlen); })
+
+#define RTA_PUT_U32(skb, attrtype, value) \
+({	u32 _tmp = (value); \
+	RTA_PUT(skb, attrtype, sizeof(u32), &_tmp); })
+
+#define RTA_PUT_U64(skb, attrtype, value) \
+({	u64 _tmp = (value); \
+	RTA_PUT(skb, attrtype, sizeof(u64), &_tmp); })
+
+#define RTA_PUT_SECS(skb, attrtype, value) \
+	RTA_PUT_U64(skb, attrtype, (value) / HZ)
+
+#define RTA_PUT_MSECS(skb, attrtype, value) \
+	RTA_PUT_U64(skb, attrtype, jiffies_to_msecs(value))
+
+#define RTA_PUT_STRING(skb, attrtype, value) \
+	RTA_PUT(skb, attrtype, strlen(value) + 1, value)
+
+#define RTA_NEST(skb, type) \
+({	struct rtattr *__start = (struct rtattr *) (skb)->tail; \
+	RTA_PUT(skb, type, 0, NULL); \
+	__start;  })
+
+#define RTA_END_NEST(skb, start) \
+({	(start)->rta_len = ((skb)->tail - (unsigned char *) (start)); })
 		
 static inline struct rtattr *
 __rta_reserve(struct sk_buff *skb, int attrtype, int attrlen)


[NEIGH] neighbour table configuration and statistics via rtnetlink

Signed-off-by: Thomas Graf <tgraf@suug.ch>

---
commit 51565b40aef15f4e4b5748f9d71121e029bc4fe7
tree 7fdf80f0bf19d8ed075ee7f423173f0838c87683
parent edab564809178ad08753d8d620fc9b518898fd79
author Thomas Graf <tgraf@suug.ch> Tue, 24 May 2005 18:48:08 +0200
committer Thomas Graf <tgraf@suug.ch> Tue, 24 May 2005 18:48:08 +0200

 include/linux/rtnetlink.h   |   94 +++++++++++++
 include/net/neighbour.h     |    4 
 net/core/neighbour.c        |  310 +++++++++++++++++++++++++++++++++++++++++++-
 net/core/rtnetlink.c        |   20 +-
 security/selinux/nlmsgtab.c |    2 
 5 files changed, 419 insertions(+), 11 deletions(-)

Index: include/linux/rtnetlink.h
===================================================================
--- d3a4a96913f779af77cd3486cdeb701dc92efed0/include/linux/rtnetlink.h  (mode:100644)
+++ 7fdf80f0bf19d8ed075ee7f423173f0838c87683/include/linux/rtnetlink.h  (mode:100644)
@@ -89,6 +89,13 @@
 	RTM_GETANYCAST	= 62,
 #define RTM_GETANYCAST	RTM_GETANYCAST
 
+	RTM_NEWNEIGHTBL	= 64,
+#define RTM_NEWNEIGHTBL	RTM_NEWNEIGHTBL
+	RTM_GETNEIGHTBL	= 66,
+#define RTM_GETNEIGHTBL	RTM_GETNEIGHTBL
+	RTM_SETNEIGHTBL,
+#define RTM_SETNEIGHTBL	RTM_SETNEIGHTBL
+
 	__RTM_MAX,
 #define RTM_MAX		(((__RTM_MAX + 3) & ~3) - 1)
 };
@@ -505,6 +512,93 @@
 	__u32		ndm_refcnt;
 };
 
+
+/*****************************************************************
+ *		Neighbour tables specific messages.
+ *
+ * Message Ordering:
+ * Phase 1: foreach neighbour table
+ *          neighbour table base configuration and statistics
+ *          NDTA_NAME, NDTA_CONFIG, NDTA_THRESH[1-3], NDTA_STATS
+ *          NDTA_PARMS
+ *
+ * Phase 2: foreach neighbour table device parameter set
+ *          NDTA_NAME, NDTA_PARMS
+ ****/
+
+struct ndt_stats
+{
+	__u64		ndts_allocs;
+	__u64		ndts_destroys;
+	__u64		ndts_hash_grows;
+	__u64		ndts_res_failed;
+	__u64		ndts_lookups;
+	__u64		ndts_hits;
+	__u64		ndts_rcv_probes_mcast;
+	__u64		ndts_rcv_probes_ucast;
+	__u64		ndts_periodic_gc_runs;
+	__u64		ndts_forced_gc_runs;
+};
+
+enum {
+	NDTPA_UNSPEC,
+	NDTPA_IFINDEX,			/* u32, read-only */
+	NDTPA_REFCNT,			/* u32, read-only */
+	NDTPA_REACHABLE_TIME,		/* u64, msecs, read-only */
+	NDTPA_BASE_REACHABLE_TIME,	/* u64, msecs */
+	NDTPA_RETRANS_TIME,		/* u64, msecs */
+	NDTPA_GC_STALETIME,		/* u64, msecs */
+	NDTPA_DELAY_PROBE_TIME,		/* u64, msecs */
+	NDTPA_QUEUE_LEN,		/* u32 */
+	NDTPA_APP_PROBES,		/* u32 */
+	NDTPA_UCAST_PROBES,		/* u32 */
+	NDTPA_MCAST_PROBES,		/* u32 */
+	NDTPA_ANYCAST_DELAY,		/* u64, msecs */
+	NDTPA_PROXY_DELAY,		/* u64, msecs */
+	NDTPA_PROXY_QLEN,		/* u32 */
+	NDTPA_LOCKTIME,			/* u64, msecs */
+	__NDTPA_MAX
+};
+#define NDTPA_MAX (__NDTPA_MAX - 1)
+
+struct ndtmsg
+{
+	__u8		ndtm_family;
+	__u8		ndtm_pad1;
+	__u16		ndtm_pad2;
+};
+
+struct ndt_config
+{
+	__u16		ndtc_key_len;
+	__u16		ndtc_entry_size;
+	__u32		ndtc_entries;
+	__u32		ndtc_last_flush;	/* delta to now in msecs */
+	__u32		ndtc_last_rand;		/* delta to now in msecs */
+	__u32		ndtc_hash_rnd;
+	__u32		ndtc_hash_mask;
+	__u32		ndtc_hash_chain_gc;
+	__u32		ndtc_proxy_qlen;
+};
+
+enum {
+	NDTA_UNSPEC,
+	NDTA_NAME,			/* char * */
+	NDTA_THRESH1,			/* u32 */
+	NDTA_THRESH2,			/* u32 */
+	NDTA_THRESH3,			/* u32 */
+	NDTA_CONFIG,			/* struct ndt_config */
+	NDTA_PARMS,			/* NDTPA_* */
+	NDTA_STATS,			/* struct ndt_stats */
+	__NDTA_MAX
+};
+#define NDTA_MAX (__NDTA_MAX - 1)
+
+#define NDTA_RTA(r) ((struct rtattr*)(((char*)(r)) + \
+		     NLMSG_ALIGN(sizeof(struct ndtmsg))))
+#define NDTA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ndtmsg))
+
+
 /****
  *		General form of address family dependent message.
  ****/
Index: include/net/neighbour.h
===================================================================
--- d3a4a96913f779af77cd3486cdeb701dc92efed0/include/net/neighbour.h  (mode:100644)
+++ 7fdf80f0bf19d8ed075ee7f423173f0838c87683/include/net/neighbour.h  (mode:100644)
@@ -65,6 +65,7 @@
 
 struct neigh_parms
 {
+	struct net_device *dev;
 	struct neigh_parms *next;
 	int	(*neigh_setup)(struct neighbour *);
 	struct neigh_table *tbl;
@@ -252,6 +253,9 @@
 extern int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg);
 extern void neigh_app_ns(struct neighbour *n);
 
+extern int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb);
+extern int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg);
+
 extern void neigh_for_each(struct neigh_table *tbl, void (*cb)(struct neighbour *, void *), void *cookie);
 extern void __neigh_for_each_release(struct neigh_table *tbl, int (*cb)(struct neighbour *));
 extern void pneigh_for_each(struct neigh_table *tbl, void (*cb)(struct pneigh_entry *));
Index: net/core/neighbour.c
===================================================================
--- d3a4a96913f779af77cd3486cdeb701dc92efed0/net/core/neighbour.c  (mode:100644)
+++ 7fdf80f0bf19d8ed075ee7f423173f0838c87683/net/core/neighbour.c  (mode:100644)
@@ -1276,9 +1276,14 @@
 		INIT_RCU_HEAD(&p->rcu_head);
 		p->reachable_time =
 				neigh_rand_reach_time(p->base_reachable_time);
-		if (dev && dev->neigh_setup && dev->neigh_setup(dev, p)) {
-			kfree(p);
-			return NULL;
+		if (dev) {
+			if (dev->neigh_setup && dev->neigh_setup(dev, p)) {
+				kfree(p);
+				return NULL;
+			}
+
+			dev_hold(dev);
+			p->dev = dev;
 		}
 		p->sysctl_table = NULL;
 		write_lock_bh(&tbl->lock);
@@ -1309,6 +1314,8 @@
 			*p = parms->next;
 			parms->dead = 1;
 			write_unlock_bh(&tbl->lock);
+			if (parms->dev)
+				dev_put(parms->dev);
 			call_rcu(&parms->rcu_head, neigh_rcu_free_parms);
 			return;
 		}
@@ -1546,6 +1553,301 @@
 	return err;
 }
 
+static int neightbl_fill_parms(struct sk_buff *skb, struct neigh_parms *parms)
+{
+	struct rtattr *nest_parms = RTA_NEST(skb, NDTA_PARMS);
+
+	if (parms->dev)
+		RTA_PUT_U32(skb, NDTPA_IFINDEX, parms->dev->ifindex);
+
+	RTA_PUT_U32(skb, NDTPA_REFCNT, atomic_read(&parms->refcnt));
+	RTA_PUT_U32(skb, NDTPA_QUEUE_LEN, parms->queue_len);
+	RTA_PUT_U32(skb, NDTPA_PROXY_QLEN, parms->proxy_qlen);
+	RTA_PUT_U32(skb, NDTPA_APP_PROBES, parms->app_probes);
+	RTA_PUT_U32(skb, NDTPA_UCAST_PROBES, parms->ucast_probes);
+	RTA_PUT_U32(skb, NDTPA_MCAST_PROBES, parms->mcast_probes);
+	RTA_PUT_MSECS(skb, NDTPA_REACHABLE_TIME, parms->reachable_time);
+	RTA_PUT_MSECS(skb, NDTPA_BASE_REACHABLE_TIME,
+		      parms->base_reachable_time);
+	RTA_PUT_MSECS(skb, NDTPA_GC_STALETIME, parms->gc_staletime);
+	RTA_PUT_MSECS(skb, NDTPA_DELAY_PROBE_TIME, parms->delay_probe_time);
+	RTA_PUT_MSECS(skb, NDTPA_RETRANS_TIME, parms->retrans_time);
+	RTA_PUT_MSECS(skb, NDTPA_ANYCAST_DELAY, parms->anycast_delay);
+	RTA_PUT_MSECS(skb, NDTPA_PROXY_DELAY, parms->proxy_delay);
+	RTA_PUT_MSECS(skb, NDTPA_LOCKTIME, parms->locktime);
+
+	RTA_END_NEST(skb, nest_parms);
+	return 0;
+
+rtattr_failure:
+	return -1;
+}
+
+static int neightbl_fill_info(struct neigh_table *tbl, struct sk_buff *skb,
+			      struct netlink_callback *cb)
+{
+	struct nlmsghdr *nlh;
+	struct ndtmsg *ndtmsg;
+
+	nlh = NLMSG_NEW_ANSWER(skb, cb, RTM_NEWNEIGHTBL, sizeof(struct ndtmsg));
+	ndtmsg = NLMSG_DATA(nlh);
+
+	read_lock_bh(&tbl->lock);
+	ndtmsg->ndtm_family = tbl->family;
+
+	RTA_PUT_STRING(skb, NDTA_NAME, tbl->id);
+	RTA_PUT_U32(skb, NDTA_THRESH1, tbl->gc_thresh1);
+	RTA_PUT_U32(skb, NDTA_THRESH2, tbl->gc_thresh2);
+	RTA_PUT_U32(skb, NDTA_THRESH3, tbl->gc_thresh3);
+
+	{
+		unsigned long now = jiffies;
+		unsigned int flush_delta = now - tbl->last_flush;
+		unsigned int rand_delta = now - tbl->last_rand;
+
+		struct ndt_config ndc = {
+			.ndtc_key_len		= tbl->key_len,
+			.ndtc_entry_size	= tbl->entry_size,
+			.ndtc_entries		= atomic_read(&tbl->entries),
+			.ndtc_last_flush	= jiffies_to_msecs(flush_delta),
+			.ndtc_last_rand		= jiffies_to_msecs(rand_delta),
+			.ndtc_hash_rnd		= tbl->hash_rnd,
+			.ndtc_hash_mask		= tbl->hash_mask,
+			.ndtc_hash_chain_gc	= tbl->hash_chain_gc,
+			.ndtc_proxy_qlen	= tbl->proxy_queue.qlen,
+		};
+
+		RTA_PUT(skb, NDTA_CONFIG, sizeof(ndc), &ndc);
+	}
+
+	{
+		int cpu;
+		struct ndt_stats ndst;
+
+		memset(&ndst, 0, sizeof(ndst));
+
+		for (cpu = 0; cpu < NR_CPUS; cpu++) {
+			struct neigh_statistics	*st;
+
+			if (!cpu_possible(cpu))
+				continue;
+
+			st = per_cpu_ptr(tbl->stats, cpu);
+			ndst.ndts_allocs		+= st->allocs;
+			ndst.ndts_destroys		+= st->destroys;
+			ndst.ndts_hash_grows		+= st->hash_grows;
+			ndst.ndts_res_failed		+= st->res_failed;
+			ndst.ndts_lookups		+= st->lookups;
+			ndst.ndts_hits			+= st->hits;
+			ndst.ndts_rcv_probes_mcast	+= st->rcv_probes_mcast;
+			ndst.ndts_rcv_probes_ucast	+= st->rcv_probes_ucast;
+			ndst.ndts_periodic_gc_runs	+= st->periodic_gc_runs;
+			ndst.ndts_forced_gc_runs	+= st->forced_gc_runs;
+		}
+
+		RTA_PUT(skb, NDTA_STATS, sizeof(ndst), &ndst);
+	}
+
+	BUG_ON(tbl->parms.dev);
+	if (neightbl_fill_parms(skb, &tbl->parms) < 0)
+		goto rtattr_failure;
+
+	read_unlock_bh(&tbl->lock);
+	return NLMSG_END(skb, nlh);
+
+rtattr_failure:
+	read_unlock_bh(&tbl->lock);
+	return NLMSG_CANCEL(skb, nlh);
+ 
+nlmsg_failure:
+	return -1;
+}
+
+static int neightbl_fill_param_info(struct neigh_table *tbl,
+				    struct neigh_parms *parms,
+				    struct sk_buff *skb,
+				    struct netlink_callback *cb)
+{
+	struct ndtmsg *ndtmsg;
+	struct nlmsghdr *nlh;
+
+	nlh = NLMSG_NEW_ANSWER(skb, cb, RTM_NEWNEIGHTBL, sizeof(struct ndtmsg));
+	ndtmsg = NLMSG_DATA(nlh);
+
+	read_lock_bh(&tbl->lock);
+	ndtmsg->ndtm_family = tbl->family;
+	RTA_PUT_STRING(skb, NDTA_NAME, tbl->id);
+
+	if (neightbl_fill_parms(skb, parms) < 0)
+		goto rtattr_failure;
+
+	read_unlock_bh(&tbl->lock);
+	return NLMSG_END(skb, nlh);
+
+rtattr_failure:
+	read_unlock_bh(&tbl->lock);
+	return NLMSG_CANCEL(skb, nlh);
+
+nlmsg_failure:
+	return -1;
+}
+ 
+static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl,
+						      int ifindex)
+{
+	struct neigh_parms *p;
+	
+	for (p = &tbl->parms; p; p = p->next)
+		if ((p->dev && p->dev->ifindex == ifindex) ||
+		    (!p->dev && !ifindex))
+			return p;
+
+	return NULL;
+}
+
+int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+{
+	struct neigh_table *tbl;
+	struct ndtmsg *ndtmsg = NLMSG_DATA(nlh);
+	struct rtattr **tb = arg;
+	int err = -EINVAL;
+
+	if (!tb[NDTA_NAME - 1] || !RTA_PAYLOAD(tb[NDTA_NAME - 1]))
+		return -EINVAL;
+
+	read_lock(&neigh_tbl_lock);
+	for (tbl = neigh_tables; tbl; tbl = tbl->next) {
+		if (ndtmsg->ndtm_family && tbl->family != ndtmsg->ndtm_family)
+			continue;
+
+		if (!rtattr_strcmp(tb[NDTA_NAME - 1], tbl->id))
+			break;
+	}
+
+	if (tbl == NULL) {
+		err = -ENOENT;
+		goto errout;
+	}
+
+	/* 
+	 * We acquire tbl->lock to be nice to the periodic timers and
+	 * make sure they always see a consistent set of values.
+	 */
+	write_lock_bh(&tbl->lock);
+
+	if (tb[NDTA_THRESH1 - 1])
+		tbl->gc_thresh1 = RTA_GET_U32(tb[NDTA_THRESH1 - 1]);
+
+	if (tb[NDTA_THRESH2 - 1])
+		tbl->gc_thresh2 = RTA_GET_U32(tb[NDTA_THRESH2 - 1]);
+
+	if (tb[NDTA_THRESH3 - 1])
+		tbl->gc_thresh3 = RTA_GET_U32(tb[NDTA_THRESH3 - 1]);
+
+	if (tb[NDTA_PARMS - 1]) {
+		struct rtattr *tbp[NDTPA_MAX];
+		struct neigh_parms *p;
+		u32 ifindex = 0;
+
+		if (rtattr_parse_nested(tbp, NDTPA_MAX, tb[NDTA_PARMS - 1]) < 0)
+			goto rtattr_failure;
+
+		if (tbp[NDTPA_IFINDEX - 1])
+			ifindex = RTA_GET_U32(tbp[NDTPA_IFINDEX - 1]);
+
+		p = lookup_neigh_params(tbl, ifindex);
+		if (p == NULL) {
+			err = -ENOENT;
+			goto rtattr_failure;
+		}
+	
+		if (tbp[NDTPA_QUEUE_LEN - 1])
+			p->queue_len = RTA_GET_U32(tbp[NDTPA_QUEUE_LEN - 1]);
+
+		if (tbp[NDTPA_PROXY_QLEN - 1])
+			p->proxy_qlen = RTA_GET_U32(tbp[NDTPA_PROXY_QLEN - 1]);
+
+		if (tbp[NDTPA_APP_PROBES - 1])
+			p->app_probes = RTA_GET_U32(tbp[NDTPA_APP_PROBES - 1]);
+
+		if (tbp[NDTPA_UCAST_PROBES - 1])
+			p->ucast_probes =
+			   RTA_GET_U32(tbp[NDTPA_UCAST_PROBES - 1]);
+
+		if (tbp[NDTPA_MCAST_PROBES - 1])
+			p->mcast_probes =
+			   RTA_GET_U32(tbp[NDTPA_MCAST_PROBES - 1]);
+
+		if (tbp[NDTPA_BASE_REACHABLE_TIME - 1])
+			p->base_reachable_time =
+			   RTA_GET_MSECS(tbp[NDTPA_BASE_REACHABLE_TIME - 1]);
+
+		if (tbp[NDTPA_GC_STALETIME - 1])
+			p->gc_staletime =
+			   RTA_GET_MSECS(tbp[NDTPA_GC_STALETIME - 1]);
+
+		if (tbp[NDTPA_DELAY_PROBE_TIME - 1])
+			p->delay_probe_time =
+			   RTA_GET_MSECS(tbp[NDTPA_DELAY_PROBE_TIME - 1]);
+
+		if (tbp[NDTPA_RETRANS_TIME - 1])
+			p->retrans_time =
+			   RTA_GET_MSECS(tbp[NDTPA_RETRANS_TIME - 1]);
+
+		if (tbp[NDTPA_ANYCAST_DELAY - 1])
+			p->anycast_delay =
+			   RTA_GET_MSECS(tbp[NDTPA_ANYCAST_DELAY - 1]);
+
+		if (tbp[NDTPA_PROXY_DELAY - 1])
+			p->proxy_delay =
+			   RTA_GET_MSECS(tbp[NDTPA_PROXY_DELAY - 1]);
+
+		if (tbp[NDTPA_LOCKTIME - 1])
+			p->locktime = RTA_GET_MSECS(tbp[NDTPA_LOCKTIME - 1]);
+	}
+
+	err = 0;
+
+rtattr_failure:
+	write_unlock_bh(&tbl->lock);
+errout:
+	read_unlock(&neigh_tbl_lock);
+	return err;
+}
+
+int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
+{
+	int idx, family;
+	int s_idx = cb->args[0];
+	struct neigh_table *tbl;
+
+	family = ((struct rtgenmsg *)NLMSG_DATA(cb->nlh))->rtgen_family;
+
+	read_lock(&neigh_tbl_lock);
+	for (tbl = neigh_tables, idx = 0; tbl; tbl = tbl->next) {
+		struct neigh_parms *p;
+
+		if (idx < s_idx || (family && tbl->family != family))
+			continue;
+
+		if (neightbl_fill_info(tbl, skb, cb) <= 0)
+			break;
+
+		for (++idx, p = tbl->parms.next; p; p = p->next, idx++) {
+			if (idx < s_idx)
+				continue;
+
+			if (neightbl_fill_param_info(tbl, p, skb, cb) <= 0)
+				goto out;
+		}
+
+	}
+out:
+	read_unlock(&neigh_tbl_lock);
+	cb->args[0] = idx;
+
+	return skb->len;
+}
 
 static int neigh_fill_info(struct sk_buff *skb, struct neighbour *n,
 			   u32 pid, u32 seq, int event)
@@ -2352,6 +2654,8 @@
 EXPORT_SYMBOL(neigh_update_hhs);
 EXPORT_SYMBOL(pneigh_enqueue);
 EXPORT_SYMBOL(pneigh_lookup);
+EXPORT_SYMBOL(neightbl_dump_info);
+EXPORT_SYMBOL(neightbl_set);
 
 #ifdef CONFIG_ARPD
 EXPORT_SYMBOL(neigh_app_ns);
Index: net/core/rtnetlink.c
===================================================================
--- d3a4a96913f779af77cd3486cdeb701dc92efed0/net/core/rtnetlink.c  (mode:100644)
+++ 7fdf80f0bf19d8ed075ee7f423173f0838c87683/net/core/rtnetlink.c  (mode:100644)
@@ -100,6 +100,7 @@
 	[RTM_FAM(RTM_NEWPREFIX)]    = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
 	[RTM_FAM(RTM_GETMULTICAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
 	[RTM_FAM(RTM_GETANYCAST)]   = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
+	[RTM_FAM(RTM_NEWNEIGHTBL)]  = NLMSG_LENGTH(sizeof(struct ndtmsg)),
 };
 
 static const int rta_max[RTM_NR_FAMILIES] =
@@ -113,6 +114,7 @@
 	[RTM_FAM(RTM_NEWTCLASS)]    = TCA_MAX,
 	[RTM_FAM(RTM_NEWTFILTER)]   = TCA_MAX,
 	[RTM_FAM(RTM_NEWACTION)]    = TCAA_MAX,
+	[RTM_FAM(RTM_NEWNEIGHTBL)]  = NDTA_MAX,
 };
 
 void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data)
@@ -649,14 +651,16 @@
 
 static struct rtnetlink_link link_rtnetlink_table[RTM_NR_MSGTYPES] =
 {
-	[RTM_GETLINK  - RTM_BASE] = { .dumpit = rtnetlink_dump_ifinfo },
-	[RTM_SETLINK  - RTM_BASE] = { .doit   = do_setlink	      },
-	[RTM_GETADDR  - RTM_BASE] = { .dumpit = rtnetlink_dump_all    },
-	[RTM_GETROUTE - RTM_BASE] = { .dumpit = rtnetlink_dump_all    },
-	[RTM_NEWNEIGH - RTM_BASE] = { .doit   = neigh_add	      },
-	[RTM_DELNEIGH - RTM_BASE] = { .doit   = neigh_delete	      },
-	[RTM_GETNEIGH - RTM_BASE] = { .dumpit = neigh_dump_info	      },
-	[RTM_GETRULE  - RTM_BASE] = { .dumpit = rtnetlink_dump_all    },
+	[RTM_GETLINK     - RTM_BASE] = { .dumpit = rtnetlink_dump_ifinfo },
+	[RTM_SETLINK     - RTM_BASE] = { .doit   = do_setlink		 },
+	[RTM_GETADDR     - RTM_BASE] = { .dumpit = rtnetlink_dump_all	 },
+	[RTM_GETROUTE    - RTM_BASE] = { .dumpit = rtnetlink_dump_all	 },
+	[RTM_NEWNEIGH    - RTM_BASE] = { .doit   = neigh_add		 },
+	[RTM_DELNEIGH    - RTM_BASE] = { .doit   = neigh_delete		 },
+	[RTM_GETNEIGH    - RTM_BASE] = { .dumpit = neigh_dump_info	 },
+	[RTM_GETRULE     - RTM_BASE] = { .dumpit = rtnetlink_dump_all	 },
+	[RTM_GETNEIGHTBL - RTM_BASE] = { .dumpit = neightbl_dump_info	 },
+	[RTM_SETNEIGHTBL - RTM_BASE] = { .doit   = neightbl_set		 },
 };
 
 static int rtnetlink_event(struct notifier_block *this, unsigned long event, void *ptr)
Index: security/selinux/nlmsgtab.c
===================================================================
--- d3a4a96913f779af77cd3486cdeb701dc92efed0/security/selinux/nlmsgtab.c  (mode:100644)
+++ 7fdf80f0bf19d8ed075ee7f423173f0838c87683/security/selinux/nlmsgtab.c  (mode:100644)
@@ -63,6 +63,8 @@
 	{ RTM_GETPREFIX,	NETLINK_ROUTE_SOCKET__NLMSG_READ  },
 	{ RTM_GETMULTICAST,	NETLINK_ROUTE_SOCKET__NLMSG_READ  },
 	{ RTM_GETANYCAST,	NETLINK_ROUTE_SOCKET__NLMSG_READ  },
+	{ RTM_GETNEIGHTBL,	NETLINK_ROUTE_SOCKET__NLMSG_READ  },
+	{ RTM_SETNEIGHTBL,	NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
 };
 
 static struct nlmsg_perm nlmsg_firewall_perms[] =

^ permalink raw reply

* tcp_mem setting bytes or memory pages
From: Paul Griffith @ 2005-05-24 16:59 UTC (permalink / raw)
  To: netdev

Greetings,

I have been searching the Internet for a final answer what the values
in net.ipv4.tcp_mem mean.

I have seen some sites say it is in memory pages (4K blocks) and other
have said it is in KB. What the real answer?

Thanks
Paul

^ permalink raw reply

* Re: [PATCH] netem: fix logic bug in reorder conditional
From: Stephen Hemminger @ 2005-05-24 16:57 UTC (permalink / raw)
  To: Julio Kriger; +Cc: David S. Miller, netdev, netem
In-Reply-To: <682bc30a050524084136fa2fe3@mail.gmail.com>

On Tue, 24 May 2005 12:41:11 -0300
Julio Kriger <juliokriger@gmail.com> wrote:

> > > 2) If I set latency = 50ms and a jitter = 300ms, tabledist can give me
> > > a negative number. This value is addes to cb->time_to_send, so it
> > > could change it to a negative value. Should we only accept positives
> > > number before add it to cb->time_to_send? or will
> > > q->qdisc->enqueue(skb, q->qdisc) put the package on the queue in a
> > > special way so it will be handled "before" other packages alrealy on
> > > the queue but with gretaer time_to_send?
> > 
> > probably should bound the value to 0 before the addition, to avoid large
> > wraparound problems, but since enqueue checks for for time it will work
> > as long as delta less than 2^32/2.
> > 
> 
> I think the value should be restricted to be positive and greater than
> zero. Becuase if a negative number is allowed we will be "losing"
> packages to be reordered, hence we will not be reordering, say 25%, of
> packages instead we will be reordering about 15%.
> In other words, packages that should be reordered will not be
> reordered because its new time to send will be the same as the old
> time to send.
> Regards,
> Julio

The problem is that the user specification (latency 50ms +/- 300ms with reordering) 
is problematic. Just like specifying reordering without delay (and a fast connection).

I chose to keep the original method of reordering by putting things at front of the
queue. Another alternative would be to keep a side-stack of packets to wait for
reordering. The problem with that is that if no following packet arrives, we end up
holding onto the last packet forever; and that would be bad.

^ permalink raw reply

* Re: [PATCH] Super TSO v3
From: Rick Jones @ 2005-05-24 16:12 UTC (permalink / raw)
  To: netdev
In-Reply-To: <20050523.193817.112290763.davem@davemloft.net>

David S. Miller wrote:
> From: Herbert Xu <herbert@gondor.apana.org.au>
> Date: Tue, 24 May 2005 12:32:57 +1000
> 
> 
>>True, the Nagle algorithm itself aims to do something different
>>from this function.  However, the act of turning Nagle off is
>>an indication that the application wants to minimise the latency
>>by sending things out ASAP.  So we should either respect that
>>here by not delaying the packets to increase the TSO size, or
>>we'll need a new socket option to do that for TSO.
> 
> 
> Sure, we can check tp->nonagle to turn this deferring off.
> 
> But, I bet there are folks who want traditional Nagle turned
> off, yet TSO chunking enabled.

I'm not sure there will be very many of those.  I would have thought the folks 
who turn-off Nagle are  typically doing small sends.  If they were not wanting 
to wait to aggregate their small sends into MSS segments, or wait for the RTT, I 
doubt thet are looking to wait to aggregate to something larger than the MSS.

rick jones

^ permalink raw reply

* Re: [PATCH] netem: fix logic bug in reorder conditional
From: Julio Kriger @ 2005-05-24 15:41 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: David S. Miller, netdev, netem
In-Reply-To: <20050523140055.127f1a9f@dxpl.pdx.osdl.net>

> > 2) If I set latency = 50ms and a jitter = 300ms, tabledist can give me
> > a negative number. This value is addes to cb->time_to_send, so it
> > could change it to a negative value. Should we only accept positives
> > number before add it to cb->time_to_send? or will
> > q->qdisc->enqueue(skb, q->qdisc) put the package on the queue in a
> > special way so it will be handled "before" other packages alrealy on
> > the queue but with gretaer time_to_send?
> 
> probably should bound the value to 0 before the addition, to avoid large
> wraparound problems, but since enqueue checks for for time it will work
> as long as delta less than 2^32/2.
> 

I think the value should be restricted to be positive and greater than
zero. Becuase if a negative number is allowed we will be "losing"
packages to be reordered, hence we will not be reordering, say 25%, of
packages instead we will be reordering about 15%.
In other words, packages that should be reordered will not be
reordered because its new time to send will be the same as the old
time to send.
Regards,
Julio

-- 
----------------------------
Julio Kriger
mailto:juliokriger@gmail.com

^ permalink raw reply

* [6/6] ipw2200: fix after "ieee80211: ethernet independency"
From: Jiri Benc @ 2005-05-24 13:20 UTC (permalink / raw)
  To: NetDev
In-Reply-To: <20050524150711.01632672@griffin.suse.cz>

Fixes ipw2200 after making the 802.11 layer independent of ethernet
(patch [4/5] ieee80211: ethernet independency).


Signed-off-by: Jiri Benc <jbenc@suse.cz>
Signed-off-by: Jirka Bohac <jbohac@suse.cz>

--- a/drivers/net/wireless/ipw2200.c	2005-05-18 16:50:29.000000000 +0200
+++ b/drivers/net/wireless/ipw2200.c	2005-05-20 14:16:40.000000000 +0200
@@ -6316,8 +6316,8 @@
 			return 0;
 
 		/* {broad,multi}cast packets to our IBSS go through */
-		if (is_broadcast_ether_addr(header->addr1) ||
-		    is_multicast_ether_addr(header->addr1))
+		if (is_broadcast_ieee80211_addr(header->addr1) ||
+		    is_multicast_ieee80211_addr(header->addr1))
 			return !memcmp(header->addr3, priv->bssid, ETH_ALEN);
 
 		/* packets to our adapter go through */
@@ -6329,8 +6329,8 @@
 			return 0;
 
 		/* {broad,multi}cast packets to our IBSS go through */
-		if (is_broadcast_ether_addr(header->addr1) ||
-		    is_multicast_ether_addr(header->addr1))
+		if (is_broadcast_ieee80211_addr(header->addr1) ||
+		    is_multicast_ieee80211_addr(header->addr1))
 			return !memcmp(header->addr2, priv->bssid, ETH_ALEN);
 
 		/* packets to our adapter go through */
@@ -7847,8 +7847,8 @@
 	switch (priv->ieee->iw_mode) {
 	case IW_MODE_ADHOC:
 		hdr_len = IEEE80211_3ADDR_LEN;
-		unicast = !is_broadcast_ether_addr(hdr->addr1) &&
-			!is_multicast_ether_addr(hdr->addr1);
+		unicast = !is_broadcast_ieee80211_addr(hdr->addr1) &&
+			!is_multicast_ieee80211_addr(hdr->addr1);
 		id = ipw_find_station(priv, hdr->addr1);
 		if (id == IPW_INVALID_STATION) {
 			id = ipw_add_station(priv, hdr->addr1);
@@ -7863,8 +7863,8 @@
 
 	case IW_MODE_INFRA:
 	default:
-		unicast = !is_broadcast_ether_addr(hdr->addr3) &&
-			!is_multicast_ether_addr(hdr->addr3);
+		unicast = !is_broadcast_ieee80211_addr(hdr->addr3) &&
+			!is_multicast_ieee80211_addr(hdr->addr3);
 		hdr_len = IEEE80211_3ADDR_LEN;
 		id = 0;
 		break;


--
Jiri Benc
SUSE Labs

^ permalink raw reply

* [5/6] ipw2200: fix after "ieee80211_device alignment fix"
From: Jiri Benc @ 2005-05-24 13:19 UTC (permalink / raw)
  To: NetDev
In-Reply-To: <20050524150711.01632672@griffin.suse.cz>

Fixes ipw2200 after ieee80211_device alignment fix
(patch [2/5] ieee80211: ieee80211_device alignment fix and cleanup).


Signed-off-by: Jiri Benc <jbenc@suse.cz>
Signed-off-by: Jirka Bohac <jbohac@suse.cz>

--- linux-2.6.12-rc2-mm3.02/drivers/net/wireless/ipw2200.c	2005-05-18 13:36:28.000000000 +0200
+++ linux-2.6.12-rc2-mm3.02-ipwfix/drivers/net/wireless/ipw2200.c	2005-05-18 16:50:29.000000000 +0200
@@ -5586,7 +5586,7 @@
 	}
 
 	if (ieee->set_security)
-		ieee->set_security(ieee->dev, &sec);
+		ieee->set_security(ieee, &sec);
 	else
 		ret = -EOPNOTSUPP;
 
@@ -5613,7 +5613,7 @@
 	}
 
 	if (ieee->set_security)
-		ieee->set_security(ieee->dev, &sec);
+		ieee->set_security(ieee, &sec);
 	else
 		ret = -EOPNOTSUPP;
 
@@ -5623,7 +5623,7 @@
 
 static int ipw_wpa_set_param(struct net_device *dev, u8 name, u32 value)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 	int ret=0;
 
 	switch (name) {
@@ -5662,7 +5662,7 @@
 
 static int ipw_wpa_mlme(struct net_device *dev, int command, int reason)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 	int ret = 0;
 
 	switch (command) {
@@ -5712,8 +5712,8 @@
 static int ipw_wpa_set_wpa_ie(struct net_device *dev,
 			      struct ipw_param *param, int plen)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
-	struct ieee80211_device *ieee = priv->ieee;
+	struct ieee80211_device *ieee = netdev_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(ieee);
 	u8 *buf;
 
 	if (!ieee->wpa_enabled)
@@ -5748,8 +5748,7 @@
 				  struct ipw_param *param, int param_len)
 {
 	int ret = 0;
-	struct ipw_priv *priv = ieee80211_priv(dev);
-	struct ieee80211_device *ieee = priv->ieee;
+	struct ieee80211_device *ieee = netdev_priv(dev);
 	struct ieee80211_crypto_ops *ops;
 	struct ieee80211_crypt_data **crypt;
 
@@ -5871,7 +5870,7 @@
 	}
  done:
 	if (ieee->set_security)
-		ieee->set_security(ieee->dev, &sec);
+		ieee->set_security(ieee, &sec);
 
 	/* Do not reset port if card is in Managed mode since resetting will
 	 * generate new IEEE 802.11 authentication which may end up in looping
@@ -5881,7 +5880,7 @@
 	if (ieee->reset_on_keychange &&
 	    ieee->iw_mode != IW_MODE_INFRA &&
 	    ieee->reset_port &&
-	    ieee->reset_port(dev)) {
+	    ieee->reset_port(ieee)) {
 		IPW_DEBUG_INFO("%s: reset_port failed\n", dev->name);
 		param->u.crypt.err = IPW_CRYPT_ERR_CARD_CONF_FAILED;
 		return -EINVAL;
@@ -6525,7 +6524,7 @@
 			   struct iw_request_info *info,
 			   union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 	down(&priv->sem);
 	if (priv->status & STATUS_RF_KILL_MASK)
 		strcpy(wrqu->name, "radio off");
@@ -6574,7 +6573,7 @@
 			   struct iw_request_info *info,
 			   union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 	struct iw_freq *fwrq = &wrqu->freq;
 	int ret = 0;
 
@@ -6610,7 +6609,7 @@
 			   struct iw_request_info *info,
 			   union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 
 	wrqu->freq.e = 0;
 
@@ -6632,7 +6631,7 @@
 			   struct iw_request_info *info,
 			   union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 	int err = 0;
 
 	IPW_DEBUG_WX("Set MODE: %d\n", wrqu->mode);
@@ -6688,7 +6687,7 @@
 			       struct iw_request_info *info,
 			       union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
         down(&priv->sem);
 	wrqu->mode = priv->ieee->iw_mode;
 	IPW_DEBUG_WX("Get MODE -> %d\n", wrqu->mode);
@@ -6725,7 +6724,7 @@
 			    struct iw_request_info *info,
 			    union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 	struct iw_range *range = (struct iw_range *)extra;
 	u16 val;
 	int i;
@@ -6789,7 +6788,7 @@
 			  struct iw_request_info *info,
 			  union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 
 	static const unsigned char any[] = {
 		0xff, 0xff, 0xff, 0xff, 0xff, 0xff
@@ -6838,7 +6837,7 @@
 			  struct iw_request_info *info,
 			  union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 	/* If we are associated, trying to associate, or have a statically
 	 * configured BSSID then return that; otherwise return ANY */
 	down(&priv->sem);
@@ -6859,7 +6858,7 @@
 			    struct iw_request_info *info,
 			    union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 	char *essid = ""; /* ANY */
 	int length = 0;
 	down(&priv->sem);
@@ -6909,7 +6908,7 @@
 			    struct iw_request_info *info,
 			    union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 
 	/* If we are associated, trying to associate, or have a statically
 	 * configured ESSID then return that; otherwise return ANY */
@@ -6934,7 +6933,7 @@
 			   struct iw_request_info *info,
 			   union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 
 	IPW_DEBUG_WX("Setting nick to '%s'\n", extra);
 	if (wrqu->data.length > IW_ESSID_MAX_SIZE)
@@ -6954,7 +6953,7 @@
 			   struct iw_request_info *info,
 			   union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 	IPW_DEBUG_WX("Getting nick\n");
 	down(&priv->sem);
 	wrqu->data.length = strlen(priv->nick) + 1;
@@ -6969,7 +6968,7 @@
 			   union iwreq_data *wrqu, char *extra)
 {
 	/* TODO: We should use semaphores or locks for access to priv */
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 	u32 target_rate = wrqu->bitrate.value;
 	u32 fixed, mask;
 
@@ -7081,7 +7080,7 @@
 			   struct iw_request_info *info,
 			   union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv * priv = ieee80211_priv(dev);
+	struct ipw_priv * priv = ieee80211_priv(netdev_priv(dev));
 	down(&priv->sem);
 	wrqu->bitrate.value = priv->last_rate;
 	up(&priv->sem);
@@ -7094,7 +7093,7 @@
 			  struct iw_request_info *info,
 			  union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 	down(&priv->sem);
 	if (wrqu->rts.disabled)
 		priv->rts_threshold = DEFAULT_RTS_THRESHOLD;
@@ -7117,7 +7116,7 @@
 			  struct iw_request_info *info,
 			  union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 	down(&priv->sem);
 	wrqu->rts.value = priv->rts_threshold;
 	wrqu->rts.fixed = 0;	/* no auto select */
@@ -7133,7 +7132,7 @@
 			    struct iw_request_info *info,
 			    union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 	struct ipw_tx_power tx_power;
 	int i;
 	down(&priv->sem);
@@ -7185,7 +7184,7 @@
 			    struct iw_request_info *info,
 			    union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 	down(&priv->sem);
 	wrqu->power.value = priv->tx_power;
 	wrqu->power.fixed = 1;
@@ -7204,7 +7203,7 @@
 			       struct iw_request_info *info,
 			       union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 	down(&priv->sem);
 	if (wrqu->frag.disabled)
 		priv->ieee->fts = DEFAULT_FTS;
@@ -7226,7 +7225,7 @@
 			       struct iw_request_info *info,
 			       union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 	down(&priv->sem);
 	wrqu->frag.value = priv->ieee->fts;
 	wrqu->frag.fixed = 0;	/* no auto select */
@@ -7260,7 +7259,7 @@
 			   struct iw_request_info *info,
 			   union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 	IPW_DEBUG_WX("Start scan\n");
 	down(&priv->sem);
 	if (ipw_request_scan(priv)) {
@@ -7275,7 +7274,7 @@
 			   struct iw_request_info *info,
 			   union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 	return ieee80211_wx_get_scan(priv->ieee, info, wrqu, extra);
 }
 
@@ -7283,7 +7282,7 @@
 				 struct iw_request_info *info,
 				 union iwreq_data *wrqu, char *key)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 	return ieee80211_wx_set_encode(priv->ieee, info, wrqu, key);
 }
 
@@ -7291,7 +7290,7 @@
 				 struct iw_request_info *info,
 				 union iwreq_data *wrqu, char *key)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 	return ieee80211_wx_get_encode(priv->ieee, info, wrqu, key);
 }
 
@@ -7299,7 +7298,7 @@
 			        struct iw_request_info *info,
 			        union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 	int err;
 	down(&priv->sem);
 	if (wrqu->power.disabled) {
@@ -7350,7 +7349,7 @@
 			        struct iw_request_info *info,
 			        union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 	down(&priv->sem);
 	if (!(priv->power_mode & IPW_POWER_ENABLED))
 		wrqu->power.disabled = 1;
@@ -7367,7 +7366,7 @@
 				    struct iw_request_info *info,
 				    union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 	int mode = *(int *)extra;
 	int err;
 	down(&priv->sem);
@@ -7396,7 +7395,7 @@
 				    struct iw_request_info *info,
 				    union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 	int level = IPW_POWER_LEVEL(priv->power_mode);
 	char *p = extra;
 
@@ -7428,7 +7427,7 @@
                                     struct iw_request_info *info,
                                     union iwreq_data *wrqu, char *extra)
 {
-        struct ipw_priv *priv = ieee80211_priv(dev);
+        struct ipw_priv *priv = ieee80211_priv(netdev_priv(netdev_priv(dev)));
 	int mode = *(int *)extra;
 	u8 band = 0, modulation = 0;
 
@@ -7495,7 +7494,7 @@
                                     struct iw_request_info *info,
                                     union iwreq_data *wrqu, char *extra)
 {
-        struct ipw_priv *priv = ieee80211_priv(dev);
+        struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 	down(&priv->sem);
 	switch (priv->ieee->mode) {
 	case IEEE_A:
@@ -7538,7 +7537,7 @@
 				   struct iw_request_info *info,
 				   union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 	int mode = *(int *)extra;
 	down(&priv->sem);
 	/* Switching from SHORT -> LONG requires a disassociation */
@@ -7570,7 +7569,7 @@
 			       struct iw_request_info *info,
 			       union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 	down(&priv->sem);
 	if (priv->config & CFG_PREAMBLE_LONG)
 		snprintf(wrqu->name, IFNAMSIZ, "long (1)");
@@ -7745,7 +7744,7 @@
  */
 static struct iw_statistics *ipw_get_wireless_stats(struct net_device * dev)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 	struct iw_statistics *wstats;
 
 	wstats = &priv->wstats;
@@ -7808,7 +7807,7 @@
 
 static int ipw_net_open(struct net_device *dev)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 	IPW_DEBUG_INFO("dev->open\n");
 	/* we should be verifying the device is ready to be opened */
 	down(&priv->sem);
@@ -7972,9 +7971,9 @@
 }
 
 static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
-				   struct net_device *dev)
+				   struct ieee80211_device *ieee)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(ieee);
 	unsigned long flags;
 
 	IPW_DEBUG_TX("dev->xmit(%d bytes)\n", txb->payload_size);
@@ -7983,7 +7982,7 @@
 	if (!(priv->status & STATUS_ASSOCIATED)) {
 		IPW_DEBUG_INFO("Tx attempt while not associated.\n");
 		priv->ieee->stats.tx_carrier_errors++;
-		netif_stop_queue(dev);
+		netif_stop_queue(ieee80211_dev(ieee));
 		goto fail_unlock;
 	}
 
@@ -8002,7 +8001,7 @@
 
 static struct net_device_stats *ipw_net_get_stats(struct net_device *dev)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 
 	priv->ieee->stats.tx_packets = priv->tx_packets;
 	priv->ieee->stats.rx_packets = priv->rx_packets;
@@ -8016,7 +8015,7 @@
 
 static int ipw_net_set_mac_address(struct net_device *dev, void *p)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 	struct sockaddr *addr = p;
 	if (!is_valid_ether_addr(addr->sa_data))
 		return -EADDRNOTAVAIL;
@@ -8033,7 +8032,7 @@
 static void ipw_ethtool_get_drvinfo(struct net_device *dev,
 				    struct ethtool_drvinfo *info)
 {
-	struct ipw_priv *p = ieee80211_priv(dev);
+	struct ipw_priv *p = ieee80211_priv(netdev_priv(dev));
 	char vers[64];
 	char date[32];
 	u32 len;
@@ -8054,7 +8053,7 @@
 
 static u32 ipw_ethtool_get_link(struct net_device *dev)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 	return (priv->status & STATUS_ASSOCIATED) != 0;
 }
 
@@ -8066,7 +8065,7 @@
 static int ipw_ethtool_get_eeprom(struct net_device *dev,
 				  struct ethtool_eeprom *eeprom, u8 *bytes)
 {
-	struct ipw_priv *p = ieee80211_priv(dev);
+	struct ipw_priv *p = ieee80211_priv(netdev_priv(dev));
 
 	if (eeprom->offset + eeprom->len > CX2_EEPROM_IMAGE_SIZE)
 		return -EINVAL;
@@ -8079,7 +8078,7 @@
 static int ipw_ethtool_set_eeprom(struct net_device *dev,
 				  struct ethtool_eeprom *eeprom, u8 *bytes)
 {
-	struct ipw_priv *p = ieee80211_priv(dev);
+	struct ipw_priv *p = ieee80211_priv(netdev_priv(dev));
 	int i;
 
 	if (eeprom->offset + eeprom->len > CX2_EEPROM_IMAGE_SIZE)
@@ -8293,10 +8292,10 @@
 }
 
 
-static void shim__set_security(struct net_device *dev,
+static void shim__set_security(struct ieee80211_device *ieee,
 			       struct ieee80211_security *sec)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(ieee);
 	int i;
 	down(&priv->sem);
 	for (i = 0; i < 4; i++) {
@@ -8579,7 +8578,7 @@
 /* Called by register_netdev() */
 static int ipw_net_init(struct net_device *dev)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = ieee80211_priv(netdev_priv(dev));
 	down(&priv->sem);
 	if (priv->status & STATUS_RF_KILL_SW) {
 		IPW_WARNING("Radio disabled by module parameter.\n");
@@ -8665,19 +8664,21 @@
 {
 	int err = 0;
 	struct net_device *net_dev;
+	struct ieee80211_device *ieee;
 	void __iomem *base;
 	u32 length, val;
 	struct ipw_priv *priv;
 	int band, modulation;
 
-	net_dev = alloc_ieee80211(sizeof(struct ipw_priv));
-	if (net_dev == NULL) {
+	ieee = alloc_ieee80211(sizeof(struct ipw_priv));
+	if (ieee == NULL) {
 		err = -ENOMEM;
 		goto out;
 	}
+	net_dev = ieee80211_dev(ieee);
 
-	priv = ieee80211_priv(net_dev);
-	priv->ieee = netdev_priv(net_dev);
+	priv = ieee80211_priv(ieee);
+	priv->ieee = ieee;
 
 	priv->net_dev = net_dev;
 	priv->pci_dev = pdev;
@@ -8882,7 +8883,7 @@
 	pci_disable_device(pdev);
 	pci_set_drvdata(pdev, NULL);
  out_free_ieee80211:
-	free_ieee80211(priv->net_dev);
+	free_ieee80211(priv->ieee);
  out:
 	return err;
 }
@@ -8924,7 +8925,7 @@
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
 	pci_set_drvdata(pdev, NULL);
-	free_ieee80211(priv->net_dev);
+	free_ieee80211(priv->ieee);
 
 #ifdef CONFIG_PM
 	if (fw_loaded) {


--
Jiri Benc
SUSE Labs

^ permalink raw reply

* [4/6] ipw2100: fix after "ieee80211_device alignment fix"
From: Jiri Benc @ 2005-05-24 13:18 UTC (permalink / raw)
  To: NetDev; +Cc: pavel
In-Reply-To: <20050524150711.01632672@griffin.suse.cz>

Fixes ipw2100 after ieee80211_device alignment fix
(patch [2/5] ieee80211: ieee80211_device alignment fix and cleanup)


Signed-off-by: Jiri Benc <jbenc@suse.cz>
Signed-off-by: Jirka Bohac <jbohac@suse.cz>

--- linux-2.6.12-rc2-mm3.01/drivers/net/wireless/ipw2100.c	2005-05-19 16:23:00.000000000 +0200
+++ linux-2.6.12-rc2-mm3.04/drivers/net/wireless/ipw2100.c	2005-05-19 17:35:48.000000000 +0200
@@ -1717,7 +1717,7 @@
 /* Called by register_netdev() */
 static int ipw2100_net_init(struct net_device *dev)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 	return ipw2100_up(priv, 1);
 }
 
@@ -3142,9 +3142,9 @@
 	return IRQ_NONE;
 }
 
-static int ipw2100_tx(struct ieee80211_txb *txb, struct net_device *dev)
+static int ipw2100_tx(struct ieee80211_txb *txb, struct ieee80211_device *ieee)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(ieee);
 	struct list_head *element;
 	struct ipw2100_tx_packet *packet;
 	unsigned long flags;
@@ -3154,7 +3154,7 @@
 	if (!(priv->status & STATUS_ASSOCIATED)) {
 		IPW_DEBUG_INFO("Can not transmit when not connected.\n");
 		priv->ieee->stats.tx_carrier_errors++;
-		netif_stop_queue(dev);
+		netif_stop_queue(ieee80211_dev(ieee));
 		goto fail_unlock;
 	}
 
@@ -3185,7 +3185,7 @@
 	return 0;
 
  fail_unlock:
-	netif_stop_queue(dev);
+	netif_stop_queue(ieee80211_dev(ieee));
 	spin_unlock_irqrestore(&priv->low_lock, flags);
 	return 1;
 }
@@ -5087,10 +5087,10 @@
 		ipw2100_configure_security(priv, 0);
 }
 
-static void shim__set_security(struct net_device *dev,
+static void shim__set_security(struct ieee80211_device *ieee,
 			       struct ieee80211_security *sec)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(ieee);
 	int i, force_update = 0;
 
 	down(&priv->action_sem);
@@ -5270,7 +5270,7 @@
  * method as well) to talk to the firmware */
 static int ipw2100_set_address(struct net_device *dev, void *p)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 	struct sockaddr *addr = p;
 	int err = 0;
 
@@ -5298,7 +5298,7 @@
 
 static int ipw2100_open(struct net_device *dev)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 	unsigned long flags;
 	IPW_DEBUG_INFO("dev->open\n");
 
@@ -5312,7 +5312,7 @@
 
 static int ipw2100_close(struct net_device *dev)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 	unsigned long flags;
 	struct list_head *element;
 	struct ipw2100_tx_packet *packet;
@@ -5348,7 +5348,7 @@
  */
 static void ipw2100_tx_timeout(struct net_device *dev)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 
 	priv->ieee->stats.tx_errors++;
 
@@ -5371,7 +5371,7 @@
  */
 static struct net_device_stats *ipw2100_stats(struct net_device *dev)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 
 	return &priv->ieee->stats;
 }
@@ -5458,7 +5458,7 @@
 	}
 
 	if (ieee->set_security)
-		ieee->set_security(ieee->dev, &sec);
+		ieee->set_security(ieee, &sec);
 	else
 		ret = -EOPNOTSUPP;
 
@@ -5485,7 +5485,7 @@
 	}
 
 	if (ieee->set_security)
-		ieee->set_security(ieee->dev, &sec);
+		ieee->set_security(ieee, &sec);
 	else
 		ret = -EOPNOTSUPP;
 
@@ -5495,7 +5495,7 @@
 
 static int ipw2100_wpa_set_param(struct net_device *dev, u8 name, u32 value){
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 	int ret=0;
 
 	switch(name){
@@ -5534,7 +5534,7 @@
 
 static int ipw2100_wpa_mlme(struct net_device *dev, int command, int reason){
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 	int ret=0;
 
 	switch(command){
@@ -5576,8 +5576,8 @@
 static int ipw2100_wpa_set_wpa_ie(struct net_device *dev,
 				struct ipw2100_param *param, int plen){
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
-	struct ieee80211_device *ieee = priv->ieee;
+	struct ieee80211_device *ieee = netdev_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(ieee);
 	u8 *buf;
 
 	if (! ieee->wpa_enabled)
@@ -5616,8 +5616,8 @@
 				struct ipw2100_param *param, int param_len){
 
 	int ret = 0;
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
-	struct ieee80211_device *ieee = priv->ieee;
+	struct ieee80211_device *ieee = netdev_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(ieee);
 	struct ieee80211_crypto_ops *ops;
 	struct ieee80211_crypt_data **crypt;
 
@@ -5737,7 +5737,7 @@
 	}
  done:
 	if (ieee->set_security)
-		ieee->set_security(ieee->dev, &sec);
+		ieee->set_security(ieee, &sec);
 
 	/* Do not reset port if card is in Managed mode since resetting will
 	 * generate new IEEE 802.11 authentication which may end up in looping
@@ -5834,7 +5834,7 @@
 static void ipw_ethtool_get_drvinfo(struct net_device *dev,
 				    struct ethtool_drvinfo *info)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 	char fw_ver[64], ucode_ver[64];
 
 	strcpy(info->driver, DRV_NAME);
@@ -5851,7 +5851,7 @@
 
 static u32 ipw2100_ethtool_get_link(struct net_device *dev)
 {
-    struct ipw2100_priv *priv = ieee80211_priv(dev);
+    struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
     return (priv->status & STATUS_ASSOCIATED) ? 1 : 0;
 }
 
@@ -5944,12 +5944,14 @@
 {
 	struct ipw2100_priv *priv;
 	struct net_device *dev;
+	struct ieee80211_device *ieee;
 
-	dev = alloc_ieee80211(sizeof(struct ipw2100_priv));
-	if (!dev)
+	ieee = alloc_ieee80211(sizeof(struct ipw2100_priv));
+	if (!ieee)
 		return NULL;
-	priv = ieee80211_priv(dev);
-	priv->ieee = netdev_priv(dev);
+	dev = ieee80211_dev(ieee);
+	priv = ieee80211_priv(ieee);
+	priv->ieee = ieee;
 	priv->pci_dev = pci_dev;
 	priv->net_dev = dev;
 
@@ -6131,7 +6133,7 @@
 		return err;
 	}
 
-	priv = ieee80211_priv(dev);
+	priv = ieee80211_priv(netdev_priv(dev));
 
 	pci_set_master(pci_dev);
 	pci_set_drvdata(pci_dev, priv);
@@ -6270,7 +6272,7 @@
 		ipw2100_queues_free(priv);
 		sysfs_remove_group(&pci_dev->dev.kobj, &ipw2100_attribute_group);
 
-		free_ieee80211(dev);
+		free_ieee80211(netdev_priv(dev));
 		pci_set_drvdata(pci_dev, NULL);
 	}
 
@@ -6326,7 +6328,7 @@
 		if (dev->base_addr)
 			iounmap((unsigned char *)dev->base_addr);
 
-		free_ieee80211(dev);
+		free_ieee80211(netdev_priv(dev));
 	}
 
 	pci_release_regions(pci_dev);
@@ -6547,7 +6549,7 @@
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 	if (!(priv->status & STATUS_ASSOCIATED))
 		strcpy(wrqu->name, "unassociated");
 	else
@@ -6562,7 +6564,7 @@
 			       struct iw_request_info *info,
 			       union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 	struct iw_freq *fwrq = &wrqu->freq;
 	int err = 0;
 
@@ -6613,7 +6615,7 @@
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 
 	wrqu->freq.e = 0;
 
@@ -6634,7 +6636,7 @@
 			       struct iw_request_info *info,
 			       union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 	int err = 0;
 
 	IPW_DEBUG_WX("SET Mode -> %d \n", wrqu->mode);
@@ -6677,7 +6679,7 @@
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 
 	wrqu->mode = priv->ieee->iw_mode;
 	IPW_DEBUG_WX("GET Mode -> %d\n", wrqu->mode);
@@ -6713,7 +6715,7 @@
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 	struct iw_range *range = (struct iw_range *)extra;
 	u16 val;
 	int i, level;
@@ -6825,7 +6827,7 @@
 			      struct iw_request_info *info,
 			      union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 	int err = 0;
 
 	static const unsigned char any[] = {
@@ -6880,7 +6882,7 @@
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 
 	/* If we are associated, trying to associate, or have a statically
 	 * configured BSSID then return that; otherwise return ANY */
@@ -6900,7 +6902,7 @@
 				struct iw_request_info *info,
 				union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 	char *essid = ""; /* ANY */
 	int length = 0;
 	int err = 0;
@@ -6954,7 +6956,7 @@
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 
 	/* If we are associated, trying to associate, or have a statically
 	 * configured ESSID then return that; otherwise return ANY */
@@ -6982,7 +6984,7 @@
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 
 	if (wrqu->data.length > IW_ESSID_MAX_SIZE)
 		return -E2BIG;
@@ -7004,7 +7006,7 @@
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 
 	wrqu->data.length = strlen(priv->nick) + 1;
 	memcpy(extra, priv->nick, wrqu->data.length);
@@ -7019,7 +7021,7 @@
 			       struct iw_request_info *info,
 			       union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 	u32 target_rate = wrqu->bitrate.value;
 	u32 rate;
 	int err = 0;
@@ -7060,7 +7062,7 @@
 			       struct iw_request_info *info,
 			       union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 	int val;
 	int len = sizeof(val);
 	int err = 0;
@@ -7112,7 +7114,7 @@
 			      struct iw_request_info *info,
 			      union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 	int value, err;
 
 	/* Auto RTS not yet supported */
@@ -7152,7 +7154,7 @@
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 
 	wrqu->rts.value = priv->rts_threshold & ~RTS_DISABLED;
 	wrqu->rts.fixed = 1; /* no auto select */
@@ -7169,7 +7171,7 @@
 				struct iw_request_info *info,
 				union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 	int err = 0, value;
 
 	if (priv->ieee->iw_mode != IW_MODE_ADHOC)
@@ -7209,7 +7211,7 @@
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 
 	if (priv->ieee->iw_mode != IW_MODE_ADHOC) {
 		wrqu->power.disabled = 1;
@@ -7245,7 +7247,7 @@
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 
 	if (!wrqu->frag.fixed)
 		return -EINVAL;
@@ -7275,7 +7277,7 @@
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 	wrqu->frag.value = priv->frag_threshold & ~FRAG_DISABLED;
 	wrqu->frag.fixed = 0;	/* no auto select */
 	wrqu->frag.disabled = (priv->frag_threshold & FRAG_DISABLED) ? 1 : 0;
@@ -7289,7 +7291,7 @@
 				struct iw_request_info *info,
 				union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 	int err = 0;
 
 	if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
@@ -7338,7 +7340,7 @@
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 
 	wrqu->retry.disabled = 0; /* can't be disabled */
 
@@ -7367,7 +7369,7 @@
 			       struct iw_request_info *info,
 			       union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 	int err = 0;
 
 	down(&priv->action_sem);
@@ -7398,7 +7400,7 @@
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 	return ieee80211_wx_get_scan(priv->ieee, info, wrqu, extra);
 }
 
@@ -7414,7 +7416,7 @@
 	 * No check of STATUS_INITIALIZED required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 	return ieee80211_wx_set_encode(priv->ieee, info, wrqu, key);
 }
 
@@ -7426,7 +7428,7 @@
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 	return ieee80211_wx_get_encode(priv->ieee, info, wrqu, key);
 }
 
@@ -7434,7 +7436,7 @@
 			        struct iw_request_info *info,
 			        union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 	int err = 0;
 
 	down(&priv->action_sem);
@@ -7484,7 +7486,7 @@
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 
 	if (!(priv->power_mode & IPW_POWER_ENABLED)) {
 		wrqu->power.disabled = 1;
@@ -7509,7 +7511,7 @@
 				  struct iw_request_info *info,
 				  union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 	int *parms = (int *)extra;
 	int enable = (parms[0] > 0);
 	int err = 0;
@@ -7540,7 +7542,7 @@
 			    struct iw_request_info *info,
 			    union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 	if (priv->status & STATUS_INITIALIZED)
 		schedule_reset(priv);
 	return 0;
@@ -7552,7 +7554,7 @@
 				    struct iw_request_info *info,
 				    union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 	int err = 0, mode = *(int *)extra;
 
 	down(&priv->action_sem);
@@ -7580,7 +7582,7 @@
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 	int level = IPW_POWER_LEVEL(priv->power_mode);
 	s32 timeout, period;
 
@@ -7617,7 +7619,7 @@
 				   struct iw_request_info *info,
 				   union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 	int err, mode = *(int *)extra;
 
 	down(&priv->action_sem);
@@ -7650,7 +7652,7 @@
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 
 	if (priv->config & CFG_LONG_PREAMBLE)
 		snprintf(wrqu->name, IFNAMSIZ, "long (1)");
@@ -7792,7 +7794,7 @@
 	int tx_qual;
 	int beacon_qual;
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = ieee80211_priv(netdev_priv(dev));
 	struct iw_statistics *wstats;
 	u32 rssi, quality, tx_retries, missed_beacons, tx_failures;
 	u32 ord_len = sizeof(u32);


--
Jiri Benc
SUSE Labs

^ permalink raw reply

* [3/6] ipw2100: fix after "ieee80211: cleanup"
From: Jiri Benc @ 2005-05-24 13:16 UTC (permalink / raw)
  To: NetDev; +Cc: pavel
In-Reply-To: <20050524150711.01632672@griffin.suse.cz>

Fixes ipw2100 after the ieee80211 header cleanup
(patch [1/5] ieee80211: cleanup).


Signed-off-by: Jiri Benc <jbenc@suse.cz>
Signed-off-by: Jirka Bohac <jbohac@suse.cz>

--- a/drivers/net/wireless/ipw2100.h	2005-05-19 16:23:00.000000000 +0200
+++ b/drivers/net/wireless/ipw2100.h	2005-05-19 16:37:14.000000000 +0200
@@ -798,7 +798,7 @@
 
 
 
-#define IPW_HEADER_802_11_SIZE		 sizeof(struct ieee80211_header_data)
+#define IPW_HEADER_802_11_SIZE		 sizeof(struct ieee80211_hdr_3addr)
 #define IPW_MAX_80211_PAYLOAD_SIZE              2304U
 #define IPW_MAX_802_11_PAYLOAD_LENGTH		2312
 #define IPW_MAX_ACCEPTABLE_TX_FRAME_LENGTH	1536


--
Jiri Benc
SUSE Labs

^ permalink raw reply

* [1-2/6] ipw2100, ipw2200: patches to merge to kernel
From: Jiri Benc @ 2005-05-24 13:15 UTC (permalink / raw)
  To: NetDev; +Cc: pavel
In-Reply-To: <20050524150711.01632672@griffin.suse.cz>

Patches to merge the ipw2100 and ipw2200 drivers to the kernel can be
downloaded from:
http://jikos.cz/~jbohac/wifi/import-ipw2100.patch
http://jikos.cz/~jbohac/wifi/import-ipw2200.patch
(they are too large to post them here)

The ipw2100 patch is just a merge of ipw2100 driver with Pavel Machek's
cleanup patch.

The ipw2200 patch is not cleaned up and is intended for testing purposes
only.


--
Jiri Benc
SUSE Labs

^ permalink raw reply

* [5/5] ieee80211: add sequence numbers
From: Jiri Benc @ 2005-05-24 13:13 UTC (permalink / raw)
  To: NetDev; +Cc: LKML, jgarzik, pavel
In-Reply-To: <20050524150711.01632672@griffin.suse.cz>

Adds sequence numbers to IEEE 802.11 headers.


Signed-off-by: Jiri Benc <jbenc@suse.cz>
Signed-off-by: Jirka Bohac <jbohac@suse.cz>

--- a/include/net/ieee80211.h
+++ b/include/net/ieee80211.h
@@ -711,6 +711,8 @@
 	unsigned int frag_next_idx;
 	u16 fts; /* Fragmentation Threshold */
 
+	u16 seq_number;	/* sequence number in transmitted frames */
+
 	/* Association info */
 	u8 bssid[IEEE80211_ALEN];
 
--- a/net/ieee80211/ieee80211_module.c
+++ b/net/ieee80211/ieee80211_module.c
@@ -333,6 +333,7 @@
 
 	/* Default fragmentation threshold is maximum payload size */
 	ieee->fts = DEFAULT_FTS;
+	ieee->seq_number = 0;
 	ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
 	ieee->open_wep = 1;
 
--- a/net/ieee80211/ieee80211_tx.c
+++ b/net/ieee80211/ieee80211_tx.c
@@ -277,6 +277,13 @@
 	else
 		bytes_last_frag = bytes_per_frag;
 
+	if (nr_frags > 16) {
+		/* Should never happen */
+		printk(KERN_WARNING "%s: Fragmentation threshold too low\n",
+			dev->name);
+		goto failed;
+	}
+
 	/* When we allocate the TXB we allocate enough space for the reserve
 	 * and full fragment bytes (bytes_per_frag doesn't include prefix,
 	 * postfix, header, FCS, etc.) */
@@ -300,6 +307,8 @@
 		frag_hdr = (struct ieee80211_hdr *)skb_put(skb_frag, hdr_len);
 		memcpy(frag_hdr, header, hdr_len);
 
+		frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_number | i);
+
 		/* If this is not the last fragment, then add the MOREFRAGS
 		 * bit to the frame control */
 		if (i != nr_frags - 1) {
@@ -324,7 +333,7 @@
 		    (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
 			skb_put(skb_frag, 4);
 	}
-
+	ieee->seq_number += 0x10;
 
  success:
 	spin_unlock_irqrestore(&ieee->lock, flags);


--
Jiri Benc
SUSE Labs

^ permalink raw reply

* [4/5] ieee80211: ethernet independency
From: Jiri Benc @ 2005-05-24 13:12 UTC (permalink / raw)
  To: NetDev; +Cc: LKML, jgarzik, pavel
In-Reply-To: <20050524150711.01632672@griffin.suse.cz>

Makes the 802.11 layer independent of ethernet. (The previous implementation
had the ethernet headers built by the ethernet layer and then parsed them and
rebuilt them into 802.11 headers.)


Signed-off-by: Jiri Benc <jbenc@suse.cz>
Signed-off-by: Jirka Bohac <jbohac@suse.cz>

--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -83,13 +83,18 @@
  *	used.
  */
  
-#if !defined(CONFIG_AX25) && !defined(CONFIG_AX25_MODULE) && !defined(CONFIG_TR)
+#if !defined(CONFIG_AX25) && !defined(CONFIG_AX25_MODULE) && !defined(CONFIG_TR) \
+	&& !defined(CONFIG_IEEE80211)
 #define LL_MAX_HEADER	32
 #else
 #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
 #define LL_MAX_HEADER	96
 #else
+#if defined(CONFIG_TR)
 #define LL_MAX_HEADER	48
+#else
+#define LL_MAX_HEADER	38
+#endif
 #endif
 #endif
 
--- a/include/net/ieee80211.h
+++ b/include/net/ieee80211.h
@@ -20,7 +20,6 @@
  */
 #ifndef IEEE80211_H
 #define IEEE80211_H
-#include <linux/if_ether.h> /* ETH_ALEN */
 #include <linux/kernel.h>   /* ARRAY_SIZE */
 
 #if WIRELESS_EXT < 17
@@ -42,25 +41,26 @@
    WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
 
 
+#define IEEE80211_ALEN			6
 #define IEEE80211_HLEN			30
 #define IEEE80211_FRAME_LEN		(IEEE80211_DATA_LEN + IEEE80211_HLEN)
 
 struct ieee80211_hdr {
 	u16 frame_ctl;
 	u16 duration_id;
-	u8 addr1[ETH_ALEN];
-	u8 addr2[ETH_ALEN];
-	u8 addr3[ETH_ALEN];
+	u8 addr1[IEEE80211_ALEN];
+	u8 addr2[IEEE80211_ALEN];
+	u8 addr3[IEEE80211_ALEN];
 	u16 seq_ctl;
-	u8 addr4[ETH_ALEN];
+	u8 addr4[IEEE80211_ALEN];
 } __attribute__ ((packed));
 
 struct ieee80211_hdr_3addr {
 	u16 frame_ctl;
 	u16 duration_id;
-	u8 addr1[ETH_ALEN];
-	u8 addr2[ETH_ALEN];
-	u8 addr3[ETH_ALEN];
+	u8 addr1[IEEE80211_ALEN];
+	u8 addr2[IEEE80211_ALEN];
+	u8 addr3[IEEE80211_ALEN];
 	u16 seq_ctl;
 } __attribute__ ((packed));
 
@@ -233,7 +233,7 @@
 #define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
 
 #ifndef ETH_P_80211_RAW
-#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
+#define ETH_P_80211_RAW 0x0003
 #endif
 
 /* IEEE 802.11 defines */
@@ -246,11 +246,29 @@
         u8    ssap;   /* always 0xAA */
         u8    ctrl;   /* always 0x03 */
         u8    oui[P80211_OUI_LEN];    /* organizational universal id */
+	u16   type;   /* packet type ID field */
 
 } __attribute__ ((packed));
 
 #define SNAP_SIZE sizeof(struct ieee80211_snap_hdr)
 
+#define IEEE80211_SNAP_IS_RFC1042(snap) \
+		((snap)->oui[0] == 0 && (snap)->oui[1] == 0 && (snap)->oui[2] == 0)
+#define IEEE80211_SNAP_IS_BRIDGE_TUNNEL(snap) \
+		((snap)->oui[0] == 0 && (snap)->oui[1] == 0 && (snap)->oui[2] == 0xf8)
+
+#define IEEE80211_FC_GET_TODS(hdr) \
+		((hdr)->frame_ctl & __constant_cpu_to_le16(IEEE80211_FCTL_TODS))
+#define IEEE80211_FC_GET_FROMDS(hdr) \
+		((hdr)->frame_ctl & __constant_cpu_to_le16(IEEE80211_FCTL_FROMDS))
+#define IEEE80211_GET_DADDR(hdr) \
+		(IEEE80211_FC_GET_TODS(hdr) ? (hdr)->addr3 : (hdr)->addr1)
+#define IEEE80211_GET_SADDR(hdr) \
+		(IEEE80211_FC_GET_FROMDS(hdr) ? \
+			(IEEE80211_FC_GET_TODS(hdr) ? (hdr)->addr4 : (hdr)->addr3) \
+			: (hdr)->addr2)
+/* IEEE80211_GET_xADDR do not work when both TODS and FROMDS are set. */
+
 #define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
 #define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
 
@@ -395,8 +413,8 @@
 	unsigned int seq;
 	unsigned int last_frag;
 	struct sk_buff *skb;
-	u8 src_addr[ETH_ALEN];
-	u8 dst_addr[ETH_ALEN];
+	u8 src_addr[IEEE80211_ALEN];
+	u8 dst_addr[IEEE80211_ALEN];
 };
 
 struct ieee80211_stats {
@@ -507,7 +525,7 @@
 	u16 auth_sequence;
 	u16 beacon_interval;
 	u16 capability;
-	u8 current_ap[ETH_ALEN];
+	u8 current_ap[IEEE80211_ALEN];
 	u16 listen_interval;
 	struct {
 		u16 association_id:14, reserved:2;
@@ -537,7 +555,7 @@
 struct ieee80211_assoc_request_frame {
 	u16 capability;
 	u16 listen_interval;
-	u8 current_ap[ETH_ALEN];
+	u8 current_ap[IEEE80211_ALEN];
 	struct ieee80211_info_element info_element;
 } __attribute__ ((packed));
 
@@ -581,7 +599,7 @@
 
 struct ieee80211_network {
 	/* These entries are used to identify a unique network */
-	u8 bssid[ETH_ALEN];
+	u8 bssid[IEEE80211_ALEN];
 	u8 channel;
 	/* Ensure null-terminated for any debug msgs */
 	u8 ssid[IW_ESSID_MAX_SIZE + 1];
@@ -625,12 +643,12 @@
 #define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
 
 
-extern inline int is_multicast_ether_addr(const u8 *addr)
+extern inline int is_multicast_ieee80211_addr(const u8 *addr)
 {
 	return ((addr[0] != 0xff) && (0x01 & addr[0]));
 }
 
-extern inline int is_broadcast_ether_addr(const u8 *addr)
+extern inline int is_broadcast_ieee80211_addr(const u8 *addr)
 {
 	return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&   \
 		(addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
@@ -694,7 +712,7 @@
 	u16 fts; /* Fragmentation Threshold */
 
 	/* Association info */
-	u8 bssid[ETH_ALEN];
+	u8 bssid[IEEE80211_ALEN];
 
 	enum ieee80211_state state;
 
@@ -774,7 +792,7 @@
 	return 0;
 }
 
-extern inline int ieee80211_get_hdrlen(u16 fc)
+extern inline int __ieee80211_get_hdrlen(u16 fc)
 {
 	int hdrlen = IEEE80211_3ADDR_LEN;
 
@@ -798,12 +816,29 @@
 
 	return hdrlen;
 }
+#define ieee80211_get_hdrlen(hdr) __ieee80211_get_hdrlen(le16_to_cpu((hdr)->frame_ctl))
+
+#define IEEE80211_GET_DATA_HDR_LEN(hdr) \
+		((((hdr)->frame_ctl & \
+			__constant_cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) \
+		 == __constant_cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) \
+		 ? IEEE80211_4ADDR_LEN : IEEE80211_3ADDR_LEN)
+#define IEEE80211_GET_SNAP(hdr) \
+		((struct ieee80211_snap_hdr *) \
+		((u8 *)(hdr) + IEEE80211_GET_DATA_HDR_LEN(hdr)))
 
+extern inline int ieee80211_get_proto(struct ieee80211_hdr *header)
+{
+	struct ieee80211_snap_hdr *snap = IEEE80211_GET_SNAP(header);
+	return (snap->dsap == 0xaa && snap->ssap == 0xaa ?
+		ntohs(snap->type) : ETH_P_802_2);
+}
 
 
 /* ieee80211.c */
 extern void free_ieee80211(struct ieee80211_device *ieee);
 extern struct ieee80211_device *alloc_ieee80211(int sizeof_priv);
+extern void ieee80211_setup(struct net_device *dev);
 
 extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
 
--- a/net/ieee80211/ieee80211_rx.c
+++ b/net/ieee80211/ieee80211_rx.c
@@ -42,11 +42,10 @@
 					struct ieee80211_rx_stats *rx_stats)
 {
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-	u16 fc = le16_to_cpu(hdr->frame_ctl);
 
 	skb->dev = ieee->dev;
 	skb->mac.raw = skb->data;
-	skb_pull(skb, ieee80211_get_hdrlen(fc));
+	skb_pull(skb, ieee80211_get_hdrlen(hdr));
 	skb->pkt_type = PACKET_OTHERHOST;
 	skb->protocol = __constant_htons(ETH_P_80211_RAW);
 	memset(skb->cb, 0, sizeof(skb->cb));
@@ -76,8 +75,8 @@
 
 		if (entry->skb != NULL && entry->seq == seq &&
 		    (entry->last_frag + 1 == frag || frag == -1) &&
-		    memcmp(entry->src_addr, src, ETH_ALEN) == 0 &&
-		    memcmp(entry->dst_addr, dst, ETH_ALEN) == 0)
+		    memcmp(entry->src_addr, src, IEEE80211_ALEN) == 0 &&
+		    memcmp(entry->dst_addr, dst, IEEE80211_ALEN) == 0)
 			return entry;
 	}
 
@@ -104,7 +103,7 @@
 				    sizeof(struct ieee80211_hdr) +
 				    8 /* LLC */ +
 				    2 /* alignment */ +
-				    8 /* WEP */ + ETH_ALEN /* WDS */);
+				    8 /* WEP */ + IEEE80211_ALEN /* WDS */);
 		if (skb == NULL)
 			return NULL;
 
@@ -120,8 +119,8 @@
 		entry->seq = seq;
 		entry->last_frag = frag;
 		entry->skb = skb;
-		memcpy(entry->src_addr, hdr->addr2, ETH_ALEN);
-		memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN);
+		memcpy(entry->src_addr, hdr->addr2, IEEE80211_ALEN);
+		memcpy(entry->dst_addr, hdr->addr1, IEEE80211_ALEN);
 	} else {
 		/* received a fragment of a frame for which the head fragment
 		 * should have already been received */
@@ -221,15 +220,6 @@
 #endif
 
 
-/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
-/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
-static unsigned char rfc1042_header[] =
-{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
-/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
-static unsigned char bridge_tunnel_header[] =
-{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
-/* No encapsulation header if EtherType < 0x600 (=length) */
-
 /* Called by ieee80211_rx_frame_decrypt */
 static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
 				    struct sk_buff *skb)
@@ -237,7 +227,6 @@
 	struct net_device *dev = ieee80211_dev(ieee);
 	u16 fc, ethertype;
 	struct ieee80211_hdr *hdr;
-	u8 *pos;
 
 	if (skb->len < 24)
 		return 0;
@@ -248,12 +237,12 @@
 	/* check that the frame is unicast frame to us */
 	if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
 	    IEEE80211_FCTL_TODS &&
-	    memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 &&
-	    memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) {
+	    memcmp(hdr->addr1, dev->dev_addr, IEEE80211_ALEN) == 0 &&
+	    memcmp(hdr->addr3, dev->dev_addr, IEEE80211_ALEN) == 0) {
 		/* ToDS frame with own addr BSSID and DA */
 	} else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
 		   IEEE80211_FCTL_FROMDS &&
-		   memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {
+		   memcmp(hdr->addr1, dev->dev_addr, IEEE80211_ALEN) == 0) {
 		/* FromDS frame with own addr as DA */
 	} else
 		return 0;
@@ -262,8 +251,7 @@
 		return 0;
 
 	/* check for port access entity Ethernet type */
-	pos = skb->data + 24;
-	ethertype = (pos[6] << 8) | pos[7];
+	ethertype = ieee80211_get_proto(hdr);
 	if (ethertype == ETH_P_PAE)
 		return 1;
 
@@ -282,7 +270,7 @@
 		return 0;
 
 	hdr = (struct ieee80211_hdr *) skb->data;
-	hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
+	hdrlen = ieee80211_get_hdrlen(hdr);
 
 #ifdef CONFIG_IEEE80211_CRYPT_TKIP
 	if (ieee->tkip_countermeasures &&
@@ -327,7 +315,7 @@
 		return 0;
 
 	hdr = (struct ieee80211_hdr *) skb->data;
-	hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
+	hdrlen = ieee80211_get_hdrlen(hdr);
 
 	atomic_inc(&crypt->refcnt);
 	res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
@@ -343,6 +331,44 @@
 }
 
 
+unsigned short ieee80211_type_trans(struct sk_buff *skb,
+		struct ieee80211_device *ieee)
+{
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+	struct ieee80211_snap_hdr *snap;
+	int hdrlen;
+	u8 *daddr = IEEE80211_GET_DADDR(hdr);
+	unsigned short type;
+
+	skb->mac.raw = skb->data;
+
+	hdrlen = ieee80211_get_hdrlen(hdr);
+	snap = (struct ieee80211_snap_hdr *)(skb->data + hdrlen);
+	if (snap->dsap == 0xaa && snap->ssap == 0xaa &&
+			((IEEE80211_SNAP_IS_RFC1042(snap) &&
+			  snap->type != __constant_htons(ETH_P_AARP) &&
+			  snap->type != __constant_htons(ETH_P_IPX)) ||
+			 IEEE80211_SNAP_IS_BRIDGE_TUNNEL(snap))) {
+		type = snap->type;
+		skb_pull(skb, hdrlen + SNAP_SIZE);
+	}
+	else {
+		type = __constant_htons(ETH_P_802_2);
+		skb_pull(skb, hdrlen);
+	}
+
+	skb->input_dev = ieee->dev;
+	if (is_broadcast_ieee80211_addr(daddr))
+		skb->pkt_type = PACKET_BROADCAST;
+	else if (is_multicast_ieee80211_addr(daddr))
+		skb->pkt_type = PACKET_MULTICAST;
+	else if (memcmp(daddr, ieee->dev->dev_addr, IEEE80211_ALEN))
+		skb->pkt_type = PACKET_OTHERHOST;
+
+	return type;
+}
+
+
 /* All received frames are sent to this function. @skb contains the frame in
  * IEEE 802.11 format, i.e., in the format it was sent over air.
  * This function is called only as a tasklet (software IRQ). */
@@ -355,8 +381,6 @@
 	u16 fc, type, stype, sc;
 	struct net_device_stats *stats;
 	unsigned int frag;
-	u8 *payload;
-	u16 ethertype;
 #ifdef NOT_YET
 	struct net_device *wds = NULL;
 	struct sk_buff *skb2 = NULL;
@@ -365,8 +389,8 @@
 	int from_assoc_ap = 0;
 	void *sta = NULL;
 #endif
-	u8 dst[ETH_ALEN];
-	u8 src[ETH_ALEN];
+	u8 dst[IEEE80211_ALEN];
+	u8 src[IEEE80211_ALEN];
 	struct ieee80211_crypt_data *crypt = NULL;
 	int keyidx = 0;
 
@@ -384,7 +408,7 @@
 	stype = WLAN_FC_GET_STYPE(fc);
 	sc = le16_to_cpu(hdr->seq_ctl);
 	frag = WLAN_GET_SEQ_FRAG(sc);
-	hdrlen = ieee80211_get_hdrlen(fc);
+	hdrlen = __ieee80211_get_hdrlen(fc);
 
 #ifdef NOT_YET
 #if WIRELESS_EXT > 15
@@ -480,22 +504,23 @@
 
 	switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
 	case IEEE80211_FCTL_FROMDS:
-		memcpy(dst, hdr->addr1, ETH_ALEN);
-		memcpy(src, hdr->addr3, ETH_ALEN);
+		memcpy(dst, hdr->addr1, IEEE80211_ALEN);
+		memcpy(src, hdr->addr3, IEEE80211_ALEN);
 		break;
 	case IEEE80211_FCTL_TODS:
-		memcpy(dst, hdr->addr3, ETH_ALEN);
-		memcpy(src, hdr->addr2, ETH_ALEN);
+		memcpy(dst, hdr->addr3, IEEE80211_ALEN);
+		memcpy(src, hdr->addr2, IEEE80211_ALEN);
 		break;
 	case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
 		if (skb->len < IEEE80211_4ADDR_LEN)
 			goto rx_dropped;
-		memcpy(dst, hdr->addr3, ETH_ALEN);
-		memcpy(src, hdr->addr4, ETH_ALEN);
+		memcpy(dst, hdr->addr3, IEEE80211_ALEN);
+		memcpy(src, hdr->addr4, IEEE80211_ALEN);
+		/* FIXME: this is wrong */
 		break;
 	case 0:
-		memcpy(dst, hdr->addr1, ETH_ALEN);
-		memcpy(src, hdr->addr2, ETH_ALEN);
+		memcpy(dst, hdr->addr1, IEEE80211_ALEN);
+		memcpy(src, hdr->addr2, IEEE80211_ALEN);
 		break;
 	}
 
@@ -510,7 +535,7 @@
 	if (ieee->iw_mode == IW_MODE_MASTER && !wds &&
 	    (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_FROMDS &&
 	    ieee->stadev &&
-	    memcmp(hdr->addr2, ieee->assoc_ap_addr, ETH_ALEN) == 0) {
+	    memcmp(hdr->addr2, ieee->assoc_ap_addr, IEEE80211_ALEN) == 0) {
 		/* Frame from BSSID of the AP for which we are a client */
 		skb->dev = dev = ieee->stadev;
 		stats = hostap_get_stats(dev);
@@ -668,9 +693,6 @@
 
 	/* skb: hdr + (possible reassembled) full plaintext payload */
 
-	payload = skb->data + hdrlen;
-	ethertype = (payload[6] << 8) | payload[7];
-
 #ifdef NOT_YET
 	/* If IEEE 802.1X is used, check whether the port is authorized to send
 	 * the received frame. */
@@ -697,38 +719,6 @@
 	}
 #endif
 
-	/* convert hdr + possible LLC headers into Ethernet header */
-	if (skb->len - hdrlen >= 8 &&
-	    ((memcmp(payload, rfc1042_header, SNAP_SIZE) == 0 &&
-	      ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
-	     memcmp(payload, bridge_tunnel_header, SNAP_SIZE) == 0)) {
-		/* remove RFC1042 or Bridge-Tunnel encapsulation and
-		 * replace EtherType */
-		skb_pull(skb, hdrlen + SNAP_SIZE);
-		memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
-		memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
-	} else {
-		u16 len;
-		/* Leave Ethernet header part of hdr and full payload */
-		skb_pull(skb, hdrlen);
-		len = htons(skb->len);
-		memcpy(skb_push(skb, 2), &len, 2);
-		memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
-		memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
-	}
-
-#ifdef NOT_YET
-	if (wds && ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
-		    IEEE80211_FCTL_TODS) &&
-	    skb->len >= ETH_HLEN + ETH_ALEN) {
-		/* Non-standard frame: get addr4 from its bogus location after
-		 * the payload */
-		memcpy(skb->data + ETH_ALEN,
-		       skb->data + skb->len - ETH_ALEN, ETH_ALEN);
-		skb_trim(skb, skb->len - ETH_ALEN);
-	}
-#endif
-
 	stats->rx_packets++;
 	stats->rx_bytes += skb->len;
 
@@ -754,7 +744,7 @@
 
 	if (skb2 != NULL) {
 		/* send to wireless media */
-		skb2->protocol = __constant_htons(ETH_P_802_3);
+		skb2->protocol = ieee80211_type_trans(skb2, ieee);
 		skb2->mac.raw = skb2->nh.raw = skb2->data;
 		/* skb2->nh.raw = skb2->data + ETH_HLEN; */
 		skb2->dev = dev;
@@ -764,7 +754,7 @@
 #endif
 
 	if (skb) {
-		skb->protocol = eth_type_trans(skb, dev);
+		skb->protocol = ieee80211_type_trans(skb, ieee);
 		memset(skb->cb, 0, sizeof(skb->cb));
 		skb->dev = dev;
 		skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
@@ -821,7 +811,7 @@
 	u8 i;
 
 	/* Pull out fixed field data */
-	memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
+	memcpy(network->bssid, beacon->header.addr3, IEEE80211_ALEN);
 	network->capability = beacon->capability;
 	network->last_scanned = jiffies;
 	network->time_stamp[0] = beacon->time_stamp[0];
@@ -849,7 +839,7 @@
 	while (left >= sizeof(struct ieee80211_info_element_hdr)) {
 		if (sizeof(struct ieee80211_info_element_hdr) + info_element->len > left) {
 			IEEE80211_DEBUG_SCAN("SCAN: parse failed: info_element->len + 2 > left : info_element->len+2=%d left=%d.\n",
-					     info_element->len + sizeof(struct ieee80211_info_element),
+					     info_element->len + (int)sizeof(struct ieee80211_info_element),
 					     left);
 			return 1;
                	}
@@ -1017,7 +1007,7 @@
 	 * as one network */
 	return ((src->ssid_len == dst->ssid_len) &&
 		(src->channel == dst->channel) &&
-		!memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
+		!memcmp(src->bssid, dst->bssid, IEEE80211_ALEN) &&
 		!memcmp(src->ssid, dst->ssid, src->ssid_len));
 }
 
--- a/net/ieee80211/ieee80211_module.c
+++ b/net/ieee80211/ieee80211_module.c
@@ -48,7 +48,6 @@
 #include <linux/types.h>
 #include <linux/version.h>
 #include <linux/wireless.h>
-#include <linux/etherdevice.h>
 #include <asm/uaccess.h>
 #include <net/arp.h>
 
@@ -99,28 +98,230 @@
 }
 
 
+static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
+{
+	if ((new_mtu < 68) || (new_mtu > IEEE80211_DATA_LEN - 8 - SNAP_SIZE))
+		return -EINVAL;
+	dev->mtu = new_mtu;
+	return 0;
+}
+
+
+static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
+static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
+
+static inline int __ieee80211_put_snap(u8 *data, u16 h_proto)
+{
+	struct ieee80211_snap_hdr *snap;
+	u8 *oui;
+
+	snap = (struct ieee80211_snap_hdr *)data;
+	snap->dsap = 0xaa;
+	snap->ssap = 0xaa;
+	snap->ctrl = 0x03;
+
+	if (h_proto == __constant_htons(ETH_P_IPX) ||
+			h_proto == __constant_htons(ETH_P_AARP))
+		oui = P802_1H_OUI;
+	else
+		oui = RFC1042_OUI;
+	snap->oui[0] = oui[0];
+	snap->oui[1] = oui[1];
+	snap->oui[2] = oui[2];
+
+	snap->type = h_proto;
+
+	return SNAP_SIZE;
+}
+
+static inline int ieee80211_put_snap(u8 *data, u16 h_proto)
+{
+	return __ieee80211_put_snap(data, htons(h_proto));
+}
+
+/*
+ *       Create the IEEE 802.11 MAC header for an arbitrary protocol layer
+ *
+ *      saddr=NULL      means use device source address
+ *      daddr=NULL      means leave destination address (eg unresolved arp)
+ */
+static int ieee80211_header(struct sk_buff *skb, struct net_device *dev,
+		unsigned short type, void *daddr, void *saddr, unsigned len)
+{
+	struct ieee80211_device *ieee = netdev_priv(dev);
+	struct ieee80211_hdr *header;
+	int fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
+	int hdr_len = IEEE80211_3ADDR_LEN;
+	
+	if (type != ETH_P_802_3 && type != ETH_P_802_2) {
+		ieee80211_put_snap(skb_push(skb, SNAP_SIZE), type);
+		hdr_len += SNAP_SIZE;
+	}
+
+	if (!saddr) saddr = dev->dev_addr;
+	header = (struct ieee80211_hdr *)skb_push(skb, IEEE80211_3ADDR_LEN);
+	header->duration_id = header->seq_ctl = 0;
+	if (ieee->iw_mode == IW_MODE_INFRA) {
+		fc |= IEEE80211_FCTL_TODS;
+		/* To DS: Addr1 = BSSID, Addr2 = SA,
+		   Addr3 = DA */
+		memcpy(header->addr1, ieee->bssid, IEEE80211_ALEN);
+		memcpy(header->addr2, saddr, IEEE80211_ALEN);
+		if (daddr)
+			memcpy(header->addr3, daddr, IEEE80211_ALEN);
+		else
+			memset(header->addr3, 0, IEEE80211_ALEN);
+	} else if (ieee->iw_mode == IW_MODE_ADHOC) {
+		/* not From/To DS: Addr1 = DA, Addr2 = SA,
+		   Addr3 = BSSID */
+		if (daddr)
+			memcpy(header->addr1, daddr, IEEE80211_ALEN);
+		else
+			memset(header->addr1, 0, IEEE80211_ALEN);
+		memcpy(header->addr2, saddr, IEEE80211_ALEN);
+		memcpy(header->addr3, ieee->bssid, IEEE80211_ALEN);
+	}
+	header->frame_ctl = cpu_to_le16(fc);
+
+	if (!daddr || (dev->flags & (IFF_LOOPBACK | IFF_NOARP)))
+		return -hdr_len;
+	return hdr_len;
+}
+
+static int ieee80211_rebuild_header(struct sk_buff *skb)
+{
+	struct ieee80211_hdr *header = (struct ieee80211_hdr *)skb->data;
+	struct net_device *dev = skb->dev;
+	unsigned short type;
+
+	type = ieee80211_get_proto(header);
+
+	switch (type) {
+#ifdef CONFIG_INET
+	case ETH_P_IP:
+		return arp_find(IEEE80211_GET_DADDR(header), skb);
+#endif
+	default:
+		printk(KERN_DEBUG
+			"%s: unable to resolve type %X addresses.\n",
+			dev->name, type);
+		break;
+	}
+	
+	return 0;
+}
+
+static int ieee80211_mac_addr(struct net_device *dev, void *p)
+{
+	struct sockaddr *addr = p;
+
+	if (netif_running(dev))
+		return -EBUSY;
+	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+	return 0;
+}
+
+static int ieee80211_header_cache(struct neighbour *neigh, struct hh_cache *hh)
+{
+	struct net_device *dev = neigh->dev;
+	struct ieee80211_device *ieee = netdev_priv(dev);
+	unsigned short type = hh->hh_type;
+	struct ieee80211_hdr *header;
+	int fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
+
+	if (type == __constant_htons(ETH_P_802_3) ||
+			type == __constant_htons(ETH_P_802_2))
+		return -1;
+
+	header = (struct ieee80211_hdr *)
+		(((u8 *)hh->hh_data) +
+			(HH_DATA_OFF(IEEE80211_3ADDR_LEN + SNAP_SIZE)));
+	__ieee80211_put_snap((u8 *)header + IEEE80211_3ADDR_LEN, type);
+	
+	header->duration_id = header->seq_ctl = 0;
+	if (ieee->iw_mode == IW_MODE_INFRA) {
+		fc |= IEEE80211_FCTL_TODS;
+		/* To DS: Addr1 = BSSID, Addr2 = SA,
+		   Addr3 = DA */
+		memcpy(header->addr1, ieee->bssid, IEEE80211_ALEN);
+		memcpy(header->addr2, dev->dev_addr, IEEE80211_ALEN);
+		memcpy(header->addr3, neigh->ha, IEEE80211_ALEN);
+	} else if (ieee->iw_mode == IW_MODE_ADHOC) {
+		/* not From/To DS: Addr1 = DA, Addr2 = SA,
+		   Addr3 = BSSID */
+		memcpy(header->addr1, neigh->ha, IEEE80211_ALEN);
+		memcpy(header->addr2, dev->dev_addr, IEEE80211_ALEN);
+		memcpy(header->addr3, ieee->bssid, IEEE80211_ALEN);
+	}
+	header->frame_ctl = cpu_to_le16(fc);
+
+	hh->hh_len = IEEE80211_3ADDR_LEN + SNAP_SIZE;
+	return 0;
+}
+
+static void ieee80211_header_cache_update(struct hh_cache *hh,
+		struct net_device *dev, unsigned char *haddr)
+{
+	struct ieee80211_hdr *header;
+
+	header = (struct ieee80211_hdr *)
+		(((u8 *)hh->hh_data) +
+			(HH_DATA_OFF(IEEE80211_3ADDR_LEN + SNAP_SIZE)));
+	memcpy(IEEE80211_GET_DADDR(header), haddr, dev->addr_len);
+}
+
+static int ieee80211_header_parse(struct sk_buff *skb, unsigned char *haddr)
+{
+	struct ieee80211_hdr *header = (struct ieee80211_hdr *)skb->data;
+
+	memcpy(haddr, IEEE80211_GET_SADDR(header), IEEE80211_ALEN);
+	return IEEE80211_ALEN;
+}
+
+
+void ieee80211_setup(struct net_device *dev)
+{
+	dev->change_mtu		 = ieee80211_change_mtu;
+	dev->hard_header	 = ieee80211_header;
+	dev->rebuild_header	 = ieee80211_rebuild_header;
+	dev->set_mac_address	 = ieee80211_mac_addr;
+	dev->hard_header_cache	 = ieee80211_header_cache;
+	dev->header_cache_update = ieee80211_header_cache_update;
+	dev->hard_header_parse	 = ieee80211_header_parse;
+
+	dev->hard_start_xmit     = ieee80211_xmit;
+
+	dev->type		 = ARPHRD_ETHER;
+	dev->hard_header_len	 = IEEE80211_3ADDR_LEN + SNAP_SIZE;
+	dev->mtu		 = IEEE80211_DATA_LEN - 8 - SNAP_SIZE;
+	dev->addr_len		 = IEEE80211_ALEN;
+	dev->tx_queue_len	 = 1000;
+	dev->flags		 = IFF_BROADCAST | IFF_MULTICAST;
+	
+	memset(dev->broadcast, 0xFF, IEEE80211_ALEN);
+}
+
+
 struct ieee80211_device *alloc_ieee80211(int sizeof_priv)
 {
 	struct ieee80211_device *ieee;
 	struct net_device *dev;
-	int alloc_size;
+ 	int alloc_size;
 	int err;
 
 	IEEE80211_DEBUG_INFO("Initializing...\n");
 
-	alloc_size = ((sizeof(struct ieee80211_device) + NETDEV_ALIGN_CONST) 
-			& ~NETDEV_ALIGN_CONST) 
-			+ sizeof_priv;
-	dev = alloc_etherdev(alloc_size);
+ 	alloc_size = ((sizeof(struct ieee80211_device) + NETDEV_ALIGN_CONST) 
+ 			& ~NETDEV_ALIGN_CONST) 
+ 			+ sizeof_priv;
+	dev = alloc_netdev(alloc_size, "wlan%d", ieee80211_setup);
 	if (!dev) {
-		IEEE80211_ERROR("Unable to network device.\n");
+		IEEE80211_ERROR("Unable to allocate network device.\n");
 		goto failed;
 	}
 	ieee = netdev_priv(dev);
 	ieee->dev = dev;
 	ieee->priv = ieee80211_priv(ieee);
-	
-	dev->hard_start_xmit = ieee80211_xmit;
 
 	err = ieee80211_networks_allocate(ieee);
 	if (err) {
@@ -201,7 +402,7 @@
 			     unsigned long count, void *data)
 {
 	char buf[] = "0x00000000";
-	unsigned long len = min(sizeof(buf) - 1, (u32)count);
+	unsigned long len = min((unsigned long)sizeof(buf) - 1, count);
 	char *p = (char *)buf;
 	unsigned long val;
 
@@ -268,4 +469,5 @@
 #endif
 
+EXPORT_SYMBOL(ieee80211_setup);
 EXPORT_SYMBOL(alloc_ieee80211);
 EXPORT_SYMBOL(free_ieee80211);
--- a/net/ieee80211/ieee80211_tx.c
+++ b/net/ieee80211/ieee80211_tx.c
@@ -84,16 +84,6 @@
 Total: 8 non-data bytes
 
 
-802.3 Ethernet Data Frame
-
-      ,-----------------------------------------.
-Bytes |   6   |   6   |  2   |  Variable |   4  |
-      |-------|-------|------|-----------|------|
-Desc. | Dest. | Source| Type | IP Packet |  fcs |
-      |  MAC  |  MAC  |      |           |      |
-      `-----------------------------------------'
-Total: 18 non-data bytes
-
 In the event that fragmentation is required, the incoming payload is split into
 N parts of size ieee->fts.  The first fragment contains the SNAP header and the
 remaining packets are just data.
@@ -104,56 +94,8 @@
 encryption it will take 3 frames.  With WEP it will take 4 frames as the
 payload of each frame is reduced to 492 bytes.
 
-* SKB visualization
-*
-*  ,- skb->data
-* |
-* |    ETHERNET HEADER        ,-<-- PAYLOAD
-* |                           |     14 bytes from skb->data
-* |  2 bytes for Type --> ,T. |     (sizeof ethhdr)
-* |                       | | |
-* |,-Dest.--. ,--Src.---. | | |
-* |  6 bytes| | 6 bytes | | | |
-* v         | |         | | | |
-* 0         | v       1 | v | v           2
-* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
-*     ^     | ^         | ^ |
-*     |     | |         | | |
-*     |     | |         | `T' <---- 2 bytes for Type
-*     |     | |         |
-*     |     | '---SNAP--' <-------- 6 bytes for SNAP
-*     |     |
-*     `-IV--' <-------------------- 4 bytes for IV (WEP)
-*
-*      SNAP HEADER
-*
 */
 
-static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
-static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
-
-static inline int ieee80211_put_snap(u8 *data, u16 h_proto)
-{
-	struct ieee80211_snap_hdr *snap;
-	u8 *oui;
-
-	snap = (struct ieee80211_snap_hdr *)data;
-	snap->dsap = 0xaa;
-	snap->ssap = 0xaa;
-	snap->ctrl = 0x03;
-
-	if (h_proto == 0x8137 || h_proto == 0x80f3)
-		oui = P802_1H_OUI;
-	else
-		oui = RFC1042_OUI;
-	snap->oui[0] = oui[0];
-	snap->oui[1] = oui[1];
-	snap->oui[2] = oui[2];
-
-	*(u16 *)(data + SNAP_SIZE) = htons(h_proto);
-
-	return SNAP_SIZE + sizeof(u16);
-}
 
 static inline int ieee80211_encrypt_fragment(
 	struct ieee80211_device *ieee,
@@ -248,19 +190,16 @@
 		   struct net_device *dev)
 {
 	struct ieee80211_device *ieee = netdev_priv(dev);
+	struct ieee80211_hdr *header = (struct ieee80211_hdr *)skb->data;
 	struct ieee80211_txb *txb = NULL;
 	struct ieee80211_hdr *frag_hdr;
 	int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
 	unsigned long flags;
 	struct net_device_stats *stats = &ieee->stats;
-	int ether_type, encrypt;
+	int type, encrypt;
 	int bytes, fc, hdr_len;
 	struct sk_buff *skb_frag;
-	struct ieee80211_hdr header = { /* Ensure zero initialized */
-		.duration_id = 0,
-		.seq_ctl = 0
-	};
-	u8 dest[ETH_ALEN], src[ETH_ALEN];
+	u8 *dest;
 
 	struct ieee80211_crypt_data* crypt;
 
@@ -269,76 +208,48 @@
 	/* If there is no driver handler to take the TXB, dont' bother
 	 * creating it... */
 	if (!ieee->hard_start_xmit) {
-		printk(KERN_WARNING "%s: No xmit handler.\n",
-		       dev->name);
+		if (printk_ratelimit())
+			printk(KERN_WARNING "%s: No xmit handler.\n",
+				dev->name);
 		goto success;
 	}
 
-	if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
-		printk(KERN_WARNING "%s: skb too small (%d).\n",
-		       dev->name, skb->len);
-		goto success;
-	}
-
-	ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
+	type = ieee80211_get_proto(header);
+	dest = IEEE80211_GET_DADDR(header);
+	hdr_len = ieee80211_get_hdrlen(header);
 
 	crypt = ieee->crypt[ieee->tx_keyidx];
 
-	encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
+	encrypt = !(type == ETH_P_PAE && ieee->ieee802_1x) &&
 		ieee->host_encrypt && crypt && crypt->ops;
 
 	if (!encrypt && ieee->ieee802_1x &&
-	    ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
+	    ieee->drop_unencrypted && type != ETH_P_PAE) {
 		stats->tx_dropped++;
 		goto success;
 	}
 
 #ifdef CONFIG_IEEE80211_DEBUG
-	if (crypt && !encrypt && ether_type == ETH_P_PAE) {
-		struct eapol *eap = (struct eapol *)(skb->data +
-			sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16));
+	if (crypt && !encrypt && type == ETH_P_PAE) {
+		struct eapol *eap = (struct eapol *)(skb->data + hdr_len);
 		IEEE80211_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n",
 			eap_get_type(eap->type));
 	}
 #endif
 
-	/* Save source and destination addresses */
-	memcpy(&dest, skb->data, ETH_ALEN);
-	memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
-
-	/* Advance the SKB to the start of the payload */
-	skb_pull(skb, sizeof(struct ethhdr));
-
 	/* Determine total amount of storage required for TXB packets */
-	bytes = skb->len + SNAP_SIZE + sizeof(u16);
+	bytes = skb->len - hdr_len;
 
+	fc = le16_to_cpu(header->frame_ctl);
 	if (encrypt)
-		fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
-			IEEE80211_FCTL_WEP;
-	else
-		fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
+		fc |= IEEE80211_FCTL_WEP;
 
-	if (ieee->iw_mode == IW_MODE_INFRA) {
-		fc |= IEEE80211_FCTL_TODS;
-		/* To DS: Addr1 = BSSID, Addr2 = SA,
-		   Addr3 = DA */
-		memcpy(&header.addr1, ieee->bssid, ETH_ALEN);
-		memcpy(&header.addr2, &src, ETH_ALEN);
-		memcpy(&header.addr3, &dest, ETH_ALEN);
-	} else if (ieee->iw_mode == IW_MODE_ADHOC) {
-		/* not From/To DS: Addr1 = DA, Addr2 = SA,
-		   Addr3 = BSSID */
-		memcpy(&header.addr1, dest, ETH_ALEN);
-		memcpy(&header.addr2, src, ETH_ALEN);
-		memcpy(&header.addr3, ieee->bssid, ETH_ALEN);
-	}
-	header.frame_ctl = cpu_to_le16(fc);
-	hdr_len = IEEE80211_3ADDR_LEN;
+	header->frame_ctl = cpu_to_le16(fc);
 
 	/* Determine fragmentation size based on destination (multicast
 	 * and broadcast are not fragmented) */
-	if (is_multicast_ether_addr(dest) ||
-	    is_broadcast_ether_addr(dest))
+	if (is_multicast_ieee80211_addr(dest) ||
+	    is_broadcast_ieee80211_addr(dest))
 		frag_size = MAX_FRAG_THRESHOLD;
 	else
 		frag_size = ieee->fts;
@@ -347,7 +258,7 @@
 	 * this stack is providing the full 802.11 header, one will
 	 * eventually be affixed to this fragment -- so we must account for
 	 * it when determining the amount of payload space. */
-	bytes_per_frag = frag_size - IEEE80211_3ADDR_LEN;
+	bytes_per_frag = frag_size - hdr_len;
 	if (ieee->config &
 	    (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
 		bytes_per_frag -= IEEE80211_FCS_LEN;
@@ -378,6 +289,8 @@
 	txb->encrypted = encrypt;
 	txb->payload_size = bytes;
 
+	skb_pull(skb, hdr_len);
+
 	for (i = 0; i < nr_frags; i++) {
 		skb_frag = txb->fragments[i];
 
@@ -385,7 +298,7 @@
 			skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
 
 		frag_hdr = (struct ieee80211_hdr *)skb_put(skb_frag, hdr_len);
-		memcpy(frag_hdr, &header, hdr_len);
+		memcpy(frag_hdr, header, hdr_len);
 
 		/* If this is not the last fragment, then add the MOREFRAGS
 		 * bit to the frame control */
@@ -398,14 +311,6 @@
 			bytes = bytes_last_frag;
 		}
 
-	       	/* Put a SNAP header on the first fragment */
-		if (i == 0) {
-			ieee80211_put_snap(
-				skb_put(skb_frag, SNAP_SIZE + sizeof(u16)),
-				ether_type);
-			bytes -= SNAP_SIZE + sizeof(u16);
-		}
-
 		memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
 
 		/* Advance the SKB... */
--- a/net/ieee80211/ieee80211_wx.c
+++ b/net/ieee80211/ieee80211_wx.c
@@ -53,7 +53,7 @@
 	/* First entry *MUST* be the AP MAC address */
 	iwe.cmd = SIOCGIWAP;
 	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
-	memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN);
+	memcpy(iwe.u.ap_addr.sa_data, network->bssid, IEEE80211_ALEN);
 	start = iwe_stream_add_event(start, stop, &iwe, IW_EV_ADDR_LEN);
 
 	/* Remaining entries will be displayed in the order we provide them */
--- a/net/ieee80211/ieee80211_crypt_ccmp.c
+++ b/net/ieee80211/ieee80211_crypt_ccmp.c
@@ -17,7 +17,6 @@
 #include <linux/random.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
-#include <linux/if_ether.h>
 #include <linux/if_arp.h>
 #include <asm/string.h>
 #include <linux/wireless.h>
@@ -156,7 +155,7 @@
 	 * Dlen */
 	b0[0] = 0x59;
 	b0[1] = qc;
-	memcpy(b0 + 2, hdr->addr2, ETH_ALEN);
+	memcpy(b0 + 2, hdr->addr2, IEEE80211_ALEN);
 	memcpy(b0 + 8, pn, CCMP_PN_LEN);
 	b0[14] = (dlen >> 8) & 0xff;
 	b0[15] = dlen & 0xff;
@@ -173,13 +172,13 @@
 	aad[1] = aad_len & 0xff;
 	aad[2] = pos[0] & 0x8f;
 	aad[3] = pos[1] & 0xc7;
-	memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN);
+	memcpy(aad + 4, hdr->addr1, 3 * IEEE80211_ALEN);
 	pos = (u8 *) &hdr->seq_ctl;
 	aad[22] = pos[0] & 0x0f;
 	aad[23] = 0; /* all bits masked */
 	memset(aad + 24, 0, 8);
 	if (a4_included)
-		memcpy(aad + 24, hdr->addr4, ETH_ALEN);
+		memcpy(aad + 24, hdr->addr4, IEEE80211_ALEN);
 	if (qc_included) {
 		aad[a4_included ? 30 : 24] = qc;
 		/* rest of QC masked */
--- a/net/ieee80211/ieee80211_crypt_tkip.c
+++ b/net/ieee80211/ieee80211_crypt_tkip.c
@@ -17,7 +17,6 @@
 #include <linux/random.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
-#include <linux/if_ether.h>
 #include <linux/if_arp.h>
 #include <asm/string.h>
 
@@ -461,20 +460,20 @@
 	switch (le16_to_cpu(hdr11->frame_ctl) &
 		(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
 	case IEEE80211_FCTL_TODS:
-		memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
-		memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
+		memcpy(hdr, hdr11->addr3, IEEE80211_ALEN); /* DA */
+		memcpy(hdr + IEEE80211_ALEN, hdr11->addr2, IEEE80211_ALEN); /* SA */
 		break;
 	case IEEE80211_FCTL_FROMDS:
-		memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
-		memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
+		memcpy(hdr, hdr11->addr1, IEEE80211_ALEN); /* DA */
+		memcpy(hdr + IEEE80211_ALEN, hdr11->addr3, IEEE80211_ALEN); /* SA */
 		break;
 	case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
-		memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
-		memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */
+		memcpy(hdr, hdr11->addr3, IEEE80211_ALEN); /* DA */
+		memcpy(hdr + IEEE80211_ALEN, hdr11->addr4, IEEE80211_ALEN); /* SA */
 		break;
 	case 0:
-		memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
-		memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
+		memcpy(hdr, hdr11->addr1, IEEE80211_ALEN); /* DA */
+		memcpy(hdr + IEEE80211_ALEN, hdr11->addr2, IEEE80211_ALEN); /* SA */
 		break;
 	}
 
@@ -521,7 +520,7 @@
 	else
 		ev.flags |= IW_MICFAILURE_PAIRWISE;
 	ev.src_addr.sa_family = ARPHRD_ETHER;
-	memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN);
+	memcpy(ev.src_addr.sa_data, hdr->addr2, IEEE80211_ALEN);
 	memset(&wrqu, 0, sizeof(wrqu));
 	wrqu.data.length = sizeof(ev);
 	wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *) &ev);


--
Jiri Benc
SUSE Labs

^ permalink raw reply

* [3/5] netdev: HH_DATA_OFF bugfix
From: Jiri Benc @ 2005-05-24 13:12 UTC (permalink / raw)
  To: NetDev; +Cc: LKML, jgarzik, pavel
In-Reply-To: <20050524150711.01632672@griffin.suse.cz>

When the hardware header size is a multiple of HH_DATA_MOD, HH_DATA_OFF()
incorrectly returns HH_DATA_MOD (instead of 0).

Signed-off-by: Jiri Benc <jbenc@suse.cz>

--- linux/include/linux/netdevice.h
+++ work/include/linux/netdevice.h
@@ -204,7 +209,7 @@
 	/* cached hardware header; allow for machine alignment needs.        */
 #define HH_DATA_MOD	16
 #define HH_DATA_OFF(__len) \
-	(HH_DATA_MOD - ((__len) & (HH_DATA_MOD - 1)))
+	(HH_DATA_MOD - (((__len - 1) & (HH_DATA_MOD - 1)) + 1))
 #define HH_DATA_ALIGN(__len) \
 	(((__len)+(HH_DATA_MOD-1))&~(HH_DATA_MOD - 1))
 	unsigned long	hh_data[HH_DATA_ALIGN(LL_MAX_HEADER) / sizeof(long)];


--
Jiri Benc
SUSE Labs

^ permalink raw reply

* [2/5] ieee80211: ieee80211_device alignment fix and cleanup
From: Jiri Benc @ 2005-05-24 13:11 UTC (permalink / raw)
  To: NetDev; +Cc: LKML, jgarzik, pavel
In-Reply-To: <20050524150711.01632672@griffin.suse.cz>

Changes to the ieee80211 layer:
- fixes a serious alignment problem of the driver's private data
- makes the drivers use the ieee80211_device instead of the net_device where
  appropriate (will ease further development of ieee80211 as a self-contained
  layer)


Signed-off-by: Jiri Benc <jbenc@suse.cz>
Signed-off-by: Jirka Bohac <jbohac@suse.cz>

--- linux-2.6.12-rc2-mm3.01/include/net/ieee80211.h	2005-05-18 10:49:01.000000000 +0200
+++ linux-2.6.12-rc2-mm3.02.0/include/net/ieee80211.h	2005-05-18 12:02:03.000000000 +0200
@@ -704,15 +704,13 @@
 	int abg_ture;   /* ABG flag              */
 
 	/* Callback functions */
-	void (*set_security)(struct net_device *dev,
+	void (*set_security)(struct ieee80211_device *ieee,
 			     struct ieee80211_security *sec);
 	int (*hard_start_xmit)(struct ieee80211_txb *txb,
-			       struct net_device *dev);
-	int (*reset_port)(struct net_device *dev);
+			       struct ieee80211_device *ieee);
+	int (*reset_port)(struct ieee80211_device *ieee);
 
-	/* This must be the last item so that it points to the data
-	 * allocated beyond this structure by alloc_ieee80211 */
-	u8 priv[0];
+	void *priv;
 };
 
 #define IEEE_A            (1<<0)
@@ -720,9 +718,18 @@
 #define IEEE_G            (1<<2)
 #define IEEE_MODE_MASK    (IEEE_A|IEEE_B|IEEE_G)
 
-extern inline void *ieee80211_priv(struct net_device *dev)
+static inline void *ieee80211_priv(struct ieee80211_device *ieee)
 {
-	return ((struct ieee80211_device *)netdev_priv(dev))->priv;
+	 return (char *)ieee + 
+	 	((sizeof(struct ieee80211_device) + NETDEV_ALIGN_CONST)
+			& ~NETDEV_ALIGN_CONST);
+}
+
+static inline struct net_device *ieee80211_dev(struct ieee80211_device *ieee)
+{
+	 return (struct net_device *)((char *)ieee - 
+	 	((sizeof(struct net_device) + NETDEV_ALIGN_CONST)
+			& ~NETDEV_ALIGN_CONST));
 }
 
 extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
@@ -795,8 +802,8 @@
 
 
 /* ieee80211.c */
-extern void free_ieee80211(struct net_device *dev);
-extern struct net_device *alloc_ieee80211(int sizeof_priv);
+extern void free_ieee80211(struct ieee80211_device *ieee);
+extern struct ieee80211_device *alloc_ieee80211(int sizeof_priv);
 
 extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
 
--- linux-2.6.12-rc2-mm3.01/net/ieee80211/ieee80211_module.c	2005-04-19 17:04:43.000000000 +0200
+++ linux-2.6.12-rc2-mm3.02.0/net/ieee80211/ieee80211_module.c	2005-05-18 12:04:30.000000000 +0200
@@ -70,7 +70,7 @@
 		GFP_KERNEL);
 	if (!ieee->networks) {
 		printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
-		       ieee->dev->name);
+		       ieee80211_dev(ieee)->name);
 		return -ENOMEM;
 	}
 
@@ -99,23 +99,28 @@
 }
 
 
-struct net_device *alloc_ieee80211(int sizeof_priv)
+struct ieee80211_device *alloc_ieee80211(int sizeof_priv)
 {
 	struct ieee80211_device *ieee;
 	struct net_device *dev;
+	int alloc_size;
 	int err;
 
 	IEEE80211_DEBUG_INFO("Initializing...\n");
 
-	dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv);
+	alloc_size = ((sizeof(struct ieee80211_device) + NETDEV_ALIGN_CONST) 
+			& ~NETDEV_ALIGN_CONST) 
+			+ sizeof_priv;
+	dev = alloc_etherdev(alloc_size);
 	if (!dev) {
 		IEEE80211_ERROR("Unable to network device.\n");
 		goto failed;
 	}
 	ieee = netdev_priv(dev);
-	dev->hard_start_xmit = ieee80211_xmit;
-
 	ieee->dev = dev;
+	ieee->priv = ieee80211_priv(ieee);
+	
+	dev->hard_start_xmit = ieee80211_xmit;
 
 	err = ieee80211_networks_allocate(ieee);
 	if (err) {
@@ -148,7 +153,7 @@
  	ieee->privacy_invoked = 0;
  	ieee->ieee802_1x = 1;
 
-	return dev;
+	return ieee;
 
  failed:
 	if (dev)
@@ -157,10 +162,8 @@
 }
 
 
-void free_ieee80211(struct net_device *dev)
+void free_ieee80211(struct ieee80211_device *ieee)
 {
-	struct ieee80211_device *ieee = netdev_priv(dev);
-
 	int i;
 
 	del_timer_sync(&ieee->crypt_deinit_timer);
@@ -179,7 +182,7 @@
 	}
 
 	ieee80211_networks_free(ieee);
-	free_netdev(dev);
+	free_netdev(ieee80211_dev(ieee));
 }
 
 #ifdef CONFIG_IEEE80211_DEBUG
--- linux-2.6.12-rc2-mm3.01/net/ieee80211/ieee80211_rx.c	2005-05-18 10:49:01.000000000 +0200
+++ linux-2.6.12-rc2-mm3.02.0/net/ieee80211/ieee80211_rx.c	2005-05-18 12:24:18.000000000 +0200
@@ -100,7 +100,7 @@
 
 	if (frag == 0) {
 		/* Reserve enough space to fit maximum frame length */
-		skb = dev_alloc_skb(ieee->dev->mtu +
+		skb = dev_alloc_skb(ieee80211_dev(ieee)->mtu +
 				    sizeof(struct ieee80211_hdr) +
 				    8 /* LLC */ +
 				    2 /* alignment */ +
@@ -176,7 +176,7 @@
 {
 	if (ieee->iw_mode == IW_MODE_MASTER) {
 		printk(KERN_DEBUG "%s: Master mode not yet suppported.\n",
-		       ieee->dev->name);
+		       ieee80211_dev(ieee)->name);
 		return 0;
 /*
   hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr *)
@@ -234,7 +234,7 @@
 static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
 				    struct sk_buff *skb)
 {
-	struct net_device *dev = ieee->dev;
+	struct net_device *dev = ieee80211_dev(ieee);
 	u16 fc, ethertype;
 	struct ieee80211_hdr *hdr;
 	u8 *pos;
@@ -290,7 +290,7 @@
 		if (net_ratelimit()) {
 			printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
 			       "received packet from " MAC_FMT "\n",
-			       ieee->dev->name, MAC_ARG(hdr->addr2));
+			       ieee80211_dev(dev)->name, MAC_ARG(hdr->addr2));
 		}
 		return -1;
 	}
@@ -335,7 +335,7 @@
 	if (res < 0) {
 		printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
 		       " (SA=" MAC_FMT " keyidx=%d)\n",
-		       ieee->dev->name, MAC_ARG(hdr->addr2), keyidx);
+		       ieee80211_dev(ieee)->name, MAC_ARG(hdr->addr2), keyidx);
 		return -1;
 	}
 
@@ -349,7 +349,7 @@
 int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 		 struct ieee80211_rx_stats *rx_stats)
 {
-	struct net_device *dev = ieee->dev;
+	struct net_device *dev = ieee80211_dev(ieee);
 	struct ieee80211_hdr *hdr;
 	size_t hdrlen;
 	u16 fc, type, stype, sc;
@@ -1195,7 +1195,7 @@
 		IEEE80211_DEBUG_MGMT("received UNKNOWN (%d)\n",
 				     WLAN_FC_GET_STYPE(header->frame_ctl));
 		IEEE80211_WARNING("%s: Unknown management packet: %d\n",
-				  ieee->dev->name,
+				  ieee80211_dev(ieee)->name,
 				  WLAN_FC_GET_STYPE(header->frame_ctl));
 		break;
 	}
--- linux-2.6.12-rc2-mm3.01/net/ieee80211/ieee80211_tx.c	2005-04-19 17:04:43.000000000 +0200
+++ linux-2.6.12-rc2-mm3.02.0/net/ieee80211/ieee80211_tx.c	2005-05-18 12:20:07.000000000 +0200
@@ -172,7 +172,7 @@
 		if (net_ratelimit()) {
 			printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
 			       "TX packet to " MAC_FMT "\n",
-			       ieee->dev->name, MAC_ARG(header->addr1));
+			       ieee80211_dev(ieee)->name, MAC_ARG(header->addr1));
 		}
 		return -1;
 	}
@@ -193,7 +193,7 @@
 	atomic_dec(&crypt->refcnt);
 	if (res < 0) {
 		printk(KERN_INFO "%s: Encryption failed: len=%d.\n",
-		       ieee->dev->name, frag->len);
+		       ieee80211_dev(ieee)->name, frag->len);
 		ieee->ieee_stats.tx_discards++;
 		return -1;
 	}
@@ -270,13 +270,13 @@
 	 * creating it... */
 	if (!ieee->hard_start_xmit) {
 		printk(KERN_WARNING "%s: No xmit handler.\n",
-		       ieee->dev->name);
+		       dev->name);
 		goto success;
 	}
 
 	if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
 		printk(KERN_WARNING "%s: skb too small (%d).\n",
-		       ieee->dev->name, skb->len);
+		       dev->name, skb->len);
 		goto success;
 	}
 
@@ -372,7 +372,7 @@
 	txb = ieee80211_alloc_txb(nr_frags, frag_size, GFP_ATOMIC);
 	if (unlikely(!txb)) {
 		printk(KERN_WARNING "%s: Could not allocate TXB\n",
-		       ieee->dev->name);
+		       dev->name);
 		goto failed;
 	}
 	txb->encrypted = encrypt;
@@ -427,7 +427,7 @@
 	dev_kfree_skb_any(skb);
 
 	if (txb) {
-		if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
+		if ((*ieee->hard_start_xmit)(txb, ieee) == 0) {
 			stats->tx_packets++;
 			stats->tx_bytes += txb->payload_size;
 			return 0;
--- linux-2.6.12-rc2-mm3.01/net/ieee80211/ieee80211_wx.c	2005-04-19 17:04:43.000000000 +0200
+++ linux-2.6.12-rc2-mm3.02.0/net/ieee80211/ieee80211_wx.c	2005-05-18 12:27:28.000000000 +0200
@@ -252,7 +252,7 @@
 			    union iwreq_data *wrqu, char *keybuf)
 {
 	struct iw_point *erq = &(wrqu->encoding);
-	struct net_device *dev = ieee->dev;
+	struct net_device *dev = ieee80211_dev(ieee);
 	struct ieee80211_security sec = {
 		.flags = 0
 	};
@@ -402,7 +402,7 @@
 	sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
 
 	if (ieee->set_security)
-		ieee->set_security(dev, &sec);
+		ieee->set_security(ieee, &sec);
 
 	/* Do not reset port if card is in Managed mode since resetting will
 	 * generate new IEEE 802.11 authentication which may end up in looping
@@ -411,7 +411,7 @@
 	 * the callbacks structures used to initialize the 802.11 stack. */
 	if (ieee->reset_on_keychange &&
 	    ieee->iw_mode != IW_MODE_INFRA &&
-	    ieee->reset_port && ieee->reset_port(dev)) {
+	    ieee->reset_port && ieee->reset_port(ieee)) {
 		printk(KERN_DEBUG "%s: reset_port failed\n", dev->name);
 		return -EINVAL;
 	}


--
Jiri Benc
SUSE Labs

^ permalink raw reply

* [1/5] ieee80211: cleanup
From: Jiri Benc @ 2005-05-24 13:10 UTC (permalink / raw)
  To: NetDev; +Cc: LKML, jgarzik, pavel
In-Reply-To: <20050524150711.01632672@griffin.suse.cz>

Cleanup of unused and duplicated constants and structures in the ieee80211
header.


Signed-off-by: Jiri Benc <jbenc@suse.cz>
Signed-off-by: Jirka Bohac <jbohac@suse.cz>

--- orig/include/net/ieee80211.h	2005-05-12 11:36:27.000000000 +0200
+++ new/include/net/ieee80211.h	2005-05-17 15:37:38.000000000 +0200
@@ -93,6 +93,8 @@
 	u16 length;
 } __attribute__ ((packed));
 
+#define IEEE80211_1ADDR_LEN 10
+#define IEEE80211_2ADDR_LEN 16
 #define IEEE80211_3ADDR_LEN 24
 #define IEEE80211_4ADDR_LEN 30
 #define IEEE80211_FCS_LEN    4
@@ -299,23 +301,6 @@
 #define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9
 
 
-/* Information Element IDs */
-#define WLAN_EID_SSID 0
-#define WLAN_EID_SUPP_RATES 1
-#define WLAN_EID_FH_PARAMS 2
-#define WLAN_EID_DS_PARAMS 3
-#define WLAN_EID_CF_PARAMS 4
-#define WLAN_EID_TIM 5
-#define WLAN_EID_IBSS_PARAMS 6
-#define WLAN_EID_CHALLENGE 16
-#define WLAN_EID_RSN 48
-#define WLAN_EID_GENERIC 221
-
-#define IEEE80211_MGMT_HDR_LEN 24
-#define IEEE80211_DATA_HDR3_LEN 24
-#define IEEE80211_DATA_HDR4_LEN 30
-
-
 #define IEEE80211_STATMASK_SIGNAL (1<<0)
 #define IEEE80211_STATMASK_RSSI (1<<1)
 #define IEEE80211_STATMASK_NOISE (1<<2)
@@ -489,15 +474,6 @@
 
 */
 
-struct ieee80211_header_data {
-	u16 frame_ctl;
-	u16 duration_id;
-	u8 addr1[6];
-	u8 addr2[6];
-	u8 addr3[6];
-	u16 seq_ctrl;
-};
-
 #define BEACON_PROBE_SSID_ID_POSITION 12
 
 /* Management Frame Information Element Types */
@@ -542,7 +518,7 @@
 */
 
 struct ieee80211_authentication {
-	struct ieee80211_header_data header;
+	struct ieee80211_hdr_3addr header;
 	u16 algorithm;
 	u16 transaction;
 	u16 status;
@@ -551,7 +527,7 @@
 
 
 struct ieee80211_probe_response {
-	struct ieee80211_header_data header;
+	struct ieee80211_hdr_3addr header;
 	u32 time_stamp[2];
 	u16 beacon_interval;
 	u16 capability;
@@ -793,21 +769,21 @@
 
 extern inline int ieee80211_get_hdrlen(u16 fc)
 {
-	int hdrlen = 24;
+	int hdrlen = IEEE80211_3ADDR_LEN;
 
 	switch (WLAN_FC_GET_TYPE(fc)) {
 	case IEEE80211_FTYPE_DATA:
 		if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
-			hdrlen = 30; /* Addr4 */
+			hdrlen = IEEE80211_4ADDR_LEN;
 		break;
 	case IEEE80211_FTYPE_CTL:
 		switch (WLAN_FC_GET_STYPE(fc)) {
 		case IEEE80211_STYPE_CTS:
 		case IEEE80211_STYPE_ACK:
-			hdrlen = 10;
+			hdrlen = IEEE80211_1ADDR_LEN;
 			break;
 		default:
-			hdrlen = 16;
+			hdrlen = IEEE80211_2ADDR_LEN;
 			break;
 		}
 		break;
--- orig/net/ieee80211/ieee80211_rx.c	2005-05-12 11:36:29.000000000 +0200
+++ new/net/ieee80211/ieee80211_rx.c	2005-05-17 15:37:38.000000000 +0200
@@ -475,7 +475,7 @@
 #endif
 
 	/* Data frame - extract src/dst addresses */
-	if (skb->len < IEEE80211_DATA_HDR3_LEN)
+	if (skb->len < IEEE80211_3ADDR_LEN)
 		goto rx_dropped;
 
 	switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
@@ -488,7 +488,7 @@
 		memcpy(src, hdr->addr2, ETH_ALEN);
 		break;
 	case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
-		if (skb->len < IEEE80211_DATA_HDR4_LEN)
+		if (skb->len < IEEE80211_4ADDR_LEN)
 			goto rx_dropped;
 		memcpy(dst, hdr->addr3, ETH_ALEN);
 		memcpy(src, hdr->addr4, ETH_ALEN);



--
Jiri Benc
SUSE Labs

^ permalink raw reply

* [0/5] Improvements to the ieee80211 layer
From: Jiri Benc @ 2005-05-24 13:07 UTC (permalink / raw)
  To: NetDev; +Cc: LKML, jgarzik, pavel

The ieee80211 layer, now present in -mm, lacks many important features
(actually it's just a part of the ipw2100/ipw2200 driver; these cards do
a lot of the processing in the hardware/firmware and thus the layer
currently can not be used for simpler devices).

This is the first series of patches that try to convert it to a generic
IEEE 802.11 layer, usable for most of today's wireless cards.

The long term plan is:
- to implement a complete 802.11 stack in the kernel, making it easy to
  write drivers for simple (cheap) devices
- to implement all of Ad-Hoc, AP and monitor modes in the layer, so it
  will be easy to support them in the drivers
- to integrate Wireless Extensions to unify the kernel-userspace
  interface of all the drivers

This means that drivers for "stupid" (simple, cheap) cards should be
very short and easy to write, whereas drivers for "clever" cards will be
longer (but still shorter than they are now).

We have a couple of cards for testing, and we gradually modify the
drivers for ipw2100 and ipw2200 with the development of the layer. When
the layer is mature enough for the "stupid" cards, we will rewrite the
driver for Atheros-based cards to use this layer. We plan to send all
the patches for these drivers to the netdev list. Of course, we are in
close contact with Pavel Machek, who is pushing the ipw2100 driver
upstream.

Any comments and suggestions are appreciated.


Jiri Benc <jbenc@suse.cz> and Jirka Bohac <jbohac@suse.cz>
SUSE Labs

^ permalink raw reply

* Re: [XFRM] Call dst_check() with appropriate cookie
From: Herbert Xu @ 2005-05-24 12:54 UTC (permalink / raw)
  To: YOSHIFUJI Hideaki / ?$B5HF#1QL@; +Cc: kazunori, davem, netdev
In-Reply-To: <20050524.174234.00553944.yoshfuji@linux-ipv6.org>

On Tue, May 24, 2005 at 05:42:34PM +0900, YOSHIFUJI Hideaki / ?$B5HF#1QL@ wrote:
>
> Probably, it should be better to introduce some upper limit of number of 
> recreation.

Yep, that's why a simple packet blackhole bug became a kernel hang.

In fact, we don't need to retry at all.  If the policy goes dead on us
or if the route becomes invalid after we passed the check in xfrm_lookup,
the packet is dropped anyway.  There is no point in retrying the lookup
here since that only covers the cases where we detect the problem before
the bundle is inserted into the list.

So we should simply return an error instead of retrying.

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* Re: [XFRM] Call dst_check() with appropriate cookie
From: Herbert Xu @ 2005-05-24 12:50 UTC (permalink / raw)
  To: Kazunori Miyazawa; +Cc: YOSHIFUJI Hideaki / ????, davem, netdev
In-Reply-To: <20050524083419.GA31586@gondor.apana.org.au>

On Tue, May 24, 2005 at 06:34:19PM +1000, herbert wrote:
> 
> Yes this makes perfect sense.  However, I'd still like to know why I
> have never seen it myself.  Let me double-check my test setup.

Aha, not all IPv6 dst entries have obsolete set to -1.  Obviously
your ones were and mine weren't :)
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* ieee80211.h and DSSS PHY type
From: Mateusz Berezecki @ 2005-05-24 12:38 UTC (permalink / raw)
  To: netdev

Hi list members,


I got a quick question regarding modulation type defines in ieee80211.h
in netdev tree ieee80211 branch from current netdev git tree.

Isn't the #define IEEE80211_DSSS_MODULATION missing in the include file?
or am I plain wrong?
Im asking because atheros driver im writing is using some constant value
which needs some name;)
And after evaluating some IEEE pdf's this appears to be a DSSS PHY type
and numeric constants do not
 look good in source code.


regards
/mb

^ permalink raw reply

* linux ipv6 multicast kernel implementation
From: Hannes Payer @ 2005-05-24 12:11 UTC (permalink / raw)
  To: netdev

Dear oss team,
last week i tryed to ask Alan Cox something about the data link layer
imlplementation in the linux kernel. He gave me your email address and 
therefore i forward you this email and hope, that you can help me.


forwarded message:
Dear Alan Cox,
we are trying to get ipv6 protocol independent multicast working on linux 
routers. We used the ipv6 multicast forwarding patch and the pim6sd daemon of 
Michael Hoerdt (http://clarinet.u-strasbg.fr/~hoerdt/linux_ipv6_mforwarding/, 
http://clarinet.u-strasbg.fr/~hoerdt/pim6sd_linux/). The ipv6 multicast kernel 
implementation is based on the existing ipv4 code and therefore we thought that 
you are the right contact person :-)
The ipv6 patch does not work well and we already found some bugs, we were able 
to correct.
We are not sure about one problem:
When the kernel receives a pim register packet, it decapsulates the packet and 
loops the multicast packet back on the register interface (netif_rx(skb) in 
pim6_rcv() pim6.c). Before the packet is looped back, the kernel sets skb->dst 
= NULL;
Therefore in ip6_input.c ip6_rcv_finish() looks up the unicast routing table 
and gets a matching entry. After that the kernel tries to forward the multicast 
packet, but stops at ip6_mr_forward() in ip6mr.c. The comparison 
vif6_table[vif].dev != skb->dev is true und therefore the packet is droped. 
(The lookup always returns dubios interfaces. It should return in our case the 
registry interface)
Our question: Why should we lookup the unicast routing table in this case? 
Would it satisfy to look up the multicast forwarding cache, where a correct 
entry exists - created by the pim6sd daemon? Would it be a problem if we 
override the lookup result with the regvif device after the lookup in this 
case?

I hope you understand the explanation of our problem.
Thank you for your answer.

Yours faithfully,
Hannes Payer

^ permalink raw reply

* Re: [XFRM] Call dst_check() with appropriate cookie
From: Herbert Xu @ 2005-05-24 11:59 UTC (permalink / raw)
  To: YOSHIFUJI Hideaki / ?$B5HF#1QL@; +Cc: davem, netdev, kazunori
In-Reply-To: <20050524.174931.46801018.yoshfuji@linux-ipv6.org>

On Tue, May 24, 2005 at 05:49:31PM +0900, YOSHIFUJI Hideaki / ?$B5HF#1QL@ wrote:
> 
> [XFRM] Call dst_check() with appropriate cookie
> 
> This fixes infinite loop issue with IPv6 tunnel mode.
> 
> Signed-off-by: Kazunori Miyazawa <kazunori@miyazawa.org>
> Signed-off-by: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>

Looks good.

Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* Re: [PATCH] : bug fix in multipath drr code.
From: pravin b shelar @ 2005-05-24  9:57 UTC (permalink / raw)
  To: Herbert Xu; +Cc: netdev, David S. Miller
In-Reply-To: <20050524071146.GA30995@gondor.apana.org.au>

[-- Attachment #1: Type: text/plain, Size: 379 bytes --]

Herbert Xu wrote:

>On Tue, May 24, 2005 at 12:16:38PM +0530, pravin b shelar wrote:
>  
>
>In fact this whole MULTIPATHOLDROUTE thing can't possibly
>work at all.  I'd suggest that it be removed.
>  
>
So I think we should ignore MULTIPATHOLDROUTE flag
in drr and rr multipath algorithms as done in random multipath algorithm.

Attached patch does same thing.

Regards,
Pravin.

[-- Attachment #2: multipath-drr_rr-last_use-fix.patch --]
[-- Type: text/x-patch, Size: 3512 bytes --]

Signed-off by: Pravin B. Shelar <pravins@calsoftinc.com>

Index: linux-2.6.12-rc4/include/net/route.h
===================================================================
--- linux-2.6.12-rc4.orig/include/net/route.h	2005-05-06 22:20:31.000000000 -0700
+++ linux-2.6.12-rc4/include/net/route.h	2005-05-24 02:37:10.000000000 -0700
@@ -181,9 +181,6 @@
 		memcpy(&fl, &(*rp)->fl, sizeof(fl));
 		fl.fl_ip_sport = sport;
 		fl.fl_ip_dport = dport;
-#if defined(CONFIG_IP_ROUTE_MULTIPATH_CACHED)
-		fl.flags |= FLOWI_FLAG_MULTIPATHOLDROUTE;
-#endif
 		ip_rt_put(*rp);
 		*rp = NULL;
 		return ip_route_output_flow(rp, &fl, sk, 0);
Index: linux-2.6.12-rc4/net/ipv4/multipath_drr.c
===================================================================
--- linux-2.6.12-rc4.orig/net/ipv4/multipath_drr.c	2005-05-06 22:20:31.000000000 -0700
+++ linux-2.6.12-rc4/net/ipv4/multipath_drr.c	2005-05-24 02:37:10.000000000 -0700
@@ -57,7 +57,6 @@
 
 static struct multipath_device state[MULTIPATH_MAX_DEVICECANDIDATES];
 static DEFINE_SPINLOCK(state_lock);
-static struct rtable *last_selection = NULL;
 
 static int inline __multipath_findslot(void)
 {
@@ -111,11 +110,6 @@
 	.notifier_call	= drr_dev_event,
 };
 
-static void drr_remove(struct rtable *rt)
-{
-	if (last_selection == rt)
-		last_selection = NULL;
-}
 
 static void drr_safe_inc(atomic_t *usecount)
 {
@@ -144,14 +138,6 @@
 	int devidx = -1;
 	int cur_min_devidx = -1;
 
-       	/* if necessary and possible utilize the old alternative */
-	if ((flp->flags & FLOWI_FLAG_MULTIPATHOLDROUTE) != 0 &&
-	    last_selection != NULL) {
-		result = last_selection;
-		*rp = result;
-		return;
-	}
-
 	/* 1. make sure all alt. nexthops have the same GC related data */
 	/* 2. determine the new candidate to be returned */
 	result = NULL;
@@ -229,12 +215,10 @@
 	}
 
 	*rp = result;
-	last_selection = result;
 }
 
 static struct ip_mp_alg_ops drr_ops = {
 	.mp_alg_select_route	=	drr_select_route,
-	.mp_alg_remove		=	drr_remove,
 };
 
 static int __init drr_init(void)
@@ -244,7 +228,7 @@
 	if (err)
 		return err;
 
-	err = multipath_alg_register(&drr_ops, IP_MP_ALG_RR);
+	err = multipath_alg_register(&drr_ops, IP_MP_ALG_DRR);
 	if (err)
 		goto fail;
 
Index: linux-2.6.12-rc4/net/ipv4/multipath_rr.c
===================================================================
--- linux-2.6.12-rc4.orig/net/ipv4/multipath_rr.c	2005-05-06 22:20:31.000000000 -0700
+++ linux-2.6.12-rc4/net/ipv4/multipath_rr.c	2005-05-24 02:37:10.000000000 -0700
@@ -47,29 +47,12 @@
 #include <net/checksum.h>
 #include <net/ip_mp_alg.h>
 
-#define MULTIPATH_MAX_CANDIDATES 40
-
-static struct rtable* last_used = NULL;
-
-static void rr_remove(struct rtable *rt)
-{
-	if (last_used == rt)
-		last_used = NULL;
-}
-
 static void rr_select_route(const struct flowi *flp,
 			    struct rtable *first, struct rtable **rp)
 {
 	struct rtable *nh, *result, *min_use_cand = NULL;
 	int min_use = -1;
 
-	/* if necessary and possible utilize the old alternative */
-	if ((flp->flags & FLOWI_FLAG_MULTIPATHOLDROUTE) != 0 &&
-	    last_used != NULL) {
-		result = last_used;
-		goto out;
-	}
-
 	/* 1. make sure all alt. nexthops have the same GC related data
 	 * 2. determine the new candidate to be returned
 	 */
@@ -90,15 +73,12 @@
 	if (!result)
 		result = first;
 
-out:
-	last_used = result;
 	result->u.dst.__use++;
 	*rp = result;
 }
 
 static struct ip_mp_alg_ops rr_ops = {
 	.mp_alg_select_route	=	rr_select_route,
-	.mp_alg_remove		=	rr_remove,
 };
 
 static int __init rr_init(void)

^ permalink raw reply

* (no subject)
From: root @ 2005-05-24  9:17 UTC (permalink / raw)


	by smtp.nexlab.net (Postfix) with ESMTP id CE413FA1F

	for <buffer@sniffo.org>; Tue, 24 May 2005 03:30:17 +0200 (CEST)

Received: from oss (localhost [127.0.0.1])

	by oss.sgi.com (8.12.10/8.12.10/SuSE Linux 0.7) with ESMTP id j4O1QmF3031979;

	Mon, 23 May 2005 18:26:48 -0700

Received: with ECARTIS (v1.0.0; list netdev); Mon, 23 May 2005 18:25:08 -0700 (PDT)

Received: from MMS2.broadcom.com (mms2.broadcom.com [216.31.210.18])

	by oss.sgi.com (8.12.10/8.12.10/SuSE Linux 0.7) with ESMTP id j4O1P4F3031331

	for <netdev@oss.sgi.com>; Mon, 23 May 2005 18:25:04 -0700

Received: from 10.10.64.121 by MMS2.broadcom.com with SMTP (Broadcom

 SMTP Relay (Email Firewall v6.1.0)); Mon, 23 May 2005 18:24:08 -0700

X-Server-Uuid: 1F20ACF3-9CAF-44F7-AB47-F294E2D5B4EA

Received: from mail-irva-8.broadcom.com ([10.10.64.221]) by

 mail-irva-1.broadcom.com (Post.Office MTA v3.5.3 release 223 ID#

 0-72233U7200L2200S0V35) with ESMTP id com; Mon, 23 May 2005 18:24:07

 -0700

Received: from mon-irva-10.broadcom.com (mon-irva-10.broadcom.com

 [10.10.64.171]) by mail-irva-8.broadcom.com (MOS 3.5.6-GR) with ESMTP

 id AZY37732; Mon, 23 May 2005 18:24:07 -0700 (PDT)

Received: from nt-irva-0741.brcm.ad.broadcom.com (

 nt-irva-0741.brcm.ad.broadcom.com [10.8.194.54]) by

 mon-irva-10.broadcom.com (8.9.1/8.9.1) with ESMTP id SAA16376; Mon, 23

 May 2005 18:24:06 -0700 (PDT)

Received: from 10.7.17.55 ([10.7.17.55]) by

 NT-IRVA-0741.brcm.ad.broadcom.com ([10.8.194.54]) with Microsoft

 Exchange Server HTTP-DAV ; Tue, 24 May 2005 01:24:06 +0000

Received: from rh4 by nt-irva-0741; 23 May 2005 17:26:23 -0700

Subject: [PATCH 2/6] bnx2: Fix rx checksum

From: "Michael Chan" <mchan@broadcom.com>
To: davem@davemloft.net
Cc: jgarzik@pobox.com, netdev@oss.sgi.com
In-Reply-To: <1116892439.4908.1.camel@rh4>

References: <1116892439.4908.1.camel@rh4>

Date: Mon, 23 May 2005 17:26:23 -0700

Message-ID: <1116894383.4908.29.camel@rh4>

MIME-Version: 1.0

X-Mailer: Evolution 2.0.2 (2.0.2-3)

X-WSS-ID: 6E8C5DB21VO1443376-01-01

Content-Type: multipart/mixed;

 boundary="=-MjP9kNbfLluHpwDwIMre"

X-archive-position: 1531

X-ecartis-version: Ecartis v1.0.0

Sender: netdev-bounce@oss.sgi.com
Errors-To: netdev-bounce@oss.sgi.com
X-original-sender: mchan@broadcom.com

Precedence: bulk

X-list: netdev

X-Virus-Scanned: ClamAV 0.83/892/Mon May 23 10:52:19 2005 on oss.sgi.com

X-Virus-Status: Clean




--=-MjP9kNbfLluHpwDwIMre
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

Fix bug in rx checksum by indicating CHECKSUM_UNNECESSARY only when the
hw calculated checksum is 0xffff.

Spotted by Jeff Garzik.

Signed-off-by: Michael Chan <mchan@broadcom.com>


--=-MjP9kNbfLluHpwDwIMre
Content-Disposition: attachment;
 filename=bnx2-12.patch
Content-Type: text/x-patch;
 charset=utf-8;
 name=bnx2-12.patch
Content-Transfer-Encoding: base64

ZGlmZiAtTnJ1IDExL2RyaXZlcnMvbmV0L2JueDIuYyAxMi9kcml2ZXJzL25ldC9ibngyLmMNCi0t
LSAxMS9kcml2ZXJzL25ldC9ibngyLmMJMjAwNS0wNS0yMyAxMDoyMDoyMC4wMDAwMDAwMDAgLTA3
MDANCisrKyAxMi9kcml2ZXJzL25ldC9ibngyLmMJMjAwNS0wNS0yMyAxMDoyOTowMi4wMDAwMDAw
MDAgLTA3MDANCkBAIC0xNDcwLDkgKzE0NzAsOCBAQA0KIA0KIAkJCXUxNiBja3N1bSA9IHJ4X2hk
ci0+bDJfZmhkcl90Y3BfdWRwX3hzdW07DQogDQotCQkJaWYgKChja3N1bSA9PSAweGZmZmYpIHx8
IChja3N1bSA9PSAwKSkgew0KKwkJCWlmIChja3N1bSA9PSAweGZmZmYpDQogCQkJCXNrYi0+aXBf
c3VtbWVkID0gQ0hFQ0tTVU1fVU5ORUNFU1NBUlk7DQotCQkJfQ0KIAkJfQ0KIA0KICNpZmRlZiBC
Q01fVkxBTg0K


--=-MjP9kNbfLluHpwDwIMre--

^ permalink raw reply

* (no subject)
From: root @ 2005-05-24  9:17 UTC (permalink / raw)


	by smtp.nexlab.net (Postfix) with ESMTP id 346A4FA13

	for <buffer@sniffo.org>; Tue, 24 May 2005 03:28:34 +0200 (CEST)

Received: from oss (localhost [127.0.0.1])

	by oss.sgi.com (8.12.10/8.12.10/SuSE Linux 0.7) with ESMTP id j4O1ScF3000570;

	Mon, 23 May 2005 18:28:39 -0700

Received: with ECARTIS (v1.0.0; list netdev); Mon, 23 May 2005 18:27:46 -0700 (PDT)

Received: from MMS2.broadcom.com (mms2.broadcom.com [216.31.210.18])

	by oss.sgi.com (8.12.10/8.12.10/SuSE Linux 0.7) with ESMTP id j4O1RhF3032603

	for <netdev@oss.sgi.com>; Mon, 23 May 2005 18:27:43 -0700

Received: from 10.10.64.121 by MMS2.broadcom.com with SMTP (Broadcom

 SMTP Relay (Email Firewall v6.1.0)); Mon, 23 May 2005 18:26:49 -0700

X-Server-Uuid: 1F20ACF3-9CAF-44F7-AB47-F294E2D5B4EA

Received: from mail-irva-8.broadcom.com ([10.10.64.221]) by

 mail-irva-1.broadcom.com (Post.Office MTA v3.5.3 release 223 ID#

 0-72233U7200L2200S0V35) with ESMTP id com; Mon, 23 May 2005 18:26:48

 -0700

Received: from mon-irva-10.broadcom.com (mon-irva-10.broadcom.com

 [10.10.64.171]) by mail-irva-8.broadcom.com (MOS 3.5.6-GR) with ESMTP

 id AZY38167; Mon, 23 May 2005 18:26:47 -0700 (PDT)

Received: from nt-irva-0741.brcm.ad.broadcom.com (

 nt-irva-0741.brcm.ad.broadcom.com [10.8.194.54]) by

 mon-irva-10.broadcom.com (8.9.1/8.9.1) with ESMTP id SAA16842; Mon, 23

 May 2005 18:26:47 -0700 (PDT)

Received: from 10.7.17.55 ([10.7.17.55]) by

 NT-IRVA-0741.brcm.ad.broadcom.com ([10.8.194.54]) with Microsoft

 Exchange Server HTTP-DAV ; Tue, 24 May 2005 01:26:47 +0000

Received: from rh4 by nt-irva-0741; 23 May 2005 17:29:03 -0700

Subject: [PATCH 4/6] bnx2: Fix bug in bnx2_close

From: "Michael Chan" <mchan@broadcom.com>
To: davem@davemloft.net
Cc: jgarzik@pobox.com, netdev@oss.sgi.com
In-Reply-To: <1116892439.4908.1.camel@rh4>

References: <1116892439.4908.1.camel@rh4>

Date: Mon, 23 May 2005 17:29:03 -0700

Message-ID: <1116894543.4908.32.camel@rh4>

MIME-Version: 1.0

X-Mailer: Evolution 2.0.2 (2.0.2-3)

X-WSS-ID: 6E8C5D531VO1443816-01-01

Content-Type: multipart/mixed;

 boundary="=-kVtupVzl5sY8iZGVxtrc"

X-archive-position: 1533

X-ecartis-version: Ecartis v1.0.0

Sender: netdev-bounce@oss.sgi.com
Errors-To: netdev-bounce@oss.sgi.com
X-original-sender: mchan@broadcom.com

Precedence: bulk

X-list: netdev

X-Virus-Scanned: ClamAV 0.83/892/Mon May 23 10:52:19 2005 on oss.sgi.com

X-Virus-Status: Clean




--=-kVtupVzl5sY8iZGVxtrc
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

Fix bug in bnx2_close() by calling flush_scheduled_work() since we are
using a work queue in netdev watchdog. Also added bnx2_netif_stop() call
in bnx2_close().

Spotted by Jeff Garzik.

Signed-off-by: Michael Chan <mchan@broadcom.com>


--=-kVtupVzl5sY8iZGVxtrc
Content-Disposition: attachment;
 filename=bnx2-14.patch
Content-Type: text/x-patch;
 charset=utf-8;
 name=bnx2-14.patch
Content-Transfer-Encoding: base64

ZGlmZiAtTnJ1IDEzL2RyaXZlcnMvbmV0L2JueDIuYyAxNC9kcml2ZXJzL25ldC9ibngyLmMNCi0t
LSAxMy9kcml2ZXJzL25ldC9ibngyLmMJMjAwNS0wNS0yMyAxMDo1Nzo0MS4wMDAwMDAwMDAgLTA3
MDANCisrKyAxNC9kcml2ZXJzL25ldC9ibngyLmMJMjAwNS0wNS0yMyAxMzowMTo0NS4wMDAwMDAw
MDAgLTA3MDANCkBAIC00MTcyLDcgKzQxNzIsOCBAQA0KIAlzdHJ1Y3QgYm54MiAqYnAgPSBkZXYt
PnByaXY7DQogCXUzMiByZXNldF9jb2RlOw0KIA0KLQlibngyX2Rpc2FibGVfaW50X3N5bmMoYnAp
Ow0KKwlmbHVzaF9zY2hlZHVsZWRfd29yaygpOw0KKwlibngyX25ldGlmX3N0b3AoYnApOw0KIAlk
ZWxfdGltZXJfc3luYygmYnAtPnRpbWVyKTsNCiAJaWYgKGJwLT53b2wpDQogCQlyZXNldF9jb2Rl
ID0gQk5YMl9EUlZfTVNHX0NPREVfU1VTUEVORF9XT0w7DQo=


--=-kVtupVzl5sY8iZGVxtrc--

^ permalink raw reply

* (no subject)
From: root @ 2005-05-24  9:16 UTC (permalink / raw)


	by smtp.nexlab.net (Postfix) with ESMTP id 8C315FB6B

	for <chiakotay@nexlab.it>; Tue, 24 May 2005 10:01:41 +0200 (CEST)

Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand

	id S261350AbVEXGeu (ORCPT <rfc822;chiakotay@nexlab.it>);

	Tue, 24 May 2005 02:34:50 -0400

Received: (majordomo@vger.kernel.org) by vger.kernel.org id S261334AbVEXGeu

	(ORCPT <rfc822;linux-kernel-outgoing>);

	Tue, 24 May 2005 02:34:50 -0400

Received: from mail.dvmed.net ([216.237.124.58]:8141 "EHLO mail.dvmed.net")

	by vger.kernel.org with ESMTP id S261353AbVEXGep (ORCPT

	<rfc822;linux-kernel@vger.kernel.org>);

	Tue, 24 May 2005 02:34:45 -0400

Received: from cpe-065-184-065-144.nc.res.rr.com ([65.184.65.144] helo=[10.10.10.88])

	by mail.dvmed.net with esmtpsa (Exim 4.51 #1 (Red Hat Linux))

	id 1DaT00-0001Ow-FO; Tue, 24 May 2005 06:34:44 +0000

Message-ID: <4292CB01.6090506@pobox.com>

Date:	Tue, 24 May 2005 02:34:41 -0400

From: Jeff Garzik <jgarzik@pobox.com>
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.6) Gecko/20050328 Fedora/1.7.6-1.2.5

X-Accept-Language: en-us, en

MIME-Version: 1.0

To: Linus Torvalds <torvalds@osdl.org>
Cc: Andrew Morton <akpm@osdl.org>, Netdev <netdev@oss.sgi.com>,
	Linux Kernel <linux-kernel@vger.kernel.org>
Subject: Re: [git patches] 2.6.x net driver updates

References: <4292BA66.8070806@pobox.com> <Pine.LNX.4.58.0505232253160.2307@ppc970.osdl.org>

In-Reply-To: <Pine.LNX.4.58.0505232253160.2307@ppc970.osdl.org>

Content-Type: text/plain; charset=us-ascii; format=flowed

Content-Transfer-Encoding: 7bit

X-Spam-Score: 0.0 (/)

Sender: linux-kernel-owner@vger.kernel.org
Precedence: bulk

X-Mailing-List:	linux-kernel@vger.kernel.org



Linus Torvalds wrote:
> I don't understand why you don't use different trees, like you did with
> BK. You can share the object directory with the different trees, but the

You really can't beat

	cp .git/refs/heads/master .git/refs/heads/new-branch

as the fastest way to create a new branch off the tip.

	Jeff



^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox