* Re: [PATCH 1/3] cxgb3: function namespace cleanup
From: David Miller @ 2010-10-21 14:19 UTC (permalink / raw)
To: divy; +Cc: shemminger, leedom, dm, netdev
In-Reply-To: <4CBCF10C.4010900@chelsio.com>
From: Divy Le Ray <divy@chelsio.com>
Date: Mon, 18 Oct 2010 18:14:52 -0700
> On 10/15/2010 03:43 PM, Stephen Hemminger wrote:
>> Make local functions static. Remove functions that are
>> defined and never used. Compile tested only.
>>
>> Signed-off-by: Stephen Hemminger<shemminger@vyatta.com>
>
> Acked-by: Divy Le Ray <divy@chelsio.com>
Applied.
^ permalink raw reply
* Re: [PATCH v2 7/9] tproxy: added IPv6 support to the TPROXY target
From: Patrick McHardy @ 2010-10-21 14:17 UTC (permalink / raw)
To: KOVACS Krisztian; +Cc: netdev, netfilter-devel, Balazs Scheidler, David Miller
In-Reply-To: <20101021104709.5192.99755.stgit@este.odu>
Am 21.10.2010 12:47, schrieb KOVACS Krisztian:
> This requires a new revision as the old target structure was
> IPv4 specific.
Applied, thanks.
^ permalink raw reply
* Re: [PATCH net-next-2.6] be2net: Changes to use only priority codes allowed by f/w
From: David Miller @ 2010-10-21 14:14 UTC (permalink / raw)
To: somnath.kotur; +Cc: netdev
In-Reply-To: <20101021134109.GA3195@emulex.com>
From: Somnath Kotur <somnath.kotur@emulex.com>
Date: Thu, 21 Oct 2010 19:11:09 +0530
> Changes to use one of the priority codes allowed by CNA f/w for NIC traffic
> from host. The driver gets the bit map of the priority codes allowed for
> host traffic through a asynchronous message from the f/w that the driver
> subscribes to.
>
> Signed-off-by: Somnath Kotur <somnath.kotur@emulex.com>
Applied.
^ permalink raw reply
* Re: [PATCH v2 6/9] tproxy: added IPv6 socket lookup function to nf_tproxy_core
From: Patrick McHardy @ 2010-10-21 14:12 UTC (permalink / raw)
To: KOVACS Krisztian; +Cc: netdev, netfilter-devel, Balazs Scheidler, David Miller
In-Reply-To: <20101021104709.5192.34304.stgit@este.odu>
Am 21.10.2010 12:47, schrieb KOVACS Krisztian:
> Signed-off-by: Balazs Scheidler <bazsi@balabit.hu>
> Signed-off-by: KOVACS Krisztian <hidden@balabit.hu>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH v2 5/9] tproxy: allow non-local binds of IPv6 sockets if IP_TRANSPARENT is enabled
From: Patrick McHardy @ 2010-10-21 14:11 UTC (permalink / raw)
To: KOVACS Krisztian; +Cc: netdev, netfilter-devel, Balazs Scheidler, David Miller
In-Reply-To: <20101021104709.5192.12412.stgit@este.odu>
Am 21.10.2010 12:47, schrieb KOVACS Krisztian:
> @@ -343,7 +343,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
> */
> v4addr = LOOPBACK4_IPV6;
> if (!(addr_type & IPV6_ADDR_MULTICAST)) {
> - if (!ipv6_chk_addr(net, &addr->sin6_addr,
> + if (!inet->transparent && !ipv6_chk_addr(net, &addr->sin6_addr,
> dev, 0)) {
This looked like it was supposed to have a line break at the &&, so I've
added that and applied it.
^ permalink raw reply
* Re: [PATCH v2] ipv4: synchronize bind() with RTM_NEWADDR notifications
From: Eric Dumazet @ 2010-10-21 14:10 UTC (permalink / raw)
To: Timo Teräs; +Cc: David Miller, netdev
In-Reply-To: <1287666383-17615-1-git-send-email-timo.teras@iki.fi>
Le jeudi 21 octobre 2010 à 16:06 +0300, Timo Teräs a écrit :
> Otherwise we have race condition to user land:
> 1. process A: changes IP address
> 2. process A: kernel sends RTM_NEWADDR (and schedules out)
> 3. process B: gets notification
> 4. process B: tries to bind() to new IP, but fails with EADDRNOTAVAIL
> because FIB is not yet updated and inet_addr_type() in inet_bind()
> does not recognize the IP as local
> 5. process A: calls inetaddr_chain notifiers which updates FIB
>
> Fix the error path to synchronize with configuration changes and retry
> the address type check.
>
> IPv6 side seems to handle the notifications properly: bind() immediately
> after RTM_NEWADDR succeeds as expected. This is because ipv6_chk_addr()
> uses inet6_addr_lst which is updated before address notification.
>
> Signed-off-by: Timo Teräs <timo.teras@iki.fi>
> ---
> Since there was no reply to my question if this is ok, I interpreted it
> as "maybe". So here's the code for review. Hopefully this helps determining
> if this is an acceptable fix.
>
Just say : no
Really Timo, this problem must get another fix.
I understand you need an urgent fix, you can use your patch in the
meantime, of course ;)
^ permalink raw reply
* Re: [PATCH v2 4/9] tproxy: added tproxy sockopt interface in the IPV6 layer
From: Patrick McHardy @ 2010-10-21 14:09 UTC (permalink / raw)
To: KOVACS Krisztian; +Cc: netdev, netfilter-devel, Balazs Scheidler, David Miller
In-Reply-To: <20101021104709.5192.34941.stgit@este.odu>
Am 21.10.2010 12:47, schrieb KOVACS Krisztian:
> Support for IPV6_RECVORIGDSTADDR sockopt for UDP sockets were contributed by
> Harry Mason.
Applied, thanks.
^ permalink raw reply
* Re: [PATCH v2 3/9] tproxy: added udp6_lib_lookup function
From: Patrick McHardy @ 2010-10-21 14:06 UTC (permalink / raw)
To: KOVACS Krisztian; +Cc: netdev, netfilter-devel, Balazs Scheidler, David Miller
In-Reply-To: <20101021104709.5192.57640.stgit@este.odu>
Am 21.10.2010 12:47, schrieb KOVACS Krisztian:
> Just like with IPv4, we need access to the UDP hash table to look up local
> sockets, but instead of exporting the global udp_table, export a lookup
> function.
Applied, thanks.
^ permalink raw reply
* Re: [PATCH v2 2/9] tproxy: added const specifiers to udp lookup functions
From: Patrick McHardy @ 2010-10-21 14:05 UTC (permalink / raw)
To: KOVACS Krisztian; +Cc: netdev, netfilter-devel, Balazs Scheidler, David Miller
In-Reply-To: <20101021104709.5192.54276.stgit@este.odu>
Am 21.10.2010 12:47, schrieb KOVACS Krisztian:
> The parameters for various UDP lookup functions were non-const, even though
> they could be const. TProxy has some const references and instead of
> downcasting it, I added const specifiers along the path.
Applied, thanks.
^ permalink raw reply
* Re: [PATCH v2 1/9] tproxy: split off ipv6 defragmentation to a separate module
From: Patrick McHardy @ 2010-10-21 14:04 UTC (permalink / raw)
To: KOVACS Krisztian; +Cc: netdev, netfilter-devel, Balazs Scheidler, David Miller
In-Reply-To: <1287661385.13326.45.camel@este.odu>
Am 21.10.2010 13:43, schrieb KOVACS Krisztian:
> tproxy: split off ipv6 defragmentation to a separate module
>
> Like with IPv4, TProxy needs IPv6 defragmentation but does not
> require connection tracking. Since defragmentation was coupled
> with conntrack, I split off the two, creating an nf_defrag_ipv6 module,
> similar to the already existing nf_defrag_ipv4.
Applied, thanks.
^ permalink raw reply
* RE: [PATCH v2 11/14] bnx2x: Update bnx2x to use new vlan accleration.
From: Vladislav Zolotarov @ 2010-10-21 14:02 UTC (permalink / raw)
To: Vladislav Zolotarov, Jesse Gross, David Miller
Cc: netdev@vger.kernel.org, Hao Zheng, Eilon Greenstein
In-Reply-To: <8628FE4E7912BF47A96AE7DD7BAC0AADDDEE429135@SJEXCHCCR02.corp.ad.broadcom.com>
> -----Original Message-----
> From: netdev-owner@vger.kernel.org [mailto:netdev-
> owner@vger.kernel.org] On Behalf Of Vladislav Zolotarov
> Sent: Thursday, October 21, 2010 3:55 PM
> To: Jesse Gross; David Miller
> Cc: netdev@vger.kernel.org; Hao Zheng; Eilon Greenstein
> Subject: RE: [PATCH v2 11/14] bnx2x: Update bnx2x to use new vlan
> accleration.
>
>
>
> > -----Original Message-----
> > From: netdev-owner@vger.kernel.org [mailto:netdev-
> > owner@vger.kernel.org] On Behalf Of Jesse Gross
> > Sent: Thursday, October 21, 2010 1:56 AM
> > To: David Miller
> > Cc: netdev@vger.kernel.org; Hao Zheng; Eilon Greenstein
> > Subject: [PATCH v2 11/14] bnx2x: Update bnx2x to use new vlan
> > accleration.
> >
> > From: Hao Zheng <hzheng@nicira.com>
> >
> > Make the bnx2x driver use the new vlan accleration model.
> >
> > Signed-off-by: Hao Zheng <hzheng@nicira.com>
> > Signed-off-by: Jesse Gross <jesse@nicira.com>
> > CC: Eilon Greenstein <eilong@broadcom.com>
> > ---
> > drivers/net/bnx2x/bnx2x.h | 10 ------
> > drivers/net/bnx2x/bnx2x_cmn.c | 60 +++++++--------------------
> --
> > --------
> > drivers/net/bnx2x/bnx2x_ethtool.c | 33 ++++++++++----------
> > drivers/net/bnx2x/bnx2x_main.c | 8 -----
> > 4 files changed, 27 insertions(+), 84 deletions(-)
> >
> > diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h
> > index 3bf236b..9571ecf 100644
> > --- a/drivers/net/bnx2x/bnx2x.h
> > +++ b/drivers/net/bnx2x/bnx2x.h
> > @@ -24,10 +24,6 @@
> > #define DRV_MODULE_RELDATE "2010/10/19"
> > #define BNX2X_BC_VER 0x040200
> >
> > -#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
> > -#define BCM_VLAN 1
> > -#endif
> > -
> > #define BNX2X_MULTI_QUEUE
> >
> > #define BNX2X_NEW_NAPI
> > @@ -858,10 +854,6 @@ struct bnx2x {
> >
> > int tx_ring_size;
> >
> > -#ifdef BCM_VLAN
> > - struct vlan_group *vlgrp;
> > -#endif
> > -
> > u32 rx_csum;
> > u32 rx_buf_size;
> > /* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */
> > @@ -925,8 +917,6 @@ struct bnx2x {
> > #define NO_MCP_FLAG 0x100
> > #define DISABLE_MSI_FLAG 0x200
> > #define BP_NOMCP(bp) (bp->flags & NO_MCP_FLAG)
> > -#define HW_VLAN_TX_FLAG 0x400
> > -#define HW_VLAN_RX_FLAG 0x800
> > #define MF_FUNC_DIS 0x1000
> >
> > int pf_num; /* absolute PF number */
> > diff --git a/drivers/net/bnx2x/bnx2x_cmn.c
> > b/drivers/net/bnx2x/bnx2x_cmn.c
> > index 6905b2e..bc58375 100644
> > --- a/drivers/net/bnx2x/bnx2x_cmn.c
> > +++ b/drivers/net/bnx2x/bnx2x_cmn.c
> > @@ -16,16 +16,13 @@
> > */
> >
> > #include <linux/etherdevice.h>
> > +#include <linux/if_vlan.h>
> > #include <linux/ip.h>
> > #include <net/ipv6.h>
> > #include <net/ip6_checksum.h>
> > #include <linux/firmware.h>
> > #include "bnx2x_cmn.h"
> >
> > -#ifdef BCM_VLAN
> > -#include <linux/if_vlan.h>
> > -#endif
> > -
> > #include "bnx2x_init.h"
> >
> >
> > @@ -346,13 +343,6 @@ static void bnx2x_tpa_stop(struct bnx2x *bp,
> > struct bnx2x_fastpath *fp,
> > if (likely(new_skb)) {
> > /* fix ip xsum and give it to the stack */
> > /* (no need to map the new skb) */
> > -#ifdef BCM_VLAN
> > - int is_vlan_cqe =
> > - (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
> > - PARSING_FLAGS_VLAN);
> > - int is_not_hwaccel_vlan_cqe =
> > - (is_vlan_cqe && (!(bp->flags & HW_VLAN_RX_FLAG)));
> > -#endif
> >
> > prefetch(skb);
> > prefetch(((char *)(skb)) + L1_CACHE_BYTES);
> > @@ -377,28 +367,18 @@ static void bnx2x_tpa_stop(struct bnx2x *bp,
> > struct bnx2x_fastpath *fp,
> > struct iphdr *iph;
> >
> > iph = (struct iphdr *)skb->data;
> > -#ifdef BCM_VLAN
> > - /* If there is no Rx VLAN offloading -
> > - take VLAN tag into an account */
> > - if (unlikely(is_not_hwaccel_vlan_cqe))
> > - iph = (struct iphdr *)((u8 *)iph + VLAN_HLEN);
> > -#endif
> > iph->check = 0;
> > iph->check = ip_fast_csum((u8 *)iph, iph->ihl);
> > }
> >
> > if (!bnx2x_fill_frag_skb(bp, fp, skb,
> > &cqe->fast_path_cqe, cqe_idx)) {
> > -#ifdef BCM_VLAN
> > - if ((bp->vlgrp != NULL) &&
> > - (le16_to_cpu(cqe->fast_path_cqe.
> > - pars_flags.flags) & PARSING_FLAGS_VLAN))
> > - vlan_gro_receive(&fp->napi, bp->vlgrp,
> > + if ((le16_to_cpu(cqe->fast_path_cqe.
> > + pars_flags.flags) & PARSING_FLAGS_VLAN))
> > + __vlan_hwaccel_put_tag(skb,
> > le16_to_cpu(cqe->fast_path_cqe.
> > - vlan_tag), skb);
> > - else
> > -#endif
> > - napi_gro_receive(&fp->napi, skb);
> > + vlan_tag));
> > + napi_gro_receive(&fp->napi, skb);
> > } else {
> > DP(NETIF_MSG_RX_STATUS, "Failed to allocate new
> > pages"
> > " - dropping packet!\n");
> > @@ -633,15 +613,11 @@ reuse_rx:
> >
> > skb_record_rx_queue(skb, fp->index);
> >
> > -#ifdef BCM_VLAN
> > - if ((bp->vlgrp != NULL) && (bp->flags & HW_VLAN_RX_FLAG) &&
> > - (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
> > - PARSING_FLAGS_VLAN))
> > - vlan_gro_receive(&fp->napi, bp->vlgrp,
> > - le16_to_cpu(cqe->fast_path_cqe.vlan_tag), skb);
> > - else
> > -#endif
> > - napi_gro_receive(&fp->napi, skb);
> > + if (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
> > + PARSING_FLAGS_VLAN)
> > + __vlan_hwaccel_put_tag(skb,
> > + le16_to_cpu(cqe->fast_path_cqe.vlan_tag));
> > + napi_gro_receive(&fp->napi, skb);
> >
> >
> > next_rx:
> > @@ -2025,14 +2001,12 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff
> > *skb, struct net_device *dev)
> > "sending pkt %u @%p next_idx %u bd %u @%p\n",
> > pkt_prod, tx_buf, fp->tx_pkt_prod, bd_prod, tx_start_bd);
> >
> > -#ifdef BCM_VLAN
> > if (vlan_tx_tag_present(skb)) {
> > tx_start_bd->vlan_or_ethertype =
> > cpu_to_le16(vlan_tx_tag_get(skb));
> > tx_start_bd->bd_flags.as_bitfield |=
> > (X_ETH_OUTBAND_VLAN <<
> > ETH_TX_BD_FLAGS_VLAN_MODE_SHIFT);
> > } else
> > -#endif
> > tx_start_bd->vlan_or_ethertype = cpu_to_le16(pkt_prod);
> >
> > /* turn on parsing and get a BD */
> > @@ -2317,18 +2291,6 @@ void bnx2x_tx_timeout(struct net_device *dev)
> > schedule_delayed_work(&bp->reset_task, 0);
> > }
> >
> > -#ifdef BCM_VLAN
> > -/* called with rtnl_lock */
> > -void bnx2x_vlan_rx_register(struct net_device *dev,
> > - struct vlan_group *vlgrp)
> > -{
> > - struct bnx2x *bp = netdev_priv(dev);
> > -
> > - bp->vlgrp = vlgrp;
> > -}
> > -
> > -#endif
> > -
> > int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state)
> > {
> > struct net_device *dev = pci_get_drvdata(pdev);
> > diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c
> > b/drivers/net/bnx2x/bnx2x_ethtool.c
> > index 54fe061..daefef6 100644
> > --- a/drivers/net/bnx2x/bnx2x_ethtool.c
> > +++ b/drivers/net/bnx2x/bnx2x_ethtool.c
> > @@ -1117,35 +1117,34 @@ static int bnx2x_set_flags(struct net_device
> > *dev, u32 data)
> > int changed = 0;
> > int rc = 0;
> >
> > - if (data & ~(ETH_FLAG_LRO | ETH_FLAG_RXHASH))
> > - return -EINVAL;
> > -
> > if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
> > printk(KERN_ERR "Handling parity error recovery. Try again
> > later\n");
> > return -EAGAIN;
> > }
> >
> > + if (!(data & ETH_FLAG_RXVLAN))
> > + return -EOPNOTSUPP;
> > +
> > + if ((data & ETH_FLAG_LRO) && bp->rx_csum && bp->disable_tpa)
> > + return -EINVAL;
> > +
> > + rc = ethtool_op_set_flags(dev, data, ETH_FLAG_LRO |
> > ETH_FLAG_RXVLAN |
> > + ETH_FLAG_TXVLAN | ETH_FLAG_RXHASH);
> > + if (rc)
> > + return rc;
> > +
> > /* TPA requires Rx CSUM offloading */
> > if ((data & ETH_FLAG_LRO) && bp->rx_csum) {
> > - if (!bp->disable_tpa) {
> > - if (!(dev->features & NETIF_F_LRO)) {
> > - dev->features |= NETIF_F_LRO;
> > - bp->flags |= TPA_ENABLE_FLAG;
> > - changed = 1;
> > - }
> > - } else
> > - rc = -EINVAL;
> > - } else if (dev->features & NETIF_F_LRO) {
> > + if (!(bp->flags & TPA_ENABLE_FLAG)) {
> > + bp->flags |= TPA_ENABLE_FLAG;
> > + changed = 1;
> > + }
> > + } else if (bp->flags & TPA_ENABLE_FLAG) {
> > dev->features &= ~NETIF_F_LRO;
> > bp->flags &= ~TPA_ENABLE_FLAG;
> > changed = 1;
> > }
> >
> > - if (data & ETH_FLAG_RXHASH)
> > - dev->features |= NETIF_F_RXHASH;
> > - else
> > - dev->features &= ~NETIF_F_RXHASH;
> > -
> > if (changed && netif_running(dev)) {
> > bnx2x_nic_unload(bp, UNLOAD_NORMAL);
> > rc = bnx2x_nic_load(bp, LOAD_NORMAL);
> > diff --git a/drivers/net/bnx2x/bnx2x_main.c
> > b/drivers/net/bnx2x/bnx2x_main.c
> > index f22e283..ff99a2f 100644
> > --- a/drivers/net/bnx2x/bnx2x_main.c
> > +++ b/drivers/net/bnx2x/bnx2x_main.c
> > @@ -2371,10 +2371,8 @@ static inline u16 bnx2x_get_cl_flags(struct
> > bnx2x *bp,
> > flags |= QUEUE_FLG_HC;
> > flags |= IS_MF(bp) ? QUEUE_FLG_OV : 0;
> >
> > -#ifdef BCM_VLAN
> > flags |= QUEUE_FLG_VLAN;
> > DP(NETIF_MSG_IFUP, "vlan removal enabled\n");
> > -#endif
> >
> > if (!fp->disable_tpa)
> > flags |= QUEUE_FLG_TPA;
> > @@ -8630,9 +8628,6 @@ static const struct net_device_ops
> > bnx2x_netdev_ops = {
> > .ndo_do_ioctl = bnx2x_ioctl,
> > .ndo_change_mtu = bnx2x_change_mtu,
> > .ndo_tx_timeout = bnx2x_tx_timeout,
> > -#ifdef BCM_VLAN
> > - .ndo_vlan_rx_register = bnx2x_vlan_rx_register,
> > -#endif
> > #ifdef CONFIG_NET_POLL_CONTROLLER
> > .ndo_poll_controller = poll_bnx2x,
> > #endif
> > @@ -8764,9 +8759,7 @@ static int __devinit bnx2x_init_dev(struct
> > pci_dev *pdev,
> > dev->features |= NETIF_F_HIGHDMA;
> > dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
> > dev->features |= NETIF_F_TSO6;
> > -#ifdef BCM_VLAN
> > dev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX);
> > - bp->flags |= (HW_VLAN_RX_FLAG | HW_VLAN_TX_FLAG);
> >
> > dev->vlan_features |= NETIF_F_SG;
> > dev->vlan_features |= NETIF_F_HW_CSUM;
> > @@ -8774,7 +8767,6 @@ static int __devinit bnx2x_init_dev(struct
> > pci_dev *pdev,
> > dev->vlan_features |= NETIF_F_HIGHDMA;
> > dev->vlan_features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
> > dev->vlan_features |= NETIF_F_TSO6;
> > -#endif
> >
> > /* get_port_hwinfo() will set prtad and mmds properly */
> > bp->mdio.prtad = MDIO_PRTAD_NONE;
> > --
> > 1.7.1
>
> Guys, when I compiled the kernel with these patches without VLAN
> support (CONFIG_VLAN_8021Q is not set) and tried to send VLAN tagged
> frames from the remote side to the bnx2x interface the kernel panicked.
>
> The stack trace got cut with the __netif_receive_skb() on top by the
> IPKVM and I'll have to connect a serial to get it all. But until I
> did that maybe somebody will have any ideas anyway...
>
> It happens regardless there is HW RX VLAN stripping enabled or not.
When RX VLAN stripping is enabled we hit the BUG() in the
vlan_hwaccel_do_receive().
>
> Thanks,
> vlad
>
> >
> > --
> > 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
>
>
> --
> 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: [PATCH v2 11/14] bnx2x: Update bnx2x to use new vlan accleration.
From: Vladislav Zolotarov @ 2010-10-21 13:54 UTC (permalink / raw)
To: Jesse Gross, David Miller
Cc: netdev@vger.kernel.org, Hao Zheng, Eilon Greenstein
In-Reply-To: <1287618974-4714-12-git-send-email-jesse@nicira.com>
> -----Original Message-----
> From: netdev-owner@vger.kernel.org [mailto:netdev-
> owner@vger.kernel.org] On Behalf Of Jesse Gross
> Sent: Thursday, October 21, 2010 1:56 AM
> To: David Miller
> Cc: netdev@vger.kernel.org; Hao Zheng; Eilon Greenstein
> Subject: [PATCH v2 11/14] bnx2x: Update bnx2x to use new vlan
> accleration.
>
> From: Hao Zheng <hzheng@nicira.com>
>
> Make the bnx2x driver use the new vlan accleration model.
>
> Signed-off-by: Hao Zheng <hzheng@nicira.com>
> Signed-off-by: Jesse Gross <jesse@nicira.com>
> CC: Eilon Greenstein <eilong@broadcom.com>
> ---
> drivers/net/bnx2x/bnx2x.h | 10 ------
> drivers/net/bnx2x/bnx2x_cmn.c | 60 +++++++----------------------
> --------
> drivers/net/bnx2x/bnx2x_ethtool.c | 33 ++++++++++----------
> drivers/net/bnx2x/bnx2x_main.c | 8 -----
> 4 files changed, 27 insertions(+), 84 deletions(-)
>
> diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h
> index 3bf236b..9571ecf 100644
> --- a/drivers/net/bnx2x/bnx2x.h
> +++ b/drivers/net/bnx2x/bnx2x.h
> @@ -24,10 +24,6 @@
> #define DRV_MODULE_RELDATE "2010/10/19"
> #define BNX2X_BC_VER 0x040200
>
> -#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
> -#define BCM_VLAN 1
> -#endif
> -
> #define BNX2X_MULTI_QUEUE
>
> #define BNX2X_NEW_NAPI
> @@ -858,10 +854,6 @@ struct bnx2x {
>
> int tx_ring_size;
>
> -#ifdef BCM_VLAN
> - struct vlan_group *vlgrp;
> -#endif
> -
> u32 rx_csum;
> u32 rx_buf_size;
> /* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */
> @@ -925,8 +917,6 @@ struct bnx2x {
> #define NO_MCP_FLAG 0x100
> #define DISABLE_MSI_FLAG 0x200
> #define BP_NOMCP(bp) (bp->flags & NO_MCP_FLAG)
> -#define HW_VLAN_TX_FLAG 0x400
> -#define HW_VLAN_RX_FLAG 0x800
> #define MF_FUNC_DIS 0x1000
>
> int pf_num; /* absolute PF number */
> diff --git a/drivers/net/bnx2x/bnx2x_cmn.c
> b/drivers/net/bnx2x/bnx2x_cmn.c
> index 6905b2e..bc58375 100644
> --- a/drivers/net/bnx2x/bnx2x_cmn.c
> +++ b/drivers/net/bnx2x/bnx2x_cmn.c
> @@ -16,16 +16,13 @@
> */
>
> #include <linux/etherdevice.h>
> +#include <linux/if_vlan.h>
> #include <linux/ip.h>
> #include <net/ipv6.h>
> #include <net/ip6_checksum.h>
> #include <linux/firmware.h>
> #include "bnx2x_cmn.h"
>
> -#ifdef BCM_VLAN
> -#include <linux/if_vlan.h>
> -#endif
> -
> #include "bnx2x_init.h"
>
>
> @@ -346,13 +343,6 @@ static void bnx2x_tpa_stop(struct bnx2x *bp,
> struct bnx2x_fastpath *fp,
> if (likely(new_skb)) {
> /* fix ip xsum and give it to the stack */
> /* (no need to map the new skb) */
> -#ifdef BCM_VLAN
> - int is_vlan_cqe =
> - (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
> - PARSING_FLAGS_VLAN);
> - int is_not_hwaccel_vlan_cqe =
> - (is_vlan_cqe && (!(bp->flags & HW_VLAN_RX_FLAG)));
> -#endif
>
> prefetch(skb);
> prefetch(((char *)(skb)) + L1_CACHE_BYTES);
> @@ -377,28 +367,18 @@ static void bnx2x_tpa_stop(struct bnx2x *bp,
> struct bnx2x_fastpath *fp,
> struct iphdr *iph;
>
> iph = (struct iphdr *)skb->data;
> -#ifdef BCM_VLAN
> - /* If there is no Rx VLAN offloading -
> - take VLAN tag into an account */
> - if (unlikely(is_not_hwaccel_vlan_cqe))
> - iph = (struct iphdr *)((u8 *)iph + VLAN_HLEN);
> -#endif
> iph->check = 0;
> iph->check = ip_fast_csum((u8 *)iph, iph->ihl);
> }
>
> if (!bnx2x_fill_frag_skb(bp, fp, skb,
> &cqe->fast_path_cqe, cqe_idx)) {
> -#ifdef BCM_VLAN
> - if ((bp->vlgrp != NULL) &&
> - (le16_to_cpu(cqe->fast_path_cqe.
> - pars_flags.flags) & PARSING_FLAGS_VLAN))
> - vlan_gro_receive(&fp->napi, bp->vlgrp,
> + if ((le16_to_cpu(cqe->fast_path_cqe.
> + pars_flags.flags) & PARSING_FLAGS_VLAN))
> + __vlan_hwaccel_put_tag(skb,
> le16_to_cpu(cqe->fast_path_cqe.
> - vlan_tag), skb);
> - else
> -#endif
> - napi_gro_receive(&fp->napi, skb);
> + vlan_tag));
> + napi_gro_receive(&fp->napi, skb);
> } else {
> DP(NETIF_MSG_RX_STATUS, "Failed to allocate new
> pages"
> " - dropping packet!\n");
> @@ -633,15 +613,11 @@ reuse_rx:
>
> skb_record_rx_queue(skb, fp->index);
>
> -#ifdef BCM_VLAN
> - if ((bp->vlgrp != NULL) && (bp->flags & HW_VLAN_RX_FLAG) &&
> - (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
> - PARSING_FLAGS_VLAN))
> - vlan_gro_receive(&fp->napi, bp->vlgrp,
> - le16_to_cpu(cqe->fast_path_cqe.vlan_tag), skb);
> - else
> -#endif
> - napi_gro_receive(&fp->napi, skb);
> + if (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
> + PARSING_FLAGS_VLAN)
> + __vlan_hwaccel_put_tag(skb,
> + le16_to_cpu(cqe->fast_path_cqe.vlan_tag));
> + napi_gro_receive(&fp->napi, skb);
>
>
> next_rx:
> @@ -2025,14 +2001,12 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff
> *skb, struct net_device *dev)
> "sending pkt %u @%p next_idx %u bd %u @%p\n",
> pkt_prod, tx_buf, fp->tx_pkt_prod, bd_prod, tx_start_bd);
>
> -#ifdef BCM_VLAN
> if (vlan_tx_tag_present(skb)) {
> tx_start_bd->vlan_or_ethertype =
> cpu_to_le16(vlan_tx_tag_get(skb));
> tx_start_bd->bd_flags.as_bitfield |=
> (X_ETH_OUTBAND_VLAN <<
> ETH_TX_BD_FLAGS_VLAN_MODE_SHIFT);
> } else
> -#endif
> tx_start_bd->vlan_or_ethertype = cpu_to_le16(pkt_prod);
>
> /* turn on parsing and get a BD */
> @@ -2317,18 +2291,6 @@ void bnx2x_tx_timeout(struct net_device *dev)
> schedule_delayed_work(&bp->reset_task, 0);
> }
>
> -#ifdef BCM_VLAN
> -/* called with rtnl_lock */
> -void bnx2x_vlan_rx_register(struct net_device *dev,
> - struct vlan_group *vlgrp)
> -{
> - struct bnx2x *bp = netdev_priv(dev);
> -
> - bp->vlgrp = vlgrp;
> -}
> -
> -#endif
> -
> int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state)
> {
> struct net_device *dev = pci_get_drvdata(pdev);
> diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c
> b/drivers/net/bnx2x/bnx2x_ethtool.c
> index 54fe061..daefef6 100644
> --- a/drivers/net/bnx2x/bnx2x_ethtool.c
> +++ b/drivers/net/bnx2x/bnx2x_ethtool.c
> @@ -1117,35 +1117,34 @@ static int bnx2x_set_flags(struct net_device
> *dev, u32 data)
> int changed = 0;
> int rc = 0;
>
> - if (data & ~(ETH_FLAG_LRO | ETH_FLAG_RXHASH))
> - return -EINVAL;
> -
> if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
> printk(KERN_ERR "Handling parity error recovery. Try again
> later\n");
> return -EAGAIN;
> }
>
> + if (!(data & ETH_FLAG_RXVLAN))
> + return -EOPNOTSUPP;
> +
> + if ((data & ETH_FLAG_LRO) && bp->rx_csum && bp->disable_tpa)
> + return -EINVAL;
> +
> + rc = ethtool_op_set_flags(dev, data, ETH_FLAG_LRO |
> ETH_FLAG_RXVLAN |
> + ETH_FLAG_TXVLAN | ETH_FLAG_RXHASH);
> + if (rc)
> + return rc;
> +
> /* TPA requires Rx CSUM offloading */
> if ((data & ETH_FLAG_LRO) && bp->rx_csum) {
> - if (!bp->disable_tpa) {
> - if (!(dev->features & NETIF_F_LRO)) {
> - dev->features |= NETIF_F_LRO;
> - bp->flags |= TPA_ENABLE_FLAG;
> - changed = 1;
> - }
> - } else
> - rc = -EINVAL;
> - } else if (dev->features & NETIF_F_LRO) {
> + if (!(bp->flags & TPA_ENABLE_FLAG)) {
> + bp->flags |= TPA_ENABLE_FLAG;
> + changed = 1;
> + }
> + } else if (bp->flags & TPA_ENABLE_FLAG) {
> dev->features &= ~NETIF_F_LRO;
> bp->flags &= ~TPA_ENABLE_FLAG;
> changed = 1;
> }
>
> - if (data & ETH_FLAG_RXHASH)
> - dev->features |= NETIF_F_RXHASH;
> - else
> - dev->features &= ~NETIF_F_RXHASH;
> -
> if (changed && netif_running(dev)) {
> bnx2x_nic_unload(bp, UNLOAD_NORMAL);
> rc = bnx2x_nic_load(bp, LOAD_NORMAL);
> diff --git a/drivers/net/bnx2x/bnx2x_main.c
> b/drivers/net/bnx2x/bnx2x_main.c
> index f22e283..ff99a2f 100644
> --- a/drivers/net/bnx2x/bnx2x_main.c
> +++ b/drivers/net/bnx2x/bnx2x_main.c
> @@ -2371,10 +2371,8 @@ static inline u16 bnx2x_get_cl_flags(struct
> bnx2x *bp,
> flags |= QUEUE_FLG_HC;
> flags |= IS_MF(bp) ? QUEUE_FLG_OV : 0;
>
> -#ifdef BCM_VLAN
> flags |= QUEUE_FLG_VLAN;
> DP(NETIF_MSG_IFUP, "vlan removal enabled\n");
> -#endif
>
> if (!fp->disable_tpa)
> flags |= QUEUE_FLG_TPA;
> @@ -8630,9 +8628,6 @@ static const struct net_device_ops
> bnx2x_netdev_ops = {
> .ndo_do_ioctl = bnx2x_ioctl,
> .ndo_change_mtu = bnx2x_change_mtu,
> .ndo_tx_timeout = bnx2x_tx_timeout,
> -#ifdef BCM_VLAN
> - .ndo_vlan_rx_register = bnx2x_vlan_rx_register,
> -#endif
> #ifdef CONFIG_NET_POLL_CONTROLLER
> .ndo_poll_controller = poll_bnx2x,
> #endif
> @@ -8764,9 +8759,7 @@ static int __devinit bnx2x_init_dev(struct
> pci_dev *pdev,
> dev->features |= NETIF_F_HIGHDMA;
> dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
> dev->features |= NETIF_F_TSO6;
> -#ifdef BCM_VLAN
> dev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX);
> - bp->flags |= (HW_VLAN_RX_FLAG | HW_VLAN_TX_FLAG);
>
> dev->vlan_features |= NETIF_F_SG;
> dev->vlan_features |= NETIF_F_HW_CSUM;
> @@ -8774,7 +8767,6 @@ static int __devinit bnx2x_init_dev(struct
> pci_dev *pdev,
> dev->vlan_features |= NETIF_F_HIGHDMA;
> dev->vlan_features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
> dev->vlan_features |= NETIF_F_TSO6;
> -#endif
>
> /* get_port_hwinfo() will set prtad and mmds properly */
> bp->mdio.prtad = MDIO_PRTAD_NONE;
> --
> 1.7.1
Guys, when I compiled the kernel with these patches without VLAN
support (CONFIG_VLAN_8021Q is not set) and tried to send VLAN tagged
frames from the remote side to the bnx2x interface the kernel panicked.
The stack trace got cut with the __netif_receive_skb() on top by the
IPKVM and I'll have to connect a serial to get it all. But until I
did that maybe somebody will have any ideas anyway...
It happens regardless there is HW RX VLAN stripping enabled or not.
Thanks,
vlad
>
> --
> 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: [PATCH net-next-2.6] be2net: Changes to use only priority codes allowed by f/w
From: Somnath.Kotur @ 2010-10-21 13:46 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <20101021.042759.52197332.davem@davemloft.net>
Dave,
Looks like there was a patch applied across all drivers including be2net after i had cut the patch and sent it out .Made a fresh patch and sent it out again.
Thanks
Som
________________________________________
From: David Miller [davem@davemloft.net]
Sent: Thursday, October 21, 2010 4:57 PM
To: Kotur, Somnath
Cc: netdev@vger.kernel.org
Subject: Re: [PATCH net-next-2.6] be2net: Changes to use only priority codes allowed by f/w
From: Somnath Kotur <somnath.kotur@emulex.com>
Date: Tue, 19 Oct 2010 14:21:14 +0530
> Changes to use one of the priority codes allowed by CNA f/w for NIC traffic
> from host. The driver gets the bit map of the priority codes allowed for
> host traffic through a asynchronous message from the f/w that the driver
> subscribes to.
>
> Signed-off-by: Somnath Kotur <somnath.kotur@emulex.com>
This patch does not apply to the current tree.
^ permalink raw reply
* [PATCH net-next-2.6] be2net: Changes to use only priority codes allowed by f/w
From: Somnath Kotur @ 2010-10-21 13:41 UTC (permalink / raw)
To: netdev
Changes to use one of the priority codes allowed by CNA f/w for NIC traffic
from host. The driver gets the bit map of the priority codes allowed for
host traffic through a asynchronous message from the f/w that the driver
subscribes to.
Signed-off-by: Somnath Kotur <somnath.kotur@emulex.com>
---
drivers/net/benet/be.h | 2 +
drivers/net/benet/be_cmds.c | 61 ++++++++++++++++++++++++++++++++++++++++--
drivers/net/benet/be_cmds.h | 33 ++++++++++++++++++++++-
drivers/net/benet/be_main.c | 20 ++++++++++----
4 files changed, 106 insertions(+), 10 deletions(-)
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
index 59a17b5..4594a28 100644
--- a/drivers/net/benet/be.h
+++ b/drivers/net/benet/be.h
@@ -264,6 +264,8 @@ struct be_adapter {
u16 vlans_added;
u16 max_vlans; /* Number of vlans supported */
u8 vlan_tag[VLAN_N_VID];
+ u8 vlan_prio_bmap; /* Available Priority BitMap */
+ u16 recommended_prio; /* Recommended Priority */
struct be_dma_mem mc_cmd_mem;
struct be_dma_mem stats_cmd;
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index bf2dc26..1e7f305 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -96,6 +96,50 @@ static void be_async_link_state_process(struct be_adapter *adapter,
evt->port_link_status == ASYNC_EVENT_LINK_UP);
}
+/* Grp5 CoS Priority evt */
+static void be_async_grp5_cos_priority_process(struct be_adapter *adapter,
+ struct be_async_event_grp5_cos_priority *evt)
+{
+ if (evt->valid) {
+ adapter->vlan_prio_bmap = evt->available_priority_bmap;
+ adapter->recommended_prio =
+ evt->reco_default_priority << VLAN_PRIO_SHIFT;
+ }
+}
+
+/* Grp5 QOS Speed evt */
+static void be_async_grp5_qos_speed_process(struct be_adapter *adapter,
+ struct be_async_event_grp5_qos_link_speed *evt)
+{
+ if (evt->physical_port == adapter->port_num) {
+ /* qos_link_speed is in units of 10 Mbps */
+ adapter->link_speed = evt->qos_link_speed * 10;
+ }
+}
+
+static void be_async_grp5_evt_process(struct be_adapter *adapter,
+ u32 trailer, struct be_mcc_compl *evt)
+{
+ u8 event_type = 0;
+
+ event_type = (trailer >> ASYNC_TRAILER_EVENT_TYPE_SHIFT) &
+ ASYNC_TRAILER_EVENT_TYPE_MASK;
+
+ switch (event_type) {
+ case ASYNC_EVENT_COS_PRIORITY:
+ be_async_grp5_cos_priority_process(adapter,
+ (struct be_async_event_grp5_cos_priority *)evt);
+ break;
+ case ASYNC_EVENT_QOS_SPEED:
+ be_async_grp5_qos_speed_process(adapter,
+ (struct be_async_event_grp5_qos_link_speed *)evt);
+ break;
+ default:
+ dev_warn(&adapter->pdev->dev, "Unknown grp5 event!\n");
+ break;
+ }
+}
+
static inline bool is_link_state_evt(u32 trailer)
{
return ((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) &
@@ -103,6 +147,13 @@ static inline bool is_link_state_evt(u32 trailer)
ASYNC_EVENT_CODE_LINK_STATE;
}
+static inline bool is_grp5_evt(u32 trailer)
+{
+ return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) &
+ ASYNC_TRAILER_EVENT_CODE_MASK) ==
+ ASYNC_EVENT_CODE_GRP_5);
+}
+
static struct be_mcc_compl *be_mcc_compl_get(struct be_adapter *adapter)
{
struct be_queue_info *mcc_cq = &adapter->mcc_obj.cq;
@@ -143,6 +194,9 @@ int be_process_mcc(struct be_adapter *adapter, int *status)
if (is_link_state_evt(compl->flags))
be_async_link_state_process(adapter,
(struct be_async_event_link_state *) compl);
+ else if (is_grp5_evt(compl->flags))
+ be_async_grp5_evt_process(adapter,
+ compl->flags, compl);
} else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) {
*status = be_mcc_compl_process(adapter, compl);
atomic_dec(&mcc_obj->q.used);
@@ -677,10 +731,10 @@ int be_cmd_mccq_create(struct be_adapter *adapter,
ctxt = &req->context;
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
- OPCODE_COMMON_MCC_CREATE);
+ OPCODE_COMMON_MCC_CREATE_EXT);
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
- OPCODE_COMMON_MCC_CREATE, sizeof(*req));
+ OPCODE_COMMON_MCC_CREATE_EXT, sizeof(*req));
req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
@@ -688,7 +742,8 @@ int be_cmd_mccq_create(struct be_adapter *adapter,
AMAP_SET_BITS(struct amap_mcc_context, ring_size, ctxt,
be_encoded_q_len(mccq->len));
AMAP_SET_BITS(struct amap_mcc_context, cq_id, ctxt, cq->id);
-
+ /* Subscribe to Link State and Group 5 Events(bits 1 and 5 set) */
+ req->async_event_bitmap[0] |= 0x00000022;
be_dws_cpu_to_le(ctxt, sizeof(req->context));
be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h
index b7a40b1..c7f6cdf 100644
--- a/drivers/net/benet/be_cmds.h
+++ b/drivers/net/benet/be_cmds.h
@@ -82,7 +82,12 @@ struct be_mcc_compl {
*/
#define ASYNC_TRAILER_EVENT_CODE_SHIFT 8 /* bits 8 - 15 */
#define ASYNC_TRAILER_EVENT_CODE_MASK 0xFF
+#define ASYNC_TRAILER_EVENT_TYPE_SHIFT 16
+#define ASYNC_TRAILER_EVENT_TYPE_MASK 0xFF
#define ASYNC_EVENT_CODE_LINK_STATE 0x1
+#define ASYNC_EVENT_CODE_GRP_5 0x5
+#define ASYNC_EVENT_QOS_SPEED 0x1
+#define ASYNC_EVENT_COS_PRIORITY 0x2
struct be_async_event_trailer {
u32 code;
};
@@ -105,6 +110,30 @@ struct be_async_event_link_state {
struct be_async_event_trailer trailer;
} __packed;
+/* When the event code of an async trailer is GRP-5 and event_type is QOS_SPEED
+ * the mcc_compl must be interpreted as follows
+ */
+struct be_async_event_grp5_qos_link_speed {
+ u8 physical_port;
+ u8 rsvd[5];
+ u16 qos_link_speed;
+ u32 event_tag;
+ struct be_async_event_trailer trailer;
+} __packed;
+
+/* When the event code of an async trailer is GRP5 and event type is
+ * CoS-Priority, the mcc_compl must be interpreted as follows
+ */
+struct be_async_event_grp5_cos_priority {
+ u8 physical_port;
+ u8 available_priority_bmap;
+ u8 reco_default_priority;
+ u8 valid;
+ u8 rsvd0;
+ u8 event_tag;
+ struct be_async_event_trailer trailer;
+} __packed;
+
struct be_mcc_mailbox {
struct be_mcc_wrb wrb;
struct be_mcc_compl compl;
@@ -123,8 +152,9 @@ struct be_mcc_mailbox {
#define OPCODE_COMMON_WRITE_FLASHROM 7
#define OPCODE_COMMON_CQ_CREATE 12
#define OPCODE_COMMON_EQ_CREATE 13
-#define OPCODE_COMMON_MCC_CREATE 21
+#define OPCODE_COMMON_MCC_CREATE 21
#define OPCODE_COMMON_SET_QOS 28
+#define OPCODE_COMMON_MCC_CREATE_EXT 90
#define OPCODE_COMMON_SEEPROM_READ 30
#define OPCODE_COMMON_NTWK_RX_FILTER 34
#define OPCODE_COMMON_GET_FW_VERSION 35
@@ -338,6 +368,7 @@ struct be_cmd_req_mcc_create {
struct be_cmd_req_hdr hdr;
u16 num_pages;
u16 rsvd0;
+ u32 async_event_bitmap[1];
u8 context[sizeof(struct amap_mcc_context) / 8];
struct phys_addr pages[8];
} __packed;
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index d5e7968..45b1f66 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -429,9 +429,12 @@ static inline void wrb_fill(struct be_eth_wrb *wrb, u64 addr, int len)
wrb->frag_len = len & ETH_WRB_FRAG_LEN_MASK;
}
-static void wrb_fill_hdr(struct be_eth_hdr_wrb *hdr, struct sk_buff *skb,
- u32 wrb_cnt, u32 len)
+static void wrb_fill_hdr(struct be_adapter *adapter, struct be_eth_hdr_wrb *hdr,
+ struct sk_buff *skb, u32 wrb_cnt, u32 len)
{
+ u8 vlan_prio = 0;
+ u16 vlan_tag = 0;
+
memset(hdr, 0, sizeof(*hdr));
AMAP_SET_BITS(struct amap_eth_hdr_wrb, crc, hdr, 1);
@@ -449,10 +452,15 @@ static void wrb_fill_hdr(struct be_eth_hdr_wrb *hdr, struct sk_buff *skb,
AMAP_SET_BITS(struct amap_eth_hdr_wrb, udpcs, hdr, 1);
}
- if (vlan_tx_tag_present(skb)) {
+ if (adapter->vlan_grp && vlan_tx_tag_present(skb)) {
AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan, hdr, 1);
- AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan_tag,
- hdr, vlan_tx_tag_get(skb));
+ vlan_tag = vlan_tx_tag_get(skb);
+ vlan_prio = (vlan_tag & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;
+ /* If vlan priority provided by OS is NOT in available bmap */
+ if (!(adapter->vlan_prio_bmap & (1 << vlan_prio)))
+ vlan_tag = (vlan_tag & ~VLAN_PRIO_MASK) |
+ adapter->recommended_prio;
+ AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan_tag, hdr, vlan_tag);
}
AMAP_SET_BITS(struct amap_eth_hdr_wrb, event, hdr, 1);
@@ -532,7 +540,7 @@ static int make_tx_wrbs(struct be_adapter *adapter,
queue_head_inc(txq);
}
- wrb_fill_hdr(hdr, first_skb, wrb_cnt, copied);
+ wrb_fill_hdr(adapter, hdr, first_skb, wrb_cnt, copied);
be_dws_cpu_to_le(hdr, sizeof(*hdr));
return copied;
--
1.5.6.1
^ permalink raw reply related
* [PATCH v2] ipv4: synchronize bind() with RTM_NEWADDR notifications
From: Timo Teräs @ 2010-10-21 13:06 UTC (permalink / raw)
To: David Miller, eric.dumazet, netdev; +Cc: Timo Teräs
In-Reply-To: <4CC02ABF.8090008@iki.fi>
Otherwise we have race condition to user land:
1. process A: changes IP address
2. process A: kernel sends RTM_NEWADDR (and schedules out)
3. process B: gets notification
4. process B: tries to bind() to new IP, but fails with EADDRNOTAVAIL
because FIB is not yet updated and inet_addr_type() in inet_bind()
does not recognize the IP as local
5. process A: calls inetaddr_chain notifiers which updates FIB
Fix the error path to synchronize with configuration changes and retry
the address type check.
IPv6 side seems to handle the notifications properly: bind() immediately
after RTM_NEWADDR succeeds as expected. This is because ipv6_chk_addr()
uses inet6_addr_lst which is updated before address notification.
Signed-off-by: Timo Teräs <timo.teras@iki.fi>
---
Since there was no reply to my question if this is ok, I interpreted it
as "maybe". So here's the code for review. Hopefully this helps determining
if this is an acceptable fix.
net/ipv4/af_inet.c | 18 ++++++++++++++++--
net/ipv6/af_inet6.c | 13 ++++++++++---
2 files changed, 26 insertions(+), 5 deletions(-)
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 6a1100c..013ab11 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -481,8 +481,22 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
addr->sin_addr.s_addr != htonl(INADDR_ANY) &&
chk_addr_ret != RTN_LOCAL &&
chk_addr_ret != RTN_MULTICAST &&
- chk_addr_ret != RTN_BROADCAST)
- goto out;
+ chk_addr_ret != RTN_BROADCAST) {
+ /* inet_addr_type() does a FIB lookup to check the
+ * address type. Since FIB is updated after sending
+ * RTM_NEWADDR notification, an application may end up
+ * doing bind() before the FIB is updated. To avoid
+ * returning a false negative, wait for possible ongoing
+ * address changes to finish by acquiring rtnl lock and
+ * retry the address type lookup. */
+ rtnl_lock();
+ rtnl_unlock();
+ chk_addr_ret = inet_addr_type(sock_net(sk), addr->sin_addr.s_addr);
+ if (chk_addr_ret != RTN_LOCAL &&
+ chk_addr_ret != RTN_MULTICAST &&
+ chk_addr_ret != RTN_BROADCAST)
+ goto out;
+ }
snum = ntohs(addr->sin_port);
err = -EACCES;
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 56b9bf2..b1a83e1 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -300,7 +300,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
goto out;
}
- /* Reproduce AF_INET checks to make the bindings consitant */
+ /* Reproduce AF_INET checks to make the bindings consistent */
v4addr = addr->sin6_addr.s6_addr32[3];
chk_addr_ret = inet_addr_type(net, v4addr);
if (!sysctl_ip_nonlocal_bind &&
@@ -309,8 +309,15 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
chk_addr_ret != RTN_LOCAL &&
chk_addr_ret != RTN_MULTICAST &&
chk_addr_ret != RTN_BROADCAST) {
- err = -EADDRNOTAVAIL;
- goto out;
+ rtnl_lock();
+ rtnl_unlock();
+ chk_addr_ret = inet_addr_type(net, v4addr);
+ if (chk_addr_ret != RTN_LOCAL &&
+ chk_addr_ret != RTN_MULTICAST &&
+ chk_addr_ret != RTN_BROADCAST) {
+ err = -EADDRNOTAVAIL;
+ goto out;
+ }
}
} else {
if (addr_type != IPV6_ADDR_ANY) {
--
1.7.1
^ permalink raw reply related
* Re: [PATCH] tipc: revert some previously ABI breaking changes to the user space tipc interface
From: Paul Gortmaker @ 2010-10-21 13:06 UTC (permalink / raw)
To: nhorman; +Cc: jon.maloy, netdev, tipc-discussion, davem, luca
In-Reply-To: <1287659176-14504-1-git-send-email-nhorman@tuxdriver.com>
On 10-10-21 07:06 AM, nhorman@tuxdriver.com wrote:
> Based on discussions with Leandro Lucarella and Jon Maloy, it appears we've
> managed to break the TIPC user space ABI. While it would be really nice to have
> some level of consistency in regards to on the wire byte order, we can't do that
> if it breaks user space. This patch series reverts the offending patches that
> caused this, and puts us back in a state that allows user space to work
> properly. We can now go back and look at methods to get consistent on the wire
> byte order while maintaining host byte order in the user space API.
Thanks Neil for working with Jon and Leandro on this and getting
a fix out quickly (faster than I could have, for sure.)
Paul.
>
> Signed-off-by: Neil Horman<nhorman@tuxdriver.com>
------------------------------------------------------------------------------
Nokia and AT&T present the 2010 Calling All Innovators-North America contest
Create new apps & games for the Nokia N8 for consumers in U.S. and Canada
$10 million total in prizes - $4M cash, 500 devices, nearly $6M in marketing
Develop with Nokia Qt SDK, Web Runtime, or Java and Publish to Ovi Store
http://p.sf.net/sfu/nokia-dev2dev
^ permalink raw reply
* [PATCH] iproute2: add VF_PORT support
From: Roopa Prabhu @ 2010-10-21 12:41 UTC (permalink / raw)
To: davem; +Cc: netdev, shemminger, scofeldm
From: Roopa Prabhu <roprabhu@cisco.com>
Resubmitting Scott Feldmans original patch with a minor fix
Changes since last posted version:
- Fix port profile strlen which was off by 1
Add support for IFLA_VF_PORTS. VF port netlink msg layout is
[IFLA_NUM_VF]
[IFLA_VF_PORTS]
[IFLA_VF_PORT]
[IFLA_PORT_*], ...
[IFLA_VF_PORT]
[IFLA_PORT_*], ...
...
[IFLA_PORT_SELF]
[IFLA_PORT_*], ...
The iproute2 cmd line for link set is now:
Usage: ip link add link DEV [ name ] NAME
[ txqueuelen PACKETS ]
[ address LLADDR ]
[ broadcast LLADDR ]
[ mtu MTU ]
type TYPE [ ARGS ]
ip link delete DEV type TYPE [ ARGS ]
ip link set DEVICE [ { up | down } ]
[ arp { on | off } ]
[ dynamic { on | off } ]
[ multicast { on | off } ]
[ allmulticast { on | off } ]
[ promisc { on | off } ]
[ trailers { on | off } ]
[ txqueuelen PACKETS ]
[ name NEWNAME ]
[ address LLADDR ]
[ broadcast LLADDR ]
[ mtu MTU ]
[ netns PID ]
[ alias NAME ]
[ port MODE { PROFILE | VSI } ]
[ vf NUM [ mac LLADDR ]
[ vlan VLANID [ qos VLAN-QOS ] ]
[ rate TXRATE ]
[ port MODE { PROFILE | VSI } ] ]
ip link show [ DEVICE ]
TYPE := { vlan | veth | vcan | dummy | ifb | macvlan | can }
MODE := { assoc | preassoc | preassocrr | disassoc }
PROFILE := profile PROFILE
[ instance UUID ]
[ host UUID ]
VSI := vsi mgr MGRID type VTID ver VER
[ instance UUID ]
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
---
ip/ipaddress.c | 115 +++++++++++++++++++++++++++++
ip/iplink.c | 225 +++++++++++++++++++++++++++++++++++++++++++++++---------
2 files changed, 302 insertions(+), 38 deletions(-)
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 19b3d6e..65be741 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -187,6 +187,107 @@ static void print_linktype(FILE *fp, struct rtattr *tb)
}
}
+static void print_port(FILE *fp, struct rtattr *port[])
+{
+ struct ifla_port_vsi *vsi;
+#define uuid_fmt "%02X%02X%02X%02X-%02X%02X-%02X%02X-" \
+ "%02X%02X-%02X%02X%02X%02X%02X%02X"
+ unsigned char *uuid;
+ __u8 request;
+ __u16 response;
+
+ if (port[IFLA_PORT_VF])
+ fprintf(fp, "\n vf %d port",
+ *(__u32 *)RTA_DATA(port[IFLA_PORT_VF]));
+ else
+ fprintf(fp, "\n port");
+
+ if (port[IFLA_PORT_REQUEST]) {
+ request = *(__u8 *)RTA_DATA(port[IFLA_PORT_REQUEST]);
+ fprintf(fp, " %s",
+ request == PORT_REQUEST_PREASSOCIATE ? "preassoc" :
+ request == PORT_REQUEST_PREASSOCIATE_RR ? "preassocrr" :
+ request == PORT_REQUEST_ASSOCIATE ? "assoc" :
+ request == PORT_REQUEST_DISASSOCIATE ? "disassoc" :
+ "unknown request");
+ }
+
+ if (port[IFLA_PORT_PROFILE])
+ fprintf(fp, " profile \"%s\"",
+ (char *)RTA_DATA(port[IFLA_PORT_PROFILE]));
+
+ if (port[IFLA_PORT_VSI_TYPE]) {
+ vsi = RTA_DATA(port[IFLA_PORT_VSI_TYPE]);
+ fprintf(fp, " vsi mgr %d type 0x%02x%02x%02x ver %d",
+ vsi->vsi_mgr_id, vsi->vsi_type_id[0],
+ vsi->vsi_type_id[1], vsi->vsi_type_id[2],
+ vsi->vsi_type_version);
+ }
+
+ if (port[IFLA_PORT_RESPONSE]) {
+ response = *(__u16 *)RTA_DATA(port[IFLA_PORT_RESPONSE]);
+ fprintf(fp, " status: %s",
+ response == PORT_VDP_RESPONSE_SUCCESS ?
+ "SUCCESS" :
+ response == PORT_VDP_RESPONSE_INVALID_FORMAT ?
+ "INVALID FORMAT" :
+ response == PORT_VDP_RESPONSE_INSUFFICIENT_RESOURCES ?
+ "INSUFFICIENT RESOURCES" :
+ response == PORT_VDP_RESPONSE_UNUSED_VTID ?
+ "UNUSED VTID" :
+ response == PORT_VDP_RESPONSE_VTID_VIOLATION ?
+ "VTID VIOLATION" :
+ response == PORT_VDP_RESPONSE_VTID_VERSION_VIOALTION ?
+ "VTID VERSION VIOLATION" :
+ response == PORT_VDP_RESPONSE_OUT_OF_SYNC ?
+ "OUT-OF-SYNC" :
+ response == PORT_PROFILE_RESPONSE_SUCCESS ?
+ "SUCCESS" :
+ response == PORT_PROFILE_RESPONSE_INPROGRESS ?
+ "IN-PROGRESS" :
+ response == PORT_PROFILE_RESPONSE_INVALID ?
+ "INVALID" :
+ response == PORT_PROFILE_RESPONSE_BADSTATE ?
+ "BAD STATE" :
+ response == PORT_PROFILE_RESPONSE_INSUFFICIENT_RESOURCES ?
+ "INSUFFICIENT RESOURCES" :
+ response == PORT_PROFILE_RESPONSE_ERROR ?
+ "ERROR" :
+ "UNKNOWN RESPONSE");
+ }
+
+ if (port[IFLA_PORT_INSTANCE_UUID]) {
+ uuid = RTA_DATA(port[IFLA_PORT_INSTANCE_UUID]);
+ fprintf(fp, "\n instance "uuid_fmt,
+ uuid[0], uuid[1], uuid[2], uuid[3],
+ uuid[4], uuid[5], uuid[6], uuid[7],
+ uuid[8], uuid[9], uuid[10], uuid[11],
+ uuid[12], uuid[13], uuid[14], uuid[15]);
+ }
+
+ if (port[IFLA_PORT_HOST_UUID]) {
+ uuid = RTA_DATA(port[IFLA_PORT_HOST_UUID]);
+ fprintf(fp, "\n host "uuid_fmt,
+ uuid[0], uuid[1], uuid[2], uuid[3],
+ uuid[4], uuid[5], uuid[6], uuid[7],
+ uuid[8], uuid[9], uuid[10], uuid[11],
+ uuid[12], uuid[13], uuid[14], uuid[15]);
+ }
+}
+
+static void print_vfport(FILE *fp, struct rtattr *vfport)
+{
+ struct rtattr *port[IFLA_PORT_MAX+1];
+
+ if (vfport->rta_type != IFLA_VF_PORT) {
+ fprintf(stderr, "BUG: rta type is %d\n", vfport->rta_type);
+ return;
+ }
+
+ parse_rtattr_nested(port, IFLA_PORT_MAX, vfport);
+ print_port(fp, port);
+}
+
static void print_vfinfo(FILE *fp, struct rtattr *vfinfo)
{
struct ifla_vf_mac *vf_mac;
@@ -421,6 +522,20 @@ int print_linkinfo(const struct sockaddr_nl *who,
print_vfinfo(fp, i);
}
+ if (do_link && tb[IFLA_PORT_SELF]) {
+ struct rtattr *port[IFLA_PORT_MAX+1];
+ parse_rtattr_nested(port, IFLA_PORT_MAX, tb[IFLA_PORT_SELF]);
+ print_port(fp, port);
+ }
+
+ if (do_link && tb[IFLA_VF_PORTS] && tb[IFLA_NUM_VF]) {
+ struct rtattr *i, *vfports = tb[IFLA_VF_PORTS];
+ int rem = RTA_PAYLOAD(vfports);
+ for (i = RTA_DATA(vfports); RTA_OK(i, rem);
+ i = RTA_NEXT(i, rem))
+ print_vfport(fp, i);
+ }
+
fprintf(fp, "\n");
fflush(fp);
return 0;
diff --git a/ip/iplink.c b/ip/iplink.c
index cb2c4f5..0a29ae5 100644
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -68,14 +68,22 @@ void iplink_usage(void)
fprintf(stderr, " [ mtu MTU ]\n");
fprintf(stderr, " [ netns PID ]\n");
fprintf(stderr, " [ alias NAME ]\n");
+ fprintf(stderr, " [ port MODE { PROFILE | VSI } ]\n");
fprintf(stderr, " [ vf NUM [ mac LLADDR ]\n");
fprintf(stderr, " [ vlan VLANID [ qos VLAN-QOS ] ]\n");
- fprintf(stderr, " [ rate TXRATE ] ] \n");
+ fprintf(stderr, " [ rate TXRATE ]\n");
+ fprintf(stderr, " [ port MODE { PROFILE | VSI } ] ]\n");
fprintf(stderr, " ip link show [ DEVICE ]\n");
if (iplink_have_newlink()) {
fprintf(stderr, "\n");
fprintf(stderr, "TYPE := { vlan | veth | vcan | dummy | ifb | macvlan | can }\n");
+ fprintf(stderr, "MODE := { assoc | preassoc | preassocrr | disassoc }\n");
+ fprintf(stderr, "PROFILE := profile PROFILE\n");
+ fprintf(stderr, " [ instance UUID ]\n");
+ fprintf(stderr, " [ host UUID ]\n");
+ fprintf(stderr, "VSI := vsi mgr MGRID type VTID ver VER\n");
+ fprintf(stderr, " [ instance UUID ]\n");
}
exit(-1);
}
@@ -176,55 +184,168 @@ struct iplink_req {
char buf[1024];
};
-int iplink_parse_vf(int vf, int *argcp, char ***argvp,
- struct iplink_req *req)
+void iplink_parse_port(int vf, int *argcp, char ***argvp,
+ struct iplink_req *req)
+{
+ int argc = *argcp;
+ char **argv = *argvp;
+ struct rtattr *nest, *nest_inner = NULL;
+ struct ifla_port_vsi port_vsi;
+ char *port_profile = NULL;
+ char *instance_uuid = NULL;
+ char *host_uuid = NULL;
+ unsigned char uuid[16];
+ char *uuid_fmt = "%02X%02X%02X%02X-%02X%02X-%02X%02X-"
+ "%02X%02X-%02X%02X%02X%02X%02X%02X";
+ int parsed;
+ int manager_id = -1;
+ int type_id = -1;
+ int type_id_version = -1;
+ int request = -1;
+ int vsi = 0;
+
+ if (NEXT_ARG_OK()) {
+ NEXT_ARG();
+ if (matches(*argv, "assoc") == 0)
+ request = PORT_REQUEST_ASSOCIATE;
+ else if (matches(*argv, "preassoc") == 0)
+ request = PORT_REQUEST_PREASSOCIATE;
+ else if (matches(*argv, "preassocrr") == 0)
+ request = PORT_REQUEST_PREASSOCIATE_RR;
+ else if (matches(*argv, "disassoc") == 0)
+ request = PORT_REQUEST_DISASSOCIATE;
+ }
+
+ while (NEXT_ARG_OK()) {
+ NEXT_ARG();
+ if (matches(*argv, "vsi") == 0) {
+ vsi = 1;
+ } else if (matches(*argv, "mgr") == 0) {
+ NEXT_ARG();
+ if (get_integer(&manager_id, *argv, 0))
+ invarg("Invalid \"mgr\" value\n", *argv);
+ } else if (matches(*argv, "type") == 0) {
+ NEXT_ARG();
+ if (get_integer(&type_id, *argv, 0))
+ invarg("Invalid \"type\" value\n", *argv);
+ } else if (matches(*argv, "ver") == 0) {
+ NEXT_ARG();
+ if (get_integer(&type_id_version, *argv, 0))
+ invarg("Invalid \"ver\" value\n", *argv);
+ } else if (matches(*argv, "profile") == 0) {
+ NEXT_ARG();
+ port_profile = *argv;
+ } else if (matches(*argv, "instance") == 0) {
+ NEXT_ARG();
+ instance_uuid = *argv;
+ } else if (matches(*argv, "host") == 0) {
+ NEXT_ARG();
+ host_uuid = *argv;
+ } else {
+ /* rewind arg */
+ PREV_ARG();
+ break;
+ }
+ }
+
+ if (argc == *argcp)
+ incomplete_command();
+
+ if (vf == PORT_SELF_VF) {
+ nest = addattr_nest(&req->n, sizeof(*req), IFLA_PORT_SELF);
+ } else {
+ nest = addattr_nest(&req->n, sizeof(*req), IFLA_VF_PORTS);
+ nest_inner = addattr_nest(&req->n, sizeof(*req), IFLA_VF_PORT);
+ addattr_l(&req->n, sizeof(*req), IFLA_PORT_VF,
+ (uint32_t *)&vf, sizeof(uint32_t));
+ }
+
+ if (port_profile)
+ addattr_l(&req->n, sizeof(*req), IFLA_PORT_PROFILE,
+ port_profile, strlen(port_profile) + 1);
+
+ if (instance_uuid) {
+ parsed = sscanf(instance_uuid, uuid_fmt,
+ &uuid[0], &uuid[1], &uuid[2], &uuid[3],
+ &uuid[4], &uuid[5], &uuid[6], &uuid[7],
+ &uuid[8], &uuid[9], &uuid[10], &uuid[11],
+ &uuid[12], &uuid[13], &uuid[14], &uuid[15]);
+ if (parsed != sizeof(uuid))
+ invarg("Invalid \"uuid\" value\n", instance_uuid);
+ addattr_l(&req->n, sizeof(*req), IFLA_PORT_INSTANCE_UUID,
+ uuid, sizeof(uuid));
+ }
+
+ if (host_uuid) {
+ parsed = sscanf(host_uuid, uuid_fmt,
+ &uuid[0], &uuid[1], &uuid[2], &uuid[3],
+ &uuid[4], &uuid[5], &uuid[6], &uuid[7],
+ &uuid[8], &uuid[9], &uuid[10], &uuid[11],
+ &uuid[12], &uuid[13], &uuid[14], &uuid[15]);
+ if (parsed != sizeof(uuid))
+ invarg("Invalid \"uuid\" value\n", host_uuid);
+ addattr_l(&req->n, sizeof(*req), IFLA_PORT_HOST_UUID,
+ uuid, sizeof(uuid));
+ }
+
+ if (vsi) {
+ port_vsi.vsi_mgr_id = manager_id;
+ memcpy(&port_vsi.vsi_type_id, &type_id,
+ sizeof(port_vsi.vsi_type_id));
+ port_vsi.vsi_type_version = type_id_version;
+ addattr_l(&req->n, sizeof(*req), IFLA_PORT_VSI_TYPE,
+ &port_vsi, sizeof(port_vsi));
+ }
+
+ addattr_l(&req->n, sizeof(*req), IFLA_PORT_REQUEST,
+ &request, 1);
+
+ if (nest_inner)
+ addattr_nest_end(&req->n, nest_inner);
+ addattr_nest_end(&req->n, nest);
+
+ *argcp = argc;
+ *argvp = argv;
+}
+
+void iplink_parse_vf(int vf, int *argcp, char ***argvp,
+ struct iplink_req *req)
{
int len, argc = *argcp;
char **argv = *argvp;
+ struct rtattr *vflist;
struct rtattr *vfinfo;
-
- vfinfo = addattr_nest(&req->n, sizeof(*req), IFLA_VF_INFO);
+ char *mac = NULL;
+ char *vlan = NULL;
+ char *qos = NULL;
+ char *rate = NULL;
+ struct ifla_vf_mac ivm = { .vf = vf, };
+ struct ifla_vf_vlan ivv = { .vf = vf, .qos = 0, };
+ struct ifla_vf_tx_rate ivt = { .vf = vf, };
while (NEXT_ARG_OK()) {
NEXT_ARG();
- if (matches(*argv, "mac") == 0) {
- struct ifla_vf_mac ivm;
+ if (matches(*argv, "port") == 0) {
+ iplink_parse_port(vf, &argc, &argv, req);
+ } else if (matches(*argv, "mac") == 0) {
NEXT_ARG();
- ivm.vf = vf;
- len = ll_addr_a2n((char *)ivm.mac, 32, *argv);
- if (len < 0)
- return -1;
- addattr_l(&req->n, sizeof(*req), IFLA_VF_MAC, &ivm, sizeof(ivm));
+ mac = *argv;
} else if (matches(*argv, "vlan") == 0) {
- struct ifla_vf_vlan ivv;
NEXT_ARG();
- if (get_unsigned(&ivv.vlan, *argv, 0)) {
- invarg("Invalid \"vlan\" value\n", *argv);
- }
- ivv.vf = vf;
- ivv.qos = 0;
+ vlan = *argv;
if (NEXT_ARG_OK()) {
NEXT_ARG();
if (matches(*argv, "qos") == 0) {
NEXT_ARG();
- if (get_unsigned(&ivv.qos, *argv, 0)) {
- invarg("Invalid \"qos\" value\n", *argv);
- }
+ qos = *argv;
} else {
/* rewind arg */
PREV_ARG();
}
}
- addattr_l(&req->n, sizeof(*req), IFLA_VF_VLAN, &ivv, sizeof(ivv));
} else if (matches(*argv, "rate") == 0) {
- struct ifla_vf_tx_rate ivt;
NEXT_ARG();
- if (get_unsigned(&ivt.rate, *argv, 0)) {
- invarg("Invalid \"rate\" value\n", *argv);
- }
- ivt.vf = vf;
- addattr_l(&req->n, sizeof(*req), IFLA_VF_TX_RATE, &ivt, sizeof(ivt));
-
+ rate = *argv;
} else {
/* rewind arg */
PREV_ARG();
@@ -235,11 +356,43 @@ int iplink_parse_vf(int vf, int *argcp, char ***argvp,
if (argc == *argcp)
incomplete_command();
- addattr_nest_end(&req->n, vfinfo);
+ if (mac || vlan || rate) {
+
+ vflist = addattr_nest(&req->n, sizeof(*req), IFLA_VFINFO_LIST);
+ vfinfo = addattr_nest(&req->n, sizeof(*req), IFLA_VF_INFO);
+
+ if (mac) {
+ len = ll_addr_a2n((char *)ivm.mac, 32, mac);
+ if (len < 0)
+ invarg("Invalid \"mac\" value\n", mac);
+ addattr_l(&req->n, sizeof(*req), IFLA_VF_MAC,
+ &ivm, sizeof(ivm));
+ }
+
+ if (vlan) {
+ if (get_unsigned(&ivv.vlan, vlan, 0))
+ invarg("Invalid \"vlan\" value\n", vlan);
+ if (qos) {
+ if (get_unsigned(&ivv.qos, qos, 0))
+ invarg("Invalid \"qos\" value\n", qos);
+ }
+ addattr_l(&req->n, sizeof(*req), IFLA_VF_VLAN,
+ &ivv, sizeof(ivv));
+ }
+
+ if (rate) {
+ if (get_unsigned(&ivt.rate, rate, 0))
+ invarg("Invalid \"rate\" value\n", rate);
+ addattr_l(&req->n, sizeof(*req), IFLA_VF_TX_RATE,
+ &ivt, sizeof(ivt));
+ }
+
+ addattr_nest_end(&req->n, vfinfo);
+ addattr_nest_end(&req->n, vflist);
+ }
*argcp = argc;
*argvp = argv;
- return 0;
}
@@ -349,18 +502,14 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req,
req->i.ifi_flags |= IFF_NOARP;
} else
return on_off("noarp");
+ } else if (strcmp(*argv, "port") == 0) {
+ iplink_parse_port(vf, &argc, &argv, req);
} else if (strcmp(*argv, "vf") == 0) {
- struct rtattr *vflist;
NEXT_ARG();
if (get_integer(&vf, *argv, 0)) {
invarg("Invalid \"vf\" value\n", *argv);
}
- vflist = addattr_nest(&req->n, sizeof(*req),
- IFLA_VFINFO_LIST);
- len = iplink_parse_vf(vf, &argc, &argv, req);
- if (len < 0)
- return -1;
- addattr_nest_end(&req->n, vflist);
+ iplink_parse_vf(vf, &argc, &argv, req);
#ifdef IFF_DYNAMIC
} else if (matches(*argv, "dynamic") == 0) {
NEXT_ARG();
^ permalink raw reply related
* Re: [PATCH 1/2] can: mcp251x: fix endless loop in interrupt handler if CANINTF_MERRF is set
From: Marc Kleine-Budde @ 2010-10-21 12:24 UTC (permalink / raw)
To: David Jander; +Cc: socketcan-core, netdev
In-Reply-To: <201010211408.08467.david.jander@protonic.nl>
[-- Attachment #1: Type: text/plain, Size: 3259 bytes --]
On 10/21/2010 02:08 PM, David Jander wrote:
> On Wednesday 20 October 2010 12:02:25 pm Marc Kleine-Budde wrote:
>> Commit d3cd15657516141adce387810be8cb377baf020e introduced a bug, the
>> interrupt handler would loop endlessly if the CANINTF_MERRF bit is set,
>> because it's not cleared.
>>
>> This patch fixes the problem by masking out the CANINTF_MERRF and all other
>> non interesting bits.
>>
>> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
>> ---
>> drivers/net/can/mcp251x.c | 14 +++++++++-----
>> 1 files changed, 9 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c
>> index c664be2..59f40bc 100644
>> --- a/drivers/net/can/mcp251x.c
>> +++ b/drivers/net/can/mcp251x.c
>> @@ -125,8 +125,9 @@
>> # define CANINTF_TX0IF 0x04
>> # define CANINTF_RX1IF 0x02
>> # define CANINTF_RX0IF 0x01
>> -# define CANINTF_ERR_TX \
>> - (CANINTF_ERRIF | CANINTF_TX2IF | CANINTF_TX1IF | CANINTF_TX0IF)
>> +# define CANINTF_RX (CANINTF_RX0IF | CANINTF_RX1IF)
>> +# define CANINTF_TX (CANINTF_TX2IF | CANINTF_TX1IF | CANINTF_TX0IF)
>> +# define CANINTF_ERR (CANINTF_ERRIF)
>
> Is it just me, or do you still miss MERRF?
>
>> #define EFLG 0x2d
>> # define EFLG_EWARN 0x01
>> # define EFLG_RXWAR 0x02
>> @@ -790,6 +791,9 @@ static irqreturn_t mcp251x_can_ist(int irq, void
>> *dev_id)
>>
>> mcp251x_read_2regs(spi, CANINTF, &intf, &eflag);
>>
>> + /* mask out flags we don't care about */
>> + intf &= CANINTF_RX | CANINTF_TX | CANINTF_ERR;
>> +
>> /* receive buffer 0 */
>> if (intf & CANINTF_RX0IF) {
>> mcp251x_hw_rx(spi, 0);
>> @@ -810,8 +814,8 @@ static irqreturn_t mcp251x_can_ist(int irq, void
>> *dev_id) }
>>
>> /* any error or tx interrupt we need to clear? */
>> - if (intf & CANINTF_ERR_TX)
>> - clear_intf |= intf & CANINTF_ERR_TX;
>> + if (intf & (CANINTF_ERR | CANINTF_TX))
>> + clear_intf |= intf & (CANINTF_ERR | CANINTF_TX);
>> if (clear_intf)
>> mcp251x_write_bits(spi, CANINTF, clear_intf, 0x00);
>>
>> @@ -887,7 +891,7 @@ static irqreturn_t mcp251x_can_ist(int irq, void
>> *dev_id) if (intf == 0)
>> break;
>>
>> - if (intf & (CANINTF_TX2IF | CANINTF_TX1IF | CANINTF_TX0IF)) {
>> + if (intf & CANINTF_TX) {
>> net->stats.tx_packets++;
>> net->stats.tx_bytes += priv->tx_len - 1;
>> if (priv->tx_len) {
>
> I've been staring at the changes for quite some time now, but I still don't
> understand how an "CANINTF" value of "0x80" is ever cleared (MERRF set).
> Granted, you don't loop anymore, but shouldn't that flag be handled properly?
No need to clear the bit, because we don't get en interrupt when it's
set. Because we don't enable it to trigger an interrupt:
> /* Enable interrupts */
> mcp251x_write_reg(spi, CANINTE,
> CANINTE_ERRIE | CANINTE_TX2IE | CANINTE_TX1IE |
> CANINTE_TX0IE | CANINTE_RX1IE | CANINTE_RX0IE);
cheers, Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 262 bytes --]
^ permalink raw reply
* Re: [PATCH 1/2] can: mcp251x: fix endless loop in interrupt handler if CANINTF_MERRF is set
From: David Jander @ 2010-10-21 12:08 UTC (permalink / raw)
To: socketcan-core-0fE9KPoRgkgATYTw5x5z8w
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, Marc Kleine-Budde
In-Reply-To: <1287568946-32727-2-git-send-email-mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
On Wednesday 20 October 2010 12:02:25 pm Marc Kleine-Budde wrote:
> Commit d3cd15657516141adce387810be8cb377baf020e introduced a bug, the
> interrupt handler would loop endlessly if the CANINTF_MERRF bit is set,
> because it's not cleared.
>
> This patch fixes the problem by masking out the CANINTF_MERRF and all other
> non interesting bits.
>
> Signed-off-by: Marc Kleine-Budde <mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
> ---
> drivers/net/can/mcp251x.c | 14 +++++++++-----
> 1 files changed, 9 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c
> index c664be2..59f40bc 100644
> --- a/drivers/net/can/mcp251x.c
> +++ b/drivers/net/can/mcp251x.c
> @@ -125,8 +125,9 @@
> # define CANINTF_TX0IF 0x04
> # define CANINTF_RX1IF 0x02
> # define CANINTF_RX0IF 0x01
> -# define CANINTF_ERR_TX \
> - (CANINTF_ERRIF | CANINTF_TX2IF | CANINTF_TX1IF | CANINTF_TX0IF)
> +# define CANINTF_RX (CANINTF_RX0IF | CANINTF_RX1IF)
> +# define CANINTF_TX (CANINTF_TX2IF | CANINTF_TX1IF | CANINTF_TX0IF)
> +# define CANINTF_ERR (CANINTF_ERRIF)
Is it just me, or do you still miss MERRF?
> #define EFLG 0x2d
> # define EFLG_EWARN 0x01
> # define EFLG_RXWAR 0x02
> @@ -790,6 +791,9 @@ static irqreturn_t mcp251x_can_ist(int irq, void
> *dev_id)
>
> mcp251x_read_2regs(spi, CANINTF, &intf, &eflag);
>
> + /* mask out flags we don't care about */
> + intf &= CANINTF_RX | CANINTF_TX | CANINTF_ERR;
> +
> /* receive buffer 0 */
> if (intf & CANINTF_RX0IF) {
> mcp251x_hw_rx(spi, 0);
> @@ -810,8 +814,8 @@ static irqreturn_t mcp251x_can_ist(int irq, void
> *dev_id) }
>
> /* any error or tx interrupt we need to clear? */
> - if (intf & CANINTF_ERR_TX)
> - clear_intf |= intf & CANINTF_ERR_TX;
> + if (intf & (CANINTF_ERR | CANINTF_TX))
> + clear_intf |= intf & (CANINTF_ERR | CANINTF_TX);
> if (clear_intf)
> mcp251x_write_bits(spi, CANINTF, clear_intf, 0x00);
>
> @@ -887,7 +891,7 @@ static irqreturn_t mcp251x_can_ist(int irq, void
> *dev_id) if (intf == 0)
> break;
>
> - if (intf & (CANINTF_TX2IF | CANINTF_TX1IF | CANINTF_TX0IF)) {
> + if (intf & CANINTF_TX) {
> net->stats.tx_packets++;
> net->stats.tx_bytes += priv->tx_len - 1;
> if (priv->tx_len) {
I've been staring at the changes for quite some time now, but I still don't
understand how an "CANINTF" value of "0x80" is ever cleared (MERRF set).
Granted, you don't loop anymore, but shouldn't that flag be handled properly?
Best regards,
--
David Jander
Protonic Holland.
^ permalink raw reply
* Re: [PATCH] Drivers: atm: Makefile: replace the use of <module>-objs with <module>-y
From: Tracey Dent @ 2010-10-21 11:59 UTC (permalink / raw)
To: David Miller; +Cc: chas, linux-kernel, netdev, linux-atm-general
In-Reply-To: <20101021.031107.226775564.davem@davemloft.net>
On 10/21/10, David Miller <davem@davemloft.net> wrote:
> From: Tracey Dent <tdent48227@gmail.com>
> Date: Fri, 15 Oct 2010 23:53:29 -0400
>
>> Changed <module>-objs to <module>-y in Makefile.
>>
>> Signed-off-by: Tracey Dent <tdent48227@gmail.com>
>
> Applied.
>
Thanks
^ permalink raw reply
* Re: [PATCH] ipv4: synchronize bind() with RTM_NEWADDR notifications
From: Timo Teräs @ 2010-10-21 11:57 UTC (permalink / raw)
To: David Miller; +Cc: eric.dumazet, netdev
In-Reply-To: <20101021.043421.108778257.davem@davemloft.net>
On 10/21/2010 02:34 PM, David Miller wrote:
> From: Timo Teräs <timo.teras@iki.fi>
> Date: Thu, 21 Oct 2010 14:29:22 +0300
>
>> This is the third time asking, what would be a good way to fix the
>> problem described in the original commit log?
>
> I kept your report in my inbox backlog and intended to think about
> it as time permitted.
>
> As the merge window has just openned up, for me time will not be
> "permitted" for some time.
Fair enough. Just getting multiple "does not work" without single
mention of "will think about this later" felt frustrating.
I have one more alternative: Would it be acceptable if we did
rtnl_lock()/rtnl_unlock() only if inet_addr_type() earlier said the
address is unacceptable for binding. And then retry inet_addr_type(). Or
do you think that the error case EADDRNOTAVAIL is a hot path too?
^ permalink raw reply
* Re: [RFC PATCH 5/9] ipvs network name space aware
From: Hans Schillstrom @ 2010-10-21 11:49 UTC (permalink / raw)
To: Eric Dumazet
Cc: Simon Horman, lvs-devel@vger.kernel.org, netdev@vger.kernel.org,
netfilter-devel@vger.kernel.org, ja@ssi.bg, wensong@linux-vs.org,
daniel.lezcano@free.fr
In-Reply-To: <1287660414.6871.85.camel@edumazet-laptop>
On Thursday 21 October 2010 13:26:54 Eric Dumazet wrote:
> Le jeudi 21 octobre 2010 à 13:16 +0200, Simon Horman a écrit :
>
> > > @@ -2680,10 +2664,15 @@ static int ip_vs_genl_dump_services(struct sk_buff *skb,
> > > int idx = 0, i;
> > > int start = cb->args[0];
> > > struct ip_vs_service *svc;
> > > -
> > > + struct net *net = skb->sk->sk_net;
> >
> > skb->sk->sk_net needs CONFIG_NS_NET.
> > Is your plan for IPVS to unconditionally depend on CONFIG_NS_NET?
> > It would be nice to avoid that, but I fear it will be too messy.
> >
>
>
> struct net *net = sock_net(skb->sk);
>
> is your friend ;)
>
>
Tanks Eric,
Simon,
do forget about my last mail....
>
--
Regards
Hans Schillstrom <hans.schillstrom@ericsson.com>
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" 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: [PATCH v2 1/9] tproxy: split off ipv6 defragmentation to a separate module
From: KOVACS Krisztian @ 2010-10-21 11:43 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netdev, netfilter-devel, Balazs Scheidler, David Miller
In-Reply-To: <4CC02456.4050301@trash.net>
On Thu, 2010-10-21 at 13:30 +0200, Patrick McHardy wrote:
> > @@ -623,11 +625,19 @@ int nf_ct_frag6_init(void)
> > inet_frags_init_net(&nf_init_frags);
> > inet_frags_init(&nf_frags);
> >
> > + nf_ct_frag6_sysctl_header = register_sysctl_paths(nf_net_netfilter_sysctl_path,
> > + nf_ct_frag6_sysctl_table);
> > + if (!nf_ct_frag6_sysctl_header)
> > + return -ENOMEM;
>
>
> This needs to call inet_frags_fini() on errors since inet_frags_init()
> starts a timer to recalculate the secret.
That's a good catch, should be fixed in the patch below. Thanks Patrick!
commit 7e9c541b2d6129757a250b8be21b46d4f84d628d
Author: Balazs Scheidler <bazsi@balabit.hu>
Date: Tue Oct 19 01:16:21 2010 +0200
tproxy: split off ipv6 defragmentation to a separate module
Like with IPv4, TProxy needs IPv6 defragmentation but does not
require connection tracking. Since defragmentation was coupled
with conntrack, I split off the two, creating an nf_defrag_ipv6 module,
similar to the already existing nf_defrag_ipv4.
Signed-off-by: Balazs Scheidler <bazsi@balabit.hu>
Signed-off-by: KOVACS Krisztian <hidden@balabit.hu>
diff --git a/include/net/netfilter/ipv6/nf_defrag_ipv6.h b/include/net/netfilter/ipv6/nf_defrag_ipv6.h
new file mode 100644
index 0000000..94dd54d
--- /dev/null
+++ b/include/net/netfilter/ipv6/nf_defrag_ipv6.h
@@ -0,0 +1,6 @@
+#ifndef _NF_DEFRAG_IPV6_H
+#define _NF_DEFRAG_IPV6_H
+
+extern void nf_defrag_ipv6_enable(void);
+
+#endif /* _NF_DEFRAG_IPV6_H */
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
index aafbba3..3f8e4a3 100644
--- a/net/ipv6/netfilter/Makefile
+++ b/net/ipv6/netfilter/Makefile
@@ -11,10 +11,11 @@ obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
obj-$(CONFIG_IP6_NF_SECURITY) += ip6table_security.o
# objects for l3 independent conntrack
-nf_conntrack_ipv6-objs := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o nf_conntrack_reasm.o
+nf_conntrack_ipv6-objs := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o
+nf_defrag_ipv6-objs := nf_defrag_ipv6_hooks.o nf_conntrack_reasm.o
# l3 independent conntrack
-obj-$(CONFIG_NF_CONNTRACK_IPV6) += nf_conntrack_ipv6.o
+obj-$(CONFIG_NF_CONNTRACK_IPV6) += nf_conntrack_ipv6.o nf_defrag_ipv6.o
# matches
obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index ff43461..c8af58b 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -16,7 +16,6 @@
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/icmp.h>
-#include <linux/sysctl.h>
#include <net/ipv6.h>
#include <net/inet_frag.h>
@@ -29,6 +28,7 @@
#include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/nf_conntrack_zones.h>
#include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
+#include <net/netfilter/ipv6/nf_defrag_ipv6.h>
#include <net/netfilter/nf_log.h>
static bool ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
@@ -189,53 +189,6 @@ out:
return nf_conntrack_confirm(skb);
}
-static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum,
- struct sk_buff *skb)
-{
- u16 zone = NF_CT_DEFAULT_ZONE;
-
- if (skb->nfct)
- zone = nf_ct_zone((struct nf_conn *)skb->nfct);
-
-#ifdef CONFIG_BRIDGE_NETFILTER
- if (skb->nf_bridge &&
- skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)
- return IP6_DEFRAG_CONNTRACK_BRIDGE_IN + zone;
-#endif
- if (hooknum == NF_INET_PRE_ROUTING)
- return IP6_DEFRAG_CONNTRACK_IN + zone;
- else
- return IP6_DEFRAG_CONNTRACK_OUT + zone;
-
-}
-
-static unsigned int ipv6_defrag(unsigned int hooknum,
- struct sk_buff *skb,
- const struct net_device *in,
- const struct net_device *out,
- int (*okfn)(struct sk_buff *))
-{
- struct sk_buff *reasm;
-
- /* Previously seen (loopback)? */
- if (skb->nfct && !nf_ct_is_template((struct nf_conn *)skb->nfct))
- return NF_ACCEPT;
-
- reasm = nf_ct_frag6_gather(skb, nf_ct6_defrag_user(hooknum, skb));
- /* queued */
- if (reasm == NULL)
- return NF_STOLEN;
-
- /* error occured or not fragmented */
- if (reasm == skb)
- return NF_ACCEPT;
-
- nf_ct_frag6_output(hooknum, reasm, (struct net_device *)in,
- (struct net_device *)out, okfn);
-
- return NF_STOLEN;
-}
-
static unsigned int __ipv6_conntrack_in(struct net *net,
unsigned int hooknum,
struct sk_buff *skb,
@@ -288,13 +241,6 @@ static unsigned int ipv6_conntrack_local(unsigned int hooknum,
static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = {
{
- .hook = ipv6_defrag,
- .owner = THIS_MODULE,
- .pf = NFPROTO_IPV6,
- .hooknum = NF_INET_PRE_ROUTING,
- .priority = NF_IP6_PRI_CONNTRACK_DEFRAG,
- },
- {
.hook = ipv6_conntrack_in,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6,
@@ -309,13 +255,6 @@ static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = {
.priority = NF_IP6_PRI_CONNTRACK,
},
{
- .hook = ipv6_defrag,
- .owner = THIS_MODULE,
- .pf = NFPROTO_IPV6,
- .hooknum = NF_INET_LOCAL_OUT,
- .priority = NF_IP6_PRI_CONNTRACK_DEFRAG,
- },
- {
.hook = ipv6_confirm,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6,
@@ -387,10 +326,6 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 __read_mostly = {
.nlattr_to_tuple = ipv6_nlattr_to_tuple,
.nla_policy = ipv6_nla_policy,
#endif
-#ifdef CONFIG_SYSCTL
- .ctl_table_path = nf_net_netfilter_sysctl_path,
- .ctl_table = nf_ct_ipv6_sysctl_table,
-#endif
.me = THIS_MODULE,
};
@@ -403,16 +338,12 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
int ret = 0;
need_conntrack();
+ nf_defrag_ipv6_enable();
- ret = nf_ct_frag6_init();
- if (ret < 0) {
- pr_err("nf_conntrack_ipv6: can't initialize frag6.\n");
- return ret;
- }
ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_tcp6);
if (ret < 0) {
pr_err("nf_conntrack_ipv6: can't register tcp.\n");
- goto cleanup_frag6;
+ return ret;
}
ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udp6);
@@ -450,8 +381,6 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp6);
cleanup_tcp:
nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp6);
- cleanup_frag6:
- nf_ct_frag6_cleanup();
return ret;
}
@@ -463,7 +392,6 @@ static void __exit nf_conntrack_l3proto_ipv6_fini(void)
nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmpv6);
nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp6);
nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp6);
- nf_ct_frag6_cleanup();
}
module_init(nf_conntrack_l3proto_ipv6_init);
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 138a8b3..489d71b 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -73,7 +73,7 @@ static struct inet_frags nf_frags;
static struct netns_frags nf_init_frags;
#ifdef CONFIG_SYSCTL
-struct ctl_table nf_ct_ipv6_sysctl_table[] = {
+struct ctl_table nf_ct_frag6_sysctl_table[] = {
{
.procname = "nf_conntrack_frag6_timeout",
.data = &nf_init_frags.timeout,
@@ -97,6 +97,8 @@ struct ctl_table nf_ct_ipv6_sysctl_table[] = {
},
{ }
};
+
+static struct ctl_table_header *nf_ct_frag6_sysctl_header;
#endif
static unsigned int nf_hashfn(struct inet_frag_queue *q)
@@ -623,11 +625,21 @@ int nf_ct_frag6_init(void)
inet_frags_init_net(&nf_init_frags);
inet_frags_init(&nf_frags);
+ nf_ct_frag6_sysctl_header = register_sysctl_paths(nf_net_netfilter_sysctl_path,
+ nf_ct_frag6_sysctl_table);
+ if (!nf_ct_frag6_sysctl_header) {
+ inet_frags_fini(&nf_frags);
+ return -ENOMEM;
+ }
+
return 0;
}
void nf_ct_frag6_cleanup(void)
{
+ unregister_sysctl_table(nf_ct_frag6_sysctl_header);
+ nf_ct_frag6_sysctl_header = NULL;
+
inet_frags_fini(&nf_frags);
nf_init_frags.low_thresh = 0;
diff --git a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
new file mode 100644
index 0000000..99abfb5
--- /dev/null
+++ b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
@@ -0,0 +1,131 @@
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/types.h>
+#include <linux/ipv6.h>
+#include <linux/in6.h>
+#include <linux/netfilter.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/icmp.h>
+#include <linux/sysctl.h>
+#include <net/ipv6.h>
+#include <net/inet_frag.h>
+
+#include <linux/netfilter_ipv6.h>
+#include <linux/netfilter_bridge.h>
+#include <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_conntrack_helper.h>
+#include <net/netfilter/nf_conntrack_l4proto.h>
+#include <net/netfilter/nf_conntrack_l3proto.h>
+#include <net/netfilter/nf_conntrack_core.h>
+#include <net/netfilter/nf_conntrack_zones.h>
+#include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
+#include <net/netfilter/ipv6/nf_defrag_ipv6.h>
+
+static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum,
+ struct sk_buff *skb)
+{
+ u16 zone = NF_CT_DEFAULT_ZONE;
+
+ if (skb->nfct)
+ zone = nf_ct_zone((struct nf_conn *)skb->nfct);
+
+#ifdef CONFIG_BRIDGE_NETFILTER
+ if (skb->nf_bridge &&
+ skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)
+ return IP6_DEFRAG_CONNTRACK_BRIDGE_IN + zone;
+#endif
+ if (hooknum == NF_INET_PRE_ROUTING)
+ return IP6_DEFRAG_CONNTRACK_IN + zone;
+ else
+ return IP6_DEFRAG_CONNTRACK_OUT + zone;
+
+}
+
+static unsigned int ipv6_defrag(unsigned int hooknum,
+ struct sk_buff *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ struct sk_buff *reasm;
+
+ /* Previously seen (loopback)? */
+ if (skb->nfct && !nf_ct_is_template((struct nf_conn *)skb->nfct))
+ return NF_ACCEPT;
+
+ reasm = nf_ct_frag6_gather(skb, nf_ct6_defrag_user(hooknum, skb));
+ /* queued */
+ if (reasm == NULL)
+ return NF_STOLEN;
+
+ /* error occured or not fragmented */
+ if (reasm == skb)
+ return NF_ACCEPT;
+
+ nf_ct_frag6_output(hooknum, reasm, (struct net_device *)in,
+ (struct net_device *)out, okfn);
+
+ return NF_STOLEN;
+}
+
+static struct nf_hook_ops ipv6_defrag_ops[] = {
+ {
+ .hook = ipv6_defrag,
+ .owner = THIS_MODULE,
+ .pf = NFPROTO_IPV6,
+ .hooknum = NF_INET_PRE_ROUTING,
+ .priority = NF_IP6_PRI_CONNTRACK_DEFRAG,
+ },
+ {
+ .hook = ipv6_defrag,
+ .owner = THIS_MODULE,
+ .pf = NFPROTO_IPV6,
+ .hooknum = NF_INET_LOCAL_OUT,
+ .priority = NF_IP6_PRI_CONNTRACK_DEFRAG,
+ },
+};
+
+static int __init nf_defrag_init(void)
+{
+ int ret = 0;
+
+ ret = nf_ct_frag6_init();
+ if (ret < 0) {
+ pr_err("nf_defrag_ipv6: can't initialize frag6.\n");
+ return ret;
+ }
+ ret = nf_register_hooks(ipv6_defrag_ops, ARRAY_SIZE(ipv6_defrag_ops));
+ if (ret < 0) {
+ pr_err("nf_defrag_ipv6: can't register hooks\n");
+ goto cleanup_frag6;
+ }
+ return ret;
+
+cleanup_frag6:
+ nf_ct_frag6_cleanup();
+ return ret;
+
+}
+
+static void __exit nf_defrag_fini(void)
+{
+ nf_unregister_hooks(ipv6_defrag_ops, ARRAY_SIZE(ipv6_defrag_ops));
+ nf_ct_frag6_cleanup();
+}
+
+void nf_defrag_ipv6_enable(void)
+{
+}
+EXPORT_SYMBOL_GPL(nf_defrag_ipv6_enable);
+
+module_init(nf_defrag_init);
+module_exit(nf_defrag_fini);
+
+MODULE_LICENSE("GPL");
^ permalink raw reply related
* Re: [RFC PATCH 5/9] ipvs network name space aware
From: Hans Schillstrom @ 2010-10-21 11:42 UTC (permalink / raw)
To: Simon Horman
Cc: lvs-devel@vger.kernel.org, netdev@vger.kernel.org,
netfilter-devel@vger.kernel.org, ja@ssi.bg, wensong@linux-vs.org,
daniel.lezcano@free.fr
In-Reply-To: <20101021111644.GA25555@verge.net.au>
On Thursday 21 October 2010 13:16:47 Simon Horman wrote:
> On Fri, Oct 08, 2010 at 01:17:02PM +0200, Hans Schillstrom wrote:
> > This patch just contains ip_vs_ctl
> >
> > Signed-off-by:Hans Schillstrom <hans.schillstrom@ericsson.com>
> >
> > diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
> > index ca8ec8c..7e99cbc 100644
> > --- a/net/netfilter/ipvs/ip_vs_ctl.c
> > +++ b/net/netfilter/ipvs/ip_vs_ctl.c
>
> [ snip ]
>
> > @@ -2680,10 +2664,15 @@ static int ip_vs_genl_dump_services(struct sk_buff *skb,
> > int idx = 0, i;
> > int start = cb->args[0];
> > struct ip_vs_service *svc;
> > -
> > + struct net *net = skb->sk->sk_net;
>
> skb->sk->sk_net needs CONFIG_NS_NET.
> Is your plan for IPVS to unconditionally depend on CONFIG_NS_NET?
No.
> It would be nice to avoid that, but I fear it will be too messy.
Crap, I missed that.
I think a couple of inlines in ip_vs.h can do the job like;
static inline struct net * ipvs_sknet(struct sock *sk)
{
#ifdef CONFIG_NS_NET
return sk->sk_net;
#else
return init_net;
#endif
}
static inline struct net * ipvs_devnet(struct skb *skb)
{
#ifdef CONFIG_NS_NET
return dev_net(skb->dev);
#else
return init_net;
#endif
}
and use it like this
struct net *net = ipvs_sknet(skb->sk);
> > + struct netns_ipvs *ipvs;
> > + if (!net)
> > + net = dev_net(dev_net(skb->dev););
net = ipvs_devnet(skb->dev);
> > + BUG_ON(!net);
> > + ipvs = net->ipvs;
> > mutex_lock(&__ip_vs_mutex);
> > for (i = 0; i < IP_VS_SVC_TAB_SIZE; i++) {
> > - list_for_each_entry(svc, &ip_vs_svc_table[i], s_list) {
> > + list_for_each_entry(svc, &ipvs->ctl_svc_table[i], s_list) {
> > if (++idx <= start)
> > continue;
> > if (ip_vs_genl_dump_service(skb, svc, cb) < 0) {
>
> [ snip ]
> --
--
Regards
Hans Schillstrom <hans.schillstrom@ericsson.com>
^ permalink raw reply
* Re: [PATCH] l2tp: small cleanup
From: David Miller @ 2010-10-21 11:39 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev
In-Reply-To: <1287660971.6871.97.camel@edumazet-laptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 21 Oct 2010 13:36:11 +0200
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Applied.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox