* Re: LC-trie FIB major rework
From: David S. Miller @ 2005-05-26 20:38 UTC (permalink / raw)
To: Robert.Olsson; +Cc: netdev
In-Reply-To: <17045.56331.653873.256686@robur.slu.se>
From: Robert Olsson <Robert.Olsson@data.slu.se>
Date: Thu, 26 May 2005 16:24:11 +0200
> Below much reworked version of the LC-trie for FIB lookup's. Much closer
> to current FIB anatomy and locking. Parent pointers in the trie to avoid
> own stacks etc. The option to merge tables has been removed and much things
> to keep things as simple and clean as possible. Although it's somewhat
> complex.
>
> Performance. We now perform about 25-30% better than current FIB in
> heavy lookup situations (we test with full rDoS) The test below illustrates
> this 123 kroutes in the routing table and rDoS is injected into eth0 at
> 720 kpps routed traffic on eth1/eth3. route hash is not used and both
> dst and src are looked up. LC-trie should work fine any size of routing table..
Very nice work Robert. Once TSO becomes less of a time sink I
intend to help you out a bit.
^ permalink raw reply
* Re: Fw: [Bugme-new] [Bug 4628] New: Test server hang while running rhr (network) test on RHEL4 with kernel 2.6.12-rc1-mm4
From: Andrew Morton @ 2005-05-26 20:31 UTC (permalink / raw)
To: Jian Jun He
Cc: ganesh.venkatesan, anton, rende, ganesh.venkatesan, herbert,
jesse.brandeburg, jgarzik, wangjs, john.ronciak, cdlwangl,
linuxppc64-dev, netdev
In-Reply-To: <OFA06E9B66.53E35770-ON4825700D.00585BAF-4825700D.00589E4E@cn.ibm.com>
Jian Jun He <hejianj@cn.ibm.com> wrote:
>
> 2. Download rhr2-rhel4-1.0-14a.noarch.rpm from rhn.redhat.com and install
> it on
> the test machine.
> 3. Configure and run the rhr test via invoking redhat-ready.
This is the problematic bit.
- Please provide a full URL which can be used to obtain rhr.
rhn.redhat.com is subscription-based.
- Please describe the hardware setup - surely the test requires at least
two machines. How are they configured?
- Provide an exact transcript of the commands which are to be used. Is
it just
redhat-ready
with no arguments?
All that begin said, we already have a quite specific diagnosis via code
inspection, from Herbert:
Herbert Xu <herbert@gondor.apana.org.au> wrote:
>
> Andrew Morton <akpm@osdl.org> wrote:
> >
> > Might be a bug in the e100 driver, might not be.
> >
> > I assume this is the
> >
> > BUG_ON(skb->list != NULL);
>
> It certainly is a bug in e100.
>
> e100_tx_timeout -> e100_down -> e100_rx_clean_list
>
> is racing against
>
> e100_poll -> e100_rx_clean -> e100_rx_indicate
>
> e100_rx_clean/e100_rx_indicate takes an skb off the RX ring and
> while it's being processed e100_rx_clean_list comes along and
> frees it.
>
> From a quick check similar problems may exist in other drivers that
> have lockless ->poll() functions with RX rings.
Do the e100 maintainers agree with this diagnosis? If so then more testing
isn't required at this stage - the next step is to fix the above bug, no?
^ permalink raw reply
* Re: user space checksum
From: Stephen Hemminger @ 2005-05-26 19:47 UTC (permalink / raw)
To: raz ben jehuda; +Cc: netdev
In-Reply-To: <1116744708.3021.12.camel@raz-laptop>
On Sun, 22 May 2005 09:51:48 +0300
raz ben jehuda <razb@bitband.com> wrote:
> I do not know if this was ever suggested.so i'll try any way.
> Why not give the user the chance to supply the kernel/card with the
> checksums instead of having the kernel/network card do the work ?
A bad idea for two reasons:
* application data units (APDU) do not match transport data units
for a stream oriented protocol.
* computing checksum is done for almost nothing as part
of the copy from user to kernel space. Modern CPU cache's
make computation cost << memory access cost.
> This is because a user is aware to the data he sends and he can optimize
> the data checksum calculations more than anyone else. for instance a web
> server sends its html pages, which are static data. it can pre-calculate
> the checksums.
Tcp will compute different transfer size's based on the congestion
window of the connection, and header part will be different.
^ permalink raw reply
* Re: [PATCH 2.6.12-rc5 9/9] tg3: Fix bug in tg3_load_firmware_cpu
From: Jeff Garzik @ 2005-05-26 19:13 UTC (permalink / raw)
To: Michael Chan; +Cc: davem, netdev
In-Reply-To: <1117130411.3744.61.camel@rh4>
Michael Chan wrote:
> Add tg3_nvram_lock() and tg3_nvram_unlock() calls around tg3_halt_cpu().
> It is possible that the bootcode may be loading code from nvram during
> this call and stopping the cpu without getting the lock may cause
> uncompleted nvram data to be left in the nvram data register. Subsequent
> calls to read/write nvram data will fail.
>
> Signed-off-by: Michael Chan <mchan@broadcom.com>
All the patches seem sane to me.
To touch a bit on patch order, I would suggest ordering bug fixes before
feature patches. Your patch #9 could have been better ordered as patch #1.
The patch order did not matter today, but sometime in the future, if an
add-a-feature patch is rejected or delayed, you would still likely want
DaveM to apply other bugfix patches.
Regards,
Jeff
^ permalink raw reply
* [NET] 2.6.x build warning
From: Jeff Garzik @ 2005-05-26 19:09 UTC (permalink / raw)
To: Netdev
from current git tree:
net/ipv6/ip6_flowlabel.c: In function `ipv6_flowlabel_opt':
net/ipv6/ip6_flowlabel.c:540: warning: ignoring return value of
`copy_to_user', declared with attribute warn_unused_result
^ permalink raw reply
* Re: [NEIGH] Remove unused fields in struct neigh_parms and neigh_table
From: Thomas Graf @ 2005-05-26 19:00 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev
In-Reply-To: <20050526185556.GA15391@postel.suug.ch>
* Thomas Graf <20050526185556.GA15391@postel.suug.ch> 2005-05-26 20:55
>
> Signed-off-by: Thomas Graf <tgraf@suug.ch>
>
> ---
> commit 45b866033b439e510f3638ce9ac0990446b8b3cd
> tree 72baef0bb9b97ac2990bcca05b8f831b30303008
> parent 3688d656f38445cc120b0970cd437cad1bb929dd
> author Thomas Graf <tgraf@suug.ch> Thu, 26 May 2005 20:42:10 +0200
> committer Thomas Graf <tgraf@suug.ch> Thu, 26 May 2005 20:42:10 +0200
This is patch 4 if it's not clear. I took the wrong patch and my script
couldn't find the parent sha1 and ommited the [PATCH 4/4]. Sorry.
^ permalink raw reply
* [NEIGH] Remove unused fields in struct neigh_parms and neigh_table
From: Thomas Graf @ 2005-05-26 18:55 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev
In-Reply-To: <20050526185306.GW15391@postel.suug.ch>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
---
commit 45b866033b439e510f3638ce9ac0990446b8b3cd
tree 72baef0bb9b97ac2990bcca05b8f831b30303008
parent 3688d656f38445cc120b0970cd437cad1bb929dd
author Thomas Graf <tgraf@suug.ch> Thu, 26 May 2005 20:42:10 +0200
committer Thomas Graf <tgraf@suug.ch> Thu, 26 May 2005 20:42:10 +0200
include/net/neighbour.h | 3 ---
1 files changed, 3 deletions(-)
Index: include/net/neighbour.h
===================================================================
--- 2fbcbf92bed82aaef81b2bcc9baecafd61dfb0ce/include/net/neighbour.h (mode:100644)
+++ 72baef0bb9b97ac2990bcca05b8f831b30303008/include/net/neighbour.h (mode:100644)
@@ -69,8 +69,6 @@
struct neigh_parms *next;
int (*neigh_setup)(struct neighbour *);
struct neigh_table *tbl;
- int entries;
- void *priv;
void *sysctl_table;
@@ -193,7 +191,6 @@
atomic_t entries;
rwlock_t lock;
unsigned long last_rand;
- struct neigh_parms *parms_list;
kmem_cache_t *kmem_cachep;
struct neigh_statistics *stats;
struct neighbour **hash_buckets;
^ permalink raw reply
* [PATCH 3/4] [NEIGH] neighbour table configuration and statistics via rtnetlink
From: Thomas Graf @ 2005-05-26 18:55 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev
In-Reply-To: <20050526185306.GW15391@postel.suug.ch>
To retrieve the neighbour tables send RTM_GETNEIGHTBL with the
NLM_F_DUMP flag set. Every neighbour table configuration is
spread over multiple messages to avoid running into message
size limits on systems with many interfaces. The first message
in the sequence transports all not device specific data such as
statistics, configuration, and the default parameter set.
This message is followed by 0..n messages carrying device
specific parameter sets. They all share the same value for
Although the ordering should be sufficient, NDTA_NAME can be
used to identify sequences. The initial message can be identified
by checking for NDTA_CONFIG. The device specific messages do
no contain this TLV but have NDTPA_IFINDEX set to the
corresponding interface index.
To change neighbour table attributes, send RTM_SETNEIGHTBL
with NDTA_NAME set. Changeable attribute include NDTA_THRESH[1-3],
NDTA_GC_INTERVAL, and all TLVs in NDTA_PARMS unless marked
otherwise. Device specific parameter sets can be changed by
setting NDTPA_IFINDEX to the interface index of the corresponding
device.
Signed-off-by: Thomas Graf <tgraf@suug.ch>
---
commit 6769b3b0603c632bda062e427178de8986900a52
tree 7e955d0e3c8fdef048336d0d7ba24a0539f28f9b
parent 98c3bc2e6320127cd96ef46d33f89ae127ce48fe
author Thomas Graf <tgraf@suug.ch> Wed, 25 May 2005 20:30:09 +0200
committer Thomas Graf <tgraf@suug.ch> Wed, 25 May 2005 20:30:09 +0200
include/linux/rtnetlink.h | 107 ++++++++++++++
include/net/neighbour.h | 4
net/core/neighbour.c | 317 +++++++++++++++++++++++++++++++++++++++++++-
net/core/rtnetlink.c | 20 +-
security/selinux/nlmsgtab.c | 2
5 files changed, 439 insertions(+), 11 deletions(-)
Index: include/linux/rtnetlink.h
===================================================================
--- 0ad944fa24c79b3eeaf06f85f5dd6d91ae1adbc9/include/linux/rtnetlink.h (mode:100644)
+++ 7e955d0e3c8fdef048336d0d7ba24a0539f28f9b/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)
};
@@ -493,6 +500,106 @@
__u32 ndm_refcnt;
};
+
+/*****************************************************************
+ * Neighbour tables specific messages.
+ *
+ * To retrieve the neighbour tables send RTM_GETNEIGHTBL with the
+ * NLM_F_DUMP flag set. Every neighbour table configuration is
+ * spread over multiple messages to avoid running into message
+ * size limits on systems with many interfaces. The first message
+ * in the sequence transports all not device specific data such as
+ * statistics, configuration, and the default parameter set.
+ * This message is followed by 0..n messages carrying device
+ * specific parameter sets. They all share the same value for
+ * Although the ordering should be sufficient, NDTA_NAME can be
+ * used to identify sequences. The initial message can be identified
+ * by checking for NDTA_CONFIG. The device specific messages do
+ * no contain this TLV but have NDTPA_IFINDEX set to the
+ * corresponding interface index.
+ *
+ * To change neighbour table attributes, send RTM_SETNEIGHTBL
+ * with NDTA_NAME set. Changeable attribute include NDTA_THRESH[1-3],
+ * NDTA_GC_INTERVAL, and all TLVs in NDTA_PARMS unless marked
+ * otherwise. Device specific parameter sets can be changed by
+ * setting NDTPA_IFINDEX to the interface index of the corresponding
+ * device.
+ ****/
+
+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, unchangeable */
+ NDTPA_REFCNT, /* u32, read-only */
+ NDTPA_REACHABLE_TIME, /* u64, read-only, msecs */
+ 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 *, unchangeable */
+ NDTA_THRESH1, /* u32 */
+ NDTA_THRESH2, /* u32 */
+ NDTA_THRESH3, /* u32 */
+ NDTA_CONFIG, /* struct ndt_config, read-only */
+ NDTA_PARMS, /* nested TLV NDTPA_* */
+ NDTA_STATS, /* struct ndt_stats, read-only */
+ NDTA_GC_INTERVAL, /* u64, msecs */
+ __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
===================================================================
--- 0ad944fa24c79b3eeaf06f85f5dd6d91ae1adbc9/include/net/neighbour.h (mode:100644)
+++ 7e955d0e3c8fdef048336d0d7ba24a0539f28f9b/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
===================================================================
--- 0ad944fa24c79b3eeaf06f85f5dd6d91ae1adbc9/net/core/neighbour.c (mode:100644)
+++ 7e955d0e3c8fdef048336d0d7ba24a0539f28f9b/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,308 @@
return err;
}
+static int neightbl_fill_parms(struct sk_buff *skb, struct neigh_parms *parms)
+{
+ struct rtattr *nest = 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);
+
+ return RTA_NEST_END(skb, nest);
+
+rtattr_failure:
+ return RTA_NEST_CANCEL(skb, nest);
+}
+
+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_PUT_ANSWER(skb, cb, RTM_NEWNEIGHTBL, sizeof(struct ndtmsg));
+ ndtmsg = NLMSG_DATA(nlh);
+
+ NLMSG_SET_MULTIPART(nlh);
+
+ read_lock_bh(&tbl->lock);
+ ndtmsg->ndtm_family = tbl->family;
+
+ RTA_PUT_STRING(skb, NDTA_NAME, tbl->id);
+ RTA_PUT_MSECS(skb, NDTA_GC_INTERVAL, tbl->gc_interval);
+ 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_PUT_ANSWER(skb, cb, RTM_NEWNEIGHTBL, sizeof(struct ndtmsg));
+ ndtmsg = NLMSG_DATA(nlh);
+
+ NLMSG_SET_MULTIPART(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_GC_INTERVAL - 1])
+ tbl->gc_interval = RTA_GET_MSECS(tb[NDTA_GC_INTERVAL - 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 +2661,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
===================================================================
--- 0ad944fa24c79b3eeaf06f85f5dd6d91ae1adbc9/net/core/rtnetlink.c (mode:100644)
+++ 7e955d0e3c8fdef048336d0d7ba24a0539f28f9b/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
===================================================================
--- 0ad944fa24c79b3eeaf06f85f5dd6d91ae1adbc9/security/selinux/nlmsgtab.c (mode:100644)
+++ 7e955d0e3c8fdef048336d0d7ba24a0539f28f9b/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
* [PATCH 2/4] [RTNETLINK] Routing attribute related shortcuts
From: Thomas Graf @ 2005-05-26 18:54 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev
In-Reply-To: <20050526185306.GW15391@postel.suug.ch>
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_NEST_END(skb, nesting_handle)
Finishes the nested TLV %nesting_handle, must be called
symmetric to RTA_NEST(). Returns skb->len
RTA_NEST_CANCEL(skb, nesting_handle)
Cancel the nested TLV %nesting_handle and trim nested TLV
from skb again, returns -1.
Signed-off-by: Thomas Graf <tgraf@suug.ch>
---
commit d24c37db15b6cd790459d9d91ee6331ce17264b4
tree 52e7990f6dee710624f823014c40c14e0e5ccf39
parent 88e04e26d887e806372014a2f7b33c6a7ea64741
author Thomas Graf <tgraf@suug.ch> Thu, 26 May 2005 18:22:23 +0200
committer Thomas Graf <tgraf@suug.ch> Thu, 26 May 2005 18:22:23 +0200
include/linux/rtnetlink.h | 45 +++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 45 insertions(+)
Index: include/linux/rtnetlink.h
===================================================================
--- 031c0e0d63096ca2dff2203940b90460f1db5c68/include/linux/rtnetlink.h (mode:100644)
+++ 52e7990f6dee710624f823014c40c14e0e5ccf39/include/linux/rtnetlink.h (mode:100644)
@@ -789,6 +789,51 @@
({ 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_NEST_END(skb, start) \
+({ (start)->rta_len = ((skb)->tail - (unsigned char *) (start)); \
+ (skb)->len; })
+
+#define RTA_NEST_CANCEL(skb, start) \
+({ skb_trim(skb, (unsigned char *) (start) - (skb)->data); \
+ -1; })
+
+#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)))
static inline struct rtattr *
__rta_reserve(struct sk_buff *skb, int attrtype, int attrlen)
^ permalink raw reply
* [PATCH 1/4] [NETLINK] New message building macros
From: Thomas Graf @ 2005-05-26 18:54 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev
In-Reply-To: <20050526185306.GW15391@postel.suug.ch>
NLMSG_PUT_ANSWER(skb, nlcb, type, length)
Start a new netlink message as answer to a request,
returns the 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 88e04e26d887e806372014a2f7b33c6a7ea64741
tree 031c0e0d63096ca2dff2203940b90460f1db5c68
parent d1faeaeb95a05275cf0c5b51b88f2fa833434625
author Thomas Graf <tgraf@suug.ch> Thu, 26 May 2005 18:21:36 +0200
committer Thomas Graf <tgraf@suug.ch> Thu, 26 May 2005 18:21:36 +0200
include/linux/netlink.h | 17 +++++++++++++++--
1 files changed, 15 insertions(+), 2 deletions(-)
Index: include/linux/netlink.h
===================================================================
--- c6f827347b3c6c28bc55a8eb1e62ea2659202cab/include/linux/netlink.h (mode:100644)
+++ 031c0e0d63096ca2dff2203940b90460f1db5c68/include/linux/netlink.h (mode:100644)
@@ -171,8 +171,21 @@
}
#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_PUT_ANSWER(skb, cb, type, len) \
+ NLMSG_PUT(skb, NETLINK_CB((cb)->skb).pid, \
+ (cb)->nlh->nlmsg_seq, type, len)
+
+#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; })
extern int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
struct nlmsghdr *nlh,
^ permalink raw reply
* [PATCHSET] neighbour tables access via rtnetlink
From: Thomas Graf @ 2005-05-26 18:53 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev
Dave,
This patchset adds neighbour table configuration and
statistics access via rtnetlink. Patches 1-2 add some
new macros to make netlink message construction simpler
and more readable, patch 3 adds the actual neighbour
table code and patch 4 removes a few unused fields
discovered while writing patch 3 ;->
include/linux/netlink.h | 17 ++
include/linux/rtnetlink.h | 45 ++++++
include/net/neighbour.h | 3
include/linux/rtnetlink.h | 107 ++++++++++++++
include/net/neighbour.h | 4
net/core/neighbour.c | 317 +++++++++++++++++++++++++++++++++++++++++++-
net/core/rtnetlink.c | 20 +-
security/selinux/nlmsgtab.c | 2
8 files changed, 499 insertions(+), 16 deletions(-)
^ permalink raw reply
* Re: RFC: PHY Abstraction Layer II
From: Andy Fleming @ 2005-05-26 18:45 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: Netdev, Embedded PPC Linux list
In-Reply-To: <20050526113218.23e44164@dxpl.pdx.osdl.net>
On May 26, 2005, at 13:32, Stephen Hemminger wrote:
> I finally got around to looking at this for the new skge driver.
> The Marvell phy code has several issues:
> * hard coded hex values rather than constants
These are hard-coded because it's errata. The errata doesn't name
the registers, nor the bits being set, so the best I could do is
something like:
phy_write(phydev, M88E1101_ERRATA_REGISTER1,
M88E1101_ERRATA_REG1_VALUE1);
I'm not sure that's more useful.
> * doesn't handle restricted autonegotiation
I'm not quite sure what you mean by this one. ALL the PHYs support
restricting auto-negotiation to certain values. See drivers/net/phy/
phy_device.c:genphy_config_advert(), which is called by marvell's
config_aneg function (eventually).
> * it doesn't really help the driver that much there are too
> many other warts in the hardware.
Err... the skge hardware, or the Marvell hardware? Could you
specify some warts, so I can look into what changes might need to be
made?
Andy
^ permalink raw reply
* Re: RFC: PHY Abstraction Layer II
From: Stephen Hemminger @ 2005-05-26 18:32 UTC (permalink / raw)
To: Andy Fleming; +Cc: Netdev, Embedded PPC Linux list
In-Reply-To: <1107b64b01fb8e9a6c84359bb56881a6@freescale.com>
I finally got around to looking at this for the new skge driver.
The Marvell phy code has several issues:
* hard coded hex values rather than constants
* doesn't handle restricted autonegotiation
* it doesn't really help the driver that much there are too
many other warts in the hardware.
^ permalink raw reply
* Re: primary and secondary ip addresses
From: Thomas Graf @ 2005-05-26 18:21 UTC (permalink / raw)
To: Harald Welte; +Cc: David Miller, Hasso Tepper, netdev
In-Reply-To: <20050526181118.GK13114@sunbeam.de.gnumonks.org>
* Harald Welte <20050526181118.GK13114@sunbeam.de.gnumonks.org> 2005-05-26 20:11
> David, would you consider applying that patch to mainline? I think
> there was concensus on this solution, and it has now received some
> amount of testing by Hasso and me.
I agree, I've been running this patch for 3 weeks now without
any problems. Two comments below.
> @@ -281,6 +289,13 @@
> if (!in_dev->ifa_list)
> inetdev_destroy(in_dev);
> }
> +
> + if (promote && IN_DEV_PROMOTE_SECONDARIES(in_dev)) {
promote can only be !=NULL if promotion is enabled, no?
> + /* not sure if we should send a delete notify first? */
> + promote->ifa_flags &= ~IFA_F_SECONDARY;
> + rtmsg_ifa(RTM_NEWADDR, promote);
This can be improved, however sending a delete/add seems
inappropriate. I've patch prepared to add a change mask
which will give us the proper methods to do this right
but for now this is just fine I guess.
^ permalink raw reply
* Re: primary and secondary ip addresses
From: Harald Welte @ 2005-05-26 18:11 UTC (permalink / raw)
To: David Miller; +Cc: Hasso Tepper, netdev
In-Reply-To: <200505081531.16106.hasso@estpak.ee>
[-- Attachment #1.1: Type: text/plain, Size: 1260 bytes --]
David, would you consider applying that patch to mainline? I think
there was concensus on this solution, and it has now received some
amount of testing by Hasso and me.
Thanks!
On Sun, May 08, 2005 at 03:31:15PM +0300, Hasso Tepper wrote:
> Harald Welte wrote:
> > On Mon, Dec 20, 2004 at 08:55:02AM -0500, jamal wrote:
> >
> > > Didnt boot ;->
> > > A small silly magic number i missed. Now boots - but doesnt mean it
> > > works. And i dont have much time to spare chasing it.
> >
> > Due to a customer having again trouble with this issue, I was forced to
> > actually spend some time testing it (and merging it to a current
> > kernel). At least in my simple tests, it worked like a charm :)
>
> I'm using it for some weeks in production and haven't noticed any issues
> either. Would be really good to see it kernel.
>
>
> regards,
>
> --
> Hasso Tepper
> Elion Enterprises Ltd.
> WAN administrator
>
--
- Harald Welte <laforge@gnumonks.org> http://gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
(ETSI EN 300 175-7 Ch. A6)
[-- Attachment #1.2: linux-2.6.12-rc2-promote_secondaries.patch --]
[-- Type: text/plain, Size: 3589 bytes --]
Signed-off-by: Harald Welte <laforge@gnumonks.org>
diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.12-rc2/include/linux/inetdevice.h linux-2.6.12-rc2-propag/include/linux/inetdevice.h
--- linux-2.6.12-rc2/include/linux/inetdevice.h 2005-03-02 08:38:13.000000000 +0100
+++ linux-2.6.12-rc2-propag/include/linux/inetdevice.h 2005-04-12 10:21:45.000000000 +0200
@@ -29,6 +29,7 @@
int no_xfrm;
int no_policy;
int force_igmp_version;
+ int promote_secondaries;
void *sysctl;
};
@@ -71,6 +72,7 @@
#define IN_DEV_SEC_REDIRECTS(in_dev) (ipv4_devconf.secure_redirects || (in_dev)->cnf.secure_redirects)
#define IN_DEV_IDTAG(in_dev) ((in_dev)->cnf.tag)
#define IN_DEV_MEDIUM_ID(in_dev) ((in_dev)->cnf.medium_id)
+#define IN_DEV_PROMOTE_SECONDARIES(in_dev) (ipv4_devconf.promote_secondaries || (in_dev)->cnf.promote_secondaries)
#define IN_DEV_RX_REDIRECTS(in_dev) \
((IN_DEV_FORWARD(in_dev) && \
diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.12-rc2/include/linux/sysctl.h linux-2.6.12-rc2-propag/include/linux/sysctl.h
--- linux-2.6.12-rc2/include/linux/sysctl.h 2005-04-09 12:59:20.000000000 +0200
+++ linux-2.6.12-rc2-propag/include/linux/sysctl.h 2005-04-12 10:18:38.000000000 +0200
@@ -399,6 +399,7 @@
NET_IPV4_CONF_FORCE_IGMP_VERSION=17,
NET_IPV4_CONF_ARP_ANNOUNCE=18,
NET_IPV4_CONF_ARP_IGNORE=19,
+ NET_IPV4_CONF_PROMOTE_SECONDARIES=20,
__NET_IPV4_CONF_MAX
};
diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.12-rc2/net/ipv4/devinet.c linux-2.6.12-rc2-propag/net/ipv4/devinet.c
--- linux-2.6.12-rc2/net/ipv4/devinet.c 2005-04-09 12:59:21.000000000 +0200
+++ linux-2.6.12-rc2-propag/net/ipv4/devinet.c 2005-04-12 10:19:53.000000000 +0200
@@ -233,11 +233,14 @@
static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
int destroy)
{
+ struct in_ifaddr *promote = NULL;
struct in_ifaddr *ifa1 = *ifap;
ASSERT_RTNL();
- /* 1. Deleting primary ifaddr forces deletion all secondaries */
+ /* 1. Deleting primary ifaddr forces deletion all secondaries
+ * unless alias promotion is set
+ **/
if (!(ifa1->ifa_flags & IFA_F_SECONDARY)) {
struct in_ifaddr *ifa;
@@ -251,11 +254,16 @@
continue;
}
- *ifap1 = ifa->ifa_next;
+ if (!IN_DEV_PROMOTE_SECONDARIES(in_dev)) {
+ *ifap1 = ifa->ifa_next;
- rtmsg_ifa(RTM_DELADDR, ifa);
- notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa);
- inet_free_ifa(ifa);
+ rtmsg_ifa(RTM_DELADDR, ifa);
+ notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa);
+ inet_free_ifa(ifa);
+ } else {
+ promote = ifa;
+ break;
+ }
}
}
@@ -281,6 +289,13 @@
if (!in_dev->ifa_list)
inetdev_destroy(in_dev);
}
+
+ if (promote && IN_DEV_PROMOTE_SECONDARIES(in_dev)) {
+ /* not sure if we should send a delete notify first? */
+ promote->ifa_flags &= ~IFA_F_SECONDARY;
+ rtmsg_ifa(RTM_NEWADDR, promote);
+ notifier_call_chain(&inetaddr_chain, NETDEV_UP, promote);
+ }
}
static int inet_insert_ifa(struct in_ifaddr *ifa)
@@ -1383,6 +1398,15 @@
.proc_handler = &ipv4_doint_and_flush,
.strategy = &ipv4_doint_and_flush_strategy,
},
+ {
+ .ctl_name = NET_IPV4_CONF_PROMOTE_SECONDARIES,
+ .procname = "promote_secondaries",
+ .data = &ipv4_devconf.promote_secondaries,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &ipv4_doint_and_flush,
+ .strategy = &ipv4_doint_and_flush_strategy,
+ },
},
.devinet_dev = {
{
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* [PATCH] (6/6) bridge: receive path optimization
From: Stephen Hemminger @ 2005-05-26 18:04 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, bridge
[-- Attachment #1: Type: text/plain, Size: 688 bytes --]
This improves the bridge local receive path by avoiding going
through another softirq. The bridge receive path is already being called
from a netif_receive_skb() there is no point in going through another
receiveq round trip.
Recursion is limited because bridge can never be a port of a bridge
so handle_bridge() always returns.
Index: bridge/net/bridge/br_input.c
===================================================================
--- bridge.orig/net/bridge/br_input.c
+++ bridge/net/bridge/br_input.c
@@ -26,7 +26,7 @@ static int br_pass_frame_up_finish(struc
#ifdef CONFIG_NETFILTER_DEBUG
skb->nf_debug = 0;
#endif
- netif_rx(skb);
+ netif_receive_skb(skb);
return 0;
}
[-- Attachment #2: Type: text/plain, Size: 140 bytes --]
_______________________________________________
Bridge mailing list
Bridge@lists.osdl.org
http://lists.osdl.org/mailman/listinfo/bridge
^ permalink raw reply
* [PATCH] (5/6) bridge: add way to flush forwarding table
From: Stephen Hemminger @ 2005-05-26 18:04 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, bridge
[-- Attachment #1: Type: text/plain, Size: 3285 bytes --]
Add a hook to allow flushing the bridge forwarding table for testing
or reconfiguration via:
echo > /sys/class/net/brX/bridge/flush
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Index: bridge/net/bridge/br_private.h
===================================================================
--- bridge.orig/net/bridge/br_private.h
+++ bridge/net/bridge/br_private.h
@@ -135,6 +135,7 @@ extern void br_fdb_fini(void);
extern void br_fdb_changeaddr(struct net_bridge_port *p,
const unsigned char *newaddr);
extern void br_fdb_cleanup(unsigned long arg);
+extern void br_fdb_flush(struct net_bridge *br);
extern void br_fdb_delete_by_port(struct net_bridge *br,
struct net_bridge_port *p);
extern struct net_bridge_fdb_entry *__br_fdb_get(struct net_bridge *br,
Index: bridge/net/bridge/br_fdb.c
===================================================================
--- bridge.orig/net/bridge/br_fdb.c
+++ bridge/net/bridge/br_fdb.c
@@ -106,26 +106,46 @@ void br_fdb_changeaddr(struct net_bridge
spin_unlock_bh(&br->hash_lock);
}
-void br_fdb_cleanup(unsigned long _data)
+static void fdb_flush(struct net_bridge *br, int all)
{
- struct net_bridge *br = (struct net_bridge *)_data;
- unsigned long delay = hold_time(br);
+ unsigned long hold = hold_time(br);
+ unsigned long interval = HZ/10;
int i;
- spin_lock_bh(&br->hash_lock);
for (i = 0; i < BR_HASH_SIZE; i++) {
struct net_bridge_fdb_entry *f;
struct hlist_node *h, *n;
hlist_for_each_entry_safe(f, h, n, &br->hash[i], hlist) {
- if (!f->is_static &&
- time_before_eq(f->ageing_timer + delay, jiffies))
+ unsigned long age = jiffies - f->ageing_timer;
+ if (f->is_static)
+ continue;
+
+ if (all || age >= hold)
fdb_delete(f);
+ else
+ interval = min(hold - age, interval);
+
}
}
+
+ mod_timer(&br->gc_timer, jiffies + interval);
+}
+
+void br_fdb_cleanup(unsigned long _data)
+{
+ struct net_bridge *br = (struct net_bridge *)_data;
+
+ spin_lock_bh(&br->hash_lock);
+ fdb_flush(br, 0);
spin_unlock_bh(&br->hash_lock);
+}
- mod_timer(&br->gc_timer, jiffies + HZ/10);
+void br_fdb_flush(struct net_bridge *br)
+{
+ spin_lock_bh(&br->hash_lock);
+ fdb_flush(br, 1);
+ spin_unlock_bh(&br->hash_lock);
}
void br_fdb_delete_by_port(struct net_bridge *br, struct net_bridge_port *p)
Index: bridge/net/bridge/br_sysfs_br.c
===================================================================
--- bridge.orig/net/bridge/br_sysfs_br.c
+++ bridge/net/bridge/br_sysfs_br.c
@@ -241,6 +241,20 @@ static ssize_t show_gc_timer(struct clas
}
static CLASS_DEVICE_ATTR(gc_timer, S_IRUGO, show_gc_timer, NULL);
+static ssize_t store_flush(struct class_device *cd,
+ const char *buf, size_t len)
+{
+ struct net_bridge *br = to_bridge(cd);
+
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+ br_fdb_flush(br);
+ return len;
+}
+static CLASS_DEVICE_ATTR(flush, S_IWUSR, NULL, store_flush);
+
+
static struct attribute *bridge_attrs[] = {
&class_device_attr_forward_delay.attr,
&class_device_attr_hello_time.attr,
@@ -258,6 +272,7 @@ static struct attribute *bridge_attrs[]
&class_device_attr_tcn_timer.attr,
&class_device_attr_topology_change_timer.attr,
&class_device_attr_gc_timer.attr,
+ &class_device_attr_flush.attr,
NULL
};
[-- Attachment #2: Type: text/plain, Size: 140 bytes --]
_______________________________________________
Bridge mailing list
Bridge@lists.osdl.org
http://lists.osdl.org/mailman/listinfo/bridge
^ permalink raw reply
* [PATCH] (4/6) bridge: prevent bad forwarding table updates
From: Stephen Hemminger @ 2005-05-26 18:04 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, bridge
[-- Attachment #1: Type: text/plain, Size: 1661 bytes --]
Avoid poisoning of the bridge forwarding table by frames that have been
dropped by filtering. This prevents spoofed source addresses on hostile
side of bridge from causing packet leakage, a small but possible security
risk.
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Index: bridge/net/bridge/br_input.c
===================================================================
--- bridge.orig/net/bridge/br_input.c
+++ bridge/net/bridge/br_input.c
@@ -54,6 +54,9 @@ int br_handle_frame_finish(struct sk_buf
struct net_bridge_fdb_entry *dst;
int passedup = 0;
+ /* insert into forwarding database after filtering to avoid spoofing */
+ br_fdb_update(p->br, p, eth_hdr(skb)->h_source);
+
if (br->dev->flags & IFF_PROMISC) {
struct sk_buff *skb2;
@@ -108,8 +111,7 @@ int br_handle_frame(struct net_bridge_po
if (!is_valid_ether_addr(eth_hdr(skb)->h_source))
goto err;
- if (p->state == BR_STATE_LEARNING ||
- p->state == BR_STATE_FORWARDING)
+ if (p->state == BR_STATE_LEARNING)
br_fdb_update(p->br, p, eth_hdr(skb)->h_source);
if (p->br->stp_enabled &&
Index: bridge/net/bridge/br_stp_bpdu.c
===================================================================
--- bridge.orig/net/bridge/br_stp_bpdu.c
+++ bridge/net/bridge/br_stp_bpdu.c
@@ -140,6 +140,9 @@ int br_stp_handle_bpdu(struct sk_buff *s
struct net_bridge *br = p->br;
unsigned char *buf;
+ /* insert into forwarding database after filtering to avoid spoofing */
+ br_fdb_update(p->br, p, eth_hdr(skb)->h_source);
+
/* need at least the 802 and STP headers */
if (!pskb_may_pull(skb, sizeof(header)+1) ||
memcmp(skb->data, header, sizeof(header)))
[-- Attachment #2: Type: text/plain, Size: 140 bytes --]
_______________________________________________
Bridge mailing list
Bridge@lists.osdl.org
http://lists.osdl.org/mailman/listinfo/bridge
^ permalink raw reply
* [PATCH] (3/6) bridge: set features based on enslaved devices
From: Stephen Hemminger @ 2005-05-26 18:04 UTC (permalink / raw)
To: David S. Miller, netdev, bridge
[-- Attachment #1: Type: text/plain, Size: 3623 bytes --]
Make features of the bridge pseudo-device be a subset of the underlying
devices. Motivated by Xen and others who use bridging to do failover.
Signed-off-by: Catalin BOIE <catab at umrella.ro>
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Index: bridge/net/bridge/br_private.h
===================================================================
--- bridge.orig/net/bridge/br_private.h
+++ bridge/net/bridge/br_private.h
@@ -174,6 +174,7 @@ extern int br_add_if(struct net_bridge *
extern int br_del_if(struct net_bridge *br,
struct net_device *dev);
extern int br_min_mtu(const struct net_bridge *br);
+extern void br_features_recompute(struct net_bridge *br);
/* br_input.c */
extern int br_handle_frame_finish(struct sk_buff *skb);
Index: bridge/net/bridge/br_notify.c
===================================================================
--- bridge.orig/net/bridge/br_notify.c
+++ bridge/net/bridge/br_notify.c
@@ -65,6 +65,15 @@ static int br_device_event(struct notifi
}
break;
+ case NETDEV_FEAT_CHANGE:
+ if (br->dev->flags & IFF_UP)
+ br_features_recompute(br);
+
+ /* could do recursive feature change notification
+ * but who would care??
+ */
+ break;
+
case NETDEV_DOWN:
if (br->dev->flags & IFF_UP)
br_stp_disable_port(p);
Index: bridge/net/bridge/br_device.c
===================================================================
--- bridge.orig/net/bridge/br_device.c
+++ bridge/net/bridge/br_device.c
@@ -21,10 +21,7 @@
static struct net_device_stats *br_dev_get_stats(struct net_device *dev)
{
- struct net_bridge *br;
-
- br = dev->priv;
-
+ struct net_bridge *br = netdev_priv(dev);
return &br->statistics;
}
@@ -54,9 +51,11 @@ int br_dev_xmit(struct sk_buff *skb, str
static int br_dev_open(struct net_device *dev)
{
- netif_start_queue(dev);
+ struct net_bridge *br = netdev_priv(dev);
- br_stp_enable_bridge(dev->priv);
+ br_features_recompute(br);
+ netif_start_queue(dev);
+ br_stp_enable_bridge(br);
return 0;
}
@@ -67,7 +66,7 @@ static void br_dev_set_multicast_list(st
static int br_dev_stop(struct net_device *dev)
{
- br_stp_disable_bridge(dev->priv);
+ br_stp_disable_bridge(netdev_priv(dev));
netif_stop_queue(dev);
@@ -76,7 +75,7 @@ static int br_dev_stop(struct net_device
static int br_change_mtu(struct net_device *dev, int new_mtu)
{
- if ((new_mtu < 68) || new_mtu > br_min_mtu(dev->priv))
+ if (new_mtu < 68 || new_mtu > br_min_mtu(netdev_priv(dev)))
return -EINVAL;
dev->mtu = new_mtu;
Index: bridge/net/bridge/br_if.c
===================================================================
--- bridge.orig/net/bridge/br_if.c
+++ bridge/net/bridge/br_if.c
@@ -314,6 +314,28 @@ int br_min_mtu(const struct net_bridge *
return mtu;
}
+/*
+ * Recomputes features using slave's features
+ */
+void br_features_recompute(struct net_bridge *br)
+{
+ struct net_bridge_port *p;
+ unsigned long features, checksum;
+
+ features = NETIF_F_SG | NETIF_F_FRAGLIST
+ | NETIF_F_HIGHDMA | NETIF_F_TSO;
+ checksum = NETIF_F_IP_CSUM; /* least commmon subset */
+
+ list_for_each_entry(p, &br->port_list, list) {
+ if (!(p->dev->features
+ & (NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM)))
+ checksum = 0;
+ features &= p->dev->features;
+ }
+
+ br->dev->features = features | checksum | NETIF_F_LLTX;
+}
+
/* called with RTNL */
int br_add_if(struct net_bridge *br, struct net_device *dev)
{
@@ -368,6 +390,7 @@ int br_del_if(struct net_bridge *br, str
spin_lock_bh(&br->lock);
br_stp_recalculate_bridge_id(br);
+ br_features_recompute(br);
spin_unlock_bh(&br->lock);
return 0;
[-- Attachment #2: Type: text/plain, Size: 140 bytes --]
_______________________________________________
Bridge mailing list
Bridge@lists.osdl.org
http://lists.osdl.org/mailman/listinfo/bridge
^ permalink raw reply
* [PATCH] (2/6) bridge: make dev->features unsigned
From: Stephen Hemminger @ 2005-05-26 18:04 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, bridge
[-- Attachment #1: Type: text/plain, Size: 1063 bytes --]
The features field in netdevice is really a bitmask, and bitmask's should
be unsigned.
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Index: bridge/net/core/ethtool.c
===================================================================
--- bridge.orig/net/core/ethtool.c
+++ bridge/net/core/ethtool.c
@@ -682,7 +682,7 @@ int dev_ethtool(struct ifreq *ifr)
void __user *useraddr = ifr->ifr_data;
u32 ethcmd;
int rc;
- int old_features;
+ unsigned long old_features;
/*
* XXX: This can be pushed down into the ethtool_* handlers that
Index: bridge/include/linux/netdevice.h
===================================================================
--- bridge.orig/include/linux/netdevice.h
+++ bridge/include/linux/netdevice.h
@@ -401,7 +401,7 @@ struct net_device
} reg_state;
/* Net device features */
- int features;
+ unsigned long features;
#define NETIF_F_SG 1 /* Scatter/gather IO. */
#define NETIF_F_IP_CSUM 2 /* Can checksum only TCP/UDP over IPv4. */
#define NETIF_F_NO_CSUM 4 /* Does not require checksum. F.e. loopack. */
[-- Attachment #2: Type: text/plain, Size: 140 bytes --]
_______________________________________________
Bridge mailing list
Bridge@lists.osdl.org
http://lists.osdl.org/mailman/listinfo/bridge
^ permalink raw reply
* [PATCH] (1/6) bridge: features change notification
From: Stephen Hemminger @ 2005-05-26 18:04 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, bridge
[-- Attachment #1: Type: text/plain, Size: 2832 bytes --]
Resend of earlier patch (no changes) from Catalin used to provide
device feature change notification.
Signed-off-by: Catalin BOIE <catab at umbrella.ro>
Acked-by: Stephen Hemminger <shemminger@osdl.org>
--- notify1/include/linux/notifier.h 2005-03-02 09:37:48.000000000 +0200
+++ linux/include/linux/notifier.h 2005-05-20 13:17:42.000000000 +0300
@@ -56,6 +56,7 @@ extern int notifier_call_chain(struct no
#define NETDEV_CHANGEADDR 0x0008
#define NETDEV_GOING_DOWN 0x0009
#define NETDEV_CHANGENAME 0x000A
+#define NETDEV_FEAT_CHANGE 0x000B
#define SYS_DOWN 0x0001 /* Notify of system down */
#define SYS_RESTART SYS_DOWN
--- notify1/net/core/ethtool.c 2005-03-02 09:38:37.000000000 +0200
+++ linux/net/core/ethtool.c 2005-05-23 11:30:47.000000000 +0300
@@ -682,6 +682,7 @@ int dev_ethtool(struct ifreq *ifr)
void __user *useraddr = ifr->ifr_data;
u32 ethcmd;
int rc;
+ int old_features;
/*
* XXX: This can be pushed down into the ethtool_* handlers that
@@ -703,6 +704,8 @@ int dev_ethtool(struct ifreq *ifr)
if ((rc = dev->ethtool_ops->begin(dev)) < 0)
return rc;
+ old_features = dev->features;
+
switch (ethcmd) {
case ETHTOOL_GSET:
rc = ethtool_get_settings(dev, useraddr);
@@ -712,7 +715,6 @@ int dev_ethtool(struct ifreq *ifr)
break;
case ETHTOOL_GDRVINFO:
rc = ethtool_get_drvinfo(dev, useraddr);
-
break;
case ETHTOOL_GREGS:
rc = ethtool_get_regs(dev, useraddr);
@@ -801,6 +803,10 @@ int dev_ethtool(struct ifreq *ifr)
if(dev->ethtool_ops->complete)
dev->ethtool_ops->complete(dev);
+
+ if (old_features != dev->features)
+ netdev_features_change(dev);
+
return rc;
ioctl:
--- notify1/net/core/dev.c 2005-03-26 05:28:21.000000000 +0200
+++ linux/net/core/dev.c 2005-05-23 12:14:32.000000000 +0300
@@ -761,6 +761,18 @@ int dev_change_name(struct net_device *d
}
/**
+ * netdev_features_change - device changes fatures
+ * @dev: device to cause notification
+ *
+ * Called to indicate a device has changed features.
+ */
+void netdev_features_change(struct net_device *dev)
+{
+ notifier_call_chain(&netdev_chain, NETDEV_FEAT_CHANGE, dev);
+}
+EXPORT_SYMBOL(netdev_features_change);
+
+/**
* netdev_state_change - device changes state
* @dev: device to cause notification
*
--- notify1/include/linux/netdevice.h 2005-03-02 09:38:26.000000000 +0200
+++ linux/include/linux/netdevice.h 2005-05-23 10:16:43.000000000 +0300
@@ -916,6 +916,7 @@ extern void dev_mc_discard(struct net_d
extern void dev_set_promiscuity(struct net_device *dev, int inc);
extern void dev_set_allmulti(struct net_device *dev, int inc);
extern void netdev_state_change(struct net_device *dev);
+extern void netdev_features_change(struct net_device *dev);
/* Load a device via the kmod */
extern void dev_load(const char *name);
extern void dev_mcast_init(void);
[-- Attachment #2: Type: text/plain, Size: 140 bytes --]
_______________________________________________
Bridge mailing list
Bridge@lists.osdl.org
http://lists.osdl.org/mailman/listinfo/bridge
^ permalink raw reply
* [PATCH 2.6.12-rc5 9/9] tg3: Fix bug in tg3_load_firmware_cpu
From: Michael Chan @ 2005-05-26 18:00 UTC (permalink / raw)
To: davem; +Cc: jgarzik, netdev
In-Reply-To: <1117128795.3744.22.camel@rh4>
[-- Attachment #1: Type: text/plain, Size: 375 bytes --]
Add tg3_nvram_lock() and tg3_nvram_unlock() calls around tg3_halt_cpu().
It is possible that the bootcode may be loading code from nvram during
this call and stopping the cpu without getting the lock may cause
uncompleted nvram data to be left in the nvram data register. Subsequent
calls to read/write nvram data will fail.
Signed-off-by: Michael Chan <mchan@broadcom.com>
[-- Attachment #2: tg3-d9.patch --]
[-- Type: text/x-patch, Size: 502 bytes --]
diff -Nru d8/drivers/net/tg3.c d9/drivers/net/tg3.c
--- d8/drivers/net/tg3.c 2005-05-25 12:59:46.000000000 -0700
+++ d9/drivers/net/tg3.c 2005-05-25 12:59:55.000000000 -0700
@@ -4370,7 +4370,12 @@
*/
tp->tg3_flags |= TG3_FLAG_PCIX_TARGET_HWBUG;
+ /* It is possible that bootcode is still loading at this point.
+ * Get the nvram lock first before halting the cpu.
+ */
+ tg3_nvram_lock(tp);
err = tg3_halt_cpu(tp, cpu_base);
+ tg3_nvram_unlock(tp);
if (err)
goto out;
^ permalink raw reply
* [PATCH 2.6.12-rc5 8/9] tg3: Add interrupt test
From: Michael Chan @ 2005-05-26 17:59 UTC (permalink / raw)
To: davem; +Cc: jgarzik, netdev
In-Reply-To: <1117128795.3744.22.camel@rh4>
[-- Attachment #1: Type: text/plain, Size: 128 bytes --]
This test uses the previously added tg3_test_interrupt() to perform the
test.
Signed-off-by: Michael Chan <mchan@broadcom.com>
[-- Attachment #2: tg3-d8.patch --]
[-- Type: text/x-patch, Size: 749 bytes --]
diff -Nru d7/drivers/net/tg3.c d8/drivers/net/tg3.c
--- d7/drivers/net/tg3.c 2005-05-25 12:59:38.000000000 -0700
+++ d8/drivers/net/tg3.c 2005-05-25 12:59:46.000000000 -0700
@@ -5894,6 +5894,9 @@
int err, i;
u32 int_mbox = 0;
+ if (!netif_running(dev))
+ return -ENODEV;
+
tg3_disable_ints(tp);
free_irq(tp->pdev->irq, dev);
@@ -7729,6 +7732,15 @@
data[4] = 1;
}
+ spin_unlock(&tp->tx_lock);
+ spin_unlock_irq(&tp->lock);
+ if (tg3_test_interrupt(tp) != 0) {
+ etest->flags |= ETH_TEST_FL_FAILED;
+ data[5] = 1;
+ }
+ spin_lock_irq(&tp->lock);
+ spin_lock(&tp->tx_lock);
+
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
if (netif_running(dev)) {
tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
^ permalink raw reply
* [PATCH 2.6.12-rc5 7/9] tg3: Add loopback test
From: Michael Chan @ 2005-05-26 17:59 UTC (permalink / raw)
To: davem; +Cc: jgarzik, netdev
In-Reply-To: <1117128795.3744.22.camel@rh4>
[-- Attachment #1: Type: text/plain, Size: 133 bytes --]
The test will loopback one packet in MAC loopback mode and verify the
packet data.
Signed-off-by: Michael Chan <mchan@broadcom.com>
[-- Attachment #2: tg3-d7.patch --]
[-- Type: text/x-patch, Size: 3431 bytes --]
diff -Nru d6/drivers/net/tg3.c d7/drivers/net/tg3.c
--- d6/drivers/net/tg3.c 2005-05-25 12:59:31.000000000 -0700
+++ d7/drivers/net/tg3.c 2005-05-25 12:59:38.000000000 -0700
@@ -7576,6 +7576,117 @@
return err;
}
+static int tg3_test_loopback(struct tg3 *tp)
+{
+ u32 mac_mode, send_idx, rx_start_idx, rx_idx, tx_idx, opaque_key;
+ u32 desc_idx;
+ struct sk_buff *skb, *rx_skb;
+ u8 *tx_data;
+ dma_addr_t map;
+ int num_pkts, tx_len, rx_len, i, err;
+ struct tg3_rx_buffer_desc *desc;
+
+ if (!netif_running(tp->dev))
+ return -ENODEV;
+
+ err = -EIO;
+
+ tg3_abort_hw(tp, 1);
+
+ /* Clearing this flag to keep interrupts disabled */
+ tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
+ tg3_reset_hw(tp);
+
+ mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) |
+ MAC_MODE_PORT_INT_LPBACK | MAC_MODE_LINK_POLARITY |
+ MAC_MODE_PORT_MODE_GMII;
+ tw32(MAC_MODE, mac_mode);
+
+ tx_len = 1514;
+ skb = dev_alloc_skb(tx_len);
+ tx_data = skb_put(skb, tx_len);
+ memcpy(tx_data, tp->dev->dev_addr, 6);
+ memset(tx_data + 6, 0x0, 8);
+
+ tw32(MAC_RX_MTU_SIZE, tx_len + 4);
+
+ for (i = 14; i < tx_len; i++)
+ tx_data[i] = (u8) (i & 0xff);
+
+ map = pci_map_single(tp->pdev, skb->data, tx_len, PCI_DMA_TODEVICE);
+
+ tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE |
+ HOSTCC_MODE_NOW);
+
+ udelay(10);
+
+ rx_start_idx = tp->hw_status->idx[0].rx_producer;
+
+ send_idx = 0;
+ num_pkts = 0;
+
+ tg3_set_txd(tp, send_idx, map, tx_len, 0, 1);
+
+ send_idx++;
+ num_pkts++;
+
+ tw32_tx_mbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW, send_idx);
+ tr32(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW);
+
+ udelay(10);
+
+ for (i = 0; i < 10; i++) {
+ tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE |
+ HOSTCC_MODE_NOW);
+
+ udelay(10);
+
+ tx_idx = tp->hw_status->idx[0].tx_consumer;
+ rx_idx = tp->hw_status->idx[0].rx_producer;
+ if ((tx_idx == send_idx) &&
+ (rx_idx == (rx_start_idx + num_pkts)))
+ break;
+ }
+
+ pci_unmap_single(tp->pdev, map, tx_len, PCI_DMA_TODEVICE);
+ dev_kfree_skb(skb);
+
+ if (tx_idx != send_idx)
+ goto out;
+
+ if (rx_idx != rx_start_idx + num_pkts)
+ goto out;
+
+ desc = &tp->rx_rcb[rx_start_idx];
+ desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK;
+ opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK;
+ if (opaque_key != RXD_OPAQUE_RING_STD)
+ goto out;
+
+ if ((desc->err_vlan & RXD_ERR_MASK) != 0 &&
+ (desc->err_vlan != RXD_ERR_ODD_NIBBLE_RCVD_MII))
+ goto out;
+
+ rx_len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT) - 4;
+ if (rx_len != tx_len)
+ goto out;
+
+ rx_skb = tp->rx_std_buffers[desc_idx].skb;
+
+ map = pci_unmap_addr(&tp->rx_std_buffers[desc_idx], mapping);
+ pci_dma_sync_single_for_cpu(tp->pdev, map, rx_len, PCI_DMA_FROMDEVICE);
+
+ for (i = 14; i < tx_len; i++) {
+ if (*(rx_skb->data + i) != (u8) (i & 0xff))
+ goto out;
+ }
+ err = 0;
+
+ /* tg3_free_rings will unmap and free the rx_skb */
+out:
+ return err;
+}
+
static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
u64 *data)
{
@@ -7613,6 +7724,10 @@
etest->flags |= ETH_TEST_FL_FAILED;
data[3] = 1;
}
+ if (tg3_test_loopback(tp) != 0) {
+ etest->flags |= ETH_TEST_FL_FAILED;
+ data[4] = 1;
+ }
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
if (netif_running(dev)) {
^ permalink raw reply
* [PATCH 2.6.12-rc5 6/9] tg3: Add memory test
From: Michael Chan @ 2005-05-26 17:58 UTC (permalink / raw)
To: davem; +Cc: jgarzik, netdev
In-Reply-To: <1117128795.3744.22.camel@rh4>
[-- Attachment #1: Type: text/plain, Size: 49 bytes --]
Signed-off-by: Michael Chan <mchan@broadcom.com>
[-- Attachment #2: tg3-d6.patch --]
[-- Type: text/x-patch, Size: 1865 bytes --]
diff -Nru d5/drivers/net/tg3.c d6/drivers/net/tg3.c
--- d5/drivers/net/tg3.c 2005-05-25 12:59:24.000000000 -0700
+++ d6/drivers/net/tg3.c 2005-05-25 12:59:31.000000000 -0700
@@ -7520,6 +7520,62 @@
return -EIO;
}
+static int tg3_do_mem_test(struct tg3 *tp, u32 offset, u32 len)
+{
+ static u32 test_pattern[] = { 0x00000000, 0xffffffff, 0xaa55a55a };
+ int i;
+ u32 j;
+
+ for (i = 0; i < sizeof(test_pattern)/sizeof(u32); i++) {
+ for (j = 0; j < len; j += 4) {
+ u32 val;
+
+ tg3_write_mem(tp, offset + j, test_pattern[i]);
+ tg3_read_mem(tp, offset + j, &val);
+ if (val != test_pattern[i])
+ return -EIO;
+ }
+ }
+ return 0;
+}
+
+static int tg3_test_memory(struct tg3 *tp)
+{
+ static struct mem_entry {
+ u32 offset;
+ u32 len;
+ } mem_tbl_570x[] = {
+ { 0x00000000, 0x01000},
+ { 0x00002000, 0x1c000},
+ { 0xffffffff, 0x00000}
+ }, mem_tbl_5705[] = {
+ { 0x00000100, 0x0000c},
+ { 0x00000200, 0x00008},
+ { 0x00000b50, 0x00400},
+ { 0x00004000, 0x00800},
+ { 0x00006000, 0x01000},
+ { 0x00008000, 0x02000},
+ { 0x00010000, 0x0e000},
+ { 0xffffffff, 0x00000}
+ };
+ struct mem_entry *mem_tbl;
+ int err = 0;
+ int i;
+
+ if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)
+ mem_tbl = mem_tbl_5705;
+ else
+ mem_tbl = mem_tbl_570x;
+
+ for (i = 0; mem_tbl[i].offset != 0xffffffff; i++) {
+ if ((err = tg3_do_mem_test(tp, mem_tbl[i].offset,
+ mem_tbl[i].len)) != 0)
+ break;
+ }
+
+ return err;
+}
+
static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
u64 *data)
{
@@ -7553,6 +7609,10 @@
etest->flags |= ETH_TEST_FL_FAILED;
data[2] = 1;
}
+ if (tg3_test_memory(tp) != 0) {
+ etest->flags |= ETH_TEST_FL_FAILED;
+ data[3] = 1;
+ }
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
if (netif_running(dev)) {
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox