* Re: [PATCH] udp: Fix inverted NAPI_GRO_CB(skb)->flush test
From: Eric Dumazet @ 2014-09-11 5:13 UTC (permalink / raw)
To: Scott Wood; +Cc: netdev, davem, Tom Herbert
In-Reply-To: <1410402198-30811-1-git-send-email-scottwood@freescale.com>
On Wed, 2014-09-10 at 21:23 -0500, Scott Wood wrote:
> Commit 2abb7cdc0d ("udp: Add support for doing checksum unnecessary
> conversion") caused napi_gro_cb structs with the "flush" field zero to
> take the "udp_gro_receive" path rather than the "set flush to 1" path
> that they would previously take. As a result I saw booting from an NFS
> root hang shortly after starting userspace, with "server not
> responding" messages.
>
> This change to the handling of "flush == 0" packets appears to be
> incidental to the goal of adding new code in the case where
> skb_gro_checksum_validate_zero_check() returns zero. Based on that and
> the fact that it breaks things, I'm assuming that it is unintentional.
>
> Fixes: 2abb7cdc0d ("udp: Add support for doing checksum unnecessary conversion")
> Cc: Tom Herbert <therbert@google.com>
> Signed-off-by: Scott Wood <scottwood@freescale.com>
> ---
> net/ipv4/udp_offload.c | 2 +-
> net/ipv6/udp_offload.c | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
Good catch, thanks !
Acked-by: Eric Dumazet <edumazet@google.com>
^ permalink raw reply
* Re: [RFC v2 3/6] kthread: warn on kill signal if not OOM
From: Alexander E. Patrakov @ 2014-09-11 5:42 UTC (permalink / raw)
To: Luis R. Rodriguez, Tom Gundersen
Cc: One Thousand Gnomes, Takashi Iwai, Kay Sievers, Sreekanth Reddy,
James Bottomley, Praveen Krishnamoorthy, hare,
Nagalakshmi Nandigama, Wu Zhangjin, Tetsuo Handa,
mpt-fusionlinux.pdl, Tim Gardner, Benjamin Poirier,
Santosh Rastapur, Casey Leedom, Hariprasad S, Pierre Fersing,
Arjan van de Ven, Abhijit Mahajan, systemd Mailing List
In-Reply-To: <CAB=NE6UprJH69hzc1mjqyq6PAn+7LZmX65Z8CDwUdJ73nDusHg@mail.gmail.com>
11.09.2014 03:10, Luis R. Rodriguez wrote:
> Tom, thanks for reviewing this! My reply below!
>
> On Tue, Sep 9, 2014 at 11:46 PM, Tom Gundersen <teg@jklm.no> wrote:
>> On Tue, Sep 9, 2014 at 10:45 PM, Luis R. Rodriguez
>> <mcgrof@do-not-panic.com> wrote:
>>> On Tue, Sep 9, 2014 at 12:35 PM, James Bottomley
>>> <James.Bottomley@hansenpartnership.com> wrote:
>>>> On Tue, 2014-09-09 at 12:16 -0700, Luis R. Rodriguez wrote:
>>>>> On Mon, Sep 8, 2014 at 10:38 PM, James Bottomley
>>>>> <James.Bottomley@hansenpartnership.com> wrote:
>>>>>> If we want to sort out some sync/async mechanism for probing devices, as
>>>>>> an agreement between the init systems and the kernel, that's fine, but
>>>>>> its a to-be negotiated enhancement.
>>>>>
>>>>> Unfortunately as Tejun notes the train has left which already made
>>>>> assumptions on this.
>>>>
>>>> Well, that's why it's a bug. It's a material regression impacting
>>>> users.
>>>
>>> Indeed. I believe the issue with this regression however was that the
>>> original commit e64fae55 (January 2012) was only accepted by *kernel
>>> folks* to be a real regression until recently.
>>
>> Just for the record, this only caused user-visible problems after
>> kernel commit 786235ee (November 2013), right?
>
> Another one was cxgb4:
>
> https://bugzilla.novell.com/show_bug.cgi?id=877622
>
> SLE12 does not yet have commit 786235ee merged. Benjamim did some hard
> work to debug this and trace the kill down to systemd-udev. A debug
> kernel build has been provided now to try to pick up exactly on the
> place where the kill was received, but its at least clear this came
> from systemd.
>
>>> More than two years
>>> have gone by on growing design and assumptions on top of that original
>>> commit. I'm not sure if *systemd folks* yet believe its was a design
>>> regression?
>>
>> I don't think so. udev should not allow its workers to run for an
>> unbounded length of time. Whether the upper bound should be 30, 60,
>> 180 seconds or something else is up for debate (currently it is 60,
>> but if that is too short for some drivers we could certainly revisit
>> that).
>
> That's the thing -- the timeout was put in place under the assumption
> probe was asyncronous and its not, the driver core issues both module
> init *and* probe together, the loader has to wait. That alone makes
> the timeout a design flaw, and then systemd carried on top of that
> design over two years after that. Its not systemd's fault, its just
> that we never spoke about this as a design thing broadly and we should
> have, and I will mention that even when the first issues creeped up,
> the issue was still tossed back a driver problems. It was only until
> recently that we realized that both init and probe run together that
> we've been thinking about this problem differently. Systemd was trying
> to ensure init on driver don't take long but its not init that is
> taking long, its probe, and probe gets then penalized as the driver
> core batches both init and probe synchronously before finishing module
> loading. Furthermore as clarified by Tejun random userland is known to
> exist that will wait indefinitely for module loading under the simple
> assumption things *are done synchronously*, and its precisely why we
> can't just blindly enable async probe upstream through a new driver
> boolean as it can be unfair to this old userland. What is being
> evaluated is to enable aync probe for *all* drivers through a new
> general system-wide option. We cannot regress old userspace and
> assumptions but we can create a new shiny universe.
>
>> Moreover, it seems from this discussion that the aim is (still)
>> that insmod should be near-instantaneous (i.e., not wait for probe),
>
> The only reason that is being discussed is that systemd has not
> accepted the timeout as a system design despite me pointing out the
> original design flaw recently and at this point even if was accepted
> as a design flaw it seems its too late. The approach taken to help
> make all drivers async is simply an afterthought to give systemd what
> it *thought* was in place, and it by no measure should be considered
> the proper fix to the regression introduced by systemd, it may perhaps
> be the right step long term for systemd systems given it goes with
> what it assumed was there, but the timeout was flawed. Its not clear
> if systemd can help with old kernels, it seems the ship has sailed and
> there seems no options but for folks to work around that -- unless of
> course some reasonable solution is found which doesn't break current
> systemd design?
>
>> so it seems to me that the basic design is correct and all we need is
>> some temporary work-around and a way to better detect misbehaving
>> drivers?
>
> As part of this series I addressed hunting for the "misbehaving
> drivers" in-kernel as I saw no progress on the systemd side of things
> to non-fatally detect "misbehaving drivers" despite my original RFCs
> and request for advice. I quote "misbehaving drivers" as its a flawed
> view to consider them misbehaving now in light of clarifications of
> how the driver core works in that it batches both init and probe
> together always and we can't be penalizing long probes due to the fact
> long probes are simply fine. My patch to pick up "misbehaving drivers"
> drivers on the kernel front by picking up systemd's signal was
> reactive but it was also simply braindead given the same exact reasons
> why systemd's original timeout was flawed. We want a general solution
> and we don't want to work around the root cause, in this case it was
> systemd's assumption on how drivers work.
>
> Keep in mind that the above just addresses kmod built-in cmd on
> systemd, its where the timeout was introduced but as has been
> clarified here assuming the same timeout on *all* other built-in
> likely is likely pretty flawed as well and this does concern me. Its
> why I mentioned that more than two years have gone by now on growing
> design and assumptions on top of that original commit and its why its
> hard for systemd to consider an alternative.
>
>>>>> I'm afraid distributions that want to avoid this
>>>>> sigkill at least on the kernel front will have to work around this
>>>>> issue either on systemd by increasing the default timeout which is now
>>>>> possible thanks to Hannes' changes or by some other means such as the
>>>>> combination of a modified non-chatty version of this patch + a check
>>>>> at the end of load_module() as mentioned earlier on these threads.
>>>>
>>>> Increasing the default timeout in systemd seems like the obvious bug fix
>>>> to me. If the patch exists already, having distros that want it use it
>>>> looks to be correct ... not every bug is a kernel bug, after all.
>>>
>>> Its merged upstream on systemd now, along with a few fixes on top of
>>> it. I also see Kay merged a change to the default timeout to 60 second
>>> on August 30. Its unclear if these discussions had any impact on that
>>> decision or if that was just because udev firmware loading got now
>>> ripped out. I'll note that the new 60 second timeout wouldn't suffice
>>> for cxgb4 even if it didn't do firmware loading, its probe takes over
>>> one full minute.
>>>
>>>> Negotiating a probe vs init split for drivers is fine too, but it's a
>>>> longer term thing rather than a bug fix.
>>>
>>> Indeed. What I proposed with a multiplier for the timeout for the
>>> different types of built in commands was deemed complex but saw no
>>> alternatives proposed despite my interest to work on one and
>>> clarifications noted that this was a design regression. Not quite sure
>>> what else I could have done here. I'm interested in learning what the
>>> better approach is for the future as if we want to marry init + kernel
>>> we need a smooth way for us to discuss design without getting worked
>>> up about it, or taking it personal. I really want this to work as I
>>> personally like systemd so far.
>>
>> How about this: keep the timeout global, but also introduce a
>> (relatively short, say 10 or 15 seconds) timeout after which a warning
>> is printed.
>
> That is something that I originally was looking forward to on systemd,
> but here's the thing once that warning comes up -- what would we do
> with it? This patch addresses this warning in-kernel and the idea was
> that we'd then peg an async_probe bool as true on the driver as a fix,
> that was decided to be silly given all the above. These drivers are
> actually not misbehaving and it would be even more incorrect to try to
> "fix" them by making them run asynchronously. In fact for some old
> storage drivers it may even be the worst thing to do given the
> possible slew of userland deployment and scripts which assume things
> *are* synchronous.
>
>> Even if nothing is actually killed, having workers (be it
>> insmod or something else) take longer than a couple of seconds is
>> likely a sign that something is seriously off somewhere.
>
> Probe can take a long time and that's fine, so for kmod the current
> assumption is flawed. If we had an option to async probe all drivers
> then perhaps this kmod timeout *might be reasonable*, and even then I
> do recommend for a clear warning that can be collected on logs on its
> first iteration rather than sigkilling, only after a whlie should
> sigkilling be done really. If systemd can deal with module loading in
> the background for drivers that take a long time and warning on that
> intsead of sigkiling it may be good start prior to enabling a default
> sigkill on drivers. This is perhaps also true for other workers but
> its not clear if this is a reasonable strategy for systemd.
>
> Luis
Just two small remarks to the whole thread.
First, I am quite surprised that nobody brought up the argument that
module loading is serialized by the kernel. So, while pata-marvell on my
laptop does its dirty "wait-reset-wait-reset-work" thing, no other
module can be loaded. This prevention of loading other drivers is the
thing that slows down the boot.
Second, I am going to XDC2014, LinuxCon Europe and Plumbers. I will take
my laptop with me, feel free to see the situation firsthand or try
debugging patches.
--
Alexander E. Patrakov
^ permalink raw reply
* Re: [PATCH v11 net-next 11/12] net: filter: move eBPF instruction macros
From: Daniel Borkmann @ 2014-09-11 6:29 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: David S. Miller, Ingo Molnar, Linus Torvalds, Andy Lutomirski,
Steven Rostedt, Hannes Frederic Sowa, Chema Gonzalez,
Eric Dumazet, Peter Zijlstra, Pablo Neira Ayuso, H. Peter Anvin,
Andrew Morton, Kees Cook, Linux API, Network Development, LKML
In-Reply-To: <CAMEtUuwQXj=oWzyBkogTSfOAhjhx0oyB5gC4+HoccTGWg8Obfg@mail.gmail.com>
On 09/10/2014 08:16 PM, Alexei Starovoitov wrote:
> On Wed, Sep 10, 2014 at 4:24 AM, Daniel Borkmann <dborkman@redhat.com> wrote:
>> On 09/10/2014 07:10 AM, Alexei Starovoitov wrote:
>>>
>>> move instruction macros (like BPF_MOV64_REG or BPF_ALU32_IMM)
>>> from linux/filter.h into uapi/linux/bpf.h
>>> so that userspace programs can use them.
>>>
>>> verifier testsuite (in later patches) will be using them.
>>>
>>> Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
>>
>> I don't think we need this commit at all. These macros are not really
>> part of the ABI and we should expose __as less as possible__, otherwise
>> we won't be able to alter them anymore. Plus, based on your previous
>> argumentation regarding the header file expose, we also won't be able
>> to add any new macros anymore since you could run into name collisions.
>>
>> Anyway, I don't see a reason why a e.g. central user space eBPF library
>> cannot live with, for example, a private copy of these helper macros or
>> whatever it wants to define by itself.
>>
>> I know in classic BPF there's BPF_STMT() and BPF_JUMP() but it's much
>> less complicated than eBPF and less likely to changes.
>
> Interesting idea. Are you saying just copy paste these
> 226 lines into user libbpf.h for now to use them in testsuite
> and examples ? Hmm.
> Indeed the less lines we add to uapi the better. I'll do that.
Yes, that should be just fine, the existing ABI is not allowed to
change anyway and we're running into less pain if we decide to change
existing or add new macros internally.
^ permalink raw reply
* Re: [PATCH v11 net-next 11/12] net: filter: move eBPF instruction macros
From: Alexei Starovoitov @ 2014-09-11 6:45 UTC (permalink / raw)
To: Daniel Borkmann
Cc: David S. Miller, Ingo Molnar, Linus Torvalds, Andy Lutomirski,
Steven Rostedt, Hannes Frederic Sowa, Chema Gonzalez,
Eric Dumazet, Peter Zijlstra, Pablo Neira Ayuso, H. Peter Anvin,
Andrew Morton, Kees Cook, Linux API, Network Development, LKML
In-Reply-To: <5411415D.4060103@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 711 bytes --]
On Wed, Sep 10, 2014 at 11:29 PM, Daniel Borkmann <dborkman@redhat.com> wrote:
>>
>> Interesting idea. Are you saying just copy paste these
>> 226 lines into user libbpf.h for now to use them in testsuite
>> and examples ? Hmm.
>> Indeed the less lines we add to uapi the better. I'll do that.
>
>
> Yes, that should be just fine, the existing ABI is not allowed to
> change anyway and we're running into less pain if we decide to change
> existing or add new macros internally.
ok. will do that in the next set.
btw, preliminary compat support in the attached patch.
It works fine, but Andy's concern about enum is starting
to get on me. May be we should replace
enum bpf_.._type with u32 just to be safe...
[-- Attachment #2: 0001-bpf-add-compat_sys_bpf-wrapper.patch --]
[-- Type: application/octet-stream, Size: 4218 bytes --]
From 9c05cc1bd18e278f0cfd5a490644105aa7cbbf52 Mon Sep 17 00:00:00 2001
From: Alexei Starovoitov <ast@plumgrid.com>
Date: Wed, 10 Sep 2014 19:41:31 -0700
Subject: [PATCH] bpf: add compat_sys_bpf wrapper
to support 32-bit user space with 64-bit kernel
Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
---
arch/x86/syscalls/syscall_32.tbl | 2 +-
include/uapi/asm-generic/unistd.h | 2 +-
kernel/bpf/syscall.c | 95 +++++++++++++++++++++++++++++++++++++
3 files changed, 97 insertions(+), 2 deletions(-)
diff --git a/arch/x86/syscalls/syscall_32.tbl b/arch/x86/syscalls/syscall_32.tbl
index 9fe1b5d002f0..2b1ddf1ddb5e 100644
--- a/arch/x86/syscalls/syscall_32.tbl
+++ b/arch/x86/syscalls/syscall_32.tbl
@@ -363,4 +363,4 @@
354 i386 seccomp sys_seccomp
355 i386 getrandom sys_getrandom
356 i386 memfd_create sys_memfd_create
-357 i386 bpf sys_bpf
+357 i386 bpf sys_bpf compat_sys_bpf
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index 22749c134117..94afed93f3cc 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -706,7 +706,7 @@ __SYSCALL(__NR_getrandom, sys_getrandom)
#define __NR_memfd_create 279
__SYSCALL(__NR_memfd_create, sys_memfd_create)
#define __NR_bpf 280
-__SYSCALL(__NR_bpf, sys_bpf)
+__SC_COMP(__NR_bpf, sys_bpf, compat_sys_bpf)
#undef __NR_syscalls
#define __NR_syscalls 281
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 6cdfe388c789..4f2c5441e175 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -16,6 +16,7 @@
#include <linux/file.h>
#include <linux/license.h>
#include <linux/filter.h>
+#include <linux/compat.h>
static LIST_HEAD(bpf_map_types);
@@ -576,6 +577,100 @@ free_attr:
return err;
}
+#ifdef CONFIG_COMPAT
+union compat_bpf_attr {
+ struct {
+ enum bpf_map_type map_type;
+ __u32 key_size;
+ __u32 value_size;
+ __u32 max_entries;
+ };
+
+ struct {
+ int map_fd;
+ compat_uptr_t key;
+ union {
+ compat_uptr_t value;
+ compat_uptr_t next_key;
+ };
+ };
+
+ struct {
+ enum bpf_prog_type prog_type;
+ __u32 insn_cnt;
+ compat_uptr_t insns;
+ compat_uptr_t license;
+ __u32 log_level;
+ __u32 log_size;
+ compat_uptr_t log_buf;
+ };
+};
+COMPAT_SYSCALL_DEFINE3(bpf, int, cmd, union compat_bpf_attr __user *, uattr,
+ unsigned int, size)
+{
+ union compat_bpf_attr compat_attr = {};
+ union bpf_attr attr = {};
+ int err;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ if (size > sizeof(compat_attr))
+ return -EINVAL;
+
+ if (copy_from_user(&compat_attr, uattr, size) != 0)
+ return -EFAULT;
+
+ switch (cmd) {
+ case BPF_MAP_CREATE:
+ attr.map_type = compat_attr.map_type;
+ attr.key_size = compat_attr.key_size;
+ attr.value_size = compat_attr.value_size;
+ attr.max_entries = compat_attr.max_entries;
+ err = map_create(&attr);
+ break;
+ case BPF_MAP_LOOKUP_ELEM:
+ attr.map_fd = compat_attr.map_fd;
+ attr.key = compat_ptr(compat_attr.key);
+ attr.value = compat_ptr(compat_attr.value);
+ err = map_lookup_elem(&attr);
+ break;
+ case BPF_MAP_UPDATE_ELEM:
+ attr.map_fd = compat_attr.map_fd;
+ attr.key = compat_ptr(compat_attr.key);
+ attr.value = compat_ptr(compat_attr.value);
+ err = map_update_elem(&attr);
+ break;
+ case BPF_MAP_DELETE_ELEM:
+ attr.map_fd = compat_attr.map_fd;
+ attr.key = compat_ptr(compat_attr.key);
+ err = map_delete_elem(&attr);
+ break;
+ case BPF_MAP_GET_NEXT_KEY:
+ attr.map_fd = compat_attr.map_fd;
+ attr.key = compat_ptr(compat_attr.key);
+ attr.next_key = compat_ptr(compat_attr.next_key);
+ err = map_get_next_key(&attr);
+ break;
+ case BPF_PROG_LOAD:
+ attr.prog_type = compat_attr.prog_type;
+ attr.insn_cnt = compat_attr.insn_cnt;
+ attr.insns = compat_ptr(compat_attr.insns);
+ attr.license = compat_ptr(compat_attr.license);
+ attr.log_level = compat_attr.log_level;
+ attr.log_size = compat_attr.log_size;
+ attr.log_buf = compat_ptr(compat_attr.log_buf);
+ err = bpf_prog_load(&attr);
+ break;
+ default:
+ err = -EINVAL;
+ break;
+ }
+
+ return err;
+}
+#endif
+
/* called from eBPF program under rcu lock
*
* if kernel subsystem is allowing eBPF programs to call this function,
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH] zd1211rw: replace ZD_ASSERT with lockdep_assert_held()
From: Johannes Berg @ 2014-09-11 6:53 UTC (permalink / raw)
To: Sharma, Sanjeev
Cc: dsd@gentoo.org, kune@deine-taler.de, linville@tuxdriver.com,
linux-wireless@vger.kernel.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <FDC088D3B5555644AE135ED28A7ABDE94DF4D490@EU-MBX-02.mgc.mentorg.com>
On Thu, 2014-09-11 at 04:02 +0000, Sharma, Sanjeev wrote:
> -----Original Message-----
> From: Johannes Berg [mailto:johannes@sipsolutions.net]
> Sent: Friday, August 22, 2014 5:01 PM
> To: Sharma, Sanjeev
> Cc: dsd@gentoo.org; kune@deine-taler.de; linville@tuxdriver.com; linux-wireless@vger.kernel.org; netdev@vger.kernel.org; linux-kernel@vger.kernel.org
> Subject: Re: [PATCH] zd1211rw: replace ZD_ASSERT with lockdep_assert_held()
>
> On Tue, 2014-08-19 at 06:39 +0000, Sharma, Sanjeev wrote:
> > Ping for review the patch.
>
> > Make sure it compiles ...
>
> Any update on this patch ?
I don't know, do you have any update for us?
Since your patch hasn't changed, it still cannot be compiled (when
lockdep is enabled). Make sure you test your patch before you submit it
again please.
johannes
^ permalink raw reply
* Re: [PATCH net-next 2/2] mac80211: Resolve sk_refcnt/sk_wmem_alloc issue in wifi ack path
From: Johannes Berg @ 2014-09-11 7:06 UTC (permalink / raw)
To: Alexander Duyck; +Cc: netdev, linux-wireless, davem, eric.dumazet, linville
In-Reply-To: <20140910220536.23225.92956.stgit@ahduyck-bv4.jf.intel.com>
On Wed, 2014-09-10 at 18:05 -0400, Alexander Duyck wrote:
> There is a possible issue with the use, or lack thereof of sk_refcnt and
> sk_wmem_alloc in the wifi ack status functionality.
>
> Specifically if a socket were to request acknowledgements, and the socket
> were to have sk_refcnt drop to 0 resulting in it waiting on sk_wmem_alloc
> to reach 0 it would be possible to have sock_queue_err_skb orphan the last
> buffer, resulting in __sk_free being called on the socket. After this the
> buffer is enqueued on sk_error_queue, however the queue has already been
> flushed resulting in at least a memory leak, if not a data corruption.
Oh. Thanks :-)
> + /* take a reference to prevent skb_orphan() from freeing the socket */
> + sock_hold(sk);
> +
> err = sock_queue_err_skb(sk, skb);
> if (err)
> kfree_skb(skb);
> +
> + sock_put(sk);
> }
> EXPORT_SYMBOL_GPL(skb_complete_wifi_ack);
Here I'm not sure it matters *for this function*? Wouldn't it be freed
then in sock_put(), which has the same net effect on this function
overall? It doesn't use it after sock_queue_err_skb().
Seems like maybe this should be in sock_queue_err_skb() itself, since it
does the orphaning first and then looks at the socket. Or the
documentation for that function should state that it has to be held, but
there are plenty of callers?
> spin_lock_irqsave(&local->ack_status_lock, flags);
> - id = idr_alloc(&local->ack_status_frames, orig_skb,
> + id = idr_alloc(&local->ack_status_frames, ack_skb,
> 1, 0x10000, GFP_ATOMIC);
> spin_unlock_irqrestore(&local->ack_status_lock, flags);
>
> if (id >= 0) {
> info_id = id;
> info_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
> - } else if (skb_shared(skb)) {
> - kfree_skb(orig_skb);
> } else {
> - kfree_skb(skb);
> - skb = orig_skb;
> + kfree_skb(ack_skb);
> }
So you're removing this part, but can't we really not reuse the clone_sk
copy? The difference is that it's charged, but that's fine for the
purposes here, no? Or am I misunderstanding that?
johannes
^ permalink raw reply
* [PATCH net-next] ethernet: amd: use pr_info_once()
From: Varka Bhadram @ 2014-09-11 7:20 UTC (permalink / raw)
To: netdev; +Cc: davem, Thomas.Lendacky, Varka Bhadram
It will use pr_info_one() to print the version info of the
driver in probe function only once. No need to use the static
variable here.
Signed-off-by: Varka Bhadram <varkab@cdac.in>
---
drivers/net/ethernet/amd/au1000_eth.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/amd/au1000_eth.c b/drivers/net/ethernet/amd/au1000_eth.c
index 31c48a7..6c323f4 100644
--- a/drivers/net/ethernet/amd/au1000_eth.c
+++ b/drivers/net/ethernet/amd/au1000_eth.c
@@ -1140,7 +1140,6 @@ static const struct net_device_ops au1000_netdev_ops = {
static int au1000_probe(struct platform_device *pdev)
{
- static unsigned version_printed;
struct au1000_private *aup = NULL;
struct au1000_eth_platform_data *pd;
struct net_device *dev = NULL;
@@ -1371,9 +1370,8 @@ static int au1000_probe(struct platform_device *pdev)
netdev_info(dev, "Au1xx0 Ethernet found at 0x%lx, irq %d\n",
(unsigned long)base->start, irq);
- if (version_printed++ == 0)
- pr_info("%s version %s %s\n",
- DRV_NAME, DRV_VERSION, DRV_AUTHOR);
+
+ pr_info_once("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR);
return 0;
--
1.7.9.5
^ permalink raw reply related
* Re: FlexCAN driver triggers kernel BUG in BUSOFF restart
From: Marc Kleine-Budde @ 2014-09-11 7:36 UTC (permalink / raw)
To: Keith Lugsden, Wolfgang Grandegger, Grant Likely, Rob Herring,
linux-can, netdev, linux-kernel, devicetree
In-Reply-To: <5411205A.4080606@lsirobway.com.au>
[-- Attachment #1: Type: text/plain, Size: 4837 bytes --]
On 09/11/2014 06:08 AM, Keith Lugsden wrote:
> I was asked by Freescale to post this kernel BUG to you and your email
> address appears in the kernel documentation, so please accept my
> apologies if you did not wish to see this.
Thanks for the bug report.
> A kernel BUG is triggered during a CAN send operation (kernel version
> 3.15.7, stack trace follows below). A simple program, such as the one
> included in the kernel's CAN documentation, will cause this problem, as
> will the can-utils programs 'cangen' and 'cansend'.
[...]
> Typical stack trace:
>
> BUG: scheduling while atomic: swapper/0/0/0x00000100
> 1 lock held by swapper/0/0:
> #0: (((&priv->restart_timer))){+.-...}, at: [<8002fe60>]
> call_timer_fn+0x0/0xe8
> Modules linked in:
> CPU: 0 PID: 0 Comm: swapper/0 Tainted: G W 3.15.7 #5
> Backtrace:
> [<80011ba4>] (dump_backtrace) from [<80011d40>] (show_stack+0x18/0x1c)
> r6:00000000 r5:00000000 r4:00000000 r3:00000000
> [<80011d28>] (show_stack) from [<805de120>] (dump_stack+0x88/0xa4)
> [<805de098>] (dump_stack) from [<805db3ec>] (__schedule_bug+0x64/0x7c)
> r5:80867268 r4:80867268
> [<805db388>] (__schedule_bug) from [<805e09b0>] (__schedule+0x540/0x5f8)
> r4:bf7c7b00 r3:00000002
> [<805e0470>] (__schedule) from [<805e0b5c>] (schedule+0x38/0x88)
> r10:8085c000 r9:00000000 r8:00000001 r7:00000000 r6:00004e20 r5:00000000
> r4:00002710
> [<805e0b24>] (schedule) from [<805e03c4>]
> (schedule_hrtimeout_range_clock+0xe0/0x158)
> [<805e02e4>] (schedule_hrtimeout_range_clock) from [<805e0450>]
> (schedule_hrtimeout_range+0x14/0x18)
> r10:808644c4 r8:bf335e00 r7:00000000 r6:c09b8000 r5:c09b8000 r4:bf335800
> [<805e043c>] (schedule_hrtimeout_range) from [<8002fb58>]
> (usleep_range+0x50/0x58)
> [<8002fb08>] (usleep_range) from [<803f2964>]
> (flexcan_chip_start+0x7c/0x440)
> [<803f28e8>] (flexcan_chip_start) from [<803f3994>]
> (flexcan_set_mode+0x28/0x54)
[...]
David Jander already provided a fix for this problem:
8badd65 can: flexcan: avoid calling usleep_range from interrupt context
It will hit mainline soon and then be backported to the stable trees.
Marc
---
From 8badd65e48c90d66587359d5329c2813088c0f50 Mon Sep 17 00:00:00 2001
From: David Jander <david@protonic.nl>
Date: Wed, 27 Aug 2014 12:02:16 +0200
Subject: [PATCH] can: flexcan: avoid calling usleep_range from interrupt
context
Apparently can_restart() runs from a (timer-) interrupt and can call
flexcan_chip_[en|dis]able(), so avoid using usleep_range()
Signed-off-by: David Jander <david@protonic.nl>
Cc: linux-stable <stable@vger.kernel.org>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/flexcan.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index 944aa5d..630c7bf 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -298,7 +298,7 @@ static int flexcan_chip_enable(struct flexcan_priv *priv)
flexcan_write(reg, ®s->mcr);
while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
- usleep_range(10, 20);
+ udelay(10);
if (flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)
return -ETIMEDOUT;
@@ -317,7 +317,7 @@ static int flexcan_chip_disable(struct flexcan_priv *priv)
flexcan_write(reg, ®s->mcr);
while (timeout-- && !(flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
- usleep_range(10, 20);
+ udelay(10);
if (!(flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
return -ETIMEDOUT;
@@ -336,7 +336,7 @@ static int flexcan_chip_freeze(struct flexcan_priv *priv)
flexcan_write(reg, ®s->mcr);
while (timeout-- && !(flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK))
- usleep_range(100, 200);
+ udelay(100);
if (!(flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK))
return -ETIMEDOUT;
@@ -355,7 +355,7 @@ static int flexcan_chip_unfreeze(struct flexcan_priv *priv)
flexcan_write(reg, ®s->mcr);
while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK))
- usleep_range(10, 20);
+ udelay(10);
if (flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)
return -ETIMEDOUT;
@@ -370,7 +370,7 @@ static int flexcan_chip_softreset(struct flexcan_priv *priv)
flexcan_write(FLEXCAN_MCR_SOFTRST, ®s->mcr);
while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_SOFTRST))
- usleep_range(10, 20);
+ udelay(10);
if (flexcan_read(®s->mcr) & FLEXCAN_MCR_SOFTRST)
return -ETIMEDOUT;
--
2.1.0
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]
^ permalink raw reply related
* My Proposal!
From: GVA&Atencia Abogados @ 2014-09-11 7:11 UTC (permalink / raw)
Please Acknowledge My Proposal!!
My name is Mr. Juan Martin Domingo a lawyer resident in Spain. I am
writing to let you know I have some FUNDS I want to transfer and am
seeking if you can be a beneficiary...Do not hesitate to Contact me for
more information if interested: gva_abogados@aim.com
Sincerely
Juan Martin Domingo.
Domijdo@aim.com
^ permalink raw reply
* pull-request: can 2014-09-11
From: Marc Kleine-Budde @ 2014-09-11 7:53 UTC (permalink / raw)
To: netdev; +Cc: davem, linux-can, kernel
Hello David,
this is a pull request for the current release cycle of a single patch.
The patch by David Jander fixes a scheduling while atomic problem in the
flexcan driver, that was introduced by me in v3.14-rc6.
Marc
The following changes since commit 1d7efe9dfaa6025acd29a726315f6f7d30a9f1ca:
Documentation: filter: Add MIPS to architectures with BPF JIT (2014-09-10 15:24:27 -0700)
are available in the git repository at:
git://gitorious.org/linux-can/linux-can.git tags/linux-can-fixes-for-3.17-20140911
for you to fetch changes up to 8badd65e48c90d66587359d5329c2813088c0f50:
can: flexcan: avoid calling usleep_range from interrupt context (2014-09-11 09:29:51 +0200)
----------------------------------------------------------------
linux-can-fixes-for-3.17-20140911
----------------------------------------------------------------
David Jander (1):
can: flexcan: avoid calling usleep_range from interrupt context
drivers/net/can/flexcan.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
^ permalink raw reply
* [PATCH] can: flexcan: avoid calling usleep_range from interrupt context
From: Marc Kleine-Budde @ 2014-09-11 7:53 UTC (permalink / raw)
To: netdev
Cc: davem, linux-can, kernel, David Jander, linux-stable,
Marc Kleine-Budde
In-Reply-To: <1410421984-15125-1-git-send-email-mkl@pengutronix.de>
From: David Jander <david@protonic.nl>
Apparently can_restart() runs from a (timer-) interrupt and can call
flexcan_chip_[en|dis]able(), so avoid using usleep_range()
Signed-off-by: David Jander <david@protonic.nl>
Cc: linux-stable <stable@vger.kernel.org>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/flexcan.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index 944aa5d..630c7bf 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -298,7 +298,7 @@ static int flexcan_chip_enable(struct flexcan_priv *priv)
flexcan_write(reg, ®s->mcr);
while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
- usleep_range(10, 20);
+ udelay(10);
if (flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)
return -ETIMEDOUT;
@@ -317,7 +317,7 @@ static int flexcan_chip_disable(struct flexcan_priv *priv)
flexcan_write(reg, ®s->mcr);
while (timeout-- && !(flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
- usleep_range(10, 20);
+ udelay(10);
if (!(flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
return -ETIMEDOUT;
@@ -336,7 +336,7 @@ static int flexcan_chip_freeze(struct flexcan_priv *priv)
flexcan_write(reg, ®s->mcr);
while (timeout-- && !(flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK))
- usleep_range(100, 200);
+ udelay(100);
if (!(flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK))
return -ETIMEDOUT;
@@ -355,7 +355,7 @@ static int flexcan_chip_unfreeze(struct flexcan_priv *priv)
flexcan_write(reg, ®s->mcr);
while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK))
- usleep_range(10, 20);
+ udelay(10);
if (flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)
return -ETIMEDOUT;
@@ -370,7 +370,7 @@ static int flexcan_chip_softreset(struct flexcan_priv *priv)
flexcan_write(FLEXCAN_MCR_SOFTRST, ®s->mcr);
while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_SOFTRST))
- usleep_range(10, 20);
+ udelay(10);
if (flexcan_read(®s->mcr) & FLEXCAN_MCR_SOFTRST)
return -ETIMEDOUT;
--
2.1.0
^ permalink raw reply related
* [PATCH net-next 00/14] tipc: new netlink API
From: richard.alpe @ 2014-09-11 8:29 UTC (permalink / raw)
To: netdev; +Cc: tipc-discussion
From: Richard Alpe <richard.alpe@ericsson.com>
This is a new netlink API for TIPC. It's intended to replace the
existing ASCII API. It utilizes many of the standard netlink
functionalities in the kernel, such as attribute nesting and
input polices.
There are a couple of reasons for this rewrite. The main and most
easily justifiable is that the existing API doesn't scale. Meaning
that a TIPC cluster with a larger amount of nodes, publications or
ports will rapidly exceed what the exiting API can handle. Resulting
in truncated or corrupt responses. In addition to this, the existing
ASCII API rarely uses "standard" kernel functions and has several
tipc specific functions for sanity checking and string formating.
The new API utilizes standard function for pushing data to socket
buffers and netlink attribute nesting to logically group data.
The new API can handle an arbitrary amount of data for things that
are likely to scale up as the TIPC usage and/or cluster size
increases.
A new user-space tool has been developed to work with this new API.
It is called "tipc" and is part of the "tipc-utils" package that
comes with many Linux distributions. The new "tipc" tool utilizes
standard functions from libnl to format, send, receive and process
messages. The tool has borrowed design philosophies from git and the
ip tool. Making the syntax resemble that of ip whiles its strong
modularity resembles that of git.
The existing tool for managing TIPC, "tipc-config" remains in the
package, but when built for kernels that has this new API it is
replaced by a script-based wrapper that maps the old syntax to the
new tool. This way, backwards compatibility is mostly preserved.
MORE ABOUT THE CODE
The main challenge here is to handle the case where the data is of
arbitrary size. This was largely neglected in the old API design.
For example when there is a lot of ports that has a large amount of
associated publications. In this specific case we can't assume that
all ports nor for that matter all the publications can fit inside a
single netlink message. Sending everything in one batch isn't an
option as we need to yield for the socket layer to cope.
This is solved by using the standard netlink callback for dumping
data and releasing the locks when the netlink message is full. The
dumping mechanism gets us back and we keep a reference (logical) to
where we where when the message became full. This means that we are
not "atomic", what is retrieved by user-space isn't a snapshot at a
certain time but rather a continuously updated data set. In the case
where we can't find our way back i.e. our logical reference are gone
we set a standard flag (NLM_F_DUMP_INTR) to tell user-space that the
dump was interrupted.
Richard Alpe (14):
tipc: add bearer disable/enable to new netlink api
tipc: add bearer get/dump to new netlink api
tipc: add bearer set to new netlink api
tipc: add sock dump to new netlink api
tipc: add link get/dump to new netlink api
tipc: add link set to new netlink api
tipc: add link stat reset to new netlink api
tipc: add media get/dump to new netlink api
tipc: add media set to new netlink api
tipc: add node get/dump to new netlink api
tipc: add net dump to new netlink api
tipc: add net set to new netlink api
tipc: add name table dump to new netlink api
tipc: remove old ASCII netlink API
include/uapi/linux/tipc_config.h | 478 ++++++++++--------------
net/tipc/Makefile | 2 +-
net/tipc/bcast.c | 130 +++++--
net/tipc/bcast.h | 4 +-
net/tipc/bearer.c | 510 ++++++++++++++++++++++----
net/tipc/bearer.h | 15 +-
net/tipc/config.c | 342 -----------------
net/tipc/config.h | 67 ----
net/tipc/core.c | 3 +-
net/tipc/link.c | 746 +++++++++++++++++++++++---------------
net/tipc/link.h | 14 +-
net/tipc/log.c | 1 -
net/tipc/name_table.c | 375 +++++++++----------
net/tipc/name_table.h | 5 +-
net/tipc/net.c | 107 +++++-
net/tipc/net.h | 8 +-
net/tipc/netlink.c | 129 +++++--
net/tipc/netlink.h | 47 +++
net/tipc/node.c | 209 +++++------
net/tipc/node.h | 6 +-
net/tipc/socket.c | 236 ++++++++----
net/tipc/socket.h | 3 +-
22 files changed, 1913 insertions(+), 1524 deletions(-)
delete mode 100644 net/tipc/config.c
delete mode 100644 net/tipc/config.h
create mode 100644 net/tipc/netlink.h
--
1.7.10.4
------------------------------------------------------------------------------
Want excitement?
Manually upgrade your production database.
When you want reliability, choose Perforce
Perforce version control. Predictably reliable.
http://pubads.g.doubleclick.net/gampad/clk?id=157508191&iu=/4140/ostg.clktrk
^ permalink raw reply
* [PATCH net-next 01/14] tipc: add bearer disable/enable to new netlink api
From: richard.alpe @ 2014-09-11 8:29 UTC (permalink / raw)
To: netdev; +Cc: tipc-discussion
In-Reply-To: <1410424167-17427-1-git-send-email-richard.alpe@ericsson.com>
From: Richard Alpe <richard.alpe@ericsson.com>
A new netlink API for tipc that can disable or enable a tipc bearer.
The API utilizes netlink policies for input validation. Where the
top-level netlink attributes are tipc-logical entities, like bearer.
The top level entities then contain nested attributes. In this case
a name, nested link properties and a domain.
Netlink commands implemented in this patch:
TIPC_NL_BEARER_ENABLE
TIPC_NL_BEARER_DISABLE
Netlink logical layout of bearer enable message:
-> bearer
-> name
[ -> domain ]
[
-> properties
-> priority
]
Netlink logical layout of bearer disable message:
-> bearer
-> name
Signed-off-by: Richard Alpe <richard.alpe@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
Acked-by: Ying Xue <ying.xue@windriver.com>
---
include/uapi/linux/tipc_config.h | 44 ++++++++++++++++-
net/tipc/bearer.c | 99 +++++++++++++++++++++++++++++++++++++-
net/tipc/bearer.h | 7 ++-
net/tipc/link.c | 47 ++++++++++++++++++
net/tipc/link.h | 3 ++
net/tipc/netlink.c | 27 +++++++++--
net/tipc/netlink.h | 47 ++++++++++++++++++
7 files changed, 266 insertions(+), 8 deletions(-)
create mode 100644 net/tipc/netlink.h
diff --git a/include/uapi/linux/tipc_config.h b/include/uapi/linux/tipc_config.h
index 876d0a1..954ecaa 100644
--- a/include/uapi/linux/tipc_config.h
+++ b/include/uapi/linux/tipc_config.h
@@ -1,7 +1,7 @@
/*
* include/uapi/linux/tipc_config.h: Header for TIPC configuration interface
*
- * Copyright (c) 2003-2006, Ericsson AB
+ * Copyright (c) 2003-2006, 2014, Ericsson AB
* Copyright (c) 2005-2007, 2010-2011, Wind River Systems
* All rights reserved.
*
@@ -46,6 +46,48 @@
#include <arpa/inet.h> /* for ntohs etc. */
#endif
+/* Netlink commands */
+enum {
+ TIPC_NL_UNSPEC,
+ TIPC_NL_LEGACY,
+ TIPC_NL_BEARER_DISABLE,
+ TIPC_NL_BEARER_ENABLE,
+
+ __TIPC_NL_CMD_MAX,
+ TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1
+};
+
+/* Top level netlink attributes */
+enum {
+ TIPC_NLA_UNSPEC,
+ TIPC_NLA_BEARER, /* nest */
+
+ __TIPC_NLA_MAX,
+ TIPC_NLA_MAX = __TIPC_NLA_MAX - 1
+};
+
+/* Bearer info */
+enum {
+ TIPC_NLA_BEARER_UNSPEC,
+ TIPC_NLA_BEARER_NAME, /* string */
+ TIPC_NLA_BEARER_PROP, /* nest */
+ TIPC_NLA_BEARER_DOMAIN, /* u32 */
+
+ __TIPC_NLA_BEARER_MAX,
+ TIPC_NLA_BEARER_MAX = __TIPC_NLA_BEARER_MAX - 1
+};
+
+/* Nest, link propreties. Valid for link, media and bearer */
+enum {
+ TIPC_NLA_PROP_UNSPEC,
+
+ TIPC_NLA_PROP_PRIO, /* u32 */
+ TIPC_NLA_PROP_TOL, /* u32 */
+ TIPC_NLA_PROP_WIN, /* u32 */
+
+ __TIPC_NLA_PROP_MAX,
+ TIPC_NLA_PROP_MAX = __TIPC_NLA_PROP_MAX - 1
+};
/*
* Configuration
*
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 2644743..59815be 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -1,7 +1,7 @@
/*
* net/tipc/bearer.c: TIPC bearer code
*
- * Copyright (c) 1996-2006, 2013, Ericsson AB
+ * Copyright (c) 1996-2006, 2013-2014, Ericsson AB
* Copyright (c) 2004-2006, 2010-2013, Wind River Systems
* All rights reserved.
*
@@ -37,6 +37,7 @@
#include "core.h"
#include "config.h"
#include "bearer.h"
+#include "link.h"
#include "discover.h"
#define MAX_ADDR_STR 60
@@ -49,6 +50,17 @@ static struct tipc_media * const media_info_array[] = {
NULL
};
+static const struct nla_policy
+tipc_nl_bearer_policy[TIPC_NLA_BEARER_MAX + 1] = {
+ [TIPC_NLA_BEARER_UNSPEC] = { .type = NLA_UNSPEC },
+ [TIPC_NLA_BEARER_NAME] = {
+ .type = NLA_STRING,
+ .len = TIPC_MAX_BEARER_NAME
+ },
+ [TIPC_NLA_BEARER_PROP] = { .type = NLA_NESTED },
+ [TIPC_NLA_BEARER_DOMAIN] = { .type = NLA_U32 }
+};
+
struct tipc_bearer __rcu *bearer_list[MAX_BEARERS + 1];
static void bearer_disable(struct tipc_bearer *b_ptr, bool shutting_down);
@@ -627,3 +639,88 @@ void tipc_bearer_stop(void)
}
}
}
+
+int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info)
+{
+ int err;
+ char *name;
+ struct tipc_bearer *bearer;
+ struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];
+
+ if (!info->attrs[TIPC_NLA_BEARER])
+ return -EINVAL;
+
+ err = nla_parse_nested(attrs, TIPC_NLA_BEARER_MAX,
+ info->attrs[TIPC_NLA_BEARER],
+ tipc_nl_bearer_policy);
+ if (err)
+ return err;
+
+ if (!attrs[TIPC_NLA_BEARER_NAME])
+ return -EINVAL;
+
+ name = nla_data(attrs[TIPC_NLA_BEARER_NAME]);
+
+ rtnl_lock();
+ bearer = tipc_bearer_find(name);
+ if (!bearer) {
+ rtnl_unlock();
+ return -EINVAL;
+ }
+
+ bearer_disable(bearer, false);
+ rtnl_unlock();
+
+ return 0;
+}
+
+int tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info)
+{
+ int err;
+ char *bearer;
+ struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];
+ u32 domain;
+ u32 prio;
+
+ prio = TIPC_MEDIA_LINK_PRI;
+ domain = tipc_own_addr & TIPC_CLUSTER_MASK;
+
+ if (!info->attrs[TIPC_NLA_BEARER])
+ return -EINVAL;
+
+ err = nla_parse_nested(attrs, TIPC_NLA_BEARER_MAX,
+ info->attrs[TIPC_NLA_BEARER],
+ tipc_nl_bearer_policy);
+ if (err)
+ return err;
+
+ if (!attrs[TIPC_NLA_BEARER_NAME])
+ return -EINVAL;
+
+ bearer = nla_data(attrs[TIPC_NLA_BEARER_NAME]);
+
+ if (attrs[TIPC_NLA_BEARER_DOMAIN])
+ domain = nla_get_u32(attrs[TIPC_NLA_BEARER_DOMAIN]);
+
+ if (attrs[TIPC_NLA_BEARER_PROP]) {
+ struct nlattr *props[TIPC_NLA_PROP_MAX + 1];
+
+ err = tipc_nl_parse_link_prop(attrs[TIPC_NLA_BEARER_PROP],
+ props);
+ if (err)
+ return err;
+
+ if (props[TIPC_NLA_PROP_PRIO])
+ prio = nla_get_u32(props[TIPC_NLA_PROP_PRIO]);
+ }
+
+ rtnl_lock();
+ err = tipc_enable_bearer(bearer, domain, prio);
+ if (err) {
+ rtnl_unlock();
+ return err;
+ }
+ rtnl_unlock();
+
+ return 0;
+}
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
index 78fccc4..a87e8c7 100644
--- a/net/tipc/bearer.h
+++ b/net/tipc/bearer.h
@@ -1,7 +1,7 @@
/*
* net/tipc/bearer.h: Include file for TIPC bearer code
*
- * Copyright (c) 1996-2006, 2013, Ericsson AB
+ * Copyright (c) 1996-2006, 2013-2014, Ericsson AB
* Copyright (c) 2005, 2010-2011, Wind River Systems
* All rights reserved.
*
@@ -38,6 +38,8 @@
#define _TIPC_BEARER_H
#include "bcast.h"
+#include "netlink.h"
+#include <net/genetlink.h>
#define MAX_BEARERS 2
#define MAX_MEDIA 2
@@ -176,6 +178,9 @@ extern struct tipc_media eth_media_info;
extern struct tipc_media ib_media_info;
#endif
+int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info);
+int tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info);
+
int tipc_media_set_priority(const char *name, u32 new_value);
int tipc_media_set_window(const char *name, u32 new_value);
void tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a);
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 65410e1..4628538 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -40,6 +40,7 @@
#include "name_distr.h"
#include "discover.h"
#include "config.h"
+#include "netlink.h"
#include <linux/pkt_sched.h>
@@ -50,6 +51,14 @@ static const char *link_co_err = "Link changeover error, ";
static const char *link_rst_msg = "Resetting link ";
static const char *link_unk_evt = "Unknown link event ";
+/* Properties valid for media, bearar and link */
+static const struct nla_policy tipc_nl_prop_policy[TIPC_NLA_PROP_MAX + 1] = {
+ [TIPC_NLA_PROP_UNSPEC] = { .type = NLA_UNSPEC },
+ [TIPC_NLA_PROP_PRIO] = { .type = NLA_U32 },
+ [TIPC_NLA_PROP_TOL] = { .type = NLA_U32 },
+ [TIPC_NLA_PROP_WIN] = { .type = NLA_U32 }
+};
+
/*
* Out-of-range value for link session numbers
*/
@@ -2370,3 +2379,41 @@ static void link_print(struct tipc_link *l_ptr, const char *str)
else
pr_cont("\n");
}
+
+/* Parse and validate nested (link) properties valid for media, bearer and link
+ */
+int tipc_nl_parse_link_prop(struct nlattr *prop, struct nlattr *props[])
+{
+ int err;
+
+ err = nla_parse_nested(props, TIPC_NLA_PROP_MAX, prop,
+ tipc_nl_prop_policy);
+ if (err)
+ return err;
+
+ if (props[TIPC_NLA_PROP_PRIO]) {
+ u32 prio;
+
+ prio = nla_get_u32(props[TIPC_NLA_PROP_PRIO]);
+ if (prio > TIPC_MAX_LINK_PRI)
+ return -EINVAL;
+ }
+
+ if (props[TIPC_NLA_PROP_TOL]) {
+ u32 tol;
+
+ tol = nla_get_u32(props[TIPC_NLA_PROP_TOL]);
+ if ((tol < TIPC_MIN_LINK_TOL) || (tol > TIPC_MAX_LINK_TOL))
+ return -EINVAL;
+ }
+
+ if (props[TIPC_NLA_PROP_WIN]) {
+ u32 win;
+
+ win = nla_get_u32(props[TIPC_NLA_PROP_WIN]);
+ if ((win < TIPC_MIN_LINK_WIN) || (win > TIPC_MAX_LINK_WIN))
+ return -EINVAL;
+ }
+
+ return 0;
+}
diff --git a/net/tipc/link.h b/net/tipc/link.h
index b567a34..4338294 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -37,6 +37,7 @@
#ifndef _TIPC_LINK_H
#define _TIPC_LINK_H
+#include <net/genetlink.h>
#include "msg.h"
#include "node.h"
@@ -239,6 +240,8 @@ void tipc_link_set_queue_limits(struct tipc_link *l_ptr, u32 window);
void tipc_link_retransmit(struct tipc_link *l_ptr,
struct sk_buff *start, u32 retransmits);
+int tipc_nl_parse_link_prop(struct nlattr *prop, struct nlattr *props[]);
+
/*
* Link sequence number manipulation routines (uses modulo 2**16 arithmetic)
*/
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index ad844d3..7c0cf46 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -1,7 +1,7 @@
/*
* net/tipc/netlink.c: TIPC configuration handling
*
- * Copyright (c) 2005-2006, Ericsson AB
+ * Copyright (c) 2005-2006, 2014, Ericsson AB
* Copyright (c) 2005-2007, Wind River Systems
* All rights reserved.
*
@@ -36,6 +36,7 @@
#include "core.h"
#include "config.h"
+#include "bearer.h"
#include <net/genetlink.h>
static int handle_cmd(struct sk_buff *skb, struct genl_info *info)
@@ -68,19 +69,35 @@ static int handle_cmd(struct sk_buff *skb, struct genl_info *info)
return 0;
}
-static struct genl_family tipc_genl_family = {
+static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 1] = {
+ [TIPC_NLA_UNSPEC] = { .type = NLA_UNSPEC, },
+ [TIPC_NLA_BEARER] = { .type = NLA_NESTED, },
+};
+
+struct genl_family tipc_genl_family = {
.id = GENL_ID_GENERATE,
.name = TIPC_GENL_NAME,
.version = TIPC_GENL_VERSION,
- .hdrsize = TIPC_GENL_HDRLEN,
- .maxattr = 0,
+ .hdrsize = 0,
+ .maxattr = TIPC_NLA_MAX,
};
-static struct genl_ops tipc_genl_ops[] = {
+static const struct genl_ops tipc_genl_ops[] = {
{
+ /* Legacy ASCII API */
.cmd = TIPC_GENL_CMD,
.doit = handle_cmd,
},
+ {
+ .cmd = TIPC_NL_BEARER_DISABLE,
+ .doit = tipc_nl_bearer_disable,
+ .policy = tipc_nl_policy,
+ },
+ {
+ .cmd = TIPC_NL_BEARER_ENABLE,
+ .doit = tipc_nl_bearer_enable,
+ .policy = tipc_nl_policy,
+ }
};
int tipc_netlink_start(void)
diff --git a/net/tipc/netlink.h b/net/tipc/netlink.h
new file mode 100644
index 0000000..e3b7890
--- /dev/null
+++ b/net/tipc/netlink.h
@@ -0,0 +1,47 @@
+/*
+ * net/tipc/netlink.h: Include file for TIPC netlink code
+ *
+ * Copyright (c) 2014, Ericsson AB
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the names of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _TIPC_NETLINK_H
+#define _TIPC_NETLINK_H
+
+extern struct genl_family tipc_genl_family;
+
+struct tipc_nl_msg {
+ struct sk_buff *skb;
+ u32 portid;
+ u32 seq;
+};
+
+#endif
--
1.7.10.4
------------------------------------------------------------------------------
Want excitement?
Manually upgrade your production database.
When you want reliability, choose Perforce
Perforce version control. Predictably reliable.
http://pubads.g.doubleclick.net/gampad/clk?id=157508191&iu=/4140/ostg.clktrk
^ permalink raw reply related
* [PATCH net-next 02/14] tipc: add bearer get/dump to new netlink api
From: richard.alpe @ 2014-09-11 8:29 UTC (permalink / raw)
To: netdev; +Cc: tipc-discussion
In-Reply-To: <1410424167-17427-1-git-send-email-richard.alpe@ericsson.com>
From: Richard Alpe <richard.alpe@ericsson.com>
Add TIPC_NL_BEARER_GET command to the new tipc netlink API.
This command supports dumping all data about all bearers or getting
all information about a specific bearer.
The information about a bearer includes name, link priorities and
domain.
Netlink logical layout of bearer get message:
-> bearer
-> name
Netlink logical layout of returned bearer information:
-> bearer
-> name
-> link properties
-> priority
-> tolerance
-> window
-> domain
Signed-off-by: Richard Alpe <richard.alpe@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
Acked-by: Ying Xue <ying.xue@windriver.com>
---
include/uapi/linux/tipc_config.h | 1 +
net/tipc/bearer.c | 125 ++++++++++++++++++++++++++++++++++++++
net/tipc/bearer.h | 2 +
net/tipc/netlink.c | 6 ++
4 files changed, 134 insertions(+)
diff --git a/include/uapi/linux/tipc_config.h b/include/uapi/linux/tipc_config.h
index 954ecaa..6caf581 100644
--- a/include/uapi/linux/tipc_config.h
+++ b/include/uapi/linux/tipc_config.h
@@ -52,6 +52,7 @@ enum {
TIPC_NL_LEGACY,
TIPC_NL_BEARER_DISABLE,
TIPC_NL_BEARER_ENABLE,
+ TIPC_NL_BEARER_GET,
__TIPC_NL_CMD_MAX,
TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 59815be..7f77cec 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -640,6 +640,131 @@ void tipc_bearer_stop(void)
}
}
+/* Caller should hold rtnl_lock to protect the bearer */
+int __tipc_nl_add_bearer(struct tipc_nl_msg *msg, struct tipc_bearer *bearer)
+{
+ void *hdr;
+ struct nlattr *attrs;
+ struct nlattr *prop;
+
+ hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
+ NLM_F_MULTI, TIPC_NL_BEARER_GET);
+ if (!hdr)
+ return -EMSGSIZE;
+
+ attrs = nla_nest_start(msg->skb, TIPC_NLA_BEARER);
+ if (!attrs)
+ goto msg_full;
+
+ if (nla_put_string(msg->skb, TIPC_NLA_BEARER_NAME, bearer->name))
+ goto attr_msg_full;
+
+ prop = nla_nest_start(msg->skb, TIPC_NLA_BEARER_PROP);
+ if (!prop)
+ goto prop_msg_full;
+ if (nla_put_u32(msg->skb, TIPC_NLA_PROP_PRIO, bearer->priority))
+ goto prop_msg_full;
+ if (nla_put_u32(msg->skb, TIPC_NLA_PROP_TOL, bearer->tolerance))
+ goto prop_msg_full;
+ if (nla_put_u32(msg->skb, TIPC_NLA_PROP_WIN, bearer->window))
+ goto prop_msg_full;
+
+ nla_nest_end(msg->skb, prop);
+ nla_nest_end(msg->skb, attrs);
+ genlmsg_end(msg->skb, hdr);
+
+ return 0;
+
+prop_msg_full:
+ nla_nest_cancel(msg->skb, prop);
+attr_msg_full:
+ nla_nest_cancel(msg->skb, attrs);
+msg_full:
+ genlmsg_cancel(msg->skb, hdr);
+
+ return -EMSGSIZE;
+}
+
+int tipc_nl_bearer_dump(struct sk_buff *skb, struct netlink_callback *cb)
+{
+ int err;
+ int i = cb->args[0];
+ struct tipc_bearer *bearer;
+ struct tipc_nl_msg msg;
+
+ if (i == MAX_BEARERS)
+ return 0;
+
+ msg.skb = skb;
+ msg.portid = NETLINK_CB(cb->skb).portid;
+ msg.seq = cb->nlh->nlmsg_seq;
+
+ rtnl_lock();
+ for (i = 0; i < MAX_BEARERS; i++) {
+ bearer = rtnl_dereference(bearer_list[i]);
+ if (!bearer)
+ continue;
+
+ err = __tipc_nl_add_bearer(&msg, bearer);
+ if (err)
+ break;
+ }
+ rtnl_unlock();
+
+ cb->args[0] = i;
+ return skb->len;
+}
+
+int tipc_nl_bearer_get(struct sk_buff *skb, struct genl_info *info)
+{
+ int err;
+ char *name;
+ struct sk_buff *rep;
+ struct tipc_bearer *bearer;
+ struct tipc_nl_msg msg;
+ struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];
+
+ if (!info->attrs[TIPC_NLA_BEARER])
+ return -EINVAL;
+
+ err = nla_parse_nested(attrs, TIPC_NLA_BEARER_MAX,
+ info->attrs[TIPC_NLA_BEARER],
+ tipc_nl_bearer_policy);
+ if (err)
+ return err;
+
+ if (!attrs[TIPC_NLA_BEARER_NAME])
+ return -EINVAL;
+ name = nla_data(attrs[TIPC_NLA_BEARER_NAME]);
+
+ rep = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+ if (!rep)
+ return -ENOMEM;
+
+ msg.skb = rep;
+ msg.portid = info->snd_portid;
+ msg.seq = info->snd_seq;
+
+ rtnl_lock();
+ bearer = tipc_bearer_find(name);
+ if (!bearer) {
+ err = -EINVAL;
+ goto err_out;
+ }
+
+ err = __tipc_nl_add_bearer(&msg, bearer);
+ if (err)
+ goto err_out;
+ rtnl_unlock();
+
+ return genlmsg_reply(rep, info);
+err_out:
+ rtnl_unlock();
+ nlmsg_free(rep);
+
+ return err;
+}
+
int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info)
{
int err;
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
index a87e8c7..2d07e35 100644
--- a/net/tipc/bearer.h
+++ b/net/tipc/bearer.h
@@ -180,6 +180,8 @@ extern struct tipc_media ib_media_info;
int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info);
int tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info);
+int tipc_nl_bearer_dump(struct sk_buff *skb, struct netlink_callback *cb);
+int tipc_nl_bearer_get(struct sk_buff *skb, struct genl_info *info);
int tipc_media_set_priority(const char *name, u32 new_value);
int tipc_media_set_window(const char *name, u32 new_value);
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index 7c0cf46..ef106a7 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -97,6 +97,12 @@ static const struct genl_ops tipc_genl_ops[] = {
.cmd = TIPC_NL_BEARER_ENABLE,
.doit = tipc_nl_bearer_enable,
.policy = tipc_nl_policy,
+ },
+ {
+ .cmd = TIPC_NL_BEARER_GET,
+ .doit = tipc_nl_bearer_get,
+ .dumpit = tipc_nl_bearer_dump,
+ .policy = tipc_nl_policy,
}
};
--
1.7.10.4
------------------------------------------------------------------------------
Want excitement?
Manually upgrade your production database.
When you want reliability, choose Perforce
Perforce version control. Predictably reliable.
http://pubads.g.doubleclick.net/gampad/clk?id=157508191&iu=/4140/ostg.clktrk
^ permalink raw reply related
* [PATCH net-next 03/14] tipc: add bearer set to new netlink api
From: richard.alpe @ 2014-09-11 8:29 UTC (permalink / raw)
To: netdev; +Cc: tipc-discussion
In-Reply-To: <1410424167-17427-1-git-send-email-richard.alpe@ericsson.com>
From: Richard Alpe <richard.alpe@ericsson.com>
Add TIPC_NL_BEARER_SET command to the new tipc netlink API.
This command can set one or more link properties for a particular
bearer.
Netlink logical layout of bearer set message:
-> bearer
-> name
-> link properties
[ -> tolerance ]
[ -> priority ]
[ -> window ]
Signed-off-by: Richard Alpe <richard.alpe@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
Acked-by: Ying Xue <ying.xue@windriver.com>
---
include/uapi/linux/tipc_config.h | 1 +
net/tipc/bearer.c | 49 ++++++++++++++++++++++++++++++++++++++
net/tipc/bearer.h | 1 +
net/tipc/netlink.c | 5 ++++
4 files changed, 56 insertions(+)
diff --git a/include/uapi/linux/tipc_config.h b/include/uapi/linux/tipc_config.h
index 6caf581..af7acac 100644
--- a/include/uapi/linux/tipc_config.h
+++ b/include/uapi/linux/tipc_config.h
@@ -53,6 +53,7 @@ enum {
TIPC_NL_BEARER_DISABLE,
TIPC_NL_BEARER_ENABLE,
TIPC_NL_BEARER_GET,
+ TIPC_NL_BEARER_SET,
__TIPC_NL_CMD_MAX,
TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 7f77cec..906e644 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -849,3 +849,52 @@ int tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info)
return 0;
}
+
+int tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info)
+{
+ int err;
+ char *name;
+ struct tipc_bearer *b;
+ struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];
+
+ if (!info->attrs[TIPC_NLA_BEARER])
+ return -EINVAL;
+
+ err = nla_parse_nested(attrs, TIPC_NLA_BEARER_MAX,
+ info->attrs[TIPC_NLA_BEARER],
+ tipc_nl_bearer_policy);
+ if (err)
+ return err;
+
+ if (!attrs[TIPC_NLA_BEARER_NAME])
+ return -EINVAL;
+ name = nla_data(attrs[TIPC_NLA_BEARER_NAME]);
+
+ rtnl_lock();
+ b = tipc_bearer_find(name);
+ if (!b) {
+ rtnl_unlock();
+ return -EINVAL;
+ }
+
+ if (attrs[TIPC_NLA_BEARER_PROP]) {
+ struct nlattr *props[TIPC_NLA_PROP_MAX + 1];
+
+ err = tipc_nl_parse_link_prop(attrs[TIPC_NLA_BEARER_PROP],
+ props);
+ if (err) {
+ rtnl_unlock();
+ return err;
+ }
+
+ if (props[TIPC_NLA_PROP_TOL])
+ b->tolerance = nla_get_u32(props[TIPC_NLA_PROP_TOL]);
+ if (props[TIPC_NLA_PROP_PRIO])
+ b->priority = nla_get_u32(props[TIPC_NLA_PROP_PRIO]);
+ if (props[TIPC_NLA_PROP_WIN])
+ b->window = nla_get_u32(props[TIPC_NLA_PROP_WIN]);
+ }
+ rtnl_unlock();
+
+ return 0;
+}
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
index 2d07e35..c6cf9df 100644
--- a/net/tipc/bearer.h
+++ b/net/tipc/bearer.h
@@ -182,6 +182,7 @@ int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info);
int tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info);
int tipc_nl_bearer_dump(struct sk_buff *skb, struct netlink_callback *cb);
int tipc_nl_bearer_get(struct sk_buff *skb, struct genl_info *info);
+int tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info);
int tipc_media_set_priority(const char *name, u32 new_value);
int tipc_media_set_window(const char *name, u32 new_value);
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index ef106a7..e5fbea9 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -103,6 +103,11 @@ static const struct genl_ops tipc_genl_ops[] = {
.doit = tipc_nl_bearer_get,
.dumpit = tipc_nl_bearer_dump,
.policy = tipc_nl_policy,
+ },
+ {
+ .cmd = TIPC_NL_BEARER_SET,
+ .doit = tipc_nl_bearer_set,
+ .policy = tipc_nl_policy,
}
};
--
1.7.10.4
------------------------------------------------------------------------------
Want excitement?
Manually upgrade your production database.
When you want reliability, choose Perforce
Perforce version control. Predictably reliable.
http://pubads.g.doubleclick.net/gampad/clk?id=157508191&iu=/4140/ostg.clktrk
^ permalink raw reply related
* [PATCH net-next 04/14] tipc: add sock dump to new netlink api
From: richard.alpe @ 2014-09-11 8:29 UTC (permalink / raw)
To: netdev; +Cc: tipc-discussion
In-Reply-To: <1410424167-17427-1-git-send-email-richard.alpe@ericsson.com>
From: Richard Alpe <richard.alpe@ericsson.com>
Add TIPC_NL_SOCK_GET command to the new tipc netlink API.
This command supports dumping of all available sockets with their
associated connection or publication(s). It could be extended to reply
with a single socket if the NLM_F_DUMP isn't set.
The information about a socket includes reference, address, connection
information / publication information.
Netlink logical layout of response message:
-> socket
-> reference
-> address
[
-> connection
-> node
-> socket
[
-> connected flag
-> type
-> instance
]
]
[
-> publications
-> publication
-> type
-> lower
-> upper
]
Signed-off-by: Richard Alpe <richard.alpe@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
Acked-by: Ying Xue <ying.xue@windriver.com>
---
include/uapi/linux/tipc_config.h | 44 +++++++++++
net/tipc/netlink.c | 7 ++
net/tipc/socket.c | 159 ++++++++++++++++++++++++++++++++++++++
net/tipc/socket.h | 2 +
4 files changed, 212 insertions(+)
diff --git a/include/uapi/linux/tipc_config.h b/include/uapi/linux/tipc_config.h
index af7acac..e09dec2 100644
--- a/include/uapi/linux/tipc_config.h
+++ b/include/uapi/linux/tipc_config.h
@@ -54,6 +54,7 @@ enum {
TIPC_NL_BEARER_ENABLE,
TIPC_NL_BEARER_GET,
TIPC_NL_BEARER_SET,
+ TIPC_NL_SOCK_GET,
__TIPC_NL_CMD_MAX,
TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1
@@ -63,6 +64,7 @@ enum {
enum {
TIPC_NLA_UNSPEC,
TIPC_NLA_BEARER, /* nest */
+ TIPC_NLA_SOCK, /* nest */
__TIPC_NLA_MAX,
TIPC_NLA_MAX = __TIPC_NLA_MAX - 1
@@ -79,6 +81,48 @@ enum {
TIPC_NLA_BEARER_MAX = __TIPC_NLA_BEARER_MAX - 1
};
+/* Port info */
+enum {
+ TIPC_NLA_SOCK_UNSPEC,
+ TIPC_NLA_SOCK_ADDR, /* u32 */
+ TIPC_NLA_SOCK_REF, /* u32 */
+ TIPC_NLA_SOCK_CON, /* nest */
+ TIPC_NLA_SOCK_PUBL, /* nest */
+
+ __TIPC_NLA_SOCK_MAX,
+ TIPC_NLA_SOCK_MAX = __TIPC_NLA_SOCK_MAX - 1
+};
+
+/* Nest, publication info */
+enum {
+ TIPC_NLA_PUBL_UNSPEC,
+
+ TIPC_NLA_PUBL_TYPE, /* u32 */
+ TIPC_NLA_PUBL_LOWER, /* u32 */
+ TIPC_NLA_PUBL_UPPER, /* u32 */
+ TIPC_NLA_PUBL_SCOPE, /* u32 */
+ TIPC_NLA_PUBL_NODE, /* u32 */
+ TIPC_NLA_PUBL_REF, /* u32 */
+ TIPC_NLA_PUBL_KEY, /* u32 */
+
+ __TIPC_NLA_PUBL_MAX,
+ TIPC_NLA_PUBL_MAX = __TIPC_NLA_PUBL_MAX - 1
+};
+
+/* Nest, connection info */
+enum {
+ TIPC_NLA_CON_UNSPEC,
+
+ TIPC_NLA_CON_FLAG, /* flag */
+ TIPC_NLA_CON_NODE, /* u32 */
+ TIPC_NLA_CON_SOCK, /* u32 */
+ TIPC_NLA_CON_TYPE, /* u32 */
+ TIPC_NLA_CON_INST, /* u32 */
+
+ __TIPC_NLA_CON_MAX,
+ TIPC_NLA_CON_MAX = __TIPC_NLA_CON_MAX - 1
+};
+
/* Nest, link propreties. Valid for link, media and bearer */
enum {
TIPC_NLA_PROP_UNSPEC,
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index e5fbea9..52973ce 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -36,6 +36,7 @@
#include "core.h"
#include "config.h"
+#include "socket.h"
#include "bearer.h"
#include <net/genetlink.h>
@@ -72,6 +73,7 @@ static int handle_cmd(struct sk_buff *skb, struct genl_info *info)
static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 1] = {
[TIPC_NLA_UNSPEC] = { .type = NLA_UNSPEC, },
[TIPC_NLA_BEARER] = { .type = NLA_NESTED, },
+ [TIPC_NLA_SOCK] = { .type = NLA_NESTED, },
};
struct genl_family tipc_genl_family = {
@@ -108,6 +110,11 @@ static const struct genl_ops tipc_genl_ops[] = {
.cmd = TIPC_NL_BEARER_SET,
.doit = tipc_nl_bearer_set,
.policy = tipc_nl_policy,
+ },
+ {
+ .cmd = TIPC_NL_SOCK_GET,
+ .dumpit = tipc_nl_sk_dump,
+ .policy = tipc_nl_policy,
}
};
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 75275c5..bb58029 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -2802,3 +2802,162 @@ void tipc_socket_stop(void)
sock_unregister(tipc_family_ops.family);
proto_unregister(&tipc_proto);
}
+
+/* Caller should hold socket lock for the passed tipc socket. */
+int __tipc_nl_list_sk_publ(struct sk_buff *skb, struct netlink_callback *cb,
+ struct tipc_sock *tsk, u32 *prev_publ)
+{
+ struct nlattr *publ;
+ struct publication *p;
+
+ if (*prev_publ) {
+ list_for_each_entry(p, &tsk->publications, pport_list) {
+ if (p->key == *prev_publ)
+ break;
+ }
+
+ if (p->key != *prev_publ) {
+ nlmsg_hdr(skb)->nlmsg_flags |= NLM_F_DUMP_INTR;
+ *prev_publ = 0;
+ return -EPIPE;
+ }
+ } else {
+ p = list_first_entry(&tsk->publications, struct publication,
+ pport_list);
+ }
+
+ list_for_each_entry_from(p, &tsk->publications, pport_list) {
+ publ = nla_nest_start(skb, TIPC_NLA_SOCK_PUBL);
+ if (nla_put_u32(skb, TIPC_NLA_PUBL_TYPE, p->type))
+ goto msg_full;
+ if (nla_put_u32(skb, TIPC_NLA_PUBL_LOWER, p->lower))
+ goto msg_full;
+ if (nla_put_u32(skb, TIPC_NLA_PUBL_UPPER, p->upper))
+ goto msg_full;
+ nla_nest_end(skb, publ);
+ }
+
+ *prev_publ = 0;
+
+ return 0;
+
+msg_full:
+ *prev_publ = p->key;
+ nla_nest_cancel(skb, publ);
+
+ return -EMSGSIZE;
+}
+
+/* Caller should hold socket lock for the passed tipc socket. */
+int __tipc_nl_add_sk_con(struct sk_buff *skb, struct tipc_sock *tsk)
+{
+ u32 peer_node;
+ u32 peer_port;
+ struct nlattr *nest;
+
+ peer_node = tsk_peer_node(tsk);
+ peer_port = tsk_peer_port(tsk);
+
+ nest = nla_nest_start(skb, TIPC_NLA_SOCK_CON);
+
+ if (nla_put_u32(skb, TIPC_NLA_CON_NODE, peer_node))
+ goto msg_full;
+ if (nla_put_u32(skb, TIPC_NLA_CON_SOCK, peer_port))
+ goto msg_full;
+
+ if (tsk->conn_type != 0) {
+ if (nla_put_flag(skb, TIPC_NLA_CON_FLAG))
+ goto msg_full;
+ if (nla_put_u32(skb, TIPC_NLA_CON_TYPE, tsk->conn_type))
+ goto msg_full;
+ if (nla_put_u32(skb, TIPC_NLA_CON_INST, tsk->conn_instance))
+ goto msg_full;
+ }
+ nla_nest_end(skb, nest);
+
+ return 0;
+
+msg_full:
+ nla_nest_cancel(skb, nest);
+
+ return -EMSGSIZE;
+}
+
+/* Caller should hold socket lock for the passed tipc socket. */
+int __tipc_nl_add_sk(struct sk_buff *skb, struct netlink_callback *cb,
+ struct tipc_sock *tsk, u32 *prev_publ)
+{
+ void *hdr;
+ int res = 0;
+ struct nlattr *attrs;
+ struct nlattr *publs;
+
+ hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
+ &tipc_genl_family, NLM_F_MULTI, TIPC_NL_SOCK_GET);
+ if (!hdr)
+ goto msg_cancel;
+
+ attrs = nla_nest_start(skb, TIPC_NLA_SOCK);
+ if (!attrs)
+ goto genlmsg_cancel;
+
+ if (nla_put_u32(skb, TIPC_NLA_SOCK_REF, tsk->ref))
+ goto attr_msg_cancel;
+ if (nla_put_u32(skb, TIPC_NLA_SOCK_ADDR, tipc_own_addr))
+ goto attr_msg_cancel;
+
+ /* We assume a socket is either connected or published */
+ if (tsk->connected) {
+ res = __tipc_nl_add_sk_con(skb, tsk);
+ if (res != 0)
+ goto attr_msg_cancel;
+ } else {
+ publs = nla_nest_start(skb, TIPC_NLA_SOCK_PUBL);
+ if (!publs)
+ goto attr_msg_cancel;
+
+ res = __tipc_nl_list_sk_publ(skb, cb, tsk, prev_publ);
+ /* As the publication count is arbitrary large, we send even an
+ * incomplete listing.
+ */
+ nla_nest_end(skb, publs);
+ }
+
+ nla_nest_end(skb, attrs);
+ genlmsg_end(skb, hdr);
+
+ return res;
+
+attr_msg_cancel:
+ nla_nest_cancel(skb, attrs);
+genlmsg_cancel:
+ genlmsg_cancel(skb, hdr);
+msg_cancel:
+ return -EMSGSIZE;
+}
+
+int tipc_nl_sk_dump(struct sk_buff *skb, struct netlink_callback *cb)
+{
+ int err;
+ struct tipc_sock *tsk;
+ u32 prev_tsk = cb->args[0];
+ u32 prev_publ = cb->args[1];
+ u32 tsk_ref = prev_tsk;
+
+ tsk = tipc_sk_get_next(&tsk_ref);
+ for (; tsk; tsk = tipc_sk_get_next(&tsk_ref)) {
+ lock_sock(&tsk->sk);
+ err = __tipc_nl_add_sk(skb, cb, tsk, &prev_publ);
+ release_sock(&tsk->sk);
+ tipc_sk_put(tsk);
+ if (err)
+ break;
+
+ prev_tsk = tsk_ref;
+ }
+
+ cb->args[0] = prev_tsk;
+ cb->args[1] = prev_publ;
+
+ return skb->len;
+}
diff --git a/net/tipc/socket.h b/net/tipc/socket.h
index baa43d0..16dfd62 100644
--- a/net/tipc/socket.h
+++ b/net/tipc/socket.h
@@ -36,6 +36,7 @@
#define _TIPC_SOCK_H
#include <net/sock.h>
+#include <net/genetlink.h>
#define TIPC_CONNACK_INTV 256
#define TIPC_FLOWCTRL_WIN (TIPC_CONNACK_INTV * 2)
@@ -47,5 +48,6 @@ void tipc_sk_mcast_rcv(struct sk_buff *buf);
void tipc_sk_reinit(void);
int tipc_sk_ref_table_init(u32 requested_size, u32 start);
void tipc_sk_ref_table_stop(void);
+int tipc_nl_sk_dump(struct sk_buff *skb, struct netlink_callback *cb);
#endif
--
1.7.10.4
------------------------------------------------------------------------------
Want excitement?
Manually upgrade your production database.
When you want reliability, choose Perforce
Perforce version control. Predictably reliable.
http://pubads.g.doubleclick.net/gampad/clk?id=157508191&iu=/4140/ostg.clktrk
^ permalink raw reply related
* [PATCH net-next 05/14] tipc: add link get/dump to new netlink api
From: richard.alpe @ 2014-09-11 8:29 UTC (permalink / raw)
To: netdev; +Cc: tipc-discussion
In-Reply-To: <1410424167-17427-1-git-send-email-richard.alpe@ericsson.com>
From: Richard Alpe <richard.alpe@ericsson.com>
Add TIPC_NL_LINK_GET command to the new tipc netlink API.
This command supports dumping all information about all links
(including the broadcast link) or getting all information about a
specific link (not the broadcast link).
The information about a link includes name, transmission info,
properties and link statistics.
As the tipc broadcast link is special we unfortunately have to treat
it specially. It is a deliberate decision not to abstract the
broadcast link on this (API) level.
Netlink logical layout of link response message:
-> port
-> name
-> MTU
-> RX
-> TX
-> up flag
-> active flag
-> properties
-> priority
-> tolerance
-> window
-> statistics
-> rx_info
-> rx_fragments
-> rx_fragmented
-> rx_bundles
-> rx_bundled
-> tx_info
-> tx_fragments
-> tx_fragmented
-> tx_bundles
-> tx_bundled
-> msg_prof_tot
-> msg_len_cnt
-> msg_len_tot
-> msg_len_p0
-> msg_len_p1
-> msg_len_p2
-> msg_len_p3
-> msg_len_p4
-> msg_len_p5
-> msg_len_p6
-> rx_states
-> rx_probes
-> rx_nacks
-> rx_deferred
-> tx_states
-> tx_probes
-> tx_nacks
-> tx_acks
-> retransmitted
-> duplicates
-> link_congs
-> max_queue
-> avg_queue
Signed-off-by: Richard Alpe <richard.alpe@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
Acked-by: Ying Xue <ying.xue@windriver.com>
---
include/uapi/linux/tipc_config.h | 62 +++++++++
net/tipc/bcast.c | 111 +++++++++++++++
net/tipc/bcast.h | 3 +
net/tipc/link.c | 284 ++++++++++++++++++++++++++++++++++++++
net/tipc/link.h | 2 +
net/tipc/netlink.c | 8 ++
6 files changed, 470 insertions(+)
diff --git a/include/uapi/linux/tipc_config.h b/include/uapi/linux/tipc_config.h
index e09dec2..9c51151 100644
--- a/include/uapi/linux/tipc_config.h
+++ b/include/uapi/linux/tipc_config.h
@@ -55,6 +55,7 @@ enum {
TIPC_NL_BEARER_GET,
TIPC_NL_BEARER_SET,
TIPC_NL_SOCK_GET,
+ TIPC_NL_LINK_GET,
__TIPC_NL_CMD_MAX,
TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1
@@ -65,6 +66,7 @@ enum {
TIPC_NLA_UNSPEC,
TIPC_NLA_BEARER, /* nest */
TIPC_NLA_SOCK, /* nest */
+ TIPC_NLA_LINK, /* nest */
__TIPC_NLA_MAX,
TIPC_NLA_MAX = __TIPC_NLA_MAX - 1
@@ -93,6 +95,23 @@ enum {
TIPC_NLA_SOCK_MAX = __TIPC_NLA_SOCK_MAX - 1
};
+/* Link info */
+enum {
+ TIPC_NLA_LINK_UNSPEC,
+ TIPC_NLA_LINK_NAME, /* string */
+ TIPC_NLA_LINK_MTU, /* u32 */
+ TIPC_NLA_LINK_BROADCAST, /* flag */
+ TIPC_NLA_LINK_UP, /* flag */
+ TIPC_NLA_LINK_ACTIVE, /* flag */
+ TIPC_NLA_LINK_PROP, /* nest */
+ TIPC_NLA_LINK_STATS, /* nest */
+ TIPC_NLA_LINK_RX, /* u32 */
+ TIPC_NLA_LINK_TX, /* u32 */
+
+ __TIPC_NLA_LINK_MAX,
+ TIPC_NLA_LINK_MAX = __TIPC_NLA_LINK_MAX - 1
+};
+
/* Nest, publication info */
enum {
TIPC_NLA_PUBL_UNSPEC,
@@ -134,6 +153,49 @@ enum {
__TIPC_NLA_PROP_MAX,
TIPC_NLA_PROP_MAX = __TIPC_NLA_PROP_MAX - 1
};
+
+/* Nest, statistics info */
+enum {
+ TIPC_NLA_STATS_UNSPEC,
+
+ TIPC_NLA_STATS_RX_INFO, /* u32 */
+ TIPC_NLA_STATS_RX_FRAGMENTS, /* u32 */
+ TIPC_NLA_STATS_RX_FRAGMENTED, /* u32 */
+ TIPC_NLA_STATS_RX_BUNDLES, /* u32 */
+ TIPC_NLA_STATS_RX_BUNDLED, /* u32 */
+ TIPC_NLA_STATS_TX_INFO, /* u32 */
+ TIPC_NLA_STATS_TX_FRAGMENTS, /* u32 */
+ TIPC_NLA_STATS_TX_FRAGMENTED, /* u32 */
+ TIPC_NLA_STATS_TX_BUNDLES, /* u32 */
+ TIPC_NLA_STATS_TX_BUNDLED, /* u32 */
+ TIPC_NLA_STATS_MSG_PROF_TOT, /* u32 */
+ TIPC_NLA_STATS_MSG_LEN_CNT, /* u32 */
+ TIPC_NLA_STATS_MSG_LEN_TOT, /* u32 */
+ TIPC_NLA_STATS_MSG_LEN_P0, /* u32 */
+ TIPC_NLA_STATS_MSG_LEN_P1, /* u32 */
+ TIPC_NLA_STATS_MSG_LEN_P2, /* u32 */
+ TIPC_NLA_STATS_MSG_LEN_P3, /* u32 */
+ TIPC_NLA_STATS_MSG_LEN_P4, /* u32 */
+ TIPC_NLA_STATS_MSG_LEN_P5, /* u32 */
+ TIPC_NLA_STATS_MSG_LEN_P6, /* u32 */
+ TIPC_NLA_STATS_RX_STATES, /* u32 */
+ TIPC_NLA_STATS_RX_PROBES, /* u32 */
+ TIPC_NLA_STATS_RX_NACKS, /* u32 */
+ TIPC_NLA_STATS_RX_DEFERRED, /* u32 */
+ TIPC_NLA_STATS_TX_STATES, /* u32 */
+ TIPC_NLA_STATS_TX_PROBES, /* u32 */
+ TIPC_NLA_STATS_TX_NACKS, /* u32 */
+ TIPC_NLA_STATS_TX_ACKS, /* u32 */
+ TIPC_NLA_STATS_RETRANSMITTED, /* u32 */
+ TIPC_NLA_STATS_DUPLICATES, /* u32 */
+ TIPC_NLA_STATS_LINK_CONGS, /* u32 */
+ TIPC_NLA_STATS_MAX_QUEUE, /* u32 */
+ TIPC_NLA_STATS_AVG_QUEUE, /* u32 */
+
+ __TIPC_NLA_STATS_MAX,
+ TIPC_NLA_STATS_MAX = __TIPC_NLA_STATS_MAX - 1
+};
+
/*
* Configuration
*
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index b2bbe69..e12476b 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -755,6 +755,117 @@ void tipc_bcbearer_sort(struct tipc_node_map *nm_ptr, u32 node, bool action)
tipc_bclink_unlock();
}
+int __tipc_nl_add_bc_link_stat(struct sk_buff *skb, struct tipc_stats *stats)
+{
+ int i;
+ struct nlattr *nest;
+
+ struct nla_map {
+ __u32 key;
+ __u32 val;
+ };
+
+ struct nla_map map[] = {
+ {TIPC_NLA_STATS_RX_INFO, stats->recv_info},
+ {TIPC_NLA_STATS_RX_FRAGMENTS, stats->recv_fragments},
+ {TIPC_NLA_STATS_RX_FRAGMENTED, stats->recv_fragmented},
+ {TIPC_NLA_STATS_RX_BUNDLES, stats->recv_bundles},
+ {TIPC_NLA_STATS_RX_BUNDLED, stats->recv_bundled},
+ {TIPC_NLA_STATS_TX_INFO, stats->sent_info},
+ {TIPC_NLA_STATS_TX_FRAGMENTS, stats->sent_fragments},
+ {TIPC_NLA_STATS_TX_FRAGMENTED, stats->sent_fragmented},
+ {TIPC_NLA_STATS_TX_BUNDLES, stats->sent_bundles},
+ {TIPC_NLA_STATS_TX_BUNDLED, stats->sent_bundled},
+ {TIPC_NLA_STATS_RX_NACKS, stats->recv_nacks},
+ {TIPC_NLA_STATS_RX_DEFERRED, stats->deferred_recv},
+ {TIPC_NLA_STATS_TX_NACKS, stats->sent_nacks},
+ {TIPC_NLA_STATS_TX_ACKS, stats->sent_acks},
+ {TIPC_NLA_STATS_RETRANSMITTED, stats->retransmitted},
+ {TIPC_NLA_STATS_DUPLICATES, stats->duplicates},
+ {TIPC_NLA_STATS_LINK_CONGS, stats->link_congs},
+ {TIPC_NLA_STATS_MAX_QUEUE, stats->max_queue_sz},
+ {TIPC_NLA_STATS_AVG_QUEUE, stats->queue_sz_counts ?
+ (stats->accu_queue_sz / stats->queue_sz_counts) : 0}
+ };
+
+ nest = nla_nest_start(skb, TIPC_NLA_LINK_STATS);
+ if (!nest)
+ return -EMSGSIZE;
+
+ for (i = 0; i < ARRAY_SIZE(map); i++)
+ if (nla_put_u32(skb, map[i].key, map[i].val))
+ goto msg_full;
+
+ nla_nest_end(skb, nest);
+
+ return 0;
+msg_full:
+ nla_nest_cancel(skb, nest);
+
+ return -EMSGSIZE;
+}
+
+int tipc_nl_add_bc_link(struct tipc_nl_msg *msg)
+{
+ int err;
+ void *hdr;
+ struct nlattr *attrs;
+ struct nlattr *prop;
+
+ if (!bcl)
+ return 0;
+
+ tipc_bclink_lock();
+
+ hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
+ NLM_F_MULTI, TIPC_NL_LINK_GET);
+ if (!hdr)
+ return -EMSGSIZE;
+
+ attrs = nla_nest_start(msg->skb, TIPC_NLA_LINK);
+ if (!attrs)
+ goto msg_full;
+
+ /* The broadcast link is always up */
+ if (nla_put_flag(msg->skb, TIPC_NLA_LINK_UP))
+ goto attr_msg_full;
+
+ if (nla_put_flag(msg->skb, TIPC_NLA_LINK_BROADCAST))
+ goto attr_msg_full;
+ if (nla_put_string(msg->skb, TIPC_NLA_LINK_NAME, bcl->name))
+ goto attr_msg_full;
+ if (nla_put_u32(msg->skb, TIPC_NLA_LINK_RX, bcl->next_in_no))
+ goto attr_msg_full;
+ if (nla_put_u32(msg->skb, TIPC_NLA_LINK_TX, bcl->next_out_no))
+ goto attr_msg_full;
+
+ prop = nla_nest_start(msg->skb, TIPC_NLA_LINK_PROP);
+ if (!prop)
+ goto attr_msg_full;
+ if (nla_put_u32(msg->skb, TIPC_NLA_PROP_WIN, bcl->queue_limit[0]))
+ goto prop_msg_full;
+ nla_nest_end(msg->skb, prop);
+
+ err = __tipc_nl_add_bc_link_stat(msg->skb, &bcl->stats);
+ if (err)
+ goto attr_msg_full;
+
+ tipc_bclink_unlock();
+ nla_nest_end(msg->skb, attrs);
+ genlmsg_end(msg->skb, hdr);
+
+ return 0;
+
+prop_msg_full:
+ nla_nest_cancel(msg->skb, prop);
+attr_msg_full:
+ nla_nest_cancel(msg->skb, attrs);
+msg_full:
+ tipc_bclink_unlock();
+ genlmsg_cancel(msg->skb, hdr);
+
+ return -EMSGSIZE;
+}
int tipc_bclink_stats(char *buf, const u32 buf_size)
{
diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h
index 4875d95..3c0263e 100644
--- a/net/tipc/bcast.h
+++ b/net/tipc/bcast.h
@@ -37,6 +37,8 @@
#ifndef _TIPC_BCAST_H
#define _TIPC_BCAST_H
+#include "netlink.h"
+
#define MAX_NODES 4096
#define WSIZE 32
#define TIPC_BCLINK_RESET 1
@@ -99,5 +101,6 @@ int tipc_bclink_set_queue_limits(u32 limit);
void tipc_bcbearer_sort(struct tipc_node_map *nm_ptr, u32 node, bool action);
uint tipc_bclink_get_mtu(void);
int tipc_bclink_xmit(struct sk_buff *buf);
+int tipc_nl_add_bc_link(struct tipc_nl_msg *msg);
#endif
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 4628538..e0aaca4 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -36,6 +36,7 @@
#include "core.h"
#include "link.h"
+#include "bcast.h"
#include "socket.h"
#include "name_distr.h"
#include "discover.h"
@@ -51,6 +52,22 @@ static const char *link_co_err = "Link changeover error, ";
static const char *link_rst_msg = "Resetting link ";
static const char *link_unk_evt = "Unknown link event ";
+static const struct nla_policy tipc_nl_link_policy[TIPC_NLA_LINK_MAX + 1] = {
+ [TIPC_NLA_LINK_UNSPEC] = { .type = NLA_UNSPEC },
+ [TIPC_NLA_LINK_NAME] = {
+ .type = NLA_STRING,
+ .len = TIPC_MAX_LINK_NAME
+ },
+ [TIPC_NLA_LINK_MTU] = { .type = NLA_U32 },
+ [TIPC_NLA_LINK_BROADCAST] = { .type = NLA_FLAG },
+ [TIPC_NLA_LINK_UP] = { .type = NLA_FLAG },
+ [TIPC_NLA_LINK_ACTIVE] = { .type = NLA_FLAG },
+ [TIPC_NLA_LINK_PROP] = { .type = NLA_NESTED },
+ [TIPC_NLA_LINK_STATS] = { .type = NLA_NESTED },
+ [TIPC_NLA_LINK_RX] = { .type = NLA_U32 },
+ [TIPC_NLA_LINK_TX] = { .type = NLA_U32 }
+};
+
/* Properties valid for media, bearar and link */
static const struct nla_policy tipc_nl_prop_policy[TIPC_NLA_PROP_MAX + 1] = {
[TIPC_NLA_PROP_UNSPEC] = { .type = NLA_UNSPEC },
@@ -2417,3 +2434,270 @@ int tipc_nl_parse_link_prop(struct nlattr *prop, struct nlattr *props[])
return 0;
}
+
+int __tipc_nl_add_stats(struct sk_buff *skb, struct tipc_stats *s)
+{
+ int i;
+ struct nlattr *stats;
+
+ struct nla_map {
+ u32 key;
+ u32 val;
+ };
+
+ struct nla_map map[] = {
+ {TIPC_NLA_STATS_RX_INFO, s->recv_info},
+ {TIPC_NLA_STATS_RX_FRAGMENTS, s->recv_fragments},
+ {TIPC_NLA_STATS_RX_FRAGMENTED, s->recv_fragmented},
+ {TIPC_NLA_STATS_RX_BUNDLES, s->recv_bundles},
+ {TIPC_NLA_STATS_RX_BUNDLED, s->recv_bundled},
+ {TIPC_NLA_STATS_TX_INFO, s->sent_info},
+ {TIPC_NLA_STATS_TX_FRAGMENTS, s->sent_fragments},
+ {TIPC_NLA_STATS_TX_FRAGMENTED, s->sent_fragmented},
+ {TIPC_NLA_STATS_TX_BUNDLES, s->sent_bundles},
+ {TIPC_NLA_STATS_TX_BUNDLED, s->sent_bundled},
+ {TIPC_NLA_STATS_MSG_PROF_TOT, (s->msg_length_counts) ?
+ s->msg_length_counts : 1},
+ {TIPC_NLA_STATS_MSG_LEN_CNT, s->msg_length_counts},
+ {TIPC_NLA_STATS_MSG_LEN_TOT, s->msg_lengths_total},
+ {TIPC_NLA_STATS_MSG_LEN_P0, s->msg_length_profile[0]},
+ {TIPC_NLA_STATS_MSG_LEN_P1, s->msg_length_profile[1]},
+ {TIPC_NLA_STATS_MSG_LEN_P2, s->msg_length_profile[2]},
+ {TIPC_NLA_STATS_MSG_LEN_P3, s->msg_length_profile[3]},
+ {TIPC_NLA_STATS_MSG_LEN_P4, s->msg_length_profile[4]},
+ {TIPC_NLA_STATS_MSG_LEN_P5, s->msg_length_profile[5]},
+ {TIPC_NLA_STATS_MSG_LEN_P6, s->msg_length_profile[6]},
+ {TIPC_NLA_STATS_RX_STATES, s->recv_states},
+ {TIPC_NLA_STATS_RX_PROBES, s->recv_probes},
+ {TIPC_NLA_STATS_RX_NACKS, s->recv_nacks},
+ {TIPC_NLA_STATS_RX_DEFERRED, s->deferred_recv},
+ {TIPC_NLA_STATS_TX_STATES, s->sent_states},
+ {TIPC_NLA_STATS_TX_PROBES, s->sent_probes},
+ {TIPC_NLA_STATS_TX_NACKS, s->sent_nacks},
+ {TIPC_NLA_STATS_TX_ACKS, s->sent_acks},
+ {TIPC_NLA_STATS_RETRANSMITTED, s->retransmitted},
+ {TIPC_NLA_STATS_DUPLICATES, s->duplicates},
+ {TIPC_NLA_STATS_LINK_CONGS, s->link_congs},
+ {TIPC_NLA_STATS_MAX_QUEUE, s->max_queue_sz},
+ {TIPC_NLA_STATS_AVG_QUEUE, s->queue_sz_counts ?
+ (s->accu_queue_sz / s->queue_sz_counts) : 0}
+ };
+
+ stats = nla_nest_start(skb, TIPC_NLA_LINK_STATS);
+ if (!stats)
+ return -EMSGSIZE;
+
+ for (i = 0; i < ARRAY_SIZE(map); i++)
+ if (nla_put_u32(skb, map[i].key, map[i].val))
+ goto msg_full;
+
+ nla_nest_end(skb, stats);
+
+ return 0;
+msg_full:
+ nla_nest_cancel(skb, stats);
+
+ return -EMSGSIZE;
+}
+
+/* Caller should hold appropriate locks to protect the link */
+int __tipc_nl_add_link(struct tipc_nl_msg *msg, struct tipc_link *link)
+{
+ int err;
+ void *hdr;
+ struct nlattr *attrs;
+ struct nlattr *prop;
+
+ hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
+ NLM_F_MULTI, TIPC_NL_LINK_GET);
+ if (!hdr)
+ return -EMSGSIZE;
+
+ attrs = nla_nest_start(msg->skb, TIPC_NLA_LINK);
+ if (!attrs)
+ goto msg_full;
+
+ if (nla_put_string(msg->skb, TIPC_NLA_LINK_NAME, link->name))
+ goto attr_msg_full;
+ if (nla_put_u32(msg->skb, TIPC_NLA_LINK_MTU, link->max_pkt))
+ goto attr_msg_full;
+ if (nla_put_u32(msg->skb, TIPC_NLA_LINK_RX, link->next_in_no))
+ goto attr_msg_full;
+ if (nla_put_u32(msg->skb, TIPC_NLA_LINK_TX, link->next_out_no))
+ goto attr_msg_full;
+
+ if (tipc_link_is_up(link))
+ if (nla_put_flag(msg->skb, TIPC_NLA_LINK_UP))
+ goto attr_msg_full;
+ if (tipc_link_is_active(link))
+ if (nla_put_flag(msg->skb, TIPC_NLA_LINK_ACTIVE))
+ goto attr_msg_full;
+
+ prop = nla_nest_start(msg->skb, TIPC_NLA_LINK_PROP);
+ if (!prop)
+ goto attr_msg_full;
+ if (nla_put_u32(msg->skb, TIPC_NLA_PROP_PRIO, link->priority))
+ goto prop_msg_full;
+ if (nla_put_u32(msg->skb, TIPC_NLA_PROP_TOL, link->tolerance))
+ goto prop_msg_full;
+ if (nla_put_u32(msg->skb, TIPC_NLA_PROP_WIN,
+ link->queue_limit[TIPC_LOW_IMPORTANCE]))
+ goto prop_msg_full;
+ if (nla_put_u32(msg->skb, TIPC_NLA_PROP_PRIO, link->priority))
+ goto prop_msg_full;
+ nla_nest_end(msg->skb, prop);
+
+ err = __tipc_nl_add_stats(msg->skb, &link->stats);
+ if (err)
+ goto attr_msg_full;
+
+ nla_nest_end(msg->skb, attrs);
+ genlmsg_end(msg->skb, hdr);
+
+ return 0;
+
+prop_msg_full:
+ nla_nest_cancel(msg->skb, prop);
+attr_msg_full:
+ nla_nest_cancel(msg->skb, attrs);
+msg_full:
+ genlmsg_cancel(msg->skb, hdr);
+
+ return -EMSGSIZE;
+}
+
+/* Caller should hold node lock */
+int __tipc_nl_add_node_links(struct tipc_nl_msg *msg, struct tipc_node *node,
+ u32 *prev_link)
+{
+ u32 i;
+ int err;
+
+ for (i = *prev_link; i < MAX_BEARERS; i++) {
+ *prev_link = i;
+
+ if (!node->links[i])
+ continue;
+
+ err = __tipc_nl_add_link(msg, node->links[i]);
+ if (err)
+ return err;
+ }
+ *prev_link = 0;
+
+ return 0;
+}
+
+int tipc_nl_link_dump(struct sk_buff *skb, struct netlink_callback *cb)
+{
+ struct tipc_node *node;
+ struct tipc_nl_msg msg;
+ u32 prev_node = cb->args[0];
+ u32 prev_link = cb->args[1];
+ int done = cb->args[2];
+ int err;
+
+ if (done)
+ return 0;
+
+ msg.skb = skb;
+ msg.portid = NETLINK_CB(cb->skb).portid;
+ msg.seq = cb->nlh->nlmsg_seq;
+
+ rcu_read_lock();
+
+ if (prev_node) {
+ node = tipc_node_find(prev_node);
+ if (!node) {
+ /* We never set seq or call nl_dump_check_consistent()
+ * this means that setting prev_seq here will cause the
+ * consistence check to fail in the netlink callback
+ * handler. Resulting in the last NLMSG_DONE message
+ * having the NLM_F_DUMP_INTR flag set.
+ */
+ cb->prev_seq = 1;
+ goto out;
+ }
+
+ list_for_each_entry_continue_rcu(node, &tipc_node_list, list) {
+ tipc_node_lock(node);
+ err = __tipc_nl_add_node_links(&msg, node, &prev_link);
+ tipc_node_unlock(node);
+ if (err)
+ goto out;
+
+ prev_node = node->addr;
+ }
+ } else {
+ err = tipc_nl_add_bc_link(&msg);
+ if (err)
+ goto out;
+
+ list_for_each_entry_rcu(node, &tipc_node_list, list) {
+ tipc_node_lock(node);
+ err = __tipc_nl_add_node_links(&msg, node, &prev_link);
+ tipc_node_unlock(node);
+ if (err)
+ goto out;
+
+ prev_node = node->addr;
+ }
+ }
+ done = 1;
+out:
+ rcu_read_unlock();
+
+ cb->args[0] = prev_node;
+ cb->args[1] = prev_link;
+ cb->args[2] = done;
+
+ return skb->len;
+}
+
+int tipc_nl_link_get(struct sk_buff *skb, struct genl_info *info)
+{
+ struct sk_buff *ans_skb;
+ struct tipc_nl_msg msg;
+ struct tipc_link *link;
+ struct tipc_node *node;
+ char *name;
+ int bearer_id;
+ int err;
+
+ if (!info->attrs[TIPC_NLA_LINK_NAME])
+ return -EINVAL;
+
+ name = nla_data(info->attrs[TIPC_NLA_LINK_NAME]);
+ node = tipc_link_find_owner(name, &bearer_id);
+ if (!node)
+ return -EINVAL;
+
+ ans_skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+ if (!ans_skb)
+ return -ENOMEM;
+
+ msg.skb = ans_skb;
+ msg.portid = info->snd_portid;
+ msg.seq = info->snd_seq;
+
+ tipc_node_lock(node);
+ link = node->links[bearer_id];
+ if (!link) {
+ err = -EINVAL;
+ goto err_out;
+ }
+
+ err = __tipc_nl_add_link(&msg, link);
+ if (err)
+ goto err_out;
+
+ tipc_node_unlock(node);
+
+ return genlmsg_reply(ans_skb, info);
+
+err_out:
+ tipc_node_unlock(node);
+ nlmsg_free(ans_skb);
+
+ return err;
+}
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 4338294..8e3542a 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -240,6 +240,8 @@ void tipc_link_set_queue_limits(struct tipc_link *l_ptr, u32 window);
void tipc_link_retransmit(struct tipc_link *l_ptr,
struct sk_buff *start, u32 retransmits);
+int tipc_nl_link_dump(struct sk_buff *skb, struct netlink_callback *cb);
+int tipc_nl_link_get(struct sk_buff *skb, struct genl_info *info);
int tipc_nl_parse_link_prop(struct nlattr *prop, struct nlattr *props[]);
/*
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index 52973ce..5ecd0d1 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -38,6 +38,7 @@
#include "config.h"
#include "socket.h"
#include "bearer.h"
+#include "link.h"
#include <net/genetlink.h>
static int handle_cmd(struct sk_buff *skb, struct genl_info *info)
@@ -74,6 +75,7 @@ static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 1] = {
[TIPC_NLA_UNSPEC] = { .type = NLA_UNSPEC, },
[TIPC_NLA_BEARER] = { .type = NLA_NESTED, },
[TIPC_NLA_SOCK] = { .type = NLA_NESTED, },
+ [TIPC_NLA_LINK] = { .type = NLA_NESTED, },
};
struct genl_family tipc_genl_family = {
@@ -115,6 +117,12 @@ static const struct genl_ops tipc_genl_ops[] = {
.cmd = TIPC_NL_SOCK_GET,
.dumpit = tipc_nl_sk_dump,
.policy = tipc_nl_policy,
+ },
+ {
+ .cmd = TIPC_NL_LINK_GET,
+ .doit = tipc_nl_link_get,
+ .dumpit = tipc_nl_link_dump,
+ .policy = tipc_nl_policy,
}
};
--
1.7.10.4
------------------------------------------------------------------------------
Want excitement?
Manually upgrade your production database.
When you want reliability, choose Perforce
Perforce version control. Predictably reliable.
http://pubads.g.doubleclick.net/gampad/clk?id=157508191&iu=/4140/ostg.clktrk
^ permalink raw reply related
* [PATCH net-next 06/14] tipc: add link set to new netlink api
From: richard.alpe @ 2014-09-11 8:29 UTC (permalink / raw)
To: netdev; +Cc: tipc-discussion
In-Reply-To: <1410424167-17427-1-git-send-email-richard.alpe@ericsson.com>
From: Richard Alpe <richard.alpe@ericsson.com>
Add TIPC_NL_LINK_SET to the new tipc netlink API.
This command can set one or more link properties for a particular
link.
Netlink logical layout of link set message:
-> link
-> name
-> properties
[ -> tolerance ]
[ -> priority ]
[ -> window ]
Signed-off-by: Richard Alpe <richard.alpe@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
Acked-by: Ying Xue <ying.xue@windriver.com>
---
include/uapi/linux/tipc_config.h | 1 +
net/tipc/link.c | 73 ++++++++++++++++++++++++++++++++++++++
net/tipc/link.h | 1 +
net/tipc/netlink.c | 5 +++
4 files changed, 80 insertions(+)
diff --git a/include/uapi/linux/tipc_config.h b/include/uapi/linux/tipc_config.h
index 9c51151..3b0c0f0 100644
--- a/include/uapi/linux/tipc_config.h
+++ b/include/uapi/linux/tipc_config.h
@@ -56,6 +56,7 @@ enum {
TIPC_NL_BEARER_SET,
TIPC_NL_SOCK_GET,
TIPC_NL_LINK_GET,
+ TIPC_NL_LINK_SET,
__TIPC_NL_CMD_MAX,
TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1
diff --git a/net/tipc/link.c b/net/tipc/link.c
index e0aaca4..6d0c1fa 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -2435,6 +2435,79 @@ int tipc_nl_parse_link_prop(struct nlattr *prop, struct nlattr *props[])
return 0;
}
+int tipc_nl_link_set(struct sk_buff *skb, struct genl_info *info)
+{
+ int err;
+ int res = 0;
+ int bearer_id;
+ char *name;
+ struct tipc_link *link;
+ struct tipc_node *node;
+ struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1];
+
+ if (!info->attrs[TIPC_NLA_LINK])
+ return -EINVAL;
+
+ err = nla_parse_nested(attrs, TIPC_NLA_LINK_MAX,
+ info->attrs[TIPC_NLA_LINK],
+ tipc_nl_link_policy);
+ if (err)
+ return err;
+
+ if (!attrs[TIPC_NLA_LINK_NAME])
+ return -EINVAL;
+
+ name = nla_data(attrs[TIPC_NLA_LINK_NAME]);
+
+ node = tipc_link_find_owner(name, &bearer_id);
+ if (!node)
+ return -EINVAL;
+
+ tipc_node_lock(node);
+
+ link = node->links[bearer_id];
+ if (!link) {
+ res = -EINVAL;
+ goto out;
+ }
+
+ if (attrs[TIPC_NLA_LINK_PROP]) {
+ struct nlattr *props[TIPC_NLA_PROP_MAX + 1];
+
+ err = tipc_nl_parse_link_prop(attrs[TIPC_NLA_LINK_PROP],
+ props);
+ if (err) {
+ res = err;
+ goto out;
+ }
+
+ if (props[TIPC_NLA_PROP_TOL]) {
+ u32 tol;
+
+ tol = nla_get_u32(props[TIPC_NLA_PROP_TOL]);
+ link_set_supervision_props(link, tol);
+ tipc_link_proto_xmit(link, STATE_MSG, 0, 0, tol, 0, 0);
+ }
+ if (props[TIPC_NLA_PROP_PRIO]) {
+ u32 prio;
+
+ prio = nla_get_u32(props[TIPC_NLA_PROP_PRIO]);
+ link->priority = prio;
+ tipc_link_proto_xmit(link, STATE_MSG, 0, 0, 0, prio, 0);
+ }
+ if (props[TIPC_NLA_PROP_WIN]) {
+ u32 win;
+
+ win = nla_get_u32(props[TIPC_NLA_PROP_WIN]);
+ tipc_link_set_queue_limits(link, win);
+ }
+ }
+
+out:
+ tipc_node_unlock(node);
+
+ return res;
+}
int __tipc_nl_add_stats(struct sk_buff *skb, struct tipc_stats *s)
{
int i;
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 8e3542a..3738ba1 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -242,6 +242,7 @@ void tipc_link_retransmit(struct tipc_link *l_ptr,
int tipc_nl_link_dump(struct sk_buff *skb, struct netlink_callback *cb);
int tipc_nl_link_get(struct sk_buff *skb, struct genl_info *info);
+int tipc_nl_link_set(struct sk_buff *skb, struct genl_info *info);
int tipc_nl_parse_link_prop(struct nlattr *prop, struct nlattr *props[]);
/*
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index 5ecd0d1..745a323 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -123,6 +123,11 @@ static const struct genl_ops tipc_genl_ops[] = {
.doit = tipc_nl_link_get,
.dumpit = tipc_nl_link_dump,
.policy = tipc_nl_policy,
+ },
+ {
+ .cmd = TIPC_NL_LINK_SET,
+ .doit = tipc_nl_link_set,
+ .policy = tipc_nl_policy,
}
};
--
1.7.10.4
------------------------------------------------------------------------------
Want excitement?
Manually upgrade your production database.
When you want reliability, choose Perforce
Perforce version control. Predictably reliable.
http://pubads.g.doubleclick.net/gampad/clk?id=157508191&iu=/4140/ostg.clktrk
^ permalink raw reply related
* [PATCH net-next 07/14] tipc: add link stat reset to new netlink api
From: richard.alpe @ 2014-09-11 8:29 UTC (permalink / raw)
To: netdev; +Cc: tipc-discussion
In-Reply-To: <1410424167-17427-1-git-send-email-richard.alpe@ericsson.com>
From: Richard Alpe <richard.alpe@ericsson.com>
Add TIPC_NL_LINK_RESET_STATS command to the new netlink API.
This command resets the link statistics for a particular link.
Netlink logical layout of link reset message:
-> link
-> name
Signed-off-by: Richard Alpe <richard.alpe@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
Acked-by: Ying Xue <ying.xue@windriver.com>
---
include/uapi/linux/tipc_config.h | 1 +
net/tipc/link.c | 49 ++++++++++++++++++++++++++++++++++++++
net/tipc/link.h | 1 +
net/tipc/netlink.c | 5 ++++
4 files changed, 56 insertions(+)
diff --git a/include/uapi/linux/tipc_config.h b/include/uapi/linux/tipc_config.h
index 3b0c0f0..b5bedf1 100644
--- a/include/uapi/linux/tipc_config.h
+++ b/include/uapi/linux/tipc_config.h
@@ -57,6 +57,7 @@ enum {
TIPC_NL_SOCK_GET,
TIPC_NL_LINK_GET,
TIPC_NL_LINK_SET,
+ TIPC_NL_LINK_RESET_STATS,
__TIPC_NL_CMD_MAX,
TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 6d0c1fa..2195197 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -2774,3 +2774,52 @@ err_out:
return err;
}
+
+int tipc_nl_link_reset_stats(struct sk_buff *skb, struct genl_info *info)
+{
+ int err;
+ char *link_name;
+ unsigned int bearer_id;
+ struct tipc_link *link;
+ struct tipc_node *node;
+ struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1];
+
+ if (!info->attrs[TIPC_NLA_LINK])
+ return -EINVAL;
+
+ err = nla_parse_nested(attrs, TIPC_NLA_LINK_MAX,
+ info->attrs[TIPC_NLA_LINK],
+ tipc_nl_link_policy);
+ if (err)
+ return err;
+
+ if (!attrs[TIPC_NLA_LINK_NAME])
+ return -EINVAL;
+
+ link_name = nla_data(attrs[TIPC_NLA_LINK_NAME]);
+
+ if (strcmp(link_name, tipc_bclink_name) == 0) {
+ err = tipc_bclink_reset_stats();
+ if (err)
+ return err;
+ return 0;
+ }
+
+ node = tipc_link_find_owner(link_name, &bearer_id);
+ if (!node)
+ return -EINVAL;
+
+ tipc_node_lock(node);
+
+ link = node->links[bearer_id];
+ if (!link) {
+ tipc_node_unlock(node);
+ return -EINVAL;
+ }
+
+ link_reset_statistics(link);
+
+ tipc_node_unlock(node);
+
+ return 0;
+}
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 3738ba1..f463e7b 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -243,6 +243,7 @@ void tipc_link_retransmit(struct tipc_link *l_ptr,
int tipc_nl_link_dump(struct sk_buff *skb, struct netlink_callback *cb);
int tipc_nl_link_get(struct sk_buff *skb, struct genl_info *info);
int tipc_nl_link_set(struct sk_buff *skb, struct genl_info *info);
+int tipc_nl_link_reset_stats(struct sk_buff *skb, struct genl_info *info);
int tipc_nl_parse_link_prop(struct nlattr *prop, struct nlattr *props[]);
/*
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index 745a323..de51267 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -128,6 +128,11 @@ static const struct genl_ops tipc_genl_ops[] = {
.cmd = TIPC_NL_LINK_SET,
.doit = tipc_nl_link_set,
.policy = tipc_nl_policy,
+ },
+ {
+ .cmd = TIPC_NL_LINK_RESET_STATS,
+ .doit = tipc_nl_link_reset_stats,
+ .policy = tipc_nl_policy,
}
};
--
1.7.10.4
------------------------------------------------------------------------------
Want excitement?
Manually upgrade your production database.
When you want reliability, choose Perforce
Perforce version control. Predictably reliable.
http://pubads.g.doubleclick.net/gampad/clk?id=157508191&iu=/4140/ostg.clktrk
^ permalink raw reply related
* [PATCH net-next 08/14] tipc: add media get/dump to new netlink api
From: richard.alpe @ 2014-09-11 8:29 UTC (permalink / raw)
To: netdev; +Cc: tipc-discussion
In-Reply-To: <1410424167-17427-1-git-send-email-richard.alpe@ericsson.com>
From: Richard Alpe <richard.alpe@ericsson.com>
Add TIPC_NL_MEDIA_GET command to the new tipc netlink API.
This command supports dumping all information about all defined
media as well as getting all information about a specific media.
The information about a media includes name and link properties.
Netlink logical layout of media get response message:
-> media
-> name
-> link properties
-> tolerance
-> priority
-> window
Signed-off-by: Richard Alpe <richard.alpe@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
Acked-by: Ying Xue <ying.xue@windriver.com>
---
include/uapi/linux/tipc_config.h | 12 ++++
net/tipc/bearer.c | 125 ++++++++++++++++++++++++++++++++++++++
net/tipc/bearer.h | 3 +
net/tipc/netlink.c | 7 +++
4 files changed, 147 insertions(+)
diff --git a/include/uapi/linux/tipc_config.h b/include/uapi/linux/tipc_config.h
index b5bedf1..33b5171 100644
--- a/include/uapi/linux/tipc_config.h
+++ b/include/uapi/linux/tipc_config.h
@@ -58,6 +58,7 @@ enum {
TIPC_NL_LINK_GET,
TIPC_NL_LINK_SET,
TIPC_NL_LINK_RESET_STATS,
+ TIPC_NL_MEDIA_GET,
__TIPC_NL_CMD_MAX,
TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1
@@ -69,6 +70,7 @@ enum {
TIPC_NLA_BEARER, /* nest */
TIPC_NLA_SOCK, /* nest */
TIPC_NLA_LINK, /* nest */
+ TIPC_NLA_MEDIA, /* nest */
__TIPC_NLA_MAX,
TIPC_NLA_MAX = __TIPC_NLA_MAX - 1
@@ -114,6 +116,16 @@ enum {
TIPC_NLA_LINK_MAX = __TIPC_NLA_LINK_MAX - 1
};
+/* Media info */
+enum {
+ TIPC_NLA_MEDIA_UNSPEC,
+ TIPC_NLA_MEDIA_NAME, /* string */
+ TIPC_NLA_MEDIA_PROP, /* nest */
+
+ __TIPC_NLA_MEDIA_MAX,
+ TIPC_NLA_MEDIA_MAX = __TIPC_NLA_MEDIA_MAX - 1
+};
+
/* Nest, publication info */
enum {
TIPC_NLA_PUBL_UNSPEC,
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 906e644..ad33e44 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -61,6 +61,12 @@ tipc_nl_bearer_policy[TIPC_NLA_BEARER_MAX + 1] = {
[TIPC_NLA_BEARER_DOMAIN] = { .type = NLA_U32 }
};
+static const struct nla_policy tipc_nl_media_policy[TIPC_NLA_MEDIA_MAX + 1] = {
+ [TIPC_NLA_MEDIA_UNSPEC] = { .type = NLA_UNSPEC },
+ [TIPC_NLA_MEDIA_NAME] = { .type = NLA_STRING },
+ [TIPC_NLA_MEDIA_PROP] = { .type = NLA_NESTED }
+};
+
struct tipc_bearer __rcu *bearer_list[MAX_BEARERS + 1];
static void bearer_disable(struct tipc_bearer *b_ptr, bool shutting_down);
@@ -898,3 +904,122 @@ int tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info)
return 0;
}
+
+int __tipc_nl_add_media(struct tipc_nl_msg *msg, struct tipc_media *media)
+{
+ void *hdr;
+ struct nlattr *attrs;
+ struct nlattr *prop;
+
+ hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
+ NLM_F_MULTI, TIPC_NL_MEDIA_GET);
+ if (!hdr)
+ return -EMSGSIZE;
+
+ attrs = nla_nest_start(msg->skb, TIPC_NLA_MEDIA);
+ if (!attrs)
+ goto msg_full;
+
+ if (nla_put_string(msg->skb, TIPC_NLA_MEDIA_NAME, media->name))
+ goto attr_msg_full;
+
+ prop = nla_nest_start(msg->skb, TIPC_NLA_MEDIA_PROP);
+ if (!prop)
+ goto prop_msg_full;
+ if (nla_put_u32(msg->skb, TIPC_NLA_PROP_PRIO, media->priority))
+ goto prop_msg_full;
+ if (nla_put_u32(msg->skb, TIPC_NLA_PROP_TOL, media->tolerance))
+ goto prop_msg_full;
+ if (nla_put_u32(msg->skb, TIPC_NLA_PROP_WIN, media->window))
+ goto prop_msg_full;
+
+ nla_nest_end(msg->skb, prop);
+ nla_nest_end(msg->skb, attrs);
+ genlmsg_end(msg->skb, hdr);
+
+ return 0;
+
+prop_msg_full:
+ nla_nest_cancel(msg->skb, prop);
+attr_msg_full:
+ nla_nest_cancel(msg->skb, attrs);
+msg_full:
+ genlmsg_cancel(msg->skb, hdr);
+
+ return -EMSGSIZE;
+}
+
+int tipc_nl_media_dump(struct sk_buff *skb, struct netlink_callback *cb)
+{
+ int err;
+ int i = cb->args[0];
+ struct tipc_nl_msg msg;
+
+ if (i == MAX_MEDIA)
+ return 0;
+
+ msg.skb = skb;
+ msg.portid = NETLINK_CB(cb->skb).portid;
+ msg.seq = cb->nlh->nlmsg_seq;
+
+ rtnl_lock();
+ for (; media_info_array[i] != NULL; i++) {
+ err = __tipc_nl_add_media(&msg, media_info_array[i]);
+ if (err)
+ break;
+ }
+ rtnl_unlock();
+
+ cb->args[0] = i;
+ return skb->len;
+}
+
+int tipc_nl_media_get(struct sk_buff *skb, struct genl_info *info)
+{
+ int err;
+ char *name;
+ struct tipc_nl_msg msg;
+ struct tipc_media *media;
+ struct sk_buff *rep;
+ struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];
+
+ if (!info->attrs[TIPC_NLA_MEDIA])
+ return -EINVAL;
+
+ err = nla_parse_nested(attrs, TIPC_NLA_MEDIA_MAX,
+ info->attrs[TIPC_NLA_MEDIA],
+ tipc_nl_media_policy);
+ if (err)
+ return err;
+
+ if (!attrs[TIPC_NLA_MEDIA_NAME])
+ return -EINVAL;
+ name = nla_data(attrs[TIPC_NLA_MEDIA_NAME]);
+
+ rep = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+ if (!rep)
+ return -ENOMEM;
+
+ msg.skb = rep;
+ msg.portid = info->snd_portid;
+ msg.seq = info->snd_seq;
+
+ rtnl_lock();
+ media = tipc_media_find(name);
+ if (!media) {
+ err = -EINVAL;
+ goto err_out;
+ }
+
+ err = __tipc_nl_add_media(&msg, media);
+ if (err)
+ goto err_out;
+ rtnl_unlock();
+
+ return genlmsg_reply(rep, info);
+err_out:
+ rtnl_unlock();
+ nlmsg_free(rep);
+
+ return err;
+}
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
index c6cf9df..bacd225 100644
--- a/net/tipc/bearer.h
+++ b/net/tipc/bearer.h
@@ -184,6 +184,9 @@ int tipc_nl_bearer_dump(struct sk_buff *skb, struct netlink_callback *cb);
int tipc_nl_bearer_get(struct sk_buff *skb, struct genl_info *info);
int tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info);
+int tipc_nl_media_dump(struct sk_buff *skb, struct netlink_callback *cb);
+int tipc_nl_media_get(struct sk_buff *skb, struct genl_info *info);
+
int tipc_media_set_priority(const char *name, u32 new_value);
int tipc_media_set_window(const char *name, u32 new_value);
void tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a);
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index de51267..d012857 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -76,6 +76,7 @@ static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 1] = {
[TIPC_NLA_BEARER] = { .type = NLA_NESTED, },
[TIPC_NLA_SOCK] = { .type = NLA_NESTED, },
[TIPC_NLA_LINK] = { .type = NLA_NESTED, },
+ [TIPC_NLA_MEDIA] = { .type = NLA_NESTED, },
};
struct genl_family tipc_genl_family = {
@@ -133,6 +134,12 @@ static const struct genl_ops tipc_genl_ops[] = {
.cmd = TIPC_NL_LINK_RESET_STATS,
.doit = tipc_nl_link_reset_stats,
.policy = tipc_nl_policy,
+ },
+ {
+ .cmd = TIPC_NL_MEDIA_GET,
+ .doit = tipc_nl_media_get,
+ .dumpit = tipc_nl_media_dump,
+ .policy = tipc_nl_policy,
}
};
--
1.7.10.4
------------------------------------------------------------------------------
Want excitement?
Manually upgrade your production database.
When you want reliability, choose Perforce
Perforce version control. Predictably reliable.
http://pubads.g.doubleclick.net/gampad/clk?id=157508191&iu=/4140/ostg.clktrk
^ permalink raw reply related
* [PATCH net-next 09/14] tipc: add media set to new netlink api
From: richard.alpe @ 2014-09-11 8:29 UTC (permalink / raw)
To: netdev; +Cc: tipc-discussion
In-Reply-To: <1410424167-17427-1-git-send-email-richard.alpe@ericsson.com>
From: Richard Alpe <richard.alpe@ericsson.com>
Add TIPC_NL_MEDIA_SET command to the new tipc netlink API.
This command can set one or more link properties for a particular
media.
Netlink logical layout of bearer set message:
-> media
-> name
-> link properties
[ -> tolerance ]
[ -> priority ]
[ -> window ]
Signed-off-by: Richard Alpe <richard.alpe@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
Acked-by: Ying Xue <ying.xue@windriver.com>
---
include/uapi/linux/tipc_config.h | 1 +
net/tipc/bearer.c | 47 ++++++++++++++++++++++++++++++++++++++
net/tipc/bearer.h | 1 +
net/tipc/netlink.c | 5 ++++
4 files changed, 54 insertions(+)
diff --git a/include/uapi/linux/tipc_config.h b/include/uapi/linux/tipc_config.h
index 33b5171..1bd9c8d 100644
--- a/include/uapi/linux/tipc_config.h
+++ b/include/uapi/linux/tipc_config.h
@@ -59,6 +59,7 @@ enum {
TIPC_NL_LINK_SET,
TIPC_NL_LINK_RESET_STATS,
TIPC_NL_MEDIA_GET,
+ TIPC_NL_MEDIA_SET,
__TIPC_NL_CMD_MAX,
TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index ad33e44..3e33771 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -1023,3 +1023,50 @@ err_out:
return err;
}
+
+int tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info)
+{
+ int err;
+ char *name;
+ struct tipc_media *m;
+ struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];
+
+ if (!info->attrs[TIPC_NLA_MEDIA])
+ return -EINVAL;
+
+ err = nla_parse_nested(attrs, TIPC_NLA_MEDIA_MAX,
+ info->attrs[TIPC_NLA_MEDIA],
+ tipc_nl_media_policy);
+
+ if (!attrs[TIPC_NLA_MEDIA_NAME])
+ return -EINVAL;
+ name = nla_data(attrs[TIPC_NLA_MEDIA_NAME]);
+
+ rtnl_lock();
+ m = tipc_media_find(name);
+ if (!m) {
+ rtnl_unlock();
+ return -EINVAL;
+ }
+
+ if (attrs[TIPC_NLA_MEDIA_PROP]) {
+ struct nlattr *props[TIPC_NLA_PROP_MAX + 1];
+
+ err = tipc_nl_parse_link_prop(attrs[TIPC_NLA_MEDIA_PROP],
+ props);
+ if (err) {
+ rtnl_unlock();
+ return err;
+ }
+
+ if (props[TIPC_NLA_PROP_TOL])
+ m->tolerance = nla_get_u32(props[TIPC_NLA_PROP_TOL]);
+ if (props[TIPC_NLA_PROP_PRIO])
+ m->priority = nla_get_u32(props[TIPC_NLA_PROP_PRIO]);
+ if (props[TIPC_NLA_PROP_WIN])
+ m->window = nla_get_u32(props[TIPC_NLA_PROP_WIN]);
+ }
+ rtnl_unlock();
+
+ return 0;
+}
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
index bacd225..b1d9052 100644
--- a/net/tipc/bearer.h
+++ b/net/tipc/bearer.h
@@ -186,6 +186,7 @@ int tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info);
int tipc_nl_media_dump(struct sk_buff *skb, struct netlink_callback *cb);
int tipc_nl_media_get(struct sk_buff *skb, struct genl_info *info);
+int tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info);
int tipc_media_set_priority(const char *name, u32 new_value);
int tipc_media_set_window(const char *name, u32 new_value);
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index d012857..2f56b05 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -140,6 +140,11 @@ static const struct genl_ops tipc_genl_ops[] = {
.doit = tipc_nl_media_get,
.dumpit = tipc_nl_media_dump,
.policy = tipc_nl_policy,
+ },
+ {
+ .cmd = TIPC_NL_MEDIA_SET,
+ .doit = tipc_nl_media_set,
+ .policy = tipc_nl_policy,
}
};
--
1.7.10.4
------------------------------------------------------------------------------
Want excitement?
Manually upgrade your production database.
When you want reliability, choose Perforce
Perforce version control. Predictably reliable.
http://pubads.g.doubleclick.net/gampad/clk?id=157508191&iu=/4140/ostg.clktrk
^ permalink raw reply related
* [PATCH net-next 10/14] tipc: add node get/dump to new netlink api
From: richard.alpe @ 2014-09-11 8:29 UTC (permalink / raw)
To: netdev; +Cc: tipc-discussion
In-Reply-To: <1410424167-17427-1-git-send-email-richard.alpe@ericsson.com>
From: Richard Alpe <richard.alpe@ericsson.com>
Add TIPC_NL_NODE_GET to the new tipc netlink API.
This command can dump the address and node status of all nodes in the
tipc cluster.
Netlink logical layout of returned node/address data:
-> node
-> address
-> up flag
Signed-off-by: Richard Alpe <richard.alpe@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
Acked-by: Ying Xue <ying.xue@windriver.com>
---
include/uapi/linux/tipc_config.h | 12 +++++
net/tipc/netlink.c | 7 +++
net/tipc/node.c | 96 ++++++++++++++++++++++++++++++++++++++
net/tipc/node.h | 4 +-
4 files changed, 118 insertions(+), 1 deletion(-)
diff --git a/include/uapi/linux/tipc_config.h b/include/uapi/linux/tipc_config.h
index 1bd9c8d..e3dfad7 100644
--- a/include/uapi/linux/tipc_config.h
+++ b/include/uapi/linux/tipc_config.h
@@ -60,6 +60,7 @@ enum {
TIPC_NL_LINK_RESET_STATS,
TIPC_NL_MEDIA_GET,
TIPC_NL_MEDIA_SET,
+ TIPC_NL_NODE_GET,
__TIPC_NL_CMD_MAX,
TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1
@@ -72,6 +73,7 @@ enum {
TIPC_NLA_SOCK, /* nest */
TIPC_NLA_LINK, /* nest */
TIPC_NLA_MEDIA, /* nest */
+ TIPC_NLA_NODE, /* nest */
__TIPC_NLA_MAX,
TIPC_NLA_MAX = __TIPC_NLA_MAX - 1
@@ -127,6 +129,16 @@ enum {
TIPC_NLA_MEDIA_MAX = __TIPC_NLA_MEDIA_MAX - 1
};
+/* Node info */
+enum {
+ TIPC_NLA_NODE_UNSPEC,
+ TIPC_NLA_NODE_ADDR, /* u32 */
+ TIPC_NLA_NODE_UP, /* flag */
+
+ __TIPC_NLA_NODE_MAX,
+ TIPC_NLA_NODE_MAX = __TIPC_NLA_NODE_MAX - 1
+};
+
/* Nest, publication info */
enum {
TIPC_NLA_PUBL_UNSPEC,
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index 2f56b05..d42027e 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -39,6 +39,7 @@
#include "socket.h"
#include "bearer.h"
#include "link.h"
+#include "node.h"
#include <net/genetlink.h>
static int handle_cmd(struct sk_buff *skb, struct genl_info *info)
@@ -77,6 +78,7 @@ static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 1] = {
[TIPC_NLA_SOCK] = { .type = NLA_NESTED, },
[TIPC_NLA_LINK] = { .type = NLA_NESTED, },
[TIPC_NLA_MEDIA] = { .type = NLA_NESTED, },
+ [TIPC_NLA_NODE] = { .type = NLA_NESTED, }
};
struct genl_family tipc_genl_family = {
@@ -145,6 +147,11 @@ static const struct genl_ops tipc_genl_ops[] = {
.cmd = TIPC_NL_MEDIA_SET,
.doit = tipc_nl_media_set,
.policy = tipc_nl_policy,
+ },
+ {
+ .cmd = TIPC_NL_NODE_GET,
+ .dumpit = tipc_nl_node_dump,
+ .policy = tipc_nl_policy,
}
};
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 17e6378..80ca561 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -58,6 +58,12 @@ struct tipc_sock_conn {
struct list_head list;
};
+static const struct nla_policy tipc_nl_node_policy[TIPC_NLA_NODE_MAX + 1] = {
+ [TIPC_NLA_NODE_UNSPEC] = { .type = NLA_UNSPEC },
+ [TIPC_NLA_NODE_ADDR] = { .type = NLA_U32 },
+ [TIPC_NLA_NODE_UP] = { .type = NLA_FLAG }
+};
+
/*
* A trivial power-of-two bitmask technique is used for speed, since this
* operation is done for every incoming TIPC packet. The number of hash table
@@ -586,3 +592,93 @@ void tipc_node_unlock(struct tipc_node *node)
if (addr)
tipc_named_node_up(addr);
}
+
+/* Caller should hold node lock for the passed node */
+int __tipc_nl_add_node(struct tipc_nl_msg *msg, struct tipc_node *node)
+{
+ void *hdr;
+ struct nlattr *attrs;
+
+ hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
+ NLM_F_MULTI, TIPC_NL_NODE_GET);
+ if (!hdr)
+ return -EMSGSIZE;
+
+ attrs = nla_nest_start(msg->skb, TIPC_NLA_NODE);
+ if (!attrs)
+ goto msg_full;
+
+ if (nla_put_u32(msg->skb, TIPC_NLA_NODE_ADDR, node->addr))
+ goto attr_msg_full;
+ if (tipc_node_is_up(node))
+ if (nla_put_flag(msg->skb, TIPC_NLA_NODE_UP))
+ goto attr_msg_full;
+
+ nla_nest_end(msg->skb, attrs);
+ genlmsg_end(msg->skb, hdr);
+
+ return 0;
+
+attr_msg_full:
+ nla_nest_cancel(msg->skb, attrs);
+msg_full:
+ genlmsg_cancel(msg->skb, hdr);
+
+ return -EMSGSIZE;
+}
+
+int tipc_nl_node_dump(struct sk_buff *skb, struct netlink_callback *cb)
+{
+ int err;
+ int done = cb->args[0];
+ int last_addr = cb->args[1];
+ struct tipc_node *node;
+ struct tipc_nl_msg msg;
+
+ if (done)
+ return 0;
+
+ msg.skb = skb;
+ msg.portid = NETLINK_CB(cb->skb).portid;
+ msg.seq = cb->nlh->nlmsg_seq;
+
+ rcu_read_lock();
+
+ if (last_addr && !tipc_node_find(last_addr)) {
+ rcu_read_unlock();
+ /* We never set seq or call nl_dump_check_consistent() this
+ * means that setting prev_seq here will cause the consistence
+ * check to fail in the netlink callback handler. Resulting in
+ * the NLMSG_DONE message having the NLM_F_DUMP_INTR flag set if
+ * the node state changed while we released the lock.
+ */
+ cb->prev_seq = 1;
+ return -EPIPE;
+ }
+
+ list_for_each_entry_rcu(node, &tipc_node_list, list) {
+ if (last_addr) {
+ if (node->addr == last_addr)
+ last_addr = 0;
+ else
+ continue;
+ }
+
+ tipc_node_lock(node);
+ err = __tipc_nl_add_node(&msg, node);
+ if (err) {
+ last_addr = node->addr;
+ tipc_node_unlock(node);
+ goto out;
+ }
+
+ tipc_node_unlock(node);
+ }
+ done = 1;
+out:
+ cb->args[0] = done;
+ cb->args[1] = last_addr;
+ rcu_read_unlock();
+
+ return skb->len;
+}
diff --git a/net/tipc/node.h b/net/tipc/node.h
index 522d6f3..17c0921 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -1,7 +1,7 @@
/*
* net/tipc/node.h: Include file for TIPC node management routines
*
- * Copyright (c) 2000-2006, Ericsson AB
+ * Copyright (c) 2000-2006, 2014, Ericsson AB
* Copyright (c) 2005, 2010-2014, Wind River Systems
* All rights reserved.
*
@@ -139,6 +139,8 @@ void tipc_node_unlock(struct tipc_node *node);
int tipc_node_add_conn(u32 dnode, u32 port, u32 peer_port);
void tipc_node_remove_conn(u32 dnode, u32 port);
+int tipc_nl_node_dump(struct sk_buff *skb, struct netlink_callback *cb);
+
static inline void tipc_node_lock(struct tipc_node *node)
{
spin_lock_bh(&node->lock);
--
1.7.10.4
------------------------------------------------------------------------------
Want excitement?
Manually upgrade your production database.
When you want reliability, choose Perforce
Perforce version control. Predictably reliable.
http://pubads.g.doubleclick.net/gampad/clk?id=157508191&iu=/4140/ostg.clktrk
^ permalink raw reply related
* [PATCH net-next 11/14] tipc: add net dump to new netlink api
From: richard.alpe @ 2014-09-11 8:29 UTC (permalink / raw)
To: netdev; +Cc: tipc-discussion
In-Reply-To: <1410424167-17427-1-git-send-email-richard.alpe@ericsson.com>
From: Richard Alpe <richard.alpe@ericsson.com>
Add TIPC_NL_NET_GET command to the new tipc netlink API.
This command dumps the network id of the node.
Netlink logical layout of returned network data:
-> net
-> id
Signed-off-by: Richard Alpe <richard.alpe@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
Acked-by: Ying Xue <ying.xue@windriver.com>
---
include/uapi/linux/tipc_config.h | 11 +++++++
net/tipc/net.c | 59 ++++++++++++++++++++++++++++++++++++++
net/tipc/net.h | 7 ++++-
net/tipc/netlink.c | 9 +++++-
4 files changed, 84 insertions(+), 2 deletions(-)
diff --git a/include/uapi/linux/tipc_config.h b/include/uapi/linux/tipc_config.h
index e3dfad7..68a58b0 100644
--- a/include/uapi/linux/tipc_config.h
+++ b/include/uapi/linux/tipc_config.h
@@ -61,6 +61,7 @@ enum {
TIPC_NL_MEDIA_GET,
TIPC_NL_MEDIA_SET,
TIPC_NL_NODE_GET,
+ TIPC_NL_NET_GET,
__TIPC_NL_CMD_MAX,
TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1
@@ -74,6 +75,7 @@ enum {
TIPC_NLA_LINK, /* nest */
TIPC_NLA_MEDIA, /* nest */
TIPC_NLA_NODE, /* nest */
+ TIPC_NLA_NET, /* nest */
__TIPC_NLA_MAX,
TIPC_NLA_MAX = __TIPC_NLA_MAX - 1
@@ -139,6 +141,15 @@ enum {
TIPC_NLA_NODE_MAX = __TIPC_NLA_NODE_MAX - 1
};
+/* Net info */
+enum {
+ TIPC_NLA_NET_UNSPEC,
+ TIPC_NLA_NET_ID, /* u32 */
+
+ __TIPC_NLA_NET_MAX,
+ TIPC_NLA_NET_MAX = __TIPC_NLA_NET_MAX - 1
+};
+
/* Nest, publication info */
enum {
TIPC_NLA_PUBL_UNSPEC,
diff --git a/net/tipc/net.c b/net/tipc/net.c
index 93b9944..b5435a6 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -42,6 +42,11 @@
#include "node.h"
#include "config.h"
+static const struct nla_policy tipc_nl_net_policy[TIPC_NLA_NET_MAX + 1] = {
+ [TIPC_NLA_NET_UNSPEC] = { .type = NLA_UNSPEC },
+ [TIPC_NLA_NET_ID] = { .type = NLA_U32 }
+};
+
/*
* The TIPC locking policy is designed to ensure a very fine locking
* granularity, permitting complete parallel access to individual
@@ -138,3 +143,57 @@ void tipc_net_stop(void)
pr_info("Left network mode\n");
}
+
+static int __tipc_nl_add_net(struct tipc_nl_msg *msg)
+{
+ void *hdr;
+ struct nlattr *attrs;
+
+ hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
+ NLM_F_MULTI, TIPC_NL_NET_GET);
+ if (!hdr)
+ return -EMSGSIZE;
+
+ attrs = nla_nest_start(msg->skb, TIPC_NLA_NET);
+ if (!attrs)
+ goto msg_full;
+
+ if (nla_put_u32(msg->skb, TIPC_NLA_NET_ID, tipc_net_id))
+ goto attr_msg_full;
+
+ nla_nest_end(msg->skb, attrs);
+ genlmsg_end(msg->skb, hdr);
+
+ return 0;
+
+attr_msg_full:
+ nla_nest_cancel(msg->skb, attrs);
+msg_full:
+ genlmsg_cancel(msg->skb, hdr);
+
+ return -EMSGSIZE;
+}
+
+int tipc_nl_net_dump(struct sk_buff *skb, struct netlink_callback *cb)
+{
+ int err;
+ int done = cb->args[0];
+ struct tipc_nl_msg msg;
+
+ if (done)
+ return 0;
+
+ msg.skb = skb;
+ msg.portid = NETLINK_CB(cb->skb).portid;
+ msg.seq = cb->nlh->nlmsg_seq;
+
+ err = __tipc_nl_add_net(&msg);
+ if (err)
+ goto out;
+
+ done = 1;
+out:
+ cb->args[0] = done;
+
+ return skb->len;
+}
diff --git a/net/tipc/net.h b/net/tipc/net.h
index 59ef338..60dc22f 100644
--- a/net/tipc/net.h
+++ b/net/tipc/net.h
@@ -1,7 +1,7 @@
/*
* net/tipc/net.h: Include file for TIPC network routing code
*
- * Copyright (c) 1995-2006, Ericsson AB
+ * Copyright (c) 1995-2006, 2014, Ericsson AB
* Copyright (c) 2005, 2010-2011, Wind River Systems
* All rights reserved.
*
@@ -37,7 +37,12 @@
#ifndef _TIPC_NET_H
#define _TIPC_NET_H
+#include <net/genetlink.h>
+
int tipc_net_start(u32 addr);
+
void tipc_net_stop(void);
+int tipc_nl_net_dump(struct sk_buff *skb, struct netlink_callback *cb);
+
#endif
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index d42027e..3730876 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -40,6 +40,7 @@
#include "bearer.h"
#include "link.h"
#include "node.h"
+#include "net.h"
#include <net/genetlink.h>
static int handle_cmd(struct sk_buff *skb, struct genl_info *info)
@@ -78,7 +79,8 @@ static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 1] = {
[TIPC_NLA_SOCK] = { .type = NLA_NESTED, },
[TIPC_NLA_LINK] = { .type = NLA_NESTED, },
[TIPC_NLA_MEDIA] = { .type = NLA_NESTED, },
- [TIPC_NLA_NODE] = { .type = NLA_NESTED, }
+ [TIPC_NLA_NODE] = { .type = NLA_NESTED, },
+ [TIPC_NLA_NET] = { .type = NLA_NESTED, }
};
struct genl_family tipc_genl_family = {
@@ -152,6 +154,11 @@ static const struct genl_ops tipc_genl_ops[] = {
.cmd = TIPC_NL_NODE_GET,
.dumpit = tipc_nl_node_dump,
.policy = tipc_nl_policy,
+ },
+ {
+ .cmd = TIPC_NL_NET_GET,
+ .dumpit = tipc_nl_net_dump,
+ .policy = tipc_nl_policy,
}
};
--
1.7.10.4
------------------------------------------------------------------------------
Want excitement?
Manually upgrade your production database.
When you want reliability, choose Perforce
Perforce version control. Predictably reliable.
http://pubads.g.doubleclick.net/gampad/clk?id=157508191&iu=/4140/ostg.clktrk
^ permalink raw reply related
* [PATCH net-next 12/14] tipc: add net set to new netlink api
From: richard.alpe @ 2014-09-11 8:29 UTC (permalink / raw)
To: netdev; +Cc: tipc-discussion
In-Reply-To: <1410424167-17427-1-git-send-email-richard.alpe@ericsson.com>
From: Richard Alpe <richard.alpe@ericsson.com>
Add TIPC_NL_NET_SET command to the new tipc netlink API.
This command can set the network id and network (tipc) address.
Netlink logical layout of network set message:
-> net
[ -> id ]
[ -> address ]
Signed-off-by: Richard Alpe <richard.alpe@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
Acked-by: Ying Xue <ying.xue@windriver.com>
---
include/uapi/linux/tipc_config.h | 2 ++
net/tipc/net.c | 47 ++++++++++++++++++++++++++++++++++++++
net/tipc/net.h | 1 +
net/tipc/netlink.c | 5 ++++
4 files changed, 55 insertions(+)
diff --git a/include/uapi/linux/tipc_config.h b/include/uapi/linux/tipc_config.h
index 68a58b0..6fdb819 100644
--- a/include/uapi/linux/tipc_config.h
+++ b/include/uapi/linux/tipc_config.h
@@ -62,6 +62,7 @@ enum {
TIPC_NL_MEDIA_SET,
TIPC_NL_NODE_GET,
TIPC_NL_NET_GET,
+ TIPC_NL_NET_SET,
__TIPC_NL_CMD_MAX,
TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1
@@ -145,6 +146,7 @@ enum {
enum {
TIPC_NLA_NET_UNSPEC,
TIPC_NLA_NET_ID, /* u32 */
+ TIPC_NLA_NET_ADDR, /* u32 */
__TIPC_NLA_NET_MAX,
TIPC_NLA_NET_MAX = __TIPC_NLA_NET_MAX - 1
diff --git a/net/tipc/net.c b/net/tipc/net.c
index b5435a6..fdbbedf 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -197,3 +197,50 @@ out:
return skb->len;
}
+
+int tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info)
+{
+ int err;
+ struct nlattr *attrs[TIPC_NLA_NET_MAX + 1];
+
+ if (!info->attrs[TIPC_NLA_NET])
+ return -EINVAL;
+
+ err = nla_parse_nested(attrs, TIPC_NLA_NET_MAX,
+ info->attrs[TIPC_NLA_NET],
+ tipc_nl_net_policy);
+ if (err)
+ return err;
+
+ if (attrs[TIPC_NLA_NET_ID]) {
+ u32 val;
+
+ /* Can't change net id once TIPC has joined a network */
+ if (tipc_own_addr)
+ return -EPERM;
+
+ val = nla_get_u32(attrs[TIPC_NLA_NET_ID]);
+ if (val < 1 || val > 9999)
+ return -EINVAL;
+
+ tipc_net_id = val;
+ }
+
+ if (attrs[TIPC_NLA_NET_ADDR]) {
+ u32 addr;
+
+ /* Can't change net addr once TIPC has joined a network */
+ if (tipc_own_addr)
+ return -EPERM;
+
+ addr = nla_get_u32(attrs[TIPC_NLA_NET_ADDR]);
+ if (!tipc_addr_node_valid(addr))
+ return -EINVAL;
+
+ rtnl_lock();
+ tipc_net_start(addr);
+ rtnl_unlock();
+ }
+
+ return 0;
+}
diff --git a/net/tipc/net.h b/net/tipc/net.h
index 60dc22f..a81c1b9 100644
--- a/net/tipc/net.h
+++ b/net/tipc/net.h
@@ -44,5 +44,6 @@ int tipc_net_start(u32 addr);
void tipc_net_stop(void);
int tipc_nl_net_dump(struct sk_buff *skb, struct netlink_callback *cb);
+int tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info);
#endif
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index 3730876..7803aa9 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -159,6 +159,11 @@ static const struct genl_ops tipc_genl_ops[] = {
.cmd = TIPC_NL_NET_GET,
.dumpit = tipc_nl_net_dump,
.policy = tipc_nl_policy,
+ },
+ {
+ .cmd = TIPC_NL_NET_SET,
+ .doit = tipc_nl_net_set,
+ .policy = tipc_nl_policy,
}
};
--
1.7.10.4
------------------------------------------------------------------------------
Want excitement?
Manually upgrade your production database.
When you want reliability, choose Perforce
Perforce version control. Predictably reliable.
http://pubads.g.doubleclick.net/gampad/clk?id=157508191&iu=/4140/ostg.clktrk
^ permalink raw reply related
* [PATCH net-next 13/14] tipc: add name table dump to new netlink api
From: richard.alpe @ 2014-09-11 8:29 UTC (permalink / raw)
To: netdev; +Cc: tipc-discussion
In-Reply-To: <1410424167-17427-1-git-send-email-richard.alpe@ericsson.com>
From: Richard Alpe <richard.alpe@ericsson.com>
Add TIPC_NL_NAME_TABLE_GET command to the new tipc netlink API.
This command supports dumping the name table of all nodes.
Netlink logical layout of name table response message:
-> name table
-> publication
-> type
-> lower
-> upper
-> scope
-> node
-> ref
-> key
Signed-off-by: Richard Alpe <richard.alpe@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
Acked-by: Ying Xue <ying.xue@windriver.com>
---
include/uapi/linux/tipc_config.h | 11 +++
net/tipc/name_table.c | 190 +++++++++++++++++++++++++++++++++++++-
net/tipc/name_table.h | 4 +-
net/tipc/netlink.c | 9 +-
4 files changed, 211 insertions(+), 3 deletions(-)
diff --git a/include/uapi/linux/tipc_config.h b/include/uapi/linux/tipc_config.h
index 6fdb819..3d1a4ab 100644
--- a/include/uapi/linux/tipc_config.h
+++ b/include/uapi/linux/tipc_config.h
@@ -63,6 +63,7 @@ enum {
TIPC_NL_NODE_GET,
TIPC_NL_NET_GET,
TIPC_NL_NET_SET,
+ TIPC_NL_NAME_TABLE_GET,
__TIPC_NL_CMD_MAX,
TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1
@@ -77,6 +78,7 @@ enum {
TIPC_NLA_MEDIA, /* nest */
TIPC_NLA_NODE, /* nest */
TIPC_NLA_NET, /* nest */
+ TIPC_NLA_NAME_TABLE, /* nest */
__TIPC_NLA_MAX,
TIPC_NLA_MAX = __TIPC_NLA_MAX - 1
@@ -152,6 +154,15 @@ enum {
TIPC_NLA_NET_MAX = __TIPC_NLA_NET_MAX - 1
};
+/* Name table info */
+enum {
+ TIPC_NLA_NAME_TABLE_UNSPEC,
+ TIPC_NLA_NAME_TABLE_PUBL, /* nest */
+
+ __TIPC_NLA_NAME_TABLE_MAX,
+ TIPC_NLA_NAME_TABLE_MAX = __TIPC_NLA_NAME_TABLE_MAX - 1
+};
+
/* Nest, publication info */
enum {
TIPC_NLA_PUBL_UNSPEC,
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 3a6a0a7..7d69229 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -1,7 +1,7 @@
/*
* net/tipc/name_table.c: TIPC name table code
*
- * Copyright (c) 2000-2006, Ericsson AB
+ * Copyright (c) 2000-2006, 2014, Ericsson AB
* Copyright (c) 2004-2008, 2010-2011, Wind River Systems
* All rights reserved.
*
@@ -42,6 +42,12 @@
#define TIPC_NAMETBL_SIZE 1024 /* must be a power of 2 */
+static const struct nla_policy
+tipc_nl_name_table_policy[TIPC_NLA_NAME_TABLE_MAX + 1] = {
+ [TIPC_NLA_NAME_TABLE_UNSPEC] = { .type = NLA_UNSPEC },
+ [TIPC_NLA_NAME_TABLE_PUBL] = { .type = NLA_NESTED }
+};
+
/**
* struct name_info - name sequence publication info
* @node_list: circular list of publications made by own node
@@ -995,3 +1001,185 @@ void tipc_nametbl_stop(void)
table.types = NULL;
write_unlock_bh(&tipc_nametbl_lock);
}
+
+int __tipc_nl_add_nametable_publ(struct tipc_nl_msg *msg, struct name_seq *seq,
+ struct sub_seq *sseq, u32 *last_publ)
+{
+ void *hdr;
+ struct nlattr *attrs;
+ struct nlattr *publ;
+ struct publication *p;
+
+ if (*last_publ) {
+ list_for_each_entry(p, &sseq->info->zone_list, zone_list)
+ if (p->key == *last_publ)
+ break;
+ if (p->key != *last_publ)
+ return -EPIPE;
+ } else {
+ p = list_first_entry(&sseq->info->zone_list, struct publication,
+ zone_list);
+ }
+
+ list_for_each_entry_from(p, &sseq->info->zone_list, zone_list) {
+ *last_publ = p->key;
+
+ hdr = genlmsg_put(msg->skb, msg->portid, msg->seq,
+ &tipc_genl_family, NLM_F_MULTI,
+ TIPC_NL_NAME_TABLE_GET);
+ if (!hdr)
+ return -EMSGSIZE;
+
+ attrs = nla_nest_start(msg->skb, TIPC_NLA_NAME_TABLE);
+ if (!attrs)
+ goto msg_full;
+
+ publ = nla_nest_start(msg->skb, TIPC_NLA_NAME_TABLE_PUBL);
+ if (!publ)
+ goto attr_msg_full;
+
+ if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_TYPE, seq->type))
+ goto publ_msg_full;
+ if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_LOWER, sseq->lower))
+ goto publ_msg_full;
+ if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_UPPER, sseq->upper))
+ goto publ_msg_full;
+ if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_SCOPE, p->scope))
+ goto publ_msg_full;
+ if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_NODE, p->node))
+ goto publ_msg_full;
+ if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_REF, p->ref))
+ goto publ_msg_full;
+ if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_KEY, p->key))
+ goto publ_msg_full;
+
+ nla_nest_end(msg->skb, publ);
+ nla_nest_end(msg->skb, attrs);
+ genlmsg_end(msg->skb, hdr);
+ }
+ *last_publ = 0;
+
+ return 0;
+
+publ_msg_full:
+ nla_nest_cancel(msg->skb, publ);
+attr_msg_full:
+ nla_nest_cancel(msg->skb, attrs);
+msg_full:
+ genlmsg_cancel(msg->skb, hdr);
+
+ return -EMSGSIZE;
+}
+
+int __tipc_nl_subseq_list(struct tipc_nl_msg *msg, struct name_seq *seq,
+ u32 *last_lower, u32 *last_publ)
+{
+ struct sub_seq *sseq;
+ struct sub_seq *sseq_start;
+ int err;
+
+ if (*last_lower) {
+ sseq_start = nameseq_find_subseq(seq, *last_lower);
+ if (!sseq_start)
+ return -EPIPE;
+ } else {
+ sseq_start = seq->sseqs;
+ }
+
+ for (sseq = sseq_start; sseq != &seq->sseqs[seq->first_free]; sseq++) {
+ err = __tipc_nl_add_nametable_publ(msg, seq, sseq, last_publ);
+ if (err) {
+ *last_lower = sseq->lower;
+ return err;
+ }
+ }
+ *last_lower = 0;
+
+ return 0;
+}
+
+int __tipc_nl_seq_list(struct tipc_nl_msg *msg, u32 *last_type, u32 *last_lower,
+ u32 *last_publ)
+{
+ struct hlist_head *seq_head;
+ struct name_seq *seq;
+ int err;
+ int i;
+
+ if (*last_type)
+ i = hash(*last_type);
+ else
+ i = 0;
+
+ for (; i < TIPC_NAMETBL_SIZE; i++) {
+ seq_head = &table.types[i];
+
+ if (*last_type) {
+ seq = nametbl_find_seq(*last_type);
+ if (!seq)
+ return -EPIPE;
+ } else {
+ seq = hlist_entry_safe((seq_head)->first,
+ struct name_seq, ns_list);
+ if (!seq)
+ continue;
+ }
+
+ hlist_for_each_entry_from(seq, ns_list) {
+ spin_lock_bh(&seq->lock);
+
+ err = __tipc_nl_subseq_list(msg, seq, last_lower,
+ last_publ);
+
+ if (err) {
+ *last_type = seq->type;
+ spin_unlock_bh(&seq->lock);
+ return err;
+ }
+ spin_unlock_bh(&seq->lock);
+ }
+ *last_type = 0;
+ }
+ return 0;
+}
+
+int tipc_nl_name_table_dump(struct sk_buff *skb, struct netlink_callback *cb)
+{
+ int err;
+ int done = cb->args[3];
+ u32 last_type = cb->args[0];
+ u32 last_lower = cb->args[1];
+ u32 last_publ = cb->args[2];
+ struct tipc_nl_msg msg;
+
+ if (done)
+ return 0;
+
+ msg.skb = skb;
+ msg.portid = NETLINK_CB(cb->skb).portid;
+ msg.seq = cb->nlh->nlmsg_seq;
+
+ read_lock_bh(&tipc_nametbl_lock);
+
+ err = __tipc_nl_seq_list(&msg, &last_type, &last_lower, &last_publ);
+ if (!err) {
+ done = 1;
+ } else if (err != -EMSGSIZE) {
+ /* We never set seq or call nl_dump_check_consistent() this
+ * means that setting prev_seq here will cause the consistence
+ * check to fail in the netlink callback handler. Resulting in
+ * the NLMSG_DONE message having the NLM_F_DUMP_INTR flag set if
+ * we got an error.
+ */
+ cb->prev_seq = 1;
+ }
+
+ read_unlock_bh(&tipc_nametbl_lock);
+
+ cb->args[0] = last_type;
+ cb->args[1] = last_lower;
+ cb->args[2] = last_publ;
+ cb->args[3] = done;
+
+ return skb->len;
+}
diff --git a/net/tipc/name_table.h b/net/tipc/name_table.h
index f02f48b..b38ebec 100644
--- a/net/tipc/name_table.h
+++ b/net/tipc/name_table.h
@@ -1,7 +1,7 @@
/*
* net/tipc/name_table.h: Include file for TIPC name table code
*
- * Copyright (c) 2000-2006, Ericsson AB
+ * Copyright (c) 2000-2006, 2014, Ericsson AB
* Copyright (c) 2004-2005, 2010-2011, Wind River Systems
* All rights reserved.
*
@@ -84,6 +84,8 @@ struct publication {
extern rwlock_t tipc_nametbl_lock;
+int tipc_nl_name_table_dump(struct sk_buff *skb, struct netlink_callback *cb);
+
struct sk_buff *tipc_nametbl_get(const void *req_tlv_area, int req_tlv_space);
u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *node);
int tipc_nametbl_mc_translate(u32 type, u32 lower, u32 upper, u32 limit,
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index 7803aa9..11a2fd8 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -37,6 +37,7 @@
#include "core.h"
#include "config.h"
#include "socket.h"
+#include "name_table.h"
#include "bearer.h"
#include "link.h"
#include "node.h"
@@ -80,7 +81,8 @@ static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 1] = {
[TIPC_NLA_LINK] = { .type = NLA_NESTED, },
[TIPC_NLA_MEDIA] = { .type = NLA_NESTED, },
[TIPC_NLA_NODE] = { .type = NLA_NESTED, },
- [TIPC_NLA_NET] = { .type = NLA_NESTED, }
+ [TIPC_NLA_NET] = { .type = NLA_NESTED, },
+ [TIPC_NLA_NAME_TABLE] = { .type = NLA_NESTED, }
};
struct genl_family tipc_genl_family = {
@@ -164,6 +166,11 @@ static const struct genl_ops tipc_genl_ops[] = {
.cmd = TIPC_NL_NET_SET,
.doit = tipc_nl_net_set,
.policy = tipc_nl_policy,
+ },
+ {
+ .cmd = TIPC_NL_NAME_TABLE_GET,
+ .dumpit = tipc_nl_name_table_dump,
+ .policy = tipc_nl_policy,
}
};
--
1.7.10.4
------------------------------------------------------------------------------
Want excitement?
Manually upgrade your production database.
When you want reliability, choose Perforce
Perforce version control. Predictably reliable.
http://pubads.g.doubleclick.net/gampad/clk?id=157508191&iu=/4140/ostg.clktrk
^ permalink raw reply related
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