Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH rfc] packet: zerocopy packet_snd
From: Michael S. Tsirkin @ 2014-11-26 21:20 UTC (permalink / raw)
  To: Willem de Bruijn
  Cc: Network Development, David Miller, Eric Dumazet, Daniel Borkmann
In-Reply-To: <CA+FuTSdYB4rDMH3gAAMwaRdbqN58f_SxLz=C3fcCACw_KosGXw@mail.gmail.com>

On Wed, Nov 26, 2014 at 02:59:34PM -0500, Willem de Bruijn wrote:
> > The main problem with zero copy ATM is with queueing disciplines
> > which might keep the socket around essentially forever.
> > The case was described here:
> > https://lkml.org/lkml/2014/1/17/105
> > and of course this will make it more serious now that
> > more applications will be able to do this, so
> > chances that an administrator enables this
> > are higher.
> 
> The denial of service issue raised there, that a single queue can
> block an entire virtio-net device, is less problematic in the case of
> packet sockets. A socket can run out of sk_wmem_alloc, but a prudent
> application can increase the limit or use separate sockets for
> separate flows.

Sounds like this interface is very hard to use correctly.

> > One possible solution is some kind of timer orphaning frags
> > for skbs that have been around for too long.
> 
> Perhaps this can be approximated without an explicit timer by calling
> skb_copy_ubufs on enqueue whenever qlen exceeds a threshold value?

Not sure.  I'll have to see that patch to judge.

> >
> >> ---
> >>  include/linux/skbuff.h        |   1 +
> >>  include/linux/socket.h        |   1 +
> >>  include/uapi/linux/errqueue.h |   1 +
> >>  net/packet/af_packet.c        | 110 ++++++++++++++++++++++++++++++++++++++----
> >>  4 files changed, 103 insertions(+), 10 deletions(-)
> >>
> >> diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
> >> index 78c299f..8e661d2 100644
> >> --- a/include/linux/skbuff.h
> >> +++ b/include/linux/skbuff.h
> >> @@ -295,6 +295,7 @@ struct ubuf_info {
> >>       void (*callback)(struct ubuf_info *, bool zerocopy_success);
> >>       void *ctx;
> >>       unsigned long desc;
> >> +     void *callback_priv;
> >>  };
> >>
> >>  /* This data is invariant across clones and lives at
> >> diff --git a/include/linux/socket.h b/include/linux/socket.h
> >> index de52228..0a2e0ea 100644
> >> --- a/include/linux/socket.h
> >> +++ b/include/linux/socket.h
> >> @@ -265,6 +265,7 @@ struct ucred {
> >>  #define MSG_SENDPAGE_NOTLAST 0x20000 /* sendpage() internal : not the last page */
> >>  #define MSG_EOF         MSG_FIN
> >>
> >> +#define MSG_ZEROCOPY 0x4000000       /* Pin user pages */
> >>  #define MSG_FASTOPEN 0x20000000      /* Send data in TCP SYN */
> >>  #define MSG_CMSG_CLOEXEC 0x40000000  /* Set close_on_exec for file
> >>                                          descriptor received through
> >> diff --git a/include/uapi/linux/errqueue.h b/include/uapi/linux/errqueue.h
> >> index 07bdce1..61bf318 100644
> >> --- a/include/uapi/linux/errqueue.h
> >> +++ b/include/uapi/linux/errqueue.h
> >> @@ -19,6 +19,7 @@ struct sock_extended_err {
> >>  #define SO_EE_ORIGIN_ICMP6   3
> >>  #define SO_EE_ORIGIN_TXSTATUS        4
> >>  #define SO_EE_ORIGIN_TIMESTAMPING SO_EE_ORIGIN_TXSTATUS
> >> +#define SO_EE_ORIGIN_UPAGE   5
> >>
> >>  #define SO_EE_OFFENDER(ee)   ((struct sockaddr*)((ee)+1))
> >>
> >> diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
> >> index 58af5802..367c23a 100644
> >> --- a/net/packet/af_packet.c
> >> +++ b/net/packet/af_packet.c
> >> @@ -2370,28 +2370,112 @@ out:
> >>
> >>  static struct sk_buff *packet_alloc_skb(struct sock *sk, size_t prepad,
> >>                                       size_t reserve, size_t len,
> >> -                                     size_t linear, int noblock,
> >> +                                     size_t linear, int flags,
> >>                                       int *err)
> >>  {
> >>       struct sk_buff *skb;
> >> +     size_t data_len;
> >>
> >> -     /* Under a page?  Don't bother with paged skb. */
> >> -     if (prepad + len < PAGE_SIZE || !linear)
> >> -             linear = len;
> >> +     if (flags & MSG_ZEROCOPY) {
> >> +             /* Minimize linear, but respect header lower bound */
> >> +             linear = min(len, max_t(size_t, linear, MAX_HEADER));
> >> +             data_len = 0;
> >> +     } else {
> >> +             /* Under a page? Don't bother with paged skb. */
> >> +             if (prepad + len < PAGE_SIZE || !linear)
> >> +                     linear = len;
> >> +             data_len = len - linear;
> >> +     }
> >>
> >> -     skb = sock_alloc_send_pskb(sk, prepad + linear, len - linear, noblock,
> >> -                                err, 0);
> >> +     skb = sock_alloc_send_pskb(sk, prepad + linear, data_len,
> >> +                                flags & MSG_DONTWAIT, err, 0);
> >>       if (!skb)
> >>               return NULL;
> >>
> >>       skb_reserve(skb, reserve);
> >>       skb_put(skb, linear);
> >> -     skb->data_len = len - linear;
> >> -     skb->len += len - linear;
> >> +     skb->data_len = data_len;
> >> +     skb->len += data_len;
> >>
> >>       return skb;
> >>  }
> >>
> >> +/* release zerocopy resources and avoid destructor callback on kfree */
> >> +static void packet_snd_zerocopy_free(struct sk_buff *skb)
> >> +{
> >> +     struct ubuf_info *uarg = skb_shinfo(skb)->destructor_arg;
> >> +
> >> +     if (uarg) {
> >> +             kfree_skb(uarg->callback_priv);
> >> +             sock_put((struct sock *) uarg->ctx);
> >> +             kfree(uarg);
> >> +
> >> +             skb_shinfo(skb)->destructor_arg = NULL;
> >> +             skb_shinfo(skb)->tx_flags &= ~SKBTX_DEV_ZEROCOPY;
> >> +     }
> >> +}
> >> +
> >> +static void packet_snd_zerocopy_callback(struct ubuf_info *uarg,
> >> +                                      bool zerocopy_success)
> >> +{
> >> +     struct sk_buff *err_skb;
> >> +     struct sock *err_sk;
> >> +     struct sock_exterr_skb *serr;
> >> +
> >> +     err_sk = uarg->ctx;
> >> +     err_skb = uarg->callback_priv;
> >> +
> >> +     serr = SKB_EXT_ERR(err_skb);
> >> +     memset(serr, 0, sizeof(*serr));
> >> +     serr->ee.ee_errno = ENOMSG;
> >> +     serr->ee.ee_origin = SO_EE_ORIGIN_UPAGE;
> >> +     serr->ee.ee_data = uarg->desc & 0xFFFFFFFF;
> >> +     serr->ee.ee_info = ((u64) uarg->desc) >> 32;
> >> +     if (sock_queue_err_skb(err_sk, err_skb))
> >> +             kfree_skb(err_skb);
> >> +
> >> +     kfree(uarg);
> >> +     sock_put(err_sk);
> >> +}
> >> +
> >> +static int packet_zerocopy_sg_from_iovec(struct sk_buff *skb,
> >> +                                      struct msghdr *msg)
> >> +{
> >> +     struct ubuf_info *uarg = NULL;
> >> +     int ret;
> >> +
> >> +     if (iov_pages(msg->msg_iov, 0, msg->msg_iovlen) > MAX_SKB_FRAGS)
> >> +             return -EMSGSIZE;
> >> +
> >> +     uarg = kzalloc(sizeof(*uarg), GFP_KERNEL);
> >> +     if (!uarg)
> >> +             return -ENOMEM;
> >> +
> >> +     uarg->callback_priv = alloc_skb(0, GFP_KERNEL);
> >> +     if (!uarg->callback_priv) {
> >> +             kfree(uarg);
> >> +             return -ENOMEM;
> >> +     }
> >> +
> >> +     ret = zerocopy_sg_from_iovec(skb, msg->msg_iov, 0, msg->msg_iovlen);
> >> +     if (ret) {
> >> +             kfree_skb(uarg->callback_priv);
> >> +             kfree(uarg);
> >> +             return -EIO;
> >> +     }
> >> +
> >> +     sock_hold(skb->sk);
> >> +     uarg->ctx = skb->sk;
> >> +     uarg->callback = packet_snd_zerocopy_callback;
> >> +     uarg->desc = (unsigned long) msg->msg_iov[0].iov_base;
> >> +
> >> +     skb_shinfo(skb)->destructor_arg = uarg;
> >> +     skb_shinfo(skb)->tx_flags |= SKBTX_DEV_ZEROCOPY;
> >> +     skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG;
> >> +
> >> +     return 0;
> >> +}
> >> +
> >>  static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
> >>  {
> >>       struct sock *sk = sock->sk;
> >> @@ -2408,6 +2492,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
> >>       unsigned short gso_type = 0;
> >>       int hlen, tlen;
> >>       int extra_len = 0;
> >> +     bool zerocopy = msg->msg_flags & MSG_ZEROCOPY;
> >>
> >>       /*
> >>        *      Get and verify the address.
> >> @@ -2501,7 +2586,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
> >>       hlen = LL_RESERVED_SPACE(dev);
> >>       tlen = dev->needed_tailroom;
> >>       skb = packet_alloc_skb(sk, hlen + tlen, hlen, len, vnet_hdr.hdr_len,
> >> -                            msg->msg_flags & MSG_DONTWAIT, &err);
> >> +                            msg->msg_flags, &err);
> >>       if (skb == NULL)
> >>               goto out_unlock;
> >>
> >> @@ -2518,7 +2603,11 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
> >>       }
> >>
> >>       /* Returns -EFAULT on error */
> >> -     err = skb_copy_datagram_from_iovec(skb, offset, msg->msg_iov, 0, len);
> >> +     if (zerocopy)
> >> +             err = packet_zerocopy_sg_from_iovec(skb, msg);
> >> +     else
> >> +             err = skb_copy_datagram_from_iovec(skb, offset, msg->msg_iov,
> >> +                                                0, len);
> >>       if (err)
> >>               goto out_free;
> >>
> >> @@ -2578,6 +2667,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
> >>       return len;
> >>
> >>  out_free:
> >> +     packet_snd_zerocopy_free(skb);
> >>       kfree_skb(skb);
> >>  out_unlock:
> >>       if (dev)
> >> --
> >> 2.1.0.rc2.206.gedb03e5

^ permalink raw reply

* Re: [PATCH rfc] packet: zerocopy packet_snd
From: Michael S. Tsirkin @ 2014-11-26 21:17 UTC (permalink / raw)
  To: Willem de Bruijn
  Cc: Network Development, David Miller, Eric Dumazet, Daniel Borkmann
In-Reply-To: <CA+FuTSdYB4rDMH3gAAMwaRdbqN58f_SxLz=C3fcCACw_KosGXw@mail.gmail.com>

On Wed, Nov 26, 2014 at 02:59:34PM -0500, Willem de Bruijn wrote:
> > The main problem with zero copy ATM is with queueing disciplines
> > which might keep the socket around essentially forever.
> > The case was described here:
> > https://lkml.org/lkml/2014/1/17/105
> > and of course this will make it more serious now that
> > more applications will be able to do this, so
> > chances that an administrator enables this
> > are higher.
> 
> The denial of service issue raised there, that a single queue can
> block an entire virtio-net device, is less problematic in the case of
> packet sockets. A socket can run out of sk_wmem_alloc, but a prudent
> application can increase the limit or use separate sockets for
> separate flows.

Socket per flow? Maybe just use TCP then?  increasing the limit
sounds like a wrong solution, it hurts security.

> > One possible solution is some kind of timer orphaning frags
> > for skbs that have been around for too long.
> 
> Perhaps this can be approximated without an explicit timer by calling
> skb_copy_ubufs on enqueue whenever qlen exceeds a threshold value?

Hard to say. Will have to see that patch to judge how robust this is.


> >
> >> ---
> >>  include/linux/skbuff.h        |   1 +
> >>  include/linux/socket.h        |   1 +
> >>  include/uapi/linux/errqueue.h |   1 +
> >>  net/packet/af_packet.c        | 110 ++++++++++++++++++++++++++++++++++++++----
> >>  4 files changed, 103 insertions(+), 10 deletions(-)
> >>
> >> diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
> >> index 78c299f..8e661d2 100644
> >> --- a/include/linux/skbuff.h
> >> +++ b/include/linux/skbuff.h
> >> @@ -295,6 +295,7 @@ struct ubuf_info {
> >>       void (*callback)(struct ubuf_info *, bool zerocopy_success);
> >>       void *ctx;
> >>       unsigned long desc;
> >> +     void *callback_priv;
> >>  };
> >>
> >>  /* This data is invariant across clones and lives at
> >> diff --git a/include/linux/socket.h b/include/linux/socket.h
> >> index de52228..0a2e0ea 100644
> >> --- a/include/linux/socket.h
> >> +++ b/include/linux/socket.h
> >> @@ -265,6 +265,7 @@ struct ucred {
> >>  #define MSG_SENDPAGE_NOTLAST 0x20000 /* sendpage() internal : not the last page */
> >>  #define MSG_EOF         MSG_FIN
> >>
> >> +#define MSG_ZEROCOPY 0x4000000       /* Pin user pages */
> >>  #define MSG_FASTOPEN 0x20000000      /* Send data in TCP SYN */
> >>  #define MSG_CMSG_CLOEXEC 0x40000000  /* Set close_on_exec for file
> >>                                          descriptor received through
> >> diff --git a/include/uapi/linux/errqueue.h b/include/uapi/linux/errqueue.h
> >> index 07bdce1..61bf318 100644
> >> --- a/include/uapi/linux/errqueue.h
> >> +++ b/include/uapi/linux/errqueue.h
> >> @@ -19,6 +19,7 @@ struct sock_extended_err {
> >>  #define SO_EE_ORIGIN_ICMP6   3
> >>  #define SO_EE_ORIGIN_TXSTATUS        4
> >>  #define SO_EE_ORIGIN_TIMESTAMPING SO_EE_ORIGIN_TXSTATUS
> >> +#define SO_EE_ORIGIN_UPAGE   5
> >>
> >>  #define SO_EE_OFFENDER(ee)   ((struct sockaddr*)((ee)+1))
> >>
> >> diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
> >> index 58af5802..367c23a 100644
> >> --- a/net/packet/af_packet.c
> >> +++ b/net/packet/af_packet.c
> >> @@ -2370,28 +2370,112 @@ out:
> >>
> >>  static struct sk_buff *packet_alloc_skb(struct sock *sk, size_t prepad,
> >>                                       size_t reserve, size_t len,
> >> -                                     size_t linear, int noblock,
> >> +                                     size_t linear, int flags,
> >>                                       int *err)
> >>  {
> >>       struct sk_buff *skb;
> >> +     size_t data_len;
> >>
> >> -     /* Under a page?  Don't bother with paged skb. */
> >> -     if (prepad + len < PAGE_SIZE || !linear)
> >> -             linear = len;
> >> +     if (flags & MSG_ZEROCOPY) {
> >> +             /* Minimize linear, but respect header lower bound */
> >> +             linear = min(len, max_t(size_t, linear, MAX_HEADER));
> >> +             data_len = 0;
> >> +     } else {
> >> +             /* Under a page? Don't bother with paged skb. */
> >> +             if (prepad + len < PAGE_SIZE || !linear)
> >> +                     linear = len;
> >> +             data_len = len - linear;
> >> +     }
> >>
> >> -     skb = sock_alloc_send_pskb(sk, prepad + linear, len - linear, noblock,
> >> -                                err, 0);
> >> +     skb = sock_alloc_send_pskb(sk, prepad + linear, data_len,
> >> +                                flags & MSG_DONTWAIT, err, 0);
> >>       if (!skb)
> >>               return NULL;
> >>
> >>       skb_reserve(skb, reserve);
> >>       skb_put(skb, linear);
> >> -     skb->data_len = len - linear;
> >> -     skb->len += len - linear;
> >> +     skb->data_len = data_len;
> >> +     skb->len += data_len;
> >>
> >>       return skb;
> >>  }
> >>
> >> +/* release zerocopy resources and avoid destructor callback on kfree */
> >> +static void packet_snd_zerocopy_free(struct sk_buff *skb)
> >> +{
> >> +     struct ubuf_info *uarg = skb_shinfo(skb)->destructor_arg;
> >> +
> >> +     if (uarg) {
> >> +             kfree_skb(uarg->callback_priv);
> >> +             sock_put((struct sock *) uarg->ctx);
> >> +             kfree(uarg);
> >> +
> >> +             skb_shinfo(skb)->destructor_arg = NULL;
> >> +             skb_shinfo(skb)->tx_flags &= ~SKBTX_DEV_ZEROCOPY;
> >> +     }
> >> +}
> >> +
> >> +static void packet_snd_zerocopy_callback(struct ubuf_info *uarg,
> >> +                                      bool zerocopy_success)
> >> +{
> >> +     struct sk_buff *err_skb;
> >> +     struct sock *err_sk;
> >> +     struct sock_exterr_skb *serr;
> >> +
> >> +     err_sk = uarg->ctx;
> >> +     err_skb = uarg->callback_priv;
> >> +
> >> +     serr = SKB_EXT_ERR(err_skb);
> >> +     memset(serr, 0, sizeof(*serr));
> >> +     serr->ee.ee_errno = ENOMSG;
> >> +     serr->ee.ee_origin = SO_EE_ORIGIN_UPAGE;
> >> +     serr->ee.ee_data = uarg->desc & 0xFFFFFFFF;
> >> +     serr->ee.ee_info = ((u64) uarg->desc) >> 32;
> >> +     if (sock_queue_err_skb(err_sk, err_skb))
> >> +             kfree_skb(err_skb);
> >> +
> >> +     kfree(uarg);
> >> +     sock_put(err_sk);
> >> +}
> >> +
> >> +static int packet_zerocopy_sg_from_iovec(struct sk_buff *skb,
> >> +                                      struct msghdr *msg)
> >> +{
> >> +     struct ubuf_info *uarg = NULL;
> >> +     int ret;
> >> +
> >> +     if (iov_pages(msg->msg_iov, 0, msg->msg_iovlen) > MAX_SKB_FRAGS)
> >> +             return -EMSGSIZE;
> >> +
> >> +     uarg = kzalloc(sizeof(*uarg), GFP_KERNEL);
> >> +     if (!uarg)
> >> +             return -ENOMEM;
> >> +
> >> +     uarg->callback_priv = alloc_skb(0, GFP_KERNEL);
> >> +     if (!uarg->callback_priv) {
> >> +             kfree(uarg);
> >> +             return -ENOMEM;
> >> +     }
> >> +
> >> +     ret = zerocopy_sg_from_iovec(skb, msg->msg_iov, 0, msg->msg_iovlen);
> >> +     if (ret) {
> >> +             kfree_skb(uarg->callback_priv);
> >> +             kfree(uarg);
> >> +             return -EIO;
> >> +     }
> >> +
> >> +     sock_hold(skb->sk);
> >> +     uarg->ctx = skb->sk;
> >> +     uarg->callback = packet_snd_zerocopy_callback;
> >> +     uarg->desc = (unsigned long) msg->msg_iov[0].iov_base;
> >> +
> >> +     skb_shinfo(skb)->destructor_arg = uarg;
> >> +     skb_shinfo(skb)->tx_flags |= SKBTX_DEV_ZEROCOPY;
> >> +     skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG;
> >> +
> >> +     return 0;
> >> +}
> >> +
> >>  static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
> >>  {
> >>       struct sock *sk = sock->sk;
> >> @@ -2408,6 +2492,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
> >>       unsigned short gso_type = 0;
> >>       int hlen, tlen;
> >>       int extra_len = 0;
> >> +     bool zerocopy = msg->msg_flags & MSG_ZEROCOPY;
> >>
> >>       /*
> >>        *      Get and verify the address.
> >> @@ -2501,7 +2586,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
> >>       hlen = LL_RESERVED_SPACE(dev);
> >>       tlen = dev->needed_tailroom;
> >>       skb = packet_alloc_skb(sk, hlen + tlen, hlen, len, vnet_hdr.hdr_len,
> >> -                            msg->msg_flags & MSG_DONTWAIT, &err);
> >> +                            msg->msg_flags, &err);
> >>       if (skb == NULL)
> >>               goto out_unlock;
> >>
> >> @@ -2518,7 +2603,11 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
> >>       }
> >>
> >>       /* Returns -EFAULT on error */
> >> -     err = skb_copy_datagram_from_iovec(skb, offset, msg->msg_iov, 0, len);
> >> +     if (zerocopy)
> >> +             err = packet_zerocopy_sg_from_iovec(skb, msg);
> >> +     else
> >> +             err = skb_copy_datagram_from_iovec(skb, offset, msg->msg_iov,
> >> +                                                0, len);
> >>       if (err)
> >>               goto out_free;
> >>
> >> @@ -2578,6 +2667,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
> >>       return len;
> >>
> >>  out_free:
> >> +     packet_snd_zerocopy_free(skb);
> >>       kfree_skb(skb);
> >>  out_unlock:
> >>       if (dev)
> >> --
> >> 2.1.0.rc2.206.gedb03e5

^ permalink raw reply

* Re: [PATCH rfc 1/4] net-timestamp: pull headers for SOCK_STREAM
From: Willem de Bruijn @ 2014-11-26 21:03 UTC (permalink / raw)
  To: Andy Lutomirski; +Cc: David Miller, Network Development, Richard Cochran
In-Reply-To: <CALCETrXHdSVC-YLsdjHxAp3rU2gGFZaz8NNgaTKYgjM-ah3z+A@mail.gmail.com>

On Tue, Nov 25, 2014 at 4:39 PM, Andy Lutomirski <luto@amacapital.net> wrote:
> On Tue, Nov 25, 2014 at 11:54 AM, David Miller <davem@davemloft.net> wrote:
>> From: Willem de Bruijn <willemb@google.com>
>> Date: Tue, 25 Nov 2014 14:52:00 -0500
>>
>>> On Tue, Nov 25, 2014 at 1:42 PM, David Miller <davem@davemloft.net> wrote:
>>>> From: Willem de Bruijn <willemb@google.com>
>>>> Date: Tue, 25 Nov 2014 12:58:03 -0500
>>>>
>>>> What's the harm in exposing the headers?  Either it's harmful, and
>>>> therefore doing so for UDP is bad too, or it's harmless and
>>>
>>> Headers may expose information not available otherwise. I don't
>>> immediately see critical problems, but that does not mean that they
>>> might not lurk there.
>>>
>>> We so far avoid exposing the sequence number, though keeping it hidden
>>> is more about third parties. More in general, unprivileged processes
>>> may start requesting timestamps only to learn tcp state that they
>>> should either get from tcpinfo or cannot currently get at all, likely
>>> for good reason. A far-fetched example is identifying admin iptables
>>> tos mangling rules by reading the tos bits at the driver layer. At least
>>> on my machine, iptables -L is privileged.
>>>
>>>> we should probably leave it alone to not risk breaking anyone.
>>>
>>> That's fair. I sent it for rfc first for that reason. I won't resubmit
>>> unless more serious concerns are raised.
>>
>> I just worry about the potential breakage.
>>
>> Your concerns are valid... I honestly don't know what we should do here.
>> Both choices have merit.
>
> Here's a scenario in which giving the headers might be dangerous:
>
> Suppose I create a network namespace that's designed to contain
> something, e.g. a Tor or Tor-like client, that shouldn't know any of
> its public addressing information.  I might assign something like a
> tunnel interface to the namespace, but, if the contained code can get
> lower-level headers, it might learn something that would identify the
> *other* end of the tunnel, which wouldn't be so good.  Admittedly,
> this would be just one of several things that would require care to
> get this right.

network namespaces are an interesting case, indeed.

>
> Also, what happens if the output is transformed by ipsec?  Does the
> timestamp message show the ciphertext?
>
> TBH, I'd rather send no payload at all and have an scm message that
> the sender provides that specifies a cookie identifying the particular
> sent data.  But that ship mostly sailed awhile ago.
>
> For bytestreams, though, isn't this all new in 3.18?  Or am I off by a release.

It was added in 3.17. That is still very recent.

One third option, though hardly pretty, is to put display of headers
under administrator control. An application cannot easily infer whether
headers are stripped, and legacy applications do not even know to try.
So, this is a bit too crude:

+    if (sk->sk_protocol == IPPROTO_TCP && sysctl_net_blind_errqueue)
+        skb_pull(skb, skb_transport_offset(skb) + tcp_hdrlen(skb));
+    else if (sk->sk_protocol == IPPROTO_UDP && sysctl_net_blind_errqueue >= 2)
+        skb_pull(skb, skb_transport_offset(skb) + sizeof(struct udphdr));

An alternative is to add a timestamping option to skip headers (or
even full payload, basically
http://patchwork.ozlabs.org/patch/366967/) and give the administrator
a sysctl to drop all requests that do not pass this flag. The intent
is that future proof applications will start requesting the flag, and
relying on the ts counter. Hardened installations can set the sysctl
from the start, accepting possible breakage.

^ permalink raw reply

* 3.12.33 Bug with ipvs
From: Smart Weblications GmbH - Florian Wiessner @ 2014-11-26 20:55 UTC (permalink / raw)
  To: netdev

Hi netdev,

On 3.12.33 i see this every 3 hours or so on a box with ip_vs running with a
setup which made no problems on 3.10.40. Could someone give me hints how to
debug this? It seems to happen instantly, when i add ip_vs_ftp and have some nat
rules. Setup is like this:

host connected to net with bond0 over eth0 eth1 (bonding mode6)
bond0 added to br0

running 5 lxc using veth on br0 as real servers to use for ipvs

we use net 10.10.1.0/24  10.10.0.0/24  on lxc, 10.10.1.1 as gw-ip on the host
and vip bound to the host so we do some aditional NAT:

iptables -t nat -A POSTROUTING -o br0 -s 10.10.0.0/24 -j SNAT --to 192.168.1.61
iptables -t nat -A POSTROUTING -o br0 -s 10.10.1.0/24 ! -d 192.168.1.0/26 -j
SNAT --to 192.168.1.62

then setup additional nat for ftp passive to a realserver:
iptables -t nat -A PREROUTING -i br0 -d 192.168.1.62 -p tcp -m multiport
--dports 64000:64444 -j DNAT --to 10.10.1.20

we also use ipv6 in the lxc container, but do not use any ip_vs ipv6 rules


[13230.422498] BUG: unable to handle kernel paging request at 00000000000600d0
[13230.422541] IP: [<ffffffff814ff2fc>] xfrm_selector_match+0x25/0x2f6
[13230.422577] PGD 57fb0d067 PUD 718403067 PMD 0
[13230.422682] Oops: 0000 [#1] SMP
[13230.422711] Modules linked in: ip6table_filter ip6_tables ebt_arp ebt_ip
ebtable_nat ebtables act_police cls_u32 sch_ingress arptable_filter arp_tables
netconsole xmand cpufreq_powersave cpufreq_conservative cpufreq_userspace
ocfs2_stack_o2cb ocfs2_dlm bridge stp llc bonding fuse nf_conntrack_ftp 8021q
openvswitch gre vxlan xt_collia_generic serpent_generic blowfish_generic
blowfish_common cast5_generic cast_common xcbc sha512_generic crypto_null af_key
psmouse serio_raw lpc_ich i2c_i801 mfd_c
[13230.423318] CPU: 6 PID: 18038 Comm: kvm.php Not tainted 3.12.33 #6
[13230.423348] Hardware name: Supermicro X9SCI/X9SCA/X9SCI/X9SCA, BIOS 1.1a
09/28/2011
[13230.423395] task: ffff88043803c680 ti: ffff880162836000 task.ti: ffff880162836000
[13230.423440] RIP: 0010:[<ffffffff814ff2fc>]  [<ffffffff814ff2fc>]
xfrm_selector_match+0x25/0x2f6
[13230.423491] RSP: 0018:ffff88083fd83a68  EFLAGS: 00010246
[13230.423519] RAX: 0000000000000001 RBX: ffff88083fd83b88 RCX: ffff8804ce5c68c0
[13230.423549] RDX: 0000000000000002 RSI: ffff88083fd83b88 RDI: 00000000000600a6
[13230.423580] RBP: 00000000000600a6 R08: 0000000000000000 R09: ffff88083fd83b08
[13230.423611] R10: 0000000000000000 R11: 0000000000000001 R12: ffff88083fd83b88
[13230.423641] R13: 0000000000000001 R14: ffffffff81812040 R15: ffffffffa01ab3b0
[13230.423672] FS:  00007f6fd48e4720(0000) GS:ffff88083fd80000(0000)
knlGS:0000000000000000
[13230.423725] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[13230.423758] CR2: 00000000000600d0 CR3: 00000007188b1000 CR4: 00000000000407e0
[13230.423790] Stack:
[13230.423817]  0000000000000000 0000000000060002 ffff8804ce5c68c0 ffff88083fd83b88
[13230.423877]  0000000000000001 ffffffff814ff611 0000000000000000 ffff8800907be740
[13230.423935]  ffff88043803c680 ffffffff81812040 000000003c9041bc ffffffff814ffa8c
[13230.423992] Call Trace:
[13230.424019]  <IRQ>
[13230.424024]  [<ffffffff814ff611>] ? xfrm_sk_policy_lookup+0x44/0x9b
[13230.424076]  [<ffffffff814ffa8c>] ? xfrm_lookup+0x91/0x446
[13230.424111]  [<ffffffff814f76a6>] ? ip_route_me_harder+0x150/0x1b0
[13230.424146]  [<ffffffffa019a457>] ? ip_vs_route_me_harder+0x86/0x91 [ip_vs]
[13230.424182]  [<ffffffffa019b97a>] ? ip_vs_out+0x2d3/0x5bc [ip_vs]
[13230.424213]  [<ffffffff814b537c>] ? ip_rcv_finish+0x2b8/0x2b8
[13230.424244]  [<ffffffff814b0237>] ? nf_iterate+0x42/0x80
[13230.424277]  [<ffffffff814b02de>] ? nf_hook_slow+0x69/0xff
[13230.424308]  [<ffffffff814b537c>] ? ip_rcv_finish+0x2b8/0x2b8
[13230.424339]  [<ffffffff814b56a0>] ? ip_local_deliver+0x6f/0x7e
[13230.424371]  [<ffffffff8148c94c>] ? __netif_receive_skb_core+0x5c6/0x62d
[13230.424404]  [<ffffffff8148cb48>] ? process_backlog+0x13e/0x13e
[13230.424438]  [<ffffffffa041adfd>] ? br_handle_frame_finish+0x382/0x382 [bridge]
[13230.424493]  [<ffffffff8148cb94>] ? netif_receive_skb+0x4c/0x7d
[13230.424526]  [<ffffffffa041ad89>] ? br_handle_frame_finish+0x30e/0x382 [bridge]
[13230.430400]  [<ffffffffa041afce>] ? br_handle_frame+0x1d1/0x217 [bridge]
[13230.430431]  [<ffffffff8148c7fb>] ? __netif_receive_skb_core+0x475/0x62d
[13230.430468]  [<ffffffff8145cf3a>] ? intel_pstate_cpu_exit+0x3c/0x3c
[13230.430504]  [<ffffffff8103eb48>] ? call_timer_fn.isra.24+0x1c/0x6f
[13230.430539]  [<ffffffff8148ca94>] ? process_backlog+0x8a/0x13e
[13230.430577]  [<ffffffff8148cd96>] ? net_rx_action+0x9e/0x175
[13230.430612]  [<ffffffff8103a4b7>] ? __do_softirq+0xb8/0x176
[13230.430643]  [<ffffffff81566c3c>] ? call_softirq+0x1c/0x30
[13230.430671]  <EOI>
[13230.430676]  [<ffffffff810040b1>] ? do_softirq+0x2c/0x5f
[13230.430727]  [<ffffffff81039ffd>] ? local_bh_enable+0x67/0x85
[13230.430756]  [<ffffffff814b8c6a>] ? ip_finish_output+0x2e1/0x33a
[13230.430790]  [<ffffffffa01a11f6>] ? ip_vs_nat_xmit+0x267/0x2b2 [ip_vs]
[13230.430822]  [<ffffffffa019b34a>] ? ip_vs_in+0x442/0x4c5 [ip_vs]
[13230.430852]  [<ffffffff814b7cec>] ? ip_forward_options+0x163/0x163
[13230.430882]  [<ffffffff814b0237>] ? nf_iterate+0x42/0x80
[13230.430910]  [<ffffffff814b02de>] ? nf_hook_slow+0x69/0xff
[13230.430939]  [<ffffffff814b7cec>] ? ip_forward_options+0x163/0x163
[13230.430970]  [<ffffffff814b9705>] ? __ip_local_out+0x69/0x76
[13230.431000]  [<ffffffff8147d5e3>] ? __sk_dst_check+0x24/0x4c
[13230.431029]  [<ffffffff814b971b>] ? ip_local_out+0x9/0x22
[13230.431058]  [<ffffffff814b99eb>] ? ip_queue_xmit+0x2b7/0x2f0
[13230.431088]  [<ffffffff814cbdd0>] ? tcp_transmit_skb+0x6f5/0x75b
[13230.431119]  [<ffffffff814cde61>] ? tcp_connect+0x44a/0x4d9
[13230.431149]  [<ffffffff8106fcf8>] ? ktime_get_real+0xc/0x3f
[13230.431180]  [<ffffffff814883cb>] ? secure_tcp_sequence_number+0x4d/0x5e
[13230.431211]  [<ffffffff814d0ae4>] ? tcp_v4_connect+0x3ab/0x402
[13230.431241]  [<ffffffff814e10b7>] ? __inet_stream_connect+0x80/0x27c
[13230.431272]  [<ffffffff81125353>] ? fsnotify_clear_marks_by_inode+0x26/0x103
[13230.431304]  [<ffffffff814e12e3>] ? inet_stream_connect+0x30/0x48
[13230.431334]  [<ffffffff8147b52e>] ? SyS_connect+0x6e/0x93
[13230.431365]  [<ffffffff8104bc74>] ? task_work_run+0x7d/0x8d
[13230.431394]  [<ffffffff81103804>] ? SyS_fcntl+0x232/0x45e
[13230.431430]  [<ffffffff81565a22>] ? system_call_fastpath+0x16/0x1b
[13230.431464] Code: 5d 41 5e 41 5f c3 41 55 66 83 fa 02 41 54 55 48 89 fd 53 48
89 f3 41 50 74 11 31 c0 66 83 fa 0a 0f 85 ce 02 00 00 e9 fd 00 00 00 <0f> b6 47
2a 8b
[13230.431740] RIP  [<ffffffff814ff2fc>] xfrm_selector_match+0x25/0x2f6
[13230.431772]  RSP <ffff88083fd83a68>
[13230.431795] CR2: 00000000000600d0
[13230.432240] ---[ end trace 103912aa204977dc ]---

node01:/ocfs2/usr/src/linux-3.12.33/scripts# ./decodecode </tmp/oops.log
[13230.431464] Code: 5d 41 5e 41 5f c3 41 55 66 83 fa 02 41 54 55 48 89 fd 53 48
89 f3 41 50 74 11 31 c0 66 83 fa 0a 0f 85 ce 02 00 00 e9 fd 00 00 00 <0f> b6 47
2a 8b 17 8b 76 18 84 c0 74 1a b9 20 00 00 00 31 f2 29
All code
========
   0:   5d                      pop    %rbp
   1:   41 5e                   pop    %r14
   3:   41 5f                   pop    %r15
   5:   c3                      retq
   6:   41 55                   push   %r13
   8:   66 83 fa 02             cmp    $0x2,%dx
   c:   41 54                   push   %r12
   e:   55                      push   %rbp
   f:   48 89 fd                mov    %rdi,%rbp
  12:   53                      push   %rbx
  13:   48 89 f3                mov    %rsi,%rbx
  16:   41 50                   push   %r8
  18:   74 11                   je     0x2b
  1a:   31 c0                   xor    %eax,%eax
  1c:   66 83 fa 0a             cmp    $0xa,%dx
  20:   0f 85 ce 02 00 00       jne    0x2f4
  26:   e9 fd 00 00 00          jmpq   0x128
  2b:*  0f b6 47 2a             movzbl 0x2a(%rdi),%eax          <-- trapping
instruction
  2f:   8b 17                   mov    (%rdi),%edx
  31:   8b 76 18                mov    0x18(%rsi),%esi
  34:   84 c0                   test   %al,%al
  36:   74 1a                   je     0x52
  38:   b9 20 00 00 00          mov    $0x20,%ecx
  3d:   31 f2                   xor    %esi,%edx
  3f:   29                      .byte 0x29

Code starting with the faulting instruction
===========================================
   0:   0f b6 47 2a             movzbl 0x2a(%rdi),%eax
   4:   8b 17                   mov    (%rdi),%edx
   6:   8b 76 18                mov    0x18(%rsi),%esi
   9:   84 c0                   test   %al,%al
   b:   74 1a                   je     0x27
   d:   b9 20 00 00 00          mov    $0x20,%ecx
  12:   31 f2                   xor    %esi,%edx
  14:   29                      .byte 0x29


I can't get a clue of that output. I rebuild the kernel now with

CONFIG_IP_VS=m
# CONFIG_IP_VS_IPV6 is not set
# CONFIG_IP_VS_DEBUG is not set
CONFIG_IP_VS_TAB_BITS=18
CONFIG_IP_VS_PROTO_TCP=y
CONFIG_IP_VS_PROTO_UDP=y
# CONFIG_IP_VS_PROTO_AH_ESP is not set
# CONFIG_IP_VS_PROTO_ESP is not set
# CONFIG_IP_VS_PROTO_AH is not set
# CONFIG_IP_VS_PROTO_SCTP is not set
CONFIG_IP_VS_RR=m
CONFIG_IP_VS_WRR=m
CONFIG_IP_VS_LC=m
CONFIG_IP_VS_WLC=m
CONFIG_IP_VS_LBLC=m
CONFIG_IP_VS_LBLCR=m
CONFIG_IP_VS_DH=m
CONFIG_IP_VS_SH=m
CONFIG_IP_VS_SED=m
CONFIG_IP_VS_NQ=m
CONFIG_IP_VS_SH_TAB_BITS=12
CONFIG_IP_VS_FTP=m
CONFIG_IP_VS_NFCT=y
CONFIG_IP_VS_PE_SIP=m

instead of:

CONFIG_IP_VS=m
CONFIG_IP_VS_IPV6=y
# CONFIG_IP_VS_DEBUG is not set
CONFIG_IP_VS_TAB_BITS=12
CONFIG_IP_VS_PROTO_TCP=y
CONFIG_IP_VS_PROTO_UDP=y
CONFIG_IP_VS_PROTO_AH_ESP=y
CONFIG_IP_VS_PROTO_ESP=y
CONFIG_IP_VS_PROTO_AH=y
# CONFIG_IP_VS_PROTO_SCTP is not set
CONFIG_IP_VS_RR=m
CONFIG_IP_VS_WRR=m
CONFIG_IP_VS_LC=m
CONFIG_IP_VS_WLC=m
CONFIG_IP_VS_LBLC=m
CONFIG_IP_VS_LBLCR=m
CONFIG_IP_VS_DH=m
CONFIG_IP_VS_SH=m
CONFIG_IP_VS_SED=m
CONFIG_IP_VS_NQ=m
CONFIG_IP_VS_SH_TAB_BITS=11
# CONFIG_IP_VS_FTP is not set
CONFIG_IP_VS_NFCT=y
# CONFIG_IP_VS_PE_SIP is not set


and try again as i think it might be ipv6 related.


Could someone shed some light on the decoded output and point me somewhere so i
can debug this further?




-- 

Mit freundlichen Grüßen,

Florian Wiessner

Smart Weblications GmbH
Martinsberger Str. 1
D-95119 Naila

fon.: +49 9282 9638 200
fax.: +49 9282 9638 205
24/7: +49 900 144 000 00 - 0,99 EUR/Min*
http://www.smart-weblications.de

--
Sitz der Gesellschaft: Naila
Geschäftsführer: Florian Wiessner
HRB-Nr.: HRB 3840 Amtsgericht Hof
*aus dem dt. Festnetz, ggf. abweichende Preise aus dem Mobilfunknetz

^ permalink raw reply

* travelling...
From: David Miller @ 2014-11-26 20:47 UTC (permalink / raw)
  To: netdev; +Cc: linux-wireless, netfilter-devel


I will be travelling for about 10 days starting tomorrow.

Email will be read and patches will be reviewed, but my response
time will be a little bit longer.

I've purged patchwork of every patch I can apply right now, the two in
there right now require either an expert review or a response to
feedback.

I plan to ask Linus to pull my 'net' tree in a little bit and I have
a stable queue submission in the works as well.

Just FYI...

^ permalink raw reply

* Re: [PATCH net-next] bridge: add vlan id to mdb notifications
From: Roopa Prabhu @ 2014-11-26 20:45 UTC (permalink / raw)
  To: Jonathan Toppins
  Cc: Stephen Hemminger, vyasevich, netdev, wkok, gospo, sashok
In-Reply-To: <54762CB3.4090101@cumulusnetworks.com>

On 11/26/14, 11:40 AM, Jonathan Toppins wrote:
> On 11/26/14 1:56 PM, Stephen Hemminger wrote:
>> On Wed, 26 Nov 2014 05:53:33 -0800
>> roopa@cumulusnetworks.com wrote:
>>
>>> diff --git a/include/uapi/linux/if_bridge.h 
>>> b/include/uapi/linux/if_bridge.h
>>> index da17e45..db061fd 100644
>>> --- a/include/uapi/linux/if_bridge.h
>>> +++ b/include/uapi/linux/if_bridge.h
>>> @@ -185,6 +185,7 @@ struct br_mdb_entry {
>>>               struct in6_addr ip6;
>>>           } u;
>>>           __be16        proto;
>>> +        __be16        vid;
>>>       } addr;
>>>   };
>>>
>>
>> You can't add fields to existing binary API
>>
>
> Roopa, maybe a description of what use case this is trying to solve 
> would better justify the addition to the UAPI?
>
I don't think a description of use case can be used to justify a UAPI 
breakage. Getting the patch out was mainly to see if this really breaks 
UAPI.
Basically to get some feedback.

^ permalink raw reply

* Re: [net-next PATCH 2/5] ethernet/intel: Use eth_skb_pad helper
From: David Miller @ 2014-11-26 20:41 UTC (permalink / raw)
  To: eric.dumazet
  Cc: alexander.duyck, alexander.h.duyck, netdev, jeffrey.t.kirsher,
	kuznet
In-Reply-To: <1416974473.29427.49.camel@edumazet-glaptop2.roam.corp.google.com>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Tue, 25 Nov 2014 20:01:13 -0800

[ I am still intrigued, CC:'ing Alexey ]

> On Tue, 2014-11-25 at 22:19 -0500, David Miller wrote:
>> From: Eric Dumazet <eric.dumazet@gmail.com>
>> Date: Tue, 25 Nov 2014 17:43:05 -0800
>> 
>> > I believe I finally have an idea why we had various + 15 in skb
>> > allocations in TCP stack !
>> 
>> It was so that you could do one level of tunneling with "for
>> free".  Or that is my recollection.
>> 
>> Those + 15 existed way before any of these padto() calls even
>> existed.
> 
> Well, tunneling is added in front of the packet. Thats why we use
> MAX_TCP_HEADER.
> 
> The +15 is in fact because TCP stack wanted to make sure the eventual
> padding (needing tailroom, not headroom) was possible...
> 
> Note that ack packets never used the +15, but other packets did.

Alexey, do you remember exact reason for that +15 everywhere in TCP
packet allocation sizing?

I thought it was for headroom, but as Eric shows that's illogical,
it can only be for tailroom considerations.

^ permalink raw reply

* Re: [PATCH net-next] bridge: add vlan id to mdb notifications
From: Roopa Prabhu @ 2014-11-26 20:40 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: vyasevich, netdev, wkok, gospo, jtoppins, sashok
In-Reply-To: <20141126105614.6a42d697@urahara>

On 11/26/14, 10:56 AM, Stephen Hemminger wrote:
> On Wed, 26 Nov 2014 05:53:33 -0800
> roopa@cumulusnetworks.com wrote:
>
>> diff --git a/include/uapi/linux/if_bridge.h b/include/uapi/linux/if_bridge.h
>> index da17e45..db061fd 100644
>> --- a/include/uapi/linux/if_bridge.h
>> +++ b/include/uapi/linux/if_bridge.h
>> @@ -185,6 +185,7 @@ struct br_mdb_entry {
>>   			struct in6_addr ip6;
>>   		} u;
>>   		__be16		proto;
>> +		__be16		vid;
>>   	} addr;
>>   };
>>   
> You can't add fields to existing binary API

Ack,  we know the concern..., The fact that it was not changing the size 
of the struct (due to existing padding and i verified that it worked 
with an older iproute2), we wanted to get the patch out and get some 
feedback.

Getting the vlan in the notification is imp and the only other option I 
see is to add a new netlink attribute in the mdb msg.

I have always wondered, if binary netlink attributes have this 
restriction, they should be discouraged. especially when the other 
extensible option is to add them as a separate netlink attribute.

Thanks for the review.

^ permalink raw reply

* Re: [PATCH net-next] macvlan: delay the header check for dodgy packets into lower device
From: David Miller @ 2014-11-26 20:37 UTC (permalink / raw)
  To: jasowang; +Cc: kaber, netdev, linux-kernel, mst, vyasevic
In-Reply-To: <1416993674-11177-1-git-send-email-jasowang@redhat.com>

From: Jason Wang <jasowang@redhat.com>
Date: Wed, 26 Nov 2014 17:21:14 +0800

> We do header check twice for a dodgy packet. One is done before
> macvlan_start_xmit(), another is done before lower device's
> ndo_start_xmit(). The first one seems redundant so this patch tries to
> delay header check until a packet reaches its lower device (or macvtap)
> through always enabling NETIF_F_GSO_ROBUST for macvlan device.
> 
> Cc: Patrick McHardy <kaber@trash.net>
> Signed-off-by: Jason Wang <jasowang@redhat.com>

Hmmm, it's the idea that if we have a dodgy packet, we want to
notice that as early as possible in the packet processing path?

^ permalink raw reply

* Re: [PATCH net] r8152: drop the tx packet with invalid length
From: David Miller @ 2014-11-26 20:33 UTC (permalink / raw)
  To: eric.dumazet; +Cc: hayeswang, netdev, nic_swsd, linux-kernel, linux-usb
In-Reply-To: <1417027459.29427.63.camel@edumazet-glaptop2.roam.corp.google.com>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Wed, 26 Nov 2014 10:44:19 -0800

> On Wed, 2014-11-26 at 12:06 -0500, David Miller wrote:
>> From: Eric Dumazet <eric.dumazet@gmail.com>
>> Date: Wed, 26 Nov 2014 08:52:28 -0800
>> 
>> > On Wed, 2014-11-26 at 17:56 +0800, Hayes Wang wrote:
>> >> Drop the tx packet which is more than the size of agg_buf_sz. When
>> >> creating a bridge with the device, we may get the tx packet with
>> >> TSO and the length is more than the gso_max_size which is set by
>> >> the driver through netif_set_gso_max_size(). Such packets couldn't
>> >> be transmitted and should be dropped directly.
>> >> 
>> >> Signed-off-by: Hayes Wang <hayeswang@realtek.com>
>>  ...
>> > Looks like a candidate for ndo_gso_check(), so that we do not drop, but
>> > instead segment from netif_needs_gso()/validate_xmit_skb()
>> 
>> You mean have the bridge implement the ndo_gso_check() method right?
> 
> No, I meant this particular driver.
> 
> Note that netif_skb_features() does only this check :
> 
> if (gso_segs > dev->gso_max_segs || gso_segs < dev->gso_min_segs)
>       features &= ~NETIF_F_GSO_MASK;
> 
> Ie not testing gso_max_size
> 
> It looks like all these particular tests should be moved on
> ndo_gso_check(), to remove code from netif_skb_features()

A check against gso_max_size is generic enough that it ought to be put
right into netif_needs_gso() rather then duplicating it into every
driver's ndo_gso_check() method don't you think?

^ permalink raw reply

* Re: [PATCH 0/5 net] bridge: Fix missing Netlink message validations
From: David Miller @ 2014-11-26 20:29 UTC (permalink / raw)
  To: tgraf; +Cc: stephen, netdev
In-Reply-To: <cover.1417005245.git.tgraf@suug.ch>

From: Thomas Graf <tgraf@suug.ch>
Date: Wed, 26 Nov 2014 13:42:15 +0100

> Adds various missing length checks in the bridging code for Netlink
> messages and corresponding attributes provided by user space.

Series applied, thanks Thomas.

^ permalink raw reply

* Re: [PATCH net-next V1 1/2] ethtool: Support for configurable RSS hash function
From: Eyal perry @ 2014-11-26 20:29 UTC (permalink / raw)
  To: David Miller, ben
  Cc: amirv, netdev, ogerlitz, yevgenyp, eyalpe, Tom Lendacky,
	ariel.elior, prashant, mchan, hariprasad, sathya.perla,
	subbu.seetharaman, ajit.khaparde, jeffrey.t.kirsher,
	jesse.brandeburg, bruce.w.allan, carolyn.wyborny,
	donald.c.skidmore, gregory.v.rose, matthew.vick, john.ronciak,
	mitch.a.williams, linux-net-drivers, sshah, sbhatewara,
	pv-drivers
In-Reply-To: <20141122.165407.641057904952001007.davem@davemloft.net>

On 11/22/2014 11:54 PM, David Miller wrote:
> From: Amir Vadai <amirv@mellanox.com>
> Date: Thu, 20 Nov 2014 16:26:49 +0200
> 
>> +	/* We require at least one supported parameter to be changed and no
>> +	 * change in any of the unsupported parameters
>> +	 */
>> +	if ((!indir && !key) || hfunc != ETH_RSS_HASH_NO_CHANGE)
>> +		return -EOPNOTSUPP;
>> +
> 
> I know it will make more work for you, but all of these driver
> implementations of this hook should:
> 
> 1) Accept hfunc of whatever hash function the chip is using,
>    not just ETH_RSS_HASH_NO_CHANGE.
> 
> 2) Provide an accurate hfunc value in the ->get() call.
Hello David, Ben, et al,
Before submitting V2, I'd like to consult you regarding the
implementation shown above. I thought of skipping the validity check
which I've described above as "We require at least one supported
parameter...", instead, I think it's better to fail the ->set() call
only in case of unsupported action requested, e.g.:
+	if (hfunc != ETH_RSS_HASH_NO_CHANGE &&
+	    hfunc != ETH_RSS_HASH_TOP)
+		return -EOPNOTSUPP;
+	if (indir)
+		/* set indirection table code ... */
+	if (key)
+		/* set hash key code ... */
The drawbacks are the change of previous behavior (only requests for at
least one change were supported), however it seems more reasonable and
makes the code much more readable.
In similar manner, for the ->get() call, remove the validity checks (as
I suggested in V1), and just protect against NULL pointer dereference, e.g:
-	if (!indir && !key)
-		return -EOPNOTSUPP;
+	if (indir)
+		/* fill in the given indirection table array */
+	if (key)
+		/* fill in the given hash key array */
+	if (hfunc)
+		*hfunc = ETH_RSS_HASH_TOP;
Please advise,
Thanks,
Eyal.

^ permalink raw reply

* Re: Multiple DSA switch on shared MII
From: Florian Fainelli @ 2014-11-26 20:23 UTC (permalink / raw)
  To: Rajib Karmakar; +Cc: netdev
In-Reply-To: <CAOi_9k8WySmjm5cdFn1kJQuE7cJ1rDyM9SV2RvbcmbB+UeTVdQ@mail.gmail.com>

On 25/11/14 23:33, Rajib Karmakar wrote:
> Hello Florian,
> 
> Thanks for your reply.
> 
> On Wed, Nov 26, 2014 at 10:52 AM, Florian Fainelli <f.fainelli@gmail.com> wrote:
>> 2014-11-25 20:52 GMT-08:00 Rajib Karmakar <rajibkit@gmail.com>:
>>> Hello,
>>>
>>> I am developing a DSA driver for Marvell 6172 and need to create 2 dsa
>>> switch chip (one for WAN and one for LAN).
>>
>> This is not typically how it is designed to work, you would register
>> one dsa switch chip with the ports assignment in this data structure.
>> Right now, DSA does not support a dual Ethernet MAC configuration,
>> although you could probably do per-port VLAN membership and create two
>> default VLANs to allow that.
>>
>>>
>>> My device has 2 MACs and one shared mii_bus. I have added two
>>> dsa_platform_data structures and registered them but cannot probe as
>>> dsa_probe tries mdio_register() on the same bus and fails.
>>>
>>> Is it possible to create two DSA switch on same (shared) mii?
>>
>> Not in its current form, and I am not exactly sure how we would support that.
> 
> Yes, not with the current DSA implementation, but I can manage to
> solve this by a small (ugly) patch - renamed the slave mii bus as
> "<master_bus->id>:<pd->sw_addr>:<platform_device->id>" instead of
> "<master_bus->id>:<pd->sw_addr>". Though I am not yet sure enough if
> this could have any negative impact or not.

This will register two virtual slave mii buses backed by the same real
mdio bus driver, although that is not necessarily a problem, you want to
make sure that they are not going to poll the same PHYs in the switch
driver.

This is probably the easiest way to achieve what you want, can you just
introduce a check on the "id" being >= 0 (using -1 with platform_devices
is valid when there is just one device in the system).

Thanks!

> 
> Comments please.
> 
>>
>>>
>>> Regards,
>>> Rajib
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe netdev" in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
>>
>>
>> --
>> Florian
> 
> ----
> diff -rup org/net/dsa/dsa.c mod/net/dsa/dsa.c
> --- org/net/dsa/dsa.c
> +++ mod/net/dsa/dsa.c
> @@ -68,7 +68,7 @@ dsa_switch_probe(struct mii_bus *bus, in
> 
>  /* basic switch operations **************************************************/
>  static struct dsa_switch *
> -dsa_switch_setup(struct dsa_switch_tree *dst, int index,
> +dsa_switch_setup(struct dsa_switch_tree *dst, int index, int id,
>   struct device *parent, struct mii_bus *bus)
>  {
>   struct dsa_chip_data *pd = dst->pd->chip + index;
> @@ -156,7 +156,7 @@ dsa_switch_setup(struct dsa_switch_tree
>   ret = -ENOMEM;
>   goto out;
>   }
> - dsa_slave_mii_bus_init(ds);
> + dsa_slave_mii_bus_init(ds, id);
> 
>   ret = mdiobus_register(ds->slave_mii_bus);
>   if (ret < 0)
> @@ -349,7 +349,7 @@ static int dsa_probe(struct platform_dev
>   continue;
>   }
> 
> - ds = dsa_switch_setup(dst, i, &pdev->dev, bus);
> + ds = dsa_switch_setup(dst, i, pdev->id, &pdev->dev, bus);
>   if (IS_ERR(ds)) {
>   printk(KERN_ERR "%s[%d]: couldn't create dsa switch "
>   "instance (error %ld)\n", dev->name, i,
> diff -rup org/net/dsa/dsa_priv.h mod/net/dsa/dsa_priv.h
> --- org/net/dsa/dsa_priv.h
> +++ mod/net/dsa/dsa_priv.h
> @@ -163,7 +163,7 @@ void register_switch_driver(struct dsa_s
>  void unregister_switch_driver(struct dsa_switch_driver *type);
> 
>  /* slave.c */
> -void dsa_slave_mii_bus_init(struct dsa_switch *ds);
> +void dsa_slave_mii_bus_init(struct dsa_switch *ds, int id);
>  struct net_device *dsa_slave_create(struct dsa_switch *ds,
>      struct device *parent,
>      int port, char *name);
> diff -rup org/net/dsa/slave.c mod/net/dsa/slave.c
> --- org/net/dsa/slave.c
> +++ mod/net/dsa/slave.c
> @@ -35,14 +35,14 @@ static int dsa_slave_phy_write(struct mi
>   return 0;
>  }
> 
> -void dsa_slave_mii_bus_init(struct dsa_switch *ds)
> +void dsa_slave_mii_bus_init(struct dsa_switch *ds, int id)
>  {
>   ds->slave_mii_bus->priv = (void *)ds;
>   ds->slave_mii_bus->name = "dsa slave smi";
>   ds->slave_mii_bus->read = dsa_slave_phy_read;
>   ds->slave_mii_bus->write = dsa_slave_phy_write;
> - snprintf(ds->slave_mii_bus->id, MII_BUS_ID_SIZE, "%s:%.2x",
> - ds->master_mii_bus->id, ds->pd->sw_addr);
> + snprintf(ds->slave_mii_bus->id, MII_BUS_ID_SIZE, "%s:%.2x:%.1x",
> + ds->master_mii_bus->id, ds->pd->sw_addr, id);
>   ds->slave_mii_bus->parent = &ds->master_mii_bus->dev;
>  }
> 

^ permalink raw reply

* Re: [PATCH net-next] sky2: Fix crash inside sky2_rx_clean
From: David Miller @ 2014-11-26 20:17 UTC (permalink / raw)
  To: mlindner; +Cc: netdev
In-Reply-To: <5475E012.3060607@marvell.com>

From: Mirko Lindner <mlindner@marvell.com>
Date: Wed, 26 Nov 2014 15:13:38 +0100

> If sky2->tx_le = pci_alloc_consistent() or sky2->tx_ring = kcalloc() in
> sky2_alloc_buffers() fails, sky2->rx_ring = kcalloc() will never be called.
> In this error case handling, sky2_rx_clean() is called from within
> sky2_free_buffers().
> 
> In sky2_rx_clean() we find the following:
> 
> ...
>    memset(sky2->rx_le, 0, RX_LE_BYTES);
> ...
> 
> This results in a memset using a NULL pointer and will crash the system.
> 
> Signed-off-by: Mirko Lindner <mlindner@marvell.com>

Applied, thanks.

^ permalink raw reply

* Re: [PATCH net-next] ipvlan: fix sparse warnings
From: David Miller @ 2014-11-26 20:13 UTC (permalink / raw)
  To: maheshb; +Cc: netdev
In-Reply-To: <1416979483-30610-1-git-send-email-maheshb@google.com>

From: Mahesh Bandewar <maheshb@google.com>
Date: Tue, 25 Nov 2014 21:24:43 -0800

> Fix sparse warnings reported by kbuild robot
> 
> drivers/net/ipvlan/ipvlan_main.c:172:13: warning: symbol 'ipvlan_start_xmit' was not declared. Should it be static?
> drivers/net/ipvlan/ipvlan_main.c:256:33: warning: incorrect type in initializer (different address spaces)
> drivers/net/ipvlan/ipvlan_main.c:256:33:    expected void const [noderef] <asn:3>*__vpp_verify
> drivers/net/ipvlan/ipvlan_main.c:256:33:    got struct ipvl_pcpu_stats *<noident>
> drivers/net/ipvlan/ipvlan_main.c:544:5: warning: symbol 'ipvlan_link_register' was not declared. Should it be static
> 
> Reported-by: kbuild test robot <fengguang.wu@intel.com>
> Signed-off-by: Mahesh Bandewar <maheshb@google.com>

Applied, can you please fix the build failures that have been
reported?  Those are more important.  Namely:

====================
Building with the attached random configuration file,

In file included from drivers/net/ipvlan/ipvlan.h:27:0,
                 from drivers/net/ipvlan/ipvlan_core.c:10:
include/net/gre.h: In function ‘gre_handle_offloads’:
include/net/gre.h:42:2: error: implicit declaration of function
‘iptunnel_handle_offloads’ [-Werror=implicit-function-declaration]
  return iptunnel_handle_offloads(skb, csum,
  ^
include/net/gre.h:42:2: warning: return makes pointer from integer
without a cast [enabled by default]
drivers/net/ipvlan/ipvlan_core.c: In function ‘ipvlan_process_v6_outbound’:
drivers/net/ipvlan/ipvlan_core.c:379:2: error: implicit declaration of function
‘ip6_route_output’ [-Werror=implicit-function-declaration]
  dst = ip6_route_output(dev_net(dev), NULL, &fl6);
  ^
drivers/net/ipvlan/ipvlan_core.c:379:6: warning: assignment makes
pointer from integer without a cast [enabled by default]
  dst = ip6_route_output(dev_net(dev), NULL, &fl6);
      ^
  CC [M]  drivers/mtd/mtdblock_ro.o
cc1: some warnings being treated as errors
make[3]: *** [drivers/net/ipvlan/ipvlan_core.o] Error 1
====================

You probably need to add a bunch of missing dependencies to
the Kconfig entry for the ipvlan driver.

For one thing it definitely needs "INET" and that explains
the lack of iptunnel_handle_offloads() when including net/gre.h

Likewise for the ipv6 stuff.

^ permalink raw reply

* Re: [PATCH net-next 0/3] net: bcmgenet: EEE support
From: David Miller @ 2014-11-26 20:09 UTC (permalink / raw)
  To: f.fainelli; +Cc: netdev, pgynther
In-Reply-To: <1416978996-24808-1-git-send-email-f.fainelli@gmail.com>

From: Florian Fainelli <f.fainelli@gmail.com>
Date: Tue, 25 Nov 2014 21:16:33 -0800

> This patch series add EEE support to the Broadcom GENET driver, first patch
> basically adds register definitions for the hardware, the second patch does the
> actual implementation and hooks the {get,set}_eee ethtool callbacks, the last
> patch adds auto-negotiation restart capability.

Series applied, thanks.

^ permalink raw reply

* Re: [PATCH net] net-timestamp: make tcp_recvmsg call ipv6_recv_error for AF_INET6 socks
From: Willem de Bruijn @ 2014-11-26 20:03 UTC (permalink / raw)
  To: Network Development
  Cc: David Miller, Eric Dumazet, kuznet, jmorris, yoshfuji,
	Patrick McHardy, Willem de Bruijn
In-Reply-To: <1417031582-16480-1-git-send-email-willemb@google.com>

On Wed, Nov 26, 2014 at 2:53 PM, Willem de Bruijn <willemb@google.com> wrote:
> From: Willem de Bruijn <willemb@google.com>
>
> TCP timestamping introduced MSG_ERRQUEUE handling for TCP sockets.
> If the socket is of family AF_INET6, call ipv6_recv_error instead
> of ip_recv_error.
>
> This change is more complex than a single branch due to the loadable
> ipv6 module. It reuses a pre-existing indirect function call from
> ping. The ping code is safe to call, because it is part of the core
> ipv6 module and always present when AF_INET6 sockets are active.

I forgot to add:

Fixes: 4ed2d765 (net-timestamp: TCP timestamping)

> Signed-off-by: Willem de Bruijn <willemb@google.com>
>
> ----
>
> It may also be worthwhile to add WARN_ON_ONCE(sk->family == AF_INET6)
> to ip_recv_error.

^ permalink raw reply

* Re: [PATCH] x86: bpf_jit_comp: simplify trivial boolean return
From: Joe Perches @ 2014-11-26 20:00 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: Quentin Lambert, David S. Miller, Alexey Kuznetsov, James Morris,
	Hideaki YOSHIFUJI, Patrick McHardy, Thomas Gleixner, Ingo Molnar,
	H. Peter Anvin, x86, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org
In-Reply-To: <CAADnVQK3iui8cAmhi28=65p2CJbTu45fR98ri8Uh8xLRb=cwnA@mail.gmail.com>

On Wed, 2014-11-26 at 10:34 -0800, Alexei Starovoitov wrote:
> On Wed, Nov 26, 2014 at 10:02 AM, Joe Perches <joe@perches.com> wrote:
> > On Wed, 2014-11-26 at 09:23 -0800, Alexei Starovoitov wrote:
> >> On Wed, Nov 26, 2014 at 8:58 AM, Joe Perches <joe@perches.com> wrote:
> >
> >> > Is there any value in reordering these tests for frequency
> >> > or maybe using | instead of || to avoid multiple jumps?
> >>
> >> probably not. It's not a critical path.
> >> compiler may fuse conditions depending on values anyway.
> >> If it was a critical path, we could have used
> >> (1 << reg) & mask trick.
> >> I picked explicit 'return true' else 'return false' here,
> >> because it felt easier to read. Just a matter of taste.
> >
> > There is a size difference though: (allyesconfig)
> >
> > $ size arch/x86/net/built-in.o*
> >    text    data     bss     dec     hex filename
> >   12999    1012    4336   18347    47ab arch/x86/net/built-in.o.new
> >   13177    1076    4592   18845    499d arch/x86/net/built-in.o.old
> 
> interesting. Compiler obviously thinks that 178 byte increase
> with -O2 is the right trade off. Which I agree with :)
> 
> If I think dropping 'inline' and using -Os will give bigger savings...

This was allyesconfig which already uses -Os

Using -O2, there is no difference using inline
or not, but the size delta with the bitmask is
much larger

$ size arch/x86/net/built-in.o* (allyesconfig, but not -Os)
   text	   data	    bss	    dec	    hex	filename
  13410	    820	   3624	  17854	   45be	arch/x86/net/built-in.o.new
  16130	    884	   4200	  21214	   52de	arch/x86/net/built-in.o.old
  16130	    884	   4200	  21214	   52de	arch/x86/net/built-in.o.static

^ permalink raw reply

* Re: [PATCH rfc] packet: zerocopy packet_snd
From: Willem de Bruijn @ 2014-11-26 19:59 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Network Development, David Miller, Eric Dumazet, Daniel Borkmann
In-Reply-To: <20141126182445.GA15744@redhat.com>

> The main problem with zero copy ATM is with queueing disciplines
> which might keep the socket around essentially forever.
> The case was described here:
> https://lkml.org/lkml/2014/1/17/105
> and of course this will make it more serious now that
> more applications will be able to do this, so
> chances that an administrator enables this
> are higher.

The denial of service issue raised there, that a single queue can
block an entire virtio-net device, is less problematic in the case of
packet sockets. A socket can run out of sk_wmem_alloc, but a prudent
application can increase the limit or use separate sockets for
separate flows.

> One possible solution is some kind of timer orphaning frags
> for skbs that have been around for too long.

Perhaps this can be approximated without an explicit timer by calling
skb_copy_ubufs on enqueue whenever qlen exceeds a threshold value?

>
>> ---
>>  include/linux/skbuff.h        |   1 +
>>  include/linux/socket.h        |   1 +
>>  include/uapi/linux/errqueue.h |   1 +
>>  net/packet/af_packet.c        | 110 ++++++++++++++++++++++++++++++++++++++----
>>  4 files changed, 103 insertions(+), 10 deletions(-)
>>
>> diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
>> index 78c299f..8e661d2 100644
>> --- a/include/linux/skbuff.h
>> +++ b/include/linux/skbuff.h
>> @@ -295,6 +295,7 @@ struct ubuf_info {
>>       void (*callback)(struct ubuf_info *, bool zerocopy_success);
>>       void *ctx;
>>       unsigned long desc;
>> +     void *callback_priv;
>>  };
>>
>>  /* This data is invariant across clones and lives at
>> diff --git a/include/linux/socket.h b/include/linux/socket.h
>> index de52228..0a2e0ea 100644
>> --- a/include/linux/socket.h
>> +++ b/include/linux/socket.h
>> @@ -265,6 +265,7 @@ struct ucred {
>>  #define MSG_SENDPAGE_NOTLAST 0x20000 /* sendpage() internal : not the last page */
>>  #define MSG_EOF         MSG_FIN
>>
>> +#define MSG_ZEROCOPY 0x4000000       /* Pin user pages */
>>  #define MSG_FASTOPEN 0x20000000      /* Send data in TCP SYN */
>>  #define MSG_CMSG_CLOEXEC 0x40000000  /* Set close_on_exec for file
>>                                          descriptor received through
>> diff --git a/include/uapi/linux/errqueue.h b/include/uapi/linux/errqueue.h
>> index 07bdce1..61bf318 100644
>> --- a/include/uapi/linux/errqueue.h
>> +++ b/include/uapi/linux/errqueue.h
>> @@ -19,6 +19,7 @@ struct sock_extended_err {
>>  #define SO_EE_ORIGIN_ICMP6   3
>>  #define SO_EE_ORIGIN_TXSTATUS        4
>>  #define SO_EE_ORIGIN_TIMESTAMPING SO_EE_ORIGIN_TXSTATUS
>> +#define SO_EE_ORIGIN_UPAGE   5
>>
>>  #define SO_EE_OFFENDER(ee)   ((struct sockaddr*)((ee)+1))
>>
>> diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
>> index 58af5802..367c23a 100644
>> --- a/net/packet/af_packet.c
>> +++ b/net/packet/af_packet.c
>> @@ -2370,28 +2370,112 @@ out:
>>
>>  static struct sk_buff *packet_alloc_skb(struct sock *sk, size_t prepad,
>>                                       size_t reserve, size_t len,
>> -                                     size_t linear, int noblock,
>> +                                     size_t linear, int flags,
>>                                       int *err)
>>  {
>>       struct sk_buff *skb;
>> +     size_t data_len;
>>
>> -     /* Under a page?  Don't bother with paged skb. */
>> -     if (prepad + len < PAGE_SIZE || !linear)
>> -             linear = len;
>> +     if (flags & MSG_ZEROCOPY) {
>> +             /* Minimize linear, but respect header lower bound */
>> +             linear = min(len, max_t(size_t, linear, MAX_HEADER));
>> +             data_len = 0;
>> +     } else {
>> +             /* Under a page? Don't bother with paged skb. */
>> +             if (prepad + len < PAGE_SIZE || !linear)
>> +                     linear = len;
>> +             data_len = len - linear;
>> +     }
>>
>> -     skb = sock_alloc_send_pskb(sk, prepad + linear, len - linear, noblock,
>> -                                err, 0);
>> +     skb = sock_alloc_send_pskb(sk, prepad + linear, data_len,
>> +                                flags & MSG_DONTWAIT, err, 0);
>>       if (!skb)
>>               return NULL;
>>
>>       skb_reserve(skb, reserve);
>>       skb_put(skb, linear);
>> -     skb->data_len = len - linear;
>> -     skb->len += len - linear;
>> +     skb->data_len = data_len;
>> +     skb->len += data_len;
>>
>>       return skb;
>>  }
>>
>> +/* release zerocopy resources and avoid destructor callback on kfree */
>> +static void packet_snd_zerocopy_free(struct sk_buff *skb)
>> +{
>> +     struct ubuf_info *uarg = skb_shinfo(skb)->destructor_arg;
>> +
>> +     if (uarg) {
>> +             kfree_skb(uarg->callback_priv);
>> +             sock_put((struct sock *) uarg->ctx);
>> +             kfree(uarg);
>> +
>> +             skb_shinfo(skb)->destructor_arg = NULL;
>> +             skb_shinfo(skb)->tx_flags &= ~SKBTX_DEV_ZEROCOPY;
>> +     }
>> +}
>> +
>> +static void packet_snd_zerocopy_callback(struct ubuf_info *uarg,
>> +                                      bool zerocopy_success)
>> +{
>> +     struct sk_buff *err_skb;
>> +     struct sock *err_sk;
>> +     struct sock_exterr_skb *serr;
>> +
>> +     err_sk = uarg->ctx;
>> +     err_skb = uarg->callback_priv;
>> +
>> +     serr = SKB_EXT_ERR(err_skb);
>> +     memset(serr, 0, sizeof(*serr));
>> +     serr->ee.ee_errno = ENOMSG;
>> +     serr->ee.ee_origin = SO_EE_ORIGIN_UPAGE;
>> +     serr->ee.ee_data = uarg->desc & 0xFFFFFFFF;
>> +     serr->ee.ee_info = ((u64) uarg->desc) >> 32;
>> +     if (sock_queue_err_skb(err_sk, err_skb))
>> +             kfree_skb(err_skb);
>> +
>> +     kfree(uarg);
>> +     sock_put(err_sk);
>> +}
>> +
>> +static int packet_zerocopy_sg_from_iovec(struct sk_buff *skb,
>> +                                      struct msghdr *msg)
>> +{
>> +     struct ubuf_info *uarg = NULL;
>> +     int ret;
>> +
>> +     if (iov_pages(msg->msg_iov, 0, msg->msg_iovlen) > MAX_SKB_FRAGS)
>> +             return -EMSGSIZE;
>> +
>> +     uarg = kzalloc(sizeof(*uarg), GFP_KERNEL);
>> +     if (!uarg)
>> +             return -ENOMEM;
>> +
>> +     uarg->callback_priv = alloc_skb(0, GFP_KERNEL);
>> +     if (!uarg->callback_priv) {
>> +             kfree(uarg);
>> +             return -ENOMEM;
>> +     }
>> +
>> +     ret = zerocopy_sg_from_iovec(skb, msg->msg_iov, 0, msg->msg_iovlen);
>> +     if (ret) {
>> +             kfree_skb(uarg->callback_priv);
>> +             kfree(uarg);
>> +             return -EIO;
>> +     }
>> +
>> +     sock_hold(skb->sk);
>> +     uarg->ctx = skb->sk;
>> +     uarg->callback = packet_snd_zerocopy_callback;
>> +     uarg->desc = (unsigned long) msg->msg_iov[0].iov_base;
>> +
>> +     skb_shinfo(skb)->destructor_arg = uarg;
>> +     skb_shinfo(skb)->tx_flags |= SKBTX_DEV_ZEROCOPY;
>> +     skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG;
>> +
>> +     return 0;
>> +}
>> +
>>  static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
>>  {
>>       struct sock *sk = sock->sk;
>> @@ -2408,6 +2492,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
>>       unsigned short gso_type = 0;
>>       int hlen, tlen;
>>       int extra_len = 0;
>> +     bool zerocopy = msg->msg_flags & MSG_ZEROCOPY;
>>
>>       /*
>>        *      Get and verify the address.
>> @@ -2501,7 +2586,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
>>       hlen = LL_RESERVED_SPACE(dev);
>>       tlen = dev->needed_tailroom;
>>       skb = packet_alloc_skb(sk, hlen + tlen, hlen, len, vnet_hdr.hdr_len,
>> -                            msg->msg_flags & MSG_DONTWAIT, &err);
>> +                            msg->msg_flags, &err);
>>       if (skb == NULL)
>>               goto out_unlock;
>>
>> @@ -2518,7 +2603,11 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
>>       }
>>
>>       /* Returns -EFAULT on error */
>> -     err = skb_copy_datagram_from_iovec(skb, offset, msg->msg_iov, 0, len);
>> +     if (zerocopy)
>> +             err = packet_zerocopy_sg_from_iovec(skb, msg);
>> +     else
>> +             err = skb_copy_datagram_from_iovec(skb, offset, msg->msg_iov,
>> +                                                0, len);
>>       if (err)
>>               goto out_free;
>>
>> @@ -2578,6 +2667,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
>>       return len;
>>
>>  out_free:
>> +     packet_snd_zerocopy_free(skb);
>>       kfree_skb(skb);
>>  out_unlock:
>>       if (dev)
>> --
>> 2.1.0.rc2.206.gedb03e5

^ permalink raw reply

* [PATCH net] net-timestamp: make tcp_recvmsg call ipv6_recv_error for AF_INET6 socks
From: Willem de Bruijn @ 2014-11-26 19:53 UTC (permalink / raw)
  To: netdev
  Cc: davem, eric.dumazet, kuznet, jmorris, yoshfuji, kaber,
	Willem de Bruijn

From: Willem de Bruijn <willemb@google.com>

TCP timestamping introduced MSG_ERRQUEUE handling for TCP sockets.
If the socket is of family AF_INET6, call ipv6_recv_error instead
of ip_recv_error.

This change is more complex than a single branch due to the loadable
ipv6 module. It reuses a pre-existing indirect function call from
ping. The ping code is safe to call, because it is part of the core
ipv6 module and always present when AF_INET6 sockets are active.

Signed-off-by: Willem de Bruijn <willemb@google.com>

----

It may also be worthwhile to add WARN_ON_ONCE(sk->family == AF_INET6)
to ip_recv_error.
---
 include/net/inet_common.h |  2 ++
 net/ipv4/af_inet.c        | 11 +++++++++++
 net/ipv4/ping.c           | 12 ++----------
 net/ipv4/tcp.c            |  2 +-
 4 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/include/net/inet_common.h b/include/net/inet_common.h
index fe7994c..b2828a0 100644
--- a/include/net/inet_common.h
+++ b/include/net/inet_common.h
@@ -37,6 +37,8 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
 int inet_ctl_sock_create(struct sock **sk, unsigned short family,
 			 unsigned short type, unsigned char protocol,
 			 struct net *net);
+int inet_recv_error(struct sock *sk, struct msghdr *msg, int len,
+		    int *addr_len);
 
 static inline void inet_ctl_sock_destroy(struct sock *sk)
 {
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 8b7fe5b..e67da4e 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1386,6 +1386,17 @@ out:
 	return pp;
 }
 
+int inet_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
+{
+	if (sk->sk_family == AF_INET)
+		return ip_recv_error(sk, msg, len, addr_len);
+#if IS_ENABLED(CONFIG_IPV6)
+	if (sk->sk_family == AF_INET6)
+		return pingv6_ops.ipv6_recv_error(sk, msg, len, addr_len);
+#endif
+	return -EINVAL;
+}
+
 static int inet_gro_complete(struct sk_buff *skb, int nhoff)
 {
 	__be16 newlen = htons(skb->len - nhoff);
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index 85a02a7..5d740cc 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -855,16 +855,8 @@ int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 	if (flags & MSG_OOB)
 		goto out;
 
-	if (flags & MSG_ERRQUEUE) {
-		if (family == AF_INET) {
-			return ip_recv_error(sk, msg, len, addr_len);
-#if IS_ENABLED(CONFIG_IPV6)
-		} else if (family == AF_INET6) {
-			return pingv6_ops.ipv6_recv_error(sk, msg, len,
-							  addr_len);
-#endif
-		}
-	}
+	if (flags & MSG_ERRQUEUE)
+		return inet_recv_error(sk, msg, len, addr_len);
 
 	skb = skb_recv_datagram(sk, flags, noblock, &err);
 	if (!skb)
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 39ec0c3..38c2bcb 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1598,7 +1598,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 	u32 urg_hole = 0;
 
 	if (unlikely(flags & MSG_ERRQUEUE))
-		return ip_recv_error(sk, msg, len, addr_len);
+		return inet_recv_error(sk, msg, len, addr_len);
 
 	if (sk_can_busy_loop(sk) && skb_queue_empty(&sk->sk_receive_queue) &&
 	    (sk->sk_state == TCP_ESTABLISHED))
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related

* pull request: wireless 2014-11-26
From: John W. Linville @ 2014-11-26 19:47 UTC (permalink / raw)
  To: davem; +Cc: linux-wireless, netdev, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 5630 bytes --]

Dave,

Please pull this little batch of fixes intended for the 3.18 stream...

For the iwlwifi one, Emmanuel says:

"Not all the firmware know how to handle the HOT_SPOT_CMD.
Make sure that the firmware will know this command before
sending it. This avoids a firmware crash."

Along with that, Larry sends a pair of rtlwifi fixes to address some
discrepancies from moving drivers out of staging.  Larry says:

"These two patches are needed to fix a regression introduced when
driver rtl8821ae was moved from staging to the regular wireless tree."

Please let me know if there are problems!

Thanks,

John

---

The following changes since commit a1d69c60c44134f64945bbf6a6dfda22eaf4a214:

  brcmfmac: don't include linux/unaligned/access_ok.h (2014-11-20 14:46:45 -0500)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git tags/master-2014-11-25

for you to fetch changes up to 7d63a5f9b25ba6b130da8eb2d32a72b1462d0249:

  rtlwifi: Change order in device startup (2014-11-25 14:22:22 -0500)

----------------------------------------------------------------
John W. Linville (1):
      Merge tag 'iwlwifi-for-john-2014-11-23' of git://git.kernel.org/.../iwlwifi/iwlwifi-fixes

Larry Finger (2):
      rtlwifi: rtl8821ae: Fix 5G detection problem
      rtlwifi: Change order in device startup

Luciano Coelho (1):
      iwlwifi: mvm: check TLV flag before trying to use hotspot firmware commands

 drivers/net/wireless/iwlwifi/iwl-fw.h       |  2 ++
 drivers/net/wireless/iwlwifi/mvm/mac80211.c | 12 +++++++++---
 drivers/net/wireless/rtlwifi/pci.c          | 20 ++++++++++----------
 drivers/net/wireless/rtlwifi/rtl8821ae/hw.c |  5 +++--
 4 files changed, 24 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
index 4f6e66892acc..b894a84e8393 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw.h
@@ -155,6 +155,7 @@ enum iwl_ucode_tlv_api {
  * @IWL_UCODE_TLV_CAPA_QUIET_PERIOD_SUPPORT: supports Quiet Period requests
  * @IWL_UCODE_TLV_CAPA_DQA_SUPPORT: supports dynamic queue allocation (DQA),
  *	which also implies support for the scheduler configuration command
+ * @IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT: supports Hot Spot Command
  */
 enum iwl_ucode_tlv_capa {
 	IWL_UCODE_TLV_CAPA_D0I3_SUPPORT			= BIT(0),
@@ -163,6 +164,7 @@ enum iwl_ucode_tlv_capa {
 	IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT	= BIT(10),
 	IWL_UCODE_TLV_CAPA_QUIET_PERIOD_SUPPORT		= BIT(11),
 	IWL_UCODE_TLV_CAPA_DQA_SUPPORT			= BIT(12),
+	IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT		= BIT(18),
 };
 
 /* The default calibrate table size if not specified by firmware file */
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index b62405865b25..b6d2683da3a9 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -2448,9 +2448,15 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw,
 
 	switch (vif->type) {
 	case NL80211_IFTYPE_STATION:
-		/* Use aux roc framework (HS20) */
-		ret = iwl_mvm_send_aux_roc_cmd(mvm, channel,
-					       vif, duration);
+		if (mvm->fw->ucode_capa.capa[0] &
+		    IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT) {
+			/* Use aux roc framework (HS20) */
+			ret = iwl_mvm_send_aux_roc_cmd(mvm, channel,
+						       vif, duration);
+			goto out_unlock;
+		}
+		IWL_ERR(mvm, "hotspot not supported\n");
+		ret = -EINVAL;
 		goto out_unlock;
 	case NL80211_IFTYPE_P2P_DEVICE:
 		/* handle below */
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index 61f5d36eca6a..846a2e6e34d8 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -2249,6 +2249,16 @@ int rtl_pci_probe(struct pci_dev *pdev,
 	/*like read eeprom and so on */
 	rtlpriv->cfg->ops->read_eeprom_info(hw);
 
+	if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't init_sw_vars\n");
+		err = -ENODEV;
+		goto fail3;
+	}
+	rtlpriv->cfg->ops->init_sw_leds(hw);
+
+	/*aspm */
+	rtl_pci_init_aspm(hw);
+
 	/* Init mac80211 sw */
 	err = rtl_init_core(hw);
 	if (err) {
@@ -2264,16 +2274,6 @@ int rtl_pci_probe(struct pci_dev *pdev,
 		goto fail3;
 	}
 
-	if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't init_sw_vars\n");
-		err = -ENODEV;
-		goto fail3;
-	}
-	rtlpriv->cfg->ops->init_sw_leds(hw);
-
-	/*aspm */
-	rtl_pci_init_aspm(hw);
-
 	err = ieee80211_register_hw(hw);
 	if (err) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c b/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c
index 310d3163dc5b..8ec8200002c7 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c
@@ -3672,8 +3672,9 @@ static void rtl8821ae_update_hal_rate_mask(struct ieee80211_hw *hw,
 		mac->opmode == NL80211_IFTYPE_ADHOC)
 		macid = sta->aid + 1;
 	if (wirelessmode == WIRELESS_MODE_N_5G ||
-	    wirelessmode == WIRELESS_MODE_AC_5G)
-		ratr_bitmap = sta->supp_rates[NL80211_BAND_5GHZ];
+	    wirelessmode == WIRELESS_MODE_AC_5G ||
+	    wirelessmode == WIRELESS_MODE_A)
+		ratr_bitmap = sta->supp_rates[NL80211_BAND_5GHZ] << 4;
 	else
 		ratr_bitmap = sta->supp_rates[NL80211_BAND_2GHZ];
 
-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply related

* Re: [PATCH net-next] bridge: add vlan id to mdb notifications
From: Jonathan Toppins @ 2014-11-26 19:40 UTC (permalink / raw)
  To: Stephen Hemminger, roopa; +Cc: vyasevich, netdev, wkok, gospo, sashok
In-Reply-To: <20141126105614.6a42d697@urahara>

On 11/26/14 1:56 PM, Stephen Hemminger wrote:
> On Wed, 26 Nov 2014 05:53:33 -0800
> roopa@cumulusnetworks.com wrote:
>
>> diff --git a/include/uapi/linux/if_bridge.h b/include/uapi/linux/if_bridge.h
>> index da17e45..db061fd 100644
>> --- a/include/uapi/linux/if_bridge.h
>> +++ b/include/uapi/linux/if_bridge.h
>> @@ -185,6 +185,7 @@ struct br_mdb_entry {
>>   			struct in6_addr ip6;
>>   		} u;
>>   		__be16		proto;
>> +		__be16		vid;
>>   	} addr;
>>   };
>>
>
> You can't add fields to existing binary API
>

Roopa, maybe a description of what use case this is trying to solve 
would better justify the addition to the UAPI?

-Jon

^ permalink raw reply

* Re: [PATCH net-next] sky2: Fix crash inside sky2_rx_clean
From: Stephen Hemminger @ 2014-11-26 18:57 UTC (permalink / raw)
  To: Mirko Lindner; +Cc: davem, netdev@vger.kernel.org
In-Reply-To: <5475E012.3060607@marvell.com>

On Wed, 26 Nov 2014 15:13:38 +0100
Mirko Lindner <mlindner@marvell.com> wrote:

> If sky2->tx_le = pci_alloc_consistent() or sky2->tx_ring = kcalloc() in
> sky2_alloc_buffers() fails, sky2->rx_ring = kcalloc() will never be called.
> In this error case handling, sky2_rx_clean() is called from within
> sky2_free_buffers().
> 
> In sky2_rx_clean() we find the following:
> 
> ...
>    memset(sky2->rx_le, 0, RX_LE_BYTES);
> ...
> 
> This results in a memset using a NULL pointer and will crash the system.
> 
> Signed-off-by: Mirko Lindner <mlindner@marvell.com>

This matches my earlier patch, but this one is just as good

Acked-by: Stephen Hemminger <stephen@networkplumber.org>

^ permalink raw reply

* Re: [PATCH net-next] bridge: add vlan id to mdb notifications
From: Stephen Hemminger @ 2014-11-26 18:56 UTC (permalink / raw)
  To: roopa; +Cc: vyasevich, netdev, wkok, gospo, jtoppins, sashok
In-Reply-To: <1417010013-31454-1-git-send-email-roopa@cumulusnetworks.com>

On Wed, 26 Nov 2014 05:53:33 -0800
roopa@cumulusnetworks.com wrote:

> diff --git a/include/uapi/linux/if_bridge.h b/include/uapi/linux/if_bridge.h
> index da17e45..db061fd 100644
> --- a/include/uapi/linux/if_bridge.h
> +++ b/include/uapi/linux/if_bridge.h
> @@ -185,6 +185,7 @@ struct br_mdb_entry {
>  			struct in6_addr ip6;
>  		} u;
>  		__be16		proto;
> +		__be16		vid;
>  	} addr;
>  };
>  

You can't add fields to existing binary API

^ permalink raw reply

* Re: [PATCH net] r8152: drop the tx packet with invalid length
From: Eric Dumazet @ 2014-11-26 18:44 UTC (permalink / raw)
  To: David Miller; +Cc: hayeswang, netdev, nic_swsd, linux-kernel, linux-usb
In-Reply-To: <20141126.120658.498602780456343676.davem@davemloft.net>

On Wed, 2014-11-26 at 12:06 -0500, David Miller wrote:
> From: Eric Dumazet <eric.dumazet@gmail.com>
> Date: Wed, 26 Nov 2014 08:52:28 -0800
> 
> > On Wed, 2014-11-26 at 17:56 +0800, Hayes Wang wrote:
> >> Drop the tx packet which is more than the size of agg_buf_sz. When
> >> creating a bridge with the device, we may get the tx packet with
> >> TSO and the length is more than the gso_max_size which is set by
> >> the driver through netif_set_gso_max_size(). Such packets couldn't
> >> be transmitted and should be dropped directly.
> >> 
> >> Signed-off-by: Hayes Wang <hayeswang@realtek.com>
>  ...
> > Looks like a candidate for ndo_gso_check(), so that we do not drop, but
> > instead segment from netif_needs_gso()/validate_xmit_skb()
> 
> You mean have the bridge implement the ndo_gso_check() method right?

No, I meant this particular driver.

Note that netif_skb_features() does only this check :

if (gso_segs > dev->gso_max_segs || gso_segs < dev->gso_min_segs)
      features &= ~NETIF_F_GSO_MASK;


Ie not testing gso_max_size

It looks like all these particular tests should be moved on
ndo_gso_check(), to remove code from netif_skb_features()

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox