* Re: [PATCH v3 05/20] selftests/ftrace: add install target to enable test install
From: Steven Rostedt @ 2015-01-02 15:45 UTC (permalink / raw)
To: Shuah Khan
Cc: mmarek, gregkh, akpm, mingo, davem, keescook, tranmanphong, mpe,
cov, dh.herrmann, hughd, bobby.prani, serge.hallyn, ebiederm,
tim.bird, josh, koct9i, linux-kbuild, linux-kernel, linux-api,
netdev
In-Reply-To: <e84eeeecde70ecb3ab82c5f825fec359f9e967ff.1419387513.git.shuahkh@osg.samsung.com>
On Wed, 24 Dec 2014 09:27:41 -0700
Shuah Khan <shuahkh@osg.samsung.com> wrote:
> Add a new make target to enable installing test. This target
> installs test in the kselftest install location and add to the
> kselftest script to run the test. Install target can be run
> only from top level kernel source directory.
>
> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
> ---
> tools/testing/selftests/ftrace/Makefile | 11 ++++++++++-
> 1 file changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/tools/testing/selftests/ftrace/Makefile b/tools/testing/selftests/ftrace/Makefile
> index 76cc9f1..7c7cf42 100644
> --- a/tools/testing/selftests/ftrace/Makefile
> +++ b/tools/testing/selftests/ftrace/Makefile
> @@ -1,7 +1,16 @@
> +TEST_STR = /bin/sh ./ftracetest || echo ftrace selftests: [FAIL]
Is it ok that this removes the quotes around the echo string? I don't
see anything wrong about it, but I don't know if there's a shell out
there that will fail due to it.
Other than than,
Acked-by: Steven Rostedt <rostedt@goodmis.org>
-- Steve
> +
> all:
>
> +install:
> +ifdef INSTALL_KSFT_PATH
> + install ./ftracetest $(INSTALL_KSFT_PATH)
> + @cp -r test.d $(INSTALL_KSFT_PATH)
> + echo "$(TEST_STR)" >> $(KSELFTEST)
> +endif
> +
> run_tests:
> - @/bin/sh ./ftracetest || echo "ftrace selftests: [FAIL]"
> + @$(TEST_STR)
>
> clean:
> rm -rf logs/*
^ permalink raw reply
* [PATCH net] enic: free all rq buffs when allocation fails
From: Govindarajulu Varadarajan @ 2015-01-02 15:23 UTC (permalink / raw)
To: davem, netdev; +Cc: ssujith, benve, Govindarajulu Varadarajan
When allocation of all RQs fail, we do not free previously allocated buffers,
before returning error. This causes memory leak.
This patch fixes this by calling vnic_rq_clean(), which frees all the rq
buffers.
Signed-off-by: Govindarajulu Varadarajan <_govind@gmx.com>
---
drivers/net/ethernet/cisco/enic/enic_main.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index 705f334..b29e027 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -1616,7 +1616,7 @@ static int enic_open(struct net_device *netdev)
if (vnic_rq_desc_used(&enic->rq[i]) == 0) {
netdev_err(netdev, "Unable to alloc receive buffers\n");
err = -ENOMEM;
- goto err_out_notify_unset;
+ goto err_out_free_rq;
}
}
@@ -1649,7 +1649,9 @@ static int enic_open(struct net_device *netdev)
return 0;
-err_out_notify_unset:
+err_out_free_rq:
+ for (i = 0; i < enic->rq_count; i++)
+ vnic_rq_clean(&enic->rq[i], enic_free_rq_buf);
enic_dev_notify_unset(enic);
err_out_free_intr:
enic_free_intr(enic);
--
2.2.1
^ permalink raw reply related
* [PATCH] qmi_wwan: Set random MAC on devices with buggy fw
From: Kristian Evensen @ 2015-01-02 15:21 UTC (permalink / raw)
To: netdev, linux-usb, bjorn; +Cc: Kristian Evensen
From: Kristian Evensen <kristian.evensen@gmail.com>
Some buggy firmwares export an incorrect MAC address (00:a0:c6:00:00:00). This
makes for example checking devices for random MAC addresses tricky, and you
might end up with multiple network interfaces with the same address.
This patch tries to fix, or at least improve, the situation by setting the MAC
address of devices with this firmware bug to a random address. I tested the
patch with two devices that has this firmware bug (Huawei E398 and E392), and
network traffic worked fine after changing the address.
Signed-off-by: Kristian Evensen <kristian.evensen@gmail.com>
---
drivers/net/usb/qmi_wwan.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index db21af8..30a716f 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -56,6 +56,8 @@ struct qmi_wwan_state {
/* default ethernet address used by the modem */
static const u8 default_modem_addr[ETH_ALEN] = {0x02, 0x50, 0xf3};
+static const u8 buggy_fw_addr[ETH_ALEN] = {0x00, 0xa0, 0xc6, 0x00, 0x00, 0x00};
+
/* Make up an ethernet header if the packet doesn't have one.
*
* A firmware bug common among several devices cause them to send raw
@@ -332,10 +334,12 @@ next_desc:
usb_driver_release_interface(driver, info->data);
}
- /* Never use the same address on both ends of the link, even
- * if the buggy firmware told us to.
+ /* Never use the same address on both ends of the link, even if the
+ * buggy firmware told us to. Or, if device is assigned the well-known
+ * buggy firmware MAC address, replace it with a random address,
*/
- if (ether_addr_equal(dev->net->dev_addr, default_modem_addr))
+ if (ether_addr_equal(dev->net->dev_addr, default_modem_addr) ||
+ ether_addr_equal(dev->net->dev_addr, buggy_fw_addr))
eth_hw_addr_random(dev->net);
/* make MAC addr easily distinguishable from an IP header */
--
1.9.1
^ permalink raw reply related
* Re: [PATCH] drivers:isdn: Remove uneeded fix me comment in capi.c for the function,decode_ie
From: Tilman Schmidt @ 2015-01-02 15:21 UTC (permalink / raw)
To: nick; +Cc: hjlipp, isdn, gigaset307x-common, netdev, linux-kernel
In-Reply-To: <54A5FAF9.1090907@gmail.com>
Am 02.01.2015 um 02:57 schrieb nick:
> In that case has anyone tested this on actual hardware supported to see if
> removing these two lines breaks anything. If not I feel it's best to just
> leave the comment for now.
I haven't tested it. The comment was intended as a reminder to myself to
do so eventually but obviously didn't succeed. :-)
So let's leave it for now.
Thanks,
Tilman
--
Tilman Schmidt E-Mail: tilman@imap.cc
Bonn, Germany
Diese Nachricht besteht zu 100% aus wiederverwerteten Bits.
Ungeöffnet mindestens haltbar bis: (siehe Rückseite)
^ permalink raw reply
* Re: How to fix CHECK warning: testing a 'safe expression'
From: Murali Karicheri @ 2015-01-02 14:51 UTC (permalink / raw)
To: netdev, josh, linux-kernel@vger.kernel.org
In-Reply-To: <54907884.2040502@ti.com>
+ Josh
On 12/16/2014 01:23 PM, Murali Karicheri wrote:
> netdev maintainers,
>
> I got a comment to address CHECK warning and wondering how to address
> 'warning: testing a 'safe expression' which appears when using
> IS_ERR_OR_NULL(foo)
>
> where foo is defined as
>
> struct foo_type *foo;
>
> The foo get assigned only NULL or ERR_PTR(error code). So I believe the
> usage is correct. But then how do I make the CHECK happy of its usage?
>
> I have tried doing a grep on the current usage of IS_ERR_OR_NULL() and
> found 276 of them causes this warning in the v3.18 version of the kernel
> that I am using
>
> $ grep -r "warning: testing a 'safe expression" * | wc -l
> 276
>
> 1) Can someone explain what this warning means?
>
> 2) Is it acceptable to post patches to netdev list with this warning?
>
> 3) if not, how this is expected to be fixed? Any example usage to fix
> this warning will be helpful.
>
> Thanks in advance for
--
Murali Karicheri
Linux Kernel, Texas Instruments
^ permalink raw reply
* Re: [PATCH] TCP: Add support for TCP Stealth
From: Christian Grothoff @ 2015-01-02 14:06 UTC (permalink / raw)
To: Daniel Borkmann; +Cc: Julian Kirsch, netdev, Jacob Appelbaum, Pavel Emelyanov
In-Reply-To: <54A69430.2060800@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 3534 bytes --]
On 01/02/2015 01:50 PM, Daniel Borkmann wrote:
> On 01/01/2015 04:32 PM, Christian Grothoff wrote:
> ...
>> That approach is highly vulnerable to timing attacks, and doesn't answer
>> how TCP clients without special capabilities could set the ISN correctly
>> either. Playing with raw sockets is the kind of geeky hack that is
>
> Right, for client/server side you'd need to have the capabilities and
> then drop them later, which would make that approach less convenient
> for user space applications (despite not having to have a port knocking
> uapi in the TCP core itself). For the server, you might get away with a
> central daemon spawning sockets via IPC, but for the unprivileged
> client to e.g., let it set it's own ISN via setsockopt(2) would be a
> bad idea.
>
>> unlikely to give us the combination of usability and security required
>> to significantly reduce the ongoing large-scale compromise of network
>> equipment by spy agencies.
>
> Out of curiosity, when you say you want to significantly reduce the
> large-scale compromise of services by hiding ports, how do you solve
> i) the pre-shared key distribution issue you need for your approach
> (are you mostly targeting administrators for accessing their companies
> router/firewall management interfaces?),
Our assumption is that this solution will work if SSH access to the
system is limited to a small set of users that can easily agree on an
additional passphrase. We do not claim to solve the key distribution
issue in general (the GNU Name System can solve it for some application
scenarios, but that's out of scope for Knock). Like most security
solutions, this works for some scenarios, but not all.
> and ii) the broad adoption of
> this setsockopt(2) in applications? I think for ii) it would be great
> not having to change and recompile every possible client _and_ server
> application if they don't have the change upstreamed in their project.
Correct, for that we have libknockify, a library you can LD_PRELOAD,
setting the passphrase via an environment variable. Now, this doesn't
work for applications that don't permit LD_PRELOAD (like openssh) or use
some TCP sockets where TCP Stealth should be active, and others where it
should not be. But for tools like 'netcat', 'telnet', 'wget' and many
other small tools, libknockify will work.
> It feels like a property that goes beyond the scope of a specific,
> individual application, put differently, what about an additional
> central configuration interface?
With our patch for systemd support, we kind of have a 'central'
configuration interface for "next-generation" servers that support
systemd-style listening. For clients, using libknockify works usually
pretty well as clients usually don't have many different types of TCP
sockets open.
> Other than that, is there a plan for
> key rotations in other words, to have a grace period for a key
> transition as peers might not have synced clocks?
I have no such plans, as it would complicate the system quite a bit and
thus also reduces usability. It would way complicate the key
distribution issue you mentioned, and also the libknockify-style
integration where currently the PSK can simply be passed via an
environment variable would also have to be done differently (i.e.
contacting some kind of PSK-oracle service via IPC). The result would be
a huge increase in complexity for IMO a rather small gain in security
for possibly only a small set of users.
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* wireless-drivers-next 2015-01-02
From: Kalle Valo @ 2015-01-02 13:59 UTC (permalink / raw)
To: David Miller; +Cc: linux-wireless, netdev
Hi Dave,
here's the first pull request for net-next. This time a slow start with
just few patches so it's easier to iron out any issues. I have a lot
more pending in patchwork and will send them later.
Please let me know if there are any issues.
Kalle
The following changes since commit b8fb4e0648a2ab3734140342002f68fb0c7d1602:
net: Reset secmark when scrubbing packet (2014-12-24 00:21:43 -0500)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git tags/wireless-drivers-next-for-davem-2015-01-02
for you to fetch changes up to 354f473ee2c5d01c1cf90f747f95218ee3e73e95:
ath9k: fix typo (2014-12-24 19:14:44 +0200)
----------------------------------------------------------------
Changes:
* ath9k: enable Transmit Power Control (TPC) for ar9003 chips
* rtlwifi: cleanup and updates from the vendor driver
* rsi: fix memory leak related to firmware image
* ath: parameter fix for FCC DFS pattern
----------------------------------------------------------------
Alexey Khoroshilov (1):
rsi: fix memory leak in rsi_load_ta_instructions()
Larry Finger (15):
rtlwifi: rtl8821ae: Fix typos in power-sequence macro
rtlwifi: rtl8192ce: Add code to set the keep-alive operation
rtlwifi: rtl8192ce: Update setting of the media status
rtlwifi: rtl8192ce: Update rate setting routines
rtlwifi: rtl8192ce: Improve RF sleep routine
rtlwifi: Remove extraneous argument for rate mapping
rtlwifi: rtl8723be: Switch to use common rate-mapping routine
rtlwifi: rtl8188ee: Switch to use common rate-mapping routine
rtlwifi: rtl8723ae: Modify driver to use rate-mapping routine in core
rtlwifi: rtl8192ee: Convert driver to use common rate-mapping code
rtlwifi: Convert all drivers to use a common set of rate descriptors
rtlwifi: rtl8821ae: Add VHT rate descriptors
rtlwifi: rtl8192cu: Rework calls to rate-control routine
rtlwifi: rtl8192de: Rework calls to rate-control routine
rtlwifi: rtl8821ae: Switch to use common rate control routine
Lorenzo Bianconi (3):
ath9k: enable TPC by default
ath9k: add debugfs support for hw TPC
ath9k: fix typo
Peter Oh (1):
ath: fix incorrect PPB on FCC radar type 5
Rickard Strandqvist (3):
rtlwifi: rtl8192de: fw.c: Remove unused function
rtlwifi: rtl8192ee: trx.c: Remove unused function
rtlwifi: rtl8723be: phy.c: Remove unused function
Troy Tan (1):
rtlwifi: rtl8821ae: Simplify loading of WOWLAN firmware
drivers/net/wireless/ath/ath9k/debug.c | 71 +++++++
drivers/net/wireless/ath/ath9k/hw.c | 3 +
drivers/net/wireless/ath/ath9k/xmit.c | 2 +-
drivers/net/wireless/ath/dfs_pattern_detector.c | 2 +-
drivers/net/wireless/rsi/rsi_91x_sdio_ops.c | 4 +-
drivers/net/wireless/rtlwifi/base.c | 156 ++++++++++----
drivers/net/wireless/rtlwifi/base.h | 4 +-
drivers/net/wireless/rtlwifi/core.c | 24 ++-
drivers/net/wireless/rtlwifi/core.h | 1 +
drivers/net/wireless/rtlwifi/rtl8188ee/trx.c | 162 +-------------
drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h | 1 +
drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 165 +++++++--------
drivers/net/wireless/rtlwifi/rtl8192ce/phy.c | 5 +-
drivers/net/wireless/rtlwifi/rtl8192ce/sw.c | 30 +--
drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | 13 +-
drivers/net/wireless/rtlwifi/rtl8192cu/mac.c | 4 +-
drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | 28 +--
drivers/net/wireless/rtlwifi/rtl8192cu/trx.c | 20 +-
drivers/net/wireless/rtlwifi/rtl8192de/fw.c | 17 --
drivers/net/wireless/rtlwifi/rtl8192de/fw.h | 1 -
drivers/net/wireless/rtlwifi/rtl8192de/sw.c | 30 +--
drivers/net/wireless/rtlwifi/rtl8192de/trx.c | 27 ++-
drivers/net/wireless/rtlwifi/rtl8192ee/trx.c | 196 +----------------
drivers/net/wireless/rtlwifi/rtl8192ee/trx.h | 9 +-
drivers/net/wireless/rtlwifi/rtl8192se/def.h | 8 +-
drivers/net/wireless/rtlwifi/rtl8192se/sw.c | 30 +--
drivers/net/wireless/rtlwifi/rtl8192se/trx.c | 23 +-
drivers/net/wireless/rtlwifi/rtl8723ae/trx.c | 162 +-------------
drivers/net/wireless/rtlwifi/rtl8723be/phy.c | 25 ---
drivers/net/wireless/rtlwifi/rtl8723be/phy.h | 2 -
drivers/net/wireless/rtlwifi/rtl8723be/trx.c | 162 +-------------
drivers/net/wireless/rtlwifi/rtl8821ae/def.h | 54 -----
drivers/net/wireless/rtlwifi/rtl8821ae/pwrseq.h | 4 +-
drivers/net/wireless/rtlwifi/rtl8821ae/sw.c | 74 +++----
drivers/net/wireless/rtlwifi/rtl8821ae/trx.c | 232 +--------------------
drivers/net/wireless/rtlwifi/wifi.h | 96 +++++----
36 files changed, 510 insertions(+), 1337 deletions(-)
--
Kalle Valo
^ permalink raw reply
* Re: [PATCH] TCP: Add support for TCP Stealth
From: Daniel Borkmann @ 2015-01-02 12:50 UTC (permalink / raw)
To: Christian Grothoff
Cc: Julian Kirsch, netdev, Jacob Appelbaum, Pavel Emelyanov
In-Reply-To: <54A56880.6040802@grothoff.org>
On 01/01/2015 04:32 PM, Christian Grothoff wrote:
...
> That approach is highly vulnerable to timing attacks, and doesn't answer
> how TCP clients without special capabilities could set the ISN correctly
> either. Playing with raw sockets is the kind of geeky hack that is
Right, for client/server side you'd need to have the capabilities and
then drop them later, which would make that approach less convenient
for user space applications (despite not having to have a port knocking
uapi in the TCP core itself). For the server, you might get away with a
central daemon spawning sockets via IPC, but for the unprivileged
client to e.g., let it set it's own ISN via setsockopt(2) would be a
bad idea.
> unlikely to give us the combination of usability and security required
> to significantly reduce the ongoing large-scale compromise of network
> equipment by spy agencies.
Out of curiosity, when you say you want to significantly reduce the
large-scale compromise of services by hiding ports, how do you solve
i) the pre-shared key distribution issue you need for your approach
(are you mostly targeting administrators for accessing their companies
router/firewall management interfaces?), and ii) the broad adoption of
this setsockopt(2) in applications? I think for ii) it would be great
not having to change and recompile every possible client _and_ server
application if they don't have the change upstreamed in their project.
It feels like a property that goes beyond the scope of a specific,
individual application, put differently, what about an additional
central configuration interface? Other than that, is there a plan for
key rotations in other words, to have a grace period for a key
transition as peers might not have synced clocks?
^ permalink raw reply
* Re: [PATCH] net: wireless: b43legacy: radio.c: Remove unused function
From: Sedat Dilek @ 2015-01-02 12:14 UTC (permalink / raw)
To: Rafał Miłecki
Cc: Rickard Strandqvist, Larry Finger, Stefano Brivio,
Network Development, linux-wireless@vger.kernel.org,
Linux Kernel Mailing List, b43-dev
In-Reply-To: <CACna6rxbGRdw7XSYvHAJGxJvMVwjVbAL4ynBM3m9rNggh7gCVQ@mail.gmail.com>
On Fri, Jan 2, 2015 at 1:06 PM, Rafał Miłecki <zajec5@gmail.com> wrote:
> On 2 January 2015 at 13:05, Rafał Miłecki <zajec5@gmail.com> wrote:
>> On 1 January 2015 at 16:46, Rickard Strandqvist
>> <rickard_strandqvist@spectrumdigital.se> wrote:
>>> Remove the function b43legacy_radio_set_tx_iq() that is not used anywhere.
>>>
>>> This was partially found by using a static code analysis program called cppcheck.
>>
>> It seems to be for A-PHY based hardware (with 0x2060 radio id) which
>> is not handled by b43legacy. Should be safe to drop this code (we
>> won't likely need it).
>>
>> Ack
>
> For future, we prefix patches with just a driver name. So this could
> be simply called
> b43legacy: radio.c: Remove unused function
>
Alternatively...
"b43legacy: Remove unused function in radio.c"
BTW, as Arnd Bergmann pointed out [1] how did you test with cppcheck
to get such stuff?
- Sedat -
[1] https://lkml.org/lkml/2015/1/2/51
^ permalink raw reply
* Re: [PATCH] net: wireless: b43legacy: radio.c: Remove unused function
From: Rafał Miłecki @ 2015-01-02 12:06 UTC (permalink / raw)
To: Rickard Strandqvist
Cc: Larry Finger, Stefano Brivio, Network Development,
linux-wireless@vger.kernel.org, Linux Kernel Mailing List,
b43-dev
In-Reply-To: <CACna6rznUcqGTK0t1k=kjn0NVLycq865780ozyB+VYu78d_BSg@mail.gmail.com>
On 2 January 2015 at 13:05, Rafał Miłecki <zajec5@gmail.com> wrote:
> On 1 January 2015 at 16:46, Rickard Strandqvist
> <rickard_strandqvist@spectrumdigital.se> wrote:
>> Remove the function b43legacy_radio_set_tx_iq() that is not used anywhere.
>>
>> This was partially found by using a static code analysis program called cppcheck.
>
> It seems to be for A-PHY based hardware (with 0x2060 radio id) which
> is not handled by b43legacy. Should be safe to drop this code (we
> won't likely need it).
>
> Ack
For future, we prefix patches with just a driver name. So this could
be simply called
b43legacy: radio.c: Remove unused function
--
Rafał
^ permalink raw reply
* Re: [PATCH] net: wireless: b43legacy: radio.c: Remove unused function
From: Rafał Miłecki @ 2015-01-02 12:05 UTC (permalink / raw)
To: Rickard Strandqvist
Cc: Larry Finger, Stefano Brivio, Network Development,
linux-wireless-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Linux Kernel Mailing List, b43-dev
In-Reply-To: <1420127170-28421-1-git-send-email-rickard_strandqvist-IW2WV5XWFqGZkjO+N0TKoMugMpMbD5Xr@public.gmane.org>
On 1 January 2015 at 16:46, Rickard Strandqvist
<rickard_strandqvist-IW2WV5XWFqGZkjO+N0TKoMugMpMbD5Xr@public.gmane.org> wrote:
> Remove the function b43legacy_radio_set_tx_iq() that is not used anywhere.
>
> This was partially found by using a static code analysis program called cppcheck.
It seems to be for A-PHY based hardware (with 0x2060 radio id) which
is not handled by b43legacy. Should be safe to drop this code (we
won't likely need it).
Ack
--
Rafał
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] drivers:net:wireless: Add proper locking for the function, b43_op_beacon_set_tim in main.c
From: Michael Büsch @ 2015-01-02 11:42 UTC (permalink / raw)
To: Rafał Miłecki
Cc: Nicholas Krause, Stefano Brivio, Network Development,
linux-wireless@vger.kernel.org, Linux Kernel Mailing List,
b43-dev, Kalle Valo
In-Reply-To: <CACna6rxP5dB7ng5pf1jeJL7TTOq4xPC9B=wmrX+yeYK-hfF5uw@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1703 bytes --]
On Fri, 2 Jan 2015 12:19:12 +0100
Rafał Miłecki <zajec5@gmail.com> wrote:
> On 2 January 2015 at 10:27, Michael Büsch <m@bues.ch> wrote:
> > On Fri, 2 Jan 2015 02:34:01 -0500
> > Nicholas Krause <xerofoify@gmail.com> wrote:
> >
> >> This adds proper locking for the function, b43_op_beacon_set_tim in main.c by using the mutex lock
> >> in the structure pointer wl, as embedded into this pointer as a mutex in order to protect against
> >> multiple access to the pointer wl when updating the templates for this pointer in the function,
> >> b43_update_templates internally in the function, b43_op_beacon_set_tim.
> >>
> >> Signed-off-by: Nicholas Krause <xerofoify@gmail.com>
> >> ---
> >> drivers/net/wireless/b43/main.c | 3 ++-
> >> 1 file changed, 2 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
> >> index 47731cb..d568fc8 100644
> >> --- a/drivers/net/wireless/b43/main.c
> >> +++ b/drivers/net/wireless/b43/main.c
> >> @@ -5094,8 +5094,9 @@ static int b43_op_beacon_set_tim(struct ieee80211_hw *hw,
> >> {
> >> struct b43_wl *wl = hw_to_b43_wl(hw);
> >>
> >> - /* FIXME: add locking */
> >> + mutex_lock(&wl->mutex);
> >> b43_update_templates(wl);
> >> + mutex_unlock(&wl->mutex);
> >>
> >> return 0;
> >> }
> >
> > Thanks for the patch.
> >
> > However, this does not work. We are in atomic context here.
> > Please see the b43-dev mailing list archives for a recent thread about that.
>
> Michael: guess who it was who sent the patch doing the same back in November.
>
> Yes, the same troll.
D'oh.
Thanks for the notice.
--
Michael
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* RE: [PATCH net-next 1/3] net: add IPv4 routing FIB support for swdev
From: Arad, Ronen @ 2015-01-02 11:39 UTC (permalink / raw)
To: Scott Feldman, roopa, Netdev
Cc: Jirí Pírko, john fastabend, Thomas Graf,
Jamal Hadi Salim, Andy Gospodarek
In-Reply-To: <CAE4R7bBJa8LiDHw8PhL6ARfK5nOfUXg36tfnggwWs=tynBw6Jw@mail.gmail.com>
>-----Original Message-----
>From: netdev-owner@vger.kernel.org [mailto:netdev-owner@vger.kernel.org] On
>Behalf Of Scott Feldman
>Sent: Friday, January 02, 2015 10:01 AM
>To: roopa
>Cc: Netdev; Jiří Pírko; john fastabend; Thomas Graf; Jamal Hadi Salim; Andy
>Gospodarek
>Subject: Re: [PATCH net-next 1/3] net: add IPv4 routing FIB support for swdev
>
>On Thu, Jan 1, 2015 at 9:49 PM, roopa <roopa@cumulusnetworks.com> wrote:
>> On 1/1/15, 7:29 PM, sfeldma@gmail.com wrote:
>>>
>>> From: Scott Feldman <sfeldma@gmail.com>
>>>
>>> To offload IPv4 L3 routing functions to swdev device, the swdev device
>>> driver
>>> implements two new ndo ops (ndo_switch_fib_ipv4_add/del). The ops are
>>> called
>>> by the core IPv4 FIB code when installing/removing FIB entries to/from the
>>> kernel FIB. On install, the driver should return 0 if FIB entry (route)
>>> can be
>>> installed to device for offloading, -EOPNOTSUPP if route cannot be
>>> installed
>>> due to device limitations, and other negative error code on failure to
>>> install
>>> route to device. On failure error code, the route is not installed to
>>> device,
>>> and not installed in kernel FIB, and the return code is propagated back to
>>> the
>>> user-space caller (via netlink). An -EOPNOTSUPP error code is skipped for
>>> the
>>> device but installed in the kernel FIB.
>>>
>>> The FIB entry (route) nexthop list is used to find the swdev device port
>>> to
>>> anchor the ndo op call. The route's fib_dev (the first nexthop's dev) is
>>> used
>>> find the swdev port by recursively traversing the fib_dev's lower_dev list
>>> until a swdev port is found. The ndo op is called on this swdev port.
>>
>>
>> scott, I posted a similar api for bridge attribute sets. But, nobody
>> supported it.
>> http://marc.info/?l=linux-netdev&m=141820234410602&w=2
>>
>> If this is acceptable, I will be resubmitting my api as well.
>>
>
>This may get shot down as well, who knows?
>
>For routes, the nexthop dev may be a bridge or a bond for an IP on the
>router, so we have no choice but to walk down from the bridge or the
>bond to find a swport dev to call the ndo op to install the route.
>
Another case is when VLAN-aware bridge with VLAN filtering is used. In that
case IP interfaces are VLAN interfaces created on top of the bridge.
>For bridge settings, I remember someone raised the issue that settings
>should be propagated down the dev hierarchy, with parent calling
>child's op and so on. I'll go back and look at your post.
>
This was my comment. I'm not sure it was correct. My concern was the VLAN
interface on top of a VLAN-aware bridge use-case. I now believe that such
interfaces are upper devices of the bridge (not master). Therefore, it seems
that traversal starting at a VLAN interface on top of a bridge will follow a
path: VLAN interface => bridge => [team/bond] => switchdev port.
One complication here is that the VLAN context is important. A "naked" nexthop
shall only be resolved within the VLAN associated with the VLAN interface. When
ARP resolution is performed by Linux stack, it goes via the VLAN interface
which imposes a tag on the packet before handing it to the bridge. The VLAN-
aware bridge floods such packet only to member ports of the VLAN. This behavior
of the software bridge has to be preserved with offloaded L3 forwarding and
offloaded L2 switching.
>>
>>
>>>
>>> Since the FIB entry is "naked" when push from the kernel, the
>>> driver/device
>>> is responsible for resolving the route's nexthops to neighbor MAC
>>> addresses.
>>> This can be done by the driver by monitoring NETEVENT_NEIGH_UPDATE
>>> netevent notifier to watch for ARP activity. Once a nexthop is resolved
>>> to
>>> neighbor MAC address, it can be installed to the device and the device
>>> will
>>> do the L3 routing offload in HW, for that nexthop.
>>>
>>> Signed-off-by: Scott Feldman <sfeldma@gmail.com>
>>> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
>>> ---
>>> include/linux/netdevice.h | 22 +++++++++++
>>> include/net/switchdev.h | 18 +++++++++
>>> net/ipv4/fib_trie.c | 17 ++++++++-
>>> net/switchdev/switchdev.c | 89
>>> +++++++++++++++++++++++++++++++++++++++++++++
>>> 4 files changed, 145 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
>>> index 679e6e9..b66d22b 100644
>>> --- a/include/linux/netdevice.h
>>> +++ b/include/linux/netdevice.h
>>> @@ -767,6 +767,8 @@ struct netdev_phys_item_id {
>>> typedef u16 (*select_queue_fallback_t)(struct net_device *dev,
>>> struct sk_buff *skb);
>>> +struct fib_info;
>>> +
>>> /*
>>> * This structure defines the management hooks for network devices.
>>> * The following hooks can be defined; unless noted otherwise, they are
>>> @@ -1030,6 +1032,14 @@ typedef u16 (*select_queue_fallback_t)(struct
>>> net_device *dev,
>>> * int (*ndo_switch_port_stp_update)(struct net_device *dev, u8 state);
>>> * Called to notify switch device port of bridge port STP
>>> * state change.
>>> + * int (*ndo_sw_parent_fib_ipv4_add)(struct net_device *dev, __be32 dst,
>>> + * int dst_len, struct fib_info *fi,
>>> + * u8 tos, u8 type, u32 tb_id);
>>> + * Called to add IPv4 route to switch device.
>>> + * int (*ndo_sw_parent_fib_ipv4_del)(struct net_device *dev, __be32 dst,
>>> + * int dst_len, struct fib_info *fi,
>>> + * u8 tos, u8 type, u32 tb_id);
>>> + * Called to delete IPv4 route from switch device.
>>> */
>>> struct net_device_ops {
>>> int (*ndo_init)(struct net_device *dev);
>>> @@ -1189,6 +1199,18 @@ struct net_device_ops {
>>> struct
>>> netdev_phys_item_id *psid);
>>> int (*ndo_switch_port_stp_update)(struct
>>> net_device *dev,
>>> u8 state);
>>> + int (*ndo_switch_fib_ipv4_add)(struct
>>> net_device *dev,
>>> + __be32 dst,
>>> + int dst_len,
>>> + struct fib_info
>>> *fi,
>>> + u8 tos, u8
>>> type,
>>> + u32 tb_id);
>>> + int (*ndo_switch_fib_ipv4_del)(struct
>>> net_device *dev,
>>> + __be32 dst,
>>> + int dst_len,
>>> + struct fib_info
>>> *fi,
>>> + u8 tos, u8
>>> type,
>>> + u32 tb_id);
>>> #endif
>>> };
>>> diff --git a/include/net/switchdev.h b/include/net/switchdev.h
>>> index 8a6d164..caebc2a 100644
>>> --- a/include/net/switchdev.h
>>> +++ b/include/net/switchdev.h
>>> @@ -17,6 +17,10 @@
>>> int netdev_switch_parent_id_get(struct net_device *dev,
>>> struct netdev_phys_item_id *psid);
>>> int netdev_switch_port_stp_update(struct net_device *dev, u8 state);
>>> +int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi,
>>> + u8 tos, u8 type, u32 tb_id);
>>> +int netdev_switch_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi,
>>> + u8 tos, u8 type, u32 tb_id);
>>> #else
>>> @@ -32,6 +36,20 @@ static inline int
>>> netdev_switch_port_stp_update(struct net_device *dev,
>>> return -EOPNOTSUPP;
>>> }
>>> +static inline int netdev_switch_fib_ipv4_add(u32 dst, int dst_len,
>>> + struct fib_info *fi,
>>> + u8 tos, u8 type, u32 tb_id)
>>> +{
>>> + return -EOPNOTSUPP;
>>> +}
>>> +
>>> +static inline int netdev_switch_fib_ipv4_del(u32 dst, int dst_len,
>>> + struct fib_info *fi,
>>> + u8 tos, u8 type, u32 tb_id)
>>> +{
>>> + return -EOPNOTSUPP;
>>> +}
>>> +
>>> #endif
>>> #endif /* _LINUX_SWITCHDEV_H_ */
>>> diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
>>> index 281e5e0..ea2dc17 100644
>>> --- a/net/ipv4/fib_trie.c
>>> +++ b/net/ipv4/fib_trie.c
>>> @@ -79,6 +79,7 @@
>>> #include <net/tcp.h>
>>> #include <net/sock.h>
>>> #include <net/ip_fib.h>
>>> +#include <net/switchdev.h>
>>> #include "fib_lookup.h"
>>> #define MAX_STAT_DEPTH 32
>>> @@ -1201,6 +1202,8 @@ int fib_table_insert(struct fib_table *tb, struct
>>> fib_config *cfg)
>>> fib_release_info(fi_drop);
>>> if (state & FA_S_ACCESSED)
>>> rt_cache_flush(cfg->fc_nlinfo.nl_net);
>>> + netdev_switch_fib_ipv4_add(key, plen, fi,
>>> fa->fa_tos,
>>> + cfg->fc_type,
>>> tb->tb_id);
>>> rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen,
>>> tb->tb_id, &cfg->fc_nlinfo,
>>> NLM_F_REPLACE);
>>> @@ -1229,6 +1232,13 @@ int fib_table_insert(struct fib_table *tb, struct
>>> fib_config *cfg)
>>> new_fa->fa_tos = tos;
>>> new_fa->fa_type = cfg->fc_type;
>>> new_fa->fa_state = 0;
>>> +
>>> + /* (Optionally) offload fib info to switch hardware. */
>>> + err = netdev_switch_fib_ipv4_add(key, plen, fi, tos,
>>> + cfg->fc_type, tb->tb_id);
>>> + if (err && err != -EOPNOTSUPP)
>>> + goto out_free_new_fa;
>>> +
>>> /*
>>> * Insert new entry to the list.
>>> */
>>> @@ -1237,7 +1247,7 @@ int fib_table_insert(struct fib_table *tb, struct
>>> fib_config *cfg)
>>> fa_head = fib_insert_node(t, key, plen);
>>> if (unlikely(!fa_head)) {
>>> err = -ENOMEM;
>>> - goto out_free_new_fa;
>>> + goto out_sw_fib_del;
>>> }
>>> }
>>> @@ -1253,6 +1263,8 @@ int fib_table_insert(struct fib_table *tb, struct
>>> fib_config *cfg)
>>> succeeded:
>>> return 0;
>>> +out_sw_fib_del:
>>> + netdev_switch_fib_ipv4_del(key, plen, fi, tos, cfg->fc_type,
>>> tb->tb_id);
>>> out_free_new_fa:
>>> kmem_cache_free(fn_alias_kmem, new_fa);
>>> out:
>>> @@ -1529,6 +1541,9 @@ int fib_table_delete(struct fib_table *tb, struct
>>> fib_config *cfg)
>>> rtmsg_fib(RTM_DELROUTE, htonl(key), fa, plen, tb->tb_id,
>>> &cfg->fc_nlinfo, 0);
>>> + netdev_switch_fib_ipv4_del(key, plen, fa->fa_info, tos,
>>> + cfg->fc_type, tb->tb_id);
>>> +
>>> list_del_rcu(&fa->fa_list);
>>> if (!plen)
>>> diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
>>> index d162b21..211a8a0 100644
>>> --- a/net/switchdev/switchdev.c
>>> +++ b/net/switchdev/switchdev.c
>>> @@ -12,6 +12,7 @@
>>> #include <linux/types.h>
>>> #include <linux/init.h>
>>> #include <linux/netdevice.h>
>>> +#include <net/ip_fib.h>
>>> #include <net/switchdev.h>
>>> /**
>>> @@ -50,3 +51,91 @@ int netdev_switch_port_stp_update(struct net_device
>>> *dev, u8 state)
>>> return ops->ndo_switch_port_stp_update(dev, state);
>>> }
>>> EXPORT_SYMBOL(netdev_switch_port_stp_update);
>>> +
>>> +static struct net_device *netdev_switch_get_by_fib_dev(struct net_device
>>> *dev)
>>> +{
>>> + const struct net_device_ops *ops = dev->netdev_ops;
>>> + struct net_device *lower_dev;
>>> + struct net_device *port_dev;
>>> + struct list_head *iter;
>>> +
>>> + /* Recusively search from fib_dev down until we find
>>> + * a sw port dev. (A sw port dev supports
>>> + * ndo_switch_parent_id_get).
>>> + */
>>> +
>>> + if (ops->ndo_switch_parent_id_get)
>>> + return dev;
>>> +
>>> + netdev_for_each_lower_dev(dev, lower_dev, iter) {
>>> + port_dev = netdev_switch_get_by_fib_dev(lower_dev);
>>> + if (port_dev)
>>> + return port_dev;
>>> + }
>>> +
>>> + return NULL;
>>> +}
>>> +
>>> +/**
>>> + * netdev_switch_fib_ipv4_add - Add IPv4 route entry to switch
>>> + *
>>> + * @dst: route's IPv4 destination address
>>> + * @dst_len: destination address length (prefix length)
>>> + * @fi: route FIB info structure
>>> + * @tos: route TOS
>>> + * @type: route type
>>> + * @tb_id: route table ID
>>> + *
>>> + * Add IPv4 route entry to switch device.
>>> + */
>>> +int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi,
>>> + u8 tos, u8 type, u32 tb_id)
>>> +{
>>> + struct net_device *dev;
>>> + const struct net_device_ops *ops;
>>> + int err = -EOPNOTSUPP;
>>> +
>>> + dev = netdev_switch_get_by_fib_dev(fi->fib_dev);
>>> + if (!dev)
>>> + return -EOPNOTSUPP;
>>> + ops = dev->netdev_ops;
>>> +
>>> + if (ops->ndo_switch_fib_ipv4_add)
>>> + err = ops->ndo_switch_fib_ipv4_add(dev, htonl(dst),
>>> dst_len,
>>> + fi, tos, type, tb_id);
>>> +
>>> + return err;
>>> +}
>>> +EXPORT_SYMBOL(netdev_switch_fib_ipv4_add);
>>> +
>>> +/**
>>> + * netdev_switch_fib_ipv4_del - Delete IPv4 route entry from switch
>>> + *
>>> + * @dst: route's IPv4 destination address
>>> + * @dst_len: destination address length (prefix length)
>>> + * @fi: route FIB info structure
>>> + * @tos: route TOS
>>> + * @type: route type
>>> + * @tb_id: route table ID
>>> + *
>>> + * Delete IPv4 route entry from switch device.
>>> + */
>>> +int netdev_switch_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi,
>>> + u8 tos, u8 type, u32 tb_id)
>>> +{
>>> + struct net_device *dev;
>>> + const struct net_device_ops *ops;
>>> + int err = -EOPNOTSUPP;
>>> +
>>> + dev = netdev_switch_get_by_fib_dev(fi->fib_dev);
>>> + if (!dev)
>>> + return -EOPNOTSUPP;
>>> + ops = dev->netdev_ops;
>>> +
>>> + if (ops->ndo_switch_fib_ipv4_del)
>>> + err = ops->ndo_switch_fib_ipv4_del(dev, htonl(dst),
>>> dst_len,
>>> + fi, tos, type, tb_id);
>>> +
>>> + return err;
>>> +}
>>> +EXPORT_SYMBOL(netdev_switch_fib_ipv4_del);
>>
>>
>--
>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 1/3] net: add IPv4 routing FIB support for swdev
From: Arad, Ronen @ 2015-01-02 11:21 UTC (permalink / raw)
To: roopa, sfeldma@gmail.com, netdev@vger.kernel.org
Cc: jiri@resnulli.us, john.fastabend@gmail.com, tgraf@suug.ch,
jhs@mojatatu.com, andy@greyhouse.net
In-Reply-To: <54A63186.1090807@cumulusnetworks.com>
>-----Original Message-----
>From: netdev-owner@vger.kernel.org [mailto:netdev-owner@vger.kernel.org] On
>Behalf Of roopa
>Sent: Friday, January 02, 2015 7:50 AM
>To: sfeldma@gmail.com
>Cc: netdev@vger.kernel.org; jiri@resnulli.us; john.fastabend@gmail.com;
>tgraf@suug.ch; jhs@mojatatu.com; andy@greyhouse.net
>Subject: Re: [PATCH net-next 1/3] net: add IPv4 routing FIB support for swdev
>
>On 1/1/15, 7:29 PM, sfeldma@gmail.com wrote:
>> From: Scott Feldman <sfeldma@gmail.com>
>>
>> To offload IPv4 L3 routing functions to swdev device, the swdev device
>driver
>> implements two new ndo ops (ndo_switch_fib_ipv4_add/del). The ops are
>called
>> by the core IPv4 FIB code when installing/removing FIB entries to/from the
>> kernel FIB. On install, the driver should return 0 if FIB entry (route) can
>be
>> installed to device for offloading, -EOPNOTSUPP if route cannot be installed
>> due to device limitations, and other negative error code on failure to
>install
>> route to device. On failure error code, the route is not installed to
>device,
>> and not installed in kernel FIB, and the return code is propagated back to
>the
>> user-space caller (via netlink). An -EOPNOTSUPP error code is skipped for
>the
>> device but installed in the kernel FIB.
>>
>> The FIB entry (route) nexthop list is used to find the swdev device port to
>> anchor the ndo op call. The route's fib_dev (the first nexthop's dev) is
>used
>> find the swdev port by recursively traversing the fib_dev's lower_dev list
>> until a swdev port is found. The ndo op is called on this swdev port.
>
>scott, I posted a similar api for bridge attribute sets. But, nobody
>supported it.
>http://marc.info/?l=linux-netdev&m=141820234410602&w=2
>
>If this is acceptable, I will be resubmitting my api as well.
>
There is certainly a need to propagate bridge and brport attributes to
switchdev driver. I believe the objections to your patch were not about that
need but about the mechanism of doing that. My understanding of the objections
on the list is that the propagation has to be delegated to intermediate master
devices (such as bond/team) in a stacked architecture instead of blindly
traverse through them to leaf switchdev ports.
An ideal traversal would allow intermediate master (or just upper) devices to
intervene or block the traversal while defaulting to the suggested transparent
traversal. This could address the objections to your patch. Maybe the traversal
requires an introduction of a new ndo.
>
>
>>
>> Since the FIB entry is "naked" when push from the kernel, the driver/device
>> is responsible for resolving the route's nexthops to neighbor MAC addresses.
>> This can be done by the driver by monitoring NETEVENT_NEIGH_UPDATE
>> netevent notifier to watch for ARP activity. Once a nexthop is resolved to
>> neighbor MAC address, it can be installed to the device and the device will
>> do the L3 routing offload in HW, for that nexthop.
>>
>> Signed-off-by: Scott Feldman <sfeldma@gmail.com>
>> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
>> ---
>> include/linux/netdevice.h | 22 +++++++++++
>> include/net/switchdev.h | 18 +++++++++
>> net/ipv4/fib_trie.c | 17 ++++++++-
>> net/switchdev/switchdev.c | 89
>+++++++++++++++++++++++++++++++++++++++++++++
>> 4 files changed, 145 insertions(+), 1 deletion(-)
>>
>> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
>> index 679e6e9..b66d22b 100644
>> --- a/include/linux/netdevice.h
>> +++ b/include/linux/netdevice.h
>> @@ -767,6 +767,8 @@ struct netdev_phys_item_id {
>> typedef u16 (*select_queue_fallback_t)(struct net_device *dev,
>> struct sk_buff *skb);
>>
>> +struct fib_info;
>> +
>> /*
>> * This structure defines the management hooks for network devices.
>> * The following hooks can be defined; unless noted otherwise, they are
>> @@ -1030,6 +1032,14 @@ typedef u16 (*select_queue_fallback_t)(struct
>net_device *dev,
>> * int (*ndo_switch_port_stp_update)(struct net_device *dev, u8 state);
>> * Called to notify switch device port of bridge port STP
>> * state change.
>> + * int (*ndo_sw_parent_fib_ipv4_add)(struct net_device *dev, __be32 dst,
>> + * int dst_len, struct fib_info *fi,
>> + * u8 tos, u8 type, u32 tb_id);
>> + * Called to add IPv4 route to switch device.
>> + * int (*ndo_sw_parent_fib_ipv4_del)(struct net_device *dev, __be32 dst,
>> + * int dst_len, struct fib_info *fi,
>> + * u8 tos, u8 type, u32 tb_id);
>> + * Called to delete IPv4 route from switch device.
>> */
>> struct net_device_ops {
>> int (*ndo_init)(struct net_device *dev);
>> @@ -1189,6 +1199,18 @@ struct net_device_ops {
>> struct netdev_phys_item_id
>*psid);
>> int (*ndo_switch_port_stp_update)(struct net_device
>*dev,
>> u8 state);
>> + int (*ndo_switch_fib_ipv4_add)(struct net_device *dev,
>> + __be32 dst,
>> + int dst_len,
>> + struct fib_info *fi,
>> + u8 tos, u8 type,
>> + u32 tb_id);
>> + int (*ndo_switch_fib_ipv4_del)(struct net_device *dev,
>> + __be32 dst,
>> + int dst_len,
>> + struct fib_info *fi,
>> + u8 tos, u8 type,
>> + u32 tb_id);
>> #endif
>> };
>>
>> diff --git a/include/net/switchdev.h b/include/net/switchdev.h
>> index 8a6d164..caebc2a 100644
>> --- a/include/net/switchdev.h
>> +++ b/include/net/switchdev.h
>> @@ -17,6 +17,10 @@
>> int netdev_switch_parent_id_get(struct net_device *dev,
>> struct netdev_phys_item_id *psid);
>> int netdev_switch_port_stp_update(struct net_device *dev, u8 state);
>> +int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi,
>> + u8 tos, u8 type, u32 tb_id);
>> +int netdev_switch_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi,
>> + u8 tos, u8 type, u32 tb_id);
>>
>> #else
>>
>> @@ -32,6 +36,20 @@ static inline int netdev_switch_port_stp_update(struct
>net_device *dev,
>> return -EOPNOTSUPP;
>> }
>>
>> +static inline int netdev_switch_fib_ipv4_add(u32 dst, int dst_len,
>> + struct fib_info *fi,
>> + u8 tos, u8 type, u32 tb_id)
>> +{
>> + return -EOPNOTSUPP;
>> +}
>> +
>> +static inline int netdev_switch_fib_ipv4_del(u32 dst, int dst_len,
>> + struct fib_info *fi,
>> + u8 tos, u8 type, u32 tb_id)
>> +{
>> + return -EOPNOTSUPP;
>> +}
>> +
>> #endif
>>
>> #endif /* _LINUX_SWITCHDEV_H_ */
>> diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
>> index 281e5e0..ea2dc17 100644
>> --- a/net/ipv4/fib_trie.c
>> +++ b/net/ipv4/fib_trie.c
>> @@ -79,6 +79,7 @@
>> #include <net/tcp.h>
>> #include <net/sock.h>
>> #include <net/ip_fib.h>
>> +#include <net/switchdev.h>
>> #include "fib_lookup.h"
>>
>> #define MAX_STAT_DEPTH 32
>> @@ -1201,6 +1202,8 @@ int fib_table_insert(struct fib_table *tb, struct
>fib_config *cfg)
>> fib_release_info(fi_drop);
>> if (state & FA_S_ACCESSED)
>> rt_cache_flush(cfg->fc_nlinfo.nl_net);
>> + netdev_switch_fib_ipv4_add(key, plen, fi, fa->fa_tos,
>> + cfg->fc_type, tb->tb_id);
>> rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen,
>> tb->tb_id, &cfg->fc_nlinfo, NLM_F_REPLACE);
>>
>> @@ -1229,6 +1232,13 @@ int fib_table_insert(struct fib_table *tb, struct
>fib_config *cfg)
>> new_fa->fa_tos = tos;
>> new_fa->fa_type = cfg->fc_type;
>> new_fa->fa_state = 0;
>> +
>> + /* (Optionally) offload fib info to switch hardware. */
>> + err = netdev_switch_fib_ipv4_add(key, plen, fi, tos,
>> + cfg->fc_type, tb->tb_id);
>> + if (err && err != -EOPNOTSUPP)
>> + goto out_free_new_fa;
>> +
>> /*
>> * Insert new entry to the list.
>> */
>> @@ -1237,7 +1247,7 @@ int fib_table_insert(struct fib_table *tb, struct
>fib_config *cfg)
>> fa_head = fib_insert_node(t, key, plen);
>> if (unlikely(!fa_head)) {
>> err = -ENOMEM;
>> - goto out_free_new_fa;
>> + goto out_sw_fib_del;
>> }
>> }
>>
>> @@ -1253,6 +1263,8 @@ int fib_table_insert(struct fib_table *tb, struct
>fib_config *cfg)
>> succeeded:
>> return 0;
>>
>> +out_sw_fib_del:
>> + netdev_switch_fib_ipv4_del(key, plen, fi, tos, cfg->fc_type, tb-
>>tb_id);
>> out_free_new_fa:
>> kmem_cache_free(fn_alias_kmem, new_fa);
>> out:
>> @@ -1529,6 +1541,9 @@ int fib_table_delete(struct fib_table *tb, struct
>fib_config *cfg)
>> rtmsg_fib(RTM_DELROUTE, htonl(key), fa, plen, tb->tb_id,
>> &cfg->fc_nlinfo, 0);
>>
>> + netdev_switch_fib_ipv4_del(key, plen, fa->fa_info, tos,
>> + cfg->fc_type, tb->tb_id);
>> +
>> list_del_rcu(&fa->fa_list);
>>
>> if (!plen)
>> diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
>> index d162b21..211a8a0 100644
>> --- a/net/switchdev/switchdev.c
>> +++ b/net/switchdev/switchdev.c
>> @@ -12,6 +12,7 @@
>> #include <linux/types.h>
>> #include <linux/init.h>
>> #include <linux/netdevice.h>
>> +#include <net/ip_fib.h>
>> #include <net/switchdev.h>
>>
>> /**
>> @@ -50,3 +51,91 @@ int netdev_switch_port_stp_update(struct net_device *dev,
>u8 state)
>> return ops->ndo_switch_port_stp_update(dev, state);
>> }
>> EXPORT_SYMBOL(netdev_switch_port_stp_update);
>> +
>> +static struct net_device *netdev_switch_get_by_fib_dev(struct net_device
>*dev)
>> +{
>> + const struct net_device_ops *ops = dev->netdev_ops;
>> + struct net_device *lower_dev;
>> + struct net_device *port_dev;
>> + struct list_head *iter;
>> +
>> + /* Recusively search from fib_dev down until we find
>> + * a sw port dev. (A sw port dev supports
>> + * ndo_switch_parent_id_get).
>> + */
>> +
>> + if (ops->ndo_switch_parent_id_get)
>> + return dev;
>> +
>> + netdev_for_each_lower_dev(dev, lower_dev, iter) {
>> + port_dev = netdev_switch_get_by_fib_dev(lower_dev);
>> + if (port_dev)
>> + return port_dev;
>> + }
>> +
>> + return NULL;
>> +}
>> +
>> +/**
>> + * netdev_switch_fib_ipv4_add - Add IPv4 route entry to switch
>> + *
>> + * @dst: route's IPv4 destination address
>> + * @dst_len: destination address length (prefix length)
>> + * @fi: route FIB info structure
>> + * @tos: route TOS
>> + * @type: route type
>> + * @tb_id: route table ID
>> + *
>> + * Add IPv4 route entry to switch device.
>> + */
>> +int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi,
>> + u8 tos, u8 type, u32 tb_id)
>> +{
>> + struct net_device *dev;
>> + const struct net_device_ops *ops;
>> + int err = -EOPNOTSUPP;
>> +
>> + dev = netdev_switch_get_by_fib_dev(fi->fib_dev);
>> + if (!dev)
>> + return -EOPNOTSUPP;
>> + ops = dev->netdev_ops;
>> +
>> + if (ops->ndo_switch_fib_ipv4_add)
>> + err = ops->ndo_switch_fib_ipv4_add(dev, htonl(dst), dst_len,
>> + fi, tos, type, tb_id);
>> +
>> + return err;
>> +}
>> +EXPORT_SYMBOL(netdev_switch_fib_ipv4_add);
>> +
>> +/**
>> + * netdev_switch_fib_ipv4_del - Delete IPv4 route entry from switch
>> + *
>> + * @dst: route's IPv4 destination address
>> + * @dst_len: destination address length (prefix length)
>> + * @fi: route FIB info structure
>> + * @tos: route TOS
>> + * @type: route type
>> + * @tb_id: route table ID
>> + *
>> + * Delete IPv4 route entry from switch device.
>> + */
>> +int netdev_switch_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi,
>> + u8 tos, u8 type, u32 tb_id)
>> +{
>> + struct net_device *dev;
>> + const struct net_device_ops *ops;
>> + int err = -EOPNOTSUPP;
>> +
>> + dev = netdev_switch_get_by_fib_dev(fi->fib_dev);
>> + if (!dev)
>> + return -EOPNOTSUPP;
>> + ops = dev->netdev_ops;
>> +
>> + if (ops->ndo_switch_fib_ipv4_del)
>> + err = ops->ndo_switch_fib_ipv4_del(dev, htonl(dst), dst_len,
>> + fi, tos, type, tb_id);
>> +
>> + return err;
>> +}
>> +EXPORT_SYMBOL(netdev_switch_fib_ipv4_del);
>
>--
>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] drivers:net:wireless: Add proper locking for the function, b43_op_beacon_set_tim in main.c
From: Rafał Miłecki @ 2015-01-02 11:19 UTC (permalink / raw)
To: Michael Büsch
Cc: Nicholas Krause, Stefano Brivio, Network Development,
linux-wireless@vger.kernel.org, Linux Kernel Mailing List,
b43-dev, Kalle Valo
In-Reply-To: <20150102102727.3918a684@wiggum>
On 2 January 2015 at 10:27, Michael Büsch <m@bues.ch> wrote:
> On Fri, 2 Jan 2015 02:34:01 -0500
> Nicholas Krause <xerofoify@gmail.com> wrote:
>
>> This adds proper locking for the function, b43_op_beacon_set_tim in main.c by using the mutex lock
>> in the structure pointer wl, as embedded into this pointer as a mutex in order to protect against
>> multiple access to the pointer wl when updating the templates for this pointer in the function,
>> b43_update_templates internally in the function, b43_op_beacon_set_tim.
>>
>> Signed-off-by: Nicholas Krause <xerofoify@gmail.com>
>> ---
>> drivers/net/wireless/b43/main.c | 3 ++-
>> 1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
>> index 47731cb..d568fc8 100644
>> --- a/drivers/net/wireless/b43/main.c
>> +++ b/drivers/net/wireless/b43/main.c
>> @@ -5094,8 +5094,9 @@ static int b43_op_beacon_set_tim(struct ieee80211_hw *hw,
>> {
>> struct b43_wl *wl = hw_to_b43_wl(hw);
>>
>> - /* FIXME: add locking */
>> + mutex_lock(&wl->mutex);
>> b43_update_templates(wl);
>> + mutex_unlock(&wl->mutex);
>>
>> return 0;
>> }
>
> Thanks for the patch.
>
> However, this does not work. We are in atomic context here.
> Please see the b43-dev mailing list archives for a recent thread about that.
Michael: guess who it was who sent the patch doing the same back in November.
Yes, the same troll.
--
Rafał
^ permalink raw reply
* Re: [PATCH] TCP: Add support for TCP Stealth
From: Hagen Paul Pfeifer @ 2015-01-02 10:36 UTC (permalink / raw)
To: Julian Kirsch, Eric Dumazet; +Cc: netdev, Christian Grothoff, Jacob Appelbaum
In-Reply-To: <54A470B3.3010501@sec.in.tum.de>
On 31 December 2014 at 22:54, Julian Kirsch <kirschju@sec.in.tum.de> wrote:
Hey Jullian
> one year ago [0] we tried to convince you to add support for a new
> socket option to the linux kernel. Equipped with an improved version of
> our patch we're back to accomplish this task today. :-)
Nice, what is the difference from the previous version? There is no
changelog in the patch. Especially issues raised by Eric (cc'ed) one
year ago and TCPM.
Hagen
^ permalink raw reply
* Re: [PATCH] drivers:net:wireless: Add proper locking for the function, b43_op_beacon_set_tim in main.c
From: Michael Büsch @ 2015-01-02 9:27 UTC (permalink / raw)
To: Nicholas Krause
Cc: stefano.brivio, netdev, linux-wireless, b43-dev, kvalo,
linux-kernel
In-Reply-To: <1420184041-6788-1-git-send-email-xerofoify@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1387 bytes --]
On Fri, 2 Jan 2015 02:34:01 -0500
Nicholas Krause <xerofoify@gmail.com> wrote:
> This adds proper locking for the function, b43_op_beacon_set_tim in main.c by using the mutex lock
> in the structure pointer wl, as embedded into this pointer as a mutex in order to protect against
> multiple access to the pointer wl when updating the templates for this pointer in the function,
> b43_update_templates internally in the function, b43_op_beacon_set_tim.
>
> Signed-off-by: Nicholas Krause <xerofoify@gmail.com>
> ---
> drivers/net/wireless/b43/main.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
> index 47731cb..d568fc8 100644
> --- a/drivers/net/wireless/b43/main.c
> +++ b/drivers/net/wireless/b43/main.c
> @@ -5094,8 +5094,9 @@ static int b43_op_beacon_set_tim(struct ieee80211_hw *hw,
> {
> struct b43_wl *wl = hw_to_b43_wl(hw);
>
> - /* FIXME: add locking */
> + mutex_lock(&wl->mutex);
> b43_update_templates(wl);
> + mutex_unlock(&wl->mutex);
>
> return 0;
> }
Thanks for the patch.
However, this does not work. We are in atomic context here.
Please see the b43-dev mailing list archives for a recent thread about that.
I'm also pretty sure that this is safe without lock, due to the higher level locks in mac80211.
--
Michael
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* Re: [PATCH net-next 0/3] swdev: add IPv4 routing offload
From: Rami Rosen @ 2015-01-02 9:04 UTC (permalink / raw)
To: sfeldma; +Cc: Netdev, jiri, john.fastabend, tgraf, jhs, andy, roopa
In-Reply-To: <1420169361-31767-1-git-send-email-sfeldma@gmail.com>
Hi, Scott,
Good work!
You say that currently the rocker driver support only unicast singlepath IPv4.
If I understand correctly, IPv4 packets with tos !=0 are skipped in
the current rocker implementation of the ndo_sw_parent_fib_ipv4_add()
callback. I am referring to the rocker_port_fib_ipv4_skip() method:
if (tos != 0)
return -EOPNOTSUPP;
see:
https://github.com/jpirko/net-next-rocker/blob/master/drivers/net/ethernet/rocker/rocker.c#L3701
Is there a reason for this? (The NDO that you suggest,
ndo_sw_parent_fib_ipv4_add(), has the tos as a parameter, so from this
aspect there is no problem).
Regards,
Rami Rosen
On Fri, Jan 2, 2015 at 5:29 AM, <sfeldma@gmail.com> wrote:
> From: Scott Feldman <sfeldma@gmail.com>
>
> This patch set adds L3 routing offload support for IPv4 routes. The idea is to
> mirror routes installed in the kernel's FIB down to a hardware switch device to
> offload the data forwarding path for L3. Only the data forwarding path is
> intercepted. Control and management of the kernel's FIB remains with the
> kernel.
>
> A couple of new ndo ops (ndo_switch_fib_ipv4_add/del) are added to the swdev
> model to add/remove FIB entries to/from the offload device. The ops are called
> from the core IPv4 FIB code directly. Just before the FIB entry is installed
> in the kernel's FIB, the swdev device driver gets a chance at the FIB entry
> (assuming the swdev driver implements the new ndo ops). This is a synchronous
> call in the RTM_NEWROUTE path, and the swdev has the option to fail the
> install, which means the FIB entry is not installed in swdev or the kernel, and
> the user is notified of the failure. The swdev driver also has the option to
> return -EOPNOTSUPP to pass on the FIB entry, so it'll only be installed in the
> kernel FIB.
>
> The FIB flush path is modified also to call into the swdev driver to flush the
> FIB entries from hardware.
>
> The rocker swdev driver is updated to support these new ndo ops. Right now
> rocker only supports IPv4 singlepath routes, but follow-on patches will add
> IPv6 and ECMP support. Also, only unicast IPv4 routes are supported, but
> follow-on patches will add multicast route support.
>
> Testing was done in my simulated network envionment using VMs and the rocker
> device. I'm using Quagga OSPFv2 for the routing protocol for automatic control
> plane processing. No modifications to Quagga or netlink/iproute2 is required;
> it just works.
>
> One important metric is the time spent installing/removing FIB entries from the
> kernel and the device. With these patches applied, I measured the wall time
> required to install and remove 10K IPv4 routes. I used ip route add cmd in
> batch mode to install static routes. I used the ip route flush cmd to delete
> the routes. This is 10000 routes installed to the kernel's FIB and to the
> swdev device's L3 tables. And then removed from each. The performance is less
> than a second for each operation. This is on my simulated rocker device running
> on a VM, so a real embedded CPU would probably do much better.
>
> My batch has 10K lines of:
>
> simp@simp:~$ head east
> route add 16.0.0.0/32 nexthop via 11.0.0.2 dev swp1
> route add 16.0.0.1/32 nexthop via 11.0.0.2 dev swp1
> route add 16.0.0.2/32 nexthop via 11.0.0.2 dev swp1
> route add 16.0.0.3/32 nexthop via 11.0.0.2 dev swp1
> route add 16.0.0.4/32 nexthop via 11.0.0.2 dev swp1
> route add 16.0.0.5/32 nexthop via 11.0.0.2 dev swp1
> route add 16.0.0.6/32 nexthop via 11.0.0.2 dev swp1
> route add 16.0.0.7/32 nexthop via 11.0.0.2 dev swp1
> route add 16.0.0.8/32 nexthop via 11.0.0.2 dev swp1
> route add 16.0.0.9/32 nexthop via 11.0.0.2 dev swp1
> [...]
>
> Install/removing routes:
>
> simp@simp:~$ wc -l east
> 10000 east
> simp@simp:~$ ip route show root 16/8 | wc -l
> 0
> simp@simp:~$ time sudo ip --batch east
>
> real 0m0.715s
> user 0m0.092s
> sys 0m0.388s
> simp@simp:~$ ip route show root 16/8 | wc -l
> 10000
>
> [At this point, 10K routes are installed in kernel and the device]
>
> simp@simp:~$ time sudo ip route flush root 16/8
>
> real 0m0.458s
> user 0m0.000s
> sys 0m0.284s
> simp@simp:~$ ip route show root 16/8 | wc -l
> 0
>
> [All gone]
>
> Scott Feldman (3):
> net: add IPv4 routing FIB support for swdev
> net: call swdev fib del for flushed routes
> rocker: implement IPv4 fib offloading
>
> drivers/net/ethernet/rocker/rocker.c | 441 +++++++++++++++++++++++++++++++++-
> include/linux/netdevice.h | 22 ++
> include/net/switchdev.h | 18 ++
> net/ipv4/fib_trie.c | 31 ++-
> net/switchdev/switchdev.c | 89 +++++++
> 5 files changed, 592 insertions(+), 9 deletions(-)
>
> --
> 1.7.10.4
>
> --
> 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 1/3] net: add IPv4 routing FIB support for swdev
From: Scott Feldman @ 2015-01-02 8:00 UTC (permalink / raw)
To: roopa
Cc: Netdev, Jiří Pírko, john fastabend, Thomas Graf,
Jamal Hadi Salim, Andy Gospodarek
In-Reply-To: <54A63186.1090807@cumulusnetworks.com>
On Thu, Jan 1, 2015 at 9:49 PM, roopa <roopa@cumulusnetworks.com> wrote:
> On 1/1/15, 7:29 PM, sfeldma@gmail.com wrote:
>>
>> From: Scott Feldman <sfeldma@gmail.com>
>>
>> To offload IPv4 L3 routing functions to swdev device, the swdev device
>> driver
>> implements two new ndo ops (ndo_switch_fib_ipv4_add/del). The ops are
>> called
>> by the core IPv4 FIB code when installing/removing FIB entries to/from the
>> kernel FIB. On install, the driver should return 0 if FIB entry (route)
>> can be
>> installed to device for offloading, -EOPNOTSUPP if route cannot be
>> installed
>> due to device limitations, and other negative error code on failure to
>> install
>> route to device. On failure error code, the route is not installed to
>> device,
>> and not installed in kernel FIB, and the return code is propagated back to
>> the
>> user-space caller (via netlink). An -EOPNOTSUPP error code is skipped for
>> the
>> device but installed in the kernel FIB.
>>
>> The FIB entry (route) nexthop list is used to find the swdev device port
>> to
>> anchor the ndo op call. The route's fib_dev (the first nexthop's dev) is
>> used
>> find the swdev port by recursively traversing the fib_dev's lower_dev list
>> until a swdev port is found. The ndo op is called on this swdev port.
>
>
> scott, I posted a similar api for bridge attribute sets. But, nobody
> supported it.
> http://marc.info/?l=linux-netdev&m=141820234410602&w=2
>
> If this is acceptable, I will be resubmitting my api as well.
>
This may get shot down as well, who knows?
For routes, the nexthop dev may be a bridge or a bond for an IP on the
router, so we have no choice but to walk down from the bridge or the
bond to find a swport dev to call the ndo op to install the route.
For bridge settings, I remember someone raised the issue that settings
should be propagated down the dev hierarchy, with parent calling
child's op and so on. I'll go back and look at your post.
>
>
>>
>> Since the FIB entry is "naked" when push from the kernel, the
>> driver/device
>> is responsible for resolving the route's nexthops to neighbor MAC
>> addresses.
>> This can be done by the driver by monitoring NETEVENT_NEIGH_UPDATE
>> netevent notifier to watch for ARP activity. Once a nexthop is resolved
>> to
>> neighbor MAC address, it can be installed to the device and the device
>> will
>> do the L3 routing offload in HW, for that nexthop.
>>
>> Signed-off-by: Scott Feldman <sfeldma@gmail.com>
>> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
>> ---
>> include/linux/netdevice.h | 22 +++++++++++
>> include/net/switchdev.h | 18 +++++++++
>> net/ipv4/fib_trie.c | 17 ++++++++-
>> net/switchdev/switchdev.c | 89
>> +++++++++++++++++++++++++++++++++++++++++++++
>> 4 files changed, 145 insertions(+), 1 deletion(-)
>>
>> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
>> index 679e6e9..b66d22b 100644
>> --- a/include/linux/netdevice.h
>> +++ b/include/linux/netdevice.h
>> @@ -767,6 +767,8 @@ struct netdev_phys_item_id {
>> typedef u16 (*select_queue_fallback_t)(struct net_device *dev,
>> struct sk_buff *skb);
>> +struct fib_info;
>> +
>> /*
>> * This structure defines the management hooks for network devices.
>> * The following hooks can be defined; unless noted otherwise, they are
>> @@ -1030,6 +1032,14 @@ typedef u16 (*select_queue_fallback_t)(struct
>> net_device *dev,
>> * int (*ndo_switch_port_stp_update)(struct net_device *dev, u8 state);
>> * Called to notify switch device port of bridge port STP
>> * state change.
>> + * int (*ndo_sw_parent_fib_ipv4_add)(struct net_device *dev, __be32 dst,
>> + * int dst_len, struct fib_info *fi,
>> + * u8 tos, u8 type, u32 tb_id);
>> + * Called to add IPv4 route to switch device.
>> + * int (*ndo_sw_parent_fib_ipv4_del)(struct net_device *dev, __be32 dst,
>> + * int dst_len, struct fib_info *fi,
>> + * u8 tos, u8 type, u32 tb_id);
>> + * Called to delete IPv4 route from switch device.
>> */
>> struct net_device_ops {
>> int (*ndo_init)(struct net_device *dev);
>> @@ -1189,6 +1199,18 @@ struct net_device_ops {
>> struct
>> netdev_phys_item_id *psid);
>> int (*ndo_switch_port_stp_update)(struct
>> net_device *dev,
>> u8 state);
>> + int (*ndo_switch_fib_ipv4_add)(struct
>> net_device *dev,
>> + __be32 dst,
>> + int dst_len,
>> + struct fib_info
>> *fi,
>> + u8 tos, u8
>> type,
>> + u32 tb_id);
>> + int (*ndo_switch_fib_ipv4_del)(struct
>> net_device *dev,
>> + __be32 dst,
>> + int dst_len,
>> + struct fib_info
>> *fi,
>> + u8 tos, u8
>> type,
>> + u32 tb_id);
>> #endif
>> };
>> diff --git a/include/net/switchdev.h b/include/net/switchdev.h
>> index 8a6d164..caebc2a 100644
>> --- a/include/net/switchdev.h
>> +++ b/include/net/switchdev.h
>> @@ -17,6 +17,10 @@
>> int netdev_switch_parent_id_get(struct net_device *dev,
>> struct netdev_phys_item_id *psid);
>> int netdev_switch_port_stp_update(struct net_device *dev, u8 state);
>> +int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi,
>> + u8 tos, u8 type, u32 tb_id);
>> +int netdev_switch_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi,
>> + u8 tos, u8 type, u32 tb_id);
>> #else
>> @@ -32,6 +36,20 @@ static inline int
>> netdev_switch_port_stp_update(struct net_device *dev,
>> return -EOPNOTSUPP;
>> }
>> +static inline int netdev_switch_fib_ipv4_add(u32 dst, int dst_len,
>> + struct fib_info *fi,
>> + u8 tos, u8 type, u32 tb_id)
>> +{
>> + return -EOPNOTSUPP;
>> +}
>> +
>> +static inline int netdev_switch_fib_ipv4_del(u32 dst, int dst_len,
>> + struct fib_info *fi,
>> + u8 tos, u8 type, u32 tb_id)
>> +{
>> + return -EOPNOTSUPP;
>> +}
>> +
>> #endif
>> #endif /* _LINUX_SWITCHDEV_H_ */
>> diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
>> index 281e5e0..ea2dc17 100644
>> --- a/net/ipv4/fib_trie.c
>> +++ b/net/ipv4/fib_trie.c
>> @@ -79,6 +79,7 @@
>> #include <net/tcp.h>
>> #include <net/sock.h>
>> #include <net/ip_fib.h>
>> +#include <net/switchdev.h>
>> #include "fib_lookup.h"
>> #define MAX_STAT_DEPTH 32
>> @@ -1201,6 +1202,8 @@ int fib_table_insert(struct fib_table *tb, struct
>> fib_config *cfg)
>> fib_release_info(fi_drop);
>> if (state & FA_S_ACCESSED)
>> rt_cache_flush(cfg->fc_nlinfo.nl_net);
>> + netdev_switch_fib_ipv4_add(key, plen, fi,
>> fa->fa_tos,
>> + cfg->fc_type,
>> tb->tb_id);
>> rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen,
>> tb->tb_id, &cfg->fc_nlinfo,
>> NLM_F_REPLACE);
>> @@ -1229,6 +1232,13 @@ int fib_table_insert(struct fib_table *tb, struct
>> fib_config *cfg)
>> new_fa->fa_tos = tos;
>> new_fa->fa_type = cfg->fc_type;
>> new_fa->fa_state = 0;
>> +
>> + /* (Optionally) offload fib info to switch hardware. */
>> + err = netdev_switch_fib_ipv4_add(key, plen, fi, tos,
>> + cfg->fc_type, tb->tb_id);
>> + if (err && err != -EOPNOTSUPP)
>> + goto out_free_new_fa;
>> +
>> /*
>> * Insert new entry to the list.
>> */
>> @@ -1237,7 +1247,7 @@ int fib_table_insert(struct fib_table *tb, struct
>> fib_config *cfg)
>> fa_head = fib_insert_node(t, key, plen);
>> if (unlikely(!fa_head)) {
>> err = -ENOMEM;
>> - goto out_free_new_fa;
>> + goto out_sw_fib_del;
>> }
>> }
>> @@ -1253,6 +1263,8 @@ int fib_table_insert(struct fib_table *tb, struct
>> fib_config *cfg)
>> succeeded:
>> return 0;
>> +out_sw_fib_del:
>> + netdev_switch_fib_ipv4_del(key, plen, fi, tos, cfg->fc_type,
>> tb->tb_id);
>> out_free_new_fa:
>> kmem_cache_free(fn_alias_kmem, new_fa);
>> out:
>> @@ -1529,6 +1541,9 @@ int fib_table_delete(struct fib_table *tb, struct
>> fib_config *cfg)
>> rtmsg_fib(RTM_DELROUTE, htonl(key), fa, plen, tb->tb_id,
>> &cfg->fc_nlinfo, 0);
>> + netdev_switch_fib_ipv4_del(key, plen, fa->fa_info, tos,
>> + cfg->fc_type, tb->tb_id);
>> +
>> list_del_rcu(&fa->fa_list);
>> if (!plen)
>> diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
>> index d162b21..211a8a0 100644
>> --- a/net/switchdev/switchdev.c
>> +++ b/net/switchdev/switchdev.c
>> @@ -12,6 +12,7 @@
>> #include <linux/types.h>
>> #include <linux/init.h>
>> #include <linux/netdevice.h>
>> +#include <net/ip_fib.h>
>> #include <net/switchdev.h>
>> /**
>> @@ -50,3 +51,91 @@ int netdev_switch_port_stp_update(struct net_device
>> *dev, u8 state)
>> return ops->ndo_switch_port_stp_update(dev, state);
>> }
>> EXPORT_SYMBOL(netdev_switch_port_stp_update);
>> +
>> +static struct net_device *netdev_switch_get_by_fib_dev(struct net_device
>> *dev)
>> +{
>> + const struct net_device_ops *ops = dev->netdev_ops;
>> + struct net_device *lower_dev;
>> + struct net_device *port_dev;
>> + struct list_head *iter;
>> +
>> + /* Recusively search from fib_dev down until we find
>> + * a sw port dev. (A sw port dev supports
>> + * ndo_switch_parent_id_get).
>> + */
>> +
>> + if (ops->ndo_switch_parent_id_get)
>> + return dev;
>> +
>> + netdev_for_each_lower_dev(dev, lower_dev, iter) {
>> + port_dev = netdev_switch_get_by_fib_dev(lower_dev);
>> + if (port_dev)
>> + return port_dev;
>> + }
>> +
>> + return NULL;
>> +}
>> +
>> +/**
>> + * netdev_switch_fib_ipv4_add - Add IPv4 route entry to switch
>> + *
>> + * @dst: route's IPv4 destination address
>> + * @dst_len: destination address length (prefix length)
>> + * @fi: route FIB info structure
>> + * @tos: route TOS
>> + * @type: route type
>> + * @tb_id: route table ID
>> + *
>> + * Add IPv4 route entry to switch device.
>> + */
>> +int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi,
>> + u8 tos, u8 type, u32 tb_id)
>> +{
>> + struct net_device *dev;
>> + const struct net_device_ops *ops;
>> + int err = -EOPNOTSUPP;
>> +
>> + dev = netdev_switch_get_by_fib_dev(fi->fib_dev);
>> + if (!dev)
>> + return -EOPNOTSUPP;
>> + ops = dev->netdev_ops;
>> +
>> + if (ops->ndo_switch_fib_ipv4_add)
>> + err = ops->ndo_switch_fib_ipv4_add(dev, htonl(dst),
>> dst_len,
>> + fi, tos, type, tb_id);
>> +
>> + return err;
>> +}
>> +EXPORT_SYMBOL(netdev_switch_fib_ipv4_add);
>> +
>> +/**
>> + * netdev_switch_fib_ipv4_del - Delete IPv4 route entry from switch
>> + *
>> + * @dst: route's IPv4 destination address
>> + * @dst_len: destination address length (prefix length)
>> + * @fi: route FIB info structure
>> + * @tos: route TOS
>> + * @type: route type
>> + * @tb_id: route table ID
>> + *
>> + * Delete IPv4 route entry from switch device.
>> + */
>> +int netdev_switch_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi,
>> + u8 tos, u8 type, u32 tb_id)
>> +{
>> + struct net_device *dev;
>> + const struct net_device_ops *ops;
>> + int err = -EOPNOTSUPP;
>> +
>> + dev = netdev_switch_get_by_fib_dev(fi->fib_dev);
>> + if (!dev)
>> + return -EOPNOTSUPP;
>> + ops = dev->netdev_ops;
>> +
>> + if (ops->ndo_switch_fib_ipv4_del)
>> + err = ops->ndo_switch_fib_ipv4_del(dev, htonl(dst),
>> dst_len,
>> + fi, tos, type, tb_id);
>> +
>> + return err;
>> +}
>> +EXPORT_SYMBOL(netdev_switch_fib_ipv4_del);
>
>
^ permalink raw reply
* [PATCH] drivers:net:wireless: Add proper locking for the function, b43_op_beacon_set_tim in main.c
From: Nicholas Krause @ 2015-01-02 7:34 UTC (permalink / raw)
To: stefano.brivio-hl5o88x/ua9eoWH0uzbU5w
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
b43-dev-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
kvalo-sgV2jX0FEOL9JmXXK+q4OQ, linux-kernel-u79uwXL29TY76Z2rM5mHXA
This adds proper locking for the function, b43_op_beacon_set_tim in main.c by using the mutex lock
in the structure pointer wl, as embedded into this pointer as a mutex in order to protect against
multiple access to the pointer wl when updating the templates for this pointer in the function,
b43_update_templates internally in the function, b43_op_beacon_set_tim.
Signed-off-by: Nicholas Krause <xerofoify-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
drivers/net/wireless/b43/main.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 47731cb..d568fc8 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -5094,8 +5094,9 @@ static int b43_op_beacon_set_tim(struct ieee80211_hw *hw,
{
struct b43_wl *wl = hw_to_b43_wl(hw);
- /* FIXME: add locking */
+ mutex_lock(&wl->mutex);
b43_update_templates(wl);
+ mutex_unlock(&wl->mutex);
return 0;
}
--
2.1.0
^ permalink raw reply related
* Re: [PATCH net-next 0/7] Fixing the "Time Counter fixes and improvements"
From: Richard Cochran @ 2015-01-02 6:14 UTC (permalink / raw)
To: Sedat Dilek; +Cc: David Miller, netdev@vger.kernel.org
In-Reply-To: <CA+icZUXF6-_W6=YsajP4W84F5yvKCNtA3EYxKBgNS=aY4qAYPg@mail.gmail.com>
On Thu, Jan 01, 2015 at 05:30:58PM +0100, Sedat Dilek wrote:
> With this conversion those 2 commits in net-next.git#master are obsolete now...
>
> e1000e: Include clocksource.h to get CLOCKSOURCE_MASK.
> igb_ptp: Include clocksource.h to get CLOCKSOURCE_MASK.
Right. Okay, I'll rework this series to undo the obsolete includes.
Thanks,
Richard
^ permalink raw reply
* Re: [PATCH net-next 1/3] net: add IPv4 routing FIB support for swdev
From: roopa @ 2015-01-02 5:49 UTC (permalink / raw)
To: sfeldma; +Cc: netdev, jiri, john.fastabend, tgraf, jhs, andy
In-Reply-To: <1420169361-31767-2-git-send-email-sfeldma@gmail.com>
On 1/1/15, 7:29 PM, sfeldma@gmail.com wrote:
> From: Scott Feldman <sfeldma@gmail.com>
>
> To offload IPv4 L3 routing functions to swdev device, the swdev device driver
> implements two new ndo ops (ndo_switch_fib_ipv4_add/del). The ops are called
> by the core IPv4 FIB code when installing/removing FIB entries to/from the
> kernel FIB. On install, the driver should return 0 if FIB entry (route) can be
> installed to device for offloading, -EOPNOTSUPP if route cannot be installed
> due to device limitations, and other negative error code on failure to install
> route to device. On failure error code, the route is not installed to device,
> and not installed in kernel FIB, and the return code is propagated back to the
> user-space caller (via netlink). An -EOPNOTSUPP error code is skipped for the
> device but installed in the kernel FIB.
>
> The FIB entry (route) nexthop list is used to find the swdev device port to
> anchor the ndo op call. The route's fib_dev (the first nexthop's dev) is used
> find the swdev port by recursively traversing the fib_dev's lower_dev list
> until a swdev port is found. The ndo op is called on this swdev port.
scott, I posted a similar api for bridge attribute sets. But, nobody
supported it.
http://marc.info/?l=linux-netdev&m=141820234410602&w=2
If this is acceptable, I will be resubmitting my api as well.
>
> Since the FIB entry is "naked" when push from the kernel, the driver/device
> is responsible for resolving the route's nexthops to neighbor MAC addresses.
> This can be done by the driver by monitoring NETEVENT_NEIGH_UPDATE
> netevent notifier to watch for ARP activity. Once a nexthop is resolved to
> neighbor MAC address, it can be installed to the device and the device will
> do the L3 routing offload in HW, for that nexthop.
>
> Signed-off-by: Scott Feldman <sfeldma@gmail.com>
> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
> ---
> include/linux/netdevice.h | 22 +++++++++++
> include/net/switchdev.h | 18 +++++++++
> net/ipv4/fib_trie.c | 17 ++++++++-
> net/switchdev/switchdev.c | 89 +++++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 145 insertions(+), 1 deletion(-)
>
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index 679e6e9..b66d22b 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -767,6 +767,8 @@ struct netdev_phys_item_id {
> typedef u16 (*select_queue_fallback_t)(struct net_device *dev,
> struct sk_buff *skb);
>
> +struct fib_info;
> +
> /*
> * This structure defines the management hooks for network devices.
> * The following hooks can be defined; unless noted otherwise, they are
> @@ -1030,6 +1032,14 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev,
> * int (*ndo_switch_port_stp_update)(struct net_device *dev, u8 state);
> * Called to notify switch device port of bridge port STP
> * state change.
> + * int (*ndo_sw_parent_fib_ipv4_add)(struct net_device *dev, __be32 dst,
> + * int dst_len, struct fib_info *fi,
> + * u8 tos, u8 type, u32 tb_id);
> + * Called to add IPv4 route to switch device.
> + * int (*ndo_sw_parent_fib_ipv4_del)(struct net_device *dev, __be32 dst,
> + * int dst_len, struct fib_info *fi,
> + * u8 tos, u8 type, u32 tb_id);
> + * Called to delete IPv4 route from switch device.
> */
> struct net_device_ops {
> int (*ndo_init)(struct net_device *dev);
> @@ -1189,6 +1199,18 @@ struct net_device_ops {
> struct netdev_phys_item_id *psid);
> int (*ndo_switch_port_stp_update)(struct net_device *dev,
> u8 state);
> + int (*ndo_switch_fib_ipv4_add)(struct net_device *dev,
> + __be32 dst,
> + int dst_len,
> + struct fib_info *fi,
> + u8 tos, u8 type,
> + u32 tb_id);
> + int (*ndo_switch_fib_ipv4_del)(struct net_device *dev,
> + __be32 dst,
> + int dst_len,
> + struct fib_info *fi,
> + u8 tos, u8 type,
> + u32 tb_id);
> #endif
> };
>
> diff --git a/include/net/switchdev.h b/include/net/switchdev.h
> index 8a6d164..caebc2a 100644
> --- a/include/net/switchdev.h
> +++ b/include/net/switchdev.h
> @@ -17,6 +17,10 @@
> int netdev_switch_parent_id_get(struct net_device *dev,
> struct netdev_phys_item_id *psid);
> int netdev_switch_port_stp_update(struct net_device *dev, u8 state);
> +int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi,
> + u8 tos, u8 type, u32 tb_id);
> +int netdev_switch_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi,
> + u8 tos, u8 type, u32 tb_id);
>
> #else
>
> @@ -32,6 +36,20 @@ static inline int netdev_switch_port_stp_update(struct net_device *dev,
> return -EOPNOTSUPP;
> }
>
> +static inline int netdev_switch_fib_ipv4_add(u32 dst, int dst_len,
> + struct fib_info *fi,
> + u8 tos, u8 type, u32 tb_id)
> +{
> + return -EOPNOTSUPP;
> +}
> +
> +static inline int netdev_switch_fib_ipv4_del(u32 dst, int dst_len,
> + struct fib_info *fi,
> + u8 tos, u8 type, u32 tb_id)
> +{
> + return -EOPNOTSUPP;
> +}
> +
> #endif
>
> #endif /* _LINUX_SWITCHDEV_H_ */
> diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
> index 281e5e0..ea2dc17 100644
> --- a/net/ipv4/fib_trie.c
> +++ b/net/ipv4/fib_trie.c
> @@ -79,6 +79,7 @@
> #include <net/tcp.h>
> #include <net/sock.h>
> #include <net/ip_fib.h>
> +#include <net/switchdev.h>
> #include "fib_lookup.h"
>
> #define MAX_STAT_DEPTH 32
> @@ -1201,6 +1202,8 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
> fib_release_info(fi_drop);
> if (state & FA_S_ACCESSED)
> rt_cache_flush(cfg->fc_nlinfo.nl_net);
> + netdev_switch_fib_ipv4_add(key, plen, fi, fa->fa_tos,
> + cfg->fc_type, tb->tb_id);
> rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen,
> tb->tb_id, &cfg->fc_nlinfo, NLM_F_REPLACE);
>
> @@ -1229,6 +1232,13 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
> new_fa->fa_tos = tos;
> new_fa->fa_type = cfg->fc_type;
> new_fa->fa_state = 0;
> +
> + /* (Optionally) offload fib info to switch hardware. */
> + err = netdev_switch_fib_ipv4_add(key, plen, fi, tos,
> + cfg->fc_type, tb->tb_id);
> + if (err && err != -EOPNOTSUPP)
> + goto out_free_new_fa;
> +
> /*
> * Insert new entry to the list.
> */
> @@ -1237,7 +1247,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
> fa_head = fib_insert_node(t, key, plen);
> if (unlikely(!fa_head)) {
> err = -ENOMEM;
> - goto out_free_new_fa;
> + goto out_sw_fib_del;
> }
> }
>
> @@ -1253,6 +1263,8 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
> succeeded:
> return 0;
>
> +out_sw_fib_del:
> + netdev_switch_fib_ipv4_del(key, plen, fi, tos, cfg->fc_type, tb->tb_id);
> out_free_new_fa:
> kmem_cache_free(fn_alias_kmem, new_fa);
> out:
> @@ -1529,6 +1541,9 @@ int fib_table_delete(struct fib_table *tb, struct fib_config *cfg)
> rtmsg_fib(RTM_DELROUTE, htonl(key), fa, plen, tb->tb_id,
> &cfg->fc_nlinfo, 0);
>
> + netdev_switch_fib_ipv4_del(key, plen, fa->fa_info, tos,
> + cfg->fc_type, tb->tb_id);
> +
> list_del_rcu(&fa->fa_list);
>
> if (!plen)
> diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
> index d162b21..211a8a0 100644
> --- a/net/switchdev/switchdev.c
> +++ b/net/switchdev/switchdev.c
> @@ -12,6 +12,7 @@
> #include <linux/types.h>
> #include <linux/init.h>
> #include <linux/netdevice.h>
> +#include <net/ip_fib.h>
> #include <net/switchdev.h>
>
> /**
> @@ -50,3 +51,91 @@ int netdev_switch_port_stp_update(struct net_device *dev, u8 state)
> return ops->ndo_switch_port_stp_update(dev, state);
> }
> EXPORT_SYMBOL(netdev_switch_port_stp_update);
> +
> +static struct net_device *netdev_switch_get_by_fib_dev(struct net_device *dev)
> +{
> + const struct net_device_ops *ops = dev->netdev_ops;
> + struct net_device *lower_dev;
> + struct net_device *port_dev;
> + struct list_head *iter;
> +
> + /* Recusively search from fib_dev down until we find
> + * a sw port dev. (A sw port dev supports
> + * ndo_switch_parent_id_get).
> + */
> +
> + if (ops->ndo_switch_parent_id_get)
> + return dev;
> +
> + netdev_for_each_lower_dev(dev, lower_dev, iter) {
> + port_dev = netdev_switch_get_by_fib_dev(lower_dev);
> + if (port_dev)
> + return port_dev;
> + }
> +
> + return NULL;
> +}
> +
> +/**
> + * netdev_switch_fib_ipv4_add - Add IPv4 route entry to switch
> + *
> + * @dst: route's IPv4 destination address
> + * @dst_len: destination address length (prefix length)
> + * @fi: route FIB info structure
> + * @tos: route TOS
> + * @type: route type
> + * @tb_id: route table ID
> + *
> + * Add IPv4 route entry to switch device.
> + */
> +int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi,
> + u8 tos, u8 type, u32 tb_id)
> +{
> + struct net_device *dev;
> + const struct net_device_ops *ops;
> + int err = -EOPNOTSUPP;
> +
> + dev = netdev_switch_get_by_fib_dev(fi->fib_dev);
> + if (!dev)
> + return -EOPNOTSUPP;
> + ops = dev->netdev_ops;
> +
> + if (ops->ndo_switch_fib_ipv4_add)
> + err = ops->ndo_switch_fib_ipv4_add(dev, htonl(dst), dst_len,
> + fi, tos, type, tb_id);
> +
> + return err;
> +}
> +EXPORT_SYMBOL(netdev_switch_fib_ipv4_add);
> +
> +/**
> + * netdev_switch_fib_ipv4_del - Delete IPv4 route entry from switch
> + *
> + * @dst: route's IPv4 destination address
> + * @dst_len: destination address length (prefix length)
> + * @fi: route FIB info structure
> + * @tos: route TOS
> + * @type: route type
> + * @tb_id: route table ID
> + *
> + * Delete IPv4 route entry from switch device.
> + */
> +int netdev_switch_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi,
> + u8 tos, u8 type, u32 tb_id)
> +{
> + struct net_device *dev;
> + const struct net_device_ops *ops;
> + int err = -EOPNOTSUPP;
> +
> + dev = netdev_switch_get_by_fib_dev(fi->fib_dev);
> + if (!dev)
> + return -EOPNOTSUPP;
> + ops = dev->netdev_ops;
> +
> + if (ops->ndo_switch_fib_ipv4_del)
> + err = ops->ndo_switch_fib_ipv4_del(dev, htonl(dst), dst_len,
> + fi, tos, type, tb_id);
> +
> + return err;
> +}
> +EXPORT_SYMBOL(netdev_switch_fib_ipv4_del);
^ permalink raw reply
* Re: [PATCH net-next 0/3] swdev: add IPv4 routing offload
From: Dave Taht @ 2015-01-02 5:11 UTC (permalink / raw)
To: Scott Feldman
Cc: netdev@vger.kernel.org, jiri, john fastabend, Thomas Graf,
Jamal Hadi Salim, andy, roopa, David Lamparter
In-Reply-To: <1420169361-31767-1-git-send-email-sfeldma@gmail.com>
On Thu, Jan 1, 2015 at 7:29 PM, <sfeldma@gmail.com> wrote:
> From: Scott Feldman <sfeldma@gmail.com>
>
> This patch set adds L3 routing offload support for IPv4 routes. The idea is to
> mirror routes installed in the kernel's FIB down to a hardware switch device to
> offload the data forwarding path for L3. Only the data forwarding path is
> intercepted. Control and management of the kernel's FIB remains with the
> kernel.
>
> A couple of new ndo ops (ndo_switch_fib_ipv4_add/del) are added to the swdev
> model to add/remove FIB entries to/from the offload device. The ops are called
> from the core IPv4 FIB code directly. Just before the FIB entry is installed
> in the kernel's FIB, the swdev device driver gets a chance at the FIB entry
> (assuming the swdev driver implements the new ndo ops). This is a synchronous
> call in the RTM_NEWROUTE path, and the swdev has the option to fail the
> install, which means the FIB entry is not installed in swdev or the kernel, and
> the user is notified of the failure. The swdev driver also has the option to
> return -EOPNOTSUPP to pass on the FIB entry, so it'll only be installed in the
> kernel FIB.
A couple notes:
1) As currently implemented in quagga, (to my knowledge), an actual
route change is actually a route delete/route add rather than an
atomic route modify or route add/route delete. While it would be nice
to fix quagga to do it atomically (and for all I know some fork does
it right?), I am curious as to the extent of serialization during the
process like this in the virtual switch. (and it does not appear you
have tested the ip route change commands above, or beat up quagga's
routing decisions)
2) It is generally helpful to be concurrently running the max traffic
you can sustain through the switch, while doing fib changes... and
observing what happens to that traffic.
3) As you attempt ipv6, life gets more complex. (you need to switch to
a later routing protocol in particular...)
4) There's a new idea on the block: Source specific routing (sometimes
called SADR) is mandated by the ietf homenet working group, in
particular, which relies on IPV6_subtrees, and link local ipv6
multicast. the code furthest enough along is babels
(http://www.pps.univ-paris-diderot.fr/~jch/software/babel/
https://github.com/boutier/babeld also with patches for quagga) which,
being easy to setup, might be a good exercise of both link local
multicast and of ipv6 in the virtual switch itself, as well as
exercising the fib. (ospfv3 and ISIS also have support for source
specific routing in various branches.)
>
> The FIB flush path is modified also to call into the swdev driver to flush the
> FIB entries from hardware.
>
> The rocker swdev driver is updated to support these new ndo ops. Right now
> rocker only supports IPv4 singlepath routes, but follow-on patches will add
> IPv6 and ECMP support. Also, only unicast IPv4 routes are supported, but
> follow-on patches will add multicast route support.
>
> Testing was done in my simulated network envionment using VMs and the rocker
> device. I'm using Quagga OSPFv2 for the routing protocol for automatic control
> plane processing. No modifications to Quagga or netlink/iproute2 is required;
> it just works.
>
> One important metric is the time spent installing/removing FIB entries from the
> kernel and the device. With these patches applied, I measured the wall time
> required to install and remove 10K IPv4 routes. I used ip route add cmd in
> batch mode to install static routes. I used the ip route flush cmd to delete
> the routes. This is 10000 routes installed to the kernel's FIB and to the
> swdev device's L3 tables. And then removed from each. The performance is less
> than a second for each operation. This is on my simulated rocker device running
> on a VM, so a real embedded CPU would probably do much better.
>
> My batch has 10K lines of:
>
> simp@simp:~$ head east
> route add 16.0.0.0/32 nexthop via 11.0.0.2 dev swp1
> route add 16.0.0.1/32 nexthop via 11.0.0.2 dev swp1
> route add 16.0.0.2/32 nexthop via 11.0.0.2 dev swp1
> route add 16.0.0.3/32 nexthop via 11.0.0.2 dev swp1
> route add 16.0.0.4/32 nexthop via 11.0.0.2 dev swp1
> route add 16.0.0.5/32 nexthop via 11.0.0.2 dev swp1
> route add 16.0.0.6/32 nexthop via 11.0.0.2 dev swp1
> route add 16.0.0.7/32 nexthop via 11.0.0.2 dev swp1
> route add 16.0.0.8/32 nexthop via 11.0.0.2 dev swp1
> route add 16.0.0.9/32 nexthop via 11.0.0.2 dev swp1
> [...]
>
> Install/removing routes:
>
> simp@simp:~$ wc -l east
> 10000 east
> simp@simp:~$ ip route show root 16/8 | wc -l
> 0
> simp@simp:~$ time sudo ip --batch east
>
> real 0m0.715s
> user 0m0.092s
> sys 0m0.388s
> simp@simp:~$ ip route show root 16/8 | wc -l
> 10000
>
> [At this point, 10K routes are installed in kernel and the device]
>
> simp@simp:~$ time sudo ip route flush root 16/8
>
> real 0m0.458s
> user 0m0.000s
> sys 0m0.284s
> simp@simp:~$ ip route show root 16/8 | wc -l
> 0
>
> [All gone]
>
> Scott Feldman (3):
> net: add IPv4 routing FIB support for swdev
> net: call swdev fib del for flushed routes
> rocker: implement IPv4 fib offloading
>
> drivers/net/ethernet/rocker/rocker.c | 441 +++++++++++++++++++++++++++++++++-
> include/linux/netdevice.h | 22 ++
> include/net/switchdev.h | 18 ++
> net/ipv4/fib_trie.c | 31 ++-
> net/switchdev/switchdev.c | 89 +++++++
> 5 files changed, 592 insertions(+), 9 deletions(-)
>
> --
> 1.7.10.4
>
> --
> 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
--
Dave Täht
thttp://www.bufferbloat.net/projects/bloat/wiki/Upcoming_Talks
^ permalink raw reply
* [PATCH net-next 3/3] rocker: implement IPv4 fib offloading
From: sfeldma @ 2015-01-02 3:29 UTC (permalink / raw)
To: netdev, jiri, john.fastabend, tgraf, jhs, andy, roopa
From: Scott Feldman <sfeldma@gmail.com>
The driver implements ndo_switch_fib_ipv4_add/del ops to add/del IPv4 routes
to/from swdev device. Once a route is added to the device, and the route's
nexthops are resolved to neighbor MAC address, the device will forward matching
pkts rather than the kernel. This offloads the L3 forwarding path from the
kernel to the device. Note that control and management planes are still
mananged by Linux; only the data plane is offloaded. Standard routing control
protocols such as OSPF and BGP run on Linux and manage the kernel's FIB via
standard rtm netlink msgs.
A new hash table is added to rocker to track neighbors. The driver listens for
neighbor updates events using netevent notifier NETEVENT_NEIGH_UPDATE. Any ARP
table updates for ports on this device are recorded in this table. Routes
installed to the device with nexthops that reference neighbors in this table
are "qualified". In the case of a route with nexthops not resolved in the
table, a kernel thread is started to ARP-ping the neighbor proactively to
resolve the MAC address for the neighbor. The driver uses arp_send() to send
the ARP request to resolve the MAC address, every 2 seconds until resolved.
Once resolved, the kernel thread is stopped.
The device can only forward to pkts matching route dst to resolved nexthops.
Currently, the device only supports single-path routes (i.e. routes with one
nexthop). Multipath (ECMP) route support will be added in followup patches.
This patch is driver support for unicast IPv4 routing only. Followup patches
will add driver and infrastructure for IPv6 routing and multicast routing.
Signed-off-by: Scott Feldman <sfeldma@gmail.com>
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
drivers/net/ethernet/rocker/rocker.c | 441 +++++++++++++++++++++++++++++++++-
1 file changed, 438 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/rocker/rocker.c b/drivers/net/ethernet/rocker/rocker.c
index 2f398fa..c554816 100644
--- a/drivers/net/ethernet/rocker/rocker.c
+++ b/drivers/net/ethernet/rocker/rocker.c
@@ -32,6 +32,9 @@
#include <linux/bitops.h>
#include <net/switchdev.h>
#include <net/rtnetlink.h>
+#include <net/ip_fib.h>
+#include <net/netevent.h>
+#include <net/arp.h>
#include <asm-generic/io-64-nonatomic-lo-hi.h>
#include <generated/utsrelease.h>
@@ -161,6 +164,19 @@ struct rocker_internal_vlan_tbl_entry {
__be16 vlan_id;
};
+struct rocker_neigh_tbl_entry {
+ struct hlist_node entry;
+ __be32 ip_addr; /* key */
+ struct net_device *dev;
+ u32 ref_count;
+ u32 index;
+ u8 eth_dst[ETH_ALEN];
+ bool ttl_check;
+ struct delayed_work arp_work;
+ unsigned long arp_delay;
+ bool arp_running;
+};
+
struct rocker_desc_info {
char *data; /* mapped */
size_t data_size;
@@ -234,6 +250,9 @@ struct rocker {
unsigned long internal_vlan_bitmap[ROCKER_INTERNAL_VLAN_BITMAP_LEN];
DECLARE_HASHTABLE(internal_vlan_tbl, 8);
spinlock_t internal_vlan_tbl_lock;
+ DECLARE_HASHTABLE(neigh_tbl, 16);
+ spinlock_t neigh_tbl_lock;
+ u32 neigh_tbl_next_index;
};
static const u8 zero_mac[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
@@ -2145,9 +2164,9 @@ static int rocker_cmd_group_tbl_del(struct rocker *rocker,
return 0;
}
-/*****************************************
- * Flow, group, FDB, internal VLAN tables
- *****************************************/
+/***************************************************
+ * Flow, group, FDB, internal VLAN and neigh tables
+ ***************************************************/
static int rocker_init_tbls(struct rocker *rocker)
{
@@ -2163,6 +2182,9 @@ static int rocker_init_tbls(struct rocker *rocker)
hash_init(rocker->internal_vlan_tbl);
spin_lock_init(&rocker->internal_vlan_tbl_lock);
+ hash_init(rocker->neigh_tbl);
+ spin_lock_init(&rocker->neigh_tbl_lock);
+
return 0;
}
@@ -2173,6 +2195,7 @@ static void rocker_free_tbls(struct rocker *rocker)
struct rocker_group_tbl_entry *group_entry;
struct rocker_fdb_tbl_entry *fdb_entry;
struct rocker_internal_vlan_tbl_entry *internal_vlan_entry;
+ struct rocker_neigh_tbl_entry *neigh_entry;
struct hlist_node *tmp;
int bkt;
@@ -2196,6 +2219,11 @@ static void rocker_free_tbls(struct rocker *rocker)
tmp, internal_vlan_entry, entry)
hash_del(&internal_vlan_entry->entry);
spin_unlock_irqrestore(&rocker->internal_vlan_tbl_lock, flags);
+
+ spin_lock_irqsave(&rocker->neigh_tbl_lock, flags);
+ hash_for_each_safe(rocker->neigh_tbl, bkt, tmp, neigh_entry, entry)
+ hash_del(&neigh_entry->entry);
+ spin_unlock_irqrestore(&rocker->neigh_tbl_lock, flags);
}
static struct rocker_flow_tbl_entry *
@@ -2444,6 +2472,29 @@ static int rocker_flow_tbl_bridge(struct rocker_port *rocker_port,
return rocker_flow_tbl_do(rocker_port, flags, entry);
}
+static int rocker_flow_tbl_ucast4_routing(struct rocker_port *rocker_port,
+ __be16 eth_type, __be32 dst,
+ __be32 dst_mask,
+ enum rocker_of_dpa_table_id goto_tbl,
+ u32 group_id, int flags)
+{
+ struct rocker_flow_tbl_entry *entry;
+
+ entry = kzalloc(sizeof(*entry), rocker_op_flags_gfp(flags));
+ if (!entry)
+ return -ENOMEM;
+
+ entry->key.tbl_id = ROCKER_OF_DPA_TABLE_ID_UNICAST_ROUTING;
+ entry->key.priority = ROCKER_PRIORITY_UNICAST_ROUTING;
+ entry->key.ucast_routing.eth_type = eth_type;
+ entry->key.ucast_routing.dst4 = dst;
+ entry->key.ucast_routing.dst4_mask = dst_mask;
+ entry->key.ucast_routing.goto_tbl = goto_tbl;
+ entry->key.ucast_routing.group_id = group_id;
+
+ return rocker_flow_tbl_do(rocker_port, flags, entry);
+}
+
static int rocker_flow_tbl_acl(struct rocker_port *rocker_port,
int flags, u32 in_lport,
u32 in_lport_mask,
@@ -2652,6 +2703,232 @@ static int rocker_group_l2_flood(struct rocker_port *rocker_port,
group_id);
}
+static int rocker_group_l3_unicast(struct rocker_port *rocker_port,
+ int flags, u32 index, u8 *src_mac,
+ u8 *dst_mac, __be16 vlan_id,
+ bool ttl_check, u32 lport)
+{
+ struct rocker_group_tbl_entry *entry;
+
+ entry = kzalloc(sizeof(*entry), rocker_op_flags_gfp(flags));
+ if (!entry)
+ return -ENOMEM;
+
+ entry->group_id = ROCKER_GROUP_L3_UNICAST(index);
+ if (src_mac)
+ ether_addr_copy(entry->l3_unicast.eth_src, src_mac);
+ if (dst_mac)
+ ether_addr_copy(entry->l3_unicast.eth_dst, dst_mac);
+ entry->l3_unicast.vlan_id = vlan_id;
+ entry->l3_unicast.ttl_check = ttl_check;
+ entry->l3_unicast.group_id = ROCKER_GROUP_L2_INTERFACE(vlan_id, lport);
+
+ return rocker_group_tbl_do(rocker_port, flags, entry);
+}
+
+static struct rocker_neigh_tbl_entry *
+ rocker_neigh_tbl_find(struct rocker *rocker, __be32 ip_addr)
+{
+ struct rocker_neigh_tbl_entry *found;
+
+ hash_for_each_possible(rocker->neigh_tbl, found, entry, ip_addr)
+ if (found->ip_addr == ip_addr)
+ return found;
+
+ return NULL;
+}
+
+static void _rocker_neigh_add(struct rocker *rocker,
+ struct rocker_neigh_tbl_entry *entry)
+{
+ entry->index = rocker->neigh_tbl_next_index++;
+ entry->ref_count++;
+ hash_add(rocker->neigh_tbl, &entry->entry, entry->ip_addr);
+}
+
+static void _rocker_neigh_del(struct rocker *rocker,
+ struct rocker_neigh_tbl_entry *entry)
+{
+ if (--entry->ref_count == 0)
+ hash_del(&entry->entry);
+}
+
+static void _rocker_neigh_update(struct rocker *rocker,
+ struct rocker_neigh_tbl_entry *entry,
+ u8 *eth_dst)
+{
+ if (eth_dst)
+ ether_addr_copy(entry->eth_dst, eth_dst);
+ else
+ entry->ref_count++;
+}
+
+static void rocker_port_neigh_resolve_work(struct work_struct *work)
+{
+ struct rocker_neigh_tbl_entry *entry =
+ container_of(to_delayed_work(work),
+ struct rocker_neigh_tbl_entry, arp_work);
+
+ arp_send(ARPOP_REQUEST, ETH_P_ARP, entry->ip_addr, entry->dev,
+ entry->ip_addr, NULL, entry->dev->dev_addr, NULL);
+
+ entry->arp_delay = entry->arp_delay ? entry->arp_delay * 2 : HZ;
+ schedule_delayed_work(&entry->arp_work, entry->arp_delay);
+}
+
+static int rocker_port_neigh(struct rocker_port *rocker_port, int flags,
+ __be32 ip_addr, u8 *eth_dst)
+{
+ struct rocker *rocker = rocker_port->rocker;
+ struct rocker_neigh_tbl_entry *entry;
+ struct rocker_neigh_tbl_entry *found;
+ unsigned long lock_flags;
+ __be16 eth_type = htons(ETH_P_IP);
+ enum rocker_of_dpa_table_id goto_tbl =
+ ROCKER_OF_DPA_TABLE_ID_ACL_POLICY;
+ u32 group_id;
+ bool adding = !(flags & ROCKER_OP_FLAG_REMOVE);
+ bool updating;
+ bool removing;
+ int err = 0;
+
+ entry = kzalloc(sizeof(*entry), rocker_op_flags_gfp(flags));
+ if (!entry)
+ return -ENOMEM;
+
+ entry->ip_addr = ip_addr;
+ entry->dev = rocker_port->dev;
+ ether_addr_copy(entry->eth_dst, eth_dst);
+ entry->ttl_check = true;
+
+ spin_lock_irqsave(&rocker->neigh_tbl_lock, lock_flags);
+
+ found = rocker_neigh_tbl_find(rocker, ip_addr);
+
+ updating = found && adding;
+ removing = found && !adding;
+ adding = !found && adding;
+
+ if (adding)
+ _rocker_neigh_add(rocker, entry);
+ else if (removing)
+ _rocker_neigh_del(rocker, found);
+ else if (updating)
+ _rocker_neigh_update(rocker, found, eth_dst);
+
+ if (found)
+ kfree(entry);
+ else
+ found = entry;
+
+ if (found->arp_running) {
+ found->arp_running = false;
+ cancel_delayed_work_sync(&found->arp_work);
+ }
+
+ spin_unlock_irqrestore(&rocker->neigh_tbl_lock, lock_flags);
+
+ if (!adding && !removing && !updating)
+ return -ENOENT;
+
+ /* For each active neighbor, we have an L3 unicast group and
+ * a /32 route to the neighbor, which uses the L3 unicast
+ * group. The L3 unicast group can also be referred to by
+ * other routes' nexthops.
+ */
+
+ err = rocker_group_l3_unicast(rocker_port, flags,
+ found->index,
+ rocker_port->dev->dev_addr,
+ found->eth_dst,
+ rocker_port->internal_vlan_id,
+ found->ttl_check,
+ rocker_port->lport);
+ if (err) {
+ netdev_err(rocker_port->dev,
+ "Error (%d) L3 unicast group index %d\n",
+ err, found->index);
+ return err;
+ }
+
+ if (adding || removing) {
+ group_id = ROCKER_GROUP_L3_UNICAST(found->index);
+ err = rocker_flow_tbl_ucast4_routing(rocker_port,
+ eth_type, found->ip_addr,
+ inet_make_mask(32),
+ goto_tbl, group_id,
+ flags);
+
+ if (err)
+ netdev_err(rocker_port->dev,
+ "Error (%d) /32 unicast route %pI4 group 0x%08x\n",
+ err, &found->ip_addr, group_id);
+ }
+
+ return err;
+}
+
+static int rocker_port_nh(struct rocker_port *rocker_port, int flags,
+ __be32 ip_addr, u32 *index)
+{
+ struct rocker *rocker = rocker_port->rocker;
+ struct rocker_neigh_tbl_entry *entry;
+ struct rocker_neigh_tbl_entry *found;
+ unsigned long lock_flags;
+ bool adding = !(flags & ROCKER_OP_FLAG_REMOVE);
+ bool updating;
+ bool removing;
+ bool completed;
+
+ entry = kzalloc(sizeof(*entry), rocker_op_flags_gfp(flags));
+ if (!entry)
+ return -ENOMEM;
+
+ entry->ip_addr = ip_addr;
+ entry->dev = rocker_port->dev;
+
+ spin_lock_irqsave(&rocker->neigh_tbl_lock, lock_flags);
+
+ found = rocker_neigh_tbl_find(rocker, ip_addr);
+
+ updating = found && adding;
+ removing = found && !adding;
+ adding = !found && adding;
+
+ if (adding)
+ _rocker_neigh_add(rocker, entry);
+ else if (removing)
+ _rocker_neigh_del(rocker, found);
+ else if (updating)
+ _rocker_neigh_update(rocker, found, NULL);
+
+ if (found)
+ kfree(entry);
+ else
+ found = entry;
+
+ /* Completed means neigh ip_addr is resolved to neigh mac.
+ * If an entry is incomplete, we need to ARP to try to
+ * resolve the neigh mac.
+ */
+
+ completed = !is_zero_ether_addr(found->eth_dst);
+
+ if (!completed && !found->arp_running) {
+ INIT_DELAYED_WORK(&found->arp_work,
+ rocker_port_neigh_resolve_work);
+ found->arp_delay = 0;
+ found->arp_running = true;
+ schedule_delayed_work(&found->arp_work, found->arp_delay);
+ }
+
+ spin_unlock_irqrestore(&rocker->neigh_tbl_lock, lock_flags);
+
+ *index = found->index;
+
+ return 0;
+}
+
static int rocker_port_vlan_flood_group(struct rocker_port *rocker_port,
int flags, __be16 vlan_id)
{
@@ -3381,6 +3658,79 @@ not_found:
spin_unlock_irqrestore(&rocker->internal_vlan_tbl_lock, lock_flags);
}
+static int rocker_port_fib_ipv4(struct rocker_port *rocker_port, __be32 dst,
+ int dst_len, struct fib_info *fi, u32 tb_id,
+ int flags)
+{
+ struct fib_nh *nh = fi->fib_nh;
+ __be16 eth_type = htons(ETH_P_IP);
+ __be32 dst_mask = inet_make_mask(dst_len);
+ __be16 internal_vlan_id = rocker_port->internal_vlan_id;
+ enum rocker_of_dpa_table_id goto_tbl =
+ ROCKER_OF_DPA_TABLE_ID_ACL_POLICY;
+ u32 group_id;
+ bool nh_on_port = (fi->fib_dev == rocker_port->dev);
+ bool has_gw = !!nh->nh_gw;
+ u32 index;
+ int err;
+
+ /* XXX support ECMP */
+
+ if (has_gw && nh_on_port) {
+ err = rocker_port_nh(rocker_port, flags, nh->nh_gw, &index);
+ if (err)
+ return err;
+
+ group_id = ROCKER_GROUP_L3_UNICAST(index);
+ } else {
+ /* Send to CPU for processing */
+ group_id = ROCKER_GROUP_L2_INTERFACE(internal_vlan_id, 0);
+ }
+
+ err = rocker_flow_tbl_ucast4_routing(rocker_port,
+ eth_type, dst,
+ dst_mask, goto_tbl,
+ group_id, flags);
+ if (err)
+ netdev_err(rocker_port->dev, "Error (%d) IPv4 route %pI4\n",
+ err, &dst);
+
+ return err;
+}
+
+static int rocker_port_fib_ipv4_skip(struct net_device *dev,
+ __be32 dst, int dst_len,
+ struct fib_info *fi,
+ u8 tos, u8 type, u32 tb_id)
+{
+ if (fi->fib_flags & RTM_F_CLONED)
+ return -EOPNOTSUPP;
+
+ if (tb_id != RT_TABLE_MAIN && tb_id != RT_TABLE_LOCAL)
+ return -EOPNOTSUPP;
+
+ if (type != RTN_UNICAST && type != RTN_BLACKHOLE &&
+ type != RTN_UNREACHABLE && type != RTN_LOCAL &&
+ type != RTN_BROADCAST)
+ return -EOPNOTSUPP;
+
+ if (tb_id == RT_TABLE_MAIN && type != RTN_UNICAST &&
+ type != RTN_BLACKHOLE && type != RTN_UNREACHABLE)
+ return -EOPNOTSUPP;
+
+ if (tos != 0)
+ return -EOPNOTSUPP;
+
+ if (ipv4_is_loopback(dst))
+ return -EOPNOTSUPP;
+
+ /* XXX not handling ECMP right now */
+ if (fi->fib_nhs != 1)
+ return -EOPNOTSUPP;
+
+ return 0;
+}
+
/*****************
* Net device ops
*****************/
@@ -3781,6 +4131,42 @@ static int rocker_port_switch_port_stp_update(struct net_device *dev, u8 state)
return rocker_port_stp_update(rocker_port, state);
}
+static int rocker_port_switch_fib_ipv4_add(struct net_device *dev,
+ __be32 dst, int dst_len,
+ struct fib_info *fi,
+ u8 tos, u8 type, u32 tb_id)
+{
+ struct rocker_port *rocker_port = netdev_priv(dev);
+ int flags = 0;
+ int err;
+
+ err = rocker_port_fib_ipv4_skip(dev, dst, dst_len, fi,
+ tos, type, tb_id);
+ if (err)
+ return err;
+
+ return rocker_port_fib_ipv4(rocker_port, dst, dst_len,
+ fi, tb_id, flags);
+}
+
+static int rocker_port_switch_fib_ipv4_del(struct net_device *dev,
+ __be32 dst, int dst_len,
+ struct fib_info *fi,
+ u8 tos, u8 type, u32 tb_id)
+{
+ struct rocker_port *rocker_port = netdev_priv(dev);
+ int flags = ROCKER_OP_FLAG_REMOVE;
+ int err;
+
+ err = rocker_port_fib_ipv4_skip(dev, dst, dst_len, fi,
+ tos, type, tb_id);
+ if (err)
+ return err;
+
+ return rocker_port_fib_ipv4(rocker_port, dst, dst_len,
+ fi, tb_id, flags);
+}
+
static const struct net_device_ops rocker_port_netdev_ops = {
.ndo_open = rocker_port_open,
.ndo_stop = rocker_port_stop,
@@ -3795,6 +4181,8 @@ static const struct net_device_ops rocker_port_netdev_ops = {
.ndo_bridge_getlink = rocker_port_bridge_getlink,
.ndo_switch_parent_id_get = rocker_port_switch_parent_id_get,
.ndo_switch_port_stp_update = rocker_port_switch_port_stp_update,
+ .ndo_switch_fib_ipv4_add = rocker_port_switch_fib_ipv4_add,
+ .ndo_switch_fib_ipv4_del = rocker_port_switch_fib_ipv4_del,
};
/********************
@@ -4340,6 +4728,50 @@ static struct notifier_block rocker_netdevice_nb __read_mostly = {
.notifier_call = rocker_netdevice_event,
};
+/************************************
+ * Net event notifier event handler
+ ************************************/
+
+static int rocker_neigh_update(struct net_device *dev, struct neighbour *neigh)
+{
+ struct rocker_port *rocker_port = netdev_priv(dev);
+ int flags = neigh->nud_state & NUD_VALID ? 0 : ROCKER_OP_FLAG_REMOVE;
+ __be32 ip_addr = *(__be32 *)neigh->primary_key;
+ unsigned char *mac = neigh->ha;
+
+ return rocker_port_neigh(rocker_port, flags, ip_addr, mac);
+}
+
+static int rocker_netevent_event(struct notifier_block *unused,
+ unsigned long event, void *ptr)
+{
+ struct net_device *dev;
+ struct neighbour *neigh;
+ int err;
+
+ switch (event) {
+ case NETEVENT_NEIGH_UPDATE:
+ neigh = ptr;
+ if (neigh->tbl != &arp_tbl)
+ return NOTIFY_DONE;
+ dev = neigh->dev;
+ if (!rocker_port_dev_check(dev))
+ return NOTIFY_DONE;
+ err = rocker_neigh_update(dev, neigh);
+ if (err)
+ netdev_warn(dev,
+ "failed to handle neigh update (err %d)\n",
+ err);
+ break;
+ }
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block rocker_netevent_nb __read_mostly = {
+ .notifier_call = rocker_netevent_event,
+};
+
/***********************
* Module init and exit
***********************/
@@ -4349,18 +4781,21 @@ static int __init rocker_module_init(void)
int err;
register_netdevice_notifier(&rocker_netdevice_nb);
+ register_netevent_notifier(&rocker_netevent_nb);
err = pci_register_driver(&rocker_pci_driver);
if (err)
goto err_pci_register_driver;
return 0;
err_pci_register_driver:
+ unregister_netdevice_notifier(&rocker_netevent_nb);
unregister_netdevice_notifier(&rocker_netdevice_nb);
return err;
}
static void __exit rocker_module_exit(void)
{
+ unregister_netevent_notifier(&rocker_netevent_nb);
unregister_netdevice_notifier(&rocker_netdevice_nb);
pci_unregister_driver(&rocker_pci_driver);
}
--
1.7.10.4
^ permalink raw reply related
* [PATCH net-next 2/3] net: call swdev fib del for flushed routes
From: sfeldma @ 2015-01-02 3:29 UTC (permalink / raw)
To: netdev, jiri, john.fastabend, tgraf, jhs, andy, roopa
From: Scott Feldman <sfeldma@gmail.com>
This is essentially the same patch Nicolas Dichtel posted, but was rejected.
The difference here is rather than calling netlink to notify, this patch
calls swdev to del the fib entry. Without this patch, when routes are flushed,
for example when an interface goes down, the normal route delete paths aren't
called, so we need to hook the flush path so swdev get's called.
Nicolas' patch is here:
http://marc.info/?l=linux-netdev&m=135161909714545&w=2
Signed-off-by: Scott Feldman <sfeldma@gmail.com>
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
net/ipv4/fib_trie.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index ea2dc17..c7a5947 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -1565,15 +1565,19 @@ int fib_table_delete(struct fib_table *tb, struct fib_config *cfg)
return 0;
}
-static int trie_flush_list(struct list_head *head)
+static int trie_flush_list(struct fib_table *tb, struct tnode *l,
+ struct leaf_info *li)
{
struct fib_alias *fa, *fa_node;
int found = 0;
- list_for_each_entry_safe(fa, fa_node, head, fa_list) {
+ list_for_each_entry_safe(fa, fa_node, &li->falh, fa_list) {
struct fib_info *fi = fa->fa_info;
if (fi && (fi->fib_flags & RTNH_F_DEAD)) {
+ netdev_switch_fib_ipv4_del(l->key, li->plen, fi,
+ fa->fa_tos, fa->fa_type,
+ tb->tb_id);
list_del_rcu(&fa->fa_list);
fib_release_info(fa->fa_info);
alias_free_mem_rcu(fa);
@@ -1583,7 +1587,7 @@ static int trie_flush_list(struct list_head *head)
return found;
}
-static int trie_flush_leaf(struct tnode *l)
+static int trie_flush_leaf(struct fib_table *tb, struct tnode *l)
{
int found = 0;
struct hlist_head *lih = &l->list;
@@ -1591,7 +1595,7 @@ static int trie_flush_leaf(struct tnode *l)
struct leaf_info *li = NULL;
hlist_for_each_entry_safe(li, tmp, lih, hlist) {
- found += trie_flush_list(&li->falh);
+ found += trie_flush_list(tb, l, li);
if (list_empty(&li->falh)) {
hlist_del_rcu(&li->hlist);
@@ -1674,7 +1678,7 @@ int fib_table_flush(struct fib_table *tb)
int found = 0;
for (l = trie_firstleaf(t); l; l = trie_nextleaf(l)) {
- found += trie_flush_leaf(l);
+ found += trie_flush_leaf(tb, l);
if (ll && hlist_empty(&ll->list))
trie_leaf_remove(t, ll);
--
1.7.10.4
^ 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