* Re: [Patch][RFC] Disabling per-tgid stats on task exit in taskstats
From: Paul Jackson @ 2006-07-03 4:53 UTC (permalink / raw)
To: Shailabh Nagar
Cc: akpm, Valdis.Kletnieks, jlan, balbir, csturtiv, linux-kernel,
hadi, netdev
In-Reply-To: <44A5EDE6.3010605@watson.ibm.com>
Shailabh wrote:
> Sends a separate "registration" message with cpumask to listen to.
> Kernel stores (real) pid and cpumask.
Question:
=========
Ah - good.
So this means that I could configure a system with a fork/exit
intensive, performance critical job on some dedicated CPUs, and be able
to collect taskstat data from tasks exiting on the -other- CPUS, while
avoiding collecting data from this special job, thus avoiding any
taskstat collection performance impact on said job.
If I'm understanding this correctly, excellent.
Caveat:
=======
Passing cpumasks across the kernel-user boundary can be tricky.
Historically, Unix has a long tradition of boloxing up the passing
of variable length data types across the kernel-user boundary.
We've got perhaps a half dozen ways of getting these masks out of the
kernel, and three ways of getting them (or the similar nodemasks) back
into the kernel. The three ways being used in the sched_setaffinity
system call, the mbind and set_mempolicy system calls, and the cpuset
file system.
All three of these ways have their controversial details:
* The kernel cpumask mask size needed for sched_setaffinity calls is
not trivially available to userland.
* The nodemask bit size is off by one in the mbind and set_mempolicy
calls.
* The CPU and Node masks are ascii, not binary, in the cpuset calls.
One option that might make sense for these task stat registrations
would be to:
1) make the kernel/sched.c get_user_cpu_mask() routine generic,
moving it to non-static lib/*.c code, and
2) provide a sensible way for user space to query the size of
the kernel cpumask (and perhaps nodemask while you're at it.)
Currently, the best way I know for user space to query the kernels
cpumask and nodemask size is to examine the length of the ascii
string values labeled "Cpus_allowed:" and "Mems_allowed:" in the file
/proc/self/status. These ascii strings always require exactly nine
ascii chars to express each 32 bits of kernel mask code, if you include
in the count the trailing ',' comma or '\n' newline after each eight
ascii character word.
Probing /proc/self/status fields for these mask sizes is rather
unobvious and indirect, and requires caching the result if you care at
all about performance. Userland code in support of your taskstat
facility might be better served by a more obvious way to size cpumasks.
... unless of course you're inclined to pass cpumasks formatted as
ascii strings, in which case speak up, as I'd be delighted to
throw in my 2 cents on how to do that ;).
--
I won't rest till it's the best ...
Programmer, Linux Scalability
Paul Jackson <pj@sgi.com> 1.925.600.0401
^ permalink raw reply
* [PATCH] ipvs: Add sysctl documentation
From: Horms @ 2006-07-03 2:31 UTC (permalink / raw)
To: David Miller; +Cc: netdev, wensong, ja
In-Reply-To: <20060630.142045.106433722.davem@davemloft.net>
* Derived from http://www.linuxvirtualserver.org/docs/sysctl.html, v1.4
maintained by Wensong Zhang
* Adjusted preample to match ip-sysctl.txt
* Sorted options into alphabetical order
* Added expire_quiescent_template
* Removed timeout_* which are no longer present
* Incoporated doc/debug-levels.txt from IPVS source tree into
description of ipvs_debug
* Minor spelling fixes
* Further editing more than welcome
* DaveM, do you need a 2.4 version of this document,
it will likely be a slightly different list of options?
Signed-Off-By: Horms <horms@verge.net.au>
Documentation/networking/ipvs-sysctl.txt | 143 ++++++++++++++++++++++++++++++
1 file changed, 143 insertions(+)
--- /dev/null 2006-06-23 09:57:18.708345250 +0900
+++ b/Documentation/networking/ipvs-sysctl.txt 2006-07-03 11:20:33.000000000 +0900
@@ -0,0 +1,143 @@
+/proc/sys/net/ipv4/vs/* Variables:
+
+am_droprate - INTEGER
+ default 10
+
+ It sets the always mode drop rate, which is used in the mode 3
+ of the drop_rate defense.
+
+amemthresh - INTEGER
+ default 1024
+
+ It sets the available memory threshold (in pages), which is
+ used in the automatic modes of defense. When there is no
+ enough available memory, the respective strategy will be
+ enabled and the variable is automatically set to 2, otherwise
+ the strategy is disabled and the variable is set to 1.
+
+cache_bypass - BOOLEAN
+ 0 - disabled (default)
+ not 0 - enabled
+
+ If it is enabled, forward packets to the original destination
+ directly when no cache server is available and destination
+ address is not local (iph->daddr is RTN_UNICAST). It is mostly
+ used in transparent web cache cluster.
+
+debug_level - INTEGER
+ 0 - transmission error messages (default)
+ 1 - non-fatal error messages
+ 2 - configuration
+ 3 - destination trash
+ 4 - drop entry
+ 5 - service lookup
+ 6 - scheduling
+ 7 - connection new/expire, lookup and synchronization
+ 8 - state transition
+ 9 - binding destination, template checks and applications
+ 10 - IPVS packet transmission
+ 11 - IPVS packet handling (ip_vs_in/ip_vs_out)
+ 12 or more - packet traversal
+
+ Only available when IPVS is compiled with the CONFIG_IPVS_DEBUG
+
+ Higher debugging levels include the messages for lower debugging
+ levels, so setting debug level 2, includes level 0, 1 and 2
+ messages. Thus, logging becomes more and more verbose the higher
+ the level.
+
+drop_entry - INTEGER
+ 0 - disabled (default)
+
+ The drop_entry defense is to randomly drop entries in the
+ connection hash table, just in order to collect back some
+ memory for new connections. In the current code, the
+ drop_entry procedure can be activated every second, then it
+ randomly scans 1/32 of the whole and drops entries that are in
+ the SYN-RECV/SYNACK state, which should be effective against
+ syn-flooding attack.
+
+ The valid values of drop_entry are from 0 to 3, where 0 means
+ that this strategy is always disabled, 1 and 2 mean automatic
+ modes (when there is no enough available memory, the strategy
+ is enabled and the variable is automatically set to 2,
+ otherwise the strategy is disabled and the variable is set to
+ 1), and 3 means that that the strategy is always enabled.
+
+drop_packet - INTEGER
+ 0 - disabled (default)
+
+ The drop_packet defense is designed to drop 1/rate packets
+ before forwarding them to real servers. If the rate is 1, then
+ drop all the incoming packets.
+
+ The value definition is the same as that of the drop_entry. In
+ the automatic mode, the rate is determined by the follow
+ formula: rate = amemthresh / (amemthresh - available_memory)
+ when available memory is less than the available memory
+ threshold. When the mode 3 is set, the always mode drop rate
+ is controlled by the /proc/sys/net/ipv4/vs/am_droprate.
+
+expire_nodest_conn - BOOLEAN
+ 0 - disabled (default)
+ not 0 - enabled
+
+ The default value is 0, the load balancer will silently drop
+ packets when its destination server is not available. It may
+ be useful, when user-space monitoring program deletes the
+ destination server (because of server overload or wrong
+ detection) and add back the server later, and the connections
+ to the server can continue.
+
+ If this feature is enabled, the load balancer will expire the
+ connection immediately when a packet arrives and its
+ destination server is not available, then the client program
+ will be notified that the connection is closed. This is
+ equivalent to the feature some people requires to flush
+ connections when its destination is not available.
+
+expire_quiescent_template - BOOLEAN
+ 0 - disabled (default)
+ not 0 - enabled
+
+ When set to a non-zero value, the load balancer will expire
+ persistent templates when the destination server is quiescent.
+ This may be useful, when a user makes a destination server
+ quiescent by setting its weight to 0 and it is desired that
+ subsequent otherwise persistent connections are sent to a
+ different destination server. By default new persistent
+ connections are allowed to quiescent destination servers.
+
+ If this feature is enabled, the load balancer will expire the
+ persistence template if it is to be used to schedule a new
+ connection and the destination server is quiescent.
+
+nat_icmp_send - BOOLEAN
+ 0 - disabled (default)
+ not 0 - enabled
+
+ It controls sending icmp error messages (ICMP_DEST_UNREACH)
+ for VS/NAT when the load balancer receives packets from real
+ servers but the connection entries don't exist.
+
+secure_tcp - INTEGER
+ 0 - disabled (default)
+
+ The secure_tcp defense is to use a more complicated state
+ transition table and some possible short timeouts of each
+ state. In the VS/NAT, it delays the entering the ESTABLISHED
+ until the real server starts to send data and ACK packet
+ (after 3-way handshake).
+
+ The value definition is the same as that of drop_entry or
+ drop_packet.
+
+sync_threshold - INTEGER
+ default 3
+
+ It sets synchronization threshold, which is the minimum number
+ of incoming packets that a connection needs to receive before
+ the connection will be synchronized. A connection will be
+ synchronized, every time the number of its incoming packets
+ modulus 50 equals the threshold. The range of the threshold is
+ from 0 to 49.
^ permalink raw reply
* Re: [PATCH] ixgb: add PCI Error recovery callbacks
From: Zhang, Yanmin @ 2006-07-03 5:49 UTC (permalink / raw)
To: Linas Vepstas
Cc: Jesse Brandeburg, Ronciak, John, bibo,mao, Rajesh Shah,
Grant Grundler, akpm, LKML, linux-pci maillist, netdev
In-Reply-To: <20060629162634.GC5472@austin.ibm.com>
On Fri, 2006-06-30 at 00:26, Linas Vepstas wrote:
> Adds PCI Error recovery callbacks to the Intel 10-gigabit ethernet
> ixgb device driver. Lightly tested, works.
>
> Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
> +/**
> + * ixgb_io_error_detected() - called when PCI error is detected
> + * @pdev pointer to pci device with error
> + * @state pci channel state after error
> + *
> + * This callback is called by the PCI subsystem whenever
> + * a PCI bus error is detected.
> + */
> +static pci_ers_result_t ixgb_io_error_detected (struct pci_dev *pdev,
> + enum pci_channel_state state)
> +{
> + struct net_device *netdev = pci_get_drvdata(pdev);
> + struct ixgb_adapter *adapter = netdev->priv;
> +
> + if(netif_running(netdev))
> + ixgb_down(adapter, TRUE);
> +
> + pci_disable_device(pdev);
> +
> + /* Request a slot reset. */
> + return PCI_ERS_RESULT_NEED_RESET;
> +}
Both pci_disable_device and ixgb_down would access the device. It doesn't
follow Documentation/pci-error-recovery.txt that error_detected shouldn't do
any access to the device.
^ permalink raw reply
* [RFC NET 00/04]: Increase number of possible routing tables
From: Patrick McHardy @ 2006-07-03 7:52 UTC (permalink / raw)
To: davem; +Cc: netdev, greearb, Patrick McHardy
I took on Ben's challenge to increase the number of possible routing tables,
these are the resulting patches.
The table IDs are changed to 32 bit values and are contained in a new netlink
routing attribute. For compatibility rtm_table in struct rtmsg can still be
used to access the first 255 tables and contains the low 8 bit of the table
ID in case of dumps. Unfortunately there are no invalid values for rtm_table,
so the best userspace can do in case of a new iproute version that tries to
access tables > 255 on an old kernel is to use RTM_UNSPEC (0) for rtm_table,
which will make the kernel allocate an empty table instead of silently adding
routes to a more or less random table. The iproute patch will follow shortly.
The hash tables are statically sized since on-the-fly resizing would require
introducing locking in the packet processing path (currently we need none),
if this is a problem we could just directly attach table references to rules,
since tables are never deleted or freed this would be a simple change.
One spot is still missing (nl_fib_lookup), so these patches are purely a RFC
for now. Tested only with IPv4, I mainly converted DECNET as well to keep it
in sync and because iteration over all possible table values, as done in many
spots, has an unacceptable overhead with 32 bit values.
include/linux/rtnetlink.h | 11 +++
include/net/dn_fib.h | 7 +-
include/net/ip_fib.h | 39 ++++---------
net/decnet/dn_fib.c | 62 ++-------------------
net/decnet/dn_route.c | 1
net/decnet/dn_rules.c | 12 ++--
net/decnet/dn_table.c | 133 ++++++++++++++++++++++++++++++++--------------
net/ipv4/fib_frontend.c | 115 +++++++++++++++++++++++++--------------
net/ipv4/fib_hash.c | 30 +++++-----
net/ipv4/fib_lookup.h | 4 -
net/ipv4/fib_rules.c | 18 +++---
net/ipv4/fib_semantics.c | 5 +
net/ipv4/fib_trie.c | 32 +++++------
net/ipv4/route.c | 1
net/ipv6/route.c | 1
15 files changed, 255 insertions(+), 216 deletions(-)
Patrick McHardy:
[NET]: Use u32 for routing table IDs
[NET]: Introduce RTA_TABLE routing attribute
[IPV4]: Increase number of possible routing tables to 2^32
[DECNET]: Increase number of possible routing tables to 2^32
^ permalink raw reply
* [RFC NET 01/04]: Use u32 for routing table IDs
From: Patrick McHardy @ 2006-07-03 7:53 UTC (permalink / raw)
To: davem; +Cc: netdev, greearb, Patrick McHardy
In-Reply-To: <20060703075259.6286.67397.sendpatchset@localhost.localdomain>
[NET]: Use u32 for routing table IDs
Use u32 for routing table IDs in net/ipv4 and net/decnet in preparation of
support for a larger number of routing tables. No functional changes are
made by this patch.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
commit 7e3ac412e095b5a4d29a7244d5cee795267a7c6a
tree cfcec90b10614b7a1401459f2ea0abec4e189799
parent f82bc1762e0e74b7e0040a4d83be06d32c37fc2e
author Patrick McHardy <kaber@trash.net> Mon, 03 Jul 2006 07:43:07 +0200
committer Patrick McHardy <kaber@trash.net> Mon, 03 Jul 2006 07:43:07 +0200
include/net/dn_fib.h | 4 ++--
include/net/ip_fib.h | 14 +++++++-------
net/decnet/dn_fib.c | 6 +++---
net/decnet/dn_rules.c | 4 ++--
net/decnet/dn_table.c | 10 +++++-----
net/ipv4/fib_frontend.c | 8 ++++----
net/ipv4/fib_hash.c | 4 ++--
net/ipv4/fib_lookup.h | 4 ++--
net/ipv4/fib_rules.c | 8 ++++----
net/ipv4/fib_semantics.c | 4 ++--
net/ipv4/fib_trie.c | 6 +++---
11 files changed, 36 insertions(+), 36 deletions(-)
diff --git a/include/net/dn_fib.h b/include/net/dn_fib.h
index a15dcf0..9464f48 100644
--- a/include/net/dn_fib.h
+++ b/include/net/dn_fib.h
@@ -94,7 +94,7 @@ #define DN_FIB_INFO(f) ((f)->fn_info)
struct dn_fib_table {
- int n;
+ u32 n;
int (*insert)(struct dn_fib_table *t, struct rtmsg *r,
struct dn_kern_rta *rta, struct nlmsghdr *n,
@@ -137,7 +137,7 @@ extern int dn_fib_sync_up(struct net_dev
/*
* dn_tables.c
*/
-extern struct dn_fib_table *dn_fib_get_table(int n, int creat);
+extern struct dn_fib_table *dn_fib_get_table(u32 n, int creat);
extern struct dn_fib_table *dn_fib_empty_table(void);
extern void dn_fib_table_init(void);
extern void dn_fib_table_cleanup(void);
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index a095d1d..ddc3ced 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -149,7 +149,7 @@ #define FIB_RES_NETMASK(res) (0)
#endif /* CONFIG_IP_ROUTE_MULTIPATH_WRANDOM */
struct fib_table {
- unsigned char tb_id;
+ u32 tb_id;
unsigned tb_stamp;
int (*tb_lookup)(struct fib_table *tb, const struct flowi *flp, struct fib_result *res);
int (*tb_insert)(struct fib_table *table, struct rtmsg *r,
@@ -172,14 +172,14 @@ #ifndef CONFIG_IP_MULTIPLE_TABLES
extern struct fib_table *ip_fib_local_table;
extern struct fib_table *ip_fib_main_table;
-static inline struct fib_table *fib_get_table(int id)
+static inline struct fib_table *fib_get_table(u32 id)
{
if (id != RT_TABLE_LOCAL)
return ip_fib_main_table;
return ip_fib_local_table;
}
-static inline struct fib_table *fib_new_table(int id)
+static inline struct fib_table *fib_new_table(u32 id)
{
return fib_get_table(id);
}
@@ -204,10 +204,10 @@ #define ip_fib_main_table (fib_tables[RT
extern struct fib_table * fib_tables[RT_TABLE_MAX+1];
extern int fib_lookup(const struct flowi *flp, struct fib_result *res);
-extern struct fib_table *__fib_new_table(int id);
+extern struct fib_table *__fib_new_table(u32 id);
extern void fib_rule_put(struct fib_rule *r);
-static inline struct fib_table *fib_get_table(int id)
+static inline struct fib_table *fib_get_table(u32 id)
{
if (id == 0)
id = RT_TABLE_MAIN;
@@ -215,7 +215,7 @@ static inline struct fib_table *fib_get_
return fib_tables[id];
}
-static inline struct fib_table *fib_new_table(int id)
+static inline struct fib_table *fib_new_table(u32 id)
{
if (id == 0)
id = RT_TABLE_MAIN;
@@ -248,7 +248,7 @@ extern int fib_convert_rtentry(int cmd,
extern u32 __fib_res_prefsrc(struct fib_result *res);
/* Exported by fib_hash.c */
-extern struct fib_table *fib_hash_init(int id);
+extern struct fib_table *fib_hash_init(u32 id);
#ifdef CONFIG_IP_MULTIPLE_TABLES
/* Exported by fib_rules.c */
diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c
index 0375077..f4c1c1e 100644
--- a/net/decnet/dn_fib.c
+++ b/net/decnet/dn_fib.c
@@ -534,8 +534,8 @@ int dn_fib_rtm_newroute(struct sk_buff *
int dn_fib_dump(struct sk_buff *skb, struct netlink_callback *cb)
{
- int t;
- int s_t;
+ u32 t;
+ u32 s_t;
struct dn_fib_table *tb;
if (NLMSG_PAYLOAD(cb->nlh, 0) >= sizeof(struct rtmsg) &&
@@ -765,7 +765,7 @@ void dn_fib_flush(void)
{
int flushed = 0;
struct dn_fib_table *tb;
- int id;
+ u32 id;
for(id = RT_TABLE_MAX; id > 0; id--) {
if ((tb = dn_fib_get_table(id, 0)) == NULL)
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c
index 06e785f..16ca66b 100644
--- a/net/decnet/dn_rules.c
+++ b/net/decnet/dn_rules.c
@@ -43,7 +43,7 @@ struct dn_fib_rule
struct hlist_node r_hlist;
atomic_t r_clntref;
u32 r_preference;
- unsigned char r_table;
+ u32 r_table;
unsigned char r_action;
unsigned char r_dst_len;
unsigned char r_src_len;
@@ -130,7 +130,7 @@ int dn_fib_rtm_newrule(struct sk_buff *s
struct rtmsg *rtm = NLMSG_DATA(nlh);
struct dn_fib_rule *r, *new_r, *last = NULL;
struct hlist_node *node = NULL;
- unsigned char table_id;
+ u32 table_id;
if (rtm->rtm_src_len > 16 || rtm->rtm_dst_len > 16)
return -EINVAL;
diff --git a/net/decnet/dn_table.c b/net/decnet/dn_table.c
index 37d9d0a..7de6a88 100644
--- a/net/decnet/dn_table.c
+++ b/net/decnet/dn_table.c
@@ -268,7 +268,7 @@ static int dn_fib_nh_match(struct rtmsg
}
static int dn_fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
- u8 tb_id, u8 type, u8 scope, void *dst, int dst_len,
+ u32 tb_id, u8 type, u8 scope, void *dst, int dst_len,
struct dn_fib_info *fi, unsigned int flags)
{
struct rtmsg *rtm;
@@ -331,7 +331,7 @@ rtattr_failure:
}
-static void dn_rtmsg_fib(int event, struct dn_fib_node *f, int z, int tb_id,
+static void dn_rtmsg_fib(int event, struct dn_fib_node *f, int z, u32 tb_id,
struct nlmsghdr *nlh, struct netlink_skb_parms *req)
{
struct sk_buff *skb;
@@ -744,7 +744,7 @@ out:
}
-struct dn_fib_table *dn_fib_get_table(int n, int create)
+struct dn_fib_table *dn_fib_get_table(u32 n, int create)
{
struct dn_fib_table *t;
@@ -781,7 +781,7 @@ struct dn_fib_table *dn_fib_get_table(in
return t;
}
-static void dn_fib_del_tree(int n)
+static void dn_fib_del_tree(u32 n)
{
struct dn_fib_table *t;
@@ -795,7 +795,7 @@ static void dn_fib_del_tree(int n)
struct dn_fib_table *dn_fib_empty_table(void)
{
- int id;
+ u32 id;
for(id = RT_TABLE_MIN; id <= RT_TABLE_MAX; id++)
if (dn_fib_tables[id] == NULL)
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index ba2a707..4d5429a 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -61,7 +61,7 @@ #define RT_TABLE_MIN 1
struct fib_table *fib_tables[RT_TABLE_MAX+1];
-struct fib_table *__fib_new_table(int id)
+struct fib_table *__fib_new_table(u32 id)
{
struct fib_table *tb;
@@ -81,7 +81,7 @@ static void fib_flush(void)
int flushed = 0;
#ifdef CONFIG_IP_MULTIPLE_TABLES
struct fib_table *tb;
- int id;
+ u32 id;
for (id = RT_TABLE_MAX; id>0; id--) {
if ((tb = fib_get_table(id))==NULL)
@@ -332,8 +332,8 @@ int inet_rtm_newroute(struct sk_buff *sk
int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
{
- int t;
- int s_t;
+ u32 t;
+ u32 s_t;
struct fib_table *tb;
if (NLMSG_PAYLOAD(cb->nlh, 0) >= sizeof(struct rtmsg) &&
diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c
index 3c1d32a..4b79173 100644
--- a/net/ipv4/fib_hash.c
+++ b/net/ipv4/fib_hash.c
@@ -766,9 +766,9 @@ static int fn_hash_dump(struct fib_table
}
#ifdef CONFIG_IP_MULTIPLE_TABLES
-struct fib_table * fib_hash_init(int id)
+struct fib_table * fib_hash_init(u32 id)
#else
-struct fib_table * __init fib_hash_init(int id)
+struct fib_table * __init fib_hash_init(u32 id)
#endif
{
struct fib_table *tb;
diff --git a/net/ipv4/fib_lookup.h b/net/ipv4/fib_lookup.h
index ef6609e..ddd5249 100644
--- a/net/ipv4/fib_lookup.h
+++ b/net/ipv4/fib_lookup.h
@@ -30,11 +30,11 @@ extern struct fib_info *fib_create_info(
extern int fib_nh_match(struct rtmsg *r, struct nlmsghdr *,
struct kern_rta *rta, struct fib_info *fi);
extern int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
- u8 tb_id, u8 type, u8 scope, void *dst,
+ u32 tb_id, u8 type, u8 scope, void *dst,
int dst_len, u8 tos, struct fib_info *fi,
unsigned int);
extern void rtmsg_fib(int event, u32 key, struct fib_alias *fa,
- int z, int tb_id,
+ int z, u32 tb_id,
struct nlmsghdr *n, struct netlink_skb_parms *req);
extern struct fib_alias *fib_find_alias(struct list_head *fah,
u8 tos, u32 prio);
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index 6c642d1..71ede02 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -56,7 +56,7 @@ struct fib_rule
struct hlist_node hlist;
atomic_t r_clntref;
u32 r_preference;
- unsigned char r_table;
+ u32 r_table;
unsigned char r_action;
unsigned char r_dst_len;
unsigned char r_src_len;
@@ -145,7 +145,7 @@ #endif
static struct fib_table *fib_empty_table(void)
{
- int id;
+ u32 id;
for (id = 1; id <= RT_TABLE_MAX; id++)
if (fib_tables[id] == NULL)
@@ -177,7 +177,7 @@ int inet_rtm_newrule(struct sk_buff *skb
struct rtmsg *rtm = NLMSG_DATA(nlh);
struct fib_rule *r, *new_r, *last = NULL;
struct hlist_node *node = NULL;
- unsigned char table_id;
+ u32 table_id;
if (rtm->rtm_src_len > 32 || rtm->rtm_dst_len > 32 ||
(rtm->rtm_tos & ~IPTOS_TOS_MASK))
@@ -320,7 +320,7 @@ #endif
(r->r_ifindex && r->r_ifindex != flp->iif))
continue;
-FRprintk("tb %d r %d ", r->r_table, r->r_action);
+FRprintk("tb %u r %d ", r->r_table, r->r_action);
switch (r->r_action) {
case RTN_UNICAST:
policy = r;
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 5f87533..84537df 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -273,7 +273,7 @@ int ip_fib_check_default(u32 gw, struct
}
void rtmsg_fib(int event, u32 key, struct fib_alias *fa,
- int z, int tb_id,
+ int z, u32 tb_id,
struct nlmsghdr *n, struct netlink_skb_parms *req)
{
struct sk_buff *skb;
@@ -940,7 +940,7 @@ u32 __fib_res_prefsrc(struct fib_result
int
fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
- u8 tb_id, u8 type, u8 scope, void *dst, int dst_len, u8 tos,
+ u32 tb_id, u8 type, u8 scope, void *dst, int dst_len, u8 tos,
struct fib_info *fi, unsigned int flags)
{
struct rtmsg *rtm;
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 1cb6530..3936f16 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -1148,7 +1148,7 @@ fn_trie_insert(struct fib_table *tb, str
key = ntohl(key);
- pr_debug("Insert table=%d %08x/%d\n", tb->tb_id, key, plen);
+ pr_debug("Insert table=%u %08x/%d\n", tb->tb_id, key, plen);
mask = ntohl(inet_make_mask(plen));
@@ -1943,9 +1943,9 @@ out:
/* Fix more generic FIB names for init later */
#ifdef CONFIG_IP_MULTIPLE_TABLES
-struct fib_table * fib_hash_init(int id)
+struct fib_table * fib_hash_init(u32 id)
#else
-struct fib_table * __init fib_hash_init(int id)
+struct fib_table * __init fib_hash_init(u32 id)
#endif
{
struct fib_table *tb;
^ permalink raw reply related
* [RFC NET 02/04]: Introduce RTA_TABLE routing attribute
From: Patrick McHardy @ 2006-07-03 7:53 UTC (permalink / raw)
To: davem; +Cc: netdev, greearb, Patrick McHardy
In-Reply-To: <20060703075259.6286.67397.sendpatchset@localhost.localdomain>
[NET]: Introduce RTA_TABLE routing attribute
Introduce RTA_TABLE routing attribute to hold 32 bit routing table IDs.
Usespace compatibility is provided by continuing to accept and send the
rtm_table field, but because of its limited size it can only carry the
low 8 bits of the table ID. This implies that if larger IDs are used,
_all_ userspace programs using them need to use RTA_TABLE.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
commit 8cf1ae7345f935350dede855381dfbb620cabc1c
tree d674b6bb251dda0fcb915db0dbca98cda7779348
parent 7e3ac412e095b5a4d29a7244d5cee795267a7c6a
author Patrick McHardy <kaber@trash.net> Mon, 03 Jul 2006 08:13:14 +0200
committer Patrick McHardy <kaber@trash.net> Mon, 03 Jul 2006 08:13:14 +0200
include/linux/rtnetlink.h | 8 ++++++++
net/decnet/dn_fib.c | 7 ++++---
net/decnet/dn_route.c | 1 +
net/decnet/dn_rules.c | 6 ++++--
net/decnet/dn_table.c | 1 +
net/ipv4/fib_frontend.c | 7 ++++---
net/ipv4/fib_rules.c | 6 ++++--
net/ipv4/fib_semantics.c | 1 +
net/ipv4/route.c | 1 +
net/ipv6/route.c | 1 +
10 files changed, 29 insertions(+), 10 deletions(-)
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index facd9ee..8f6efff 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -263,6 +263,7 @@ enum rtattr_type_t
RTA_CACHEINFO,
RTA_SESSION,
RTA_MP_ALGO,
+ RTA_TABLE,
__RTA_MAX
};
@@ -1065,6 +1066,13 @@ #define BUG_TRAP(x) do { \
} \
} while(0)
+static inline u32 rtm_get_table(struct rtmsg *rtm, struct rtattr **rta)
+{
+ return RTA_GET_U32(rta[RTA_TABLE-1]);
+rtattr_failure:
+ return rtm->rtm_table;
+}
+
#endif /* __KERNEL__ */
diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c
index f4c1c1e..a43e59b 100644
--- a/net/decnet/dn_fib.c
+++ b/net/decnet/dn_fib.c
@@ -491,7 +491,8 @@ static int dn_fib_check_attr(struct rtms
if (attr) {
if (RTA_PAYLOAD(attr) < 4 && RTA_PAYLOAD(attr) != 2)
return -EINVAL;
- if (i != RTA_MULTIPATH && i != RTA_METRICS)
+ if (i != RTA_MULTIPATH && i != RTA_METRICS &&
+ i != RTA_TABLE)
rta[i-1] = (struct rtattr *)RTA_DATA(attr);
}
}
@@ -508,7 +509,7 @@ int dn_fib_rtm_delroute(struct sk_buff *
if (dn_fib_check_attr(r, rta))
return -EINVAL;
- tb = dn_fib_get_table(r->rtm_table, 0);
+ tb = dn_fib_get_table(rtm_get_table(r, rta), 0);
if (tb)
return tb->delete(tb, r, (struct dn_kern_rta *)rta, nlh, &NETLINK_CB(skb));
@@ -524,7 +525,7 @@ int dn_fib_rtm_newroute(struct sk_buff *
if (dn_fib_check_attr(r, rta))
return -EINVAL;
- tb = dn_fib_get_table(r->rtm_table, 1);
+ tb = dn_fib_get_table(rtm_get_table(r, rta), 1);
if (tb)
return tb->insert(tb, r, (struct dn_kern_rta *)rta, nlh, &NETLINK_CB(skb));
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index 1355614..2c5bc4e 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -1480,6 +1480,7 @@ static int dn_rt_fill_info(struct sk_buf
r->rtm_src_len = 0;
r->rtm_tos = 0;
r->rtm_table = RT_TABLE_MAIN;
+ RTA_PUT_U32(skb, RTA_TABLE, RT_TABLE_MAIN);
r->rtm_type = rt->rt_type;
r->rtm_flags = (rt->rt_flags & ~0xFFFF) | RTM_F_CLONED;
r->rtm_scope = RT_SCOPE_UNIVERSE;
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c
index 16ca66b..d274d59 100644
--- a/net/decnet/dn_rules.c
+++ b/net/decnet/dn_rules.c
@@ -77,6 +77,7 @@ int dn_fib_rtm_delrule(struct sk_buff *s
struct rtmsg *rtm = NLMSG_DATA(nlh);
struct dn_fib_rule *r;
struct hlist_node *node;
+ u32 table = rtm_get_table(rtm, rta);
int err = -ESRCH;
hlist_for_each_entry(r, node, &dn_fib_rules, r_hlist) {
@@ -90,7 +91,7 @@ #endif
(!rtm->rtm_type || rtm->rtm_type == r->r_action) &&
(!rta[RTA_PRIORITY-1] || memcmp(RTA_DATA(rta[RTA_PRIORITY-1]), &r->r_preference, 4) == 0) &&
(!rta[RTA_IIF-1] || rtattr_strcmp(rta[RTA_IIF-1], r->r_ifname) == 0) &&
- (!rtm->rtm_table || (r && rtm->rtm_table == r->r_table))) {
+ (!table || (r && table == r->r_table))) {
err = -EPERM;
if (r == &default_rule)
@@ -141,7 +142,7 @@ int dn_fib_rtm_newrule(struct sk_buff *s
if (rtm->rtm_type == RTN_NAT)
return -EINVAL;
- table_id = rtm->rtm_table;
+ table_id = rtm_get_table(rtm, rta);
if (table_id == RT_TABLE_UNSPEC) {
struct dn_fib_table *tb;
if (rtm->rtm_type == RTN_UNICAST) {
@@ -365,6 +366,7 @@ #ifdef CONFIG_DECNET_ROUTE_FWMARK
RTA_PUT(skb, RTA_PROTOINFO, 4, &r->r_fwmark);
#endif
rtm->rtm_table = r->r_table;
+ RTA_PUT_U32(skb, RTA_TABLE, r->r_table);
rtm->rtm_protocol = 0;
rtm->rtm_scope = 0;
rtm->rtm_type = r->r_action;
diff --git a/net/decnet/dn_table.c b/net/decnet/dn_table.c
index 7de6a88..b165282 100644
--- a/net/decnet/dn_table.c
+++ b/net/decnet/dn_table.c
@@ -282,6 +282,7 @@ static int dn_fib_dump_info(struct sk_bu
rtm->rtm_src_len = 0;
rtm->rtm_tos = 0;
rtm->rtm_table = tb_id;
+ RTA_PUT_U32(skb, RTA_TABLE, tb_id);
rtm->rtm_flags = fi->fib_flags;
rtm->rtm_scope = scope;
rtm->rtm_type = type;
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 4d5429a..2f54f22 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -293,7 +293,8 @@ static int inet_check_attr(struct rtmsg
if (attr) {
if (RTA_PAYLOAD(attr) < 4)
return -EINVAL;
- if (i != RTA_MULTIPATH && i != RTA_METRICS)
+ if (i != RTA_MULTIPATH && i != RTA_METRICS &&
+ i != RTA_TABLE)
*rta = (struct rtattr*)RTA_DATA(attr);
}
}
@@ -309,7 +310,7 @@ int inet_rtm_delroute(struct sk_buff *sk
if (inet_check_attr(r, rta))
return -EINVAL;
- tb = fib_get_table(r->rtm_table);
+ tb = fib_get_table(rtm_get_table(r, rta));
if (tb)
return tb->tb_delete(tb, r, (struct kern_rta*)rta, nlh, &NETLINK_CB(skb));
return -ESRCH;
@@ -324,7 +325,7 @@ int inet_rtm_newroute(struct sk_buff *sk
if (inet_check_attr(r, rta))
return -EINVAL;
- tb = fib_new_table(r->rtm_table);
+ tb = fib_new_table(rtm_get_table(r, rta));
if (tb)
return tb->tb_insert(tb, r, (struct kern_rta*)rta, nlh, &NETLINK_CB(skb));
return -ENOBUFS;
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index 71ede02..e6d1f5a 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -111,6 +111,7 @@ int inet_rtm_delrule(struct sk_buff *skb
struct rtmsg *rtm = NLMSG_DATA(nlh);
struct fib_rule *r;
struct hlist_node *node;
+ u32 table = rtm_get_table(rtm, rta);
int err = -ESRCH;
hlist_for_each_entry(r, node, &fib_rules, hlist) {
@@ -125,7 +126,7 @@ #endif
(!rtm->rtm_type || rtm->rtm_type == r->r_action) &&
(!rta[RTA_PRIORITY-1] || memcmp(RTA_DATA(rta[RTA_PRIORITY-1]), &r->r_preference, 4) == 0) &&
(!rta[RTA_IIF-1] || rtattr_strcmp(rta[RTA_IIF-1], r->r_ifname) == 0) &&
- (!rtm->rtm_table || (r && rtm->rtm_table == r->r_table))) {
+ (!table || (r && table == r->r_table))) {
err = -EPERM;
if (r == &local_rule)
break;
@@ -186,7 +187,7 @@ int inet_rtm_newrule(struct sk_buff *skb
if (rta[RTA_IIF-1] && RTA_PAYLOAD(rta[RTA_IIF-1]) > IFNAMSIZ)
return -EINVAL;
- table_id = rtm->rtm_table;
+ table_id = rtm_get_table(rtm, rta);
if (table_id == RT_TABLE_UNSPEC) {
struct fib_table *table;
if (rtm->rtm_type == RTN_UNICAST) {
@@ -403,6 +404,7 @@ #ifdef CONFIG_IP_ROUTE_FWMARK
RTA_PUT(skb, RTA_PROTOINFO, 4, &r->r_fwmark);
#endif
rtm->rtm_table = r->r_table;
+ RTA_PUT_U32(skb, RTA_TABLE, r->r_table);
rtm->rtm_protocol = 0;
rtm->rtm_scope = 0;
rtm->rtm_type = r->r_action;
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 84537df..3c45256 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -954,6 +954,7 @@ fib_dump_info(struct sk_buff *skb, u32 p
rtm->rtm_src_len = 0;
rtm->rtm_tos = tos;
rtm->rtm_table = tb_id;
+ RTA_PUT_U32(skb, RTA_TABLE, tb_id);
rtm->rtm_type = type;
rtm->rtm_flags = fi->fib_flags;
rtm->rtm_scope = scope;
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index da44fab..7ef78f3 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -2638,6 +2638,7 @@ #endif
r->rtm_src_len = 0;
r->rtm_tos = rt->fl.fl4_tos;
r->rtm_table = RT_TABLE_MAIN;
+ RTA_PUT_U32(skb, RTA_TABLE, RT_TABLE_MAIN);
r->rtm_type = rt->rt_type;
r->rtm_scope = RT_SCOPE_UNIVERSE;
r->rtm_protocol = RTPROT_UNSPEC;
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 87c39c9..4410282 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1745,6 +1745,7 @@ static int rt6_fill_node(struct sk_buff
rtm->rtm_src_len = rt->rt6i_src.plen;
rtm->rtm_tos = 0;
rtm->rtm_table = RT_TABLE_MAIN;
+ RTA_PUT_U32(skb, RTA_TABLE, RT_TABLE_MAIN);
if (rt->rt6i_flags&RTF_REJECT)
rtm->rtm_type = RTN_UNREACHABLE;
else if (rt->rt6i_dev && (rt->rt6i_dev->flags&IFF_LOOPBACK))
^ permalink raw reply related
* [RFC IPV4 03/04]: Increase number of possible routing tables to 2^32
From: Patrick McHardy @ 2006-07-03 7:53 UTC (permalink / raw)
To: davem; +Cc: netdev, greearb, Patrick McHardy
In-Reply-To: <20060703075259.6286.67397.sendpatchset@localhost.localdomain>
[IPV4]: Increase number of possible routing tables to 2^32
Increase the nubmer of possible routing tables to 2^32 by replacing the
fixed sized array of tables by a hash table.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
commit aab791510bc6fb2392ac361b0375f60a24b02659
tree f198102cd18b1a6233c573cf4f1f5f0b8827e724
parent 8cf1ae7345f935350dede855381dfbb620cabc1c
author Patrick McHardy <kaber@trash.net> Mon, 03 Jul 2006 09:21:22 +0200
committer Patrick McHardy <kaber@trash.net> Mon, 03 Jul 2006 09:21:22 +0200
include/linux/rtnetlink.h | 3 -
include/net/ip_fib.h | 25 ++---------
net/ipv4/fib_frontend.c | 100 ++++++++++++++++++++++++++++++---------------
net/ipv4/fib_hash.c | 26 ++++++------
net/ipv4/fib_rules.c | 4 +-
net/ipv4/fib_trie.c | 26 ++++++------
6 files changed, 100 insertions(+), 84 deletions(-)
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index 8f6efff..c1217e4 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -238,9 +238,8 @@ enum rt_class_t
RT_TABLE_DEFAULT=253,
RT_TABLE_MAIN=254,
RT_TABLE_LOCAL=255,
- __RT_TABLE_MAX
};
-#define RT_TABLE_MAX (__RT_TABLE_MAX - 1)
+#define RT_TABLE_MAX 0xFFFFFFFF
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index ddc3ced..4b764e2 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -149,6 +149,7 @@ #define FIB_RES_NETMASK(res) (0)
#endif /* CONFIG_IP_ROUTE_MULTIPATH_WRANDOM */
struct fib_table {
+ struct hlist_node tb_hlist;
u32 tb_id;
unsigned tb_stamp;
int (*tb_lookup)(struct fib_table *tb, const struct flowi *flp, struct fib_result *res);
@@ -199,30 +200,14 @@ static inline void fib_select_default(co
}
#else /* CONFIG_IP_MULTIPLE_TABLES */
-#define ip_fib_local_table (fib_tables[RT_TABLE_LOCAL])
-#define ip_fib_main_table (fib_tables[RT_TABLE_MAIN])
+#define ip_fib_local_table fib_get_table(RT_TABLE_LOCAL)
+#define ip_fib_main_table fib_get_table(RT_TABLE_MAIN)
-extern struct fib_table * fib_tables[RT_TABLE_MAX+1];
extern int fib_lookup(const struct flowi *flp, struct fib_result *res);
-extern struct fib_table *__fib_new_table(u32 id);
+extern struct fib_table *fib_new_table(u32 id);
+extern struct fib_table *fib_get_table(u32 id);
extern void fib_rule_put(struct fib_rule *r);
-static inline struct fib_table *fib_get_table(u32 id)
-{
- if (id == 0)
- id = RT_TABLE_MAIN;
-
- return fib_tables[id];
-}
-
-static inline struct fib_table *fib_new_table(u32 id)
-{
- if (id == 0)
- id = RT_TABLE_MAIN;
-
- return fib_tables[id] ? : __fib_new_table(id);
-}
-
extern void fib_select_default(const struct flowi *flp, struct fib_result *res);
#endif /* CONFIG_IP_MULTIPLE_TABLES */
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 2f54f22..3c49e6b 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -36,6 +36,7 @@ #include <linux/if_arp.h>
#include <linux/skbuff.h>
#include <linux/netlink.h>
#include <linux/init.h>
+#include <linux/list.h>
#include <net/ip.h>
#include <net/protocol.h>
@@ -50,48 +51,67 @@ #define FFprint(a...) printk(KERN_DEBUG
#ifndef CONFIG_IP_MULTIPLE_TABLES
-#define RT_TABLE_MIN RT_TABLE_MAIN
-
struct fib_table *ip_fib_local_table;
struct fib_table *ip_fib_main_table;
-#else
+#define FIB_TABLE_HASHSZ 1
+static struct hlist_head fib_table_hash[FIB_TABLE_HASHSZ];
-#define RT_TABLE_MIN 1
+#else
-struct fib_table *fib_tables[RT_TABLE_MAX+1];
+#define FIB_TABLE_HASHSZ 256
+static struct hlist_head fib_table_hash[FIB_TABLE_HASHSZ];
-struct fib_table *__fib_new_table(u32 id)
+struct fib_table *fib_new_table(u32 id)
{
struct fib_table *tb;
+ unsigned int h;
+ if (id == 0)
+ id = RT_TABLE_MAIN;
+ tb = fib_get_table(id);
+ if (tb)
+ return tb;
tb = fib_hash_init(id);
if (!tb)
return NULL;
- fib_tables[id] = tb;
+ h = id & (FIB_TABLE_HASHSZ - 1);
+ hlist_add_head_rcu(&tb->tb_hlist, &fib_table_hash[h]);
return tb;
}
+struct fib_table *fib_get_table(u32 id)
+{
+ struct fib_table *tb;
+ struct hlist_node *node;
+ unsigned int h;
+ if (id == 0)
+ id = RT_TABLE_MAIN;
+ h = id & (FIB_TABLE_HASHSZ - 1);
+ rcu_read_lock();
+ hlist_for_each_entry_rcu(tb, node, &fib_table_hash[h], tb_hlist) {
+ if (tb->tb_id == id) {
+ rcu_read_unlock();
+ return tb;
+ }
+ }
+ rcu_read_unlock();
+ return NULL;
+}
#endif /* CONFIG_IP_MULTIPLE_TABLES */
-
static void fib_flush(void)
{
int flushed = 0;
-#ifdef CONFIG_IP_MULTIPLE_TABLES
struct fib_table *tb;
- u32 id;
+ struct hlist_node *node;
+ unsigned int h;
- for (id = RT_TABLE_MAX; id>0; id--) {
- if ((tb = fib_get_table(id))==NULL)
- continue;
- flushed += tb->tb_flush(tb);
+ for (h = 0; h < FIB_TABLE_HASHSZ; h++) {
+ hlist_for_each_entry(tb, node, &fib_table_hash[h], tb_hlist)
+ flushed += tb->tb_flush(tb);
}
-#else /* CONFIG_IP_MULTIPLE_TABLES */
- flushed += ip_fib_main_table->tb_flush(ip_fib_main_table);
- flushed += ip_fib_local_table->tb_flush(ip_fib_local_table);
-#endif /* CONFIG_IP_MULTIPLE_TABLES */
if (flushed)
rt_cache_flush(-1);
@@ -333,29 +353,35 @@ int inet_rtm_newroute(struct sk_buff *sk
int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
{
- u32 t;
- u32 s_t;
+ unsigned int h, s_h;
+ unsigned int e = 0, s_e;
struct fib_table *tb;
+ struct hlist_node *node;
if (NLMSG_PAYLOAD(cb->nlh, 0) >= sizeof(struct rtmsg) &&
((struct rtmsg*)NLMSG_DATA(cb->nlh))->rtm_flags&RTM_F_CLONED)
return ip_rt_dump(skb, cb);
- s_t = cb->args[0];
- if (s_t == 0)
- s_t = cb->args[0] = RT_TABLE_MIN;
-
- for (t=s_t; t<=RT_TABLE_MAX; t++) {
- if (t < s_t) continue;
- if (t > s_t)
- memset(&cb->args[1], 0, sizeof(cb->args)-sizeof(cb->args[0]));
- if ((tb = fib_get_table(t))==NULL)
- continue;
- if (tb->tb_dump(tb, skb, cb) < 0)
- break;
+ s_h = cb->args[0];
+ s_e = cb->args[1];
+
+ for (h = s_h; h < FIB_TABLE_HASHSZ; h++) {
+ e = 0;
+ hlist_for_each_entry(tb, node, &fib_table_hash[h], tb_hlist) {
+ if (e < s_e)
+ goto next;
+ if (e > s_e)
+ memset(&cb->args[1], 0, sizeof(cb->args) -
+ 2 * sizeof(cb->args[0]));
+ if (tb->tb_dump(tb, skb, cb) < 0)
+ goto out;
+next:
+ e++;
+ }
}
-
- cb->args[0] = t;
+out:
+ cb->args[1] = e;
+ cb->args[0] = h;
return skb->len;
}
@@ -653,9 +679,15 @@ static struct notifier_block fib_netdev_
void __init ip_fib_init(void)
{
+ unsigned int i;
+
+ for (i = 0; i < FIB_TABLE_HASHSZ; i++)
+ INIT_HLIST_HEAD(&fib_table_hash[i]);
#ifndef CONFIG_IP_MULTIPLE_TABLES
ip_fib_local_table = fib_hash_init(RT_TABLE_LOCAL);
+ hlist_add_head_rcu(&ip_fib_local_table->tb_hlist, &fib_table_hash[0]);
ip_fib_main_table = fib_hash_init(RT_TABLE_MAIN);
+ hlist_add_head_rcu(&ip_fib_main_table->tb_hlist, &fib_table_hash[0]);
#else
fib_rules_init();
#endif
diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c
index 4b79173..fcbf2d6 100644
--- a/net/ipv4/fib_hash.c
+++ b/net/ipv4/fib_hash.c
@@ -685,7 +685,7 @@ fn_hash_dump_bucket(struct sk_buff *skb,
struct fib_node *f;
int i, s_i;
- s_i = cb->args[3];
+ s_i = cb->args[4];
i = 0;
hlist_for_each_entry(f, node, head, fn_hash) {
struct fib_alias *fa;
@@ -705,14 +705,14 @@ fn_hash_dump_bucket(struct sk_buff *skb,
fa->fa_tos,
fa->fa_info,
NLM_F_MULTI) < 0) {
- cb->args[3] = i;
+ cb->args[4] = i;
return -1;
}
next:
i++;
}
}
- cb->args[3] = i;
+ cb->args[4] = i;
return skb->len;
}
@@ -723,21 +723,21 @@ fn_hash_dump_zone(struct sk_buff *skb, s
{
int h, s_h;
- s_h = cb->args[2];
+ s_h = cb->args[3];
for (h=0; h < fz->fz_divisor; h++) {
if (h < s_h) continue;
if (h > s_h)
- memset(&cb->args[3], 0,
- sizeof(cb->args) - 3*sizeof(cb->args[0]));
+ memset(&cb->args[4], 0,
+ sizeof(cb->args) - 4*sizeof(cb->args[0]));
if (fz->fz_hash == NULL ||
hlist_empty(&fz->fz_hash[h]))
continue;
if (fn_hash_dump_bucket(skb, cb, tb, fz, &fz->fz_hash[h])<0) {
- cb->args[2] = h;
+ cb->args[3] = h;
return -1;
}
}
- cb->args[2] = h;
+ cb->args[3] = h;
return skb->len;
}
@@ -747,21 +747,21 @@ static int fn_hash_dump(struct fib_table
struct fn_zone *fz;
struct fn_hash *table = (struct fn_hash*)tb->tb_data;
- s_m = cb->args[1];
+ s_m = cb->args[2];
read_lock(&fib_hash_lock);
for (fz = table->fn_zone_list, m=0; fz; fz = fz->fz_next, m++) {
if (m < s_m) continue;
if (m > s_m)
- memset(&cb->args[2], 0,
- sizeof(cb->args) - 2*sizeof(cb->args[0]));
+ memset(&cb->args[3], 0,
+ sizeof(cb->args) - 3*sizeof(cb->args[0]));
if (fn_hash_dump_zone(skb, cb, tb, fz) < 0) {
- cb->args[1] = m;
+ cb->args[2] = m;
read_unlock(&fib_hash_lock);
return -1;
}
}
read_unlock(&fib_hash_lock);
- cb->args[1] = m;
+ cb->args[2] = m;
return skb->len;
}
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index e6d1f5a..a41ab4b 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -149,8 +149,8 @@ static struct fib_table *fib_empty_table
u32 id;
for (id = 1; id <= RT_TABLE_MAX; id++)
- if (fib_tables[id] == NULL)
- return __fib_new_table(id);
+ if (fib_get_table(id) == NULL)
+ return fib_new_table(id);
return NULL;
}
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 3936f16..92b1d77 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -1848,7 +1848,7 @@ static int fn_trie_dump_fa(t_key key, in
u32 xkey = htonl(key);
- s_i = cb->args[3];
+ s_i = cb->args[4];
i = 0;
/* rcu_read_lock is hold by caller */
@@ -1870,12 +1870,12 @@ static int fn_trie_dump_fa(t_key key, in
plen,
fa->fa_tos,
fa->fa_info, 0) < 0) {
- cb->args[3] = i;
+ cb->args[4] = i;
return -1;
}
i++;
}
- cb->args[3] = i;
+ cb->args[4] = i;
return skb->len;
}
@@ -1886,14 +1886,14 @@ static int fn_trie_dump_plen(struct trie
struct list_head *fa_head;
struct leaf *l = NULL;
- s_h = cb->args[2];
+ s_h = cb->args[3];
for (h = 0; (l = nextleaf(t, l)) != NULL; h++) {
if (h < s_h)
continue;
if (h > s_h)
- memset(&cb->args[3], 0,
- sizeof(cb->args) - 3*sizeof(cb->args[0]));
+ memset(&cb->args[4], 0,
+ sizeof(cb->args) - 4*sizeof(cb->args[0]));
fa_head = get_fa_head(l, plen);
@@ -1904,11 +1904,11 @@ static int fn_trie_dump_plen(struct trie
continue;
if (fn_trie_dump_fa(l->key, plen, fa_head, tb, skb, cb)<0) {
- cb->args[2] = h;
+ cb->args[3] = h;
return -1;
}
}
- cb->args[2] = h;
+ cb->args[3] = h;
return skb->len;
}
@@ -1917,23 +1917,23 @@ static int fn_trie_dump(struct fib_table
int m, s_m;
struct trie *t = (struct trie *) tb->tb_data;
- s_m = cb->args[1];
+ s_m = cb->args[2];
rcu_read_lock();
for (m = 0; m <= 32; m++) {
if (m < s_m)
continue;
if (m > s_m)
- memset(&cb->args[2], 0,
- sizeof(cb->args) - 2*sizeof(cb->args[0]));
+ memset(&cb->args[3], 0,
+ sizeof(cb->args) - 3*sizeof(cb->args[0]));
if (fn_trie_dump_plen(t, 32-m, tb, skb, cb)<0) {
- cb->args[1] = m;
+ cb->args[2] = m;
goto out;
}
}
rcu_read_unlock();
- cb->args[1] = m;
+ cb->args[2] = m;
return skb->len;
out:
rcu_read_unlock();
^ permalink raw reply related
* [RFC DECNET 04/04]: Increase number of possible routing tables to 2^32
From: Patrick McHardy @ 2006-07-03 7:53 UTC (permalink / raw)
To: davem; +Cc: netdev, greearb, Patrick McHardy
In-Reply-To: <20060703075259.6286.67397.sendpatchset@localhost.localdomain>
[DECNET]: Increase number of possible routing tables to 2^32
Increase the nubmer of possible routing tables to 2^32 by replacing the
fixed sized array of tables by a hash table.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
commit 2bafd208cbec6b6291662bf39d94f1f9e3a54e31
tree 1b922ca700a00f4fcb97d7567d85bd9d49b5bc90
parent aab791510bc6fb2392ac361b0375f60a24b02659
author Patrick McHardy <kaber@trash.net> Mon, 03 Jul 2006 09:21:50 +0200
committer Patrick McHardy <kaber@trash.net> Mon, 03 Jul 2006 09:21:50 +0200
include/net/dn_fib.h | 3 -
net/decnet/dn_fib.c | 49 --------------------
net/decnet/dn_rules.c | 2 -
net/decnet/dn_table.c | 122 +++++++++++++++++++++++++++++++++++--------------
4 files changed, 90 insertions(+), 86 deletions(-)
diff --git a/include/net/dn_fib.h b/include/net/dn_fib.h
index 9464f48..8098bdd 100644
--- a/include/net/dn_fib.h
+++ b/include/net/dn_fib.h
@@ -94,6 +94,7 @@ #define DN_FIB_INFO(f) ((f)->fn_info)
struct dn_fib_table {
+ struct hlist_node hlist;
u32 n;
int (*insert)(struct dn_fib_table *t, struct rtmsg *r,
@@ -179,8 +180,6 @@ static inline void dn_fib_res_put(struct
dn_fib_rule_put(res->r);
}
-extern struct dn_fib_table *dn_fib_tables[];
-
#else /* Endnode */
#define dn_fib_init() do { } while(0)
diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c
index a43e59b..7127d36 100644
--- a/net/decnet/dn_fib.c
+++ b/net/decnet/dn_fib.c
@@ -532,39 +532,6 @@ int dn_fib_rtm_newroute(struct sk_buff *
return -ENOBUFS;
}
-
-int dn_fib_dump(struct sk_buff *skb, struct netlink_callback *cb)
-{
- u32 t;
- u32 s_t;
- struct dn_fib_table *tb;
-
- if (NLMSG_PAYLOAD(cb->nlh, 0) >= sizeof(struct rtmsg) &&
- ((struct rtmsg *)NLMSG_DATA(cb->nlh))->rtm_flags&RTM_F_CLONED)
- return dn_cache_dump(skb, cb);
-
- s_t = cb->args[0];
- if (s_t == 0)
- s_t = cb->args[0] = RT_MIN_TABLE;
-
- for(t = s_t; t <= RT_TABLE_MAX; t++) {
- if (t < s_t)
- continue;
- if (t > s_t)
- memset(&cb->args[1], 0,
- sizeof(cb->args) - sizeof(cb->args[0]));
- tb = dn_fib_get_table(t, 0);
- if (tb == NULL)
- continue;
- if (tb->dump(tb, skb, cb) < 0)
- break;
- }
-
- cb->args[0] = t;
-
- return skb->len;
-}
-
static void fib_magic(int cmd, int type, __le16 dst, int dst_len, struct dn_ifaddr *ifa)
{
struct dn_fib_table *tb;
@@ -762,22 +729,6 @@ int dn_fib_sync_up(struct net_device *de
return ret;
}
-void dn_fib_flush(void)
-{
- int flushed = 0;
- struct dn_fib_table *tb;
- u32 id;
-
- for(id = RT_TABLE_MAX; id > 0; id--) {
- if ((tb = dn_fib_get_table(id, 0)) == NULL)
- continue;
- flushed += tb->flush(tb);
- }
-
- if (flushed)
- dn_rt_cache_flush(-1);
-}
-
static struct notifier_block dn_fib_dnaddr_notifier = {
.notifier_call = dn_fib_dnaddr_event,
};
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c
index d274d59..6d1752a 100644
--- a/net/decnet/dn_rules.c
+++ b/net/decnet/dn_rules.c
@@ -273,7 +273,7 @@ unsigned dnet_addr_type(__le16 addr)
struct flowi fl = { .nl_u = { .dn_u = { .daddr = addr } } };
struct dn_fib_res res;
unsigned ret = RTN_UNICAST;
- struct dn_fib_table *tb = dn_fib_tables[RT_TABLE_LOCAL];
+ struct dn_fib_table *tb = dn_fib_get_table(RT_TABLE_LOCAL, 0);
res.r = NULL;
diff --git a/net/decnet/dn_table.c b/net/decnet/dn_table.c
index b165282..0c3417c 100644
--- a/net/decnet/dn_table.c
+++ b/net/decnet/dn_table.c
@@ -74,9 +74,9 @@ #define DN_FIB_SCAN_KEY(f, fp, key) \
for( ; ((f) = *(fp)) != NULL && dn_key_eq((f)->fn_key, (key)); (fp) = &(f)->fn_next)
#define RT_TABLE_MIN 1
-
+#define DN_FIB_TABLE_HASHSZ 256
+static struct hlist_head dn_fib_table_hash[DN_FIB_TABLE_HASHSZ];
static DEFINE_RWLOCK(dn_fib_tables_lock);
-struct dn_fib_table *dn_fib_tables[RT_TABLE_MAX + 1];
static kmem_cache_t *dn_hash_kmem __read_mostly;
static int dn_fib_hash_zombies;
@@ -365,7 +365,7 @@ static __inline__ int dn_hash_dump_bucke
{
int i, s_i;
- s_i = cb->args[3];
+ s_i = cb->args[4];
for(i = 0; f; i++, f = f->fn_next) {
if (i < s_i)
continue;
@@ -378,11 +378,11 @@ static __inline__ int dn_hash_dump_bucke
(f->fn_state & DN_S_ZOMBIE) ? 0 : f->fn_type,
f->fn_scope, &f->fn_key, dz->dz_order,
f->fn_info, NLM_F_MULTI) < 0) {
- cb->args[3] = i;
+ cb->args[4] = i;
return -1;
}
}
- cb->args[3] = i;
+ cb->args[4] = i;
return skb->len;
}
@@ -393,20 +393,20 @@ static __inline__ int dn_hash_dump_zone(
{
int h, s_h;
- s_h = cb->args[2];
+ s_h = cb->args[3];
for(h = 0; h < dz->dz_divisor; h++) {
if (h < s_h)
continue;
if (h > s_h)
- memset(&cb->args[3], 0, sizeof(cb->args) - 3*sizeof(cb->args[0]));
+ memset(&cb->args[4], 0, sizeof(cb->args) - 4*sizeof(cb->args[0]));
if (dz->dz_hash == NULL || dz->dz_hash[h] == NULL)
continue;
if (dn_hash_dump_bucket(skb, cb, tb, dz, dz->dz_hash[h]) < 0) {
- cb->args[2] = h;
+ cb->args[3] = h;
return -1;
}
}
- cb->args[2] = h;
+ cb->args[3] = h;
return skb->len;
}
@@ -417,26 +417,61 @@ static int dn_fib_table_dump(struct dn_f
struct dn_zone *dz;
struct dn_hash *table = (struct dn_hash *)tb->data;
- s_m = cb->args[1];
+ s_m = cb->args[2];
read_lock(&dn_fib_tables_lock);
for(dz = table->dh_zone_list, m = 0; dz; dz = dz->dz_next, m++) {
if (m < s_m)
continue;
if (m > s_m)
- memset(&cb->args[2], 0, sizeof(cb->args) - 2*sizeof(cb->args[0]));
+ memset(&cb->args[3], 0, sizeof(cb->args) - 3*sizeof(cb->args[0]));
if (dn_hash_dump_zone(skb, cb, tb, dz) < 0) {
- cb->args[1] = m;
+ cb->args[2] = m;
read_unlock(&dn_fib_tables_lock);
return -1;
}
}
read_unlock(&dn_fib_tables_lock);
- cb->args[1] = m;
+ cb->args[2] = m;
return skb->len;
}
+int dn_fib_dump(struct sk_buff *skb, struct netlink_callback *cb)
+{
+ unsigned int h, s_h;
+ unsigned int e = 0, s_e;
+ struct dn_fib_table *tb;
+ struct hlist_node *node;
+
+ if (NLMSG_PAYLOAD(cb->nlh, 0) >= sizeof(struct rtmsg) &&
+ ((struct rtmsg *)NLMSG_DATA(cb->nlh))->rtm_flags&RTM_F_CLONED)
+ return dn_cache_dump(skb, cb);
+
+ s_h = cb->args[0];
+ s_e = cb->args[1];
+
+ for (h = s_h; h < DN_FIB_TABLE_HASHSZ; h++) {
+ e = 0;
+ hlist_for_each_entry(tb, node, &dn_fib_table_hash[h], hlist) {
+ if (e < s_e)
+ goto next;
+ if (e > s_e)
+ memset(&cb->args[2], 0, sizeof(cb->args) -
+ 2 * sizeof(cb->args[0]));
+ if (tb->dump(tb, skb, cb) < 0)
+ goto out;
+next:
+ e++;
+ }
+ }
+out:
+ cb->args[1] = e;
+ cb->args[0] = h;
+
+ return skb->len;
+}
+
static int dn_fib_table_insert(struct dn_fib_table *tb, struct rtmsg *r, struct dn_kern_rta *rta, struct nlmsghdr *n, struct netlink_skb_parms *req)
{
struct dn_hash *table = (struct dn_hash *)tb->data;
@@ -748,6 +783,8 @@ out:
struct dn_fib_table *dn_fib_get_table(u32 n, int create)
{
struct dn_fib_table *t;
+ struct hlist_node *node;
+ unsigned int h;
if (n < RT_TABLE_MIN)
return NULL;
@@ -755,8 +792,15 @@ struct dn_fib_table *dn_fib_get_table(u3
if (n > RT_TABLE_MAX)
return NULL;
- if (dn_fib_tables[n])
- return dn_fib_tables[n];
+ h = n & (DN_FIB_TABLE_HASHSZ - 1);
+ rcu_read_lock();
+ hlist_for_each_entry_rcu(t, node, &dn_fib_table_hash[h], hlist) {
+ if (t->n == n) {
+ rcu_read_unlock();
+ return t;
+ }
+ }
+ rcu_read_unlock();
if (!create)
return NULL;
@@ -777,33 +821,37 @@ struct dn_fib_table *dn_fib_get_table(u3
t->flush = dn_fib_table_flush;
t->dump = dn_fib_table_dump;
memset(t->data, 0, sizeof(struct dn_hash));
- dn_fib_tables[n] = t;
+ hlist_add_head_rcu(&t->hlist, &dn_fib_table_hash[h]);
return t;
}
-static void dn_fib_del_tree(u32 n)
-{
- struct dn_fib_table *t;
-
- write_lock(&dn_fib_tables_lock);
- t = dn_fib_tables[n];
- dn_fib_tables[n] = NULL;
- write_unlock(&dn_fib_tables_lock);
-
- kfree(t);
-}
-
struct dn_fib_table *dn_fib_empty_table(void)
{
u32 id;
for(id = RT_TABLE_MIN; id <= RT_TABLE_MAX; id++)
- if (dn_fib_tables[id] == NULL)
+ if (dn_fib_get_table(id, 0) == NULL)
return dn_fib_get_table(id, 1);
return NULL;
}
+void dn_fib_flush(void)
+{
+ int flushed = 0;
+ struct dn_fib_table *tb;
+ struct hlist_node *node;
+ unsigned int h;
+
+ for (h = 0; h < DN_FIB_TABLE_HASHSZ; h++) {
+ hlist_for_each_entry(tb, node, &dn_fib_table_hash[h], hlist)
+ flushed += tb->flush(tb);
+ }
+
+ if (flushed)
+ dn_rt_cache_flush(-1);
+}
+
void __init dn_fib_table_init(void)
{
dn_hash_kmem = kmem_cache_create("dn_fib_info_cache",
@@ -814,10 +862,16 @@ void __init dn_fib_table_init(void)
void __exit dn_fib_table_cleanup(void)
{
- int i;
-
- for (i = RT_TABLE_MIN; i <= RT_TABLE_MAX; ++i)
- dn_fib_del_tree(i);
+ struct dn_fib_table *t;
+ struct hlist_node *node, *next;
+ unsigned int h;
- return;
+ write_lock(&dn_fib_tables_lock);
+ for (h = 0; h < DN_FIB_TABLE_HASHSZ; h++)
+ hlist_for_each_entry_safe(t, node, next, &dn_fib_table_hash[h],
+ hlist) {
+ hlist_del(&t->hlist);
+ kfree(t);
+ }
+ write_unlock(&dn_fib_tables_lock);
}
^ permalink raw reply related
* Re: [PATCH 2.6.17.1 2/2] dllink driver: porting v1.19 to linux 2.6.17
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2006-07-03 8:14 UTC (permalink / raw)
To: hayim; +Cc: arjan, edward_peng, linux-kernel, netdev
In-Reply-To: <1151914066.3108.4.camel@laptopd505.fenrus.org>
In article <1151914066.3108.4.camel@laptopd505.fenrus.org> (at Mon, 03 Jul 2006 10:07:46 +0200), Arjan van de Ven <arjan@infradead.org> says:
> Since you still have the patches correct on your machine, could you
> resend them in "Preformat" mode? That makes it a lot easier for people
> to do anything with them
And, please CC: <netdev@vger.kernel.org>.
--yoshfuji
^ permalink raw reply
* [PATCH 2.6.17.1 2/2] dllink driver: porting v1.19 to linux 2.6.17
From: Hayim Shaul @ 2006-07-03 8:19 UTC (permalink / raw)
To: linux-kernel, edward_peng; +Cc: netdev
Description:
For DLink Fiber NIC, Linux 2.4.22 ships with driver version 1.19,
whereas, Linux 2.6.x ship with driver version 1.17.
The following patch upgrades the 2.6.x driver to include changes (and
bug fixes done until 1.19b).
These fixes are (copied from the driver):
1.18 2002/11/07 New tx scheme, adaptive tx_coalesce.
Remove tx_coalesce option.
1.19 2003/12/16 Fix problem parsing the eeprom on big endian
systems. (philt@4bridgeworks.com)
Disclaimer:
Since I returned my DLink NIC to the store I couldn't test it
thoroughly. It seemed to work just as well as v1.17. However, both
version made the NIC hang after a few minutes.
Signed-off-by: Hayim Shaul <hayim@iportent.com>
--- linux-2.6.17.1/drivers/net/dl2k.h.orig 2006-07-03 10:28:47.000000000 +0300
+++ linux-2.6.17.1/drivers/net/dl2k.h 2006-07-03 10:41:13.000000000 +0300
@@ -36,7 +36,7 @@
#include <linux/spinlock.h>
#include <linux/time.h>
#define TX_RING_SIZE 256
-#define TX_QUEUE_LEN (TX_RING_SIZE - 1) /* Limit ring entries actually used.*/
+#define TX_QUEUE_LEN (TX_RING_SIZE - 10) /* Limit ring entries actually used.*/
#define RX_RING_SIZE 256
#define TX_TOTAL_SIZE TX_RING_SIZE*sizeof(struct netdev_desc)
#define RX_TOTAL_SIZE RX_RING_SIZE*sizeof(struct netdev_desc)
@@ -243,6 +243,9 @@ enum TFC_bits {
VLANTagInsert = 0x0000000010000000,
TFDDone = 0x80000000,
VIDShift = 32,
+ /* This const is too large for 32bit CPUs */
+ /* and is not used anyway */
+/* CFI = 0x0000100000000000, */
UsePriorityShift = 48,
};
@@ -512,7 +515,7 @@ typedef union t_MII_ESR {
u16 image;
struct {
u16 _bit_11_0:12; // bit 11:0
- u16 media_1000BT_HD:2; // bit 12
+ u16 media_1000BT_HD:1; // bit 12
u16 media_1000BT_FD:1; // bit 13
u16 media_1000BX_HD:1; // bit 14
u16 media_1000BX_FD:1; // bit 15
@@ -655,6 +658,8 @@ struct netdev_private {
struct net_device_stats stats;
unsigned int rx_buf_sz; /* Based on MTU+slack. */
unsigned int speed; /* Operating speed */
+ struct tasklet_struct tx_tasklet;
+ struct tasklet_struct rx_tasklet;
unsigned int vlan; /* VLAN Id */
unsigned int chip_id; /* PCI table chip id */
unsigned int rx_coalesce; /* Maximum frames each RxDMAComplete intr */
@@ -672,6 +677,9 @@ struct netdev_private {
struct netdev_desc *last_tx; /* Last Tx descriptor used. */
unsigned long cur_rx, old_rx; /* Producer/consumer ring indices */
unsigned long cur_tx, old_tx;
+ unsigned long cur_task;
+ atomic_t tx_desc_lock;
+ int budget;
struct timer_list timer;
int wake_polarity;
char name[256]; /* net device description */
@@ -695,7 +703,7 @@ struct netdev_private {
class_mask of the class are honored during the comparison.
driver_data Data private to the driver.
*/
-static struct pci_device_id rio_pci_tbl[] = {
+static struct pci_device_id rio_pci_tbl[] __devinitdata = {
{0x1186, 0x4000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{0,}
};
@@ -708,4 +716,5 @@ MODULE_DEVICE_TABLE (pci, rio_pci_tbl);
#define DEFAULT_RXT 750
#define DEFAULT_TXC 1
#define MAX_TXC 8
+#define RX_BUDGET RX_RING_SIZE/2
#endif /* __DL2K_H__ */
^ permalink raw reply
* [PATCH 2.6.17.1 1/2] dllink driver: porting v1.19 to linux 2.6.17
From: Hayim Shaul @ 2006-07-03 8:19 UTC (permalink / raw)
To: linux-kernel, edward_peng; +Cc: netdev
Description:
For DLink Fiber NIC, Linux 2.4.22 ships with driver version 1.19,
whereas, Linux 2.6.x ship with driver version 1.17.
The following patch upgrades the 2.6.x driver to include changes (and
bug fixes done until 1.19b).
These fixes are (copied from the driver):
1.18 2002/11/07 New tx scheme, adaptive tx_coalesce.
Remove tx_coalesce option.
1.19 2003/12/16 Fix problem parsing the eeprom on big endian
systems. (philt@4bridgeworks.com)
Disclaimer:
Since I returned my DLink NIC to the store I couldn't test it
thoroughly. It seemed to work just as well as v1.17. However, both
version made the NIC hang after a few minutes.
Signed-off-by: Hayim Shaul <hayim@iportent.com>
--- linux-2.6.17.1/drivers/net/dl2k.c.orig 2006-07-03 10:28:43.000000000 +0300
+++ linux-2.6.17.1/drivers/net/dl2k.c 2006-07-03 10:31:31.000000000 +0300
@@ -1,7 +1,8 @@
/* D-Link DL2000-based Gigabit Ethernet Adapter Linux driver */
/*
Copyright (c) 2001, 2002 by D-Link Corporation
- Written by Edward Peng.<edward_peng@dlink.com.tw>
+ Copyright (c) 2003 by Alpha Networks
+ Written by Edward Peng.<edward_peng@alphanetworks.com.tw>
Created 03-May-2001, base on Linux' sundance.c.
This program is free software; you can redistribute it and/or modify
@@ -47,11 +48,16 @@
1.17 2002/10/03 Fix RMON statistics overflow.
Always use I/O mapping to access eeprom,
avoid system freezing with some chipsets.
+ 1.18 2002/11/07 New tx scheme, adaptive tx_coalesce.
+ Remove tx_coalesce option.
+ 1.19 2003/12/16 Fix problem parsing the eeprom on big endian
+ systems. (philt@4bridgeworks.com)
+ 1.19a 2006/07/01 made compile on kernel 2.6.15. (hayim@iportent.com)
*/
#define DRV_NAME "D-Link DL2000-based linux driver"
-#define DRV_VERSION "v1.17b"
-#define DRV_RELDATE "2006/03/10"
+#define DRV_VERSION "v1.19a"
+#define DRV_RELDATE "2006/07/01"
#include "dl2k.h"
#include <linux/dma-mapping.h>
@@ -65,9 +71,8 @@ static char *media[MAX_UNITS];
static int tx_flow=-1;
static int rx_flow=-1;
static int copy_thresh;
-static int rx_coalesce=10; /* Rx frame count each interrupt */
+static int rx_coalesce=0; /* Rx frame count each interrupt */
static int rx_timeout=200; /* Rx DMA wait time in 640ns increments */
-static int tx_coalesce=16; /* HW xmit count each TxDMAComplete */
MODULE_AUTHOR ("Edward Peng");
@@ -82,12 +87,11 @@ module_param(rx_flow, int, 0);
module_param(copy_thresh, int, 0);
module_param(rx_coalesce, int, 0); /* Rx frame count each interrupt */
module_param(rx_timeout, int, 0); /* Rx DMA wait time in 64ns increments */
-module_param(tx_coalesce, int, 0); /* HW xmit count each TxDMAComplete */
/* Enable the default interrupts */
#define DEFAULT_INTR (RxDMAComplete | HostError | IntRequested | TxDMAComplete| \
- UpdateStats | LinkEvent)
+ UpdateStats | LinkEvent|TxComplete)
#define EnableInt() \
writew(DEFAULT_INTR, ioaddr + IntEnable)
@@ -98,11 +102,13 @@ static int rio_open (struct net_device *
static void rio_timer (unsigned long data);
static void rio_tx_timeout (struct net_device *dev);
static void alloc_list (struct net_device *dev);
+static void tx_poll (unsigned long data);
static int start_xmit (struct sk_buff *skb, struct net_device *dev);
static irqreturn_t rio_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
-static void rio_free_tx (struct net_device *dev, int irq);
+static void rio_free_tx (struct net_device *dev);
static void tx_error (struct net_device *dev, int tx_status);
-static int receive_packet (struct net_device *dev);
+static void rx_poll (unsigned long data);
+static void refill_rx (struct net_device *dev);
static void rio_error (struct net_device *dev, int int_status);
static int change_mtu (struct net_device *dev, int new_mtu);
static void set_multicast (struct net_device *dev);
@@ -175,10 +181,11 @@ rio_probe1 (struct pci_dev *pdev, const
np->pdev = pdev;
spin_lock_init (&np->tx_lock);
spin_lock_init (&np->rx_lock);
+ tasklet_init(&np->tx_tasklet, tx_poll, (unsigned long) dev);
+ tasklet_init(&np->rx_tasklet, rx_poll, (unsigned long) dev);
/* Parse manual configuration */
np->an_enable = 1;
- np->tx_coalesce = 1;
if (card_idx < MAX_UNITS) {
if (media[card_idx] != NULL) {
np->an_enable = 0;
@@ -232,10 +239,6 @@ rio_probe1 (struct pci_dev *pdev, const
np->tx_flow = (tx_flow == 0) ? 0 : 1;
np->rx_flow = (rx_flow == 0) ? 0 : 1;
- if (tx_coalesce < 1)
- tx_coalesce = 1;
- else if (tx_coalesce > TX_RING_SIZE-1)
- tx_coalesce = TX_RING_SIZE - 1;
}
dev->open = &rio_open;
dev->hard_start_xmit = &start_xmit;
@@ -301,9 +304,6 @@ rio_probe1 (struct pci_dev *pdev, const
dev->name, np->name,
dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5], irq);
- if (tx_coalesce > 1)
- printk(KERN_INFO "tx_coalesce:\t%d packets\n",
- tx_coalesce);
if (np->coalesce)
printk(KERN_INFO "rx_coalesce:\t%d packets\n"
KERN_INFO "rx_timeout: \t%d ns\n",
@@ -374,8 +374,9 @@ parse_eeprom (struct net_device *dev)
#endif
/* Read eeprom */
for (i = 0; i < 128; i++) {
- ((u16 *) sromdata)[i] = le16_to_cpu (read_eeprom (ioaddr, i));
+ ((u16 *) sromdata)[i] = cpu_to_le16 (read_eeprom (ioaddr, i));
}
+ psrom->crc = le32_to_cpu(psrom->crc);
#ifdef MEM_MAPPING
ioaddr = dev->base_addr;
#endif
@@ -473,9 +474,12 @@ rio_open (struct net_device *dev)
writeb (0x30, ioaddr + RxDMABurstThresh);
writeb (0x30, ioaddr + RxDMAUrgentThresh);
writel (0x0007ffff, ioaddr + RmonStatMask);
+
/* clear statistics */
clear_stats (dev);
+ atomic_set(&np->tx_desc_lock, 0);
+
/* VLAN supported */
if (np->vlan) {
/* priority field in RxDMAIntCtrl */
@@ -560,17 +564,31 @@ rio_timer (unsigned long data)
np->timer.expires = jiffies + next_tick;
add_timer(&np->timer);
}
-
+
static void
rio_tx_timeout (struct net_device *dev)
{
+ struct netdev_private *np = dev->priv;
long ioaddr = dev->base_addr;
- printk (KERN_INFO "%s: Tx timed out (%4.4x), is buffer full?\n",
+ printk (KERN_INFO "%s: Tx timed out (%4.4x), "
+ "clean up tx queue to restart..\n",
dev->name, readl (ioaddr + TxStatus));
- rio_free_tx(dev, 0);
+ printk (KERN_INFO "%s: cur_tx=%lx cur_task=%lx old_tx=%lx "
+ "TFDListPtr=%08x tx_full=%d",
+ dev->name, np->cur_tx, np->cur_task, np->old_tx,
+ readl(ioaddr + TFDListPtr0),
+ netif_queue_stopped(dev));
+ writew(0, ioaddr + IntEnable);
+ writew(0, ioaddr + TFDListPtr0);
+ writew(0, ioaddr + TFDListPtr1);
+ tasklet_disable(&np->tx_tasklet);
+ rio_free_tx(dev);
dev->if_port = 0;
dev->trans_start = jiffies;
+ tasklet_enable(&np->tx_tasklet);
+ writew(DEFAULT_INTR, ioaddr + IntEnable);
+ return;
}
/* allocate and initialize Tx and Rx descriptors */
@@ -582,6 +600,7 @@ alloc_list (struct net_device *dev)
np->cur_rx = np->cur_tx = 0;
np->old_rx = np->old_tx = 0;
+ np->cur_task = 0;
np->rx_buf_sz = (dev->mtu <= 1500 ? PACKET_SIZE : dev->mtu + 32);
/* Initialize Tx descriptors, TFDListPtr leaves in start_xmit(). */
@@ -631,6 +650,31 @@ alloc_list (struct net_device *dev)
return;
}
+static void tx_poll (unsigned long data)
+{
+ struct net_device *dev = (struct net_device*) data;
+ struct netdev_private *np = dev->priv;
+ unsigned head = np->cur_task % TX_RING_SIZE;
+ struct netdev_desc *txdesc =
+ &np->tx_ring[(np->cur_tx + TX_RING_SIZE - 1) % TX_RING_SIZE];
+
+ /* Indicate the latest descriptor of tx ring */
+ txdesc->status |= cpu_to_le64 (TxDMAIndicate);
+
+ while ((np->cur_task + TX_RING_SIZE - np->cur_tx) % TX_RING_SIZE > 0) {
+ txdesc = &np->tx_ring[np->cur_task];
+ txdesc->status &= cpu_to_le64 (~TFDDone);
+ np->cur_task = (np->cur_task + 1) % TX_RING_SIZE;
+ }
+
+ if (readl (dev->base_addr + TFDListPtr0) == 0) {
+ writel (np->tx_ring_dma + head * sizeof (struct netdev_desc),
+ dev->base_addr + TFDListPtr0);
+ writel (0, dev->base_addr + TFDListPtr1);
+ }
+
+ return;
+}
static int
start_xmit (struct sk_buff *skb, struct net_device *dev)
{
@@ -669,35 +713,40 @@ start_xmit (struct sk_buff *skb, struct
/* DL2K bug: DMA fails to get next descriptor ptr in 10Mbps mode
* Work around: Always use 1 descriptor in 10Mbps mode */
- if (entry % np->tx_coalesce == 0 || np->speed == 10)
- txdesc->status = cpu_to_le64 (entry | tfc_vlan_tag |
+ if (np->speed == 10) {
+ /* Note the order! Stop queue before hardware processing
+ * this descriptor */
+ netif_stop_queue (dev);
+ txdesc->status = cpu_to_le64 (entry | tfc_vlan_tag |
WordAlignDisable |
- TxDMAIndicate |
+ TxDMAIndicate | TxComplete |
(1 << FragCountShift));
- else
- txdesc->status = cpu_to_le64 (entry | tfc_vlan_tag |
+ /* TxDMAPollNow */
+ writel(readl(ioaddr + DMACtrl) | 0x00001000, ioaddr + DMACtrl);
+ if (readl (dev->base_addr + TFDListPtr0) == 0) {
+ writel (np->tx_ring_dma +
+ entry * sizeof (struct netdev_desc),
+ dev->base_addr + TFDListPtr0);
+ writel (0, dev->base_addr + TFDListPtr1);
+ }
+ np->cur_tx = np->cur_task = (np->cur_tx + 1) % TX_RING_SIZE;
+ } else {
+ np->cur_tx = (np->cur_tx + 1) % TX_RING_SIZE;
+ mb();
+ txdesc->status = cpu_to_le64 (entry | tfc_vlan_tag | TFDDone |
WordAlignDisable |
(1 << FragCountShift));
-
- /* TxDMAPollNow */
- writel (readl (ioaddr + DMACtrl) | 0x00001000, ioaddr + DMACtrl);
- /* Schedule ISR */
- writel(10000, ioaddr + CountDown);
- np->cur_tx = (np->cur_tx + 1) % TX_RING_SIZE;
- if ((np->cur_tx - np->old_tx + TX_RING_SIZE) % TX_RING_SIZE
- < TX_QUEUE_LEN - 1 && np->speed != 10) {
- /* do nothing */
- } else if (!netif_queue_stopped(dev)) {
- netif_stop_queue (dev);
+ tasklet_schedule (&np->tx_tasklet);
+ /* Schedule ISR */
+ if ((np->cur_tx - np->old_tx + TX_RING_SIZE) % TX_RING_SIZE
+ < TX_QUEUE_LEN - 1) {
+ /* do nothing */
+ } else if (!netif_queue_stopped(dev)) {
+ netif_stop_queue (dev);
+ }
}
- /* The first TFDListPtr */
- if (readl (dev->base_addr + TFDListPtr0) == 0) {
- writel (np->tx_ring_dma + entry * sizeof (struct netdev_desc),
- dev->base_addr + TFDListPtr0);
- writel (0, dev->base_addr + TFDListPtr1);
- }
-
+
/* NETDEV WATCHDOG timer */
dev->trans_start = jiffies;
return 0;
@@ -723,16 +772,22 @@ rio_interrupt (int irq, void *dev_instan
break;
handled = 1;
/* Processing received packets */
- if (int_status & RxDMAComplete)
- receive_packet (dev);
+ if (int_status & RxDMAComplete) {
+ writew(DEFAULT_INTR & ~(RxDMAComplete | RxComplete),
+ ioaddr + IntEnable);
+ if (np->budget < 0) {
+ np->budget = RX_BUDGET;
+ }
+ tasklet_schedule (&np->rx_tasklet);
+ }
/* TxDMAComplete interrupt */
- if ((int_status & (TxDMAComplete|IntRequested))) {
+ if ((int_status & (TxDMAComplete|IntRequested|TxComplete))) {
int tx_status;
tx_status = readl (ioaddr + TxStatus);
if (tx_status & 0x01)
tx_error (dev, tx_status);
/* Free used tx skbuffs */
- rio_free_tx (dev, 1);
+ rio_free_tx (dev);
}
/* Handle uncommon events */
@@ -740,26 +795,28 @@ rio_interrupt (int irq, void *dev_instan
(HostError | LinkEvent | UpdateStats))
rio_error (dev, int_status);
}
- if (np->cur_tx != np->old_tx)
- writel (100, ioaddr + CountDown);
+ writel(5000, ioaddr + CountDown);
return IRQ_RETVAL(handled);
}
static void
-rio_free_tx (struct net_device *dev, int irq)
+rio_free_tx (struct net_device *dev)
{
struct netdev_private *np = netdev_priv(dev);
int entry = np->old_tx % TX_RING_SIZE;
- int tx_use = 0;
unsigned long flag = 0;
+ int irq = in_interrupt();
+
+ if (atomic_read(&np->tx_desc_lock))
+ return;
+ atomic_inc(&np->tx_desc_lock);
if (irq)
spin_lock(&np->tx_lock);
else
spin_lock_irqsave(&np->tx_lock, flag);
-
/* Free used tx skbuffs */
- while (entry != np->cur_tx) {
+ while (entry != np->cur_task) {
struct sk_buff *skb;
if (!(np->tx_ring[entry].status & TFDDone))
@@ -775,8 +832,8 @@ rio_free_tx (struct net_device *dev, int
np->tx_skbuff[entry] = NULL;
entry = (entry + 1) % TX_RING_SIZE;
- tx_use++;
}
+
if (irq)
spin_unlock(&np->tx_lock);
else
@@ -785,12 +842,19 @@ rio_free_tx (struct net_device *dev, int
/* If the ring is no longer full, clear tx_full and
call netif_wake_queue() */
-
- if (netif_queue_stopped(dev) &&
+ if (np->speed != 10) {
+ if (netif_queue_stopped(dev) &&
((np->cur_tx - np->old_tx + TX_RING_SIZE) % TX_RING_SIZE
- < TX_QUEUE_LEN - 1 || np->speed == 10)) {
+ < TX_QUEUE_LEN - 1)) {
netif_wake_queue (dev);
+ }
}
+ else {
+ if (netif_queue_stopped(dev) &&
+ np->cur_tx == np->old_tx)
+ netif_wake_queue(dev);
+ }
+ atomic_dec(&np->tx_desc_lock);
}
static void
@@ -821,7 +885,7 @@ tx_error (struct net_device *dev, int tx
break;
mdelay (1);
}
- rio_free_tx (dev, 1);
+ rio_free_tx (dev);
/* Reset TFDListPtr */
writel (np->tx_ring_dma +
np->old_tx * sizeof (struct netdev_desc),
@@ -855,28 +919,36 @@ tx_error (struct net_device *dev, int tx
writel (readw (dev->base_addr + MACCtrl) | TxEnable, ioaddr + MACCtrl);
}
-static int
-receive_packet (struct net_device *dev)
+static void rx_poll (unsigned long data)
{
- struct netdev_private *np = netdev_priv(dev);
+ struct net_device *dev = (struct net_device*) data;
+ struct netdev_private *np = (struct netdev_private *) dev->priv;
int entry = np->cur_rx % RX_RING_SIZE;
- int cnt = 30;
-
+ int cnt = np->budget;
+ long ioaddr = dev->base_addr;
+ int received = 0;
/* If RFDDone, FrameStart and FrameEnd set, there is a new packet in. */
while (1) {
struct netdev_desc *desc = &np->rx_ring[entry];
int pkt_len;
u64 frame_status;
- if (!(desc->status & RFDDone) ||
- !(desc->status & FrameStart) || !(desc->status & FrameEnd))
- break;
+ if (--cnt < 0) {
+ np->cur_rx = entry;
+ goto not_done;
+ }
/* Chip omits the CRC. */
pkt_len = le64_to_cpu (desc->status & 0xffff);
frame_status = le64_to_cpu (desc->status);
- if (--cnt < 0)
+
+ if (!(desc->status & RFDDone) ||
+ !(desc->status & FrameStart) || !(desc->status & FrameEnd))
break;
+
+
+ pci_dma_sync_single_for_device (np->pdev, desc->fraginfo, np->rx_buf_sz,
+ PCI_DMA_FROMDEVICE);
/* Update rx error statistics, drop packet. */
if (frame_status & RFS_Errors) {
np->stats.rx_errors++;
@@ -930,9 +1002,37 @@ receive_packet (struct net_device *dev)
dev->last_rx = jiffies;
}
entry = (entry + 1) % RX_RING_SIZE;
+ received++;
}
- spin_lock(&np->rx_lock);
np->cur_rx = entry;
+ refill_rx (dev);
+ np->budget -= received;
+ writew (DEFAULT_INTR, ioaddr + IntEnable);
+ return;
+
+not_done:
+ refill_rx (dev);
+ if (!received)
+ received = 1;
+ np->budget -= received;
+ if (np->budget <= 0)
+ np->budget = RX_BUDGET;
+ tasklet_schedule (&np->rx_tasklet);
+ return;
+}
+
+static void refill_rx (struct net_device *dev)
+{
+ struct netdev_private *np = dev->priv;
+ int entry;
+ int irq = in_interrupt();
+ unsigned long flag = 0;
+
+ if (irq)
+ spin_lock(&np->rx_lock);
+ else
+ spin_lock_irqsave(&np->rx_lock, flag);
+
/* Re-allocate skbuffs to fill the descriptor ring */
entry = np->old_rx;
while (entry != np->cur_rx) {
@@ -963,8 +1063,12 @@ receive_packet (struct net_device *dev)
entry = (entry + 1) % RX_RING_SIZE;
}
np->old_rx = entry;
- spin_unlock(&np->rx_lock);
- return 0;
+
+ if (irq)
+ spin_unlock(&np->rx_lock);
+ else
+ spin_unlock_irqrestore(&np->rx_lock, flag);
+ return;
}
static void
@@ -982,10 +1086,6 @@ rio_error (struct net_device *dev, int i
mii_get_media_pcs (dev);
else
mii_get_media (dev);
- if (np->speed == 1000)
- np->tx_coalesce = tx_coalesce;
- else
- np->tx_coalesce = 1;
macctrl = 0;
macctrl |= (np->vlan) ? AutoVLANuntagging : 0;
macctrl |= (np->full_duplex) ? DuplexSelect : 0;
@@ -1023,10 +1123,10 @@ get_stats (struct net_device *dev)
{
long ioaddr = dev->base_addr;
struct netdev_private *np = netdev_priv(dev);
+ unsigned int stat_reg;
#ifdef MEM_MAPPING
int i;
#endif
- unsigned int stat_reg;
/* All statistics registers need to be acknowledged,
else statistic overflow could cause problems */
@@ -1067,7 +1167,6 @@ get_stats (struct net_device *dev)
readw (ioaddr + BcstFramesXmtdOk);
readw (ioaddr + MacControlFramesXmtd);
readw (ioaddr + FramesWEXDeferal);
-
#ifdef MEM_MAPPING
for (i = 0x100; i <= 0x150; i += 4)
readl (ioaddr + i);
@@ -1086,7 +1185,7 @@ clear_stats (struct net_device *dev)
long ioaddr = dev->base_addr;
#ifdef MEM_MAPPING
int i;
-#endif
+#endif
/* All statistics registers need to be acknowledged,
else statistic overflow could cause problems */
@@ -1125,7 +1224,7 @@ clear_stats (struct net_device *dev)
#ifdef MEM_MAPPING
for (i = 0x100; i <= 0x150; i += 4)
readl (ioaddr + i);
-#endif
+#endif
readw (ioaddr + TxJumboFrames);
readw (ioaddr + RxJumboFrames);
readw (ioaddr + TCPCheckSumErrors);
@@ -1791,6 +1890,8 @@ rio_close (struct net_device *dev)
/* Stop Tx and Rx logics */
writel (TxDisable | RxDisable | StatsDisable, ioaddr + MACCtrl);
synchronize_irq (dev->irq);
+ tasklet_kill (&np->tx_tasklet);
+ tasklet_kill (&np->rx_tasklet);
free_irq (dev->irq, dev);
del_timer_sync (&np->timer);
^ permalink raw reply
* Re: [PATCH 9/15] pcmcia: hostap_cs.c - 0xc00f, 0x0000 conflicts with pcnet_cs
From: Dominik Brodowski @ 2006-07-03 8:56 UTC (permalink / raw)
To: Pavel Roskin; +Cc: netdev, linux-pcmcia, hostap, linville, jkmaline
In-Reply-To: <1151702323.21767.3.camel@dv>
Hi Pavel,
On Fri, Jun 30, 2006 at 05:18:43PM -0400, Pavel Roskin wrote:
> On Fri, 2006-06-30 at 21:59 +0200, Dominik Brodowski wrote:
> > - PCMCIA_DEVICE_MANF_CARD(0xc00f, 0x0000),
> > +/* PCMCIA_DEVICE_MANF_CARD(0xc00f, 0x0000), conflict with pcnet_cs */
>
> That's fine if we also add symbolic names. I could identify two
> hostap_cs compatible cards using this ID :
>
> card "Allied Telesyn AT-WCL452"
> version "Allied Telesyn", "AT-WCL452 Wireless PCMCIA Radio", "Ver.
> 1.00"
> manfid 0xc00f, 0x0000
> bind "hostap_cs"
>
> card "corega WL PCCL-11"
> version "corega", "WL PCCL-11", "ISL37300P", "RevA"
> manfid 0xc00f, 0x0000
> bind "hostap_cs"
Like this?
From: Dominik Brodowski <linux@dominikbrodowski.net>
Date: Sun, 2 Jul 2006 21:21:51 +0200
Subject: [PATCH] pcmcia: add more IDs to hostap_cs.c
As a replacement for the broad manufactor/card ID match we commented out
because of conflicts with pcnet_cs, add two product ID matches.
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
---
drivers/net/wireless/hostap/hostap_cs.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index 52e6df5..f39d735 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -886,6 +886,13 @@ static struct pcmcia_device_id hostap_cs
PCMCIA_DEVICE_PROD_ID123(
"U.S. Robotics", "IEEE 802.11b PC-CARD", "Version 01.02",
0xc7b8df9d, 0x1700d087, 0x4b74baa0),
+ PCMCIA_DEVICE_PROD_ID123(
+ "Allied Telesyn", "AT-WCL452 Wireless PCMCIA Radio",
+ "Ver. 1.00",
+ 0x5cd01705, 0x4271660f, 0x9d08ee12),
+ PCMCIA_DEVICE_PROD_ID1234(
+ "corega", "WL PCCL-11", "ISL37300P", "RevA",
+ 0xa21501a, 0x59868926, 0xc9049a39, 0x57a66194),
PCMCIA_DEVICE_NULL
};
MODULE_DEVICE_TABLE(pcmcia, hostap_cs_ids);
--
1.4.0
^ permalink raw reply related
* Re: [RFC NET 00/04]: Increase number of possible routing tables
From: Patrick McHardy @ 2006-07-03 9:23 UTC (permalink / raw)
To: netdev; +Cc: davem, greearb, Stephen Hemminger
In-Reply-To: <20060703075259.6286.67397.sendpatchset@localhost.localdomain>
[-- Attachment #1: Type: text/plain, Size: 1323 bytes --]
Patrick McHardy wrote:
> I took on Ben's challenge to increase the number of possible routing tables,
> these are the resulting patches.
>
> The table IDs are changed to 32 bit values and are contained in a new netlink
> routing attribute. For compatibility rtm_table in struct rtmsg can still be
> used to access the first 255 tables and contains the low 8 bit of the table
> ID in case of dumps. Unfortunately there are no invalid values for rtm_table,
> so the best userspace can do in case of a new iproute version that tries to
> access tables > 255 on an old kernel is to use RTM_UNSPEC (0) for rtm_table,
> which will make the kernel allocate an empty table instead of silently adding
> routes to a more or less random table. The iproute patch will follow shortly.
Actually that last part wasn't entirely true. The last couple of
releases of the kernel include the inet_check_attr function,
which (unwillingly) breaks with the tradition of ignoring
unknown attributes and signals an error on receiving the RTA_TABLE
attribute. So the iproute patch only includes the RTA_TABLE
attribute when the table ID is > 255, in which case rtm_table
is set to RT_TABLE_UNSPEC. Old kernels will still have the
behaviour I described above. The patch has been tested to
behave as expected on both patched and unpatched kernels.
[-- Attachment #2: x --]
[-- Type: text/plain, Size: 10047 bytes --]
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index 5e33a20..7573c62 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -238,9 +238,8 @@ enum rt_class_t
RT_TABLE_DEFAULT=253,
RT_TABLE_MAIN=254,
RT_TABLE_LOCAL=255,
- __RT_TABLE_MAX
};
-#define RT_TABLE_MAX (__RT_TABLE_MAX - 1)
+#define RT_TABLE_MAX 0xFFFFFFFF
@@ -263,6 +262,7 @@ enum rtattr_type_t
RTA_CACHEINFO,
RTA_SESSION,
RTA_MP_ALGO,
+ RTA_TABLE,
__RTA_MAX
};
diff --git a/include/rt_names.h b/include/rt_names.h
index 2d9ef10..07a10e0 100644
--- a/include/rt_names.h
+++ b/include/rt_names.h
@@ -5,7 +5,7 @@ #include <asm/types.h>
char* rtnl_rtprot_n2a(int id, char *buf, int len);
char* rtnl_rtscope_n2a(int id, char *buf, int len);
-char* rtnl_rttable_n2a(int id, char *buf, int len);
+char* rtnl_rttable_n2a(__u32 id, char *buf, int len);
char* rtnl_rtrealm_n2a(int id, char *buf, int len);
char* rtnl_dsfield_n2a(int id, char *buf, int len);
int rtnl_rtprot_a2n(__u32 *id, char *arg);
diff --git a/ip/ip_common.h b/ip/ip_common.h
index 1fe4a69..8b286b0 100644
--- a/ip/ip_common.h
+++ b/ip/ip_common.h
@@ -32,4 +32,12 @@ extern int do_multiaddr(int argc, char *
extern int do_multiroute(int argc, char **argv);
extern int do_xfrm(int argc, char **argv);
+static inline int rtm_get_table(struct rtmsg *r, struct rtattr **tb)
+{
+ __u32 table = r->rtm_table;
+ if (tb[RTA_TABLE])
+ table = *(__u32*) RTA_DATA(tb[RTA_TABLE]);
+ return table;
+}
+
extern struct rtnl_handle rth;
diff --git a/ip/iproute.c b/ip/iproute.c
index a43c09e..4ebe617 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -75,7 +75,8 @@ static void usage(void)
static struct
{
- int tb;
+ __u32 tb;
+ int cloned;
int flushed;
char *flushb;
int flushp;
@@ -125,6 +126,7 @@ int print_route(const struct sockaddr_nl
inet_prefix prefsrc;
inet_prefix via;
int host_len = -1;
+ __u32 table;
SPRINT_BUF(b1);
@@ -151,27 +153,23 @@ int print_route(const struct sockaddr_nl
host_len = 80;
if (r->rtm_family == AF_INET6) {
+ if (filter.cloned) {
+ if (!(r->rtm_flags&RTM_F_CLONED))
+ return 0;
+ }
if (filter.tb) {
- if (filter.tb < 0) {
- if (!(r->rtm_flags&RTM_F_CLONED))
- return 0;
- } else {
- if (r->rtm_flags&RTM_F_CLONED)
+ if (r->rtm_flags&RTM_F_CLONED)
+ return 0;
+ if (filter.tb == RT_TABLE_LOCAL) {
+ if (r->rtm_type != RTN_LOCAL)
return 0;
- if (filter.tb == RT_TABLE_LOCAL) {
- if (r->rtm_type != RTN_LOCAL)
- return 0;
- } else if (filter.tb == RT_TABLE_MAIN) {
- if (r->rtm_type == RTN_LOCAL)
- return 0;
- } else {
+ } else if (filter.tb == RT_TABLE_MAIN) {
+ if (r->rtm_type == RTN_LOCAL)
return 0;
- }
+ } else {
+ return 0;
}
}
- } else {
- if (filter.tb > 0 && filter.tb != r->rtm_table)
- return 0;
}
if ((filter.protocol^r->rtm_protocol)&filter.protocolmask)
return 0;
@@ -225,6 +223,10 @@ int print_route(const struct sockaddr_nl
memcpy(&prefsrc.data, RTA_DATA(tb[RTA_PREFSRC]), host_len/8);
}
+ table = rtm_get_table(r, tb);
+ if (r->rtm_family == AF_INET && filter.tb > 0 && filter.tb != table)
+ return 0;
+
if (filter.rdst.family && inet_addr_match(&dst, &filter.rdst, filter.rdst.bitlen))
return 0;
if (filter.mdst.family && filter.mdst.bitlen >= 0 &&
@@ -354,8 +356,8 @@ int print_route(const struct sockaddr_nl
fprintf(fp, "dev %s ", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_OIF])));
if (!(r->rtm_flags&RTM_F_CLONED)) {
- if (r->rtm_table != RT_TABLE_MAIN && !filter.tb)
- fprintf(fp, " table %s ", rtnl_rttable_n2a(r->rtm_table, b1, sizeof(b1)));
+ if (table != RT_TABLE_MAIN && !filter.tb)
+ fprintf(fp, " table %s ", rtnl_rttable_n2a(table, b1, sizeof(b1)));
if (r->rtm_protocol != RTPROT_BOOT && filter.protocolmask != -1)
fprintf(fp, " proto %s ", rtnl_rtprot_n2a(r->rtm_protocol, b1, sizeof(b1)));
if (r->rtm_scope != RT_SCOPE_UNIVERSE && filter.scopemask != -1)
@@ -840,7 +842,12 @@ #endif
NEXT_ARG();
if (rtnl_rttable_a2n(&tid, *argv))
invarg("\"table\" value is invalid\n", *argv);
- req.r.rtm_table = tid;
+ if (tid < 256)
+ req.r.rtm_table = tid;
+ else {
+ req.r.rtm_table = RT_TABLE_UNSPEC;
+ addattr32(&req.n, sizeof(req), RTA_TABLE, tid);
+ }
table_ok = 1;
} else if (strcmp(*argv, "dev") == 0 ||
strcmp(*argv, "oif") == 0) {
@@ -1022,7 +1029,7 @@ static int iproute_list_or_flush(int arg
filter.tb = tid;
} else if (matches(*argv, "cached") == 0 ||
matches(*argv, "cloned") == 0) {
- filter.tb = -1;
+ filter.cloned = 1;
} else if (strcmp(*argv, "tos") == 0 ||
matches(*argv, "dsfield") == 0) {
__u32 tos;
diff --git a/ip/iprule.c b/ip/iprule.c
index ccf699f..6caf573 100644
--- a/ip/iprule.c
+++ b/ip/iprule.c
@@ -27,6 +27,7 @@ #include <string.h>
#include "rt_names.h"
#include "utils.h"
+#include "ip_common.h"
extern struct rtnl_handle rth;
@@ -51,6 +52,7 @@ static int print_rule(const struct socka
struct rtmsg *r = NLMSG_DATA(n);
int len = n->nlmsg_len;
int host_len = -1;
+ __u32 table;
struct rtattr * tb[RTA_MAX+1];
char abuf[256];
SPRINT_BUF(b1);
@@ -129,8 +131,9 @@ static int print_rule(const struct socka
fprintf(fp, "iif %s ", (char*)RTA_DATA(tb[RTA_IIF]));
}
- if (r->rtm_table)
- fprintf(fp, "lookup %s ", rtnl_rttable_n2a(r->rtm_table, b1, sizeof(b1)));
+ table = rtm_get_table(r, tb);
+ if (table)
+ fprintf(fp, "lookup %s ", rtnl_rttable_n2a(table, b1, sizeof(b1)));
if (tb[RTA_FLOW]) {
__u32 to = *(__u32*)RTA_DATA(tb[RTA_FLOW]);
@@ -257,7 +260,12 @@ static int iprule_modify(int cmd, int ar
NEXT_ARG();
if (rtnl_rttable_a2n(&tid, *argv))
invarg("invalid table ID\n", *argv);
- req.r.rtm_table = tid;
+ if (tid < 256)
+ req.r.rtm_table = tid;
+ else {
+ req.r.rtm_table = RT_TABLE_UNSPEC;
+ addattr32(&req.n, sizeof(req), RTA_TABLE, tid);
+ }
table_ok = 1;
} else if (strcmp(*argv, "dev") == 0 ||
strcmp(*argv, "iif") == 0) {
diff --git a/lib/rt_names.c b/lib/rt_names.c
index 05046c2..2ff984a 100644
--- a/lib/rt_names.c
+++ b/lib/rt_names.c
@@ -23,6 +23,51 @@ #include <linux/rtnetlink.h>
#include "rt_names.h"
+struct rtnl_hash_entry {
+ struct rtnl_hash_entry *next;
+ unsigned int id;
+ char * name;
+};
+
+static void
+rtnl_hash_initialize(char *file, struct rtnl_hash_entry **hash, int size)
+{
+ struct rtnl_hash_entry *entry;
+ char buf[512];
+ FILE *fp;
+
+ fp = fopen(file, "r");
+ if (!fp)
+ return;
+ while (fgets(buf, sizeof(buf), fp)) {
+ char *p = buf;
+ int id;
+ char namebuf[512];
+
+ while (*p == ' ' || *p == '\t')
+ p++;
+ if (*p == '#' || *p == '\n' || *p == 0)
+ continue;
+ if (sscanf(p, "0x%x %s\n", &id, namebuf) != 2 &&
+ sscanf(p, "0x%x %s #", &id, namebuf) != 2 &&
+ sscanf(p, "%d %s\n", &id, namebuf) != 2 &&
+ sscanf(p, "%d %s #", &id, namebuf) != 2) {
+ fprintf(stderr, "Database %s is corrupted at %s\n",
+ file, p);
+ return;
+ }
+
+ if (id<0)
+ continue;
+ entry = malloc(sizeof(*entry));
+ entry->id = id;
+ entry->name = strdup(namebuf);
+ entry->next = hash[id & (size - 1)];
+ hash[id & (size - 1)] = entry;
+ }
+ fclose(fp);
+}
+
static void rtnl_tab_initialize(char *file, char **tab, int size)
{
char buf[512];
@@ -57,7 +102,6 @@ static void rtnl_tab_initialize(char *fi
fclose(fp);
}
-
static char * rtnl_rtprot_tab[256] = {
[RTPROT_UNSPEC] = "none",
[RTPROT_REDIRECT] ="redirect",
@@ -266,9 +310,14 @@ int rtnl_rtrealm_a2n(__u32 *id, char *ar
}
+static struct rtnl_hash_entry dflt_table_entry = { .id = 253, .name = "default" };
+static struct rtnl_hash_entry main_table_entry = { .id = 254, .name = "main" };
+static struct rtnl_hash_entry local_table_entry = { .id = 255, .name = "local" };
-static char * rtnl_rttable_tab[256] = {
- "unspec",
+static struct rtnl_hash_entry * rtnl_rttable_hash[256] = {
+ [253] = &dflt_table_entry,
+ [254] = &main_table_entry,
+ [255] = &local_table_entry,
};
static int rtnl_rttable_init;
@@ -276,26 +325,26 @@ static int rtnl_rttable_init;
static void rtnl_rttable_initialize(void)
{
rtnl_rttable_init = 1;
- rtnl_rttable_tab[255] = "local";
- rtnl_rttable_tab[254] = "main";
- rtnl_rttable_tab[253] = "default";
- rtnl_tab_initialize("/etc/iproute2/rt_tables",
- rtnl_rttable_tab, 256);
+ rtnl_hash_initialize("/etc/iproute2/rt_tables",
+ rtnl_rttable_hash, 256);
}
-char * rtnl_rttable_n2a(int id, char *buf, int len)
+char * rtnl_rttable_n2a(__u32 id, char *buf, int len)
{
- if (id<0 || id>=256) {
- snprintf(buf, len, "%d", id);
+ struct rtnl_hash_entry *entry;
+
+ if (id >= RT_TABLE_MAX) {
+ snprintf(buf, len, "%u", id);
return buf;
}
- if (!rtnl_rttable_tab[id]) {
- if (!rtnl_rttable_init)
- rtnl_rttable_initialize();
- }
- if (rtnl_rttable_tab[id])
- return rtnl_rttable_tab[id];
- snprintf(buf, len, "%d", id);
+ if (!rtnl_rttable_init)
+ rtnl_rttable_initialize();
+ entry = rtnl_rttable_hash[id & 255];
+ while (entry && entry->id != id)
+ entry = entry->next;
+ if (entry)
+ return entry->name;
+ snprintf(buf, len, "%u", id);
return buf;
}
@@ -303,8 +352,9 @@ int rtnl_rttable_a2n(__u32 *id, char *ar
{
static char *cache = NULL;
static unsigned long res;
+ struct rtnl_hash_entry *entry;
char *end;
- int i;
+ __u32 i;
if (cache && strcmp(cache, arg) == 0) {
*id = res;
@@ -315,9 +365,11 @@ int rtnl_rttable_a2n(__u32 *id, char *ar
rtnl_rttable_initialize();
for (i=0; i<256; i++) {
- if (rtnl_rttable_tab[i] &&
- strcmp(rtnl_rttable_tab[i], arg) == 0) {
- cache = rtnl_rttable_tab[i];
+ entry = rtnl_rttable_hash[i];
+ while (entry && strcmp(entry->name, arg))
+ entry = entry->next;
+ if (entry) {
+ cache = entry->name;
res = i;
*id = res;
return 0;
@@ -325,7 +377,7 @@ int rtnl_rttable_a2n(__u32 *id, char *ar
}
i = strtoul(arg, &end, 0);
- if (!end || end == arg || *end || i > 255)
+ if (!end || end == arg || *end || i > RT_TABLE_MAX)
return -1;
*id = i;
return 0;
^ permalink raw reply related
* Re: [RFC NET 00/04]: Increase number of possible routing tables
From: Patrick McHardy @ 2006-07-03 9:38 UTC (permalink / raw)
To: netdev; +Cc: davem, greearb, Stephen Hemminger
In-Reply-To: <44A8E211.4090005@trash.net>
Patrick McHardy wrote:
> Patrick McHardy wrote:
>
>>I took on Ben's challenge to increase the number of possible routing tables,
>>these are the resulting patches.
>>
>>The table IDs are changed to 32 bit values and are contained in a new netlink
>>routing attribute. For compatibility rtm_table in struct rtmsg can still be
>>used to access the first 255 tables and contains the low 8 bit of the table
>>ID in case of dumps. Unfortunately there are no invalid values for rtm_table,
>>so the best userspace can do in case of a new iproute version that tries to
>>access tables > 255 on an old kernel is to use RTM_UNSPEC (0) for rtm_table,
>>which will make the kernel allocate an empty table instead of silently adding
>>routes to a more or less random table. The iproute patch will follow shortly.
>
>
> Actually that last part wasn't entirely true. The last couple of
> releases of the kernel include the inet_check_attr function,
> which (unwillingly) breaks with the tradition of ignoring
> unknown attributes and signals an error on receiving the RTA_TABLE
> attribute. So the iproute patch only includes the RTA_TABLE
> attribute when the table ID is > 255, in which case rtm_table
> is set to RT_TABLE_UNSPEC. Old kernels will still have the
> behaviour I described above. The patch has been tested to
> behave as expected on both patched and unpatched kernels.
That wasn't entirely true either, its not inet_check_attr but
rtnetlink_rcv_message that aborts, and it does this on all
kernels. Somehow I thought unknown attributes were usually
ignored .. anyway, this is a good thing in this case as it
will avoid unexpected behaviour and simply return an error
on kernels where this feature is not available.
^ permalink raw reply
* Re: [IPROUTE]: Introduce tc monitor
From: Patrick McHardy @ 2006-07-03 10:13 UTC (permalink / raw)
To: hadi; +Cc: Stephen Hemminger, netdev, Thomas Graf
In-Reply-To: <1151860849.5093.259.camel@jzny2>
jamal wrote:
> Speaking of events reminded me of this.. Managed to get some quality
> time, so heres a patch against current iproute2 git that adds something
> useful.
>
> This patch adds ability to monitor tc events similar to ipmonitor.
> User runs "tc monitor" (without quotes) and watches events of
> addition, deletion and updates from qdiscs, classes, filters and
> actions as they happen.
Looks good to me. Speaking of actions, do you have any plans to
add help-texts? Currently the output is very confusing, whenever
I use them I need to google for examples.
$ tc action help
action usage improper
$ tc action add mirred help
mirred not supported help
bad action parsing
parse_action: bad value (2:mirred)!
Illegal "action"
Command "add" is unknown, try "tc action help".
^ permalink raw reply
* Re: [RFC DECNET 04/04]: Increase number of possible routing tables to 2^32
From: Steven Whitehouse @ 2006-07-03 11:20 UTC (permalink / raw)
To: Patrick McHardy; +Cc: davem, netdev, greearb, Patrick Caulfield
In-Reply-To: <20060703075305.6286.18061.sendpatchset@localhost.localdomain>
Hi,
On Mon, Jul 03, 2006 at 09:53:05AM +0200, Patrick McHardy wrote:
> [DECNET]: Increase number of possible routing tables to 2^32
>
> Increase the nubmer of possible routing tables to 2^32 by replacing the
> fixed sized array of tables by a hash table.
>
> Signed-off-by: Patrick McHardy <kaber@trash.net>
>
I've had a quick look though the DECnet parts of this and it looks good,
atthough I've not had a chance to test it at all. Please cc Patrick Caulfield
on DECnet changes,
Steve.
^ permalink raw reply
* Re: [RFC DECNET 04/04]: Increase number of possible routing tables to 2^32
From: Patrick McHardy @ 2006-07-03 11:21 UTC (permalink / raw)
To: Steven Whitehouse; +Cc: davem, netdev, greearb, Patrick Caulfield
In-Reply-To: <20060703112012.GA24742@souterrain.chygwyn.com>
Steven Whitehouse wrote:
> Hi,
>
> On Mon, Jul 03, 2006 at 09:53:05AM +0200, Patrick McHardy wrote:
>
>>[DECNET]: Increase number of possible routing tables to 2^32
>>
>>Increase the nubmer of possible routing tables to 2^32 by replacing the
>>fixed sized array of tables by a hash table.
>>
>>Signed-off-by: Patrick McHardy <kaber@trash.net>
>>
> I've had a quick look though the DECnet parts of this and it looks good,
> atthough I've not had a chance to test it at all. Please cc Patrick Caulfield
> on DECnet changes,
Thanks, will do on the next submission.
^ permalink raw reply
* Re: [RFC NET 00/04]: Increase number of possible routing tables
From: Thomas Graf @ 2006-07-03 11:34 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netdev, davem, greearb, Stephen Hemminger
In-Reply-To: <44A8E57E.4080805@trash.net>
* Patrick McHardy <kaber@trash.net> 2006-07-03 11:38
> That wasn't entirely true either, its not inet_check_attr but
> rtnetlink_rcv_message that aborts, and it does this on all
> kernels. Somehow I thought unknown attributes were usually
> ignored ..
This only applies to the first level of rtnetlink attributes,
when using rtattr_parse() unknown attributes are ignored.
Once this ugly rta_buf has disappeared it will become more
consistent.
Patches look good to me except that new iproute binaries
won't work with older kernels anymore?
^ permalink raw reply
* Re: [RFC NET 00/04]: Increase number of possible routing tables
From: Patrick McHardy @ 2006-07-03 11:36 UTC (permalink / raw)
To: Thomas Graf; +Cc: netdev, davem, greearb, Stephen Hemminger
In-Reply-To: <20060703113447.GU14627@postel.suug.ch>
Thomas Graf wrote:
> * Patrick McHardy <kaber@trash.net> 2006-07-03 11:38
>
>>That wasn't entirely true either, its not inet_check_attr but
>>rtnetlink_rcv_message that aborts, and it does this on all
>>kernels. Somehow I thought unknown attributes were usually
>>ignored ..
>
>
> This only applies to the first level of rtnetlink attributes,
> when using rtattr_parse() unknown attributes are ignored.
>
> Once this ugly rta_buf has disappeared it will become more
> consistent.
>
> Patches look good to me except that new iproute binaries
> won't work with older kernels anymore?
They will as long as this feature isn't used, the RTA_TABLE
attribute is only added to the message when the table id
is > 255. Worked fine during my tests, or are you refering
to something else?
^ permalink raw reply
* Re: [RFC NET 00/04]: Increase number of possible routing tables
From: Thomas Graf @ 2006-07-03 11:41 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netdev, davem, greearb, Stephen Hemminger
In-Reply-To: <44A90149.6090304@trash.net>
* Patrick McHardy <kaber@trash.net> 2006-07-03 13:36
> They will as long as this feature isn't used, the RTA_TABLE
> attribute is only added to the message when the table id
> is > 255. Worked fine during my tests, or are you refering
> to something else?
Perfect, I said nothing :)
^ permalink raw reply
* Re: [PATCH] d80211: Take lowlevel driver's channel change time into account during scanning.
From: Jiri Benc @ 2006-07-03 11:58 UTC (permalink / raw)
To: Gertjan van Wingerde; +Cc: netdev, jkmaline, linville
In-Reply-To: <44A6DDC6.1040005@kpnplanet.nl>
On Sat, 01 Jul 2006 22:40:38 +0200, Gertjan van Wingerde wrote:
> Make the dscape stack take the driver-supplied channel change time into
> account when actively scanning for networks.
> This particularly has been a problem in the rt2x00 driver, where
> configuration changes are done via a work-queue, and
> the subsequent channel changes failed due to the dscape stack scheduling
> a channel update while the previous one had not
> been performed yet, resulting in failed scans.
Your mail client converts tabs to spaces. Nevertheless, I applied the
patch to my git tree.
Thanks for fixing this,
Jiri
--
Jiri Benc
SUSE Labs
^ permalink raw reply
* [patch] bridge: br_dump_ifinfo index fix
From: Andrey Savochkin @ 2006-07-03 12:06 UTC (permalink / raw)
To: netdev; +Cc: Kirill Korotaev, Ben Greear, Stephen Hemminger
Fix for inability of br_dump_ifinfo to handle non-zero start index:
loop index never increases when entered with non-zero start.
Spotted by Kirill Korotaev.
Signed-off-by: Andrey Savochkin <saw@swsoft.com>
Cc: Kirill Korotaev <dev@openvz.org>
---
Against 2.6.17-mm6
--- ./net/bridge/br_netlink.c.vebridge-dump Wed Jun 21 18:53:18 2006
+++ ./net/bridge/br_netlink.c Mon Jul 3 14:31:03 2006
@@ -117,12 +117,13 @@ static int br_dump_ifinfo(struct sk_buff
continue;
if (idx < s_idx)
- continue;
+ goto cont;
err = br_fill_ifinfo(skb, p, NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq, RTM_NEWLINK, NLM_F_MULTI);
if (err <= 0)
break;
+cont:
++idx;
}
read_unlock(&dev_base_lock);
^ permalink raw reply
* Re: strict isolation of net interfaces
From: Herbert Poetzl @ 2006-07-03 13:36 UTC (permalink / raw)
To: Cedric Le Goater
Cc: Serge E. Hallyn, Sam Vilain, hadi, Alexey Kuznetsov, viro, devel,
dev, Andrew Morton, netdev, linux-kernel, Andrey Savochkin,
Daniel Lezcano, Ben Greear, Dave Hansen, Alexey Kuznetsov,
Eric W. Biederman
In-Reply-To: <44A4E72D.2060105@fr.ibm.com>
On Fri, Jun 30, 2006 at 10:56:13AM +0200, Cedric Le Goater wrote:
> Serge E. Hallyn wrote:
> >
> > The last one in your diagram confuses me - why foo0:1? I would
> > have thought it'd be
>
> just thinking aloud. I thought that any kind/type of interface could be
> mapped from host to guest.
>
> > host | guest 0 | guest 1 | guest2
> > ----------------------+-----------+-----------+--------------
> > | | | |
> > |-> l0 <-------+-> lo0 ... | lo0 | lo0
> > | | | |
> > |-> eth0 | | |
> > | | | |
> > |-> veth0 <--------+-> eth0 | |
> > | | | |
> > |-> veth1 <--------+-----------+-----------+-> eth0
> > | | | |
> > |-> veth2 <-------+-----------+-> eth0 |
> >
> > I think we should avoid using device aliases, as trying to do
> > something like giving eth0:1 to guest1 and eth0:2 to guest2
> > while hiding eth0:1 from guest2 requires some uglier code (as
> > I recall) than working with full devices. In other words,
> > if a namespace can see eth0, and eth0:2 exists, it should always
> > see eth0:2.
> >
> > So conceptually using a full virtual net device per container
> > certainly seems cleaner to me, and it seems like it should be
> > simpler by way of statistics gathering etc, but are there actually
> > any real gains? Or is the support for multiple IPs per device
> > actually enough?
> >
> > Herbert, is this basically how ngnet is supposed to work?
hard to tell, we have at least three ngnet prototypes
and basically all variants are covered there, from
separate interfaces which map to real ones to perfect
isolation of addresses assigned to global interfaces
IMHO the 'virtual' interface per guest is fine, as
the overhead and consumed resources are non critical
and it will definitely simplify handling for the
guest side
I'd really appreciate if we could find a solution which
allows both, isolation and virtualization, and if the
bridge scenario is as fast as a direct mapping, I'm
perfectly fine with a big bridge + ebtables to handle
security issues
best,
Herbert
^ permalink raw reply
* Re: [PATCH] xfrm6: move define/ifdef check order
From: Nicolas DICHTEL @ 2006-07-03 13:39 UTC (permalink / raw)
To: Randy.Dunlap; +Cc: netdev, davem
In-Reply-To: <20060702143611.dffe7b15.rdunlap@xenotime.net>
I point out this issue a long time ago ...
http://marc.theaimsgroup.com/?l=linux-netdev&m=113032946908126&w=2
Regards,
Nicolas
Randy.Dunlap a écrit :
> From: Randy Dunlap <rdunlap@xenotime.net>
>
> The first check for #ifdef XFRM6_TUNNEL_SPI_MAGIC needs to come after
> the optional #define of it, otherwise the variable won't be there
> for the rest of the code to use.
>
> Shouldn't that CONFIG_IPV6_XFRM6_TUNNEL_DEBUG be part of Kconfig
> or have its name changed?
>
> Signed-off-by: Randy Dunlap <rdunlap@xenotime.net>
> ---
> net/ipv6/xfrm6_tunnel.c | 8 ++++----
> 1 files changed, 4 insertions(+), 4 deletions(-)
>
> --- linux-2617-g20.orig/net/ipv6/xfrm6_tunnel.c
> +++ linux-2617-g20/net/ipv6/xfrm6_tunnel.c
> @@ -52,6 +52,10 @@
> # define X6TPRINTK3 X6TNOPRINTK
> #endif
>
> +#ifdef CONFIG_IPV6_XFRM6_TUNNEL_DEBUG
> +# define XFRM6_TUNNEL_SPI_MAGIC 0xdeadbeef
> +#endif
> +
> /*
> * xfrm_tunnel_spi things are for allocating unique id ("spi")
> * per xfrm_address_t.
> @@ -67,10 +71,6 @@ struct xfrm6_tunnel_spi {
> #endif
> };
>
> -#ifdef CONFIG_IPV6_XFRM6_TUNNEL_DEBUG
> -# define XFRM6_TUNNEL_SPI_MAGIC 0xdeadbeef
> -#endif
> -
> static DEFINE_RWLOCK(xfrm6_tunnel_spi_lock);
>
> static u32 xfrm6_tunnel_spi;
>
>
> ---
> -
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
>
>
^ permalink raw reply
* Re: strict isolation of net interfaces
From: Andrey Savochkin @ 2006-07-03 14:53 UTC (permalink / raw)
To: Sam Vilain, Serge E. Hallyn, Cedric Le Goater
Cc: hadi, Herbert Poetzl, Alexey Kuznetsov, viro, devel, dev,
Andrew Morton, netdev, linux-kernel, Daniel Lezcano, Ben Greear,
Dave Hansen, Alexey Kuznetsov, Eric W. Biederman
In-Reply-To: <44A49121.4050004@vilain.net>
Sam, Serge, Cedric,
On Fri, Jun 30, 2006 at 02:49:05PM +1200, Sam Vilain wrote:
> Serge E. Hallyn wrote:
> > The last one in your diagram confuses me - why foo0:1? I would
> > have thought it'd be
> >
> > host | guest 0 | guest 1 | guest2
> > ----------------------+-----------+-----------+--------------
> > | | | |
> > |-> l0 <-------+-> lo0 ... | lo0 | lo0
> > | | | |
> > |-> eth0 | | |
> > | | | |
> > |-> veth0 <--------+-> eth0 | |
> > | | | |
> > |-> veth1 <--------+-----------+-----------+-> eth0
> > | | | |
> > |-> veth2 <-------+-----------+-> eth0 |
> >
> > [...]
> >
> > So conceptually using a full virtual net device per container
> > certainly seems cleaner to me, and it seems like it should be
> > simpler by way of statistics gathering etc, but are there actually
> > any real gains? Or is the support for multiple IPs per device
> > actually enough?
> >
>
> Why special case loopback?
>
> Why not:
>
> host | guest 0 | guest 1 | guest2
> ----------------------+-----------+-----------+--------------
> | | | |
> |-> lo | | |
> | | | |
> |-> vlo0 <---------+-> lo | |
> | | | |
> |-> vlo1 <---------+-----------+-----------+-> lo
> | | | |
> |-> vlo2 <--------+-----------+-> lo |
> | | | |
> |-> eth0 | | |
> | | | |
> |-> veth0 <--------+-> eth0 | |
> | | | |
> |-> veth1 <--------+-----------+-----------+-> eth0
> | | | |
> |-> veth2 <-------+-----------+-> eth0 |
I still can't completely understand your direction of thoughts.
Could you elaborate on IP address assignment in your diagram, please? For
example, guest0 wants 127.0.0.1 and 192.168.0.1 addresses on its lo
interface, and 10.1.1.1 on its eth0 interface.
Does this diagram assume any local IP addresses on v* interfaces in the
"host"?
And the second question.
Are vlo0, veth0, etc. devices supposed to have hard_xmit routines?
Best regards
Andrey
^ 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