* [PATCH] datapath: 16bit inner_network_header field in struct ovs_gso_cb
@ 2014-05-20 10:41 Simon Horman
[not found] ` <1400582464-2917-1-git-send-email-horms-/R6kz+dDXgpPR4JQBCEnsQ@public.gmane.org>
0 siblings, 1 reply; 5+ messages in thread
From: Simon Horman @ 2014-05-20 10:41 UTC (permalink / raw)
To: dev; +Cc: netdev, Simon Horman, Thomas Graf, Jesse Gross
The motivation for this is to create a 16bit hole in struct ovs_gso_cb
which may be used for the inner_protocol field which is needed
for the proposed implementation of compatibility for MPLS GSO segmentation.
This should be safe as inner_network_header is now an offset to
the inner_mac_header rather than skb->head.
As pointed out by Thomas Graf simply making both inner offsets 16bis is not
safe as there have been cases of overflow with "with collapsed TCP frames
on IB when the headroom grew beyond 64K. See commit 50bceae9bd ``tcp:
Reallocate headroom if it would overflow csum_start'' for additional
details."
This patch is based on suggestions by Thomas Graf and Jesse Gross.
Cc: Thomas Graf <tgraf@suug.ch>
Cc: Jesse Gross <jesse@nicira.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
datapath/linux/compat/gso.h | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/datapath/linux/compat/gso.h b/datapath/linux/compat/gso.h
index b83a4c3..f459c18 100644
--- a/datapath/linux/compat/gso.h
+++ b/datapath/linux/compat/gso.h
@@ -11,8 +11,10 @@
struct ovs_gso_cb {
struct ovs_skb_cb dp_cb;
- sk_buff_data_t inner_network_header;
- sk_buff_data_t inner_mac_header;
+ u16 inner_network_header; /* Offset from
+ * inner_mac_header */
+ /* 16bit hole */
+ sk_buff_data_t inner_mac_header; /* Offset from skb->head */
void (*fix_segment)(struct sk_buff *);
};
#define OVS_GSO_CB(skb) ((struct ovs_gso_cb *)(skb)->cb)
@@ -20,18 +22,19 @@ struct ovs_gso_cb {
#define skb_inner_network_header rpl_skb_inner_network_header
#ifdef NET_SKBUFF_DATA_USES_OFFSET
-#define skb_inner_network_header rpl_skb_inner_network_header
-static inline unsigned char *skb_inner_network_header(const struct sk_buff *skb)
-{
- return skb->head + OVS_GSO_CB(skb)->inner_network_header;
-}
-
#define skb_inner_mac_header rpl_skb_inner_mac_header
static inline unsigned char *skb_inner_mac_header(const struct sk_buff *skb)
{
return skb->head + OVS_GSO_CB(skb)->inner_mac_header;
}
+#define skb_inner_network_header rpl_skb_inner_network_header
+static inline unsigned char *skb_inner_network_header(const struct sk_buff *skb)
+{
+ return skb_inner_mac_header(skb) +
+ OVS_GSO_CB(skb)->inner_network_header;
+}
+
#else
#define skb_inner_network_header rpl_skb_inner_network_header
@@ -64,7 +67,8 @@ static inline int skb_inner_mac_offset(const struct sk_buff *skb)
static inline void skb_reset_inner_headers(struct sk_buff *skb)
{
BUILD_BUG_ON(sizeof(struct ovs_gso_cb) > FIELD_SIZEOF(struct sk_buff, cb));
- OVS_GSO_CB(skb)->inner_network_header = skb->network_header;
+ OVS_GSO_CB(skb)->inner_network_header = skb->network_header -
+ skb->mac_header;
OVS_GSO_CB(skb)->inner_mac_header = skb->mac_header;
OVS_GSO_CB(skb)->fix_segment = NULL;
--
1.8.4
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] datapath: 16bit inner_network_header field in struct ovs_gso_cb
[not found] ` <1400582464-2917-1-git-send-email-horms-/R6kz+dDXgpPR4JQBCEnsQ@public.gmane.org>
@ 2014-05-20 19:54 ` Jesse Gross
2014-05-20 23:31 ` Simon Horman
0 siblings, 1 reply; 5+ messages in thread
From: Jesse Gross @ 2014-05-20 19:54 UTC (permalink / raw)
To: Simon Horman; +Cc: dev-yBygre7rU0TnMu66kgdUjQ@public.gmane.org, netdev
On Tue, May 20, 2014 at 3:41 AM, Simon Horman <horms-/R6kz+dDXgpPR4JQBCEnsQ@public.gmane.org> wrote:
> diff --git a/datapath/linux/compat/gso.h b/datapath/linux/compat/gso.h
> index b83a4c3..f459c18 100644
> --- a/datapath/linux/compat/gso.h
> +++ b/datapath/linux/compat/gso.h
> #ifdef NET_SKBUFF_DATA_USES_OFFSET
> -#define skb_inner_network_header rpl_skb_inner_network_header
> -static inline unsigned char *skb_inner_network_header(const struct sk_buff *skb)
> -{
> - return skb->head + OVS_GSO_CB(skb)->inner_network_header;
> -}
> -
> #define skb_inner_mac_header rpl_skb_inner_mac_header
> static inline unsigned char *skb_inner_mac_header(const struct sk_buff *skb)
> {
> return skb->head + OVS_GSO_CB(skb)->inner_mac_header;
> }
>
> +#define skb_inner_network_header rpl_skb_inner_network_header
> +static inline unsigned char *skb_inner_network_header(const struct sk_buff *skb)
> +{
> + return skb_inner_mac_header(skb) +
> + OVS_GSO_CB(skb)->inner_network_header;
> +}
> +
> #else
This looks mostly fine to me but doesn't this need to be outside the
#ifdef NET_SKBUFF_DATA_USES_OFFSET block? Otherwise we will treat the
offset as a pointer on 32 bit kernels.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] datapath: 16bit inner_network_header field in struct ovs_gso_cb
2014-05-20 19:54 ` Jesse Gross
@ 2014-05-20 23:31 ` Simon Horman
[not found] ` <20140520233145.GA30260-/R6kz+dDXgpPR4JQBCEnsQ@public.gmane.org>
0 siblings, 1 reply; 5+ messages in thread
From: Simon Horman @ 2014-05-20 23:31 UTC (permalink / raw)
To: Jesse Gross; +Cc: dev@openvswitch.org, netdev, Thomas Graf
On Tue, May 20, 2014 at 12:54:32PM -0700, Jesse Gross wrote:
> On Tue, May 20, 2014 at 3:41 AM, Simon Horman <horms@verge.net.au> wrote:
> > diff --git a/datapath/linux/compat/gso.h b/datapath/linux/compat/gso.h
> > index b83a4c3..f459c18 100644
> > --- a/datapath/linux/compat/gso.h
> > +++ b/datapath/linux/compat/gso.h
> > #ifdef NET_SKBUFF_DATA_USES_OFFSET
> > -#define skb_inner_network_header rpl_skb_inner_network_header
> > -static inline unsigned char *skb_inner_network_header(const struct sk_buff *skb)
> > -{
> > - return skb->head + OVS_GSO_CB(skb)->inner_network_header;
> > -}
> > -
> > #define skb_inner_mac_header rpl_skb_inner_mac_header
> > static inline unsigned char *skb_inner_mac_header(const struct sk_buff *skb)
> > {
> > return skb->head + OVS_GSO_CB(skb)->inner_mac_header;
> > }
> >
> > +#define skb_inner_network_header rpl_skb_inner_network_header
> > +static inline unsigned char *skb_inner_network_header(const struct sk_buff *skb)
> > +{
> > + return skb_inner_mac_header(skb) +
> > + OVS_GSO_CB(skb)->inner_network_header;
> > +}
> > +
> > #else
>
> This looks mostly fine to me but doesn't this need to be outside the
> #ifdef NET_SKBUFF_DATA_USES_OFFSET block? Otherwise we will treat the
> offset as a pointer on 32 bit kernels.
Thanks, Somehow I completely missed that.
How about this?
From: Simon Horman <horms@verge.net.au>
[PATCH v1.1] datapath: 16bit inner_network_header field in struct ovs_gso_cb
The motivation for this is to create a 16bit hole in struct ovs_gso_cb
which may be used for the inner_protocol field which is needed
for the proposed implementation of compatibility for MPLS GSO segmentation.
This should be safe as inner_network_header is now an offset to
the inner_mac_header rather than skb->head.
As pointed out by Thomas Graf simply making both inner offsets 16bis is not
safe as there have been cases of overflow with "with collapsed TCP frames
on IB when the headroom grew beyond 64K. See commit 50bceae9bd ``tcp:
Reallocate headroom if it would overflow csum_start'' for additional
details."
This patch is based on suggestions by Thomas Graf and Jesse Gross.
Cc: Thomas Graf <tgraf@suug.ch>
Cc: Jesse Gross <jesse@nicira.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
v1.1
* Move skb_inner_network_header outside #ifdef NET_SKBUFF_DATA_USES_OFFSET
block so that the 16bit offset is not treated as a pointer on
32bit kernels.
---
datapath/linux/compat/gso.h | 28 +++++++++++++---------------
1 file changed, 13 insertions(+), 15 deletions(-)
diff --git a/datapath/linux/compat/gso.h b/datapath/linux/compat/gso.h
index b83a4c3..3041e88 100644
--- a/datapath/linux/compat/gso.h
+++ b/datapath/linux/compat/gso.h
@@ -11,8 +11,10 @@
struct ovs_gso_cb {
struct ovs_skb_cb dp_cb;
- sk_buff_data_t inner_network_header;
- sk_buff_data_t inner_mac_header;
+ u16 inner_network_header; /* Offset from
+ * inner_mac_header */
+ /* 16bit hole */
+ sk_buff_data_t inner_mac_header; /* Offset from skb->head */
void (*fix_segment)(struct sk_buff *);
};
#define OVS_GSO_CB(skb) ((struct ovs_gso_cb *)(skb)->cb)
@@ -20,12 +22,6 @@ struct ovs_gso_cb {
#define skb_inner_network_header rpl_skb_inner_network_header
#ifdef NET_SKBUFF_DATA_USES_OFFSET
-#define skb_inner_network_header rpl_skb_inner_network_header
-static inline unsigned char *skb_inner_network_header(const struct sk_buff *skb)
-{
- return skb->head + OVS_GSO_CB(skb)->inner_network_header;
-}
-
#define skb_inner_mac_header rpl_skb_inner_mac_header
static inline unsigned char *skb_inner_mac_header(const struct sk_buff *skb)
{
@@ -34,12 +30,6 @@ static inline unsigned char *skb_inner_mac_header(const struct sk_buff *skb)
#else
-#define skb_inner_network_header rpl_skb_inner_network_header
-static inline unsigned char *skb_inner_network_header(const struct sk_buff *skb)
-{
- return OVS_GSO_CB(skb)->inner_network_header;
-}
-
#define skb_inner_mac_header rpl_skb_inner_mac_header
static inline unsigned char *skb_inner_mac_header(const struct sk_buff *skb)
{
@@ -48,6 +38,13 @@ static inline unsigned char *skb_inner_mac_header(const struct sk_buff *skb)
#endif
+#define skb_inner_network_header rpl_skb_inner_network_header
+static inline unsigned char *skb_inner_network_header(const struct sk_buff *skb)
+{
+ return skb_inner_mac_header(skb) +
+ OVS_GSO_CB(skb)->inner_network_header;
+}
+
#define skb_inner_network_offset rpl_skb_inner_network_offset
static inline int skb_inner_network_offset(const struct sk_buff *skb)
{
@@ -64,7 +61,8 @@ static inline int skb_inner_mac_offset(const struct sk_buff *skb)
static inline void skb_reset_inner_headers(struct sk_buff *skb)
{
BUILD_BUG_ON(sizeof(struct ovs_gso_cb) > FIELD_SIZEOF(struct sk_buff, cb));
- OVS_GSO_CB(skb)->inner_network_header = skb->network_header;
+ OVS_GSO_CB(skb)->inner_network_header = skb->network_header -
+ skb->mac_header;
OVS_GSO_CB(skb)->inner_mac_header = skb->mac_header;
OVS_GSO_CB(skb)->fix_segment = NULL;
--
1.8.4
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] datapath: 16bit inner_network_header field in struct ovs_gso_cb
[not found] ` <20140520233145.GA30260-/R6kz+dDXgpPR4JQBCEnsQ@public.gmane.org>
@ 2014-05-21 0:14 ` Jesse Gross
2014-05-21 1:18 ` Simon Horman
0 siblings, 1 reply; 5+ messages in thread
From: Jesse Gross @ 2014-05-21 0:14 UTC (permalink / raw)
To: Simon Horman; +Cc: dev-yBygre7rU0TnMu66kgdUjQ@public.gmane.org, netdev
On Tue, May 20, 2014 at 4:31 PM, Simon Horman <horms-/R6kz+dDXgpPR4JQBCEnsQ@public.gmane.org> wrote:
> On Tue, May 20, 2014 at 12:54:32PM -0700, Jesse Gross wrote:
>> On Tue, May 20, 2014 at 3:41 AM, Simon Horman <horms-/R6kz+dDXgpPR4JQBCEnsQ@public.gmane.org> wrote:
>> > diff --git a/datapath/linux/compat/gso.h b/datapath/linux/compat/gso.h
>> > index b83a4c3..f459c18 100644
>> > --- a/datapath/linux/compat/gso.h
>> > +++ b/datapath/linux/compat/gso.h
>> > #ifdef NET_SKBUFF_DATA_USES_OFFSET
>> > -#define skb_inner_network_header rpl_skb_inner_network_header
>> > -static inline unsigned char *skb_inner_network_header(const struct sk_buff *skb)
>> > -{
>> > - return skb->head + OVS_GSO_CB(skb)->inner_network_header;
>> > -}
>> > -
>> > #define skb_inner_mac_header rpl_skb_inner_mac_header
>> > static inline unsigned char *skb_inner_mac_header(const struct sk_buff *skb)
>> > {
>> > return skb->head + OVS_GSO_CB(skb)->inner_mac_header;
>> > }
>> >
>> > +#define skb_inner_network_header rpl_skb_inner_network_header
>> > +static inline unsigned char *skb_inner_network_header(const struct sk_buff *skb)
>> > +{
>> > + return skb_inner_mac_header(skb) +
>> > + OVS_GSO_CB(skb)->inner_network_header;
>> > +}
>> > +
>> > #else
>>
>> This looks mostly fine to me but doesn't this need to be outside the
>> #ifdef NET_SKBUFF_DATA_USES_OFFSET block? Otherwise we will treat the
>> offset as a pointer on 32 bit kernels.
>
> Thanks, Somehow I completely missed that.
> How about this?
>
>
> From: Simon Horman <horms-/R6kz+dDXgpPR4JQBCEnsQ@public.gmane.org>
>
> [PATCH v1.1] datapath: 16bit inner_network_header field in struct ovs_gso_cb
>
> The motivation for this is to create a 16bit hole in struct ovs_gso_cb
> which may be used for the inner_protocol field which is needed
> for the proposed implementation of compatibility for MPLS GSO segmentation.
>
> This should be safe as inner_network_header is now an offset to
> the inner_mac_header rather than skb->head.
>
> As pointed out by Thomas Graf simply making both inner offsets 16bis is not
> safe as there have been cases of overflow with "with collapsed TCP frames
> on IB when the headroom grew beyond 64K. See commit 50bceae9bd ``tcp:
> Reallocate headroom if it would overflow csum_start'' for additional
> details."
>
> This patch is based on suggestions by Thomas Graf and Jesse Gross.
>
> Cc: Thomas Graf <tgraf-G/eBtMaohhA@public.gmane.org>
> Cc: Jesse Gross <jesse-l0M0P4e3n4LQT0dZR+AlfA@public.gmane.org>
> Signed-off-by: Simon Horman <horms-/R6kz+dDXgpPR4JQBCEnsQ@public.gmane.org>
Applied, thanks.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] datapath: 16bit inner_network_header field in struct ovs_gso_cb
2014-05-21 0:14 ` Jesse Gross
@ 2014-05-21 1:18 ` Simon Horman
0 siblings, 0 replies; 5+ messages in thread
From: Simon Horman @ 2014-05-21 1:18 UTC (permalink / raw)
To: Jesse Gross; +Cc: dev@openvswitch.org, netdev, Thomas Graf
On Tue, May 20, 2014 at 05:14:25PM -0700, Jesse Gross wrote:
> On Tue, May 20, 2014 at 4:31 PM, Simon Horman <horms@verge.net.au> wrote:
> > On Tue, May 20, 2014 at 12:54:32PM -0700, Jesse Gross wrote:
> >> On Tue, May 20, 2014 at 3:41 AM, Simon Horman <horms@verge.net.au> wrote:
> >> > diff --git a/datapath/linux/compat/gso.h b/datapath/linux/compat/gso.h
> >> > index b83a4c3..f459c18 100644
> >> > --- a/datapath/linux/compat/gso.h
> >> > +++ b/datapath/linux/compat/gso.h
> >> > #ifdef NET_SKBUFF_DATA_USES_OFFSET
> >> > -#define skb_inner_network_header rpl_skb_inner_network_header
> >> > -static inline unsigned char *skb_inner_network_header(const struct sk_buff *skb)
> >> > -{
> >> > - return skb->head + OVS_GSO_CB(skb)->inner_network_header;
> >> > -}
> >> > -
> >> > #define skb_inner_mac_header rpl_skb_inner_mac_header
> >> > static inline unsigned char *skb_inner_mac_header(const struct sk_buff *skb)
> >> > {
> >> > return skb->head + OVS_GSO_CB(skb)->inner_mac_header;
> >> > }
> >> >
> >> > +#define skb_inner_network_header rpl_skb_inner_network_header
> >> > +static inline unsigned char *skb_inner_network_header(const struct sk_buff *skb)
> >> > +{
> >> > + return skb_inner_mac_header(skb) +
> >> > + OVS_GSO_CB(skb)->inner_network_header;
> >> > +}
> >> > +
> >> > #else
> >>
> >> This looks mostly fine to me but doesn't this need to be outside the
> >> #ifdef NET_SKBUFF_DATA_USES_OFFSET block? Otherwise we will treat the
> >> offset as a pointer on 32 bit kernels.
> >
> > Thanks, Somehow I completely missed that.
> > How about this?
> >
> >
> > From: Simon Horman <horms@verge.net.au>
> >
> > [PATCH v1.1] datapath: 16bit inner_network_header field in struct ovs_gso_cb
> >
> > The motivation for this is to create a 16bit hole in struct ovs_gso_cb
> > which may be used for the inner_protocol field which is needed
> > for the proposed implementation of compatibility for MPLS GSO segmentation.
> >
> > This should be safe as inner_network_header is now an offset to
> > the inner_mac_header rather than skb->head.
> >
> > As pointed out by Thomas Graf simply making both inner offsets 16bis is not
> > safe as there have been cases of overflow with "with collapsed TCP frames
> > on IB when the headroom grew beyond 64K. See commit 50bceae9bd ``tcp:
> > Reallocate headroom if it would overflow csum_start'' for additional
> > details."
> >
> > This patch is based on suggestions by Thomas Graf and Jesse Gross.
> >
> > Cc: Thomas Graf <tgraf@suug.ch>
> > Cc: Jesse Gross <jesse@nicira.com>
> > Signed-off-by: Simon Horman <horms@verge.net.au>
>
> Applied, thanks.
Thanks
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2014-05-21 1:18 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-05-20 10:41 [PATCH] datapath: 16bit inner_network_header field in struct ovs_gso_cb Simon Horman
[not found] ` <1400582464-2917-1-git-send-email-horms-/R6kz+dDXgpPR4JQBCEnsQ@public.gmane.org>
2014-05-20 19:54 ` Jesse Gross
2014-05-20 23:31 ` Simon Horman
[not found] ` <20140520233145.GA30260-/R6kz+dDXgpPR4JQBCEnsQ@public.gmane.org>
2014-05-21 0:14 ` Jesse Gross
2014-05-21 1:18 ` Simon Horman
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox