* Re: [PATCH] ath9k: debug: remove set but not used variable 'fops_dump_nfcal'
From: Kalle Valo @ 2018-10-01 14:06 UTC (permalink / raw)
To: YueHaibing
Cc: ath9k-devel, linux-kernel, netdev, davem, linux-wireless,
YueHaibing
In-Reply-To: <20180910031128.12164-1-yuehaibing@huawei.com>
YueHaibing <yuehaibing@huawei.com> wrote:
> 'fops_dump_nfcal' is not used since commit 4447d815fd0f ("ath: ath9k: use debugfs_create_devm_seqfile() helper for seq_file entries")
>
> Signed-off-by: YueHaibing <yuehaibing@huawei.com>
> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Patch applied to ath-next branch of ath.git, thanks.
b8f3d1635103 ath9k: debug: remove set but not used variable 'fops_dump_nfcal'
--
https://patchwork.kernel.org/patch/10593539/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply
* Re: [PATCH v3] PCI: Reprogram bridge prefetch registers on resume
From: Thomas Martitz @ 2018-10-01 14:25 UTC (permalink / raw)
To: Daniel Drake
Cc: andy.shevchenko-VuQAYsv1563Yd54FQh9/CA,
nic_swsd-Rasf1IRRPZFBDgjK7y7TUQ, Linux PM, Linux PCI,
Wysocki, Rafael J, Linux Kernel, Keith Busch, netdev,
Bjorn Helgaas, nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
Bjorn Helgaas, rchang-eYqpPyKDWXRBDgjK7y7TUQ,
Linux Upstreaming Team, David Miller, Jon Derrick,
Heiner Kallweit
In-Reply-To: <CAD8Lp47uL3DQTBiVTduO1+Cg8px4CDpv26qVJsgT+RJ4WZx9oA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
Am 01.10.18 um 06:57 schrieb Daniel Drake:
> On Sun, Sep 30, 2018 at 5:07 AM Thomas Martitz <kugel@rockbox.org> wrote:
>> The latest iteration does not work on my HP system. The GPU fails to
>> power up just like the unpatched kernel.
>
> That's weird, I would not expect a behaviour change in the latest
> patch. pci_restore_config_dword() has some debug messages, could you
> please make them visible and show logs again?
> Also remind us of the PCI device address of the parent bridge (lspci -vt)
>
I'll follow up with more the requested information on bugzilla
(Link: https://bugzilla.kernel.org/show_bug.cgi?id=201069).
On a quick re-check, it seems to depend on if I used the eGPU before
the initial suspend. If I run glxgears (with DRI_PRIME=1) before suspend
it seems fine.
Best regards.
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply
* Re: [PATCH] ipw2x00: clean up clang warning on extraneous parentheses
From: Sergei Shtylyov @ 2018-10-01 8:14 UTC (permalink / raw)
To: Colin King, Stanislav Yakovlev, Kalle Valo, David S . Miller,
linux-wireless, netdev
Cc: kernel-janitors, linux-kernel
In-Reply-To: <20180930223809.18136-1-colin.king@canonical.com>
Hello!
On 10/1/2018 1:38 AM, Colin King wrote:
> From: Colin Ian King <colin.king@canonical.com>
>
> There are extraneous parantheses that are causing clang to produce a
Parentheses.
> warning so remove these.
>
> Clean up clang warning:
> equality comparison with extraneous parentheses [-Wparentheses-equality]
>
> Signed-off-by: Colin Ian King <colin.king@canonical.com>
[...]
MBR, Sergei
^ permalink raw reply
* Re: [PATCH net-next] net: mscc: allow extracting the FCS into the skb
From: Alexandre Belloni @ 2018-10-01 14:59 UTC (permalink / raw)
To: Antoine Tenart
Cc: davem, netdev, linux-kernel, thomas.petazzoni, quentin.schulz,
allan.nielsen
In-Reply-To: <20181001095714.26024-1-antoine.tenart@bootlin.com>
On 01/10/2018 11:57:14+0200, Antoine Ténart wrote:
> This patch adds support for the NETIF_F_RXFCS feature in the Mscc
> Ethernet driver. This feature is disabled by default and allow an user
> to request the driver not to drop the FCS and to extract it into the skb
> for debugging purposes.
>
> Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
> ---
> drivers/net/ethernet/mscc/ocelot.c | 2 +-
> drivers/net/ethernet/mscc/ocelot_board.c | 7 ++++++-
> 2 files changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
> index 1a4f2bb48ead..eb5119e7e60b 100644
> --- a/drivers/net/ethernet/mscc/ocelot.c
> +++ b/drivers/net/ethernet/mscc/ocelot.c
> @@ -1606,7 +1606,7 @@ int ocelot_probe_port(struct ocelot *ocelot, u8 port,
> dev->ethtool_ops = &ocelot_ethtool_ops;
> dev->switchdev_ops = &ocelot_port_switchdev_ops;
>
> - dev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER;
> + dev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_RXFCS;
> dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
>
> memcpy(dev->dev_addr, ocelot->base_mac, ETH_ALEN);
> diff --git a/drivers/net/ethernet/mscc/ocelot_board.c b/drivers/net/ethernet/mscc/ocelot_board.c
> index 3cdf63e35b53..245452a0f244 100644
> --- a/drivers/net/ethernet/mscc/ocelot_board.c
> +++ b/drivers/net/ethernet/mscc/ocelot_board.c
> @@ -126,11 +126,16 @@ static irqreturn_t ocelot_xtr_irq_handler(int irq, void *arg)
> len += sz;
> } while (len < buf_len);
>
> - /* Read the FCS and discard it */
> + /* Read the FCS */
> sz = ocelot_rx_frame_word(ocelot, grp, false, &val);
> /* Update the statistics if part of the FCS was read before */
> len -= ETH_FCS_LEN - sz;
>
> + if (unlikely(dev->features & NETIF_F_RXFCS)) {
> + buf = (u32 *)skb_put(skb, ETH_FCS_LEN);
> + *buf = val;
> + }
> +
> if (sz < 0) {
> err = sz;
> break;
> --
> 2.17.1
>
--
Alexandre Belloni, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* [PATCH net-next] ipv4: Allow sending multicast packets on specific i/f using VRF socket
From: Mike Manning @ 2018-10-01 8:40 UTC (permalink / raw)
To: netdev; +Cc: Robert Shearman
From: Robert Shearman <rshearma@vyatta.att-mail.com>
It is useful to be able to use the same socket for listening in a
specific VRF, as for sending multicast packets out of a specific
interface. However, the bound device on the socket currently takes
precedence and results in the packets not being sent.
Relax the condition on overriding the output interface to use for
sending packets out of UDP, raw and ping sockets to allow multicast
packets to be sent using the specified multicast interface.
Signed-off-by: Robert Shearman <rshearma@vyatta.att-mail.com>
Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
---
net/ipv4/datagram.c | 2 +-
net/ipv4/ping.c | 2 +-
net/ipv4/raw.c | 2 +-
net/ipv4/udp.c | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c
index f915abff1350..300921417f89 100644
--- a/net/ipv4/datagram.c
+++ b/net/ipv4/datagram.c
@@ -42,7 +42,7 @@ int __ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len
oif = sk->sk_bound_dev_if;
saddr = inet->inet_saddr;
if (ipv4_is_multicast(usin->sin_addr.s_addr)) {
- if (!oif)
+ if (!oif || netif_index_is_l3_master(sock_net(sk), oif))
oif = inet->mc_index;
if (!saddr)
saddr = inet->mc_addr;
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index 8d7aaf118a30..7ccb5f87f70b 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -779,7 +779,7 @@ static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
}
if (ipv4_is_multicast(daddr)) {
- if (!ipc.oif)
+ if (!ipc.oif || netif_index_is_l3_master(sock_net(sk), ipc.oif))
ipc.oif = inet->mc_index;
if (!saddr)
saddr = inet->mc_addr;
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 33df4d76db2d..8ca3eb06ba04 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -608,7 +608,7 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
tos |= RTO_ONLINK;
if (ipv4_is_multicast(daddr)) {
- if (!ipc.oif)
+ if (!ipc.oif || netif_index_is_l3_master(sock_net(sk), ipc.oif))
ipc.oif = inet->mc_index;
if (!saddr)
saddr = inet->mc_addr;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index f4e35b2ff8b8..3386b3b0218c 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1042,7 +1042,7 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
}
if (ipv4_is_multicast(daddr)) {
- if (!ipc.oif)
+ if (!ipc.oif || netif_index_is_l3_master(sock_net(sk), ipc.oif))
ipc.oif = inet->mc_index;
if (!saddr)
saddr = inet->mc_addr;
--
2.11.0
^ permalink raw reply related
* [PATCH net-next] ipv6: add vrf table handling code for ipv6 mcast
From: Mike Manning @ 2018-10-01 8:41 UTC (permalink / raw)
To: netdev; +Cc: Patrick Ruddy
From: Patrick Ruddy <pruddy@vyatta.att-mail.com>
The code to obtain the correct table for the incoming interface was
missing for IPv6. This has been added along with the table creation
notification to fib rules for the RTNL_FAMILY_IP6MR address family.
Signed-off-by: Patrick Ruddy <pruddy@vyatta.att-mail.com>
Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
---
drivers/net/vrf.c | 11 +++++++++++
net/ipv6/ip6mr.c | 48 ++++++++++++++++++++++++++++++++++++------------
2 files changed, 47 insertions(+), 12 deletions(-)
diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
index f93547f257fb..69b7227c637e 100644
--- a/drivers/net/vrf.c
+++ b/drivers/net/vrf.c
@@ -1215,8 +1215,19 @@ static int vrf_add_fib_rules(const struct net_device *dev)
goto ipmr_err;
#endif
+#if IS_ENABLED(CONFIG_IPV6_MROUTE_MULTIPLE_TABLES)
+ err = vrf_fib_rule(dev, RTNL_FAMILY_IP6MR, true);
+ if (err < 0)
+ goto ip6mr_err;
+#endif
+
return 0;
+#if IS_ENABLED(CONFIG_IPV6_MROUTE_MULTIPLE_TABLES)
+ip6mr_err:
+ vrf_fib_rule(dev, RTNL_FAMILY_IPMR, false);
+#endif
+
#if IS_ENABLED(CONFIG_IP_MROUTE_MULTIPLE_TABLES)
ipmr_err:
vrf_fib_rule(dev, AF_INET6, false);
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index d0b7e0249c13..6f07b8380425 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -85,7 +85,8 @@ static struct mr_table *ip6mr_new_table(struct net *net, u32 id);
static void ip6mr_free_table(struct mr_table *mrt);
static void ip6_mr_forward(struct net *net, struct mr_table *mrt,
- struct sk_buff *skb, struct mfc6_cache *cache);
+ struct net_device *dev, struct sk_buff *skb,
+ struct mfc6_cache *cache);
static int ip6mr_cache_report(struct mr_table *mrt, struct sk_buff *pkt,
mifi_t mifi, int assert);
static void mr6_netlink_event(struct mr_table *mrt, struct mfc6_cache *mfc,
@@ -138,6 +139,9 @@ static int ip6mr_fib_lookup(struct net *net, struct flowi6 *flp6,
.flags = FIB_LOOKUP_NOREF,
};
+ /* update flow if oif or iif point to device enslaved to l3mdev */
+ l3mdev_update_flow(net, flowi6_to_flowi(flp6));
+
err = fib_rules_lookup(net->ipv6.mr6_rules_ops,
flowi6_to_flowi(flp6), 0, &arg);
if (err < 0)
@@ -164,7 +168,9 @@ static int ip6mr_rule_action(struct fib_rule *rule, struct flowi *flp,
return -EINVAL;
}
- mrt = ip6mr_get_table(rule->fr_net, rule->table);
+ arg->table = fib_rule_get_table(rule, arg);
+
+ mrt = ip6mr_get_table(rule->fr_net, arg->table);
if (!mrt)
return -EAGAIN;
res->mrt = mrt;
@@ -1014,7 +1020,7 @@ static void ip6mr_cache_resolve(struct net *net, struct mr_table *mrt,
}
rtnl_unicast(skb, net, NETLINK_CB(skb).portid);
} else
- ip6_mr_forward(net, mrt, skb, c);
+ ip6_mr_forward(net, mrt, skb->dev, skb, c);
}
}
@@ -1120,7 +1126,7 @@ static int ip6mr_cache_report(struct mr_table *mrt, struct sk_buff *pkt,
/* Queue a packet for resolution. It gets locked cache entry! */
static int ip6mr_cache_unresolved(struct mr_table *mrt, mifi_t mifi,
- struct sk_buff *skb)
+ struct sk_buff *skb, struct net_device *dev)
{
struct mfc6_cache *c;
bool found = false;
@@ -1180,6 +1186,10 @@ static int ip6mr_cache_unresolved(struct mr_table *mrt, mifi_t mifi,
kfree_skb(skb);
err = -ENOBUFS;
} else {
+ if (dev) {
+ skb->dev = dev;
+ skb->skb_iif = dev->ifindex;
+ }
skb_queue_tail(&c->_c.mfc_un.unres.unresolved, skb);
err = 0;
}
@@ -2043,11 +2053,12 @@ static int ip6mr_find_vif(struct mr_table *mrt, struct net_device *dev)
}
static void ip6_mr_forward(struct net *net, struct mr_table *mrt,
- struct sk_buff *skb, struct mfc6_cache *c)
+ struct net_device *dev, struct sk_buff *skb,
+ struct mfc6_cache *c)
{
int psend = -1;
int vif, ct;
- int true_vifi = ip6mr_find_vif(mrt, skb->dev);
+ int true_vifi = ip6mr_find_vif(mrt, dev);
vif = c->_c.mfc_parent;
c->_c.mfc_un.res.pkt++;
@@ -2073,7 +2084,7 @@ static void ip6_mr_forward(struct net *net, struct mr_table *mrt,
/*
* Wrong interface: drop packet and (maybe) send PIM assert.
*/
- if (mrt->vif_table[vif].dev != skb->dev) {
+ if (mrt->vif_table[vif].dev != dev) {
c->_c.mfc_un.res.wrong_if++;
if (true_vifi >= 0 && mrt->mroute_do_assert &&
@@ -2154,6 +2165,19 @@ int ip6_mr_input(struct sk_buff *skb)
.flowi6_mark = skb->mark,
};
int err;
+ struct net_device *dev;
+
+ /* skb->dev passed in is the master dev for vrfs.
+ * Get the proper interface that does have a vif associated with it.
+ */
+ dev = skb->dev;
+ if (netif_is_l3_master(skb->dev)) {
+ dev = dev_get_by_index_rcu(net, IPCB(skb)->iif);
+ if (!dev) {
+ kfree_skb(skb);
+ return -ENODEV;
+ }
+ }
err = ip6mr_fib_lookup(net, &fl6, &mrt);
if (err < 0) {
@@ -2165,7 +2189,7 @@ int ip6_mr_input(struct sk_buff *skb)
cache = ip6mr_cache_find(mrt,
&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr);
if (!cache) {
- int vif = ip6mr_find_vif(mrt, skb->dev);
+ int vif = ip6mr_find_vif(mrt, dev);
if (vif >= 0)
cache = ip6mr_cache_find_any(mrt,
@@ -2179,9 +2203,9 @@ int ip6_mr_input(struct sk_buff *skb)
if (!cache) {
int vif;
- vif = ip6mr_find_vif(mrt, skb->dev);
+ vif = ip6mr_find_vif(mrt, dev);
if (vif >= 0) {
- int err = ip6mr_cache_unresolved(mrt, vif, skb);
+ int err = ip6mr_cache_unresolved(mrt, vif, skb, dev);
read_unlock(&mrt_lock);
return err;
@@ -2191,7 +2215,7 @@ int ip6_mr_input(struct sk_buff *skb)
return -ENODEV;
}
- ip6_mr_forward(net, mrt, skb, cache);
+ ip6_mr_forward(net, mrt, dev, skb, cache);
read_unlock(&mrt_lock);
@@ -2257,7 +2281,7 @@ int ip6mr_get_route(struct net *net, struct sk_buff *skb, struct rtmsg *rtm,
iph->saddr = rt->rt6i_src.addr;
iph->daddr = rt->rt6i_dst.addr;
- err = ip6mr_cache_unresolved(mrt, vif, skb2);
+ err = ip6mr_cache_unresolved(mrt, vif, skb2, dev);
read_unlock(&mrt_lock);
return err;
--
2.11.0
^ permalink raw reply related
* [PATCH net-next v2 00/10] vrf: allow simultaneous service instances in default and other VRFs
From: Mike Manning @ 2018-10-01 8:43 UTC (permalink / raw)
To: netdev
Services currently have to be VRF-aware if they are using an unbound
socket. One cannot have multiple service instances running in the
default and other VRFs for services that are not VRF-aware and listen
on an unbound socket. This is because there is no way of isolating
packets received in the default VRF from those arriving in other VRFs.
This series provides this isolation subject to the existing kernel
parameter net.ipv4.tcp_l3mdev_accept not being set, given that this is
documented as allowing a single service instance to work across all
VRF domains. The functionality applies to UDP & TCP services, for IPv4
and IPv6, in particular adding VRF table handling for IPv6 multicast.
Example of running ssh instances in default and blue VRF:
$ /usr/sbin/sshd -D
$ ip vrf exec vrf-blue /usr/sbin/sshd
$ ss -ta | egrep 'State|ssh'
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 0.0.0.0%vrf-blue:ssh 0.0.0.0:*
LISTEN 0 128 0.0.0.0:ssh 0.0.0.0:*
ESTAB 0 0 192.168.122.220:ssh 192.168.122.1:50282
LISTEN 0 128 [::]%vrf-blue:ssh [::]:*
LISTEN 0 128 [::]:ssh [::]:*
ESTAB 0 0 [3000::2]%vrf-blue:ssh [3000::9]:45896
ESTAB 0 0 [2000::2]:ssh [2000::9]:46398
v1:
- Address Paolo Abeni's comments (patch 4/5)
- Fix build when CONFIG_NET_L3_MASTER_DEV not defined (patch 1/5)
v2:
- Address David Aherns' comments (patches 4/5 and 5/5)
- Remove patches 3/5 and 5/5 from series for individual submissions
- Include a sysctl for raw sockets as recommended by David Ahern
- Expand series into 10 patches and provide improved descriptions
Dewi Morgan (1):
ipv6: do not drop vrf udp multicast packets
Duncan Eastoe (2):
net: fix raw socket lookup device bind matching with VRFs
net: IP[V6]_MULTICAST_IF constraint on unbound socket if VRFs present
Mike Manning (6):
net: ensure unbound stream socket to be chosen when not in a VRF
net: ensure unbound datagram socket to be chosen when not in a VRF
net: provide a sysctl raw_l3mdev_accept for raw socket lookup with
VRFs
vrf: mark skb for multicast or link-local as enslaved to VRF
ipv6: allow ping to link-local address in VRF
ipv6: handling of multicast packets received in VRF
Robert Shearman (1):
net: allow binding socket in a VRF when there's an unbound socket
Documentation/networking/ip-sysctl.txt | 9 +++++++++
Documentation/networking/vrf.txt | 17 ++++++++++-------
drivers/net/vrf.c | 19 +++++++++---------
include/net/inet6_hashtables.h | 5 ++---
include/net/inet_hashtables.h | 24 ++++++++++++++++-------
include/net/inet_sock.h | 21 ++++++++++++++++++++
include/net/netns/ipv4.h | 3 +++
include/net/raw.h | 12 ++++++++++++
include/net/udp.h | 11 +++++++++++
net/core/sock.c | 2 ++
net/ipv4/inet_connection_sock.c | 13 ++++++++++---
net/ipv4/inet_hashtables.c | 34 ++++++++++++++++++++-------------
net/ipv4/ip_sockglue.c | 3 +++
net/ipv4/raw.c | 4 ++--
net/ipv4/sysctl_net_ipv4.c | 11 +++++++++++
net/ipv4/udp.c | 15 ++++++---------
net/ipv6/datagram.c | 5 ++++-
net/ipv6/inet6_hashtables.c | 14 ++++++--------
net/ipv6/ip6_input.c | 35 +++++++++++++++++++++++++++++++---
net/ipv6/ipv6_sockglue.c | 5 ++++-
net/ipv6/raw.c | 6 +++---
net/ipv6/udp.c | 22 ++++++++++-----------
22 files changed, 208 insertions(+), 82 deletions(-)
--
2.11.0
^ permalink raw reply
* [PATCH net-next v2 01/10] net: allow binding socket in a VRF when there's an unbound socket
From: Mike Manning @ 2018-10-01 8:43 UTC (permalink / raw)
To: netdev; +Cc: Robert Shearman
In-Reply-To: <20181001084320.32453-1-mmanning@vyatta.att-mail.com>
From: Robert Shearman <rshearma@vyatta.att-mail.com>
There is no easy way currently for applications that want to receive
packets in the default VRF to be isolated from packets arriving in
VRFs, which makes using VRF-unaware applications in a VRF-aware system
a potential security risk.
So change the inet socket lookup to avoid packets arriving on a device
enslaved to an l3mdev from matching unbound sockets by removing the
wildcard for non sk_bound_dev_if and instead relying on check against
the secondary device index, which will be 0 when the input device is
not enslaved to an l3mdev and so match against an unbound socket and
not match when the input device is enslaved.
Change the socket binding to take the l3mdev into account to allow an
unbound socket to not conflict sockets bound to an l3mdev given the
datapath isolation now guaranteed.
Signed-off-by: Robert Shearman <rshearma@vyatta.att-mail.com>
Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
---
Documentation/networking/vrf.txt | 9 +++++----
include/net/inet6_hashtables.h | 5 ++---
include/net/inet_hashtables.h | 13 ++++++-------
include/net/inet_sock.h | 13 +++++++++++++
net/ipv4/inet_connection_sock.c | 13 ++++++++++---
net/ipv4/inet_hashtables.c | 20 +++++++++++++++-----
6 files changed, 51 insertions(+), 22 deletions(-)
diff --git a/Documentation/networking/vrf.txt b/Documentation/networking/vrf.txt
index 8ff7b4c8f91b..d4b129402d57 100644
--- a/Documentation/networking/vrf.txt
+++ b/Documentation/networking/vrf.txt
@@ -103,6 +103,11 @@ VRF device:
or to specify the output device using cmsg and IP_PKTINFO.
+By default the scope of the port bindings for unbound sockets is
+limited to the default VRF. That is, it will not be matched by packets
+arriving on interfaces enslaved to an l3mdev and processes may bind to
+the same port if they bind to an l3mdev.
+
TCP & UDP services running in the default VRF context (ie., not bound
to any VRF device) can work across all VRF domains by enabling the
tcp_l3mdev_accept and udp_l3mdev_accept sysctl options:
@@ -112,10 +117,6 @@ tcp_l3mdev_accept and udp_l3mdev_accept sysctl options:
netfilter rules on the VRF device can be used to limit access to services
running in the default VRF context as well.
-The default VRF does not have limited scope with respect to port bindings.
-That is, if a process does a wildcard bind to a port in the default VRF it
-owns the port across all VRF domains within the network namespace.
-
################################################################################
Using iproute2 for VRFs
diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h
index 6e91e38a31da..9db98af46985 100644
--- a/include/net/inet6_hashtables.h
+++ b/include/net/inet6_hashtables.h
@@ -115,9 +115,8 @@ int inet6_hash(struct sock *sk);
((__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 == (__sdif))) && \
+ (((__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/inet_hashtables.h b/include/net/inet_hashtables.h
index 9141e95529e7..4ae060b4bac2 100644
--- a/include/net/inet_hashtables.h
+++ b/include/net/inet_hashtables.h
@@ -79,6 +79,7 @@ struct inet_ehash_bucket {
struct inet_bind_bucket {
possible_net_t ib_net;
+ int l3mdev;
unsigned short port;
signed char fastreuse;
signed char fastreuseport;
@@ -191,7 +192,7 @@ static inline void inet_ehash_locks_free(struct inet_hashinfo *hashinfo)
struct inet_bind_bucket *
inet_bind_bucket_create(struct kmem_cache *cachep, struct net *net,
struct inet_bind_hashbucket *head,
- const unsigned short snum);
+ const unsigned short snum, int l3mdev);
void inet_bind_bucket_destroy(struct kmem_cache *cachep,
struct inet_bind_bucket *tb);
@@ -282,9 +283,8 @@ static inline struct sock *inet_lookup_listener(struct net *net,
#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 == (__sdif))) && \
+ (((__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) \
@@ -294,9 +294,8 @@ static inline struct sock *inet_lookup_listener(struct net *net,
(((__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 == (__sdif))) && \
+ (((__sk)->sk_bound_dev_if == (__dif)) || \
+ ((__sk)->sk_bound_dev_if == (__sdif))) && \
net_eq(sock_net(__sk), (__net)))
#endif /* 64-bit arch */
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
index e03b93360f33..92e0aa3958f6 100644
--- a/include/net/inet_sock.h
+++ b/include/net/inet_sock.h
@@ -130,6 +130,19 @@ static inline int inet_request_bound_dev_if(const struct sock *sk,
return sk->sk_bound_dev_if;
}
+static inline int inet_sk_bound_l3mdev(const struct sock *sk)
+{
+#ifdef CONFIG_NET_L3_MASTER_DEV
+ struct net *net = sock_net(sk);
+
+ if (!net->ipv4.sysctl_tcp_l3mdev_accept)
+ return l3mdev_master_ifindex_by_index(net,
+ sk->sk_bound_dev_if);
+#endif
+
+ return 0;
+}
+
static inline struct ip_options_rcu *ireq_opt_deref(const struct inet_request_sock *ireq)
{
return rcu_dereference_check(ireq->ireq_opt,
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index dfd5009f96ef..97bba5b3d69f 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -183,7 +183,9 @@ inet_csk_find_open_port(struct sock *sk, struct inet_bind_bucket **tb_ret, int *
int i, low, high, attempt_half;
struct inet_bind_bucket *tb;
u32 remaining, offset;
+ int l3mdev;
+ l3mdev = inet_sk_bound_l3mdev(sk);
attempt_half = (sk->sk_reuse == SK_CAN_REUSE) ? 1 : 0;
other_half_scan:
inet_get_local_port_range(net, &low, &high);
@@ -219,7 +221,8 @@ inet_csk_find_open_port(struct sock *sk, struct inet_bind_bucket **tb_ret, int *
hinfo->bhash_size)];
spin_lock_bh(&head->lock);
inet_bind_bucket_for_each(tb, &head->chain)
- if (net_eq(ib_net(tb), net) && tb->port == port) {
+ if (net_eq(ib_net(tb), net) && tb->l3mdev == l3mdev &&
+ tb->port == port) {
if (!inet_csk_bind_conflict(sk, tb, false, false))
goto success;
goto next_port;
@@ -293,6 +296,9 @@ int inet_csk_get_port(struct sock *sk, unsigned short snum)
struct net *net = sock_net(sk);
struct inet_bind_bucket *tb = NULL;
kuid_t uid = sock_i_uid(sk);
+ int l3mdev;
+
+ l3mdev = inet_sk_bound_l3mdev(sk);
if (!port) {
head = inet_csk_find_open_port(sk, &tb, &port);
@@ -306,11 +312,12 @@ int inet_csk_get_port(struct sock *sk, unsigned short snum)
hinfo->bhash_size)];
spin_lock_bh(&head->lock);
inet_bind_bucket_for_each(tb, &head->chain)
- if (net_eq(ib_net(tb), net) && tb->port == port)
+ if (net_eq(ib_net(tb), net) && tb->l3mdev == l3mdev &&
+ tb->port == port)
goto tb_found;
tb_not_found:
tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep,
- net, head, port);
+ net, head, port, l3mdev);
if (!tb)
goto fail_unlock;
tb_found:
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index f5c9ef2586de..260531dc6458 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -65,12 +65,14 @@ static u32 sk_ehashfn(const struct sock *sk)
struct inet_bind_bucket *inet_bind_bucket_create(struct kmem_cache *cachep,
struct net *net,
struct inet_bind_hashbucket *head,
- const unsigned short snum)
+ const unsigned short snum,
+ int l3mdev)
{
struct inet_bind_bucket *tb = kmem_cache_alloc(cachep, GFP_ATOMIC);
if (tb) {
write_pnet(&tb->ib_net, net);
+ tb->l3mdev = l3mdev;
tb->port = snum;
tb->fastreuse = 0;
tb->fastreuseport = 0;
@@ -135,6 +137,7 @@ int __inet_inherit_port(const struct sock *sk, struct sock *child)
table->bhash_size);
struct inet_bind_hashbucket *head = &table->bhash[bhash];
struct inet_bind_bucket *tb;
+ int l3mdev;
spin_lock(&head->lock);
tb = inet_csk(sk)->icsk_bind_hash;
@@ -143,6 +146,8 @@ int __inet_inherit_port(const struct sock *sk, struct sock *child)
return -ENOENT;
}
if (tb->port != port) {
+ l3mdev = inet_sk_bound_l3mdev(sk);
+
/* NOTE: using tproxy and redirecting skbs to a proxy
* on a different listener port breaks the assumption
* that the listener socket's icsk_bind_hash is the same
@@ -150,12 +155,13 @@ int __inet_inherit_port(const struct sock *sk, struct sock *child)
* create a new bind bucket for the child here. */
inet_bind_bucket_for_each(tb, &head->chain) {
if (net_eq(ib_net(tb), sock_net(sk)) &&
- tb->port == port)
+ tb->l3mdev == l3mdev && tb->port == port)
break;
}
if (!tb) {
tb = inet_bind_bucket_create(table->bind_bucket_cachep,
- sock_net(sk), head, port);
+ sock_net(sk), head, port,
+ l3mdev);
if (!tb) {
spin_unlock(&head->lock);
return -ENOMEM;
@@ -675,6 +681,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
u32 remaining, offset;
int ret, i, low, high;
static u32 hint;
+ int l3mdev;
if (port) {
head = &hinfo->bhash[inet_bhashfn(net, port,
@@ -693,6 +700,8 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
return ret;
}
+ l3mdev = inet_sk_bound_l3mdev(sk);
+
inet_get_local_port_range(net, &low, &high);
high++; /* [32768, 60999] -> [32768, 61000[ */
remaining = high - low;
@@ -719,7 +728,8 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
* the established check is already unique enough.
*/
inet_bind_bucket_for_each(tb, &head->chain) {
- if (net_eq(ib_net(tb), net) && tb->port == port) {
+ if (net_eq(ib_net(tb), net) && tb->l3mdev == l3mdev &&
+ tb->port == port) {
if (tb->fastreuse >= 0 ||
tb->fastreuseport >= 0)
goto next_port;
@@ -732,7 +742,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
}
tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep,
- net, head, port);
+ net, head, port, l3mdev);
if (!tb) {
spin_unlock_bh(&head->lock);
return -ENOMEM;
--
2.11.0
^ permalink raw reply related
* [PATCH net-next v2 05/10] net: fix raw socket lookup device bind matching with VRFs
From: Mike Manning @ 2018-10-01 8:43 UTC (permalink / raw)
To: netdev; +Cc: Duncan Eastoe
In-Reply-To: <20181001084320.32453-1-mmanning@vyatta.att-mail.com>
From: Duncan Eastoe <deastoe@vyatta.att-mail.com>
When there exist a pair of raw sockets one unbound and one bound
to a VRF but equal in all other respects, when a packet is received
in the VRF context, __raw_v4_lookup() matches on both sockets.
This results in the packet being delivered over both sockets,
instead of only the raw socket bound to the VRF. The bound device
checks in __raw_v4_lookup() are replaced with a call to
raw_sk_bound_dev_eq() which correctly handles whether the packet
should be delivered over the unbound socket in such cases.
In __raw_v6_lookup() the match on the device binding of the socket is
similarly updated to use raw_sk_bound_dev_eq() which matches the
handling in __raw_v4_lookup().
Importantly raw_sk_bound_dev_eq() takes the raw_l3mdev_accept sysctl
into account.
Signed-off-by: Duncan Eastoe <deastoe@vyatta.att-mail.com>
Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
---
include/net/raw.h | 12 ++++++++++++
net/ipv4/raw.c | 4 ++--
net/ipv6/raw.c | 6 +++---
3 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/include/net/raw.h b/include/net/raw.h
index 9c9fa98a91a4..ce88fdd68933 100644
--- a/include/net/raw.h
+++ b/include/net/raw.h
@@ -18,6 +18,7 @@
#define _RAW_H
+#include <net/inet_sock.h>
#include <net/protocol.h>
#include <linux/icmp.h>
@@ -74,4 +75,15 @@ static inline struct raw_sock *raw_sk(const struct sock *sk)
return (struct raw_sock *)sk;
}
+static inline bool raw_sk_bound_dev_eq(struct net *net, int bound_dev_if,
+ int dif, int sdif)
+{
+#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV)
+ return inet_bound_dev_eq(net->ipv4.sysctl_raw_l3mdev_accept,
+ bound_dev_if, dif, sdif);
+#else
+ return inet_bound_dev_eq(1, bound_dev_if, dif, sdif);
+#endif
+}
+
#endif /* _RAW_H */
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 8ca3eb06ba04..6d8006c86dc0 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -70,6 +70,7 @@
#include <net/snmp.h>
#include <net/tcp_states.h>
#include <net/inet_common.h>
+#include <net/inet_hashtables.h>
#include <net/checksum.h>
#include <net/xfrm.h>
#include <linux/rtnetlink.h>
@@ -131,8 +132,7 @@ 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 != sdif))
+ raw_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif))
goto found; /* gotcha */
}
sk = NULL;
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 413d98bf24f4..5b363d315b06 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -49,6 +49,7 @@
#include <net/transp_v6.h>
#include <net/udp.h>
#include <net/inet_common.h>
+#include <net/inet_hashtables.h>
#include <net/tcp_states.h>
#if IS_ENABLED(CONFIG_IPV6_MIP6)
#include <net/mip6.h>
@@ -86,9 +87,8 @@ 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 &&
- sk->sk_bound_dev_if != sdif)
+ if (!raw_sk_bound_dev_eq(net, sk->sk_bound_dev_if,
+ dif, sdif))
continue;
if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr)) {
--
2.11.0
^ permalink raw reply related
* [PATCH net-next v2 03/10] net: ensure unbound datagram socket to be chosen when not in a VRF
From: Mike Manning @ 2018-10-01 8:43 UTC (permalink / raw)
To: netdev
In-Reply-To: <20181001084320.32453-1-mmanning@vyatta.att-mail.com>
Ensure an unbound datagram skt is chosen when not in a VRF. The check
for a device match in compute_score() for UDP must be performed when
there is no device match. For this, a failure is returned when there is
no device match. This ensures that bound sockets are never selected,
even if there is no unbound socket.
Allow IPv6 packets to be sent over a datagram skt bound to a VRF. These
packets are currently blocked, as flowi6_oif was set to that of the
master vrf device, and the ipi6_ifindex is that of the slave device.
Allow these packets to be sent by checking the device with ipi6_ifindex
has the same L3 scope as that of the bound device of the skt, which is
the master vrf device. Note that this check always succeeds if the skt
is unbound.
Even though the right datagram skt is now selected by compute_score(),
a different skt is being returned that is bound to the wrong vrf. The
difference between these and stream sockets is the handling of the skt
option for SO_REUSEPORT. While the handling when adding a skt for reuse
correctly checks that the bound device of the skt is a match, the skts
in the hashslot are already incorrect. So for the same hash, a skt for
the wrong vrf may be selected for the required port. The root cause is
that the skt is immediately placed into a slot when it is created,
but when the skt is then bound using SO_BINDTODEVICE, it remains in the
same slot. The solution is to move the skt to the correct slot by
forcing a rehash.
Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
---
include/net/udp.h | 11 +++++++++++
net/core/sock.c | 2 ++
net/ipv4/udp.c | 15 ++++++---------
net/ipv6/datagram.c | 5 ++++-
net/ipv6/udp.c | 14 +++++---------
5 files changed, 28 insertions(+), 19 deletions(-)
diff --git a/include/net/udp.h b/include/net/udp.h
index 8482a990b0bb..1e4fb8feaf50 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -252,6 +252,17 @@ static inline int udp_rqueue_get(struct sock *sk)
return sk_rmem_alloc_get(sk) - READ_ONCE(udp_sk(sk)->forward_deficit);
}
+static inline bool udp_sk_bound_dev_eq(struct net *net, int bound_dev_if,
+ int dif, int sdif)
+{
+#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV)
+ return inet_bound_dev_eq(net->ipv4.sysctl_udp_l3mdev_accept,
+ bound_dev_if, dif, sdif);
+#else
+ return inet_bound_dev_eq(1, bound_dev_if, dif, sdif);
+#endif
+}
+
/* net/ipv4/udp.c */
void udp_destruct_sock(struct sock *sk);
void skb_consume_udp(struct sock *sk, struct sk_buff *skb, int len);
diff --git a/net/core/sock.c b/net/core/sock.c
index 3730eb855095..da1cbb88a6bf 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -567,6 +567,8 @@ static int sock_setbindtodevice(struct sock *sk, char __user *optval,
lock_sock(sk);
sk->sk_bound_dev_if = index;
+ if (sk->sk_prot->rehash)
+ sk->sk_prot->rehash(sk);
sk_dst_reset(sk);
release_sock(sk);
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 3386b3b0218c..0559a7f4c83a 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -371,6 +371,7 @@ static int compute_score(struct sock *sk, struct net *net,
{
int score;
struct inet_sock *inet;
+ bool dev_match;
if (!net_eq(sock_net(sk), net) ||
udp_sk(sk)->udp_port_hash != hnum ||
@@ -398,15 +399,11 @@ static int compute_score(struct sock *sk, struct net *net,
score += 4;
}
- if (sk->sk_bound_dev_if || exact_dif) {
- bool dev_match = (sk->sk_bound_dev_if == dif ||
- sk->sk_bound_dev_if == sdif);
-
- if (!dev_match)
- return -1;
- if (sk->sk_bound_dev_if)
- score += 4;
- }
+ dev_match = udp_sk_bound_dev_eq(net, sk->sk_bound_dev_if,
+ dif, sdif);
+ if (!dev_match)
+ return -1;
+ score += 4;
if (sk->sk_incoming_cpu == raw_smp_processor_id())
score++;
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 1ede7a16a0be..4813293d4fad 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -782,7 +782,10 @@ int ip6_datagram_send_ctl(struct net *net, struct sock *sk,
if (src_info->ipi6_ifindex) {
if (fl6->flowi6_oif &&
- src_info->ipi6_ifindex != fl6->flowi6_oif)
+ src_info->ipi6_ifindex != fl6->flowi6_oif &&
+ (sk->sk_bound_dev_if != fl6->flowi6_oif ||
+ !sk_dev_equal_l3scope(
+ sk, src_info->ipi6_ifindex)))
return -EINVAL;
fl6->flowi6_oif = src_info->ipi6_ifindex;
}
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 83f4c77c79d8..6722490c87b9 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -117,6 +117,7 @@ static int compute_score(struct sock *sk, struct net *net,
{
int score;
struct inet_sock *inet;
+ bool dev_match;
if (!net_eq(sock_net(sk), net) ||
udp_sk(sk)->udp_port_hash != hnum ||
@@ -144,15 +145,10 @@ static int compute_score(struct sock *sk, struct net *net,
score++;
}
- if (sk->sk_bound_dev_if || exact_dif) {
- bool dev_match = (sk->sk_bound_dev_if == dif ||
- sk->sk_bound_dev_if == sdif);
-
- if (!dev_match)
- return -1;
- if (sk->sk_bound_dev_if)
- score++;
- }
+ dev_match = udp_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif);
+ if (!dev_match)
+ return -1;
+ score++;
if (sk->sk_incoming_cpu == raw_smp_processor_id())
score++;
--
2.11.0
^ permalink raw reply related
* [PATCH net-next v2 06/10] net: IP[V6]_MULTICAST_IF constraint on unbound socket if VRFs present
From: Mike Manning @ 2018-10-01 8:43 UTC (permalink / raw)
To: netdev; +Cc: Duncan Eastoe
In-Reply-To: <20181001084320.32453-1-mmanning@vyatta.att-mail.com>
From: Duncan Eastoe <deastoe@vyatta.att-mail.com>
If setsockopt(IP_MULTICAST_IF) or setsockopt(IPV6_MULTICAST_IF) is
called on a socket which is not bound to a VRF then we should ensure
that the output device chosen is also not bound to a VRF master.
This avoids inadvertently sending traffic out of the wrong interface.
This can be particularly problematic for IP_MULTICAST_IF since the
interface lookup can be performed by address as well as ifindex. If
there are interfaces with the same address, one unbound and one bound
to a VRF, then the interface bound to the VRF may be chosen when the
sockopt is called on an unbound socket.
Signed-off-by: Duncan Eastoe <deastoe@vyatta.att-mail.com>
Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
---
net/ipv4/ip_sockglue.c | 3 +++
net/ipv6/ipv6_sockglue.c | 3 +++
2 files changed, 6 insertions(+)
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index c0fe5ad996f2..026971314c43 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -892,6 +892,9 @@ static int do_ip_setsockopt(struct sock *sk, int level,
dev_put(dev);
err = -EINVAL;
+ if (!sk->sk_bound_dev_if && midx)
+ break;
+
if (sk->sk_bound_dev_if &&
mreq.imr_ifindex != sk->sk_bound_dev_if &&
(!midx || midx != sk->sk_bound_dev_if))
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index c0cac9cc3a28..7dfbc797b130 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -626,6 +626,9 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
rcu_read_unlock();
+ if (!sk->sk_bound_dev_if && midx)
+ goto e_inval;
+
if (sk->sk_bound_dev_if &&
sk->sk_bound_dev_if != val &&
(!midx || midx != sk->sk_bound_dev_if))
--
2.11.0
^ permalink raw reply related
* [PATCH net-next v2 02/10] net: ensure unbound stream socket to be chosen when not in a VRF
From: Mike Manning @ 2018-10-01 8:43 UTC (permalink / raw)
To: netdev
In-Reply-To: <20181001084320.32453-1-mmanning@vyatta.att-mail.com>
The commit a04a480d4392 ("net: Require exact match for TCP socket
lookups if dif is l3mdev") only ensures that the correct socket is
selected for packets in a VRF. However, there is no guarantee that
the unbound socket will be selected for packets when not in a VRF.
By checking for a device match in compute_score() also for the case
when there is no bound device and attaching a score to this, the
unbound socket is selected. And if a failure is returned when there
is no device match, this ensures that bound sockets are never selected,
even if there is no unbound socket.
Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
---
include/net/inet_hashtables.h | 11 +++++++++++
include/net/inet_sock.h | 8 ++++++++
net/ipv4/inet_hashtables.c | 14 ++++++--------
net/ipv6/inet6_hashtables.c | 14 ++++++--------
4 files changed, 31 insertions(+), 16 deletions(-)
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
index 4ae060b4bac2..5de2d9f24c05 100644
--- a/include/net/inet_hashtables.h
+++ b/include/net/inet_hashtables.h
@@ -189,6 +189,17 @@ static inline void inet_ehash_locks_free(struct inet_hashinfo *hashinfo)
hashinfo->ehash_locks = NULL;
}
+static inline bool inet_sk_bound_dev_eq(struct net *net, int bound_dev_if,
+ int dif, int sdif)
+{
+#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV)
+ return inet_bound_dev_eq(net->ipv4.sysctl_tcp_l3mdev_accept,
+ bound_dev_if, dif, sdif);
+#else
+ return inet_bound_dev_eq(1, bound_dev_if, dif, sdif);
+#endif
+}
+
struct inet_bind_bucket *
inet_bind_bucket_create(struct kmem_cache *cachep, struct net *net,
struct inet_bind_hashbucket *head,
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
index 92e0aa3958f6..47c03ea989ad 100644
--- a/include/net/inet_sock.h
+++ b/include/net/inet_sock.h
@@ -143,6 +143,14 @@ static inline int inet_sk_bound_l3mdev(const struct sock *sk)
return 0;
}
+static inline bool inet_bound_dev_eq(bool l3mdev_accept, int bound_dev_if,
+ int dif, int sdif)
+{
+ if (!bound_dev_if)
+ return !sdif || l3mdev_accept;
+ return bound_dev_if == dif || bound_dev_if == sdif;
+}
+
static inline struct ip_options_rcu *ireq_opt_deref(const struct inet_request_sock *ireq)
{
return rcu_dereference_check(ireq->ireq_opt,
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index 260531dc6458..2ec684057ebd 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -235,6 +235,7 @@ static inline int compute_score(struct sock *sk, struct net *net,
{
int score = -1;
struct inet_sock *inet = inet_sk(sk);
+ bool dev_match;
if (net_eq(sock_net(sk), net) && inet->inet_num == hnum &&
!ipv6_only_sock(sk)) {
@@ -245,15 +246,12 @@ static inline int compute_score(struct sock *sk, struct net *net,
return -1;
score += 4;
}
- if (sk->sk_bound_dev_if || exact_dif) {
- bool dev_match = (sk->sk_bound_dev_if == dif ||
- sk->sk_bound_dev_if == sdif);
+ dev_match = inet_sk_bound_dev_eq(net, sk->sk_bound_dev_if,
+ dif, sdif);
+ if (!dev_match)
+ return -1;
+ score += 4;
- if (!dev_match)
- return -1;
- if (sk->sk_bound_dev_if)
- score += 4;
- }
if (sk->sk_incoming_cpu == raw_smp_processor_id())
score++;
}
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index 3d7c7460a0c5..5eeeba7181a1 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -99,6 +99,7 @@ static inline int compute_score(struct sock *sk, struct net *net,
const int dif, const int sdif, bool exact_dif)
{
int score = -1;
+ bool dev_match;
if (net_eq(sock_net(sk), net) && inet_sk(sk)->inet_num == hnum &&
sk->sk_family == PF_INET6) {
@@ -109,15 +110,12 @@ static inline int compute_score(struct sock *sk, struct net *net,
return -1;
score++;
}
- if (sk->sk_bound_dev_if || exact_dif) {
- bool dev_match = (sk->sk_bound_dev_if == dif ||
- sk->sk_bound_dev_if == sdif);
+ dev_match = inet_sk_bound_dev_eq(net, sk->sk_bound_dev_if,
+ dif, sdif);
+ if (!dev_match)
+ return -1;
+ score++;
- if (!dev_match)
- return -1;
- if (sk->sk_bound_dev_if)
- score++;
- }
if (sk->sk_incoming_cpu == raw_smp_processor_id())
score++;
}
--
2.11.0
^ permalink raw reply related
* [PATCH net-next v2 07/10] vrf: mark skb for multicast or link-local as enslaved to VRF
From: Mike Manning @ 2018-10-01 8:43 UTC (permalink / raw)
To: netdev
In-Reply-To: <20181001084320.32453-1-mmanning@vyatta.att-mail.com>
The skb for packets that are multicast or to a link-local address are
not marked as being enslaved to a VRF, if they are received on a socket
bound to the VRF. This is needed for ND and it is preferable for the
kernel not to have to deal with the additional use-cases if ll or mcast
packets are handled as enslaved. However, this does not allow service
instances listening on unbound and bound to VRF sockets to distinguish
the VRF used, if packets are sent as multicast or to a link-local
address. The fix is for the VRF driver to also mark these skb as being
enslaved to the VRF.
Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
---
drivers/net/vrf.c | 19 +++++++++----------
1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
index 69b7227c637e..21ad4b1d7f03 100644
--- a/drivers/net/vrf.c
+++ b/drivers/net/vrf.c
@@ -981,24 +981,23 @@ static struct sk_buff *vrf_ip6_rcv(struct net_device *vrf_dev,
struct sk_buff *skb)
{
int orig_iif = skb->skb_iif;
- bool need_strict;
+ bool need_strict = rt6_need_strict(&ipv6_hdr(skb)->daddr);
+ bool is_ndisc = ipv6_ndisc_frame(skb);
- /* loopback traffic; do not push through packet taps again.
- * Reset pkt_type for upper layers to process skb
+ /* loopback, multicast & non-ND link-local traffic; do not push through
+ * packet taps again. Reset pkt_type for upper layers to process skb
*/
- if (skb->pkt_type == PACKET_LOOPBACK) {
+ if (skb->pkt_type == PACKET_LOOPBACK || (need_strict && !is_ndisc)) {
skb->dev = vrf_dev;
skb->skb_iif = vrf_dev->ifindex;
IP6CB(skb)->flags |= IP6SKB_L3SLAVE;
- skb->pkt_type = PACKET_HOST;
+ if (skb->pkt_type == PACKET_LOOPBACK)
+ skb->pkt_type = PACKET_HOST;
goto out;
}
- /* if packet is NDISC or addressed to multicast or link-local
- * then keep the ingress interface
- */
- need_strict = rt6_need_strict(&ipv6_hdr(skb)->daddr);
- if (!ipv6_ndisc_frame(skb) && !need_strict) {
+ /* if packet is NDISC then keep the ingress interface */
+ if (!is_ndisc) {
vrf_rx_stats(vrf_dev, skb->len);
skb->dev = vrf_dev;
skb->skb_iif = vrf_dev->ifindex;
--
2.11.0
^ permalink raw reply related
* [PATCH net-next v2 04/10] net: provide a sysctl raw_l3mdev_accept for raw socket lookup with VRFs
From: Mike Manning @ 2018-10-01 8:43 UTC (permalink / raw)
To: netdev
In-Reply-To: <20181001084320.32453-1-mmanning@vyatta.att-mail.com>
Add a sysctl raw_l3mdev_accept to control raw socket lookup in a manner
similar to use of tcp_l3mdev_accept for stream and of udp_l3mdev_accept
for datagram sockets. Have this default to off as this is what users
expect, given that there is no explicit mechanism to set unmodified
VRF-unaware application into a default VRF.
Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
---
Documentation/networking/ip-sysctl.txt | 9 +++++++++
Documentation/networking/vrf.txt | 8 +++++---
include/net/netns/ipv4.h | 3 +++
net/ipv4/sysctl_net_ipv4.c | 11 +++++++++++
4 files changed, 28 insertions(+), 3 deletions(-)
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index 8313a636dd53..a46be4a5b7a0 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -788,6 +788,15 @@ udp_wmem_min - INTEGER
total pages of UDP sockets exceed udp_mem pressure. The unit is byte.
Default: 4K
+RAW variables:
+
+raw_l3mdev_accept - BOOLEAN
+ Enabling this option allows a "global" bound socket to work
+ across L3 master domains (e.g., VRFs) with packets capable of
+ being received regardless of the L3 domain in which they
+ originated. Only valid when the kernel was compiled with
+ CONFIG_NET_L3_MASTER_DEV.
+
CIPSOv4 Variables:
cipso_cache_enable - BOOLEAN
diff --git a/Documentation/networking/vrf.txt b/Documentation/networking/vrf.txt
index d4b129402d57..deb798342f1e 100644
--- a/Documentation/networking/vrf.txt
+++ b/Documentation/networking/vrf.txt
@@ -108,11 +108,13 @@ limited to the default VRF. That is, it will not be matched by packets
arriving on interfaces enslaved to an l3mdev and processes may bind to
the same port if they bind to an l3mdev.
-TCP & UDP services running in the default VRF context (ie., not bound
-to any VRF device) can work across all VRF domains by enabling the
-tcp_l3mdev_accept and udp_l3mdev_accept sysctl options:
+TCP & UDP services & services using RAW sockets that are running in the
+default VRF context (ie., not bound to any VRF device) can work across
+all VRF domains by enabling the tcp_l3mdev_accept, udp_l3mdev_accept and
+raw_l3mdev_accept sysctl options:
sysctl -w net.ipv4.tcp_l3mdev_accept=1
sysctl -w net.ipv4.udp_l3mdev_accept=1
+ sysctl -w net.ipv4.raw_l3mdev_accept=1
netfilter rules on the VRF device can be used to limit access to services
running in the default VRF context as well.
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
index e47503b4e4d1..104a6669e344 100644
--- a/include/net/netns/ipv4.h
+++ b/include/net/netns/ipv4.h
@@ -103,6 +103,9 @@ struct netns_ipv4 {
/* Shall we try to damage output packets if routing dev changes? */
int sysctl_ip_dynaddr;
int sysctl_ip_early_demux;
+#ifdef CONFIG_NET_L3_MASTER_DEV
+ int sysctl_raw_l3mdev_accept;
+#endif
int sysctl_tcp_early_demux;
int sysctl_udp_early_demux;
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index b92f422f2fa8..d173337040ee 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -601,6 +601,17 @@ static struct ctl_table ipv4_net_table[] = {
.mode = 0644,
.proc_handler = ipv4_ping_group_range,
},
+#ifdef CONFIG_NET_L3_MASTER_DEV
+ {
+ .procname = "raw_l3mdev_accept",
+ .data = &init_net.ipv4.sysctl_raw_l3mdev_accept,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = &zero,
+ .extra2 = &one,
+ },
+#endif
{
.procname = "tcp_ecn",
.data = &init_net.ipv4.sysctl_tcp_ecn,
--
2.11.0
^ permalink raw reply related
* [PATCH net-next v2 09/10] ipv6: handling of multicast packets received in VRF
From: Mike Manning @ 2018-10-01 8:43 UTC (permalink / raw)
To: netdev; +Cc: Dewi Morgan
In-Reply-To: <20181001084320.32453-1-mmanning@vyatta.att-mail.com>
If the skb for multicast packets marked as enslaved to a VRF are
received, then the secondary device index should be used to obtain
the real device. And verify the multicast address against the
enslaved rather than the l3mdev device.
Signed-off-by: Dewi Morgan <morgand@vyatta.att-mail.com>
Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
---
net/ipv6/ip6_input.c | 35 ++++++++++++++++++++++++++++++++---
1 file changed, 32 insertions(+), 3 deletions(-)
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 96577e742afd..df58e1100226 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -359,6 +359,8 @@ static int ip6_input_finish(struct net *net, struct sock *sk, struct sk_buff *sk
}
} else if (ipprot->flags & INET6_PROTO_FINAL) {
const struct ipv6hdr *hdr;
+ int sdif = inet6_sdif(skb);
+ struct net_device *dev;
/* Only do this once for first final protocol */
have_final = true;
@@ -371,9 +373,19 @@ static int ip6_input_finish(struct net *net, struct sock *sk, struct sk_buff *sk
skb_postpull_rcsum(skb, skb_network_header(skb),
skb_network_header_len(skb));
hdr = ipv6_hdr(skb);
+
+ /* skb->dev passed may be master dev for vrfs. */
+ if (sdif) {
+ dev = dev_get_by_index_rcu(net, sdif);
+ if (!dev)
+ goto discard;
+ } else {
+ dev = skb->dev;
+ }
+
if (ipv6_addr_is_multicast(&hdr->daddr) &&
- !ipv6_chk_mcast_addr(skb->dev, &hdr->daddr,
- &hdr->saddr) &&
+ !ipv6_chk_mcast_addr(dev, &hdr->daddr,
+ &hdr->saddr) &&
!ipv6_is_mld(skb, nexthdr, skb_network_header_len(skb)))
goto discard;
}
@@ -432,15 +444,32 @@ EXPORT_SYMBOL_GPL(ip6_input);
int ip6_mc_input(struct sk_buff *skb)
{
+ int sdif = inet6_sdif(skb);
const struct ipv6hdr *hdr;
+ struct net_device *dev;
bool deliver;
__IP6_UPD_PO_STATS(dev_net(skb_dst(skb)->dev),
__in6_dev_get_safely(skb->dev), IPSTATS_MIB_INMCAST,
skb->len);
+ /* skb->dev passed may be master dev for vrfs. */
+ if (sdif) {
+ rcu_read_lock();
+ dev = dev_get_by_index_rcu(dev_net(skb->dev), sdif);
+ if (!dev) {
+ rcu_read_unlock();
+ kfree_skb(skb);
+ return -ENODEV;
+ }
+ } else {
+ dev = skb->dev;
+ }
+
hdr = ipv6_hdr(skb);
- deliver = ipv6_chk_mcast_addr(skb->dev, &hdr->daddr, NULL);
+ deliver = ipv6_chk_mcast_addr(dev, &hdr->daddr, NULL);
+ if (sdif)
+ rcu_read_unlock();
#ifdef CONFIG_IPV6_MROUTE
/*
--
2.11.0
^ permalink raw reply related
* [PATCH net-next v2 08/10] ipv6: allow ping to link-local address in VRF
From: Mike Manning @ 2018-10-01 8:43 UTC (permalink / raw)
To: netdev
In-Reply-To: <20181001084320.32453-1-mmanning@vyatta.att-mail.com>
If link-local packets are marked as enslaved to a VRF, then to allow
ping to the link-local from a vrf, the error handling for IPV6_PKTINFO
needs to be relaxed to also allow the pkt ipi6_ifindex to be that of a
slave device to the vrf.
Note that the real device also needs to be retrieved in icmp6_iif()
to set the ipv6 flow oif to this for icmp echo reply handling. The
recent commit 24b711edfc34 ("net/ipv6: Fix linklocal to global address
with VRF") takes care of this, so the sdif does not need checking here.
This fix makes ping to link-local consistent with that to global
addresses, in that this can now be done from within the same VRF that
the address is in.
Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
---
net/ipv6/ipv6_sockglue.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 7dfbc797b130..4ebd395dd3df 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -486,7 +486,7 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
retv = -EFAULT;
break;
}
- if (sk->sk_bound_dev_if && pkt.ipi6_ifindex != sk->sk_bound_dev_if)
+ if (!sk_dev_equal_l3scope(sk, pkt.ipi6_ifindex))
goto e_inval;
np->sticky_pktinfo.ipi6_ifindex = pkt.ipi6_ifindex;
--
2.11.0
^ permalink raw reply related
* [PATCH net-next v2 10/10] ipv6: do not drop vrf udp multicast packets
From: Mike Manning @ 2018-10-01 8:43 UTC (permalink / raw)
To: netdev; +Cc: Dewi Morgan
In-Reply-To: <20181001084320.32453-1-mmanning@vyatta.att-mail.com>
From: Dewi Morgan <morgand@vyatta.att-mail.com>
For bound udp sockets in a vrf, also check the sdif to get the index
for ingress devices enslaved to an l3mdev.
Signed-off-by: Dewi Morgan <morgand@vyatta.att-mail.com>
Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
---
net/ipv6/udp.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 6722490c87b9..821fdc31dbc0 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -637,7 +637,7 @@ static int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
static bool __udp_v6_is_mcast_sock(struct net *net, struct sock *sk,
__be16 loc_port, const struct in6_addr *loc_addr,
__be16 rmt_port, const struct in6_addr *rmt_addr,
- int dif, unsigned short hnum)
+ int dif, int sdif, unsigned short hnum)
{
struct inet_sock *inet = inet_sk(sk);
@@ -649,7 +649,7 @@ static bool __udp_v6_is_mcast_sock(struct net *net, struct sock *sk,
(inet->inet_dport && inet->inet_dport != rmt_port) ||
(!ipv6_addr_any(&sk->sk_v6_daddr) &&
!ipv6_addr_equal(&sk->sk_v6_daddr, rmt_addr)) ||
- (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif) ||
+ !udp_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif) ||
(!ipv6_addr_any(&sk->sk_v6_rcv_saddr) &&
!ipv6_addr_equal(&sk->sk_v6_rcv_saddr, loc_addr)))
return false;
@@ -683,6 +683,7 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
unsigned int offset = offsetof(typeof(*sk), sk_node);
unsigned int hash2 = 0, hash2_any = 0, use_hash2 = (hslot->count > 10);
int dif = inet6_iif(skb);
+ int sdif = inet6_sdif(skb);
struct hlist_node *node;
struct sk_buff *nskb;
@@ -697,7 +698,8 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
sk_for_each_entry_offset_rcu(sk, node, &hslot->head, offset) {
if (!__udp_v6_is_mcast_sock(net, sk, uh->dest, daddr,
- uh->source, saddr, dif, hnum))
+ uh->source, saddr, dif, sdif,
+ hnum))
continue;
/* If zero checksum and no_check is not on for
* the socket then skip it.
--
2.11.0
^ permalink raw reply related
* Re: [PATCH net 2/5] net/smc: remove duplicate mutex_unlock
From: Ursula Braun @ 2018-10-01 15:22 UTC (permalink / raw)
To: Dan Carpenter, kbuild
Cc: kbuild-all, davem, netdev, linux-s390, schwidefsky,
heiko.carstens, raspl, linux-kernel
In-Reply-To: <20180920091243.xgansymg6a4dfixg@mwanda>
On 09/20/2018 11:12 AM, Dan Carpenter wrote:
> Hi Ursula,
>
> I love your patch! Perhaps something to improve:
>
> [auto build test WARNING on net/master]
>
> url: https://github.com/0day-ci/linux/commits/Ursula-Braun/net-smc-fixes-2018-09-18/20180919-080857
>
> smatch warnings:
> net/smc/af_smc.c:1289 smc_listen_work() warn: inconsistent returns 'mutex:&smc_create_lgr_pending'.
> Locked on: line 1285
> Unlocked on: line 1209
>
> # https://github.com/0day-ci/linux/commit/c69342ef9becfe90f3778db1c386abdd80b786d1
> git remote add linux-review https://github.com/0day-ci/linux
> git remote update linux-review
> git checkout c69342ef9becfe90f3778db1c386abdd80b786d1
> vim +1289 net/smc/af_smc.c
>
> 3b2dec260 Hans Wippel 2018-05-18 1231 /* IPSec connections opt out of SMC-R optimizations */
> 3b2dec260 Hans Wippel 2018-05-18 1232 if (using_ipsec(new_smc)) {
> 3b2dec260 Hans Wippel 2018-05-18 1233 smc_listen_decline(new_smc, SMC_CLC_DECL_IPSEC, 0);
> 3b2dec260 Hans Wippel 2018-05-18 1234 return;
> 3b2dec260 Hans Wippel 2018-05-18 1235 }
> 3b2dec260 Hans Wippel 2018-05-18 1236
> 3b2dec260 Hans Wippel 2018-05-18 1237 mutex_lock(&smc_create_lgr_pending);
> 3b2dec260 Hans Wippel 2018-05-18 1238 smc_close_init(new_smc);
> 3b2dec260 Hans Wippel 2018-05-18 1239 smc_rx_init(new_smc);
> 3b2dec260 Hans Wippel 2018-05-18 1240 smc_tx_init(new_smc);
> 3b2dec260 Hans Wippel 2018-05-18 1241
> 413498440 Hans Wippel 2018-06-28 1242 /* check if ISM is available */
> 413498440 Hans Wippel 2018-06-28 1243 if ((pclc->hdr.path == SMC_TYPE_D || pclc->hdr.path == SMC_TYPE_B) &&
> 413498440 Hans Wippel 2018-06-28 1244 !smc_check_ism(new_smc, &ismdev) &&
> 413498440 Hans Wippel 2018-06-28 1245 !smc_listen_ism_init(new_smc, pclc, ismdev, &local_contact)) {
> 413498440 Hans Wippel 2018-06-28 1246 ism_supported = true;
> 413498440 Hans Wippel 2018-06-28 1247 }
> 413498440 Hans Wippel 2018-06-28 1248
> 3b2dec260 Hans Wippel 2018-05-18 1249 /* check if RDMA is available */
> 413498440 Hans Wippel 2018-06-28 1250 if (!ism_supported &&
> 413498440 Hans Wippel 2018-06-28 1251 ((pclc->hdr.path != SMC_TYPE_R && pclc->hdr.path != SMC_TYPE_B) ||
> 7005ada68 Ursula Braun 2018-07-25 1252 smc_vlan_by_tcpsk(new_smc->clcsock, &vlan) ||
> 7005ada68 Ursula Braun 2018-07-25 1253 smc_check_rdma(new_smc, &ibdev, &ibport, vlan, NULL) ||
> 3b2dec260 Hans Wippel 2018-05-18 1254 smc_listen_rdma_check(new_smc, pclc) ||
> 3b2dec260 Hans Wippel 2018-05-18 1255 smc_listen_rdma_init(new_smc, pclc, ibdev, ibport,
> 3b2dec260 Hans Wippel 2018-05-18 1256 &local_contact) ||
> 413498440 Hans Wippel 2018-06-28 1257 smc_listen_rdma_reg(new_smc, local_contact))) {
> 3b2dec260 Hans Wippel 2018-05-18 1258 /* SMC not supported, decline */
> 145686baa Ursula Braun 2017-10-25 1259 mutex_unlock(&smc_create_lgr_pending);
> 603cc1498 Karsten Graul 2018-07-25 1260 smc_listen_decline(new_smc, SMC_CLC_DECL_MODEUNSUPP,
> 603cc1498 Karsten Graul 2018-07-25 1261 local_contact);
> 3b2dec260 Hans Wippel 2018-05-18 1262 return;
> a046d57da Ursula Braun 2017-01-09 1263 }
> a046d57da Ursula Braun 2017-01-09 1264
> 3b2dec260 Hans Wippel 2018-05-18 1265 /* send SMC Accept CLC message */
> 3b2dec260 Hans Wippel 2018-05-18 1266 rc = smc_clc_send_accept(new_smc, local_contact);
> 3b2dec260 Hans Wippel 2018-05-18 1267 if (rc) {
> 145686baa Ursula Braun 2017-10-25 1268 mutex_unlock(&smc_create_lgr_pending);
> 3b2dec260 Hans Wippel 2018-05-18 1269 smc_listen_decline(new_smc, rc, local_contact);
> 3b2dec260 Hans Wippel 2018-05-18 1270 return;
> 3b2dec260 Hans Wippel 2018-05-18 1271 }
> 3b2dec260 Hans Wippel 2018-05-18 1272
> 3b2dec260 Hans Wippel 2018-05-18 1273 /* receive SMC Confirm CLC message */
> 3b2dec260 Hans Wippel 2018-05-18 1274 reason_code = smc_clc_wait_msg(new_smc, &cclc, sizeof(cclc),
> 3b2dec260 Hans Wippel 2018-05-18 1275 SMC_CLC_CONFIRM);
> 3b2dec260 Hans Wippel 2018-05-18 1276 if (reason_code) {
> 3b2dec260 Hans Wippel 2018-05-18 1277 mutex_unlock(&smc_create_lgr_pending);
> 3b2dec260 Hans Wippel 2018-05-18 1278 smc_listen_decline(new_smc, reason_code, local_contact);
> 3b2dec260 Hans Wippel 2018-05-18 1279 return;
> 3b2dec260 Hans Wippel 2018-05-18 1280 }
> 3b2dec260 Hans Wippel 2018-05-18 1281
> 3b2dec260 Hans Wippel 2018-05-18 1282 /* finish worker */
> c69342ef9 Ursula Braun 2018-09-18 1283 if (!ism_supported) {
> c69342ef9 Ursula Braun 2018-09-18 1284 if (smc_listen_rdma_finish(new_smc, &cclc, local_contact))
> c69342ef9 Ursula Braun 2018-09-18 1285 return;
> ^^^^^^
> We need to mutex_unlock(&smc_create_lgr_pending); before the return.
>
The smatch warning is not necessary, since the mutex_unlock(&smc_create_lgr_pending)
for this case is done within smc_listen_rdma_finish().
> c69342ef9 Ursula Braun 2018-09-18 1286 }
> 3b2dec260 Hans Wippel 2018-05-18 1287 smc_conn_save_peer_info(new_smc, &cclc);
> 3b2dec260 Hans Wippel 2018-05-18 1288 mutex_unlock(&smc_create_lgr_pending);
> 3b2dec260 Hans Wippel 2018-05-18 @1289 smc_listen_out_connected(new_smc);
> a046d57da Ursula Braun 2017-01-09 1290 }
> a046d57da Ursula Braun 2017-01-09 1291
>
> ---
> 0-DAY kernel test infrastructure Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all Intel Corporation
>
But you could argue the code confuses smatch and other readers. Thus I could improve
readability with a patch like this:
---
net/smc/af_smc.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
--- a/net/smc/af_smc.c
+++ b/net/smc/af_smc.c
@@ -1184,7 +1184,6 @@ static int smc_listen_rdma_finish(struct
return 0;
decline:
- mutex_unlock(&smc_create_lgr_pending);
smc_listen_decline(new_smc, reason_code, local_contact);
return reason_code;
}
@@ -1284,8 +1283,10 @@ static void smc_listen_work(struct work_
/* finish worker */
if (!ism_supported) {
- if (smc_listen_rdma_finish(new_smc, &cclc, local_contact))
+ if (smc_listen_rdma_finish(new_smc, &cclc, local_contact)) {
+ mutex_unlock(&smc_create_lgr_pending);
return;
+ }
}
smc_conn_save_peer_info(new_smc, &cclc);
mutex_unlock(&smc_create_lgr_pending);
---
^ permalink raw reply
* Re: [PATCH net-next v1 1/5] net: allow binding socket in a VRF when there's an unbound socket
From: Mike Manning @ 2018-10-01 8:48 UTC (permalink / raw)
To: David Ahern, netdev; +Cc: Robert Shearman
In-Reply-To: <d00ca59b-1065-0f5e-f798-8551e1e01be2@gmail.com>
On 25/09/2018 18:16, David Ahern wrote:
> On 9/25/18 9:26 AM, Mike Manning wrote:
>> On 24/09/2018 23:44, David Ahern wrote:
>>> On 9/24/18 10:13 AM, Mike Manning wrote:
>>>> From: Robert Shearman <rshearma@vyatta.att-mail.com>
>>>>
>>>> There is no easy way currently for applications that want to receive
>>>> packets in the default VRF to be isolated from packets arriving in
>>>> VRFs, which makes using VRF-unaware applications in a VRF-aware system
>>>> a potential security risk.
>>> That comment is not correct.
>>>
>>> The point of the l3mdev sysctl's is to prohibit this case. Setting
>>> net.ipv4.{tcp,udp}_l3mdev_accept=0 means that a packet arriving on an
>>> interface enslaved to a VRF can not be received by a global socket.
>> Hi David, thanks for reviewing this. The converse does not hold though,
>> i.e. there is no guarantee that the unbound socket will be selected for
>> packets when not in a VRF, if there is an unbound socket and a socket
>> bound to a VRF. Also, such packets should not be handled by the socket
> I need an explicit example here. You are saying a packet arriving on an
> interface not enslaved to a VRF might match a socket bound to a VRF?
This problem occurs when different service instances are listening on an
unbound socket and sockets bound to VRFs respectively. Received packets
that are not in a VRF are not guaranteed to be handled by the unbound
socket.
>> in the VRF if there is no unbound socket. We also had an issue with raw
>> socket lookup device bind matching. I can break this particular patch
>> into smaller patches and provide more detail, would this help? I will
>> also update/break up the other patches according to your comments.
> Why not add an l3mdev sysctl for raw sockets then?
I have now added this, see patch 4/10.
> Yes, please send smaller patches. A diff stat of:
> 15 files changed, 109 insertions(+), 62 deletions(-)
> is a bit harsh.
I have removed the 2 patches you are ok with and have submitted them
separately , and have split the remaining 3 into 10 smaller patches.
>>> Setting the l3mdev to 1 allows the default socket to work across VRFs.
>>> If that is not what you want for a given app or a given VRF, then one
>>> option is to add netfilter rules on the VRF device to prohibit it. I
>>> just verified this works for both tcp and udp.
>> Netfilter is per application and so does not scale. I have not checked
>> if it is suitable for packet handling on raw sockets.
>>
>>> Further, overlapping binds are allowed using SO_REUSEPORT meaning I can
>>> have a server running in the default vrf bound to a port AND a server
>>> running bound to a specific vrf and the same port:
>>>
>>> udp UNCONN 0 0 *%red:12345 *:*
>>> users:(("vrf-test",pid=1376,fd=3))
>>> udp UNCONN 0 0 *:12345 *:*
>>> users:(("vrf-test",pid=1375,fd=3))
>>>
>>> tcp LISTEN 0 1 *%red:12345 *:*
>>> users:(("vrf-test",pid=1356,fd=3))
>>> tcp LISTEN 0 1 *:12345 *:*
>>> users:(("vrf-test",pid=1352,fd=3))
>>>
>>> For packets arriving on an interface enslaved to a VRF the socket lookup
>>> will pick the VRF server over the global one.
>> Agreed, but the converse is not guaranteed to hold i.e. packets that are
>> not in a VRF may be handled by a socket bound to a VRF.
>>
>> We do use SO_REUSEPORT for our own applications so as to run instances
>> in the default and other VRFs, but still require these patches (or
>> similar) due to how packets are handled when there is an unbound socket
>> and sockets bound to different VRFs.
> Why can't compute_score be adjusted to account for that case?
Yes, this is what we are doing. This is now in patch 2/10 for stream and
3/10 for datagram sockets, and see 5/10 for raw sockets.
>>> --
>>>
>>> With this patch set I am seeing a number of tests failing -- socket
>>> connections working when they should not or not working when they
>>> should. I only skimmed the results. I am guessing this patch is the
>>> reason, but that is just a guess.
>>>
>>> You need to make sure all permutations of:
>>> 1. net.ipv4.{tcp,udp}_l3mdev_accept={0,1},
>>> 2. connection in the default VRF and in a VRF,
>>> 3. locally originated and remote traffic,
>>> 4. ipv4 and ipv6
>>>
>> We are using raw, datagram and stream sockets for ipv4 & ipv6, require
>> connectivity for local and remote addresses where appropriate and need
>> route leaking between VRFs when configured, we are unaware of any
>> outstanding bugs. Is there some way that I can run/analyze the tests
>> that are failing for you?
> I am not distributing my vrf tests right now. Before sending the
> response I quickly verified one case is easy for you to see: set the udp
> sysctl to 0, start a global server, send a packet to it via an interface
> enslaved to a VRF. It should fail ECONNREFUSED (no socket match) but
> instead packet reaches the server.
I have tried with netcat & socat to check this, and while the
connectivity handling is correct, this does not show the failure error
(it doesn't without the changes either). Before I look further into
this, can I check whether you had only the udp sysctl set to 0 i.e. the
tcp sysctl to 1? The reason I ask is that in the original series, we
were using a common function inet_sk_bound_dev_eq() for
raw/stream/datagram sockets, and this fn was checking only the tcp
sysctl (as we always have the udp and tcp sysctl set to 0). In series
v2, I have provided separate fns which check the relevant raw, tcp or
udp sysctl.
>> Also cf patch 2/5 note that ping to link-local addresses is handled
>> consistently with that to global addresses in a VRF, so this now
>> succeeds if ping is done in the VRF, i.e. 'sudo ip vrf exec <vrf> ping
>> <ll> -I <intf>
> Shifting packets destined to a LLA from the real device to the vrf
> device is a change in behavior. It is not clear to me at the moment that
> it will not cause a problem.
I have provided a clearer description of why we have had to do this in
patch 7/10.
>>> continue to work as expected meaning packets flow when they should and
>>> fail with the right error when they should not. I believe the UDP cases
>>> were the main ones failing.
>>>
>>> Given the test failures, I did not look at the code changes in the patch.
>>>
> A couple of the patches are fine as is - or need a small change. It
> might be easier for you to send those outside of the socket lookup set.
Thank you for reviewing these.
^ permalink raw reply
* Re: [PATCH] ipw2x00: Remove unnecessary parentheses
From: Kalle Valo @ 2018-10-01 15:30 UTC (permalink / raw)
To: Nathan Chancellor
Cc: Stanislav Yakovlev, linux-wireless, netdev, linux-kernel,
Nathan Chancellor
In-Reply-To: <20180920204548.2405-1-natechancellor@gmail.com>
Nathan Chancellor <natechancellor@gmail.com> wrote:
> Clang warns when multiple pairs of parentheses are used for a single
> conditional statement.
>
> drivers/net/wireless/intel/ipw2x00/ipw2200.c:5655:28: warning: equality
> comparison with extraneous parentheses [-Wparentheses-equality]
> if ((priv->ieee->iw_mode == IW_MODE_ADHOC)) {
> ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~
> drivers/net/wireless/intel/ipw2x00/ipw2200.c:5655:28: note: remove
> extraneous parentheses around the comparison to silence this warning
> if ((priv->ieee->iw_mode == IW_MODE_ADHOC)) {
> ~ ^ ~
> drivers/net/wireless/intel/ipw2x00/ipw2200.c:5655:28: note: use '=' to
> turn this equality comparison into an assignment
> if ((priv->ieee->iw_mode == IW_MODE_ADHOC)) {
> ^~
> =
> 1 warning generated.
>
> Link: https://github.com/ClangBuiltLinux/linux/issues/134
> Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
Patch applied to wireless-drivers-next.git, thanks.
c15ace868dd1 ipw2x00: Remove unnecessary parentheses
--
https://patchwork.kernel.org/patch/10608735/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply
* Re: [PATCH] rsi: Remove unnecessary boolean condition
From: Kalle Valo @ 2018-10-01 15:32 UTC (permalink / raw)
To: Nathan Chancellor; +Cc: linux-wireless, netdev, linux-kernel, Nathan Chancellor
In-Reply-To: <20180921094828.16976-1-natechancellor@gmail.com>
Nathan Chancellor <natechancellor@gmail.com> wrote:
> Clang warns that the address of a pointer will always evaluated as true
> in a boolean context.
>
> drivers/net/wireless/rsi/rsi_91x_mac80211.c:927:50: warning: address of
> array 'key->key' will always evaluate to 'true'
> [-Wpointer-bool-conversion]
> if (vif->type == NL80211_IFTYPE_STATION && key->key &&
> ~~ ~~~~~^~~
> 1 warning generated.
>
> Link: https://github.com/ClangBuiltLinux/linux/issues/136
> Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
Patch applied to wireless-drivers-next.git, thanks.
f613e4803dd6 rsi: Remove unnecessary boolean condition
--
https://patchwork.kernel.org/patch/10609513/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply
* [PATCH net-next] bridge: mcast: Default back to multicast enabled state
From: Ido Schimmel @ 2018-10-01 8:57 UTC (permalink / raw)
To: netdev; +Cc: davem, nikolay, roopa, bridge, mlxsw, Ido Schimmel
Commit 13cefad2f2c1 ("net: bridge: convert and rename mcast disabled")
converted the 'multicast_disabled' field to an option bit named
'BROPT_MULTICAST_ENABLED'.
While the old field was implicitly initialized to 0, the new field is
not initialized, resulting in the bridge defaulting to multicast
disabled state and breaking existing applications.
Fix this by explicitly initializing the option.
Fixes: 13cefad2f2c1 ("net: bridge: convert and rename mcast disabled")
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
---
net/bridge/br_multicast.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index 928024d8360d..024139b51d3a 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -1976,6 +1976,7 @@ void br_multicast_init(struct net_bridge *br)
br->ip6_other_query.delay_time = 0;
br->ip6_querier.port = NULL;
#endif
+ br_opt_toggle(br, BROPT_MULTICAST_ENABLED, true);
br_opt_toggle(br, BROPT_HAS_IPV6_ADDR, true);
spin_lock_init(&br->multicast_lock);
--
2.17.1
^ permalink raw reply related
* pull request (net): ipsec 2018-10-01
From: Steffen Klassert @ 2018-10-01 8:58 UTC (permalink / raw)
To: David Miller; +Cc: Herbert Xu, Steffen Klassert, netdev
1) Validate address prefix lengths in the xfrm selector,
otherwise we may hit undefined behaviour in the
address matching functions if the prefix is too
big for the given address family.
2) Fix skb leak on local message size errors.
From Thadeu Lima de Souza Cascardo.
3) We currently reset the transport header back to the network
header after a transport mode transformation is applied. This
leads to an incorrect transport header when multiple transport
mode transformations are applied. Reset the transport header
only after all transformations are already applied to fix this.
From Sowmini Varadhan.
4) We only support one offloaded xfrm, so reset crypto_done after
the first transformation in xfrm_input(). Otherwise we may call
the wrong input method for subsequent transformations.
From Sowmini Varadhan.
5) Fix NULL pointer dereference when skb_dst_force clears the dst_entry.
skb_dst_force does not really force a dst refcount anymore, it might
clear it instead. xfrm code did not expect this, add a check to not
dereference skb_dst() if it was cleared by skb_dst_force.
6) Validate xfrm template mode, otherwise we can get a stack-out-of-bounds
read in xfrm_state_find. From Sean Tranchetti.
Please pull or let me know if there are problems.
Thanks!
The following changes since commit 25432eba9cd8f2ef5afef55be811b010a004b5fa:
openvswitch: meter: Fix setting meter id for new entries (2018-07-29 13:20:54 -0700)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec.git master
for you to fetch changes up to 32bf94fb5c2ec4ec842152d0e5937cd4bb6738fa:
xfrm: validate template mode (2018-09-20 08:30:42 +0200)
----------------------------------------------------------------
Sean Tranchetti (1):
xfrm: validate template mode
Sowmini Varadhan (2):
xfrm: reset transport header back to network header after all input transforms ahave been applied
xfrm: reset crypto_done when iterating over multiple input xfrms
Steffen Klassert (2):
xfrm: Validate address prefix lengths in the xfrm selector.
xfrm: Fix NULL pointer dereference when skb_dst_force clears the dst_entry.
Thadeu Lima de Souza Cascardo (1):
xfrm6: call kfree_skb when skb is toobig
net/ipv4/xfrm4_input.c | 1 +
net/ipv4/xfrm4_mode_transport.c | 4 +---
net/ipv6/xfrm6_input.c | 1 +
net/ipv6/xfrm6_mode_transport.c | 4 +---
net/ipv6/xfrm6_output.c | 2 ++
net/xfrm/xfrm_input.c | 1 +
net/xfrm/xfrm_output.c | 4 ++++
net/xfrm/xfrm_policy.c | 4 ++++
net/xfrm/xfrm_user.c | 15 +++++++++++++++
9 files changed, 30 insertions(+), 6 deletions(-)
^ permalink raw reply
* [PATCH 2/6] xfrm6: call kfree_skb when skb is toobig
From: Steffen Klassert @ 2018-10-01 8:58 UTC (permalink / raw)
To: David Miller; +Cc: Herbert Xu, Steffen Klassert, netdev
In-Reply-To: <20181001085855.12057-1-steffen.klassert@secunet.com>
From: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
After commit d6990976af7c5d8f55903bfb4289b6fb030bf754 ("vti6: fix PMTU caching
and reporting on xmit"), some too big skbs might be potentially passed down to
__xfrm6_output, causing it to fail to transmit but not free the skb, causing a
leak of skb, and consequentially a leak of dst references.
After running pmtu.sh, that shows as failure to unregister devices in a namespace:
[ 311.397671] unregister_netdevice: waiting for veth_b to become free. Usage count = 1
The fix is to call kfree_skb in case of transmit failures.
Fixes: dd767856a36e ("xfrm6: Don't call icmpv6_send on local error")
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
net/ipv6/xfrm6_output.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index 5959ce9620eb..6a74080005cf 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -170,9 +170,11 @@ static int __xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
if (toobig && xfrm6_local_dontfrag(skb)) {
xfrm6_local_rxpmtu(skb, mtu);
+ kfree_skb(skb);
return -EMSGSIZE;
} else if (!skb->ignore_df && toobig && skb->sk) {
xfrm_local_error(skb, mtu);
+ kfree_skb(skb);
return -EMSGSIZE;
}
--
2.17.1
^ permalink raw reply related
* [PATCH 1/6] xfrm: Validate address prefix lengths in the xfrm selector.
From: Steffen Klassert @ 2018-10-01 8:58 UTC (permalink / raw)
To: David Miller; +Cc: Herbert Xu, Steffen Klassert, netdev
In-Reply-To: <20181001085855.12057-1-steffen.klassert@secunet.com>
We don't validate the address prefix lengths in the xfrm
selector we got from userspace. This can lead to undefined
behaviour in the address matching functions if the prefix
is too big for the given address family. Fix this by checking
the prefixes and refuse SA/policy insertation when a prefix
is invalid.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: Air Icy <icytxw@gmail.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
net/xfrm/xfrm_user.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 33878e6e0d0a..5151b3ebf068 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -151,10 +151,16 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
err = -EINVAL;
switch (p->family) {
case AF_INET:
+ if (p->sel.prefixlen_d > 32 || p->sel.prefixlen_s > 32)
+ goto out;
+
break;
case AF_INET6:
#if IS_ENABLED(CONFIG_IPV6)
+ if (p->sel.prefixlen_d > 128 || p->sel.prefixlen_s > 128)
+ goto out;
+
break;
#else
err = -EAFNOSUPPORT;
@@ -1359,10 +1365,16 @@ static int verify_newpolicy_info(struct xfrm_userpolicy_info *p)
switch (p->sel.family) {
case AF_INET:
+ if (p->sel.prefixlen_d > 32 || p->sel.prefixlen_s > 32)
+ return -EINVAL;
+
break;
case AF_INET6:
#if IS_ENABLED(CONFIG_IPV6)
+ if (p->sel.prefixlen_d > 128 || p->sel.prefixlen_s > 128)
+ return -EINVAL;
+
break;
#else
return -EAFNOSUPPORT;
--
2.17.1
^ 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