* [PATCH net-next 0/3] fix use-after-free bugs in skb list processing
From: Edward Cree @ 2018-07-06 17:01 UTC (permalink / raw)
To: davem; +Cc: netdev
A couple of bugs in skb list handling were spotted by Dan Carpenter, with
the help of Smatch; following up on them I found a couple more similar
cases. This series fixes them by changing the relevant loops to use the
dequeue-enqueue model (rather than in-place list modification), and then
adds a list.h helper macro to refactor code using the dequeue-enqueue
model.
Edward Cree (3):
net: core: fix uses-after-free in list processing
netfilter: fix use-after-free in NF_HOOK_LIST
net: refactor dequeue-model list processing
include/linux/list.h | 15 +++++++++++++++
include/linux/netfilter.h | 16 +++++++++-------
net/core/dev.c | 23 +++++++++++++----------
net/ipv4/ip_input.c | 10 ++++------
net/ipv6/ip6_input.c | 10 ++++------
5 files changed, 45 insertions(+), 29 deletions(-)
^ permalink raw reply
* [PATCH net-next 1/3] net: core: fix uses-after-free in list processing
From: Edward Cree @ 2018-07-06 17:06 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <3c007026-e27a-6ac9-4a29-9746840e24ed@solarflare.com>
In netif_receive_skb_list_internal(), all of skb_defer_rx_timestamp(),
do_xdp_generic() and enqueue_to_backlog() can lead to kfree(skb). Thus,
we cannot wait until after they return to remove the skb from the list;
instead, we remove it first and, in the pass case, add it to a sublist
afterwards.
In the case of enqueue_to_backlog() we have already decided not to pass
when we call the function, so we do not need a sublist.
Fixes: 7da517a3bc52 ("net: core: Another step of skb receive list processing")
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Edward Cree <ecree@solarflare.com>
---
net/core/dev.c | 21 +++++++++++++--------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index 89825c1eccdc..ce4583564e00 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4982,25 +4982,30 @@ static void netif_receive_skb_list_internal(struct list_head *head)
{
struct bpf_prog *xdp_prog = NULL;
struct sk_buff *skb, *next;
+ struct list_head sublist;
+ INIT_LIST_HEAD(&sublist);
list_for_each_entry_safe(skb, next, head, list) {
net_timestamp_check(netdev_tstamp_prequeue, skb);
- if (skb_defer_rx_timestamp(skb))
- /* Handled, remove from list */
- list_del(&skb->list);
+ list_del(&skb->list);
+ if (!skb_defer_rx_timestamp(skb))
+ list_add_tail(&skb->list, &sublist);
}
+ list_splice_init(&sublist, head);
if (static_branch_unlikely(&generic_xdp_needed_key)) {
preempt_disable();
rcu_read_lock();
list_for_each_entry_safe(skb, next, head, list) {
xdp_prog = rcu_dereference(skb->dev->xdp_prog);
- if (do_xdp_generic(xdp_prog, skb) != XDP_PASS)
- /* Dropped, remove from list */
- list_del(&skb->list);
+ list_del(&skb->list);
+ if (do_xdp_generic(xdp_prog, skb) == XDP_PASS)
+ list_add_tail(&skb->list, &sublist);
}
rcu_read_unlock();
preempt_enable();
+ /* Put passed packets back on main list */
+ list_splice_init(&sublist, head);
}
rcu_read_lock();
@@ -5011,9 +5016,9 @@ static void netif_receive_skb_list_internal(struct list_head *head)
int cpu = get_rps_cpu(skb->dev, skb, &rflow);
if (cpu >= 0) {
- enqueue_to_backlog(skb, cpu, &rflow->last_qtail);
- /* Handled, remove from list */
+ /* Will be handled, remove from list */
list_del(&skb->list);
+ enqueue_to_backlog(skb, cpu, &rflow->last_qtail);
}
}
}
^ permalink raw reply related
* [PATCH net-next 2/3] netfilter: fix use-after-free in NF_HOOK_LIST
From: Edward Cree @ 2018-07-06 17:07 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <3c007026-e27a-6ac9-4a29-9746840e24ed@solarflare.com>
nf_hook() can free the skb, so we need to remove it from the list before
calling, and add passed skbs to a sublist afterwards.
Fixes: 17266ee93984 ("net: ipv4: listified version of ip_rcv")
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Edward Cree <ecree@solarflare.com>
---
include/linux/netfilter.h | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index 5a5e0a2ab2a3..23b48de8c2e2 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -294,12 +294,16 @@ NF_HOOK_LIST(uint8_t pf, unsigned int hook, struct net *net, struct sock *sk,
int (*okfn)(struct net *, struct sock *, struct sk_buff *))
{
struct sk_buff *skb, *next;
+ struct list_head sublist;
+ INIT_LIST_HEAD(&sublist);
list_for_each_entry_safe(skb, next, head, list) {
- int ret = nf_hook(pf, hook, net, sk, skb, in, out, okfn);
- if (ret != 1)
- list_del(&skb->list);
+ list_del(&skb->list);
+ if (nf_hook(pf, hook, net, sk, skb, in, out, okfn) == 1)
+ list_add_tail(&skb->list, &sublist);
}
+ /* Put passed packets back on main list */
+ list_splice(&sublist, head);
}
/* Call setsockopt() */
^ permalink raw reply related
* [PATCH net-next 3/3] net: refactor dequeue-model list processing
From: Edward Cree @ 2018-07-06 17:07 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <3c007026-e27a-6ac9-4a29-9746840e24ed@solarflare.com>
New macro list_for_each_entry_dequeue loops over a list by popping entries
from the head, allowing a more concise expression of the dequeue-enqueue
model of list processing and avoiding the need for a 'next' pointer (as
used in list_for_each_entry_safe).
Signed-off-by: Edward Cree <ecree@solarflare.com>
---
include/linux/list.h | 15 +++++++++++++++
include/linux/netfilter.h | 6 ++----
net/core/dev.c | 6 ++----
net/ipv4/ip_input.c | 10 ++++------
net/ipv6/ip6_input.c | 10 ++++------
5 files changed, 27 insertions(+), 20 deletions(-)
diff --git a/include/linux/list.h b/include/linux/list.h
index de04cc5ed536..150751d03441 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -645,6 +645,21 @@ static inline void list_splice_tail_init(struct list_head *list,
#define list_safe_reset_next(pos, n, member) \
n = list_next_entry(pos, member)
+/**
+ * list_for_each_entry_dequeue - iterate over list by removing entries
+ * @pos: the type * to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the list_head within the struct.
+ *
+ * Iterate over list of given type, removing each entry from the list before
+ * running the loop body. The loop will run until the list is empty, so
+ * adding an entry back onto the list in the loop body will requeue it.
+ */
+#define list_for_each_entry_dequeue(pos, head, member) \
+ while (!list_empty(head) && \
+ (pos = list_first_entry(head, typeof(*pos), member)) && \
+ (list_del(&pos->member), true))
+
/*
* Double linked lists with a single pointer list head.
* Mostly useful for hash tables where the two pointer list head is
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index 23b48de8c2e2..f9a037eb053d 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -293,15 +293,13 @@ NF_HOOK_LIST(uint8_t pf, unsigned int hook, struct net *net, struct sock *sk,
struct list_head *head, struct net_device *in, struct net_device *out,
int (*okfn)(struct net *, struct sock *, struct sk_buff *))
{
- struct sk_buff *skb, *next;
struct list_head sublist;
+ struct sk_buff *skb;
INIT_LIST_HEAD(&sublist);
- list_for_each_entry_safe(skb, next, head, list) {
- list_del(&skb->list);
+ list_for_each_entry_dequeue(skb, head, list)
if (nf_hook(pf, hook, net, sk, skb, in, out, okfn) == 1)
list_add_tail(&skb->list, &sublist);
- }
/* Put passed packets back on main list */
list_splice(&sublist, head);
}
diff --git a/net/core/dev.c b/net/core/dev.c
index ce4583564e00..68055f012d13 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4985,9 +4985,8 @@ static void netif_receive_skb_list_internal(struct list_head *head)
struct list_head sublist;
INIT_LIST_HEAD(&sublist);
- list_for_each_entry_safe(skb, next, head, list) {
+ list_for_each_entry_dequeue(skb, head, list) {
net_timestamp_check(netdev_tstamp_prequeue, skb);
- list_del(&skb->list);
if (!skb_defer_rx_timestamp(skb))
list_add_tail(&skb->list, &sublist);
}
@@ -4996,9 +4995,8 @@ static void netif_receive_skb_list_internal(struct list_head *head)
if (static_branch_unlikely(&generic_xdp_needed_key)) {
preempt_disable();
rcu_read_lock();
- list_for_each_entry_safe(skb, next, head, list) {
+ list_for_each_entry_dequeue(skb, head, list) {
xdp_prog = rcu_dereference(skb->dev->xdp_prog);
- list_del(&skb->list);
if (do_xdp_generic(xdp_prog, skb) == XDP_PASS)
list_add_tail(&skb->list, &sublist);
}
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index 1a3b6f32b1c9..26285a24c067 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -538,14 +538,13 @@ static void ip_list_rcv_finish(struct net *net, struct sock *sk,
struct list_head *head)
{
struct dst_entry *curr_dst = NULL;
- struct sk_buff *skb, *next;
struct list_head sublist;
+ struct sk_buff *skb;
INIT_LIST_HEAD(&sublist);
- list_for_each_entry_safe(skb, next, head, list) {
+ list_for_each_entry_dequeue(skb, head, list) {
struct dst_entry *dst;
- list_del(&skb->list);
/* if ingress device is enslaved to an L3 master device pass the
* skb to its handler for processing
*/
@@ -584,15 +583,14 @@ void ip_list_rcv(struct list_head *head, struct packet_type *pt,
{
struct net_device *curr_dev = NULL;
struct net *curr_net = NULL;
- struct sk_buff *skb, *next;
struct list_head sublist;
+ struct sk_buff *skb;
INIT_LIST_HEAD(&sublist);
- list_for_each_entry_safe(skb, next, head, list) {
+ list_for_each_entry_dequeue(skb, head, list) {
struct net_device *dev = skb->dev;
struct net *net = dev_net(dev);
- list_del(&skb->list);
skb = ip_rcv_core(skb, net);
if (skb == NULL)
continue;
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 6242682be876..65344cef0edd 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -88,14 +88,13 @@ static void ip6_list_rcv_finish(struct net *net, struct sock *sk,
struct list_head *head)
{
struct dst_entry *curr_dst = NULL;
- struct sk_buff *skb, *next;
struct list_head sublist;
+ struct sk_buff *skb;
INIT_LIST_HEAD(&sublist);
- list_for_each_entry_safe(skb, next, head, list) {
+ list_for_each_entry_dequeue(skb, head, list) {
struct dst_entry *dst;
- list_del(&skb->list);
/* if ingress device is enslaved to an L3 master device pass the
* skb to its handler for processing
*/
@@ -287,15 +286,14 @@ void ipv6_list_rcv(struct list_head *head, struct packet_type *pt,
{
struct net_device *curr_dev = NULL;
struct net *curr_net = NULL;
- struct sk_buff *skb, *next;
struct list_head sublist;
+ struct sk_buff *skb;
INIT_LIST_HEAD(&sublist);
- list_for_each_entry_safe(skb, next, head, list) {
+ list_for_each_entry_dequeue(skb, head, list) {
struct net_device *dev = skb->dev;
struct net *net = dev_net(dev);
- list_del(&skb->list);
skb = ip6_rcv_core(skb, dev, net);
if (skb == NULL)
continue;
^ permalink raw reply related
* Re: [PATCH net-next 0/6] sock cookie initializers
From: Jesus Sanchez-Palencia @ 2018-07-06 17:19 UTC (permalink / raw)
To: Willem de Bruijn, netdev; +Cc: davem, Willem de Bruijn
In-Reply-To: <20180706141259.29295-1-willemdebruijn.kernel@gmail.com>
On 07/06/2018 07:12 AM, Willem de Bruijn wrote:
> From: Willem de Bruijn <willemb@google.com>
>
> Recent UDP GSO and SO_TXTIME features added new fields to cookie
> structs.
>
> When adding a field, all sites where a struct is initialized have to
> be updated, which is a lot of boilerplate. Alternatively, a field can
> be initialized selectively, but this is fragile. I introduced a bug
> in udp gso where an uninitialized field was read. See also fix commit
> ("9887cba19978 ip: limit use of gso_size to udp").
>
> Introduce initializers for structs ipcm(6)_cookie and sockc_cookie.
>
> patch 1..3 do exactly this.
> patch 4..5 make ipv4 and ipv6 handle cookies the same way and
> remove some boilerplate in doing so.
> patch 6 removes the udp gso branch that needed the above fix
Acked-by: Jesus Sanchez-Palencia <jesus.sanchez-palencia@intel.com>
I've applied this series and tested SO_TXTIME + the etf qdisc and everything is
working just fine.
Thanks,
Jesus
>
> Willem de Bruijn (6):
> ipv4: ipcm_cookie initializers
> ipv6: ipcm6_cookie initializer
> sock: sockc cookie initializer
> ipv6: fold sockcm_cookie into ipcm6_cookie
> ip: remove tx_flags from ipcm_cookie and use same logic for v4 and v6
> ip: unconditionally set cork gso_size
>
> include/net/ip.h | 16 ++++++++++++++-
> include/net/ipv6.h | 26 ++++++++++++++++++++----
> include/net/sock.h | 6 ++++++
> include/net/transp_v6.h | 3 +--
> net/ipv4/icmp.c | 11 ++--------
> net/ipv4/ip_output.c | 12 ++++-------
> net/ipv4/ping.c | 11 +---------
> net/ipv4/raw.c | 11 +---------
> net/ipv4/tcp.c | 2 +-
> net/ipv4/udp.c | 12 +----------
> net/ipv6/datagram.c | 4 ++--
> net/ipv6/icmp.c | 14 ++++---------
> net/ipv6/ip6_flowlabel.c | 3 +--
> net/ipv6/ip6_output.c | 43 +++++++++++++++++-----------------------
> net/ipv6/ipv6_sockglue.c | 3 +--
> net/ipv6/ping.c | 7 ++-----
> net/ipv6/raw.c | 15 +++++---------
> net/ipv6/udp.c | 14 +++++--------
> net/l2tp/l2tp_ip6.c | 10 +++-------
> net/packet/af_packet.c | 9 +++------
> 20 files changed, 98 insertions(+), 134 deletions(-)
>
^ permalink raw reply
* Re: [PATCH v2 net-next 1/3] rds: Changing IP address internal representation to struct in6_addr
From: Santosh Shilimkar @ 2018-07-06 17:26 UTC (permalink / raw)
To: Ka-Cheong Poon; +Cc: Sowmini Varadhan, davem, netdev, rds-devel
In-Reply-To: <20180706152558.GJ30983@oracle.com>
Hi Ka-Cheong,
On 7/6/2018 8:25 AM, Sowmini Varadhan wrote:
> On (07/06/18 23:08), Ka-Cheong Poon wrote:
>>
>> As mentioned in a previous mail, it is unclear why the
>> port number is transport specific. Most Internet services
>> use the same port number running over TCP/UDP as shown
>> in the IANA database. And the IANA RDS registration is
>> the same. What is the rationale of having a transport
>> specific number in the RDS implementation?
>
> because not every transport may need a port number.
>
Lets keep separate port for RDMA and TCP transport. This has been
already useful for wireshark dissector and can also help for eBPF
like external tooling. The fragment format and re-assembly is
different across transports.
I do see your point and also agree that port number isn't transport
specific and in case we need to add another transport, what port
to use. But may be till then lets keep the existing behavior.
As such this port switch is not related to IPv6 support as such
so lets deal with it separately.
Regards,
Santosh
^ permalink raw reply
* Re: KASAN: use-after-free Read in ipv6_gso_pull_exthdrs
From: syzbot @ 2018-07-06 17:52 UTC (permalink / raw)
To: davem, kuznet, linux-kernel, netdev, syzkaller-bugs, yoshfuji
In-Reply-To: <000000000000b0ee7a056eea93a7@google.com>
syzbot has found a reproducer for the following crash on:
HEAD commit: 70ba5b6db96f ipv4: Return EINVAL when ping_group_range sys..
git tree: net
console output: https://syzkaller.appspot.com/x/log.txt?x=13cd2970400000
kernel config: https://syzkaller.appspot.com/x/.config?x=2ca6c7a31d407f86
dashboard link: https://syzkaller.appspot.com/bug?extid=7b9ed9872dab8c32305d
compiler: gcc (GCC) 8.0.1 20180413 (experimental)
syzkaller repro:https://syzkaller.appspot.com/x/repro.syz?x=15dfb748400000
C reproducer: https://syzkaller.appspot.com/x/repro.c?x=12a1050c400000
IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+7b9ed9872dab8c32305d@syzkaller.appspotmail.com
IPv6: ADDRCONF(NETDEV_UP): veth0: link is not ready
IPv6: ADDRCONF(NETDEV_CHANGE): veth0: link becomes ready
IPv6: ADDRCONF(NETDEV_CHANGE): bond0: link becomes ready
8021q: adding VLAN 0 to HW filter on device team0
==================================================================
BUG: KASAN: use-after-free in ipv6_gso_pull_exthdrs+0x57a/0x5f0
net/ipv6/ip6_offload.c:45
Read of size 1 at addr ffff8801ce17f3a9 by task syz-executor655/4567
CPU: 1 PID: 4567 Comm: syz-executor655 Not tainted 4.18.0-rc3+ #1
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
Google 01/01/2011
Call Trace:
__dump_stack lib/dump_stack.c:77 [inline]
dump_stack+0x1c9/0x2b4 lib/dump_stack.c:113
print_address_description+0x6c/0x20b mm/kasan/report.c:256
kasan_report_error mm/kasan/report.c:354 [inline]
kasan_report.cold.7+0x242/0x2fe mm/kasan/report.c:412
__asan_report_load1_noabort+0x14/0x20 mm/kasan/report.c:430
ipv6_gso_pull_exthdrs+0x57a/0x5f0 net/ipv6/ip6_offload.c:45
ipv6_gso_segment+0x37a/0x11e0 net/ipv6/ip6_offload.c:87
skb_mac_gso_segment+0x3b5/0x740 net/core/dev.c:2792
nsh_gso_segment+0x470/0xb40 net/nsh/nsh.c:111
skb_mac_gso_segment+0x3b5/0x740 net/core/dev.c:2792
__skb_gso_segment+0x3c3/0x880 net/core/dev.c:2865
skb_gso_segment include/linux/netdevice.h:4099 [inline]
validate_xmit_skb+0x640/0xf30 net/core/dev.c:3104
__dev_queue_xmit+0xc14/0x3910 net/core/dev.c:3561
dev_queue_xmit+0x17/0x20 net/core/dev.c:3602
packet_snd net/packet/af_packet.c:2919 [inline]
packet_sendmsg+0x428e/0x6130 net/packet/af_packet.c:2944
sock_sendmsg_nosec net/socket.c:641 [inline]
sock_sendmsg+0xd5/0x120 net/socket.c:651
__sys_sendto+0x3d7/0x670 net/socket.c:1797
__do_sys_sendto net/socket.c:1809 [inline]
__se_sys_sendto net/socket.c:1805 [inline]
__x64_sys_sendto+0xe1/0x1a0 net/socket.c:1805
do_syscall_64+0x1b9/0x820 arch/x86/entry/common.c:290
entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x441de9
Code: 25 02 00 85 c0 b8 00 00 00 00 48 0f 44 c3 5b c3 90 48 89 f8 48 89 f7
48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff
ff 0f 83 8b 0d fc ff c3 66 2e 0f 1f 84 00 00 00 00
RSP: 002b:00000000007dfe28 EFLAGS: 00000212 ORIG_RAX: 000000000000002c
RAX: ffffffffffffffda RBX: 0000000000000021 RCX: 0000000000441de9
RDX: 0000000000000012 RSI: 0000000020000000 RDI: 0000000000000003
RBP: 00000000004a3f10 R08: 00000000200000c0 R09: 000000000000001c
R10: 0000000000000000 R11: 0000000000000212 R12: 00000000007dff68
R13: 0000000000403090 R14: 0000000000000000 R15: 0000000000000000
Allocated by task 3516:
save_stack+0x43/0xd0 mm/kasan/kasan.c:448
set_track mm/kasan/kasan.c:460 [inline]
kasan_kmalloc+0xc4/0xe0 mm/kasan/kasan.c:553
kasan_slab_alloc+0x12/0x20 mm/kasan/kasan.c:490
kmem_cache_alloc+0x12e/0x760 mm/slab.c:3554
kmem_cache_zalloc include/linux/slab.h:697 [inline]
get_empty_filp+0x12d/0x530 fs/file_table.c:122
path_openat+0x11e/0x4e10 fs/namei.c:3516
do_filp_open+0x255/0x380 fs/namei.c:3574
do_sys_open+0x584/0x760 fs/open.c:1101
__do_sys_open fs/open.c:1119 [inline]
__se_sys_open fs/open.c:1114 [inline]
__x64_sys_open+0x7e/0xc0 fs/open.c:1114
do_syscall_64+0x1b9/0x820 arch/x86/entry/common.c:290
entry_SYSCALL_64_after_hwframe+0x49/0xbe
Freed by task 3519:
save_stack+0x43/0xd0 mm/kasan/kasan.c:448
set_track mm/kasan/kasan.c:460 [inline]
__kasan_slab_free+0x11a/0x170 mm/kasan/kasan.c:521
kasan_slab_free+0xe/0x10 mm/kasan/kasan.c:528
__cache_free mm/slab.c:3498 [inline]
kmem_cache_free+0x86/0x2d0 mm/slab.c:3756
file_free_rcu+0x6f/0x90 fs/file_table.c:49
__rcu_reclaim kernel/rcu/rcu.h:178 [inline]
rcu_do_batch kernel/rcu/tree.c:2558 [inline]
invoke_rcu_callbacks kernel/rcu/tree.c:2818 [inline]
__rcu_process_callbacks kernel/rcu/tree.c:2785 [inline]
rcu_process_callbacks+0xed5/0x1850 kernel/rcu/tree.c:2802
__do_softirq+0x2e8/0xb17 kernel/softirq.c:288
The buggy address belongs to the object at ffff8801ce17f280
which belongs to the cache filp of size 456
The buggy address is located 297 bytes inside of
456-byte region [ffff8801ce17f280, ffff8801ce17f448)
The buggy address belongs to the page:
page:ffffea0007385fc0 count:1 mapcount:0 mapping:ffff8801da987940
index:0xffff8801ce17f780
flags: 0x2fffc0000000100(slab)
raw: 02fffc0000000100 ffffea0007368048 ffffea0007368148 ffff8801da987940
raw: ffff8801ce17f780 ffff8801ce17f000 0000000100000005 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff8801ce17f280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff8801ce17f300: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
> ffff8801ce17f380: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff8801ce17f400: fb fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc
ffff8801ce17f480: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
==================================================================
^ permalink raw reply
* Re: [PATCH net-next 0/6] sock cookie initializers
From: Willem de Bruijn @ 2018-07-06 18:00 UTC (permalink / raw)
To: Jesus Sanchez-Palencia
Cc: Network Development, David Miller, Willem de Bruijn
In-Reply-To: <99f67dc2-0cbf-210a-e5ab-7574a4879d98@intel.com>
On Fri, Jul 6, 2018 at 1:24 PM Jesus Sanchez-Palencia
<jesus.sanchez-palencia@intel.com> wrote:
>
>
>
> On 07/06/2018 07:12 AM, Willem de Bruijn wrote:
> > From: Willem de Bruijn <willemb@google.com>
> >
> > Recent UDP GSO and SO_TXTIME features added new fields to cookie
> > structs.
> >
> > When adding a field, all sites where a struct is initialized have to
> > be updated, which is a lot of boilerplate. Alternatively, a field can
> > be initialized selectively, but this is fragile. I introduced a bug
> > in udp gso where an uninitialized field was read. See also fix commit
> > ("9887cba19978 ip: limit use of gso_size to udp").
> >
> > Introduce initializers for structs ipcm(6)_cookie and sockc_cookie.
> >
> > patch 1..3 do exactly this.
> > patch 4..5 make ipv4 and ipv6 handle cookies the same way and
> > remove some boilerplate in doing so.
> > patch 6 removes the udp gso branch that needed the above fix
>
>
> Acked-by: Jesus Sanchez-Palencia <jesus.sanchez-palencia@intel.com>
>
> I've applied this series and tested SO_TXTIME + the etf qdisc and everything is
> working just fine.
Thanks for testing, Jesus!
I also ran the udpgso and txtimestamp tests (and am expanding
the second to run as part of kselftest, and have ipv6 and cmsg support).
^ permalink raw reply
* [net 4/4] tipc: make function tipc_net_finalize() thread safe
From: Jon Maloy @ 2018-07-06 18:10 UTC (permalink / raw)
To: davem, netdev; +Cc: tipc-discussion, gordan.mihaljevic
In-Reply-To: <1530900606-24429-1-git-send-email-jon.maloy@ericsson.com>
The setting of the node address is not thread safe, meaning that
two discoverers may decide to set it simultanously, with a duplicate
entry in the name table as result. We fix that with this commit.
Fixes: 25b0b9c4e835 ("tipc: handle collisions of 32-bit node address hash values")
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/tipc/net.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/net/tipc/net.c b/net/tipc/net.c
index 4fbaa04..a7f6964 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -121,12 +121,17 @@ int tipc_net_init(struct net *net, u8 *node_id, u32 addr)
void tipc_net_finalize(struct net *net, u32 addr)
{
- tipc_set_node_addr(net, addr);
- smp_mb();
- tipc_named_reinit(net);
- tipc_sk_reinit(net);
- tipc_nametbl_publish(net, TIPC_CFG_SRV, addr, addr,
- TIPC_CLUSTER_SCOPE, 0, addr);
+ struct tipc_net *tn = tipc_net(net);
+
+ spin_lock_bh(&tn->node_list_lock);
+ if (!tipc_own_addr(net)) {
+ tipc_set_node_addr(net, addr);
+ tipc_named_reinit(net);
+ tipc_sk_reinit(net);
+ tipc_nametbl_publish(net, TIPC_CFG_SRV, addr, addr,
+ TIPC_CLUSTER_SCOPE, 0, addr);
+ }
+ spin_unlock_bh(&tn->node_list_lock);
}
void tipc_net_stop(struct net *net)
--
2.1.4
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
^ permalink raw reply related
* [net 0/4] tipc: fixes in duplicate address discovery function
From: Jon Maloy @ 2018-07-06 18:10 UTC (permalink / raw)
To: davem, netdev
Cc: gordan.mihaljevic, tung.q.nguyen, hoang.h.le, jon.maloy,
canh.d.luu, ying.xue, tipc-discussion
commit 25b0b9c4e835 ("tipc: handle collisions of 32-bit node address
hash values") introduced new functionality that has turned out to
contain several bugs and weaknesses.
We address those in this series.
Jon Maloy (4):
tipc: fix wrong return value from function tipc_node_try_addr()
tipc: correct discovery message handling during address trial period
tipc: fix correct setting of message type in second discoverer
tipc: make function tipc_net_finalize() thread safe
net/tipc/discover.c | 18 +++++++++++-------
net/tipc/net.c | 17 +++++++++++------
net/tipc/node.c | 7 +++++--
3 files changed, 27 insertions(+), 15 deletions(-)
--
2.1.4
^ permalink raw reply
* [net 2/4] tipc: correct discovery message handling during address trial period
From: Jon Maloy @ 2018-07-06 18:10 UTC (permalink / raw)
To: davem, netdev
Cc: gordan.mihaljevic, tung.q.nguyen, hoang.h.le, jon.maloy,
canh.d.luu, ying.xue, tipc-discussion
In-Reply-To: <1530900606-24429-1-git-send-email-jon.maloy@ericsson.com>
With the duplicate address discovery protocol for tipc nodes addresses
we introduced a one second trial period before a node is allocated a
hash number to use as address.
Unfortunately, we miss to handle the case when a regular LINK REQUEST/
RESPONSE arrives from a cluster node during the trial period. Such
messages are not ignored as they should be, leading to links setup
attempts while the node still has no address.
Fixes: 25b0b9c4e835 ("tipc: handle collisions of 32-bit node address hash values")
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/tipc/discover.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index 9f666e0..dcadc10 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -133,6 +133,8 @@ static void disc_dupl_alert(struct tipc_bearer *b, u32 node_addr,
}
/* tipc_disc_addr_trial(): - handle an address uniqueness trial from peer
+ * Returns true if message should be dropped by caller, i.e., if it is a
+ * trial message or we are inside trial period. Otherwise false.
*/
static bool tipc_disc_addr_trial_msg(struct tipc_discoverer *d,
struct tipc_media_addr *maddr,
@@ -168,8 +170,9 @@ static bool tipc_disc_addr_trial_msg(struct tipc_discoverer *d,
msg_set_type(buf_msg(d->skb), DSC_REQ_MSG);
}
+ /* Accept regular link requests/responses only after trial period */
if (mtyp != DSC_TRIAL_MSG)
- return false;
+ return trial;
sugg_addr = tipc_node_try_addr(net, peer_id, src);
if (sugg_addr)
--
2.1.4
^ permalink raw reply related
* [net 1/4] tipc: fix wrong return value from function tipc_node_try_addr()
From: Jon Maloy @ 2018-07-06 18:10 UTC (permalink / raw)
To: davem, netdev
Cc: gordan.mihaljevic, tung.q.nguyen, hoang.h.le, jon.maloy,
canh.d.luu, ying.xue, tipc-discussion
In-Reply-To: <1530900606-24429-1-git-send-email-jon.maloy@ericsson.com>
The function for checking if there is an node address conflict is
supposed to return a suggestion for a new address if it finds a
conflict, and zero otherwise. But in case the peer being checked
is previously unknown it does instead return a "suggestion" for
the checked address itself. This results in a DSC_TRIAL_FAIL_MSG
being sent unecessarily to the peer, and sometimes makes the trial
period starting over again.
Fixes: 25b0b9c4e835 ("tipc: handle collisions of 32-bit node address hash values")
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/tipc/node.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 6a44eb8..0453bd4 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -797,6 +797,7 @@ static u32 tipc_node_suggest_addr(struct net *net, u32 addr)
}
/* tipc_node_try_addr(): Check if addr can be used by peer, suggest other if not
+ * Returns suggested address if any, otherwise 0
*/
u32 tipc_node_try_addr(struct net *net, u8 *id, u32 addr)
{
@@ -819,12 +820,14 @@ u32 tipc_node_try_addr(struct net *net, u8 *id, u32 addr)
if (n) {
addr = n->addr;
tipc_node_put(n);
+ return addr;
}
- /* Even this node may be in trial phase */
+
+ /* Even this node may be in conflict */
if (tn->trial_addr == addr)
return tipc_node_suggest_addr(net, addr);
- return addr;
+ return 0;
}
void tipc_node_check_dest(struct net *net, u32 addr,
--
2.1.4
^ permalink raw reply related
* [net 3/4] tipc: fix correct setting of message type in second discoverer
From: Jon Maloy @ 2018-07-06 18:10 UTC (permalink / raw)
To: davem, netdev
Cc: gordan.mihaljevic, tung.q.nguyen, hoang.h.le, jon.maloy,
canh.d.luu, ying.xue, tipc-discussion
In-Reply-To: <1530900606-24429-1-git-send-email-jon.maloy@ericsson.com>
The duplicate address discovery protocol is not safe against two
discoverers running in parallel. The one executing first after the
trial period is over will set the node address and change its own
message type to DSC_REQ_MSG. The one executing last may find that the
node address is already set, and never change message type, with the
result that its links may never be established.
In this commmit we ensure that the message type always is set correctly
after the trial period is over.
Fixes: 25b0b9c4e835 ("tipc: handle collisions of 32-bit node address hash values")
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/tipc/discover.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index dcadc10..2830709 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -287,7 +287,6 @@ static void tipc_disc_timeout(struct timer_list *t)
{
struct tipc_discoverer *d = from_timer(d, t, timer);
struct tipc_net *tn = tipc_net(d->net);
- u32 self = tipc_own_addr(d->net);
struct tipc_media_addr maddr;
struct sk_buff *skb = NULL;
struct net *net = d->net;
@@ -301,12 +300,14 @@ static void tipc_disc_timeout(struct timer_list *t)
goto exit;
}
- /* Did we just leave the address trial period ? */
- if (!self && !time_before(jiffies, tn->addr_trial_end)) {
- self = tn->trial_addr;
- tipc_net_finalize(net, self);
- msg_set_prevnode(buf_msg(d->skb), self);
+ /* Trial period over ? */
+ if (!time_before(jiffies, tn->addr_trial_end)) {
+ /* Did we just leave it ? */
+ if (!tipc_own_addr(net))
+ tipc_net_finalize(net, tn->trial_addr);
+
msg_set_type(buf_msg(d->skb), DSC_REQ_MSG);
+ msg_set_prevnode(buf_msg(d->skb), tipc_own_addr(net));
}
/* Adjust timeout interval according to discovery phase */
--
2.1.4
^ permalink raw reply related
* Re: [PATCH bpf-next 1/2] bpftool: introduce cgroup tree command
From: Roman Gushchin @ 2018-07-06 18:25 UTC (permalink / raw)
To: Jakub Kicinski
Cc: netdev, linux-kernel, kernel-team, Quentin Monnet,
Daniel Borkmann, Alexei Starovoitov, David Ahern
In-Reply-To: <20180705190116.7737d66d@cakuba.netronome.com>
On Thu, Jul 05, 2018 at 07:01:16PM -0700, Jakub Kicinski wrote:
> On Thu, 5 Jul 2018 18:05:20 -0700, Roman Gushchin wrote:
> > This commit introduces a new bpftool command: cgroup tree.
> > The idea is to iterate over the whole cgroup tree and print
> > all attached programs.
> >
> > I was debugging a bpf/systemd issue, and found, that there is
> > no simple way to listen all bpf programs attached to cgroups.
> > I did master something in bash, but after some time got tired of it,
> > and decided, that adding a dedicated bpftool command could be
> > a better idea.
> >
> > So, here it is:
> > $ sudo ./bpftool cgroup tree
> > CgroupPath
> > ID AttachType AttachFlags Name
> > /sys/fs/cgroup/system.slice/systemd-machined.service
> > 18 ingress
> > 17 egress
> > /sys/fs/cgroup/system.slice/systemd-logind.service
> > 20 ingress
> > 19 egress
> > /sys/fs/cgroup/system.slice/systemd-udevd.service
> > 16 ingress
> > 15 egress
> > /sys/fs/cgroup/system.slice/systemd-journald.service
> > 14 ingress
> > 13 egress
> >
> > Signed-off-by: Roman Gushchin <guro@fb.com>
> > Cc: Jakub Kicinski <jakub.kicinski@netronome.com>
> > Cc: Quentin Monnet <quentin.monnet@netronome.com>
> > Cc: Daniel Borkmann <daniel@iogearbox.net>
> > Cc: Alexei Starovoitov <ast@kernel.org>
>
> Looks very useful! Minor nits/questions below. I think the reverse
> mapping could also be interesting - similar to how -f flag shows where
> program is pinned, we could add a flag which in
>
> # bpftool prog show/list
>
> adds info about cgroups where the program is attached? Obviously as a
> future extension.
Well, it would be convenient, but it's not always possible.
A program can be attached to a dying cgroup (a cgroup which was deleted
by a user, but still has some associated resources, e.g. pagecache).
>
> > diff --git a/tools/bpf/bpftool/cgroup.c b/tools/bpf/bpftool/cgroup.c
> > index 16bee011e16c..125d5b6db568 100644
> > --- a/tools/bpf/bpftool/cgroup.c
> > +++ b/tools/bpf/bpftool/cgroup.c
> > @@ -2,7 +2,12 @@
> > // Copyright (C) 2017 Facebook
> > // Author: Roman Gushchin <guro@fb.com>
> >
> > +#define _XOPEN_SOURCE 500
> > +#include <errno.h>
> > #include <fcntl.h>
> > +#include <ftw.h>
> > +#include <mntent.h>
> > +#include <stdio.h>
> > #include <stdlib.h>
> > #include <string.h>
> > #include <sys/stat.h>
> > @@ -53,7 +58,8 @@ static enum bpf_attach_type parse_attach_type(const char *str)
> > }
> >
> > static int show_bpf_prog(int id, const char *attach_type_str,
> > - const char *attach_flags_str)
> > + const char *attach_flags_str,
> > + int level)
> > {
> > struct bpf_prog_info info = {};
> > __u32 info_len = sizeof(info);
> > @@ -78,7 +84,8 @@ static int show_bpf_prog(int id, const char *attach_type_str,
> > jsonw_string_field(json_wtr, "name", info.name);
> > jsonw_end_object(json_wtr);
> > } else {
> > - printf("%-8u %-15s %-15s %-15s\n", info.id,
> > + printf("%s%-8u %-15s %-15s %-15s\n", level ? " " : "",
> > + info.id,
> > attach_type_str,
> > attach_flags_str,
> > info.name);
> > @@ -88,7 +95,20 @@ static int show_bpf_prog(int id, const char *attach_type_str,
> > return 0;
> > }
> >
> > -static int show_attached_bpf_progs(int cgroup_fd, enum bpf_attach_type type)
> > +static int count_attached_bpf_progs(int cgroup_fd, enum bpf_attach_type type)
> > +{
> > + __u32 prog_cnt = 0;
> > + int ret;
> > +
> > + ret = bpf_prog_query(cgroup_fd, type, 0, NULL, NULL, &prog_cnt);
> > + if (ret)
> > + return -1;
> > +
> > + return prog_cnt;
> > +}
> > +
> > +static int show_attached_bpf_progs(int cgroup_fd, enum bpf_attach_type type,
> > + int level)
> > {
> > __u32 prog_ids[1024] = {0};
> > char *attach_flags_str;
> > @@ -123,7 +143,7 @@ static int show_attached_bpf_progs(int cgroup_fd, enum bpf_attach_type type)
> >
> > for (iter = 0; iter < prog_cnt; iter++)
> > show_bpf_prog(prog_ids[iter], attach_type_strings[type],
> > - attach_flags_str);
> > + attach_flags_str, level);
> >
> > return 0;
> > }
> > @@ -161,7 +181,7 @@ static int do_show(int argc, char **argv)
> > * If we were able to get the show for at least one
> > * attach type, let's return 0.
> > */
> > - if (show_attached_bpf_progs(cgroup_fd, type) == 0)
> > + if (show_attached_bpf_progs(cgroup_fd, type, 0) == 0)
> > ret = 0;
> > }
> >
> > @@ -173,6 +193,123 @@ static int do_show(int argc, char **argv)
> > return ret;
> > }
> >
> > +static int do_show_tree_fn(const char *fpath, const struct stat *sb,
> > + int typeflag, struct FTW *ftw)
> > +{
> > + enum bpf_attach_type type;
> > + bool skip = true;
> > + int cgroup_fd;
> > +
> > + if (typeflag != FTW_D)
> > + return 0;
> > +
> > + cgroup_fd = open(fpath, O_RDONLY);
> > + if (cgroup_fd < 0) {
> > + p_err("can't open cgroup %s: %s", fpath, strerror(errno));
> > + return -1;
> > + }
> > +
> > + for (type = 0; type < __MAX_BPF_ATTACH_TYPE; type++) {
> > + int count = count_attached_bpf_progs(cgroup_fd, type);
> > +
> > + if (count < 0 && errno != EINVAL) {
> > + p_err("can't query bpf programs attached to %s: %s",
> > + fpath, strerror(errno));
> > + close(cgroup_fd);
> > + return -1;
> > + }
> > + if (count > 0) {
> > + skip = false;
> > + break;
> > + }
> > + }
> > +
> > + if (skip) {
> > + close(cgroup_fd);
> > + return 0;
> > + }
> > +
> > + if (json_output) {
> > + jsonw_start_object(json_wtr);
> > + jsonw_string_field(json_wtr, "cgroup", fpath);
> > + jsonw_name(json_wtr, "programs");
> > + jsonw_start_array(json_wtr);
> > + } else {
> > + printf("%s\n", fpath);
> > + }
> > +
> > + for (type = 0; type < __MAX_BPF_ATTACH_TYPE; type++)
> > + show_attached_bpf_progs(cgroup_fd, type, ftw->level);
> > +
> > + if (json_output) {
> > + jsonw_end_array(json_wtr);
> > + jsonw_end_object(json_wtr);
> > + }
> > +
> > + close(cgroup_fd);
> > +
> > + return 0;
> > +}
> > +
> > +static char *find_cgroup_root(void)
> > +{
> > + struct mntent *mnt;
> > + FILE *f;
> > +
> > + f = fopen("/proc/mounts", "r");
> > + if (f == NULL)
> > + return NULL;
> > +
> > + while ((mnt = getmntent(f))) {
> > + if (strcmp(mnt->mnt_type, "cgroup2") == 0) {
> > + fclose(f);
> > + return strdup(mnt->mnt_dir);
>
> FWIW you don't free this memory.
Doesn't really matter, as we do exit immediately after,
but fixed in v2 anyway.
>
> > + }
> > + }
> > +
> > + fclose(f);
> > + return NULL;
> > +}
> > +
> > +static int do_show_tree(int argc, char **argv)
> > +{
> > + char *cgroup_root;
> > + int ret;
> > +
> > + if (argc > 1) {
> > + p_err("too many parameters for cgroup tree");
> > + return -1;
> > + }
> > +
> > + if (argc == 1) {
> > + cgroup_root = argv[0];
> > + } else {
> > + cgroup_root = find_cgroup_root();
> > +
> > + if (!cgroup_root) {
> > + p_err("cgroup v2 isn't mounted");
> > + return -1;
> > + }
> > + }
> > +
> > + if (json_output)
> > + jsonw_start_array(json_wtr);
> > + else
> > + printf("%s\n"
> > + "%-8s %-15s %-15s %-15s\n",
> > + "CgroupPath",
> > + "ID", "AttachType", "AttachFlags", "Name");
> > +
> > + ret = nftw(cgroup_root, do_show_tree_fn, 1024, FTW_MOUNT);
> > + if (ret && errno == ENOENT)
> > + p_err("can't iterate over %s: %s", cgroup_root,
> > + strerror(errno));
>
> I'm worried this could lead to a duplicated error in JSON output, no?
> Is it possible that do_show_tree_fn() would have already printed an
> error?
Fixed in v2.
>
> > +
> > + if (json_output)
> > + jsonw_end_array(json_wtr);
> > +
> > + return ret;
> > +}
> > +
> > static int do_attach(int argc, char **argv)
> > {
> > enum bpf_attach_type attach_type;
> > @@ -289,6 +426,7 @@ static int do_help(int argc, char **argv)
> >
> > fprintf(stderr,
> > "Usage: %s %s { show | list } CGROUP\n"
> > + " %s %s tree [CGROUP_ROOT]\n"
> > " %s %s attach CGROUP ATTACH_TYPE PROG [ATTACH_FLAGS]\n"
> > " %s %s detach CGROUP ATTACH_TYPE PROG\n"
> > " %s %s help\n"
> > @@ -298,6 +436,7 @@ static int do_help(int argc, char **argv)
> > " " HELP_SPEC_PROGRAM "\n"
> > " " HELP_SPEC_OPTIONS "\n"
> > "",
> > + bin_name, argv[-2],
> > bin_name, argv[-2], bin_name, argv[-2],
> > bin_name, argv[-2], bin_name, argv[-2]);
> >
> > @@ -307,6 +446,7 @@ static int do_help(int argc, char **argv)
> > static const struct cmd cmds[] = {
> > { "show", do_show },
> > { "list", do_show },
> > + { "tree", do_show_tree },
> > { "attach", do_attach },
> > { "detach", do_detach },
> > { "help", do_help },
>
> Could you please also add this new command to bash completions? It
> should be fairly trivial to handle.
Sure.
Thanks!
^ permalink raw reply
* [PATCH V2 net-next] liquidio: fix kernel panic when NIC firmware is older than 1.7.2
From: Felix Manlunas @ 2018-07-06 18:27 UTC (permalink / raw)
To: davem
Cc: netdev, raghu.vatsavayi, derek.chickles, satananda.burla,
ricardo.farrington, felix.manlunas
From: Rick Farrington <ricardo.farrington@cavium.com>
Pre-1.7.2 NIC firmware does not support (and does not respond to) the "get
speed" command which is sent by the 1.7.2 driver (for CN23XX-225 cards
only) during modprobe. Due to a bug in older firmware (with respect to
unknown commands), this unsupported command causes a cascade of errors that
ends in a kernel panic.
Fix it by making the sending of the "get speed" command conditional on the
firmware version.
Signed-off-by: Rick Farrington <ricardo.farrington@cavium.com>
Signed-off-by: Felix Manlunas <felix.manlunas@cavium.com>
---
Patch Change Log:
V1 -> V2:
* In the if-statement that checks the firmware version, replace the
boolean expression that calls strcmp() (which is not suitable when
the firmware micro version has more than one digit) with a boolean
expression that works in all cases.
* In the patch description, specify which types of liquidio cards are
afffected.
drivers/net/ethernet/cavium/liquidio/lio_main.c | 26 ++++++++++++++++++++--
.../net/ethernet/cavium/liquidio/octeon_device.h | 9 ++++++++
2 files changed, 33 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c
index 7cb4e75..ebda6ef 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_main.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c
@@ -3299,7 +3299,9 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
{
struct lio *lio = NULL;
struct net_device *netdev;
- u8 mac[6], i, j, *fw_ver;
+ u8 mac[6], i, j, *fw_ver, *micro_ver;
+ unsigned long micro;
+ u32 cur_ver;
struct octeon_soft_command *sc;
struct liquidio_if_cfg_context *ctx;
struct liquidio_if_cfg_resp *resp;
@@ -3429,6 +3431,14 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
fw_ver);
}
+ /* extract micro version field; point past '<maj>.<min>.' */
+ micro_ver = fw_ver + strlen(LIQUIDIO_BASE_VERSION) + 1;
+ if (kstrtoul(micro_ver, 10, µ) != 0)
+ micro = 0;
+ octeon_dev->fw_info.ver.maj = LIQUIDIO_BASE_MAJOR_VERSION;
+ octeon_dev->fw_info.ver.min = LIQUIDIO_BASE_MINOR_VERSION;
+ octeon_dev->fw_info.ver.rev = micro;
+
octeon_swap_8B_data((u64 *)(&resp->cfg_info),
(sizeof(struct liquidio_if_cfg_info)) >> 3);
@@ -3671,7 +3681,19 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
OCTEON_CN2350_25GB_SUBSYS_ID ||
octeon_dev->subsystem_id ==
OCTEON_CN2360_25GB_SUBSYS_ID) {
- liquidio_get_speed(lio);
+ cur_ver = OCT_FW_VER(octeon_dev->fw_info.ver.maj,
+ octeon_dev->fw_info.ver.min,
+ octeon_dev->fw_info.ver.rev);
+
+ /* speed control unsupported in f/w older than 1.7.2 */
+ if (cur_ver < OCT_FW_VER(1, 7, 2)) {
+ dev_info(&octeon_dev->pci_dev->dev,
+ "speed setting not supported by f/w.");
+ octeon_dev->speed_setting = 25;
+ octeon_dev->no_speed_setting = 1;
+ } else {
+ liquidio_get_speed(lio);
+ }
if (octeon_dev->speed_setting == 0) {
octeon_dev->speed_setting = 25;
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_device.h b/drivers/net/ethernet/cavium/liquidio/octeon_device.h
index 94a4ed88d..d99ca6b 100644
--- a/drivers/net/ethernet/cavium/liquidio/octeon_device.h
+++ b/drivers/net/ethernet/cavium/liquidio/octeon_device.h
@@ -288,8 +288,17 @@ struct oct_fw_info {
*/
u32 app_mode;
char liquidio_firmware_version[32];
+ /* Fields extracted from legacy string 'liquidio_firmware_version' */
+ struct {
+ u8 maj;
+ u8 min;
+ u8 rev;
+ } ver;
};
+#define OCT_FW_VER(maj, min, rev) \
+ (((u32)(maj) << 16) | ((u32)(min) << 8) | ((u32)(rev)))
+
/* wrappers around work structs */
struct cavium_wk {
struct delayed_work work;
^ permalink raw reply related
* [PATCH v2 bpf-next 1/3] bpftool: introduce cgroup tree command
From: Roman Gushchin @ 2018-07-06 18:30 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel-team, Jakub Kicinski, Roman Gushchin,
Quentin Monnet, Daniel Borkmann, Alexei Starovoitov
This commit introduces a new bpftool command: cgroup tree.
The idea is to iterate over the whole cgroup tree and print
all attached programs.
I was debugging a bpf/systemd issue, and found, that there is
no simple way to listen all bpf programs attached to cgroups.
I did master something in bash, but after some time got tired of it,
and decided, that adding a dedicated bpftool command could be
a better idea.
So, here it is:
$ sudo ./bpftool cgroup tree
CgroupPath
ID AttachType AttachFlags Name
/sys/fs/cgroup/system.slice/systemd-machined.service
18 ingress
17 egress
/sys/fs/cgroup/system.slice/systemd-logind.service
20 ingress
19 egress
/sys/fs/cgroup/system.slice/systemd-udevd.service
16 ingress
15 egress
/sys/fs/cgroup/system.slice/systemd-journald.service
14 ingress
13 egress
Signed-off-by: Roman Gushchin <guro@fb.com>
Cc: Jakub Kicinski <jakub.kicinski@netronome.com>
Cc: Quentin Monnet <quentin.monnet@netronome.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Alexei Starovoitov <ast@kernel.org>
---
tools/bpf/bpftool/cgroup.c | 170 +++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 165 insertions(+), 5 deletions(-)
diff --git a/tools/bpf/bpftool/cgroup.c b/tools/bpf/bpftool/cgroup.c
index 16bee011e16c..ee7a9765c6b3 100644
--- a/tools/bpf/bpftool/cgroup.c
+++ b/tools/bpf/bpftool/cgroup.c
@@ -2,7 +2,12 @@
// Copyright (C) 2017 Facebook
// Author: Roman Gushchin <guro@fb.com>
+#define _XOPEN_SOURCE 500
+#include <errno.h>
#include <fcntl.h>
+#include <ftw.h>
+#include <mntent.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
@@ -53,7 +58,8 @@ static enum bpf_attach_type parse_attach_type(const char *str)
}
static int show_bpf_prog(int id, const char *attach_type_str,
- const char *attach_flags_str)
+ const char *attach_flags_str,
+ int level)
{
struct bpf_prog_info info = {};
__u32 info_len = sizeof(info);
@@ -78,7 +84,8 @@ static int show_bpf_prog(int id, const char *attach_type_str,
jsonw_string_field(json_wtr, "name", info.name);
jsonw_end_object(json_wtr);
} else {
- printf("%-8u %-15s %-15s %-15s\n", info.id,
+ printf("%s%-8u %-15s %-15s %-15s\n", level ? " " : "",
+ info.id,
attach_type_str,
attach_flags_str,
info.name);
@@ -88,7 +95,20 @@ static int show_bpf_prog(int id, const char *attach_type_str,
return 0;
}
-static int show_attached_bpf_progs(int cgroup_fd, enum bpf_attach_type type)
+static int count_attached_bpf_progs(int cgroup_fd, enum bpf_attach_type type)
+{
+ __u32 prog_cnt = 0;
+ int ret;
+
+ ret = bpf_prog_query(cgroup_fd, type, 0, NULL, NULL, &prog_cnt);
+ if (ret)
+ return -1;
+
+ return prog_cnt;
+}
+
+static int show_attached_bpf_progs(int cgroup_fd, enum bpf_attach_type type,
+ int level)
{
__u32 prog_ids[1024] = {0};
char *attach_flags_str;
@@ -123,7 +143,7 @@ static int show_attached_bpf_progs(int cgroup_fd, enum bpf_attach_type type)
for (iter = 0; iter < prog_cnt; iter++)
show_bpf_prog(prog_ids[iter], attach_type_strings[type],
- attach_flags_str);
+ attach_flags_str, level);
return 0;
}
@@ -161,7 +181,7 @@ static int do_show(int argc, char **argv)
* If we were able to get the show for at least one
* attach type, let's return 0.
*/
- if (show_attached_bpf_progs(cgroup_fd, type) == 0)
+ if (show_attached_bpf_progs(cgroup_fd, type, 0) == 0)
ret = 0;
}
@@ -173,6 +193,143 @@ static int do_show(int argc, char **argv)
return ret;
}
+/*
+ * To distinguish nftw() errors and do_show_tree_fn() errors
+ * and avoid duplicating error messages, let's return -2
+ * from do_show_tree_fn() in case of error.
+ */
+#define NFTW_ERR -1
+#define SHOW_TREE_FN_ERR -2
+static int do_show_tree_fn(const char *fpath, const struct stat *sb,
+ int typeflag, struct FTW *ftw)
+{
+ enum bpf_attach_type type;
+ bool skip = true;
+ int cgroup_fd;
+
+ if (typeflag != FTW_D)
+ return 0;
+
+ cgroup_fd = open(fpath, O_RDONLY);
+ if (cgroup_fd < 0) {
+ p_err("can't open cgroup %s: %s", fpath, strerror(errno));
+ return SHOW_TREE_FN_ERR;
+ }
+
+ for (type = 0; type < __MAX_BPF_ATTACH_TYPE; type++) {
+ int count = count_attached_bpf_progs(cgroup_fd, type);
+
+ if (count < 0 && errno != EINVAL) {
+ p_err("can't query bpf programs attached to %s: %s",
+ fpath, strerror(errno));
+ close(cgroup_fd);
+ return SHOW_TREE_FN_ERR;
+ }
+ if (count > 0) {
+ skip = false;
+ break;
+ }
+ }
+
+ if (skip) {
+ close(cgroup_fd);
+ return 0;
+ }
+
+ if (json_output) {
+ jsonw_start_object(json_wtr);
+ jsonw_string_field(json_wtr, "cgroup", fpath);
+ jsonw_name(json_wtr, "programs");
+ jsonw_start_array(json_wtr);
+ } else {
+ printf("%s\n", fpath);
+ }
+
+ for (type = 0; type < __MAX_BPF_ATTACH_TYPE; type++)
+ show_attached_bpf_progs(cgroup_fd, type, ftw->level);
+
+ if (json_output) {
+ jsonw_end_array(json_wtr);
+ jsonw_end_object(json_wtr);
+ }
+
+ close(cgroup_fd);
+
+ return 0;
+}
+
+static char *find_cgroup_root(void)
+{
+ struct mntent *mnt;
+ FILE *f;
+
+ f = fopen("/proc/mounts", "r");
+ if (f == NULL)
+ return NULL;
+
+ while ((mnt = getmntent(f))) {
+ if (strcmp(mnt->mnt_type, "cgroup2") == 0) {
+ fclose(f);
+ return strdup(mnt->mnt_dir);
+ }
+ }
+
+ fclose(f);
+ return NULL;
+}
+
+static int do_show_tree(int argc, char **argv)
+{
+ char *cgroup_root;
+ int ret;
+
+ switch (argc) {
+ case 0:
+ cgroup_root = find_cgroup_root();
+ if (!cgroup_root) {
+ p_err("cgroup v2 isn't mounted");
+ return -1;
+ }
+ break;
+ case 1:
+ cgroup_root = argv[0];
+ break;
+ default:
+ p_err("too many parameters for cgroup tree");
+ return -1;
+ }
+
+
+ if (json_output)
+ jsonw_start_array(json_wtr);
+ else
+ printf("%s\n"
+ "%-8s %-15s %-15s %-15s\n",
+ "CgroupPath",
+ "ID", "AttachType", "AttachFlags", "Name");
+
+ switch (nftw(cgroup_root, do_show_tree_fn, 1024, FTW_MOUNT)) {
+ case NFTW_ERR:
+ p_err("can't iterate over %s: %s", cgroup_root,
+ strerror(errno));
+ ret = -1;
+ break;
+ case SHOW_TREE_FN_ERR:
+ ret = -1;
+ break;
+ default:
+ ret = 0;
+ }
+
+ if (json_output)
+ jsonw_end_array(json_wtr);
+
+ if (argc == 0)
+ free(cgroup_root);
+
+ return ret;
+}
+
static int do_attach(int argc, char **argv)
{
enum bpf_attach_type attach_type;
@@ -289,6 +446,7 @@ static int do_help(int argc, char **argv)
fprintf(stderr,
"Usage: %s %s { show | list } CGROUP\n"
+ " %s %s tree [CGROUP_ROOT]\n"
" %s %s attach CGROUP ATTACH_TYPE PROG [ATTACH_FLAGS]\n"
" %s %s detach CGROUP ATTACH_TYPE PROG\n"
" %s %s help\n"
@@ -298,6 +456,7 @@ static int do_help(int argc, char **argv)
" " HELP_SPEC_PROGRAM "\n"
" " HELP_SPEC_OPTIONS "\n"
"",
+ bin_name, argv[-2],
bin_name, argv[-2], bin_name, argv[-2],
bin_name, argv[-2], bin_name, argv[-2]);
@@ -307,6 +466,7 @@ static int do_help(int argc, char **argv)
static const struct cmd cmds[] = {
{ "show", do_show },
{ "list", do_show },
+ { "tree", do_show_tree },
{ "attach", do_attach },
{ "detach", do_detach },
{ "help", do_help },
--
2.14.4
^ permalink raw reply related
* [PATCH v2 bpf-next 2/3] bpftool: document cgroup tree command
From: Roman Gushchin @ 2018-07-06 18:30 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel-team, Jakub Kicinski, Roman Gushchin,
Quentin Monnet, Daniel Borkmann, Alexei Starovoitov
In-Reply-To: <20180706183012.6475-1-guro@fb.com>
Describe cgroup tree command in the corresponding bpftool man page.
Signed-off-by: Roman Gushchin <guro@fb.com>
Acked-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Cc: Quentin Monnet <quentin.monnet@netronome.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Alexei Starovoitov <ast@kernel.org>
---
tools/bpf/bpftool/Documentation/bpftool-cgroup.rst | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst b/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst
index 7b0e6d453e92..edbe81534c6d 100644
--- a/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst
+++ b/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst
@@ -15,12 +15,13 @@ SYNOPSIS
*OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-f** | **--bpffs** } }
*COMMANDS* :=
- { **show** | **list** | **attach** | **detach** | **help** }
+ { **show** | **list** | **tree** | **attach** | **detach** | **help** }
MAP COMMANDS
=============
| **bpftool** **cgroup { show | list }** *CGROUP*
+| **bpftool** **cgroup tree** [*CGROUP_ROOT*]
| **bpftool** **cgroup attach** *CGROUP* *ATTACH_TYPE* *PROG* [*ATTACH_FLAGS*]
| **bpftool** **cgroup detach** *CGROUP* *ATTACH_TYPE* *PROG*
| **bpftool** **cgroup help**
@@ -39,6 +40,15 @@ DESCRIPTION
Output will start with program ID followed by attach type,
attach flags and program name.
+ **bpftool cgroup tree** [*CGROUP_ROOT*]
+ Iterate over all cgroups in *CGROUP_ROOT* and list all
+ attached programs. If *CGROUP_ROOT* is not specified,
+ bpftool uses cgroup v2 mountpoint.
+
+ The output is similar to the output of cgroup show/list
+ commands: it starts with absolute cgroup path, followed by
+ program ID, attach type, attach flags and program name.
+
**bpftool cgroup attach** *CGROUP* *ATTACH_TYPE* *PROG* [*ATTACH_FLAGS*]
Attach program *PROG* to the cgroup *CGROUP* with attach type
*ATTACH_TYPE* and optional *ATTACH_FLAGS*.
--
2.14.4
^ permalink raw reply related
* [PATCH v2 bpf-next 3/3] bpftool: add bash completion for cgroup tree command
From: Roman Gushchin @ 2018-07-06 18:30 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel-team, Jakub Kicinski, Roman Gushchin,
Quentin Monnet, Daniel Borkmann, Alexei Starovoitov
In-Reply-To: <20180706183012.6475-1-guro@fb.com>
This commit adds a bash completion to the bpftool cgroup tree
command.
Signed-off-by: Roman Gushchin <guro@fb.com>
Cc: Jakub Kicinski <jakub.kicinski@netronome.com>
Cc: Quentin Monnet <quentin.monnet@netronome.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Alexei Starovoitov <ast@kernel.org>
---
tools/bpf/bpftool/bash-completion/bpftool | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tools/bpf/bpftool/bash-completion/bpftool b/tools/bpf/bpftool/bash-completion/bpftool
index fffd76f4998b..82681eb9c02a 100644
--- a/tools/bpf/bpftool/bash-completion/bpftool
+++ b/tools/bpf/bpftool/bash-completion/bpftool
@@ -414,6 +414,9 @@ _bpftool()
_filedir
return 0
;;
+ tree)
+ _filedir
+ return 0
attach|detach)
local ATTACH_TYPES='ingress egress sock_create sock_ops \
device bind4 bind6 post_bind4 post_bind6 connect4 \
--
2.14.4
^ permalink raw reply related
* Re: [PATCH] netfilter: conntrack: add weak IPV6 dependency
From: Florian Westphal @ 2018-07-06 18:35 UTC (permalink / raw)
To: Florian Westphal
Cc: Arnd Bergmann, Pablo Neira Ayuso, Jozsef Kadlecsik,
David S. Miller, Máté Eckl, Fernando Fernandez Mancera,
Pablo M. Bermudo Garay, Felix Fietkau, netfilter-devel, coreteam,
Networking, Linux Kernel Mailing List
In-Reply-To: <20180706150037.knqt736uq6uyh3bs@breakpoint.cc>
Florian Westphal <fw@strlen.de> wrote:
> Arnd Bergmann <arnd@arndb.de> wrote:
> > and that resulted in a new build failure:
> >
> > net/netfilter/nf_conntrack_proto.o:(.rodata+0x788): undefined
> > reference to `nf_conntrack_l4proto_icmpv6'
> > net/ipv6/netfilter/nf_conntrack_reasm.o: In function `nf_ct_frag6_expire':
> > nf_conntrack_reasm.c:(.text+0x2320): undefined reference to
> > `ip6_expire_frag_queue'
> > net/ipv6/netfilter/nf_conntrack_reasm.o: In function `nf_ct_frag6_init':
> > nf_conntrack_reasm.c:(.text+0x2384): undefined reference to `ip6_frag_init'
> > nf_conntrack_reasm.c:(.text+0x2394): undefined reference to `ip6_frag_init'
> > nf_conntrack_reasm.c:(.text+0x2398): undefined reference to `ip6_rhash_params'
> > net/ipv6/netfilter/nf_conntrack_reasm.o: In function `nf_ct_frag6_expire':
> > nf_conntrack_reasm.c:(.text+0x10bc): undefined reference to
> > `ip6_expire_frag_queue'
> >
> > I don't think we can get CONFIG_NF_DEFRAG_IPV6=y to work with IPV6=m.
>
> Yes, not with current implementation, but I still don't think this
> is unavoidable.
>
> In case this is urgent I'm fine with the patch that adds the dependency,
> otherwise I'd like to try and disentangle nf_conntrack_reasm and ipv6.
This links fine for me with IPV6=m:
Pablo, do you think this is too ugly?
It requires some copypastry from ipv6 defrag into nfct ipv6 defrag
to avoid the link errors outlined above.
Rest of defrag uses generic inet_defrag routines.
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index 07516d5c2f80..339d0762b027 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -5,10 +5,6 @@
menu "IPv6: Netfilter Configuration"
depends on INET && IPV6 && NETFILTER
-config NF_DEFRAG_IPV6
- tristate
- default n
-
config NF_SOCKET_IPV6
tristate "IPv6 socket lookup support"
help
@@ -349,6 +345,7 @@ config IP6_NF_TARGET_NPT
endif # IP6_NF_NAT
endif # IP6_NF_IPTABLES
-
endmenu
+config NF_DEFRAG_IPV6
+ tristate
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 5e0332014c17..9973aadc6b71 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -142,6 +142,50 @@ static inline u8 ip6_frag_ecn(const struct ipv6hdr *ipv6h)
return 1 << (ipv6_get_dsfield(ipv6h) & INET_ECN_MASK);
}
+static void nfct_expire_frag_queue(struct net *net, struct frag_queue *fq)
+{
+ struct net_device *dev = NULL;
+ struct sk_buff *head;
+
+ rcu_read_lock();
+ spin_lock(&fq->q.lock);
+
+ if (fq->q.flags & INET_FRAG_COMPLETE)
+ goto out;
+
+ inet_frag_kill(&fq->q);
+
+ dev = dev_get_by_index_rcu(net, fq->iif);
+ if (!dev)
+ goto out;
+
+ __IP6_INC_STATS(net, __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS);
+ __IP6_INC_STATS(net, __in6_dev_get(dev), IPSTATS_MIB_REASMTIMEOUT);
+
+ /* Don't send error if the first segment did not arrive. */
+ head = fq->q.fragments;
+ if (!(fq->q.flags & INET_FRAG_FIRST_IN) || !head)
+ goto out;
+
+ /* But use as source device on which LAST ARRIVED
+ * segment was received. And do not use fq->dev
+ * pointer directly, device might already disappeared.
+ */
+ head->dev = dev;
+ skb_get(head);
+ spin_unlock(&fq->q.lock);
+
+ icmpv6_send(head, ICMPV6_TIME_EXCEED, ICMPV6_EXC_FRAGTIME, 0);
+ kfree_skb(head);
+ goto out_rcu_unlock;
+
+out:
+ spin_unlock(&fq->q.lock);
+out_rcu_unlock:
+ rcu_read_unlock();
+ inet_frag_put(&fq->q);
+}
+
static void nf_ct_frag6_expire(struct timer_list *t)
{
struct inet_frag_queue *frag = from_timer(frag, t, timer);
@@ -151,7 +195,7 @@ static void nf_ct_frag6_expire(struct timer_list *t)
fq = container_of(frag, struct frag_queue, q);
net = container_of(fq->q.net, struct net, nf_frag.frags);
- ip6_expire_frag_queue(net, fq);
+ nfct_expire_frag_queue(net, fq);
}
/* Creation primitives. */
@@ -622,16 +666,55 @@ static struct pernet_operations nf_ct_net_ops = {
.exit = nf_ct_net_exit,
};
+static u32 ip6_key_hashfn(const void *data, u32 len, u32 seed)
+{
+ return jhash2(data,
+ sizeof(struct frag_v6_compare_key) / sizeof(u32), seed);
+}
+
+static u32 ip6_obj_hashfn(const void *data, u32 len, u32 seed)
+{
+ const struct inet_frag_queue *fq = data;
+
+ return jhash2((const u32 *)&fq->key.v6,
+ sizeof(struct frag_v6_compare_key) / sizeof(u32), seed);
+}
+
+static int ip6_obj_cmpfn(struct rhashtable_compare_arg *arg, const void *ptr)
+{
+ const struct frag_v6_compare_key *key = arg->key;
+ const struct inet_frag_queue *fq = ptr;
+
+ return !!memcmp(&fq->key, key, sizeof(*key));
+}
+
+static const struct rhashtable_params nfct_rhash_params = {
+ .head_offset = offsetof(struct inet_frag_queue, node),
+ .hashfn = ip6_key_hashfn,
+ .obj_hashfn = ip6_obj_hashfn,
+ .obj_cmpfn = ip6_obj_cmpfn,
+ .automatic_shrinking = true,
+};
+
+static void nfct_frag_init(struct inet_frag_queue *q, const void *a)
+{
+ struct frag_queue *fq = container_of(q, struct frag_queue, q);
+ const struct frag_v6_compare_key *key = a;
+
+ q->key.v6 = *key;
+ fq->ecn = 0;
+}
+
int nf_ct_frag6_init(void)
{
int ret = 0;
- nf_frags.constructor = ip6_frag_init;
+ nf_frags.constructor = nfct_frag_init;
nf_frags.destructor = NULL;
nf_frags.qsize = sizeof(struct frag_queue);
nf_frags.frag_expire = nf_ct_frag6_expire;
nf_frags.frags_cache_name = nf_frags_cache_name;
- nf_frags.rhash_params = ip6_rhash_params;
+ nf_frags.rhash_params = nfct_rhash_params;
ret = inet_frags_init(&nf_frags);
if (ret)
goto out;
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 6c65d756e603..e0ab50c58dc4 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -50,7 +50,7 @@ config NF_CONNTRACK
tristate "Netfilter connection tracking support"
default m if NETFILTER_ADVANCED=n
select NF_DEFRAG_IPV4
- select NF_DEFRAG_IPV6 if IPV6
+ select NF_DEFRAG_IPV6 if IPV6 != n
help
Connection tracking keeps a record of what packets have passed
through your machine, in order to figure out how they are related
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 0b3851e825fa..53bd1ed1228a 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -6,7 +6,7 @@ nf_conntrack-y := nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_exp
nf_conntrack_proto_icmp.o \
nf_conntrack_extend.o nf_conntrack_acct.o nf_conntrack_seqadj.o
-nf_conntrack-$(CONFIG_IPV6) += nf_conntrack_proto_icmpv6.o
+nf_conntrack-$(subst m,y,$(CONFIG_IPV6)) += nf_conntrack_proto_icmpv6.o
nf_conntrack-$(CONFIG_NF_CONNTRACK_TIMEOUT) += nf_conntrack_timeout.o
nf_conntrack-$(CONFIG_NF_CONNTRACK_TIMESTAMP) += nf_conntrack_timestamp.o
nf_conntrack-$(CONFIG_NF_CONNTRACK_EVENTS) += nf_conntrack_ecache.o
^ permalink raw reply related
* Re: [RFC PATCH 0/1] net: phy: skip autoneg of ethernet(fec) on network boot
From: Florian Fainelli @ 2018-07-06 18:41 UTC (permalink / raw)
To: Masahiko Kimoto, Fugang Duan, Andrew Lunn, netdev,
Linux Kernel Mailing List, Hiraku Toyooka
In-Reply-To: <1530857230-31124-1-git-send-email-masahiko.kimoto@cybertrust.co.jp>
On 07/05/2018 11:07 PM, Masahiko Kimoto wrote:
> Hello,
>
> This patch introduces auto negotiation skipping for Ethernet.
> It is useful to shorten boot time on network boot like the following
> environment;
>
> - target board is NXP i.MX6.
> - NIC is fec.
> - using u-boot as boot loader.
> - boot from kernel and initramfs obtained via TFTP.
> - mount remote file system and switch root to that.
> - thus all file system is on network.
>
> In this case, u-boot and kernel initialize NIC three times,
> once in boot loader, once in device attach and once more in phy attach.
> Each causes link auto negotiation and wait several seconds.
> However link state is stable after reset by boot loader, therefore we
> can skip hardware re-initialization of NIC in kernel.
>
> The patch skips link down in Ethernet(i.MX's fec) driver and initialization
> in PHY layer if kernel option 'anegskip' is supplied.
>
> By this patch boot time becomes 3secs shorter.
>
> I think current patch is dirty hack, because;
> - modification is split into PHY and Ethernet driver.
> - in the case of two or more Ethernet I/F exist, currently there is
> no way to specify whith I/F skips autonego.
>
> I would like to implement such skpping auto negotiation feature in generic
> framework. How should we implement these requirements?
I completely acknowledge and support the use case, but your
implementation is definitively not the way to go. In my experience the
problem is usually that there may be a disagreement on the
Pause/Asym_Pause advertisement bits and that alone is responsible for
triggering a re-negotiation. Can yo check if that is the case here?
Thank you
--
Florian
^ permalink raw reply
* Re: [PATCH v2 02/14] sh_eth: fix invalid context bug while changing link options by ethtool
From: Sergei Shtylyov @ 2018-07-06 18:43 UTC (permalink / raw)
To: Vladimir Zapolskiy, David S . Miller
Cc: Andrew Lunn, Geert Uytterhoeven, netdev, linux-renesas-soc
In-Reply-To: <20180704081245.7395-3-vladimir_zapolskiy@mentor.com>
On 07/04/2018 11:12 AM, Vladimir Zapolskiy wrote:
> The change fixes sleep in atomic context bug, which is encountered
> every time when link settings are changed by ethtool.
>
> Since commit 35b5f6b1a82b ("PHYLIB: Locking fixes for PHY I/O
> potentially sleeping") phy_start_aneg() function utilizes a mutex
> to serialize changes to phy state, however that helper function is
> called in atomic context under a grabbed spinlock, because
> phy_start_aneg() is called by phy_ethtool_ksettings_set() and by
> replaced phy_ethtool_sset() helpers from phylib.
So if all this boils down to phy_start_aneg(), shouldn't this patch
precede patch #1. Or even fixing both call chains with 1 patch? :-)
> Now duplex mode setting is enforced in sh_eth_adjust_link() only,
> also now RX/TX is disabled when link is put down or modifications
> to E-MAC registers ECMR and GECMR are expected for both cases of
> checked and ignored link status pin state from E-MAC interrupt handler.
>
> For reference the change is a partial rework of commit 1e1b812bbe10
> ("sh_eth: fix handling of no LINK signal").
>
> Fixes: dc19e4e5e02f ("sh: sh_eth: Add support ethtool")
> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
[...]
Reviewed-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
MBR, Sergei
^ permalink raw reply
* [PATCH 0/2] allow PTP 224.0.0.107 to be timestamped
From: Ivan Khoronzhuk @ 2018-07-06 18:44 UTC (permalink / raw)
To: grygorii.strashko, davem
Cc: linux-omap, netdev, linux-kernel, Ivan Khoronzhuk
Allows packets with 224.0.0.107 mcas address for PTP packets to be timestamped.
Only for cpsw version > v1.15.
Ivan Khoronzhuk (2):
net: ethernet: ti: cpsw: use BIT macro
net: ethernet: ti: cpsw: allow PTP 224.0.0.107 to be timestamped
drivers/net/ethernet/ti/cpsw.c | 37 +++++++++++++++++-----------------
1 file changed, 19 insertions(+), 18 deletions(-)
--
2.17.1
^ permalink raw reply
* [PATCH 2/2] net: ethernet: ti: cpsw: allow PTP 224.0.0.107 to be timestamped
From: Ivan Khoronzhuk @ 2018-07-06 18:44 UTC (permalink / raw)
To: grygorii.strashko, davem
Cc: linux-omap, netdev, linux-kernel, Ivan Khoronzhuk
In-Reply-To: <20180706184445.29111-1-ivan.khoronzhuk@linaro.org>
Tested on AM572x with cpsw v1.15 for PTP sync and delay_req messages.
It doesn't work on cpsw v1.12, so added only for cpsw v > 1.15.
Command for testing:
ptp4l -P -4 -H -i eth0 -l 6 -m -q -p /dev/ptp0 -f ptp.cfg
where ptp.cfg:
[global]
tx_timestamp_timeout 20
Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
---
drivers/net/ethernet/ti/cpsw.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index f355e65323f3..00761fe59848 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -257,6 +257,7 @@ struct cpsw_ss_regs {
#define VLAN_LTYPE2_EN BIT(21) /* VLAN LTYPE 2 enable */
#define VLAN_LTYPE1_EN BIT(20) /* VLAN LTYPE 1 enable */
#define DSCP_PRI_EN BIT(16) /* DSCP Priority Enable */
+#define TS_107 BIT(15) /* Tyme Sync Dest IP Address 107 */
#define TS_320 BIT(14) /* Time Sync Dest Port 320 enable */
#define TS_319 BIT(13) /* Time Sync Dest Port 319 enable */
#define TS_132 BIT(12) /* Time Sync Dest IP Addr 132 enable */
@@ -281,7 +282,7 @@ struct cpsw_ss_regs {
#define CTRL_V3_TS_BITS \
- (TS_320 | TS_319 | TS_132 | TS_131 | TS_130 | TS_129 |\
+ (TS_107 | TS_320 | TS_319 | TS_132 | TS_131 | TS_130 | TS_129 |\
TS_TTL_NONZERO | TS_ANNEX_F_EN | TS_ANNEX_D_EN |\
TS_LTYPE1_EN)
--
2.17.1
^ permalink raw reply related
* [PATCH 1/2] net: ethernet: ti: cpsw: use BIT macro
From: Ivan Khoronzhuk @ 2018-07-06 18:44 UTC (permalink / raw)
To: grygorii.strashko, davem
Cc: linux-omap, netdev, linux-kernel, Ivan Khoronzhuk
In-Reply-To: <20180706184445.29111-1-ivan.khoronzhuk@linaro.org>
It's needed to avoid checkpatch warnings for farther changes.
Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
---
drivers/net/ethernet/ti/cpsw.c | 34 +++++++++++++++++-----------------
1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 093998124149..f355e65323f3 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -253,23 +253,23 @@ struct cpsw_ss_regs {
#define RX_DSCP_PRI_MAP7 0x4c /* Rx DSCP Priority to Rx Packet Mapping */
/* Bit definitions for the CPSW2_CONTROL register */
-#define PASS_PRI_TAGGED (1<<24) /* Pass Priority Tagged */
-#define VLAN_LTYPE2_EN (1<<21) /* VLAN LTYPE 2 enable */
-#define VLAN_LTYPE1_EN (1<<20) /* VLAN LTYPE 1 enable */
-#define DSCP_PRI_EN (1<<16) /* DSCP Priority Enable */
-#define TS_320 (1<<14) /* Time Sync Dest Port 320 enable */
-#define TS_319 (1<<13) /* Time Sync Dest Port 319 enable */
-#define TS_132 (1<<12) /* Time Sync Dest IP Addr 132 enable */
-#define TS_131 (1<<11) /* Time Sync Dest IP Addr 131 enable */
-#define TS_130 (1<<10) /* Time Sync Dest IP Addr 130 enable */
-#define TS_129 (1<<9) /* Time Sync Dest IP Addr 129 enable */
-#define TS_TTL_NONZERO (1<<8) /* Time Sync Time To Live Non-zero enable */
-#define TS_ANNEX_F_EN (1<<6) /* Time Sync Annex F enable */
-#define TS_ANNEX_D_EN (1<<4) /* Time Sync Annex D enable */
-#define TS_LTYPE2_EN (1<<3) /* Time Sync LTYPE 2 enable */
-#define TS_LTYPE1_EN (1<<2) /* Time Sync LTYPE 1 enable */
-#define TS_TX_EN (1<<1) /* Time Sync Transmit Enable */
-#define TS_RX_EN (1<<0) /* Time Sync Receive Enable */
+#define PASS_PRI_TAGGED BIT(24) /* Pass Priority Tagged */
+#define VLAN_LTYPE2_EN BIT(21) /* VLAN LTYPE 2 enable */
+#define VLAN_LTYPE1_EN BIT(20) /* VLAN LTYPE 1 enable */
+#define DSCP_PRI_EN BIT(16) /* DSCP Priority Enable */
+#define TS_320 BIT(14) /* Time Sync Dest Port 320 enable */
+#define TS_319 BIT(13) /* Time Sync Dest Port 319 enable */
+#define TS_132 BIT(12) /* Time Sync Dest IP Addr 132 enable */
+#define TS_131 BIT(11) /* Time Sync Dest IP Addr 131 enable */
+#define TS_130 BIT(10) /* Time Sync Dest IP Addr 130 enable */
+#define TS_129 BIT(9) /* Time Sync Dest IP Addr 129 enable */
+#define TS_TTL_NONZERO BIT(8) /* Time Sync Time To Live Non-zero enable */
+#define TS_ANNEX_F_EN BIT(6) /* Time Sync Annex F enable */
+#define TS_ANNEX_D_EN BIT(4) /* Time Sync Annex D enable */
+#define TS_LTYPE2_EN BIT(3) /* Time Sync LTYPE 2 enable */
+#define TS_LTYPE1_EN BIT(2) /* Time Sync LTYPE 1 enable */
+#define TS_TX_EN BIT(1) /* Time Sync Transmit Enable */
+#define TS_RX_EN BIT(0) /* Time Sync Receive Enable */
#define CTRL_V2_TS_BITS \
(TS_320 | TS_319 | TS_132 | TS_131 | TS_130 | TS_129 |\
--
2.17.1
^ permalink raw reply related
* Re: [PATCH v2 03/14] sh_eth: simplify link auto-negotiation by ethtool
From: Sergei Shtylyov @ 2018-07-06 18:48 UTC (permalink / raw)
To: Vladimir Zapolskiy, David S . Miller
Cc: Andrew Lunn, Geert Uytterhoeven, netdev, linux-renesas-soc
In-Reply-To: <20180704081245.7395-4-vladimir_zapolskiy@mentor.com>
On 07/04/2018 11:12 AM, Vladimir Zapolskiy wrote:
> There is no need to call a heavyweight phy_start_aneg() for phy
> auto-negotiation by ethtool, the phy is already initialized and
> link auto-negotiation is started by calling phy_start() from
> sh_eth_phy_start() when a network device is opened.
>
> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
[...]
Reviewed-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
MBR, Sergei
^ 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