* Re: [PATCH] of_mdio: use of_property_read_u32_array()
From: Sergei Shtylyov @ 2017-08-07 16:18 UTC (permalink / raw)
To: Rob Herring
Cc: Andrew Lunn, Florian Fainelli, Frank Rowand, netdev,
devicetree@vger.kernel.org
In-Reply-To: <CAL_JsqKDXAbAVpgMSU39+9mF7MZWQotLUNkjePy9eUsnBs99Vw@mail.gmail.com>
Hello!
On 08/07/2017 05:18 PM, Rob Herring wrote:
>> The "fixed-link" prop support predated of_property_read_u32_array(), so
>> basically had to open-code it. Using the modern API saves 24 bytes of the
>> object code (ARM gcc 4.8.5); the only behavior change would be that the
>> prop length check is now less strict (however the strict pre-check done
>> in of_phy_is_fixed_link() is left intact anyway)...
>>
>> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
>>
>> ---
>> The patch is against the 'dt/next' branch of Rob Herring's 'linux-git' repo
>> plus the previously posted patch killing the useless local variable in
>> of_phy_register_fixed_link().
>
> It shouldn't depend on anything in my tree and David normally takes
> of_mdio.c changes.
MAINTAINERS still only point at the DT repo, perhaps it should be updated?
> Reviewed-by: Rob Herring <robh@kernel.org>
Thank you.
>> drivers/of/of_mdio.c | 16 ++++++++--------
>> 1 file changed, 8 insertions(+), 8 deletions(-)
MBR, Sergei
^ permalink raw reply
* [PATCH net-next v3 3/3] net: dsa: remove useless args of dsa_slave_create
From: Vivien Didelot @ 2017-08-07 16:17 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
Andrew Lunn, Vivien Didelot
In-Reply-To: <20170807161710.5357-1-vivien.didelot@savoirfairelinux.com>
dsa_slave_create currently takes 4 arguments while it only needs the
related dsa_port and its name. Remove all other arguments.
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
---
net/dsa/dsa2.c | 2 +-
net/dsa/dsa_priv.h | 3 +--
net/dsa/legacy.c | 2 +-
net/dsa/slave.c | 14 +++++++-------
4 files changed, 10 insertions(+), 11 deletions(-)
diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
index 2a0120493cf1..cceaa4dd9f53 100644
--- a/net/dsa/dsa2.c
+++ b/net/dsa/dsa2.c
@@ -275,7 +275,7 @@ static int dsa_user_port_apply(struct dsa_port *port)
if (!name)
name = "eth%d";
- err = dsa_slave_create(ds, ds->dev, port->index, name);
+ err = dsa_slave_create(port, name);
if (err) {
dev_warn(ds->dev, "Failed to create slave %d: %d\n",
port->index, err);
diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
index 2873d912b12e..945ded148c9c 100644
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -148,8 +148,7 @@ int dsa_port_vlan_dump(struct dsa_port *dp,
extern const struct dsa_device_ops notag_netdev_ops;
void dsa_slave_mii_bus_init(struct dsa_switch *ds);
void dsa_cpu_port_ethtool_init(struct ethtool_ops *ops);
-int dsa_slave_create(struct dsa_switch *ds, struct device *parent,
- int port, const char *name);
+int dsa_slave_create(struct dsa_port *port, const char *name);
void dsa_slave_destroy(struct net_device *slave_dev);
int dsa_slave_suspend(struct net_device *slave_dev);
int dsa_slave_resume(struct net_device *slave_dev);
diff --git a/net/dsa/legacy.c b/net/dsa/legacy.c
index 903e8d70c792..612acf16d573 100644
--- a/net/dsa/legacy.c
+++ b/net/dsa/legacy.c
@@ -194,7 +194,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds,
if (!(ds->enabled_port_mask & (1 << i)))
continue;
- ret = dsa_slave_create(ds, ds->dev, i, cd->port_names[i]);
+ ret = dsa_slave_create(&ds->ports[i], cd->port_names[i]);
if (ret < 0)
netdev_err(master, "[%d]: can't create dsa slave device for port %d(%s): %d\n",
index, i, cd->port_names[i], ret);
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 75c5c5808220..6f2c1be1942f 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -1190,9 +1190,9 @@ int dsa_slave_resume(struct net_device *slave_dev)
return 0;
}
-int dsa_slave_create(struct dsa_switch *ds, struct device *parent,
- int port, const char *name)
+int dsa_slave_create(struct dsa_port *port, const char *name)
{
+ struct dsa_switch *ds = port->ds;
struct dsa_switch_tree *dst = ds->dst;
struct net_device *master;
struct net_device *slave_dev;
@@ -1222,8 +1222,8 @@ int dsa_slave_create(struct dsa_switch *ds, struct device *parent,
netdev_for_each_tx_queue(slave_dev, dsa_slave_set_lockdep_class_one,
NULL);
- SET_NETDEV_DEV(slave_dev, parent);
- slave_dev->dev.of_node = ds->ports[port].dn;
+ SET_NETDEV_DEV(slave_dev, port->ds->dev);
+ slave_dev->dev.of_node = port->dn;
slave_dev->vlan_features = master->vlan_features;
p = netdev_priv(slave_dev);
@@ -1232,7 +1232,7 @@ int dsa_slave_create(struct dsa_switch *ds, struct device *parent,
free_netdev(slave_dev);
return -ENOMEM;
}
- p->dp = &ds->ports[port];
+ p->dp = port;
INIT_LIST_HEAD(&p->mall_tc_list);
p->xmit = dst->tag_ops->xmit;
@@ -1240,12 +1240,12 @@ int dsa_slave_create(struct dsa_switch *ds, struct device *parent,
p->old_link = -1;
p->old_duplex = -1;
- ds->ports[port].netdev = slave_dev;
+ port->netdev = slave_dev;
ret = register_netdev(slave_dev);
if (ret) {
netdev_err(master, "error %d registering interface %s\n",
ret, slave_dev->name);
- ds->ports[port].netdev = NULL;
+ port->netdev = NULL;
free_percpu(p->stats64);
free_netdev(slave_dev);
return ret;
--
2.14.0
^ permalink raw reply related
* [PATCH net-next v3 2/3] net: dsa: remove useless args of dsa_cpu_dsa_setup
From: Vivien Didelot @ 2017-08-07 16:17 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
Andrew Lunn, Vivien Didelot
In-Reply-To: <20170807161710.5357-1-vivien.didelot@savoirfairelinux.com>
dsa_cpu_dsa_setup currently takes 4 arguments but they are all available
from the dsa_port argument. Remove all others.
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
---
net/dsa/dsa.c | 10 +++++-----
net/dsa/dsa2.c | 4 ++--
net/dsa/dsa_priv.h | 3 +--
net/dsa/legacy.c | 4 +---
4 files changed, 9 insertions(+), 12 deletions(-)
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index a91e520e735f..4118848b8e58 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -67,17 +67,17 @@ const struct dsa_device_ops *dsa_device_ops[DSA_TAG_LAST] = {
[DSA_TAG_PROTO_NONE] = &none_ops,
};
-int dsa_cpu_dsa_setup(struct dsa_switch *ds, struct device *dev,
- struct dsa_port *dport, int port)
+int dsa_cpu_dsa_setup(struct dsa_port *port)
{
- struct device_node *port_dn = dport->dn;
+ struct device_node *port_dn = port->dn;
+ struct dsa_switch *ds = port->ds;
struct phy_device *phydev;
int ret, mode;
if (of_phy_is_fixed_link(port_dn)) {
ret = of_phy_register_fixed_link(port_dn);
if (ret) {
- dev_err(dev, "failed to register fixed PHY\n");
+ dev_err(ds->dev, "failed to register fixed PHY\n");
return ret;
}
phydev = of_phy_find_device(port_dn);
@@ -90,7 +90,7 @@ int dsa_cpu_dsa_setup(struct dsa_switch *ds, struct device *dev,
genphy_config_init(phydev);
genphy_read_status(phydev);
if (ds->ops->adjust_link)
- ds->ops->adjust_link(ds, port, phydev);
+ ds->ops->adjust_link(ds, port->index, phydev);
put_device(&phydev->mdio.dev);
}
diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
index c442051d5a55..2a0120493cf1 100644
--- a/net/dsa/dsa2.c
+++ b/net/dsa/dsa2.c
@@ -219,7 +219,7 @@ static int dsa_dsa_port_apply(struct dsa_port *port)
struct dsa_switch *ds = port->ds;
int err;
- err = dsa_cpu_dsa_setup(ds, ds->dev, port, port->index);
+ err = dsa_cpu_dsa_setup(port);
if (err) {
dev_warn(ds->dev, "Failed to setup dsa port %d: %d\n",
port->index, err);
@@ -243,7 +243,7 @@ static int dsa_cpu_port_apply(struct dsa_port *port)
struct dsa_switch *ds = port->ds;
int err;
- err = dsa_cpu_dsa_setup(ds, ds->dev, port, port->index);
+ err = dsa_cpu_dsa_setup(port);
if (err) {
dev_warn(ds->dev, "Failed to setup cpu port %d: %d\n",
port->index, err);
diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
index 306cff229def..2873d912b12e 100644
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -101,8 +101,7 @@ struct dsa_slave_priv {
};
/* dsa.c */
-int dsa_cpu_dsa_setup(struct dsa_switch *ds, struct device *dev,
- struct dsa_port *dport, int port);
+int dsa_cpu_dsa_setup(struct dsa_port *port);
void dsa_cpu_dsa_destroy(struct dsa_port *dport);
const struct dsa_device_ops *dsa_resolve_tag_protocol(int tag_protocol);
int dsa_cpu_port_ethtool_setup(struct dsa_port *cpu_dp);
diff --git a/net/dsa/legacy.c b/net/dsa/legacy.c
index fa162030a69c..903e8d70c792 100644
--- a/net/dsa/legacy.c
+++ b/net/dsa/legacy.c
@@ -80,15 +80,13 @@ dsa_switch_probe(struct device *parent, struct device *host_dev, int sw_addr,
/* basic switch operations **************************************************/
static int dsa_cpu_dsa_setups(struct dsa_switch *ds)
{
- struct dsa_port *dport;
int ret, port;
for (port = 0; port < ds->num_ports; port++) {
if (!(dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)))
continue;
- dport = &ds->ports[port];
- ret = dsa_cpu_dsa_setup(ds, ds->dev, dport, port);
+ ret = dsa_cpu_dsa_setup(&ds->ports[port]);
if (ret)
return ret;
}
--
2.14.0
^ permalink raw reply related
* [PATCH net-next v3 1/3] net: dsa: remove useless argument in legacy setup
From: Vivien Didelot @ 2017-08-07 16:17 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
Andrew Lunn, Vivien Didelot
In-Reply-To: <20170807161710.5357-1-vivien.didelot@savoirfairelinux.com>
dsa_switch_alloc() already assigns ds-dev, which can be used in
dsa_switch_setup_one and dsa_cpu_dsa_setups instead of requiring an
additional struct device argument.
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
---
net/dsa/legacy.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/net/dsa/legacy.c b/net/dsa/legacy.c
index 1d7a3282f2a7..fa162030a69c 100644
--- a/net/dsa/legacy.c
+++ b/net/dsa/legacy.c
@@ -78,7 +78,7 @@ dsa_switch_probe(struct device *parent, struct device *host_dev, int sw_addr,
}
/* basic switch operations **************************************************/
-static int dsa_cpu_dsa_setups(struct dsa_switch *ds, struct device *dev)
+static int dsa_cpu_dsa_setups(struct dsa_switch *ds)
{
struct dsa_port *dport;
int ret, port;
@@ -88,15 +88,15 @@ static int dsa_cpu_dsa_setups(struct dsa_switch *ds, struct device *dev)
continue;
dport = &ds->ports[port];
- ret = dsa_cpu_dsa_setup(ds, dev, dport, port);
+ ret = dsa_cpu_dsa_setup(ds, ds->dev, dport, port);
if (ret)
return ret;
}
return 0;
}
-static int dsa_switch_setup_one(struct dsa_switch *ds, struct net_device *master,
- struct device *parent)
+static int dsa_switch_setup_one(struct dsa_switch *ds,
+ struct net_device *master)
{
const struct dsa_switch_ops *ops = ds->ops;
struct dsa_switch_tree *dst = ds->dst;
@@ -176,7 +176,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct net_device *master
}
if (!ds->slave_mii_bus && ops->phy_read) {
- ds->slave_mii_bus = devm_mdiobus_alloc(parent);
+ ds->slave_mii_bus = devm_mdiobus_alloc(ds->dev);
if (!ds->slave_mii_bus)
return -ENOMEM;
dsa_slave_mii_bus_init(ds);
@@ -196,14 +196,14 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct net_device *master
if (!(ds->enabled_port_mask & (1 << i)))
continue;
- ret = dsa_slave_create(ds, parent, i, cd->port_names[i]);
+ ret = dsa_slave_create(ds, ds->dev, i, cd->port_names[i]);
if (ret < 0)
netdev_err(master, "[%d]: can't create dsa slave device for port %d(%s): %d\n",
index, i, cd->port_names[i], ret);
}
/* Perform configuration of the CPU and DSA ports */
- ret = dsa_cpu_dsa_setups(ds, parent);
+ ret = dsa_cpu_dsa_setups(ds);
if (ret < 0)
netdev_err(master, "[%d] : can't configure CPU and DSA ports\n",
index);
@@ -252,7 +252,7 @@ dsa_switch_setup(struct dsa_switch_tree *dst, struct net_device *master,
ds->ops = ops;
ds->priv = priv;
- ret = dsa_switch_setup_one(ds, master, parent);
+ ret = dsa_switch_setup_one(ds, master);
if (ret)
return ERR_PTR(ret);
--
2.14.0
^ permalink raw reply related
* [PATCH net-next v3 0/3] net: dsa: remove useless arguments
From: Vivien Didelot @ 2017-08-07 16:17 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
Andrew Lunn, Vivien Didelot
Several DSA core setup functions take many arguments, mostly because of
the legacy code. This patch series removes the useless args of these
functions, where either the dsa_switch or dsa_port argument is enough.
Changes in v3:
- rebased on top of conflicting 5f6b4e14cada ("net: dsa: User per-cpu
64-bit statistics")
- added Florian's tags
Changes in v2:
- ds->dev is already assigned by dsa_switch_alloc
Vivien Didelot (3):
net: dsa: remove useless argument in legacy setup
net: dsa: remove useless args of dsa_cpu_dsa_setup
net: dsa: remove useless args of dsa_slave_create
net/dsa/dsa.c | 10 +++++-----
net/dsa/dsa2.c | 6 +++---
net/dsa/dsa_priv.h | 6 ++----
net/dsa/legacy.c | 18 ++++++++----------
net/dsa/slave.c | 14 +++++++-------
5 files changed, 25 insertions(+), 29 deletions(-)
--
2.14.0
^ permalink raw reply
* Re: [PATCH 05/27] ip: ipaddress.c: add support for json output
From: Stephen Hemminger @ 2017-08-07 16:12 UTC (permalink / raw)
To: Julien Fortin; +Cc: netdev, roopa, nikolay, dsa
In-Reply-To: <20170803155515.99226-6-julien@cumulusnetworks.com>
On Thu, 3 Aug 2017 17:54:53 +0200
Julien Fortin <julien@cumulusnetworks.com> wrote:
> From: Julien Fortin <julien@cumulusnetworks.com>
>
> This patch converts all output (mostly fprintfs) to the new ip_print api
> which handle both regular and json output.
> Initialize a json_writer and open an array object if -json was specified.
> Note that the JSON attribute naming follows the NETLINK_ATTRIBUTE naming.
>
> In many places throughout the code, IP, matches integer values with
> hardcoded strings tables, such as link mode, link operstate or link
> family.
> In JSON context, this will result in a named string field. In the
> very unlikely event that the requested index is out of bound, IP
> displays the raw integer value. For JSON context this result in
> having a different integer field example bellow:
>
> if (mode >= ARRAY_SIZE(link_modes))
> print_int(PRINT_ANY, "linkmode_index", "mode %d ", mode);
> else
> print_string(PRINT_ANY, "linkmode", "mode %s ",
> link_modes[mode]);
>
> The "_index" suffix is open to discussion and it is something that I came
> up with. The bottom line is that you can't have a string field that may
> become an int field in specific cases. Programs written in strongly type
> languages (like C) might break if they are expecting a string value and
> got an integer instead. We don't want to confuse anybody or make the code
> even more complicated handling these specifics cases.
> Hence the extra "_index" field that is easy to check for and deal with.
>
This patch does not apply to current master branch.
Please rebase.
^ permalink raw reply
* RE: EMPLOYEE SURVEY!!!!
From: Oo, Thiri T (OOTT15) @ 2017-08-07 16:10 UTC (permalink / raw)
To: Oo, Thiri T (OOTT15)
In-Reply-To: <2DAEB8DA4E10E74F9E6537665BF9D3CF0D67796C@Michael.juniata.edu>
________________________________
From: Oo, Thiri T (OOTT15)
Sent: Monday, August 07, 2017 10:20 PM
To: Oo, Thiri T (OOTT15)
Subject: EMPLOYEE SURVEY!!!!
Dear Colleague,
Please take a moment to complete a survey on incident INC0903501
Regarding "help desk survey on your email" Your feedback is extremely valuable.
Please Click HERE<https://www.powr.io/plugins/form-builder/view/10850205?mode=page> To Begin Survey.
HR Management
IT-SERVICE HELPDESK
CONFIDENTIALITY NOTICE: The materials in this electronic mail transmission (including all attachments) are private and confidential and are the property of the sender. The information contained in the material is privileged and is intended only for the use of the named addressee(s). If you are not the intended addressee, be advised that any unauthorized disclosure, copying, distribution or the taking of any action in reliance on the contents of this material is strictly prohibited. If you have received this e-mail in error, please immediately notify the sender by replying to the e-mail, and then destroy it immediately. Thank you.
^ permalink raw reply
* [PATCH v3 net-next 7/7] net: ipv6: add second dif to raw socket lookups
From: David Ahern @ 2017-08-07 15:44 UTC (permalink / raw)
To: netdev; +Cc: David Ahern
In-Reply-To: <1502120662-1430-1-git-send-email-dsahern@gmail.com>
Add a second device index, sdif, to raw socket lookups. sdif is the
index for ingress devices enslaved to an l3mdev. It allows the lookups
to consider the enslaved device as well as the L3 domain when searching
for a socket.
Signed-off-by: David Ahern <dsahern@gmail.com>
---
include/net/rawv6.h | 2 +-
net/ipv4/raw_diag.c | 2 +-
net/ipv6/raw.c | 13 ++++++++-----
3 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/include/net/rawv6.h b/include/net/rawv6.h
index cbe4e9de1894..4addc5c988e0 100644
--- a/include/net/rawv6.h
+++ b/include/net/rawv6.h
@@ -6,7 +6,7 @@
extern struct raw_hashinfo raw_v6_hashinfo;
struct sock *__raw_v6_lookup(struct net *net, struct sock *sk,
unsigned short num, const struct in6_addr *loc_addr,
- const struct in6_addr *rmt_addr, int dif);
+ const struct in6_addr *rmt_addr, int dif, int sdif);
int raw_abort(struct sock *sk, int err);
diff --git a/net/ipv4/raw_diag.c b/net/ipv4/raw_diag.c
index c600d3c71d4d..c200065ef9a5 100644
--- a/net/ipv4/raw_diag.c
+++ b/net/ipv4/raw_diag.c
@@ -52,7 +52,7 @@ static struct sock *raw_lookup(struct net *net, struct sock *from,
sk = __raw_v6_lookup(net, from, r->sdiag_raw_protocol,
(const struct in6_addr *)r->id.idiag_src,
(const struct in6_addr *)r->id.idiag_dst,
- r->id.idiag_if);
+ r->id.idiag_if, 0);
#endif
return sk;
}
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 60be012fe708..e4462b0ff801 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -72,7 +72,7 @@ EXPORT_SYMBOL_GPL(raw_v6_hashinfo);
struct sock *__raw_v6_lookup(struct net *net, struct sock *sk,
unsigned short num, const struct in6_addr *loc_addr,
- const struct in6_addr *rmt_addr, int dif)
+ const struct in6_addr *rmt_addr, int dif, int sdif)
{
bool is_multicast = ipv6_addr_is_multicast(loc_addr);
@@ -86,7 +86,9 @@ struct sock *__raw_v6_lookup(struct net *net, struct sock *sk,
!ipv6_addr_equal(&sk->sk_v6_daddr, rmt_addr))
continue;
- if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif)
+ if (sk->sk_bound_dev_if &&
+ sk->sk_bound_dev_if != dif &&
+ sk->sk_bound_dev_if != sdif)
continue;
if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr)) {
@@ -178,7 +180,8 @@ static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
goto out;
net = dev_net(skb->dev);
- sk = __raw_v6_lookup(net, sk, nexthdr, daddr, saddr, inet6_iif(skb));
+ sk = __raw_v6_lookup(net, sk, nexthdr, daddr, saddr,
+ inet6_iif(skb), inet6_sdif(skb));
while (sk) {
int filtered;
@@ -222,7 +225,7 @@ static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
}
}
sk = __raw_v6_lookup(net, sk_next(sk), nexthdr, daddr, saddr,
- inet6_iif(skb));
+ inet6_iif(skb), inet6_sdif(skb));
}
out:
read_unlock(&raw_v6_hashinfo.lock);
@@ -378,7 +381,7 @@ void raw6_icmp_error(struct sk_buff *skb, int nexthdr,
net = dev_net(skb->dev);
while ((sk = __raw_v6_lookup(net, sk, nexthdr, saddr, daddr,
- inet6_iif(skb)))) {
+ inet6_iif(skb), inet6_iif(skb)))) {
rawv6_err(sk, skb, NULL, type, code,
inner_offset, info);
sk = sk_next(sk);
--
2.1.4
^ permalink raw reply related
* [PATCH v3 net-next 6/7] net: ipv6: add second dif to inet6 socket lookups
From: David Ahern @ 2017-08-07 15:44 UTC (permalink / raw)
To: netdev; +Cc: David Ahern
In-Reply-To: <1502120662-1430-1-git-send-email-dsahern@gmail.com>
Add a second device index, sdif, to inet6 socket lookups. sdif is the
index for ingress devices enslaved to an l3mdev. It allows the lookups
to consider the enslaved device as well as the L3 domain when searching
for a socket.
TCP moves the data in the cb. Prior to tcp_v4_rcv (e.g., early demux) the
ingress index is obtained from IPCB using inet_sdif and after tcp_v4_rcv
tcp_v4_sdif is used.
Signed-off-by: David Ahern <dsahern@gmail.com>
---
include/net/inet6_hashtables.h | 22 +++++++++++++---------
include/net/tcp.h | 10 ++++++++++
net/dccp/ipv6.c | 4 ++--
net/ipv6/inet6_hashtables.c | 28 +++++++++++++++++-----------
net/ipv6/tcp_ipv6.c | 13 ++++++++-----
net/ipv6/udp.c | 7 ++++---
net/netfilter/xt_TPROXY.c | 4 ++--
7 files changed, 56 insertions(+), 32 deletions(-)
diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h
index b87becacd9d3..6e91e38a31da 100644
--- a/include/net/inet6_hashtables.h
+++ b/include/net/inet6_hashtables.h
@@ -49,7 +49,8 @@ struct sock *__inet6_lookup_established(struct net *net,
const struct in6_addr *saddr,
const __be16 sport,
const struct in6_addr *daddr,
- const u16 hnum, const int dif);
+ const u16 hnum, const int dif,
+ const int sdif);
struct sock *inet6_lookup_listener(struct net *net,
struct inet_hashinfo *hashinfo,
@@ -57,7 +58,8 @@ struct sock *inet6_lookup_listener(struct net *net,
const struct in6_addr *saddr,
const __be16 sport,
const struct in6_addr *daddr,
- const unsigned short hnum, const int dif);
+ const unsigned short hnum,
+ const int dif, const int sdif);
static inline struct sock *__inet6_lookup(struct net *net,
struct inet_hashinfo *hashinfo,
@@ -66,24 +68,25 @@ static inline struct sock *__inet6_lookup(struct net *net,
const __be16 sport,
const struct in6_addr *daddr,
const u16 hnum,
- const int dif,
+ const int dif, const int sdif,
bool *refcounted)
{
struct sock *sk = __inet6_lookup_established(net, hashinfo, saddr,
- sport, daddr, hnum, dif);
+ sport, daddr, hnum,
+ dif, sdif);
*refcounted = true;
if (sk)
return sk;
*refcounted = false;
return inet6_lookup_listener(net, hashinfo, skb, doff, saddr, sport,
- daddr, hnum, dif);
+ daddr, hnum, dif, sdif);
}
static inline struct sock *__inet6_lookup_skb(struct inet_hashinfo *hashinfo,
struct sk_buff *skb, int doff,
const __be16 sport,
const __be16 dport,
- int iif,
+ int iif, int sdif,
bool *refcounted)
{
struct sock *sk = skb_steal_sock(skb);
@@ -95,7 +98,7 @@ static inline struct sock *__inet6_lookup_skb(struct inet_hashinfo *hashinfo,
return __inet6_lookup(dev_net(skb_dst(skb)->dev), hashinfo, skb,
doff, &ipv6_hdr(skb)->saddr, sport,
&ipv6_hdr(skb)->daddr, ntohs(dport),
- iif, refcounted);
+ iif, sdif, refcounted);
}
struct sock *inet6_lookup(struct net *net, struct inet_hashinfo *hashinfo,
@@ -107,13 +110,14 @@ struct sock *inet6_lookup(struct net *net, struct inet_hashinfo *hashinfo,
int inet6_hash(struct sock *sk);
#endif /* IS_ENABLED(CONFIG_IPV6) */
-#define INET6_MATCH(__sk, __net, __saddr, __daddr, __ports, __dif) \
+#define INET6_MATCH(__sk, __net, __saddr, __daddr, __ports, __dif, __sdif) \
(((__sk)->sk_portpair == (__ports)) && \
((__sk)->sk_family == AF_INET6) && \
ipv6_addr_equal(&(__sk)->sk_v6_daddr, (__saddr)) && \
ipv6_addr_equal(&(__sk)->sk_v6_rcv_saddr, (__daddr)) && \
(!(__sk)->sk_bound_dev_if || \
- ((__sk)->sk_bound_dev_if == (__dif))) && \
+ ((__sk)->sk_bound_dev_if == (__dif)) || \
+ ((__sk)->sk_bound_dev_if == (__sdif))) && \
net_eq(sock_net(__sk), (__net)))
#endif /* _INET6_HASHTABLES_H */
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 2b89f1ab8552..999f3efe572b 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -827,6 +827,16 @@ static inline int tcp_v6_iif(const struct sk_buff *skb)
return l3_slave ? skb->skb_iif : TCP_SKB_CB(skb)->header.h6.iif;
}
+
+/* TCP_SKB_CB reference means this can not be used from early demux */
+static inline int tcp_v6_sdif(const struct sk_buff *skb)
+{
+#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV)
+ if (skb && ipv6_l3mdev_skb(TCP_SKB_CB(skb)->header.h6.flags))
+ return TCP_SKB_CB(skb)->header.h6.iif;
+#endif
+ return 0;
+}
#endif
/* TCP_SKB_CB reference means this can not be used from early demux */
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 1b58eac8aad3..47a7b59b355e 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -89,7 +89,7 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
sk = __inet6_lookup_established(net, &dccp_hashinfo,
&hdr->daddr, dh->dccph_dport,
&hdr->saddr, ntohs(dh->dccph_sport),
- inet6_iif(skb));
+ inet6_iif(skb), 0);
if (!sk) {
__ICMP6_INC_STATS(net, __in6_dev_get(skb->dev),
@@ -687,7 +687,7 @@ static int dccp_v6_rcv(struct sk_buff *skb)
lookup:
sk = __inet6_lookup_skb(&dccp_hashinfo, skb, __dccp_hdr_len(dh),
dh->dccph_sport, dh->dccph_dport,
- inet6_iif(skb), &refcounted);
+ inet6_iif(skb), 0, &refcounted);
if (!sk) {
dccp_pr_debug("failed to look up flow ID in table and "
"get corresponding socket\n");
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index b13b8f93079d..b01858f5deb1 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -56,7 +56,7 @@ struct sock *__inet6_lookup_established(struct net *net,
const __be16 sport,
const struct in6_addr *daddr,
const u16 hnum,
- const int dif)
+ const int dif, const int sdif)
{
struct sock *sk;
const struct hlist_nulls_node *node;
@@ -73,12 +73,12 @@ struct sock *__inet6_lookup_established(struct net *net,
sk_nulls_for_each_rcu(sk, node, &head->chain) {
if (sk->sk_hash != hash)
continue;
- if (!INET6_MATCH(sk, net, saddr, daddr, ports, dif))
+ if (!INET6_MATCH(sk, net, saddr, daddr, ports, dif, sdif))
continue;
if (unlikely(!refcount_inc_not_zero(&sk->sk_refcnt)))
goto out;
- if (unlikely(!INET6_MATCH(sk, net, saddr, daddr, ports, dif))) {
+ if (unlikely(!INET6_MATCH(sk, net, saddr, daddr, ports, dif, sdif))) {
sock_gen_put(sk);
goto begin;
}
@@ -96,7 +96,7 @@ EXPORT_SYMBOL(__inet6_lookup_established);
static inline int compute_score(struct sock *sk, struct net *net,
const unsigned short hnum,
const struct in6_addr *daddr,
- const int dif, bool exact_dif)
+ const int dif, const int sdif, bool exact_dif)
{
int score = -1;
@@ -110,9 +110,13 @@ static inline int compute_score(struct sock *sk, struct net *net,
score++;
}
if (sk->sk_bound_dev_if || exact_dif) {
- if (sk->sk_bound_dev_if != dif)
+ bool dev_match = (sk->sk_bound_dev_if == dif ||
+ sk->sk_bound_dev_if == sdif);
+
+ if (exact_dif && !dev_match)
return -1;
- score++;
+ if (sk->sk_bound_dev_if && dev_match)
+ score++;
}
if (sk->sk_incoming_cpu == raw_smp_processor_id())
score++;
@@ -126,7 +130,7 @@ struct sock *inet6_lookup_listener(struct net *net,
struct sk_buff *skb, int doff,
const struct in6_addr *saddr,
const __be16 sport, const struct in6_addr *daddr,
- const unsigned short hnum, const int dif)
+ const unsigned short hnum, const int dif, const int sdif)
{
unsigned int hash = inet_lhashfn(net, hnum);
struct inet_listen_hashbucket *ilb = &hashinfo->listening_hash[hash];
@@ -136,7 +140,7 @@ struct sock *inet6_lookup_listener(struct net *net,
u32 phash = 0;
sk_for_each(sk, &ilb->head) {
- score = compute_score(sk, net, hnum, daddr, dif, exact_dif);
+ score = compute_score(sk, net, hnum, daddr, dif, sdif, exact_dif);
if (score > hiscore) {
reuseport = sk->sk_reuseport;
if (reuseport) {
@@ -171,7 +175,7 @@ struct sock *inet6_lookup(struct net *net, struct inet_hashinfo *hashinfo,
bool refcounted;
sk = __inet6_lookup(net, hashinfo, skb, doff, saddr, sport, daddr,
- ntohs(dport), dif, &refcounted);
+ ntohs(dport), dif, 0, &refcounted);
if (sk && !refcounted && !refcount_inc_not_zero(&sk->sk_refcnt))
sk = NULL;
return sk;
@@ -187,8 +191,9 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row,
const struct in6_addr *daddr = &sk->sk_v6_rcv_saddr;
const struct in6_addr *saddr = &sk->sk_v6_daddr;
const int dif = sk->sk_bound_dev_if;
- const __portpair ports = INET_COMBINED_PORTS(inet->inet_dport, lport);
struct net *net = sock_net(sk);
+ const int sdif = l3mdev_master_ifindex_by_index(net, dif);
+ const __portpair ports = INET_COMBINED_PORTS(inet->inet_dport, lport);
const unsigned int hash = inet6_ehashfn(net, daddr, lport, saddr,
inet->inet_dport);
struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash);
@@ -203,7 +208,8 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row,
if (sk2->sk_hash != hash)
continue;
- if (likely(INET6_MATCH(sk2, net, saddr, daddr, ports, dif))) {
+ if (likely(INET6_MATCH(sk2, net, saddr, daddr, ports,
+ dif, sdif))) {
if (sk2->sk_state == TCP_TIME_WAIT) {
tw = inet_twsk(sk2);
if (twsk_unique(sk, sk2, twp))
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index ced5dcf37465..f776ec4ecf6d 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -350,7 +350,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
sk = __inet6_lookup_established(net, &tcp_hashinfo,
&hdr->daddr, th->dest,
&hdr->saddr, ntohs(th->source),
- skb->dev->ifindex);
+ skb->dev->ifindex, inet6_sdif(skb));
if (!sk) {
__ICMP6_INC_STATS(net, __in6_dev_get(skb->dev),
@@ -918,7 +918,8 @@ static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb)
&tcp_hashinfo, NULL, 0,
&ipv6h->saddr,
th->source, &ipv6h->daddr,
- ntohs(th->source), tcp_v6_iif(skb));
+ ntohs(th->source), tcp_v6_iif(skb),
+ tcp_v6_sdif(skb));
if (!sk1)
goto out;
@@ -1397,6 +1398,7 @@ static void tcp_v6_fill_cb(struct sk_buff *skb, const struct ipv6hdr *hdr,
static int tcp_v6_rcv(struct sk_buff *skb)
{
+ int sdif = inet6_sdif(skb);
const struct tcphdr *th;
const struct ipv6hdr *hdr;
bool refcounted;
@@ -1430,7 +1432,7 @@ static int tcp_v6_rcv(struct sk_buff *skb)
lookup:
sk = __inet6_lookup_skb(&tcp_hashinfo, skb, __tcp_hdrlen(th),
- th->source, th->dest, inet6_iif(skb),
+ th->source, th->dest, inet6_iif(skb), sdif,
&refcounted);
if (!sk)
goto no_tcp_socket;
@@ -1563,7 +1565,8 @@ static int tcp_v6_rcv(struct sk_buff *skb)
skb, __tcp_hdrlen(th),
&ipv6_hdr(skb)->saddr, th->source,
&ipv6_hdr(skb)->daddr,
- ntohs(th->dest), tcp_v6_iif(skb));
+ ntohs(th->dest), tcp_v6_iif(skb),
+ sdif);
if (sk2) {
struct inet_timewait_sock *tw = inet_twsk(sk);
inet_twsk_deschedule_put(tw);
@@ -1610,7 +1613,7 @@ static void tcp_v6_early_demux(struct sk_buff *skb)
sk = __inet6_lookup_established(dev_net(skb->dev), &tcp_hashinfo,
&hdr->saddr, th->source,
&hdr->daddr, ntohs(th->dest),
- inet6_iif(skb));
+ inet6_iif(skb), inet6_sdif(skb));
if (sk) {
skb->sk = sk;
skb->destructor = sock_edemux;
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index d96a877798a7..19afcaf4a22e 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -897,7 +897,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
static struct sock *__udp6_lib_demux_lookup(struct net *net,
__be16 loc_port, const struct in6_addr *loc_addr,
__be16 rmt_port, const struct in6_addr *rmt_addr,
- int dif)
+ int dif, int sdif)
{
unsigned short hnum = ntohs(loc_port);
unsigned int hash2 = udp6_portaddr_hash(net, loc_addr, hnum);
@@ -908,7 +908,7 @@ static struct sock *__udp6_lib_demux_lookup(struct net *net,
udp_portaddr_for_each_entry_rcu(sk, &hslot2->head) {
if (sk->sk_state == TCP_ESTABLISHED &&
- INET6_MATCH(sk, net, rmt_addr, loc_addr, ports, dif))
+ INET6_MATCH(sk, net, rmt_addr, loc_addr, ports, dif, sdif))
return sk;
/* Only check first socket in chain */
break;
@@ -923,6 +923,7 @@ static void udp_v6_early_demux(struct sk_buff *skb)
struct sock *sk;
struct dst_entry *dst;
int dif = skb->dev->ifindex;
+ int sdif = inet6_sdif(skb);
if (!pskb_may_pull(skb, skb_transport_offset(skb) +
sizeof(struct udphdr)))
@@ -934,7 +935,7 @@ static void udp_v6_early_demux(struct sk_buff *skb)
sk = __udp6_lib_demux_lookup(net, uh->dest,
&ipv6_hdr(skb)->daddr,
uh->source, &ipv6_hdr(skb)->saddr,
- dif);
+ dif, sdif);
else
return;
diff --git a/net/netfilter/xt_TPROXY.c b/net/netfilter/xt_TPROXY.c
index 94fb0fd0c667..ade4c10c28c6 100644
--- a/net/netfilter/xt_TPROXY.c
+++ b/net/netfilter/xt_TPROXY.c
@@ -195,7 +195,7 @@ nf_tproxy_get_sock_v6(struct net *net, struct sk_buff *skb, int thoff, void *hp,
thoff + __tcp_hdrlen(tcph),
saddr, sport,
daddr, ntohs(dport),
- in->ifindex);
+ in->ifindex, 0);
if (sk && !refcount_inc_not_zero(&sk->sk_refcnt))
sk = NULL;
@@ -208,7 +208,7 @@ nf_tproxy_get_sock_v6(struct net *net, struct sk_buff *skb, int thoff, void *hp,
case NFT_LOOKUP_ESTABLISHED:
sk = __inet6_lookup_established(net, &tcp_hashinfo,
saddr, sport, daddr, ntohs(dport),
- in->ifindex);
+ in->ifindex, 0);
break;
default:
BUG();
--
2.1.4
^ permalink raw reply related
* [PATCH v3 net-next 5/7] net: ipv6: add second dif to udp socket lookups
From: David Ahern @ 2017-08-07 15:44 UTC (permalink / raw)
To: netdev; +Cc: David Ahern
In-Reply-To: <1502120662-1430-1-git-send-email-dsahern@gmail.com>
Add a second device index, sdif, to udp socket lookups. sdif is the
index for ingress devices enslaved to an l3mdev. It allows the lookups
to consider the enslaved device as well as the L3 domain when searching
for a socket.
Early demux lookups are handled in the next patch as part of INET_MATCH
changes.
Signed-off-by: David Ahern <dsahern@gmail.com>
---
include/linux/ipv6.h | 10 ++++++++++
include/net/udp.h | 2 +-
net/ipv4/udp_diag.c | 4 ++--
net/ipv6/udp.c | 40 ++++++++++++++++++++++------------------
4 files changed, 35 insertions(+), 21 deletions(-)
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 474d6bbc158c..ac2da4e11d5e 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -159,6 +159,16 @@ static inline bool inet6_is_jumbogram(const struct sk_buff *skb)
}
/* can not be used in TCP layer after tcp_v6_fill_cb */
+static inline int inet6_sdif(const struct sk_buff *skb)
+{
+#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV)
+ if (skb && ipv6_l3mdev_skb(IP6CB(skb)->flags))
+ return IP6CB(skb)->iif;
+#endif
+ return 0;
+}
+
+/* can not be used in TCP layer after tcp_v6_fill_cb */
static inline bool inet6_exact_dif_match(struct net *net, struct sk_buff *skb)
{
#if defined(CONFIG_NET_L3_MASTER_DEV)
diff --git a/include/net/udp.h b/include/net/udp.h
index 826c713d5a48..20dcdca4e85c 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -298,7 +298,7 @@ struct sock *udp6_lib_lookup(struct net *net,
struct sock *__udp6_lib_lookup(struct net *net,
const struct in6_addr *saddr, __be16 sport,
const struct in6_addr *daddr, __be16 dport,
- int dif, struct udp_table *tbl,
+ int dif, int sdif, struct udp_table *tbl,
struct sk_buff *skb);
struct sock *udp6_lib_lookup_skb(struct sk_buff *skb,
__be16 sport, __be16 dport);
diff --git a/net/ipv4/udp_diag.c b/net/ipv4/udp_diag.c
index 1f07fe109535..d0390d844ac8 100644
--- a/net/ipv4/udp_diag.c
+++ b/net/ipv4/udp_diag.c
@@ -53,7 +53,7 @@ static int udp_dump_one(struct udp_table *tbl, struct sk_buff *in_skb,
req->id.idiag_sport,
(struct in6_addr *)req->id.idiag_dst,
req->id.idiag_dport,
- req->id.idiag_if, tbl, NULL);
+ req->id.idiag_if, 0, tbl, NULL);
#endif
if (sk && !refcount_inc_not_zero(&sk->sk_refcnt))
sk = NULL;
@@ -198,7 +198,7 @@ static int __udp_diag_destroy(struct sk_buff *in_skb,
req->id.idiag_dport,
(struct in6_addr *)req->id.idiag_src,
req->id.idiag_sport,
- req->id.idiag_if, tbl, NULL);
+ req->id.idiag_if, 0, tbl, NULL);
}
#endif
else {
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 578142b7ca3e..d96a877798a7 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -129,7 +129,7 @@ static void udp_v6_rehash(struct sock *sk)
static int compute_score(struct sock *sk, struct net *net,
const struct in6_addr *saddr, __be16 sport,
const struct in6_addr *daddr, unsigned short hnum,
- int dif, bool exact_dif)
+ int dif, int sdif, bool exact_dif)
{
int score;
struct inet_sock *inet;
@@ -161,9 +161,13 @@ static int compute_score(struct sock *sk, struct net *net,
}
if (sk->sk_bound_dev_if || exact_dif) {
- if (sk->sk_bound_dev_if != dif)
+ bool dev_match = (sk->sk_bound_dev_if == dif ||
+ sk->sk_bound_dev_if == sdif);
+
+ if (exact_dif && !dev_match)
return -1;
- score++;
+ if (sk->sk_bound_dev_if && dev_match)
+ score++;
}
if (sk->sk_incoming_cpu == raw_smp_processor_id())
@@ -175,9 +179,9 @@ static int compute_score(struct sock *sk, struct net *net,
/* called with rcu_read_lock() */
static struct sock *udp6_lib_lookup2(struct net *net,
const struct in6_addr *saddr, __be16 sport,
- const struct in6_addr *daddr, unsigned int hnum, int dif,
- bool exact_dif, struct udp_hslot *hslot2,
- struct sk_buff *skb)
+ const struct in6_addr *daddr, unsigned int hnum,
+ int dif, int sdif, bool exact_dif,
+ struct udp_hslot *hslot2, struct sk_buff *skb)
{
struct sock *sk, *result;
int score, badness, matches = 0, reuseport = 0;
@@ -187,7 +191,7 @@ static struct sock *udp6_lib_lookup2(struct net *net,
badness = -1;
udp_portaddr_for_each_entry_rcu(sk, &hslot2->head) {
score = compute_score(sk, net, saddr, sport,
- daddr, hnum, dif, exact_dif);
+ daddr, hnum, dif, sdif, exact_dif);
if (score > badness) {
reuseport = sk->sk_reuseport;
if (reuseport) {
@@ -214,10 +218,10 @@ static struct sock *udp6_lib_lookup2(struct net *net,
/* rcu_read_lock() must be held */
struct sock *__udp6_lib_lookup(struct net *net,
- const struct in6_addr *saddr, __be16 sport,
- const struct in6_addr *daddr, __be16 dport,
- int dif, struct udp_table *udptable,
- struct sk_buff *skb)
+ const struct in6_addr *saddr, __be16 sport,
+ const struct in6_addr *daddr, __be16 dport,
+ int dif, int sdif, struct udp_table *udptable,
+ struct sk_buff *skb)
{
struct sock *sk, *result;
unsigned short hnum = ntohs(dport);
@@ -235,7 +239,7 @@ struct sock *__udp6_lib_lookup(struct net *net,
goto begin;
result = udp6_lib_lookup2(net, saddr, sport,
- daddr, hnum, dif, exact_dif,
+ daddr, hnum, dif, sdif, exact_dif,
hslot2, skb);
if (!result) {
unsigned int old_slot2 = slot2;
@@ -250,7 +254,7 @@ struct sock *__udp6_lib_lookup(struct net *net,
goto begin;
result = udp6_lib_lookup2(net, saddr, sport,
- daddr, hnum, dif,
+ daddr, hnum, dif, sdif,
exact_dif, hslot2,
skb);
}
@@ -261,7 +265,7 @@ struct sock *__udp6_lib_lookup(struct net *net,
badness = -1;
sk_for_each_rcu(sk, &hslot->head) {
score = compute_score(sk, net, saddr, sport, daddr, hnum, dif,
- exact_dif);
+ sdif, exact_dif);
if (score > badness) {
reuseport = sk->sk_reuseport;
if (reuseport) {
@@ -294,7 +298,7 @@ static struct sock *__udp6_lib_lookup_skb(struct sk_buff *skb,
return __udp6_lib_lookup(dev_net(skb->dev), &iph->saddr, sport,
&iph->daddr, dport, inet6_iif(skb),
- udptable, skb);
+ inet6_sdif(skb), udptable, skb);
}
struct sock *udp6_lib_lookup_skb(struct sk_buff *skb,
@@ -304,7 +308,7 @@ struct sock *udp6_lib_lookup_skb(struct sk_buff *skb,
return __udp6_lib_lookup(dev_net(skb->dev), &iph->saddr, sport,
&iph->daddr, dport, inet6_iif(skb),
- &udp_table, skb);
+ inet6_sdif(skb), &udp_table, skb);
}
EXPORT_SYMBOL_GPL(udp6_lib_lookup_skb);
@@ -320,7 +324,7 @@ struct sock *udp6_lib_lookup(struct net *net, const struct in6_addr *saddr, __be
struct sock *sk;
sk = __udp6_lib_lookup(net, saddr, sport, daddr, dport,
- dif, &udp_table, NULL);
+ dif, 0, &udp_table, NULL);
if (sk && !refcount_inc_not_zero(&sk->sk_refcnt))
sk = NULL;
return sk;
@@ -501,7 +505,7 @@ void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
struct net *net = dev_net(skb->dev);
sk = __udp6_lib_lookup(net, daddr, uh->dest, saddr, uh->source,
- inet6_iif(skb), udptable, skb);
+ inet6_iif(skb), 0, udptable, skb);
if (!sk) {
__ICMP6_INC_STATS(net, __in6_dev_get(skb->dev),
ICMP6_MIB_INERRORS);
--
2.1.4
^ permalink raw reply related
* [PATCH v3 net-next 4/7] net: ipv4: add second dif to multicast source filter
From: David Ahern @ 2017-08-07 15:44 UTC (permalink / raw)
To: netdev; +Cc: David Ahern
In-Reply-To: <1502120662-1430-1-git-send-email-dsahern@gmail.com>
Signed-off-by: David Ahern <dsahern@gmail.com>
---
include/linux/igmp.h | 3 ++-
net/ipv4/igmp.c | 6 ++++--
net/ipv4/raw.c | 2 +-
net/ipv4/udp.c | 2 +-
4 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/include/linux/igmp.h b/include/linux/igmp.h
index 97caf1821de8..f8231854b5d6 100644
--- a/include/linux/igmp.h
+++ b/include/linux/igmp.h
@@ -118,7 +118,8 @@ extern int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf,
struct ip_msfilter __user *optval, int __user *optlen);
extern int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf,
struct group_filter __user *optval, int __user *optlen);
-extern int ip_mc_sf_allow(struct sock *sk, __be32 local, __be32 rmt, int dif);
+extern int ip_mc_sf_allow(struct sock *sk, __be32 local, __be32 rmt,
+ int dif, int sdif);
extern void ip_mc_init_dev(struct in_device *);
extern void ip_mc_destroy_dev(struct in_device *);
extern void ip_mc_up(struct in_device *);
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 28f14afd0dd3..5bc8570c2ec3 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -2549,7 +2549,8 @@ int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf,
/*
* check if a multicast source filter allows delivery for a given <src,dst,intf>
*/
-int ip_mc_sf_allow(struct sock *sk, __be32 loc_addr, __be32 rmt_addr, int dif)
+int ip_mc_sf_allow(struct sock *sk, __be32 loc_addr, __be32 rmt_addr,
+ int dif, int sdif)
{
struct inet_sock *inet = inet_sk(sk);
struct ip_mc_socklist *pmc;
@@ -2564,7 +2565,8 @@ int ip_mc_sf_allow(struct sock *sk, __be32 loc_addr, __be32 rmt_addr, int dif)
rcu_read_lock();
for_each_pmc_rcu(inet, pmc) {
if (pmc->multi.imr_multiaddr.s_addr == loc_addr &&
- pmc->multi.imr_ifindex == dif)
+ (pmc->multi.imr_ifindex == dif ||
+ (sdif && pmc->multi.imr_ifindex == sdif)))
break;
}
ret = inet->mc_all;
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 2726aecf224b..33b70bfd1122 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -193,7 +193,7 @@ static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash)
delivered = 1;
if ((iph->protocol != IPPROTO_ICMP || !icmp_filter(sk, skb)) &&
ip_mc_sf_allow(sk, iph->daddr, iph->saddr,
- skb->dev->ifindex)) {
+ skb->dev->ifindex, sdif)) {
struct sk_buff *clone = skb_clone(skb, GFP_ATOMIC);
/* Not releasing hash table! */
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 99f25bfec606..cac59d7420cd 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -606,7 +606,7 @@ static inline bool __udp_is_mcast_sock(struct net *net, struct sock *sk,
(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif &&
sk->sk_bound_dev_if != sdif))
return false;
- if (!ip_mc_sf_allow(sk, loc_addr, rmt_addr, dif))
+ if (!ip_mc_sf_allow(sk, loc_addr, rmt_addr, dif, sdif))
return false;
return true;
}
--
2.1.4
^ permalink raw reply related
* [PATCH v3 net-next 3/7] net: ipv4: add second dif to raw socket lookups
From: David Ahern @ 2017-08-07 15:44 UTC (permalink / raw)
To: netdev; +Cc: David Ahern
In-Reply-To: <1502120662-1430-1-git-send-email-dsahern@gmail.com>
Add a second device index, sdif, to raw socket lookups. sdif is the
index for ingress devices enslaved to an l3mdev. It allows the lookups
to consider the enslaved device as well as the L3 domain when searching
for a socket.
Signed-off-by: David Ahern <dsahern@gmail.com>
---
include/net/raw.h | 2 +-
net/ipv4/raw.c | 16 +++++++++++-----
net/ipv4/raw_diag.c | 2 +-
3 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/include/net/raw.h b/include/net/raw.h
index 57c33dd22ec4..99d26d0c4a19 100644
--- a/include/net/raw.h
+++ b/include/net/raw.h
@@ -26,7 +26,7 @@ extern struct proto raw_prot;
extern struct raw_hashinfo raw_v4_hashinfo;
struct sock *__raw_v4_lookup(struct net *net, struct sock *sk,
unsigned short num, __be32 raddr,
- __be32 laddr, int dif);
+ __be32 laddr, int dif, int sdif);
int raw_abort(struct sock *sk, int err);
void raw_icmp_error(struct sk_buff *, int, u32);
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index b0bb5d0a30bd..2726aecf224b 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -122,7 +122,8 @@ void raw_unhash_sk(struct sock *sk)
EXPORT_SYMBOL_GPL(raw_unhash_sk);
struct sock *__raw_v4_lookup(struct net *net, struct sock *sk,
- unsigned short num, __be32 raddr, __be32 laddr, int dif)
+ unsigned short num, __be32 raddr, __be32 laddr,
+ int dif, int sdif)
{
sk_for_each_from(sk) {
struct inet_sock *inet = inet_sk(sk);
@@ -130,7 +131,8 @@ struct sock *__raw_v4_lookup(struct net *net, struct sock *sk,
if (net_eq(sock_net(sk), net) && inet->inet_num == num &&
!(inet->inet_daddr && inet->inet_daddr != raddr) &&
!(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) &&
- !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
+ !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif &&
+ sk->sk_bound_dev_if != sdif))
goto found; /* gotcha */
}
sk = NULL;
@@ -171,6 +173,7 @@ static int icmp_filter(const struct sock *sk, const struct sk_buff *skb)
*/
static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash)
{
+ int sdif = inet_sdif(skb);
struct sock *sk;
struct hlist_head *head;
int delivered = 0;
@@ -184,7 +187,7 @@ static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash)
net = dev_net(skb->dev);
sk = __raw_v4_lookup(net, __sk_head(head), iph->protocol,
iph->saddr, iph->daddr,
- skb->dev->ifindex);
+ skb->dev->ifindex, sdif);
while (sk) {
delivered = 1;
@@ -199,7 +202,7 @@ static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash)
}
sk = __raw_v4_lookup(net, sk_next(sk), iph->protocol,
iph->saddr, iph->daddr,
- skb->dev->ifindex);
+ skb->dev->ifindex, sdif);
}
out:
read_unlock(&raw_v4_hashinfo.lock);
@@ -297,12 +300,15 @@ void raw_icmp_error(struct sk_buff *skb, int protocol, u32 info)
read_lock(&raw_v4_hashinfo.lock);
raw_sk = sk_head(&raw_v4_hashinfo.ht[hash]);
if (raw_sk) {
+ int dif = skb->dev->ifindex;
+ int sdif = inet_sdif(skb);
+
iph = (const struct iphdr *)skb->data;
net = dev_net(skb->dev);
while ((raw_sk = __raw_v4_lookup(net, raw_sk, protocol,
iph->daddr, iph->saddr,
- skb->dev->ifindex)) != NULL) {
+ dif, sdif)) != NULL) {
raw_err(raw_sk, skb, info);
raw_sk = sk_next(raw_sk);
iph = (const struct iphdr *)skb->data;
diff --git a/net/ipv4/raw_diag.c b/net/ipv4/raw_diag.c
index e1a51ca68d23..c600d3c71d4d 100644
--- a/net/ipv4/raw_diag.c
+++ b/net/ipv4/raw_diag.c
@@ -46,7 +46,7 @@ static struct sock *raw_lookup(struct net *net, struct sock *from,
sk = __raw_v4_lookup(net, from, r->sdiag_raw_protocol,
r->id.idiag_dst[0],
r->id.idiag_src[0],
- r->id.idiag_if);
+ r->id.idiag_if, 0);
#if IS_ENABLED(CONFIG_IPV6)
else
sk = __raw_v6_lookup(net, from, r->sdiag_raw_protocol,
--
2.1.4
^ permalink raw reply related
* [PATCH v3 net-next 2/7] net: ipv4: add second dif to inet socket lookups
From: David Ahern @ 2017-08-07 15:44 UTC (permalink / raw)
To: netdev; +Cc: David Ahern
In-Reply-To: <1502120662-1430-1-git-send-email-dsahern@gmail.com>
Add a second device index, sdif, to inet socket lookups. sdif is the
index for ingress devices enslaved to an l3mdev. It allows the lookups
to consider the enslaved device as well as the L3 domain when searching
for a socket.
TCP moves the data in the cb. Prior to tcp_v4_rcv (e.g., early demux) the
ingress index is obtained from IPCB using inet_sdif and after the cb move
in tcp_v4_rcv the tcp_v4_sdif helper is used.
Signed-off-by: David Ahern <dsahern@gmail.com>
---
include/net/inet_hashtables.h | 31 +++++++++++++++++--------------
include/net/tcp.h | 10 ++++++++++
net/dccp/ipv4.c | 4 ++--
net/ipv4/inet_hashtables.c | 27 +++++++++++++++++----------
net/ipv4/tcp_ipv4.c | 13 ++++++++-----
net/ipv4/udp.c | 6 +++---
net/netfilter/xt_TPROXY.c | 2 +-
7 files changed, 58 insertions(+), 35 deletions(-)
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
index 5026b1f08bb8..2dbbbff5e1e3 100644
--- a/include/net/inet_hashtables.h
+++ b/include/net/inet_hashtables.h
@@ -221,16 +221,16 @@ struct sock *__inet_lookup_listener(struct net *net,
const __be32 saddr, const __be16 sport,
const __be32 daddr,
const unsigned short hnum,
- const int dif);
+ const int dif, const int sdif);
static inline struct sock *inet_lookup_listener(struct net *net,
struct inet_hashinfo *hashinfo,
struct sk_buff *skb, int doff,
__be32 saddr, __be16 sport,
- __be32 daddr, __be16 dport, int dif)
+ __be32 daddr, __be16 dport, int dif, int sdif)
{
return __inet_lookup_listener(net, hashinfo, skb, doff, saddr, sport,
- daddr, ntohs(dport), dif);
+ daddr, ntohs(dport), dif, sdif);
}
/* Socket demux engine toys. */
@@ -262,22 +262,24 @@ static inline struct sock *inet_lookup_listener(struct net *net,
(((__force __u64)(__be32)(__daddr)) << 32) | \
((__force __u64)(__be32)(__saddr)))
#endif /* __BIG_ENDIAN */
-#define INET_MATCH(__sk, __net, __cookie, __saddr, __daddr, __ports, __dif) \
+#define INET_MATCH(__sk, __net, __cookie, __saddr, __daddr, __ports, __dif, __sdif) \
(((__sk)->sk_portpair == (__ports)) && \
((__sk)->sk_addrpair == (__cookie)) && \
(!(__sk)->sk_bound_dev_if || \
- ((__sk)->sk_bound_dev_if == (__dif))) && \
+ ((__sk)->sk_bound_dev_if == (__dif)) || \
+ ((__sk)->sk_bound_dev_if == (__sdif))) && \
net_eq(sock_net(__sk), (__net)))
#else /* 32-bit arch */
#define INET_ADDR_COOKIE(__name, __saddr, __daddr) \
const int __name __deprecated __attribute__((unused))
-#define INET_MATCH(__sk, __net, __cookie, __saddr, __daddr, __ports, __dif) \
+#define INET_MATCH(__sk, __net, __cookie, __saddr, __daddr, __ports, __dif, __sdif) \
(((__sk)->sk_portpair == (__ports)) && \
((__sk)->sk_daddr == (__saddr)) && \
((__sk)->sk_rcv_saddr == (__daddr)) && \
(!(__sk)->sk_bound_dev_if || \
- ((__sk)->sk_bound_dev_if == (__dif))) && \
+ ((__sk)->sk_bound_dev_if == (__dif)) || \
+ ((__sk)->sk_bound_dev_if == (__sdif))) && \
net_eq(sock_net(__sk), (__net)))
#endif /* 64-bit arch */
@@ -288,7 +290,7 @@ struct sock *__inet_lookup_established(struct net *net,
struct inet_hashinfo *hashinfo,
const __be32 saddr, const __be16 sport,
const __be32 daddr, const u16 hnum,
- const int dif);
+ const int dif, const int sdif);
static inline struct sock *
inet_lookup_established(struct net *net, struct inet_hashinfo *hashinfo,
@@ -297,7 +299,7 @@ static inline struct sock *
const int dif)
{
return __inet_lookup_established(net, hashinfo, saddr, sport, daddr,
- ntohs(dport), dif);
+ ntohs(dport), dif, 0);
}
static inline struct sock *__inet_lookup(struct net *net,
@@ -305,20 +307,20 @@ static inline struct sock *__inet_lookup(struct net *net,
struct sk_buff *skb, int doff,
const __be32 saddr, const __be16 sport,
const __be32 daddr, const __be16 dport,
- const int dif,
+ const int dif, const int sdif,
bool *refcounted)
{
u16 hnum = ntohs(dport);
struct sock *sk;
sk = __inet_lookup_established(net, hashinfo, saddr, sport,
- daddr, hnum, dif);
+ daddr, hnum, dif, sdif);
*refcounted = true;
if (sk)
return sk;
*refcounted = false;
return __inet_lookup_listener(net, hashinfo, skb, doff, saddr,
- sport, daddr, hnum, dif);
+ sport, daddr, hnum, dif, sdif);
}
static inline struct sock *inet_lookup(struct net *net,
@@ -332,7 +334,7 @@ static inline struct sock *inet_lookup(struct net *net,
bool refcounted;
sk = __inet_lookup(net, hashinfo, skb, doff, saddr, sport, daddr,
- dport, dif, &refcounted);
+ dport, dif, 0, &refcounted);
if (sk && !refcounted && !refcount_inc_not_zero(&sk->sk_refcnt))
sk = NULL;
@@ -344,6 +346,7 @@ static inline struct sock *__inet_lookup_skb(struct inet_hashinfo *hashinfo,
int doff,
const __be16 sport,
const __be16 dport,
+ const int sdif,
bool *refcounted)
{
struct sock *sk = skb_steal_sock(skb);
@@ -355,7 +358,7 @@ static inline struct sock *__inet_lookup_skb(struct inet_hashinfo *hashinfo,
return __inet_lookup(dev_net(skb_dst(skb)->dev), hashinfo, skb,
doff, iph->saddr, sport,
- iph->daddr, dport, inet_iif(skb),
+ iph->daddr, dport, inet_iif(skb), sdif,
refcounted);
}
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 5173fecde495..2b89f1ab8552 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -840,6 +840,16 @@ static inline bool inet_exact_dif_match(struct net *net, struct sk_buff *skb)
return false;
}
+/* TCP_SKB_CB reference means this can not be used from early demux */
+static inline int tcp_v4_sdif(struct sk_buff *skb)
+{
+#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV)
+ if (skb && ipv4_l3mdev_skb(TCP_SKB_CB(skb)->header.h4.flags))
+ return TCP_SKB_CB(skb)->header.h4.iif;
+#endif
+ return 0;
+}
+
/* Due to TSO, an SKB can be composed of multiple actual
* packets. To keep these tracked properly, we use this.
*/
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 1b202f16531f..001c08696334 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -256,7 +256,7 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info)
sk = __inet_lookup_established(net, &dccp_hashinfo,
iph->daddr, dh->dccph_dport,
iph->saddr, ntohs(dh->dccph_sport),
- inet_iif(skb));
+ inet_iif(skb), 0);
if (!sk) {
__ICMP_INC_STATS(net, ICMP_MIB_INERRORS);
return;
@@ -804,7 +804,7 @@ static int dccp_v4_rcv(struct sk_buff *skb)
lookup:
sk = __inet_lookup_skb(&dccp_hashinfo, skb, __dccp_hdr_len(dh),
- dh->dccph_sport, dh->dccph_dport, &refcounted);
+ dh->dccph_sport, dh->dccph_dport, 0, &refcounted);
if (!sk) {
dccp_pr_debug("failed to look up flow ID in table and "
"get corresponding socket\n");
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index 2e3389d614d1..597bb4cfe805 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -170,7 +170,7 @@ EXPORT_SYMBOL_GPL(__inet_inherit_port);
static inline int compute_score(struct sock *sk, struct net *net,
const unsigned short hnum, const __be32 daddr,
- const int dif, bool exact_dif)
+ const int dif, const int sdif, bool exact_dif)
{
int score = -1;
struct inet_sock *inet = inet_sk(sk);
@@ -185,9 +185,13 @@ static inline int compute_score(struct sock *sk, struct net *net,
score += 4;
}
if (sk->sk_bound_dev_if || exact_dif) {
- if (sk->sk_bound_dev_if != dif)
+ bool dev_match = (sk->sk_bound_dev_if == dif ||
+ sk->sk_bound_dev_if == sdif);
+
+ if (exact_dif && !dev_match)
return -1;
- score += 4;
+ if (sk->sk_bound_dev_if && dev_match)
+ score += 4;
}
if (sk->sk_incoming_cpu == raw_smp_processor_id())
score++;
@@ -208,7 +212,7 @@ struct sock *__inet_lookup_listener(struct net *net,
struct sk_buff *skb, int doff,
const __be32 saddr, __be16 sport,
const __be32 daddr, const unsigned short hnum,
- const int dif)
+ const int dif, const int sdif)
{
unsigned int hash = inet_lhashfn(net, hnum);
struct inet_listen_hashbucket *ilb = &hashinfo->listening_hash[hash];
@@ -218,7 +222,8 @@ struct sock *__inet_lookup_listener(struct net *net,
u32 phash = 0;
sk_for_each_rcu(sk, &ilb->head) {
- score = compute_score(sk, net, hnum, daddr, dif, exact_dif);
+ score = compute_score(sk, net, hnum, daddr,
+ dif, sdif, exact_dif);
if (score > hiscore) {
reuseport = sk->sk_reuseport;
if (reuseport) {
@@ -268,7 +273,7 @@ struct sock *__inet_lookup_established(struct net *net,
struct inet_hashinfo *hashinfo,
const __be32 saddr, const __be16 sport,
const __be32 daddr, const u16 hnum,
- const int dif)
+ const int dif, const int sdif)
{
INET_ADDR_COOKIE(acookie, saddr, daddr);
const __portpair ports = INET_COMBINED_PORTS(sport, hnum);
@@ -286,11 +291,12 @@ struct sock *__inet_lookup_established(struct net *net,
if (sk->sk_hash != hash)
continue;
if (likely(INET_MATCH(sk, net, acookie,
- saddr, daddr, ports, dif))) {
+ saddr, daddr, ports, dif, sdif))) {
if (unlikely(!refcount_inc_not_zero(&sk->sk_refcnt)))
goto out;
if (unlikely(!INET_MATCH(sk, net, acookie,
- saddr, daddr, ports, dif))) {
+ saddr, daddr, ports,
+ dif, sdif))) {
sock_gen_put(sk);
goto begin;
}
@@ -321,9 +327,10 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row,
__be32 daddr = inet->inet_rcv_saddr;
__be32 saddr = inet->inet_daddr;
int dif = sk->sk_bound_dev_if;
+ struct net *net = sock_net(sk);
+ int sdif = l3mdev_master_ifindex_by_index(net, dif);
INET_ADDR_COOKIE(acookie, saddr, daddr);
const __portpair ports = INET_COMBINED_PORTS(inet->inet_dport, lport);
- struct net *net = sock_net(sk);
unsigned int hash = inet_ehashfn(net, daddr, lport,
saddr, inet->inet_dport);
struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash);
@@ -339,7 +346,7 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row,
continue;
if (likely(INET_MATCH(sk2, net, acookie,
- saddr, daddr, ports, dif))) {
+ saddr, daddr, ports, dif, sdif))) {
if (sk2->sk_state == TCP_TIME_WAIT) {
tw = inet_twsk(sk2);
if (twsk_unique(sk, sk2, twp))
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 5f708c85110e..c8784ab37852 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -383,7 +383,7 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
sk = __inet_lookup_established(net, &tcp_hashinfo, iph->daddr,
th->dest, iph->saddr, ntohs(th->source),
- inet_iif(icmp_skb));
+ inet_iif(icmp_skb), 0);
if (!sk) {
__ICMP_INC_STATS(net, ICMP_MIB_INERRORS);
return;
@@ -659,7 +659,8 @@ static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb)
sk1 = __inet_lookup_listener(net, &tcp_hashinfo, NULL, 0,
ip_hdr(skb)->saddr,
th->source, ip_hdr(skb)->daddr,
- ntohs(th->source), inet_iif(skb));
+ ntohs(th->source), inet_iif(skb),
+ tcp_v4_sdif(skb));
/* don't send rst if it can't find key */
if (!sk1)
goto out;
@@ -1523,7 +1524,7 @@ void tcp_v4_early_demux(struct sk_buff *skb)
sk = __inet_lookup_established(dev_net(skb->dev), &tcp_hashinfo,
iph->saddr, th->source,
iph->daddr, ntohs(th->dest),
- skb->skb_iif);
+ skb->skb_iif, inet_sdif(skb));
if (sk) {
skb->sk = sk;
skb->destructor = sock_edemux;
@@ -1588,6 +1589,7 @@ EXPORT_SYMBOL(tcp_filter);
int tcp_v4_rcv(struct sk_buff *skb)
{
struct net *net = dev_net(skb->dev);
+ int sdif = inet_sdif(skb);
const struct iphdr *iph;
const struct tcphdr *th;
bool refcounted;
@@ -1638,7 +1640,7 @@ int tcp_v4_rcv(struct sk_buff *skb)
lookup:
sk = __inet_lookup_skb(&tcp_hashinfo, skb, __tcp_hdrlen(th), th->source,
- th->dest, &refcounted);
+ th->dest, sdif, &refcounted);
if (!sk)
goto no_tcp_socket;
@@ -1766,7 +1768,8 @@ int tcp_v4_rcv(struct sk_buff *skb)
__tcp_hdrlen(th),
iph->saddr, th->source,
iph->daddr, th->dest,
- inet_iif(skb));
+ inet_iif(skb),
+ sdif);
if (sk2) {
inet_twsk_deschedule_put(inet_twsk(sk));
sk = sk2;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index fe14429e4a6c..99f25bfec606 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -2196,7 +2196,7 @@ static struct sock *__udp4_lib_mcast_demux_lookup(struct net *net,
static struct sock *__udp4_lib_demux_lookup(struct net *net,
__be16 loc_port, __be32 loc_addr,
__be16 rmt_port, __be32 rmt_addr,
- int dif)
+ int dif, int sdif)
{
unsigned short hnum = ntohs(loc_port);
unsigned int hash2 = udp4_portaddr_hash(net, loc_addr, hnum);
@@ -2208,7 +2208,7 @@ static struct sock *__udp4_lib_demux_lookup(struct net *net,
udp_portaddr_for_each_entry_rcu(sk, &hslot2->head) {
if (INET_MATCH(sk, net, acookie, rmt_addr,
- loc_addr, ports, dif))
+ loc_addr, ports, dif, sdif))
return sk;
/* Only check first socket in chain */
break;
@@ -2254,7 +2254,7 @@ void udp_v4_early_demux(struct sk_buff *skb)
dif, sdif);
} else if (skb->pkt_type == PACKET_HOST) {
sk = __udp4_lib_demux_lookup(net, uh->dest, iph->daddr,
- uh->source, iph->saddr, dif);
+ uh->source, iph->saddr, dif, sdif);
}
if (!sk || !refcount_inc_not_zero(&sk->sk_refcnt))
diff --git a/net/netfilter/xt_TPROXY.c b/net/netfilter/xt_TPROXY.c
index d767e35fff6b..94fb0fd0c667 100644
--- a/net/netfilter/xt_TPROXY.c
+++ b/net/netfilter/xt_TPROXY.c
@@ -125,7 +125,7 @@ nf_tproxy_get_sock_v4(struct net *net, struct sk_buff *skb, void *hp,
__tcp_hdrlen(tcph),
saddr, sport,
daddr, dport,
- in->ifindex);
+ in->ifindex, 0);
if (sk && !refcount_inc_not_zero(&sk->sk_refcnt))
sk = NULL;
--
2.1.4
^ permalink raw reply related
* [PATCH v3 net-next 1/7] net: ipv4: add second dif to udp socket lookups
From: David Ahern @ 2017-08-07 15:44 UTC (permalink / raw)
To: netdev; +Cc: David Ahern
In-Reply-To: <1502120662-1430-1-git-send-email-dsahern@gmail.com>
Add a second device index, sdif, to udp socket lookups. sdif is the
index for ingress devices enslaved to an l3mdev. It allows the lookups
to consider the enslaved device as well as the L3 domain when searching
for a socket.
Early demux lookups are handled in the next patch as part of INET_MATCH
changes.
Signed-off-by: David Ahern <dsahern@gmail.com>
---
include/net/ip.h | 10 +++++++++
include/net/udp.h | 2 +-
net/ipv4/udp.c | 58 +++++++++++++++++++++++++++++++----------------------
net/ipv4/udp_diag.c | 6 +++---
4 files changed, 48 insertions(+), 28 deletions(-)
diff --git a/include/net/ip.h b/include/net/ip.h
index 9e59dcf1787a..39db596eb89f 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -78,6 +78,16 @@ struct ipcm_cookie {
#define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb))
#define PKTINFO_SKB_CB(skb) ((struct in_pktinfo *)((skb)->cb))
+/* return enslaved device index if relevant */
+static inline int inet_sdif(struct sk_buff *skb)
+{
+#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV)
+ if (skb && ipv4_l3mdev_skb(IPCB(skb)->flags))
+ return IPCB(skb)->iif;
+#endif
+ return 0;
+}
+
struct ip_ra_chain {
struct ip_ra_chain __rcu *next;
struct sock *sk;
diff --git a/include/net/udp.h b/include/net/udp.h
index cc8036987dcb..826c713d5a48 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -287,7 +287,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport,
__be32 daddr, __be16 dport, int dif);
struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport,
- __be32 daddr, __be16 dport, int dif,
+ __be32 daddr, __be16 dport, int dif, int sdif,
struct udp_table *tbl, struct sk_buff *skb);
struct sock *udp4_lib_lookup_skb(struct sk_buff *skb,
__be16 sport, __be16 dport);
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 38bca2c4897d..fe14429e4a6c 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -380,8 +380,8 @@ int udp_v4_get_port(struct sock *sk, unsigned short snum)
static int compute_score(struct sock *sk, struct net *net,
__be32 saddr, __be16 sport,
- __be32 daddr, unsigned short hnum, int dif,
- bool exact_dif)
+ __be32 daddr, unsigned short hnum,
+ int dif, int sdif, bool exact_dif)
{
int score;
struct inet_sock *inet;
@@ -413,10 +413,15 @@ static int compute_score(struct sock *sk, struct net *net,
}
if (sk->sk_bound_dev_if || exact_dif) {
- if (sk->sk_bound_dev_if != dif)
+ bool dev_match = (sk->sk_bound_dev_if == dif ||
+ sk->sk_bound_dev_if == sdif);
+
+ if (exact_dif && !dev_match)
return -1;
- score += 4;
+ if (sk->sk_bound_dev_if && dev_match)
+ score += 4;
}
+
if (sk->sk_incoming_cpu == raw_smp_processor_id())
score++;
return score;
@@ -436,10 +441,11 @@ static u32 udp_ehashfn(const struct net *net, const __be32 laddr,
/* called with rcu_read_lock() */
static struct sock *udp4_lib_lookup2(struct net *net,
- __be32 saddr, __be16 sport,
- __be32 daddr, unsigned int hnum, int dif, bool exact_dif,
- struct udp_hslot *hslot2,
- struct sk_buff *skb)
+ __be32 saddr, __be16 sport,
+ __be32 daddr, unsigned int hnum,
+ int dif, int sdif, bool exact_dif,
+ struct udp_hslot *hslot2,
+ struct sk_buff *skb)
{
struct sock *sk, *result;
int score, badness, matches = 0, reuseport = 0;
@@ -449,7 +455,7 @@ static struct sock *udp4_lib_lookup2(struct net *net,
badness = 0;
udp_portaddr_for_each_entry_rcu(sk, &hslot2->head) {
score = compute_score(sk, net, saddr, sport,
- daddr, hnum, dif, exact_dif);
+ daddr, hnum, dif, sdif, exact_dif);
if (score > badness) {
reuseport = sk->sk_reuseport;
if (reuseport) {
@@ -477,8 +483,8 @@ static struct sock *udp4_lib_lookup2(struct net *net,
* harder than this. -DaveM
*/
struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
- __be16 sport, __be32 daddr, __be16 dport,
- int dif, struct udp_table *udptable, struct sk_buff *skb)
+ __be16 sport, __be32 daddr, __be16 dport, int dif,
+ int sdif, struct udp_table *udptable, struct sk_buff *skb)
{
struct sock *sk, *result;
unsigned short hnum = ntohs(dport);
@@ -496,7 +502,7 @@ struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
goto begin;
result = udp4_lib_lookup2(net, saddr, sport,
- daddr, hnum, dif,
+ daddr, hnum, dif, sdif,
exact_dif, hslot2, skb);
if (!result) {
unsigned int old_slot2 = slot2;
@@ -511,7 +517,7 @@ struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
goto begin;
result = udp4_lib_lookup2(net, saddr, sport,
- daddr, hnum, dif,
+ daddr, hnum, dif, sdif,
exact_dif, hslot2, skb);
}
return result;
@@ -521,7 +527,7 @@ struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
badness = 0;
sk_for_each_rcu(sk, &hslot->head) {
score = compute_score(sk, net, saddr, sport,
- daddr, hnum, dif, exact_dif);
+ daddr, hnum, dif, sdif, exact_dif);
if (score > badness) {
reuseport = sk->sk_reuseport;
if (reuseport) {
@@ -554,7 +560,7 @@ static inline struct sock *__udp4_lib_lookup_skb(struct sk_buff *skb,
return __udp4_lib_lookup(dev_net(skb->dev), iph->saddr, sport,
iph->daddr, dport, inet_iif(skb),
- udptable, skb);
+ inet_sdif(skb), udptable, skb);
}
struct sock *udp4_lib_lookup_skb(struct sk_buff *skb,
@@ -576,7 +582,7 @@ struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport,
struct sock *sk;
sk = __udp4_lib_lookup(net, saddr, sport, daddr, dport,
- dif, &udp_table, NULL);
+ dif, 0, &udp_table, NULL);
if (sk && !refcount_inc_not_zero(&sk->sk_refcnt))
sk = NULL;
return sk;
@@ -587,7 +593,7 @@ EXPORT_SYMBOL_GPL(udp4_lib_lookup);
static inline bool __udp_is_mcast_sock(struct net *net, struct sock *sk,
__be16 loc_port, __be32 loc_addr,
__be16 rmt_port, __be32 rmt_addr,
- int dif, unsigned short hnum)
+ int dif, int sdif, unsigned short hnum)
{
struct inet_sock *inet = inet_sk(sk);
@@ -597,7 +603,8 @@ static inline bool __udp_is_mcast_sock(struct net *net, struct sock *sk,
(inet->inet_dport != rmt_port && inet->inet_dport) ||
(inet->inet_rcv_saddr && inet->inet_rcv_saddr != loc_addr) ||
ipv6_only_sock(sk) ||
- (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
+ (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif &&
+ sk->sk_bound_dev_if != sdif))
return false;
if (!ip_mc_sf_allow(sk, loc_addr, rmt_addr, dif))
return false;
@@ -628,8 +635,8 @@ void __udp4_lib_err(struct sk_buff *skb, u32 info, struct udp_table *udptable)
struct net *net = dev_net(skb->dev);
sk = __udp4_lib_lookup(net, iph->daddr, uh->dest,
- iph->saddr, uh->source, skb->dev->ifindex, udptable,
- NULL);
+ iph->saddr, uh->source, skb->dev->ifindex, 0,
+ udptable, NULL);
if (!sk) {
__ICMP_INC_STATS(net, ICMP_MIB_INERRORS);
return; /* No socket for error */
@@ -1953,6 +1960,7 @@ static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
unsigned int hash2 = 0, hash2_any = 0, use_hash2 = (hslot->count > 10);
unsigned int offset = offsetof(typeof(*sk), sk_node);
int dif = skb->dev->ifindex;
+ int sdif = inet_sdif(skb);
struct hlist_node *node;
struct sk_buff *nskb;
@@ -1967,7 +1975,7 @@ static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
sk_for_each_entry_offset_rcu(sk, node, &hslot->head, offset) {
if (!__udp_is_mcast_sock(net, sk, uh->dest, daddr,
- uh->source, saddr, dif, hnum))
+ uh->source, saddr, dif, sdif, hnum))
continue;
if (!first) {
@@ -2157,7 +2165,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
static struct sock *__udp4_lib_mcast_demux_lookup(struct net *net,
__be16 loc_port, __be32 loc_addr,
__be16 rmt_port, __be32 rmt_addr,
- int dif)
+ int dif, int sdif)
{
struct sock *sk, *result;
unsigned short hnum = ntohs(loc_port);
@@ -2171,7 +2179,7 @@ static struct sock *__udp4_lib_mcast_demux_lookup(struct net *net,
result = NULL;
sk_for_each_rcu(sk, &hslot->head) {
if (__udp_is_mcast_sock(net, sk, loc_port, loc_addr,
- rmt_port, rmt_addr, dif, hnum)) {
+ rmt_port, rmt_addr, dif, sdif, hnum)) {
if (result)
return NULL;
result = sk;
@@ -2216,6 +2224,7 @@ void udp_v4_early_demux(struct sk_buff *skb)
struct sock *sk = NULL;
struct dst_entry *dst;
int dif = skb->dev->ifindex;
+ int sdif = inet_sdif(skb);
int ours;
/* validate the packet */
@@ -2241,7 +2250,8 @@ void udp_v4_early_demux(struct sk_buff *skb)
}
sk = __udp4_lib_mcast_demux_lookup(net, uh->dest, iph->daddr,
- uh->source, iph->saddr, dif);
+ uh->source, iph->saddr,
+ dif, sdif);
} else if (skb->pkt_type == PACKET_HOST) {
sk = __udp4_lib_demux_lookup(net, uh->dest, iph->daddr,
uh->source, iph->saddr, dif);
diff --git a/net/ipv4/udp_diag.c b/net/ipv4/udp_diag.c
index 4515836d2a3a..1f07fe109535 100644
--- a/net/ipv4/udp_diag.c
+++ b/net/ipv4/udp_diag.c
@@ -45,7 +45,7 @@ static int udp_dump_one(struct udp_table *tbl, struct sk_buff *in_skb,
sk = __udp4_lib_lookup(net,
req->id.idiag_src[0], req->id.idiag_sport,
req->id.idiag_dst[0], req->id.idiag_dport,
- req->id.idiag_if, tbl, NULL);
+ req->id.idiag_if, 0, tbl, NULL);
#if IS_ENABLED(CONFIG_IPV6)
else if (req->sdiag_family == AF_INET6)
sk = __udp6_lib_lookup(net,
@@ -182,7 +182,7 @@ static int __udp_diag_destroy(struct sk_buff *in_skb,
sk = __udp4_lib_lookup(net,
req->id.idiag_dst[0], req->id.idiag_dport,
req->id.idiag_src[0], req->id.idiag_sport,
- req->id.idiag_if, tbl, NULL);
+ req->id.idiag_if, 0, tbl, NULL);
#if IS_ENABLED(CONFIG_IPV6)
else if (req->sdiag_family == AF_INET6) {
if (ipv6_addr_v4mapped((struct in6_addr *)req->id.idiag_dst) &&
@@ -190,7 +190,7 @@ static int __udp_diag_destroy(struct sk_buff *in_skb,
sk = __udp4_lib_lookup(net,
req->id.idiag_dst[3], req->id.idiag_dport,
req->id.idiag_src[3], req->id.idiag_sport,
- req->id.idiag_if, tbl, NULL);
+ req->id.idiag_if, 0, tbl, NULL);
else
sk = __udp6_lib_lookup(net,
--
2.1.4
^ permalink raw reply related
* [PATCH v3 net-next 0/7] net: l3mdev: Support for sockets bound to enslaved device
From: David Ahern @ 2017-08-07 15:44 UTC (permalink / raw)
To: netdev; +Cc: David Ahern
A missing piece to the VRF puzzle is the ability to bind sockets to
devices enslaved to a VRF. This patch set adds the enslaved device
index, sdif, to IPv4 and IPv6 socket lookups. The end result for users
is the following scope options for services:
1. "global" services - sockets not bound to any device
Allows 1 service to work across all network interfaces with
connected sockets bound to the VRF the connection originates
(Requires net.ipv4.tcp_l3mdev_accept=1 for TCP and
net.ipv4.udp_l3mdev_accept=1 for UDP)
2. "VRF" local services - sockets bound to a VRF
Sockets work across all network interfaces enslaved to a VRF but
are limited to just the one VRF.
3. "device" services - sockets bound to a specific network interface
Service works only through the one specific interface.
v3
- convert __inet_lookup_established in dccp_v4_err; missed in v2
v2
- remove sk_lookup struct and add sdif as an argument to existing
functions
Changes since RFC:
- no significant logic changes; mainly whitespace cleanups
David Ahern (7):
net: ipv4: add second dif to udp socket lookups
net: ipv4: add second dif to inet socket lookups
net: ipv4: add second dif to raw socket lookups
net: ipv4: add second dif to multicast source filter
net: ipv6: add second dif to udp socket lookups
net: ipv6: add second dif to inet6 socket lookups
net: ipv6: add second dif to raw socket lookups
include/linux/igmp.h | 3 +-
include/linux/ipv6.h | 10 +++++++
include/net/inet6_hashtables.h | 22 ++++++++------
include/net/inet_hashtables.h | 31 +++++++++++---------
include/net/ip.h | 10 +++++++
include/net/raw.h | 2 +-
include/net/rawv6.h | 2 +-
include/net/tcp.h | 20 +++++++++++++
include/net/udp.h | 4 +--
net/dccp/ipv4.c | 4 +--
net/dccp/ipv6.c | 4 +--
net/ipv4/igmp.c | 6 ++--
net/ipv4/inet_hashtables.c | 27 ++++++++++-------
net/ipv4/raw.c | 18 ++++++++----
net/ipv4/raw_diag.c | 4 +--
net/ipv4/tcp_ipv4.c | 13 +++++----
net/ipv4/udp.c | 66 ++++++++++++++++++++++++------------------
net/ipv4/udp_diag.c | 10 +++----
net/ipv6/inet6_hashtables.c | 28 +++++++++++-------
net/ipv6/raw.c | 13 +++++----
net/ipv6/tcp_ipv6.c | 13 +++++----
net/ipv6/udp.c | 47 ++++++++++++++++--------------
net/netfilter/xt_TPROXY.c | 6 ++--
23 files changed, 228 insertions(+), 135 deletions(-)
--
2.1.4
^ permalink raw reply
* Re: [PATCH net-next] ibmvnic: Add netdev_dbg output for debugging
From: Joe Perches @ 2017-08-07 15:29 UTC (permalink / raw)
To: Nathan Fontenot, netdev; +Cc: jallen, tlfalcon
In-Reply-To: <20170807190258.13228.24698.stgit@ltcalpine2-lp23.aus.stglabs.ibm.com>
On Mon, 2017-08-07 at 15:02 -0400, Nathan Fontenot wrote:
> To ease debugging of the ibmvnic driver add a series of netdev_dbg()
> statements to track driver status, especially during initialization,
> removal, and resetting of the driver.
For some of the function entry logging, it seems
better to use ftrace instead.
> diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
[]
> @@ -389,6 +389,8 @@ static int init_stats_token(struct ibmvnic_adapter *adapter)
> struct device *dev = &adapter->vdev->dev;
> dma_addr_t stok;
>
> + netdev_dbg(adapter->netdev, "Initializing stats token\n");
here and subsequent.
^ permalink raw reply
* Re: [PATCH net-next 1/1] netvsc: fix rtnl deadlock on unregister of vf
From: Stephen Hemminger @ 2017-08-07 15:21 UTC (permalink / raw)
To: Vitaly Kuznetsov; +Cc: devel, haiyangz, sthemmin, netdev
In-Reply-To: <87a83bcsqo.fsf@vitty.brq.redhat.com>
On Mon, 07 Aug 2017 17:17:19 +0200
Vitaly Kuznetsov <vkuznets@redhat.com> wrote:
> Vitaly Kuznetsov <vkuznets@redhat.com> writes:
>
> > Vitaly Kuznetsov <vkuznets@redhat.com> writes:
> >
> >> Stephen Hemminger <stephen@networkplumber.org> writes:
> >>
> >>> With new transparent VF support, it is possible to get a deadlock
> >>> when some of the deferred work is running and the unregister_vf
> >>> is trying to cancel the work element. The solution is to use
> >>> trylock and reschedule (similar to bonding and team device).
> >>>
> >>> Reported-by: Vitaly Kuznetsov <vkuznets@redhat.com>
> >>> Fixes: 0c195567a8f6 ("netvsc: transparent VF management")
> >>> Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
> >>> ---
> >>> drivers/net/hyperv/netvsc_drv.c | 12 ++++++++++--
> >>> 1 file changed, 10 insertions(+), 2 deletions(-)
> >>>
> >>> diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
> >>> index c71728d82049..e75c0f852a63 100644
> >>> --- a/drivers/net/hyperv/netvsc_drv.c
> >>> +++ b/drivers/net/hyperv/netvsc_drv.c
> >>> @@ -1601,7 +1601,11 @@ static void netvsc_vf_setup(struct work_struct *w)
> >>> struct net_device *ndev = hv_get_drvdata(ndev_ctx->device_ctx);
> >>> struct net_device *vf_netdev;
> >>>
> >>> - rtnl_lock();
> >>> + if (!rtnl_trylock()) {
> >>> + schedule_work(w);
> >>> + return;
> >>> + }
> >>> +
> >>> vf_netdev = rtnl_dereference(ndev_ctx->vf_netdev);
> >>> if (vf_netdev)
> >>> __netvsc_vf_setup(ndev, vf_netdev);
> >>> @@ -1655,7 +1659,11 @@ static void netvsc_vf_update(struct work_struct *w)
> >>> struct net_device *vf_netdev;
> >>> bool vf_is_up;
> >>>
> >>> - rtnl_lock();
> >>> + if (!rtnl_trylock()) {
> >>> + schedule_work(w);
> >>> + return;
> >>> + }
> >>> +
> >>
> >> So in the situation when we're currently in netvsc_unregister_vf() and
> >> trying to do
> >> cancel_work_sync(&net_device_ctx->vf_takeover);
> >> cancel_work_sync(&net_device_ctx->vf_notify);
> >>
> >> we'll end up not executing netvsc_vf_update() at all, right? Wouldn't it
> >> create an issue as nobody is switching the datapath back to netvsc?
> >>
> >
> > Actually, looking more at this I think we have additional issues:
> >
> > netvsc_unregister_vf() may get executed _before_ netvsc_vf_update() gets
> > a chance and we just cancel it so the data path is never switched
> > back. I actually have a VM where I suppose it happens ...
> >
> > [ 7.235566] hv_netvsc 33b7a6f9-6736-451f-8fce-b382eaa50bee eth1: VF up: enP2p0s2
> > [ 7.235569] hv_netvsc 33b7a6f9-6736-451f-8fce-b382eaa50bee eth1: Datapath switched to VF: enP2p0s2
> >
> > On VF removal:
> >
> > [ 17.675885] mlx4_en: enP2p0s2: Close port called
> > [ 17.727005] hv_netvsc 33b7a6f9-6736-451f-8fce-b382eaa50bee eth1: VF unregistering: enP2p0s2
> > <and nothing after - so the data path is not switched>
> >
> > We need to make sure netvsc_vf_update() is always processed on removal.
>
> So the question I have is: why do we need to call netvsc_vf_update()
> from a work? I tried calling it directly from netvsc_netdev_event() (and
> with rtnl_lock()/unlock() calls dropped from it as we already have it,
> of course) and everything seems to work for me.
Switching datapath needs to be waiting for ack and isn't
>
> Shall I send a patch removing the work?
I will take care of that.
^ permalink raw reply
* Re: [PATCH net-next 1/1] netvsc: fix rtnl deadlock on unregister of vf
From: Stephen Hemminger @ 2017-08-07 15:17 UTC (permalink / raw)
To: Vitaly Kuznetsov; +Cc: devel, haiyangz, sthemmin, netdev
In-Reply-To: <87y3qvcxci.fsf@vitty.brq.redhat.com>
On Mon, 07 Aug 2017 15:37:49 +0200
Vitaly Kuznetsov <vkuznets@redhat.com> wrote:
> Vitaly Kuznetsov <vkuznets@redhat.com> writes:
>
> > Stephen Hemminger <stephen@networkplumber.org> writes:
> >
> >> With new transparent VF support, it is possible to get a deadlock
> >> when some of the deferred work is running and the unregister_vf
> >> is trying to cancel the work element. The solution is to use
> >> trylock and reschedule (similar to bonding and team device).
> >>
> >> Reported-by: Vitaly Kuznetsov <vkuznets@redhat.com>
> >> Fixes: 0c195567a8f6 ("netvsc: transparent VF management")
> >> Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
> >> ---
> >> drivers/net/hyperv/netvsc_drv.c | 12 ++++++++++--
> >> 1 file changed, 10 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
> >> index c71728d82049..e75c0f852a63 100644
> >> --- a/drivers/net/hyperv/netvsc_drv.c
> >> +++ b/drivers/net/hyperv/netvsc_drv.c
> >> @@ -1601,7 +1601,11 @@ static void netvsc_vf_setup(struct work_struct *w)
> >> struct net_device *ndev = hv_get_drvdata(ndev_ctx->device_ctx);
> >> struct net_device *vf_netdev;
> >>
> >> - rtnl_lock();
> >> + if (!rtnl_trylock()) {
> >> + schedule_work(w);
> >> + return;
> >> + }
> >> +
> >> vf_netdev = rtnl_dereference(ndev_ctx->vf_netdev);
> >> if (vf_netdev)
> >> __netvsc_vf_setup(ndev, vf_netdev);
> >> @@ -1655,7 +1659,11 @@ static void netvsc_vf_update(struct work_struct *w)
> >> struct net_device *vf_netdev;
> >> bool vf_is_up;
> >>
> >> - rtnl_lock();
> >> + if (!rtnl_trylock()) {
> >> + schedule_work(w);
> >> + return;
> >> + }
> >> +
> >
> > So in the situation when we're currently in netvsc_unregister_vf() and
> > trying to do
> > cancel_work_sync(&net_device_ctx->vf_takeover);
> > cancel_work_sync(&net_device_ctx->vf_notify);
> >
> > we'll end up not executing netvsc_vf_update() at all, right? Wouldn't it
> > create an issue as nobody is switching the datapath back to netvsc?
It worked testing, but most likely only because host is doing it for us.
Not a good thing to rely on.
>
> Actually, looking more at this I think we have additional issues:
>
> netvsc_unregister_vf() may get executed _before_ netvsc_vf_update() gets
> a chance and we just cancel it so the data path is never switched
> back. I actually have a VM where I suppose it happens ...
>
> [ 7.235566] hv_netvsc 33b7a6f9-6736-451f-8fce-b382eaa50bee eth1: VF up: enP2p0s2
> [ 7.235569] hv_netvsc 33b7a6f9-6736-451f-8fce-b382eaa50bee eth1: Datapath switched to VF: enP2p0s2
>
> On VF removal:
>
> [ 17.675885] mlx4_en: enP2p0s2: Close port called
> [ 17.727005] hv_netvsc 33b7a6f9-6736-451f-8fce-b382eaa50bee eth1: VF unregistering: enP2p0s2
> <and nothing after - so the data path is not switched>
>
> We need to make sure netvsc_vf_update() is always processed on removal.
The reason vf_update was converted to work queue was because there were some
case the old code could sleep. Probably best to go back to doing it directly
in notifier and handle the special cases.
^ permalink raw reply
* Re: [PATCH net-next 1/1] netvsc: fix rtnl deadlock on unregister of vf
From: Vitaly Kuznetsov @ 2017-08-07 15:17 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: devel, haiyangz, sthemmin, netdev
In-Reply-To: <87y3qvcxci.fsf@vitty.brq.redhat.com>
Vitaly Kuznetsov <vkuznets@redhat.com> writes:
> Vitaly Kuznetsov <vkuznets@redhat.com> writes:
>
>> Stephen Hemminger <stephen@networkplumber.org> writes:
>>
>>> With new transparent VF support, it is possible to get a deadlock
>>> when some of the deferred work is running and the unregister_vf
>>> is trying to cancel the work element. The solution is to use
>>> trylock and reschedule (similar to bonding and team device).
>>>
>>> Reported-by: Vitaly Kuznetsov <vkuznets@redhat.com>
>>> Fixes: 0c195567a8f6 ("netvsc: transparent VF management")
>>> Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
>>> ---
>>> drivers/net/hyperv/netvsc_drv.c | 12 ++++++++++--
>>> 1 file changed, 10 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
>>> index c71728d82049..e75c0f852a63 100644
>>> --- a/drivers/net/hyperv/netvsc_drv.c
>>> +++ b/drivers/net/hyperv/netvsc_drv.c
>>> @@ -1601,7 +1601,11 @@ static void netvsc_vf_setup(struct work_struct *w)
>>> struct net_device *ndev = hv_get_drvdata(ndev_ctx->device_ctx);
>>> struct net_device *vf_netdev;
>>>
>>> - rtnl_lock();
>>> + if (!rtnl_trylock()) {
>>> + schedule_work(w);
>>> + return;
>>> + }
>>> +
>>> vf_netdev = rtnl_dereference(ndev_ctx->vf_netdev);
>>> if (vf_netdev)
>>> __netvsc_vf_setup(ndev, vf_netdev);
>>> @@ -1655,7 +1659,11 @@ static void netvsc_vf_update(struct work_struct *w)
>>> struct net_device *vf_netdev;
>>> bool vf_is_up;
>>>
>>> - rtnl_lock();
>>> + if (!rtnl_trylock()) {
>>> + schedule_work(w);
>>> + return;
>>> + }
>>> +
>>
>> So in the situation when we're currently in netvsc_unregister_vf() and
>> trying to do
>> cancel_work_sync(&net_device_ctx->vf_takeover);
>> cancel_work_sync(&net_device_ctx->vf_notify);
>>
>> we'll end up not executing netvsc_vf_update() at all, right? Wouldn't it
>> create an issue as nobody is switching the datapath back to netvsc?
>>
>
> Actually, looking more at this I think we have additional issues:
>
> netvsc_unregister_vf() may get executed _before_ netvsc_vf_update() gets
> a chance and we just cancel it so the data path is never switched
> back. I actually have a VM where I suppose it happens ...
>
> [ 7.235566] hv_netvsc 33b7a6f9-6736-451f-8fce-b382eaa50bee eth1: VF up: enP2p0s2
> [ 7.235569] hv_netvsc 33b7a6f9-6736-451f-8fce-b382eaa50bee eth1: Datapath switched to VF: enP2p0s2
>
> On VF removal:
>
> [ 17.675885] mlx4_en: enP2p0s2: Close port called
> [ 17.727005] hv_netvsc 33b7a6f9-6736-451f-8fce-b382eaa50bee eth1: VF unregistering: enP2p0s2
> <and nothing after - so the data path is not switched>
>
> We need to make sure netvsc_vf_update() is always processed on removal.
So the question I have is: why do we need to call netvsc_vf_update()
from a work? I tried calling it directly from netvsc_netdev_event() (and
with rtnl_lock()/unlock() calls dropped from it as we already have it,
of course) and everything seems to work for me.
Shall I send a patch removing the work?
--
Vitaly
^ permalink raw reply
* [PATCH net-next] ibmvnic: Add netdev_dbg output for debugging
From: Nathan Fontenot @ 2017-08-07 19:02 UTC (permalink / raw)
To: netdev; +Cc: jallen, tlfalcon
To ease debugging of the ibmvnic driver add a series of netdev_dbg()
statements to track driver status, especially during initialization,
removal, and resetting of the driver.
Signed-off-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
---
drivers/net/ethernet/ibm/ibmvnic.c | 78 +++++++++++++++++++++++++++++++++---
1 file changed, 72 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
index 5932160..4dd9415 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -389,6 +389,8 @@ static int init_stats_token(struct ibmvnic_adapter *adapter)
struct device *dev = &adapter->vdev->dev;
dma_addr_t stok;
+ netdev_dbg(adapter->netdev, "Initializing stats token\n");
+
stok = dma_map_single(dev, &adapter->stats,
sizeof(struct ibmvnic_statistics),
DMA_FROM_DEVICE);
@@ -411,6 +413,8 @@ static int reset_rx_pools(struct ibmvnic_adapter *adapter)
for (i = 0; i < rx_scrqs; i++) {
rx_pool = &adapter->rx_pool[i];
+ netdev_dbg(adapter->netdev, "Re-setting rx_pool[%d]\n", i);
+
rc = reset_long_term_buff(adapter, &rx_pool->long_term_buff);
if (rc)
return rc;
@@ -443,6 +447,8 @@ static void release_rx_pools(struct ibmvnic_adapter *adapter)
for (i = 0; i < rx_scrqs; i++) {
rx_pool = &adapter->rx_pool[i];
+ netdev_dbg(adapter->netdev, "Releasing rx_pool[%d]\n", i);
+
kfree(rx_pool->free_map);
free_long_term_buff(adapter, &rx_pool->long_term_buff);
@@ -489,7 +495,7 @@ static int init_rx_pools(struct net_device *netdev)
rx_pool = &adapter->rx_pool[i];
netdev_dbg(adapter->netdev,
- "Initializing rx_pool %d, %lld buffs, %lld bytes each\n",
+ "Initializing rx_pool[%d], %lld buffs, %lld bytes each\n",
i, adapter->req_rx_add_entries_per_subcrq,
be64_to_cpu(size_array[i]));
@@ -539,6 +545,8 @@ static int reset_tx_pools(struct ibmvnic_adapter *adapter)
tx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_txsubm_subcrqs);
for (i = 0; i < tx_scrqs; i++) {
+ netdev_dbg(adapter->netdev, "Re-setting tx_pool[%d]\n", i);
+
tx_pool = &adapter->tx_pool[i];
rc = reset_long_term_buff(adapter, &tx_pool->long_term_buff);
@@ -569,6 +577,7 @@ static void release_tx_pools(struct ibmvnic_adapter *adapter)
tx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_txsubm_subcrqs);
for (i = 0; i < tx_scrqs; i++) {
+ netdev_dbg(adapter->netdev, "Releasing tx_pool[%d]\n", i);
tx_pool = &adapter->tx_pool[i];
kfree(tx_pool->tx_buff);
free_long_term_buff(adapter, &tx_pool->long_term_buff);
@@ -595,6 +604,11 @@ static int init_tx_pools(struct net_device *netdev)
for (i = 0; i < tx_subcrqs; i++) {
tx_pool = &adapter->tx_pool[i];
+
+ netdev_dbg(adapter->netdev,
+ "Initializing tx_pool[%d], %lld buffs\n",
+ i, adapter->req_tx_entries_per_subcrq);
+
tx_pool->tx_buff = kcalloc(adapter->req_tx_entries_per_subcrq,
sizeof(struct ibmvnic_tx_buff),
GFP_KERNEL);
@@ -665,8 +679,10 @@ static void ibmvnic_napi_disable(struct ibmvnic_adapter *adapter)
if (!adapter->napi_enabled)
return;
- for (i = 0; i < adapter->req_rx_queues; i++)
+ for (i = 0; i < adapter->req_rx_queues; i++) {
+ netdev_dbg(adapter->netdev, "Disabling napi[%d]\n", i);
napi_disable(&adapter->napi[i]);
+ }
adapter->napi_enabled = false;
}
@@ -677,6 +693,8 @@ static int ibmvnic_login(struct net_device *netdev)
unsigned long timeout = msecs_to_jiffies(30000);
struct device *dev = &adapter->vdev->dev;
+ netdev_dbg(netdev, "Logging into server\n");
+
do {
if (adapter->renegotiate) {
adapter->renegotiate = false;
@@ -716,8 +734,11 @@ static void release_resources(struct ibmvnic_adapter *adapter)
if (adapter->napi) {
for (i = 0; i < adapter->req_rx_queues; i++) {
- if (&adapter->napi[i])
+ if (&adapter->napi[i]) {
+ netdev_dbg(adapter->netdev,
+ "Releasing napi[%d]\n", i);
netif_napi_del(&adapter->napi[i]);
+ }
}
}
}
@@ -730,7 +751,8 @@ static int set_link_state(struct ibmvnic_adapter *adapter, u8 link_state)
bool resend;
int rc;
- netdev_err(netdev, "setting link state %d\n", link_state);
+ netdev_dbg(netdev, "setting link state %d\n", link_state);
+
memset(&crq, 0, sizeof(crq));
crq.logical_link_state.first = IBMVNIC_CRQ_CMD;
crq.logical_link_state.cmd = LOGICAL_LINK_STATE;
@@ -767,6 +789,9 @@ static int set_real_num_queues(struct net_device *netdev)
struct ibmvnic_adapter *adapter = netdev_priv(netdev);
int rc;
+ netdev_dbg(netdev, "Setting TX queues (%llx) and RX queues (%llx)\n",
+ adapter->req_tx_queues, adapter->req_rx_queues);
+
rc = netif_set_real_num_tx_queues(netdev, adapter->req_tx_queues);
if (rc) {
netdev_err(netdev, "failed to set the number of tx queues\n");
@@ -804,6 +829,7 @@ static int init_resources(struct ibmvnic_adapter *adapter)
return -ENOMEM;
for (i = 0; i < adapter->req_rx_queues; i++) {
+ netdev_dbg(netdev, "Adding napi[%d]\n", i);
netif_napi_add(netdev, &adapter->napi[i], ibmvnic_poll,
NAPI_POLL_WEIGHT);
}
@@ -832,6 +858,7 @@ static int __ibmvnic_open(struct net_device *netdev)
* set the logical link state to up
*/
for (i = 0; i < adapter->req_rx_queues; i++) {
+ netdev_dbg(netdev, "Enabling rx_scrq[%d] irq\n", i);
if (prev_state == VNIC_CLOSED)
enable_irq(adapter->rx_scrq[i]->irq);
else
@@ -839,6 +866,7 @@ static int __ibmvnic_open(struct net_device *netdev)
}
for (i = 0; i < adapter->req_tx_queues; i++) {
+ netdev_dbg(netdev, "Enabling tx_scrq[%d] irq\n", i);
if (prev_state == VNIC_CLOSED)
enable_irq(adapter->tx_scrq[i]->irq);
else
@@ -912,6 +940,7 @@ static void clean_tx_pools(struct ibmvnic_adapter *adapter)
if (!tx_pool)
continue;
+ netdev_dbg(adapter->netdev, "Cleaning tx_pool[%d]\n", i);
for (j = 0; j < tx_entries; j++) {
if (tx_pool->tx_buff[j].skb) {
dev_kfree_skb_any(tx_pool->tx_buff[j].skb);
@@ -927,6 +956,7 @@ static int __ibmvnic_close(struct net_device *netdev)
int rc = 0;
int i;
+ netdev_dbg(adapter->netdev, "Closing device\n");
adapter->state = VNIC_CLOSING;
/* ensure that transmissions are stopped if called by do_reset */
@@ -939,8 +969,11 @@ static int __ibmvnic_close(struct net_device *netdev)
if (adapter->tx_scrq) {
for (i = 0; i < adapter->req_tx_queues; i++)
- if (adapter->tx_scrq[i]->irq)
+ if (adapter->tx_scrq[i]->irq) {
+ netdev_dbg(adapter->netdev,
+ "Disabling tx_scrq[%d] irq\n", i);
disable_irq(adapter->tx_scrq[i]->irq);
+ }
}
rc = set_link_state(adapter, IBMVNIC_LOGICAL_LNK_DN);
@@ -959,8 +992,11 @@ static int __ibmvnic_close(struct net_device *netdev)
break;
}
- if (adapter->rx_scrq[i]->irq)
+ if (adapter->rx_scrq[i]->irq) {
+ netdev_dbg(adapter->netdev,
+ "Disabling rx_scrq[%d] irq\n", i);
disable_irq(adapter->rx_scrq[i]->irq);
+ }
}
}
@@ -1353,6 +1389,9 @@ static int do_reset(struct ibmvnic_adapter *adapter,
struct net_device *netdev = adapter->netdev;
int i, rc;
+ netdev_dbg(adapter->netdev, "Re-setting driver (%d)\n",
+ rwi->reset_reason);
+
netif_carrier_off(netdev);
adapter->reset_reason = rwi->reset_reason;
@@ -1477,6 +1516,7 @@ static void __ibmvnic_reset(struct work_struct *work)
}
if (rc) {
+ netdev_dbg(adapter->netdev, "Reset failed\n");
free_all_rwi(adapter);
mutex_unlock(&adapter->reset_lock);
return;
@@ -1526,6 +1566,8 @@ static void ibmvnic_reset(struct ibmvnic_adapter *adapter,
rwi->reset_reason = reason;
list_add_tail(&rwi->list, &adapter->rwi_list);
mutex_unlock(&adapter->rwi_lock);
+
+ netdev_dbg(adapter->netdev, "Scheduling reset (reason %d)\n", reason);
schedule_work(&adapter->ibmvnic_reset);
}
@@ -1885,12 +1927,14 @@ static int reset_sub_crq_queues(struct ibmvnic_adapter *adapter)
int i, rc;
for (i = 0; i < adapter->req_tx_queues; i++) {
+ netdev_dbg(adapter->netdev, "Re-setting tx_scrq[%d]\n", i);
rc = reset_one_sub_crq_queue(adapter, adapter->tx_scrq[i]);
if (rc)
return rc;
}
for (i = 0; i < adapter->req_rx_queues; i++) {
+ netdev_dbg(adapter->netdev, "Re-setting rx_scrq[%d]\n", i);
rc = reset_one_sub_crq_queue(adapter, adapter->rx_scrq[i]);
if (rc)
return rc;
@@ -1994,6 +2038,8 @@ static void release_sub_crqs(struct ibmvnic_adapter *adapter)
if (!adapter->tx_scrq[i])
continue;
+ netdev_dbg(adapter->netdev, "Releasing tx_scrq[%d]\n",
+ i);
if (adapter->tx_scrq[i]->irq) {
free_irq(adapter->tx_scrq[i]->irq,
adapter->tx_scrq[i]);
@@ -2013,6 +2059,8 @@ static void release_sub_crqs(struct ibmvnic_adapter *adapter)
if (!adapter->rx_scrq[i])
continue;
+ netdev_dbg(adapter->netdev, "Releasing rx_scrq[%d]\n",
+ i);
if (adapter->rx_scrq[i]->irq) {
free_irq(adapter->rx_scrq[i]->irq,
adapter->rx_scrq[i]);
@@ -2167,6 +2215,8 @@ static int init_sub_crq_irqs(struct ibmvnic_adapter *adapter)
int rc = 0;
for (i = 0; i < adapter->req_tx_queues; i++) {
+ netdev_dbg(adapter->netdev, "Initializing tx_scrq[%d] irq\n",
+ i);
scrq = adapter->tx_scrq[i];
scrq->irq = irq_create_mapping(NULL, scrq->hw_irq);
@@ -2188,6 +2238,8 @@ static int init_sub_crq_irqs(struct ibmvnic_adapter *adapter)
}
for (i = 0; i < adapter->req_rx_queues; i++) {
+ netdev_dbg(adapter->netdev, "Initializing rx_scrq[%d] irq\n",
+ i);
scrq = adapter->rx_scrq[i];
scrq->irq = irq_create_mapping(NULL, scrq->hw_irq);
if (!scrq->irq) {
@@ -2230,6 +2282,8 @@ static int init_sub_crqs(struct ibmvnic_adapter *adapter)
int more = 0;
int i;
+ netdev_dbg(adapter->netdev, "Initializing sub-CRQs\n");
+
total_queues = adapter->req_tx_queues + adapter->req_rx_queues;
allqueues = kcalloc(total_queues, sizeof(*allqueues), GFP_KERNEL);
@@ -2309,6 +2363,8 @@ static void ibmvnic_send_req_caps(struct ibmvnic_adapter *adapter, int retry)
struct device *dev = &adapter->vdev->dev;
union ibmvnic_crq crq;
+ netdev_dbg(adapter->netdev, "Sending requested capabilities\n");
+
if (!retry) {
/* Sub-CRQ entries are 32 byte long */
int entries_page = 4 * PAGE_SIZE / (sizeof(u64) * 4);
@@ -2696,6 +2752,8 @@ static void send_cap_queries(struct ibmvnic_adapter *adapter)
{
union ibmvnic_crq crq;
+ netdev_dbg(adapter->netdev, "Sending capability queries\n");
+
atomic_set(&adapter->running_cap_crqs, 0);
memset(&crq, 0, sizeof(crq));
crq.query_capability.first = IBMVNIC_CRQ_CMD;
@@ -3580,6 +3638,8 @@ static int ibmvnic_reenable_crq_queue(struct ibmvnic_adapter *adapter)
struct vio_dev *vdev = adapter->vdev;
int rc;
+ netdev_dbg(adapter->netdev, "Re-enabling CRQ\n");
+
do {
rc = plpar_hcall_norets(H_ENABLE_CRQ, vdev->unit_address);
} while (rc == H_IN_PROGRESS || rc == H_BUSY || H_IS_LONG_BUSY(rc));
@@ -3597,6 +3657,8 @@ static int ibmvnic_reset_crq(struct ibmvnic_adapter *adapter)
struct vio_dev *vdev = adapter->vdev;
int rc;
+ netdev_dbg(adapter->netdev, "Re-setting CRQ\n");
+
/* Close the CRQ */
do {
rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address);
@@ -3648,6 +3710,8 @@ static int init_crq_queue(struct ibmvnic_adapter *adapter)
struct vio_dev *vdev = adapter->vdev;
int rc, retrc = -ENOMEM;
+ netdev_dbg(adapter->netdev, "Initializing CRQ\n");
+
if (crq->msgs)
return 0;
@@ -3722,6 +3786,8 @@ static int ibmvnic_init(struct ibmvnic_adapter *adapter)
unsigned long timeout = msecs_to_jiffies(30000);
int rc;
+ netdev_dbg(adapter->netdev, "Initializing driver.\n");
+
if (adapter->resetting) {
rc = ibmvnic_reset_crq(adapter);
if (!rc)
^ permalink raw reply related
* Re: [PATCH] ip/link_vti6.c: Fix local/remote any handling
From: Stephen Hemminger @ 2017-08-07 15:12 UTC (permalink / raw)
To: Christian Langrock; +Cc: netdev
In-Reply-To: <4608c5ed-6b73-4bc2-f193-66e5129d855e@secunet.com>
[-- Attachment #1: Type: text/plain, Size: 1640 bytes --]
On Mon, 7 Aug 2017 08:41:23 +0200
Christian Langrock <christian.langrock@secunet.com> wrote:
> According to the IPv4 behavior of 'ip' it should be possible to omit the
> arguments for local and remote address.
> Without this patch omitting these parameters would lead to
> uninitialized memory being interpreted as IPv6 addresses.
>
> Signed-off-by: Christian Langrock <christian.langrock@secunet.com>
I don't like extra flag values. Why not just:
diff --git a/ip/link_vti6.c b/ip/link_vti6.c
index be4e33cee606..6ea1fc2306ce 100644
--- a/ip/link_vti6.c
+++ b/ip/link_vti6.c
@@ -59,8 +59,8 @@ static int vti6_parse_opt(struct link_util *lu, int argc, char **argv,
struct rtattr *tb[IFLA_MAX + 1];
struct rtattr *linkinfo[IFLA_INFO_MAX+1];
struct rtattr *vtiinfo[IFLA_VTI_MAX + 1];
- struct in6_addr saddr;
- struct in6_addr daddr;
+ struct in6_addr saddr = IN6ADDR_ANY_INIT;
+ struct in6_addr daddr = IN6ADDR_ANY_INIT;
unsigned int ikey = 0;
unsigned int okey = 0;
unsigned int link = 0;
@@ -195,8 +195,11 @@ get_failed:
addattr32(n, 1024, IFLA_VTI_IKEY, ikey);
addattr32(n, 1024, IFLA_VTI_OKEY, okey);
- addattr_l(n, 1024, IFLA_VTI_LOCAL, &saddr, sizeof(saddr));
- addattr_l(n, 1024, IFLA_VTI_REMOTE, &daddr, sizeof(daddr));
+
+ if (memcmp(&saddr, &in6addr_any, sizeof(in6addr_any)))
+ addattr_l(n, 1024, IFLA_VTI_LOCAL, &saddr, sizeof(saddr));
+ if (memcmp(&daddr, &in6addr_any, sizeof(in6addr_any)))
+ addattr_l(n, 1024, IFLA_VTI_REMOTE, &daddr, sizeof(daddr));
addattr32(n, 1024, IFLA_VTI_FWMARK, fwmark);
if (link)
addattr32(n, 1024, IFLA_VTI_LINK, link);
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply related
* Re: [PATCH net-next v3 00/13] Update DSA's FDB API and perform switchdev cleanup
From: Vivien Didelot @ 2017-08-07 14:59 UTC (permalink / raw)
To: Arkadi Sharshevsky, netdev
Cc: davem, jiri, ivecera, f.fainelli, andrew, Woojung.Huh, mlxsw,
Arkadi Sharshevsky
In-Reply-To: <1502025351-41261-1-git-send-email-arkadis@mellanox.com>
Hi Arkadi,
Arkadi Sharshevsky <arkadis@mellanox.com> writes:
> The patchset adds support for configuring static FDB entries via the
> switchdev notification chain. The current method for FDB configuration
> uses the switchdev's bridge bypass implementation. In order to support
> this legacy way and to perform the switchdev cleanup, the implementation
> is moved inside DSA.
>
> The DSA drivers cannot sync the software bridge with hardware learned
> entries and use the switchdev's implementation of bypass FDB dumping.
> Because they are the only ones using this functionality, the fdb_dump
> implementation is moved from switchdev code into DSA.
>
> Finally after this changes a major cleanup in switchdev can be done.
> ---
> Please see individual patches for patch specific change logs.
> v1->v2
> - Split MDB/vlan dump removal into core/driver removal.
>
> v2->v3
> - The self implementation for FDB add/del is moved inside DSA.
v3 behaves correctly:
# bridge fdb add e4:1d:2d:a5:f0:2a dev lan3
# bridge fdb add e4:1d:2d:a5:f0:4a dev lan4 master
# bridge fdb show
01:00:5e:00:00:01 dev eth0 self permanent
01:00:5e:00:00:01 dev eth1 self permanent
b6:f2:c8:3a:1c:71 dev lan0 master br0 permanent
e4:1d:2d:a5:f0:2a dev lan3 self static
e4:1d:2d:a5:f0:4a dev lan4 offload master br0 permanent
e4:1d:2d:a5:f0:4a dev lan4 self static
01:00:5e:00:00:01 dev br0 self permanent
# bridge fdb del e4:1d:2d:a5:f0:2a dev lan3
# bridge fdb del e4:1d:2d:a5:f0:4a dev lan4 master
# bridge fdb show
01:00:5e:00:00:01 dev eth0 self permanent
01:00:5e:00:00:01 dev eth1 self permanent
b6:f2:c8:3a:1c:71 dev lan0 master br0 permanent
01:00:5e:00:00:01 dev br0 self permanent
Tested-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Thanks,
Vivien
^ permalink raw reply
* pull-request: wireless-drivers-next 2017-08-07
From: Kalle Valo @ 2017-08-07 14:55 UTC (permalink / raw)
To: David Miller; +Cc: linux-wireless, netdev, linux-kernel
Hi Dave,
here's the first pull request to net-next for 4.14, more info in the
signed tag below. This time there's a simple conflict in iwlwifi but
you can fix it just like Stephen did:
https://lkml.kernel.org/r/20170804120408.0d147e86@canb.auug.org.au
Please let me know if you have any problems.
Kalle
The following changes since commit 53d56f79a0b2e4bc5bbc04988e5bfde768db604f:
Merge branch 'qed-next' (2017-07-27 00:05:23 -0700)
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-2017-08-07
for you to fetch changes up to 9d546198705a79630cb29b1cc47a43e75b8afb89:
rtlwifi: Replace hardcode value with macro (2017-08-03 13:20:43 +0300)
----------------------------------------------------------------
wireless-drivers-next patches for 4.14
The first wireless-drivers-next pull request for 4.14. I'm submitting
this unusally late in the cycle as my vacation postponed this. But
even if this is late there's not still that much new features, mostly
cleanup or fixes.
Major changes:
ath10k
* preparation for wcn3990 support
iwlwifi
* Reorganization of the code into separate directories continues
qtnfmac
* regulatory support updates
* add get_channel, dump_survey and channel_switch cfg80211 handlers
----------------------------------------------------------------
Amitkumar Karwar (5):
rsi: use BUILD_BUG_ON check for fsm_state
rsi: correct the logic of deriving queue number
rsi: use macro for allocating USB buffer
rsi: check length before USB read/write register
rsi: fix static checker warning
Arvind Yadav (9):
brcmfmac: constify pci_device_id
rtlwifi: rtl8192de: constify pci_device_id.
rtlwifi: rtl8192se: constify pci_device_id.
rtlwifi: rtl8821ae: constify pci_device_id.
rtlwifi: rtl8723ae: constify pci_device_id.
rtlwifi: rtl8723be: constify pci_device_id.
rtlwifi: rtl8188ee: constify pci_device_id.
rtlwifi: rtl8192ee: constify pci_device_id.
net: qtnfmac: constify pci_device_id.
Brian Norris (21):
mwifiex: correct channel stat buffer overflows
mwifiex: reunite copy-and-pasted remove/reset code
mwifiex: reset interrupt status across device reset
mwifiex: pcie: don't allow cmd buffer reuse after reset
mwifiex: re-register wiphy across reset
mwifiex: unregister wiphy before freeing resources
mwifiex: don't short-circuit netdev notifiers on interface deletion
mwifiex: fixup init_channel_scan_gap error case
mwifiex: ensure "disable auto DS" struct is initialized
mwifiex: fix misnomers in mwifiex_free_lock_list()
mwifiex: make mwifiex_free_cmd_buffer() return void
mwifiex: utilize netif_tx_{wake,stop}_all_queues()
mwifiex: don't open-code ARRAY_SIZE()
mwifiex: drop 'add_tail' param from mwifiex_insert_cmd_to_pending_q()
mwifiex: pcie: remove unnecessary masks
mwifiex: pcie: unify MSI-X / non-MSI-X interrupt process
mwifiex: debugfs: allow card_reset() to cancel things
mwifiex: pcie: disable device DMA before unmapping/freeing buffers
mwifiex: pcie: remove unnecessary 'pdev' check
mwifiex: keep mwifiex_cancel_pending_ioctl() static
mwifiex: drop num CPU notice
Colin Ian King (5):
rtlwifi: kfree entry until after entry->bssid has been accessed
mwifiex: usb: fix spelling mistake: "aggreataon"-> "aggregation"
mwifiex: fix spelling mistake: "Insuffient" -> "Insufficient"
zd1211rw: fix spelling mistake 'hybernate' -> 'hibernate'
wl3501_cs: fix spelling mistake: "Insupported" -> "Unsupported"
Cong Wang (1):
wl1251: add a missing spin_lock_init()
Dan Carpenter (2):
mwifiex: usb: unlock on error in mwifiex_usb_tx_aggr_tmo()
rtlwifi: rtl8821ae: Fix HW_VAR_NAV_UPPER operation
Dan Williams (1):
ipw2100: don't return positive values to PCI probe on error
Emmanuel Grumbach (3):
iwlwifi: mvm: fix the FIFO numbers in A000 devices
iwlwifi: pcie: fix A-MSDU on gen2 devices
iwlwifi: mvm: don't retake the pointer to skb's CB
Florian Fainelli (1):
bcma: gpio: Correct number of GPIOs for BCM53573
Govind Singh (2):
ath10k: make CE layer bus agnostic
ath10k: add copy engine register MAP for wcn3990 target
Jeffy Chen (1):
mwifiex: uninit wakeup info in the error handling
Johannes Berg (13):
iwlwifi: refactor out paging code
iwlwifi: refactor shared mem parsing
iwlwifi: track current firmware image in common code
iwlwifi: refactor firmware debug code
iwlwifi: reorganize firmware API
iwlwifi: fw api: fix various kernel-doc warnings
iwlwifi: mvm: add and use iwl_mvm_has_unified_ucode()
iwlwifi: mvm: check family instead of new TX API for workarounds
iwlwifi: mvm: byte-swap constant instead of variable
iwlwifi: pcie: rename iwl_trans_check_hw_rf_kill() to pcie
iwlwifi: mvm: require AP_LINK_PS for TVQM
iwlwifi: mvm: simplify bufferable MMPDU check
iwlwifi: mvm: remove non-DQA mode
Kalle Valo (3):
ath10k: fix indenting in ath10k_wmi_update_noa()
Merge ath-next from git://git.kernel.org/.../kvalo/ath.git
Merge tag 'iwlwifi-next-for-kalle-2017-08-01' of git://git.kernel.org/.../iwlwifi/iwlwifi-next
Karun Eagalapati (13):
rsi: fix sdio card reset problem
rsi: chip reset for SDIO interface
rsi: correct SDIO disconnect path handling
rsi: card reset for USB interface
rsi: USB tx headroom cleanup
rsi: rename USB endpoint macros
rsi: choose correct endpoint based on queue.
rsi: set immediate wakeup bit
rsi: rename variable in_sdio_litefi_irq
rsi: Optimise sdio claim and release host
rsi: SDIO Rx packet processing enhancement
rsi: use separate mutex lock for receive thread
rsi: Rename mutex tx_rxlock to the tx_lock.
Liad Kaufman (1):
iwlwifi: mvm: support fw reading empty OTP
Luca Coelho (2):
iwlwifi: mvm: refactor beacon template command code
iwlwifi: mvm: rename p2p-specific sta functions to include p2p in the names
Malcolm Priestley (1):
rtlwifi: rtl_pci_probe: Fix fail path of _rtl_pci_find_adapter
Mordechai Goodstein (1):
iwlwifi: implement fseq version mismatch warning
Pavani Muthyala (4):
rsi: management frame descriptor preparation cleanup
rsi: data packet descriptor code cleanup
rsi: data packet descriptor enhancements
rsi: separate function for data packet descriptor
Ping-Ke Shih (8):
rtlwifi: Fill in_4way field by driver
rtlwifi: Add BT_MP_INFO to c2h handler.
rtlwifi: Add board type for 8723be and 8192ee
rtlwifi: add amplifier type for 8812ae
rtlwifi: Update 8723be new phy parameters and its parser.
rtlwifi: Rename rtl_desc92_rate to rtl_desc_rate
rtlwifi: Uses addr1 instead DA to determine broadcast and multicast addr.
rtlwifi: move IS_HARDWARE_TYPE_xxx checker to wifi.h
Prameela Rani Garnepudi (19):
rsi: changes in eeprom read frame
rsi: separate function for management packet descriptor
rsi: add common structures needed for command packets
rsi: immediate wakeup bit and priority for TX command packets
rsi: Update in tx command frame radio capabilities
rsi: remove unnecessary check for 802.11 management packet
rsi: Update peer notify command frame
rsi: Update aggregation parameters command frame
rsi: Update baseband RF programming frame
rsi: update set_channel command frame
rsi: update vap capabilities command frame
rsi: update set_key command frame
rsi: set_key enhancements
rsi: update autorate request command frame
rsi: block/unblock data queues as per connection status
rsi: update tx command frame block/unblock data
rsi: Remove internal header from Tx status skb
rsi: Send rx filter frame to device when interface is down
rsi: regulatory enhancements
Robin Murphy (1):
qtnfmac: Tidy up DMA mask setting
Seraphime Kirkovski (1):
iwlwifi: dvm: remove unused defines
Sergey Matyukevich (12):
qtnfmac: updates for regulatory support
qtnfmac: regulatory configuration for self-managed setup
qtnfmac: add missing bus lock
qtnfmac: implement cfg80211 dump_survey handler
qtnfmac: implement reporting current channel
qtnfmac: fix station leave reason endianness
qtnfmac: move current channel info from vif to mac
qtnfmac: implement cfg80211 channel_switch handler
qtnfmac: implement scan timeout
qtnfmac: fix handling of iftype mask reported by firmware
qtnfmac: remove function qtnf_cmd_skb_put_action
qtnfmac: prepare for AP_VLAN interface type support
Sharon Dvir (1):
iwlwifi: mvm: fix uninitialized var while waiting for queues to empty
Shawn Lin (1):
mwifiex: fix compile warning of unused variable
Souptick Joarder (4):
rtlwifi: remove dummy function call
rtlwifi: Remove unused dummy function
rtlwifi: Fix memory leak when firmware request fails
rtlwifi: Replace hardcode value with macro
Stefano Brivio (1):
hostap: Fix outdated comment about dev->destructor
Sven Joachim (1):
rtlwifi: Fix fallback firmware loading
Tamizh chelvam (1):
ath10k: increase buffer len to print all wmi services
Xinming Hu (4):
mwifiex: disable uapsd in tdls config
mwifiex: correct IE parse during association
mwifiex: make addba request command clean
mwifiex: pcie: compatible with wifi-only image while extract wifi-part fw
Zamir, Roee (1):
iwlwifi: mvm: add compile-time option to disable EBS
drivers/bcma/driver_gpio.c | 1 +
drivers/net/wireless/ath/ath10k/ahb.c | 3 +-
drivers/net/wireless/ath/ath10k/ce.c | 299 +-
drivers/net/wireless/ath/ath10k/ce.h | 30 +-
drivers/net/wireless/ath/ath10k/core.c | 5 +
drivers/net/wireless/ath/ath10k/core.h | 2 +
drivers/net/wireless/ath/ath10k/debug.c | 2 +-
drivers/net/wireless/ath/ath10k/hw.c | 150 ++
drivers/net/wireless/ath/ath10k/hw.h | 9 +
drivers/net/wireless/ath/ath10k/pci.c | 55 +-
drivers/net/wireless/ath/ath10k/pci.h | 14 +-
drivers/net/wireless/ath/ath10k/wmi.c | 2 +-
.../wireless/broadcom/brcm80211/brcmfmac/pcie.c | 2 +-
drivers/net/wireless/intel/ipw2x00/ipw2100.c | 28 +-
drivers/net/wireless/intel/iwlwifi/Makefile | 2 +
drivers/net/wireless/intel/iwlwifi/dvm/commands.h | 16 -
drivers/net/wireless/intel/iwlwifi/fw/api/alive.h | 206 ++
.../net/wireless/intel/iwlwifi/fw/api/binding.h | 144 +
.../intel/iwlwifi/fw/{api.h => api/cmdhdr.h} | 78 +-
.../iwlwifi/{mvm/fw-api-coex.h => fw/api/coex.h} | 11 +-
.../net/wireless/intel/iwlwifi/fw/api/commands.h | 664 +++++
drivers/net/wireless/intel/iwlwifi/fw/api/config.h | 192 ++
.../net/wireless/intel/iwlwifi/fw/api/context.h | 94 +
.../intel/iwlwifi/{mvm/fw-api-d3.h => fw/api/d3.h} | 11 +-
.../net/wireless/intel/iwlwifi/fw/api/datapath.h | 127 +
drivers/net/wireless/intel/iwlwifi/fw/api/debug.h | 345 +++
drivers/net/wireless/intel/iwlwifi/fw/api/filter.h | 183 ++
.../net/wireless/intel/iwlwifi/fw/api/mac-cfg.h | 152 ++
.../iwlwifi/{mvm/fw-api-mac.h => fw/api/mac.h} | 33 +-
.../net/wireless/intel/iwlwifi/fw/api/nvm-reg.h | 386 +++
.../net/wireless/intel/iwlwifi/fw/api/offload.h | 101 +
drivers/net/wireless/intel/iwlwifi/fw/api/paging.h | 108 +
.../net/wireless/intel/iwlwifi/fw/api/phy-ctxt.h | 164 ++
drivers/net/wireless/intel/iwlwifi/fw/api/phy.h | 258 ++
.../iwlwifi/{mvm/fw-api-power.h => fw/api/power.h} | 13 +-
.../intel/iwlwifi/{mvm/fw-api-rs.h => fw/api/rs.h} | 13 +-
.../intel/iwlwifi/{mvm/fw-api-rx.h => fw/api/rx.h} | 31 +-
.../iwlwifi/{mvm/fw-api-scan.h => fw/api/scan.h} | 11 +-
drivers/net/wireless/intel/iwlwifi/fw/api/sf.h | 138 +
.../iwlwifi/{mvm/fw-api-sta.h => fw/api/sta.h} | 15 +-
.../iwlwifi/{mvm/fw-api-stats.h => fw/api/stats.h} | 13 +-
drivers/net/wireless/intel/iwlwifi/fw/api/tdls.h | 208 ++
.../net/wireless/intel/iwlwifi/fw/api/time-event.h | 386 +++
.../iwlwifi/{mvm/fw-api-tof.h => fw/api/tof.h} | 9 +-
.../intel/iwlwifi/{mvm/fw-api-tx.h => fw/api/tx.h} | 42 +-
drivers/net/wireless/intel/iwlwifi/fw/api/txq.h | 163 ++
drivers/net/wireless/intel/iwlwifi/fw/common_rx.c | 88 +
.../intel/iwlwifi/{mvm/fw-dbg.c => fw/dbg.c} | 438 +--
.../intel/iwlwifi/{mvm/fw-dbg.h => fw/dbg.h} | 125 +-
drivers/net/wireless/intel/iwlwifi/fw/init.c | 75 +
drivers/net/wireless/intel/iwlwifi/fw/paging.c | 414 +++
drivers/net/wireless/intel/iwlwifi/fw/runtime.h | 156 ++
drivers/net/wireless/intel/iwlwifi/fw/smem.c | 152 ++
drivers/net/wireless/intel/iwlwifi/iwl-trans.h | 3 +-
drivers/net/wireless/intel/iwlwifi/mvm/Makefile | 2 +-
drivers/net/wireless/intel/iwlwifi/mvm/coex.c | 2 +-
drivers/net/wireless/intel/iwlwifi/mvm/constants.h | 2 +-
.../net/wireless/intel/iwlwifi/mvm/debugfs-vif.c | 2 +-
drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c | 21 +-
drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h | 2845 +-------------------
drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 482 +---
drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 382 +--
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 194 +-
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 121 +-
drivers/net/wireless/intel/iwlwifi/mvm/nvm.c | 7 +-
drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 152 +-
drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c | 2 +-
drivers/net/wireless/intel/iwlwifi/mvm/power.c | 25 +-
drivers/net/wireless/intel/iwlwifi/mvm/rx.c | 11 +-
drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 9 +-
drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 4 +-
drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 452 +---
drivers/net/wireless/intel/iwlwifi/mvm/sta.h | 18 +-
.../net/wireless/intel/iwlwifi/mvm/time-event.c | 20 +-
drivers/net/wireless/intel/iwlwifi/mvm/tof.c | 2 +-
drivers/net/wireless/intel/iwlwifi/mvm/tof.h | 2 +-
drivers/net/wireless/intel/iwlwifi/mvm/tt.c | 6 +-
drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 155 +-
drivers/net/wireless/intel/iwlwifi/mvm/utils.c | 18 +-
drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 4 +-
drivers/net/wireless/intel/iwlwifi/pcie/internal.h | 2 +-
.../net/wireless/intel/iwlwifi/pcie/trans-gen2.c | 4 +-
drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 8 +-
drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c | 8 +-
drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 5 +-
drivers/net/wireless/intersil/hostap/hostap_main.c | 4 +-
drivers/net/wireless/marvell/mwifiex/11n.c | 2 +
drivers/net/wireless/marvell/mwifiex/cfg80211.c | 6 +-
drivers/net/wireless/marvell/mwifiex/cfp.c | 4 +-
drivers/net/wireless/marvell/mwifiex/cmdevt.c | 15 +-
drivers/net/wireless/marvell/mwifiex/debugfs.c | 2 -
drivers/net/wireless/marvell/mwifiex/init.c | 32 +-
drivers/net/wireless/marvell/mwifiex/main.c | 133 +-
drivers/net/wireless/marvell/mwifiex/main.h | 7 +-
drivers/net/wireless/marvell/mwifiex/pcie.c | 126 +-
drivers/net/wireless/marvell/mwifiex/scan.c | 11 +-
drivers/net/wireless/marvell/mwifiex/sdio.c | 3 +-
drivers/net/wireless/marvell/mwifiex/sta_cmd.c | 19 +-
drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c | 5 +-
drivers/net/wireless/marvell/mwifiex/sta_ioctl.c | 121 +-
drivers/net/wireless/marvell/mwifiex/tdls.c | 2 +-
drivers/net/wireless/marvell/mwifiex/usb.c | 3 +-
drivers/net/wireless/quantenna/qtnfmac/cfg80211.c | 315 ++-
drivers/net/wireless/quantenna/qtnfmac/cfg80211.h | 4 +
drivers/net/wireless/quantenna/qtnfmac/commands.c | 486 +++-
drivers/net/wireless/quantenna/qtnfmac/commands.h | 5 +
drivers/net/wireless/quantenna/qtnfmac/core.c | 5 +
drivers/net/wireless/quantenna/qtnfmac/core.h | 27 +-
drivers/net/wireless/quantenna/qtnfmac/event.c | 67 +-
.../net/wireless/quantenna/qtnfmac/pearl/pcie.c | 30 +-
drivers/net/wireless/quantenna/qtnfmac/qlink.h | 202 +-
.../net/wireless/quantenna/qtnfmac/qlink_util.c | 26 +-
.../net/wireless/quantenna/qtnfmac/qlink_util.h | 10 +-
drivers/net/wireless/realtek/rtlwifi/base.c | 22 +-
drivers/net/wireless/realtek/rtlwifi/base.h | 2 +
.../realtek/rtlwifi/btcoexist/halbt_precomp.h | 16 -
.../realtek/rtlwifi/btcoexist/halbtcoutsrc.c | 17 +-
.../wireless/realtek/rtlwifi/btcoexist/rtl_btc.c | 28 +
.../wireless/realtek/rtlwifi/btcoexist/rtl_btc.h | 1 +
drivers/net/wireless/realtek/rtlwifi/core.c | 2 +
drivers/net/wireless/realtek/rtlwifi/pci.c | 4 +-
.../net/wireless/realtek/rtlwifi/rtl8188ee/sw.c | 4 +-
.../net/wireless/realtek/rtlwifi/rtl8192ce/sw.c | 2 +
.../net/wireless/realtek/rtlwifi/rtl8192cu/hw.c | 5 -
.../net/wireless/realtek/rtlwifi/rtl8192cu/mac.c | 3 +-
.../net/wireless/realtek/rtlwifi/rtl8192cu/sw.c | 6 +-
.../net/wireless/realtek/rtlwifi/rtl8192cu/trx.c | 12 -
.../net/wireless/realtek/rtlwifi/rtl8192cu/trx.h | 3 -
.../net/wireless/realtek/rtlwifi/rtl8192de/sw.c | 4 +-
.../net/wireless/realtek/rtlwifi/rtl8192ee/fw.c | 9 +-
.../net/wireless/realtek/rtlwifi/rtl8192ee/hw.c | 5 +
.../net/wireless/realtek/rtlwifi/rtl8192ee/sw.c | 4 +-
.../net/wireless/realtek/rtlwifi/rtl8192se/sw.c | 4 +-
.../net/wireless/realtek/rtlwifi/rtl8723ae/sw.c | 4 +-
.../net/wireless/realtek/rtlwifi/rtl8723be/fw.c | 9 +-
.../net/wireless/realtek/rtlwifi/rtl8723be/hw.c | 7 +
.../net/wireless/realtek/rtlwifi/rtl8723be/phy.c | 365 ++-
.../net/wireless/realtek/rtlwifi/rtl8723be/sw.c | 17 +-
.../net/wireless/realtek/rtlwifi/rtl8723be/table.c | 192 +-
.../net/wireless/realtek/rtlwifi/rtl8723be/table.h | 10 +-
.../net/wireless/realtek/rtlwifi/rtl8821ae/fw.c | 13 +-
.../net/wireless/realtek/rtlwifi/rtl8821ae/hw.c | 43 +-
.../net/wireless/realtek/rtlwifi/rtl8821ae/sw.c | 21 +-
drivers/net/wireless/realtek/rtlwifi/wifi.h | 49 +-
drivers/net/wireless/rsi/rsi_91x_core.c | 10 +-
drivers/net/wireless/rsi/rsi_91x_debugfs.c | 3 +
drivers/net/wireless/rsi/rsi_91x_hal.c | 270 +-
drivers/net/wireless/rsi/rsi_91x_mac80211.c | 63 +-
drivers/net/wireless/rsi/rsi_91x_main.c | 3 +-
drivers/net/wireless/rsi/rsi_91x_mgmt.c | 470 ++--
drivers/net/wireless/rsi/rsi_91x_sdio.c | 154 +-
drivers/net/wireless/rsi/rsi_91x_sdio_ops.c | 44 +-
drivers/net/wireless/rsi/rsi_91x_usb.c | 137 +-
drivers/net/wireless/rsi/rsi_91x_usb_ops.c | 6 +-
drivers/net/wireless/rsi/rsi_hal.h | 64 +
drivers/net/wireless/rsi/rsi_main.h | 52 +-
drivers/net/wireless/rsi/rsi_mgmt.h | 171 +-
drivers/net/wireless/rsi/rsi_sdio.h | 4 +-
drivers/net/wireless/rsi/rsi_usb.h | 6 +-
drivers/net/wireless/ti/wl1251/main.c | 1 +
drivers/net/wireless/wl3501_cs.c | 2 +-
drivers/net/wireless/zydas/zd1211rw/zd_rf_rf2959.c | 2 +-
162 files changed, 9060 insertions(+), 6294 deletions(-)
create mode 100644 drivers/net/wireless/intel/iwlwifi/fw/api/alive.h
create mode 100644 drivers/net/wireless/intel/iwlwifi/fw/api/binding.h
rename drivers/net/wireless/intel/iwlwifi/fw/{api.h => api/cmdhdr.h} (82%)
rename drivers/net/wireless/intel/iwlwifi/{mvm/fw-api-coex.h => fw/api/coex.h} (96%)
create mode 100644 drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
create mode 100644 drivers/net/wireless/intel/iwlwifi/fw/api/config.h
create mode 100644 drivers/net/wireless/intel/iwlwifi/fw/api/context.h
rename drivers/net/wireless/intel/iwlwifi/{mvm/fw-api-d3.h => fw/api/d3.h} (98%)
create mode 100644 drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h
create mode 100644 drivers/net/wireless/intel/iwlwifi/fw/api/debug.h
create mode 100644 drivers/net/wireless/intel/iwlwifi/fw/api/filter.h
create mode 100644 drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h
rename drivers/net/wireless/intel/iwlwifi/{mvm/fw-api-mac.h => fw/api/mac.h} (93%)
create mode 100644 drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
create mode 100644 drivers/net/wireless/intel/iwlwifi/fw/api/offload.h
create mode 100644 drivers/net/wireless/intel/iwlwifi/fw/api/paging.h
create mode 100644 drivers/net/wireless/intel/iwlwifi/fw/api/phy-ctxt.h
create mode 100644 drivers/net/wireless/intel/iwlwifi/fw/api/phy.h
rename drivers/net/wireless/intel/iwlwifi/{mvm/fw-api-power.h => fw/api/power.h} (98%)
rename drivers/net/wireless/intel/iwlwifi/{mvm/fw-api-rs.h => fw/api/rs.h} (97%)
rename drivers/net/wireless/intel/iwlwifi/{mvm/fw-api-rx.h => fw/api/rx.h} (95%)
rename drivers/net/wireless/intel/iwlwifi/{mvm/fw-api-scan.h => fw/api/scan.h} (98%)
create mode 100644 drivers/net/wireless/intel/iwlwifi/fw/api/sf.h
rename drivers/net/wireless/intel/iwlwifi/{mvm/fw-api-sta.h => fw/api/sta.h} (98%)
rename drivers/net/wireless/intel/iwlwifi/{mvm/fw-api-stats.h => fw/api/stats.h} (97%)
create mode 100644 drivers/net/wireless/intel/iwlwifi/fw/api/tdls.h
create mode 100644 drivers/net/wireless/intel/iwlwifi/fw/api/time-event.h
rename drivers/net/wireless/intel/iwlwifi/{mvm/fw-api-tof.h => fw/api/tof.h} (98%)
rename drivers/net/wireless/intel/iwlwifi/{mvm/fw-api-tx.h => fw/api/tx.h} (98%)
create mode 100644 drivers/net/wireless/intel/iwlwifi/fw/api/txq.h
create mode 100644 drivers/net/wireless/intel/iwlwifi/fw/common_rx.c
rename drivers/net/wireless/intel/iwlwifi/{mvm/fw-dbg.c => fw/dbg.c} (69%)
rename drivers/net/wireless/intel/iwlwifi/{mvm/fw-dbg.h => fw/dbg.h} (59%)
create mode 100644 drivers/net/wireless/intel/iwlwifi/fw/init.c
create mode 100644 drivers/net/wireless/intel/iwlwifi/fw/paging.c
create mode 100644 drivers/net/wireless/intel/iwlwifi/fw/runtime.h
create mode 100644 drivers/net/wireless/intel/iwlwifi/fw/smem.c
--
Kalle Valo
^ permalink raw reply
* Re: [PATCH v2 net-next 0/7] net: l3mdev: Support for sockets bound to enslaved device
From: David Ahern @ 2017-08-07 14:35 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20170806.235145.398118943167397128.davem@davemloft.net>
On 8/7/17 12:51 AM, David Miller wrote:
> David, I had to revert. You didn't convert dccp which breaks
> the build.
>
> net/dccp/ipv4.c: In function ‘dccp_v4_err’:
> net/dccp/ipv4.c:256:7: error: too few arguments to function ‘__inet_lookup_established’
> sk = __inet_lookup_established(net, &dccp_hashinfo,
> ^~~~~~~~~~~~~~~~~~~~~~~~~
> In file included from net/dccp/ipv4.c:22:0:
> ./include/net/inet_hashtables.h:289:14: note: declared here
> struct sock *__inet_lookup_established(struct net *net,
> ^~~~~~~~~~~~~~~~~~~~~~~~~
That's embarrassing. Will fix
^ permalink raw reply
* [PATCH v5 net-next 12/12] bpf/verifier: increase complexity limit to 128k
From: Edward Cree @ 2017-08-07 14:30 UTC (permalink / raw)
To: davem, Alexei Starovoitov, Alexei Starovoitov, Daniel Borkmann
Cc: netdev, linux-kernel, iovisor-dev
In-Reply-To: <ad840039-8d4a-b2a9-b2eb-a8f079926b53@solarflare.com>
The more detailed value tracking can reduce the effectiveness of pruning
for some programs. So, to avoid rejecting previously valid programs, up
the limit to 128kinsns. Hopefully we will be able to bring this back
down later by improving pruning performance.
Signed-off-by: Edward Cree <ecree@solarflare.com>
---
kernel/bpf/verifier.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 08a6fa0..8160a81 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -140,7 +140,7 @@ struct bpf_verifier_stack_elem {
struct bpf_verifier_stack_elem *next;
};
-#define BPF_COMPLEXITY_LIMIT_INSNS 98304
+#define BPF_COMPLEXITY_LIMIT_INSNS 131072
#define BPF_COMPLEXITY_LIMIT_STACK 1024
#define BPF_MAP_PTR_POISON ((void *)0xeB9F + POISON_POINTER_DELTA)
^ 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