* Re: [PATCH net] net/sched: cls_flower: Set egress_dev mark when calling into the HW driver
From: Jiri Pirko @ 2017-10-16 12:41 UTC (permalink / raw)
To: Or Gerlitz; +Cc: David S. Miller, Jiri Pirko, netdev, mlxsw, Roi Dayan
In-Reply-To: <1508145588-29959-1-git-send-email-ogerlitz@mellanox.com>
Mon, Oct 16, 2017 at 11:19:48AM CEST, ogerlitz@mellanox.com wrote:
>Commit 7091d8c '(net/sched: cls_flower: Add offload support using egress
>Hardware device') made sure (when fl_hw_replace_filter is called) to put
>the egress_dev mark on persisent structure instance. Hence, following calls
>into the HW driver for stats and deletion will note it and act accordingly.
>
>With commit de4784ca030f this property is lost and hence when called,
>the HW driver failes to operate (stats, delete) on the offloaded flow.
>
>Fix it by setting the egress_dev flag whenever the ingress device is
>different from the hw device since this is exactly the condition under
>which we're calling into the HW driver through the egress port net-device.
>
>Fixes: de4784ca030f ('net: sched: get rid of struct tc_to_netdev')
>Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
>Signed-off-by: Roi Dayan <roid@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
^ permalink raw reply
* Re: [PATCH net-next] dsa: slave: support phy devices on external MII bus
From: Martin Hundebøll @ 2017-10-16 12:48 UTC (permalink / raw)
To: Andrew Lunn; +Cc: David S . Miller, netdev, Vivien Didelot, Florian Fainelli
In-Reply-To: <20171016124002.GE4255@lunn.ch>
[-- Attachment #1: Type: text/plain, Size: 1045 bytes --]
Hi Andrew,
On 2017-10-16 14:40, Andrew Lunn wrote:
>> /* internal MII */
>> mdio {
>> switch0phy1@1 {
>> reg = <1>;
>> };
>> };
>>
>> /* external MII */
>> mdio1 {
>> switch0phy0: switch0phy0@0 {
>> reg = <0>;
>> };
>
> Hi Martin
>
> You are missing a compatible string here. The binding document says:
>
> - mdio? : Container of PHYs and devices on the external MDIO
> bus. The node must contains a compatible string of
> "marvell,mv88e6xxx-mdio-external"
>
> Andrew
>
Yeah, I have it in my full dts file (attached snippet), but decided to
limit the commit-message version to keep it short(er). Should I update
the commit message to avoid confusing others?
The issue is really that dsa_slave_phy_connect() always uses the the
mdio bus associated with struct dsa_switch, even when the phy-handle
refers to a phy from another mdio bus.
Or am I missing something ?
// Martin
[-- Attachment #2: armada-388-gp.dts --]
[-- Type: audio/vnd.dts, Size: 2311 bytes --]
^ permalink raw reply
* Re: [PATCH net-next] dsa: slave: support phy devices on external MII bus
From: Martin Hundebøll @ 2017-10-16 12:56 UTC (permalink / raw)
To: Andrew Lunn; +Cc: David S . Miller, netdev, Vivien Didelot, Florian Fainelli
In-Reply-To: <20171016123233.GD4255@lunn.ch>
On 2017-10-16 14:32, Andrew Lunn wrote:
> On Mon, Oct 16, 2017 at 12:45:25PM +0200, Martin Hundebøll wrote:
>> When configuring a switch port to use an external phy, the phy is
>> connected to external switch MII bus:
>
> So this is a 6390?
6390X
> So this used to work. I have a 10G phy connected to the external MII
> bus on a 6390. I wonder when this got broken? Supporting phy-handle is
> old code, so when i added the external MII i don't think i needed to
> change any generic code.
I had debug printing verifying that the external phy got registered with
mdiobus_register_device(), and that dsa_slave_phy_connect() looked in
the wrong mdio_map[].
// Martin
^ permalink raw reply
* Re: [PATCH v3 1/2] dt-bindings: add device tree binding for Allwinner XR819 SDIO Wi-Fi
From: Kalle Valo @ 2017-10-16 12:58 UTC (permalink / raw)
To: icenowy-h8G6r0blFSE
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Arend van Spriel,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Rob Herring, Maxime Ripard,
Chen-Yu Tsai, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <dba5f095f9f25f0726ee3a2852e01b88-h8G6r0blFSE@public.gmane.org>
icenowy-h8G6r0blFSE@public.gmane.org writes:
>>>>> > > Like I asked already last time, AFAICS there is no upstream xr819
>>>>> > > wireless driver in drivers/net/wireless directory. Do we still
>>>> accept
>>>>> > > bindings like this for out-of-tree drivers?
>>>>> >
>>>>> > See esp8089.
>>>>> >
>>>>> > There's also no in-tree driver for it.
>>>>>
>>>>> The question is whether we should. The above might be a precedent,
>>>> but it
>>>>> may not necessarily be the way to go. The commit message for esp8089
>>>> seems
>>>>> to hint that there is intent to have an in-tree driver:
>>>>>
>>>>> """
>>>>> Note that at this point there only is an out of tree driver for
>>>> this
>>>>> hardware, there is no clear timeline / path for merging this.
>>>> Still
>>>>> I believe it would be good to specify the binding for this in
>>>> tree
>>>>> now, so that any future migration to an in tree driver will not
>>>> cause
>>>>> compatiblity issues.
>>>>>
>>>>> Cc: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
>>>>> Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
>>>>> Signed-off-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>>>>> """
>>>>>
>>>>> Regardless the bindings are in principle independent of the kernel
>>>> and just
>>>>> describing hardware. I think there have been discussions to move the
>>>>> bindings to their own repository, but apparently it was decided
>>>> otherwise.
>>>>
>>>> Yeah, I guess especially how it could be merged with the cw1200
>>>> driver
>>>> would be very relevant to that commit log.
>>>
>>> The cw1200 driver seems to still have some legacy platform
>>> data. Maybe they should also be convert to DT.
>>> (Or maybe compatible = "allwinner,xr819" is enough, as
>>> xr819 is a specified variant of cw1200 family)
>>
>> Ah, so the upstream cw1200 driver supports xr819? Has anyone tested
>> that? Or does cw1200 more changes than just adding the DT support?
>
> The support of XR819 in CW1200 driver is far more difficult than I
> imagined -- the codedrop used in the mainlined CW1200 driver seems to
> be so old that it's before XR819 (which seems to be based on CW1160),
> and there's a large number of problems to adapt it to a modern CW1200
> variant.
>
> P.S. could you apply this device tree binding patch now?
As I haven't seen any consensus that applying bindings document for
out-of-tree drivers is ok so at least I'm not taking this. Though not
sure what DT maintainers are planning to do.
--
Kalle Valo
^ permalink raw reply
* RE: [PATCH net-next 00/10] korina cleanups/optimizations
From: David Laight @ 2017-10-16 12:59 UTC (permalink / raw)
To: 'Roman Yeryomin', netdev
In-Reply-To: <20171015162226.606-1-roman@advem.lv>
From: Roman Yeryomin
> Sent: 15 October 2017 17:22
> TX optimizations have led to ~15% performance increase (35->40Mbps)
> in local tx usecase (tested with iperf v3.2).
Indicate which patches give the improvement.
IIRC some just changed the source without changing what the code really did.
(Not a problem in itself.)
...
> net: korina: optimize tx/rx interrupt handlers
You'd probably get a noticeable improvement from caching the
value of the interrupt mask - instead of reading it from the hardware.
...
David
^ permalink raw reply
* Re: [PATCH net-next] dsa: slave: support phy devices on external MII bus
From: Martin Hundebøll @ 2017-10-16 13:16 UTC (permalink / raw)
To: Andrew Lunn; +Cc: David S . Miller, netdev, Vivien Didelot, Florian Fainelli
In-Reply-To: <20171016123233.GD4255@lunn.ch>
On 2017-10-16 14:32, Andrew Lunn wrote:
> So this used to work. I have a 10G phy connected to the external MII
> bus on a 6390. I wonder when this got broken? Supporting phy-handle is
> old code, so when i added the external MII i don't think i needed to
> change any generic code.
It could look like commit cd28a1a9baee7 ('net: dsa: fully divert PHY
reads/writes if requested') changed the of-case to use the mdio bus
associated with struct dsa_switch unconditionally.
// Martin
^ permalink raw reply
* [PATCH] xen-netfront, xen-netback: Use correct minimum MTU values
From: Mohammed Gamal @ 2017-10-16 13:20 UTC (permalink / raw)
To: netdev, xen-devel, paul.durrant, wei.liu2
Cc: linux-kernel, vkuznets, otubo, cavery, cheshi, Mohammed Gamal
RFC791 specifies the minimum MTU to be 68, while xen-net{front|back}
drivers use a minimum value of 0.
When set MTU to 0~67 with xen_net{front|back} driver, the network
will become unreachable immediately, the guest can no longer be pinged.
xen_net{front|back} should not allow the user to set this value which causes
network problems.
Reported-by: Chen Shi <cheshi@redhat.com>
Signed-off-by: Mohammed Gamal <mgamal@redhat.com>
---
drivers/net/xen-netback/interface.c | 2 +-
drivers/net/xen-netfront.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
index ee8ed9da..4491ca5 100644
--- a/drivers/net/xen-netback/interface.c
+++ b/drivers/net/xen-netback/interface.c
@@ -486,7 +486,7 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid,
dev->tx_queue_len = XENVIF_QUEUE_LENGTH;
- dev->min_mtu = 0;
+ dev->min_mtu = ETH_MIN_MTU;
dev->max_mtu = ETH_MAX_MTU - VLAN_ETH_HLEN;
/*
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 523387e..8b8689c 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -1316,7 +1316,7 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev)
netdev->features |= netdev->hw_features;
netdev->ethtool_ops = &xennet_ethtool_ops;
- netdev->min_mtu = 0;
+ netdev->min_mtu = ETH_MIN_MTU;
netdev->max_mtu = XEN_NETIF_MAX_TX_SIZE;
SET_NETDEV_DEV(netdev, &dev->dev);
--
1.8.3.1
^ permalink raw reply related
* RE: [net-next 6/9] e1000e: fix buffer overrun while the I219 is processing DMA transactions
From: David Laight @ 2017-10-16 13:27 UTC (permalink / raw)
To: 'Neftin, Sasha', 'Jeff Kirsher',
davem@davemloft.net
Cc: netdev@vger.kernel.org, nhorman@redhat.com, sassmann@redhat.com,
jogreene@redhat.com
In-Reply-To: <2c60b0c2-b257-fa86-c1c8-c8aa1fd40908@intel.com>
From: Neftin, Sasha
> Sent: 16 October 2017 11:40
> On 10/11/2017 12:07, David Laight wrote:
> > From: Jeff Kirsher
> >> Sent: 10 October 2017 18:22
> >> Intel 100/200 Series Chipset platforms reduced the round-trip
> >> latency for the LAN Controller DMA accesses, causing in some high
> >> performance cases a buffer overrun while the I219 LAN Connected
> >> Device is processing the DMA transactions. I219LM and I219V devices
> >> can fall into unrecovered Tx hang under very stressfully UDP traffic
> >> and multiple reconnection of Ethernet cable. This Tx hang of the LAN
> >> Controller is only recovered if the system is rebooted. Slightly slow
> >> down DMA access by reducing the number of outstanding requests.
> >> This workaround could have an impact on TCP traffic performance
> >> on the platform. Disabling TSO eliminates performance loss for TCP
> >> traffic without a noticeable impact on CPU performance.
> >>
> >> Please, refer to I218/I219 specification update:
> >> https://www.intel.com/content/www/us/en/embedded/products/networking/
> >> ethernet-connection-i218-family-documentation.html
> >>
> >> Signed-off-by: Sasha Neftin <sasha.neftin@intel.com>
> >> Reviewed-by: Dima Ruinskiy <dima.ruinskiy@intel.com>
> >> Reviewed-by: Raanan Avargil <raanan.avargil@intel.com>
> >> Tested-by: Aaron Brown <aaron.f.brown@intel.com>
> >> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> >> ---
> >> drivers/net/ethernet/intel/e1000e/netdev.c | 8 +++++---
> >> 1 file changed, 5 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c
> b/drivers/net/ethernet/intel/e1000e/netdev.c
> >> index ee9de3500331..14b096f3d1da 100644
> >> --- a/drivers/net/ethernet/intel/e1000e/netdev.c
> >> +++ b/drivers/net/ethernet/intel/e1000e/netdev.c
> >> @@ -3021,8 +3021,8 @@ static void e1000_configure_tx(struct e1000_adapter *adapter)
> >>
> >> hw->mac.ops.config_collision_dist(hw);
> >>
> >> - /* SPT and CNP Si errata workaround to avoid data corruption */
> >> - if (hw->mac.type >= e1000_pch_spt) {
> >> + /* SPT and KBL Si errata workaround to avoid data corruption */
> >> + if (hw->mac.type == e1000_pch_spt) {
> >> u32 reg_val;
> >>
> >> reg_val = er32(IOSFPC);
> >> @@ -3030,7 +3030,9 @@ static void e1000_configure_tx(struct e1000_adapter *adapter)
> >> ew32(IOSFPC, reg_val);
> >>
> >> reg_val = er32(TARC(0));
> >> - reg_val |= E1000_TARC0_CB_MULTIQ_3_REQ;
> >> + /* SPT and KBL Si errata workaround to avoid Tx hang */
> >> + reg_val &= ~BIT(28);
> >> + reg_val |= BIT(29);
> > Shouldn't some more of the commit message about what this is doing
> > be in the comment?
> There is provided link on specification update:
> https://www.intel.com/content/dam/www/public/us/en/documents/specification-updates/i218-i219-ethernet-
> connection-spec-update.pdf?asset=9561.
> This is Intel's public release.
And sometime next week the marketing people will decide to reorganise the
web site and the link will become invalid.
> > And shouldn't the 28 and 28 be named constants?
> (28 and 29) - you can easy understand from code that same value has been
> changed from 3 to 2. There is no point add flag here I thought.
Oh, there is. The 'workaround is':
Slightly slow down DMA access by reducing the number of outstanding requests.
This workaround could have an impact on TCP traffic performance and could
reduce performance up to 5 to 15% (depending) on the platform.
Disabling TSO eliminates performance loss for TCP traffic without a
noticeable impact on CPU performance.
I wonder what tests they did to show that TSO doesn't save cpu cycles!
So my guess is that you are changing the number of outstanding PCIe reads
(or reads for tx buffers, or ???) from 3 to 2.
Lets read between the lines a little further
(since you are at Intel you can probably check this):
Assuming that TSO is 'Transmit Segmentation Offload' and that TSO packets
might be 64k, then reading 3 TSO packets might issue PCIe reads for 196k
bytes of data (under 4k for non-TSO).
If the internal buffer that this data is stored in isn't that big then
that internal buffer would overflow.
It might be that data is removed from this buffer as soon as the last
completion TLP arrives - but they can be interleaved with other
outstanding PCIe reads.
It all rather depends on the negotiated maximum TLP size and number
of tags.
Perhaps reducing the maximum TSO packet to 32k stops the overflow
as well...
David
^ permalink raw reply
* [PATCH] tcp: cdg: make struct tcp_cdg static
From: Colin King @ 2017-10-16 13:33 UTC (permalink / raw)
To: David S . Miller, Alexey Kuznetsov, Hideaki YOSHIFUJI, netdev
Cc: kernel-janitors, linux-kernel
From: Colin Ian King <colin.king@canonical.com>
The structure tcp_cdg is local to the source and
does not need to be in global scope, so make it static.
Cleans up sparse warning:
symbol 'tcp_cdg' was not declared. Should it be static?
Signed-off-by: Colin Ian King <colin.king@canonical.com>
---
net/ipv4/tcp_cdg.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/ipv4/tcp_cdg.c b/net/ipv4/tcp_cdg.c
index 66ac69f7bd19..06fbe102a425 100644
--- a/net/ipv4/tcp_cdg.c
+++ b/net/ipv4/tcp_cdg.c
@@ -389,7 +389,7 @@ static void tcp_cdg_release(struct sock *sk)
kfree(ca->gradients);
}
-struct tcp_congestion_ops tcp_cdg __read_mostly = {
+static struct tcp_congestion_ops tcp_cdg __read_mostly = {
.cong_avoid = tcp_cdg_cong_avoid,
.cwnd_event = tcp_cdg_cwnd_event,
.pkts_acked = tcp_cdg_acked,
--
2.14.1
^ permalink raw reply related
* Re: Kernel Performance Tuning for High Volume SCTP traffic
From: Neil Horman @ 2017-10-16 13:34 UTC (permalink / raw)
To: Traiano Welcome
Cc: David Laight, linux-sctp@vger.kernel.org, netdev@vger.kernel.org
In-Reply-To: <CAFKCRVKScoF+AkBtsgGiFogN3KQP704v8Us9-OABy2BS-w4EVA@mail.gmail.com>
On Sat, Oct 14, 2017 at 10:29:53PM +0800, Traiano Welcome wrote:
> I've upped the value of the following sctp and udp related parameters,
> in the hope that this would help:
>
> sysctl -w net.core.rmem_max=900000000
> sysctl -w net.core.wmem_max=900000000
>
> sysctl -w net.sctp.sctp_mem="2100000000 2100000000 2100000000"
> sysctl -w net.sctp.sctp_rmem="2100000000 2100000000 2100000000"
> sysctl -w net.sctp.sctp_wmem="2100000000 2100000000 2100000000"
>
> sysctl -w net.ipv4.udp_mem="5000000000 5000000000 5000000000"
> sysctl -w net.ipv4.udp_mem="10000000000 10000000000 10000000000"
>
> However, I'm still seeing rapidly incrementing rx discards reported on the NIC:
>
> :~# ethtool -S ens4f1 | egrep -i rx_discards
> [0]: rx_discards: 6390805462
> [1]: rx_discards: 6659315919
> [2]: rx_discards: 6542570026
> [3]: rx_discards: 6431513008
> [4]: rx_discards: 6436779078
> [5]: rx_discards: 6665897051
> [6]: rx_discards: 6167985560
> [7]: rx_discards: 11340068788
> rx_discards: 56634934892
>
If you're getting drops in the hardware and nothing in the higher layers is
overflowing, then your problem is likely due to one of two things:
1) The NIC is discarding frames for reasons orthogonal to provisioning. That is
to say you are getting a large number of frames in that are being purposely
discarded. Check the other stats for the nic in ethtool to try give you some
additional visibilty on what these frames might be.
2) You're not servicing the NIC fast enough to pull frames out prior to its
internal buffer overflowing. Check the interrupt mitigation and flow
director/ntuple settings to make sure that you're seeing proper spreading of
packets to per-cpu queues, that interrupt mitigation is preventing undue cpu
load, and that irqbalance is properly distributing that interrupt rate to all
cpus in the system
Neil
> Despite the fact that I've set the NIC ring buffer on the Netextreme
> interface to he maximum:
>
> :~# ethtool -g ens4f0
> Ring parameters for ens4f0:
> Pre-set maximums:
> RX: 4078
> RX Mini: 0
> RX Jumbo: 0
> TX: 4078
> Current hardware settings:
> RX: 4078
> RX Mini: 0
> RX Jumbo: 0
> TX: 4078
>
> I see no ip errors at the physical interface:
>
> ethtool -S ens4f0 | egrep phy_ip_err_discard| tail -1
> rx_phy_ip_err_discards: 0
>
>
> Could anyone suggest alternative approaches I might take to optimising
> the system's handling of SCTP traffic?
>
>
>
> On Sat, Oct 14, 2017 at 12:35 AM, David Laight <David.Laight@aculab.com> wrote:
> > From: Traiano Welcome
> >> Sent: 13 October 2017 17:04
> >> On Fri, Oct 13, 2017 at 11:56 PM, David Laight <David.Laight@aculab.com> wrote:
> >> > From: Traiano Welcome
> >> >
> >> > (copied to netdev)
> >> >> Sent: 13 October 2017 07:16
> >> >> To: linux-sctp@vger.kernel.org
> >> >> Subject: Kernel Performance Tuning for High Volume SCTP traffic
> >> >>
> >> >> Hi List
> >> >>
> >> >> I'm running a linux server processing high volumes of SCTP traffic and
> >> >> am seeing large numbers of packet overruns (ifconfig output).
> >> >
> >> > I'd guess that overruns indicate that the ethernet MAC is failing to
> >> > copy the receive frames into kernel memory.
> >> > It is probably running out of receive buffers, but might be
> >> > suffering from a lack of bus bandwidth.
> >> > MAC drivers usually discard receive frames if they can't get
> >> > a replacement buffer - so you shouldn't run out of rx buffers.
> >> >
> >> > This means the errors are probably below SCTP - so changing SCTP parameters
> >> > is unlikely to help.
> >>
> >> Does this mean that tuning UDP performance could help ? Or do you mean
> >> hardware (NIC) performance could be the issue?
> >
> > I'd certainly check UDP performance.
> >
> > David
> >
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sctp" 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] dsa: slave: support phy devices on external MII bus
From: Andrew Lunn @ 2017-10-16 13:39 UTC (permalink / raw)
To: Martin Hundebøll
Cc: David S . Miller, netdev, Vivien Didelot, Florian Fainelli
In-Reply-To: <02997de6-1c8a-d69b-d19b-3a811288e8ed@prevas.dk>
On Mon, Oct 16, 2017 at 03:16:51PM +0200, Martin Hundebøll wrote:
> On 2017-10-16 14:32, Andrew Lunn wrote:
> >So this used to work. I have a 10G phy connected to the external MII
> >bus on a 6390. I wonder when this got broken? Supporting phy-handle is
> >old code, so when i added the external MII i don't think i needed to
> >change any generic code.
>
> It could look like commit cd28a1a9baee7 ('net: dsa: fully divert PHY
> reads/writes if requested') changed the of-case to use the mdio bus
> associated with struct dsa_switch unconditionally.
Hi Martin
I think ds->phys_mii_mask is playing a role here. I need to add some
debug prints to my setup and see what is happening with my external
10G PHY.
This phy code is just too complex :-(
Andrew
^ permalink raw reply
* [PATCH] sunrcp: make function _svc_create_xprt static
From: Colin King @ 2017-10-16 13:40 UTC (permalink / raw)
To: J . Bruce Fields, Jeff Layton, Trond Myklebust, Anna Schumaker,
David S . Miller, linux-nfs, netdev
Cc: kernel-janitors, linux-kernel
From: Colin Ian King <colin.king@canonical.com>
The function _svc_create_xprt is local to the source and
does not need to be in global scope, so make it static.
Cleans up sparse warning:
symbol '_svc_create_xprt' was not declared. Should it be static?
Signed-off-by: Colin Ian King <colin.king@canonical.com>
---
net/sunrpc/svc_xprt.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index d16a8b423c20..18e87791350f 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -250,9 +250,9 @@ void svc_add_new_perm_xprt(struct svc_serv *serv, struct svc_xprt *new)
svc_xprt_received(new);
}
-int _svc_create_xprt(struct svc_serv *serv, const char *xprt_name,
- struct net *net, const int family,
- const unsigned short port, int flags)
+static int _svc_create_xprt(struct svc_serv *serv, const char *xprt_name,
+ struct net *net, const int family,
+ const unsigned short port, int flags)
{
struct svc_xprt_class *xcl;
--
2.14.1
^ permalink raw reply related
* [PATCH net-next 0/2] net: core: rcuify rtnl af_ops
From: Florian Westphal @ 2017-10-16 13:44 UTC (permalink / raw)
To: netdev
None of the rtnl af_ops callbacks sleep, so they can be called while
holding rcu read lock.
Switch handling of af_ops to rcu.
This would allow to later call af_ops functions without holding
the rtnl mutex anymore.
core/rtnetlink.c | 134 ++++++++++++++++++++++++++++++++++++-------------------
ipv4/devinet.c | 4 -
2 files changed, 90 insertions(+), 48 deletions(-)
^ permalink raw reply
* [PATCH net-next 1/2] rtnetlink: place link af dump into own helper
From: Florian Westphal @ 2017-10-16 13:44 UTC (permalink / raw)
To: netdev; +Cc: Florian Westphal
In-Reply-To: <20171016134436.25282-1-fw@strlen.de>
next patch will rcu-ify rtnl af_ops, i.e. allow af_ops
lookup and function calls with rcu read lock held instead
of rtnl mutex.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
net/core/rtnetlink.c | 72 ++++++++++++++++++++++++++++++----------------------
1 file changed, 42 insertions(+), 30 deletions(-)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 6a09f3d575af..a49cad25e577 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1382,6 +1382,47 @@ static int rtnl_fill_link_netnsid(struct sk_buff *skb,
return 0;
}
+static int rtnl_fill_link_af(struct sk_buff *skb,
+ const struct net_device *dev,
+ u32 ext_filter_mask)
+{
+ const struct rtnl_af_ops *af_ops;
+ struct nlattr *af_spec;
+
+ af_spec = nla_nest_start(skb, IFLA_AF_SPEC);
+ if (!af_spec)
+ return -EMSGSIZE;
+
+ list_for_each_entry(af_ops, &rtnl_af_ops, list) {
+ struct nlattr *af;
+ int err;
+
+ if (!af_ops->fill_link_af)
+ continue;
+
+ af = nla_nest_start(skb, af_ops->family);
+ if (!af)
+ return -EMSGSIZE;
+
+ err = af_ops->fill_link_af(skb, dev, ext_filter_mask);
+ /*
+ * Caller may return ENODATA to indicate that there
+ * was no data to be dumped. This is not an error, it
+ * means we should trim the attribute header and
+ * continue.
+ */
+ if (err == -ENODATA)
+ nla_nest_cancel(skb, af);
+ else if (err < 0)
+ return -EMSGSIZE;
+
+ nla_nest_end(skb, af);
+ }
+
+ nla_nest_end(skb, af_spec);
+ return 0;
+}
+
static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
int type, u32 pid, u32 seq, u32 change,
unsigned int flags, u32 ext_filter_mask,
@@ -1389,8 +1430,6 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
{
struct ifinfomsg *ifm;
struct nlmsghdr *nlh;
- struct nlattr *af_spec;
- struct rtnl_af_ops *af_ops;
ASSERT_RTNL();
nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags);
@@ -1477,36 +1516,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
nla_put_s32(skb, IFLA_NEW_NETNSID, *new_nsid) < 0)
goto nla_put_failure;
- if (!(af_spec = nla_nest_start(skb, IFLA_AF_SPEC)))
+ if (rtnl_fill_link_af(skb, dev, ext_filter_mask))
goto nla_put_failure;
- list_for_each_entry(af_ops, &rtnl_af_ops, list) {
- if (af_ops->fill_link_af) {
- struct nlattr *af;
- int err;
-
- if (!(af = nla_nest_start(skb, af_ops->family)))
- goto nla_put_failure;
-
- err = af_ops->fill_link_af(skb, dev, ext_filter_mask);
-
- /*
- * Caller may return ENODATA to indicate that there
- * was no data to be dumped. This is not an error, it
- * means we should trim the attribute header and
- * continue.
- */
- if (err == -ENODATA)
- nla_nest_cancel(skb, af);
- else if (err < 0)
- goto nla_put_failure;
-
- nla_nest_end(skb, af);
- }
- }
-
- nla_nest_end(skb, af_spec);
-
nlmsg_end(skb, nlh);
return 0;
--
2.13.6
^ permalink raw reply related
* [PATCH net-next 2/2] net: core: rcu-ify rtnl af_ops
From: Florian Westphal @ 2017-10-16 13:44 UTC (permalink / raw)
To: netdev; +Cc: Florian Westphal
In-Reply-To: <20171016134436.25282-1-fw@strlen.de>
rtnl af_ops currently rely on rtnl mutex: unregister (called from module
exit functions) takes the rtnl mutex and all users that do af_ops lookup
also take the rtnl mutex. IOW, parallel rmmod will block until doit()
callback is done.
As none of the af_ops implementation sleep we can use rcu instead.
doit functions that need the af_ops can now use rcu instead of the
rtnl mutex provided the mutex isn't needed for other reasons.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
net/core/rtnetlink.c | 62 ++++++++++++++++++++++++++++++++++++++--------------
net/ipv4/devinet.c | 4 ++--
2 files changed, 48 insertions(+), 18 deletions(-)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index a49cad25e577..20b550d07fe3 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -453,7 +453,7 @@ static const struct rtnl_af_ops *rtnl_af_lookup(const int family)
{
const struct rtnl_af_ops *ops;
- list_for_each_entry(ops, &rtnl_af_ops, list) {
+ list_for_each_entry_rcu(ops, &rtnl_af_ops, list) {
if (ops->family == family)
return ops;
}
@@ -470,7 +470,7 @@ static const struct rtnl_af_ops *rtnl_af_lookup(const int family)
void rtnl_af_register(struct rtnl_af_ops *ops)
{
rtnl_lock();
- list_add_tail(&ops->list, &rtnl_af_ops);
+ list_add_tail_rcu(&ops->list, &rtnl_af_ops);
rtnl_unlock();
}
EXPORT_SYMBOL_GPL(rtnl_af_register);
@@ -482,8 +482,10 @@ EXPORT_SYMBOL_GPL(rtnl_af_register);
void rtnl_af_unregister(struct rtnl_af_ops *ops)
{
rtnl_lock();
- list_del(&ops->list);
+ list_del_rcu(&ops->list);
rtnl_unlock();
+
+ synchronize_rcu();
}
EXPORT_SYMBOL_GPL(rtnl_af_unregister);
@@ -496,13 +498,15 @@ static size_t rtnl_link_get_af_size(const struct net_device *dev,
/* IFLA_AF_SPEC */
size = nla_total_size(sizeof(struct nlattr));
- list_for_each_entry(af_ops, &rtnl_af_ops, list) {
+ rcu_read_lock();
+ list_for_each_entry_rcu(af_ops, &rtnl_af_ops, list) {
if (af_ops->get_link_af_size) {
/* AF_* + nested data */
size += nla_total_size(sizeof(struct nlattr)) +
af_ops->get_link_af_size(dev, ext_filter_mask);
}
}
+ rcu_read_unlock();
return size;
}
@@ -1393,7 +1397,7 @@ static int rtnl_fill_link_af(struct sk_buff *skb,
if (!af_spec)
return -EMSGSIZE;
- list_for_each_entry(af_ops, &rtnl_af_ops, list) {
+ list_for_each_entry_rcu(af_ops, &rtnl_af_ops, list) {
struct nlattr *af;
int err;
@@ -1516,12 +1520,16 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
nla_put_s32(skb, IFLA_NEW_NETNSID, *new_nsid) < 0)
goto nla_put_failure;
+ rcu_read_lock();
if (rtnl_fill_link_af(skb, dev, ext_filter_mask))
- goto nla_put_failure;
+ goto nla_put_failure_rcu;
+ rcu_read_unlock();
nlmsg_end(skb, nlh);
return 0;
+nla_put_failure_rcu:
+ rcu_read_unlock();
nla_put_failure:
nlmsg_cancel(skb, nlh);
return -EMSGSIZE;
@@ -1783,17 +1791,27 @@ static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[])
nla_for_each_nested(af, tb[IFLA_AF_SPEC], rem) {
const struct rtnl_af_ops *af_ops;
- if (!(af_ops = rtnl_af_lookup(nla_type(af))))
+ rcu_read_lock();
+ af_ops = rtnl_af_lookup(nla_type(af));
+ if (!af_ops) {
+ rcu_read_unlock();
return -EAFNOSUPPORT;
+ }
- if (!af_ops->set_link_af)
+ if (!af_ops->set_link_af) {
+ rcu_read_unlock();
return -EOPNOTSUPP;
+ }
if (af_ops->validate_link_af) {
err = af_ops->validate_link_af(dev, af);
- if (err < 0)
+ if (err < 0) {
+ rcu_read_unlock();
return err;
+ }
}
+
+ rcu_read_unlock();
}
}
@@ -2251,13 +2269,18 @@ static int do_setlink(const struct sk_buff *skb,
nla_for_each_nested(af, tb[IFLA_AF_SPEC], rem) {
const struct rtnl_af_ops *af_ops;
+ rcu_read_lock();
+
if (!(af_ops = rtnl_af_lookup(nla_type(af))))
BUG();
err = af_ops->set_link_af(dev, af);
- if (err < 0)
+ if (err < 0) {
+ rcu_read_unlock();
goto errout;
+ }
+ rcu_read_unlock();
status |= DO_SETLINK_NOTIFY;
}
}
@@ -4004,25 +4027,30 @@ static int rtnl_fill_statsinfo(struct sk_buff *skb, struct net_device *dev,
if (!attr)
goto nla_put_failure;
- list_for_each_entry(af_ops, &rtnl_af_ops, list) {
+ rcu_read_lock();
+ list_for_each_entry_rcu(af_ops, &rtnl_af_ops, list) {
if (af_ops->fill_stats_af) {
struct nlattr *af;
int err;
af = nla_nest_start(skb, af_ops->family);
- if (!af)
+ if (!af) {
+ rcu_read_unlock();
goto nla_put_failure;
-
+ }
err = af_ops->fill_stats_af(skb, dev);
- if (err == -ENODATA)
+ if (err == -ENODATA) {
nla_nest_cancel(skb, af);
- else if (err < 0)
+ } else if (err < 0) {
+ rcu_read_unlock();
goto nla_put_failure;
+ }
nla_nest_end(skb, af);
}
}
+ rcu_read_unlock();
nla_nest_end(skb, attr);
@@ -4091,7 +4119,8 @@ static size_t if_nlmsg_stats_size(const struct net_device *dev,
/* for IFLA_STATS_AF_SPEC */
size += nla_total_size(0);
- list_for_each_entry(af_ops, &rtnl_af_ops, list) {
+ rcu_read_lock();
+ list_for_each_entry_rcu(af_ops, &rtnl_af_ops, list) {
if (af_ops->get_stats_af_size) {
size += nla_total_size(
af_ops->get_stats_af_size(dev));
@@ -4100,6 +4129,7 @@ static size_t if_nlmsg_stats_size(const struct net_device *dev,
size += nla_total_size(0);
}
}
+ rcu_read_unlock();
}
return size;
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 7ce22a2c07ce..6d9b072d903b 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1757,7 +1757,7 @@ static int inet_validate_link_af(const struct net_device *dev,
struct nlattr *a, *tb[IFLA_INET_MAX+1];
int err, rem;
- if (dev && !__in_dev_get_rtnl(dev))
+ if (dev && !__in_dev_get_rcu(dev))
return -EAFNOSUPPORT;
err = nla_parse_nested(tb, IFLA_INET_MAX, nla, inet_af_policy, NULL);
@@ -1781,7 +1781,7 @@ static int inet_validate_link_af(const struct net_device *dev,
static int inet_set_link_af(struct net_device *dev, const struct nlattr *nla)
{
- struct in_device *in_dev = __in_dev_get_rtnl(dev);
+ struct in_device *in_dev = __in_dev_get_rcu(dev);
struct nlattr *a, *tb[IFLA_INET_MAX+1];
int rem;
--
2.13.6
^ permalink raw reply related
* pull-request: mac80211 2017-10-16
From: Johannes Berg @ 2017-10-16 13:46 UTC (permalink / raw)
To: David Miller
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
linux-wireless-u79uwXL29TY76Z2rM5mHXA
Hi Dave,
Here's a fix, for a small part of the "KRACK" announced today
(krackattacks.com).
Please pull and let me know if there's any problem.
Thanks,
johannes
The following changes since commit c0576e3975084d4699b7bfef578613fb8e1144f6:
net: call cgroup_sk_alloc() earlier in sk_clone_lock() (2017-10-10 20:24:29 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git tags/mac80211-for-davem-2017-10-16
for you to fetch changes up to fdf7cb4185b60c68e1a75e61691c4afdc15dea0e:
mac80211: accept key reinstall without changing anything (2017-10-16 13:02:03 +0200)
----------------------------------------------------------------
Just a single fix, for a WoWLAN-related part of CVE-2017-13080.
----------------------------------------------------------------
Johannes Berg (1):
mac80211: accept key reinstall without changing anything
net/mac80211/key.c | 21 +++++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)
^ permalink raw reply
* [PATCH net-next v12] openvswitch: enable NSH support
From: Yi Yang @ 2017-10-16 13:53 UTC (permalink / raw)
To: netdev; +Cc: dev, jbenc, e, pshelar, davem, Yi Yang
v11->v12
- Fix missing changes old comments pointed out
- Fix new comments for v11
v10->v11
- Fix the left three disputable comments for v9
but not fixed in v10.
v9->v10
- Change struct ovs_key_nsh to
struct ovs_nsh_key_base base;
__be32 context[NSH_MD1_CONTEXT_SIZE];
- Fix new comments for v9
v8->v9
- Fix build error reported by daily intel build
because nsh module isn't selected by openvswitch
v7->v8
- Rework nested value and mask for OVS_KEY_ATTR_NSH
- Change pop_nsh to adapt to nsh kernel module
- Fix many issues per comments from Jiri Benc
v6->v7
- Remove NSH GSO patches in v6 because Jiri Benc
reworked it as another patch series and they have
been merged.
- Change it to adapt to nsh kernel module added by NSH
GSO patch series
v5->v6
- Fix the rest comments for v4.
- Add NSH GSO support for VxLAN-gpe + NSH and
Eth + NSH.
v4->v5
- Fix many comments by Jiri Benc and Eric Garver
for v4.
v3->v4
- Add new NSH match field ttl
- Update NSH header to the latest format
which will be final format and won't change
per its author's confirmation.
- Fix comments for v3.
v2->v3
- Change OVS_KEY_ATTR_NSH to nested key to handle
length-fixed attributes and length-variable
attriubte more flexibly.
- Remove struct ovs_action_push_nsh completely
- Add code to handle nested attribute for SET_MASKED
- Change PUSH_NSH to use the nested OVS_KEY_ATTR_NSH
to transfer NSH header data.
- Fix comments and coding style issues by Jiri and Eric
v1->v2
- Change encap_nsh and decap_nsh to push_nsh and pop_nsh
- Dynamically allocate struct ovs_action_push_nsh for
length-variable metadata.
OVS master and 2.8 branch has merged NSH userspace
patch series, this patch is to enable NSH support
in kernel data path in order that OVS can support
NSH in compat mode by porting this.
Signed-off-by: Yi Yang <yi.y.yang@intel.com>
---
include/net/nsh.h | 3 +
include/uapi/linux/openvswitch.h | 29 ++++
net/nsh/nsh.c | 61 ++++++++
net/openvswitch/Kconfig | 1 +
net/openvswitch/actions.c | 119 +++++++++++++++
net/openvswitch/flow.c | 51 +++++++
net/openvswitch/flow.h | 7 +
net/openvswitch/flow_netlink.c | 310 ++++++++++++++++++++++++++++++++++++++-
net/openvswitch/flow_netlink.h | 5 +
9 files changed, 585 insertions(+), 1 deletion(-)
diff --git a/include/net/nsh.h b/include/net/nsh.h
index a1eaea2..7dcf377 100644
--- a/include/net/nsh.h
+++ b/include/net/nsh.h
@@ -304,4 +304,7 @@ static inline void nsh_set_flags_ttl_len(struct nshhdr *nsh, u8 flags,
NSH_FLAGS_MASK | NSH_TTL_MASK | NSH_LEN_MASK);
}
+int skb_push_nsh(struct sk_buff *skb, const struct nshhdr *pushed_nh);
+int skb_pop_nsh(struct sk_buff *skb);
+
#endif /* __NET_NSH_H */
diff --git a/include/uapi/linux/openvswitch.h b/include/uapi/linux/openvswitch.h
index 0cd6f88..ac2623b 100644
--- a/include/uapi/linux/openvswitch.h
+++ b/include/uapi/linux/openvswitch.h
@@ -333,6 +333,7 @@ enum ovs_key_attr {
OVS_KEY_ATTR_CT_LABELS, /* 16-octet connection tracking label */
OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4, /* struct ovs_key_ct_tuple_ipv4 */
OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6, /* struct ovs_key_ct_tuple_ipv6 */
+ OVS_KEY_ATTR_NSH, /* Nested set of ovs_nsh_key_* */
#ifdef __KERNEL__
OVS_KEY_ATTR_TUNNEL_INFO, /* struct ip_tunnel_info */
@@ -492,6 +493,30 @@ struct ovs_key_ct_tuple_ipv6 {
__u8 ipv6_proto;
};
+enum ovs_nsh_key_attr {
+ OVS_NSH_KEY_ATTR_UNSPEC,
+ OVS_NSH_KEY_ATTR_BASE, /* struct ovs_nsh_key_base. */
+ OVS_NSH_KEY_ATTR_MD1, /* struct ovs_nsh_key_md1. */
+ OVS_NSH_KEY_ATTR_MD2, /* variable-length octets for MD type 2. */
+ __OVS_NSH_KEY_ATTR_MAX
+};
+
+#define OVS_NSH_KEY_ATTR_MAX (__OVS_NSH_KEY_ATTR_MAX - 1)
+
+struct ovs_nsh_key_base {
+ __u8 flags;
+ __u8 ttl;
+ __u8 mdtype;
+ __u8 np;
+ __be32 path_hdr;
+};
+
+#define NSH_MD1_CONTEXT_SIZE 4
+
+struct ovs_nsh_key_md1 {
+ __be32 context[NSH_MD1_CONTEXT_SIZE];
+};
+
/**
* enum ovs_flow_attr - attributes for %OVS_FLOW_* commands.
* @OVS_FLOW_ATTR_KEY: Nested %OVS_KEY_ATTR_* attributes specifying the flow
@@ -808,6 +833,8 @@ struct ovs_action_push_eth {
* @OVS_ACTION_ATTR_POP_ETH: Pop the outermost Ethernet header off the
* packet.
* @OVS_ACTION_ATTR_CT_CLEAR: Clear conntrack state from the packet.
+ * @OVS_ACTION_ATTR_PUSH_NSH: push NSH header to the packet.
+ * @OVS_ACTION_ATTR_POP_NSH: pop the outermost NSH header off the packet.
*
* Only a single header can be set with a single %OVS_ACTION_ATTR_SET. Not all
* fields within a header are modifiable, e.g. the IPv4 protocol and fragment
@@ -838,6 +865,8 @@ enum ovs_action_attr {
OVS_ACTION_ATTR_PUSH_ETH, /* struct ovs_action_push_eth. */
OVS_ACTION_ATTR_POP_ETH, /* No argument. */
OVS_ACTION_ATTR_CT_CLEAR, /* No argument. */
+ OVS_ACTION_ATTR_PUSH_NSH, /* Nested OVS_NSH_KEY_ATTR_*. */
+ OVS_ACTION_ATTR_POP_NSH, /* No argument. */
__OVS_ACTION_ATTR_MAX, /* Nothing past this will be accepted
* from userspace. */
diff --git a/net/nsh/nsh.c b/net/nsh/nsh.c
index 58fb827..229a0f8 100644
--- a/net/nsh/nsh.c
+++ b/net/nsh/nsh.c
@@ -14,6 +14,67 @@
#include <net/nsh.h>
#include <net/tun_proto.h>
+int skb_push_nsh(struct sk_buff *skb, const struct nshhdr *pushed_nh)
+{
+ struct nshhdr *nh;
+ size_t length = nsh_hdr_len(pushed_nh);
+ u8 next_proto;
+
+ if (skb->mac_len) {
+ next_proto = TUN_P_ETHERNET;
+ } else {
+ next_proto = tun_p_from_eth_p(skb->protocol);
+ if (!next_proto)
+ return -EAFNOSUPPORT;
+ }
+
+ /* Add the NSH header */
+ if (skb_cow_head(skb, length) < 0)
+ return -ENOMEM;
+
+ skb_push(skb, length);
+ nh = (struct nshhdr *)(skb->data);
+ memcpy(nh, pushed_nh, length);
+ nh->np = next_proto;
+
+ skb->protocol = htons(ETH_P_NSH);
+ skb_reset_mac_header(skb);
+ skb_reset_network_header(skb);
+ skb_reset_mac_len(skb);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(skb_push_nsh);
+
+int skb_pop_nsh(struct sk_buff *skb)
+{
+ struct nshhdr *nh;
+ size_t length;
+ __be16 inner_proto;
+
+ if (!pskb_may_pull(skb, NSH_BASE_HDR_LEN))
+ return -ENOMEM;
+ nh = (struct nshhdr *)(skb->data);
+ length = nsh_hdr_len(nh);
+ if (!pskb_may_pull(skb, length))
+ return -ENOMEM;
+
+ nh = (struct nshhdr *)(skb->data);
+ inner_proto = tun_p_to_eth_p(nh->np);
+ if (!inner_proto)
+ return -EAFNOSUPPORT;
+
+ length = nsh_hdr_len(nh);
+ skb_pull(skb, length);
+ skb_reset_mac_header(skb);
+ skb_reset_network_header(skb);
+ skb_reset_mac_len(skb);
+ skb->protocol = inner_proto;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(skb_pop_nsh);
+
static struct sk_buff *nsh_gso_segment(struct sk_buff *skb,
netdev_features_t features)
{
diff --git a/net/openvswitch/Kconfig b/net/openvswitch/Kconfig
index ce94729..2650205 100644
--- a/net/openvswitch/Kconfig
+++ b/net/openvswitch/Kconfig
@@ -14,6 +14,7 @@ config OPENVSWITCH
select MPLS
select NET_MPLS_GSO
select DST_CACHE
+ select NET_NSH
---help---
Open vSwitch is a multilayer Ethernet switch targeted at virtualized
environments. In addition to supporting a variety of features
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
index a551232..1ab3c51 100644
--- a/net/openvswitch/actions.c
+++ b/net/openvswitch/actions.c
@@ -43,6 +43,7 @@
#include "flow.h"
#include "conntrack.h"
#include "vport.h"
+#include "flow_netlink.h"
struct deferred_action {
struct sk_buff *skb;
@@ -380,6 +381,43 @@ static int push_eth(struct sk_buff *skb, struct sw_flow_key *key,
return 0;
}
+static int push_nsh(struct sk_buff *skb, struct sw_flow_key *key,
+ const struct nshhdr *nh)
+{
+ int err;
+
+ err = skb_push_nsh(skb, nh);
+ if (err)
+ return err;
+
+ /* safe right before invalidate_flow_key */
+ key->mac_proto = MAC_PROTO_NONE;
+ invalidate_flow_key(key);
+ return 0;
+}
+
+static int pop_nsh(struct sk_buff *skb, struct sw_flow_key *key)
+{
+ int err;
+
+ if (ovs_key_mac_proto(key) != MAC_PROTO_NONE ||
+ skb->protocol != htons(ETH_P_NSH)) {
+ return -EINVAL;
+ }
+
+ err = skb_pop_nsh(skb);
+ if (err)
+ return err;
+
+ /* safe right before invalidate_flow_key */
+ if (skb->protocol == htons(ETH_P_TEB))
+ key->mac_proto = MAC_PROTO_ETHERNET;
+ else
+ key->mac_proto = MAC_PROTO_NONE;
+ invalidate_flow_key(key);
+ return 0;
+}
+
static void update_ip_l4_checksum(struct sk_buff *skb, struct iphdr *nh,
__be32 addr, __be32 new_addr)
{
@@ -602,6 +640,69 @@ static int set_ipv6(struct sk_buff *skb, struct sw_flow_key *flow_key,
return 0;
}
+static int set_nsh(struct sk_buff *skb, struct sw_flow_key *flow_key,
+ const struct nlattr *a)
+{
+ struct nshhdr *nh;
+ size_t length;
+ int err;
+ u8 flags;
+ u8 ttl;
+ int i;
+
+ struct ovs_key_nsh key;
+ struct ovs_key_nsh mask;
+
+ err = nsh_key_from_nlattr(a, &key, &mask);
+ if (err)
+ return err;
+
+ /* Make sure the NSH base header is there */
+ err = skb_ensure_writable(skb, skb_network_offset(skb) +
+ NSH_BASE_HDR_LEN);
+ if (unlikely(err))
+ return err;
+
+ nh = nsh_hdr(skb);
+ length = nsh_hdr_len(nh);
+
+ /* Make sure the whole NSH header is there */
+ err = skb_ensure_writable(skb, skb_network_offset(skb) +
+ length);
+ if (unlikely(err))
+ return err;
+
+ nh = nsh_hdr(skb);
+ flags = nsh_get_flags(nh);
+ flags = OVS_MASKED(flags, key.base.flags, mask.base.flags);
+ flow_key->nsh.base.flags = flags;
+ ttl = nsh_get_ttl(nh);
+ ttl = OVS_MASKED(ttl, key.base.ttl, mask.base.ttl);
+ flow_key->nsh.base.ttl = ttl;
+ nsh_set_flags_and_ttl(nh, flags, ttl);
+ nh->path_hdr = OVS_MASKED(nh->path_hdr, key.base.path_hdr,
+ mask.base.path_hdr);
+ flow_key->nsh.base.path_hdr = nh->path_hdr;
+ switch (nh->mdtype) {
+ case NSH_M_TYPE1:
+ for (i = 0; i < NSH_MD1_CONTEXT_SIZE; i++) {
+ nh->md1.context[i] =
+ OVS_MASKED(nh->md1.context[i], key.context[i],
+ mask.context[i]);
+ }
+ memcpy(flow_key->nsh.context, nh->md1.context,
+ sizeof(nh->md1.context));
+ break;
+ case NSH_M_TYPE2:
+ memset(flow_key->nsh.context, 0,
+ sizeof(flow_key->nsh.context));
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
/* Must follow skb_ensure_writable() since that can move the skb data. */
static void set_tp_port(struct sk_buff *skb, __be16 *port,
__be16 new_port, __sum16 *check)
@@ -1024,6 +1125,10 @@ static int execute_masked_set_action(struct sk_buff *skb,
get_mask(a, struct ovs_key_ethernet *));
break;
+ case OVS_KEY_ATTR_NSH:
+ err = set_nsh(skb, flow_key, a);
+ break;
+
case OVS_KEY_ATTR_IPV4:
err = set_ipv4(skb, flow_key, nla_data(a),
get_mask(a, struct ovs_key_ipv4 *));
@@ -1214,6 +1319,20 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
case OVS_ACTION_ATTR_POP_ETH:
err = pop_eth(skb, key);
break;
+
+ case OVS_ACTION_ATTR_PUSH_NSH: {
+ u8 buffer[NSH_HDR_MAX_LEN];
+ struct nshhdr *nh = (struct nshhdr *)buffer;
+
+ nsh_hdr_from_nlattr(nla_data(a), nh,
+ NSH_HDR_MAX_LEN);
+ err = push_nsh(skb, key, nh);
+ break;
+ }
+
+ case OVS_ACTION_ATTR_POP_NSH:
+ err = pop_nsh(skb, key);
+ break;
}
if (unlikely(err)) {
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c
index 8c94cef..864ddb1 100644
--- a/net/openvswitch/flow.c
+++ b/net/openvswitch/flow.c
@@ -46,6 +46,7 @@
#include <net/ipv6.h>
#include <net/mpls.h>
#include <net/ndisc.h>
+#include <net/nsh.h>
#include "conntrack.h"
#include "datapath.h"
@@ -490,6 +491,52 @@ static int parse_icmpv6(struct sk_buff *skb, struct sw_flow_key *key,
return 0;
}
+static int parse_nsh(struct sk_buff *skb, struct sw_flow_key *key)
+{
+ struct nshhdr *nh;
+ unsigned int nh_ofs = skb_network_offset(skb);
+ u8 version, length;
+ int err;
+
+ err = check_header(skb, nh_ofs + NSH_BASE_HDR_LEN);
+ if (unlikely(err))
+ return err;
+
+ nh = nsh_hdr(skb);
+ version = nsh_get_ver(nh);
+ length = nsh_hdr_len(nh);
+
+ if (version != 0)
+ return -EINVAL;
+
+ err = check_header(skb, nh_ofs + length);
+ if (unlikely(err))
+ return err;
+
+ nh = nsh_hdr(skb);
+ key->nsh.base.flags = nsh_get_flags(nh);
+ key->nsh.base.ttl = nsh_get_ttl(nh);
+ key->nsh.base.mdtype = nh->mdtype;
+ key->nsh.base.np = nh->np;
+ key->nsh.base.path_hdr = nh->path_hdr;
+ switch (key->nsh.base.mdtype) {
+ case NSH_M_TYPE1:
+ if (length != NSH_M_TYPE1_LEN)
+ return -EINVAL;
+ memcpy(key->nsh.context, nh->md1.context,
+ sizeof(nh->md1));
+ break;
+ case NSH_M_TYPE2:
+ memset(key->nsh.context, 0,
+ sizeof(nh->md1));
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
/**
* key_extract - extracts a flow key from an Ethernet frame.
* @skb: sk_buff that contains the frame, with skb->data pointing to the
@@ -735,6 +782,10 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
memset(&key->tp, 0, sizeof(key->tp));
}
}
+ } else if (key->eth.type == htons(ETH_P_NSH)) {
+ error = parse_nsh(skb, key);
+ if (error)
+ return error;
}
return 0;
}
diff --git a/net/openvswitch/flow.h b/net/openvswitch/flow.h
index 1875bba..8eeae749 100644
--- a/net/openvswitch/flow.h
+++ b/net/openvswitch/flow.h
@@ -35,6 +35,7 @@
#include <net/inet_ecn.h>
#include <net/ip_tunnels.h>
#include <net/dst_metadata.h>
+#include <net/nsh.h>
struct sk_buff;
@@ -66,6 +67,11 @@ struct vlan_head {
(offsetof(struct sw_flow_key, recirc_id) + \
FIELD_SIZEOF(struct sw_flow_key, recirc_id))
+struct ovs_key_nsh {
+ struct ovs_nsh_key_base base;
+ __be32 context[NSH_MD1_CONTEXT_SIZE];
+};
+
struct sw_flow_key {
u8 tun_opts[IP_TUNNEL_OPTS_MAX];
u8 tun_opts_len;
@@ -144,6 +150,7 @@ struct sw_flow_key {
};
} ipv6;
};
+ struct ovs_key_nsh nsh; /* network service header */
struct {
/* Connection tracking fields not packed above. */
struct {
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
index dc0d790..bdbc239 100644
--- a/net/openvswitch/flow_netlink.c
+++ b/net/openvswitch/flow_netlink.c
@@ -48,6 +48,7 @@
#include <net/ndisc.h>
#include <net/mpls.h>
#include <net/vxlan.h>
+#include <net/tun_proto.h>
#include <net/erspan.h>
#include "flow_netlink.h"
@@ -80,9 +81,11 @@ static bool actions_may_change_flow(const struct nlattr *actions)
case OVS_ACTION_ATTR_HASH:
case OVS_ACTION_ATTR_POP_ETH:
case OVS_ACTION_ATTR_POP_MPLS:
+ case OVS_ACTION_ATTR_POP_NSH:
case OVS_ACTION_ATTR_POP_VLAN:
case OVS_ACTION_ATTR_PUSH_ETH:
case OVS_ACTION_ATTR_PUSH_MPLS:
+ case OVS_ACTION_ATTR_PUSH_NSH:
case OVS_ACTION_ATTR_PUSH_VLAN:
case OVS_ACTION_ATTR_SAMPLE:
case OVS_ACTION_ATTR_SET:
@@ -325,12 +328,27 @@ size_t ovs_tun_key_attr_size(void)
+ nla_total_size(4); /* OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS */
}
+size_t ovs_nsh_key_attr_size(void)
+{
+ /* Whenever adding new OVS_NSH_KEY_ FIELDS, we should consider
+ * updating this function.
+ */
+ return nla_total_size(NSH_BASE_HDR_LEN) /* OVS_NSH_KEY_ATTR_BASE */
+ /* OVS_NSH_KEY_ATTR_MD1 and OVS_NSH_KEY_ATTR_MD2 are
+ * mutually exclusive, so the bigger one can cover
+ * the small one.
+ *
+ * OVS_NSH_KEY_ATTR_MD2
+ */
+ + nla_total_size(NSH_CTX_HDRS_MAX_LEN);
+}
+
size_t ovs_key_attr_size(void)
{
/* Whenever adding new OVS_KEY_ FIELDS, we should consider
* updating this function.
*/
- BUILD_BUG_ON(OVS_KEY_ATTR_TUNNEL_INFO != 28);
+ BUILD_BUG_ON(OVS_KEY_ATTR_TUNNEL_INFO != 29);
return nla_total_size(4) /* OVS_KEY_ATTR_PRIORITY */
+ nla_total_size(0) /* OVS_KEY_ATTR_TUNNEL */
@@ -344,6 +362,8 @@ size_t ovs_key_attr_size(void)
+ nla_total_size(4) /* OVS_KEY_ATTR_CT_MARK */
+ nla_total_size(16) /* OVS_KEY_ATTR_CT_LABELS */
+ nla_total_size(40) /* OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6 */
+ + nla_total_size(0) /* OVS_KEY_ATTR_NSH */
+ + ovs_nsh_key_attr_size()
+ nla_total_size(12) /* OVS_KEY_ATTR_ETHERNET */
+ nla_total_size(2) /* OVS_KEY_ATTR_ETHERTYPE */
+ nla_total_size(4) /* OVS_KEY_ATTR_VLAN */
@@ -377,6 +397,13 @@ static const struct ovs_len_tbl ovs_tunnel_key_lens[OVS_TUNNEL_KEY_ATTR_MAX + 1]
[OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS] = { .len = sizeof(u32) },
};
+static const struct ovs_len_tbl
+ovs_nsh_key_attr_lens[OVS_NSH_KEY_ATTR_MAX + 1] = {
+ [OVS_NSH_KEY_ATTR_BASE] = { .len = sizeof(struct ovs_nsh_key_base) },
+ [OVS_NSH_KEY_ATTR_MD1] = { .len = sizeof(struct ovs_nsh_key_md1) },
+ [OVS_NSH_KEY_ATTR_MD2] = { .len = OVS_ATTR_VARIABLE },
+};
+
/* The size of the argument for each %OVS_KEY_ATTR_* Netlink attribute. */
static const struct ovs_len_tbl ovs_key_lens[OVS_KEY_ATTR_MAX + 1] = {
[OVS_KEY_ATTR_ENCAP] = { .len = OVS_ATTR_NESTED },
@@ -409,6 +436,8 @@ static const struct ovs_len_tbl ovs_key_lens[OVS_KEY_ATTR_MAX + 1] = {
.len = sizeof(struct ovs_key_ct_tuple_ipv4) },
[OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6] = {
.len = sizeof(struct ovs_key_ct_tuple_ipv6) },
+ [OVS_KEY_ATTR_NSH] = { .len = OVS_ATTR_NESTED,
+ .next = ovs_nsh_key_attr_lens, },
};
static bool check_attr_len(unsigned int attr_len, unsigned int expected_len)
@@ -1227,6 +1256,214 @@ static int metadata_from_nlattrs(struct net *net, struct sw_flow_match *match,
return 0;
}
+int nsh_hdr_from_nlattr(const struct nlattr *attr,
+ struct nshhdr *nh, size_t size)
+{
+ struct nlattr *a;
+ int rem;
+ u8 flags = 0;
+ u8 ttl = 0;
+ int mdlen = 0;
+
+ /* validate_nsh has check this, so we needn't do duplicate check here
+ */
+ nla_for_each_nested(a, attr, rem) {
+ int type = nla_type(a);
+
+ switch (type) {
+ case OVS_NSH_KEY_ATTR_BASE: {
+ const struct ovs_nsh_key_base *base = nla_data(a);
+
+ flags = base->flags;
+ ttl = base->ttl;
+ nh->np = base->np;
+ nh->mdtype = base->mdtype;
+ nh->path_hdr = base->path_hdr;
+ break;
+ }
+ case OVS_NSH_KEY_ATTR_MD1:
+ mdlen = nla_len(a);
+ memcpy(&nh->md1, nla_data(a), mdlen);
+ break;
+
+ case OVS_NSH_KEY_ATTR_MD2:
+ mdlen = nla_len(a);
+ memcpy(&nh->md2, nla_data(a), mdlen);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ }
+
+ /* nsh header length = NSH_BASE_HDR_LEN + mdlen */
+ nh->ver_flags_ttl_len = 0;
+ nsh_set_flags_ttl_len(nh, flags, ttl, NSH_BASE_HDR_LEN + mdlen);
+
+ return 0;
+}
+
+int nsh_key_from_nlattr(const struct nlattr *attr,
+ struct ovs_key_nsh *nsh, struct ovs_key_nsh *nsh_mask)
+{
+ struct nlattr *a;
+ int rem;
+
+ /* validate_nsh has check this, so we needn't do duplicate check here
+ */
+ nla_for_each_nested(a, attr, rem) {
+ int type = nla_type(a);
+
+ switch (type) {
+ case OVS_NSH_KEY_ATTR_BASE: {
+ const struct ovs_nsh_key_base *base = nla_data(a);
+ const struct ovs_nsh_key_base *base_mask = base + 1;
+
+ nsh->base = *base;
+ nsh_mask->base = *base_mask;
+ break;
+ }
+ case OVS_NSH_KEY_ATTR_MD1: {
+ const struct ovs_nsh_key_md1 *md1 = nla_data(a);
+ const struct ovs_nsh_key_md1 *md1_mask = md1 + 1;
+
+ memcpy(nsh->context, md1->context, sizeof(*md1));
+ memcpy(nsh_mask->context, md1_mask->context,
+ sizeof(*md1_mask));
+ break;
+ }
+ case OVS_NSH_KEY_ATTR_MD2:
+ /* Not supported yet */
+ return -ENOTSUPP;
+ default:
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+static int nsh_key_put_from_nlattr(const struct nlattr *attr,
+ struct sw_flow_match *match, bool is_mask,
+ bool is_push_nsh, bool log)
+{
+ struct nlattr *a;
+ int rem;
+ bool has_base = false;
+ bool has_md1 = false;
+ bool has_md2 = false;
+ u8 mdtype = 0;
+ int mdlen = 0;
+
+ if (WARN_ON(is_push_nsh && is_mask))
+ return -EINVAL;
+
+ nla_for_each_nested(a, attr, rem) {
+ int type = nla_type(a);
+ int i;
+
+ if (type > OVS_NSH_KEY_ATTR_MAX) {
+ OVS_NLERR(log, "nsh attr %d is out of range max %d",
+ type, OVS_NSH_KEY_ATTR_MAX);
+ return -EINVAL;
+ }
+
+ if (!check_attr_len(nla_len(a),
+ ovs_nsh_key_attr_lens[type].len)) {
+ OVS_NLERR(
+ log,
+ "nsh attr %d has unexpected len %d expected %d",
+ type,
+ nla_len(a),
+ ovs_nsh_key_attr_lens[type].len
+ );
+ return -EINVAL;
+ }
+
+ switch (type) {
+ case OVS_NSH_KEY_ATTR_BASE: {
+ const struct ovs_nsh_key_base *base = nla_data(a);
+
+ has_base = true;
+ mdtype = base->mdtype;
+ SW_FLOW_KEY_PUT(match, nsh.base.flags,
+ base->flags, is_mask);
+ SW_FLOW_KEY_PUT(match, nsh.base.ttl,
+ base->ttl, is_mask);
+ SW_FLOW_KEY_PUT(match, nsh.base.mdtype,
+ base->mdtype, is_mask);
+ SW_FLOW_KEY_PUT(match, nsh.base.np,
+ base->np, is_mask);
+ SW_FLOW_KEY_PUT(match, nsh.base.path_hdr,
+ base->path_hdr, is_mask);
+ break;
+ }
+ case OVS_NSH_KEY_ATTR_MD1: {
+ const struct ovs_nsh_key_md1 *md1 = nla_data(a);
+
+ has_md1 = true;
+ for (i = 0; i < NSH_MD1_CONTEXT_SIZE; i++)
+ SW_FLOW_KEY_PUT(match, nsh.context[i],
+ md1->context[i], is_mask);
+ break;
+ }
+ case OVS_NSH_KEY_ATTR_MD2:
+ if (!is_push_nsh) /* Not supported MD type 2 yet */
+ return -ENOTSUPP;
+
+ has_md2 = true;
+ mdlen = nla_len(a);
+ if (mdlen > NSH_CTX_HDRS_MAX_LEN || mdlen <= 0) {
+ OVS_NLERR(
+ log,
+ "Invalid MD length %d for MD type %d",
+ mdlen,
+ mdtype
+ );
+ return -EINVAL;
+ }
+ break;
+ default:
+ OVS_NLERR(log, "Unknown nsh attribute %d",
+ type);
+ return -EINVAL;
+ }
+ }
+
+ if (rem > 0) {
+ OVS_NLERR(log, "nsh attribute has %d unknown bytes.", rem);
+ return -EINVAL;
+ }
+
+ if (has_md1 && has_md2) {
+ OVS_NLERR(
+ 1,
+ "invalid nsh attribute: md1 and md2 are exclusive."
+ );
+ return -EINVAL;
+ }
+
+ if (!is_mask) {
+ if ((has_md1 && mdtype != NSH_M_TYPE1) ||
+ (has_md2 && mdtype != NSH_M_TYPE2)) {
+ OVS_NLERR(1, "nsh attribute has unmatched MD type %d.",
+ mdtype);
+ return -EINVAL;
+ }
+
+ if (is_push_nsh &&
+ (!has_base || (!has_md1 && !has_md2))) {
+ OVS_NLERR(
+ 1,
+ "push_nsh: missing base or metadata attributes"
+ );
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
static int ovs_key_from_nlattrs(struct net *net, struct sw_flow_match *match,
u64 attrs, const struct nlattr **a,
bool is_mask, bool log)
@@ -1354,6 +1591,13 @@ static int ovs_key_from_nlattrs(struct net *net, struct sw_flow_match *match,
attrs &= ~(1 << OVS_KEY_ATTR_ARP);
}
+ if (attrs & (1 << OVS_KEY_ATTR_NSH)) {
+ if (nsh_key_put_from_nlattr(a[OVS_KEY_ATTR_NSH], match,
+ is_mask, false, log) < 0)
+ return -EINVAL;
+ attrs &= ~(1 << OVS_KEY_ATTR_NSH);
+ }
+
if (attrs & (1 << OVS_KEY_ATTR_MPLS)) {
const struct ovs_key_mpls *mpls_key;
@@ -1670,6 +1914,34 @@ static int ovs_nla_put_vlan(struct sk_buff *skb, const struct vlan_head *vh,
return 0;
}
+static int nsh_key_to_nlattr(const struct ovs_key_nsh *nsh, bool is_mask,
+ struct sk_buff *skb)
+{
+ struct nlattr *start;
+
+ start = nla_nest_start(skb, OVS_KEY_ATTR_NSH);
+ if (!start)
+ return -EMSGSIZE;
+
+ if (nla_put(skb, OVS_NSH_KEY_ATTR_BASE, sizeof(nsh->base), &nsh->base))
+ goto nla_put_failure;
+
+ if (is_mask || nsh->base.mdtype == NSH_M_TYPE1) {
+ if (nla_put(skb, OVS_NSH_KEY_ATTR_MD1,
+ sizeof(nsh->context), nsh->context))
+ goto nla_put_failure;
+ }
+
+ /* Don't support MD type 2 yet */
+
+ nla_nest_end(skb, start);
+
+ return 0;
+
+nla_put_failure:
+ return -EMSGSIZE;
+}
+
static int __ovs_nla_put_key(const struct sw_flow_key *swkey,
const struct sw_flow_key *output, bool is_mask,
struct sk_buff *skb)
@@ -1798,6 +2070,9 @@ static int __ovs_nla_put_key(const struct sw_flow_key *swkey,
ipv6_key->ipv6_tclass = output->ip.tos;
ipv6_key->ipv6_hlimit = output->ip.ttl;
ipv6_key->ipv6_frag = output->ip.frag;
+ } else if (swkey->eth.type == htons(ETH_P_NSH)) {
+ if (nsh_key_to_nlattr(&output->nsh, is_mask, skb))
+ goto nla_put_failure;
} else if (swkey->eth.type == htons(ETH_P_ARP) ||
swkey->eth.type == htons(ETH_P_RARP)) {
struct ovs_key_arp *arp_key;
@@ -2292,6 +2567,19 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
return err;
}
+static bool validate_nsh(const struct nlattr *attr, bool is_mask,
+ bool is_push_nsh, bool log)
+{
+ struct sw_flow_match match;
+ struct sw_flow_key key;
+ int ret = 0;
+
+ ovs_match_init(&match, &key, true, NULL);
+ ret = nsh_key_put_from_nlattr(attr, &match, is_mask,
+ is_push_nsh, log);
+ return !ret;
+}
+
/* Return false if there are any non-masked bits set.
* Mask follows data immediately, before any netlink padding.
*/
@@ -2434,6 +2722,11 @@ static int validate_set(const struct nlattr *a,
break;
+ case OVS_KEY_ATTR_NSH:
+ if (!validate_nsh(nla_data(a), masked, false, log))
+ return -EINVAL;
+ break;
+
default:
return -EINVAL;
}
@@ -2533,6 +2826,8 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
[OVS_ACTION_ATTR_TRUNC] = sizeof(struct ovs_action_trunc),
[OVS_ACTION_ATTR_PUSH_ETH] = sizeof(struct ovs_action_push_eth),
[OVS_ACTION_ATTR_POP_ETH] = 0,
+ [OVS_ACTION_ATTR_PUSH_NSH] = (u32)-1,
+ [OVS_ACTION_ATTR_POP_NSH] = 0,
};
const struct ovs_action_push_vlan *vlan;
int type = nla_type(a);
@@ -2690,6 +2985,19 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
mac_proto = MAC_PROTO_ETHERNET;
break;
+ case OVS_ACTION_ATTR_PUSH_NSH:
+ mac_proto = MAC_PROTO_NONE;
+ if (!validate_nsh(nla_data(a), false, true, true))
+ return -EINVAL;
+ break;
+
+ case OVS_ACTION_ATTR_POP_NSH:
+ if (key->nsh.base.np == TUN_P_ETHERNET)
+ mac_proto = MAC_PROTO_ETHERNET;
+ else
+ mac_proto = MAC_PROTO_NONE;
+ break;
+
default:
OVS_NLERR(log, "Unknown Action type %d", type);
return -EINVAL;
diff --git a/net/openvswitch/flow_netlink.h b/net/openvswitch/flow_netlink.h
index 929c665..6657606 100644
--- a/net/openvswitch/flow_netlink.h
+++ b/net/openvswitch/flow_netlink.h
@@ -79,4 +79,9 @@ int ovs_nla_put_actions(const struct nlattr *attr,
void ovs_nla_free_flow_actions(struct sw_flow_actions *);
void ovs_nla_free_flow_actions_rcu(struct sw_flow_actions *);
+int nsh_key_from_nlattr(const struct nlattr *attr, struct ovs_key_nsh *nsh,
+ struct ovs_key_nsh *nsh_mask);
+int nsh_hdr_from_nlattr(const struct nlattr *attr, struct nshhdr *nh,
+ size_t size);
+
#endif /* flow_netlink.h */
--
2.5.5
^ permalink raw reply related
* [net-next 1/1] tipc: fix rebasing error
From: Jon Maloy @ 2017-10-16 14:04 UTC (permalink / raw)
To: davem, netdev; +Cc: parthasarathy.bhuvaragan, ying.xue, tipc-discussion
In commit 2f487712b893 ("tipc: guarantee that group broadcast doesn't
bypass group unicast") there was introduced a last-minute rebasing
error that broke non-group communication.
We fix this here.
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/tipc/link.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 723dd69..870b9b8 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -1052,6 +1052,7 @@ static bool tipc_data_input(struct tipc_link *l, struct sk_buff *skb,
return true;
}
case CONN_MANAGER:
+ skb_queue_tail(inputq, skb);
return true;
case GROUP_PROTOCOL:
skb_queue_tail(mc_inputq, skb);
--
2.1.4
^ permalink raw reply related
* Re: [PATCH] sunrcp: make function _svc_create_xprt static
From: Jeff Layton @ 2017-10-16 14:09 UTC (permalink / raw)
To: Colin King, J . Bruce Fields, Trond Myklebust, Anna Schumaker,
David S . Miller, linux-nfs, netdev
Cc: kernel-janitors, linux-kernel
In-Reply-To: <20171016134021.15702-1-colin.king@canonical.com>
On Mon, 2017-10-16 at 14:40 +0100, Colin King wrote:
> From: Colin Ian King <colin.king@canonical.com>
>
> The function _svc_create_xprt is local to the source and
> does not need to be in global scope, so make it static.
>
> Cleans up sparse warning:
> symbol '_svc_create_xprt' was not declared. Should it be static?
>
> Signed-off-by: Colin Ian King <colin.king@canonical.com>
> ---
> net/sunrpc/svc_xprt.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
> index d16a8b423c20..18e87791350f 100644
> --- a/net/sunrpc/svc_xprt.c
> +++ b/net/sunrpc/svc_xprt.c
> @@ -250,9 +250,9 @@ void svc_add_new_perm_xprt(struct svc_serv *serv, struct svc_xprt *new)
> svc_xprt_received(new);
> }
>
> -int _svc_create_xprt(struct svc_serv *serv, const char *xprt_name,
> - struct net *net, const int family,
> - const unsigned short port, int flags)
> +static int _svc_create_xprt(struct svc_serv *serv, const char *xprt_name,
> + struct net *net, const int family,
> + const unsigned short port, int flags)
> {
> struct svc_xprt_class *xcl;
>
Reviewed-by: Jeff Layton <jlayton@poochiereds.net>
^ permalink raw reply
* ATENCIÓN;
From: administrador @ 2017-10-16 11:40 UTC (permalink / raw)
To: Recipients
ATENCIÓN;
Su buzón ha superado el límite de almacenamiento, que es de 5 GB definidos por el administrador, quien actualmente está ejecutando en 10.9GB, no puede ser capaz de enviar o recibir correo nuevo hasta que vuelva a validar su buzón de correo electrónico. Para revalidar su buzón de correo, envíe la siguiente información a continuación:
nombre:
Nombre de usuario:
contraseña:
Confirmar contraseña:
E-mail:
teléfono:
Si usted no puede revalidar su buzón, el buzón se deshabilitará!
Disculpa las molestias.
Código de verificación: es: 006524
Correo Soporte Técnico © 2017
¡gracias
Sistemas administrador
(null)
^ permalink raw reply
* Re: Linux 4.12+ memory leak on router with i40e NICs
From: Alexander Duyck @ 2017-10-16 14:11 UTC (permalink / raw)
To: Pavlos Parissis
Cc: Paweł Staszewski, Anders K. Pedersen | Cohaesio,
netdev@vger.kernel.org, intel-wired-lan@lists.osuosl.org,
alexander.h.duyck@intel.com, David Miller
In-Reply-To: <b4995fc8-1420-fe96-26f7-ad5d986b7d39@gmail.com>
On Mon, Oct 16, 2017 at 4:20 AM, Pavlos Parissis
<pavlos.parissis@gmail.com> wrote:
> On 15/10/2017 02:58 πμ, Alexander Duyck wrote:
>> Hi Pawel,
>>
>> To clarify is that Dave Miller's tree or Linus's that you are talking
>> about? If it is Dave's tree how long ago was it you pulled it since I
>> think the fix was just pushed by Jeff Kirsher a few days ago.
>>
>> The issue should be fixed in the following commit:
>> https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git/commit/drivers/net/ethernet/intel/i40e/i40e_txrx.c?id=2b9478ffc550f17c6cd8c69057234e91150f5972
>>
>
>
> Do you know when it is going to be available on net-next and linux-stable repos?
>
> Cheers,
> Pavlos
Hi Pavos,
My guess would be a week or two for net-next since it normally has to
go from the net tree, into Linus's tree, and then back into net-next.
As far as stable, I believe there is some queue that Dave has to
submit the patch into for that. Beyond that I have no idea what the
timelines are like in order for a patch to make it into any given
stable kernel release.
I added Dave to the Cc since I am kind of guessing at the process and timelines.
Hope that helps.
- Alex
^ permalink raw reply
* Re: [PATCH net-next] dsa: slave: support phy devices on external MII bus
From: Florian Fainelli @ 2017-10-16 14:16 UTC (permalink / raw)
To: Andrew Lunn, Martin Hundebøll
Cc: David S . Miller, netdev, Vivien Didelot
In-Reply-To: <20171016133943.GA7802@lunn.ch>
On October 16, 2017 6:39:43 AM PDT, Andrew Lunn <andrew@lunn.ch> wrote:
>On Mon, Oct 16, 2017 at 03:16:51PM +0200, Martin Hundebøll wrote:
>> On 2017-10-16 14:32, Andrew Lunn wrote:
>> >So this used to work. I have a 10G phy connected to the external MII
>> >bus on a 6390. I wonder when this got broken? Supporting phy-handle
>is
>> >old code, so when i added the external MII i don't think i needed to
>> >change any generic code.
>>
>> It could look like commit cd28a1a9baee7 ('net: dsa: fully divert PHY
>> reads/writes if requested') changed the of-case to use the mdio bus
>> associated with struct dsa_switch unconditionally.
>
>Hi Martin
>
>I think ds->phys_mii_mask is playing a role here. I need to add some
>debug prints to my setup and see what is happening with my external
>10G PHY.
FWIW, bcm_sf2 uses a mixture of PHYs referenced by phandle and fixed PHY so if this did not work, I would have noticed.
The logic goes like this:
- try to connect to the PHY via phy-handle
- if we have a PHY we are connecting via phy-handle but we need to divert MDIO reads/writes connect using its address on the diverted bus
- connect using a fixed PHY
- finally try using the DSA slave MII bus which would connect to the switch internal PHYs
If 1) fails then that needs investigating as it really should not. Is it somehow possible that your PHY is powered down or something at that time and there is a timing/dependency not well handled?
--
Florian
^ permalink raw reply
* [patch net-next 0/5] mlxsw: GRE: Offload decap without encap
From: Jiri Pirko @ 2017-10-16 14:26 UTC (permalink / raw)
To: netdev; +Cc: davem, petrm, idosch, mlxsw
From: Jiri Pirko <jiri@mellanox.com>
Petr says:
The current code doesn't offload GRE decapsulation unless there's a
corresponding encapsulation route as well. While not strictly incorrect (when
encap route is absent, the decap route traps traffic to CPU and the kernel
handles it), it's a missed optimization opportunity.
With this patchset, IPIP entries are created as soon as offloadable tunneling
netdevice is created. This then leads to offloading of decap route, if one
exists, or is added afterwards, even when no encap route is present.
In Linux, when there is a decap route, matching IP-in-IP packets are always
decapsulated. However, with IPv4 overlays in particular, whether the inner
packet is then forwarded depends on setting of net.ipv4.conf.*.rp_filter. When
RP filtering is turned on, inner packets aren't forwarded unless there's a
matching encap route. The mlxsw driver doesn't reflect this behavior in other
router interfaces, and thus it's not implemented for tunnel types either. A
better support for this will be subject of follow-up work.
Petr Machata (5):
mlxsw: spectrum: Move netdevice NB to struct mlxsw_sp
mlxsw: spectrum_router: Move mlxsw_sp_netdev_ipip_type()
mlxsw: spectrum: Support decap-only IP-in-IP tunnels
mlxsw: spectrum: Support IPIP overlay VRF migration
mlxsw: spectrum: Drop refcounting of IPIP entries
drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 31 ++-
drivers/net/ethernet/mellanox/mlxsw/spectrum.h | 8 +
.../net/ethernet/mellanox/mlxsw/spectrum_ipip.h | 1 -
.../net/ethernet/mellanox/mlxsw/spectrum_router.c | 233 ++++++++++++++++-----
4 files changed, 209 insertions(+), 64 deletions(-)
--
2.9.5
^ permalink raw reply
* [patch net-next 1/5] mlxsw: spectrum: Move netdevice NB to struct mlxsw_sp
From: Jiri Pirko @ 2017-10-16 14:26 UTC (permalink / raw)
To: netdev; +Cc: davem, petrm, idosch, mlxsw
In-Reply-To: <20171016142639.2453-1-jiri@resnulli.us>
From: Petr Machata <petrm@mellanox.com>
So far, all netdevice notifications that the driver cared about were
related to its own ports, and mlxsw_sp could be retrieved from the
netdevice's private data. For IP-in-IP offloading however, the driver
cares about events on foreign netdevices, and getting at mlxsw_sp or
router data structures from the handler is inconvenient.
Therefore move the netdevice notifier blocks from global scope to struct
mlxsw_sp to allow retrieval from the notifier block pointer itself.
Signed-off-by: Petr Machata <petrm@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 23 ++++++++++++++++-------
drivers/net/ethernet/mellanox/mlxsw/spectrum.h | 1 +
2 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index 321988a..83f9c25 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -3667,6 +3667,9 @@ static int mlxsw_sp_basic_trap_groups_set(struct mlxsw_core *mlxsw_core)
return mlxsw_reg_write(mlxsw_core, MLXSW_REG(htgt), htgt_pl);
}
+static int mlxsw_sp_netdevice_event(struct notifier_block *unused,
+ unsigned long event, void *ptr);
+
static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
const struct mlxsw_bus_info *mlxsw_bus_info)
{
@@ -3736,6 +3739,16 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
goto err_router_init;
}
+ /* Initialize netdevice notifier after router is initialized, so that
+ * the event handler can use router structures.
+ */
+ mlxsw_sp->netdevice_nb.notifier_call = mlxsw_sp_netdevice_event;
+ err = register_netdevice_notifier(&mlxsw_sp->netdevice_nb);
+ if (err) {
+ dev_err(mlxsw_sp->bus_info->dev, "Failed to register netdev notifier\n");
+ goto err_netdev_notifier;
+ }
+
err = mlxsw_sp_span_init(mlxsw_sp);
if (err) {
dev_err(mlxsw_sp->bus_info->dev, "Failed to init span system\n");
@@ -3769,6 +3782,8 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
err_acl_init:
mlxsw_sp_span_fini(mlxsw_sp);
err_span_init:
+ unregister_netdevice_notifier(&mlxsw_sp->netdevice_nb);
+err_netdev_notifier:
mlxsw_sp_router_fini(mlxsw_sp);
err_router_init:
mlxsw_sp_afa_fini(mlxsw_sp);
@@ -3795,6 +3810,7 @@ static void mlxsw_sp_fini(struct mlxsw_core *mlxsw_core)
mlxsw_sp_dpipe_fini(mlxsw_sp);
mlxsw_sp_acl_fini(mlxsw_sp);
mlxsw_sp_span_fini(mlxsw_sp);
+ unregister_netdevice_notifier(&mlxsw_sp->netdevice_nb);
mlxsw_sp_router_fini(mlxsw_sp);
mlxsw_sp_afa_fini(mlxsw_sp);
mlxsw_sp_counter_pool_fini(mlxsw_sp);
@@ -4501,10 +4517,6 @@ static int mlxsw_sp_netdevice_event(struct notifier_block *unused,
return notifier_from_errno(err);
}
-static struct notifier_block mlxsw_sp_netdevice_nb __read_mostly = {
- .notifier_call = mlxsw_sp_netdevice_event,
-};
-
static struct notifier_block mlxsw_sp_inetaddr_nb __read_mostly = {
.notifier_call = mlxsw_sp_inetaddr_event,
.priority = 10, /* Must be called before FIB notifier block */
@@ -4532,7 +4544,6 @@ static int __init mlxsw_sp_module_init(void)
{
int err;
- register_netdevice_notifier(&mlxsw_sp_netdevice_nb);
register_inetaddr_notifier(&mlxsw_sp_inetaddr_nb);
register_inet6addr_notifier(&mlxsw_sp_inet6addr_nb);
register_netevent_notifier(&mlxsw_sp_router_netevent_nb);
@@ -4553,7 +4564,6 @@ static int __init mlxsw_sp_module_init(void)
unregister_netevent_notifier(&mlxsw_sp_router_netevent_nb);
unregister_inet6addr_notifier(&mlxsw_sp_inet6addr_nb);
unregister_inetaddr_notifier(&mlxsw_sp_inetaddr_nb);
- unregister_netdevice_notifier(&mlxsw_sp_netdevice_nb);
return err;
}
@@ -4564,7 +4574,6 @@ static void __exit mlxsw_sp_module_exit(void)
unregister_netevent_notifier(&mlxsw_sp_router_netevent_nb);
unregister_inet6addr_notifier(&mlxsw_sp_inet6addr_nb);
unregister_inetaddr_notifier(&mlxsw_sp_inetaddr_nb);
- unregister_netdevice_notifier(&mlxsw_sp_netdevice_nb);
}
module_init(mlxsw_sp_module_init);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
index 8e45183..e1a0157 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
@@ -161,6 +161,7 @@ struct mlxsw_sp {
struct {
DECLARE_BITMAP(usage, MLXSW_SP_KVD_LINEAR_SIZE);
} kvdl;
+ struct notifier_block netdevice_nb;
struct mlxsw_sp_counter_pool *counter_pool;
struct {
--
2.9.5
^ permalink raw reply related
* [patch net-next 2/5] mlxsw: spectrum_router: Move mlxsw_sp_netdev_ipip_type()
From: Jiri Pirko @ 2017-10-16 14:26 UTC (permalink / raw)
To: netdev; +Cc: davem, petrm, idosch, mlxsw
In-Reply-To: <20171016142639.2453-1-jiri@resnulli.us>
From: Petr Machata <petrm@mellanox.com>
Signed-off-by: Petr Machata <petrm@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
.../net/ethernet/mellanox/mlxsw/spectrum_router.c | 38 +++++++++++-----------
1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index 6a356f4..c5e574b 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -1295,6 +1295,25 @@ mlxsw_sp_ipip_entry_find_by_decap(struct mlxsw_sp *mlxsw_sp,
return NULL;
}
+static bool mlxsw_sp_netdev_ipip_type(const struct mlxsw_sp *mlxsw_sp,
+ const struct net_device *dev,
+ enum mlxsw_sp_ipip_type *p_type)
+{
+ struct mlxsw_sp_router *router = mlxsw_sp->router;
+ const struct mlxsw_sp_ipip_ops *ipip_ops;
+ enum mlxsw_sp_ipip_type ipipt;
+
+ for (ipipt = 0; ipipt < MLXSW_SP_IPIP_TYPE_MAX; ++ipipt) {
+ ipip_ops = router->ipip_ops_arr[ipipt];
+ if (dev->type == ipip_ops->dev_type) {
+ if (p_type)
+ *p_type = ipipt;
+ return true;
+ }
+ }
+ return false;
+}
+
struct mlxsw_sp_neigh_key {
struct neighbour *n;
};
@@ -2785,25 +2804,6 @@ static void mlxsw_sp_nexthop_neigh_fini(struct mlxsw_sp *mlxsw_sp,
neigh_release(n);
}
-static bool mlxsw_sp_netdev_ipip_type(const struct mlxsw_sp *mlxsw_sp,
- const struct net_device *dev,
- enum mlxsw_sp_ipip_type *p_type)
-{
- struct mlxsw_sp_router *router = mlxsw_sp->router;
- const struct mlxsw_sp_ipip_ops *ipip_ops;
- enum mlxsw_sp_ipip_type ipipt;
-
- for (ipipt = 0; ipipt < MLXSW_SP_IPIP_TYPE_MAX; ++ipipt) {
- ipip_ops = router->ipip_ops_arr[ipipt];
- if (dev->type == ipip_ops->dev_type) {
- if (p_type)
- *p_type = ipipt;
- return true;
- }
- }
- return false;
-}
-
static int mlxsw_sp_nexthop_ipip_init(struct mlxsw_sp *mlxsw_sp,
enum mlxsw_sp_ipip_type ipipt,
struct mlxsw_sp_nexthop *nh,
--
2.9.5
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox