* [PATCH] tun: don't look at current when non-blocking
From: Michael S. Tsirkin @ 2013-10-06 18:25 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: David S. Miller, Jason Wang, Eric Dumazet, Pavel Emelyanov
We play with a wait queue even if socket is
non blocking. This is an obvious waste.
Besides, it will prevent calling the non blocking
variant when current is not valid.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
drivers/net/tun.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 807815f..7cb105c 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1293,7 +1293,8 @@ static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile,
if (unlikely(!noblock))
add_wait_queue(&tfile->wq.wait, &wait);
while (len) {
- current->state = TASK_INTERRUPTIBLE;
+ if (unlikely(!noblock))
+ current->state = TASK_INTERRUPTIBLE;
/* Read frames from the queue */
if (!(skb = skb_dequeue(&tfile->socket.sk->sk_receive_queue))) {
@@ -1320,9 +1321,10 @@ static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile,
break;
}
- current->state = TASK_RUNNING;
- if (unlikely(!noblock))
+ if (unlikely(!noblock)) {
+ current->state = TASK_RUNNING;
remove_wait_queue(&tfile->wq.wait, &wait);
+ }
return ret;
}
--
MST
^ permalink raw reply related
* [PATCH] static_key: WARN on usage before jump_label_init was called
From: Hannes Frederic Sowa @ 2013-10-06 18:29 UTC (permalink / raw)
To: Steven Rostedt, netdev, linux-kernel, Thomas Gleixner,
Ingo Molnar, H. Peter Anvin, Jason Baron, Peter Zijlstra,
Eric Dumazet, andi @ firstfloor. org David S. Miller, x86
In-Reply-To: <20131006001247.GB25076@order.stressinduktion.org>
On Sun, Oct 06, 2013 at 02:12:47AM +0200, Hannes Frederic Sowa wrote:
> On Sat, Oct 05, 2013 at 08:05:58PM -0400, Steven Rostedt wrote:
> > > if (type == JUMP_LABEL_ENABLE) {
> > > - /*
> > > - * We are enabling this jump label. If it is not a nop
> > > - * then something must have gone wrong.
> > > - */
> > > - if (unlikely(memcmp((void *)entry->code, ideal_nop, 5) != 0))
> > > - bug_at((void *)entry->code, __LINE__);
> > > + if (init) {
> > > + /*
> > > + * Jump label is enabled for the first time.
> > > + * So we expect a default_nop...
> > > + */
> > > + if (unlikely(memcmp((void *)entry->code, default_nop, 5)
> > > + != 0))
> > > + bug_at((void *)entry->code, __LINE__);
> > > + } else {
> > > + /*
> > > + * ...otherwise expect an ideal_nop. Otherwise
> > > + * something went horribly wrong.
> > > + */
> > > + if (unlikely(memcmp((void *)entry->code, ideal_nop, 5)
> > > + != 0))
> > > + bug_at((void *)entry->code, __LINE__);
> > > + }
> >
> > I don't know if I like this change. This is similar to a bug we had
> > with the Xen folks, where they didn't realize that jump labels are not
> > suppose to be used (or set) before jump_label_init() is called.
> >
> > I'll have to take a deeper look at this on Monday.
>
> Yes, I understand and saw the commit to call jump_label_init
> earlier. Maybe the default could be to insert illegal instructions by
> default if we try to replace them with nops or branches afterwards anyway.
This would not help, but maybe someting like this patch. Andi Kleen
also recently posted something similar, I cleaned it up a bit.
[PATCH] static_key: WARN on usage before jump_label_init was called
Based on a patch from Andi Kleen.
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Andi Kleen <andi@firstfloor.org>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
---
include/linux/jump_label.h | 11 +++++++++++
include/linux/jump_label_ratelimit.h | 2 ++
kernel/jump_label.c | 5 +++++
lib/Makefile | 2 +-
lib/jump_label_initialized.c | 6 ++++++
5 files changed, 25 insertions(+), 1 deletion(-)
create mode 100644 lib/jump_label_initialized.c
diff --git a/include/linux/jump_label.h b/include/linux/jump_label.h
index a507907..ed3a4bd 100644
--- a/include/linux/jump_label.h
+++ b/include/linux/jump_label.h
@@ -48,6 +48,14 @@
#include <linux/types.h>
#include <linux/compiler.h>
+#include <linux/bug.h>
+
+extern bool static_key_initialized;
+
+#define STATIC_KEY_CHECK_USE() do { \
+ WARN(!static_key_initialized, "%s used before call to jump_label_init", \
+ __func__); \
+} while (0)
#if defined(CC_HAVE_ASM_GOTO) && defined(CONFIG_JUMP_LABEL)
@@ -128,6 +136,7 @@ struct static_key {
static __always_inline void jump_label_init(void)
{
+ static_key_initialized = true;
}
static __always_inline bool static_key_false(struct static_key *key)
@@ -146,11 +155,13 @@ static __always_inline bool static_key_true(struct static_key *key)
static inline void static_key_slow_inc(struct static_key *key)
{
+ STATIC_KEY_CHECK_USE();
atomic_inc(&key->enabled);
}
static inline void static_key_slow_dec(struct static_key *key)
{
+ STATIC_KEY_CHECK_USE();
atomic_dec(&key->enabled);
}
diff --git a/include/linux/jump_label_ratelimit.h b/include/linux/jump_label_ratelimit.h
index 1137883..089f70f 100644
--- a/include/linux/jump_label_ratelimit.h
+++ b/include/linux/jump_label_ratelimit.h
@@ -23,12 +23,14 @@ struct static_key_deferred {
};
static inline void static_key_slow_dec_deferred(struct static_key_deferred *key)
{
+ STATIC_KEY_CHECK_USE();
static_key_slow_dec(&key->key);
}
static inline void
jump_label_rate_limit(struct static_key_deferred *key,
unsigned long rl)
{
+ STATIC_KEY_CHECK_USE();
}
#endif /* HAVE_JUMP_LABEL */
#endif /* _LINUX_JUMP_LABEL_RATELIMIT_H */
diff --git a/kernel/jump_label.c b/kernel/jump_label.c
index 297a924..9019f15 100644
--- a/kernel/jump_label.c
+++ b/kernel/jump_label.c
@@ -58,6 +58,7 @@ static void jump_label_update(struct static_key *key, int enable);
void static_key_slow_inc(struct static_key *key)
{
+ STATIC_KEY_CHECK_USE();
if (atomic_inc_not_zero(&key->enabled))
return;
@@ -103,12 +104,14 @@ static void jump_label_update_timeout(struct work_struct *work)
void static_key_slow_dec(struct static_key *key)
{
+ STATIC_KEY_CHECK_USE();
__static_key_slow_dec(key, 0, NULL);
}
EXPORT_SYMBOL_GPL(static_key_slow_dec);
void static_key_slow_dec_deferred(struct static_key_deferred *key)
{
+ STATIC_KEY_CHECK_USE();
__static_key_slow_dec(&key->key, key->timeout, &key->work);
}
EXPORT_SYMBOL_GPL(static_key_slow_dec_deferred);
@@ -116,6 +119,7 @@ EXPORT_SYMBOL_GPL(static_key_slow_dec_deferred);
void jump_label_rate_limit(struct static_key_deferred *key,
unsigned long rl)
{
+ STATIC_KEY_CHECK_USE();
key->timeout = rl;
INIT_DELAYED_WORK(&key->work, jump_label_update_timeout);
}
@@ -212,6 +216,7 @@ void __init jump_label_init(void)
key->next = NULL;
#endif
}
+ static_key_initialized = true;
jump_label_unlock();
}
diff --git a/lib/Makefile b/lib/Makefile
index f3bb2cb..7f48ddc 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -26,7 +26,7 @@ obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \
bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \
gcd.o lcm.o list_sort.o uuid.o flex_array.o iovec.o clz_ctz.o \
bsearch.o find_last_bit.o find_next_bit.o llist.o memweight.o kfifo.o \
- percpu_ida.o
+ percpu_ida.o jump_label_initialized.o
obj-y += string_helpers.o
obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o
obj-y += kstrtox.o
diff --git a/lib/jump_label_initialized.c b/lib/jump_label_initialized.c
new file mode 100644
index 0000000..a668a40
--- /dev/null
+++ b/lib/jump_label_initialized.c
@@ -0,0 +1,6 @@
+#include <linux/types.h>
+#include <linux/cache.h>
+
+bool static_key_initialized __read_mostly = false;
+EXPORT_SYMBOL_GPL(static_key_initialized);
+
--
1.8.3.1
^ permalink raw reply related
* CONTACT FEDEX EXPRESS COURIER SERVICE FOR YOUR PACKAGE
From: 019 @ 2013-10-06 18:52 UTC (permalink / raw)
To: Recipients
Dear Friend,
I cashed your shell oil company's compensation check of $1.5Million USD which has been with me for a very long time to avoid expiration,contact fedex Courier service with the below info for your fund consignment delivery,Note that security and insurance fees has been paid,all you will pay them is their delivery fees 150 USD only,
Director:Dr.Dennis Meijs,
E-mail ( fedexcourierserviii@yahoo.fr )
Tel: +9178-3835-5947
Please make sure you send this needed info to the Director Dr.Dennis Meijs
with the E-mail given to you to avoid wrong delivery of your consignment
Full Name.....................
Country...............
Home address.................
Home & Mobile phone numbers......
Your picture..........
Call Dr Dennis Meijs on phone Tel:+9178-3835-5947 as soon as you send email to him because your call would facilitate the immediate attention to you due to his tight delivery schedule.
I waiting for your urgent response
Remain blessed
Best Regards.
Barrister.Don Philip
^ permalink raw reply
* Re: [PATCH] Fix the upper MTU limit in ipv6 GRE tunnel
From: Oussama Ghorbel @ 2013-10-06 19:18 UTC (permalink / raw)
To: Oussama Ghorbel, David S. Miller, Alexey Kuznetsov, James Morris,
Hideaki YOSHIFUJI, Patrick McHardy, netdev, linux-kernel
In-Reply-To: <20131006161910.GC9295@order.stressinduktion.org>
Yes, to summarize, the idea of this patch was to fix the incoherence
in the condition of ip6gre_tunnel_change_mtu function
if (new_mtu < 68 ||
new_mtu > 0xFFF8 - dev->hard_header_len - tunnel->hlen)
>From the ip6gre_tnl_link_config function we can see that:
The variable addend is equal the ipv6 header + gre header (including
the gre options)
On the other hand hard_header_len equal to the header of the lower
layer + addend.
So the quantity - (dev->hard_header_len + tunnel->hlen) equals - (eth
header + ipv6 header + gre header + ipv6 header + gre header) which by
no means this would represent anything! (I've just taken ipv6 over
ethernet as example)
As we have seen there is another approach to fix this issue is to
re-factor the hlen to hold only the length of gre as it's done for
ipv4 gre, however the solution provided in the patch seems to be
regression risk-less.
Although the value hold by hlen is not coherent with the variable name
nor with ipv4, I think there is an advantage of the current approach
of ipv6 hlen over ipv4 hlen, because we save the calculation of ipv6
header each time. Ex:
In ipv4 gre and in the function ipgre_header:
iph = (struct iphdr *)skb_push(skb, t->hlen + sizeof(*iph));
In ipv6 and in the function ip6gre_header
ipv6h = (struct ipv6hdr *)skb_push(skb, t->hlen);
Thanks,
Oussama
On Sun, Oct 6, 2013 at 5:19 PM, Hannes Frederic Sowa
<hannes@stressinduktion.org> wrote:
> On Sun, Oct 06, 2013 at 04:36:56PM +0100, Oussama Ghorbel wrote:
>> On Sun, Oct 6, 2013 at 4:13 PM, Hannes Frederic Sowa
>> <hannes@stressinduktion.org> wrote:
>> > On Sun, Oct 06, 2013 at 03:42:15PM +0100, Oussama Ghorbel wrote:
>> >> The initialization in ip6gre_tnl_link_config is done as the following:
>> >> static void ip6gre_tnl_link_config(struct ip6_tnl *t, int set_mtu)
>> >> {
>> >> ...
>> >> int addend = sizeof(struct ipv6hdr) + 4;
>> >> ...
>> >> /* Precalculate GRE options length */
>> >> if (t->parms.o_flags&(GRE_CSUM|GRE_KEY|GRE_SEQ)) {
>> >> if (t->parms.o_flags&GRE_CSUM)
>> >> addend += 4;
>> >> if (t->parms.o_flags&GRE_KEY)
>> >> addend += 4;
>> >> if (t->parms.o_flags&GRE_SEQ)
>> >> addend += 4;
>> >> }
>> >> ...
>> >> dev->hard_header_len = rt->dst.dev->hard_header_len + addend;
>> >> ...
>> >> t->hlen = addend;
>> >> ..
>> >> }
>> >>
>> >> Unless they are other reasons, the hard_header_len is taken into
>> >> account the GRE_KEY, GRE_SEQ ..
>> >
>> > But only if a new route is found. The hard_header_len reinitialization is
>> > guarded by a (rt == NULL). We may have not found one on boot up.
>> >
>> In that case the function will make a return and hlen will be zero.
>> Subtracting hlen in ip6gre_tunnel_change_mtu has no effect ...
>
> Oh yes, somehow I missed that.
>
> We depend on t->hlen when pushing the gre header onto the skb. t->hlen == 0
> should never be the case because we assume t->hlen > sizeof(struct ipv6_hdr).
>
^ permalink raw reply
* VERY URGENT..!
From: Mr. M. Barlow @ 2013-10-06 20:30 UTC (permalink / raw)
To: Recipients
Hello, I am Mr. M. Barlow from Paris, France. I have been advised to contact you regarding my business investment in your country. For urgent response and more details, kindly get back to me via this E-mail: bc82022@gmail.com or Telephone number below. Thank you as I wait for your response.
Mr. M. Barlow.
+33-753-194-496
Sent from Orange Wireless BlackBerry Smartphone, France.
^ permalink raw reply
* Re: [PATCH 0/4] connector fixes
From: Рустафа Джамурахметов @ 2013-10-06 20:46 UTC (permalink / raw)
To: David Miller, minipli@googlemail.com; +Cc: netdev@vger.kernel.org
In-Reply-To: <20131002.160430.1701387005902696709.davem@davemloft.net>
03.10.2013, 00:04, "David Miller" <davem@davemloft.net>:
> From: Mathias Krause <minipli@googlemail.com>
> Date: Mon, 30 Sep 2013 22:03:05 +0200
>
>> This series fixes a few netlink related issues of the connector interface.
>>
>> The first two patches are bug fixes. The last two are cleanups.
>>
>> Please apply!
>
> Series applied and first two patches queued up for -stable, thanks.
Thank you.
^ permalink raw reply
* [PATCH] net: af802154: Fix wrong structure declaration
From: Guenter Roeck @ 2013-10-06 21:44 UTC (permalink / raw)
To: Alexander Smirnov, Dmitry Eremin-Solenikov
Cc: David S. Miller, netdev, linux-zigbee-devel, Guenter Roeck
net_devce doesn't exist.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
net/ieee802154/af802154.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/ieee802154/af802154.h b/net/ieee802154/af802154.h
index b1ec525..62f5f63 100644
--- a/net/ieee802154/af802154.h
+++ b/net/ieee802154/af802154.h
@@ -25,7 +25,7 @@
#define AF802154_H
struct sk_buff;
-struct net_devce;
+struct net_device;
extern struct proto ieee802154_raw_prot;
extern struct proto ieee802154_dgram_prot;
void ieee802154_raw_deliver(struct net_device *dev, struct sk_buff *skb);
--
1.7.9.7
^ permalink raw reply related
* Re: [PATCH] net: af802154: Fix wrong structure declaration
From: Joe Perches @ 2013-10-06 22:20 UTC (permalink / raw)
To: Guenter Roeck
Cc: Dmitry, netdev-u79uwXL29TY76Z2rM5mHXA,
linux-zigbee-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
David S. Miller
In-Reply-To: <1381095841-15031-1-git-send-email-linux-0h96xk9xTtrk1uMJSBkQmQ@public.gmane.org>
On Sun, 2013-10-06 at 14:44 -0700, Guenter Roeck wrote:
> net_devce doesn't exist.
[]
> diff --git a/net/ieee802154/af802154.h b/net/ieee802154/af802154.h
[]
> @@ -25,7 +25,7 @@
> #define AF802154_H
>
> struct sk_buff;
> -struct net_devce;
> +struct net_device;
That argues more for deletion than correction.
------------------------------------------------------------------------------
October Webinars: Code for Performance
Free Intel webinars can help you accelerate application performance.
Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from
the latest Intel processors and coprocessors. See abstracts and register >
http://pubads.g.doubleclick.net/gampad/clk?id=60134791&iu=/4140/ostg.clktrk
^ permalink raw reply
* Re: [PATCH] net: af802154: Fix wrong structure declaration
From: Guenter Roeck @ 2013-10-06 23:18 UTC (permalink / raw)
To: Joe Perches
Cc: Alexander Smirnov, Dmitry Eremin-Solenikov, David S. Miller,
netdev, linux-zigbee-devel
In-Reply-To: <1381098047.2081.169.camel@joe-AO722>
On 10/06/2013 03:20 PM, Joe Perches wrote:
> On Sun, 2013-10-06 at 14:44 -0700, Guenter Roeck wrote:
>> net_devce doesn't exist.
> []
>> diff --git a/net/ieee802154/af802154.h b/net/ieee802154/af802154.h
> []
>> @@ -25,7 +25,7 @@
>> #define AF802154_H
>>
>> struct sk_buff;
>> -struct net_devce;
>> +struct net_device;
>
> That argues more for deletion than correction.
>
I thought the idea was to ensure that every structure is declared.
In this case it appears that the structure happens to be declared
in other include files, so we are lucky. On the other side, if so,
"struct proto", "struct net" and "struct ieee802154_addr" should
probably be declared as well ...
Ultimately, I don't really care one way or another. I just happened
to stumble over it. Fine with me to remove it. Maybe the maintainers
should decide what if anything to do.
Guenter
^ permalink raw reply
* Re: [PATCH net-next] xen-netback: fix xenvif_count_skb_slots()
From: Matt Wilson @ 2013-10-07 0:06 UTC (permalink / raw)
To: Paul Durrant
Cc: xen-devel, netdev, Xi Xiong, Matt Wilson, Annie Li, Wei Liu,
Ian Campbell, Simon Graham
In-Reply-To: <1380903983-27429-1-git-send-email-paul.durrant@citrix.com>
On Fri, Oct 04, 2013 at 05:26:23PM +0100, Paul Durrant wrote:
> Commit 4f0581d25827d5e864bcf07b05d73d0d12a20a5c introduced an error into
> xenvif_count_skb_slots() for skbs with a linear area spanning a page
> boundary. The alignment of skb->data needs to be taken into account, not
> just the head length. This patch fixes the issue by dry-running the code
> from xenvif_gop_skb() (and adjusting the comment above the function to note
> that).
>
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> Cc: Xi Xiong <xixiong@amazon.com>
> Cc: Matt Wilson <msw@amazon.com>
> Cc: Annie Li <annie.li@oracle.com>
> Cc: Wei Liu <wei.liu2@citrix.com>
> Cc: Ian Campbell <Ian.Campbell@citrix.com>
Paul, can you reconcile this change with the one made by Simon in cs
8f985b4f7a5394c8f8725a5109451a541ddb9eea?
--msw
> ---
> drivers/net/xen-netback/netback.c | 17 +++++++++++++++--
> 1 file changed, 15 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
> index d0b0feb..6f680f4 100644
> --- a/drivers/net/xen-netback/netback.c
> +++ b/drivers/net/xen-netback/netback.c
> @@ -223,15 +223,28 @@ static bool start_new_rx_buffer(int offset, unsigned long size, int head)
> /*
> * Figure out how many ring slots we're going to need to send @skb to
> * the guest. This function is essentially a dry run of
> - * xenvif_gop_frag_copy.
> + * xenvif_gop_skb.
> */
> unsigned int xenvif_count_skb_slots(struct xenvif *vif, struct sk_buff *skb)
> {
> + unsigned char *data;
> unsigned int count;
> int i, copy_off;
> struct skb_cb_overlay *sco;
>
> - count = DIV_ROUND_UP(skb_headlen(skb), PAGE_SIZE);
> + count = 0;
> +
> + data = skb->data;
> + while (data < skb_tail_pointer(skb)) {
> + unsigned int offset = offset_in_page(data);
> + unsigned int len = PAGE_SIZE - offset;
> +
> + if (data + len > skb_tail_pointer(skb))
> + len = skb_tail_pointer(skb) - data;
> +
> + count++;
> + data += len;
> + }
>
> copy_off = skb_headlen(skb) % PAGE_SIZE;
>
^ permalink raw reply
* Re: [PATCH net-next] xen-netback: fix xenvif_count_skb_slots()
From: Matt Wilson @ 2013-10-07 0:07 UTC (permalink / raw)
To: Paul Durrant
Cc: xen-devel, netdev, Xi Xiong, Matt Wilson, Annie Li, Wei Liu,
Ian Campbell, Simon Graham
In-Reply-To: <20131007000652.GA5970@u109add4315675089e695.ant.amazon.com>
On Sun, Oct 06, 2013 at 05:06:52PM -0700, Matt Wilson wrote:
> On Fri, Oct 04, 2013 at 05:26:23PM +0100, Paul Durrant wrote:
> > Commit 4f0581d25827d5e864bcf07b05d73d0d12a20a5c introduced an error into
> > xenvif_count_skb_slots() for skbs with a linear area spanning a page
> > boundary. The alignment of skb->data needs to be taken into account, not
> > just the head length. This patch fixes the issue by dry-running the code
> > from xenvif_gop_skb() (and adjusting the comment above the function to note
> > that).
> >
> > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > Cc: Xi Xiong <xixiong@amazon.com>
> > Cc: Matt Wilson <msw@amazon.com>
> > Cc: Annie Li <annie.li@oracle.com>
> > Cc: Wei Liu <wei.liu2@citrix.com>
> > Cc: Ian Campbell <Ian.Campbell@citrix.com>
>
> Paul, can you reconcile this change with the one made by Simon in cs
> 8f985b4f7a5394c8f8725a5109451a541ddb9eea?
Correction: e26b203ede31fffd52571a5ba607a26c79dc5c0d
> --msw
>
> > ---
> > drivers/net/xen-netback/netback.c | 17 +++++++++++++++--
> > 1 file changed, 15 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
> > index d0b0feb..6f680f4 100644
> > --- a/drivers/net/xen-netback/netback.c
> > +++ b/drivers/net/xen-netback/netback.c
> > @@ -223,15 +223,28 @@ static bool start_new_rx_buffer(int offset, unsigned long size, int head)
> > /*
> > * Figure out how many ring slots we're going to need to send @skb to
> > * the guest. This function is essentially a dry run of
> > - * xenvif_gop_frag_copy.
> > + * xenvif_gop_skb.
> > */
> > unsigned int xenvif_count_skb_slots(struct xenvif *vif, struct sk_buff *skb)
> > {
> > + unsigned char *data;
> > unsigned int count;
> > int i, copy_off;
> > struct skb_cb_overlay *sco;
> >
> > - count = DIV_ROUND_UP(skb_headlen(skb), PAGE_SIZE);
> > + count = 0;
> > +
> > + data = skb->data;
> > + while (data < skb_tail_pointer(skb)) {
> > + unsigned int offset = offset_in_page(data);
> > + unsigned int len = PAGE_SIZE - offset;
> > +
> > + if (data + len > skb_tail_pointer(skb))
> > + len = skb_tail_pointer(skb) - data;
> > +
> > + count++;
> > + data += len;
> > + }
> >
> > copy_off = skb_headlen(skb) % PAGE_SIZE;
> >
^ permalink raw reply
* Re: IPv6 path MTU discovery broken
From: Hannes Frederic Sowa @ 2013-10-07 1:52 UTC (permalink / raw)
To: Steinar H. Gunderson; +Cc: netdev, edumazet, fan.du
In-Reply-To: <20131006120612.GA27852@sesse.net>
On Sun, Oct 06, 2013 at 02:06:12PM +0200, Steinar H. Gunderson wrote:
> On Sat, Sep 28, 2013 at 10:33:18PM +0200, Hannes Frederic Sowa wrote:
> >> So the “packet too big” packets really look like they're being ignored.
> >> However, they _do_ reach the kernel somehow, since Icmp6InPktTooBigs
> >> seems to increase.
> >>
> >> Could this be related somehow to the packets coming from 2001:67c:29f4::31,
> >> while the default route is to a link-local address? (An RPF issue?) This used
> >> to work (although it was often flaky for me) in 3.10 and before. I can't
> >> easily bisect, though, as I don't boot this machine too often.
> > This looks like a bug and should definitely get fixed. There should be
> > no RPF issue. May I have a look at your /proc/net/ipv6_route?
>
> It started again, so now I could capture what you asked for:
>
> pannekake:~> cat /proc/net/ipv6_route
> 2001067c00a400037c4d9ae8ab73230f 80 00000000000000000000000000000000 00 fe80000000000000023048fffe555743 00000000 00000001 00000137 01000023 eth0
This one does look like the most probable route which could have the problem.
It has a RTF_MODIFIED flag indicating it received a pmtu update.
Did you take the snapshot while the tcp connection was hanging? We normally
take 2 references to the rt6_info while the tcp connection is running, this
oddly only has one (but got used a lot). But doing a judgement on the
reference count is imprecise.
If you write that this got worse in recent kernels I suspect commit
commit ca4c3fc24e293719fe7410c4e63da9b6bc633b83
Author: fan.du <fan.du@windriver.com>
Date: Tue Jul 30 08:33:53 2013 +0800
net: split rt_genid for ipv4 and ipv6
The commit itself is fine, we may have a problem in our dst check logic
or do not bump rt6_genid at some point? If this is the case I might have
an idea how to reproduce the problem.
Greetings,
Hannes
^ permalink raw reply
* Re: [PATCH] Fix the upper MTU limit in ipv6 GRE tunnel
From: Hannes Frederic Sowa @ 2013-10-07 2:02 UTC (permalink / raw)
To: Oussama Ghorbel
Cc: David S. Miller, Alexey Kuznetsov, James Morris,
Hideaki YOSHIFUJI, Patrick McHardy, netdev, linux-kernel
In-Reply-To: <CABfLueGW34XnTEJWsb5FA=pWfwwKqTTj31xCZyr78CNtTZWx6Q@mail.gmail.com>
On Sun, Oct 06, 2013 at 08:18:15PM +0100, Oussama Ghorbel wrote:
> Yes, to summarize, the idea of this patch was to fix the incoherence
> in the condition of ip6gre_tunnel_change_mtu function
>
> if (new_mtu < 68 ||
> new_mtu > 0xFFF8 - dev->hard_header_len - tunnel->hlen)
>
> From the ip6gre_tnl_link_config function we can see that:
> The variable addend is equal the ipv6 header + gre header (including
> the gre options)
> On the other hand hard_header_len equal to the header of the lower
> layer + addend.
> So the quantity - (dev->hard_header_len + tunnel->hlen) equals - (eth
> header + ipv6 header + gre header + ipv6 header + gre header) which by
> no means this would represent anything! (I've just taken ipv6 over
> ethernet as example)
>
> As we have seen there is another approach to fix this issue is to
> re-factor the hlen to hold only the length of gre as it's done for
> ipv4 gre, however the solution provided in the patch seems to be
> regression risk-less.
I agree, it actually does not worsen the situation:
Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
> Although the value hold by hlen is not coherent with the variable name
> nor with ipv4, I think there is an advantage of the current approach
> of ipv6 hlen over ipv4 hlen, because we save the calculation of ipv6
> header each time. Ex:
> In ipv4 gre and in the function ipgre_header:
> iph = (struct iphdr *)skb_push(skb, t->hlen + sizeof(*iph));
> In ipv6 and in the function ip6gre_header
> ipv6h = (struct ipv6hdr *)skb_push(skb, t->hlen);
I see your point. But we should take care that t->hlen is always initialized,
regardless if we got a route and outgoing device or not.
Greetings,
Hannes
^ permalink raw reply
* Re: [PATCH nf-next] netfilter: xtables: lightweight process control group matching
From: Gao feng @ 2013-10-07 3:07 UTC (permalink / raw)
To: Daniel Borkmann; +Cc: pablo, netfilter-devel, netdev, Tejun Heo, cgroups
In-Reply-To: <1380910855-12325-1-git-send-email-dborkman@redhat.com>
On 10/05/2013 02:20 AM, Daniel Borkmann wrote:
> +static void cgroup_attach(struct cgroup_subsys_state *css,
> + struct cgroup_taskset *tset)
> +{
> + struct task_struct *p;
> + void *v;
> +
> + cgroup_taskset_for_each(p, css, tset) {
> + task_lock(p);
> + v = (void *)(unsigned long) task_fwid(p);
Shouldn't v be css_nf_state(css)->fwid?
> + iterate_fd(p->files, 0, cgroup_fwid_update, v);
> + task_unlock(p);
> + }
> +}
^ permalink raw reply
* Re: IPv6 path MTU discovery broken
From: Hannes Frederic Sowa @ 2013-10-07 3:09 UTC (permalink / raw)
To: Steinar H. Gunderson, netdev, edumazet, fan.du
In-Reply-To: <20131007015252.GE9295@order.stressinduktion.org>
On Mon, Oct 07, 2013 at 03:52:52AM +0200, Hannes Frederic Sowa wrote:
> On Sun, Oct 06, 2013 at 02:06:12PM +0200, Steinar H. Gunderson wrote:
> > On Sat, Sep 28, 2013 at 10:33:18PM +0200, Hannes Frederic Sowa wrote:
> > >> So the “packet too big” packets really look like they're being ignored.
> > >> However, they _do_ reach the kernel somehow, since Icmp6InPktTooBigs
> > >> seems to increase.
> > >>
> > >> Could this be related somehow to the packets coming from 2001:67c:29f4::31,
> > >> while the default route is to a link-local address? (An RPF issue?) This used
> > >> to work (although it was often flaky for me) in 3.10 and before. I can't
> > >> easily bisect, though, as I don't boot this machine too often.
> > > This looks like a bug and should definitely get fixed. There should be
> > > no RPF issue. May I have a look at your /proc/net/ipv6_route?
> >
> > It started again, so now I could capture what you asked for:
> >
> > pannekake:~> cat /proc/net/ipv6_route
> > 2001067c00a400037c4d9ae8ab73230f 80 00000000000000000000000000000000 00 fe80000000000000023048fffe555743 00000000 00000001 00000137 01000023 eth0
>
> This one does look like the most probable route which could have the problem.
> It has a RTF_MODIFIED flag indicating it received a pmtu update.
>
> Did you take the snapshot while the tcp connection was hanging? We normally
> take 2 references to the rt6_info while the tcp connection is running, this
> oddly only has one (but got used a lot). But doing a judgement on the
> reference count is imprecise.
>
> If you write that this got worse in recent kernels I suspect commit
>
> commit ca4c3fc24e293719fe7410c4e63da9b6bc633b83
> Author: fan.du <fan.du@windriver.com>
> Date: Tue Jul 30 08:33:53 2013 +0800
>
> net: split rt_genid for ipv4 and ipv6
>
Hm, this actually went in in 3.12, so a bit too late for things to start
failing in 3.11.
> The commit itself is fine, we may have a problem in our dst check logic
> or do not bump rt6_genid at some point? If this is the case I might have
> an idea how to reproduce the problem.
Seems fine.
Could you try to check (with e.g. nstat) if any of the following counters
change if the icmp messages hit the host?
TcpExtOutOfWindowIcmps
Icmp6InErrors
TcpExtTCPMinTTLDrop
TcpExtListenDrops
Thanks,
Hannes
^ permalink raw reply
* Re: [PATCH v2.42 2/5] ofp-actions: Add separate OpenFlow 1.3 action parser
From: Simon Horman @ 2013-10-07 6:25 UTC (permalink / raw)
To: Ben Pfaff
Cc: dev, netdev, Jesse Gross, Pravin B Shelar, Ravi K, Isaku Yamahata,
Joe Stringer
In-Reply-To: <20131004163105.GH29572@nicira.com>
On Fri, Oct 04, 2013 at 09:31:05AM -0700, Ben Pfaff wrote:
> On Fri, Oct 04, 2013 at 05:09:57PM +0900, Simon Horman wrote:
> > From: Joe Stringer <joe@wand.net.nz>
> >
> > This patch adds new ofpact_from_openflow13() and
> > ofpacts_from_openflow13() functions parallel to the existing ofpact
> > handling code. In the OpenFlow 1.3 version, push_mpls is handled
> > differently, but all other actions are handled by the existing code.
> >
> > In the case of push_mpls for OpenFlow 1.3 the new mpls_before_vlan field of
> > struct ofpact_push_mpls is set to true. This will be used by a subsequent
> > patch to allow allow the correct VLAN+MPLS datapath behaviour to be
> > determined at odp translation time.
> >
> > Signed-off-by: Joe Stringer <joe@wand.net.nz>
> > Signed-off-by: Simon Horman <horms@verge.net.au>
>
> The need for a huge comment on mpls_before_vlan suggests to me that
> breaking it out as a separate type would be helpful. How about this:
>
> /* The position in the packet at which to insert an MPLS header.
> *
> * Used NXAST_PUSH_MPLS, OFPAT11_PUSH_MPLS. */
> enum ofpact_mpls_position {
> /* Add the MPLS LSE after the Ethernet header but before any VLAN tags.
> * OpenFlow 1.3+ requires this behavior. */
> OFPACT_MPLS_BEFORE_VLAN,
>
> /* Add the MPLS LSE after the Ethernet header and any VLAN tags.
> * OpenFlow 1.1 and 1.2 require this behavior. */
> OFPACT_MPLS_AFTER_VLAN
> };
>
> /* OFPACT_PUSH_VLAN/MPLS/PBB
> *
> * Used for NXAST_PUSH_MPLS, OFPAT11_PUSH_MPLS. */
> struct ofpact_push_mpls {
> struct ofpact ofpact;
> ovs_be16 ethertype;
> enum ofpact_mpls_position position;
> };
Hi Ben,
thanks, that looks very nice.
I will incorporate it in the next revision of the patchset.
^ permalink raw reply
* Re: [PATCH v2.42 1/5] odp: Allow VLAN actions after MPLS actions
From: Simon Horman @ 2013-10-07 6:34 UTC (permalink / raw)
To: Ben Pfaff
Cc: dev, netdev, Jesse Gross, Pravin B Shelar, Ravi K, Isaku Yamahata,
Joe Stringer
In-Reply-To: <20131004162133.GG29572@nicira.com>
On Fri, Oct 04, 2013 at 09:21:33AM -0700, Ben Pfaff wrote:
> On Fri, Oct 04, 2013 at 05:09:56PM +0900, Simon Horman wrote:
> > From: Joe Stringer <joe@wand.net.nz>
> >
> > OpenFlow 1.1 and 1.2, and 1.3 differ in their handling of MPLS actions in the
> > presence of VLAN tags. To allow correct behaviour to be committed in
> > each situation, this patch adds a second round of VLAN tag action
> > handling to commit_odp_actions(), which occurs after MPLS actions. This
> > is implemented with a new field in 'struct xlate_in' called 'vlan_tci'.
> >
> > When an push_mpls action is composed, the flow's current VLAN state is
> > stored into xin->vlan_tci, and flow->vlan_tci is set to 0 (pop_vlan). If
> > a VLAN tag is present, it is stripped; if not, then there is no change.
> > Any later modifications to the VLAN state is written to xin->vlan_tci.
> > When committing the actions, flow->vlan_tci is used before MPLS actions,
> > and xin->vlan_tci is used afterwards. This retains the current datapath
> > behaviour, but allows VLAN actions to be applied in a more flexible
> > manner.
> >
> > Both before and after this patch MPLS LSEs are pushed onto a packet after
> > any VLAN tags that may be present. This is the behaviour described in
> > OpenFlow 1.1 and 1.2. OpenFlow 1.3 specifies that MPLS LSEs should be
> > pushed onto a packet before any VLAN tags that are present. Support
> > for this will be added by a subsequent patch that makes use of
> > the infrastructure added by this patch.
> >
> > Signed-off-by: Joe Stringer <joe@wand.net.nz>
> > Signed-off-by: Simon Horman <horms@verge.net.au>
>
> I noticed a couple more minor points.
>
> First, it seems to me that the "vlan_tci" member that this adds to
> xlate_in could go in xlate_ctx just as well. I would prefer that,
> because (as far as I can tell) there is no reason for the client to use
> any value other than flow->vlan_tci here, and putting it in xlate_ctx
> hides it from the client.
Thanks. Yes I agree that is a good idea.
> Thanks for rearranging the code and updating the comment in
> do_xlate_actions(). It makes the operation clearer. But now that it's
> clear I have an additional question. Does it really make sense to have
> 'vlan_tci' as only a local variable in do_xlate_actions()? Presumably,
> MPLS and VLANs should interact the same way regardless of whether they
> are separated by resubmits or goto_tables. That is, I suspect that this
> is xlate_ctx state, not local state.
Agreed.
What I have done is to make an incremental patch which:
1. Moves the 'vlan_tci' member of strict xlate_in to
be the 'final_vlan_tci' member of struct xlate_ctx.
2. Moves the 'vlan_tci' local variable of do_xlate_actions()
to be the 'next_vlan_tci' member of struct xlate_ctx.
3. Restructures the comments surrounding the logic of the vlan_tci
code that this patch adds mostly as comments for the new
members of struct xlate_ctx. I hope things are (still?) clear.
For reference, the incremental patch I have so far is as follows.
I will squash it into this patch before reposting this series.
commit d57735cec0d3e53c7479725ae1cf825563902c30
Author: Simon Horman <horms@verge.net.au>
Date: Mon Oct 7 14:30:28 2013 +0900
Move vlan state into struct xlate_ctx
1. Add final_vlan_tci member to struct xlate_ctx instead of vlan_tci member
struct xlate_xin. This seems to be a better palace for it as it does
not need to be accessible from the caller.
2. Move local vlan_tci variable of do_xlate_actions() to be the
next_vlan_tci member of strict xlate_ctx. This allows for it to work
across resubmit actions and goto table instructions.
As suggested by Ben Pfaff
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index 2afd760..845c6fe 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -172,6 +172,37 @@ struct xlate_ctx {
odp_port_t sflow_odp_port; /* Output port for composing sFlow action. */
uint16_t user_cookie_offset;/* Used for user_action_cookie fixup. */
bool exit; /* No further actions should be processed. */
+
+ /* The final vlan_tci state.
+ *
+ * The value of the vlan TCI prior to the committing of ODP MPLS
+ * actions should be stored in 'xin->flow->vlan_tci'.
+ *
+ * The final value of the VLAN TCI should be stored in 'vlan_tci'. And
+ * is if the value of 'vlan_tci' and 'xin->flow->vlan_tci' differ then
+ * VLAN ODP actions will be committed after any MPLS actions regardless
+ * of whether VLAN actions were also committed before the MPLS actions or
+ * not.
+ *
+ * This mechanism allows a VLAN tag to be popped before pushing
+ * an MPLS LSE and then the same VLAN tag pushed after pushing
+ * the MPLS LSE. In this way it is possible to push an MPLS LSE
+ * before an existing VLAN tag. Moreover this mechanism allows
+ * the order in which VLAN tags and MPLS LSEs are pushed. */
+ ovs_be16 final_vlan_tci;
+
+ /* The next vlan_tci state.
+ *
+ * This value this variable points to updated each time an
+ * action updates the VLAN tci.
+ *
+ * This variable initially points to 'xin->flow->vlan_tci' so that ODP
+ * VLAN actions are committed before any MPLS actions. When an MPLS
+ * action is composed 'next_vlan_tci' is updated to point to
+ * 'final_vlan_tci'. This causes subsequent VLAN actions to be
+ * committed after MPLS actions. */
+ ovs_be16 *next_vlan_tci;
+
};
/* A controller may use OFPP_NONE as the ingress port to indicate that
@@ -982,7 +1013,7 @@ static void
output_normal(struct xlate_ctx *ctx, const struct xbundle *out_xbundle,
uint16_t vlan)
{
- ovs_be16 *flow_tci = &ctx->xin->vlan_tci;
+ ovs_be16 *flow_tci = &ctx->final_vlan_tci;
uint16_t vid;
ovs_be16 tci, old_tci;
struct xport *xport;
@@ -1258,7 +1289,7 @@ xlate_normal(struct xlate_ctx *ctx)
/* Drop malformed frames. */
if (flow->dl_type == htons(ETH_TYPE_VLAN) &&
- !(ctx->xin->vlan_tci & htons(VLAN_CFI))) {
+ !(ctx->final_vlan_tci & htons(VLAN_CFI))) {
if (ctx->xin->packet != NULL) {
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
VLOG_WARN_RL(&rl, "bridge %s: dropping packet with partial "
@@ -1282,7 +1313,7 @@ xlate_normal(struct xlate_ctx *ctx)
}
/* Check VLAN. */
- vid = vlan_tci_to_vid(ctx->xin->vlan_tci);
+ vid = vlan_tci_to_vid(ctx->final_vlan_tci);
if (!input_vid_is_valid(vid, in_xbundle, ctx->xin->packet != NULL)) {
xlate_report(ctx, "disallowed VLAN VID for this input port, dropping");
return;
@@ -1540,7 +1571,7 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port,
const struct xport *xport = get_ofp_port(ctx->xbridge, ofp_port);
struct flow_wildcards *wc = &ctx->xout->wc;
struct flow *flow = &ctx->xin->flow;
- ovs_be16 flow_vlan_tci, xin_vlan_tci;
+ ovs_be16 flow_vlan_tci, vlan_tci;
uint32_t flow_pkt_mark;
uint8_t flow_nw_tos;
odp_port_t out_port, odp_port;
@@ -1609,7 +1640,7 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port,
}
flow_vlan_tci = flow->vlan_tci;
- xin_vlan_tci = ctx->xin->vlan_tci;
+ vlan_tci = ctx->final_vlan_tci;
flow_pkt_mark = flow->pkt_mark;
flow_nw_tos = flow->nw_tos;
@@ -1649,20 +1680,20 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port,
wc->masks.vlan_tci |= htons(VLAN_VID_MASK | VLAN_CFI);
}
vlandev_port = vsp_realdev_to_vlandev(ctx->xbridge->ofproto, ofp_port,
- ctx->xin->vlan_tci);
+ ctx->final_vlan_tci);
if (vlandev_port == ofp_port) {
out_port = odp_port;
} else {
out_port = ofp_port_to_odp_port(ctx->xbridge, vlandev_port);
flow->vlan_tci = htons(0);
- ctx->xin->vlan_tci = htons(0);
+ ctx->final_vlan_tci = htons(0);
}
}
if (out_port != ODPP_NONE) {
commit_odp_actions(flow, &ctx->base_flow,
&ctx->xout->odp_actions, &ctx->xout->wc,
- &ctx->mpls_depth_delta, ctx->xin->vlan_tci);
+ &ctx->mpls_depth_delta, ctx->final_vlan_tci);
nl_msg_put_odp_port(&ctx->xout->odp_actions, OVS_ACTION_ATTR_OUTPUT,
out_port);
@@ -1674,7 +1705,7 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port,
out:
/* Restore flow */
flow->vlan_tci = flow_vlan_tci;
- ctx->xin->vlan_tci = xin_vlan_tci;
+ ctx->final_vlan_tci = vlan_tci;
flow->pkt_mark = flow_pkt_mark;
flow->nw_tos = flow_nw_tos;
}
@@ -1819,7 +1850,7 @@ execute_controller_action(struct xlate_ctx *ctx, int len,
commit_odp_actions(&ctx->xin->flow, &ctx->base_flow,
&ctx->xout->odp_actions, &ctx->xout->wc,
- &ctx->mpls_depth_delta, ctx->xin->vlan_tci);
+ &ctx->mpls_depth_delta, ctx->final_vlan_tci);
odp_execute_actions(NULL, packet, &key, ctx->xout->odp_actions.data,
ctx->xout->odp_actions.size, NULL, NULL);
@@ -2207,7 +2238,7 @@ xlate_sample_action(struct xlate_ctx *ctx,
commit_odp_actions(&ctx->xin->flow, &ctx->base_flow,
&ctx->xout->odp_actions, &ctx->xout->wc,
- &ctx->mpls_depth_delta, ctx->xin->vlan_tci);
+ &ctx->mpls_depth_delta, ctx->final_vlan_tci);
compose_flow_sample_cookie(os->probability, os->collector_set_id,
os->obs_domain_id, os->obs_point_id, &cookie);
@@ -2236,13 +2267,14 @@ may_receive(const struct xport *xport, struct xlate_ctx *ctx)
}
static void
-vlan_tci_restore(struct xlate_in *xin, ovs_be16 *tci_ptr, ovs_be16 orig_tci)
+vlan_tci_restore(struct xlate_ctx *ctx, ovs_be16 orig_tci)
{
/* If MPLS actions were executed after vlan actions then
* copy the final vlan_tci out and restore the intermediate VLAN state. */
- if (xin->flow.vlan_tci != orig_tci && tci_ptr == &xin->vlan_tci) {
- xin->vlan_tci = xin->flow.vlan_tci;
- xin->flow.vlan_tci = orig_tci;
+ if (ctx->xin->flow.vlan_tci != orig_tci &&
+ ctx->next_vlan_tci == &ctx->final_vlan_tci) {
+ ctx->final_vlan_tci = ctx->xin->flow.vlan_tci;
+ ctx->xin->flow.vlan_tci = orig_tci;
}
}
@@ -2252,19 +2284,8 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
{
struct flow_wildcards *wc = &ctx->xout->wc;
struct flow *flow = &ctx->xin->flow;
- ovs_be16 *vlan_tci;
const struct ofpact *a;
-
- /* VLAN actions are stored in '*vlan_tci'. This variable initially
- * points to 'xin->flow->vlan_tci', so that VLAN actions are applied
- * before any MPLS actions. When an MPLS action is translated,
- * 'vlan_tci' is updated to point to 'xin->vlan_tci'. This causes later
- * VLAN actions to be applied after MPLS actions. For each iteration
- * of the loop 'xin->vlan_tci' is updated to reflect the final VLAN
- * state of the flow. */
- vlan_tci = &ctx->xin->flow.vlan_tci;
-
OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) {
struct ofpact_controller *controller;
const struct ofpact_metadata *metadata;
@@ -2274,7 +2295,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
}
/* Update the final vlan state to match the current state. */
- ctx->xin->vlan_tci = *vlan_tci;
+ ctx->final_vlan_tci = *ctx->next_vlan_tci;
switch (a->type) {
case OFPACT_OUTPUT:
@@ -2299,28 +2320,28 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
case OFPACT_SET_VLAN_VID:
wc->masks.vlan_tci |= htons(VLAN_VID_MASK | VLAN_CFI);
- *vlan_tci &= ~htons(VLAN_VID_MASK);
- *vlan_tci |= (htons(ofpact_get_SET_VLAN_VID(a)->vlan_vid)
+ *ctx->next_vlan_tci &= ~htons(VLAN_VID_MASK);
+ *ctx->next_vlan_tci |= (htons(ofpact_get_SET_VLAN_VID(a)->vlan_vid)
| htons(VLAN_CFI));
break;
case OFPACT_SET_VLAN_PCP:
wc->masks.vlan_tci |= htons(VLAN_VID_MASK | VLAN_CFI);
- *vlan_tci &= ~htons(VLAN_PCP_MASK);
- *vlan_tci |=
+ *ctx->next_vlan_tci &= ~htons(VLAN_PCP_MASK);
+ *ctx->next_vlan_tci |=
htons((ofpact_get_SET_VLAN_PCP(a)->vlan_pcp << VLAN_PCP_SHIFT)
| VLAN_CFI);
break;
case OFPACT_STRIP_VLAN:
memset(&wc->masks.vlan_tci, 0xff, sizeof wc->masks.vlan_tci);
- *vlan_tci = htons(0);
+ *ctx->next_vlan_tci = htons(0);
break;
case OFPACT_PUSH_VLAN:
/* XXX 802.1AD(QinQ) */
memset(&wc->masks.vlan_tci, 0xff, sizeof wc->masks.vlan_tci);
- *vlan_tci = htons(VLAN_CFI);
+ *ctx->next_vlan_tci = htons(VLAN_CFI);
break;
case OFPACT_SET_ETH_SRC:
@@ -2391,20 +2412,20 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
case OFPACT_REG_MOVE: {
ovs_be16 orig_tci = flow->vlan_tci;
nxm_execute_reg_move(ofpact_get_REG_MOVE(a), flow, wc);
- vlan_tci_restore(ctx->xin, vlan_tci, orig_tci);
+ vlan_tci_restore(ctx, orig_tci);
break;
}
case OFPACT_REG_LOAD: {
ovs_be16 orig_tci = flow->vlan_tci;
nxm_execute_reg_load(ofpact_get_REG_LOAD(a), flow);
- vlan_tci_restore(ctx->xin, vlan_tci, orig_tci);
+ vlan_tci_restore(ctx, orig_tci);
break;
}
case OFPACT_STACK_PUSH: {
ovs_be16 orig_tci = flow->vlan_tci;
- flow->vlan_tci = *vlan_tci;
+ flow->vlan_tci = *ctx->next_vlan_tci;
nxm_execute_stack_push(ofpact_get_STACK_PUSH(a), flow, wc,
&ctx->stack);
flow->vlan_tci = orig_tci;
@@ -2415,7 +2436,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
ovs_be16 orig_tci = flow->vlan_tci;
nxm_execute_stack_pop(ofpact_get_STACK_POP(a), flow, wc,
&ctx->stack);
- vlan_tci_restore(ctx->xin, vlan_tci, orig_tci);
+ vlan_tci_restore(ctx, orig_tci);
break;
}
@@ -2433,11 +2454,11 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
* Do not save and therefore pop the VLAN tags if the MPLS LSE
* should be pushed before any VLAN tags that are present.
* This is the behaviour described for OpenFlow 1.3. */
- ctx->xin->vlan_tci = *vlan_tci;
+ ctx->final_vlan_tci = *ctx->next_vlan_tci;
if (!oam->mpls_before_vlan) {
flow->vlan_tci = htons(0);
}
- vlan_tci = &ctx->xin->vlan_tci;
+ ctx->next_vlan_tci = &ctx->final_vlan_tci;
break;
}
@@ -2540,7 +2561,6 @@ xlate_in_init(struct xlate_in *xin, struct ofproto_dpif *ofproto,
{
xin->ofproto = ofproto;
xin->flow = *flow;
- xin->vlan_tci = flow->vlan_tci;
xin->packet = packet;
xin->may_learn = packet != NULL;
xin->rule = rule;
@@ -2770,6 +2790,8 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout)
ctx.table_id = 0;
ctx.exit = false;
ctx.mpls_depth_delta = 0;
+ ctx.final_vlan_tci = ctx->xin->flow.vlan_tci;
+ ctx.next_vlan_tci = &ctx->xin->flow.vlan_tci;
if (xin->ofpacts) {
ofpacts = xin->ofpacts;
diff --git a/ofproto/ofproto-dpif-xlate.h b/ofproto/ofproto-dpif-xlate.h
index 54fd36d..6403f50 100644
--- a/ofproto/ofproto-dpif-xlate.h
+++ b/ofproto/ofproto-dpif-xlate.h
@@ -60,11 +60,6 @@ struct xlate_in {
* this flow when actions change header fields. */
struct flow flow;
- /* If MPLS and VLAN actions were both present in the translation, and VLAN
- * actions should occur after the MPLS actions, then this field is used
- * to store the final vlan_tci state. */
- ovs_be16 vlan_tci;
-
/* The packet corresponding to 'flow', or a null pointer if we are
* revalidating without a packet to refer to. */
const struct ofpbuf *packet;
^ permalink raw reply related
* [PATCH] net: sh_eth: Fix RX packets errors on R8A7740
From: Nguyen Hong Ky @ 2013-10-07 6:29 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Ryusuke Sakato, Sergei Shtylyov, Simon Horman
Hi David S. Miller,
This patch will fix RX packets errors when receiving big size of data.
Moreover, I set suitable parameters for get more stable when receiving
packets.
It was created on the top of mainline kernel v3.11.
I tested this patch on Armadillo800eva, it appears to be working well.
Would you please review and apply it for me.
Thank you,
Nguyen Hong Ky
Nguyen Hong Ky (1):
net: sh_eth: Fix RX packets errors on R8A7740
drivers/net/ethernet/renesas/sh_eth.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
--
1.7.5.4
^ permalink raw reply
* [PATCH] net: sh_eth: Fix RX packets errors on R8A7740
From: Nguyen Hong Ky @ 2013-10-07 6:29 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Ryusuke Sakato, Sergei Shtylyov, Simon Horman
In-Reply-To: <1381127365-6521-1-git-send-email-nh-ky@jinso.co.jp>
This patch will fix RX packets errors when receiving big size
of data by set bit RNC = 1.
RNC - Receive Enable Control
0: Upon completion of reception of one frame, the E-DMAC writes
the receive status to the descriptor and clears the RR bit in
EDRRR to 0.
1: Upon completion of reception of one frame, the E-DMAC writes
(writes back) the receive status to the descriptor. In addition,
the E-DMAC reads the next descriptor and prepares for reception
of the next frame.
In addition, for get more stable when receiving packets, I set
maximum size for the transmit/receive FIFO and inserts padding
in receive data.
Signed-off-by: Nguyen Hong Ky <nh-ky@jinso.co.jp>
---
drivers/net/ethernet/renesas/sh_eth.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index a753928..11d34f0 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -649,12 +649,16 @@ static struct sh_eth_cpu_data r8a7740_data = {
.eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT |
EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE |
EESR_TDE | EESR_ECI,
+ .fdr_value = 0x0000070f,
+ .rmcr_value = 0x00000001,
.apr = 1,
.mpr = 1,
.tpauser = 1,
.bculr = 1,
.hw_swap = 1,
+ .rpadir = 1,
+ .rpadir_value = 2 << 16,
.no_trimd = 1,
.no_ade = 1,
.tsu = 1,
--
1.7.5.4
^ permalink raw reply related
* Congratulations !!!
From: office1 @ 2013-10-07 6:44 UTC (permalink / raw)
To: Recipients
Ticket Number: 7PWYZ2008
Ballot Number: BT:12052008/20
Draw:#1471
Special Notification to you,You are receiving this email because you have just been picked for a total grand prize of One Million Dollars in the top 10 winners of the Coca-Cola Consumer`s Award for the year 2013: kindly send your:
Name:
Address:
Country:
Phone Number:
To Mr. Bruce Morgan
via Email: colaclaims13@msn.com
Telephone Number:+44701006909
^ permalink raw reply
* [PATCH 02/11] mdio_bus: convert bus code to use dev_groups
From: Greg Kroah-Hartman @ 2013-10-07 6:55 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, David S. Miller, Mark Brown, Nick Bowler,
netdev
In-Reply-To: <1381128950-28125-1-git-send-email-gregkh@linuxfoundation.org>
The dev_attrs field of struct bus_type is going away soon, dev_groups
should be used instead. This converts the MDIO bus code to use the
correct field.
Cc: David S. Miller <davem@davemloft.net>
Cc: Mark Brown <broonie@opensource.wolfsonmicro.com>
Cc: Nick Bowler <nbowler@elliptictech.com>
Cc: <netdev@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
David, I can take this through my driver-core tree if you like, just let
me know what would be the easiest for you.
drivers/net/phy/mdio_bus.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index dc92097..5617876 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -438,17 +438,19 @@ phy_id_show(struct device *dev, struct device_attribute *attr, char *buf)
return sprintf(buf, "0x%.8lx\n", (unsigned long)phydev->phy_id);
}
+static DEVICE_ATTR_RO(phy_id);
-static struct device_attribute mdio_dev_attrs[] = {
- __ATTR_RO(phy_id),
- __ATTR_NULL
+static struct attribute *mdio_dev_attrs[] = {
+ &dev_attr_phy_id.attr,
+ NULL,
};
+ATTRIBUTE_GROUPS(mdio_dev);
struct bus_type mdio_bus_type = {
.name = "mdio_bus",
.match = mdio_bus_match,
.pm = MDIO_BUS_PM_OPS,
- .dev_attrs = mdio_dev_attrs,
+ .dev_groups = mdio_dev_groups,
};
EXPORT_SYMBOL(mdio_bus_type);
--
1.8.4.6.g82e253f.dirty
^ permalink raw reply related
* [PATCH 09/11] ssb: convert bus code to use dev_groups
From: Greg Kroah-Hartman @ 2013-10-07 6:55 UTC (permalink / raw)
To: linux-kernel; +Cc: Greg Kroah-Hartman, Michael Buesch, netdev
In-Reply-To: <1381128950-28125-1-git-send-email-gregkh@linuxfoundation.org>
The dev_attrs field of struct bus_type is going away soon, dev_groups
should be used instead. This converts the ssb bus code to use the
correct field.
Cc: Michael Buesch <m@bues.ch>
Cc: <netdev@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
Michael, I can take this through my driver-core tree if you like, just
let me know what would be the easiest for you.
drivers/ssb/main.c | 25 ++++++++++++++-----------
1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index e55ddf7..32a811d 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -374,7 +374,8 @@ static ssize_t \
attrib##_show(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return sprintf(buf, format_string, dev_to_ssb_dev(dev)->field); \
-}
+} \
+static DEVICE_ATTR_RO(attrib);
ssb_config_attr(core_num, core_index, "%u\n")
ssb_config_attr(coreid, id.coreid, "0x%04x\n")
@@ -387,16 +388,18 @@ name_show(struct device *dev, struct device_attribute *attr, char *buf)
return sprintf(buf, "%s\n",
ssb_core_name(dev_to_ssb_dev(dev)->id.coreid));
}
-
-static struct device_attribute ssb_device_attrs[] = {
- __ATTR_RO(name),
- __ATTR_RO(core_num),
- __ATTR_RO(coreid),
- __ATTR_RO(vendor),
- __ATTR_RO(revision),
- __ATTR_RO(irq),
- __ATTR_NULL,
+static DEVICE_ATTR_RO(name);
+
+static struct attribute *ssb_device_attrs[] = {
+ &dev_attr_name.attr,
+ &dev_attr_core_num.attr,
+ &dev_attr_coreid.attr,
+ &dev_attr_vendor.attr,
+ &dev_attr_revision.attr,
+ &dev_attr_irq.attr,
+ NULL,
};
+ATTRIBUTE_GROUPS(ssb_device);
static struct bus_type ssb_bustype = {
.name = "ssb",
@@ -407,7 +410,7 @@ static struct bus_type ssb_bustype = {
.suspend = ssb_device_suspend,
.resume = ssb_device_resume,
.uevent = ssb_device_uevent,
- .dev_attrs = ssb_device_attrs,
+ .dev_groups = ssb_device_groups,
};
static void ssb_buses_lock(void)
--
1.8.4.6.g82e253f.dirty
^ permalink raw reply related
* [PATCH net-next] bonding: ensure that TLB mode's active slave has correct mac filter
From: Veaceslav Falico @ 2013-10-07 7:17 UTC (permalink / raw)
To: netdev; +Cc: Veaceslav Falico, Jay Vosburgh, Andy Gospodarek, Yuval Mintz
Currently, in TLB mode we change mac addresses only by memcpy-ing the to
net_device->dev_addr, without actually setting them via
dev_set_mac_address(). This permits us to receive all the traffic always on
one mac address.
However, in case the interface flips, some drivers might enforce the
mac filtering for its FW/HW based on current ->dev_addr, and thus we won't
be able to receive traffic on that interface, in case it will be selected
as active in TLB mode.
Fix it by setting the mac address forcefully on every new active slave that
we select in TLB mode.
CC: Jay Vosburgh <fubar@us.ibm.com>
CC: Andy Gospodarek <andy@greyhouse.net>
CC: Yuval Mintz <yuvalmin@broadcom.com>
Reported-by: Yuval Mintz <yuvalmin@broadcom.com>
Tested-by: Yuval Mintz <yuvalmin@broadcom.com>
Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
---
Notes:
It seems that it's the least intrusive fix. The, maybe, better
way would be to leave the dev_addr unchainged and play around
with mac addresses in logic, however it's making the code a lot
more bloated, error prone and hard to read, so it's not worth it,
imho.
drivers/net/bonding/bond_alb.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index e960418..576ccea 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -1699,6 +1699,23 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
ASSERT_RTNL();
+ /* in TLB mode, the slave might flip down/up with the old dev_addr,
+ * and thus filter bond->dev_addr's packets, so force bond's mac
+ */
+ if (bond->params.mode == BOND_MODE_TLB) {
+ struct sockaddr sa;
+ u8 tmp_addr[ETH_ALEN];
+
+ memcpy(tmp_addr, new_slave->dev->dev_addr, ETH_ALEN);
+
+ memcpy(sa.sa_data, bond->dev->dev_addr, bond->dev->addr_len);
+ sa.sa_family = bond->dev->type;
+ /* we don't care if it can't change its mac, best effort */
+ dev_set_mac_address(new_slave->dev, &sa);
+
+ memcpy(new_slave->dev->dev_addr, tmp_addr, ETH_ALEN);
+ }
+
/* curr_active_slave must be set before calling alb_swap_mac_addr */
if (swap_slave) {
/* swap mac address */
--
1.8.4
^ permalink raw reply related
* [PATCH v2.43 2/5] ofp-actions: Add separate OpenFlow 1.3 action parser
From: Simon Horman @ 2013-10-07 8:00 UTC (permalink / raw)
To: dev-yBygre7rU0TnMu66kgdUjQ, netdev-u79uwXL29TY76Z2rM5mHXA,
Jesse Gross, Ben Pfaff
Cc: Isaku Yamahata, Ravi K
In-Reply-To: <1381132847-12589-1-git-send-email-horms-/R6kz+dDXgpPR4JQBCEnsQ@public.gmane.org>
From: Joe Stringer <joe-Q1GJJQv1iO6lP80pJB477g@public.gmane.org>
This patch adds new ofpact_from_openflow13() and
ofpacts_from_openflow13() functions parallel to the existing ofpact
handling code. In the OpenFlow 1.3 version, push_mpls is handled
differently, but all other actions are handled by the existing code.
In the case of push_mpls for OpenFlow 1.3 the new mpls_before_vlan field of
struct ofpact_push_mpls is set to true. This will be used by a subsequent
patch to allow allow the correct VLAN+MPLS datapath behaviour to be
determined at odp translation time.
enum ofpact_mpls_position contributed by Ben Pfaff.
Signed-off-by: Joe Stringer <joe-Q1GJJQv1iO6lP80pJB477g@public.gmane.org>
Signed-off-by: Simon Horman <horms-/R6kz+dDXgpPR4JQBCEnsQ@public.gmane.org>
---
Ben, please feel free to add yourself as a co-author
as you wrote the enum ofpact_mpls_position portion.
v2.43 [Ben Pfaff and Simon Horman]
* Code contributed by Ben Pfaff
+ Use enum for to control order of MPLS LSE insertion
This makes the logic somewhat clearer
* Add a helper push_mpls_from_openflow() to consolidate
the same logic that appears in three locations.
v2.42
* No change
v2.41 [Simon Horman]
* As suggested by Ben Pfaff
+ Expand struct ofpact_reg_load to include a mpls_before_vlan field
rather than using the compat field of the ofpact field of
struct ofpact_reg_load.
+ Pass version to ofpacts_pull_openflow11_actions and
ofpacts_pull_openflow11_instructions. This removes the invalid
assumption that that these functions are passed a full message and are
thus able to deduce the OpenFlow version.
v2.36 - v2.40
* No change
v2.35 [Joe Stringer]
* First post
---
lib/ofp-actions.c | 91 ++++++++++++++++++++++++++++++++++++++++++++-------
lib/ofp-actions.h | 16 +++++++++
lib/ofp-print.c | 2 +-
lib/ofp-util.c | 24 ++++++++------
lib/ofp-util.h | 2 +-
utilities/ovs-ofctl.c | 8 ++---
6 files changed, 115 insertions(+), 28 deletions(-)
diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
index 65430f3..dc0c9c8 100644
--- a/lib/ofp-actions.c
+++ b/lib/ofp-actions.c
@@ -238,6 +238,22 @@ sample_from_openflow(const struct nx_action_sample *nas,
}
static enum ofperr
+push_mpls_from_openflow(ovs_be16 ethertype, enum ofpact_mpls_position position,
+ struct ofpbuf *out)
+{
+ struct ofpact_push_mpls *oam;
+
+ if (!eth_type_mpls(ethertype)) {
+ return OFPERR_OFPBAC_BAD_ARGUMENT;
+ }
+ oam = ofpact_put_PUSH_MPLS(out);
+ oam->ethertype = ethertype;
+ oam->position = position;
+
+ return 0;
+}
+
+static enum ofperr
decode_nxast_action(const union ofp_action *a, enum ofputil_action_code *code)
{
const struct nx_action_header *nah = (const struct nx_action_header *) a;
@@ -430,10 +446,8 @@ ofpact_from_nxast(const union ofp_action *a, enum ofputil_action_code code,
case OFPUTIL_NXAST_PUSH_MPLS: {
struct nx_action_push_mpls *nxapm = (struct nx_action_push_mpls *)a;
- if (!eth_type_mpls(nxapm->ethertype)) {
- return OFPERR_OFPBAC_BAD_ARGUMENT;
- }
- ofpact_put_PUSH_MPLS(out)->ethertype = nxapm->ethertype;
+ error = push_mpls_from_openflow(nxapm->ethertype,
+ OFPACT_MPLS_AFTER_VLAN, out);
break;
}
@@ -844,10 +858,8 @@ ofpact_from_openflow11(const union ofp_action *a, struct ofpbuf *out)
case OFPUTIL_OFPAT11_PUSH_MPLS: {
struct ofp11_action_push *oap = (struct ofp11_action_push *)a;
- if (!eth_type_mpls(oap->ethertype)) {
- return OFPERR_OFPBAC_BAD_ARGUMENT;
- }
- ofpact_put_PUSH_MPLS(out)->ethertype = oap->ethertype;
+ error = push_mpls_from_openflow(oap->ethertype,
+ OFPACT_MPLS_AFTER_VLAN, out);
break;
}
@@ -881,6 +893,35 @@ ofpacts_from_openflow11(const union ofp_action *in, size_t n_in,
return ofpacts_from_openflow(in, n_in, out, ofpact_from_openflow11);
}
\f
+static enum ofperr
+ofpact_from_openflow13(const union ofp_action *a, struct ofpbuf *out)
+{
+ enum ofputil_action_code code;
+ enum ofperr error;
+
+ error = decode_openflow11_action(a, &code);
+ if (error) {
+ return error;
+ }
+
+ if (code == OFPUTIL_OFPAT11_PUSH_MPLS) {
+ struct ofp11_action_push *oap = (struct ofp11_action_push *)a;
+ error = push_mpls_from_openflow(oap->ethertype,
+ OFPACT_MPLS_BEFORE_VLAN, out);
+ } else {
+ error = ofpact_from_openflow11(a, out);
+ }
+
+ return error;
+}
+
+static enum ofperr
+ofpacts_from_openflow13(const union ofp_action *in, size_t n_in,
+ struct ofpbuf *out)
+{
+ return ofpacts_from_openflow(in, n_in, out, ofpact_from_openflow13);
+}
+\f
/* OpenFlow 1.1 instructions. */
#define DEFINE_INST(ENUM, STRUCT, EXTENSIBLE, NAME) \
@@ -1085,11 +1126,14 @@ get_actions_from_instruction(const struct ofp11_instruction *inst,
*n_actions = (ntohs(inst->len) - sizeof *inst) / OFP11_INSTRUCTION_ALIGN;
}
-/* Attempts to convert 'actions_len' bytes of OpenFlow 1.1 actions from the
+/* Attempts to convert 'actions_len' bytes of OpenFlow actions from the
* front of 'openflow' into ofpacts. On success, replaces any existing content
* in 'ofpacts' by the converted ofpacts; on failure, clears 'ofpacts'.
* Returns 0 if successful, otherwise an OpenFlow error.
*
+ * Actions are processed according to their OpenFlow version which
+ * is provided in the 'version' parameter.
+ *
* In most places in OpenFlow 1.1 and 1.2, actions appear encapsulated in
* instructions, so you should call ofpacts_pull_openflow11_instructions()
* instead of this function.
@@ -1101,15 +1145,27 @@ get_actions_from_instruction(const struct ofp11_instruction *inst,
* valid in a specific context. */
enum ofperr
ofpacts_pull_openflow11_actions(struct ofpbuf *openflow,
+ enum ofp_version version,
unsigned int actions_len,
struct ofpbuf *ofpacts)
{
- return ofpacts_pull_actions(openflow, actions_len, ofpacts,
- ofpacts_from_openflow11);
+ switch (version) {
+ case OFP10_VERSION:
+ case OFP11_VERSION:
+ case OFP12_VERSION:
+ return ofpacts_pull_actions(openflow, actions_len, ofpacts,
+ ofpacts_from_openflow11);
+ case OFP13_VERSION:
+ return ofpacts_pull_actions(openflow, actions_len, ofpacts,
+ ofpacts_from_openflow13);
+ default:
+ NOT_REACHED();
+ }
}
enum ofperr
ofpacts_pull_openflow11_instructions(struct ofpbuf *openflow,
+ enum ofp_version version,
unsigned int instructions_len,
struct ofpbuf *ofpacts)
{
@@ -1160,7 +1216,18 @@ ofpacts_pull_openflow11_instructions(struct ofpbuf *openflow,
get_actions_from_instruction(insts[OVSINST_OFPIT11_APPLY_ACTIONS],
&actions, &n_actions);
- error = ofpacts_from_openflow11(actions, n_actions, ofpacts);
+ switch (version) {
+ case OFP10_VERSION:
+ case OFP11_VERSION:
+ case OFP12_VERSION:
+ error = ofpacts_from_openflow11(actions, n_actions, ofpacts);
+ break;
+ case OFP13_VERSION:
+ error = ofpacts_from_openflow13(actions, n_actions, ofpacts);
+ break;
+ default:
+ NOT_REACHED();
+ }
if (error) {
goto exit;
}
diff --git a/lib/ofp-actions.h b/lib/ofp-actions.h
index 0876ed7..87764df 100644
--- a/lib/ofp-actions.h
+++ b/lib/ofp-actions.h
@@ -326,12 +326,26 @@ struct ofpact_reg_load {
union mf_subvalue subvalue; /* Least-significant bits are used. */
};
+/* The position in the packet at which to insert an MPLS header.
+ *
+ * Used NXAST_PUSH_MPLS, OFPAT11_PUSH_MPLS. */
+enum ofpact_mpls_position {
+ /* Add the MPLS LSE after the Ethernet header but before any VLAN tags.
+ * OpenFlow 1.3+ requires this behavior. */
+ OFPACT_MPLS_BEFORE_VLAN,
+
+ /* Add the MPLS LSE after the Ethernet header and any VLAN tags.
+ * OpenFlow 1.1 and 1.2 require this behavior. */
+ OFPACT_MPLS_AFTER_VLAN
+};
+
/* OFPACT_PUSH_VLAN/MPLS/PBB
*
* Used for NXAST_PUSH_MPLS, OFPAT11_PUSH_MPLS. */
struct ofpact_push_mpls {
struct ofpact ofpact;
ovs_be16 ethertype;
+ enum ofpact_mpls_position position;
};
/* OFPACT_POP_MPLS
@@ -504,9 +518,11 @@ enum ofperr ofpacts_pull_openflow10(struct ofpbuf *openflow,
unsigned int actions_len,
struct ofpbuf *ofpacts);
enum ofperr ofpacts_pull_openflow11_actions(struct ofpbuf *openflow,
+ enum ofp_version version,
unsigned int actions_len,
struct ofpbuf *ofpacts);
enum ofperr ofpacts_pull_openflow11_instructions(struct ofpbuf *openflow,
+ enum ofp_version version,
unsigned int instructions_len,
struct ofpbuf *ofpacts);
enum ofperr ofpacts_check(const struct ofpact[], size_t ofpacts_len,
diff --git a/lib/ofp-print.c b/lib/ofp-print.c
index 6fe1cee..a0615b5 100644
--- a/lib/ofp-print.c
+++ b/lib/ofp-print.c
@@ -2224,7 +2224,7 @@ ofp_print_group_desc(struct ds *s, const struct ofp_header *oh)
struct ofputil_group_desc gd;
int retval;
- retval = ofputil_decode_group_desc_reply(&gd, &b);
+ retval = ofputil_decode_group_desc_reply(&gd, &b, oh->version);
if (retval) {
if (retval != EOF) {
ds_put_cstr(s, " ***parse error***");
diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index 173b534..570447a 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -1504,7 +1504,8 @@ ofputil_decode_flow_mod(struct ofputil_flow_mod *fm,
return error;
}
- error = ofpacts_pull_openflow11_instructions(&b, b.size, ofpacts);
+ error = ofpacts_pull_openflow11_instructions(&b, oh->version,
+ b.size, ofpacts);
if (error) {
return error;
}
@@ -2360,7 +2361,8 @@ ofputil_decode_flow_stats_reply(struct ofputil_flow_stats *fs,
return EINVAL;
}
- if (ofpacts_pull_openflow11_instructions(msg, length - sizeof *ofs -
+ if (ofpacts_pull_openflow11_instructions(msg, oh->version,
+ length - sizeof *ofs -
padded_match_len, ofpacts)) {
VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST_FLOW reply bad instructions");
return EINVAL;
@@ -3092,7 +3094,8 @@ ofputil_decode_packet_out(struct ofputil_packet_out *po,
return error;
}
- error = ofpacts_pull_openflow11_actions(&b, ntohs(opo->actions_len),
+ error = ofpacts_pull_openflow11_actions(&b, oh->version,
+ ntohs(opo->actions_len),
ofpacts);
if (error) {
return error;
@@ -5674,8 +5677,8 @@ ofputil_append_group_desc_reply(const struct ofputil_group_desc *gds,
}
static enum ofperr
-ofputil_pull_buckets(struct ofpbuf *msg, size_t buckets_length,
- struct list *buckets)
+ofputil_pull_buckets(struct ofpbuf *msg, enum ofp_version version,
+ size_t buckets_length, struct list *buckets)
{
struct ofp11_bucket *ob;
@@ -5708,8 +5711,8 @@ ofputil_pull_buckets(struct ofpbuf *msg, size_t buckets_length,
buckets_length -= ob_len;
ofpbuf_init(&ofpacts, 0);
- error = ofpacts_pull_openflow11_actions(msg, ob_len - sizeof *ob,
- &ofpacts);
+ error = ofpacts_pull_openflow11_actions(msg, version,
+ ob_len - sizeof *ob, &ofpacts);
if (error) {
ofpbuf_uninit(&ofpacts);
ofputil_bucket_list_destroy(buckets);
@@ -5745,7 +5748,7 @@ ofputil_pull_buckets(struct ofpbuf *msg, size_t buckets_length,
* otherwise a positive errno value. */
int
ofputil_decode_group_desc_reply(struct ofputil_group_desc *gd,
- struct ofpbuf *msg)
+ struct ofpbuf *msg, enum ofp_version version)
{
struct ofp11_group_desc_stats *ogds;
size_t length;
@@ -5774,7 +5777,8 @@ ofputil_decode_group_desc_reply(struct ofputil_group_desc *gd,
return OFPERR_OFPBRC_BAD_LEN;
}
- return ofputil_pull_buckets(msg, length - sizeof *ogds, &gd->buckets);
+ return ofputil_pull_buckets(msg, version, length - sizeof *ogds,
+ &gd->buckets);
}
/* Converts abstract group mod 'gm' into a message for OpenFlow version
@@ -5857,7 +5861,7 @@ ofputil_decode_group_mod(const struct ofp_header *oh,
gm->type = ogm->type;
gm->group_id = ntohl(ogm->group_id);
- return ofputil_pull_buckets(&msg, msg.size, &gm->buckets);
+ return ofputil_pull_buckets(&msg, oh->version, msg.size, &gm->buckets);
}
/* Parse a queue status request message into 'oqsr'.
diff --git a/lib/ofp-util.h b/lib/ofp-util.h
index d5f34d7..5fa8fee 100644
--- a/lib/ofp-util.h
+++ b/lib/ofp-util.h
@@ -973,7 +973,7 @@ int ofputil_decode_group_stats_reply(struct ofpbuf *,
struct ofputil_group_stats *);
int ofputil_decode_group_desc_reply(struct ofputil_group_desc *,
- struct ofpbuf *);
+ struct ofpbuf *, enum ofp_version);
void ofputil_append_group_desc_reply(const struct ofputil_group_desc *,
struct list *buckets,
diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c
index c2cc1f6..00d35aa 100644
--- a/utilities/ovs-ofctl.c
+++ b/utilities/ovs-ofctl.c
@@ -2968,8 +2968,8 @@ ofctl_parse_ofp11_actions(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
/* Convert to ofpacts. */
ofpbuf_init(&ofpacts, 0);
size = of11_in.size;
- error = ofpacts_pull_openflow11_actions(&of11_in, of11_in.size,
- &ofpacts);
+ error = ofpacts_pull_openflow11_actions(&of11_in, OFP11_VERSION,
+ of11_in.size, &ofpacts);
if (error) {
printf("bad OF1.1 actions: %s\n\n", ofperr_get_name(error));
ofpbuf_uninit(&ofpacts);
@@ -3036,8 +3036,8 @@ ofctl_parse_ofp11_instructions(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
/* Convert to ofpacts. */
ofpbuf_init(&ofpacts, 0);
size = of11_in.size;
- error = ofpacts_pull_openflow11_instructions(&of11_in, of11_in.size,
- &ofpacts);
+ error = ofpacts_pull_openflow11_instructions(&of11_in, OFP11_VERSION,
+ of11_in.size, &ofpacts);
if (!error) {
/* Verify actions. */
struct flow flow;
--
1.8.4
^ permalink raw reply related
* [PATCH v2.43 4/5] datapath: Break out deacceleration portion of vlan_push
From: Simon Horman @ 2013-10-07 8:00 UTC (permalink / raw)
To: dev-yBygre7rU0TnMu66kgdUjQ, netdev-u79uwXL29TY76Z2rM5mHXA,
Jesse Gross, Ben Pfaff
Cc: Isaku Yamahata, Ravi K
In-Reply-To: <1381132847-12589-1-git-send-email-horms-/R6kz+dDXgpPR4JQBCEnsQ@public.gmane.org>
Break out deacceleration portion of vlan_push into vlan_put
so that it may be re-used by mpls_push.
For both vlan_push and mpls_push if there is an accelerated VLAN tag
present then it should be deaccelerated, adding it to the data of
the skb, before the new tag is added.
Signed-off-by: Simon Horman <horms-/R6kz+dDXgpPR4JQBCEnsQ@public.gmane.org>
---
v2.41 - v2.43
* No change
v2.40
* As suggested by Jesse Gross
+ Simplify vlan_push by returning an error code
rather than an error code encoded as a struct xkb_buff *
v2.39
* First post
---
datapath/actions.c | 29 +++++++++++++++++++----------
1 file changed, 19 insertions(+), 10 deletions(-)
diff --git a/datapath/actions.c b/datapath/actions.c
index 30ea1d2..d961e5d 100644
--- a/datapath/actions.c
+++ b/datapath/actions.c
@@ -105,22 +105,31 @@ static int pop_vlan(struct sk_buff *skb)
return 0;
}
-static int push_vlan(struct sk_buff *skb, const struct ovs_action_push_vlan *vlan)
+/* push down current VLAN tag */
+static int put_vlan(struct sk_buff *skb)
{
- if (unlikely(vlan_tx_tag_present(skb))) {
- u16 current_tag;
+ u16 current_tag = vlan_tx_tag_get(skb);
- /* push down current VLAN tag */
- current_tag = vlan_tx_tag_get(skb);
+ if (!__vlan_put_tag(skb, skb->vlan_proto, current_tag))
+ return -ENOMEM;
- if (!__vlan_put_tag(skb, skb->vlan_proto, current_tag))
- return -ENOMEM;
+ if (skb->ip_summed == CHECKSUM_COMPLETE)
+ skb->csum = csum_add(skb->csum, csum_partial(skb->data
+ + (2 * ETH_ALEN), VLAN_HLEN, 0));
- if (skb->ip_summed == CHECKSUM_COMPLETE)
- skb->csum = csum_add(skb->csum, csum_partial(skb->data
- + (2 * ETH_ALEN), VLAN_HLEN, 0));
+ return 0;
+}
+static int push_vlan(struct sk_buff *skb, const struct ovs_action_push_vlan *vlan)
+{
+ if (unlikely(vlan_tx_tag_present(skb))) {
+ int err;
+
+ err = put_vlan(skb);
+ if (unlikely(err))
+ return err;
}
+
__vlan_hwaccel_put_tag(skb, vlan->vlan_tpid, ntohs(vlan->vlan_tci) & ~VLAN_TAG_PRESENT);
return 0;
}
--
1.8.4
^ 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