* Re: TC-pedit man page examples error
From: Tyler Bautista @ 2017-07-26 16:47 UTC (permalink / raw)
To: Phil Sutter, Tyler Bautista, netdev
In-Reply-To: <20170726084338.GH2235@orbyte.nwl.cc>
Hello Phil,
Thank you for taking my message. I have gotten a solution working so
feel free to ignore the rest of this email. By vanilla iproute2 do you
mean the latest package through the yum or apt repository? All I can
tell you is that in the example I gave the iproute2 package was the
latest one through the RHEL 7 yum repository. Otherwise I will need
clarification on what vanilla means. I attempted the above example
code on two other Ubuntu machines, one of which I can confirm is
Ubuntu 16.04 LTS. Unfortunately I am not at that machine right now so
I cannot give you the output. Both machines gave similar error
messages. The reason I emailed you via netdev was because the example
code I used was taken verbatim from the tc-pedit man page on my
machine. The man page also gave me email addresses to contact in case
an error was found with the man page, which is what I did. I did get
the code to work when using the latest version of iproute2, so I
assume the only practical solution is to manually install the latest
version of iproute2 or wait for the various distros of Linux to use
updated iproute2. I appreciate your help. Have a nice day.
Tyler Bautista
On Wed, Jul 26, 2017 at 1:43 AM, Phil Sutter <phil@nwl.cc> wrote:
> Hi Tyler,
>
> On Tue, Jul 25, 2017 at 08:33:40AM -0700, Tyler Bautista wrote:
>> To whom it may concern,
>> I recently attempted to use simple tc action pedit commands on the man
>> page and I ran into some errors. The following is some information
>> about my version of iproute and my machine:
>> ----------------------------
>> the following is my iproute package information
>>
>> Loaded plugins: fastestmirror, langpacks
>> iproute-3.10.0-74.el7.x86_64
>
> This mailing list is for upstream issues only. Can you reproduce the
> problem with vanilla iproute2?
>
> You are using RHEL7's iproute package, which has a number of known
> issues in pedit action:
>
> https://bugzilla.redhat.com/show_bug.cgi?id=1322406
>
> These are planned to be resolved for RHEL7.5, not sure when it will land
> in CentOS.
>
> Cheers, Phil
^ permalink raw reply
* Re: [PATCH net-next v2 01/10] net: dsa: lan9303: Fixed MDIO interface
From: Andrew Lunn @ 2017-07-26 16:55 UTC (permalink / raw)
To: Egil Hjelmeland
Cc: corbet, vivien.didelot, f.fainelli, davem, kernel, linux-doc,
linux-kernel, netdev
In-Reply-To: <20170725161553.30147-2-privat@egil-hjelmeland.no>
On Tue, Jul 25, 2017 at 06:15:44PM +0200, Egil Hjelmeland wrote:
> Fixes after testing on actual HW:
>
> - lan9303_mdio_write()/_read() must multiply register number
> by 4 to get offset
>
> - Indirect access (PMI) to phy register only work in I2C mode. In
> MDIO mode phy registers must be accessed directly. Introduced
> struct lan9303_phy_ops to handle the two modes. Renamed functions
> to clarify.
>
> - lan9303_detect_phy_setup() : Failed MDIO read return 0xffff.
> Handle that.
>
> Signed-off-by: Egil Hjelmeland <privat@egil-hjelmeland.no>
> ---
> drivers/net/dsa/lan9303-core.c | 42 +++++++++++++++++++++++++++---------------
> drivers/net/dsa/lan9303.h | 11 +++++++++++
> drivers/net/dsa/lan9303_i2c.c | 2 ++
> drivers/net/dsa/lan9303_mdio.c | 34 ++++++++++++++++++++++++++++++++++
> 4 files changed, 74 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c
> index cd76e61f1fca..e622db586c3d 100644
> --- a/drivers/net/dsa/lan9303-core.c
> +++ b/drivers/net/dsa/lan9303-core.c
> @@ -20,6 +20,9 @@
>
> #include "lan9303.h"
>
> +/* 13.2 System Control and Status Registers
> + * Multiply register number by 4 to get address offset.
> + */
> #define LAN9303_CHIP_REV 0x14
> # define LAN9303_CHIP_ID 0x9303
> #define LAN9303_IRQ_CFG 0x15
> @@ -53,6 +56,9 @@
> #define LAN9303_VIRT_PHY_BASE 0x70
> #define LAN9303_VIRT_SPECIAL_CTRL 0x77
>
> +/*13.4 Switch Fabric Control and Status Registers
> + * Accessed indirectly via SWITCH_CSR_CMD, SWITCH_CSR_DATA.
> + */
> #define LAN9303_SW_DEV_ID 0x0000
> #define LAN9303_SW_RESET 0x0001
> #define LAN9303_SW_RESET_RESET BIT(0)
> @@ -242,7 +248,7 @@ static int lan9303_virt_phy_reg_write(struct lan9303 *chip, int regnum, u16 val)
> return regmap_write(chip->regmap, LAN9303_VIRT_PHY_BASE + regnum, val);
> }
>
> -static int lan9303_port_phy_reg_wait_for_completion(struct lan9303 *chip)
> +static int lan9303_indirect_phy_wait_for_completion(struct lan9303 *chip)
> {
> int ret, i;
> u32 reg;
> @@ -262,7 +268,7 @@ static int lan9303_port_phy_reg_wait_for_completion(struct lan9303 *chip)
> return -EIO;
> }
>
> -static int lan9303_port_phy_reg_read(struct lan9303 *chip, int addr, int regnum)
> +static int lan9303_indirect_phy_read(struct lan9303 *chip, int addr, int regnum)
> {
> int ret;
> u32 val;
> @@ -272,7 +278,7 @@ static int lan9303_port_phy_reg_read(struct lan9303 *chip, int addr, int regnum)
>
> mutex_lock(&chip->indirect_mutex);
>
> - ret = lan9303_port_phy_reg_wait_for_completion(chip);
> + ret = lan9303_indirect_phy_wait_for_completion(chip);
> if (ret)
> goto on_error;
>
> @@ -281,7 +287,7 @@ static int lan9303_port_phy_reg_read(struct lan9303 *chip, int addr, int regnum)
> if (ret)
> goto on_error;
>
> - ret = lan9303_port_phy_reg_wait_for_completion(chip);
> + ret = lan9303_indirect_phy_wait_for_completion(chip);
> if (ret)
> goto on_error;
>
> @@ -299,8 +305,8 @@ static int lan9303_port_phy_reg_read(struct lan9303 *chip, int addr, int regnum)
> return ret;
> }
>
> -static int lan9303_phy_reg_write(struct lan9303 *chip, int addr, int regnum,
> - unsigned int val)
> +static int lan9303_indirect_phy_write(struct lan9303 *chip, int addr,
> + int regnum, u16 val)
> {
> int ret;
> u32 reg;
> @@ -311,7 +317,7 @@ static int lan9303_phy_reg_write(struct lan9303 *chip, int addr, int regnum,
>
> mutex_lock(&chip->indirect_mutex);
>
> - ret = lan9303_port_phy_reg_wait_for_completion(chip);
> + ret = lan9303_indirect_phy_wait_for_completion(chip);
> if (ret)
> goto on_error;
>
> @@ -328,6 +334,11 @@ static int lan9303_phy_reg_write(struct lan9303 *chip, int addr, int regnum,
> return ret;
> }
>
> +const struct lan9303_phy_ops lan9303_indirect_phy_ops = {
> + .phy_read = lan9303_indirect_phy_read,
> + .phy_write = lan9303_indirect_phy_write,
> +};
> +
> static int lan9303_switch_wait_for_completion(struct lan9303 *chip)
> {
> int ret, i;
> @@ -427,14 +438,15 @@ static int lan9303_detect_phy_setup(struct lan9303 *chip)
> * Special reg 18 of phy 3 reads as 0x0000, if 'phy_addr_sel_strap' is 0
> * and the IDs are 0-1-2, else it contains something different from
> * 0x0000, which means 'phy_addr_sel_strap' is 1 and the IDs are 1-2-3.
> + * 0xffff is returned for failed MDIO access.
Hi Egil
0xffff is not really a failure. It just means there is nothing on the
bus at that address. The bus has a weak pull-up, so defaults to one.
> */
> - reg = lan9303_port_phy_reg_read(chip, 3, MII_LAN911X_SPECIAL_MODES);
> + reg = chip->ops->phy_read(chip, 3, MII_LAN911X_SPECIAL_MODES);
> if (reg < 0) {
> dev_err(chip->dev, "Failed to detect phy config: %d\n", reg);
> return reg;
> }
>
> - if (reg != 0)
> + if ((reg != 0) && (reg != 0xffff))
> chip->phy_addr_sel_strap = 1;
> else
> chip->phy_addr_sel_strap = 0;
> @@ -719,7 +731,7 @@ static int lan9303_phy_read(struct dsa_switch *ds, int phy, int regnum)
> if (phy > phy_base + 2)
> return -ENODEV;
>
> - return lan9303_port_phy_reg_read(chip, phy, regnum);
> + return chip->ops->phy_read(chip, phy, regnum);
> }
>
> static int lan9303_phy_write(struct dsa_switch *ds, int phy, int regnum,
> @@ -733,7 +745,7 @@ static int lan9303_phy_write(struct dsa_switch *ds, int phy, int regnum,
> if (phy > phy_base + 2)
> return -ENODEV;
>
> - return lan9303_phy_reg_write(chip, phy, regnum, val);
> + return chip->ops->phy_write(chip, phy, regnum, val);
> }
>
> static int lan9303_port_enable(struct dsa_switch *ds, int port,
> @@ -766,13 +778,13 @@ static void lan9303_port_disable(struct dsa_switch *ds, int port,
> switch (port) {
> case 1:
> lan9303_disable_packet_processing(chip, LAN9303_PORT_1_OFFSET);
> - lan9303_phy_reg_write(chip, chip->phy_addr_sel_strap + 1,
> - MII_BMCR, BMCR_PDOWN);
> + lan9303_phy_write(ds, chip->phy_addr_sel_strap + 1,
> + MII_BMCR, BMCR_PDOWN);
> break;
> case 2:
> lan9303_disable_packet_processing(chip, LAN9303_PORT_2_OFFSET);
> - lan9303_phy_reg_write(chip, chip->phy_addr_sel_strap + 2,
> - MII_BMCR, BMCR_PDOWN);
> + lan9303_phy_write(ds, chip->phy_addr_sel_strap + 2,
> + MII_BMCR, BMCR_PDOWN);
> break;
> default:
> dev_dbg(chip->dev,
> diff --git a/drivers/net/dsa/lan9303.h b/drivers/net/dsa/lan9303.h
> index d1512dad2d90..444d00b460e1 100644
> --- a/drivers/net/dsa/lan9303.h
> +++ b/drivers/net/dsa/lan9303.h
> @@ -2,6 +2,15 @@
> #include <linux/device.h>
> #include <net/dsa.h>
>
> +struct lan9303;
> +
> +struct lan9303_phy_ops {
> + /* PHY 1 &2 access*/
A space would be nice here after the &.
> + int (*phy_read)(struct lan9303 *chip, int port, int regnum);
> + int (*phy_write)(struct lan9303 *chip, int port,
> + int regnum, u16 val);
> +};
> +
> struct lan9303 {
> struct device *dev;
> struct regmap *regmap;
> @@ -11,9 +20,11 @@ struct lan9303 {
> bool phy_addr_sel_strap;
> struct dsa_switch *ds;
> struct mutex indirect_mutex; /* protect indexed register access */
> + const struct lan9303_phy_ops *ops;
> };
>
> extern const struct regmap_access_table lan9303_register_set;
> +extern const struct lan9303_phy_ops lan9303_indirect_phy_ops;
>
> int lan9303_probe(struct lan9303 *chip, struct device_node *np);
> int lan9303_remove(struct lan9303 *chip);
> diff --git a/drivers/net/dsa/lan9303_i2c.c b/drivers/net/dsa/lan9303_i2c.c
> index ab3ce0da5071..24ec20f7f444 100644
> --- a/drivers/net/dsa/lan9303_i2c.c
> +++ b/drivers/net/dsa/lan9303_i2c.c
> @@ -63,6 +63,8 @@ static int lan9303_i2c_probe(struct i2c_client *client,
> i2c_set_clientdata(client, sw_dev);
> sw_dev->chip.dev = &client->dev;
>
> + sw_dev->chip.ops = &lan9303_indirect_phy_ops;
> +
> ret = lan9303_probe(&sw_dev->chip, client->dev.of_node);
> if (ret != 0)
> return ret;
> diff --git a/drivers/net/dsa/lan9303_mdio.c b/drivers/net/dsa/lan9303_mdio.c
> index 93c36c0541cf..94df12c5362f 100644
> --- a/drivers/net/dsa/lan9303_mdio.c
> +++ b/drivers/net/dsa/lan9303_mdio.c
> @@ -39,6 +39,7 @@ static void lan9303_mdio_real_write(struct mdio_device *mdio, int reg, u16 val)
> static int lan9303_mdio_write(void *ctx, uint32_t reg, uint32_t val)
> {
> struct lan9303_mdio *sw_dev = (struct lan9303_mdio *)ctx;
> + reg <<= 2; /* reg num to offset */
>
> mutex_lock(&sw_dev->device->bus->mdio_lock);
> lan9303_mdio_real_write(sw_dev->device, reg, val & 0xffff);
> @@ -56,6 +57,7 @@ static u16 lan9303_mdio_real_read(struct mdio_device *mdio, int reg)
> static int lan9303_mdio_read(void *ctx, uint32_t reg, uint32_t *val)
> {
> struct lan9303_mdio *sw_dev = (struct lan9303_mdio *)ctx;
> + reg <<= 2; /* reg num to offset */
>
> mutex_lock(&sw_dev->device->bus->mdio_lock);
> *val = lan9303_mdio_real_read(sw_dev->device, reg);
> @@ -65,6 +67,36 @@ static int lan9303_mdio_read(void *ctx, uint32_t reg, uint32_t *val)
> return 0;
> }
>
> +int lan9303_mdio_phy_write(struct lan9303 *chip, int phy, int regnum, u16 val)
> +{
> + struct lan9303_mdio *sw_dev = dev_get_drvdata(chip->dev);
> + struct mdio_device *mdio = sw_dev->device;
> +
> + mutex_lock(&mdio->bus->mdio_lock);
> + mdio->bus->write(mdio->bus, phy, regnum, val);
> + mutex_unlock(&mdio->bus->mdio_lock);
It is better to use mdiobus_read/write or if you are nesting mdio
busses, mdiobus_read_nested/mdiobus_write_nested. Please test this
code with lockdep enabled.
And as others have pointed out, there are too many changes in this one
patch.
Thanks
Andrew
^ permalink raw reply
* Re: [PATCH net-next v2 02/10] net: dsa: lan9303: Do not disable/enable switch fabric port 0 at startup
From: Andrew Lunn @ 2017-07-26 16:58 UTC (permalink / raw)
To: Egil Hjelmeland
Cc: corbet, vivien.didelot, f.fainelli, davem, kernel, linux-doc,
linux-kernel, netdev
In-Reply-To: <20170725161553.30147-3-privat@egil-hjelmeland.no>
On Tue, Jul 25, 2017 at 06:15:45PM +0200, Egil Hjelmeland wrote:
> For some mysterious reason enable switch fabric port 0 TX fails to
> work, when the TX has previous been disabled. Resolved by not
> disable/enable switch fabric port 0 at startup. Port 1 and 2 are
> still disabled in early init.
>
> Signed-off-by: Egil Hjelmeland <privat@egil-hjelmeland.no>
> ---
> drivers/net/dsa/lan9303-core.c | 7 -------
> 1 file changed, 7 deletions(-)
>
> diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c
> index e622db586c3d..c2b53659f58f 100644
> --- a/drivers/net/dsa/lan9303-core.c
> +++ b/drivers/net/dsa/lan9303-core.c
> @@ -557,9 +557,6 @@ static int lan9303_disable_processing(struct lan9303 *chip)
> {
> int ret;
>
> - ret = lan9303_disable_packet_processing(chip, LAN9303_PORT_0_OFFSET);
> - if (ret)
> - return ret;
> ret = lan9303_disable_packet_processing(chip, LAN9303_PORT_1_OFFSET);
> if (ret)
> return ret;
> @@ -633,10 +630,6 @@ static int lan9303_setup(struct dsa_switch *ds)
> if (ret)
> dev_err(chip->dev, "failed to separate ports %d\n", ret);
>
> - ret = lan9303_enable_packet_processing(chip, LAN9303_PORT_0_OFFSET);
> - if (ret)
> - dev_err(chip->dev, "failed to re-enable switching %d\n", ret);
> -
Does this mean you are relying on something else enabling port 0? The
bootloader?
I'm wondering if it is better to keep the enable, but remove the
disable?
Andrew
^ permalink raw reply
* [RFC] net: make net.core.{r,w}mem_{default,max} namespaced
From: Matteo Croce @ 2017-07-26 17:03 UTC (permalink / raw)
To: netdev
The following sysctl are global and can't be read or set from a netns:
net.core.rmem_default
net.core.rmem_max
net.core.wmem_default
net.core.wmem_max
Make the following sysctl parameters available from within a network
namespace, allowing to set unique values per network namespace.
My concern is about the initial value of this sysctl in the newly
creates netns: I'm not sure if is better to copy them from the init
namespace or set them to the default values.
Setting them to the default value has the advantage that a new namespace
behaves like a freshly booted system, while copying them from the init
netns has the advantage of keeping the current behaviour as the values
from the init netns are used.
Signed-off-by: Matteo Croce <mcroce@redhat.com>
---
include/net/netns/core.h | 5 +++
include/net/sock.h | 6 ----
include/net/tcp.h | 3 +-
net/core/net_namespace.c | 22 +++++++++++++
net/core/sock.c | 31 +++++-------------
net/core/sysctl_net_core.c | 70 ++++++++++++++++++++++-------------------
net/ipv4/ip_output.c | 2 +-
net/ipv4/syncookies.c | 3 +-
net/ipv4/tcp_minisocks.c | 3 +-
net/ipv4/tcp_output.c | 12 ++++---
net/ipv6/syncookies.c | 3 +-
net/netfilter/ipvs/ip_vs_sync.c | 4 +--
12 files changed, 89 insertions(+), 75 deletions(-)
diff --git a/include/net/netns/core.h b/include/net/netns/core.h
index 78eb1ff75475..9b613162467d 100644
--- a/include/net/netns/core.h
+++ b/include/net/netns/core.h
@@ -9,6 +9,11 @@ struct netns_core {
struct ctl_table_header *sysctl_hdr;
int sysctl_somaxconn;
+ u32 sysctl_wmem_max;
+ u32 sysctl_rmem_max;
+
+ u32 sysctl_wmem_default;
+ u32 sysctl_rmem_default;
struct prot_inuse __percpu *inuse;
};
diff --git a/include/net/sock.h b/include/net/sock.h
index 7c0632c7e870..e62a279e420f 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -2363,13 +2363,7 @@ bool sk_net_capable(const struct sock *sk, int cap);
void sk_get_meminfo(const struct sock *sk, u32 *meminfo);
-extern __u32 sysctl_wmem_max;
-extern __u32 sysctl_rmem_max;
-
extern int sysctl_tstamp_allow_data;
extern int sysctl_optmem_max;
-extern __u32 sysctl_wmem_default;
-extern __u32 sysctl_rmem_default;
-
#endif /* _SOCK_H */
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 70483296157f..460f4373d42a 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1300,7 +1300,8 @@ static inline void tcp_slow_start_after_idle_check(struct sock *sk)
/* Determine a window scaling and initial window to offer. */
void tcp_select_initial_window(int __space, __u32 mss, __u32 *rcv_wnd,
__u32 *window_clamp, int wscale_ok,
- __u8 *rcv_wscale, __u32 init_rcv_wnd);
+ __u8 *rcv_wscale, __u32 init_rcv_wnd,
+ __u32 rmem_max);
static inline int tcp_win_from_space(int space)
{
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 8726d051f31d..2d72b2bd6eab 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -23,6 +23,16 @@
#include <net/net_namespace.h>
#include <net/netns/generic.h>
+/* Take into consideration the size of the struct sk_buff overhead in the
+ * determination of these values, since that is non-constant across
+ * platforms. This makes socket queueing behavior and performance
+ * not depend upon such differences.
+ */
+#define _SK_MEM_PACKETS 256
+#define _SK_MEM_OVERHEAD SKB_TRUESIZE(256)
+#define SK_WMEM_MAX (_SK_MEM_OVERHEAD * _SK_MEM_PACKETS)
+#define SK_RMEM_MAX (_SK_MEM_OVERHEAD * _SK_MEM_PACKETS)
+
/*
* Our network namespace constructor/destructor lists
*/
@@ -318,6 +328,18 @@ static __net_init int setup_net(struct net *net, struct user_namespace *user_ns)
static int __net_init net_defaults_init_net(struct net *net)
{
net->core.sysctl_somaxconn = SOMAXCONN;
+ if (net_eq(net, &init_net)) {
+ init_net.core.sysctl_wmem_max = SK_WMEM_MAX;
+ init_net.core.sysctl_rmem_max = SK_RMEM_MAX;
+ init_net.core.sysctl_wmem_default = SK_WMEM_MAX;
+ init_net.core.sysctl_rmem_default = SK_RMEM_MAX;
+ } else {
+ net->core.sysctl_wmem_max = init_net.core.sysctl_wmem_max;
+ net->core.sysctl_rmem_max = init_net.core.sysctl_rmem_max;
+ net->core.sysctl_wmem_default = init_net.core.sysctl_wmem_default;
+ net->core.sysctl_rmem_default = init_net.core.sysctl_rmem_default;
+ }
+
return 0;
}
diff --git a/net/core/sock.c b/net/core/sock.c
index ac2a404c73eb..8086a660d75f 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -307,24 +307,6 @@ static struct lock_class_key af_wlock_keys[AF_MAX];
static struct lock_class_key af_elock_keys[AF_MAX];
static struct lock_class_key af_kern_callback_keys[AF_MAX];
-/* Take into consideration the size of the struct sk_buff overhead in the
- * determination of these values, since that is non-constant across
- * platforms. This makes socket queueing behavior and performance
- * not depend upon such differences.
- */
-#define _SK_MEM_PACKETS 256
-#define _SK_MEM_OVERHEAD SKB_TRUESIZE(256)
-#define SK_WMEM_MAX (_SK_MEM_OVERHEAD * _SK_MEM_PACKETS)
-#define SK_RMEM_MAX (_SK_MEM_OVERHEAD * _SK_MEM_PACKETS)
-
-/* Run time adjustable parameters. */
-__u32 sysctl_wmem_max __read_mostly = SK_WMEM_MAX;
-EXPORT_SYMBOL(sysctl_wmem_max);
-__u32 sysctl_rmem_max __read_mostly = SK_RMEM_MAX;
-EXPORT_SYMBOL(sysctl_rmem_max);
-__u32 sysctl_wmem_default __read_mostly = SK_WMEM_MAX;
-__u32 sysctl_rmem_default __read_mostly = SK_RMEM_MAX;
-
/* Maximal space eaten by iovec or ancillary data plus some space */
int sysctl_optmem_max __read_mostly = sizeof(unsigned long)*(2*UIO_MAXIOV+512);
EXPORT_SYMBOL(sysctl_optmem_max);
@@ -702,6 +684,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
char __user *optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
+ struct net *net = sock_net(sk);
int val;
int valbool;
struct linger ling;
@@ -755,7 +738,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
* play 'guess the biggest size' games. RCVBUF/SNDBUF
* are treated in BSD as hints
*/
- val = min_t(u32, val, sysctl_wmem_max);
+ val = min_t(u32, val, net->core.sysctl_wmem_max);
set_sndbuf:
sk->sk_userlocks |= SOCK_SNDBUF_LOCK;
sk->sk_sndbuf = max_t(int, val * 2, SOCK_MIN_SNDBUF);
@@ -776,7 +759,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
* play 'guess the biggest size' games. RCVBUF/SNDBUF
* are treated in BSD as hints
*/
- val = min_t(u32, val, sysctl_rmem_max);
+ val = min_t(u32, val, net->core.sysctl_rmem_max);
set_rcvbuf:
sk->sk_userlocks |= SOCK_RCVBUF_LOCK;
/*
@@ -820,7 +803,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
case SO_PRIORITY:
if ((val >= 0 && val <= 6) ||
- ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
+ ns_capable(net->user_ns, CAP_NET_ADMIN))
sk->sk_priority = val;
else
ret = -EPERM;
@@ -994,7 +977,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
clear_bit(SOCK_PASSSEC, &sock->flags);
break;
case SO_MARK:
- if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
+ if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
ret = -EPERM;
else
sk->sk_mark = val;
@@ -2626,8 +2609,8 @@ void sock_init_data(struct socket *sock, struct sock *sk)
init_timer(&sk->sk_timer);
sk->sk_allocation = GFP_KERNEL;
- sk->sk_rcvbuf = sysctl_rmem_default;
- sk->sk_sndbuf = sysctl_wmem_default;
+ sk->sk_rcvbuf = sock_net(sk)->core.sysctl_rmem_default;
+ sk->sk_sndbuf = sock_net(sk)->core.sysctl_wmem_default;
sk->sk_state = TCP_CLOSE;
sk_set_socket(sk, sock);
diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
index b7cd9aafe99e..01bb23ba4c86 100644
--- a/net/core/sysctl_net_core.c
+++ b/net/core/sysctl_net_core.c
@@ -252,38 +252,6 @@ static int proc_do_rss_key(struct ctl_table *table, int write,
static struct ctl_table net_core_table[] = {
#ifdef CONFIG_NET
{
- .procname = "wmem_max",
- .data = &sysctl_wmem_max,
- .maxlen = sizeof(int),
- .mode = 0644,
- .proc_handler = proc_dointvec_minmax,
- .extra1 = &min_sndbuf,
- },
- {
- .procname = "rmem_max",
- .data = &sysctl_rmem_max,
- .maxlen = sizeof(int),
- .mode = 0644,
- .proc_handler = proc_dointvec_minmax,
- .extra1 = &min_rcvbuf,
- },
- {
- .procname = "wmem_default",
- .data = &sysctl_wmem_default,
- .maxlen = sizeof(int),
- .mode = 0644,
- .proc_handler = proc_dointvec_minmax,
- .extra1 = &min_sndbuf,
- },
- {
- .procname = "rmem_default",
- .data = &sysctl_rmem_default,
- .maxlen = sizeof(int),
- .mode = 0644,
- .proc_handler = proc_dointvec_minmax,
- .extra1 = &min_rcvbuf,
- },
- {
.procname = "dev_weight",
.data = &weight_p,
.maxlen = sizeof(int),
@@ -472,6 +440,38 @@ static struct ctl_table netns_core_table[] = {
.extra1 = &zero,
.proc_handler = proc_dointvec_minmax
},
+ {
+ .procname = "wmem_max",
+ .data = &init_net.core.sysctl_wmem_max,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = &min_sndbuf,
+ },
+ {
+ .procname = "rmem_max",
+ .data = &init_net.core.sysctl_rmem_max,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = &min_rcvbuf,
+ },
+ {
+ .procname = "wmem_default",
+ .data = &init_net.core.sysctl_wmem_default,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = &min_sndbuf,
+ },
+ {
+ .procname = "rmem_default",
+ .data = &init_net.core.sysctl_rmem_default,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = &min_rcvbuf,
+ },
{ }
};
@@ -481,11 +481,15 @@ static __net_init int sysctl_core_net_init(struct net *net)
tbl = netns_core_table;
if (!net_eq(net, &init_net)) {
+ int i;
+
tbl = kmemdup(tbl, sizeof(netns_core_table), GFP_KERNEL);
if (tbl == NULL)
goto err_dup;
- tbl[0].data = &net->core.sysctl_somaxconn;
+ /* Update the variables to point into the current struct net */
+ for (i = 0; i < ARRAY_SIZE(netns_core_table) - 1; i++)
+ tbl[i].data += (void *)net - (void *)&init_net;
/* Don't export any sysctls to unprivileged users */
if (net->user_ns != &init_user_ns) {
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 50c74cd890bc..658927c673ee 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -1639,7 +1639,7 @@ void ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb,
sk->sk_priority = skb->priority;
sk->sk_protocol = ip_hdr(skb)->protocol;
sk->sk_bound_dev_if = arg->bound_dev_if;
- sk->sk_sndbuf = sysctl_wmem_default;
+ sk->sk_sndbuf = net->core.sysctl_wmem_default;
sk->sk_mark = fl4.flowi4_mark;
err = ip_append_data(sk, &fl4, ip_reply_glue_bits, arg->iov->iov_base,
len, 0, &ipc, &rt, MSG_DONTWAIT);
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index 03ad8778c395..ee364e5976a4 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -388,7 +388,8 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
tcp_select_initial_window(tcp_full_space(sk), req->mss,
&req->rsk_rcv_wnd, &req->rsk_window_clamp,
ireq->wscale_ok, &rcv_wscale,
- dst_metric(&rt->dst, RTAX_INITRWND));
+ dst_metric(&rt->dst, RTAX_INITRWND),
+ sock_net(sk)->core.sysctl_rmem_max);
ireq->rcv_wscale = rcv_wscale;
ireq->ecn_ok = cookie_ecn_ok(&tcp_opt, sock_net(sk), &rt->dst);
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index 0ff83c1637d8..e5243ac2edd3 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -377,7 +377,8 @@ void tcp_openreq_init_rwin(struct request_sock *req,
&req->rsk_window_clamp,
ireq->wscale_ok,
&rcv_wscale,
- rcv_wnd);
+ rcv_wnd,
+ sock_net(sk_listener)->core.sysctl_rmem_max);
ireq->rcv_wscale = rcv_wscale;
}
EXPORT_SYMBOL(tcp_openreq_init_rwin);
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 4e985dea1dd2..9173d01e7d21 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -206,7 +206,7 @@ u32 tcp_default_init_rwnd(u32 mss)
void tcp_select_initial_window(int __space, __u32 mss,
__u32 *rcv_wnd, __u32 *window_clamp,
int wscale_ok, __u8 *rcv_wscale,
- __u32 init_rcv_wnd)
+ __u32 init_rcv_wnd, __u32 rmem_max)
{
unsigned int space = (__space < 0 ? 0 : __space);
@@ -236,7 +236,7 @@ void tcp_select_initial_window(int __space, __u32 mss,
if (wscale_ok) {
/* Set window scaling on max possible window */
space = max_t(u32, space, sysctl_tcp_rmem[2]);
- space = max_t(u32, space, sysctl_rmem_max);
+ space = max_t(u32, space, rmem_max);
space = min_t(u32, space, *window_clamp);
while (space > U16_MAX && (*rcv_wscale) < TCP_MAX_WSCALE) {
space >>= 1;
@@ -3268,6 +3268,7 @@ static void tcp_connect_init(struct sock *sk)
{
const struct dst_entry *dst = __sk_dst_get(sk);
struct tcp_sock *tp = tcp_sk(sk);
+ struct net *net = sock_net(sk);
__u8 rcv_wscale;
u32 rcv_wnd;
@@ -3275,7 +3276,7 @@ static void tcp_connect_init(struct sock *sk)
* See tcp_input.c:tcp_rcv_state_process case TCP_SYN_SENT.
*/
tp->tcp_header_len = sizeof(struct tcphdr);
- if (sock_net(sk)->ipv4.sysctl_tcp_timestamps)
+ if (net->ipv4.sysctl_tcp_timestamps)
tp->tcp_header_len += TCPOLEN_TSTAMP_ALIGNED;
#ifdef CONFIG_TCP_MD5SIG
@@ -3311,9 +3312,10 @@ static void tcp_connect_init(struct sock *sk)
tp->advmss - (tp->rx_opt.ts_recent_stamp ? tp->tcp_header_len - sizeof(struct tcphdr) : 0),
&tp->rcv_wnd,
&tp->window_clamp,
- sock_net(sk)->ipv4.sysctl_tcp_window_scaling,
+ net->ipv4.sysctl_tcp_window_scaling,
&rcv_wscale,
- rcv_wnd);
+ rcv_wnd,
+ net->core.sysctl_rmem_max);
tp->rx_opt.rcv_wscale = rcv_wscale;
tp->rcv_ssthresh = tp->rcv_wnd;
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
index 4e7817abc0b9..bf38ee15766c 100644
--- a/net/ipv6/syncookies.c
+++ b/net/ipv6/syncookies.c
@@ -247,7 +247,8 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
tcp_select_initial_window(tcp_full_space(sk), req->mss,
&req->rsk_rcv_wnd, &req->rsk_window_clamp,
ireq->wscale_ok, &rcv_wscale,
- dst_metric(dst, RTAX_INITRWND));
+ dst_metric(dst, RTAX_INITRWND),
+ sock_net(sk)->core.sysctl_rmem_max);
ireq->rcv_wscale = rcv_wscale;
ireq->ecn_ok = cookie_ecn_ok(&tcp_opt, sock_net(sk), dst);
diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c
index 0e5b64a75da0..4ad447333379 100644
--- a/net/netfilter/ipvs/ip_vs_sync.c
+++ b/net/netfilter/ipvs/ip_vs_sync.c
@@ -1283,12 +1283,12 @@ static void set_sock_size(struct sock *sk, int mode, int val)
lock_sock(sk);
if (mode) {
val = clamp_t(int, val, (SOCK_MIN_SNDBUF + 1) / 2,
- sysctl_wmem_max);
+ sock_net(sk)->core.sysctl_wmem_max);
sk->sk_sndbuf = val * 2;
sk->sk_userlocks |= SOCK_SNDBUF_LOCK;
} else {
val = clamp_t(int, val, (SOCK_MIN_RCVBUF + 1) / 2,
- sysctl_rmem_max);
+ sock_net(sk)->core.sysctl_rmem_max);
sk->sk_rcvbuf = val * 2;
sk->sk_userlocks |= SOCK_RCVBUF_LOCK;
}
--
2.13.3
^ permalink raw reply related
* Re: [PATCH v2 2/4] can: fixed-transceiver: Add documentation for CAN fixed transceiver bindings
From: Oliver Hartkopp @ 2017-07-26 17:05 UTC (permalink / raw)
To: Andrew Lunn, Franklin S Cooper Jr
Cc: linux-kernel, devicetree, netdev, linux-can, wg, mkl, robh+dt,
quentin.schulz, dev.kurt, sergei.shtylyov
In-Reply-To: <20170726164124.GL12049@lunn.ch>
On 07/26/2017 06:41 PM, Andrew Lunn wrote:
> On Mon, Jul 24, 2017 at 06:05:19PM -0500, Franklin S Cooper Jr wrote:
>> +
>> +Optional:
>> + max-arbitration-speed: a positive non 0 value that determines the max
>> + speed that CAN can run in non CAN-FD mode or during the
>> + arbitration phase in CAN-FD mode.
>
> Hi Franklin
>
> Since this and the next property are optional, it is good to document
> what happens when they are not in the DT blob. Also document what 0
> means.
>
>> +
>> + max-data-speed: a positive non 0 value that determines the max data rate
>> + that can be used in CAN-FD mode. A value of -1 implies
>> + CAN-FD is not supported by the transceiver.
>
> -1 is ugly. I think it would be better to have a missing
> max-data-speed property indicate that CAN-FD is not supported.
Thanks Andrew! I had the same feeling about '-1' :-)
> And
> maybe put 'fd' into the property name.
Good point. In fact the common naming to set bitrates for CAN(FD)
controllers are 'bitrate' and 'data bitrate'.
'speed' is not really a good word for that.
Finally, @Franklin:
A CAN transceiver is limited in bandwidth. But you only have one RX and
one TX line between the CAN controller and the CAN transceiver. The
transceiver does not know about CAN FD - it has just a physical(!) layer
with a limited bandwidth. This is ONE limitation.
So I tend to specify only ONE 'max-bitrate' property for the
fixed-transceiver binding.
The fact whether the CAN controller is CAN FD capable or not is provided
by the netlink configuration interface for CAN controllers.
Regards,
Oliver
^ permalink raw reply
* Re: TCP fast retransmit issues
From: Neal Cardwell @ 2017-07-26 17:06 UTC (permalink / raw)
To: Willy Tarreau
Cc: Eric Dumazet, Klavs Klavsen, Netdev, Yuchung Cheng,
Nandita Dukkipati
In-Reply-To: <CADVnQymKZAc+SFD7X-FoP9UwHgB2MBCY48=dL8mH6XuKumkx4g@mail.gmail.com>
On Wed, Jul 26, 2017 at 12:43 PM, Neal Cardwell <ncardwell@google.com> wrote:
> (1) Because the connection negotiated SACK, the Linux TCP sender does
> not get to its tcp_add_reno_sack() code to count dupacks and enter
> fast recovery on the 3rd dupack. The sender keeps waiting for specific
> packets to be SACKed that would signal that something has probably
> been lost. We could probably mitigate this by having the sender turn
> off SACK once it sees SACKed ranges that are completely invalid (way
> out of window). Then it should use the old non-SACK "Recovery on 3rd
> dupack" path.
>
> (2) It looks like there is a bug in the sender code where it seems to
> be repeatedly using a TLP timer firing 211ms after every ACK is
> received to transmit another TLP probe (a new packet in this case).
> Somehow these weird invalid SACKs seem to be triggering a code path
> that makes us think we can send another TLP, when we probably should
> be firing an RTO. That's my interpretation, anyway. I will try to
> reproduce this with packetdrill.
Hmm. It looks like this might be a general issue, where any time we
get an ACK that doesn't ACK/SACK anything new (whether because it's
incoming data in a bi-directional flow, or a middlebox breaking the
SACKs), then we schedule a TLP timer further out in time. Probably we
should only push the TLP timer out if something is cumulatively ACKed.
But that's not a trivial thing to do, because by the time we are
deciding whether to schedule another TLP, we have already canceled the
previous TLP and reinstalled an RTO. Hmm.
neal
^ permalink raw reply
* Re: [PATCH net-next v2 04/10] net: dsa: lan9303: Added adjust_link() method
From: Andrew Lunn @ 2017-07-26 17:09 UTC (permalink / raw)
To: Egil Hjelmeland
Cc: corbet, vivien.didelot, f.fainelli, davem, kernel, linux-doc,
linux-kernel, netdev
In-Reply-To: <20170725161553.30147-5-privat@egil-hjelmeland.no>
On Tue, Jul 25, 2017 at 06:15:47PM +0200, Egil Hjelmeland wrote:
> This makes the driver react to device tree "fixed-link" declaration
> on CPU port.
>
> - turn off autonegotiation
> - force speed 10 or 100 mb/s
> - force duplex mode
>
> Signed-off-by: Egil Hjelmeland <privat@egil-hjelmeland.no>
> ---
> drivers/net/dsa/lan9303-core.c | 33 +++++++++++++++++++++++++++++++++
> 1 file changed, 33 insertions(+)
>
> diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c
> index 0806a0684d55..be6d78f45a5f 100644
> --- a/drivers/net/dsa/lan9303-core.c
> +++ b/drivers/net/dsa/lan9303-core.c
> @@ -17,6 +17,7 @@
> #include <linux/regmap.h>
> #include <linux/mutex.h>
> #include <linux/mii.h>
> +#include <linux/phy.h>
>
> #include "lan9303.h"
>
> @@ -746,6 +747,37 @@ static int lan9303_phy_write(struct dsa_switch *ds, int phy, int regnum,
> return chip->ops->phy_write(chip, phy, regnum, val);
> }
>
> +static void lan9303_adjust_link(struct dsa_switch *ds, int port,
> + struct phy_device *phydev)
> +{
> + struct lan9303 *chip = ds->priv;
> +
> + int ctl, res;
> +
> + ctl = lan9303_phy_read(ds, port, MII_BMCR);
> +
> + if (!phy_is_pseudo_fixed_link(phydev))
> + return;
> +
Hi Egil
Maybe do this check before reading MII_BMCR?
> + ctl &= ~BMCR_ANENABLE;
Should this also mask out BMCR_SPEED100 and DUPLEX_FULL? Otherwise how
do you select 10/Half if it is already configured for 100/Full?
> + if (phydev->speed == SPEED_100)
> + ctl |= BMCR_SPEED100;
> +
> + if (phydev->duplex == DUPLEX_FULL)
> + ctl |= BMCR_FULLDPLX;
> +
> + res = lan9303_phy_write(ds, port, MII_BMCR, ctl);
> +
> + if (port == chip->phy_addr_sel_strap) {
> + /* Virtual Phy: Remove Turbo 200Mbit mode */
> + lan9303_read(chip->regmap, LAN9303_VIRT_SPECIAL_CTRL, &ctl);
> +
> + ctl &= ~(1 << 10); // TURBO BIT
BIT(10), or better still something like BIT(LAN9303_VIRT_SPECIAL_TURBO)
> + res = regmap_write(chip->regmap,
> + LAN9303_VIRT_SPECIAL_CTRL, ctl);
> + }
> +}
Andrew
^ permalink raw reply
* Re: [PATCHv3 net] ipv6: no need to return rt->dst.error if it is prohibit entry
From: David Ahern @ 2017-07-26 17:09 UTC (permalink / raw)
To: Hangbin Liu, netdev; +Cc: Cong Wang, Roopa Prabhu
In-Reply-To: <1501060829-11928-1-git-send-email-liuhangbin@gmail.com>
On 7/26/17 3:20 AM, Hangbin Liu wrote:
> After commit 18c3a61c4264 ("net: ipv6: RTM_GETROUTE: return matched fib
> result when requested"). When we get a prohibit ertry, we will return
> -EACCES directly.
>
> Before:
Do you mean "Before commit 18c3a61c4264?"
> + ip netns exec client ip -6 route get 2003::1
> prohibit 2003::1 dev lo table unspec proto kernel src 2001::1 metric
> 4294967295 error -13
>
> After:
And "After commit 18c3a61c4264?"
> + ip netns exec server ip -6 route get 2002::1
> RTNETLINK answers: Permission denied
>
> Fix this by add prohibit and blk hole check.
>
> At the same time, after commit
> 2f460933f58e ("ipv6: initialize route null entry in addrconf_init()") and
> 242d3a49a2a1 ("ipv6: reorder ip6_route_dev_notifier after ipv6_dev_notf")
> We will init rt6i_idev correctly. So we could dump ip6_null_entry
> (unreachable route entry) safely now.
>
> Fixes: 18c3a61c4264 ("net: ipv6: RTM_GETROUTE: return matched fib...")
> Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
> ---
> net/ipv6/route.c | 13 ++++++-------
> 1 file changed, 6 insertions(+), 7 deletions(-)
>
> diff --git a/net/ipv6/route.c b/net/ipv6/route.c
> index 4d30c96..b05da74 100644
> --- a/net/ipv6/route.c
> +++ b/net/ipv6/route.c
> @@ -3637,13 +3637,12 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
> dst = ip6_route_lookup(net, &fl6, 0);
>
> rt = container_of(dst, struct rt6_info, dst);
> - if (rt->dst.error) {
> - err = rt->dst.error;
> - ip6_rt_put(rt);
> - goto errout;
> - }
> -
> - if (rt == net->ipv6.ip6_null_entry) {
> + if (rt->dst.error &&
> +#ifdef CONFIG_IPV6_MULTIPLE_TABLES
> + rt != net->ipv6.ip6_prohibit_entry &&
> + rt != net->ipv6.ip6_blk_hole_entry &&
> +#endif
> + rt != net->ipv6.ip6_null_entry) {
> err = rt->dst.error;
> ip6_rt_put(rt);
> goto errout;
>
This is what I see with your patch:
# ip -6 ro ls vrf red
2001:db8:1::/120 dev eth1 proto kernel metric 256 pref medium
prohibit 5000::/120 dev lo metric 1024 error -13 pref medium
fe80::/64 dev eth1 proto kernel metric 256 pref medium
ff00::/8 dev eth1 metric 256 pref medium
unreachable default dev lo metric 8192 error -113 pref medium
ie., I added a prohibit route for 5000:/120
and then running:
# ip -6 ro get vrf red 5000::1
RTNETLINK answers: Permission denied
Which is the behavior without your patch.
Now if I delete just the first bit:
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 4d30c96a819d..8fc52de40175 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -3637,12 +3637,6 @@ static int inet6_rtm_getroute(struct sk_buff
*in_skb, struct nlmsghdr *nlh,
dst = ip6_route_lookup(net, &fl6, 0);
rt = container_of(dst, struct rt6_info, dst);
- if (rt->dst.error) {
- err = rt->dst.error;
- ip6_rt_put(rt);
- goto errout;
- }
-
if (rt == net->ipv6.ip6_null_entry) {
err = rt->dst.error;
ip6_rt_put(rt);
Then I get:
# ip -6 ro get vrf red 5000::1
prohibit 5000::1 from :: dev lo table red src 2001:db8::2 metric 1024
error -13 pref medium
which seems to be your objective.
I don't understand why you are focused on the built-in null and prohibit
route entries. When I add a default unreachable or prohibit route those
are different rt6_info entries. Take a look at ip6_route_info_create.
^ permalink raw reply related
* Re: [PATCH net-next v2 06/10] net: dsa: lan9303: added sysfs node swe_bcst_throt
From: Andrew Lunn @ 2017-07-26 17:14 UTC (permalink / raw)
To: Egil Hjelmeland
Cc: corbet, vivien.didelot, f.fainelli, davem, kernel, linux-doc,
linux-kernel, netdev
In-Reply-To: <20170725161553.30147-7-privat@egil-hjelmeland.no>
On Tue, Jul 25, 2017 at 06:15:49PM +0200, Egil Hjelmeland wrote:
> Allowing per-port access to Switch Engine Broadcast Throttling Register
Hi Egil
In general, we are against using sysfs. If there is a generic
mechanism, that applies for all sorts of network interfaces, it should
be used instead of sysfs.
Is this intended to reduce the effect of broadcast storms?
Andrew
^ permalink raw reply
* Re: [PATCH net] ipv6: no need to return rt->dst.error if it is not null entry.
From: David Ahern @ 2017-07-26 17:18 UTC (permalink / raw)
To: Hangbin Liu; +Cc: Cong Wang, network dev, Roopa Prabhu
In-Reply-To: <20170725073202.GE2938@leo.usersys.redhat.com>
On 7/25/17 1:32 AM, Hangbin Liu wrote:
> On Mon, Jul 24, 2017 at 09:28:07PM -0600, David Ahern wrote:
>> On 7/24/17 6:08 PM, Hangbin Liu wrote:
>>> That's why I think we should remove both rt->dst.error and ip6_null_entry
>>> check in inet6_rtm_getroute(). And even further, remove the ip6_null_entry
>>> check in rt6_dump_route().
>>
>> git blame net/ipv6/route.c
>>
>> find the commits and review.
>
> Hi David,
>
> Sorry, would you like to give me more hints?
>
> I saw your commit 1f17e2f2c8a8 ("net: ipv6: ignore null_entry on route
> dumps"). But I think this issue has been fixed by
>
> 2f460933f58e ("ipv6: initialize route null entry in addrconf_init()") and
> 242d3a49a2a1 ("ipv6: reorder ip6_route_dev_notifier after ipv6_dev_notf")
>
> I use a reproducer which add unreachable route in netns with lo down. And I
> could not trigger Panic in the fixed kernel. That's why I think we could
> remove ip6_null_entry check in rt6_dump_route().
Understood. Cong's patch to fix the intialization order (lo device
before route init) makes sure the idev is not null. That said, the
null_entry route is internal ipv6 logic and is not a route entry to be
returned to userspace.
^ permalink raw reply
* [PATCH] net: inet: diag: expose sockets cgroup classid
From: Levin, Alexander (Sasha Levin) @ 2017-07-26 17:22 UTC (permalink / raw)
To: davem@davemloft.net, kuznet@ms2.inr.ac.ru,
yoshfuji@linux-ipv6.org
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
Levin, Alexander (Sasha Levin)
This is useful for directly looking up a task based on class id rather than
having to scan through all open file descriptors.
Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
---
include/uapi/linux/inet_diag.h | 1 +
net/ipv4/inet_diag.c | 10 ++++++++++
2 files changed, 11 insertions(+)
diff --git a/include/uapi/linux/inet_diag.h b/include/uapi/linux/inet_diag.h
index bbe201047df6..678496897a68 100644
--- a/include/uapi/linux/inet_diag.h
+++ b/include/uapi/linux/inet_diag.h
@@ -142,6 +142,7 @@ enum {
INET_DIAG_PAD,
INET_DIAG_MARK,
INET_DIAG_BBRINFO,
+ INET_DIAG_CLASS_ID,
__INET_DIAG_MAX,
};
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 3828b3a805cd..ffc6dad9780a 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -274,6 +274,16 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
goto errout;
}
+ if (ext & (1 << (INET_DIAG_CLASS_ID - 1))) {
+ u32 classid = 0;
+
+#ifdef CONFIG_SOCK_CGROUP_DATA
+ classid = sock_cgroup_classid(&sk->sk_cgrp_data);
+#endif
+
+ nla_put(skb, INET_DIAG_CLASS_ID, sizeof(classid), &classid);
+ }
+
out:
nlmsg_end(skb, nlh);
return 0;
--
2.11.0
^ permalink raw reply related
* Re: [PATCH net-next v2 07/10] net: dsa: lan9303: Added basic offloading of unicast traffic
From: Andrew Lunn @ 2017-07-26 17:24 UTC (permalink / raw)
To: Egil Hjelmeland
Cc: corbet, vivien.didelot, f.fainelli, davem, kernel, linux-doc,
linux-kernel, netdev
In-Reply-To: <20170725161553.30147-8-privat@egil-hjelmeland.no>
Hi Egil
> +/* forward special tagged packets from port 0 to port 1 *or* port 2 */
> +static int lan9303_setup_tagging(struct lan9303 *chip)
> +{
> + int ret;
Blank line please.
> + /* enable defining the destination port via special VLAN tagging
> + * for port 0
> + */
> + ret = lan9303_write_switch_reg(chip, LAN9303_SWE_INGRESS_PORT_TYPE,
> + 0x03);
#define for 0x03.
> + if (ret)
> + return ret;
> +
> + /* tag incoming packets at port 1 and 2 on their way to port 0 to be
> + * able to discover their source port
> + */
> + return lan9303_write_switch_reg(
> + chip, LAN9303_BM_EGRSS_PORT_TYPE,
> + LAN9303_BM_EGRSS_PORT_TYPE_SPECIAL_TAG_PORT0);
> +}
> +
> /* We want a special working switch:
> * - do not forward packets between port 1 and 2
> * - forward everything from port 1 to port 0
> * - forward everything from port 2 to port 0
> - * - forward special tagged packets from port 0 to port 1 *or* port 2
> */
> static int lan9303_separate_ports(struct lan9303 *chip)
> {
> @@ -534,22 +555,6 @@ static int lan9303_separate_ports(struct lan9303 *chip)
> if (ret)
> return ret;
>
> - /* enable defining the destination port via special VLAN tagging
> - * for port 0
> - */
> - ret = lan9303_write_switch_reg(chip, LAN9303_SWE_INGRESS_PORT_TYPE,
> - 0x03);
> - if (ret)
> - return ret;
> -
> - /* tag incoming packets at port 1 and 2 on their way to port 0 to be
> - * able to discover their source port
> - */
> - ret = lan9303_write_switch_reg(chip, LAN9303_BM_EGRSS_PORT_TYPE,
> - LAN9303_BM_EGRSS_PORT_TYPE_SPECIAL_TAG_PORT0);
> - if (ret)
> - return ret;
> -
> /* prevent port 1 and 2 from forwarding packets by their own */
> return lan9303_write_switch_reg(chip, LAN9303_SWE_PORT_STATE,
> LAN9303_SWE_PORT_STATE_FORWARDING_PORT0 |
> @@ -557,6 +562,12 @@ static int lan9303_separate_ports(struct lan9303 *chip)
> LAN9303_SWE_PORT_STATE_BLOCKING_PORT2);
> }
>
> +static void lan9303_bridge_ports(struct lan9303 *chip)
> +{
> + /* ports bridged: remove mirroring */
> + lan9303_write_switch_reg(chip, LAN9303_SWE_PORT_MIRROR, 0);
> +}
> +
> static int lan9303_handle_reset(struct lan9303 *chip)
> {
> if (!chip->reset_gpio)
> @@ -707,6 +718,10 @@ static int lan9303_setup(struct dsa_switch *ds)
> return -EINVAL;
> }
>
> + ret = lan9303_setup_tagging(chip);
> + if (ret)
> + dev_err(chip->dev, "failed to setup port tagging %d\n", ret);
> +
> ret = lan9303_separate_ports(chip);
> if (ret)
> dev_err(chip->dev, "failed to separate ports %d\n", ret);
> @@ -898,17 +913,81 @@ static void lan9303_port_disable(struct dsa_switch *ds, int port,
> }
> }
>
> +static int lan9303_port_bridge_join(struct dsa_switch *ds, int port,
> + struct net_device *br)
> +{
> + struct lan9303 *chip = ds->priv;
> +
> + dev_dbg(chip->dev, "%s(port %d)\n", __func__, port);
> + if (ds->ports[1].bridge_dev == ds->ports[2].bridge_dev) {
> + lan9303_bridge_ports(chip);
> + chip->is_bridged = true; /* unleash stp_state_set() */
> + }
> +
> + return 0;
> +}
> +
> +static void lan9303_port_bridge_leave(struct dsa_switch *ds, int port,
> + struct net_device *br)
> +{
> + struct lan9303 *chip = ds->priv;
> +
> + dev_dbg(chip->dev, "%s(port %d)\n", __func__, port);
> + if (chip->is_bridged) {
> + lan9303_separate_ports(chip);
> + chip->is_bridged = false;
> + }
> +}
> +
> +static void lan9303_port_stp_state_set(struct dsa_switch *ds, int port,
> + u8 state)
> +{
> + int portmask, portstate;
> + struct lan9303 *chip = ds->priv;
> +
> + dev_dbg(chip->dev, "%s(port %d, state %d)\n",
> + __func__, port, state);
> + if (!chip->is_bridged)
> + return;
I think you are over-simplifying here. Say i have a layer 2 VPN and i
bridge port 1 and the VPN? The software bridge still wants to do STP
on port 1, in order to solve loops.
> +
> + switch (state) {
> + case BR_STATE_DISABLED:
> + portstate = LAN9303_SWE_PORT_STATE_DISABLED_PORT0;
> + break;
> + case BR_STATE_BLOCKING:
> + case BR_STATE_LISTENING:
> + portstate = LAN9303_SWE_PORT_STATE_BLOCKING_PORT0;
> + break;
> + case BR_STATE_LEARNING:
> + portstate = LAN9303_SWE_PORT_STATE_LEARNING_PORT0;
> + break;
> + case BR_STATE_FORWARDING:
> + portstate = LAN9303_SWE_PORT_STATE_FORWARDING_PORT0;
> + break;
> + default:
> + dev_err(chip->dev, "%s(port %d, state %d)\n",
> + __func__, port, state);
> + }
> + portmask = 0x3 << (port * 2);
> + portstate <<= (port * 2);
> + lan9303_write_switch_reg_mask(chip, LAN9303_SWE_PORT_STATE,
> + portstate, portmask);
> +}
> +
> static struct dsa_switch_ops lan9303_switch_ops = {
> .get_tag_protocol = lan9303_get_tag_protocol,
> .setup = lan9303_setup,
> - .get_strings = lan9303_get_strings,
????
> .phy_read = lan9303_phy_read,
> .phy_write = lan9303_phy_write,
> .adjust_link = lan9303_adjust_link,
> + .get_strings = lan9303_get_strings,
Please don't include other unrelated changes.
Andrew
^ permalink raw reply
* Re: [PATCH] net: phy: Log only PHY state transitions
From: Florian Fainelli @ 2017-07-26 17:24 UTC (permalink / raw)
To: David Miller, marc_gonzalez; +Cc: andrew, netdev, slash.tmp
In-Reply-To: <20170725.123303.483987159585881971.davem@davemloft.net>
On 07/25/2017 12:33 PM, David Miller wrote:
> From: Marc Gonzalez <marc_gonzalez@sigmadesigns.com>
> Date: Tue, 25 Jul 2017 11:31:46 +0200
>
>> In the current code, old and new PHY states are always logged.
>> From now on, log only PHY state transitions.
>>
>> Signed-off-by: Marc Gonzalez <marc_gonzalez@sigmadesigns.com>
>> ---
>> drivers/net/phy/phy.c | 3 ++-
>> 1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
>> index d0626bf5c540..6bb764e716fc 100644
>> --- a/drivers/net/phy/phy.c
>> +++ b/drivers/net/phy/phy.c
>> @@ -1226,7 +1226,8 @@ void phy_state_machine(struct work_struct *work)
>> if (err < 0)
>> phy_error(phydev);
>>
>> - phydev_dbg(phydev, "PHY state change %s -> %s\n",
>> + if (old_state != phydev->state)
>> + phydev_dbg(phydev, "PHY state change %s -> %s\n",
>> phy_state_to_str(old_state),
>> phy_state_to_str(phydev->state));
>
> Something is not kosher with this indentation at all.
Indeed, please align the two phy_state_to_str() where the opening
parenthesis for phydev_dbg() starts, such this visually looks like:
if (old_state != phydev->state)
phydev_dbg(phydev, "PHY state change %s -> %s\n",
phy_state_to_str(old_state),
phy_state_to_str(phydev->state));
Thanks!
--
Florian
^ permalink raw reply
* Re: [PATCH net-next v2 08/10] net: dsa: lan9303: Added ALR/fdb/mdb handling
From: Andrew Lunn @ 2017-07-26 17:41 UTC (permalink / raw)
To: Egil Hjelmeland
Cc: corbet, vivien.didelot, f.fainelli, davem, kernel, linux-doc,
linux-kernel, netdev
In-Reply-To: <20170725161553.30147-9-privat@egil-hjelmeland.no>
Hi Egil
> +/* This function will wait a while until mask & reg == value */
> +/* Otherwise, return timeout */
> +static int lan9303_csr_reg_wait(struct lan9303 *chip, int regno,
> + int mask, char value)
> +{
> + int i;
> +
> + for (i = 0; i < 0x1000; i++) {
> + u32 reg;
> +
> + lan9303_read_switch_reg(chip, regno, ®);
> + if ((reg & mask) == value)
> + return 0;
> + }
> + return -ETIMEDOUT;
Busy looping is probably not a good idea. Can you add a usleep()?
> +}
> +
> +static int _lan9303_alr_make_entry_raw(struct lan9303 *chip, u32 dat0, u32 dat1)
What does the _ indicate. I could understand having it when you have
lan9303_alr_make_entry_raw() call _lan9303_alr_make_entry_raw() after
taking a lock, but i don't see anything like that here.
> +{
> + lan9303_write_switch_reg(
> + chip, LAN9303_SWE_ALR_WR_DAT_0, dat0);
> + lan9303_write_switch_reg(
> + chip, LAN9303_SWE_ALR_WR_DAT_1, dat1);
> + lan9303_write_switch_reg(
> + chip, LAN9303_SWE_ALR_CMD, ALR_CMD_MAKE_ENTRY);
> + lan9303_csr_reg_wait(
> + chip, LAN9303_SWE_ALR_CMD_STS, ALR_STS_MAKE_PEND, 0);
> + lan9303_write_switch_reg(chip, LAN9303_SWE_ALR_CMD, 0);
> + return 0;
> +}
> +
> +typedef void alr_loop_cb_t(
> + struct lan9303 *chip, u32 dat0, u32 dat1, int portmap, void *ctx);
> +
> +static void lan9303_alr_loop(struct lan9303 *chip, alr_loop_cb_t *cb, void *ctx)
> +{
> + int i;
> +
> + lan9303_write_switch_reg(chip, LAN9303_SWE_ALR_CMD, ALR_CMD_GET_FIRST);
> + lan9303_write_switch_reg(chip, LAN9303_SWE_ALR_CMD, 0);
> +
> + for (i = 1; i < LAN9303_NUM_ALR_RECORDS; i++) {
> + u32 dat0, dat1;
> + int alrport, portmap;
> +
> + lan9303_read_switch_reg(chip, LAN9303_SWE_ALR_RD_DAT_0, &dat0);
> + lan9303_read_switch_reg(chip, LAN9303_SWE_ALR_RD_DAT_1, &dat1);
> + if (dat1 & ALR_DAT1_END_OF_TABL)
> + break;
> +
> + alrport = (dat1 & ALR_DAT1_PORT_MASK) >> ALR_DAT1_PORT_BITOFFS;
> + portmap = alrport_2_portmap[alrport];
> +
> + cb(chip, dat0, dat1, portmap, ctx);
> +
> + lan9303_write_switch_reg(
> + chip, LAN9303_SWE_ALR_CMD, ALR_CMD_GET_NEXT);
> + lan9303_write_switch_reg(chip, LAN9303_SWE_ALR_CMD, 0);
> + }
> +}
> +
> +/* ALR: lan9303_alr_loop callback functions */
> +
> +static void _alr_reg_to_mac(u32 dat0, u32 dat1, u8 mac[6])
> +{
> + mac[0] = (dat0 >> 0) & 0xff;
> + mac[1] = (dat0 >> 8) & 0xff;
> + mac[2] = (dat0 >> 16) & 0xff;
> + mac[3] = (dat0 >> 24) & 0xff;
> + mac[4] = (dat1 >> 0) & 0xff;
> + mac[5] = (dat1 >> 8) & 0xff;
> +}
> +
> +/* Clear learned (non-static) entry on given port */
> +static void alr_loop_cb_del_port_learned(
> + struct lan9303 *chip, u32 dat0, u32 dat1, int portmap, void *ctx)
> +{
> + int *port = ctx;
> +
> + if (((BIT(*port) & portmap) == 0) || (dat1 & ALR_DAT1_STATIC))
> + return;
> +
> + /* learned entries has only one port, we can just delete */
> + dat1 &= ~ALR_DAT1_VALID; /* delete entry */
> + _lan9303_alr_make_entry_raw(chip, dat0, dat1);
> +}
> +
> +struct port_fdb_dump_ctx {
> + int port;
> + struct switchdev_obj_port_fdb *fdb;
> + switchdev_obj_dump_cb_t *cb;
> +};
> +
> +static void alr_loop_cb_fdb_port_dump(
> + struct lan9303 *chip, u32 dat0, u32 dat1, int portmap, void *ctx)
> +{
> + struct port_fdb_dump_ctx *dump_ctx = ctx;
> + struct switchdev_obj_port_fdb *fdb = dump_ctx->fdb;
> + u8 mac[ETH_ALEN];
> +
> + if ((BIT(dump_ctx->port) & portmap) == 0)
> + return;
> +
> + _alr_reg_to_mac(dat0, dat1, mac);
> + ether_addr_copy(fdb->addr, mac);
> + fdb->vid = 0;
> + fdb->ndm_state = (dat1 & ALR_DAT1_STATIC) ?
> + NUD_NOARP : NUD_REACHABLE;
> + dump_ctx->cb(&fdb->obj);
> +}
> +
> +/* ALR: Add/modify/delete ALR entries */
> +
> +/* Set a static ALR entry. Delete entry if port_map is zero */
> +static void _lan9303_alr_set_entry(struct lan9303 *chip, const u8 *mac,
> + u8 port_map, bool stp_override)
> +{
> + u32 dat0, dat1, alr_port;
> +
> + dat1 = ALR_DAT1_STATIC;
> + if (port_map)
> + dat1 |= ALR_DAT1_VALID; /* otherwise no ports: delete entry */
> + if (stp_override)
> + dat1 |= ALR_DAT1_AGE_OVERRID;
> +
> + alr_port = portmap_2_alrport[port_map & 7];
> + dat1 &= ~ALR_DAT1_PORT_MASK;
> + dat1 |= alr_port << ALR_DAT1_PORT_BITOFFS;
> +
> + dat0 = 0;
> + dat0 |= (mac[0] << 0);
> + dat0 |= (mac[1] << 8);
> + dat0 |= (mac[2] << 16);
> + dat0 |= (mac[3] << 24);
> +
> + dat1 |= (mac[4] << 0);
> + dat1 |= (mac[5] << 8);
> +
> + dev_dbg(chip->dev, "%s %pM %d %08x %08x\n",
> + __func__, mac, port_map, dat0, dat1);
> + _lan9303_alr_make_entry_raw(chip, dat0, dat1);
> +}
> +
> +/* Add port to static ALR entry, create new static entry if needed */
> +static int lan9303_alr_add_port(struct lan9303 *chip, const u8 *mac,
> + int port, bool stp_override)
> +{
> + struct lan9303_alr_cache_entry *entr = lan9303_alr_cache_find_mac(
> + chip, mac);
A long line like this should be split into a declaration and an
assignment.
> +
> + if (!entr) { /*New entry */
> + entr = lan9303_alr_cache_find_free(chip);
> + if (!entr)
> + return -ENOSPC;
> + ether_addr_copy(entr->mac_addr, mac);
> + }
> + entr->port_map |= BIT(port);
> + entr->stp_override = stp_override;
> + _lan9303_alr_set_entry(chip, mac, entr->port_map, stp_override);
> + return 0;
> +}
> +
> +/* Delete static port from ALR entry, delete entry if last port */
> +static int lan9303_alr_del_port(struct lan9303 *chip, const u8 *mac,
> + int port)
> +{
> + struct lan9303_alr_cache_entry *entr = lan9303_alr_cache_find_mac(
> + chip, mac);
> +
> + if (!entr) { /* no static entry found */
> + /* Should we delete any learned entry?
> + * _lan9303_alr_set_entry(chip, mac, 0, false);
> + */
> + return 0;
> + }
> + entr->port_map &= ~BIT(port); /* zero means its free again */
> + if (entr->port_map == 0)
> + eth_zero_addr(&entr->port_map);
> + _lan9303_alr_set_entry(chip, mac, entr->port_map, entr->stp_override);
> + return 0;
> +}
> +
> +/* --------------------- Various chip setup ----------------------*/
> static int lan9303_disable_packet_processing(struct lan9303 *chip,
> unsigned int port)
> {
> @@ -729,6 +968,14 @@ static int lan9303_setup(struct dsa_switch *ds)
> return 0;
> }
>
> +static int lan9303_set_addr(struct dsa_switch *ds, u8 *addr)
> +{
> + struct lan9303 *chip = ds->priv;
> +
> + lan9303_alr_add_port(chip, addr, 0, false);
> + return 0;
> +}
> +
I would probably make this a separate patch.
Andrew
^ permalink raw reply
* Re: [PATCH net-next v2 01/10] net: dsa: lan9303: Fixed MDIO interface
From: Andrew Lunn @ 2017-07-26 17:52 UTC (permalink / raw)
To: Vivien Didelot
Cc: Egil Hjelmeland, corbet, f.fainelli, davem, kernel, linux-doc,
linux-kernel, netdev
In-Reply-To: <87lgnbgtiq.fsf@weeman.i-did-not-set--mail-host-address--so-tickle-me>
> > So I really want to group the patches into only a few series in order
> > to not spend months on the process.
I strongly agree with Vivien here. Good patches get accepted in about
3 days. You should expect feedback within a day or two. That allows
you to have fast cycle times for getting patches in.
Andrew
^ permalink raw reply
* Re: [RFC] switchdev: clarify ndo_get_phys_port_name() formats
From: Andy Gospodarek @ 2017-07-26 17:54 UTC (permalink / raw)
To: Jakub Kicinski
Cc: netdev, Jiri Pirko, Or Gerlitz, Michael Chan, Sathya Perla,
simon.horman, davem
In-Reply-To: <20170725193447.3a714d61@cakuba.netronome.com>
On Tue, Jul 25, 2017 at 07:34:47PM -0700, Jakub Kicinski wrote:
> On Tue, 25 Jul 2017 21:48:15 -0400, Andy Gospodarek wrote:
> > On Tue, Jul 25, 2017 at 03:26:47PM -0700, Jakub Kicinski wrote:
> > > On Tue, 25 Jul 2017 11:22:41 -0400, Andy Gospodarek wrote:
> > > > On Mon, Jul 24, 2017 at 10:13:44PM -0700, Jakub Kicinski wrote:
> > > > > We are still in position where we can suggest uniform naming
> > > > > convention for ndo_get_phys_port_name(). switchdev.txt file
> > > > > already contained a suggestion of how to name external ports.
> > > > > Since the use of switchdev for SR-IOV NIC's eswitches is growing,
> > > > > establish a format for ports of those devices as well.
> > > > >
> > > > > Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
> > > >
> > > > This is a nice addition and I suspect there could be even more done to
> > > > update this file to cover the VF rep usage.
> > > >
> > > > > ---
> > > > > Documentation/networking/switchdev.txt | 14 +++++++++++---
> > > > > 1 file changed, 11 insertions(+), 3 deletions(-)
> > > > >
> > > > > diff --git a/Documentation/networking/switchdev.txt b/Documentation/networking/switchdev.txt
> > > > > index 3e7b946dea27..7c4b6025fb4b 100644
> > > > > --- a/Documentation/networking/switchdev.txt
> > > > > +++ b/Documentation/networking/switchdev.txt
> > > > > @@ -119,9 +119,17 @@ into 4 10G ports, resulting in 4 port netdevs, the device can give a unique
> > > > > SUBSYSTEM=="net", ACTION=="add", ATTR{phys_switch_id}=="<phys_switch_id>", \
> > > > > ATTR{phys_port_name}!="", NAME="swX$attr{phys_port_name}"
> > > > >
> > > > > -Suggested naming convention is "swXpYsZ", where X is the switch name or ID, Y
> > > > > -is the port name or ID, and Z is the sub-port name or ID. For example, sw1p1s0
> > > > > -would be sub-port 0 on port 1 on switch 1.
> > > > > +Suggested formats of the port name returned by ndo_get_phys_port_name are:
> > > > > + - pA for external ports;
> > > > > + - pAsB for split external ports;
> > > > > + - pfC for PF ports (so called PF representors);
> > > > > + - pfCvfD for VF ports (so called VF representors).
> > > >
> > > > I hate to clutter this up, but might be also need to add:
> > > >
> > > > - pfCsB for split PF ports (so called PF representors);
> > > > - pfCsBvfD for split VF ports (so called VF representors).
> > > >
> > > > or are we comfortable that these additions to the name for split ports
> > > > are implied?
> > >
> > > Hm.. What is a split PF port? Splits happen on the physical port - see
> > > my rant on the thread this is a reply to ;) PFs are PCIe functions,
> > > on the opposite side of the eswitch from the wires.
> >
> > I'm with you that I think there is value in separate netdevs to
> > represent "PFs, VFs and external ports/MACs" -- particularly for the
> > use-case you to create rules to control PF<->VF traffic.
> >
> > So while I'm not saying it is a _great_ idea to support such a thing as
> > port-splitting of PFs, I suggested this addition as I'm not willing to restrict
> > such a design/implementation if a vendor or customer desired. It seemed
> > useful to provde some guidance on how to name them -- even if we do not
> > like them. :-)
>
> If I understand you correctly split PF would be a situation where
> device has multiple port instances on the PCIe PF side? IOW switch sees
> multiple endpoints on the PF side? Let me attempt an ASCII diagram :)
>
>
> HOST A || HOST B
> ||
> PF A | V | V | V | V || PF B | V | V | V
> | F | F | F | F ... || | F | F | F ...
> port A0 | port A1 | 0 | 1 | 2 | 3 || port B0 | port B1 | 0 | 1 | 2
> ||
> PCI Express link || PCI Express link
> \ \ \ | | | | | / / /
> \ \ \ | | | | | / / /
> \______\______\' | | | '____/___/___/
> /---------------------------\
> |<<========== |
> | ==========>> |
> | SR-IOV e-switch |
> |<<========== |
> | ==========>> |
> \---------------------------/
> | | |
> | | |
> || ||
> MAC 0 || MAC 1 || MAC 2
> || ||
>
>
> Seems to be a valid configuration, perhaps this would actually be of
> some use in container workloads, especially if the ports could be
> instantiated at runtime in high numbers. I would be cautious though
> with calling the instances splits. The more different PFs look from
> MACs the better IMHO. Do you actually have that problem today?
>
> Is there any HW supported upstream which would benefit from this? Could we
> decide on naming when we have an example implementation? In theory
> nothing stops us from splitting VFs the same way.
Not that I know about right now.
> Another note on PF netdevs, perhaps the most awkward thing about them,
> is that they result in two netdevs being visible to the host. This is
> not incorrect, since VFs if unassigned to VMs will end up creating an
> "actual" netdev and the switchdev port representor too, but it rubs
> some people the wrong way. Which in turn makes those people try to not
> spawn separate netdevs, which is incorrect IMHO, and breaks down e.g.
> when the real netdev gets assigned to a namespace.
For me, the most awkward part of having a separate netdev for the PF and
the MAC is that is really not how things were thought about in the
nominal switching case (the non e-switch case).
Since idea behind switchdev when it was created was to make sure that
each front-panel port on a switch was represented by a netdev in the
kernel (and the 'CPU interface' was abstracted away by the driver) I was
always a bit uneasy about having a separate netdev allocated for the CPU
port when in the switching case it really wasn't necessary.
> I'm not sure if this clarifies my thinking, I have, however, seem to
> have drawn a moose :)
Which looks great, BTW. The moose may turn out to be one of the major
benefits from this thread!
^ permalink raw reply
* Re: [PATCH RFC 00/13] phylink and sfp support
From: Russell King - ARM Linux @ 2017-07-26 18:07 UTC (permalink / raw)
To: Andrew Lunn; +Cc: Florian Fainelli, netdev
In-Reply-To: <20170726164411.GM12049@lunn.ch>
On Wed, Jul 26, 2017 at 06:44:11PM +0200, Andrew Lunn wrote:
> Do you have a git branch we can look at to see these changes. It helps
> understand the API when you can see both sides of it.
git://git.armlinux.org.uk/~rmk/linux-arm.git phy
or head to the cgit at:
git.armlinux.org.uk/cgit/linux-arm.git/log/?h=phy
Not only does that include the mvneta changes, but also the changes to
the 88x3310 driver (although incomplete, but functional.)
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
^ permalink raw reply
* [PATCH net-next 0/3] nfp: extend firmware request logic
From: Jakub Kicinski @ 2017-07-26 18:09 UTC (permalink / raw)
To: netdev; +Cc: oss-drivers, Jakub Kicinski
Hi!
We have been pondering for some time how to support loading different
application firmwares onto NFP. We want to support both users selecting
one of the firmware images provided by Netronome (which are optimized
for different use cases each) as well as firmware images created by
users themselves or other companies.
In the end we decided to go with the simplest solution - depending on
the right firmware image being placed in /lib/firmware. This vastly
simplifies driver logic and also doesn't require any new API.
Different NICs on one system may want to run different applications
therefore we first try to load firmware specific to the device (by
serial number of PCI slot) and if not present try the device model
based name we have been using so far.
Jakub Kicinski (3):
nfp: remove the probe deferral when FW not present
nfp: look for firmware image by device serial number and PCI name
nfp: only use direct firmware requests
drivers/net/ethernet/netronome/nfp/nfp_main.c | 48 ++++++++++++++++++-----
drivers/net/ethernet/netronome/nfp/nfp_net_main.c | 2 +-
2 files changed, 39 insertions(+), 11 deletions(-)
--
2.11.0
^ permalink raw reply
* [PATCH net-next 1/3] nfp: remove the probe deferral when FW not present
From: Jakub Kicinski @ 2017-07-26 18:09 UTC (permalink / raw)
To: netdev; +Cc: oss-drivers, Jakub Kicinski
In-Reply-To: <20170726180948.3220-1-jakub.kicinski@netronome.com>
We use a hack to defer probe when firmware was not pre-loaded
or found on disk. This helps in case users forgot to include
firmware in initramfs, the driver will most likely get another
shot at probing after real root is mounted.
This is not for what EPROBE_DEFER is supposed to be used, and
when FW is completely missing every time new device is probed
NFP will reprobe spamming kernel logs.
Remove this hack, users will now have to make sure the right
firmware image is present in initramfs if nfp.ko is placed
there or built in.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
drivers/net/ethernet/netronome/nfp/nfp_net_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
index 5797dbf2b507..d5e2361f0e86 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
@@ -704,7 +704,7 @@ int nfp_net_pci_probe(struct nfp_pf *pf)
if (!pf->rtbl) {
nfp_err(pf->cpp, "No %s, giving up.\n",
pf->fw_loaded ? "symbol table" : "firmware found");
- return -EPROBE_DEFER;
+ return -EINVAL;
}
mutex_lock(&pf->lock);
--
2.11.0
^ permalink raw reply related
* [PATCH net-next 2/3] nfp: look for firmware image by device serial number and PCI name
From: Jakub Kicinski @ 2017-07-26 18:09 UTC (permalink / raw)
To: netdev; +Cc: oss-drivers, Jakub Kicinski
In-Reply-To: <20170726180948.3220-1-jakub.kicinski@netronome.com>
We generally look up firmware by card type, but that doesn't allow
users who have more than one card of the same type in their system
to select firmware per adapter.
Unfortunately user space firmware helper seems fraught with
difficulties and to be on its way out. In particular support for
handling firmware uevents have been dropped from systemd and most
distributions don't enable the FW fallback by default any more.
To allow users selecting firmware for a particular device look up
firmware names by serial and pci_name(). Use the direct lookup to
disable generating uevents when enabled in Kconfig and not print
any warnings to logs if adapter-specific files are missing. Users
can place in /lib/firmware/netronome files named:
pci-${pci_name}.nffw
serial-${serial}.nffw
to target a specific card. E.g.:
pci-0000:04:00.0.nffw
pci-0000:82:00.0.nffw
serial-00-aa-bb-11-22-33-10-ff.nffw
We use the full serial number including the interface id, as it
appears in lspci output (bytes separated by '-').
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
drivers/net/ethernet/netronome/nfp/nfp_main.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_main.c b/drivers/net/ethernet/netronome/nfp/nfp_main.c
index d67969d3e484..13d056da0765 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_main.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_main.c
@@ -188,9 +188,27 @@ nfp_net_fw_find(struct pci_dev *pdev, struct nfp_pf *pf)
struct nfp_eth_table_port *port;
const char *fw_model;
char fw_name[256];
+ const u8 *serial;
int spc, err = 0;
+ u16 interface;
int i, j;
+ /* First try to find a firmware image specific for this device */
+ interface = nfp_cpp_interface(pf->cpp);
+ nfp_cpp_serial(pf->cpp, &serial);
+ sprintf(fw_name, "netronome/serial-%pMF-%02hhx-%02hhx.nffw",
+ serial, interface >> 8, interface & 0xff);
+ err = request_firmware_direct(&fw, fw_name, &pdev->dev);
+ if (!err)
+ goto done;
+
+ /* Then try the PCI name */
+ sprintf(fw_name, "netronome/pci-%s.nffw", pci_name(pdev));
+ err = request_firmware_direct(&fw, fw_name, &pdev->dev);
+ if (!err)
+ goto done;
+
+ /* Finally try the card type and media */
if (!pf->eth_tbl) {
dev_err(&pdev->dev, "Error: can't identify media config\n");
return NULL;
@@ -226,7 +244,7 @@ nfp_net_fw_find(struct pci_dev *pdev, struct nfp_pf *pf)
err = request_firmware(&fw, fw_name, &pdev->dev);
if (err)
return NULL;
-
+done:
dev_info(&pdev->dev, "Loading FW image: %s\n", fw_name);
return fw;
--
2.11.0
^ permalink raw reply related
* [PATCH net-next 3/3] nfp: only use direct firmware requests
From: Jakub Kicinski @ 2017-07-26 18:09 UTC (permalink / raw)
To: netdev; +Cc: oss-drivers, Jakub Kicinski
In-Reply-To: <20170726180948.3220-1-jakub.kicinski@netronome.com>
request_firmware() will fallback to user space helper and may cause
long delays when driver is loaded if udev doesn't correctly handle
FW requests. Since we never really made use of the user space
helper functionality switch to the simpler request_firmware_direct()
call. The side effect of this change is that no warning will be
printed when the FW image does not exists. To help users figure
out which FW file is missing print a info message when we request
each file.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
drivers/net/ethernet/netronome/nfp/nfp_main.c | 42 +++++++++++++++++----------
1 file changed, 26 insertions(+), 16 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_main.c b/drivers/net/ethernet/netronome/nfp/nfp_main.c
index 13d056da0765..dd769eceb33d 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_main.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_main.c
@@ -174,6 +174,21 @@ static int nfp_pcie_sriov_configure(struct pci_dev *pdev, int num_vfs)
return nfp_pcie_sriov_enable(pdev, num_vfs);
}
+static const struct firmware *
+nfp_net_fw_request(struct pci_dev *pdev, struct nfp_pf *pf, const char *name)
+{
+ const struct firmware *fw = NULL;
+ int err;
+
+ err = request_firmware_direct(&fw, name, &pdev->dev);
+ nfp_info(pf->cpp, " %s: %s\n",
+ name, err ? "not found" : "found, loading...");
+ if (err)
+ return NULL;
+
+ return fw;
+}
+
/**
* nfp_net_fw_find() - Find the correct firmware image for netdev mode
* @pdev: PCI Device structure
@@ -184,29 +199,30 @@ static int nfp_pcie_sriov_configure(struct pci_dev *pdev, int num_vfs)
static const struct firmware *
nfp_net_fw_find(struct pci_dev *pdev, struct nfp_pf *pf)
{
- const struct firmware *fw = NULL;
struct nfp_eth_table_port *port;
+ const struct firmware *fw;
const char *fw_model;
char fw_name[256];
const u8 *serial;
- int spc, err = 0;
u16 interface;
- int i, j;
+ int spc, i, j;
+
+ nfp_info(pf->cpp, "Looking for firmware file in order of priority:\n");
/* First try to find a firmware image specific for this device */
interface = nfp_cpp_interface(pf->cpp);
nfp_cpp_serial(pf->cpp, &serial);
sprintf(fw_name, "netronome/serial-%pMF-%02hhx-%02hhx.nffw",
serial, interface >> 8, interface & 0xff);
- err = request_firmware_direct(&fw, fw_name, &pdev->dev);
- if (!err)
- goto done;
+ fw = nfp_net_fw_request(pdev, pf, fw_name);
+ if (fw)
+ return fw;
/* Then try the PCI name */
sprintf(fw_name, "netronome/pci-%s.nffw", pci_name(pdev));
- err = request_firmware_direct(&fw, fw_name, &pdev->dev);
- if (!err)
- goto done;
+ fw = nfp_net_fw_request(pdev, pf, fw_name);
+ if (fw)
+ return fw;
/* Finally try the card type and media */
if (!pf->eth_tbl) {
@@ -241,13 +257,7 @@ nfp_net_fw_find(struct pci_dev *pdev, struct nfp_pf *pf)
if (spc <= 0)
return NULL;
- err = request_firmware(&fw, fw_name, &pdev->dev);
- if (err)
- return NULL;
-done:
- dev_info(&pdev->dev, "Loading FW image: %s\n", fw_name);
-
- return fw;
+ return nfp_net_fw_request(pdev, pf, fw_name);
}
/**
--
2.11.0
^ permalink raw reply related
* Re: [PATCH 0/4] Configuring traffic classes via new hardware offload mechanism in tc/mqprio
From: Nambiar, Amritha @ 2017-07-26 18:18 UTC (permalink / raw)
To: Richard Cochran, Jeff Kirsher
Cc: intel-wired-lan, Or Gerlitz, alexander.h.duyck, kiran.patil,
sridhar.samudrala, mitch.a.williams, neerav.parikh, netdev,
John Fastabend, Wyborny, Carolyn
In-Reply-To: <20170721094244.nkkmvb7fvk6akbvq@localhost.localdomain>
On 7/21/2017 2:42 AM, Richard Cochran wrote:
> On Mon, May 22, 2017 at 12:31:12PM -0700, Jeff Kirsher wrote:
>> On Fri, 2017-05-19 at 17:58 -0700, Amritha Nambiar wrote:
>>> The following series introduces a new harware offload mode in tc/mqprio
>>> where the TCs, the queue configurations and bandwidth rate limits are
>>> offloaded to the hardware.
>
> ...
>
>> This was meant to be sent out as an RFC, but apparently that did not get
>> conveyed when these were sent out Friday.
>
> I am looking at tc/mqprio and dcb with the purpose of implementing
>
> - Forwarding and Queuing Enhancements for Time-Sensitive Streams (FQTSS)
> 802.1Q-2014 Clause 34
>
> - Scheduled Traffic (time based scheduling)
> P802.1Qbv
>
> using the HW capabilities of the i210. This series looks like a
> promising avenue for these features.
>
> My question is, did series go anywhere?
>
> I didn't see any follow ups on netdev, but maybe I missed something.
I have submitted another series as non-RFC for next-queue maintained by
Jeff Kirsher. This is going to come through the next-queue tree. You can
follow the new series "[PATCH 0/6] Configuring traffic classes via new
hardware offload mechanism in tc/mqprio" at
https://www.mail-archive.com/netdev@vger.kernel.org/msg177390.html
>
> Thanks,
> Richard
>
>
>
^ permalink raw reply
* Re: [PATCH v7 2/3] PCI: Enable PCIe Relaxed Ordering if supported
From: Casey Leedom @ 2017-07-26 18:26 UTC (permalink / raw)
To: Alex Williamson, Ding Tianhong
Cc: Sinan Kaya, ashok.raj@intel.com, bhelgaas@google.com,
helgaas@kernel.org, Michael Werner, Ganesh GR,
asit.k.mallick@intel.com, patrick.j.cramer@intel.com,
Suravee.Suthikulpanit@amd.com, Bob.Shaw@amd.com,
l.stach@pengutronix.de, amira@mellanox.com,
gabriele.paoloni@huawei.com, David.Laight@aculab.com,
jeffrey.t.kirsher@intel.com, catalin.marinas@arm.com
In-Reply-To: <20170724090516.2e0f0d2a@w520.home>
By the way Ding, two issues:
1. Did we ever get any acknowledgement from either Intel or AMD
on this patch? I know that we can't ensure that, but it sure would
be nice since the PCI Quirks that we're putting in affect their
products.
2. I just realized that there's still a small hole in the patch with
respect to PCIe SR-IOV Virtual Functions. When the PCI Quirk
notices a problematic PCIe Device and marks it to note that
it's not "happy" receiving Transaction Layer Packets with the
Relaxed Ordering Attribute set, it's my understanding that your
current patch iterates down the PCIe Fabric and turns off the
PCIe Capability Device Control[Relaxed Ordering Enable].
But this scan may miss any SR-IOV VFs because they
probably won't be instantiated at that time. And, at a later
time, when they are instantiated, they could well have their
Relaxed Ordering Enable set.
I think that the patch will need to be extended to modify
drivers/pci.c/iov.c:sriov_enable() to explicitly turn off
Relaxed Ordering Enable if the Root Complex is marked
for no RO TLPs.
Casey
^ permalink raw reply
* Re: [PATCH net] ipv6: no need to return rt->dst.error if it is not null entry.
From: Roopa Prabhu @ 2017-07-26 18:27 UTC (permalink / raw)
To: David Ahern; +Cc: Hangbin Liu, Cong Wang, network dev
In-Reply-To: <9e198c2a-c026-f4bd-f190-8d5a887efe7f@gmail.com>
On Wed, Jul 26, 2017 at 10:18 AM, David Ahern <dsahern@gmail.com> wrote:
> On 7/25/17 1:32 AM, Hangbin Liu wrote:
>> On Mon, Jul 24, 2017 at 09:28:07PM -0600, David Ahern wrote:
>>> On 7/24/17 6:08 PM, Hangbin Liu wrote:
>>>> That's why I think we should remove both rt->dst.error and ip6_null_entry
>>>> check in inet6_rtm_getroute(). And even further, remove the ip6_null_entry
>>>> check in rt6_dump_route().
>>>
>>> git blame net/ipv6/route.c
>>>
>>> find the commits and review.
>>
>> Hi David,
>>
>> Sorry, would you like to give me more hints?
>>
>> I saw your commit 1f17e2f2c8a8 ("net: ipv6: ignore null_entry on route
>> dumps"). But I think this issue has been fixed by
>>
>> 2f460933f58e ("ipv6: initialize route null entry in addrconf_init()") and
>> 242d3a49a2a1 ("ipv6: reorder ip6_route_dev_notifier after ipv6_dev_notf")
>>
>> I use a reproducer which add unreachable route in netns with lo down. And I
>> could not trigger Panic in the fixed kernel. That's why I think we could
>> remove ip6_null_entry check in rt6_dump_route().
>
> Understood. Cong's patch to fix the intialization order (lo device
> before route init) makes sure the idev is not null. That said, the
> null_entry route is internal ipv6 logic and is not a route entry to be
> returned to userspace.
agreed...so looks like the check in v3 should be
+ if ( rt == net->ipv6.ip6_null_entry ||
+ (rt->dst.error &&
+ #ifdef CONFIG_IPV6_MULTIPLE_TABLES
+ rt != net->ipv6.ip6_prohibit_entry &&
+ rt != net->ipv6.ip6_blk_hole_entry &&
+#endif
+ )) {
err = rt->dst.error;
ip6_rt_put(rt);
goto errout;
^ permalink raw reply
* Re: [PATCH v2 2/4] can: fixed-transceiver: Add documentation for CAN fixed transceiver bindings
From: Franklin S Cooper Jr @ 2017-07-26 18:29 UTC (permalink / raw)
To: Oliver Hartkopp, Andrew Lunn
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
linux-can-u79uwXL29TY76Z2rM5mHXA, wg-5Yr1BZd7O62+XT7JhA+gdA,
mkl-bIcnvbaLZ9MEGnE8C9+IrQ, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
quentin.schulz-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
dev.kurt-yI9piX4KPfawT/RRk36CISFp6vIno51x,
sergei.shtylyov-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8
In-Reply-To: <355b90b3-97ce-1057-6617-d5d709449c48-fJ+pQTUTwRTk1uMJSBkQmQ@public.gmane.org>
On 07/26/2017 12:05 PM, Oliver Hartkopp wrote:
> On 07/26/2017 06:41 PM, Andrew Lunn wrote:
>> On Mon, Jul 24, 2017 at 06:05:19PM -0500, Franklin S Cooper Jr wrote:
>
>>> +
>>> +Optional:
>>> + max-arbitration-speed: a positive non 0 value that determines the max
>>> + speed that CAN can run in non CAN-FD mode or during the
>>> + arbitration phase in CAN-FD mode.
>>
>> Hi Franklin
>>
>> Since this and the next property are optional, it is good to document
>> what happens when they are not in the DT blob. Also document what 0
>> means.
The driver ignores values less than 0 with the exception being
max-data-speed which supports a value of -1. Not sure what I'm
documenting when the binding specifically says to use a positive non
zero value. Its the same reason I don't document what happens if you
give it a negative value.
>>
>>> +
>>> + max-data-speed: a positive non 0 value that determines the max
>>> data rate
>>> + that can be used in CAN-FD mode. A value of -1 implies
>>> + CAN-FD is not supported by the transceiver.
>>
>> -1 is ugly. I think it would be better to have a missing
>> max-data-speed property indicate that CAN-FD is not supported.
>
Although this leads to your later point I don't think this is the right
approach. Its an optional property. Not including the property should
not assume it isn't supported.
> Thanks Andrew! I had the same feeling about '-1' :-)
Ok I'll go back to having 0 = not supported. Which will handle the
documentation comment above.
>
>> And
>> maybe put 'fd' into the property name.
>
> Good point. In fact the common naming to set bitrates for CAN(FD)
> controllers are 'bitrate' and 'data bitrate'.
>
> 'speed' is not really a good word for that.
I'm fine with switching to using bitrate instead of speed. Kurk was
originally the one that suggested to use the term arbitration and data
since thats how the spec refers to it. Which I do agree with. But your
right that in the drivers (struct can_priv) we just use bittiming and
data_bittiming (CAN-FD timings). I don't think adding "fd" into the
property name makes sense unless we are calling it something like
"max-canfd-bitrate" which I would agree is the easiest to understand.
So what is the preference if we end up sticking with two properties?
Option 1 or 2?
1)
max-bitrate
max-data-bitrate
2)
max-bitrate
max-canfd-bitrate
>
> Finally, @Franklin:
>
> A CAN transceiver is limited in bandwidth. But you only have one RX and
> one TX line between the CAN controller and the CAN transceiver. The
> transceiver does not know about CAN FD - it has just a physical(!) layer
> with a limited bandwidth. This is ONE limitation.
>
> So I tend to specify only ONE 'max-bitrate' property for the
> fixed-transceiver binding.
>
> The fact whether the CAN controller is CAN FD capable or not is provided
> by the netlink configuration interface for CAN controllers.
Part of the reasoning to have two properties is to indicate that you
don't support CAN FD while limiting the "arbitration" bit rate. With one
property you can not determine this and end up having to make some
assumptions that can quickly end up biting people.
>
> Regards,
> Oliver
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" 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
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