* Re: [net-next-2.6 PATCH] enic: Add timestamp to network interface stats
From: Stephen Hemminger @ 2011-08-05 4:42 UTC (permalink / raw)
To: Danny Guo; +Cc: davem, netdev
In-Reply-To: <20110805001124.32402.42919.stgit@savbu-pc100.cisco.com>
On Thu, 04 Aug 2011 17:11:24 -0700
Danny Guo <dannguo@cisco.com> wrote:
> From: Danny Guo <dannguo@cisco.com>
>
> This patch adds timestamps in ethtool stats. It makes it easier to provide scripts to users to calculate throughput, etc. It also allows software to synchronize timestamps with host time for correlating host events with stats collection.
>
> Signed-off-by: Danny Guo <dannguo@cisco.com>
> Signed-off-by: Vasanthy Kolluri <vkolluri@cisco.com>
> Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
> Signed-off-by: David Wang <dwang2@cisco.com>
The concept is okay, but don't like drivers doing device specific
things all the time.
> ---
> drivers/net/enic/enic.h | 2 +-
> drivers/net/enic/enic_main.c | 7 ++++++-
> drivers/net/enic/vnic_dev.c | 1 +
> drivers/net/enic/vnic_stats.h | 1 +
> 4 files changed, 9 insertions(+), 2 deletions(-)
>
>
> diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
> index ce76d9a..2e58bdc 100644
> --- a/drivers/net/enic/enic.h
> +++ b/drivers/net/enic/enic.h
> @@ -32,7 +32,7 @@
>
> #define DRV_NAME "enic"
> #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver"
> -#define DRV_VERSION "2.1.1.24"
> +#define DRV_VERSION "2.1.1.25"
> #define DRV_COPYRIGHT "Copyright 2008-2011 Cisco Systems, Inc"
>
> #define ENIC_BARS_MAX 6
> diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
> index 67a27cd..a3f61c1 100644
> --- a/drivers/net/enic/enic_main.c
> +++ b/drivers/net/enic/enic_main.c
> @@ -121,6 +121,8 @@ static const struct enic_stat enic_rx_stats[] = {
> static const unsigned int enic_n_tx_stats = ARRAY_SIZE(enic_tx_stats);
> static const unsigned int enic_n_rx_stats = ARRAY_SIZE(enic_rx_stats);
>
> +#define ENIC_TIMESTAMP_STAT_NAME "timestamp(ns)"
> +
> static int enic_is_dynamic(struct enic *enic)
> {
> return enic->pdev->device == PCI_DEVICE_ID_CISCO_VIC_ENET_DYN;
> @@ -224,6 +226,8 @@ static void enic_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
> memcpy(data, enic_rx_stats[i].name, ETH_GSTRING_LEN);
> data += ETH_GSTRING_LEN;
> }
> + memcpy(data, ENIC_TIMESTAMP_STAT_NAME, ETH_GSTRING_LEN);
> + data += ETH_GSTRING_LEN;
> break;
> }
> }
> @@ -232,7 +236,7 @@ static int enic_get_sset_count(struct net_device *netdev, int sset)
> {
> switch (sset) {
> case ETH_SS_STATS:
> - return enic_n_tx_stats + enic_n_rx_stats;
> + return enic_n_tx_stats + enic_n_rx_stats + 1;
> default:
> return -EOPNOTSUPP;
> }
> @@ -251,6 +255,7 @@ static void enic_get_ethtool_stats(struct net_device *netdev,
> *(data++) = ((u64 *)&vstats->tx)[enic_tx_stats[i].offset];
> for (i = 0; i < enic_n_rx_stats; i++)
> *(data++) = ((u64 *)&vstats->rx)[enic_rx_stats[i].offset];
> + *(data++) = vstats->timestamp_ns;
> }
>
> static u32 enic_get_msglevel(struct net_device *netdev)
> diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c
> index 8c4c8cf..656871a 100644
> --- a/drivers/net/enic/vnic_dev.c
> +++ b/drivers/net/enic/vnic_dev.c
> @@ -467,6 +467,7 @@ int vnic_dev_stats_dump(struct vnic_dev *vdev, struct vnic_stats **stats)
> if (!vdev->stats)
> return -ENOMEM;
> }
> + memset(vdev->stats, 0, sizeof(*vdev->stats));
No, reading stats should not clear them!
> *stats = vdev->stats;
> a0 = vdev->stats_pa;
> diff --git a/drivers/net/enic/vnic_stats.h b/drivers/net/enic/vnic_stats.h
> index 77750ec..9d5158d 100644
> --- a/drivers/net/enic/vnic_stats.h
> +++ b/drivers/net/enic/vnic_stats.h
> @@ -65,6 +65,7 @@ struct vnic_rx_stats {
> struct vnic_stats {
> struct vnic_tx_stats tx;
> struct vnic_rx_stats rx;
> + u64 timestamp_ns;
> };
Two problems: one is that you are exposing a timestamp in a random unit, and
the other problem is that is never set (at least in this code).
^ permalink raw reply
* Re: [PATCHv3] Bridge: Always send NETDEV_CHANGEADDR up on br MAC change.
From: Stephen Hemminger @ 2011-08-05 4:36 UTC (permalink / raw)
To: Andrei Warkentin; +Cc: netdev
In-Reply-To: <1312510625-26596-2-git-send-email-andreiw@motorola.com>
On Thu, 4 Aug 2011 21:17:05 -0500
Andrei Warkentin <andreiw@motorola.com> wrote:
Half ok, half not.
> diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
> index cf09fe5..ef18070 100644
> --- a/net/bridge/br_device.c
> +++ b/net/bridge/br_device.c
> @@ -162,6 +162,7 @@ static int br_set_mac_address(struct net_device *dev, void *p)
> br->flags |= BR_SET_MAC_ADDR;
> spin_unlock_bh(&br->lock);
>
> + call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
> return 0;
> }
This is unnecessary since already done by dev_set_mac_address.
> @@ -492,10 +493,13 @@ int br_del_if(struct net_bridge *br, struct net_device *dev)
> del_nbp(p);
>
> spin_lock_bh(&br->lock);
> - br_stp_recalculate_bridge_id(br);
> + changed_addr = br_stp_recalculate_bridge_id(br);
> br_features_recompute(br);
> spin_unlock_bh(&br->lock);
>
> + if (changed_addr)
> + call_netdevice_notifiers(NETDEV_CHANGEADDR, br->dev);
> +
> return 0;
> }
>
Good, I forgot that case.
> diff --git a/net/bridge/br_notify.c b/net/bridge/br_notify.c
> index 404d4e1..651eac3 100644
> --- a/net/bridge/br_notify.c
> +++ b/net/bridge/br_notify.c
> @@ -34,6 +34,7 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
> struct net_device *dev = ptr;
> struct net_bridge_port *p = br_port_get(dev);
> struct net_bridge *br;
> + bool changed_addr;
> int err;
>
> /* not a port of a bridge */
> @@ -51,8 +52,11 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
> case NETDEV_CHANGEADDR:
> spin_lock_bh(&br->lock);
> br_fdb_changeaddr(p, dev->dev_addr);
> - br_stp_recalculate_bridge_id(br);
> + changed_addr = br_stp_recalculate_bridge_id(br);
> spin_unlock_bh(&br->lock);
> +
> + if (changed_addr)
> + call_netdevice_notifiers(NETDEV_CHANGEADDR, br->dev);
> break;
>
> case NETDEV_CHANGE:
This is also fine.
> iff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
> index c0990ba..4528e9a 100644
> --- a/net/bridge/br_stp_if.c
> +++ b/net/bridge/br_stp_if.c
> @@ -213,7 +213,7 @@ bool br_stp_recalculate_bridge_id(struct net_bridge *br)
>
> /* user has chosen a value so keep it */
> if (br->flags & BR_SET_MAC_ADDR)
> - return;
> + return false;
>
> list_for_each_entry(p, &br->port_list, list) {
> if (addr == br_mac_zero ||
This is already in net-next.
^ permalink raw reply
* Re: [PATCH 2/3] net: Cap number of elements for sendmmsg
From: Tetsuo Handa @ 2011-08-05 4:29 UTC (permalink / raw)
To: anton, acme; +Cc: netdev, linux-security-module, davem, eparis, casey, mjt
In-Reply-To: <20110805000822.327910762@samba.org>
Anton Blanchard wrote:
> To limit the amount of time we can spend in sendmmsg, cap the
> number of elements to UIO_MAXIOV (currently 1024).
>
> For error handling an application using sendmmsg needs to retry at
> the first unsent message, so capping is simpler and requires less
> application logic than returning EINVAL.
>
> Signed-off-by: Anton Blanchard <anton@samba.org>
> Cc: stable <stable@kernel.org> [3.0+]
I think 1024 is a reasonable value.
But I also worry that programmers may wish to send more.
Apart from the upper limit for vlen argument of sendmmsg()/recvmmsg(),
we need to deal with stall problem (described below).
It may be possible to abuse sendmmsg() which was introduced in Linux 3.0 and
recvmmsg() which was introduced in Linux 2.6.33 for triggering CPU stall
warning.
I ran below program
---------- Test program start ----------
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <asm/unistd.h>
#include <errno.h>
#ifndef __NR_sendmmsg
#if defined( __PPC__)
#define __NR_sendmmsg 349
#elif defined(__x86_64__)
#define __NR_sendmmsg 307
#elif defined(__i386__)
#define __NR_sendmmsg 345
#else
#error __NR_sendmmsg not defined
#endif
#endif
struct mmsghdr {
struct msghdr msg_hdr;
unsigned int msg_len;
};
static inline int sendmmsg(int fd, struct mmsghdr *mmsg, unsigned vlen,
unsigned flags)
{
return syscall(__NR_sendmmsg, fd, mmsg, vlen, flags, NULL);
}
#define NUMBATCH (1048576 * 64)
int main(int argc, char *argv[])
{
const int fd = socket(AF_INET, SOCK_DGRAM, 0);
struct mmsghdr *datagrams;
unsigned int i;
struct iovec iovec = { };
struct sockaddr_in addr = { };
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
addr.sin_port = htons(10000);
datagrams = calloc(sizeof(*datagrams), NUMBATCH);
for (i = 0; i < NUMBATCH; ++i) {
datagrams[i].msg_hdr.msg_iov = &iovec;
datagrams[i].msg_hdr.msg_iovlen = 1;
datagrams[i].msg_hdr.msg_name = &addr;
datagrams[i].msg_hdr.msg_namelen = sizeof(addr);
}
printf("Calling sendmmsg()\n");
printf("%d\n", sendmmsg(fd, datagrams, NUMBATCH, 0));
printf("Done\n");
return 0;
}
---------- Test program end ----------
and got below output.
# time ./a.out
Calling sendmmsg()
INFO: rcu_sched_state detected stall on CPU 0 (t=15000 jiffies)
67108864
Done
real 2m48.736s
user 0m0.128s
sys 0m16.489s
If this application created threads that matches number of CPUs available, and
entered into sendmmsg(), the machine will hang for many seconds.
Also, signals are ignored when this application is in sendmmsg(). That is,
if this application is holding much RAM (like above program) and is selected by
OOM-killer, this application cannot be killed until returns from sendmmsg().
Applying below patch solves the stall message and signal delaying problem.
----------------------------------------
[PATCH] net: Fix sendmmsg() stall problem.
If the caller passed a huge value (e.g. 64M) to vlen argument of sendmmsg(),
the caller triggers "INFO: rcu_sched_state detected stall on CPU X" message
because there is no chance to call scheduler. Thus give a chance to call
scheduler and also check for pending signal.
Also, if the caller passed a value where IS_ERR() returns true (e.g. UINT_MAX),
the caller will get EOF and errno will be set to (e.g.) EPERM when all
datagrams are successfully sent. Thus, limit the max value of vlen to INT_MAX.
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Cc: stable <stable@kernel.org> [3.0+]
---
net/socket.c | 5 +++++
1 file changed, 5 insertions(+)
--- linux-3.0.orig/net/socket.c
+++ linux-3.0/net/socket.c
@@ -1999,6 +1999,8 @@ int __sys_sendmmsg(int fd, struct mmsghd
struct compat_mmsghdr __user *compat_entry;
struct msghdr msg_sys;
+ if ((int) vlen < 0)
+ return -EINVAL;
datagrams = 0;
sock = sockfd_lookup_light(fd, &err, &fput_needed);
@@ -2035,6 +2037,9 @@ int __sys_sendmmsg(int fd, struct mmsghd
if (err)
break;
++datagrams;
+ cond_resched();
+ if (signal_pending(current))
+ break;
}
out_put:
----------------------------------------
The situation is similar regaring recvmmsg(). Although recvmmsg() less likely
stalls than sendmmsg() does, it could happen if a huge number of datagrams are
in the socket's receive queue and the caller attempted to fetch all of them at
once. Thus, we may want below patch as well.
----------------------------------------
[PATCH] net: Fix recvmmsg() stall problem.
If the caller passed a huge value to vlen argument of recvmmsg() and there are
enough datagrams in the socket's receive queue, trying to pick up all at once
may trigger "INFO: rcu_sched_state detected stall on CPU X" message because
there is no chance to call scheduler. Thus give a chance to call scheduler and
also check for pending signal.
Also, if the caller passed a value where IS_ERR() returns true (e.g. UINT_MAX),
the caller will get EOF and errno will be set to (e.g.) EPERM when all
datagrams are successfully received. Thus, limit the max value of vlen to
INT_MAX.
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Cc: stable <stable@kernel.org> [2.6.33+]
---
net/socket.c | 5 +++++
1 file changed, 5 insertions(+)
--- linux-3.0.orig/net/socket.c
+++ linux-3.0/net/socket.c
@@ -2204,6 +2204,8 @@ int __sys_recvmmsg(int fd, struct mmsghd
struct msghdr msg_sys;
struct timespec end_time;
+ if ((int) vlen < 0)
+ return -EINVAL;
if (timeout &&
poll_select_set_timeout(&end_time, timeout->tv_sec,
timeout->tv_nsec))
@@ -2247,6 +2249,9 @@ int __sys_recvmmsg(int fd, struct mmsghd
if (err)
break;
++datagrams;
+ cond_resched();
+ if (signal_pending(current))
+ break;
/* MSG_WAITFORONE turns on MSG_DONTWAIT after one packet */
if (flags & MSG_WAITFORONE)
----------------------------------------
^ permalink raw reply
* Re: PHY down?
From: Edgar E. Iglesias @ 2011-08-05 4:13 UTC (permalink / raw)
To: Joakim Tjernlund; +Cc: Ben Hutchings, netdev
In-Reply-To: <OFEC77B7FA.1BCB17E8-ONC12578E0.0043754B-C12578E0.00441F36@transmode.se>
On Tue, Aug 02, 2011 at 02:24:04PM +0200, Joakim Tjernlund wrote:
> Ben Hutchings <bhutchings@solarflare.com> wrote on 2011/08/02 13:01:08:
> >
> > On Tue, 2011-08-02 at 11:24 +0200, Joakim Tjernlund wrote:
> > > I must be missing something obvious but I cannot find how
> > > to bring eth0's PHY down (link down) from user space.
> > > Tried various settings with ethtool and ifconfig eth0 down but it didn't help.
> >
> > If you configure an interface down, and if the interface is not used for
> > remote management, then some drivers will turn the PHY off. But there
> > is no general way to control this explicitly.
>
> OK, when to stop the PHY doesn't seem standardized. Seem logical to me
> to also turn off the PHY when interface is configured down. Perhaps this could
> be agreed upon?
> What does remote management mean? How do I identify if the I/F is used for remote management?
>
> Jocke
I'd rather see an explicit way of turning off the PHY. Downing the interface might be
useful without killing the PHY. I've seen PoE switches that kill you when you bring
the link down or reset the PHY after once beeing up, Down/up of interface might become
impossible in some environments if we would standardize on PHY off for interface down.
Maybe an explicit ethtool option?
Cheers
^ permalink raw reply
* Re: Fw: [Bug 39132] Starting with 3.0.0-rc6, masquerading seems to be broken.
From: David Hill @ 2011-08-05 4:09 UTC (permalink / raw)
To: Julian Anastasov, Florian Mickler; +Cc: netdev, David Miller
In-Reply-To: <alpine.LFD.2.00.1108042131040.1495@ja.ssi.bg>
Hello Julian,
I'm not using TPROXY and I've used a blank firewall with only
masquerading and reproduced the issue.
Nothing is in NAT/mangle nor OUTPUT but the rules mentionned in the
attached files to this bug.
Francis Whittle (Comment #18) has the same issue.
Thank you ,
Dave
----- Original Message -----
From: "Julian Anastasov" <ja@ssi.bg>
To: "Florian Mickler" <florian@mickler.org>
Cc: <hilld@binarystorm.net>; <netdev@vger.kernel.org>; "David Miller"
<davem@davemloft.net>
Sent: Thursday, August 04, 2011 2:38 PM
Subject: Re: Fw: [Bug 39132] Starting with 3.0.0-rc6, masquerading seems to
be broken.
>
> Hello,
>
> On Thu, 4 Aug 2011, Florian Mickler wrote:
>
>> Can someone take a look at this regression?
>>
>> Begin forwarded message:
>>
>> Date: Thu, 28 Jul 2011 04:51:12 GMT
>> From: bugzilla-daemon@bugzilla.kernel.org
>> To: florian@mickler.org
>> Subject: [Bug 39132] Starting with 3.0.0-rc6, masquerading seems to be
>> broken.
>>
>>
>> https://bugzilla.kernel.org/show_bug.cgi?id=39132
>
> So, problem points again to
> "Fix ip_route_me_harder triggering ip_rt_bug" ? May be
> David C. Hill or Florian can provide some information, eg. is
> tproxy used, what NAT rules are used, any rules in OUTPUT
> hooks (NAT/mangle) and which packets are dropped.
>
> Regards
>
> --
> Julian Anastasov <ja@ssi.bg>
>
> --
> This message has been scanned for viruses and
> dangerous content by MailScanner, and is
> believed to be clean.
>
>
>
>
> -----
> No virus found in this message.
> Checked by AVG - www.avg.com
> Version: 10.0.1390 / Virus Database: 1518/3810 - Release Date: 08/04/11
>
--
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.
^ permalink raw reply
* Re: [PATCH 1/3] net: sendmmsg should only return an error if no messages were sent
From: Tetsuo Handa @ 2011-08-05 3:57 UTC (permalink / raw)
To: acme, rdenis, swhiteho; +Cc: netdev
In-Reply-To: <20110805000822.240895823@samba.org>
Anton Blanchard wrote:
> sendmmsg uses a similar error return strategy as recvmmsg but it
> turns out to be a confusing way to communicate errors.
>
> The current code stores the error code away and returns it on the next
> sendmmsg call. This means a call with completely valid arguments could
> get an error from a previous call.
>
> Change things so we only return an error if no datagrams could be sent.
> If less than the requested number of messages were sent, the application
> must retry starting at the first failed one and if the problem is
> persistent the error will be returned.
>
> This matches the behaviour of other syscalls like read/write - it
> is not an error if less than the requested number of elements are sent.
OK. David S. Miller suggested this behavior and Anton Blanchard agreed with
this behavior.
Quoting from commit a2e27255 "net: Introduce recvmmsg socket syscall":
| . R?mi Denis-Courmont & Steven Whitehouse: If we receive N < vlen
| datagrams and then recvmsg returns an error, recvmmsg will return
| the successfully received datagrams, store the error and return it
| in the next call.
R?mi Denis-Courmont, Steven Whitehouse and Arnaldo Carvalho de Melo, do you
want to change recvmmsg()'s behaviour as well?
^ permalink raw reply
* Re: return of ip_rt_bug()
From: Tom London @ 2011-08-05 2:45 UTC (permalink / raw)
To: Julian Anastasov; +Cc: Dave Jones, netdev
In-Reply-To: <CAFiZG+W9-vV6o9EbuVEwztW4sQ1QV-MxD+xCHFw7TbNAryzN6A@mail.gmail.com>
On Thu, Aug 4, 2011 at 10:48 AM, Tom London <selinux@gmail.com> wrote:
> On Thu, Aug 4, 2011 at 10:37 AM, Julian Anastasov <ja@ssi.bg> wrote:
>>
>> Hello,
>>
>> On Thu, 4 Aug 2011, Tom London wrote:
>>
>>> How else can I help?
>>
>> From your bug report at
>> https://bugzilla.redhat.com/show_bug.cgi?id=712632 I see that
>> the application is xsane, "Manufacturer: EPSON". I downloaded
>> some sources and in sane-backends-git20110804/sanei/sanei_udp.c
>> I see some UDP usage.
>>
>> For example, sane-backends-git20110804/backend/epson2.c
>> calls sanei_udp_open_broadcast (UDP socket with SO_BROADCAST).
>> The socket is not bound, not connected, application sends packet to
>> 255.255.255.255:3289 in blocking mode and waits for reply for
>> 1 second. It is done for "net autodiscovery" config. As the socket
>> is not bound, kernel should search source address for every packet.
>> Nothing special so far. Not sure why your report has 2 oopses in
>> period of 1 second, may be config has 2 lines "net autodiscovery"
>> and 2 packets are sent?
>>
>> Your first report was for 192.168.2.5 but
>> I don't see the IP from your last report that is with
>> kernel-3.1.0-0.rc0.git12.1.fc17.x86_64. Now you show local IP is
>> 192.168.2.6. Do you have 192.168.2.5 as local IP, what shows
>> 'ip addr' ?
>>
>> Can you confirm that the IP you see in oops is always
>> configured (ip addr). Or may be it comes from DHCP and now is
>> 192.168.2.6?
>>
>> Can you start 'ip monitor' in one console while
>> attaching the USB device, so that we can know if any IP
>> addresses are reconfigured due to some events. For example,
>> script that restarts DHCP.
>>
>> Regards
>>
>> --
>> Julian Anastasov <ja@ssi.bg>
>>
>
> Sure. I'll set this up when I get back home this evening.
>
> Not sure about the 192.168.2.5 vs 192.168.2.6 confusion. My laptop
> is connected to a Belkin router, and uses DHCP. I sometimes have the
> wireless interface connected as well, so perhaps this sometimes occurs
> when only the wired NIC is connected and sometimes when both the wired
> and wireless NICs are connected? I'll also see if I can uncover any
> DHCP history
>
> I'll try to follow the above instructions, and will report out about 8PM PDT.
>
> tom
OK. Booted up. Here is what 'ifconfig' says:
[root@tlondon ~]# ifconfig
eth0 Link encap:Ethernet HWaddr 00:1F:16:0B:56:A8
inet addr:192.168.2.6 Bcast:192.168.2.255 Mask:255.255.255.0
inet6 addr: fe80::21f:16ff:fe0b:56a8/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:2101 errors:0 dropped:0 overruns:0 frame:0
TX packets:1814 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1719912 (1.6 MiB) TX bytes:268153 (261.8 KiB)
Interrupt:20 Memory:f2600000-f2620000
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:79 errors:0 dropped:0 overruns:0 frame:0
TX packets:79 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:19162 (18.7 KiB) TX bytes:19162 (18.7 KiB)
virbr0 Link encap:Ethernet HWaddr 52:54:00:B9:89:30
inet addr:192.168.122.1 Bcast:192.168.122.255 Mask:255.255.255.0
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)
wlan0 Link encap:Ethernet HWaddr 00:21:5D:AC:C6:92
inet addr:192.168.2.9 Bcast:192.168.2.255 Mask:255.255.255.0
inet6 addr: fe80::221:5dff:feac:c692/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:22 errors:0 dropped:0 overruns:0 frame:0
TX packets:26 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:2767 (2.7 KiB) TX bytes:5705 (5.5 KiB)
[root@tlondon ~]#
'ip addr' says:
[root@tlondon ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast
state UP qlen 1000
link/ether 00:1f:16:0b:56:a8 brd ff:ff:ff:ff:ff:ff
inet 192.168.2.6/24 brd 192.168.2.255 scope global eth0
inet6 fe80::21f:16ff:fe0b:56a8/64 scope link
valid_lft forever preferred_lft forever
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
link/ether 00:21:5d:ac:c6:92 brd ff:ff:ff:ff:ff:ff
inet 192.168.2.9/24 brd 192.168.2.255 scope global wlan0
inet6 fe80::221:5dff:feac:c692/64 scope link
valid_lft forever preferred_lft forever
4: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue
state DOWN
link/ether 52:54:00:b9:89:30 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
5: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc noop master virbr0
state DOWN qlen 500
link/ether 52:54:00:b9:89:30 brd ff:ff:ff:ff:ff:ff
[root@tlondon ~]#
I ran 'ip monitor' in one terminal window, ran 'inotail -f
/var/log/messages' in another, started 'gimp', and
did a 'create from usb:epson'.
I got this in the 'ip monitor' window:
[root@tlondon ~]# ip monitor
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP>
link/ether
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP>
link/ether
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP>
link/ether
192.168.2.1 dev eth0 lladdr 00:1c:df:e2:3e:e9 STALE
I got this in the 'inotify -f /var/log/messages' window:
Aug 4 19:29:27 tlondon kernel: [ 305.997223] usb 3-1: new full speed
USB device number 2 using uhci_hcd
Aug 4 19:29:28 tlondon kernel: [ 306.581320] usb 3-1: New USB device
found, idVendor=04b8, idProduct=010a
Aug 4 19:29:28 tlondon kernel: [ 306.581332] usb 3-1: New USB device
strings: Mfr=1, Product=2, SerialNumber=0
Aug 4 19:29:28 tlondon kernel: [ 306.581340] usb 3-1: Product: Perfection1640
Aug 4 19:29:28 tlondon kernel: [ 306.581346] usb 3-1: Manufacturer: EPSON
Aug 4 19:29:28 tlondon mtp-probe: checking bus 3, device 2:
"/sys/devices/pci0000:00/0000:00:1a.0/usb3/3-1"
Aug 4 19:29:28 tlondon mtp-probe: bus: 3, device: 2 was not an MTP device
Aug 4 19:30:07 tlondon kernel: [ 345.300960] ------------[ cut here
]------------
Aug 4 19:30:07 tlondon kernel: [ 345.300977] WARNING: at
net/ipv4/route.c:1714 ip_rt_bug+0x5c/0x62()
Aug 4 19:30:07 tlondon kernel: [ 345.300984] Hardware name: 74585FU
Aug 4 19:30:07 tlondon kernel: [ 345.300989] Modules linked in: fuse
ip6table_filter ip6_tables ebtable_nat ebtables ipt_MASQUERADE
iptable_nat nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 xt_state
nf_conntrack xt_CHECKSUM ppdev iptable_mangle parport_pc lp parport
tun bridge stp llc rfcomm bnep usblp arc4 snd_usb_audio
snd_usbmidi_lib snd_hda_codec_conexant snd_rawmidi uvcvideo videodev
snd_hda_intel snd_hda_codec media v4l2_compat_ioctl32 snd_hwdep
snd_seq snd_seq_device iwlagn snd_pcm btusb microcode iTCO_wdt
i2c_i801 iTCO_vendor_support thinkpad_acpi mac80211 snd_timer
bluetooth cfg80211 snd_page_alloc rfkill snd soundcore e1000e
virtio_net kvm_intel kvm uinput wmi i915 drm_kms_helper drm
i2c_algo_bit i2c_core video [last unloaded: scsi_wait_scan]
Aug 4 19:30:07 tlondon kernel: [ 345.301272] Pid: 2348, comm: xsane
Not tainted 3.1.0-0.rc0.git17.1.fc17.x86_64 #1
Aug 4 19:30:07 tlondon kernel: [ 345.301280] Call Trace:
Aug 4 19:30:07 tlondon kernel: [ 345.301300] [<ffffffff8105c470>]
warn_slowpath_common+0x83/0x9b
Aug 4 19:30:07 tlondon kernel: [ 345.301315] [<ffffffff8105c4a2>]
warn_slowpath_null+0x1a/0x1c
Aug 4 19:30:07 tlondon kernel: [ 345.301329] [<ffffffff8142f625>]
ip_rt_bug+0x5c/0x62
Aug 4 19:30:07 tlondon kernel: [ 345.301342] [<ffffffff81437231>]
dst_output+0x19/0x1d
Aug 4 19:30:07 tlondon kernel: [ 345.301355] [<ffffffff81438952>]
ip_local_out+0x20/0x25
Aug 4 19:30:07 tlondon kernel: [ 345.301369] [<ffffffff81439819>]
ip_send_skb+0x19/0x3e
Aug 4 19:30:07 tlondon kernel: [ 345.301385] [<ffffffff81456016>]
udp_send_skb+0x239/0x29b
Aug 4 19:30:07 tlondon kernel: [ 345.301399] [<ffffffff814577b3>]
udp_sendmsg+0x5a1/0x7d4
Aug 4 19:30:07 tlondon kernel: [ 345.301415] [<ffffffff813f69f7>] ?
release_sock+0x35/0x155
Aug 4 19:30:07 tlondon kernel: [ 345.301428] [<ffffffff8143732c>] ?
ip_select_ident+0x3d/0x3d
Aug 4 19:30:07 tlondon kernel: [ 345.301443] [<ffffffff81062587>] ?
local_bh_enable_ip+0xe/0x10
Aug 4 19:30:07 tlondon kernel: [ 345.301457] [<ffffffff814f1519>] ?
_raw_spin_unlock_bh+0x40/0x44
Aug 4 19:30:07 tlondon kernel: [ 345.301470] [<ffffffff813f6b0e>] ?
release_sock+0x14c/0x155
Aug 4 19:30:07 tlondon kernel: [ 345.301485] [<ffffffff8145eccc>]
inet_sendmsg+0x66/0x6f
Aug 4 19:30:07 tlondon kernel: [ 345.301498] [<ffffffff813f1fc2>]
sock_sendmsg+0xe6/0x109
Aug 4 19:30:07 tlondon kernel: [ 345.301513] [<ffffffff8108f078>] ?
lock_acquire+0x10f/0x13e
Aug 4 19:30:07 tlondon kernel: [ 345.301528] [<ffffffff8110d89e>] ?
might_fault+0x5c/0xac
Aug 4 19:30:07 tlondon kernel: [ 345.301542] [<ffffffff8108ef3c>] ?
lock_release+0x1a4/0x1d1
Aug 4 19:30:07 tlondon kernel: [ 345.301556] [<ffffffff8110d8e7>] ?
might_fault+0xa5/0xac
Aug 4 19:30:07 tlondon kernel: [ 345.301569] [<ffffffff813f2d07>] ?
copy_from_user+0x2f/0x31
Aug 4 19:30:07 tlondon kernel: [ 345.301582] [<ffffffff813f4b9d>]
sys_sendto+0x132/0x174
AugAug 4 19:30:08 tlondon kernel: [ 346.314606] ------------[ cut
here ]------------
Aug 4 19:30:08 tlondon kernel: [ 346.314612] WARNING: at
net/ipv4/route.c:1714 ip_rt_bug+0x5c/0x62()
Aug 4 19:30:08 tlondon kernel: [ 346.314615] Hardware name: 74585FU
Aug 4 19:30:08 tlondon kernel: [ 346.314616] Modules linked in: fuse
ip6table_filter ip6_tables ebtable_nat ebtables ipt_MASQUERADE
iptable_nat nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 xt_state
nf_conntrack xt_CHECKSUM ppdev iptable_mangle parport_pc lp parport
tun bridge stp llc rfcomm bnep usblp arc4 snd_usb_audio
snd_usbmidi_lib snd_hda_codec_conexant snd_rawmidi uvcvideo videodev
snd_hda_intel snd_hda_codec media v4l2_compat_ioctl32 snd_hwdep
snd_seq snd_seq_device iwlagn snd_pcm btusb microcode iTCO_wdt
i2c_i801 iTCO_vendor_support thinkpad_acpi mac80211 snd_timer
bluetooth cfg80211 snd_page_alloc rfkill snd soundcore e1000e
virtio_net kvm_intel kvm uinput wmi i915 drm_kms_helper drm
i2c_algo_bit i2c_core video [last unloaded: scsi_wait_scan]
Aug 4 19:30:08 tlondon kernel: [ 346.314693] Pid: 2348, comm: xsane
Tainted: G W 3.1.0-0.rc0.git17.1.fc17.x86_64 #1
Aug 4 19:30:08 tlondon kernel: [ 346.314695] Call Trace:
Aug 4 19:30:08 tlondon kernel: [ 346.314701] [<ffffffff8105c470>]
warn_slowpath_common+0x83/0x9b
Aug 4 19:30:08 tlondon kernel: [ 346.314704] [<ffffffff8105c4a2>]
warn_slowpath_null+0x1a/0x1c
Aug 4 19:30:08 tlondon kernel: [ 346.314708] [<ffffffff8142f625>]
ip_rt_bug+0x5c/0x62
Aug 4 19:30:08 tlondon kernel: [ 346.314711] [<ffffffff81437231>]
dst_output+0x19/0x1d
Aug 4 19:30:08 tlondon kernel: [ 346.314714] [<ffffffff81438952>]
ip_local_out+0x20/0x25
Aug 4 19:30:08 tlondon kernel: [ 346.314717] [<ffffffff81439819>]
ip_send_skb+0x19/0x3e
Aug 4 19:30:08 tlondon kernel: [ 346.314721] [<ffffffff81456016>]
udp_send_skb+0x239/0x29b
Aug 4 19:30:08 tlondon kernel: [ 346.314725] [<ffffffff814577b3>]
udp_sendmsg+0x5a1/0x7d4
Aug 4 19:30:08 tlondon kernel: [ 346.314729] [<ffffffff813f69f7>] ?
release_sock+0x35/0x155
Aug 4 19:30:08 tlondon kernel: [ 346.314732] [<ffffffff8143732c>] ?
ip_select_ident+0x3d/0x3d
Aug 4 19:30:08 tlondon kernel: [ 346.314736] [<ffffffff81062587>] ?
local_bh_enable_ip+0xe/0x10
Aug 4 19:30:08 tlondon kernel: [ 346.314740] [<ffffffff814f1519>] ?
_raw_spin_unlock_bh+0x40/0x44
Aug 4 19:30:08 tlondon kernel: [ 346.314743] [<ffffffff813f6b0e>] ?
release_sock+0x14c/0x155
Aug 4 19:30:08 tlondon kernel: [ 346.314747] [<ffffffff8145eccc>]
inet_sendmsg+0x66/0x6f
Aug 4 19:30:08 tlondon kernel: [ 346.314750] [<ffffffff813f1fc2>]
sock_sendmsg+0xe6/0x109
Aug 4 19:30:08 tlondon kernel: [ 346.314754] [<ffffffff8108f078>] ?
lock_acquire+0x10f/0x13e
Aug 4 19:30:08 tlondon kernel: [ 346.314758] [<ffffffff8110d89e>] ?
might_fault+0x5c/0xac
Aug 4 19:30:08 tlondon kernel: [ 346.314761] [<ffffffff8108ef3c>] ?
lock_release+0x1a4/0x1d1
Aug 4 19:30:08 tlondon kernel: [ 346.314765] [<ffffffff8110d8e7>] ?
might_fault+0xa5/0xac
Aug 4 19:30:08 tlondon kernel: [ 346.314768] [<ffffffff813f2d07>] ?
copy_from_user+0x2f/0x31
Aug 4 19:30:08 tlondon kernel: [ 346.314771] [<ffffffff813f4b9d>]
sys_sendto+0x132/0x174
Aug 4 19:30:08 tlondon kernel: [ 346.314775] [<ffffffff810b29eb>] ?
audit_syscall_entry+0x11c/0x148
Aug 4 19:30:08 tlondon kernel: [ 346.314780] [<ffffffff8124f03e>] ?
trace_hardirqs_on_thunk+0x3a/0x3f
Aug 4 19:30:08 tlondon kernel: [ 346.314784] [<ffffffff814f8382>]
system_call_fastpath+0x16/0x1b
Aug 4 19:30:08 tlondon kernel: [ 346.314786] ---[ end trace
97e7c0a8de097c51 ]---
Regarding the 'movable IP Address' issue (.5 vs. .6), I found the
following in /var/lib/dhclient/dhclient-5fb06bd0-0bb0-7ffb-45f1-d6edd65f3e03-eth0.lease
lease {
interface "eth0";
fixed-address 192.168.2.5;
option subnet-mask 255.255.255.0;
option dhcp-lease-time 4294967295;
option routers 192.168.2.1;
option dhcp-message-type 5;
option dhcp-server-identifier 192.168.2.1;
option domain-name-servers 192.168.2.1;
option domain-name "TintonFalls";
renew 4 2079/07/06 21:52:00;
rebind 1 2130/10/30 06:17:29;
expire 6 2147/11/04 01:06:07;
}
lease {
interface "eth0";
fixed-address 192.168.2.6;
option subnet-mask 255.255.255.0;
option dhcp-lease-time 4294967295;
option routers 192.168.2.1;
option dhcp-message-type 5;
option dhcp-server-identifier 192.168.2.1;
option domain-name-servers 192.168.2.1;
option domain-name "TintonFalls";
renew 2 2079/08/22 16:15:42;
rebind 4 2130/09/07 00:41:11;
expire 1 2147/09/11 19:29:49;
}
So, my router is just giving my wired NIC different addresses....
More I can provide?
tom
--
Tom London
^ permalink raw reply
* [PATCHv3] Bridge: Always send NETDEV_CHANGEADDR up on br MAC change.
From: Andrei Warkentin @ 2011-08-05 2:17 UTC (permalink / raw)
To: netdev; +Cc: Andrei Warkentin, Stephen Hemminger
In-Reply-To: <1312509349-23363-1-git-send-email-andreiw@motorola.com>
This ensures the neighbor entries associated with the bridge
dev are flushed, also invalidating the associated cached L2 headers.
This means we br_add_if/br_del_if ports to implement hand-over and
not wind up with bridge packets going out with stale MAC.
This means we can also change MAC of port device and also not wind
up with bridge packets going out with stale MAC.
This builds on Stephen Hemminger's patch, also handling the br_del_if
case, port MAC change case, and bridge MAC manual assignment case.
Cc: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: Andrei Warkentin <andreiw@motorola.com>
---
net/bridge/br_device.c | 1 +
net/bridge/br_if.c | 6 +++++-
net/bridge/br_notify.c | 6 +++++-
net/bridge/br_stp_if.c | 2 +-
4 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index cf09fe5..ef18070 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -162,6 +162,7 @@ static int br_set_mac_address(struct net_device *dev, void *p)
br->flags |= BR_SET_MAC_ADDR;
spin_unlock_bh(&br->lock);
+ call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
return 0;
}
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 204e542..36ad887 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -481,6 +481,7 @@ put_back:
int br_del_if(struct net_bridge *br, struct net_device *dev)
{
struct net_bridge_port *p;
+ bool changed_addr;
if (!br_port_exists(dev))
return -EINVAL;
@@ -492,10 +493,13 @@ int br_del_if(struct net_bridge *br, struct net_device *dev)
del_nbp(p);
spin_lock_bh(&br->lock);
- br_stp_recalculate_bridge_id(br);
+ changed_addr = br_stp_recalculate_bridge_id(br);
br_features_recompute(br);
spin_unlock_bh(&br->lock);
+ if (changed_addr)
+ call_netdevice_notifiers(NETDEV_CHANGEADDR, br->dev);
+
return 0;
}
diff --git a/net/bridge/br_notify.c b/net/bridge/br_notify.c
index 404d4e1..651eac3 100644
--- a/net/bridge/br_notify.c
+++ b/net/bridge/br_notify.c
@@ -34,6 +34,7 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
struct net_device *dev = ptr;
struct net_bridge_port *p = br_port_get(dev);
struct net_bridge *br;
+ bool changed_addr;
int err;
/* not a port of a bridge */
@@ -51,8 +52,11 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
case NETDEV_CHANGEADDR:
spin_lock_bh(&br->lock);
br_fdb_changeaddr(p, dev->dev_addr);
- br_stp_recalculate_bridge_id(br);
+ changed_addr = br_stp_recalculate_bridge_id(br);
spin_unlock_bh(&br->lock);
+
+ if (changed_addr)
+ call_netdevice_notifiers(NETDEV_CHANGEADDR, br->dev);
break;
case NETDEV_CHANGE:
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
index c0990ba..4528e9a 100644
--- a/net/bridge/br_stp_if.c
+++ b/net/bridge/br_stp_if.c
@@ -213,7 +213,7 @@ bool br_stp_recalculate_bridge_id(struct net_bridge *br)
/* user has chosen a value so keep it */
if (br->flags & BR_SET_MAC_ADDR)
- return;
+ return false;
list_for_each_entry(p, &br->port_list, list) {
if (addr == br_mac_zero ||
--
1.7.0.4
^ permalink raw reply related
* Always send NETDEV_CHANGEADDR up
From: Andrei Warkentin @ 2011-08-05 2:17 UTC (permalink / raw)
To: netdev
In-Reply-To: <1312509349-23363-1-git-send-email-andreiw@motorola.com>
Hi,
I apologize for spamming. I removed the meaningless Change-Id from
the patch.
ToC:
[PATCHv3] Bridge: Always send NETDEV_CHANGEADDR up on br MAC change.
A
^ permalink raw reply
* [PATCHv2] Bridge: Always send NETDEV_CHANGEADDR up on br MAC change.
From: Andrei Warkentin @ 2011-08-05 2:11 UTC (permalink / raw)
To: netdev; +Cc: Andrei Warkentin, Stephen Hemminger
In-Reply-To: <1312509349-23363-1-git-send-email-andreiw@motorola.com>
This ensures the neighbor entries associated with the bridge
dev are flushed, also invalidating the associated cached L2 headers.
This means we br_add_if/br_del_if ports to implement hand-over and
not wind up with bridge packets going out with stale MAC.
This means we can also change MAC of port device and also not wind
up with bridge packets going out with stale MAC.
This builds on Stephen Hemminger's patch, also handling the br_del_if
case, port MAC change case, and bridge MAC manual assignment case.
Change-Id: I6039ba021006f854e0e7e83dd1c4261c500aeab7
Cc: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: Andrei Warkentin <andreiw@motorola.com>
---
net/bridge/br_device.c | 1 +
net/bridge/br_if.c | 6 +++++-
net/bridge/br_notify.c | 6 +++++-
net/bridge/br_stp_if.c | 2 +-
4 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index cf09fe5..ef18070 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -162,6 +162,7 @@ static int br_set_mac_address(struct net_device *dev, void *p)
br->flags |= BR_SET_MAC_ADDR;
spin_unlock_bh(&br->lock);
+ call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
return 0;
}
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 204e542..36ad887 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -481,6 +481,7 @@ put_back:
int br_del_if(struct net_bridge *br, struct net_device *dev)
{
struct net_bridge_port *p;
+ bool changed_addr;
if (!br_port_exists(dev))
return -EINVAL;
@@ -492,10 +493,13 @@ int br_del_if(struct net_bridge *br, struct net_device *dev)
del_nbp(p);
spin_lock_bh(&br->lock);
- br_stp_recalculate_bridge_id(br);
+ changed_addr = br_stp_recalculate_bridge_id(br);
br_features_recompute(br);
spin_unlock_bh(&br->lock);
+ if (changed_addr)
+ call_netdevice_notifiers(NETDEV_CHANGEADDR, br->dev);
+
return 0;
}
diff --git a/net/bridge/br_notify.c b/net/bridge/br_notify.c
index 404d4e1..651eac3 100644
--- a/net/bridge/br_notify.c
+++ b/net/bridge/br_notify.c
@@ -34,6 +34,7 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
struct net_device *dev = ptr;
struct net_bridge_port *p = br_port_get(dev);
struct net_bridge *br;
+ bool changed_addr;
int err;
/* not a port of a bridge */
@@ -51,8 +52,11 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
case NETDEV_CHANGEADDR:
spin_lock_bh(&br->lock);
br_fdb_changeaddr(p, dev->dev_addr);
- br_stp_recalculate_bridge_id(br);
+ changed_addr = br_stp_recalculate_bridge_id(br);
spin_unlock_bh(&br->lock);
+
+ if (changed_addr)
+ call_netdevice_notifiers(NETDEV_CHANGEADDR, br->dev);
break;
case NETDEV_CHANGE:
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
index c0990ba..4528e9a 100644
--- a/net/bridge/br_stp_if.c
+++ b/net/bridge/br_stp_if.c
@@ -213,7 +213,7 @@ bool br_stp_recalculate_bridge_id(struct net_bridge *br)
/* user has chosen a value so keep it */
if (br->flags & BR_SET_MAC_ADDR)
- return;
+ return false;
list_for_each_entry(p, &br->port_list, list) {
if (addr == br_mac_zero ||
--
1.7.0.4
^ permalink raw reply related
* Always send NETDEV_CHANGEADDR up
From: Andrei Warkentin @ 2011-08-05 2:11 UTC (permalink / raw)
To: netdev
In-Reply-To: <1312509349-23363-1-git-send-email-andreiw@motorola.com>
Minor fix in br_notify, such that notification only is sent if
bridge MAC address is updated.
ToC:
[PATCHv2] Bridge: Always send NETDEV_CHANGEADDR up on br MAC change.
A
^ permalink raw reply
* [RFC 1/4] [flexcan] Abstract off read/write for big/little endian.
From: Robin Holt @ 2011-08-05 2:06 UTC (permalink / raw)
To: Robin Holt, Marc Kleine-Budde, Wolfgang Grandegger
Cc: Robin Holt, socketcan-core, netdev
In-Reply-To: <1312509979-13226-1-git-send-email-holt@sgi.com>
First step in converting the flexcan driver from supporting just arm to
supporting both arm and powerpc architectures.
Signed-off-by: Robin Holt <holt@sgi.com>
To: Marc Kleine-Budde <mkl@pengutronix.de>
To: Wolfgang Grandegger <wg@grandegger.com>
Cc: socketcan-core@lists.berlios.de
Cc: netdev@vger.kernel.org
---
drivers/net/can/flexcan.c | 140 ++++++++++++++++++++++++++------------------
1 files changed, 83 insertions(+), 57 deletions(-)
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index 67d9fc0..74b1706 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -196,6 +196,31 @@ static struct can_bittiming_const flexcan_bittiming_const = {
};
/*
+ * Abstract off the read/write for arm versus ppc.
+ */
+#if defined(__BIG_ENDIAN)
+static inline u32 flexcan_read(void __iomem *addr)
+{
+ return in_be32(addr);
+}
+
+static inline void flexcan_write(u32 val, void __iomem *addr)
+{
+ out_be32(addr, val);
+}
+#else
+static inline u32 flexcan_read(void __iomem *addr)
+{
+ return readl(addr);
+}
+
+static inline void flexcan_write(u32 val, void __iomem *addr)
+{
+ writel(val, addr);
+}
+#endif
+
+/*
* Swtich transceiver on or off
*/
static void flexcan_transceiver_switch(const struct flexcan_priv *priv, int on)
@@ -216,9 +241,9 @@ static inline void flexcan_chip_enable(struct flexcan_priv *priv)
struct flexcan_regs __iomem *regs = priv->base;
u32 reg;
- reg = readl(®s->mcr);
+ reg = flexcan_read(®s->mcr);
reg &= ~FLEXCAN_MCR_MDIS;
- writel(reg, ®s->mcr);
+ flexcan_write(reg, ®s->mcr);
udelay(10);
}
@@ -228,9 +253,9 @@ static inline void flexcan_chip_disable(struct flexcan_priv *priv)
struct flexcan_regs __iomem *regs = priv->base;
u32 reg;
- reg = readl(®s->mcr);
+ reg = flexcan_read(®s->mcr);
reg |= FLEXCAN_MCR_MDIS;
- writel(reg, ®s->mcr);
+ flexcan_write(reg, ®s->mcr);
}
static int flexcan_get_berr_counter(const struct net_device *dev,
@@ -238,7 +263,7 @@ static int flexcan_get_berr_counter(const struct net_device *dev,
{
const struct flexcan_priv *priv = netdev_priv(dev);
struct flexcan_regs __iomem *regs = priv->base;
- u32 reg = readl(®s->ecr);
+ u32 reg = flexcan_read(®s->ecr);
bec->txerr = (reg >> 0) & 0xff;
bec->rxerr = (reg >> 8) & 0xff;
@@ -272,15 +297,15 @@ static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (cf->can_dlc > 0) {
u32 data = be32_to_cpup((__be32 *)&cf->data[0]);
- writel(data, ®s->cantxfg[FLEXCAN_TX_BUF_ID].data[0]);
+ flexcan_write(data, ®s->cantxfg[FLEXCAN_TX_BUF_ID].data[0]);
}
if (cf->can_dlc > 3) {
u32 data = be32_to_cpup((__be32 *)&cf->data[4]);
- writel(data, ®s->cantxfg[FLEXCAN_TX_BUF_ID].data[1]);
+ flexcan_write(data, ®s->cantxfg[FLEXCAN_TX_BUF_ID].data[1]);
}
- writel(can_id, ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_id);
- writel(ctrl, ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl);
+ flexcan_write(can_id, ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_id);
+ flexcan_write(ctrl, ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl);
kfree_skb(skb);
@@ -468,8 +493,8 @@ static void flexcan_read_fifo(const struct net_device *dev,
struct flexcan_mb __iomem *mb = ®s->cantxfg[0];
u32 reg_ctrl, reg_id;
- reg_ctrl = readl(&mb->can_ctrl);
- reg_id = readl(&mb->can_id);
+ reg_ctrl = flexcan_read(&mb->can_ctrl);
+ reg_id = flexcan_read(&mb->can_id);
if (reg_ctrl & FLEXCAN_MB_CNT_IDE)
cf->can_id = ((reg_id >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG;
else
@@ -479,12 +504,12 @@ static void flexcan_read_fifo(const struct net_device *dev,
cf->can_id |= CAN_RTR_FLAG;
cf->can_dlc = get_can_dlc((reg_ctrl >> 16) & 0xf);
- *(__be32 *)(cf->data + 0) = cpu_to_be32(readl(&mb->data[0]));
- *(__be32 *)(cf->data + 4) = cpu_to_be32(readl(&mb->data[1]));
+ *(__be32 *)(cf->data + 0) = cpu_to_be32(flexcan_read(&mb->data[0]));
+ *(__be32 *)(cf->data + 4) = cpu_to_be32(flexcan_read(&mb->data[1]));
/* mark as read */
- writel(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1);
- readl(®s->timer);
+ flexcan_write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1);
+ flexcan_read(®s->timer);
}
static int flexcan_read_frame(struct net_device *dev)
@@ -520,17 +545,17 @@ static int flexcan_poll(struct napi_struct *napi, int quota)
* The error bits are cleared on read,
* use saved value from irq handler.
*/
- reg_esr = readl(®s->esr) | priv->reg_esr;
+ reg_esr = flexcan_read(®s->esr) | priv->reg_esr;
/* handle state changes */
work_done += flexcan_poll_state(dev, reg_esr);
/* handle RX-FIFO */
- reg_iflag1 = readl(®s->iflag1);
+ reg_iflag1 = flexcan_read(®s->iflag1);
while (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE &&
work_done < quota) {
work_done += flexcan_read_frame(dev);
- reg_iflag1 = readl(®s->iflag1);
+ reg_iflag1 = flexcan_read(®s->iflag1);
}
/* report bus errors */
@@ -540,8 +565,8 @@ static int flexcan_poll(struct napi_struct *napi, int quota)
if (work_done < quota) {
napi_complete(napi);
/* enable IRQs */
- writel(FLEXCAN_IFLAG_DEFAULT, ®s->imask1);
- writel(priv->reg_ctrl_default, ®s->ctrl);
+ flexcan_write(FLEXCAN_IFLAG_DEFAULT, ®s->imask1);
+ flexcan_write(priv->reg_ctrl_default, ®s->ctrl);
}
return work_done;
@@ -555,9 +580,9 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
struct flexcan_regs __iomem *regs = priv->base;
u32 reg_iflag1, reg_esr;
- reg_iflag1 = readl(®s->iflag1);
- reg_esr = readl(®s->esr);
- writel(FLEXCAN_ESR_ERR_INT, ®s->esr); /* ACK err IRQ */
+ reg_iflag1 = flexcan_read(®s->iflag1);
+ reg_esr = flexcan_read(®s->esr);
+ flexcan_write(FLEXCAN_ESR_ERR_INT, ®s->esr); /* ACK err IRQ */
/*
* schedule NAPI in case of:
@@ -573,16 +598,16 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
* save them for later use.
*/
priv->reg_esr = reg_esr & FLEXCAN_ESR_ERR_BUS;
- writel(FLEXCAN_IFLAG_DEFAULT & ~FLEXCAN_IFLAG_RX_FIFO_AVAILABLE,
- ®s->imask1);
- writel(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
+ flexcan_write(FLEXCAN_IFLAG_DEFAULT &
+ ~FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->imask1);
+ flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
®s->ctrl);
napi_schedule(&priv->napi);
}
/* FIFO overflow */
if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_OVERFLOW) {
- writel(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW, ®s->iflag1);
+ flexcan_write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW, ®s->iflag1);
dev->stats.rx_over_errors++;
dev->stats.rx_errors++;
}
@@ -591,7 +616,7 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
if (reg_iflag1 & (1 << FLEXCAN_TX_BUF_ID)) {
/* tx_bytes is incremented in flexcan_start_xmit */
stats->tx_packets++;
- writel((1 << FLEXCAN_TX_BUF_ID), ®s->iflag1);
+ flexcan_write((1 << FLEXCAN_TX_BUF_ID), ®s->iflag1);
netif_wake_queue(dev);
}
@@ -605,7 +630,7 @@ static void flexcan_set_bittiming(struct net_device *dev)
struct flexcan_regs __iomem *regs = priv->base;
u32 reg;
- reg = readl(®s->ctrl);
+ reg = flexcan_read(®s->ctrl);
reg &= ~(FLEXCAN_CTRL_PRESDIV(0xff) |
FLEXCAN_CTRL_RJW(0x3) |
FLEXCAN_CTRL_PSEG1(0x7) |
@@ -629,11 +654,11 @@ static void flexcan_set_bittiming(struct net_device *dev)
reg |= FLEXCAN_CTRL_SMP;
dev_info(dev->dev.parent, "writing ctrl=0x%08x\n", reg);
- writel(reg, ®s->ctrl);
+ flexcan_write(reg, ®s->ctrl);
/* print chip status */
dev_dbg(dev->dev.parent, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__,
- readl(®s->mcr), readl(®s->ctrl));
+ flexcan_read(®s->mcr), flexcan_read(®s->ctrl));
}
/*
@@ -654,10 +679,10 @@ static int flexcan_chip_start(struct net_device *dev)
flexcan_chip_enable(priv);
/* soft reset */
- writel(FLEXCAN_MCR_SOFTRST, ®s->mcr);
+ flexcan_write(FLEXCAN_MCR_SOFTRST, ®s->mcr);
udelay(10);
- reg_mcr = readl(®s->mcr);
+ reg_mcr = flexcan_read(®s->mcr);
if (reg_mcr & FLEXCAN_MCR_SOFTRST) {
dev_err(dev->dev.parent,
"Failed to softreset can module (mcr=0x%08x)\n",
@@ -679,12 +704,12 @@ static int flexcan_chip_start(struct net_device *dev)
* choose format C
*
*/
- reg_mcr = readl(®s->mcr);
+ reg_mcr = flexcan_read(®s->mcr);
reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_FEN | FLEXCAN_MCR_HALT |
FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN |
FLEXCAN_MCR_IDAM_C;
dev_dbg(dev->dev.parent, "%s: writing mcr=0x%08x", __func__, reg_mcr);
- writel(reg_mcr, ®s->mcr);
+ flexcan_write(reg_mcr, ®s->mcr);
/*
* CTRL
@@ -702,7 +727,7 @@ static int flexcan_chip_start(struct net_device *dev)
* (FLEXCAN_CTRL_ERR_MSK), too. Otherwise we don't get any
* warning or bus passive interrupts.
*/
- reg_ctrl = readl(®s->ctrl);
+ reg_ctrl = flexcan_read(®s->ctrl);
reg_ctrl &= ~FLEXCAN_CTRL_TSYN;
reg_ctrl |= FLEXCAN_CTRL_BOFF_REC | FLEXCAN_CTRL_LBUF |
FLEXCAN_CTRL_ERR_STATE | FLEXCAN_CTRL_ERR_MSK;
@@ -710,38 +735,39 @@ static int flexcan_chip_start(struct net_device *dev)
/* save for later use */
priv->reg_ctrl_default = reg_ctrl;
dev_dbg(dev->dev.parent, "%s: writing ctrl=0x%08x", __func__, reg_ctrl);
- writel(reg_ctrl, ®s->ctrl);
+ flexcan_write(reg_ctrl, ®s->ctrl);
for (i = 0; i < ARRAY_SIZE(regs->cantxfg); i++) {
- writel(0, ®s->cantxfg[i].can_ctrl);
- writel(0, ®s->cantxfg[i].can_id);
- writel(0, ®s->cantxfg[i].data[0]);
- writel(0, ®s->cantxfg[i].data[1]);
+ flexcan_write(0, ®s->cantxfg[i].can_ctrl);
+ flexcan_write(0, ®s->cantxfg[i].can_id);
+ flexcan_write(0, ®s->cantxfg[i].data[0]);
+ flexcan_write(0, ®s->cantxfg[i].data[1]);
/* put MB into rx queue */
- writel(FLEXCAN_MB_CNT_CODE(0x4), ®s->cantxfg[i].can_ctrl);
+ flexcan_write(FLEXCAN_MB_CNT_CODE(0x4),
+ ®s->cantxfg[i].can_ctrl);
}
/* acceptance mask/acceptance code (accept everything) */
- writel(0x0, ®s->rxgmask);
- writel(0x0, ®s->rx14mask);
- writel(0x0, ®s->rx15mask);
+ flexcan_write(0x0, ®s->rxgmask);
+ flexcan_write(0x0, ®s->rx14mask);
+ flexcan_write(0x0, ®s->rx15mask);
flexcan_transceiver_switch(priv, 1);
/* synchronize with the can bus */
- reg_mcr = readl(®s->mcr);
+ reg_mcr = flexcan_read(®s->mcr);
reg_mcr &= ~FLEXCAN_MCR_HALT;
- writel(reg_mcr, ®s->mcr);
+ flexcan_write(reg_mcr, ®s->mcr);
priv->can.state = CAN_STATE_ERROR_ACTIVE;
/* enable FIFO interrupts */
- writel(FLEXCAN_IFLAG_DEFAULT, ®s->imask1);
+ flexcan_write(FLEXCAN_IFLAG_DEFAULT, ®s->imask1);
/* print chip status */
dev_dbg(dev->dev.parent, "%s: reading mcr=0x%08x ctrl=0x%08x\n",
- __func__, readl(®s->mcr), readl(®s->ctrl));
+ __func__, flexcan_read(®s->mcr), flexcan_read(®s->ctrl));
return 0;
@@ -763,12 +789,12 @@ static void flexcan_chip_stop(struct net_device *dev)
u32 reg;
/* Disable all interrupts */
- writel(0, ®s->imask1);
+ flexcan_write(0, ®s->imask1);
/* Disable + halt module */
- reg = readl(®s->mcr);
+ reg = flexcan_read(®s->mcr);
reg |= FLEXCAN_MCR_MDIS | FLEXCAN_MCR_HALT;
- writel(reg, ®s->mcr);
+ flexcan_write(reg, ®s->mcr);
flexcan_transceiver_switch(priv, 0);
priv->can.state = CAN_STATE_STOPPED;
@@ -860,24 +886,24 @@ static int __devinit register_flexcandev(struct net_device *dev)
/* select "bus clock", chip must be disabled */
flexcan_chip_disable(priv);
- reg = readl(®s->ctrl);
+ reg = flexcan_read(®s->ctrl);
reg |= FLEXCAN_CTRL_CLK_SRC;
- writel(reg, ®s->ctrl);
+ flexcan_write(reg, ®s->ctrl);
flexcan_chip_enable(priv);
/* set freeze, halt and activate FIFO, restrict register access */
- reg = readl(®s->mcr);
+ reg = flexcan_read(®s->mcr);
reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT |
FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV;
- writel(reg, ®s->mcr);
+ flexcan_write(reg, ®s->mcr);
/*
* Currently we only support newer versions of this core
* featuring a RX FIFO. Older cores found on some Coldfire
* derivates are not yet supported.
*/
- reg = readl(®s->mcr);
+ reg = flexcan_read(®s->mcr);
if (!(reg & FLEXCAN_MCR_FEN)) {
dev_err(dev->dev.parent,
"Could not enable RX FIFO, unsupported core\n");
--
1.7.2.1
^ permalink raw reply related
* [RFC 4/4] [flexcan] Add support for FLEXCAN_DEBUG
From: Robin Holt @ 2011-08-05 2:06 UTC (permalink / raw)
To: Robin Holt, Marc Kleine-Budde, Wolfgang Grandegger
Cc: Robin Holt, socketcan-core, netdev
In-Reply-To: <1312509979-13226-1-git-send-email-holt@sgi.com>
Add a wrapper function for a register dump when a developer defines
FLEXCAN_DEBUG.
Signed-off-by: Robin Holt <holt@sgi.com>
To: Marc Kleine-Budde <mkl@pengutronix.de>
To: Wolfgang Grandegger <wg@grandegger.com>
Cc: socketcan-core@lists.berlios.de
Cc: netdev@vger.kernel.org
---
drivers/net/can/flexcan.c | 40 ++++++++++++++++++++++++++++++++++++++++
1 files changed, 40 insertions(+), 0 deletions(-)
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index fbb61c6..96684ca 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -316,6 +316,38 @@ static inline unsigned long flexcan_clk_get_rate(struct clk *clk)
#endif
+#if defined(FLEXCAN_DEBUG)
+void _flexcan_reg_dump(struct net_device *dev, const char *file, int line,
+ const char *func)
+{
+ const struct flexcan_priv *priv = netdev_priv(dev);
+ struct flexcan_regs __iomem *regs = priv->base;
+
+ printk(KERN_INFO "flexcan_reg_dump:%s:%d:%s()\n", file, line, func);
+ printk(KERN_INFO
+ "\t mcr 0x%08x ctrl 0x%08x timer 0x%08x rxg 0x%08x",
+ flexcan_read(®s->mcr),
+ flexcan_read(®s->ctrl),
+ flexcan_read(®s->timer),
+ flexcan_read(®s->rxgmask));
+ printk(KERN_INFO
+ "\t rx14 0x%08x rx15 0x%08x ecr 0x%08x esr 0x%08x",
+ flexcan_read(®s->rx14mask),
+ flexcan_read(®s->rx15mask),
+ flexcan_read(®s->ecr),
+ flexcan_read(®s->esr));
+ printk(KERN_INFO
+ "\timsk2 0x%08x imsk1 0x%08x iflg2 0x%08x iflg1 0x%08x",
+ flexcan_read(®s->imask2),
+ flexcan_read(®s->imask1),
+ flexcan_read(®s->iflag2),
+ flexcan_read(®s->iflag1));
+}
+#define flexcan_reg_dump(_d) _flexcan_reg_dump(_d, __FILE__, __LINE__, __func__)
+#else
+#define flexcan_reg_dump(_d)
+#endif
+
/*
* Swtich transceiver on or off
*/
@@ -376,6 +408,8 @@ static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
u32 can_id;
u32 ctrl = FLEXCAN_MB_CNT_CODE(0xc) | (cf->can_dlc << 16);
+ flexcan_reg_dump(dev);
+
if (can_dropped_invalid_skb(dev, skb))
return NETDEV_TX_OK;
@@ -408,6 +442,8 @@ static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* tx_packets is incremented in flexcan_irq */
stats->tx_bytes += cf->can_dlc;
+ flexcan_reg_dump(dev);
+
return NETDEV_TX_OK;
}
@@ -676,6 +712,8 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
struct flexcan_regs __iomem *regs = priv->base;
u32 reg_iflag1, reg_esr;
+ flexcan_reg_dump(dev);
+
reg_iflag1 = flexcan_read(®s->iflag1);
reg_esr = flexcan_read(®s->esr);
flexcan_write(FLEXCAN_ESR_ERR_INT, ®s->esr); /* ACK err IRQ */
@@ -716,6 +754,8 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
netif_wake_queue(dev);
}
+ flexcan_reg_dump(dev);
+
return IRQ_HANDLED;
}
--
1.7.2.1
^ permalink raw reply related
* [RFC 2/4] [flexcan] Introduce a flexcan_clk set of functions.
From: Robin Holt @ 2011-08-05 2:06 UTC (permalink / raw)
To: Robin Holt, Marc Kleine-Budde, Wolfgang Grandegger
Cc: Robin Holt, socketcan-core, netdev
In-Reply-To: <1312509979-13226-1-git-send-email-holt@sgi.com>
The freescale P1010RDB board does not have a
clk_{get,put,get_rate,enable,disable} set of functions. Wrap these with a
flexcan_ #define for arm, and implement a more complete function for ppc.
Signed-off-by: Robin Holt <holt@sgi.com>
To: Marc Kleine-Budde <mkl@pengutronix.de>
To: Wolfgang Grandegger <wg@grandegger.com>
Cc: socketcan-core@lists.berlios.de
Cc: netdev@vger.kernel.org
---
drivers/net/can/flexcan.c | 114 +++++++++++++++++++++++++++++++++++++++++----
1 files changed, 105 insertions(+), 9 deletions(-)
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index 74b1706..3417d0b 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -220,6 +220,102 @@ static inline void flexcan_write(u32 val, void __iomem *addr)
}
#endif
+#if defined(__powerpc__)
+struct flexcan_clk {
+ unsigned long rate;
+ void *data;
+};
+
+static struct clk *flexcan_clk_get(struct device *dev, const char *id)
+{
+ struct flexcan_clk *clock;
+ u32 *clock_freq;
+ u32 *clock_divider;
+ int err;
+
+ clock = kmalloc(sizeof(struct flexcan_clk), GFP_KERNEL);
+ if (!clock) {
+ dev_err(dev, "Cannot allocate memory\n");
+ err = -ENOMEM;
+ goto failed_clock;
+ }
+ clock_freq = (u32 *)of_get_property(dev->of_node, "clock_freq", NULL);
+ if (!clock_freq) {
+ dev_err(dev, "Cannot find clock_freq property\n");
+ err = -EINVAL;
+ goto failed_clock;
+ }
+
+ clock_divider = (u32 *) of_get_property(dev->of_node,
+ "fsl,flexcan-clock-divider", NULL);
+ if (clock_divider == NULL) {
+ dev_err(dev, "Cannot find fsl,flexcan-clock-divider property\n");
+ err = -EINVAL;
+ goto failed_clock;
+ }
+
+ clock->rate = DIV_ROUND_CLOSEST(*clock_freq / *clock_divider, 1000);
+ clock->rate *= 1000;
+
+ return (struct clk *)clock;
+
+ failed_clock:
+ kfree(clock);
+ return ERR_PTR(err);
+}
+
+static inline void flexcan_clk_put(struct clk *_clk)
+{
+ struct flexcan_clk *clk = (struct flexcan_clk *)_clk;
+
+ kfree(clk);
+}
+
+static inline int flexcan_clk_enable(struct clk *clk)
+{
+ return 0;
+}
+
+static inline void flexcan_clk_disable(struct clk *clk)
+{
+ return;
+}
+
+static inline unsigned long flexcan_clk_get_rate(struct clk *_clk)
+{
+ struct flexcan_clk *clk = (struct flexcan_clk *)_clk;
+
+ return clk->rate;
+}
+
+#else
+static inline struct clk *flexcan_clk_get(struct device *dev, const char *id)
+{
+ return clk_get(dev, id);
+}
+
+static inline void flexcan_clk_put(struct clk *clk)
+{
+ clk_put(clk);
+}
+
+static inline int flexcan_clk_enable(struct clk *clk)
+{
+ return clk_enable(clk);
+}
+
+static inline void flexcan_clk_disable(struct clk *clk)
+{
+ clk_disable(clk);
+}
+
+static inline unsigned long flexcan_clk_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk);
+}
+
+#endif
+
/*
* Swtich transceiver on or off
*/
@@ -807,7 +903,7 @@ static int flexcan_open(struct net_device *dev)
struct flexcan_priv *priv = netdev_priv(dev);
int err;
- clk_enable(priv->clk);
+ flexcan_clk_enable(priv->clk);
err = open_candev(dev);
if (err)
@@ -829,7 +925,7 @@ static int flexcan_open(struct net_device *dev)
out_close:
close_candev(dev);
out:
- clk_disable(priv->clk);
+ flexcan_clk_disable(priv->clk);
return err;
}
@@ -843,7 +939,7 @@ static int flexcan_close(struct net_device *dev)
flexcan_chip_stop(dev);
free_irq(dev->irq, dev);
- clk_disable(priv->clk);
+ flexcan_clk_disable(priv->clk);
close_candev(dev);
@@ -882,7 +978,7 @@ static int __devinit register_flexcandev(struct net_device *dev)
struct flexcan_regs __iomem *regs = priv->base;
u32 reg, err;
- clk_enable(priv->clk);
+ flexcan_clk_enable(priv->clk);
/* select "bus clock", chip must be disabled */
flexcan_chip_disable(priv);
@@ -916,7 +1012,7 @@ static int __devinit register_flexcandev(struct net_device *dev)
out:
/* disable core and turn off clocks */
flexcan_chip_disable(priv);
- clk_disable(priv->clk);
+ flexcan_clk_disable(priv->clk);
return err;
}
@@ -936,7 +1032,7 @@ static int __devinit flexcan_probe(struct platform_device *pdev)
resource_size_t mem_size;
int err, irq;
- clk = clk_get(&pdev->dev, NULL);
+ clk = flexcan_clk_get(&pdev->dev, NULL);
if (IS_ERR(clk)) {
dev_err(&pdev->dev, "no clock defined\n");
err = PTR_ERR(clk);
@@ -973,7 +1069,7 @@ static int __devinit flexcan_probe(struct platform_device *pdev)
dev->flags |= IFF_ECHO; /* we support local echo in hardware */
priv = netdev_priv(dev);
- priv->can.clock.freq = clk_get_rate(clk);
+ priv->can.clock.freq = flexcan_clk_get_rate(clk);
priv->can.bittiming_const = &flexcan_bittiming_const;
priv->can.do_set_mode = flexcan_set_mode;
priv->can.do_get_berr_counter = flexcan_get_berr_counter;
@@ -1008,7 +1104,7 @@ static int __devinit flexcan_probe(struct platform_device *pdev)
failed_map:
release_mem_region(mem->start, mem_size);
failed_get:
- clk_put(clk);
+ flexcan_clk_put(clk);
failed_clock:
return err;
}
@@ -1026,7 +1122,7 @@ static int __devexit flexcan_remove(struct platform_device *pdev)
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
release_mem_region(mem->start, resource_size(mem));
- clk_put(priv->clk);
+ flexcan_clk_put(priv->clk);
free_candev(dev);
--
1.7.2.1
^ permalink raw reply related
* [RFC 3/4] [flexcan] Add of_match to platform_device definition.
From: Robin Holt @ 2011-08-05 2:06 UTC (permalink / raw)
To: Robin Holt, Marc Kleine-Budde, Wolfgang Grandegger
Cc: Robin Holt, socketcan-core, netdev
In-Reply-To: <1312509979-13226-1-git-send-email-holt@sgi.com>
It looks like the of_device stuff got moved under the
platform_device->driver and all we should need to do is define an of_match
to get a flexcan_probe call out.
Signed-off-by: Robin Holt <holt@sgi.com>
To: Marc Kleine-Budde <mkl@pengutronix.de>
To: Wolfgang Grandegger <wg@grandegger.com>
Cc: socketcan-core@lists.berlios.de
Cc: netdev@vger.kernel.org
---
drivers/net/can/flexcan.c | 13 ++++++++++++-
1 files changed, 12 insertions(+), 1 deletions(-)
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index 3417d0b..fbb61c6 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -1129,8 +1129,19 @@ static int __devexit flexcan_remove(struct platform_device *pdev)
return 0;
}
+static struct of_device_id flexcan_of_match[] = {
+ {
+ .compatible = "fsl,flexcan",
+ },
+ {},
+};
+
static struct platform_driver flexcan_driver = {
- .driver.name = DRV_NAME,
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = flexcan_of_match,
+ },
.probe = flexcan_probe,
.remove = __devexit_p(flexcan_remove),
};
--
1.7.2.1
^ permalink raw reply related
* [RFC 0/4] [flexcan] Add support for powerpc (freescale p1010) -V4
From: Robin Holt @ 2011-08-05 2:06 UTC (permalink / raw)
To: Robin Holt, Marc Kleine-Budde, Wolfgang Grandegger
Cc: Robin Holt, socketcan-core, netdev
Marc or Wolfgang,
This patch set should have all your comments included.
Could you please apply these four patches to a test branch, compile
and test them on an arm based system? I would like to at least feel
comfortable that I have not broken anything there so far.
Before the integration of the comments, I had verified the flexcan
driver was able to communicate. I still need to do more testing, but
it certainly looks very promising at this point.
Thanks,
Robin Holt
^ permalink raw reply
* [RFC 0/4] [flexcan] Add support for powerpc (freescale p1010) -V4
From: Robin Holt @ 2011-08-05 2:06 UTC (permalink / raw)
To: Robin Holt, Marc Kleine-Budde, Wolfgang Grandegger
Cc: socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
netdev-u79uwXL29TY76Z2rM5mHXA
Marc or Wolfgang,
This patch set should have all your comments included.
Could you please apply these four patches to a test branch, compile
and test them on an arm based system? I would like to at least feel
comfortable that I have not broken anything there so far.
Before the integration of the comments, I had verified the flexcan
driver was able to communicate. I still need to do more testing, but
it certainly looks very promising at this point.
Thanks,
Robin Holt
^ permalink raw reply
* Re: [PATCH 3/3] net: Fix security_socket_sendmsg() bypass problem.
From: Casey Schaufler @ 2011-08-05 0:38 UTC (permalink / raw)
To: Anton Blanchard
Cc: penguin-kernel, davem, eparis, mjt, netdev, linux-security-module,
Casey Schaufler
In-Reply-To: <20110805000822.408914956@samba.org>
On 8/4/2011 5:07 PM, Anton Blanchard wrote:
> From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
>
> The sendmmsg() introduced by commit 228e548e "net: Add sendmmsg socket system
> call" is capable of sending to multiple different destination addresses.
>
> SMACK is using destination's address for checking sendmsg() permission.
> However, security_socket_sendmsg() is called for only once even if multiple
> different destination addresses are passed to sendmmsg().
>
> Therefore, we need to call security_socket_sendmsg() for each destination
> address rather than only the first destination address.
>
> Since calling security_socket_sendmsg() every time when only single destination
> address was passed to sendmmsg() is a waste of time, omit calling
> security_socket_sendmsg() unless destination address of previous datagram and
> that of current datagram differs.
Thank you.
>
> Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
> Acked-off: Anton Blanchard <anton@samba.org>
> Cc: stable <stable@kernel.org> [3.0+]
> ---
>
> Index: linux-net/net/socket.c
> ===================================================================
> --- linux-net.orig/net/socket.c 2011-08-05 09:31:27.000000000 +1000
> +++ linux-net/net/socket.c 2011-08-05 09:32:46.146436405 +1000
> @@ -1871,8 +1871,14 @@ SYSCALL_DEFINE2(shutdown, int, fd, int,
> #define COMPAT_NAMELEN(msg) COMPAT_MSG(msg, msg_namelen)
> #define COMPAT_FLAGS(msg) COMPAT_MSG(msg, msg_flags)
>
> +struct used_address {
> + struct sockaddr_storage name;
> + unsigned int name_len;
> +};
> +
> static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
> - struct msghdr *msg_sys, unsigned flags, int nosec)
> + struct msghdr *msg_sys, unsigned flags,
> + struct used_address *used_address)
> {
> struct compat_msghdr __user *msg_compat =
> (struct compat_msghdr __user *)msg;
> @@ -1953,8 +1959,28 @@ static int __sys_sendmsg(struct socket *
>
> if (sock->file->f_flags & O_NONBLOCK)
> msg_sys->msg_flags |= MSG_DONTWAIT;
> - err = (nosec ? sock_sendmsg_nosec : sock_sendmsg)(sock, msg_sys,
> - total_len);
> + /*
> + * If this is sendmmsg() and current destination address is same as
> + * previously succeeded address, omit asking LSM's decision.
> + * used_address->name_len is initialized to UINT_MAX so that the first
> + * destination address never matches.
> + */
> + if (used_address && used_address->name_len == msg_sys->msg_namelen &&
> + !memcmp(&used_address->name, msg->msg_name,
> + used_address->name_len)) {
> + err = sock_sendmsg_nosec(sock, msg_sys, total_len);
> + goto out_freectl;
> + }
> + err = sock_sendmsg(sock, msg_sys, total_len);
> + /*
> + * If this is sendmmsg() and sending to current destination address was
> + * successful, remember it.
> + */
> + if (used_address && err >= 0) {
> + used_address->name_len = msg_sys->msg_namelen;
> + memcpy(&used_address->name, msg->msg_name,
> + used_address->name_len);
> + }
>
> out_freectl:
> if (ctl_buf != ctl)
> @@ -1979,7 +2005,7 @@ SYSCALL_DEFINE3(sendmsg, int, fd, struct
> if (!sock)
> goto out;
>
> - err = __sys_sendmsg(sock, msg, &msg_sys, flags, 0);
> + err = __sys_sendmsg(sock, msg, &msg_sys, flags, NULL);
>
> fput_light(sock->file, fput_needed);
> out:
> @@ -1998,6 +2024,7 @@ int __sys_sendmmsg(int fd, struct mmsghd
> struct mmsghdr __user *entry;
> struct compat_mmsghdr __user *compat_entry;
> struct msghdr msg_sys;
> + struct used_address used_address;
>
> if (vlen > UIO_MAXIOV)
> vlen = UIO_MAXIOV;
> @@ -2008,24 +2035,22 @@ int __sys_sendmmsg(int fd, struct mmsghd
> if (!sock)
> return err;
>
> + used_address.name_len = UINT_MAX;
> entry = mmsg;
> compat_entry = (struct compat_mmsghdr __user *)mmsg;
> err = 0;
>
> while (datagrams < vlen) {
> - /*
> - * No need to ask LSM for more than the first datagram.
> - */
> if (MSG_CMSG_COMPAT & flags) {
> err = __sys_sendmsg(sock, (struct msghdr __user *)compat_entry,
> - &msg_sys, flags, datagrams);
> + &msg_sys, flags, &used_address);
> if (err < 0)
> break;
> err = __put_user(err, &compat_entry->msg_len);
> ++compat_entry;
> } else {
> err = __sys_sendmsg(sock, (struct msghdr __user *)entry,
> - &msg_sys, flags, datagrams);
> + &msg_sys, flags, &used_address);
> if (err < 0)
> break;
> err = put_user(err, &entry->msg_len);
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-security-module" 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
* [net-next-2.6 PATCH] enic: Add timestamp to network interface stats
From: Danny Guo @ 2011-08-05 0:11 UTC (permalink / raw)
To: davem; +Cc: netdev
From: Danny Guo <dannguo@cisco.com>
This patch adds timestamps in ethtool stats. It makes it easier to provide scripts to users to calculate throughput, etc. It also allows software to synchronize timestamps with host time for correlating host events with stats collection.
Signed-off-by: Danny Guo <dannguo@cisco.com>
Signed-off-by: Vasanthy Kolluri <vkolluri@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: David Wang <dwang2@cisco.com>
---
drivers/net/enic/enic.h | 2 +-
drivers/net/enic/enic_main.c | 7 ++++++-
drivers/net/enic/vnic_dev.c | 1 +
drivers/net/enic/vnic_stats.h | 1 +
4 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index ce76d9a..2e58bdc 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -32,7 +32,7 @@
#define DRV_NAME "enic"
#define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver"
-#define DRV_VERSION "2.1.1.24"
+#define DRV_VERSION "2.1.1.25"
#define DRV_COPYRIGHT "Copyright 2008-2011 Cisco Systems, Inc"
#define ENIC_BARS_MAX 6
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 67a27cd..a3f61c1 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -121,6 +121,8 @@ static const struct enic_stat enic_rx_stats[] = {
static const unsigned int enic_n_tx_stats = ARRAY_SIZE(enic_tx_stats);
static const unsigned int enic_n_rx_stats = ARRAY_SIZE(enic_rx_stats);
+#define ENIC_TIMESTAMP_STAT_NAME "timestamp(ns)"
+
static int enic_is_dynamic(struct enic *enic)
{
return enic->pdev->device == PCI_DEVICE_ID_CISCO_VIC_ENET_DYN;
@@ -224,6 +226,8 @@ static void enic_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
memcpy(data, enic_rx_stats[i].name, ETH_GSTRING_LEN);
data += ETH_GSTRING_LEN;
}
+ memcpy(data, ENIC_TIMESTAMP_STAT_NAME, ETH_GSTRING_LEN);
+ data += ETH_GSTRING_LEN;
break;
}
}
@@ -232,7 +236,7 @@ static int enic_get_sset_count(struct net_device *netdev, int sset)
{
switch (sset) {
case ETH_SS_STATS:
- return enic_n_tx_stats + enic_n_rx_stats;
+ return enic_n_tx_stats + enic_n_rx_stats + 1;
default:
return -EOPNOTSUPP;
}
@@ -251,6 +255,7 @@ static void enic_get_ethtool_stats(struct net_device *netdev,
*(data++) = ((u64 *)&vstats->tx)[enic_tx_stats[i].offset];
for (i = 0; i < enic_n_rx_stats; i++)
*(data++) = ((u64 *)&vstats->rx)[enic_rx_stats[i].offset];
+ *(data++) = vstats->timestamp_ns;
}
static u32 enic_get_msglevel(struct net_device *netdev)
diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c
index 8c4c8cf..656871a 100644
--- a/drivers/net/enic/vnic_dev.c
+++ b/drivers/net/enic/vnic_dev.c
@@ -467,6 +467,7 @@ int vnic_dev_stats_dump(struct vnic_dev *vdev, struct vnic_stats **stats)
if (!vdev->stats)
return -ENOMEM;
}
+ memset(vdev->stats, 0, sizeof(*vdev->stats));
*stats = vdev->stats;
a0 = vdev->stats_pa;
diff --git a/drivers/net/enic/vnic_stats.h b/drivers/net/enic/vnic_stats.h
index 77750ec..9d5158d 100644
--- a/drivers/net/enic/vnic_stats.h
+++ b/drivers/net/enic/vnic_stats.h
@@ -65,6 +65,7 @@ struct vnic_rx_stats {
struct vnic_stats {
struct vnic_tx_stats tx;
struct vnic_rx_stats rx;
+ u64 timestamp_ns;
};
#endif /* _VNIC_STATS_H_ */
^ permalink raw reply related
* [PATCH 3/3] net: Fix security_socket_sendmsg() bypass problem.
From: Anton Blanchard @ 2011-08-05 0:07 UTC (permalink / raw)
To: penguin-kernel, davem, eparis, casey, mjt; +Cc: netdev, linux-security-module
In-Reply-To: <20110805000737.743684961@samba.org>
[-- Attachment #1: sendmmsg_v2 --]
[-- Type: text/plain, Size: 4180 bytes --]
From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
The sendmmsg() introduced by commit 228e548e "net: Add sendmmsg socket system
call" is capable of sending to multiple different destination addresses.
SMACK is using destination's address for checking sendmsg() permission.
However, security_socket_sendmsg() is called for only once even if multiple
different destination addresses are passed to sendmmsg().
Therefore, we need to call security_socket_sendmsg() for each destination
address rather than only the first destination address.
Since calling security_socket_sendmsg() every time when only single destination
address was passed to sendmmsg() is a waste of time, omit calling
security_socket_sendmsg() unless destination address of previous datagram and
that of current datagram differs.
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Acked-off: Anton Blanchard <anton@samba.org>
Cc: stable <stable@kernel.org> [3.0+]
---
Index: linux-net/net/socket.c
===================================================================
--- linux-net.orig/net/socket.c 2011-08-05 09:31:27.000000000 +1000
+++ linux-net/net/socket.c 2011-08-05 09:32:46.146436405 +1000
@@ -1871,8 +1871,14 @@ SYSCALL_DEFINE2(shutdown, int, fd, int,
#define COMPAT_NAMELEN(msg) COMPAT_MSG(msg, msg_namelen)
#define COMPAT_FLAGS(msg) COMPAT_MSG(msg, msg_flags)
+struct used_address {
+ struct sockaddr_storage name;
+ unsigned int name_len;
+};
+
static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
- struct msghdr *msg_sys, unsigned flags, int nosec)
+ struct msghdr *msg_sys, unsigned flags,
+ struct used_address *used_address)
{
struct compat_msghdr __user *msg_compat =
(struct compat_msghdr __user *)msg;
@@ -1953,8 +1959,28 @@ static int __sys_sendmsg(struct socket *
if (sock->file->f_flags & O_NONBLOCK)
msg_sys->msg_flags |= MSG_DONTWAIT;
- err = (nosec ? sock_sendmsg_nosec : sock_sendmsg)(sock, msg_sys,
- total_len);
+ /*
+ * If this is sendmmsg() and current destination address is same as
+ * previously succeeded address, omit asking LSM's decision.
+ * used_address->name_len is initialized to UINT_MAX so that the first
+ * destination address never matches.
+ */
+ if (used_address && used_address->name_len == msg_sys->msg_namelen &&
+ !memcmp(&used_address->name, msg->msg_name,
+ used_address->name_len)) {
+ err = sock_sendmsg_nosec(sock, msg_sys, total_len);
+ goto out_freectl;
+ }
+ err = sock_sendmsg(sock, msg_sys, total_len);
+ /*
+ * If this is sendmmsg() and sending to current destination address was
+ * successful, remember it.
+ */
+ if (used_address && err >= 0) {
+ used_address->name_len = msg_sys->msg_namelen;
+ memcpy(&used_address->name, msg->msg_name,
+ used_address->name_len);
+ }
out_freectl:
if (ctl_buf != ctl)
@@ -1979,7 +2005,7 @@ SYSCALL_DEFINE3(sendmsg, int, fd, struct
if (!sock)
goto out;
- err = __sys_sendmsg(sock, msg, &msg_sys, flags, 0);
+ err = __sys_sendmsg(sock, msg, &msg_sys, flags, NULL);
fput_light(sock->file, fput_needed);
out:
@@ -1998,6 +2024,7 @@ int __sys_sendmmsg(int fd, struct mmsghd
struct mmsghdr __user *entry;
struct compat_mmsghdr __user *compat_entry;
struct msghdr msg_sys;
+ struct used_address used_address;
if (vlen > UIO_MAXIOV)
vlen = UIO_MAXIOV;
@@ -2008,24 +2035,22 @@ int __sys_sendmmsg(int fd, struct mmsghd
if (!sock)
return err;
+ used_address.name_len = UINT_MAX;
entry = mmsg;
compat_entry = (struct compat_mmsghdr __user *)mmsg;
err = 0;
while (datagrams < vlen) {
- /*
- * No need to ask LSM for more than the first datagram.
- */
if (MSG_CMSG_COMPAT & flags) {
err = __sys_sendmsg(sock, (struct msghdr __user *)compat_entry,
- &msg_sys, flags, datagrams);
+ &msg_sys, flags, &used_address);
if (err < 0)
break;
err = __put_user(err, &compat_entry->msg_len);
++compat_entry;
} else {
err = __sys_sendmsg(sock, (struct msghdr __user *)entry,
- &msg_sys, flags, datagrams);
+ &msg_sys, flags, &used_address);
if (err < 0)
break;
err = put_user(err, &entry->msg_len);
^ permalink raw reply
* [PATCH 2/3] net: Cap number of elements for sendmmsg
From: Anton Blanchard @ 2011-08-05 0:07 UTC (permalink / raw)
To: penguin-kernel, davem, eparis, casey, mjt; +Cc: netdev, linux-security-module
In-Reply-To: <20110805000737.743684961@samba.org>
[-- Attachment #1: cap_sendmmsg --]
[-- Type: text/plain, Size: 871 bytes --]
To limit the amount of time we can spend in sendmmsg, cap the
number of elements to UIO_MAXIOV (currently 1024).
For error handling an application using sendmmsg needs to retry at
the first unsent message, so capping is simpler and requires less
application logic than returning EINVAL.
Signed-off-by: Anton Blanchard <anton@samba.org>
Cc: stable <stable@kernel.org> [3.0+]
---
Index: linux-net/net/socket.c
===================================================================
--- linux-net.orig/net/socket.c 2011-08-04 20:16:58.667081839 +1000
+++ linux-net/net/socket.c 2011-08-04 20:37:32.399602006 +1000
@@ -1999,6 +1999,9 @@ int __sys_sendmmsg(int fd, struct mmsghd
struct compat_mmsghdr __user *compat_entry;
struct msghdr msg_sys;
+ if (vlen > UIO_MAXIOV)
+ vlen = UIO_MAXIOV;
+
datagrams = 0;
sock = sockfd_lookup_light(fd, &err, &fput_needed);
^ permalink raw reply
* [PATCH 1/3] net: sendmmsg should only return an error if no messages were sent
From: Anton Blanchard @ 2011-08-05 0:07 UTC (permalink / raw)
To: penguin-kernel, davem, eparis, casey, mjt; +Cc: netdev, linux-security-module
In-Reply-To: <20110805000737.743684961@samba.org>
[-- Attachment #1: sendmmsg_errno --]
[-- Type: text/plain, Size: 2002 bytes --]
sendmmsg uses a similar error return strategy as recvmmsg but it
turns out to be a confusing way to communicate errors.
The current code stores the error code away and returns it on the next
sendmmsg call. This means a call with completely valid arguments could
get an error from a previous call.
Change things so we only return an error if no datagrams could be sent.
If less than the requested number of messages were sent, the application
must retry starting at the first failed one and if the problem is
persistent the error will be returned.
This matches the behaviour of other syscalls like read/write - it
is not an error if less than the requested number of elements are sent.
Signed-off-by: Anton Blanchard <anton@samba.org>
Cc: stable <stable@kernel.org> [3.0+]
---
Index: linux-net/net/socket.c
===================================================================
--- linux-net.orig/net/socket.c 2011-08-04 20:37:53.959996025 +1000
+++ linux-net/net/socket.c 2011-08-05 09:31:11.724704078 +1000
@@ -2005,12 +2005,9 @@ int __sys_sendmmsg(int fd, struct mmsghd
if (!sock)
return err;
- err = sock_error(sock->sk);
- if (err)
- goto out_put;
-
entry = mmsg;
compat_entry = (struct compat_mmsghdr __user *)mmsg;
+ err = 0;
while (datagrams < vlen) {
/*
@@ -2037,29 +2034,11 @@ int __sys_sendmmsg(int fd, struct mmsghd
++datagrams;
}
-out_put:
fput_light(sock->file, fput_needed);
- if (err == 0)
- return datagrams;
-
- if (datagrams != 0) {
- /*
- * We may send less entries than requested (vlen) if the
- * sock is non blocking...
- */
- if (err != -EAGAIN) {
- /*
- * ... or if sendmsg returns an error after we
- * send some datagrams, where we record the
- * error to return on the next call or if the
- * app asks about it using getsockopt(SO_ERROR).
- */
- sock->sk->sk_err = -err;
- }
-
+ /* We only return an error if no datagrams were able to be sent */
+ if (datagrams != 0)
return datagrams;
- }
return err;
}
^ permalink raw reply
* [PATCH 0/3] sendmmsg fixes
From: Anton Blanchard @ 2011-08-05 0:07 UTC (permalink / raw)
To: penguin-kernel, davem, eparis, casey, mjt; +Cc: netdev, linux-security-module
Here are the current set of sendmmsg fixes that pass my test
cases. Any review would be much appreciated.
Anton
^ permalink raw reply
* Re: [PATCH 10/14] net/core/scm.c: target capable() calls to user_ns owning the net_ns
From: Serge E. Hallyn @ 2011-08-04 22:06 UTC (permalink / raw)
To: Serge Hallyn; +Cc: linux-kernel, dhowells, ebiederm, containers, netdev, akpm
In-Reply-To: <1311706717-7398-11-git-send-email-serge@hallyn.com>
Quoting Serge Hallyn (serge@hallyn.com):
> From: Serge E. Hallyn <serge.hallyn@canonical.com>
>
> The uid/gid comparisons don't have to be pulled out. This just seemed
> more easily proved correct.
The following needs to be folded into this patch:
From: Serge Hallyn <serge.hallyn@canonical.com>
Date: Thu, 4 Aug 2011 21:48:13 +0000
Subject: [PATCH 2/2] fold up - net/core/scm.c: cred is const
Signed-off-by: Serge Hallyn <serge.hallyn@canonical.com>
---
net/core/scm.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/core/scm.c b/net/core/scm.c
index 21b5d0b..528fa36 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -43,7 +43,7 @@
* setu(g)id.
*/
-static __inline__ bool uidequiv(struct cred *src, struct ucred *tgt,
+static __inline__ bool uidequiv(const struct cred *src, struct ucred *tgt,
struct user_namespace *ns)
{
if (src->user_ns != ns)
@@ -57,7 +57,7 @@ check_capable:
return false;
}
-static __inline__ bool gidequiv(struct cred *src, struct ucred *tgt,
+static __inline__ bool gidequiv(const struct cred *src, struct ucred *tgt,
struct user_namespace *ns)
{
if (src->user_ns != ns)
--
1.7.5.4
^ permalink raw reply related
* IMPORTANT NOTICE: YOU WON
From: Vittorio Fondazione @ 2011-08-04 22:04 UTC (permalink / raw)
VITTORIO FONDAZIONE.
Corso Ercole I d'Este 44,
Ferrara 44100 - Italy.
IMPORTANT NOTICE
Foundation's Officer,
Fondazion Di Vittorio, Italy
http://www.fondazionedivittorio.it
CONCERN
You were selected among the lucky recipients to receive the award sum of US$650,000.00 (Six Hundred Fifty Thousand United State Dollars) as charity donations/aid from the Vittorio Fondazione, Ecowas and the UN These funds are freely given to you for your business, educational and personal development in accordance with the enabling act of Parliament.
You are required to expeditiously contact the Executive Secretary with your Qualification numbers (P-333-7858, B-011-67) for processing of your claims, you will be given your donation pin number. Contact Claudio Giovanni (DPU) Information Officer.
Enter Personal Details:
Beneficiary full name:
Nationality:
Complete home address:
Tel:
Mobile/Cell:(Very important):
Fax number:(optional)
Email address:
---------------------------------------------------------
DUE PROCESS UNIT:
Executive Secretary - Claudio Giovanni.
Email: ssww102@rediffmail.com
--------------------------------------------------------
On behalf of the Board kindly accept our warmest
congratulations.
Yours faithfully,
Mrs. Marian Bern.
(Foundation's Officer)
^ 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