* Re: [RFC PATCH 00/24] TRILL implementation
From: Cong Wang @ 2014-09-24 17:24 UTC (permalink / raw)
To: William Dauchy
Cc: Stephen Hemminger, Ahmed Amamou, netdev, f.cachereul,
Fengguang Wu
In-Reply-To: <20140924165447.GG27183@gandi.net>
On Wed, Sep 24, 2014 at 9:54 AM, William Dauchy <william@gandi.net> wrote:
> On Sep24 09:44, Stephen Hemminger wrote:
>> Is this patch series bisectable? does it build at each step?
>
> it should be the case but we will double check that.
>
You can ask Fengguang to add your repo to his kbuild bot,
I am sure it can catch much more than we do. :)
^ permalink raw reply
* Re: [net-next PATCH 1/1 V4] qdisc: bulk dequeue support for qdiscs with TCQ_F_ONETXQUEUE
From: Eric Dumazet @ 2014-09-24 17:23 UTC (permalink / raw)
To: Jesper Dangaard Brouer
Cc: netdev, therbert, David S. Miller, Alexander Duyck, toke,
Florian Westphal, jhs, Dave Taht, John Fastabend, Daniel Borkmann,
Hannes Frederic Sowa
In-Reply-To: <20140924161047.9721.43080.stgit@localhost>
On Wed, 2014-09-24 at 18:12 +0200, Jesper Dangaard Brouer wrote:
> Based on DaveM's recent API work on dev_hard_start_xmit(), that allows
> sending/processing an entire skb list.
>
> This patch implements qdisc bulk dequeue, by allowing multiple packets
> to be dequeued in dequeue_skb().
>
> The optimization principle for this is two fold, (1) to amortize
> locking cost and (2) avoid expensive tailptr update for notifying HW.
> (1) Several packets are dequeued while holding the qdisc root_lock,
> amortizing locking cost over several packet. The dequeued SKB list is
> processed under the TXQ lock in dev_hard_start_xmit(), thus also
> amortizing the cost of the TXQ lock.
> (2) Further more, dev_hard_start_xmit() will utilize the skb->xmit_more
> API to delay HW tailptr update, which also reduces the cost per
> packet.
>
> One restriction of the new API is that every SKB must belong to the
> same TXQ. This patch takes the easy way out, by restricting bulk
> dequeue to qdisc's with the TCQ_F_ONETXQUEUE flag, that specifies the
> qdisc only have attached a single TXQ.
>
> Some detail about the flow; dev_hard_start_xmit() will process the skb
> list, and transmit packets individually towards the driver (see
> xmit_one()). In case the driver stops midway in the list, the
> remaining skb list is returned by dev_hard_start_xmit(). In
> sch_direct_xmit() this returned list is requeued by dev_requeue_skb().
>
> To avoid overshooting the HW limits, which results in requeuing, the
> patch limits the amount of bytes dequeued, based on the drivers BQL
> limits. In-effect bulking will only happen for BQL enabled drivers.
> Besides the bytelimit from BQL, also limit bulking to maximum 8
> packets to avoid any issues with available descriptor in HW.
>
> For now, as a conservative approach, don't bulk dequeue GSO and
> segmented GSO packets, because testing showed requeuing occuring
> with segmented GSO packets.
>
> Jointed work with Hannes, Daniel and Florian.
>
> Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
> Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
> Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
> Signed-off-by: Florian Westphal <fw@strlen.de>
>
> ---
> V4:
> - Patch rewritten in the Red Hat Neuchatel office jointed work with
> Hannes, Daniel and Florian.
> - Conservative approach of only using on BQL enabled drivers
> - No user tunable parameter, but limit bulking to 8 packets.
> - For now, avoid bulking GSO packets packets.
>
> V3:
> - Correct use of BQL
> - Some minor adjustments based on feedback.
> - Default setting only bulk dequeue 1 extra packet (2 packets).
>
> V2:
> - Restruct functions, split out functionality
> - Use BQL bytelimit to avoid overshooting driver limits
> ---
> include/net/sch_generic.h | 16 +++++++++++++++
> net/sched/sch_generic.c | 47 +++++++++++++++++++++++++++++++++++++++++++--
> 2 files changed, 61 insertions(+), 2 deletions(-)
>
> diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
> index a3cfb8e..4e39a3e 100644
> --- a/include/net/sch_generic.h
> +++ b/include/net/sch_generic.h
> @@ -6,6 +6,7 @@
> #include <linux/rcupdate.h>
> #include <linux/pkt_sched.h>
> #include <linux/pkt_cls.h>
> +#include <linux/dynamic_queue_limits.h>
> #include <net/gen_stats.h>
> #include <net/rtnetlink.h>
>
> @@ -111,6 +112,21 @@ static inline void qdisc_run_end(struct Qdisc *qdisc)
> qdisc->__state &= ~__QDISC___STATE_RUNNING;
> }
>
> +static inline bool qdisc_may_bulk(const struct Qdisc *qdisc)
> +{
> + return qdisc->flags & TCQ_F_ONETXQUEUE;
> +}
> +
> +static inline int qdisc_avail_bulklimit(const struct netdev_queue *txq)
> +{
> +#ifdef CONFIG_BQL
> + /* Non-BQL migrated drivers will return 0, too. */
> + return dql_avail(&txq->dql);
> +#else
> + return 0;
> +#endif
> +}
> +
> static inline bool qdisc_is_throttled(const struct Qdisc *qdisc)
> {
> return test_bit(__QDISC_STATE_THROTTLED, &qdisc->state) ? true : false;
> diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
> index 19696eb..6fba089 100644
> --- a/net/sched/sch_generic.c
> +++ b/net/sched/sch_generic.c
> @@ -56,6 +56,42 @@ static inline int dev_requeue_skb(struct sk_buff *skb, struct Qdisc *q)
> return 0;
> }
>
> +static struct sk_buff *try_bulk_dequeue_skb(struct Qdisc *q,
> + struct sk_buff *head_skb,
> + int bytelimit)
> +{
> + struct sk_buff *skb, *tail_skb = head_skb;
> + int budget = 8; /* Arbitrary, but conservatively choosen limit */
> +
> + while (bytelimit > 0 && --budget > 0) {
> + /* For now, don't bulk dequeue GSO (or GSO segmented) pkts */
Hmm... this is a serious limitation.
> + if (tail_skb->next || skb_is_gso(tail_skb))
> + break;
> +
> + skb = q->dequeue(q);
> + if (!skb)
> + break;
> +
> + bytelimit -= skb->len; /* covers GSO len */
Not really, use qdisc_pkt_len(skb) instead, to have a better byte count.
> + skb = validate_xmit_skb(skb, qdisc_dev(q));
> + if (!skb)
> + break;
> +
> + /* "skb" can be a skb list after validate call above
> + * (GSO segmented), but it is okay to append it to
> + * current tail_skb->next, because next round will exit
> + * in-case "tail_skb->next" is a skb list.
> + */
It would be trivial to change validate_xmit_skb() to return the head and
tail of the chain. Walking the chain would hit hot cache lines, but it
is better not having to walk it.
> + tail_skb->next = skb;
> + tail_skb = skb;
So that here we do : tail_skb = tail;
> + }
> +
> + return head_skb;
> +}
> +
> +/* Note that dequeue_skb can possibly return a SKB list (via skb->next).
> + * A requeued skb (via q->gso_skb) can also be a SKB list.
> + */
> static inline struct sk_buff *dequeue_skb(struct Qdisc *q)
> {
> struct sk_buff *skb = q->gso_skb;
> @@ -70,10 +106,17 @@ static inline struct sk_buff *dequeue_skb(struct Qdisc *q)
> } else
> skb = NULL;
> } else {
> - if (!(q->flags & TCQ_F_ONETXQUEUE) || !netif_xmit_frozen_or_stopped(txq)) {
> + if (!(q->flags & TCQ_F_ONETXQUEUE) ||
> + !netif_xmit_frozen_or_stopped(txq)) {
> + int bytelimit = qdisc_avail_bulklimit(txq);
> +
> skb = q->dequeue(q);
> - if (skb)
> + if (skb) {
> + bytelimit -= skb->len;
qdisc_pkt_len(skb)
> skb = validate_xmit_skb(skb, qdisc_dev(q));
> + }
> + if (skb && qdisc_may_bulk(q))
> + skb = try_bulk_dequeue_skb(q, skb, bytelimit);
> }
> }
>
It looks good, but we really need to take care of TSO packets.
pktgen is nice, but do not represent the majority of the traffic we send
from high performance host where we want this bulk dequeue thing ;)
Thanks guys !
^ permalink raw reply
* [PATCH net] ematch: Fix matching of inverted containers.
From: Ignacy Gawędzki @ 2014-09-24 16:38 UTC (permalink / raw)
To: netdev
Negated expressions and sub-expressions need to have their flags checked for
TCF_EM_INVERT and their result negated accordingly.
Signed-off-by: Ignacy Gawędzki <ignacy.gawedzki@green-communications.fr>
---
net/sched/ematch.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/net/sched/ematch.c b/net/sched/ematch.c
index 3a633de..ad57f44 100644
--- a/net/sched/ematch.c
+++ b/net/sched/ematch.c
@@ -526,9 +526,11 @@ pop_stack:
match_idx = stack[--stackp];
cur_match = tcf_em_get_match(tree, match_idx);
- if (tcf_em_early_end(cur_match, res))
+ if (tcf_em_early_end(cur_match, res)) {
+ if (tcf_em_is_inverted(cur_match))
+ res = !res;
goto pop_stack;
- else {
+ } else {
match_idx++;
goto proceed;
}
--
1.9.1
^ permalink raw reply related
* Re: [RFC PATCH 03/24] net: rbridge: Add RBridge structure
From: Cong Wang @ 2014-09-24 17:18 UTC (permalink / raw)
To: Ahmed Amamou; +Cc: netdev, william, f.cachereul, Kamel Haddadou
In-Reply-To: <1411573940-14079-4-git-send-email-ahmed@gandi.net>
On Wed, Sep 24, 2014 at 8:51 AM, Ahmed Amamou <ahmed@gandi.net> wrote:
> add basic RBridge structure
> add basic TRILL constant
> define rbr_nickinfo structure which represent distant RBridge information
>
> Signed-off-by: Ahmed Amamou <ahmed@gandi.net>
> Signed-off-by: Kamel Haddadou <kamel@gandi.net>
> ---
> net/bridge/rbridge/rbr_private.h | 60 ++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 60 insertions(+)
> create mode 100644 net/bridge/rbridge/rbr_private.h
Do you really need to create net/bridge/rbridge/ for the code?
Using rbr_* prefix seems enough for me since they anyway
share some code elsewhere.
^ permalink raw reply
* Re: [RFC PATCH net-next v2 0/5] netns: allow to identify peer netns
From: Andy Lutomirski @ 2014-09-24 17:05 UTC (permalink / raw)
To: Nicolas Dichtel
Cc: Network Development, Linux Containers,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Linux API,
David S. Miller, Eric W. Biederman, Stephen Hemminger,
Andrew Morton
In-Reply-To: <54228F8B.2030804-pdR9zngts4EAvxtiuMwx3w@public.gmane.org>
On Wed, Sep 24, 2014 at 2:31 AM, Nicolas Dichtel
<nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w@public.gmane.org> wrote:
> Le 23/09/2014 21:26, Andy Lutomirski a écrit :
>
>> On Tue, Sep 23, 2014 at 6:20 AM, Nicolas Dichtel
>> <nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w@public.gmane.org> wrote:
>>>
>>> The goal of this serie is to be able to multicast netlink messages with
>>> an
>>> attribute that identify a peer netns.
>>> This is needed by the userland to interpret some informations contained
>>> in
>>> netlink messages (like IFLA_LINK value, but also some other attributes in
>>> case
>>> of x-netns netdevice (see also
>>> http://thread.gmane.org/gmane.linux.network/315933/focus=316064 and
>>> http://thread.gmane.org/gmane.linux.kernel.containers/28301/focus=4239)).
>>>
>>> Ids are stored in the parent user namespace. These ids are valid only
>>> inside
>>> this user namespace. The user can retrieve these ids via a new netlink
>>> messages,
>>> but only if peer netns are in the same user namespace.
>>
>>
>> What about the parent / ancestors of the owning userns? Can processes
>> in those usernses see any form of netns id?
>
> With this serie no. I'm not sure if ancestors really needs to be able to
> get these ids. What is your opinion?
I might be missing some consideration here, but I would hope that ip
link would work correctly if I have a veth interface shared with a
netns that's in a child userns.
--Andy
--
Andy Lutomirski
AMA Capital Management, LLC
^ permalink raw reply
* Re: [RFC PATCH 01/24] net: rbridge: add trill frame description
From: Cong Wang @ 2014-09-24 17:01 UTC (permalink / raw)
To: Ahmed Amamou
Cc: netdev, william, f.cachereul, Emmanuel Hocdet, Kamel Haddadou
In-Reply-To: <1411573940-14079-2-git-send-email-ahmed@gandi.net>
On Wed, Sep 24, 2014 at 8:51 AM, Ahmed Amamou <ahmed@gandi.net> wrote:
> diff --git a/include/linux/if_trill.h b/include/linux/if_trill.h
> new file mode 100644
> index 0000000..ad9c631
> --- /dev/null
> +++ b/include/linux/if_trill.h
Keep it in include/net/ directory unless you plan to use it for non-networking,
I don't think this is case here.
^ permalink raw reply
* Re: [RFC PATCH 03/24] net: rbridge: Add RBridge structure
From: William Dauchy @ 2014-09-24 16:55 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Ahmed Amamou, netdev, william, f.cachereul, Kamel Haddadou
In-Reply-To: <20140924094048.05fbd3ea@urahara>
[-- Attachment #1: Type: text/plain, Size: 156 bytes --]
On Sep24 09:40, Stephen Hemminger wrote:
> Be consistent, always use kernel types (u16) not stdint types (uint16_t)
true, we'll fix that
--
William
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]
^ permalink raw reply
* Re: [RFC PATCH 00/24] TRILL implementation
From: William Dauchy @ 2014-09-24 16:54 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: Ahmed Amamou, netdev, william, f.cachereul
In-Reply-To: <20140924094422.2e710ead@urahara>
[-- Attachment #1: Type: text/plain, Size: 457 bytes --]
On Sep24 09:44, Stephen Hemminger wrote:
> Is this patch series bisectable? does it build at each step?
it should be the case but we will double check that.
> Also, it seems when you build with trill you lose normal bridge functionality.
> Whether kernel is doing bridge or rbridge has to be a runtime (not compile time)
> choice on a per-bridge basis.
The normal bridge functionnality are still ok until TRILL is not
enabled.
--
William
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]
^ permalink raw reply
* Re: [RFC PATCH 01/24] net: rbridge: add trill frame description
From: William Dauchy @ 2014-09-24 16:48 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Ahmed Amamou, netdev, william, f.cachereul, Emmanuel Hocdet,
Kamel Haddadou
In-Reply-To: <20140924093846.292a964f@urahara>
[-- Attachment #1: Type: text/plain, Size: 221 bytes --]
On Sep24 09:38, Stephen Hemminger wrote:
> Excessive paren's.
true; to be exact, forgot to add a patch that was fixing this.
> Did you even run this through checkpatch?
no but we will.
Thanks,
--
William
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]
^ permalink raw reply
* Re: [RFC PATCH net-next v2 0/5] netns: allow to identify peer netns
From: Cong Wang @ 2014-09-24 16:48 UTC (permalink / raw)
To: Nicolas Dichtel
Cc: netdev, containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Andy Lutomirski, Stephen Hemminger, Eric W. Biederman,
linux-api-u79uwXL29TY76Z2rM5mHXA, Andrew Morton, David Miller
In-Reply-To: <5422F1F7.8010308-pdR9zngts4EAvxtiuMwx3w@public.gmane.org>
On Wed, Sep 24, 2014 at 9:31 AM, Nicolas Dichtel
<nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w@public.gmane.org> wrote:
>> I think in this case your ID's are still available, but aren't you
>> providing a new way
>> for the inner netns device to escape which we are trying to avoid?
>
> It's why the ids depend on user ns. Only if user ns are the same we allow to
> get an id for a peer netns.
Too late, userns is relatively new, relying on it breaks our existing
assumption.
^ permalink raw reply
* Re: [RFC PATCH net-next v2 0/5] netns: allow to identify peer netns
From: Cong Wang @ 2014-09-24 16:45 UTC (permalink / raw)
To: Nicolas Dichtel
Cc: netdev, containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Andy Lutomirski, Stephen Hemminger, Eric W. Biederman,
linux-api-u79uwXL29TY76Z2rM5mHXA, Andrew Morton, David Miller
In-Reply-To: <5422F0F4.6000709-pdR9zngts4EAvxtiuMwx3w@public.gmane.org>
On Wed, Sep 24, 2014 at 9:27 AM, Nicolas Dichtel
<nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w@public.gmane.org> wrote:
> Now informations got with 'ip link' are wrong and incomplete:
> - the link dev is now tunl0 instead of eth0, because we only got an
> ifindex
> from the kernel without any netns informations.
This is not new, macvlan has the same problem. This is why I said
it is mostly a display problem, maybe just mark the ifindex as -1 or
something when it is not in this netns. At least I don't expect the inner
netns know anything outside, and I don't think I am the only one using
netns in this way.
> - the encapsulation addresses are not part of this netns but the user
> doesn't
> known that (still because netns info is missing). These IPv4 addresses
> may
> exist into this netns.
I don't remember your x-netns code, but we have two choices:
1) Lookup the route of the netns which it is in
If the address is not available in this netns, it will fail, this is expected
since tunnel device is not a pure L2 device. Or maybe just fail
early when we move it.
2) Lookup the route of the netns where it was created
Transparent for upper layer, but as you said, the outer address is not
available in this netns therefore hard to display. Just hiding this information
doesn't seem wrong to me.
> - it's not possible to create the same netdevice with these infos.
>
This is expected, because after all you are already in a different netns.
^ permalink raw reply
* Re: [RFC PATCH 00/24] TRILL implementation
From: Stephen Hemminger @ 2014-09-24 16:44 UTC (permalink / raw)
To: Ahmed Amamou; +Cc: netdev, william, f.cachereul
In-Reply-To: <1411573940-14079-1-git-send-email-ahmed@gandi.net>
On Wed, 24 Sep 2014 17:51:56 +0200
Ahmed Amamou <ahmed@gandi.net> wrote:
> Hi,
>
> We have been working on a TRILL implementation in the Linux kernel for some
> months now. The code has been pushed here https://github.com/Gandi/ktrill.git
> along the way. Attached a series of patch as a first proposition. The code is
> not perfect and probably still lacks of improvements. It's a first request of
> comment in order to get some feedbacks. This code has been tested for some
> months now.
>
> These patch tries to implement TRILL protocol RFC 6325. As a First
> implementation, some RFC details are still not implemented.
>
> We still need to fix these points:
> - The use of rtnetlink instead of the actual netlink.
> - BPDU handling
>
> Also some parts may not be fully linux compliant, so we are waiting for
> comments
>
> In order to test theses patches please follow this small wiki download quagga
> (userland) from here https://github.com/Gandi/quagga.git compile it using these
> options ./bootstrap.sh && ./configure --localstatedir=/var/run/quagga
> --enable-isisd --enable-trilld --disable-ipv6 --disable-ospfd
> --disable-ospfclient --disable-ripd --disable-babeld --disable-bgpd && make &&
> make install
>
> start zebra and trilld $ zebra -f $ZEBRA_CONF -P 2121 -u quagga -d $ trilld -f
> $TRILLD_CONF -P 2021 -u quagga -d
>
> configuration sample can be found here
> https://github.com/Gandi/quagga/blob/dev_trill/zebra/zebra.conf.sample and here
> https://github.com/Gandi/quagga/blob/dev_trill/isisd/trilld.conf.sample
>
>
> Finally you need to correctly configure bridge port
>
> For access port (native frames) echo 4 >
> /sys/class/net/<INTERFACE>/brport/trill_state For trunk port (trill frame and
> control frames) echo 8 > /sys/class/net/<INTERFACE>/brport/trill_state
>
> more detail can be found here: https://github.com/Gandi/ktrill/wiki NB: for port
> state github version has different flags as we did not take into consideration
> all port flag when implementing it
Is this patch series bisectable? does it build at each step?
Also, it seems when you build with trill you lose normal bridge functionality.
Whether kernel is doing bridge or rbridge has to be a runtime (not compile time)
choice on a per-bridge basis.
^ permalink raw reply
* Re: [RFC PATCH 03/24] net: rbridge: Add RBridge structure
From: Stephen Hemminger @ 2014-09-24 16:40 UTC (permalink / raw)
To: Ahmed Amamou; +Cc: netdev, william, f.cachereul, Kamel Haddadou
In-Reply-To: <1411573940-14079-4-git-send-email-ahmed@gandi.net>
On Wed, 24 Sep 2014 17:51:59 +0200
Ahmed Amamou <ahmed@gandi.net> wrote:
> +struct rbr_nickinfo {
> + /* Nickname of the RBridge */
> + uint16_t nick;
> + /* Next-hop SNPA address to reach this RBridge */
> + u8 adjsnpa[ETH_ALEN];
Be consistent, always use kernel types (u16) not stdint types (uint16_t)
^ permalink raw reply
* Re: [RFC PATCH 01/24] net: rbridge: add trill frame description
From: Stephen Hemminger @ 2014-09-24 16:38 UTC (permalink / raw)
To: Ahmed Amamou
Cc: netdev, william, f.cachereul, Emmanuel Hocdet, Kamel Haddadou
In-Reply-To: <1411573940-14079-2-git-send-email-ahmed@gandi.net>
On Wed, 24 Sep 2014 17:51:57 +0200
Ahmed Amamou <ahmed@gandi.net> wrote:
> add basic trill header description and basic header getter and setter fuctions
>
> Signed-off-by: Ahmed Amamou <ahmed@gandi.net>
> Signed-off-by: Emmanuel Hocdet <manu@gandi.net>
> Signed-off-by: Kamel Haddadou <kamel@gandi.net>
Excessive paren's.
Did you even run this through checkpatch?
^ permalink raw reply
* Fw: [Bug 85091] New: neighbour table overflow is not reported and impacts localhost TCP connectivity
From: Stephen Hemminger @ 2014-09-24 16:32 UTC (permalink / raw)
To: netdev
Begin forwarded message:
Date: Wed, 24 Sep 2014 03:44:41 -0700
From: "bugzilla-daemon@bugzilla.kernel.org" <bugzilla-daemon@bugzilla.kernel.org>
To: "stephen@networkplumber.org" <stephen@networkplumber.org>
Subject: [Bug 85091] New: neighbour table overflow is not reported and impacts localhost TCP connectivity
https://bugzilla.kernel.org/show_bug.cgi?id=85091
Bug ID: 85091
Summary: neighbour table overflow is not reported and impacts
localhost TCP connectivity
Product: Networking
Version: 2.5
Kernel Version: 3.8 - 3.17-rc6
Hardware: All
OS: Linux
Tree: Mainline
Status: NEW
Severity: normal
Priority: P1
Component: IPV4
Assignee: shemminger@linux-foundation.org
Reporter: aschultz@tpip.net
Regression: No
With the default gc_thresh values and a busy /16 network attached, the
neighbour cache can overflow. No indication is given that this happens and it
does impact TCP on localhost.
Test setup:
* about 16k (simulated IP/MAC's) on one interface
* web server behind on second interface
* routing between the two
* HTTP benchmark from the 16k IP's to the web server
* for localhost connectivity verification a netperf instance is run on
localhost like so: 'netperf -D 1 -l 600 127.0.0.1'
Result:
Kernel has to learn the 16k IP/MAC combinations, as soon as gc_thresh3 is hit,
netperf stalls, no syslog/kernel message indicates the problem.
The only indication are log entries like this:
"net_ratelimit: 1464 callbacks suppressed"
No other messages are logged.
--
You are receiving this mail because:
You are the assignee for the bug.
^ permalink raw reply
* Re: [RFC PATCH net-next v2 0/5] netns: allow to identify peer netns
From: Nicolas Dichtel @ 2014-09-24 16:31 UTC (permalink / raw)
To: Cong Wang
Cc: netdev, containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Andy Lutomirski, Stephen Hemminger, Eric W. Biederman,
linux-api-u79uwXL29TY76Z2rM5mHXA, Andrew Morton, David Miller
In-Reply-To: <CAHA+R7MVL=WpepRy8iz6iT6Kkq1RHG+b9TxJothP94ixyAj-3Q-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
Le 24/09/2014 18:15, Cong Wang a écrit :
> On Wed, Sep 24, 2014 at 9:01 AM, Cong Wang <cwang@twopensource.com> wrote:
>>
>> And clearly you missed my question above: how do you get netns id
>> without sharing /var/run/netns/ ?
>
> OK, I found it:
>
>> Ids are stored in the parent user namespace. These ids are valid only inside
>> this user namespace. The user can retrieve these ids via a new netlink messages,
>> but only if peer netns are in the same user namespace.
>
> So your example is confusing, perhaps you need some other way to show the ID's
> instead of binding to ip netns output which is basically ls
> /var/run/netns/. We don't
> want an inner netns know anything outside, IOW, we don't share /var/run/netns/.
Hmm, not sure to understand you. My usecase shares /var/run/netns, because
there is only one user ns and one mount ns.
> I think in this case your ID's are still available, but aren't you
> providing a new way
> for the inner netns device to escape which we are trying to avoid?
It's why the ids depend on user ns. Only if user ns are the same we allow to
get an id for a peer netns.
_______________________________________________
Containers mailing list
Containers@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/containers
^ permalink raw reply
* Re: [RFC PATCH net-next v2 0/5] netns: allow to identify peer netns
From: Nicolas Dichtel @ 2014-09-24 16:27 UTC (permalink / raw)
To: Cong Wang
Cc: netdev, containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Andy Lutomirski, Stephen Hemminger, Eric W. Biederman,
linux-api-u79uwXL29TY76Z2rM5mHXA, Andrew Morton, David Miller
In-Reply-To: <CAHA+R7NfJYzCsZx0E9YVXKVCQbCm_thPSi+80tix8Z9nVA82Ug-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
Le 24/09/2014 18:01, Cong Wang a écrit :
> On Wed, Sep 24, 2014 at 2:23 AM, Nicolas Dichtel
> <nicolas.dichtel@6wind.com> wrote:
>> Le 23/09/2014 21:22, Cong Wang a écrit :
>>
>>> On Tue, Sep 23, 2014 at 6:20 AM, Nicolas Dichtel
>>> <nicolas.dichtel@6wind.com> wrote:
>>>>
>>>>
>>>> Here is a small screenshot to show how it can be used by userland:
>>>> $ ip netns add foo
>>>> $ ip netns del foo
>>>> $ ip netns
>>>> $ touch /var/run/netns/init_net
>>>> $ mount --bind /proc/1/ns/net /var/run/netns/init_net
>>>> $ ip netns add foo
>>>> $ ip netns
>>>> foo (id: 3)
>>>> init_net (id: 1)
>>>> $ ip netns exec foo ip netns
>>>> foo (id: 3)
>>>> init_net (id: 1)
>>>> $ ip netns exec foo ip link add ipip1 link-netnsid 1 type ipip remote
>>>> 10.16.0.121 local 10.16.0.249
>>>> $ ip netns exec foo ip l ls ipip1
>>>> 6: ipip1@NONE: <POINTOPOINT,NOARP> mtu 1480 qdisc noop state DOWN mode
>>>> DEFAULT group default
>>>> link/ipip 10.16.0.249 peer 10.16.0.121 link-netnsid 1
>>>>
>>>> The parameter link-netnsid shows us where the interface sends and
>>>> receives
>>>> packets (and thus we know where encapsulated addresses are set).
>>>>
>>>
>>> So ipip1 is shown in netns foo but functioning in netns init_net? Getting
>>> the
>>> id of init_net in foo depends on your mount namespace, /var/run/netns/ may
>>> not visible inside foo, in this case, link-netnsid is meaningless. It
>>> is not your
>>> fault, network namespace already heavily relies on mount namespace (sysfs
>>> needs to be remount otherwise you can not create device with the same
>>> name.)
>>>
>>> On the other hand, what's the problem you are trying to solve? AFAIK,
>>> the ifindex
>>> issue is purely in output, IOW, the device still functions correctly
>>> even through
>>> its link ifindex is not correct after moving to another namespace. If
>>> not, it is bug
>>> we need to fix.
>>>
>> The problem is explained here:
>> http://thread.gmane.org/gmane.linux.network/315933/focus=316064
>> and here:
>> http://thread.gmane.org/gmane.linux.kernel.containers/28301/focus=4239
>>
>
> Please, summarize the discussion in your changelog, instead of pointing
> to a long thread.
The thread is long, but the mail in focus contains the information. Here is a
copy and paste:
What I'm trying to solve is to have full info in netlink messages sent by the
kernel, thus beeing able to identify a peer netns (and this is close from what
audit guys are trying to have). Theorically, messages sent by the kernel can be
reused as is to have the same configuration. This is not the case with x-netns
devices. Here is an example, with ip tunnels:
$ ip netns add 1
$ ip link add ipip1 type ipip remote 10.16.0.121 local 10.16.0.249 dev eth0
$ ip -d link ls ipip1
8: ipip1 <at> eth0: <POINTOPOINT,NOARP> mtu 1480 qdisc noop state DOWN mode DEFAULT
group default
link/ipip 10.16.0.249 peer 10.16.0.121 promiscuity 0
ipip remote 10.16.0.121 local 10.16.0.249 dev eth0 ttl inherit pmtudisc
$ ip link set ipip1 netns 1
$ ip netns exec 1 ip -d link ls ipip1
8: ipip1 <at> tunl0: <POINTOPOINT,NOARP,M-DOWN> mtu 1480 qdisc noop state DOWN mode
DEFAULT group default
link/ipip 10.16.0.249 peer 10.16.0.121 promiscuity 0
ipip remote 10.16.0.121 local 10.16.0.249 dev tunl0 ttl inherit pmtudisc
Now informations got with 'ip link' are wrong and incomplete:
- the link dev is now tunl0 instead of eth0, because we only got an ifindex
from the kernel without any netns informations.
- the encapsulation addresses are not part of this netns but the user doesn't
known that (still because netns info is missing). These IPv4 addresses may
exist into this netns.
- it's not possible to create the same netdevice with these infos.
Hope it's more clear now.
>
> And clearly you missed my question above: how do you get netns id
> without sharing /var/run/netns/ ?
>
You can get an id only if you already have a "pointer" to this netns.
_______________________________________________
Containers mailing list
Containers@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/containers
^ permalink raw reply
* Bug report: broadcast address as incomplete entry in arp table, effectively a blackhole; reproducer included
From: Lars Ellenberg @ 2014-09-24 16:18 UTC (permalink / raw)
To: netdev
You have some interface you want to broadcast on,
so you resolve its broadcast address (once),
and keep sending (e.g. some continuous status updates, or "heartbeat").
For some reason that interface goes down.
If you keep sending to the previously resolved address,
that will create an incomplete arp entry.
Unfortunately, that entry *stays* there, even if the interface is then
brought back up (with the same network and broadcast settings).
Once the interface is up, you won't be able to delete that entry
(because, its a broadcast address; that arp entry is not supposed to be
there anyways; that deletion request will be filtered out early...)
Anyone trying to send to that broadcast address will now effectively
send to a black hole: there is an incomplete arp entry.
Fix is then to stop all processes sending to that address,
bring down the device, delete the arp entry, bring it back up,
and then continue all processes sending to that address.
I can reproduce this easily with the script below, anywhere I tested,
on a large variety of platforms and kernels.
(you'll obviously have to adjust DEV, BROADCAST and possibly PORT).
I suspect this is not intentional, but there is simply some
neigh_flush_dev() or similar missing "somewhere".
If you want to point me in the right direction as to probable values of
"somewhere", I'll likely be able to figure out a minimal patch myself.
If you know the right place to fix this from the top of your head,
even better ;-)
Thanks,
Lars
------------------------------------------------------
#!/bin/bash
DEV=eth1
BROADCAST=192.168.133.255
PORT=6666
send_udp_broadcast()
{
exec python -c '
from socket import *
from time import sleep
from struct import pack
from datetime import datetime
s = socket(AF_INET, SOCK_DGRAM)
s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
s.setsockopt(SOL_SOCKET, SO_BINDTODEVICE, pack("'$(( 1+${#DEV} ))'s","'$DEV'"))
while 1:
s.sendto(datetime.now().strftime("hi there, it is now %T.%f"), ("'$BROADCAST'",'$PORT'))
sleep(0.1)
'
}
p() { printf "\n"; printf "::: %s\n" "$@"; printf "%s\n" "-----------"; }
arp -n | grep $BROADCAST && {
echo >&2 "Sorry, fix the arp table first!"
exit 1
}
( set +x ; send_udp_broadcast ) &
kid=$!
p "[$kid] Started to send udp broadcasts on $DEV to $BROADCAST:$PORT"
p "We should see the packets being sent on $DEV"
tcpdump -n -i $DEV -c 2 -xX udp and port $PORT
p "We should not have any arp entries for $BROADCAST"
arp -n | grep $BROADCAST
p "But we soon will, after we take down $DEV"
ip link set down $DEV
sleep 2
p "Now we should have an incomplete arp entry for $BROADCAST"
arp -n | grep $BROADCAST
p "It will still be there after we bring $DEV back up"
ip link set up $DEV
p "There won't be any packets now, this should timeout:"
while read -r -t 5 line ; do
echo "$line"
done < <(tcpdump -n -i $DEV -c 2 -xX udp and port $PORT 2>&1)
p "Because we still have that arp entry"
arp -n | grep $BROADCAST
p "And we cannot get rid of it, either, as long as this $DEV is up"
arp -d $BROADCAST
arp -n | grep $BROADCAST
p "but we can stop the child," \
"take down the device," \
"remove the arp entry then," \
"and bring the device back up"
kill -STOP $kid
ip link set down $DEV
sleep 1
arp -d $BROADCAST
ip link set up $DEV
arp -n | grep $BROADCAST
p "continue the child" \
"and now we should see outgoing packets again"
kill -CONT $kid
tcpdump -n -i $DEV -c 2 -xX udp and port $PORT
p "and no more arp entry"
arp -n | grep $BROADCAST
p "Done."
kill $kid
^ permalink raw reply
* Re: [RFC PATCH net-next v2 0/5] netns: allow to identify peer netns
From: Cong Wang @ 2014-09-24 16:15 UTC (permalink / raw)
To: Nicolas Dichtel
Cc: netdev, containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Andy Lutomirski, Stephen Hemminger, Eric W. Biederman,
linux-api-u79uwXL29TY76Z2rM5mHXA, Andrew Morton, David Miller
In-Reply-To: <CAHA+R7NfJYzCsZx0E9YVXKVCQbCm_thPSi+80tix8Z9nVA82Ug-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Wed, Sep 24, 2014 at 9:01 AM, Cong Wang <cwang-xCSkyg8dI+0RB7SZvlqPiA@public.gmane.org> wrote:
>
> And clearly you missed my question above: how do you get netns id
> without sharing /var/run/netns/ ?
OK, I found it:
> Ids are stored in the parent user namespace. These ids are valid only inside
> this user namespace. The user can retrieve these ids via a new netlink messages,
> but only if peer netns are in the same user namespace.
So your example is confusing, perhaps you need some other way to show the ID's
instead of binding to ip netns output which is basically ls
/var/run/netns/. We don't
want an inner netns know anything outside, IOW, we don't share /var/run/netns/.
I think in this case your ID's are still available, but aren't you
providing a new way
for the inner netns device to escape which we are trying to avoid?
^ permalink raw reply
* [net-next PATCH 1/1 V4] qdisc: bulk dequeue support for qdiscs with TCQ_F_ONETXQUEUE
From: Jesper Dangaard Brouer @ 2014-09-24 16:12 UTC (permalink / raw)
To: netdev, therbert, David S. Miller, Eric Dumazet,
Jesper Dangaard Brouer
Cc: Alexander Duyck, toke, Florian Westphal, jhs, Dave Taht,
John Fastabend, Daniel Borkmann, Hannes Frederic Sowa
In-Reply-To: <20140924160932.9721.56450.stgit@localhost>
Based on DaveM's recent API work on dev_hard_start_xmit(), that allows
sending/processing an entire skb list.
This patch implements qdisc bulk dequeue, by allowing multiple packets
to be dequeued in dequeue_skb().
The optimization principle for this is two fold, (1) to amortize
locking cost and (2) avoid expensive tailptr update for notifying HW.
(1) Several packets are dequeued while holding the qdisc root_lock,
amortizing locking cost over several packet. The dequeued SKB list is
processed under the TXQ lock in dev_hard_start_xmit(), thus also
amortizing the cost of the TXQ lock.
(2) Further more, dev_hard_start_xmit() will utilize the skb->xmit_more
API to delay HW tailptr update, which also reduces the cost per
packet.
One restriction of the new API is that every SKB must belong to the
same TXQ. This patch takes the easy way out, by restricting bulk
dequeue to qdisc's with the TCQ_F_ONETXQUEUE flag, that specifies the
qdisc only have attached a single TXQ.
Some detail about the flow; dev_hard_start_xmit() will process the skb
list, and transmit packets individually towards the driver (see
xmit_one()). In case the driver stops midway in the list, the
remaining skb list is returned by dev_hard_start_xmit(). In
sch_direct_xmit() this returned list is requeued by dev_requeue_skb().
To avoid overshooting the HW limits, which results in requeuing, the
patch limits the amount of bytes dequeued, based on the drivers BQL
limits. In-effect bulking will only happen for BQL enabled drivers.
Besides the bytelimit from BQL, also limit bulking to maximum 8
packets to avoid any issues with available descriptor in HW.
For now, as a conservative approach, don't bulk dequeue GSO and
segmented GSO packets, because testing showed requeuing occuring
with segmented GSO packets.
Jointed work with Hannes, Daniel and Florian.
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
V4:
- Patch rewritten in the Red Hat Neuchatel office jointed work with
Hannes, Daniel and Florian.
- Conservative approach of only using on BQL enabled drivers
- No user tunable parameter, but limit bulking to 8 packets.
- For now, avoid bulking GSO packets packets.
V3:
- Correct use of BQL
- Some minor adjustments based on feedback.
- Default setting only bulk dequeue 1 extra packet (2 packets).
V2:
- Restruct functions, split out functionality
- Use BQL bytelimit to avoid overshooting driver limits
---
include/net/sch_generic.h | 16 +++++++++++++++
net/sched/sch_generic.c | 47 +++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 61 insertions(+), 2 deletions(-)
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index a3cfb8e..4e39a3e 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -6,6 +6,7 @@
#include <linux/rcupdate.h>
#include <linux/pkt_sched.h>
#include <linux/pkt_cls.h>
+#include <linux/dynamic_queue_limits.h>
#include <net/gen_stats.h>
#include <net/rtnetlink.h>
@@ -111,6 +112,21 @@ static inline void qdisc_run_end(struct Qdisc *qdisc)
qdisc->__state &= ~__QDISC___STATE_RUNNING;
}
+static inline bool qdisc_may_bulk(const struct Qdisc *qdisc)
+{
+ return qdisc->flags & TCQ_F_ONETXQUEUE;
+}
+
+static inline int qdisc_avail_bulklimit(const struct netdev_queue *txq)
+{
+#ifdef CONFIG_BQL
+ /* Non-BQL migrated drivers will return 0, too. */
+ return dql_avail(&txq->dql);
+#else
+ return 0;
+#endif
+}
+
static inline bool qdisc_is_throttled(const struct Qdisc *qdisc)
{
return test_bit(__QDISC_STATE_THROTTLED, &qdisc->state) ? true : false;
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 19696eb..6fba089 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -56,6 +56,42 @@ static inline int dev_requeue_skb(struct sk_buff *skb, struct Qdisc *q)
return 0;
}
+static struct sk_buff *try_bulk_dequeue_skb(struct Qdisc *q,
+ struct sk_buff *head_skb,
+ int bytelimit)
+{
+ struct sk_buff *skb, *tail_skb = head_skb;
+ int budget = 8; /* Arbitrary, but conservatively choosen limit */
+
+ while (bytelimit > 0 && --budget > 0) {
+ /* For now, don't bulk dequeue GSO (or GSO segmented) pkts */
+ if (tail_skb->next || skb_is_gso(tail_skb))
+ break;
+
+ skb = q->dequeue(q);
+ if (!skb)
+ break;
+
+ bytelimit -= skb->len; /* covers GSO len */
+ skb = validate_xmit_skb(skb, qdisc_dev(q));
+ if (!skb)
+ break;
+
+ /* "skb" can be a skb list after validate call above
+ * (GSO segmented), but it is okay to append it to
+ * current tail_skb->next, because next round will exit
+ * in-case "tail_skb->next" is a skb list.
+ */
+ tail_skb->next = skb;
+ tail_skb = skb;
+ }
+
+ return head_skb;
+}
+
+/* Note that dequeue_skb can possibly return a SKB list (via skb->next).
+ * A requeued skb (via q->gso_skb) can also be a SKB list.
+ */
static inline struct sk_buff *dequeue_skb(struct Qdisc *q)
{
struct sk_buff *skb = q->gso_skb;
@@ -70,10 +106,17 @@ static inline struct sk_buff *dequeue_skb(struct Qdisc *q)
} else
skb = NULL;
} else {
- if (!(q->flags & TCQ_F_ONETXQUEUE) || !netif_xmit_frozen_or_stopped(txq)) {
+ if (!(q->flags & TCQ_F_ONETXQUEUE) ||
+ !netif_xmit_frozen_or_stopped(txq)) {
+ int bytelimit = qdisc_avail_bulklimit(txq);
+
skb = q->dequeue(q);
- if (skb)
+ if (skb) {
+ bytelimit -= skb->len;
skb = validate_xmit_skb(skb, qdisc_dev(q));
+ }
+ if (skb && qdisc_may_bulk(q))
+ skb = try_bulk_dequeue_skb(q, skb, bytelimit);
}
}
^ permalink raw reply related
* [net-next PATCH 0/1 V4] qdisc bulk dequeuing and utilizing delayed tailptr updates
From: Jesper Dangaard Brouer @ 2014-09-24 16:10 UTC (permalink / raw)
To: netdev, therbert, David S. Miller, Eric Dumazet,
Jesper Dangaard Brouer
Cc: Alexander Duyck, John Fastabend, toke, jhs, Dave Taht
This patch uses DaveM's recent API changes to dev_hard_start_xmit(),
from the qdisc layer, to implement dequeue bulking.
In this V4 iteration we are choosing an conservative approach.
Patch V4:
- Patch rewritten in the Red Hat Neuchatel office jointed work with
Hannes, Daniel and Florian.
- Conservative approach of only using on BQL enabled drivers
- No user tunable parameter, but limit bulking to 8 packets.
- For now, avoid bulking GSO packets packets.
---
Jesper Dangaard Brouer (1):
qdisc: bulk dequeue support for qdiscs with TCQ_F_ONETXQUEUE
include/net/sch_generic.h | 16 +++++++++++++++
net/sched/sch_generic.c | 47 +++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 61 insertions(+), 2 deletions(-)
--
^ permalink raw reply
* [RFC PATCH 21/24] net: rbridge: Add decapsulation function
From: Ahmed Amamou @ 2014-09-24 15:52 UTC (permalink / raw)
To: netdev; +Cc: william, f.cachereul, Ahmed Amamou, Kamel Haddadou
In-Reply-To: <1411573940-14079-1-git-send-email-ahmed@gandi.net>
for frame destined to local RBridge (egress Rbridge == local_nick)
have de be decapsuled and forwarded to corresponding host
if frame is from type multicast a copy has to be decapsulated locally
Signed-off-by: Ahmed Amamou <ahmed@gandi.net>
Signed-off-by: Kamel Haddadou <kamel@gandi.net>
Signed-off-by: William Dauchy <william@gandi.net>
---
net/bridge/rbridge/rbr.c | 56 +++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 53 insertions(+), 3 deletions(-)
diff --git a/net/bridge/rbridge/rbr.c b/net/bridge/rbridge/rbr.c
index 9206682..8aa5182 100644
--- a/net/bridge/rbridge/rbr.c
+++ b/net/bridge/rbridge/rbr.c
@@ -247,9 +247,59 @@ static void rbr_encaps(struct sk_buff *skb, uint16_t egressnick, u16 vid)
return;
}
+static void rbr_decap_finish(struct sk_buff *skb, u16 vid)
+{
+ struct net_bridge *br;
+ const unsigned char *dest = eth_hdr(skb)->h_dest;
+ struct net_bridge_fdb_entry *dst;
+ struct net_device *dev = skb->dev;
+
+ br = netdev_priv(dev);
+ dst = __br_fdb_get(br, dest, vid);
+ if (likely(dst))
+ br_deliver(dst->dst, skb);
+ else
+ /* destination unknown flood on all access ports */
+ br_flood_deliver_flags(br, skb, true, TRILL_FLAG_ACCESS);
+
+}
+
+static void rbr_decaps(struct net_bridge_port *p,
+ struct sk_buff *skb, size_t trhsize, u16 vid)
+{
+ struct trill_hdr *trh;
+ struct ethhdr *hdr;
+
+ if (unlikely(p == NULL))
+ goto rbr_decaps_drop;
+ trh = (struct trill_hdr *)skb->data;
+ if (trhsize >= sizeof(*trh))
+ skb_pull(skb, sizeof(*trh));
+ else
+ goto rbr_decaps_drop;
+ trhsize -= sizeof(*trh);
+ skb_reset_mac_header(skb); /* instead of the inner one */
+ skb->protocol = eth_hdr(skb)->h_proto;
+ hdr = (struct ethhdr *)skb->data;
+ skb_pull(skb, ETH_HLEN);
+ skb_reset_network_header(skb);
+ if (skb->encapsulation)
+ skb->encapsulation = 0;
+ /* Mark bridge as source device */
+ skb->dev = p->br->dev;
+ br_fdb_update_nick(p->br, p, hdr->h_source, vid, false,
+ trh->th_ingressnick);
+ rbr_decap_finish(skb, vid);
+ return;
+ rbr_decaps_drop:
+ if (likely(p && p->br))
+ p->br->dev->stats.rx_dropped++;
+ kfree_skb(skb);
+}
+
static void rbr_recv(struct sk_buff *skb, u16 vid)
{
- uint16_t local_nick, dtrNick, adjnick, idx;;
+ uint16_t local_nick, dtrNick, adjnick, idx;
struct rbr *rbr;
uint8_t srcaddr[ETH_ALEN];
struct trill_hdr *trh;
@@ -329,7 +379,7 @@ static void rbr_recv(struct sk_buff *skb, u16 vid)
goto recv_drop;
}
if (trh->th_egressnick == local_nick) {
- /* TODO decapsulate function */
+ rbr_decaps(p, skb, trhsize, vid);
} else if (likely(trill_get_hopcount(trill_flags))) {
br_fdb_update(p->br, p, srcaddr, vid, false);
/* TODO simple forwarding */
@@ -424,7 +474,7 @@ static void rbr_recv(struct sk_buff *skb, u16 vid)
/*
* Send de-capsulated frame locally
*/
- /* TODO decapsulate function */
+ rbr_decaps(p, skb, trhsize, vid);
return;
--
1.9.1
^ permalink raw reply related
* [RFC PATCH 15/24] net: rbridge: Add basic trill frame handling function
From: Ahmed Amamou @ 2014-09-24 15:52 UTC (permalink / raw)
To: netdev; +Cc: william, f.cachereul, Ahmed Amamou, Kamel Haddadou
In-Reply-To: <1411573940-14079-1-git-send-email-ahmed@gandi.net>
if trill is not enabled pass frame directly to the old handling function
if trill is enabled
frames from access port:
- destination is another access port -> deliver directly
- unknown or not an access port -> encapsulate (TODO)
frames from trunk port:
- 0x22F3 protocol -> trill frame -> TRILL handling process (TODO)
- desintation is localhost consume frame
Signed-off-by: Ahmed Amamou <ahmed@gandi.net>
Signed-off-by: Kamel Haddadou <kamel@gandi.net>
Signed-off-by: William Dauchy <william@gandi.net>
Suggested-by: François Cachereul <f.cachereul@alphalink.fr>
---
net/bridge/rbridge/rbr.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 100 insertions(+)
diff --git a/net/bridge/rbridge/rbr.c b/net/bridge/rbridge/rbr.c
index edd1e7c..4b41d4c 100644
--- a/net/bridge/rbridge/rbr.c
+++ b/net/bridge/rbridge/rbr.c
@@ -129,3 +129,103 @@ static void rbr_del_all(struct rbr *rbr)
rbr_del_node(rbr, i);
}
}
+
+/* handling function hook allow handling
+ * a frame upon reception called via
+ * br_handle_frame_hook = rbr_handle_frame
+ * in br.c
+ * Return NULL if skb is handled
+ * note: already called with rcu_read_lock (preempt_disabled)
+ */
+rx_handler_result_t rbr_handle_frame(struct sk_buff **pskb)
+{
+ struct net_bridge *br;
+ struct net_bridge_port *p;
+ struct sk_buff *skb = *pskb;
+ u16 vid = 0;
+
+ p = br_port_get_rcu(skb->dev);
+ if (unlikely(!p))
+ goto drop_no_stat;
+ br = p->br;
+
+ /* if trill is not enabled, handle by bridge */
+ if (br->trill_enabled == BR_NO_TRILL) {
+ goto handle_by_bridge;
+ } else {
+ if (unlikely(skb->pkt_type == PACKET_LOOPBACK))
+ return RX_HANDLER_PASS;
+ skb = skb_share_check(skb, GFP_ATOMIC);
+ if (!skb)
+ return RX_HANDLER_CONSUMED;
+ if (unlikely(!is_valid_ether_addr(eth_hdr(skb)->h_source))) {
+ pr_warn_ratelimited
+ ("rbr_handle_frame:invalid src address\n");
+ goto drop;
+ }
+ if (!br_allowed_ingress(p->br, nbp_get_vlan_info(p), skb, &vid))
+ goto drop;
+ /* do not handle any BPDU from the moment */
+ if (is_all_rbr_address((const u8 *)ð_hdr(skb)->h_dest)) {
+ br_fdb_update(br, p, eth_hdr(skb)->h_source, vid, false);
+ /* BPDU has to be dropped */
+ goto drop_no_stat;
+ }
+ /* DROP if port is in disable state */
+ if (p->trill_flag & TRILL_FLAG_DISABLE)
+ goto drop;
+
+ /* ACCESS port encapsulate packets */
+ if (p->trill_flag & TRILL_FLAG_ACCESS) {
+ /* check if destination is connected on the same bridge */
+ struct net_bridge_fdb_entry *dst;
+ dst = __br_fdb_get(br, eth_hdr(skb)->h_dest, vid);
+ if (likely(dst)) {
+ if (dst->dst->trill_flag & TRILL_FLAG_ACCESS) {
+ br_deliver(dst->dst, skb);
+ return RX_HANDLER_CONSUMED;
+ }
+ }
+ /* if packet is from access port and trill is enabled and dest
+ * is not an access port or is unknown, encaps it
+ */
+ /* TODO */
+ return RX_HANDLER_CONSUMED;
+ }
+ if (p->trill_flag & TRILL_FLAG_TRUNK) {
+ /* packet is from trunk port and trill is enabled */
+ if (eth_hdr(skb)->h_proto ==
+ __constant_htons(ETH_P_TRILL)) {
+ /*
+ * Packet is from trunk port, decapsulate if destined to access port
+ * or trill forward to next hop
+ */
+ /* TODO */
+ return RX_HANDLER_CONSUMED;
+ } else {
+ /* packet is destinated to localhost */
+ if (ether_addr_equal(p->br->dev->dev_addr,
+ eth_hdr(skb)->h_dest)) {
+ skb->pkt_type = PACKET_HOST;
+ br_handle_frame_finish(skb);
+ return RX_HANDLER_CONSUMED;
+ }
+ /*
+ * packet is not from trill we don't handle
+ * such packet from the moment
+ */
+
+ }
+ }
+ }
+
+ drop:
+ if (br->dev)
+ br->dev->stats.rx_dropped++;
+ drop_no_stat:
+ kfree_skb(skb);
+ return RX_HANDLER_CONSUMED;
+ handle_by_bridge:
+ /* trill is not enable return to bridge handle function */
+ return br_handle_frame(pskb);
+}
--
1.9.1
^ permalink raw reply related
* [RFC PATCH 22/24] net: rbridge: Add rbr_fwd
From: Ahmed Amamou @ 2014-09-24 15:52 UTC (permalink / raw)
To: netdev; +Cc: william, f.cachereul, Ahmed Amamou, Kamel Haddadou
In-Reply-To: <1411573940-14079-1-git-send-email-ahmed@gandi.net>
add rbridge forward function
packets arriving to rbr_fwd should be already encapsulated and correct egress
and ingress nickname should be already assigned
rbr_fwd function will assign correct source and destination outer MAC addresses
according to which port will send the frame and next hop to reach
the engress nickname
Nexthope to reach the egress will be found in node database
Signed-off-by: Ahmed Amamou <ahmed@gandi.net>
Signed-off-by: Kamel Haddadou <kamel@gandi.net>
Signed-off-by: William Dauchy <william@gandi.net>
Signed-off-by: François Cachereul <f.cachereul@alphalink.fr>
---
net/bridge/rbridge/rbr.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 47 insertions(+), 2 deletions(-)
diff --git a/net/bridge/rbridge/rbr.c b/net/bridge/rbridge/rbr.c
index 8aa5182..39aa816c 100644
--- a/net/bridge/rbridge/rbr.c
+++ b/net/bridge/rbridge/rbr.c
@@ -177,6 +177,51 @@ static bool add_header(struct sk_buff *skb, uint16_t ingressnick,
return 0;
}
+static void rbr_fwd(struct net_bridge_port *p, struct sk_buff *skb,
+ uint16_t adj_nick, u16 vid)
+{
+ struct rbr_node *adj;
+ struct trill_hdr *trh;
+ struct ethhdr *outerethhdr;
+ struct net *net = dev_net(p->br->dev);
+ struct net_device *outdev;
+
+ adj = rbr_find_node(p->br->rbr, adj_nick);
+ outdev = __dev_get_by_index(net, adj->rbr_ni->linkid);
+ if (!outdev) {
+ pr_warn_ratelimited("rbr_fwd: cannot find source port device for forwrding\n");
+ goto dest_fwd_fail;
+ }
+ if (unlikely(adj == NULL)) {
+ pr_warn_ratelimited
+ ("rbr_fwd: unable to find adjacent RBridge\n");
+ goto dest_fwd_fail;
+ }
+
+ trh = (struct trill_hdr *)skb->data;
+ trillhdr_dec_hopcount(trh);
+ outerethhdr = eth_hdr(skb);
+
+ /* change outer ether header */
+ /* bridge become the source_port address in outeretherhdr */
+ memcpy(outerethhdr->h_source, p->br->dev->dev_addr, ETH_ALEN);
+ /* dist port become dest address in outeretherhdr */
+ memcpy(outerethhdr->h_dest, adj->rbr_ni->adjsnpa, ETH_ALEN);
+ rbr_node_put(adj);
+ /* set Bridge as source device */
+ skb->dev = p->br->dev;
+ br_forward(br_port_get_rcu(outdev), skb, NULL);
+
+ return;
+
+ dest_fwd_fail:
+ if (likely(p && p->br))
+ p->br->dev->stats.tx_dropped++;
+ kfree_skb(skb);
+ return;
+}
+
+
static void rbr_encaps(struct sk_buff *skb, uint16_t egressnick, u16 vid)
{
uint16_t local_nick;
@@ -236,7 +281,7 @@ static void rbr_encaps(struct sk_buff *skb, uint16_t egressnick, u16 vid)
} else {
if (unlikely(add_header(skb, local_nick, egressnick, 0)))
goto encaps_drop;
- /* TODO simple forwarding */
+ rbr_fwd(p, skb, egressnick, vid);
}
return;
@@ -382,7 +427,7 @@ static void rbr_recv(struct sk_buff *skb, u16 vid)
rbr_decaps(p, skb, trhsize, vid);
} else if (likely(trill_get_hopcount(trill_flags))) {
br_fdb_update(p->br, p, srcaddr, vid, false);
- /* TODO simple forwarding */
+ rbr_fwd(p, skb, trh->th_egressnick, vid);
} else {
pr_warn_ratelimited
("rbr_recv: hop count limit reached\n");
--
1.9.1
^ permalink raw reply related
* [RFC PATCH 20/24] net: rbridge: Add multicast recv handling
From: Ahmed Amamou @ 2014-09-24 15:52 UTC (permalink / raw)
To: netdev; +Cc: william, f.cachereul, Ahmed Amamou, Kamel Haddadou
In-Reply-To: <1411573940-14079-1-git-send-email-ahmed@gandi.net>
in receiving function: add multicast frame processing
Signed-off-by: Ahmed Amamou <ahmed@gandi.net>
Signed-off-by: Kamel Haddadou <kamel@gandi.net>
Signed-off-by: William Dauchy <william@gandi.net>
---
net/bridge/rbridge/rbr.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 85 insertions(+)
diff --git a/net/bridge/rbridge/rbr.c b/net/bridge/rbridge/rbr.c
index 29ef0f7..9206682 100644
--- a/net/bridge/rbridge/rbr.c
+++ b/net/bridge/rbridge/rbr.c
@@ -340,6 +340,91 @@ static void rbr_recv(struct sk_buff *skb, u16 vid)
}
return;
}
+ /* Multi-destination frame:
+ * Check if received multi-destination frame from an
+ * adjacency in the distribution tree rooted at egress nick
+ * indicated in the frame header
+ */
+ dest = rbr_find_node(rbr, trh->th_egressnick);
+ if (unlikely(dest == NULL)) {
+ pr_warn_ratelimited
+ ("rbr_recv: mulicast with unknown destination\n");
+ goto recv_drop;
+ }
+ for (idx = 0; idx < dest->rbr_ni->adjcount; idx++) {
+ adjnick = RBR_NI_ADJNICK(dest->rbr_ni, idx);
+ adj = rbr_find_node(rbr, adjnick);
+ if (adj == NULL)
+ continue;
+ if (memcmp(adj->rbr_ni->adjsnpa, srcaddr, ETH_ALEN) == 0) {
+ rbr_node_put(adj);
+ break;
+ }
+ rbr_node_put(adj);
+ }
+
+ if (unlikely(idx >= dest->rbr_ni->adjcount)) {
+ pr_warn_ratelimited("rbr_recv: multicast unknow mac source\n");
+ rbr_node_put(dest);
+ goto recv_drop;
+ }
+
+ /* Reverse path forwarding check.
+ * Check if the ingress RBridge that has forwarded
+ * the frame advertised the use of the distribution tree specified
+ * in the egress nick
+ */
+ source_node = rbr_find_node(rbr, trh->th_ingressnick);
+ if (unlikely(source_node == NULL)) {
+ pr_warn_ratelimited
+ ("rbr_recv: reverse path forwarding check failed\n");
+ rbr_node_put(dest);
+ goto recv_drop;
+ }
+ for (idx = 0; idx < source_node->rbr_ni->dtrootcount; idx++) {
+ if (RBR_NI_DTROOTNICK(source_node->rbr_ni, idx) ==
+ trh->th_egressnick)
+ break;
+ }
+
+ if (idx >= source_node->rbr_ni->dtrootcount) {
+ /* Allow receipt of forwarded frame with the highest
+ * tree root RBridge as the egress RBridge when the
+ * ingress RBridge has not advertised the use of any
+ * distribution trees.
+ */
+ if (source_node->rbr_ni->dtrootcount != 0 ||
+ trh->th_egressnick != dtrNick) {
+ rbr_node_put(source_node);
+ rbr_node_put(dest);
+ goto recv_drop;
+ }
+ }
+
+ /* Check hop count before doing any forwarding */
+ if (unlikely(trill_get_hopcount(trill_flags) == 0)) {
+ pr_warn_ratelimited
+ ("rbr_recv: multicast hop count limit reached\n");
+ rbr_node_put(dest);
+ goto recv_drop;
+ }
+ /* Forward frame using the distribution tree specified by egress nick */
+ rbr_node_put(source_node);
+ rbr_node_put(dest);
+
+ /* skb2 will be multi forwarded and skb will be locally decaps */
+ if (unlikely((skb2 = skb_clone(skb, GFP_ATOMIC)) == NULL)) {
+ p->br->dev->stats.tx_dropped++;
+ pr_warn_ratelimited("rbr_recv: multicast skb_clone failed\n");
+ goto recv_drop;
+ }
+
+ /* TODO multi forwarding */
+
+ /*
+ * Send de-capsulated frame locally
+ */
+ /* TODO decapsulate function */
return;
--
1.9.1
^ 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