* Re: [PATCHv2 bluetooth-next 00/10] 6lowpan: introduce basic 6lowpan-nd
From: Marcel Holtmann @ 2016-05-02 17:25 UTC (permalink / raw)
To: Alexander Aring, David S. Miller
Cc: linux-wpan-u79uwXL29TY76Z2rM5mHXA, kernel-bIcnvbaLZ9MEGnE8C9+IrQ,
Jukka Rissanen, hannes-tFNcAqjVMyqKXQKiL6tip0B+6BGkLq7r,
Stefan Schmidt, mcr-SWp7JaYWvAQV+D8aMU/kSg, Werner Almesberger,
Linux Bluetooth, Network Development, Alexey Kuznetsov,
James Morris, Hideaki YOSHIFUJI, Patrick McHardy
In-Reply-To: <1461140382-4784-1-git-send-email-aar-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
Hi Dave,
> this patch series introduces a layer for IPv6 neighbour discovery. At first
> it introduce the "ndisc_ops" to run a different handling for recv/send of
> NA/NS messages. The use case for such ndisc operation is RFC 6775 [0].
> Which describes a different neighbour discovery handling for 6LoWPAN networks.
>
> I didn't implement RFC 6775 in this patch series, but introduce callback
> structure for replace different functions in ndisc implementation might be
> the right direction.
>
> Another use case would be RFC 7400 [1] which describes a new option field to
> getting capabilities of 6LoWPAN next header compression methods.
>
> What I implemented is a necessary functionality to handle short address for
> 802.15.4 6LoWPAN networks. The L2-Layer "802.15.4" can have two different
> link-layer addresses which can be used mixed at the same time inside 802.15.4
> networks. To deal with such behaviour in ndisc, it is defined at RFC 4944 [2].
> The bad news is, that I saw different handling of such handling. What Linux
> will do is to add two source/target address information option fields, each
> with different length, if short address is valid (can also not be given).
> Example:
>
> - WPAN interface address settings
> - extended addr (must always be there)
> - short addr (0xfffe or 0xffff -> invalid)
>
> Will add an extended addr to source/target address information option field.
> If short addr is in some valid range, then both address will be added to
> the option fields. Indicated are these different address types by the length
> field (extended -> length=2, short -> length=1), according to [1].
>
> The tested 6LoWPAN implementation (RIOT-OS) allows only one source/target
> option field which is short XOR extended, otherwise it will be dropped.
> There is some lack of information there [2] and I don't know how do deal with
> it right, maybe we need to update the implementation there if it's really
> wrong.
>
> To save such information for each neighbour we use the already implemented
> neighbour private data which some casting strategy for 6LoWPAN and 6LoWPAN
> link-layer specific data e.g. 802.15.4 short address handling.
>
> Additional I implemented to add 6CO to the is_useropt callback in case of
> 6LoWPAN interface. The 6CO option will currently parsed in userspace which
> are placed in RA-Messages.
>
> The ndisc_ops are not finished yet, of course we need handling for RS messages
> to place the 802.15.4 short address there as well and then also processing
> of RA messages for the 802.15.4 SLLAO option field.
>
> - Alex
>
> [0] https://tools.ietf.org/html/rfc6775
> [1] https://tools.ietf.org/html/rfc7400#section-3.3
> [2] https://tools.ietf.org/html/rfc4944#section-8
>
> Cc: David S. Miller <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
> Cc: Alexey Kuznetsov <kuznet-v/Mj1YrvjDBInbfyfbPRSQ@public.gmane.org>
> Cc: James Morris <jmorris-gx6/JNMH7DfYtjvyW6yDsg@public.gmane.org>
> Cc: Hideaki YOSHIFUJI <yoshfuji-VfPWfsRibaP+Ru+s062T9g@public.gmane.org>
> Cc: Patrick McHardy <kaber-dcUjhNyLwpNeoWH0uzbU5w@public.gmane.org>
>
> changes since v2:
> - replace #ifdef CONFIG_IPV6 to #if IS_ENABLED(...)
> - replace #ifdef CONFIG_IEEE802154... to #if IS_ENABLED(...)
> - add more #if IS_ENABLED(CONFIG_IPV6) in ndisc.h
>
> Alexander Aring (10):
> 6lowpan: add private neighbour data
> 6lowpan: add 802.15.4 short addr slaac
> 6lowpan: remove ipv6 module request
> ndisc: add addr_len parameter to ndisc_opt_addr_space
> ndisc: add addr_len parameter to ndisc_opt_addr_data
> ndisc: add addr_len parameter to ndisc_fill_addr_option
> ipv6: introduce neighbour discovery ops
> ipv6: export ndisc functions
> 6lowpan: introduce 6lowpan-nd
> 6lowpan: add support for 802.15.4 short addr handling
>
> include/linux/netdevice.h | 6 +-
> include/net/6lowpan.h | 24 ++
> include/net/addrconf.h | 3 +
> include/net/ndisc.h | 124 ++++++++-
> net/6lowpan/6lowpan_i.h | 2 +
> net/6lowpan/Makefile | 2 +-
> net/6lowpan/core.c | 50 +++-
> net/6lowpan/iphc.c | 167 +++++++++--
> net/6lowpan/ndisc.c | 633 ++++++++++++++++++++++++++++++++++++++++++
> net/bluetooth/6lowpan.c | 2 +
> net/ieee802154/6lowpan/core.c | 12 +
> net/ieee802154/6lowpan/tx.c | 107 ++++---
> net/ipv6/addrconf.c | 7 +-
> net/ipv6/ndisc.c | 132 +++++----
> net/ipv6/route.c | 4 +-
> 15 files changed, 1117 insertions(+), 158 deletions(-)
> create mode 100644 net/6lowpan/ndisc.c
is there a chance that we get input into this patch set? I wonder also if it would be acceptable to take this through bluetooth-next or should it better go straight into net-next?
Regards
Marcel
^ permalink raw reply
* Re: VRF_DEVICE integration plan
From: David Ahern @ 2016-05-02 17:43 UTC (permalink / raw)
To: Elluru, Krishna Mohan, netdev@vger.kernel.org
Cc: Kumara, Shantha (HP Networking), Govindan Nair, Anoop
In-Reply-To: <CS1PR84MB0072AC62E9EBCC5A42E33952CA650@CS1PR84MB0072.NAMPRD84.PROD.OUTLOOK.COM>
On 4/28/16 11:16 AM, Elluru, Krishna Mohan wrote:
>
> I posted a few bug fix patches a week or two ago. Not sure what the
> status is with respect to 4.3 - 4.5 trees.
>
> MOHAN> Sure. Are those patches sent over netdev mailer list?
yes. All patches for VRF - kernel and iproute2 - are sent to netdev.
> MOHAN> sorry for not being clear. My ask was, to create a namespace we need cap_admin privileges currently, but your earlier mails suggested that we should be able to configure/create vrf device with net_admin capabilities. Is this support present /expected to be added soon?
VRF is implemented using a netdevice. As such the ability to create one
requires the same permissions as creating any other netdevice
(CAP_NET_ADMIN).
>> 5. Is there a possibility of enabling secondary level lookup, to give a leak functionality to parent route table from device local route table? I tested with veth pair, configured one as default gateway, it is possible to forward traffic b/w the interfaces, looking for cleaner method.
>
> Are you referring to inter-vrf routing? See slide 27
> http://www.netdevconf.org/1.1/proceedings/slides/ahern-vrf-tutorial.pdf
> Full lookup in VRF table
> ▪ ip route add table vrf-red 1.1.1.0/24 dev vrf-green
> MOHAN> In slide 27 above shows inter vrf routing, requirement is to use current namespace global route table if the ip lookup fails in vrf-device routing table.
> Reference: https://www.juniper.net/techpubs/en_US/junose16.1/topics/task/configuration/mbgp-secondary-routing-table-search.html
One solution is to create a VRF device that is associated with the main
table and then use an inter-vrf route to jump to the main table.
VRF tables do need a default route (e.g., unreachable with high metric
value) else the FIB lookups will proceed to the next table which is most
likely not what you want.
David
^ permalink raw reply
* [PATCH net-next] net: add __sock_wfree() helper
From: Eric Dumazet @ 2016-05-02 17:56 UTC (permalink / raw)
To: David Miller; +Cc: netdev
From: Eric Dumazet <edumazet@google.com>
Hosts sending lot of ACK packets exhibit high sock_wfree() cost
because of cache line miss to test SOCK_USE_WRITE_QUEUE
We could move this flag close to sk_wmem_alloc but it is better
to perform the atomic_sub_and_test() on a clean cache line,
as it avoid one extra bus transaction.
skb_orphan_partial() can also have a fast track for packets that either
are TCP acks, or already went through another skb_orphan_partial()
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
include/net/sock.h | 1 +
net/core/sock.c | 24 ++++++++++++++++++++++++
net/ipv4/tcp_output.c | 2 +-
3 files changed, 26 insertions(+), 1 deletion(-)
diff --git a/include/net/sock.h b/include/net/sock.h
index 3df778ccaa820b00b4038feedae30cd444e9a212..9be2ffb4b8fcf54cc9c8bd73628dd7572b1d783d 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1434,6 +1434,7 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority);
struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force,
gfp_t priority);
+void __sock_wfree(struct sk_buff *skb);
void sock_wfree(struct sk_buff *skb);
void skb_orphan_partial(struct sk_buff *skb);
void sock_rfree(struct sk_buff *skb);
diff --git a/net/core/sock.c b/net/core/sock.c
index e16a5db853c6f455b0ac826744d0ee5e96a44863..e1151f11eb4aa0a5afa95bfee9d00a85c4d50af6 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1655,6 +1655,17 @@ void sock_wfree(struct sk_buff *skb)
}
EXPORT_SYMBOL(sock_wfree);
+/* This variant of sock_wfree() is used by TCP,
+ * since it sets SOCK_USE_WRITE_QUEUE.
+ */
+void __sock_wfree(struct sk_buff *skb)
+{
+ struct sock *sk = skb->sk;
+
+ if (atomic_sub_and_test(skb->truesize, &sk->sk_wmem_alloc))
+ __sk_free(sk);
+}
+
void skb_set_owner_w(struct sk_buff *skb, struct sock *sk)
{
skb_orphan(skb);
@@ -1677,8 +1688,21 @@ void skb_set_owner_w(struct sk_buff *skb, struct sock *sk)
}
EXPORT_SYMBOL(skb_set_owner_w);
+/* This helper is used by netem, as it can hold packets in its
+ * delay queue. We want to allow the owner socket to send more
+ * packets, as if they were already TX completed by a typical driver.
+ * But we also want to keep skb->sk set because some packet schedulers
+ * rely on it (sch_fq for example). So we set skb->truesize to a small
+ * amount (1) and decrease sk_wmem_alloc accordingly.
+ */
void skb_orphan_partial(struct sk_buff *skb)
{
+ /* If this skb is a TCP pure ACK or already went here,
+ * we have nothing to do. 2 is already a very small truesize.
+ */
+ if (skb->truesize <= 2)
+ return;
+
/* TCP stack sets skb->ooo_okay based on sk_wmem_alloc,
* so we do not completely orphan skb, but transfert all
* accounted bytes but one, to avoid unexpected reorders.
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 1a487ff95d4c0572737e4f972666229f12ef1e08..778ac8f2d84be389478e4d92335e1979482b3817 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -949,7 +949,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
skb_orphan(skb);
skb->sk = sk;
- skb->destructor = skb_is_tcp_pure_ack(skb) ? sock_wfree : tcp_wfree;
+ skb->destructor = skb_is_tcp_pure_ack(skb) ? __sock_wfree : tcp_wfree;
skb_set_hash_from_sk(skb, sk);
atomic_add(skb->truesize, &sk->sk_wmem_alloc);
^ permalink raw reply related
* Re: [PATCH] Bluetooth: Use hci_conn_hash_lookup_le
From: Johan Hedberg @ 2016-05-02 18:02 UTC (permalink / raw)
To: Julia Lawall
Cc: Marcel Holtmann, kernel-janitors, Gustavo Padovan,
David S. Miller, linux-bluetooth, netdev, linux-kernel
In-Reply-To: <1461957760-753-1-git-send-email-Julia.Lawall@lip6.fr>
Hi,
On Fri, Apr 29, 2016, Julia Lawall wrote:
> --- a/net/bluetooth/mgmt.c
> +++ b/net/bluetooth/mgmt.c
> @@ -4773,7 +4773,8 @@ static int get_conn_info(struct sock *sk, struct hci_dev *hdev, void *data,
> conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK,
> &cp->addr.bdaddr);
> else
> - conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr);
> + conn = hci_conn_hash_lookup_le(hdev, &cp->addr.bdaddr,
> + cp->addr.type);
I don't think is is correct. There are two possible domains for address
types: the user space-facing interface that has three values: BR/EDR, LE
public & LE random, and the internal one which maps to HCI that has two
values: random or public. You'd need to convert from the former to the
latter when making the lookup call, i.e:
conn = hci_conn_hash_lookup_le(hdev, &cp->addr.bdaddr,
le_addr_type(cp->addr.type));
Johan
^ permalink raw reply
* Re: [PATCH net 1/2] RDS:TCP: Synchronize rds_tcp_accept_one with rds_send_xmit when resetting t_sock
From: Santosh Shilimkar @ 2016-05-02 18:05 UTC (permalink / raw)
To: Sowmini Varadhan; +Cc: netdev, rds-devel, davem
In-Reply-To: <20160502163715.GD20517@oracle.com>
On 5/2/2016 9:37 AM, Sowmini Varadhan wrote:
> On (05/02/16 09:20), Santosh Shilimkar wrote:
>>> rds_conn_transition(conn, RDS_CONN_DOWN, RDS_CONN_CONNECTING);
>>> + if (rs_tcp->t_sock) {
>>> + /* Need to resolve a duelling SYN between peers.
>>> + * We have an outstanding SYN to this peer, which may
>>> + * potentially have transitioned to the RDS_CONN_UP state,
>>> + * so we must quiesce any send threads before resetting
>>> + * c_transport_data.
>>> + */
>>> + wait_event(conn->c_waitq,
>>> + !test_bit(RDS_IN_XMIT, &conn->c_flags));
>> Would it be good to check the return value of rds_conn_transition()
>> since if CONN is already UP above will fail and then send message
>> might again race and we will let message through even though passive
>> hasn't finished its connection.
>
> no, that was the original issue that I was running into, which needed
> commit 241b2719 - prior to that commit, if the conn was already UP,
> we'd end up doing a rds_conn_drop on a good connection, and both sides
> would end up in a pair of infinite 3WH loops. Even if we dont do
> a rds_conn_drop on the UP connection, we've just (before
> rds_tcp_accept_one) sent out a syn-ack on the incoming syn, and now
> need to RST that syn-ac. The other side is going to receive the rst,
> and get confused about what to clean up (since there's already an UP
> connection going on).
>
> In short, when there is a duel, it's cleanest to have a deterministic
> arbitration- both sides use the numeric value of saddr and faddr to
> figure out which side is active, which side is passive. (Thus the
> basis on the BGP router-id based model for 241b2719)
>
> FWIW, much of this is actually a corner case- in practice, its not
> frequent to have syns crossing each other at "almost the same time".
>
Sounds good. Thanks for expanding it. Patch looks good to me.
Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
^ permalink raw reply
* Re: [PATCH net 2/2] RDS: TCP: Synchrnozize accept() and connect() paths on t_conn_lock.
From: Santosh Shilimkar @ 2016-05-02 18:08 UTC (permalink / raw)
To: Sowmini Varadhan; +Cc: netdev, rds-devel, davem
In-Reply-To: <20160502164307.GE20517@oracle.com>
On 5/2/2016 9:43 AM, Sowmini Varadhan wrote:
> On (05/02/16 09:33), Santosh Shilimkar wrote:
>>> + mutex_unlock(&tc->t_conn_lock);
>> Just wondering whether the spin_lock() would better here considering
>> entry into rds_tcp_conn_connect() & rds_tcp_accept_one() might be
>> from softirq context. Ignore it if its not applicable.
>
> It's not from softirq context (both are workqs), but I used a mutex
> to follow c_cm_lock (which I considered reusing, given that it
> is only IB specific?) But spin_lock vs mutex may not be a big
> differentiator here- this is really a one-time start up (corner-case)
> issue in the control path.
>
That should be fine then.
>>> rds_conn_transition(conn, RDS_CONN_DOWN, RDS_CONN_CONNECTING);
>> Like patch 1/2, probably we can leverage return value of above.
> :
>> You probably don't need the local 'conn_state' and below should work.
>> if (!rds_conn_connecting(conn) && !rds_conn_up(conn))
>
> see explanation for comment to 1/2.
>
Yep.
> +rst_nsk:
> + /* rest the newly returned accept sock and bail */
s/rest/reset
With typo fixed,
Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
^ permalink raw reply
* [PATCH net v2 1/2] RDS:TCP: Synchronize rds_tcp_accept_one with rds_send_xmit when resetting t_sock
From: Sowmini Varadhan @ 2016-05-02 18:24 UTC (permalink / raw)
To: sowmini.varadhan, netdev, rds-devel; +Cc: santosh.shilimkar, davem
In-Reply-To: <cover.1462212462.git.sowmini.varadhan@oracle.com>
There is a race condition between rds_send_xmit -> rds_tcp_xmit
and the code that deals with resolution of duelling syns added
by commit 241b271952eb ("RDS-TCP: Reset tcp callbacks if re-using an
outgoing socket in rds_tcp_accept_one()").
Specifically, we may end up derefencing a null pointer in rds_send_xmit
if we have the interleaving sequence:
rds_tcp_accept_one rds_send_xmit
conn is RDS_CONN_UP, so
invoke rds_tcp_xmit
tc = conn->c_transport_data
rds_tcp_restore_callbacks
/* reset t_sock */
null ptr deref from tc->t_sock
The race condition can be avoided without adding the overhead of
additional locking in the xmit path: have rds_tcp_accept_one wait
for rds_tcp_xmit threads to complete before resetting callbacks.
The synchronization can be done in the same manner as rds_conn_shutdown().
First set the rds_conn_state to something other than RDS_CONN_UP
(so that new threads cannot get into rds_tcp_xmit()), then wait for
RDS_IN_XMIT to be cleared in the conn->c_flags indicating that any
threads in rds_tcp_xmit are done.
Fixes: 241b271952eb ("RDS-TCP: Reset tcp callbacks if re-using an
outgoing socket in rds_tcp_accept_one()")
Signed-off-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
---
v2: spelling edit in commit: s/sequencee/sequence
net/rds/tcp.c | 2 +-
net/rds/tcp_listen.c | 40 ++++++++++++++++++++++++----------------
2 files changed, 25 insertions(+), 17 deletions(-)
diff --git a/net/rds/tcp.c b/net/rds/tcp.c
index 61ed2a8..9134544 100644
--- a/net/rds/tcp.c
+++ b/net/rds/tcp.c
@@ -127,7 +127,7 @@ void rds_tcp_restore_callbacks(struct socket *sock,
/*
* This is the only path that sets tc->t_sock. Send and receive trust that
- * it is set. The RDS_CONN_CONNECTED bit protects those paths from being
+ * it is set. The RDS_CONN_UP bit protects those paths from being
* called while it isn't set.
*/
void rds_tcp_set_callbacks(struct socket *sock, struct rds_connection *conn)
diff --git a/net/rds/tcp_listen.c b/net/rds/tcp_listen.c
index 0936a4a..0896187 100644
--- a/net/rds/tcp_listen.c
+++ b/net/rds/tcp_listen.c
@@ -115,24 +115,32 @@ int rds_tcp_accept_one(struct socket *sock)
* rds_tcp_state_change() will do that cleanup
*/
rs_tcp = (struct rds_tcp_connection *)conn->c_transport_data;
- if (rs_tcp->t_sock &&
- ntohl(inet->inet_saddr) < ntohl(inet->inet_daddr)) {
- struct sock *nsk = new_sock->sk;
-
- nsk->sk_user_data = NULL;
- nsk->sk_prot->disconnect(nsk, 0);
- tcp_done(nsk);
- new_sock = NULL;
- ret = 0;
- goto out;
- } else if (rs_tcp->t_sock) {
- rds_tcp_restore_callbacks(rs_tcp->t_sock, rs_tcp);
- conn->c_outgoing = 0;
- }
-
rds_conn_transition(conn, RDS_CONN_DOWN, RDS_CONN_CONNECTING);
+ if (rs_tcp->t_sock) {
+ /* Need to resolve a duelling SYN between peers.
+ * We have an outstanding SYN to this peer, which may
+ * potentially have transitioned to the RDS_CONN_UP state,
+ * so we must quiesce any send threads before resetting
+ * c_transport_data.
+ */
+ wait_event(conn->c_waitq,
+ !test_bit(RDS_IN_XMIT, &conn->c_flags));
+ if (ntohl(inet->inet_saddr) < ntohl(inet->inet_daddr)) {
+ struct sock *nsk = new_sock->sk;
+
+ nsk->sk_user_data = NULL;
+ nsk->sk_prot->disconnect(nsk, 0);
+ tcp_done(nsk);
+ new_sock = NULL;
+ ret = 0;
+ goto out;
+ } else if (rs_tcp->t_sock) {
+ rds_tcp_restore_callbacks(rs_tcp->t_sock, rs_tcp);
+ conn->c_outgoing = 0;
+ }
+ }
rds_tcp_set_callbacks(new_sock, conn);
- rds_connect_complete(conn);
+ rds_connect_complete(conn); /* marks RDS_CONN_UP */
new_sock = NULL;
ret = 0;
--
1.7.1
^ permalink raw reply related
* [PATCH net v2 2/2] RDS: TCP: Synchronize accept() and connect() paths on t_conn_lock.
From: Sowmini Varadhan @ 2016-05-02 18:24 UTC (permalink / raw)
To: sowmini.varadhan, netdev, rds-devel; +Cc: santosh.shilimkar, davem
In-Reply-To: <cover.1462212462.git.sowmini.varadhan@oracle.com>
An arbitration scheme for duelling SYNs is implemented as part of
commit 241b271952eb ("RDS-TCP: Reset tcp callbacks if re-using an
outgoing socket in rds_tcp_accept_one()") which ensures that both nodes
involved will arrive at the same arbitration decision. However, this
needs to be synchronized with an outgoing SYN to be generated by
rds_tcp_conn_connect(). This commit achieves the synchronization
through the t_conn_lock mutex in struct rds_tcp_connection.
The rds_conn_state is checked in rds_tcp_conn_connect() after acquiring
the t_conn_lock mutex. A SYN is sent out only if the RDS connection is
not already UP (an UP would indicate that rds_tcp_accept_one() has
completed 3WH, so no SYN needs to be generated).
Similarly, the rds_conn_state is checked in rds_tcp_accept_one() after
acquiring the t_conn_lock mutex. The only acceptable states (to
allow continuation of the arbitration logic) are UP (i.e., outgoing SYN
was SYN-ACKed by peer after it sent us the SYN) or CONNECTING (we sent
outgoing SYN before we saw incoming SYN).
Signed-off-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
---
v2: review comments from Santosh Shilimkar
net/rds/tcp.c | 1 +
net/rds/tcp.h | 4 ++++
net/rds/tcp_connect.c | 8 ++++++++
net/rds/tcp_listen.c | 30 ++++++++++++++++++++----------
4 files changed, 33 insertions(+), 10 deletions(-)
diff --git a/net/rds/tcp.c b/net/rds/tcp.c
index 9134544..86187da 100644
--- a/net/rds/tcp.c
+++ b/net/rds/tcp.c
@@ -216,6 +216,7 @@ static int rds_tcp_conn_alloc(struct rds_connection *conn, gfp_t gfp)
if (!tc)
return -ENOMEM;
+ mutex_init(&tc->t_conn_lock);
tc->t_sock = NULL;
tc->t_tinc = NULL;
tc->t_tinc_hdr_rem = sizeof(struct rds_header);
diff --git a/net/rds/tcp.h b/net/rds/tcp.h
index 64f873c..41c2283 100644
--- a/net/rds/tcp.h
+++ b/net/rds/tcp.h
@@ -12,6 +12,10 @@ struct rds_tcp_connection {
struct list_head t_tcp_node;
struct rds_connection *conn;
+ /* t_conn_lock synchronizes the connection establishment between
+ * rds_tcp_accept_one and rds_tcp_conn_connect
+ */
+ struct mutex t_conn_lock;
struct socket *t_sock;
void *t_orig_write_space;
void *t_orig_data_ready;
diff --git a/net/rds/tcp_connect.c b/net/rds/tcp_connect.c
index 5cb1687..49a3fcf 100644
--- a/net/rds/tcp_connect.c
+++ b/net/rds/tcp_connect.c
@@ -78,7 +78,14 @@ int rds_tcp_conn_connect(struct rds_connection *conn)
struct socket *sock = NULL;
struct sockaddr_in src, dest;
int ret;
+ struct rds_tcp_connection *tc = conn->c_transport_data;
+
+ mutex_lock(&tc->t_conn_lock);
+ if (rds_conn_up(conn)) {
+ mutex_unlock(&tc->t_conn_lock);
+ return 0;
+ }
ret = sock_create_kern(rds_conn_net(conn), PF_INET,
SOCK_STREAM, IPPROTO_TCP, &sock);
if (ret < 0)
@@ -120,6 +127,7 @@ int rds_tcp_conn_connect(struct rds_connection *conn)
}
out:
+ mutex_unlock(&tc->t_conn_lock);
if (sock)
sock_release(sock);
return ret;
diff --git a/net/rds/tcp_listen.c b/net/rds/tcp_listen.c
index 0896187..be263cd 100644
--- a/net/rds/tcp_listen.c
+++ b/net/rds/tcp_listen.c
@@ -76,7 +76,9 @@ int rds_tcp_accept_one(struct socket *sock)
struct rds_connection *conn;
int ret;
struct inet_sock *inet;
- struct rds_tcp_connection *rs_tcp;
+ struct rds_tcp_connection *rs_tcp = NULL;
+ int conn_state;
+ struct sock *nsk;
ret = sock_create_kern(sock_net(sock->sk), sock->sk->sk_family,
sock->sk->sk_type, sock->sk->sk_protocol,
@@ -116,6 +118,10 @@ int rds_tcp_accept_one(struct socket *sock)
*/
rs_tcp = (struct rds_tcp_connection *)conn->c_transport_data;
rds_conn_transition(conn, RDS_CONN_DOWN, RDS_CONN_CONNECTING);
+ mutex_lock(&rs_tcp->t_conn_lock);
+ conn_state = rds_conn_state(conn);
+ if (conn_state != RDS_CONN_CONNECTING && conn_state != RDS_CONN_UP)
+ goto rst_nsk;
if (rs_tcp->t_sock) {
/* Need to resolve a duelling SYN between peers.
* We have an outstanding SYN to this peer, which may
@@ -126,14 +132,7 @@ int rds_tcp_accept_one(struct socket *sock)
wait_event(conn->c_waitq,
!test_bit(RDS_IN_XMIT, &conn->c_flags));
if (ntohl(inet->inet_saddr) < ntohl(inet->inet_daddr)) {
- struct sock *nsk = new_sock->sk;
-
- nsk->sk_user_data = NULL;
- nsk->sk_prot->disconnect(nsk, 0);
- tcp_done(nsk);
- new_sock = NULL;
- ret = 0;
- goto out;
+ goto rst_nsk;
} else if (rs_tcp->t_sock) {
rds_tcp_restore_callbacks(rs_tcp->t_sock, rs_tcp);
conn->c_outgoing = 0;
@@ -143,8 +142,19 @@ int rds_tcp_accept_one(struct socket *sock)
rds_connect_complete(conn); /* marks RDS_CONN_UP */
new_sock = NULL;
ret = 0;
-
+ goto out;
+rst_nsk:
+ /* reset the newly returned accept sock and bail */
+ nsk = new_sock->sk;
+ rds_tcp_stats_inc(s_tcp_listen_closed_stale);
+ nsk->sk_user_data = NULL;
+ nsk->sk_prot->disconnect(nsk, 0);
+ tcp_done(nsk);
+ new_sock = NULL;
+ ret = 0;
out:
+ if (rs_tcp)
+ mutex_unlock(&rs_tcp->t_conn_lock);
if (new_sock)
sock_release(new_sock);
return ret;
--
1.7.1
^ permalink raw reply related
* [PATCH net v2 0/2] RDS: TCP: sychronization during connection startup
From: Sowmini Varadhan @ 2016-05-02 18:24 UTC (permalink / raw)
To: sowmini.varadhan, netdev, rds-devel; +Cc: santosh.shilimkar, davem
This patch series ensures that the passive (accept) side of the
TCP connection used for RDS-TCP is correctly synchronized with
any concurrent active (connect) attempts for a given pair of peers.
Patch 1 in the series makes sure that the t_sock in struct
rds_tcp_connection is only reset after any threads in rds_tcp_xmit
have completed (otherwise a null-ptr deref may be encountered).
Patch 2 synchronizes rds_tcp_accept_one() with the rds_tcp*connect()
path.
v2: review comments from Santosh Shilimkar, other spelling corrections
Sowmini Varadhan (2):
RDS:TCP: Synchronize rds_tcp_accept_one with rds_send_xmit when
resetting t_sock
RDS: TCP: Synchronize accept() and connect() paths on t_conn_lock.
net/rds/tcp.c | 3 +-
net/rds/tcp.h | 4 +++
net/rds/tcp_connect.c | 8 +++++++
net/rds/tcp_listen.c | 54 ++++++++++++++++++++++++++++++++----------------
4 files changed, 50 insertions(+), 19 deletions(-)
^ permalink raw reply
* Re: [PATCH v2] net: macb: do not scan PHYs manually
From: Josh Cartwright @ 2016-05-02 18:36 UTC (permalink / raw)
To: Nicolas Ferre
Cc: Andrew Lunn, Nathan Sullivan, netdev, linux-kernel,
Florian Fainelli, Alexandre Belloni
In-Reply-To: <57235655.3030104@atmel.com>
[-- Attachment #1: Type: text/plain, Size: 1941 bytes --]
On Fri, Apr 29, 2016 at 02:40:53PM +0200, Nicolas Ferre wrote:
[..]
> > static int macb_mii_init(struct macb *bp)
> > {
> > struct macb_platform_data *pdata;
> > struct device_node *np;
> > - int err = -ENXIO, i;
> > + int err = -ENXIO;
> >
> > /* Enable management port */
> > macb_writel(bp, NCR, MACB_BIT(MPE));
> > @@ -446,33 +497,10 @@ static int macb_mii_init(struct macb *bp)
> > dev_set_drvdata(&bp->dev->dev, bp->mii_bus);
> >
> > np = bp->pdev->dev.of_node;
> > - if (np) {
> > - /* try dt phy registration */
> > - err = of_mdiobus_register(bp->mii_bus, np);
> > -
> > - /* fallback to standard phy registration if no phy were
> > - * found during dt phy registration
> > - */
> > - if (!err && !phy_find_first(bp->mii_bus)) {
> > - for (i = 0; i < PHY_MAX_ADDR; i++) {
> > - struct phy_device *phydev;
> > -
> > - phydev = mdiobus_scan(bp->mii_bus, i);
> > - if (IS_ERR(phydev)) {
> > - err = PTR_ERR(phydev);
> > - break;
> > - }
> > - }
> > -
> > - if (err)
> > - goto err_out_unregister_bus;
> > - }
> > - } else {
> > - if (pdata)
> > - bp->mii_bus->phy_mask = pdata->phy_mask;
> > -
> > - err = mdiobus_register(bp->mii_bus);
> > - }
> > + if (np)
> > + err = macb_mii_of_init(bp, np);
> > + else
> > + err = macb_mii_pdata_init(bp, pdata);
> >
> > if (err)
> > goto err_out_free_mdiobus;
>
> I'm okay with this. Thanks for having taken the initiative to implement it.
Unfortunately, I don't think it's going to be as straightforward
as I originally thought. Still doable, but more complicated.
In particular, the macb bindings allow for a user to specify a
'reset-gpios' property _at the PHY_ level, which is consumed by the
macb to adjust the PHY reset state on remove.
My question is: why is the PHY reset GPIO management not the
responsibility of the PHY driver/core itself?
Josh
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]
^ permalink raw reply
* Re: [PATCHv2 bluetooth-next 01/10] 6lowpan: add private neighbour data
From: Hannes Frederic Sowa @ 2016-05-02 18:59 UTC (permalink / raw)
To: Alexander Aring, linux-wpan
Cc: kernel, marcel, jukka.rissanen, stefan, mcr, werner,
linux-bluetooth, netdev, David S . Miller
In-Reply-To: <1461140382-4784-2-git-send-email-aar@pengutronix.de>
Hello,
On 20.04.2016 10:19, Alexander Aring wrote:
> This patch will introduce a 6lowpan neighbour private data. Like the
> interface private data we handle private data for generic 6lowpan and
> for link-layer specific 6lowpan.
>
> The current first use case if to save the short address for a 802.15.4
> 6lowpan neighbour.
>
> Cc: David S. Miller <davem@davemloft.net>
> Signed-off-by: Alexander Aring <aar@pengutronix.de>
> ---
> include/linux/netdevice.h | 3 +--
> include/net/6lowpan.h | 24 ++++++++++++++++++++++++
> net/bluetooth/6lowpan.c | 2 ++
> net/ieee802154/6lowpan/core.c | 12 ++++++++++++
> 4 files changed, 39 insertions(+), 2 deletions(-)
>
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index 166402a..0052c42 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -1487,8 +1487,7 @@ enum netdev_priv_flags {
> * @perm_addr: Permanent hw address
> * @addr_assign_type: Hw address assignment type
> * @addr_len: Hardware address length
> - * @neigh_priv_len; Used in neigh_alloc(),
> - * initialized only in atm/clip.c
> + * @neigh_priv_len; Used in neigh_alloc()
> * @dev_id: Used to differentiate devices that share
> * the same link layer address
> * @dev_port: Used to differentiate devices that share
> diff --git a/include/net/6lowpan.h b/include/net/6lowpan.h
> index da84cf9..61c6517 100644
> --- a/include/net/6lowpan.h
> +++ b/include/net/6lowpan.h
> @@ -98,6 +98,9 @@ static inline bool lowpan_is_iphc(u8 dispatch)
> #define LOWPAN_PRIV_SIZE(llpriv_size) \
> (sizeof(struct lowpan_dev) + llpriv_size)
>
> +#define LOWPAN_NEIGH_PRIV_SIZE(llneigh_priv_size) \
> + (sizeof(struct lowpan_neigh) + llneigh_priv_size)
> +
> enum lowpan_lltypes {
> LOWPAN_LLTYPE_BTLE,
> LOWPAN_LLTYPE_IEEE802154,
> @@ -141,6 +144,27 @@ struct lowpan_dev {
> u8 priv[0] __aligned(sizeof(void *));
> };
>
> +struct lowpan_neigh {
> + /* 6LoWPAN neigh private data */
> + /* must be last */
> + u8 priv[0] __aligned(sizeof(void *));
Are you sure this declaration is correct? You take its size above, which
should result in zero. Looks a little bit strange. :)
> +};
> +
> +struct lowpan_802154_neigh {
> + __le16 short_addr;
> +};
> +
> +static inline struct lowpan_neigh *lowpan_neigh(void *neigh_priv)
> +{
> + return neigh_priv;
> +}
> +
> +static inline
> +struct lowpan_802154_neigh *lowpan_802154_neigh(void *neigh_priv)
> +{
> + return (struct lowpan_802154_neigh *)lowpan_neigh(neigh_priv)->priv;
> +}
Can't you remove lowpan_neigh completely and just use 802154_neigh at
this point?
Bye,
Hannes
^ permalink raw reply
* Re: [PATCHv2 bluetooth-next 02/10] 6lowpan: add 802.15.4 short addr slaac
From: Hannes Frederic Sowa @ 2016-05-02 19:06 UTC (permalink / raw)
To: Alexander Aring, linux-wpan
Cc: kernel, marcel, jukka.rissanen, stefan, mcr, werner,
linux-bluetooth, netdev, David S . Miller, Alexey Kuznetsov,
James Morris, Hideaki YOSHIFUJI, Patrick McHardy
In-Reply-To: <1461140382-4784-3-git-send-email-aar@pengutronix.de>
On 20.04.2016 10:19, Alexander Aring wrote:
> This patch adds the autoconfiguration if a valid 802.15.4 short address
> is available for 802.15.4 6LoWPAN interfaces.
>
> Cc: David S. Miller <davem@davemloft.net>
> Cc: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
> Cc: James Morris <jmorris@namei.org>
> Cc: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
> Cc: Patrick McHardy <kaber@trash.net>
> Signed-off-by: Alexander Aring <aar@pengutronix.de>
Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Thanks,
Hannes
^ permalink raw reply
* Re: [PATCHv2 bluetooth-next 03/10] 6lowpan: remove ipv6 module request
From: Hannes Frederic Sowa @ 2016-05-02 19:06 UTC (permalink / raw)
To: Alexander Aring, linux-wpan
Cc: kernel, marcel, jukka.rissanen, stefan, mcr, werner,
linux-bluetooth, netdev
In-Reply-To: <1461140382-4784-4-git-send-email-aar@pengutronix.de>
On 20.04.2016 10:19, Alexander Aring wrote:
> Since we use exported function from ipv6 kernel module we don't need to
> request the module anymore to have ipv6 functionality.
>
> Signed-off-by: Alexander Aring <aar@pengutronix.de>
Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
^ permalink raw reply
* Re: [PATCH v2] net: macb: do not scan PHYs manually
From: Florian Fainelli @ 2016-05-02 19:08 UTC (permalink / raw)
To: Josh Cartwright, Nicolas Ferre
Cc: Andrew Lunn, Nathan Sullivan, netdev, linux-kernel,
Alexandre Belloni
In-Reply-To: <20160502183626.GC31001@jcartwri.amer.corp.natinst.com>
On 02/05/16 11:36, Josh Cartwright wrote:
> On Fri, Apr 29, 2016 at 02:40:53PM +0200, Nicolas Ferre wrote:
> [..]
>>> static int macb_mii_init(struct macb *bp)
>>> {
>>> struct macb_platform_data *pdata;
>>> struct device_node *np;
>>> - int err = -ENXIO, i;
>>> + int err = -ENXIO;
>>>
>>> /* Enable management port */
>>> macb_writel(bp, NCR, MACB_BIT(MPE));
>>> @@ -446,33 +497,10 @@ static int macb_mii_init(struct macb *bp)
>>> dev_set_drvdata(&bp->dev->dev, bp->mii_bus);
>>>
>>> np = bp->pdev->dev.of_node;
>>> - if (np) {
>>> - /* try dt phy registration */
>>> - err = of_mdiobus_register(bp->mii_bus, np);
>>> -
>>> - /* fallback to standard phy registration if no phy were
>>> - * found during dt phy registration
>>> - */
>>> - if (!err && !phy_find_first(bp->mii_bus)) {
>>> - for (i = 0; i < PHY_MAX_ADDR; i++) {
>>> - struct phy_device *phydev;
>>> -
>>> - phydev = mdiobus_scan(bp->mii_bus, i);
>>> - if (IS_ERR(phydev)) {
>>> - err = PTR_ERR(phydev);
>>> - break;
>>> - }
>>> - }
>>> -
>>> - if (err)
>>> - goto err_out_unregister_bus;
>>> - }
>>> - } else {
>>> - if (pdata)
>>> - bp->mii_bus->phy_mask = pdata->phy_mask;
>>> -
>>> - err = mdiobus_register(bp->mii_bus);
>>> - }
>>> + if (np)
>>> + err = macb_mii_of_init(bp, np);
>>> + else
>>> + err = macb_mii_pdata_init(bp, pdata);
>>>
>>> if (err)
>>> goto err_out_free_mdiobus;
>>
>> I'm okay with this. Thanks for having taken the initiative to implement it.
>
> Unfortunately, I don't think it's going to be as straightforward
> as I originally thought. Still doable, but more complicated.
>
> In particular, the macb bindings allow for a user to specify a
> 'reset-gpios' property _at the PHY_ level, which is consumed by the
> macb to adjust the PHY reset state on remove.
In fact, not just on remove, anytime there is an opportunity to save
power (interface down, closed) and putting the PHY into reset is usually
guaranteed to be saving more power than e.g: a BMCR power down.
>
> My question is: why is the PHY reset GPIO management not the
> responsibility of the PHY driver/core itself?
Well, this is actually being worked on at the moment by Sergei, since
there is not necessarily a reason why PHYLIB can't deal with that:
https://lkml.org/lkml/2016/4/28/831
--
Florian
^ permalink raw reply
* Re: [PATCH net-next 1/2] net: SOCKWQ_ASYNC_NOSPACE optimizations
From: Jiri Pirko @ 2016-05-02 19:12 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Eric Dumazet, David S . Miller, netdev, eladr, idosch
In-Reply-To: <1462206138.5535.255.camel@edumazet-glaptop3.roam.corp.google.com>
Mon, May 02, 2016 at 06:22:18PM CEST, eric.dumazet@gmail.com wrote:
>On Mon, 2016-05-02 at 18:16 +0200, Jiri Pirko wrote:
>> Mon, Apr 25, 2016 at 07:39:32PM CEST, edumazet@google.com wrote:
>> >SOCKWQ_ASYNC_NOSPACE is tested in sock_wake_async()
>> >so that a SIGIO signal is sent when needed.
>> >
>> >tcp_sendmsg() clears the bit.
>> >tcp_poll() sets the bit when stream is not writeable.
>> >
>> >We can avoid two atomic operations by first checking if socket
>> >is actually interested in the FASYNC business (most sockets in
>> >real applications do not use AIO, but select()/poll()/epoll())
>> >
>> >This also removes one cache line miss to access sk->sk_wq->flags
>> >in tcp_sendmsg()
>> >
>> >Signed-off-by: Eric Dumazet <edumazet@google.com>
>>
>> I just bisected down to this. This is causing a regression for me when
>> my nfs mount becomes stuck. I can easily reproduce this if you need to
>> test the fix.
>
>What do you mean by 'when nfs mount becomes stuck' ?
>
>Is this patch making nfs not functional , or does it make recovery from
>some nfs error bad ?
I can mount nfs on the host. But when I do something (compile a kernel
module in my case), it gets stuck. Then I cannot even ssh to the machine.
No messages in dmesg. I didn't debug it any further. I just bisected and
verified that this patch caused this behaviour.
^ permalink raw reply
* Re: [PATCH next-next 0/7] net: Cleanup IPv6 ip tunnels
From: Tom Herbert @ 2016-05-02 19:32 UTC (permalink / raw)
To: Alexander Duyck; +Cc: David Miller, Netdev, Kernel Team
In-Reply-To: <CAKgT0UfwyZW7kifpU18xtwT77=Zex3AzJp=xry=siW1NVCyX+A@mail.gmail.com>
On Fri, Apr 29, 2016 at 6:00 PM, Alexander Duyck
<alexander.duyck@gmail.com> wrote:
> On Fri, Apr 29, 2016 at 5:12 PM, Tom Herbert <tom@herbertland.com> wrote:
>> The IPv6 tunnel code is very different from IPv4 code. There is a lot
>> of redundancy with the IPv4 code, particularly in the GRE tunneling.
>>
>> This patch set cleans up the tunnel code to make the IPv6 code look
>> more like the IPv4 code and use common functions between the two
>> stacks where possible.
>>
>> This work should make it easier to maintain and extend the IPv6 ip
>> tunnels.
>>
>> Items in this patch set:
>> - Cleanup IPv6 tunnel receive path (ip6_tnl_rcv). Includes using
>> gro_cells and exporting ip6_tnl_rcv so the ip6_gre can call it
>> - Move GRE functions to common header file (tx functions) or
>> gre_demux.c (rx functions like gre_parse_header)
>> - Call common GRE functions from IPv6 GRE
>> - Create ip6_tnl_xmit (to be like ip_tunnel_xmit)
>>
>> Tested:
>> Ran super_netperf tests for TCP_RR and TCP_STREAM for:
>> - IPv4 over gre, gretap, gre6, gre6tap
>> - IPv6 over gre, gretap, gre6, gre6tap
>> - ipip
>> - ip6ip6
>> - ipip/gue
>> - IPv6 over gre/gue
>> - IPv4 over gre/gue
>
> You should probably add 2 additional test cases. One for IPv4 GRE/GUE
> w/ checksum on the GRE header, and same for IPv6. It was broken
> previously in terms of offloads so we need to make sure we don't
> introduce a regression and break it again.
>
Hi Alexander,
I did test GRE/GUE with checksum and remcsum for IPv4, that works okay.
Support for GUE with IPv6 is in the next patch set I am working on.
Thanks,
Tom
>> Tom Herbert (7):
>> ipv6: Cleanup IPv6 tunnel receive path
>> gre: Move utility functions to common headers
>> gre6: Cleanup GREv6 receive path, call common GRE functions
>> ipv6: Create ip6_tnl_xmit
>> gre: Create common functions for transmit
>> ipv6: Generic tunnel cleanup
>> gre6: Cleanup GREv6 transmit path, call common GRE functions
>>
>> include/net/gre.h | 104 +++++++++++++
>> include/net/ip6_tunnel.h | 11 +-
>> net/ipv4/gre_demux.c | 64 ++++++++
>> net/ipv4/ip_gre.c | 199 +++---------------------
>> net/ipv6/ip6_gre.c | 392 +++++++++--------------------------------------
>> net/ipv6/ip6_tunnel.c | 266 +++++++++++++++++++++-----------
>> 6 files changed, 452 insertions(+), 584 deletions(-)
>>
>> --
>> 2.8.0.rc2
>>
^ permalink raw reply
* Re: [PATCH] Bluetooth: Use hci_conn_hash_lookup_le
From: Julia Lawall @ 2016-05-02 19:33 UTC (permalink / raw)
To: Johan Hedberg
Cc: Julia Lawall, Marcel Holtmann, kernel-janitors, Gustavo Padovan,
David S. Miller, linux-bluetooth, netdev, linux-kernel
In-Reply-To: <20160502180256.GA22757@t440s>
On Mon, 2 May 2016, Johan Hedberg wrote:
> Hi,
>
> On Fri, Apr 29, 2016, Julia Lawall wrote:
> > --- a/net/bluetooth/mgmt.c
> > +++ b/net/bluetooth/mgmt.c
> > @@ -4773,7 +4773,8 @@ static int get_conn_info(struct sock *sk, struct hci_dev *hdev, void *data,
> > conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK,
> > &cp->addr.bdaddr);
> > else
> > - conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr);
> > + conn = hci_conn_hash_lookup_le(hdev, &cp->addr.bdaddr,
> > + cp->addr.type);
>
> I don't think is is correct. There are two possible domains for address
> types: the user space-facing interface that has three values: BR/EDR, LE
> public & LE random, and the internal one which maps to HCI that has two
> values: random or public. You'd need to convert from the former to the
> latter when making the lookup call, i.e:
>
> conn = hci_conn_hash_lookup_le(hdev, &cp->addr.bdaddr,
> le_addr_type(cp->addr.type));
OK, thanks for the feedback.
julia
>
>
> Johan
> --
> To unsubscribe from this list: send the line "unsubscribe kernel-janitors" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* Re: [PATCHv2 bluetooth-next 07/10] ipv6: introduce neighbour discovery ops
From: Hannes Frederic Sowa @ 2016-05-02 19:36 UTC (permalink / raw)
To: Alexander Aring, linux-wpan
Cc: kernel, marcel, jukka.rissanen, stefan, mcr, werner,
linux-bluetooth, netdev, David S . Miller, Alexey Kuznetsov,
James Morris, Hideaki YOSHIFUJI, Patrick McHardy
In-Reply-To: <1461140382-4784-8-git-send-email-aar@pengutronix.de>
On 20.04.2016 10:19, Alexander Aring wrote:
> This patch introduces neighbour discovery ops callback structure. The
> structure contains at first receive and transmit handling for NS/NA and
> userspace option field functionality.
>
> These callback offers 6lowpan different handling, such as 802.15.4 short
> address handling or RFC6775 (Neighbor Discovery Optimization for IPv6 over
> 6LoWPANs).
>
> Cc: David S. Miller <davem@davemloft.net>
> Cc: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
> Cc: James Morris <jmorris@namei.org>
> Cc: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
> Cc: Patrick McHardy <kaber@trash.net>
> Signed-off-by: Alexander Aring <aar@pengutronix.de>
> ---
> include/linux/netdevice.h | 3 ++
> include/net/ndisc.h | 96 +++++++++++++++++++++++++++++++++++++++++++----
> net/ipv6/addrconf.c | 1 +
> net/ipv6/ndisc.c | 71 ++++++++++++++++++++++++-----------
> net/ipv6/route.c | 2 +-
> 5 files changed, 144 insertions(+), 29 deletions(-)
>
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index 0052c42..bc60033 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -1677,6 +1677,9 @@ struct net_device {
> #ifdef CONFIG_NET_L3_MASTER_DEV
> const struct l3mdev_ops *l3mdev_ops;
> #endif
> +#if IS_ENABLED(CONFIG_IPV6)
> + const struct ndisc_ops *ndisc_ops;
> +#endif
>
> const struct header_ops *header_ops;
>
> diff --git a/include/net/ndisc.h b/include/net/ndisc.h
> index aac868e..14ed016 100644
> --- a/include/net/ndisc.h
> +++ b/include/net/ndisc.h
> @@ -110,7 +110,8 @@ struct ndisc_options {
>
> #define NDISC_OPT_SPACE(len) (((len)+2+7)&~7)
>
> -struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len,
> +struct ndisc_options *ndisc_parse_options(const struct net_device *dev,
> + u8 *opt, int opt_len,
> struct ndisc_options *ndopts);
>
> /*
> @@ -173,6 +174,93 @@ static inline struct neighbour *__ipv6_neigh_lookup(struct net_device *dev, cons
> return n;
> }
>
> +static inline int __ip6_ndisc_is_useropt(struct nd_opt_hdr *opt)
> +{
> + return opt->nd_opt_type == ND_OPT_RDNSS ||
> + opt->nd_opt_type == ND_OPT_DNSSL;
> +}
> +
> +#if IS_ENABLED(CONFIG_IPV6)
> +struct ndisc_ops {
> + int (*is_useropt)(struct nd_opt_hdr *opt);
> + void (*send_na)(struct net_device *dev,
> + const struct in6_addr *daddr,
> + const struct in6_addr *solicited_addr,
> + bool router, bool solicited,
> + bool override, bool inc_opt);
> + void (*recv_na)(struct sk_buff *skb);
> + void (*send_ns)(struct net_device *dev,
> + const struct in6_addr *solicit,
> + const struct in6_addr *daddr,
> + const struct in6_addr *saddr);
> + void (*recv_ns)(struct sk_buff *skb);
> +};
> +
> +static inline int ndisc_is_useropt(const struct net_device *dev,
> + struct nd_opt_hdr *opt)
> +{
> + if (likely(dev->ndisc_ops->is_useropt))
> + return dev->ndisc_ops->is_useropt(opt);
> + else
> + return 0;
> +}
> +
> +static inline void ndisc_send_na(struct net_device *dev,
> + const struct in6_addr *daddr,
> + const struct in6_addr *solicited_addr,
> + bool router, bool solicited, bool override,
> + bool inc_opt)
> +{
> + if (likely(dev->ndisc_ops->send_na))
> + dev->ndisc_ops->send_na(dev, daddr, solicited_addr, router,
> + solicited, override, inc_opt);
> +}
> +
> +static inline void ndisc_recv_na(struct sk_buff *skb)
> +{
> + if (likely(skb->dev->ndisc_ops->recv_na))
> + skb->dev->ndisc_ops->recv_na(skb);
> +}
> +
> +static inline void ndisc_send_ns(struct net_device *dev,
> + const struct in6_addr *solicit,
> + const struct in6_addr *daddr,
> + const struct in6_addr *saddr)
> +{
> + if (likely(dev->ndisc_ops->send_ns))
> + dev->ndisc_ops->send_ns(dev, solicit, daddr, saddr);
> +}
> +
> +static inline void ndisc_recv_ns(struct sk_buff *skb)
> +{
> + if (likely(skb->dev->ndisc_ops->recv_ns))
> + skb->dev->ndisc_ops->recv_ns(skb);
> +}
> +#else
> +static inline int ndisc_is_useropt(const struct net_device *dev,
> + struct nd_opt_hdr *opt)
> +{
> + return 0;
> +}
> +
> +static inline void ndisc_send_na(struct net_device *dev,
> + const struct in6_addr *daddr,
> + const struct in6_addr *solicited_addr,
> + bool router, bool solicited, bool override,
> + bool inc_opt) { }
> +
> +static inline void ndisc_recv_na(struct sk_buff *skb) { }
> +
> +static inline void ndisc_send_ns(struct net_device *dev,
> + const struct in6_addr *solicit,
> + const struct in6_addr *daddr,
> + const struct in6_addr *saddr) { }
> +
> +static inline void ndisc_recv_ns(struct sk_buff *skb) { }
> +#endif
Do those empty functions actually make sense? I wonder a bit because
6lowpan strictly depends on ipv6 and they should never be called without
IPv6, no?
> +
> +void ip6_register_ndisc_ops(struct net_device *dev);
> +
> int ndisc_init(void);
> int ndisc_late_init(void);
>
> @@ -181,14 +269,8 @@ void ndisc_cleanup(void);
>
> int ndisc_rcv(struct sk_buff *skb);
>
> -void ndisc_send_ns(struct net_device *dev, const struct in6_addr *solicit,
> - const struct in6_addr *daddr, const struct in6_addr *saddr);
> -
> void ndisc_send_rs(struct net_device *dev,
> const struct in6_addr *saddr, const struct in6_addr *daddr);
> -void ndisc_send_na(struct net_device *dev, const struct in6_addr *daddr,
> - const struct in6_addr *solicited_addr,
> - bool router, bool solicited, bool override, bool inc_opt);
>
> void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target);
>
> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
> index 54e18c2..a2ef04b 100644
> --- a/net/ipv6/addrconf.c
> +++ b/net/ipv6/addrconf.c
> @@ -3266,6 +3266,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
> idev = ipv6_add_dev(dev);
> if (IS_ERR(idev))
> return notifier_from_errno(PTR_ERR(idev));
> + ip6_register_ndisc_ops(dev);
Is it possible to register the ndisc options before we make the device
visible to the stack? Maybe even as a pointer to ipv6_add_dev.
> }
> break;
>
> diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
> index 176c7c4..297080a 100644
> --- a/net/ipv6/ndisc.c
> +++ b/net/ipv6/ndisc.c
> @@ -185,24 +185,25 @@ static struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur,
> return cur <= end && cur->nd_opt_type == type ? cur : NULL;
> }
>
> -static inline int ndisc_is_useropt(struct nd_opt_hdr *opt)
> +static inline int ip6_ndisc_is_useropt(struct nd_opt_hdr *opt)
> {
> - return opt->nd_opt_type == ND_OPT_RDNSS ||
> - opt->nd_opt_type == ND_OPT_DNSSL;
> + return __ip6_ndisc_is_useropt(opt);
> }
inline in C functions are not necessary.
>
> -static struct nd_opt_hdr *ndisc_next_useropt(struct nd_opt_hdr *cur,
> +static struct nd_opt_hdr *ndisc_next_useropt(const struct net_device *dev,
> + struct nd_opt_hdr *cur,
> struct nd_opt_hdr *end)
> {
> if (!cur || !end || cur >= end)
> return NULL;
> do {
> cur = ((void *)cur) + (cur->nd_opt_len << 3);
> - } while (cur < end && !ndisc_is_useropt(cur));
> - return cur <= end && ndisc_is_useropt(cur) ? cur : NULL;
> + } while (cur < end && !ndisc_is_useropt(dev, cur));
> + return cur <= end && ndisc_is_useropt(dev, cur) ? cur : NULL;
> }
>
> -struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len,
> +struct ndisc_options *ndisc_parse_options(const struct net_device *dev,
> + u8 *opt, int opt_len,
> struct ndisc_options *ndopts)
> {
> struct nd_opt_hdr *nd_opt = (struct nd_opt_hdr *)opt;
> @@ -243,7 +244,7 @@ struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len,
> break;
> #endif
> default:
> - if (ndisc_is_useropt(nd_opt)) {
> + if (ndisc_is_useropt(dev, nd_opt)) {
> ndopts->nd_useropts_end = nd_opt;
> if (!ndopts->nd_useropts)
> ndopts->nd_useropts = nd_opt;
> @@ -479,9 +480,11 @@ static void ndisc_send_skb(struct sk_buff *skb,
> rcu_read_unlock();
> }
>
> -void ndisc_send_na(struct net_device *dev, const struct in6_addr *daddr,
> - const struct in6_addr *solicited_addr,
> - bool router, bool solicited, bool override, bool inc_opt)
> +static void ip6_ndisc_send_na(struct net_device *dev,
> + const struct in6_addr *daddr,
> + const struct in6_addr *solicited_addr,
> + bool router, bool solicited, bool override,
> + bool inc_opt)
> {
> struct sk_buff *skb;
> struct in6_addr tmpaddr;
> @@ -555,8 +558,10 @@ static void ndisc_send_unsol_na(struct net_device *dev)
> in6_dev_put(idev);
> }
>
> -void ndisc_send_ns(struct net_device *dev, const struct in6_addr *solicit,
> - const struct in6_addr *daddr, const struct in6_addr *saddr)
> +static void ip6_ndisc_send_ns(struct net_device *dev,
> + const struct in6_addr *solicit,
> + const struct in6_addr *daddr,
> + const struct in6_addr *saddr)
> {
> struct sk_buff *skb;
> struct in6_addr addr_buf;
> @@ -702,7 +707,7 @@ static int pndisc_is_router(const void *pkey,
> return ret;
> }
>
> -static void ndisc_recv_ns(struct sk_buff *skb)
> +static void ip6_ndisc_recv_ns(struct sk_buff *skb)
> {
> struct nd_msg *msg = (struct nd_msg *)skb_transport_header(skb);
> const struct in6_addr *saddr = &ipv6_hdr(skb)->saddr;
> @@ -738,7 +743,7 @@ static void ndisc_recv_ns(struct sk_buff *skb)
> return;
> }
>
> - if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) {
> + if (!ndisc_parse_options(dev, msg->opt, ndoptlen, &ndopts)) {
> ND_PRINTK(2, warn, "NS: invalid ND options\n");
> return;
> }
> @@ -874,7 +879,7 @@ out:
> in6_dev_put(idev);
> }
>
> -static void ndisc_recv_na(struct sk_buff *skb)
> +static void ip6_ndisc_recv_na(struct sk_buff *skb)
> {
> struct nd_msg *msg = (struct nd_msg *)skb_transport_header(skb);
> struct in6_addr *saddr = &ipv6_hdr(skb)->saddr;
> @@ -912,7 +917,7 @@ static void ndisc_recv_na(struct sk_buff *skb)
> idev->cnf.drop_unsolicited_na)
> return;
>
> - if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) {
> + if (!ndisc_parse_options(dev, msg->opt, ndoptlen, &ndopts)) {
> ND_PRINTK(2, warn, "NS: invalid ND option\n");
> return;
> }
> @@ -1019,7 +1024,7 @@ static void ndisc_recv_rs(struct sk_buff *skb)
> goto out;
>
> /* Parse ND options */
> - if (!ndisc_parse_options(rs_msg->opt, ndoptlen, &ndopts)) {
> + if (!ndisc_parse_options(skb->dev, rs_msg->opt, ndoptlen, &ndopts)) {
> ND_PRINTK(2, notice, "NS: invalid ND option, ignored\n");
> goto out;
> }
> @@ -1137,7 +1142,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
> return;
> }
>
> - if (!ndisc_parse_options(opt, optlen, &ndopts)) {
> + if (!ndisc_parse_options(skb->dev, opt, optlen, &ndopts)) {
> ND_PRINTK(2, warn, "RA: invalid ND options\n");
> return;
> }
> @@ -1424,7 +1429,8 @@ skip_routeinfo:
> struct nd_opt_hdr *p;
> for (p = ndopts.nd_useropts;
> p;
> - p = ndisc_next_useropt(p, ndopts.nd_useropts_end)) {
> + p = ndisc_next_useropt(skb->dev, p,
> + ndopts.nd_useropts_end)) {
> ndisc_ra_useropt(skb, p);
> }
> }
> @@ -1462,7 +1468,7 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
> return;
> }
>
> - if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts))
> + if (!ndisc_parse_options(skb->dev, msg->opt, ndoptlen, &ndopts))
> return;
>
> if (!ndopts.nd_opts_rh) {
> @@ -1783,6 +1789,29 @@ int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write, void __user *bu
>
> #endif
>
> +static const struct ndisc_ops ip6_ndisc_ops = {
> + .is_useropt = ip6_ndisc_is_useropt,
> + .send_na = ip6_ndisc_send_na,
> + .recv_na = ip6_ndisc_recv_na,
> + .send_ns = ip6_ndisc_send_ns,
> + .recv_ns = ip6_ndisc_recv_ns,
> +};
> +
> +void ip6_register_ndisc_ops(struct net_device *dev)
> +{
> + switch (dev->type) {
> + default:
> + if (dev->ndisc_ops) {
> + ND_PRINTK(2, warn,
> + "%s: ndisc_ops already defined for interface type=%d\n",
> + __func__, dev->type);
> + } else {
> + dev->ndisc_ops = &ip6_ndisc_ops;
> + }
> + break;
I would be more stricht with validation:
if (!WARN_ON(dev->ndisc_ops))
dev->ndisc_ops = &ip6_ndisc_ops;
> + }
> +}
> +
> static int __net_init ndisc_net_init(struct net *net)
> {
> struct ipv6_pinfo *np;
> diff --git a/net/ipv6/route.c b/net/ipv6/route.c
> index cc180b3..5fa276d 100644
> --- a/net/ipv6/route.c
> +++ b/net/ipv6/route.c
> @@ -2149,7 +2149,7 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_bu
> * first-hop router for the specified ICMP Destination Address.
> */
>
> - if (!ndisc_parse_options(msg->opt, optlen, &ndopts)) {
> + if (!ndisc_parse_options(skb->dev, msg->opt, optlen, &ndopts)) {
> net_dbg_ratelimited("rt6_redirect: invalid ND options\n");
> return;
> }
>
^ permalink raw reply
* Re: [PATCHv2 bluetooth-next 04/10] ndisc: add addr_len parameter to ndisc_opt_addr_space
From: Hannes Frederic Sowa @ 2016-05-02 19:37 UTC (permalink / raw)
To: Alexander Aring, linux-wpan
Cc: kernel, marcel, jukka.rissanen, stefan, mcr, werner,
linux-bluetooth, netdev, David S . Miller, Alexey Kuznetsov,
James Morris, Hideaki YOSHIFUJI, Patrick McHardy
In-Reply-To: <1461140382-4784-5-git-send-email-aar@pengutronix.de>
On 20.04.2016 10:19, Alexander Aring wrote:
> This patch makes the address length as argument for the
> ndisc_opt_addr_space function. This is necessary to handle addresses
> which don't use dev->addr_len as address length.
Would it make sense for patch 4, 5 and 6 to add the operation to ndisc_ops?
Thanks,
Hannes
^ permalink raw reply
* Re: [PATCH v2] net: macb: do not scan PHYs manually
From: Josh Cartwright @ 2016-05-02 19:38 UTC (permalink / raw)
To: Florian Fainelli
Cc: Nicolas Ferre, Andrew Lunn, Nathan Sullivan, netdev, linux-kernel,
Alexandre Belloni
In-Reply-To: <5727A5C2.804@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 2958 bytes --]
On Mon, May 02, 2016 at 12:08:50PM -0700, Florian Fainelli wrote:
> On 02/05/16 11:36, Josh Cartwright wrote:
> > On Fri, Apr 29, 2016 at 02:40:53PM +0200, Nicolas Ferre wrote:
> > [..]
> >>> static int macb_mii_init(struct macb *bp)
> >>> {
> >>> struct macb_platform_data *pdata;
> >>> struct device_node *np;
> >>> - int err = -ENXIO, i;
> >>> + int err = -ENXIO;
> >>>
> >>> /* Enable management port */
> >>> macb_writel(bp, NCR, MACB_BIT(MPE));
> >>> @@ -446,33 +497,10 @@ static int macb_mii_init(struct macb *bp)
> >>> dev_set_drvdata(&bp->dev->dev, bp->mii_bus);
> >>>
> >>> np = bp->pdev->dev.of_node;
> >>> - if (np) {
> >>> - /* try dt phy registration */
> >>> - err = of_mdiobus_register(bp->mii_bus, np);
> >>> -
> >>> - /* fallback to standard phy registration if no phy were
> >>> - * found during dt phy registration
> >>> - */
> >>> - if (!err && !phy_find_first(bp->mii_bus)) {
> >>> - for (i = 0; i < PHY_MAX_ADDR; i++) {
> >>> - struct phy_device *phydev;
> >>> -
> >>> - phydev = mdiobus_scan(bp->mii_bus, i);
> >>> - if (IS_ERR(phydev)) {
> >>> - err = PTR_ERR(phydev);
> >>> - break;
> >>> - }
> >>> - }
> >>> -
> >>> - if (err)
> >>> - goto err_out_unregister_bus;
> >>> - }
> >>> - } else {
> >>> - if (pdata)
> >>> - bp->mii_bus->phy_mask = pdata->phy_mask;
> >>> -
> >>> - err = mdiobus_register(bp->mii_bus);
> >>> - }
> >>> + if (np)
> >>> + err = macb_mii_of_init(bp, np);
> >>> + else
> >>> + err = macb_mii_pdata_init(bp, pdata);
> >>>
> >>> if (err)
> >>> goto err_out_free_mdiobus;
> >>
> >> I'm okay with this. Thanks for having taken the initiative to implement it.
> >
> > Unfortunately, I don't think it's going to be as straightforward
> > as I originally thought. Still doable, but more complicated.
> >
> > In particular, the macb bindings allow for a user to specify a
> > 'reset-gpios' property _at the PHY_ level, which is consumed by the
> > macb to adjust the PHY reset state on remove.
>
> In fact, not just on remove, anytime there is an opportunity to save
> power (interface down, closed) and putting the PHY into reset is usually
> guaranteed to be saving more power than e.g: a BMCR power down.
I can understand how that might have been a long term goal of managing a
reset GPIO in general, however as it stands in the macb driver the only
callsite where the reset gpio is tweaked macb_remove().
> > My question is: why is the PHY reset GPIO management not the
> > responsibility of the PHY driver/core itself?
>
> Well, this is actually being worked on at the moment by Sergei, since
> there is not necessarily a reason why PHYLIB can't deal with that:
>
> https://lkml.org/lkml/2016/4/28/831
Cool, thanks. I was about to see about implementing this...but since
it's already been done, I'll rebase my set on Sergei's changes.
Thanks,
Josh
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]
^ permalink raw reply
* Re: [PATCHv2 bluetooth-next 08/10] ipv6: export ndisc functions
From: Hannes Frederic Sowa @ 2016-05-02 19:39 UTC (permalink / raw)
To: Alexander Aring, linux-wpan
Cc: kernel, marcel, jukka.rissanen, stefan, mcr, werner,
linux-bluetooth, netdev, David S . Miller, Alexey Kuznetsov,
James Morris, Hideaki YOSHIFUJI, Patrick McHardy
In-Reply-To: <1461140382-4784-9-git-send-email-aar@pengutronix.de>
On 20.04.2016 10:19, Alexander Aring wrote:
> This patch exports some neighbour discovery functions which can be used
> by 6lowpan neighbour discovery ops functionality then.
>
> Cc: David S. Miller <davem@davemloft.net>
> Cc: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
> Cc: James Morris <jmorris@namei.org>
> Cc: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
> Cc: Patrick McHardy <kaber@trash.net>
> Signed-off-by: Alexander Aring <aar@pengutronix.de>
> ---
> include/net/ndisc.h | 16 ++++++++++++++++
> net/ipv6/addrconf.c | 1 +
> net/ipv6/ndisc.c | 28 ++++++++++------------------
> 3 files changed, 27 insertions(+), 18 deletions(-)
>
> diff --git a/include/net/ndisc.h b/include/net/ndisc.h
> index 14ed016..35a4396 100644
> --- a/include/net/ndisc.h
> +++ b/include/net/ndisc.h
> @@ -53,6 +53,15 @@ enum {
>
> #include <net/neighbour.h>
>
> +/* Set to 3 to get tracing... */
> +#define ND_DEBUG 1
> +
> +#define ND_PRINTK(val, level, fmt, ...) \
> +do { \
> + if (val <= ND_DEBUG) \
> + net_##level##_ratelimited(fmt, ##__VA_ARGS__); \
> +} while (0)
> +
If the debug messages are well thought out, I think we could install
them always on debug level.
There are valid users now, so
Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
^ permalink raw reply
* Re: [PATCH next-next 0/7] net: Cleanup IPv6 ip tunnels
From: Alexander Duyck @ 2016-05-02 19:42 UTC (permalink / raw)
To: Tom Herbert; +Cc: David Miller, Netdev, Kernel Team
In-Reply-To: <CALx6S379KxUkLRaE70AtaPgM8NqEieavd1+hcX=Z4Jfdn=CFDw@mail.gmail.com>
On Mon, May 2, 2016 at 12:32 PM, Tom Herbert <tom@herbertland.com> wrote:
> On Fri, Apr 29, 2016 at 6:00 PM, Alexander Duyck
> <alexander.duyck@gmail.com> wrote:
>> On Fri, Apr 29, 2016 at 5:12 PM, Tom Herbert <tom@herbertland.com> wrote:
>>> The IPv6 tunnel code is very different from IPv4 code. There is a lot
>>> of redundancy with the IPv4 code, particularly in the GRE tunneling.
>>>
>>> This patch set cleans up the tunnel code to make the IPv6 code look
>>> more like the IPv4 code and use common functions between the two
>>> stacks where possible.
>>>
>>> This work should make it easier to maintain and extend the IPv6 ip
>>> tunnels.
>>>
>>> Items in this patch set:
>>> - Cleanup IPv6 tunnel receive path (ip6_tnl_rcv). Includes using
>>> gro_cells and exporting ip6_tnl_rcv so the ip6_gre can call it
>>> - Move GRE functions to common header file (tx functions) or
>>> gre_demux.c (rx functions like gre_parse_header)
>>> - Call common GRE functions from IPv6 GRE
>>> - Create ip6_tnl_xmit (to be like ip_tunnel_xmit)
>>>
>>> Tested:
>>> Ran super_netperf tests for TCP_RR and TCP_STREAM for:
>>> - IPv4 over gre, gretap, gre6, gre6tap
>>> - IPv6 over gre, gretap, gre6, gre6tap
>>> - ipip
>>> - ip6ip6
>>> - ipip/gue
>>> - IPv6 over gre/gue
>>> - IPv4 over gre/gue
>>
>> You should probably add 2 additional test cases. One for IPv4 GRE/GUE
>> w/ checksum on the GRE header, and same for IPv6. It was broken
>> previously in terms of offloads so we need to make sure we don't
>> introduce a regression and break it again.
>>
> Hi Alexander,
>
> I did test GRE/GUE with checksum and remcsum for IPv4, that works okay.
>
> Support for GUE with IPv6 is in the next patch set I am working on.
>
> Thanks,
> Tom
Just so it is clear I am talking about having a checksum in the GRE
header, not the GUE header. If there is a GRE checksum present we
have to force software segmentation since we don't have any means of
pointing to the header in a way that is meaningful for hardware. As
long as we don't see any regressions I am good with these changes.
Thanks.
- Alex
^ permalink raw reply
* Re: [PATCHv2 bluetooth-next 00/10] 6lowpan: introduce basic 6lowpan-nd
From: Hannes Frederic Sowa @ 2016-05-02 19:52 UTC (permalink / raw)
To: Marcel Holtmann, Alexander Aring, David S. Miller
Cc: linux-wpan-u79uwXL29TY76Z2rM5mHXA, kernel-bIcnvbaLZ9MEGnE8C9+IrQ,
Jukka Rissanen, Stefan Schmidt, mcr-SWp7JaYWvAQV+D8aMU/kSg,
Werner Almesberger, Linux Bluetooth, Network Development,
Alexey Kuznetsov, James Morris, Hideaki YOSHIFUJI,
Patrick McHardy
In-Reply-To: <D212A5BF-A414-403B-A409-1F8C2D279883-kz+m5ild9QBg9hUCZPvPmw@public.gmane.org>
On 02.05.2016 19:25, Marcel Holtmann wrote:
> Hi Dave,
>
>> this patch series introduces a layer for IPv6 neighbour discovery. At first
>> it introduce the "ndisc_ops" to run a different handling for recv/send of
>> NA/NS messages. The use case for such ndisc operation is RFC 6775 [0].
>> Which describes a different neighbour discovery handling for 6LoWPAN networks.
>>
>> I didn't implement RFC 6775 in this patch series, but introduce callback
>> structure for replace different functions in ndisc implementation might be
>> the right direction.
>>
>> Another use case would be RFC 7400 [1] which describes a new option field to
>> getting capabilities of 6LoWPAN next header compression methods.
>>
>> What I implemented is a necessary functionality to handle short address for
>> 802.15.4 6LoWPAN networks. The L2-Layer "802.15.4" can have two different
>> link-layer addresses which can be used mixed at the same time inside 802.15.4
>> networks. To deal with such behaviour in ndisc, it is defined at RFC 4944 [2].
>> The bad news is, that I saw different handling of such handling. What Linux
>> will do is to add two source/target address information option fields, each
>> with different length, if short address is valid (can also not be given).
>> Example:
>>
>> - WPAN interface address settings
>> - extended addr (must always be there)
>> - short addr (0xfffe or 0xffff -> invalid)
>>
>> Will add an extended addr to source/target address information option field.
>> If short addr is in some valid range, then both address will be added to
>> the option fields. Indicated are these different address types by the length
>> field (extended -> length=2, short -> length=1), according to [1].
>>
>> The tested 6LoWPAN implementation (RIOT-OS) allows only one source/target
>> option field which is short XOR extended, otherwise it will be dropped.
>> There is some lack of information there [2] and I don't know how do deal with
>> it right, maybe we need to update the implementation there if it's really
>> wrong.
>>
>> To save such information for each neighbour we use the already implemented
>> neighbour private data which some casting strategy for 6LoWPAN and 6LoWPAN
>> link-layer specific data e.g. 802.15.4 short address handling.
>>
>> Additional I implemented to add 6CO to the is_useropt callback in case of
>> 6LoWPAN interface. The 6CO option will currently parsed in userspace which
>> are placed in RA-Messages.
>>
>> The ndisc_ops are not finished yet, of course we need handling for RS messages
>> to place the 802.15.4 short address there as well and then also processing
>> of RA messages for the 802.15.4 SLLAO option field.
>>
>> - Alex
>>
>> [0] https://tools.ietf.org/html/rfc6775
>> [1] https://tools.ietf.org/html/rfc7400#section-3.3
>> [2] https://tools.ietf.org/html/rfc4944#section-8
>>
>> Cc: David S. Miller <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
>> Cc: Alexey Kuznetsov <kuznet-v/Mj1YrvjDBInbfyfbPRSQ@public.gmane.org>
>> Cc: James Morris <jmorris-gx6/JNMH7DfYtjvyW6yDsg@public.gmane.org>
>> Cc: Hideaki YOSHIFUJI <yoshfuji-VfPWfsRibaP+Ru+s062T9g@public.gmane.org>
>> Cc: Patrick McHardy <kaber-dcUjhNyLwpNeoWH0uzbU5w@public.gmane.org>
>>
>> changes since v2:
>> - replace #ifdef CONFIG_IPV6 to #if IS_ENABLED(...)
>> - replace #ifdef CONFIG_IEEE802154... to #if IS_ENABLED(...)
>> - add more #if IS_ENABLED(CONFIG_IPV6) in ndisc.h
>>
>> Alexander Aring (10):
>> 6lowpan: add private neighbour data
>> 6lowpan: add 802.15.4 short addr slaac
>> 6lowpan: remove ipv6 module request
>> ndisc: add addr_len parameter to ndisc_opt_addr_space
>> ndisc: add addr_len parameter to ndisc_opt_addr_data
>> ndisc: add addr_len parameter to ndisc_fill_addr_option
>> ipv6: introduce neighbour discovery ops
>> ipv6: export ndisc functions
>> 6lowpan: introduce 6lowpan-nd
>> 6lowpan: add support for 802.15.4 short addr handling
>>
>> include/linux/netdevice.h | 6 +-
>> include/net/6lowpan.h | 24 ++
>> include/net/addrconf.h | 3 +
>> include/net/ndisc.h | 124 ++++++++-
>> net/6lowpan/6lowpan_i.h | 2 +
>> net/6lowpan/Makefile | 2 +-
>> net/6lowpan/core.c | 50 +++-
>> net/6lowpan/iphc.c | 167 +++++++++--
>> net/6lowpan/ndisc.c | 633 ++++++++++++++++++++++++++++++++++++++++++
>> net/bluetooth/6lowpan.c | 2 +
>> net/ieee802154/6lowpan/core.c | 12 +
>> net/ieee802154/6lowpan/tx.c | 107 ++++---
>> net/ipv6/addrconf.c | 7 +-
>> net/ipv6/ndisc.c | 132 +++++----
>> net/ipv6/route.c | 4 +-
>> 15 files changed, 1117 insertions(+), 158 deletions(-)
>> create mode 100644 net/6lowpan/ndisc.c
>
> is there a chance that we get input into this patch set? I wonder also if it would be acceptable to take this through bluetooth-next or should it better go straight into net-next?
My proposal would be that the IPv6 patches go via net-next to reduce
merge conflicts with maybe upcoming changes. If they are split up, they
seem very much self contained and easy to review. The rest seems to be
also very much self contained and can go in via bluetooth-next, then.
What do you think?
Bye,
Hannes
^ permalink raw reply
* Re: [PATCH net-next 1/2] net: SOCKWQ_ASYNC_NOSPACE optimizations
From: Eric Dumazet @ 2016-05-02 20:23 UTC (permalink / raw)
To: Jiri Pirko; +Cc: Eric Dumazet, David S . Miller, netdev, eladr, idosch
In-Reply-To: <20160502191229.GA1946@nanopsycho.orion>
On Mon, 2016-05-02 at 21:12 +0200, Jiri Pirko wrote:
> Mon, May 02, 2016 at 06:22:18PM CEST, eric.dumazet@gmail.com wrote:
> >On Mon, 2016-05-02 at 18:16 +0200, Jiri Pirko wrote:
> >> Mon, Apr 25, 2016 at 07:39:32PM CEST, edumazet@google.com wrote:
> >> >SOCKWQ_ASYNC_NOSPACE is tested in sock_wake_async()
> >> >so that a SIGIO signal is sent when needed.
> >> >
> >> >tcp_sendmsg() clears the bit.
> >> >tcp_poll() sets the bit when stream is not writeable.
> >> >
> >> >We can avoid two atomic operations by first checking if socket
> >> >is actually interested in the FASYNC business (most sockets in
> >> >real applications do not use AIO, but select()/poll()/epoll())
> >> >
> >> >This also removes one cache line miss to access sk->sk_wq->flags
> >> >in tcp_sendmsg()
> >> >
> >> >Signed-off-by: Eric Dumazet <edumazet@google.com>
> >>
> >> I just bisected down to this. This is causing a regression for me when
> >> my nfs mount becomes stuck. I can easily reproduce this if you need to
> >> test the fix.
> >
> >What do you mean by 'when nfs mount becomes stuck' ?
> >
> >Is this patch making nfs not functional , or does it make recovery from
> >some nfs error bad ?
>
> I can mount nfs on the host. But when I do something (compile a kernel
> module in my case), it gets stuck. Then I cannot even ssh to the machine.
> No messages in dmesg. I didn't debug it any further. I just bisected and
> verified that this patch caused this behaviour.
Interesting.
It looks like net/sunrpc/xprtsock.c should set SOCK_FASYNC
even if it is not actually using fasync_list
Could you try this quick hack to check if this is the right way ?
Thanks !
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index a6c68dc086af83233ee315642638f4a1990ee622..b90c5397b5e137c6cc8accad6eebe2b876363d4e 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -1950,6 +1950,7 @@ static int xs_local_finish_connecting(struct rpc_xprt *xprt,
sk->sk_user_data = xprt;
sk->sk_data_ready = xs_data_ready;
sk->sk_write_space = xs_udp_write_space;
+ sock_set_flag(sk, SOCK_FASYNC);
sk->sk_error_report = xs_error_report;
sk->sk_allocation = GFP_NOIO;
@@ -2136,6 +2137,7 @@ static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)
sk->sk_user_data = xprt;
sk->sk_data_ready = xs_data_ready;
sk->sk_write_space = xs_udp_write_space;
+ sock_set_flag(sk, SOCK_FASYNC);
sk->sk_allocation = GFP_NOIO;
xprt_set_connected(xprt);
@@ -2237,6 +2239,7 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)
sk->sk_data_ready = xs_tcp_data_ready;
sk->sk_state_change = xs_tcp_state_change;
sk->sk_write_space = xs_tcp_write_space;
+ sock_set_flag(sk, SOCK_FASYNC);
sk->sk_error_report = xs_error_report;
sk->sk_allocation = GFP_NOIO;
^ permalink raw reply related
* NULL dereference on v4.1.x while enabling VF
From: William Dauchy @ 2016-05-02 20:25 UTC (permalink / raw)
To: NETDEV, intel-wired-lan; +Cc: Emil Tantilov, Jeff Kirsher, Alex Duyck
Hello,
I am getting a NULL dereference on v4.1.x while enabling VF on a ixgbe
( Intel Corporation 82599ES 10-Gigabit) card during boot.
It seems to be related to a race since I don't have the issue if I
test it a few seconds after boot. I had the same issue while testing
on v4.5.x
What can I do to help debug the issue?
ip link set dev eth0 up
echo 32 > /sys/class/net/eth0/device/sriov_numvfs
part of the dmesg:
ixgbe 0000:82:00.1: removed PHC on eth1
ixgbe 0000:82:00.1: Multiqueue Enabled: Rx Queue count = 2, Tx Queue count = 2
ixgbe 0000:82:00.1: registered PHC device on eth1
ixgbe 0000:82:00.1 eth1: detected SFP+: 4
ixgbe 0000:82:00.1 eth1: NIC Link is Up 10 Gbps, Flow Control: RX/TX
ixgbevf: Could not enable Tx Queue 0
ixgbevf: Could not enable Tx Queue 1
8021q: adding VLAN 0 to HW filter on device eth2
ixgbe 0000:82:00.0 eth0: VF Reset msg received from vf 0
ixgbe 0000:82:00.0: VF 0 has no MAC address assigned, you may have to
assign one manually
BUG: unable to handle kernel NULL pointer dereference at 0000000000000008
ixgbevf: Could not enable Tx Queue 0
ixgbevf: Could not enable Tx Queue 1
IP: [<ffffffff813d3873>] ixgbevf_alloc_rx_buffers+0x53/0x170
PGD 0
Oops: 0000 [#1] PREEMPT SMP
Modules linked in:
CPU: 8 PID: 1034 Comm: kworker/8:1 Tainted: G W 4.1.23 #1
Workqueue: events ixgbevf_service_task
task: ffff882021558000 ti: ffff882021554000 task.ti: ffff882021554000
RIP: 0010:[<ffffffff813d3873>] [<ffffffff813d3873>]
ixgbevf_alloc_rx_buffers+0x53/0x170
RSP: 0018:ffff882021557c58 EFLAGS: 00010246
RAX: 0000000000000200 RBX: ffff88201ccc09c0 RCX: 0000000000000000
RDX: ffffc9000e860000 RSI: 00000000000001ff RDI: ffff88201ccc09c0
RBP: ffff882021557c98 R08: 0000000000000001 R09: 0000000000000001
R10: ffff882021558000 R11: 000000000000017e R12: 0000000000000000
R13: 00000000fffffe00 R14: 0000000000000000 R15: 0000000000000000
FS: 0000000000000000(0000) GS:ffff88207fc00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000000008 CR3: 0000000001a08000 CR4: 00000000001406e0
Stack:
ffff88201d630940 01ff00000000000a ffff882021557c78 ffff88201d630c28
ffff88201d630940 0000000000000009 ffff88201ccc09c0 0000000000000000
ffff882021557d18 ffffffff813d54b8 0000102800001028 0000000000000000
Call Trace:
[<ffffffff813d54b8>] ixgbevf_configure+0x50d/0x54e
[<ffffffff813d6a11>] ? ixgbevf_down+0x2ba/0x2cb
[<ffffffff813d6687>] ixgbevf_up+0x13/0x1f
[<ffffffff813d6a85>] ixgbevf_reinit_locked+0x63/0x6c
[<ffffffff813d76c9>] ixgbevf_service_task+0xe5/0x2dc
[<ffffffff810743b7>] process_one_work+0x275/0x4f2
[<ffffffff81074ae1>] worker_thread+0x1f5/0x2a9
[<ffffffff810748ec>] ? rescuer_thread+0x289/0x289
[<ffffffff810748ec>] ? rescuer_thread+0x289/0x289
[<ffffffff81079775>] kthread+0xc5/0xcd
[<ffffffff81577e9f>] ? _raw_spin_unlock_irq+0x2d/0x4c
[<ffffffff810796b0>] ? __kthread_parkme+0x87/0x87
[<ffffffff81578a82>] ret_from_fork+0x42/0x70
[<ffffffff810796b0>] ? __kthread_parkme+0x87/0x87
Code: 0f 84 33 01 00 00 44 0f b7 67 2e 48 89 fb 0f b7 47 2c 4d 89 e5
4d 89 e6 4d 6b e4 18 49 c1 e6 04 4c 03 77 18 41 29 c5 4c 03 67 38 <49>
83 7c 24 08 00 0f 85 9e 00 00 00 65 8b 05 2a dc c3 7e 48 98
RIP [<ffffffff813d3873>] ixgbevf_alloc_rx_buffers+0x53/0x170
RSP <ffff882021557c58>
CR2: 0000000000000008
---[ end trace 6e4d9e7fa97d4fca ]---
BUG: sleeping function called from invalid context at kernel/locking/rwsem.c:21
in_atomic(): 0, irqs_disabled(): 1, pid: 1034, name: kworker/8:1
INFO: lockdep is turned off.
irq event stamp: 43238
hardirqs last enabled at (43237): [<ffffffff81577efd>]
_raw_spin_unlock_irqrestore+0x3f/0x60
hardirqs last disabled at (43238): [ 41.225859] 8021q: adding VLAN 0
to HW filter on device eth3
[<ffffffff8157a4b3>] error_sti+0x5/0x6
Thanks,
--
William
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox