* RE
From: Dr.Fatih Baja @ 2011-12-20 3:51 UTC (permalink / raw)
Dear Friend,I have a very important and vital information for you which
will benefit us and you have to know about it. Please contact me through
my email so we can talk about it; Dr. Fatih Baja
^ permalink raw reply
* RE
From: Dr.Fatih Baja @ 2011-12-20 3:52 UTC (permalink / raw)
Dear Friend,I have a very important and vital information for you which
will benefit us and you have to know about it. Please contact me through
my email so we can talk about it; Dr. Fatih Baja
^ permalink raw reply
* RE
From: Dr.Fatih Baja @ 2011-12-20 3:53 UTC (permalink / raw)
Dear Friend,I have a very important and vital information for you which
will benefit us and you have to know about it. Please contact me through
my email so we can talk about it; Dr. Fatih Baja
^ permalink raw reply
* Re: An error in my HFSC sysadmin documentation
From: John A. Sullivan III @ 2011-12-20 3:54 UTC (permalink / raw)
To: netdev
In-Reply-To: <1323459325.3159.73.camel@denise.theartistscloset.com>
On Fri, 2011-12-09 at 14:35 -0500, John A. Sullivan III wrote:
> On Fri, 2011-12-09 at 13:24 -0500, John A. Sullivan III wrote:
> > Hello, all. As I mentioned, I'm trying to compile documentation on IFB
> > and HFSC from a sysadmin's perspective but I think I have an error in
> > the way I'm explaining how HFSC determines when to send which packet to
> > meet bandwidth and latency guarantees of the rt service curve. I'll
> > show where my math is breaking down in the hope someone can see and
> > correct my error.
> Argh!! After walking through it again, correcting my original error and
> using much closer rounding, I still hit a problem. I'll paste in the
> documentation I've written on deadline time and the walk through of how
> it works but, at the very end, Queue B's rt service curve is violated
> when it should not be:
>
> <snip>
> Deadline time is closely related to eligible time and is likewise
> measured against clock time. However, deadline time is measured against
> the end or tail of the packet, i.e., by when must we have finished
> sending this packet at the specified bandwidth in order to meet our
> packet delivery guarantees for bandwidth and latency. Once again,
> http://www.sonycsl.co.jp/~kjc/software/TIPS.txt has an excellent ASCII
> graphic for illustrating the relationship between eligible time measured
> at the beginning of the packet and deadline time measured from the end:
> bytes
> | /
> | /service curve
> | /
> next -->+ +----------------+
> packet | | /|
> length | | / |
> | | / |
> cumulative --> + +------------+ |
> bytes | /| |
> already | / | |
> sent | / | |
> / | |
> | |
> | |
> --------+---+--------------> time
> eligible deadline
> time
>
> This time, the slope is the rt service curve. The way in which HFSC
> chooses from among several different queues all with packets whose
> eligible time is greater than current clock time is almost identical to
> the way it chooses among backlogged queues with virtual time, viz., it
> chooses the packet with the lowest deadline time. Remember that the
> steeper the curve, the greater the bandwidth and the shorter the
> distance between eligible time and deadline time for the same sized
> packet.
> Let's walk through a real example. We have Queue A with VoIP traffic -
> small, 222 byte packets and an rt service curve bandwidth such that it
> takes 0.2ms to send its packets; that equates to roughly 8.88 Mbps ((222
> * 8)bits/0.0002s). Let's also assume that we have so much VoIP traffic
> that the queue is filled so we always have a VoIP packet asking to be
> dequeued. Queue B is sending FTP with large packets and an rt service
> curve rate such that each packet takes 2ms to send; this equates to
> 6.056 Mbps ((1514 * 8)bits/0.002s). Queue B is also completely full.
> Let's assume that the maximum bandwidth available is the sum of the
> guaranteed bandwidths, viz., 14.936 Mbps. This will allow us to
> calculated the progress of clock time, i.e., how long it actually takes
> to send each packet. Also remember that each packet has a 4 byte CRC,
> and 8 byte preamble, and a 12 byte interframe gap time at least in
> traditional Ethernet. Thus to transmit a packet in Queue A, we really
> need to transmit 246 bytes and, to transmit one in Queue B, we need to
> transmit 1538 bytes. Thus, the elapsed time to send a Queue A packet is
> (246 * 8)bits / 14,936,000(b/s) = 0.132ms and the time to transmit a
> Queue B packet is (1538 * 8)bits / 14,936,000(b/s) = 0.824ms. Sorry for
> all the math but this is what is inside the black box (and a very
> simplified version!).
> Let's assume that clock time (CT - the actual time) is 1000ms (not
> realistic but it makes the explanation easier!). The next packet queued
> in Queue A has an ET (eligible time) of 1000ms and the next packet in
> Queue B has an ET of 999ms, i.e., both are eligible to be sent. A less
> sophisticated traffic shaping algorithm would send the FTP packet first.
> However, HFSC calculates the deadline time (DT) for the packet in Queue
> A at 1000.2 (1000 + 0.2) and the deadline time for the packet in Queue B
> at 1001ms (999 + 2) so it sends A instead since it has the smaller DT.
> 0.132ms has elapsed in real time so CT is now 1000.132. The
> eligible/deadline times (ET/DT) for A and B respectively are
> 1000.2/1000.4 and 999/1001. Notice that A is no longer eligible to send
> because its ET > CT so B is serviced. 0.824ms has elapsed to send B's
> packet so CT is now 1000.956. ET/DT for A is still 1000.2/1000.4 but B
> has changed to 1001/1003. B just misses being eligible to send but A is
> eligible so A is sent. Elapsed time is 0.132, CT is now 1001.088, ET/DT
> for A is 1000.4/1000.6. Both A and B are eligible at the same time
> again as both their ETs <= CT. A's DT is less than B's DT so A is
> serviced.
> In fact, A will send 11 packets. Let's see the result after A sends 11
> packets. Elapsed time is 11* 0.132 = 1.452ms so clock time is 1002.54.
> A's ET/DT have incremented by 11 * 0.2 so they are 1002.6/1002.8. B's
> ET/DT have remained at 1001/1003. A is no longer eligible so the fact
> that its DT is less than B's DT is irrelevant. B is serviced.
>
> Here's the problem. B is serviced when clock time is 1002.54. It takes
> 0.824 to send B's packet so it has finished dequeueing at 1002.54 +
> 0.824 = 1003.364 which violates B's deadline time of 1003. That seems
> too big for a rounding error. Where am I wrong? Thanks - John
<snip>
Michal Soltys graciously pointed out to me off list that I had used the
full sized packet (CRC + preamble + IFG) to calculate clock time but did
not do so when calculating the overall bandwidth. Once I used the same
method on both, the numbers worked perfectly. Many thanks to Michal -
John
^ permalink raw reply
* Re: [PATCH 1/1] tcp: Replace constants with #define macros
From: Vijay Subramanian @ 2011-12-20 3:54 UTC (permalink / raw)
To: netdev
Cc: David S. Miller, Eric Dumazet, ilpo.jarvinen, H.K. Jerry Chu,
Vijay Subramanian
In-Reply-To: <1324351929-2588-1-git-send-email-subramanian.vijay@gmail.com>
On 19 December 2011 19:32, Vijay Subramanian
<subramanian.vijay@gmail.com> wrote:
> to record the state of SACK/FACK and DSACK for better readability and maintenance.
>
> Signed-off-by: Vijay Subramanian <subramanian.vijay@gmail.com>
> ---
> include/linux/tcp.h | 5 +++++
> include/net/tcp.h | 4 ++--
> net/ipv4/syncookies.c | 2 +-
> net/ipv4/tcp_input.c | 6 +++---
> 4 files changed, 11 insertions(+), 6 deletions(-)
>
> diff --git a/include/linux/tcp.h b/include/linux/tcp.h
> index 7f59ee9..874b043 100644
> --- a/include/linux/tcp.h
> +++ b/include/linux/tcp.h
> @@ -238,6 +238,11 @@ struct tcp_sack_block {
> u32 end_seq;
> };
>
> +/*These are used to set the sack_ok field in struct tcp_options_received */
> +#define SACK_SEEN (1 << 0) /*1 = peer is SACK capable, */
> +#define FACK_ENABLED (1 << 1) /*1 = FACK is enabled locally*/
> +#define DSACK_SEEN (1 << 2) /*1 = DSACK was received from peer*/
> +
> struct tcp_options_received {
> /* PAWS/RTTM data */
> long ts_recent_stamp;/* Time we stored ts_recent (for aging) */
> diff --git a/include/net/tcp.h b/include/net/tcp.h
> index a4f52e1..cbb943e 100644
> --- a/include/net/tcp.h
> +++ b/include/net/tcp.h
> @@ -773,12 +773,12 @@ static inline int tcp_is_reno(const struct tcp_sock *tp)
>
> static inline int tcp_is_fack(const struct tcp_sock *tp)
> {
> - return tp->rx_opt.sack_ok & 2;
> + return tp->rx_opt.sack_ok & FACK_ENABLED;
> }
>
> static inline void tcp_enable_fack(struct tcp_sock *tp)
> {
> - tp->rx_opt.sack_ok |= 2;
> + tp->rx_opt.sack_ok |= FACK_ENABLED;
> }
>
> static inline unsigned int tcp_left_out(const struct tcp_sock *tp)
> diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
> index 90f6544..dfba6a5 100644
> --- a/net/ipv4/syncookies.c
> +++ b/net/ipv4/syncookies.c
> @@ -245,7 +245,7 @@ bool cookie_check_timestamp(struct tcp_options_received *tcp_opt, bool *ecn_ok)
> if (!sysctl_tcp_timestamps)
> return false;
>
> - tcp_opt->sack_ok = (options >> 4) & 0x1;
> + tcp_opt->sack_ok = (options >> 4) & SACK_SEEN;
> *ecn_ok = (options >> 5) & 1;
> if (*ecn_ok && !sysctl_tcp_ecn)
> return false;
> diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
> index f131d92..5cbc788 100644
> --- a/net/ipv4/tcp_input.c
> +++ b/net/ipv4/tcp_input.c
> @@ -865,13 +865,13 @@ static void tcp_disable_fack(struct tcp_sock *tp)
> /* RFC3517 uses different metric in lost marker => reset on change */
> if (tcp_is_fack(tp))
> tp->lost_skb_hint = NULL;
> - tp->rx_opt.sack_ok &= ~2;
> + tp->rx_opt.sack_ok &= ~FACK_ENABLED;
> }
>
> /* Take a notice that peer is sending D-SACKs */
> static void tcp_dsack_seen(struct tcp_sock *tp)
> {
> - tp->rx_opt.sack_ok |= 4;
> + tp->rx_opt.sack_ok |= DSACK_SEEN;
> }
>
> /* Initialize metrics on socket. */
> @@ -3878,7 +3878,7 @@ void tcp_parse_options(const struct sk_buff *skb, struct tcp_options_received *o
> case TCPOPT_SACK_PERM:
> if (opsize == TCPOLEN_SACK_PERM && th->syn &&
> !estab && sysctl_tcp_sack) {
> - opt_rx->sack_ok = 1;
> + opt_rx->sack_ok = SACK_SEEN;
> tcp_sack_reset(opt_rx);
> }
> break;
> --
> 1.7.0.4
>
This patch was created against net-next tree and not -net tree.
Apologies for the error. Should I resend it?
Regards,
Vijay
^ permalink raw reply
* [ANN] compat-wireless for 3.2-rc6
From: Luis R. Rodriguez @ 2011-12-20 3:55 UTC (permalink / raw)
To: linux-kernel; +Cc: linux-wireless, netdev, linux-bluetooth
You all know what this is, only difference is we have a few
pending-stable patches not yet merged into Linus' tree but that are on
linux-next.git so we suck those in and provide an "-s" release. Below
are the statistics of both releases. We have an "-s" release [1] and a
vanilla release [2]. I'll note that I expect a few set of patches are
desirable to cherry pick from linux-next.git for a type of stable
release that we will support but for now I have yet to hear back which
patches those are. Feel free to reply here with the sha1sums you want
but please be specific of the linux-next.git tag you used.
For the -s release:
Updated from local tree: /home/mcgrof/linux-stable
Origin remote URL:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git
compat-wireless code metrics
814570 - Total upstream lines of code being pulled
2488 - backport code changes
2143 - backport code additions
345 - backport code deletions
8670 - backport from compat module
11158 - total backport code
1.3698 - % of code consists of backport work
57 - Code changes brought in from pending-stable
44 - Code additions brought in from pending-stable
13 - Code deletions brought in from pending-stable
0.0070 - % of code being cherry picked from pending-stable
Base tree: linux-stable.git
Base tree version: v3.2-rc6
compat-wireless release: compat-wireless-v3.2-rc6-3-s
For the vanilla release:
Updated from local tree: /home/mcgrof/linux-stable
Origin remote URL:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git
compat-wireless code metrics
814570 - Total upstream lines of code being pulled
2488 - backport code changes
2143 - backport code additions
345 - backport code deletions
8670 - backport from compat module
11158 - total backport code
1.3698 - % of code consists of backport work
Base tree: linux-stable.git
Base tree version: v3.2-rc6
compat-wireless release: compat-wireless-v3.2-rc6-3
[1] http://www.orbit-lab.org/kernel/compat-wireless-3-stable/v3.2/compat-wireless-3.2-rc6-3-s.tar.bz2
[2] http://www.orbit-lab.org/kernel/compat-wireless-3-stable/v3.2/compat-wireless-3.2-rc1-1.tar.bz2
^ permalink raw reply
* Re: [ANN] compat-wireless for 3.2-rc6
From: Luis R. Rodriguez @ 2011-12-20 3:58 UTC (permalink / raw)
To: linux-kernel; +Cc: linux-wireless, netdev, linux-bluetooth
In-Reply-To: <CAB=NE6WfBDqQzqxNaZm5mMhjyP2t7M-5t=+RA-A2JAKUKjmJzw@mail.gmail.com>
On Mon, Dec 19, 2011 at 7:55 PM, Luis R. Rodriguez <mcgrof@frijolero.org> wrote:
> [1] http://www.orbit-lab.org/kernel/compat-wireless-3-stable/v3.2/compat-wireless-3.2-rc6-3-s.tar.bz2
> [2] http://www.orbit-lab.org/kernel/compat-wireless-3-stable/v3.2/compat-wireless-3.2-rc1-1.tar.bz2
I messed up on the URL to the vanilla release [2] but here is the right one:
http://www.orbit-lab.org/kernel/compat-wireless-3-stable/v3.2/compat-wireless-3.2-rc6-3.tar.bz2
Luis
^ permalink raw reply
* Re: [PATCH] sctp: Do not account for sizeof(struct sk_buff) in estimated rwnd
From: Wei Yongjun @ 2011-12-20 5:00 UTC (permalink / raw)
To: tgraf; +Cc: vladislav.yasevich, linux-sctp, davem, netdev
Hi Thomas,
> On Mon, Dec 19, 2011 at 03:11:40PM +0100, Thomas Graf wrote:
>> Trying to reproduce this I found that with the sk_buff overhead removed,
>> the performance would improve significantly unless socket buffer limits
>> are increased.
> I believe this is likely to be misunderstood. What I meant is that by
> removing the sk_buff overhead and while using default socket buffer limits
> the performance increases as shown below. If socket buffers are enlarged
> performance differences fade until there is no longer any difference.
>
> Sorry for poor wording.
>
>> The following numbers have been gathered using a patched iperf
>> supporting SCTP over a live 1 Gbit ethernet network. The -l option
>> was used to limit DATA chunk sizes. The numbers listed are based on
>> the average of 3 test runs each. Default values have been used for
>> sk_(r|w)mem.
>>
>> Chunk
>> Size Unpatched No Overhead
>> -------------------------------------
>> 4 15.2 Kbit [!] 12.2 Mbit [!]
>> 8 35.8 Kbit [!] 26.0 Mbit [!]
>> 16 95.5 Kbit [!] 54.4 Mbit [!]
>> 32 106.7 Mbit 102.3 Mbit
>> 64 189.2 Mbit 188.3 Mbit
>> 128 331.2 Mbit 334.8 Mbit
>> 256 537.7 Mbit 536.0 Mbit
>> 512 766.9 Mbit 766.6 Mbit
>> 1024 810.1 Mbit 808.6 Mbit
I saw you discussed this with Vlad in old mail:
http://www.spinics.net/lists/linux-sctp/msg01365.html
You said you will update patch to include a per packet overhead,
but it does not include in this patch, what's wrong with in?
^ permalink raw reply
* [PATCH] IPv6 : add multicast routing verify which net_device is lo
From: Wang Xingtong @ 2011-12-20 6:13 UTC (permalink / raw)
To: netdev; +Cc: davem
In currently routing subsystem, when we lookup a multicast routing
to send muticast packets to outside, rt6_device_match will return
the rt6_info which it's match first. if we add a multicast route on
loopback devices beforce the others interface, rt6_device_match will
retrun the rt6_info which rt6i_dev->name is "lo". But, obviously,
we can't send a muticast packet to outside using loopback devices.
It case all multicast packets blocking.
Commit 4af04aba93f47699e disabled kernel add multicast route on lo
automatically. However, we can't surmise the routing-add order or
interdict add multicast routing on loopback devices in user space.
The bug still exist. So, i think more stronger routing subsystem is
necessary.
Signed-off-by: Wang xingtong <wangxingtong@cn.fujitsu.com>
---
net/ipv6/route.c | 19 ++++++++++++++++---
1 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index b582a0a..3871ef4 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -334,9 +334,16 @@ static inline struct rt6_info
*rt6_device_match(struct net *net,
struct rt6_info *local = NULL;
struct rt6_info *sprt;
- if (!oif && ipv6_addr_any(saddr))
+ if (!oif && ipv6_addr_any(saddr)){
+ if (unlikely(rt->rt6i_dev->flags & IFF_LOOPBACK &&
+ ipv6_addr_is_multicast(&rt->rt6i_dst.addr))){
+ rt=rt->dst.rt6_next;
+ goto match;
+ }
goto out;
+ }
+match:
for (sprt = rt; sprt; sprt = sprt->dst.rt6_next) {
struct net_device *dev = sprt->rt6i_dev;
@@ -355,9 +362,15 @@ static inline struct rt6_info
*rt6_device_match(struct net *net,
local = sprt;
}
} else {
- if (ipv6_chk_addr(net, saddr, dev,
- flags & RT6_LOOKUP_F_IFACE))
+ if (ipv6_addr_any(saddr)){
+ if (unlikely(rt->rt6i_dev->flags & IFF_LOOPBACK &&
+ ipv6_addr_is_multicast(&rt->rt6i_dst.addr))){
+ continue;
return sprt;
+ }
+ else if (ipv6_chk_addr(net, saddr, dev,
+ flags & RT6_LOOKUP_F_IFACE))
+ return sprt;
}
}
--
1.7.1
^ permalink raw reply related
* RE: [linux-firmware v6 2/4] rtl_nic: add new firmware for RTL8111F
From: hayeswang @ 2011-12-20 6:52 UTC (permalink / raw)
To: 'Ben Hutchings'; +Cc: dwmw2, romieu, netdev
In-Reply-To: <1324012690.2825.271.camel@deadeye>
Ben Hutchings [mailto:ben@decadent.org.uk]
> Sent: Friday, December 16, 2011 1:18 PM
> To: Hayeswang
> Cc: dwmw2@infradead.org; romieu@fr.zoreil.com; netdev@vger.kernel.org
> Subject: RE: [linux-firmware v6 2/4] rtl_nic: add new
> firmware for RTL8111F
>
> On Thu, 2011-11-17 at 20:16 +0800, hayeswang wrote:
> >
> > > -----Original Message-----
> > > From: Hayeswang [mailto:hayeswang@realtek.com]
> > > Sent: Wednesday, October 26, 2011 9:07 PM
> > > To: dwmw2@infradead.org; ben@decadent.org.uk
> > > Cc: romieu@fr.zoreil.com; netdev@vger.kernel.org; Hayeswang
> > > Subject: [linux-firmware v6 2/4] rtl_nic: add new firmware
> > > for RTL8111F
> > >
>
> Sorry Hayes, these were held up due to the rebuiling of kernel.org
> services.
>
> I already applied your earlier changes (v0.0.2 of the 8186E and 8186F
> firmware) locally. I have rebased this series of 4 patches on top of
> that, and pushed the result out. Please check that I got it right.
>
Thanks you very much. They are all right. Besides, should I change the
repository from
http://git.kernel.org/pub/scm/linux/kernel/git/dwmw2/linux-firmware.git
to
http://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git
for reference? I don't see any update for the original repository to which the
document of kernel says to submit firmware.
Best Regards,
Hayes
^ permalink raw reply
* Re: linux-3.0.x regression with ipv4 routes having mtu
From: Timo Teräs @ 2011-12-20 6:53 UTC (permalink / raw)
To: David Miller; +Cc: steffen.klassert, netdev
In-Reply-To: <20111219.161053.148816799233666803.davem@davemloft.net>
On 12/19/2011 11:10 PM, David Miller wrote:
> From: Steffen Klassert <steffen.klassert@secunet.com>
> Date: Fri, 16 Dec 2011 13:21:47 +0100
>
>> Subject: [PATCH] route: Initialize with the fib_metrics in the non default case
>>
>> We initialize the routing metrics with the cached values in
>> rt_init_metrics(). So if we have the metrics cached on the
>> inetpeer, we ignore the user configured fib_metrics. So
>> initialize the routing metrics with the fib_metrics if they
>> are different from dst_default_metrics.
>>
>> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
>
> The current behavior is intentional.
>
> Learned metrics should be used on all routes for which a inetpeer
> peer exists and the destination matches.
>
> There is no sane way to allow overrides.
>
> I'm pretty sure all of Timo's bugs will be fixed when you add the
> generation count for PMTU stuff.
I tried to look at the code to see how the fib MTU is handled, but I
don't think just generation count for PMTU would solve it.
My problem is that after inetpeer is created, the fib mtu is never
looked again at. The code that updates it, is in rt_init_metrics():
if (inet_metrics_new(peer))
memcpy(peer->metrics, fi->fib_metrics,
sizeof(u32) * RTAX_MAX);
Since the inetpeer there never gets recycled (peer lookup does not look
at generation count), the metrics are initialised from the fib exactly
once: when the inetpeer is initially created.
Now, if I have running system, there's traffic to specific inetpeer, and
later I add a system wide override route with mtu to that destination,
the updated mtu is never honoured. Because it comes from fib, and not
via the pmtu mechanism.
Or maybe I missed the place where that updated would happen?
It seems that the inetpeer.c comment that " The (inetpeer) nodes
contains long-living information about the peer which doesn't depend on
routes." does not hold true any more. Since mtu is (or at least used to
be) a route dependant value.
Perhaps we could then at least check the fib MTU and update inetpeer if
it's lower than what inetpeer used to be. This means of course that if
there's various routes to same destination (e.g. due to policy routing)
with different MTUs, only the smallest one would get used system wide.
But at least the route specific MTU would work then.
This is basically a problem for me, as I have userland code adding
dynamically per-destination mtu routes to workaround black hole ISP routers.
- Timo
^ permalink raw reply
* Re: [PATCH 1/2] net: fix assignment of 0/1 to bool variables.
From: David Miller @ 2011-12-20 6:56 UTC (permalink / raw)
To: rusty; +Cc: joe, netdev
In-Reply-To: <87iplcm7ya.fsf@rustcorp.com.au>
Applied.
^ permalink raw reply
* Re: [PATCH 2/2] module_param: make bool parameters really bool (net & drivers/net)
From: David Miller @ 2011-12-20 6:56 UTC (permalink / raw)
To: rusty; +Cc: joe, netdev
In-Reply-To: <87fwggm7fi.fsf@rustcorp.com.au>
From: Rusty Russell <rusty@rustcorp.com.au>
Date: Tue, 20 Dec 2011 10:38:01 +1030
> module_param(bool) used to counter-intuitively take an int. In
> fddd5201 (mid-2009) we allowed bool or int/unsigned int using a messy
> trick.
>
> It's time to remove the int/unsigned int option. For this version
> it'll simply give a warning, but it'll break next kernel version.
>
> (Thanks to Joe Perches for suggesting coccinelle for 0/1 -> true/false).
>
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: netdev@vger.kernel.org
> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Applied.
^ permalink raw reply
* Re: linux-3.0.x regression with ipv4 routes having mtu
From: David Miller @ 2011-12-20 7:03 UTC (permalink / raw)
To: timo.teras; +Cc: steffen.klassert, netdev
In-Reply-To: <4EF030D5.6040603@iki.fi>
From: Timo Teräs <timo.teras@iki.fi>
Date: Tue, 20 Dec 2011 08:53:09 +0200
> Or maybe I missed the place where that updated would happen?
It should happen on every routing cache lookup hit just like we
validate the peer for redirect information.
^ permalink raw reply
* Re: linux-3.0.x regression with ipv4 routes having mtu
From: Steffen Klassert @ 2011-12-20 7:18 UTC (permalink / raw)
To: David Miller; +Cc: timo.teras, netdev
In-Reply-To: <20111220.020355.942849877817117461.davem@davemloft.net>
On Tue, Dec 20, 2011 at 02:03:55AM -0500, David Miller wrote:
> From: Timo Teräs <timo.teras@iki.fi>
> Date: Tue, 20 Dec 2011 08:53:09 +0200
>
> > Or maybe I missed the place where that updated would happen?
>
> It should happen on every routing cache lookup hit just like we
> validate the peer for redirect information.
The problem is that we need to do a route cache lookup to
validate the peer informations. This does not happen if
somebody adds a new route. I tried already to add a pmtu specific
generation id and it appears to not solve the problem. We would
still need to overwrite the cached value if we add a route with mtu.
^ permalink raw reply
* Re: [PATCH] stmmac: reduce queue lengths if MTU is very large
From: Alessandro Rubini @ 2011-12-20 7:30 UTC (permalink / raw)
To: davem; +Cc: peppe.cavallaro, netdev, giancarlo.asnaghi
In-Reply-To: <20111219.163337.1185514300243434827.davem@davemloft.net>
> This change doesn't make sense.
I disagree, but you are the boss here, so I accept that.
> I'm not applying this, it just points out that the amount of reserved
> space in your SWIOMMU setup might be insufficient for this situation
> rather than something that should be tweaked in this driver.
Allocation of the queues is based on a parameter. If the parameter was
a size, instead of a lenght, all would be fine, wouldn't it? If you
agree, then this patch is turning the lenght into a size, in a way.
Now, how could we deal with the fact that the size explodes if the MTU
is increased? I don't want to reserve and waste 16MB of RAM for a
single device: the device won't even use them for non-jumbo setups. I
can use the parameter to shorten the queue in all cases, but this is
not good either.
What's your suggestion?
thanks
/alessandro
^ permalink raw reply
* Re: linux-3.0.x regression with ipv4 routes having mtu
From: Steffen Klassert @ 2011-12-20 8:03 UTC (permalink / raw)
To: David Miller; +Cc: timo.teras, netdev
In-Reply-To: <20111219.150903.108164273331779302.davem@davemloft.net>
On Mon, Dec 19, 2011 at 03:09:03PM -0500, David Miller wrote:
>
> Actually, adding yet another ID is pointless.
>
> Just get rid of redirect_genid, and use net->ipv4.rt_genid for all of
> the necessary purposes.
I already thought about such a solution, but is this really save?
What if somebody adds/deletes/flushes routes? rt_cache_invalidate()
is invoked and we increment net->ipv4.rt_genid. Then an icmp redirect
may appear and we call ip_rt_redirect() which sets the id on the
inetpeer to the new value of net->ipv4.rt_genid. After that,
ipv4_validate_peer() will find the generation id in proper state
and does not invalidate the learned pmtu value.
I think we could either have two separate generation ids for
pmtu and redirect handling, or we could handle both cases together
by accumulating check_peer_redir() and check_peer_pmtu() into a
check_peer() function. But the latter seems to be a bit too extensive
for a simple bug fix.
^ permalink raw reply
* Re: [PATCH] net/flow: remove sleeping and deferral mechanism from flow_cache_flush
From: Steffen Klassert @ 2011-12-20 8:23 UTC (permalink / raw)
To: David Miller; +Cc: madalin.bucur, eric.dumazet, netdev, timo.teras
In-Reply-To: <20110927.153132.900366550174236643.davem@davemloft.net>
On Tue, Sep 27, 2011 at 03:31:32PM -0400, David Miller wrote:
> From: David Miller <davem@davemloft.net>
> Date: Tue, 27 Sep 2011 15:28:36 -0400 (EDT)
>
> > afinfo->garbage_collect is the only other place __xfrm_garbage_collect
> > is referenced, and that is completely unused and should thus be deleted
> > (I'll take care of that in net-next).
>
> Nevermind I see how these are referenced directly via xfrm4_policy.c
> and xfrm6_policy.c, sigh...
Is there any progress in fixing this issue? I've seen this occasionally
on some of our production systems, so I fixed it for us in the meantime
with the patch below. I could submit this for inclusion if noone else
wants to fix it in a different manner.
------
net: Add a flow_cache_flush_deferred function
flow_cach_flush() might sleep but can be called from
atomic context via the xfrm garbage collector. So add
a flow_cache_flush_deferred() function and use this if
the xfrm garbage colector is invoked from within the
packet path.
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
include/net/flow.h | 1 +
net/core/flow.c | 12 ++++++++++++
net/xfrm/xfrm_policy.c | 18 ++++++++++++++----
3 files changed, 27 insertions(+), 4 deletions(-)
diff --git a/include/net/flow.h b/include/net/flow.h
index a094477..57f15a7 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -207,6 +207,7 @@ extern struct flow_cache_object *flow_cache_lookup(
u8 dir, flow_resolve_t resolver, void *ctx);
extern void flow_cache_flush(void);
+extern void flow_cache_flush_deferred(void);
extern atomic_t flow_cache_genid;
#endif
diff --git a/net/core/flow.c b/net/core/flow.c
index 8ae42de..e318c7e 100644
--- a/net/core/flow.c
+++ b/net/core/flow.c
@@ -358,6 +358,18 @@ void flow_cache_flush(void)
put_online_cpus();
}
+static void flow_cache_flush_task(struct work_struct *work)
+{
+ flow_cache_flush();
+}
+
+static DECLARE_WORK(flow_cache_flush_work, flow_cache_flush_task);
+
+void flow_cache_flush_deferred(void)
+{
+ schedule_work(&flow_cache_flush_work);
+}
+
static int __cpuinit flow_cache_cpu_prepare(struct flow_cache *fc, int cpu)
{
struct flow_cache_percpu *fcp = per_cpu_ptr(fc->percpu, cpu);
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 2118d64..9049a5c 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -2276,8 +2276,6 @@ static void __xfrm_garbage_collect(struct net *net)
{
struct dst_entry *head, *next;
- flow_cache_flush();
-
spin_lock_bh(&xfrm_policy_sk_bundle_lock);
head = xfrm_policy_sk_bundles;
xfrm_policy_sk_bundles = NULL;
@@ -2290,6 +2288,18 @@ static void __xfrm_garbage_collect(struct net *net)
}
}
+static void xfrm_garbage_collect(struct net *net)
+{
+ flow_cache_flush();
+ __xfrm_garbage_collect(net);
+}
+
+static void xfrm_garbage_collect_deferred(struct net *net)
+{
+ flow_cache_flush_deferred();
+ __xfrm_garbage_collect(net);
+}
+
static void xfrm_init_pmtu(struct dst_entry *dst)
{
do {
@@ -2422,7 +2432,7 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
if (likely(dst_ops->neigh_lookup == NULL))
dst_ops->neigh_lookup = xfrm_neigh_lookup;
if (likely(afinfo->garbage_collect == NULL))
- afinfo->garbage_collect = __xfrm_garbage_collect;
+ afinfo->garbage_collect = xfrm_garbage_collect_deferred;
xfrm_policy_afinfo[afinfo->family] = afinfo;
}
write_unlock_bh(&xfrm_policy_afinfo_lock);
@@ -2516,7 +2526,7 @@ static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void
switch (event) {
case NETDEV_DOWN:
- __xfrm_garbage_collect(dev_net(dev));
+ xfrm_garbage_collect(dev_net(dev));
}
return NOTIFY_DONE;
}
--
1.7.0.4
^ permalink raw reply related
* Re: [PATCH] net/flow: remove sleeping and deferral mechanism from flow_cache_flush
From: Timo Teräs @ 2011-12-20 8:41 UTC (permalink / raw)
To: Steffen Klassert; +Cc: David Miller, madalin.bucur, eric.dumazet, netdev
In-Reply-To: <20111220082332.GN6348@secunet.com>
On 12/20/2011 10:23 AM, Steffen Klassert wrote:
> On Tue, Sep 27, 2011 at 03:31:32PM -0400, David Miller wrote:
>> From: David Miller <davem@davemloft.net>
>> Date: Tue, 27 Sep 2011 15:28:36 -0400 (EDT)
>>
>>> afinfo->garbage_collect is the only other place __xfrm_garbage_collect
>>> is referenced, and that is completely unused and should thus be deleted
>>> (I'll take care of that in net-next).
>>
>> Nevermind I see how these are referenced directly via xfrm4_policy.c
>> and xfrm6_policy.c, sigh...
>
> Is there any progress in fixing this issue? I've seen this occasionally
> on some of our production systems, so I fixed it for us in the meantime
> with the patch below. I could submit this for inclusion if noone else
> wants to fix it in a different manner.
>
> ------
> net: Add a flow_cache_flush_deferred function
>
> flow_cach_flush() might sleep but can be called from
> atomic context via the xfrm garbage collector. So add
> a flow_cache_flush_deferred() function and use this if
> the xfrm garbage colector is invoked from within the
> packet path.
>
> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Acked-by: Timo Teräs <timo.teras@iki.fi>
I was first thinking if it made sense to run the local CPUs task
immediately on gc. But since all it does is queue the removed nodes to
the second gc that actually frees the dst's, it doesn't really make a
difference.
So this is probably as good as it gets.
^ permalink raw reply
* [patch 03/10] [PATCH] af_iucv: release reference to HS device
From: frank.blaschka @ 2011-12-20 8:56 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-s390, Ursula Braun
In-Reply-To: <20111220085626.924756639@de.ibm.com>
[-- Attachment #1: 602-af_iucv-release-skb-hs.diff --]
[-- Type: text/plain, Size: 4314 bytes --]
From: Ursula Braun <ursula.braun@de.ibm.com>
For HiperSockets transport skbs sent are bound to one of the
available HiperSockets devices. Add missing release of reference to
a HiperSockets device before freeing an skb.
Signed-off-by: Ursula Braun <ursula.braun@de.ibm.com>
Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com>
---
net/iucv/af_iucv.c | 37 ++++++++++++++++++++++++-------------
1 file changed, 24 insertions(+), 13 deletions(-)
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -130,6 +130,17 @@ static inline void low_nmcpy(unsigned ch
memcpy(&dst[8], src, 8);
}
+static void iucv_skb_queue_purge(struct sk_buff_head *list)
+{
+ struct sk_buff *skb;
+
+ while ((skb = skb_dequeue(list)) != NULL) {
+ if (skb->dev)
+ dev_put(skb->dev);
+ kfree_skb(skb);
+ }
+}
+
static int afiucv_pm_prepare(struct device *dev)
{
#ifdef CONFIG_PM_DEBUG
@@ -164,7 +175,7 @@ static int afiucv_pm_freeze(struct devic
read_lock(&iucv_sk_list.lock);
sk_for_each(sk, node, &iucv_sk_list.head) {
iucv = iucv_sk(sk);
- skb_queue_purge(&iucv->send_skb_q);
+ iucv_skb_queue_purge(&iucv->send_skb_q);
skb_queue_purge(&iucv->backlog_skb_q);
switch (sk->sk_state) {
case IUCV_SEVERED:
@@ -366,9 +377,7 @@ static int afiucv_hs_send(struct iucv_me
if (imsg)
memcpy(&phs_hdr->iucv_hdr, imsg, sizeof(struct iucv_message));
- rcu_read_lock();
- skb->dev = dev_get_by_index_rcu(net, sock->sk_bound_dev_if);
- rcu_read_unlock();
+ skb->dev = dev_get_by_index(net, sock->sk_bound_dev_if);
if (!skb->dev)
return -ENODEV;
if (!(skb->dev->flags & IFF_UP))
@@ -388,6 +397,7 @@ static int afiucv_hs_send(struct iucv_me
err = dev_queue_xmit(skb);
if (err) {
skb_unlink(nskb, &iucv->send_skb_q);
+ dev_put(nskb->dev);
kfree_skb(nskb);
} else {
atomic_sub(confirm_recv, &iucv->msg_recv);
@@ -481,16 +491,14 @@ static void iucv_sock_close(struct sock
blen = sizeof(struct af_iucv_trans_hdr) + ETH_HLEN;
skb = sock_alloc_send_skb(sk, blen, 1, &err);
if (skb) {
- skb_reserve(skb,
- sizeof(struct af_iucv_trans_hdr) +
- ETH_HLEN);
+ skb_reserve(skb, blen);
err = afiucv_hs_send(NULL, sk, skb,
AF_IUCV_FLAG_FIN);
}
sk->sk_state = IUCV_DISCONN;
sk->sk_state_change(sk);
}
- case IUCV_DISCONN:
+ case IUCV_DISCONN: /* fall through */
sk->sk_state = IUCV_CLOSING;
sk->sk_state_change(sk);
@@ -520,7 +528,7 @@ static void iucv_sock_close(struct sock
sk->sk_err = ECONNRESET;
sk->sk_state_change(sk);
- skb_queue_purge(&iucv->send_skb_q);
+ iucv_skb_queue_purge(&iucv->send_skb_q);
skb_queue_purge(&iucv->backlog_skb_q);
break;
@@ -739,7 +747,7 @@ static int iucv_sock_bind(struct socket
if (!memcmp(dev->perm_addr, uid, 8)) {
memcpy(iucv->src_name, sa->siucv_name, 8);
memcpy(iucv->src_user_id, sa->siucv_user_id, 8);
- sock->sk->sk_bound_dev_if = dev->ifindex;
+ sk->sk_bound_dev_if = dev->ifindex;
sk->sk_state = IUCV_BOUND;
iucv->transport = AF_IUCV_TRANS_HIPER;
if (!iucv->msglimit)
@@ -1225,6 +1233,8 @@ release:
return len;
fail:
+ if (skb->dev)
+ dev_put(skb->dev);
kfree_skb(skb);
out:
release_sock(sk);
@@ -1441,9 +1451,7 @@ static int iucv_sock_recvmsg(struct kioc
ETH_HLEN;
sskb = sock_alloc_send_skb(sk, blen, 1, &err);
if (sskb) {
- skb_reserve(sskb,
- sizeof(struct af_iucv_trans_hdr)
- + ETH_HLEN);
+ skb_reserve(sskb, blen);
err = afiucv_hs_send(NULL, sk, sskb,
AF_IUCV_FLAG_WIN);
}
@@ -2261,6 +2269,7 @@ static void afiucv_hs_callback_txnotify(
case TX_NOTIFY_OK:
__skb_unlink(this, list);
iucv_sock_wake_msglim(sk);
+ dev_put(this->dev);
kfree_skb(this);
break;
case TX_NOTIFY_PENDING:
@@ -2271,6 +2280,7 @@ static void afiucv_hs_callback_txnotify(
atomic_dec(&iucv->pendings);
if (atomic_read(&iucv->pendings) <= 0)
iucv_sock_wake_msglim(sk);
+ dev_put(this->dev);
kfree_skb(this);
break;
case TX_NOTIFY_UNREACHABLE:
@@ -2279,6 +2289,7 @@ static void afiucv_hs_callback_txnotify(
case TX_NOTIFY_GENERALERROR:
case TX_NOTIFY_DELAYED_GENERALERROR:
__skb_unlink(this, list);
+ dev_put(this->dev);
kfree_skb(this);
if (!list_empty(&iucv->accept_q))
sk->sk_state = IUCV_SEVERED;
^ permalink raw reply
* [patch 09/10] [PATCH] qeth: improve recovery during resource shortage
From: frank.blaschka @ 2011-12-20 8:56 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-s390
In-Reply-To: <20111220085626.924756639@de.ibm.com>
[-- Attachment #1: 610-qeth-resource-shortage.diff --]
[-- Type: text/plain, Size: 1372 bytes --]
From: Frank Blaschka <frank.blaschka@de.ibm.com>
In case there are no system resources to run a recovery we have to clear
recovery bitmasks so a further automatic or manual driven recovery can
fix up the device.
Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com>
---
drivers/s390/net/qeth_core_main.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -1329,6 +1329,7 @@ static int qeth_do_start_thread(struct q
static void qeth_start_kernel_thread(struct work_struct *work)
{
+ struct task_struct *ts;
struct qeth_card *card = container_of(work, struct qeth_card,
kernel_thread_starter);
QETH_CARD_TEXT(card , 2, "strthrd");
@@ -1336,9 +1337,15 @@ static void qeth_start_kernel_thread(str
if (card->read.state != CH_STATE_UP &&
card->write.state != CH_STATE_UP)
return;
- if (qeth_do_start_thread(card, QETH_RECOVER_THREAD))
- kthread_run(card->discipline.recover, (void *) card,
+ if (qeth_do_start_thread(card, QETH_RECOVER_THREAD)) {
+ ts = kthread_run(card->discipline.recover, (void *)card,
"qeth_recover");
+ if (IS_ERR(ts)) {
+ qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
+ qeth_clear_thread_running_bit(card,
+ QETH_RECOVER_THREAD);
+ }
+ }
}
static int qeth_setup_card(struct qeth_card *card)
^ permalink raw reply
* [patch 02/10] [PATCH] af_iucv: accelerate close for HS transport
From: frank.blaschka @ 2011-12-20 8:56 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-s390, Ursula Braun
In-Reply-To: <20111220085626.924756639@de.ibm.com>
[-- Attachment #1: 601-af_iucv-fast-close-hs.diff --]
[-- Type: text/plain, Size: 751 bytes --]
From: Ursula Braun <ursula.braun@de.ibm.com>
Closing an af_iucv socket may wait for confirmation of outstanding
send requests. This patch adds confirmation code for the new
HiperSockets transport.
Signed-off-by: Ursula Braun <ursula.braun@de.ibm.com>
Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com>
---
net/iucv/af_iucv.c | 7 +++++++
1 file changed, 7 insertions(+)
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -2293,6 +2293,13 @@ static void afiucv_hs_callback_txnotify(
}
spin_unlock_irqrestore(&list->lock, flags);
+ if (sk->sk_state == IUCV_CLOSING) {
+ if (skb_queue_empty(&iucv_sk(sk)->send_skb_q)) {
+ sk->sk_state = IUCV_CLOSED;
+ sk->sk_state_change(sk);
+ }
+ }
+
out_unlock:
bh_unlock_sock(sk);
}
^ permalink raw reply
* [patch 00/10] s390: network driver features and fixes for net-next
From: frank.blaschka @ 2011-12-20 8:56 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-s390
Hi Dave,
here are some s390 network driver features and fixes for net-next
shortlog:
Ursula Braun (8)
af_iucv: support ancillary data with HS transport
af_iucv: accelerate close for HS transport
af_iucv: release reference to HS device
af_iucv: remove unused timer infrastructure
af_iucv: get rid of state IUCV_SEVERED
qeth: suspicious rcu_dereference_check in recovery
qeth: forbid recovery during shutdown
netiucv: allow multiple interfaces to same peer
Frank Blaschka (1)
qeth: improve recovery during resource shortage
Einar Lueck (1)
qeth: recovery through asynchronous delivery
Thanks,
Frank
^ permalink raw reply
* [patch 08/10] [PATCH] netiucv: allow multiple interfaces to same peer
From: frank.blaschka @ 2011-12-20 8:56 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-s390, Ursula Braun
In-Reply-To: <20111220085626.924756639@de.ibm.com>
[-- Attachment #1: 608-netiucv-multi-if-peer.diff --]
[-- Type: text/plain, Size: 15365 bytes --]
From: Ursula Braun <ursula.braun@de.ibm.com>
The NETIUCV device driver allows to connect a Linux guest on z/VM to
another z/VM guest based on the z/VM communication facility IUCV.
Multiple output paths to different guests are possible, as well as
multiple input paths from different guests.
With this feature, you can configure multiple point-to-point NETIUCV
interfaces between your Linux on System z instance and another z/VM
guest.
Signed-off-by: Ursula Braun <ursula.braun@de.ibm.com>
Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com>
---
drivers/s390/net/netiucv.c | 217 +++++++++++++++++++++++++++------------------
1 file changed, 135 insertions(+), 82 deletions(-)
--- a/drivers/s390/net/netiucv.c
+++ b/drivers/s390/net/netiucv.c
@@ -63,6 +63,7 @@
#include <asm/io.h>
#include <asm/uaccess.h>
+#include <asm/ebcdic.h>
#include <net/iucv/iucv.h>
#include "fsm.h"
@@ -75,7 +76,7 @@ MODULE_DESCRIPTION ("Linux for S/390 IUC
* Debug Facility stuff
*/
#define IUCV_DBF_SETUP_NAME "iucv_setup"
-#define IUCV_DBF_SETUP_LEN 32
+#define IUCV_DBF_SETUP_LEN 64
#define IUCV_DBF_SETUP_PAGES 2
#define IUCV_DBF_SETUP_NR_AREAS 1
#define IUCV_DBF_SETUP_LEVEL 3
@@ -226,6 +227,7 @@ struct iucv_connection {
struct net_device *netdev;
struct connection_profile prof;
char userid[9];
+ char userdata[17];
};
/**
@@ -263,7 +265,7 @@ struct ll_header {
};
#define NETIUCV_HDRLEN (sizeof(struct ll_header))
-#define NETIUCV_BUFSIZE_MAX 32768
+#define NETIUCV_BUFSIZE_MAX 65537
#define NETIUCV_BUFSIZE_DEFAULT NETIUCV_BUFSIZE_MAX
#define NETIUCV_MTU_MAX (NETIUCV_BUFSIZE_MAX - NETIUCV_HDRLEN)
#define NETIUCV_MTU_DEFAULT 9216
@@ -288,7 +290,12 @@ static inline int netiucv_test_and_set_b
return test_and_set_bit(0, &priv->tbusy);
}
-static u8 iucvMagic[16] = {
+static u8 iucvMagic_ascii[16] = {
+ 0x30, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x30, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
+};
+
+static u8 iucvMagic_ebcdic[16] = {
0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40
};
@@ -301,18 +308,38 @@ static u8 iucvMagic[16] = {
*
* @returns The printable string (static data!!)
*/
-static char *netiucv_printname(char *name)
+static char *netiucv_printname(char *name, int len)
{
- static char tmp[9];
+ static char tmp[17];
char *p = tmp;
- memcpy(tmp, name, 8);
- tmp[8] = '\0';
- while (*p && (!isspace(*p)))
+ memcpy(tmp, name, len);
+ tmp[len] = '\0';
+ while (*p && ((p - tmp) < len) && (!isspace(*p)))
p++;
*p = '\0';
return tmp;
}
+static char *netiucv_printuser(struct iucv_connection *conn)
+{
+ static char tmp_uid[9];
+ static char tmp_udat[17];
+ static char buf[100];
+
+ if (memcmp(conn->userdata, iucvMagic_ebcdic, 16)) {
+ tmp_uid[8] = '\0';
+ tmp_udat[16] = '\0';
+ memcpy(tmp_uid, conn->userid, 8);
+ memcpy(tmp_uid, netiucv_printname(tmp_uid, 8), 8);
+ memcpy(tmp_udat, conn->userdata, 16);
+ EBCASC(tmp_udat, 16);
+ memcpy(tmp_udat, netiucv_printname(tmp_udat, 16), 16);
+ sprintf(buf, "%s.%s", tmp_uid, tmp_udat);
+ return buf;
+ } else
+ return netiucv_printname(conn->userid, 8);
+}
+
/**
* States of the interface statemachine.
*/
@@ -563,15 +590,18 @@ static int netiucv_callback_connreq(stru
{
struct iucv_connection *conn = path->private;
struct iucv_event ev;
+ static char tmp_user[9];
+ static char tmp_udat[17];
int rc;
- if (memcmp(iucvMagic, ipuser, 16))
- /* ipuser must match iucvMagic. */
- return -EINVAL;
rc = -EINVAL;
+ memcpy(tmp_user, netiucv_printname(ipvmid, 8), 8);
+ memcpy(tmp_udat, ipuser, 16);
+ EBCASC(tmp_udat, 16);
read_lock_bh(&iucv_connection_rwlock);
list_for_each_entry(conn, &iucv_connection_list, list) {
- if (strncmp(ipvmid, conn->userid, 8))
+ if (strncmp(ipvmid, conn->userid, 8) ||
+ strncmp(ipuser, conn->userdata, 16))
continue;
/* Found a matching connection for this path. */
conn->path = path;
@@ -580,6 +610,8 @@ static int netiucv_callback_connreq(stru
fsm_event(conn->fsm, CONN_EVENT_CONN_REQ, &ev);
rc = 0;
}
+ IUCV_DBF_TEXT_(setup, 2, "Connection requested for %s.%s\n",
+ tmp_user, netiucv_printname(tmp_udat, 16));
read_unlock_bh(&iucv_connection_rwlock);
return rc;
}
@@ -816,7 +848,7 @@ static void conn_action_connaccept(fsm_i
conn->path = path;
path->msglim = NETIUCV_QUEUELEN_DEFAULT;
path->flags = 0;
- rc = iucv_path_accept(path, &netiucv_handler, NULL, conn);
+ rc = iucv_path_accept(path, &netiucv_handler, conn->userdata , conn);
if (rc) {
IUCV_DBF_TEXT_(setup, 2, "rc %d from iucv_accept", rc);
return;
@@ -854,7 +886,7 @@ static void conn_action_conntimsev(fsm_i
IUCV_DBF_TEXT(trace, 3, __func__);
fsm_deltimer(&conn->timer);
- iucv_path_sever(conn->path, NULL);
+ iucv_path_sever(conn->path, conn->userdata);
fsm_newstate(fi, CONN_STATE_STARTWAIT);
}
@@ -867,9 +899,9 @@ static void conn_action_connsever(fsm_in
IUCV_DBF_TEXT(trace, 3, __func__);
fsm_deltimer(&conn->timer);
- iucv_path_sever(conn->path, NULL);
- dev_info(privptr->dev, "The peer interface of the IUCV device"
- " has closed the connection\n");
+ iucv_path_sever(conn->path, conn->userdata);
+ dev_info(privptr->dev, "The peer z/VM guest %s has closed the "
+ "connection\n", netiucv_printuser(conn));
IUCV_DBF_TEXT(data, 2,
"conn_action_connsever: Remote dropped connection\n");
fsm_newstate(fi, CONN_STATE_STARTWAIT);
@@ -886,8 +918,6 @@ static void conn_action_start(fsm_instan
IUCV_DBF_TEXT(trace, 3, __func__);
fsm_newstate(fi, CONN_STATE_STARTWAIT);
- IUCV_DBF_TEXT_(setup, 2, "%s('%s'): connecting ...\n",
- netdev->name, conn->userid);
/*
* We must set the state before calling iucv_connect because the
@@ -897,8 +927,11 @@ static void conn_action_start(fsm_instan
fsm_newstate(fi, CONN_STATE_SETUPWAIT);
conn->path = iucv_path_alloc(NETIUCV_QUEUELEN_DEFAULT, 0, GFP_KERNEL);
+ IUCV_DBF_TEXT_(setup, 2, "%s: connecting to %s ...\n",
+ netdev->name, netiucv_printuser(conn));
+
rc = iucv_path_connect(conn->path, &netiucv_handler, conn->userid,
- NULL, iucvMagic, conn);
+ NULL, conn->userdata, conn);
switch (rc) {
case 0:
netdev->tx_queue_len = conn->path->msglim;
@@ -908,13 +941,13 @@ static void conn_action_start(fsm_instan
case 11:
dev_warn(privptr->dev,
"The IUCV device failed to connect to z/VM guest %s\n",
- netiucv_printname(conn->userid));
+ netiucv_printname(conn->userid, 8));
fsm_newstate(fi, CONN_STATE_STARTWAIT);
break;
case 12:
dev_warn(privptr->dev,
"The IUCV device failed to connect to the peer on z/VM"
- " guest %s\n", netiucv_printname(conn->userid));
+ " guest %s\n", netiucv_printname(conn->userid, 8));
fsm_newstate(fi, CONN_STATE_STARTWAIT);
break;
case 13:
@@ -927,7 +960,7 @@ static void conn_action_start(fsm_instan
dev_err(privptr->dev,
"z/VM guest %s has too many IUCV connections"
" to connect with the IUCV device\n",
- netiucv_printname(conn->userid));
+ netiucv_printname(conn->userid, 8));
fsm_newstate(fi, CONN_STATE_CONNERR);
break;
case 15:
@@ -972,7 +1005,7 @@ static void conn_action_stop(fsm_instanc
netiucv_purge_skb_queue(&conn->collect_queue);
if (conn->path) {
IUCV_DBF_TEXT(trace, 5, "calling iucv_path_sever\n");
- iucv_path_sever(conn->path, iucvMagic);
+ iucv_path_sever(conn->path, conn->userdata);
kfree(conn->path);
conn->path = NULL;
}
@@ -1090,7 +1123,8 @@ dev_action_connup(fsm_instance *fi, int
fsm_newstate(fi, DEV_STATE_RUNNING);
dev_info(privptr->dev,
"The IUCV device has been connected"
- " successfully to %s\n", privptr->conn->userid);
+ " successfully to %s\n",
+ netiucv_printuser(privptr->conn));
IUCV_DBF_TEXT(setup, 3,
"connection is up and running\n");
break;
@@ -1452,45 +1486,72 @@ static ssize_t user_show(struct device *
struct netiucv_priv *priv = dev_get_drvdata(dev);
IUCV_DBF_TEXT(trace, 5, __func__);
- return sprintf(buf, "%s\n", netiucv_printname(priv->conn->userid));
+ return sprintf(buf, "%s\n", netiucv_printuser(priv->conn));
}
-static ssize_t user_write(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
+static int netiucv_check_user(const char *buf, size_t count, char *username,
+ char *userdata)
{
- struct netiucv_priv *priv = dev_get_drvdata(dev);
- struct net_device *ndev = priv->conn->netdev;
- char *p;
- char *tmp;
- char username[9];
- int i;
- struct iucv_connection *cp;
+ const char *p;
+ int i;
- IUCV_DBF_TEXT(trace, 3, __func__);
- if (count > 9) {
- IUCV_DBF_TEXT_(setup, 2,
- "%d is length of username\n", (int) count);
+ p = strchr(buf, '.');
+ if ((p && ((count > 26) ||
+ ((p - buf) > 8) ||
+ (buf + count - p > 18))) ||
+ (!p && (count > 9))) {
+ IUCV_DBF_TEXT(setup, 2, "conn_write: too long\n");
return -EINVAL;
}
- tmp = strsep((char **) &buf, "\n");
- for (i = 0, p = tmp; i < 8 && *p; i++, p++) {
- if (isalnum(*p) || (*p == '$')) {
- username[i]= toupper(*p);
+ for (i = 0, p = buf; i < 8 && *p && *p != '.'; i++, p++) {
+ if (isalnum(*p) || *p == '$') {
+ username[i] = toupper(*p);
continue;
}
- if (*p == '\n') {
+ if (*p == '\n')
/* trailing lf, grr */
break;
- }
IUCV_DBF_TEXT_(setup, 2,
- "username: invalid character %c\n", *p);
+ "conn_write: invalid character %02x\n", *p);
return -EINVAL;
}
while (i < 8)
username[i++] = ' ';
username[8] = '\0';
+ if (*p == '.') {
+ p++;
+ for (i = 0; i < 16 && *p; i++, p++) {
+ if (*p == '\n')
+ break;
+ userdata[i] = toupper(*p);
+ }
+ while (i > 0 && i < 16)
+ userdata[i++] = ' ';
+ } else
+ memcpy(userdata, iucvMagic_ascii, 16);
+ userdata[16] = '\0';
+ ASCEBC(userdata, 16);
+
+ return 0;
+}
+
+static ssize_t user_write(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct netiucv_priv *priv = dev_get_drvdata(dev);
+ struct net_device *ndev = priv->conn->netdev;
+ char username[9];
+ char userdata[17];
+ int rc;
+ struct iucv_connection *cp;
+
+ IUCV_DBF_TEXT(trace, 3, __func__);
+ rc = netiucv_check_user(buf, count, username, userdata);
+ if (rc)
+ return rc;
+
if (memcmp(username, priv->conn->userid, 9) &&
(ndev->flags & (IFF_UP | IFF_RUNNING))) {
/* username changed while the interface is active. */
@@ -1499,15 +1560,17 @@ static ssize_t user_write(struct device
}
read_lock_bh(&iucv_connection_rwlock);
list_for_each_entry(cp, &iucv_connection_list, list) {
- if (!strncmp(username, cp->userid, 9) && cp->netdev != ndev) {
+ if (!strncmp(username, cp->userid, 9) &&
+ !strncmp(userdata, cp->userdata, 17) && cp->netdev != ndev) {
read_unlock_bh(&iucv_connection_rwlock);
- IUCV_DBF_TEXT_(setup, 2, "user_write: Connection "
- "to %s already exists\n", username);
+ IUCV_DBF_TEXT_(setup, 2, "user_write: Connection to %s "
+ "already exists\n", netiucv_printuser(cp));
return -EEXIST;
}
}
read_unlock_bh(&iucv_connection_rwlock);
memcpy(priv->conn->userid, username, 9);
+ memcpy(priv->conn->userdata, userdata, 17);
return count;
}
@@ -1537,7 +1600,8 @@ static ssize_t buffer_write (struct devi
bs1 = simple_strtoul(buf, &e, 0);
if (e && (!isspace(*e))) {
- IUCV_DBF_TEXT_(setup, 2, "buffer_write: invalid char %c\n", *e);
+ IUCV_DBF_TEXT_(setup, 2, "buffer_write: invalid char %02x\n",
+ *e);
return -EINVAL;
}
if (bs1 > NETIUCV_BUFSIZE_MAX) {
@@ -1864,7 +1928,8 @@ static void netiucv_unregister_device(st
* Add it to the list of netiucv connections;
*/
static struct iucv_connection *netiucv_new_connection(struct net_device *dev,
- char *username)
+ char *username,
+ char *userdata)
{
struct iucv_connection *conn;
@@ -1893,6 +1958,8 @@ static struct iucv_connection *netiucv_n
fsm_settimer(conn->fsm, &conn->timer);
fsm_newstate(conn->fsm, CONN_STATE_INVALID);
+ if (userdata)
+ memcpy(conn->userdata, userdata, 17);
if (username) {
memcpy(conn->userid, username, 9);
fsm_newstate(conn->fsm, CONN_STATE_STOPPED);
@@ -1919,6 +1986,7 @@ out:
*/
static void netiucv_remove_connection(struct iucv_connection *conn)
{
+
IUCV_DBF_TEXT(trace, 3, __func__);
write_lock_bh(&iucv_connection_rwlock);
list_del_init(&conn->list);
@@ -1926,7 +1994,7 @@ static void netiucv_remove_connection(st
fsm_deltimer(&conn->timer);
netiucv_purge_skb_queue(&conn->collect_queue);
if (conn->path) {
- iucv_path_sever(conn->path, iucvMagic);
+ iucv_path_sever(conn->path, conn->userdata);
kfree(conn->path);
conn->path = NULL;
}
@@ -1985,7 +2053,7 @@ static void netiucv_setup_netdevice(stru
/**
* Allocate and initialize everything of a net device.
*/
-static struct net_device *netiucv_init_netdevice(char *username)
+static struct net_device *netiucv_init_netdevice(char *username, char *userdata)
{
struct netiucv_priv *privptr;
struct net_device *dev;
@@ -2004,7 +2072,7 @@ static struct net_device *netiucv_init_n
if (!privptr->fsm)
goto out_netdev;
- privptr->conn = netiucv_new_connection(dev, username);
+ privptr->conn = netiucv_new_connection(dev, username, userdata);
if (!privptr->conn) {
IUCV_DBF_TEXT(setup, 2, "NULL from netiucv_new_connection\n");
goto out_fsm;
@@ -2022,47 +2090,31 @@ out_netdev:
static ssize_t conn_write(struct device_driver *drv,
const char *buf, size_t count)
{
- const char *p;
char username[9];
- int i, rc;
+ char userdata[17];
+ int rc;
struct net_device *dev;
struct netiucv_priv *priv;
struct iucv_connection *cp;
IUCV_DBF_TEXT(trace, 3, __func__);
- if (count>9) {
- IUCV_DBF_TEXT(setup, 2, "conn_write: too long\n");
- return -EINVAL;
- }
-
- for (i = 0, p = buf; i < 8 && *p; i++, p++) {
- if (isalnum(*p) || *p == '$') {
- username[i] = toupper(*p);
- continue;
- }
- if (*p == '\n')
- /* trailing lf, grr */
- break;
- IUCV_DBF_TEXT_(setup, 2,
- "conn_write: invalid character %c\n", *p);
- return -EINVAL;
- }
- while (i < 8)
- username[i++] = ' ';
- username[8] = '\0';
+ rc = netiucv_check_user(buf, count, username, userdata);
+ if (rc)
+ return rc;
read_lock_bh(&iucv_connection_rwlock);
list_for_each_entry(cp, &iucv_connection_list, list) {
- if (!strncmp(username, cp->userid, 9)) {
+ if (!strncmp(username, cp->userid, 9) &&
+ !strncmp(userdata, cp->userdata, 17)) {
read_unlock_bh(&iucv_connection_rwlock);
- IUCV_DBF_TEXT_(setup, 2, "conn_write: Connection "
- "to %s already exists\n", username);
+ IUCV_DBF_TEXT_(setup, 2, "conn_write: Connection to %s "
+ "already exists\n", netiucv_printuser(cp));
return -EEXIST;
}
}
read_unlock_bh(&iucv_connection_rwlock);
- dev = netiucv_init_netdevice(username);
+ dev = netiucv_init_netdevice(username, userdata);
if (!dev) {
IUCV_DBF_TEXT(setup, 2, "NULL from netiucv_init_netdevice\n");
return -ENODEV;
@@ -2083,8 +2135,9 @@ static ssize_t conn_write(struct device_
if (rc)
goto out_unreg;
- dev_info(priv->dev, "The IUCV interface to %s has been"
- " established successfully\n", netiucv_printname(username));
+ dev_info(priv->dev, "The IUCV interface to %s has been established "
+ "successfully\n",
+ netiucv_printuser(priv->conn));
return count;
^ permalink raw reply
* [patch 01/10] [PATCH] af_iucv: support ancillary data with HS transport
From: frank.blaschka @ 2011-12-20 8:56 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-s390, Ursula Braun
In-Reply-To: <20111220085626.924756639@de.ibm.com>
[-- Attachment #1: 600-af_iucv-ancillary-hs.diff --]
[-- Type: text/plain, Size: 670 bytes --]
From: Ursula Braun <ursula.braun@de.ibm.com>
The AF_IUCV address family offers support for ancillary data.
This patch enables usage of ancillary data with the new
HiperSockets transport.
Signed-off-by: Ursula Braun <ursula.braun@de.ibm.com>
Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com>
---
net/iucv/af_iucv.c | 2 ++
1 file changed, 2 insertions(+)
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -2209,6 +2209,8 @@ static int afiucv_hs_rcv(struct sk_buff
break;
case 0:
/* plain data frame */
+ memcpy(CB_TRGCLS(skb), &trans_hdr->iucv_hdr.class,
+ CB_TRGCLS_LEN);
err = afiucv_hs_callback_rx(sk, skb);
break;
default:
^ 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