Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH net-next v2] ipvlan: Initial check-in of the IPVLAN driver.
From: Mahesh Bandewar @ 2014-11-19  5:27 UTC (permalink / raw)
  To: David Miller
  Cc: linux-netdev, Eric Dumazet, Maciej Żenczykowski,
	Laurent Chavey, Tim Hockin, brandon.philips, xemul
In-Reply-To: <20141118.155437.1582768084232091503.davem@davemloft.net>

On Tue, Nov 18, 2014 at 12:54 PM, David Miller <davem@davemloft.net> wrote:
>
> From: Mahesh Bandewar <maheshb@google.com>
> Date: Sun, 16 Nov 2014 22:27:14 -0800
>
> > +/* Define IPVL_DEBUG and set the appropriate dbg_level for debugging. */
> > +#ifdef       IPVL_DEBUG
> > +/*
> > + * 1 : non-datapath debugging
> > + * 2 : Custom
> > + * 3 : function enters and exists.
> > + * 4 : printk in data path (be careful!)
> > + */
> > +#define IPVL_DBG_LEVEL 1
> > +#define ipvlan_dbg(level, msg...)    do { \
> > +                                             if (level <= IPVL_DBG_LEVEL) \
> > +                                             printk(KERN_DEBUG msg); \
> > +                                     } while (0)
> > +#else
> > +#define ipvlan_dbg(level, msg...) do { ; } while (0)
> > +#endif
>
> The day of having code use custom local debug logging facilities is long
> gone, please use a standard mechanism for this rather than home cooked
> reimplementations.
>
Do you mean pr_err() / pr_warn() / pr_debug() etc.? or something else?

> > +/* ---- Prototype declarations ---- */
> > +/* ---- ipvlan_main.c ---- */
>
> Everone knows these are prototype declarations by virtue of them being
> functions declarations in a header file.
>
> Anyone who wants to know where these are defined can run grep.
>
> So these comments are superfluous, please remove them across this
> entire submission.
>
> > +     const struct in_addr *ip4_addr = iaddr;
> > +     return jhash_1word(ip4_addr->s_addr, ipvlan_jhash_secret)
> > +            & IPVLAN_HASH_MASK;
>
> When an expression spans multiple lines, lines end rather than begin
> with an operator.
>
> > +             if (is_v6 && addr->atype == IPVL_IPV6 &&
> > +                     ipv6_addr_equal(&addr->ip6addr, iaddr))
>
> For multi-line if() statements, the second line and subsequent lines
> must begine exactly at the first column after the openning parenthesis
> of the first line.
>
> If you are purely using TAB characters to indent, you are likely doing
> it wrong.
> > +             if ((is_v6 && addr->atype == IPVL_IPV6 &&
> > +                  ipv6_addr_equal(&addr->ip6addr, iaddr))
> > +                || (!is_v6 && addr->atype == IPVL_IPV4 &&
> > +                   addr->ip4addr.s_addr == ((struct in_addr *)iaddr)->s_addr)
>
> Lines end, not begin, with operators.
>
> > --- /dev/null
> > +++ b/drivers/net/ipvlan/ipvlan_sysfs.c
>
> Please do not add sysfs configuration knobs, netlink is sufficient.

Having it does neither add complexity nor too much code, wo why not?
May be I'm missing something! But I was think that this might provide
foundation for adding other things like config locking from master's
namespace etc. (discussed in the thread) in the future.

Thanks,
--mahesh..

^ permalink raw reply

* Re: [PATCH] bonding: clear header_ops when last slave detached (v2)
From: Eric Dumazet @ 2014-11-19  5:39 UTC (permalink / raw)
  To: Wengang Wang; +Cc: wwgwork, netdev
In-Reply-To: <1416374292-10993-1-git-send-email-wen.gang.wang@oracle.com>

On Wed, 2014-11-19 at 13:18 +0800, Wengang Wang wrote:
> When last slave of a bonding master is removed, the bonding then does not work.
> When packet_snd is called against with a master net_device, it accesses
> header_ops. In case the header_ops is not valid any longer(say ipoib module
> unloaded), it will then access an invalid memory address.
> This patch try to fix this issue by clearing header_ops when last slave
> detached.
> 
> Signed-off-by: Wengang Wang <wen.gang.wang@oracle.com>
> ---
>  drivers/net/bonding/bond_main.c | 1 +
>  1 file changed, 1 insertion(+)

It seems you basically ignored my feedback.



Some code is doing :

[A] if (dev->header_ops) {
    ...
[B]    dev->header_ops->XXX()



Nothing prevents you doing the clear after [A] , and before [B]

^ permalink raw reply

* Re: [PATCH net-next v2] ipvlan: Initial check-in of the IPVLAN driver.
From: David Miller @ 2014-11-19  5:48 UTC (permalink / raw)
  To: maheshb; +Cc: netdev, edumazet, maze, chavey, thockin, brandon.philips, xemul
In-Reply-To: <CAF2d9jjrN4cDmtN_yKTe0BS+cAqE=hqgsT_6mOEBuMTTPOaPRg@mail.gmail.com>

From: Mahesh Bandewar <maheshb@google.com>
Date: Tue, 18 Nov 2014 21:27:48 -0800

> On Tue, Nov 18, 2014 at 12:54 PM, David Miller <davem@davemloft.net> wrote:
>>
>> From: Mahesh Bandewar <maheshb@google.com>
>> Date: Sun, 16 Nov 2014 22:27:14 -0800
>>
>> > +/* Define IPVL_DEBUG and set the appropriate dbg_level for debugging. */
>> > +#ifdef       IPVL_DEBUG
>> > +/*
>> > + * 1 : non-datapath debugging
>> > + * 2 : Custom
>> > + * 3 : function enters and exists.
>> > + * 4 : printk in data path (be careful!)
>> > + */
>> > +#define IPVL_DBG_LEVEL 1
>> > +#define ipvlan_dbg(level, msg...)    do { \
>> > +                                             if (level <= IPVL_DBG_LEVEL) \
>> > +                                             printk(KERN_DEBUG msg); \
>> > +                                     } while (0)
>> > +#else
>> > +#define ipvlan_dbg(level, msg...) do { ; } while (0)
>> > +#endif
>>
>> The day of having code use custom local debug logging facilities is long
>> gone, please use a standard mechanism for this rather than home cooked
>> reimplementations.
>>
> Do you mean pr_err() / pr_warn() / pr_debug() etc.? or something else?

And netdev_dbg(), etc.

And about sysfs, we're not having two ways to do the same exact
thing.  Whatever functionality you want to provide, implement it
via netlink and that's the end of it.

^ permalink raw reply

* Re: [PATCH net] openvswitch: Fix mask generation for IPv6 labels.
From: Pravin Shelar @ 2014-11-19  6:09 UTC (permalink / raw)
  To: Joe Stringer; +Cc: netdev, LKML, dev@openvswitch.org
In-Reply-To: <1416336857-61405-1-git-send-email-joestringer@nicira.com>

On Tue, Nov 18, 2014 at 10:54 AM, Joe Stringer <joestringer@nicira.com> wrote:
> When userspace doesn't provide a mask, OVS datapath generates a fully
> unwildcarded mask for the flow. This is done by taking a copy of the
> flow key, then iterating across its attributes, setting all values to
> 0xff. This works for most attributes, as the length of the netlink
> attribute typically matches the length of the value. However, IPv6
> labels only use the lower 20 bits of the field. This patch makes a
> special case to handle this.
>
> This fixes the following error seen when installing IPv6 flows without a mask:
>
> openvswitch: netlink: Invalid IPv6 flow label value (value=ffffffff, max=fffff)
>
We should allow exact match mask here rather than generating
wildcarded mask. So that ovs can catch invalid ipv6.label.


> Signed-off-by: Joe Stringer <joestringer@nicira.com>
> ---
>  net/openvswitch/flow_netlink.c |   22 ++++++++++++----------
>  1 file changed, 12 insertions(+), 10 deletions(-)
>
> diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
> index fa4ec2e..7a5b28f 100644
> --- a/net/openvswitch/flow_netlink.c
> +++ b/net/openvswitch/flow_netlink.c
> @@ -825,7 +825,7 @@ static int ovs_key_from_nlattrs(struct sw_flow_match *match, u64 attrs,
>         return 0;
>  }
>
> -static void nlattr_set(struct nlattr *attr, u8 val, bool is_attr_mask_key)
> +static void mask_set_nlattr(struct nlattr *attr)
>  {
>         struct nlattr *nla;
>         int rem;
> @@ -835,16 +835,18 @@ static void nlattr_set(struct nlattr *attr, u8 val, bool is_attr_mask_key)
>                 /* We assume that ovs_key_lens[type] == -1 means that type is a
>                  * nested attribute
>                  */
> -               if (is_attr_mask_key && ovs_key_lens[nla_type(nla)] == -1)
> -                       nlattr_set(nla, val, false);
> +               if (ovs_key_lens[nla_type(nla)] == -1)
> +                       nla_for_each_nested(nla, attr, rem)
> +                               memset(nla_data(nla), 0xff, nla_len(nla));
>                 else
> -                       memset(nla_data(nla), val, nla_len(nla));
> -       }
> -}
> +                       memset(nla_data(nla), 0xff, nla_len(nla));
>
> -static void mask_set_nlattr(struct nlattr *attr, u8 val)
> -{
> -       nlattr_set(attr, val, true);
> +               if (nla_type(nla) == OVS_KEY_ATTR_IPV6) {
> +                       struct ovs_key_ipv6 *ipv6_key = nla_data(nla);
> +
> +                       ipv6_key->ipv6_label &= htonl(0x000FFFFF);
> +               }
> +       }
>  }
>
>  /**
> @@ -926,7 +928,7 @@ int ovs_nla_get_match(struct sw_flow_match *match,
>                 if (!newmask)
>                         return -ENOMEM;
>
> -               mask_set_nlattr(newmask, 0xff);
> +               mask_set_nlattr(newmask);
>
>                 /* The userspace does not send tunnel attributes that are 0,
>                  * but we should not wildcard them nonetheless.
> --
> 1.7.10.4
>

^ permalink raw reply

* Re: [PATCH v2 net-next] tcp: make connect() mem charging friendly
From: Yuchung Cheng @ 2014-11-19  6:10 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Denys Fedoryshchenko, David Miller, netdev, Neal Cardwell
In-Reply-To: <1416294380.14060.6.camel@edumazet-glaptop2.roam.corp.google.com>

On Tue, Nov 18, 2014 at 3:06 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> From: Eric Dumazet <edumazet@google.com>
>
> While working on sk_forward_alloc problems reported by Denys
> Fedoryshchenko, we found that tcp connect() (and fastopen) do not call
> sk_wmem_schedule() for SYN packet (and/or SYN/DATA packet), so
> sk_forward_alloc is negative while connect is in progress.
>
> We can fix this by calling regular sk_stream_alloc_skb() both for the
> SYN packet (in tcp_connect()) and the syn_data packet in
> tcp_send_syn_data()
>
> Then, tcp_send_syn_data() can avoid copying syn_data as we simply
> can manipulate syn_data->cb[] to remove SYN flag (and increment seq)
>
> Instead of open coding memcpy_fromiovecend(), simply use this helper.
>
> This leaves in socket write queue clean fast clone skbs.
>
> This was tested against our fastopen packetdrill tests.
>
> Reported-by: Denys Fedoryshchenko <nuclearcat@nuclearcat.com>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
Acked-by: Yuchung Cheng <ycheng@google.com>

Thanks! this simplifies the code a lot.

> ---
> v2: added a kfree_skb(syn_data) if memcpy_fromiovecend() fails,
>     as spotted by Yuchung.
>
>  net/ipv4/tcp_output.c |   68 ++++++++++++++++------------------------
>  1 file changed, 28 insertions(+), 40 deletions(-)
>
> diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
> index eb73a1dccf56b823a45c0ca034e40dc50fc48068..f5bd4bd3f7e669b3fd48a843d55e7313a30a3409 100644
> --- a/net/ipv4/tcp_output.c
> +++ b/net/ipv4/tcp_output.c
> @@ -3011,9 +3011,9 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn)
>  {
>         struct tcp_sock *tp = tcp_sk(sk);
>         struct tcp_fastopen_request *fo = tp->fastopen_req;
> -       int syn_loss = 0, space, i, err = 0, iovlen = fo->data->msg_iovlen;
> -       struct sk_buff *syn_data = NULL, *data;
> +       int syn_loss = 0, space, err = 0;
>         unsigned long last_syn_loss = 0;
> +       struct sk_buff *syn_data;
>
>         tp->rx_opt.mss_clamp = tp->advmss;  /* If MSS is not cached */
>         tcp_fastopen_cache_get(sk, &tp->rx_opt.mss_clamp, &fo->cookie,
> @@ -3044,48 +3044,40 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn)
>         /* limit to order-0 allocations */
>         space = min_t(size_t, space, SKB_MAX_HEAD(MAX_TCP_HEADER));
>
> -       syn_data = skb_copy_expand(syn, MAX_TCP_HEADER, space,
> -                                  sk->sk_allocation);
> -       if (syn_data == NULL)
> +       syn_data = sk_stream_alloc_skb(sk, space, sk->sk_allocation);
> +       if (!syn_data)
>                 goto fallback;
> +       syn_data->ip_summed = CHECKSUM_PARTIAL;
> +       memcpy(syn_data->cb, syn->cb, sizeof(syn->cb));
> +       if (unlikely(memcpy_fromiovecend(skb_put(syn_data, space),
> +                                        fo->data->msg_iov, 0, space))) {
> +               kfree_skb(syn_data);
> +               goto fallback;
> +       }
>
> -       for (i = 0; i < iovlen && syn_data->len < space; ++i) {
> -               struct iovec *iov = &fo->data->msg_iov[i];
> -               unsigned char __user *from = iov->iov_base;
> -               int len = iov->iov_len;
> +       /* No more data pending in inet_wait_for_connect() */
> +       if (space == fo->size)
> +               fo->data = NULL;
> +       fo->copied = space;
>
> -               if (syn_data->len + len > space)
> -                       len = space - syn_data->len;
> -               else if (i + 1 == iovlen)
> -                       /* No more data pending in inet_wait_for_connect() */
> -                       fo->data = NULL;
> +       tcp_connect_queue_skb(sk, syn_data);
>
> -               if (skb_add_data(syn_data, from, len))
> -                       goto fallback;
> -       }
> +       err = tcp_transmit_skb(sk, syn_data, 1, sk->sk_allocation);
>
> -       /* Queue a data-only packet after the regular SYN for retransmission */
> -       data = pskb_copy(syn_data, sk->sk_allocation);
> -       if (data == NULL)
> -               goto fallback;
> -       TCP_SKB_CB(data)->seq++;
> -       TCP_SKB_CB(data)->tcp_flags &= ~TCPHDR_SYN;
> -       TCP_SKB_CB(data)->tcp_flags = (TCPHDR_ACK|TCPHDR_PSH);
> -       tcp_connect_queue_skb(sk, data);
> -       fo->copied = data->len;
> -
> -       /* syn_data is about to be sent, we need to take current time stamps
> -        * for the packets that are in write queue : SYN packet and DATA
> -        */
> -       skb_mstamp_get(&syn->skb_mstamp);
> -       data->skb_mstamp = syn->skb_mstamp;
> +       syn->skb_mstamp = syn_data->skb_mstamp;
>
> -       if (tcp_transmit_skb(sk, syn_data, 0, sk->sk_allocation) == 0) {
> +       /* Now full SYN+DATA was cloned and sent (or not),
> +        * remove the SYN from the original skb (syn_data)
> +        * we keep in write queue in case of a retransmit, as we
> +        * also have the SYN packet (with no data) in the same queue.
> +        */
> +       TCP_SKB_CB(syn_data)->seq++;
> +       TCP_SKB_CB(syn_data)->tcp_flags = TCPHDR_ACK | TCPHDR_PSH;
> +       if (!err) {
>                 tp->syn_data = (fo->copied > 0);
>                 NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPORIGDATASENT);
>                 goto done;
>         }
> -       syn_data = NULL;
>
>  fallback:
>         /* Send a regular SYN with Fast Open cookie request option */
> @@ -3094,7 +3086,6 @@ fallback:
>         err = tcp_transmit_skb(sk, syn, 1, sk->sk_allocation);
>         if (err)
>                 tp->syn_fastopen = 0;
> -       kfree_skb(syn_data);
>  done:
>         fo->cookie.len = -1;  /* Exclude Fast Open option for SYN retries */
>         return err;
> @@ -3114,13 +3105,10 @@ int tcp_connect(struct sock *sk)
>                 return 0;
>         }
>
> -       buff = alloc_skb_fclone(MAX_TCP_HEADER + 15, sk->sk_allocation);
> -       if (unlikely(buff == NULL))
> +       buff = sk_stream_alloc_skb(sk, 0, sk->sk_allocation);
> +       if (unlikely(!buff))
>                 return -ENOBUFS;
>
> -       /* Reserve space for headers. */
> -       skb_reserve(buff, MAX_TCP_HEADER);
> -
>         tcp_init_nondata_skb(buff, tp->write_seq++, TCPHDR_SYN);
>         tp->retrans_stamp = tcp_time_stamp;
>         tcp_connect_queue_skb(sk, buff);
>
>

^ permalink raw reply

* Re: [PATCH net] bonding: fix curr_active_slave/carrier with loadbalance arp monitoring
From: Ding Tianhong @ 2014-11-19  6:20 UTC (permalink / raw)
  To: Andy Gospodarek, Veaceslav Falico
  Cc: Nikolay Aleksandrov, netdev, davem, Jay Vosburgh, Andy Gospodarek
In-Reply-To: <20141118152847.GB2002@gospo.home.greyhouse.net>

On 2014/11/18 23:28, Andy Gospodarek wrote:
> On Tue, Nov 18, 2014 at 03:37:27PM +0100, Veaceslav Falico wrote:
>> On Tue, Nov 18, 2014 at 03:14:44PM +0100, Nikolay Aleksandrov wrote:
>>> Since commit 6fde8f037e60 ("bonding: fix locking in
>>> bond_loadbalance_arp_mon()") we can have a stale bond carrier state and
>>> stale curr_active_slave when using arp monitoring in loadbalance modes. The
>>> reason is that in bond_loadbalance_arp_mon() we can't have
>>> do_failover == true but slave_state_changed == false, whenever do_failover
>>> is true then slave_state_changed is also true. Then the following piece
>> >from bond_loadbalance_arp_mon():
>>>               if (slave_state_changed) {
>>>                       bond_slave_state_change(bond);
>>>                       if (BOND_MODE(bond) == BOND_MODE_XOR)
>>>                               bond_update_slave_arr(bond, NULL);
>>>               } else if (do_failover) {
>>
>> Ouch, must have been a big PITA to track :).
> 
> Agreed!
> 
>>
>>>                       block_netpoll_tx();
>>>                       bond_select_active_slave(bond);
>>>                       unblock_netpoll_tx();
>>>               }
>>>
>>> will execute only the first branch, always and regardless of do_failover.
>>> Since these two events aren't related in such way, we need to decouple and
>>> consider them separately.
>>>
>>> For example this issue could lead to the following result:
>>> Bonding Mode: load balancing (round-robin)
>>> *MII Status: down*
>>> MII Polling Interval (ms): 0
>>> Up Delay (ms): 0
>>> Down Delay (ms): 0
>>> ARP Polling Interval (ms): 100
>>> ARP IP target/s (n.n.n.n form): 192.168.9.2
>>>
>>> Slave Interface: ens12
>>> *MII Status: up*
>>> Speed: 10000 Mbps
>>> Duplex: full
>>> Link Failure Count: 2
>>> Permanent HW addr: 00:0f:53:01:42:2c
>>> Slave queue ID: 0
>>>
>>> Slave Interface: eth1
>>> *MII Status: up*
>>> Speed: Unknown
>>> Duplex: Unknown
>>> Link Failure Count: 70
>>> Permanent HW addr: 52:54:00:2f:0f:8e
>>> Slave queue ID: 0
>>>
>>> Since some interfaces are up, then the status of the bond should also be
>>> up, but it will never change unless something invokes bond_set_carrier()
>>> (i.e. enslave, bond_select_active_slave etc). Now, if I force the
>>> calling of bond_select_active_slave via for example changing
>>> primary_reselect (it can change in any mode), then the MII status goes to
>>> "up" because it calls bond_select_active_slave() which should've been done
>> >from bond_loadbalance_arp_mon() itself.
>>>
>>> CC: Veaceslav Falico <vfalico@gmail.com>
>>
>> Acked-by: Veaceslav Falico <vfalico@gmail.com>
> 
> Acked-by: Andy Gospodarek <gospo@cumulusnetworks.com>
> 
Acked-by: Ding Tianhong <dingtianhong@huawei.com>

>>
>>> CC: Jay Vosburgh <j.vosburgh@gmail.com>
>>> CC: Andy Gospodarek <andy@greyhouse.net>
>>> CC: Ding Tianhong <dingtianhong@huawei.com>
>>>
>>> Fixes: 6fde8f037e60 ("bonding: fix locking in bond_loadbalance_arp_mon()")
>>> Signed-off-by: Nikolay Aleksandrov <nikolay@redhat.com>
>>> ---
>>> Note: I left the parent if() the same even though we can shorten it. I think
>>>     it's better this way since it shows that any of the two events can cause
>>>     it to enter even though currently we can't have do_failover without
>>>     slave_state_changed, that may also change in the future.
>>>
>>> drivers/net/bonding/bond_main.c | 3 ++-
>>> 1 file changed, 2 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
>>> index c9ac06cfe6b7..a5115fb7cf33 100644
>>> --- a/drivers/net/bonding/bond_main.c
>>> +++ b/drivers/net/bonding/bond_main.c
>>> @@ -2471,7 +2471,8 @@ static void bond_loadbalance_arp_mon(struct work_struct *work)
>>> 			bond_slave_state_change(bond);
>>> 			if (BOND_MODE(bond) == BOND_MODE_XOR)
>>> 				bond_update_slave_arr(bond, NULL);
>>> -		} else if (do_failover) {
>>> +		}
>>> +		if (do_failover) {
>>> 			block_netpoll_tx();
>>> 			bond_select_active_slave(bond);
>>> 			unblock_netpoll_tx();
>>> -- 
>>> 1.9.3
>>>
>> --
>> 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
> 
> .
> 

^ permalink raw reply

* Re: [BNX2] A Netdev Watchdog with kernel stable 3.4
From: Rui Xiang @ 2014-11-19  6:28 UTC (permalink / raw)
  To: Michael Chan; +Cc: netdev
In-Reply-To: <5469ED24.7010008@huawei.com>

ping...

On 2014/11/17 20:42, Rui Xiang wrote:
> Hi Michael,
> 
> On a system that was running stable 3.4.87, I got the below stack.
> That was a NETDEV WATCHDOG. And we could also see watchdog timeouts with the 
> BNX2. (After the stack, an oops occurred while running ifconfig. I think it 
> would be related to this timeout.)
> 
> Otherwises, the bnx2_dump_state and bnx2_dump_mcp_state have printed the states. 
> Through these states info, can we got the real situation of NIC1.
> Or can we see what resulted the WATCHDOG, a bnx2 device fault or other reasons.
> 
> Thanks.
> 
> 
> *The stack*:
> 
>  WARNING: at /usr/src/packages/BUILD/kernel-default-3.4.87/linux-3.4/net/sched/sch_generic.c:256 dev_watchdog+0x256/0x260()
>  NETDEV WATCHDOG: NIC1 (bnx2): transmit queue 3 timed out
>  Modules linked in: smb3_failover(O) smb2(O) smb(O) smb_manager(O) nfs(O) nfs_acl(O) nfsd(O) lockd(O) nal(O) auth_rpcgss(O) 
> scsi_dh_hp_sw scsi_dh_alua scsi_dh_emc scsi_dh_rdac scsi_dh scsi_mod [last unloaded: ipmi_msghandler]
>  Pid: 0, comm: swapper/0 Tainted: P        W  O 3.4.87-default #1
>  Call Trace:
>   <IRQ>  [<ffffffff8103fcea>] warn_slowpath_common+0x7a/0xb0
>   [<ffffffff8103fdc1>] warn_slowpath_fmt+0x41/0x50
>   [<ffffffff81047749>] ? raise_softirq_irqoff+0x9/0x30
>   [<ffffffff813ae0f6>] dev_watchdog+0x256/0x260
>   [<ffffffff813adea0>] ? dev_deactivate_queue.constprop.30+0x70/0x70
>   [<ffffffff8104edc7>] run_timer_softirq+0x147/0x340
>   [<ffffffff810470d8>] __do_softirq+0xc8/0x1e0
>   [<ffffffff8109250f>] ? tick_program_event+0x1f/0x30
>   [<ffffffff81460a6c>] call_softirq+0x1c/0x30
>   [<ffffffff8100417d>] do_softirq+0x9d/0xd0
>   [<ffffffff810474a5>] irq_exit+0xb5/0xc0
>   [<ffffffff81021b49>] smp_apic_timer_interrupt+0x69/0xa0
>   [<ffffffff8146006f>] apic_timer_interrupt+0x6f/0x80
>   <EOI>  [<ffffffff81457bdd>] ? retint_restore_args+0x13/0x13
>   [<ffffffff81360149>] ? poll_idle+0x49/0x90
>   [<ffffffff8136011f>] ? poll_idle+0x1f/0x90
>   [<ffffffff8135fcc9>] cpuidle_enter+0x19/0x20
>   [<ffffffff813602f2>] cpuidle_idle_call+0xa2/0x250
>   [<ffffffff8100b08f>] cpu_idle+0x6f/0xe0
>   [<ffffffff81915960>] ? rawsock_init+0x12/0x12
>   [<ffffffff814331c9>] rest_init+0x6d/0x74
>   [<ffffffff818d3be5>] start_kernel+0x3a2/0x3af
>   [<ffffffff818d3642>] ? repair_env_string+0x5e/0x5e
>   [<ffffffff818d332a>] x86_64_start_reservations+0x131/0x135
>   [<ffffffff818d342e>] x86_64_start_kernel+0x100/0x10f
>  ---[ end trace 497e24e681e0c02d ]---
>  bnx2 0000:05:00.1: NIC1: DEBUG: intr_sem[0] PCI_CMD[00100002]
>  bnx2 0000:05:00.1: NIC1: DEBUG: PCI_PM[19002008] PCI_MISC_CFG[92000088]
>  bnx2 0000:05:00.1: NIC1: DEBUG: EMAC_TX_STATUS[00000008] EMAC_RX_STATUS[00000000]
>  bnx2 0000:05:00.1: NIC1: DEBUG: RPM_MGMT_PKT_CTRL[40000088]
>  bnx2 0000:05:00.1: NIC1: DEBUG: HC_STATS_INTERRUPT_STATUS[01ff0000]
>  bnx2 0000:05:00.1: NIC1: DEBUG: PBA[00000000]
>  bnx2 0000:05:00.1: NIC1: <--- start MCP states dump --->
>  bnx2 0000:05:00.1: NIC1: DEBUG: MCP_STATE_P0[0003e10e] MCP_STATE_P1[0003e10e]
>  bnx2 0000:05:00.1: NIC1: DEBUG: MCP mode[0000b800] state[80008000] evt_mask[00000500]
>  bnx2 0000:05:00.1: NIC1: DEBUG: pc[08008f60] pc[0800d21c] instr[00051080]
>  bnx2 0000:05:00.1: NIC1: DEBUG: shmem states:
>  bnx2 0000:05:00.1: NIC1: DEBUG: drv_mb[01030003] fw_mb[00000003] link_status[0000006f] drv_pulse_mb[0000073d]
>  bnx2 0000:05:00.1: NIC1: DEBUG: dev_info_signature[44564907] reset_type[01005254] condition[0003e10e]
>  bnx2 0000:05:00.1: NIC1: DEBUG: 000003cc: 00000000 00000000 00000000 00000000
>  bnx2 0000:05:00.1: NIC1: DEBUG: 000003dc: 00000000 00000000 00000000 00000000
>  bnx2 0000:05:00.1: NIC1: DEBUG: 000003ec: 00000000 00000000 00000000 00000000
>  bnx2 0000:05:00.1: NIC1: DEBUG: 0x3fc[00000000]
>  bnx2 0000:05:00.1: NIC1: <--- end MCP states dump --->
> 

^ permalink raw reply

* Re: [PATCH net-next 0/4] igb: auxiliary PHC functions for the i210.
From: Richard Cochran @ 2014-11-19  6:31 UTC (permalink / raw)
  To: Jeff Kirsher
  Cc: netdev, David Miller, bruce.w.allan, Jacob Keller, John Ronciak,
	Matthew Vick
In-Reply-To: <1416266118.2983.3.camel@jtkirshe-mobl.jf.intel.com>

On Mon, Nov 17, 2014 at 03:15:18PM -0800, Jeff Kirsher wrote:
> Thanks Richard, I have added your series of igb patches to my queue.

Jeff, please hold off on these. I found a bug in the PPS code. I will
re-submit with a fix.

Thanks,
Richard

^ permalink raw reply

* [PATCH net] virtio-net: validate features during probe
From: Jason Wang @ 2014-11-19  6:35 UTC (permalink / raw)
  To: rusty, mst, virtualization, netdev, linux-kernel

This patch validates feature dependencies during probe and fail the probing
if a dependency is missed. This fixes the issues of hitting BUG()
when qemu fails to advertise features correctly. One example is booting
guest with ctrl_vq=off through qemu.

Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: Wanlong Gao <gaowanlong@cn.fujitsu.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
 drivers/net/virtio_net.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 93 insertions(+)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index ec2a8b4..4a0ad46 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1673,6 +1673,95 @@ static const struct attribute_group virtio_net_mrg_rx_group = {
 };
 #endif
 
+static int virtnet_validate_features(struct virtio_device *dev,
+				     unsigned int *table,
+				     int table_size,
+				     unsigned int feature)
+{
+	int i;
+
+	if (!virtio_has_feature(dev, feature)) {
+		for (i = 0; i < table_size; i++) {
+			unsigned int f = table[i];
+
+			if (virtio_has_feature(dev, f)) {
+				dev_err(&dev->dev,
+					"buggy hyperviser: feature 0x%x was advertised but its dependency 0x%x was not",
+					f, feature);
+				return -EINVAL;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int virtnet_check_features(struct virtio_device *dev)
+{
+	unsigned int features_for_ctrl_vq[] = {
+		VIRTIO_NET_F_CTRL_RX,
+		VIRTIO_NET_F_CTRL_VLAN,
+		VIRTIO_NET_F_GUEST_ANNOUNCE,
+		VIRTIO_NET_F_MQ,
+		VIRTIO_NET_F_CTRL_MAC_ADDR
+	};
+	unsigned int features_for_guest_csum[] = {
+		VIRTIO_NET_F_GUEST_TSO4,
+		VIRTIO_NET_F_GUEST_TSO6,
+		VIRTIO_NET_F_GUEST_ECN,
+		VIRTIO_NET_F_GUEST_UFO,
+	};
+	unsigned int features_for_host_csum[] = {
+		VIRTIO_NET_F_HOST_TSO4,
+		VIRTIO_NET_F_HOST_TSO6,
+		VIRTIO_NET_F_HOST_ECN,
+		VIRTIO_NET_F_HOST_UFO,
+	};
+	int err;
+
+	err = virtnet_validate_features(dev, features_for_ctrl_vq,
+					ARRAY_SIZE(features_for_ctrl_vq),
+					VIRTIO_NET_F_CTRL_VQ);
+	if (err)
+		return err;
+
+	err = virtnet_validate_features(dev, features_for_guest_csum,
+					ARRAY_SIZE(features_for_guest_csum),
+					VIRTIO_NET_F_GUEST_CSUM);
+	if (err)
+		return err;
+
+	err = virtnet_validate_features(dev, features_for_host_csum,
+					ARRAY_SIZE(features_for_host_csum),
+					VIRTIO_NET_F_CSUM);
+	if (err)
+		return err;
+
+	if (virtio_has_feature(dev, VIRTIO_NET_F_GUEST_ECN) &&
+	    (!virtio_has_feature(dev, VIRTIO_NET_F_GUEST_TSO4) ||
+	     !virtio_has_feature(dev, VIRTIO_NET_F_GUEST_TSO6))) {
+		dev_err(&dev->dev,
+			"buggy hyperviser: feature 0x%x was advertised but its dependency 0x%x or 0x%x was not",
+			VIRTIO_NET_F_GUEST_ECN,
+			VIRTIO_NET_F_GUEST_TSO4,
+			VIRTIO_NET_F_GUEST_TSO6);
+		return -EINVAL;
+	}
+
+	if (virtio_has_feature(dev, VIRTIO_NET_F_HOST_ECN) &&
+	    (!virtio_has_feature(dev, VIRTIO_NET_F_HOST_TSO4) ||
+	     !virtio_has_feature(dev, VIRTIO_NET_F_HOST_TSO6))) {
+		dev_err(&dev->dev,
+			"buggy hyperviser: feature 0x%x was advertised but its dependency 0x%x or 0x%x was not",
+			VIRTIO_NET_F_HOST_ECN,
+			VIRTIO_NET_F_HOST_TSO4,
+			VIRTIO_NET_F_HOST_TSO6);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int virtnet_probe(struct virtio_device *vdev)
 {
 	int i, err;
@@ -1680,6 +1769,10 @@ static int virtnet_probe(struct virtio_device *vdev)
 	struct virtnet_info *vi;
 	u16 max_queue_pairs;
 
+	err = virtnet_check_features(vdev);
+	if (err)
+		return -EINVAL;
+
 	/* Find if host supports multiqueue virtio_net device */
 	err = virtio_cread_feature(vdev, VIRTIO_NET_F_MQ,
 				   struct virtio_net_config,
-- 
1.9.1

^ permalink raw reply related

* Re: [PATCH net-next 3/4] igb: enable internal PPS for the i210.
From: Richard Cochran @ 2014-11-19  6:37 UTC (permalink / raw)
  To: netdev
  Cc: David Miller, bruce.w.allan, Jacob Keller, Jeff Kirsher,
	John Ronciak, Matthew Vick
In-Reply-To: <e5b4ef7c56119e2d86e42f5680b1b82c9ec1a38e.1416265321.git.richardcochran@gmail.com>

On Tue, Nov 18, 2014 at 12:06:24AM +0100, Richard Cochran wrote:
> --- a/drivers/net/ethernet/intel/igb/igb_main.c
> +++ b/drivers/net/ethernet/intel/igb/igb_main.c
> @@ -5386,8 +5386,14 @@ void igb_update_stats(struct igb_adapter *adapter,
>  static void igb_tsync_interrupt(struct igb_adapter *adapter)
>  {
>  	struct e1000_hw *hw = &adapter->hw;
> +	struct ptp_clock_event event;
>  	u32 tsicr = rd32(E1000_TSICR);
>  
> +	if (tsicr & TSINTR_SYS_WRAP) {
> +		event.type = PTP_CLOCK_PPS;
> +		ptp_clock_event(adapter->ptp_clock, &event);

This causes a BUG for the 82580. When you enable E1000_TSICR_TXTS, it
seems that TSINTR_SYS_WRAP is also automatically enabled. Because the
82580 variant has no pps device enabled, the driver then dereferences
a null pointer.

So we need to make the call to ptp_clock_event() conditional based on
whether pps is enabled. I'll fix this in V2.

> +	}
> +

Thanks,
Richard

^ permalink raw reply

* [PATCH net] tcp: fix connect() invalid -EADDRNOTAVAIL error
From: Jon Maxwell @ 2014-11-19  6:37 UTC (permalink / raw)
  To: davem
  Cc: kuznet, jmorris, yoshfuji, kaber, netdev, linux-kernel, jmaxwell,
	Jon Maxwell

The connect() routine returns -EADDRNOTAVAIL without doing a 4 
tuple check when the hash buckets were previously allocated by 
bind() and all local ports are used.

The bind() routine creates the local port hash buckets in 
inet_csk_get_port(). Depending on the socket options it sets 
tb->fastreuse and tb->fastreuseport to 0 or 1 in the bucket.

However the __inet_hash_connect() routine initializes the hash 
buckets differently and sets these to -1. The end result is 
that connect() calling into __inet_hash_connect() will 
subsequently ignore the check_established() routine if, here

__inet_hash_connect()
.
.
if (tb->fastreuse >= 0 ||↩
    tb->fastreuseport >= 0)↩
    goto next_port;

and cycle through all local ports until it returns -EADDRNOTAVAIL. 
The 4 tuple check is in check_established() so connect() can fail 
unnecessarily.

Prerequisites for this to happen:
1) The local tcp port range must be exhausted.
2) A process must have called bind() followed by connect() for all 
local ports.
3) A different process calls connect() only which returns -EADDRNOTAVAIL. 
4) The system more than 1 interface configured.

If a system has 2 IP Addresses and all local tcp ports are in use
for connection from IP Address (1). Connecting to the same ports 
via IP Address (2) should work based on the 4 tuple rule. But it 
fails under this condition. 

To fix this make __inet_hash_connect() honour inet_csk_get_port()'s
tb->fastreuse* variables.

Signed-off-by: Jon Maxwell <jmaxwell37@gmail.com>
---
 net/ipv4/inet_hashtables.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index 9111a4e..b39e89e 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -513,8 +513,8 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
 			inet_bind_bucket_for_each(tb, &head->chain) {
 				if (net_eq(ib_net(tb), net) &&
 				    tb->port == port) {
-					if (tb->fastreuse >= 0 ||
-					    tb->fastreuseport >= 0)
+					if (tb->fastreuse > 0 ||
+					    tb->fastreuseport > 0)
 						goto next_port;
 					WARN_ON(hlist_empty(&tb->owners));
 					if (!check_established(death_row, sk,
@@ -530,8 +530,6 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
 				spin_unlock(&head->lock);
 				break;
 			}
-			tb->fastreuse = -1;
-			tb->fastreuseport = -1;
 			goto ok;
 
 		next_port:
-- 
1.8.3.1

^ permalink raw reply related

* Re: [BNX2] A Netdev Watchdog with kernel stable 3.4
From: Michael Chan @ 2014-11-19  6:58 UTC (permalink / raw)
  To: Rui Xiang, sony.chacko; +Cc: netdev
In-Reply-To: <546C388B.2050603@huawei.com>

Copying the current maintainer Sony.  The PCI command register looks
strange.  Please see below.

On Wed, 2014-11-19 at 14:28 +0800, Rui Xiang wrote: 
> ping...
> 
> On 2014/11/17 20:42, Rui Xiang wrote:
> > Hi Michael,
> > 
> > On a system that was running stable 3.4.87, I got the below stack.
> > That was a NETDEV WATCHDOG. And we could also see watchdog timeouts with the 
> > BNX2. (After the stack, an oops occurred while running ifconfig. I think it 
> > would be related to this timeout.)
> > 
> > Otherwises, the bnx2_dump_state and bnx2_dump_mcp_state have printed the states. 
> > Through these states info, can we got the real situation of NIC1.
> > Or can we see what resulted the WATCHDOG, a bnx2 device fault or other reasons.
> > 
> > Thanks.
> > 
> > 
> > *The stack*:
> > 
> >  WARNING: at /usr/src/packages/BUILD/kernel-default-3.4.87/linux-3.4/net/sched/sch_generic.c:256 dev_watchdog+0x256/0x260()
> >  NETDEV WATCHDOG: NIC1 (bnx2): transmit queue 3 timed out
> >  Modules linked in: smb3_failover(O) smb2(O) smb(O) smb_manager(O) nfs(O) nfs_acl(O) nfsd(O) lockd(O) nal(O) auth_rpcgss(O) 
> > scsi_dh_hp_sw scsi_dh_alua scsi_dh_emc scsi_dh_rdac scsi_dh scsi_mod [last unloaded: ipmi_msghandler]
> >  Pid: 0, comm: swapper/0 Tainted: P        W  O 3.4.87-default #1
> >  Call Trace:
> >   <IRQ>  [<ffffffff8103fcea>] warn_slowpath_common+0x7a/0xb0
> >   [<ffffffff8103fdc1>] warn_slowpath_fmt+0x41/0x50
> >   [<ffffffff81047749>] ? raise_softirq_irqoff+0x9/0x30
> >   [<ffffffff813ae0f6>] dev_watchdog+0x256/0x260
> >   [<ffffffff813adea0>] ? dev_deactivate_queue.constprop.30+0x70/0x70
> >   [<ffffffff8104edc7>] run_timer_softirq+0x147/0x340
> >   [<ffffffff810470d8>] __do_softirq+0xc8/0x1e0
> >   [<ffffffff8109250f>] ? tick_program_event+0x1f/0x30
> >   [<ffffffff81460a6c>] call_softirq+0x1c/0x30
> >   [<ffffffff8100417d>] do_softirq+0x9d/0xd0
> >   [<ffffffff810474a5>] irq_exit+0xb5/0xc0
> >   [<ffffffff81021b49>] smp_apic_timer_interrupt+0x69/0xa0
> >   [<ffffffff8146006f>] apic_timer_interrupt+0x6f/0x80
> >   <EOI>  [<ffffffff81457bdd>] ? retint_restore_args+0x13/0x13
> >   [<ffffffff81360149>] ? poll_idle+0x49/0x90
> >   [<ffffffff8136011f>] ? poll_idle+0x1f/0x90
> >   [<ffffffff8135fcc9>] cpuidle_enter+0x19/0x20
> >   [<ffffffff813602f2>] cpuidle_idle_call+0xa2/0x250
> >   [<ffffffff8100b08f>] cpu_idle+0x6f/0xe0
> >   [<ffffffff81915960>] ? rawsock_init+0x12/0x12
> >   [<ffffffff814331c9>] rest_init+0x6d/0x74
> >   [<ffffffff818d3be5>] start_kernel+0x3a2/0x3af
> >   [<ffffffff818d3642>] ? repair_env_string+0x5e/0x5e
> >   [<ffffffff818d332a>] x86_64_start_reservations+0x131/0x135
> >   [<ffffffff818d342e>] x86_64_start_kernel+0x100/0x10f
> >  ---[ end trace 497e24e681e0c02d ]---
> >  bnx2 0000:05:00.1: NIC1: DEBUG: intr_sem[0] PCI_CMD[00100002]

The memory bit in PCI_CMD is set, but the bus master bit is not set.
DMA won't work if the bus master bit is not set.  What was happening
before the timeout?  Was it working fine for a while and it suddenly
stopped?

> >  bnx2 0000:05:00.1: NIC1: DEBUG: PCI_PM[19002008] PCI_MISC_CFG[92000088]
> >  bnx2 0000:05:00.1: NIC1: DEBUG: EMAC_TX_STATUS[00000008] EMAC_RX_STATUS[00000000]
> >  bnx2 0000:05:00.1: NIC1: DEBUG: RPM_MGMT_PKT_CTRL[40000088]
> >  bnx2 0000:05:00.1: NIC1: DEBUG: HC_STATS_INTERRUPT_STATUS[01ff0000]
> >  bnx2 0000:05:00.1: NIC1: DEBUG: PBA[00000000]
> >  bnx2 0000:05:00.1: NIC1: <--- start MCP states dump --->
> >  bnx2 0000:05:00.1: NIC1: DEBUG: MCP_STATE_P0[0003e10e] MCP_STATE_P1[0003e10e]
> >  bnx2 0000:05:00.1: NIC1: DEBUG: MCP mode[0000b800] state[80008000] evt_mask[00000500]
> >  bnx2 0000:05:00.1: NIC1: DEBUG: pc[08008f60] pc[0800d21c] instr[00051080]
> >  bnx2 0000:05:00.1: NIC1: DEBUG: shmem states:
> >  bnx2 0000:05:00.1: NIC1: DEBUG: drv_mb[01030003] fw_mb[00000003] link_status[0000006f] drv_pulse_mb[0000073d]
> >  bnx2 0000:05:00.1: NIC1: DEBUG: dev_info_signature[44564907] reset_type[01005254] condition[0003e10e]
> >  bnx2 0000:05:00.1: NIC1: DEBUG: 000003cc: 00000000 00000000 00000000 00000000
> >  bnx2 0000:05:00.1: NIC1: DEBUG: 000003dc: 00000000 00000000 00000000 00000000
> >  bnx2 0000:05:00.1: NIC1: DEBUG: 000003ec: 00000000 00000000 00000000 00000000
> >  bnx2 0000:05:00.1: NIC1: DEBUG: 0x3fc[00000000]
> >  bnx2 0000:05:00.1: NIC1: <--- end MCP states dump --->
> > 
> 
> 

^ permalink raw reply

* Re: [PATCH] bonding: clear header_ops when last slave detached (v2)
From: Wengang @ 2014-11-19  7:00 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: netdev
In-Reply-To: <1416375565.14060.43.camel@edumazet-glaptop2.roam.corp.google.com>

Hi Eric,

于 2014年11月19日 13:39, Eric Dumazet 写道:
> On Wed, 2014-11-19 at 13:18 +0800, Wengang Wang wrote:
>> When last slave of a bonding master is removed, the bonding then does not work.
>> When packet_snd is called against with a master net_device, it accesses
>> header_ops. In case the header_ops is not valid any longer(say ipoib module
>> unloaded), it will then access an invalid memory address.
>> This patch try to fix this issue by clearing header_ops when last slave
>> detached.
>>
>> Signed-off-by: Wengang Wang <wen.gang.wang@oracle.com>
>> ---
>>   drivers/net/bonding/bond_main.c | 1 +
>>   1 file changed, 1 insertion(+)
> It seems you basically ignored my feedback.
>
>
>
> Some code is doing :
>
> [A] if (dev->header_ops) {
>      ...
> [B]    dev->header_ops->XXX()
>
>
>
> Nothing prevents you doing the clear after [A] , and before [B]
>

Yes, that's true. So the simplest way is move ipoib_header_ops to vmlinux.

thanks for review.
wengang

^ permalink raw reply

* Re: [PATCH net] virtio-net: validate features during probe
From: Jason Wang @ 2014-11-19  7:07 UTC (permalink / raw)
  To: rusty, mst, virtualization, netdev, linux-kernel
In-Reply-To: <1416378939-28821-1-git-send-email-jasowang@redhat.com>

On 11/19/2014 02:35 PM, Jason Wang wrote:
> This patch validates feature dependencies during probe and fail the probing
> if a dependency is missed. This fixes the issues of hitting BUG()
> when qemu fails to advertise features correctly. One example is booting
> guest with ctrl_vq=off through qemu.
>
> Cc: Rusty Russell <rusty@rustcorp.com.au>
> Cc: Michael S. Tsirkin <mst@redhat.com>
> Cc: Cornelia Huck <cornelia.huck@de.ibm.com>
> Cc: Wanlong Gao <gaowanlong@cn.fujitsu.com>
> Signed-off-by: Jason Wang <jasowang@redhat.com>
> ---

Just notice UFO has been disabled after
3d0ad09412ffe00c9afa201d01effdb6023d09b4 "drivers/net: Disable UFO
through virtio". Will post V2 and drop VIRTIO_NET_F_*_UFO from the
checklist.

^ permalink raw reply

* Re: [PATCH] [net]ip_tunnel: the lack of vti_link_ops' dellink() cause kernel panic
From: lucien xin @ 2014-11-19  7:10 UTC (permalink / raw)
  To: Cong Wang; +Cc: network dev
In-Reply-To: <CAHA+R7N7x5eMKFtyWpOcM_FGJ+9h-K+wLEwzpZya1kiztUo8RQ@mail.gmail.com>

>>
>
> Hmm, your fix is correct, but the description is wrong, we should just skip
> the unregister of fb tunnel device like other tunnels. Without ->dellink()
> the fb device is still removed from the global netdev list, this needs to skip,
> otherwise ip_vti0 will disappear from your system.

yes, you are right. the issue only exist in the fb tunnel device, I will change
the description.

^ permalink raw reply

* [PATCH V2 net] virtio-net: validate features during probe
From: Jason Wang @ 2014-11-19  7:21 UTC (permalink / raw)
  To: rusty, mst, virtualization, netdev, linux-kernel

This patch validates feature dependencies during probe and fail the probing
if a dependency is missed. This fixes the issues of hitting BUG()
when qemu fails to advertise features correctly. One example is booting
guest with ctrl_vq=off through qemu.

Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: Wanlong Gao <gaowanlong@cn.fujitsu.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
Changes from V1:
- Drop VIRTIO_NET_F_*_UFO from the checklist, since it was disabled
---
 drivers/net/virtio_net.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 91 insertions(+)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index ec2a8b4..b16a761 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1673,6 +1673,93 @@ static const struct attribute_group virtio_net_mrg_rx_group = {
 };
 #endif
 
+static int virtnet_validate_features(struct virtio_device *dev,
+				     unsigned int *table,
+				     int table_size,
+				     unsigned int feature)
+{
+	int i;
+
+	if (!virtio_has_feature(dev, feature)) {
+		for (i = 0; i < table_size; i++) {
+			unsigned int f = table[i];
+
+			if (virtio_has_feature(dev, f)) {
+				dev_err(&dev->dev,
+					"buggy hyperviser: feature 0x%x was advertised but its dependency 0x%x was not",
+					f, feature);
+				return -EINVAL;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int virtnet_check_features(struct virtio_device *dev)
+{
+	unsigned int features_for_ctrl_vq[] = {
+		VIRTIO_NET_F_CTRL_RX,
+		VIRTIO_NET_F_CTRL_VLAN,
+		VIRTIO_NET_F_GUEST_ANNOUNCE,
+		VIRTIO_NET_F_MQ,
+		VIRTIO_NET_F_CTRL_MAC_ADDR
+	};
+	unsigned int features_for_guest_csum[] = {
+		VIRTIO_NET_F_GUEST_TSO4,
+		VIRTIO_NET_F_GUEST_TSO6,
+		VIRTIO_NET_F_GUEST_ECN,
+	};
+	unsigned int features_for_host_csum[] = {
+		VIRTIO_NET_F_HOST_TSO4,
+		VIRTIO_NET_F_HOST_TSO6,
+		VIRTIO_NET_F_HOST_ECN,
+	};
+	int err;
+
+	err = virtnet_validate_features(dev, features_for_ctrl_vq,
+					ARRAY_SIZE(features_for_ctrl_vq),
+					VIRTIO_NET_F_CTRL_VQ);
+	if (err)
+		return err;
+
+	err = virtnet_validate_features(dev, features_for_guest_csum,
+					ARRAY_SIZE(features_for_guest_csum),
+					VIRTIO_NET_F_GUEST_CSUM);
+	if (err)
+		return err;
+
+	err = virtnet_validate_features(dev, features_for_host_csum,
+					ARRAY_SIZE(features_for_host_csum),
+					VIRTIO_NET_F_CSUM);
+	if (err)
+		return err;
+
+	if (virtio_has_feature(dev, VIRTIO_NET_F_GUEST_ECN) &&
+	    (!virtio_has_feature(dev, VIRTIO_NET_F_GUEST_TSO4) ||
+	     !virtio_has_feature(dev, VIRTIO_NET_F_GUEST_TSO6))) {
+		dev_err(&dev->dev,
+			"buggy hyperviser: feature 0x%x was advertised but its dependency 0x%x or 0x%x was not",
+			VIRTIO_NET_F_GUEST_ECN,
+			VIRTIO_NET_F_GUEST_TSO4,
+			VIRTIO_NET_F_GUEST_TSO6);
+		return -EINVAL;
+	}
+
+	if (virtio_has_feature(dev, VIRTIO_NET_F_HOST_ECN) &&
+	    (!virtio_has_feature(dev, VIRTIO_NET_F_HOST_TSO4) ||
+	     !virtio_has_feature(dev, VIRTIO_NET_F_HOST_TSO6))) {
+		dev_err(&dev->dev,
+			"buggy hyperviser: feature 0x%x was advertised but its dependency 0x%x or 0x%x was not",
+			VIRTIO_NET_F_HOST_ECN,
+			VIRTIO_NET_F_HOST_TSO4,
+			VIRTIO_NET_F_HOST_TSO6);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int virtnet_probe(struct virtio_device *vdev)
 {
 	int i, err;
@@ -1680,6 +1767,10 @@ static int virtnet_probe(struct virtio_device *vdev)
 	struct virtnet_info *vi;
 	u16 max_queue_pairs;
 
+	err = virtnet_check_features(vdev);
+	if (err)
+		return -EINVAL;
+
 	/* Find if host supports multiqueue virtio_net device */
 	err = virtio_cread_feature(vdev, VIRTIO_NET_F_MQ,
 				   struct virtio_net_config,
-- 
1.9.1

^ permalink raw reply related

* Re: [PATCH net] openvswitch: Fix mask generation for IPv6 labels.
From: Joe Stringer @ 2014-11-19  7:25 UTC (permalink / raw)
  To: Pravin Shelar; +Cc: dev-yBygre7rU0TnMu66kgdUjQ@public.gmane.org, netdev, LKML
In-Reply-To: <CALnjE+qrkw92tZ-wgpGOPtbuMJVVCfo--7w6PAGO6OW4skiGQQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

On 18 November 2014 22:09, Pravin Shelar <pshelar@nicira.com> wrote:

> On Tue, Nov 18, 2014 at 10:54 AM, Joe Stringer <joestringer@nicira.com>
> wrote:
> > When userspace doesn't provide a mask, OVS datapath generates a fully
> > unwildcarded mask for the flow. This is done by taking a copy of the
> > flow key, then iterating across its attributes, setting all values to
> > 0xff. This works for most attributes, as the length of the netlink
> > attribute typically matches the length of the value. However, IPv6
> > labels only use the lower 20 bits of the field. This patch makes a
> > special case to handle this.
> >
> > This fixes the following error seen when installing IPv6 flows without a
> mask:
> >
> > openvswitch: netlink: Invalid IPv6 flow label value (value=ffffffff,
> max=fffff)
> >
> We should allow exact match mask here rather than generating
> wildcarded mask. So that ovs can catch invalid ipv6.label.


I don't quite follow, I thought this was exact-match? (The existing
function sets all bits to 1)

In this case, userspace has not specified a mask, but the kernel complains
about a mask that is too wide (because it generated a mask that's too
wide). Do you have an alternative fix in mind?
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

^ permalink raw reply

* [PATCH net-next v2] enic: support skb->xmit_more
From: Govindarajulu Varadarajan @ 2014-11-19  7:29 UTC (permalink / raw)
  To: davem, netdev; +Cc: ssujith, benve, eric.dumazet, Govindarajulu Varadarajan

Check and update posted_index only when skb->xmit_more is 0 or tx queue is full.

v2:
use txq_map instead of skb_get_queue_mapping(skb)

Signed-off-by: Govindarajulu Varadarajan <_govind@gmx.com>
---
 drivers/net/ethernet/cisco/enic/enic_main.c |  8 ++++++--
 drivers/net/ethernet/cisco/enic/vnic_wq.h   | 20 +++++++++++---------
 2 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index 5afe360..b9cda2f 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -533,6 +533,7 @@ static netdev_tx_t enic_hard_start_xmit(struct sk_buff *skb,
 	struct vnic_wq *wq;
 	unsigned long flags;
 	unsigned int txq_map;
+	struct netdev_queue *txq;
 
 	if (skb->len <= 0) {
 		dev_kfree_skb_any(skb);
@@ -541,6 +542,7 @@ static netdev_tx_t enic_hard_start_xmit(struct sk_buff *skb,
 
 	txq_map = skb_get_queue_mapping(skb) % enic->wq_count;
 	wq = &enic->wq[txq_map];
+	txq = netdev_get_tx_queue(netdev, txq_map);
 
 	/* Non-TSO sends must fit within ENIC_NON_TSO_MAX_DESC descs,
 	 * which is very likely.  In the off chance it's going to take
@@ -558,7 +560,7 @@ static netdev_tx_t enic_hard_start_xmit(struct sk_buff *skb,
 
 	if (vnic_wq_desc_avail(wq) <
 	    skb_shinfo(skb)->nr_frags + ENIC_DESC_MAX_SPLITS) {
-		netif_tx_stop_queue(netdev_get_tx_queue(netdev, txq_map));
+		netif_tx_stop_queue(txq);
 		/* This is a hard error, log it */
 		netdev_err(netdev, "BUG! Tx ring full when queue awake!\n");
 		spin_unlock_irqrestore(&enic->wq_lock[txq_map], flags);
@@ -568,7 +570,9 @@ static netdev_tx_t enic_hard_start_xmit(struct sk_buff *skb,
 	enic_queue_wq_skb(enic, wq, skb);
 
 	if (vnic_wq_desc_avail(wq) < MAX_SKB_FRAGS + ENIC_DESC_MAX_SPLITS)
-		netif_tx_stop_queue(netdev_get_tx_queue(netdev, txq_map));
+		netif_tx_stop_queue(txq);
+	if (!skb->xmit_more || netif_xmit_stopped(txq))
+		vnic_wq_doorbell(wq);
 
 	spin_unlock_irqrestore(&enic->wq_lock[txq_map], flags);
 
diff --git a/drivers/net/ethernet/cisco/enic/vnic_wq.h b/drivers/net/ethernet/cisco/enic/vnic_wq.h
index 2c6c708..816f1ad 100644
--- a/drivers/net/ethernet/cisco/enic/vnic_wq.h
+++ b/drivers/net/ethernet/cisco/enic/vnic_wq.h
@@ -104,6 +104,17 @@ static inline void *vnic_wq_next_desc(struct vnic_wq *wq)
 	return wq->to_use->desc;
 }
 
+static inline void vnic_wq_doorbell(struct vnic_wq *wq)
+{
+	/* Adding write memory barrier prevents compiler and/or CPU
+	 * reordering, thus avoiding descriptor posting before
+	 * descriptor is initialized. Otherwise, hardware can read
+	 * stale descriptor fields.
+	 */
+	wmb();
+	iowrite32(wq->to_use->index, &wq->ctrl->posted_index);
+}
+
 static inline void vnic_wq_post(struct vnic_wq *wq,
 	void *os_buf, dma_addr_t dma_addr,
 	unsigned int len, int sop, int eop,
@@ -122,15 +133,6 @@ static inline void vnic_wq_post(struct vnic_wq *wq,
 	buf->wr_id = wrid;
 
 	buf = buf->next;
-	if (eop) {
-		/* Adding write memory barrier prevents compiler and/or CPU
-		 * reordering, thus avoiding descriptor posting before
-		 * descriptor is initialized. Otherwise, hardware can read
-		 * stale descriptor fields.
-		 */
-		wmb();
-		iowrite32(buf->index, &wq->ctrl->posted_index);
-	}
 	wq->to_use = buf;
 
 	wq->ring.desc_avail -= desc_skip_cnt;
-- 
2.1.3

^ permalink raw reply related

* Re: [PATCH] [net]ip_tunnel: the lack of vti_link_ops' dellink() cause kernel panic
From: lucien xin @ 2014-11-19  7:44 UTC (permalink / raw)
  To: Cong Wang; +Cc: Nicolas Dichtel, network dev, Steffen Klassert
In-Reply-To: <CAHA+R7NjO+bDhN5QX95d8V0VqvbacxCzoHWT5NpDaDn3YCtCeg@mail.gmail.com>

On Wed, Nov 19, 2014 at 7:25 AM, Cong Wang <cwang@twopensource.com> wrote:
> On Tue, Nov 18, 2014 at 9:23 AM, Nicolas Dichtel
> <nicolas.dichtel@6wind.com> wrote:
>>
>> A quick look at the ipv6 side seems to show that there is the same problem.
>> Can
>> you provide the IPv6 patch too?
>>
>
> IPv6 doesn't use ip_tunnel library, so needs to provide its own implementation:
>
> diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
> index ec84d03..3ae094b 100644
> --- a/net/ipv6/ip6_vti.c
> +++ b/net/ipv6/ip6_vti.c
> @@ -911,6 +911,16 @@ static int vti6_newlink(struct net *src_net,
> struct net_device *dev,
>         return vti6_tnl_create2(dev);
>  }
>
> +static void vti6_dellink(struct net_device *dev, struct list_head *head)
> +{
> +       struct net *net = dev_net(dev);
> +       struct vti6_net *ip6n = net_generic(net, vti6_net_id);
> +
> +       if (dev != ip6n->fb_tnl_dev)
> +               unregister_netdevice_queue(dev, head);
> +}
> +
> +
>  static int vti6_changelink(struct net_device *dev, struct nlattr *tb[],
>                            struct nlattr *data[])
>  {
> @@ -986,6 +996,7 @@ static struct rtnl_link_ops vti6_link_ops __read_mostly = {
>         .setup          = vti6_dev_setup,
>         .validate       = vti6_validate,
>         .newlink        = vti6_newlink,
> +       .dellink        = vti6_dellink,
>         .changelink     = vti6_changelink,
>         .get_size       = vti6_get_size,
>         .fill_info      = vti6_fill_info,

the issue do not exist in ip6_vti. cause vti6_init_net() complete the
device ip6_vti0 initialization,
 in which dev->rtnl_link_ops never be pointed.  so the ip6_vti0's
rtnl_link_ops is null, which lead
 to the  dellink() will never be invoked in rtnl_dellink():

        if (!ops || !ops->dellink)
                return -EOPNOTSUPP;

        ops->dellink(dev, &list_kill);
        unregister_netdevice_many(&list_kill);

instead, "ip link del ip6_vti0" wil return:
RTNETLINK answers: Operation not supported

if this patch for ip6 is to be consistent with ipv4 vti. I suggest we
should also add the below code
to init ip6_vti0's rtnl_link_ops when the ip6_vti0 is inited:
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
index 31089d1..e68c099 100644
--- a/net/ipv6/ip6_vti.c
+++ b/net/ipv6/ip6_vti.c
@@ -1020,6 +1020,7 @@ static int __net_init vti6_init_net(struct net *net)
        if (!ip6n->fb_tnl_dev)
                goto err_alloc_dev;
        dev_net_set(ip6n->fb_tnl_dev, net);
+       ip6n->fb_tnl_dev->rtnl_link_ops = &vti6_link_ops;

        err = vti6_fb_tnl_dev_init(ip6n->fb_tnl_dev);
        if (err < 0)

^ permalink raw reply related

* Re: [PATCH] [net]ip_tunnel: the lack of vti_link_ops' dellink() cause kernel panic
From: lucien xin @ 2014-11-19  7:47 UTC (permalink / raw)
  To: Nicolas Dichtel; +Cc: network dev, Steffen Klassert
In-Reply-To: <546B8093.4080507@6wind.com>

>> ---
>>   net/ipv4/ip_vti.c | 1 +
>>   1 file changed, 1 insertion(+)
>>
>> diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c
>> index 3e86101..1a7e979 100644
>> --- a/net/ipv4/ip_vti.c
>> +++ b/net/ipv4/ip_vti.c
>> @@ -528,6 +528,7 @@ static struct rtnl_link_ops vti_link_ops __read_mostly
>> = {
>>         .validate       = vti_tunnel_validate,
>>         .newlink        = vti_newlink,
>>         .changelink     = vti_changelink,
>> +       .dellink        = ip_tunnel_dellink,
>
> Nitpicking: other lines into this struct uses tabs to align the '=', but
> the one you add uses spaces.
>
>
okay, thanks, I will correct it.

^ permalink raw reply

* Re: Device Tree Binding for Marvell DSA Switch on imx28 board over Mdio Interface
From: Oliver Graute @ 2014-11-19  7:49 UTC (permalink / raw)
  To: Florian Fainelli; +Cc: Andrew Lunn, netdev@vger.kernel.org, buytenh
In-Reply-To: <546B8E92.7080000@gmail.com>

On Tue, Nov 18, 2014 at 7:23 PM, Florian Fainelli <f.fainelli@gmail.com> wrote:
> On 11/18/2014 12:30 AM, Oliver Graute wrote:
>>> Hi Oliver
>>>
>>> How do you have the strapping pins on the switch set? They determine
>>> what address on the mdio bus the chip responds to.
>>
>> On the circuit diagram the PIN 54  (P5_IND1/P5ID1) is set to
>> "Configuration Address: 0101"
>> P5_MODE[3:0]=0111 = Single RMII MAC Mode (100Mbps FD with 50 MHz clock input)
>> PIN 59 R1_LED/NO_CPU Configuration: CPU is attached SMI address is 0x10 to 0x1F
>>
>> But what is the mdio address of the whole switch? or can I only
>> address individual phy ports?
>
> You should specify in the Device Tree the switch pseudo-PHY address,
> typically 16 for Marvell switches. You can still access the individual
> ports' PHY addresses using address 0 through N.
>

How do I do that exactly? do you have an example Device Tree Snippet?


Best regards,

Oliver

^ permalink raw reply

* Re: [patch net-next v3 2/9] vlan: make __vlan_hwaccel_put_tag return void
From: Pravin Shelar @ 2014-11-19  8:05 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: netdev, David Miller, Jamal Hadi Salim, Tom Herbert, Eric Dumazet,
	Willem de Bruijn, Daniel Borkmann, mst, fw, Paul.Durrant,
	Thomas Graf, Cong Wang
In-Reply-To: <1416346664-9290-3-git-send-email-jiri@resnulli.us>

On Tue, Nov 18, 2014 at 1:37 PM, Jiri Pirko <jiri@resnulli.us> wrote:
> Always returns the same skb it gets, so change to void.
>
> Signed-off-by: Jiri Pirko <jiri@resnulli.us>

Acked-by: Pravin B Shelar <pshelar@nicira.com>

> ---
>  drivers/scsi/fcoe/fcoe.c | 6 ++----
>  include/linux/if_vlan.h  | 9 ++++-----
>  net/8021q/vlan_dev.c     | 2 +-
>  3 files changed, 7 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
> index 4a8ac7d..73a8cc4 100644
> --- a/drivers/scsi/fcoe/fcoe.c
> +++ b/drivers/scsi/fcoe/fcoe.c
> @@ -1669,10 +1669,8 @@ static int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp)
>             fcoe->realdev->features & NETIF_F_HW_VLAN_CTAG_TX) {
>                 /* must set skb->dev before calling vlan_put_tag */
>                 skb->dev = fcoe->realdev;
> -               skb = __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
> -                                            vlan_dev_vlan_id(fcoe->netdev));
> -               if (!skb)
> -                       return -ENOMEM;
> +               __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
> +                                      vlan_dev_vlan_id(fcoe->netdev));
>         } else
>                 skb->dev = fcoe->netdev;
>
> diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
> index d69f057..1b5dbc2 100644
> --- a/include/linux/if_vlan.h
> +++ b/include/linux/if_vlan.h
> @@ -347,13 +347,11 @@ static inline struct sk_buff *__vlan_put_tag(struct sk_buff *skb,
>   *
>   * Puts the VLAN TCI in @skb->vlan_tci and lets the device do the rest
>   */
> -static inline struct sk_buff *__vlan_hwaccel_put_tag(struct sk_buff *skb,
> -                                                    __be16 vlan_proto,
> -                                                    u16 vlan_tci)
> +static inline void __vlan_hwaccel_put_tag(struct sk_buff *skb,
> +                                         __be16 vlan_proto, u16 vlan_tci)
>  {
>         skb->vlan_proto = vlan_proto;
>         skb->vlan_tci = VLAN_TAG_PRESENT | vlan_tci;
> -       return skb;
>  }
>
>  /**
> @@ -368,7 +366,8 @@ static inline struct sk_buff *vlan_put_tag(struct sk_buff *skb,
>                                            __be16 vlan_proto, u16 vlan_tci)
>  {
>         if (vlan_hw_offload_capable(skb->dev->features, vlan_proto)) {
> -               return __vlan_hwaccel_put_tag(skb, vlan_proto, vlan_tci);
> +               __vlan_hwaccel_put_tag(skb, vlan_proto, vlan_tci);
> +               return skb;
>         } else {
>                 return __vlan_put_tag(skb, vlan_proto, vlan_tci);
>         }
> diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
> index 0d441ec..d6524b2 100644
> --- a/net/8021q/vlan_dev.c
> +++ b/net/8021q/vlan_dev.c
> @@ -150,7 +150,7 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb,
>                 u16 vlan_tci;
>                 vlan_tci = vlan->vlan_id;
>                 vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb->priority);
> -               skb = __vlan_hwaccel_put_tag(skb, vlan->vlan_proto, vlan_tci);
> +               __vlan_hwaccel_put_tag(skb, vlan->vlan_proto, vlan_tci);
>         }
>
>         skb->dev = vlan->real_dev;
> --
> 1.9.3
>

^ permalink raw reply

* Re: [patch net-next v3 4/9] vlan: rename __vlan_put_tag to vlan_insert_tag_set_proto
From: Pravin Shelar @ 2014-11-19  8:05 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: netdev, David Miller, Jamal Hadi Salim, Tom Herbert, Eric Dumazet,
	Willem de Bruijn, Daniel Borkmann, mst, fw, Paul.Durrant,
	Thomas Graf, Cong Wang
In-Reply-To: <1416346664-9290-5-git-send-email-jiri@resnulli.us>

On Tue, Nov 18, 2014 at 1:37 PM, Jiri Pirko <jiri@resnulli.us> wrote:
> Name fits better. Plus there's going to be introduced
> __vlan_insert_tag later on.
>
> Signed-off-by: Jiri Pirko <jiri@resnulli.us>

Acked-by: Pravin B Shelar <pshelar@nicira.com>

> ---
>  drivers/net/bonding/bond_main.c             |  4 ++--
>  drivers/net/ethernet/emulex/benet/be_main.c |  6 ++++--
>  drivers/net/vxlan.c                         | 12 ++++++------
>  include/linux/if_vlan.h                     |  8 +++++---
>  net/bridge/br_vlan.c                        |  4 ++--
>  net/core/dev.c                              |  4 ++--
>  net/core/netpoll.c                          |  4 ++--
>  net/ipv4/geneve.c                           | 11 +++++------
>  net/openvswitch/actions.c                   |  4 +++-
>  net/openvswitch/datapath.c                  |  3 ++-
>  net/openvswitch/vport-gre.c                 |  6 +++---
>  11 files changed, 36 insertions(+), 30 deletions(-)
>
> diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
> index e26c682..c1d7da4 100644
> --- a/drivers/net/bonding/bond_main.c
> +++ b/drivers/net/bonding/bond_main.c
> @@ -2146,8 +2146,8 @@ static void bond_arp_send(struct net_device *slave_dev, int arp_op,
>
>                 netdev_dbg(slave_dev, "inner tag: proto %X vid %X\n",
>                            ntohs(outer_tag->vlan_proto), tags->vlan_id);
> -               skb = __vlan_put_tag(skb, tags->vlan_proto,
> -                                    tags->vlan_id);
> +               skb = vlan_insert_tag_set_proto(skb, tags->vlan_proto,
> +                                               tags->vlan_id);
>                 if (!skb) {
>                         net_err_ratelimited("failed to insert inner VLAN tag\n");
>                         return;
> diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
> index 54160cc..d02fbc7 100644
> --- a/drivers/net/ethernet/emulex/benet/be_main.c
> +++ b/drivers/net/ethernet/emulex/benet/be_main.c
> @@ -887,7 +887,8 @@ static struct sk_buff *be_insert_vlan_in_pkt(struct be_adapter *adapter,
>         }
>
>         if (vlan_tag) {
> -               skb = __vlan_put_tag(skb, htons(ETH_P_8021Q), vlan_tag);
> +               skb = vlan_insert_tag_set_proto(skb, htons(ETH_P_8021Q),
> +                                               vlan_tag);
>                 if (unlikely(!skb))
>                         return skb;
>                 skb->vlan_tci = 0;
> @@ -896,7 +897,8 @@ static struct sk_buff *be_insert_vlan_in_pkt(struct be_adapter *adapter,
>         /* Insert the outer VLAN, if any */
>         if (adapter->qnq_vid) {
>                 vlan_tag = adapter->qnq_vid;
> -               skb = __vlan_put_tag(skb, htons(ETH_P_8021Q), vlan_tag);
> +               skb = vlan_insert_tag_set_proto(skb, htons(ETH_P_8021Q),
> +                                               vlan_tag);
>                 if (unlikely(!skb))
>                         return skb;
>                 if (skip_hw_vlan)
> diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
> index 23b1e8c..bb8fbab 100644
> --- a/drivers/net/vxlan.c
> +++ b/drivers/net/vxlan.c
> @@ -1600,9 +1600,9 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs,
>                 return err;
>
>         if (vlan_tx_tag_present(skb)) {
> -               if (WARN_ON(!__vlan_put_tag(skb,
> -                                           skb->vlan_proto,
> -                                           vlan_tx_tag_get(skb))))
> +               skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto,
> +                                               vlan_tx_tag_get(skb));
> +               if (WARN_ON(!skb))
>                         return -ENOMEM;
>
>                 skb->vlan_tci = 0;
> @@ -1644,9 +1644,9 @@ int vxlan_xmit_skb(struct vxlan_sock *vs,
>                 return err;
>
>         if (vlan_tx_tag_present(skb)) {
> -               if (WARN_ON(!__vlan_put_tag(skb,
> -                                           skb->vlan_proto,
> -                                           vlan_tx_tag_get(skb))))
> +               skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto,
> +                                               vlan_tx_tag_get(skb));
> +               if (WARN_ON(!skb))
>                         return -ENOMEM;
>
>                 skb->vlan_tci = 0;
> diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
> index 75b70a5..46e4a15 100644
> --- a/include/linux/if_vlan.h
> +++ b/include/linux/if_vlan.h
> @@ -320,8 +320,9 @@ static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb,
>  }
>
>  /**
> - * __vlan_put_tag - regular VLAN tag inserting
> + * vlan_insert_tag_set_proto - regular VLAN tag inserting
>   * @skb: skbuff to tag
> + * @vlan_proto: VLAN encapsulation protocol
>   * @vlan_tci: VLAN TCI to insert
>   *
>   * Inserts the VLAN tag into @skb as part of the payload
> @@ -330,8 +331,9 @@ static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb,
>   * Following the skb_unshare() example, in case of error, the calling function
>   * doesn't have to worry about freeing the original skb.
>   */
> -static inline struct sk_buff *__vlan_put_tag(struct sk_buff *skb,
> -                                            __be16 vlan_proto, u16 vlan_tci)
> +static inline struct sk_buff *vlan_insert_tag_set_proto(struct sk_buff *skb,
> +                                                       __be16 vlan_proto,
> +                                                       u16 vlan_tci)
>  {
>         skb = vlan_insert_tag(skb, vlan_proto, vlan_tci);
>         if (skb)
> diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
> index 150048f..97b8ddf 100644
> --- a/net/bridge/br_vlan.c
> +++ b/net/bridge/br_vlan.c
> @@ -199,8 +199,8 @@ bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v,
>                 if (skb->vlan_proto != proto) {
>                         /* Protocol-mismatch, empty out vlan_tci for new tag */
>                         skb_push(skb, ETH_HLEN);
> -                       skb = __vlan_put_tag(skb, skb->vlan_proto,
> -                                            vlan_tx_tag_get(skb));
> +                       skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto,
> +                                                       vlan_tx_tag_get(skb));
>                         if (unlikely(!skb))
>                                 return false;
>
> diff --git a/net/core/dev.c b/net/core/dev.c
> index 1ab168e..3611e60 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -2645,8 +2645,8 @@ static struct sk_buff *validate_xmit_vlan(struct sk_buff *skb,
>  {
>         if (vlan_tx_tag_present(skb) &&
>             !vlan_hw_offload_capable(features, skb->vlan_proto)) {
> -               skb = __vlan_put_tag(skb, skb->vlan_proto,
> -                                    vlan_tx_tag_get(skb));
> +               skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto,
> +                                               vlan_tx_tag_get(skb));
>                 if (skb)
>                         skb->vlan_tci = 0;
>         }
> diff --git a/net/core/netpoll.c b/net/core/netpoll.c
> index e6645b4..65d3723 100644
> --- a/net/core/netpoll.c
> +++ b/net/core/netpoll.c
> @@ -79,8 +79,8 @@ static int netpoll_start_xmit(struct sk_buff *skb, struct net_device *dev,
>
>         if (vlan_tx_tag_present(skb) &&
>             !vlan_hw_offload_capable(features, skb->vlan_proto)) {
> -               skb = __vlan_put_tag(skb, skb->vlan_proto,
> -                                    vlan_tx_tag_get(skb));
> +               skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto,
> +                                               vlan_tx_tag_get(skb));
>                 if (unlikely(!skb)) {
>                         /* This is actually a packet drop, but we
>                          * don't want the code that calls this
> diff --git a/net/ipv4/geneve.c b/net/ipv4/geneve.c
> index 31802af..fd430a6 100644
> --- a/net/ipv4/geneve.c
> +++ b/net/ipv4/geneve.c
> @@ -132,12 +132,11 @@ int geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt,
>                 return err;
>
>         if (vlan_tx_tag_present(skb)) {
> -               if (unlikely(!__vlan_put_tag(skb,
> -                                            skb->vlan_proto,
> -                                            vlan_tx_tag_get(skb)))) {
> -                       err = -ENOMEM;
> -                       return err;
> -               }
> +               skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto,
> +                                               vlan_tx_tag_get(skb));
> +               if (unlikely(!skb)
> +                       return -ENOMEM;
> +
>                 skb->vlan_tci = 0;
>         }
>
> diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
> index 749a301..426b913 100644
> --- a/net/openvswitch/actions.c
> +++ b/net/openvswitch/actions.c
> @@ -287,7 +287,9 @@ static int push_vlan(struct sk_buff *skb, struct sw_flow_key *key,
>                 /* push down current VLAN tag */
>                 current_tag = vlan_tx_tag_get(skb);
>
> -               if (!__vlan_put_tag(skb, skb->vlan_proto, current_tag))
> +               skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto,
> +                                               current_tag);
> +               if (!skb)
>                         return -ENOMEM;
>                 /* Update mac_len for subsequent MPLS actions */
>                 skb->mac_len += VLAN_HLEN;
> diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
> index ab141d4..c63e60e 100644
> --- a/net/openvswitch/datapath.c
> +++ b/net/openvswitch/datapath.c
> @@ -425,7 +425,8 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
>                 if (!nskb)
>                         return -ENOMEM;
>
> -               nskb = __vlan_put_tag(nskb, nskb->vlan_proto, vlan_tx_tag_get(nskb));
> +               nskb = vlan_insert_tag_set_proto(nskb, nskb->vlan_proto,
> +                                                vlan_tx_tag_get(nskb));
>                 if (!nskb)
>                         return -ENOMEM;
>
> diff --git a/net/openvswitch/vport-gre.c b/net/openvswitch/vport-gre.c
> index 8e61a5c..777cd8c 100644
> --- a/net/openvswitch/vport-gre.c
> +++ b/net/openvswitch/vport-gre.c
> @@ -176,9 +176,9 @@ static int gre_tnl_send(struct vport *vport, struct sk_buff *skb)
>         }
>
>         if (vlan_tx_tag_present(skb)) {
> -               if (unlikely(!__vlan_put_tag(skb,
> -                                            skb->vlan_proto,
> -                                            vlan_tx_tag_get(skb)))) {
> +               skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto,
> +                                               vlan_tx_tag_get(skb));
> +               if (unlikely(!skb) {
>                         err = -ENOMEM;
>                         goto err_free_rt;
>                 }
> --
> 1.9.3
>

^ permalink raw reply

* Re: [patch net-next v3 5/9] vlan: introduce *vlan_hwaccel_push_inside helpers
From: Pravin Shelar @ 2014-11-19  8:05 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: netdev, David Miller, Jamal Hadi Salim, Tom Herbert, Eric Dumazet,
	Willem de Bruijn, Daniel Borkmann, mst, fw, Paul.Durrant,
	Thomas Graf, Cong Wang
In-Reply-To: <1416346664-9290-6-git-send-email-jiri@resnulli.us>

On Tue, Nov 18, 2014 at 1:37 PM, Jiri Pirko <jiri@resnulli.us> wrote:
> Use them to push skb->vlan_tci into the payload and avoid code
> duplication.
>
> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
> ---
>  drivers/net/vxlan.c         | 22 ++++++----------------
>  include/linux/if_vlan.h     | 34 ++++++++++++++++++++++++++++++++++
>  net/core/dev.c              |  8 ++------
>  net/core/netpoll.c          |  4 +---
>  net/ipv4/geneve.c           | 11 +++--------
>  net/openvswitch/datapath.c  |  6 +-----
>  net/openvswitch/vport-gre.c | 12 ++++--------
>  7 files changed, 51 insertions(+), 46 deletions(-)
>
> diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
> index bb8fbab..64d45fa 100644
> --- a/drivers/net/vxlan.c
> +++ b/drivers/net/vxlan.c
> @@ -1599,14 +1599,9 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs,
>         if (unlikely(err))
>                 return err;
>
> -       if (vlan_tx_tag_present(skb)) {
> -               skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto,
> -                                               vlan_tx_tag_get(skb));
> -               if (WARN_ON(!skb))
> -                       return -ENOMEM;
> -
> -               skb->vlan_tci = 0;
> -       }
> +       skb = vlan_hwaccel_push_inside(skb);
> +       if (WARN_ON(!skb))
> +               return -ENOMEM;
>
>         vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh));
>         vxh->vx_flags = htonl(VXLAN_FLAGS);
> @@ -1643,14 +1638,9 @@ int vxlan_xmit_skb(struct vxlan_sock *vs,
>         if (unlikely(err))
>                 return err;
>
> -       if (vlan_tx_tag_present(skb)) {
> -               skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto,
> -                                               vlan_tx_tag_get(skb));
> -               if (WARN_ON(!skb))
> -                       return -ENOMEM;
> -
> -               skb->vlan_tci = 0;
> -       }
> +       skb = vlan_hwaccel_push_inside(skb);
> +       if (WARN_ON(!skb))
> +               return -ENOMEM;
>
>         vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh));
>         vxh->vx_flags = htonl(VXLAN_FLAGS);
> diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
> index 46e4a15..291e670 100644
> --- a/include/linux/if_vlan.h
> +++ b/include/linux/if_vlan.h
> @@ -341,6 +341,40 @@ static inline struct sk_buff *vlan_insert_tag_set_proto(struct sk_buff *skb,
>         return skb;
>  }
>
> +/*
> + * __vlan_hwaccel_push_inside - pushes vlan tag to the payload
> + * @skb: skbuff to tag
> + *
> + * Pushes the VLAN tag from @skb->vlan_tci inside to the payload.
> + *
> + * Following the skb_unshare() example, in case of error, the calling function
> + * doesn't have to worry about freeing the original skb.
> + */
> +static inline struct sk_buff *__vlan_hwaccel_push_inside(struct sk_buff *skb)
> +{
> +       skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto,
> +                                       vlan_tx_tag_get(skb));
> +       if (likely(skb))
> +               skb->vlan_tci = 0;
> +       return skb;
> +}
> +/*
> + * vlan_hwaccel_push_inside - pushes vlan tag to the payload
> + * @skb: skbuff to tag
> + *
> + * Checks is tag is present in @skb->vlan_tci and if it is, it pushes the
> + * VLAN tag from @skb->vlan_tci inside to the payload.
> + *
> + * Following the skb_unshare() example, in case of error, the calling function
> + * doesn't have to worry about freeing the original skb.
> + */
> +static inline struct sk_buff *vlan_hwaccel_push_inside(struct sk_buff *skb)
> +{
> +       if (vlan_tx_tag_present(skb))
> +               skb = __vlan_hwaccel_push_inside(skb);
> +       return skb;
> +}
> +
>  /**
>   * __vlan_hwaccel_put_tag - hardware accelerated VLAN inserting
>   * @skb: skbuff to tag
> diff --git a/net/core/dev.c b/net/core/dev.c
> index 3611e60..ac48362 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -2644,12 +2644,8 @@ static struct sk_buff *validate_xmit_vlan(struct sk_buff *skb,
>                                           netdev_features_t features)
>  {
>         if (vlan_tx_tag_present(skb) &&
> -           !vlan_hw_offload_capable(features, skb->vlan_proto)) {
> -               skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto,
> -                                               vlan_tx_tag_get(skb));
> -               if (skb)
> -                       skb->vlan_tci = 0;
> -       }
> +           !vlan_hw_offload_capable(features, skb->vlan_proto))
> +               skb = __vlan_hwaccel_push_inside(skb);
>         return skb;
>  }
>
> diff --git a/net/core/netpoll.c b/net/core/netpoll.c
> index 65d3723..e0ad5d1 100644
> --- a/net/core/netpoll.c
> +++ b/net/core/netpoll.c
> @@ -79,8 +79,7 @@ static int netpoll_start_xmit(struct sk_buff *skb, struct net_device *dev,
>
>         if (vlan_tx_tag_present(skb) &&
>             !vlan_hw_offload_capable(features, skb->vlan_proto)) {
> -               skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto,
> -                                               vlan_tx_tag_get(skb));
> +               skb = __vlan_hwaccel_push_inside(skb);
>                 if (unlikely(!skb)) {
>                         /* This is actually a packet drop, but we
>                          * don't want the code that calls this
> @@ -88,7 +87,6 @@ static int netpoll_start_xmit(struct sk_buff *skb, struct net_device *dev,
>                          */
>                         goto out;
>                 }
> -               skb->vlan_tci = 0;
>         }
>
>         status = netdev_start_xmit(skb, dev, txq, false);
> diff --git a/net/ipv4/geneve.c b/net/ipv4/geneve.c
> index fd430a6..a457232 100644
> --- a/net/ipv4/geneve.c
> +++ b/net/ipv4/geneve.c
> @@ -131,14 +131,9 @@ int geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt,
>         if (unlikely(err))
>                 return err;
>
> -       if (vlan_tx_tag_present(skb)) {
> -               skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto,
> -                                               vlan_tx_tag_get(skb));
> -               if (unlikely(!skb)
> -                       return -ENOMEM;
> -
> -               skb->vlan_tci = 0;
> -       }
> +       skb = vlan_hwaccel_push_inside(skb);
> +       if (unlikely(!skb))
> +               return -ENOMEM;
>
>         gnvh = (struct genevehdr *)__skb_push(skb, sizeof(*gnvh) + opt_len);
>         geneve_build_header(gnvh, tun_flags, vni, opt_len, opt);
> diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
> index c63e60e..0cb9d4f 100644
> --- a/net/openvswitch/datapath.c
> +++ b/net/openvswitch/datapath.c
> @@ -425,12 +425,8 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
>                 if (!nskb)
>                         return -ENOMEM;
>
> -               nskb = vlan_insert_tag_set_proto(nskb, nskb->vlan_proto,
> -                                                vlan_tx_tag_get(nskb));
> -               if (!nskb)
> -                       return -ENOMEM;
> +               nskb = __vlan_hwaccel_push_inside(nskb);
>
> -               nskb->vlan_tci = 0;

Need to check for returned nskb for NULL case.

>                 skb = nskb;
>         }
>
> diff --git a/net/openvswitch/vport-gre.c b/net/openvswitch/vport-gre.c
> index 777cd8c..6b69df5 100644
> --- a/net/openvswitch/vport-gre.c
> +++ b/net/openvswitch/vport-gre.c
> @@ -175,14 +175,10 @@ static int gre_tnl_send(struct vport *vport, struct sk_buff *skb)
>                         goto err_free_rt;
>         }
>
> -       if (vlan_tx_tag_present(skb)) {
> -               skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto,
> -                                               vlan_tx_tag_get(skb));
> -               if (unlikely(!skb) {
> -                       err = -ENOMEM;
> -                       goto err_free_rt;
> -               }
> -               skb->vlan_tci = 0;
> +       skb = vlan_hwaccel_push_inside(skb);
> +       if (unlikely(!skb)) {
> +               err = -ENOMEM;
> +               goto err_free_rt;
>         }
>
>         /* Push Tunnel header. */
> --
> 1.9.3
>

^ permalink raw reply

* Re: [patch net-next v3 6/9] vlan: introduce __vlan_insert_tag helper which does not free skb
From: Pravin Shelar @ 2014-11-19  8:05 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: netdev, David Miller, Jamal Hadi Salim, Tom Herbert, Eric Dumazet,
	Willem de Bruijn, Daniel Borkmann, mst, fw, Paul.Durrant,
	Thomas Graf, Cong Wang
In-Reply-To: <1416346664-9290-7-git-send-email-jiri@resnulli.us>

On Tue, Nov 18, 2014 at 1:37 PM, Jiri Pirko <jiri@resnulli.us> wrote:
> There's a need for helper which inserts vlan tag but does not free the
> skb in case of an error.
>
> Suggested-by: Pravin Shelar <pshelar@nicira.com>
> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Acked-by: Pravin B Shelar <pshelar@nicira.com>

> ---
>  include/linux/if_vlan.h | 45 ++++++++++++++++++++++++++++++++++-----------
>  1 file changed, 34 insertions(+), 11 deletions(-)
>
> diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
> index 291e670..515a35e 100644
> --- a/include/linux/if_vlan.h
> +++ b/include/linux/if_vlan.h
> @@ -282,28 +282,24 @@ static inline bool vlan_hw_offload_capable(netdev_features_t features,
>  }
>
>  /**
> - * vlan_insert_tag - regular VLAN tag inserting
> + * __vlan_insert_tag - regular VLAN tag inserting
>   * @skb: skbuff to tag
>   * @vlan_proto: VLAN encapsulation protocol
>   * @vlan_tci: VLAN TCI to insert
>   *
>   * Inserts the VLAN tag into @skb as part of the payload
> - * Returns a VLAN tagged skb. If a new skb is created, @skb is freed.
> - *
> - * Following the skb_unshare() example, in case of error, the calling function
> - * doesn't have to worry about freeing the original skb.
> + * Returns error if skb_cow_head failes.
>   *
>   * Does not change skb->protocol so this function can be used during receive.
>   */
> -static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb,
> -                                             __be16 vlan_proto, u16 vlan_tci)
> +static inline int __vlan_insert_tag(struct sk_buff *skb,
> +                                   __be16 vlan_proto, u16 vlan_tci)
>  {
>         struct vlan_ethhdr *veth;
>
> -       if (skb_cow_head(skb, VLAN_HLEN) < 0) {
> -               dev_kfree_skb_any(skb);
> -               return NULL;
> -       }
> +       if (skb_cow_head(skb, VLAN_HLEN) < 0)
> +               return -ENOMEM;
> +
>         veth = (struct vlan_ethhdr *)skb_push(skb, VLAN_HLEN);
>
>         /* Move the mac addresses to the beginning of the new header. */
> @@ -316,6 +312,33 @@ static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb,
>         /* now, the TCI */
>         veth->h_vlan_TCI = htons(vlan_tci);
>
> +       return 0;
> +}
> +
> +/**
> + * vlan_insert_tag - regular VLAN tag inserting
> + * @skb: skbuff to tag
> + * @vlan_proto: VLAN encapsulation protocol
> + * @vlan_tci: VLAN TCI to insert
> + *
> + * Inserts the VLAN tag into @skb as part of the payload
> + * Returns a VLAN tagged skb. If a new skb is created, @skb is freed.
> + *
> + * Following the skb_unshare() example, in case of error, the calling function
> + * doesn't have to worry about freeing the original skb.
> + *
> + * Does not change skb->protocol so this function can be used during receive.
> + */
> +static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb,
> +                                             __be16 vlan_proto, u16 vlan_tci)
> +{
> +       int err;
> +
> +       err = __vlan_insert_tag(skb, vlan_proto, vlan_tci);
> +       if (err) {
> +               dev_kfree_skb_any(skb);
> +               return NULL;
> +       }
>         return skb;
>  }
>
> --
> 1.9.3
>

^ 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