* Re: [patch net-next RFC 04/12] dsa: set devlink port attrs for dsa ports
From: Jiri Pirko @ 2018-05-17 14:02 UTC (permalink / raw)
To: Florian Fainelli
Cc: Andrew Lunn, netdev, davem, idosch, jakub.kicinski, mlxsw,
vivien.didelot, michael.chan, ganeshgr, saeedm, simon.horman,
pieter.jansenvanvuuren, john.hurley, dirk.vandermerwe,
alexander.h.duyck, ogerlitz, dsahern, vijaya.guvva,
satananda.burla, raghu.vatsavayi, felix.manlunas, gospo,
sathya.perla, vasundhara-v.volam, tariqt, eranbe,
jeffrey.t.kirsher
In-Reply-To: <e8cc464f-6fcb-7ecd-10f3-b6d80aa7dad5@gmail.com>
Fri, Mar 23, 2018 at 06:09:29PM CET, f.fainelli@gmail.com wrote:
>On 03/23/2018 07:49 AM, Jiri Pirko wrote:
>> Fri, Mar 23, 2018 at 02:30:02PM CET, andrew@lunn.ch wrote:
>>> On Thu, Mar 22, 2018 at 11:55:14AM +0100, Jiri Pirko wrote:
>>>> From: Jiri Pirko <jiri@mellanox.com>
>>>>
>>>> Set the attrs and allow to expose port flavour to user via devlink.
>>>>
>>>> Signed-off-by: Jiri Pirko <jiri@mellanox.com>
>>>> ---
>>>> net/dsa/dsa2.c | 23 +++++++++++++++++++++++
>>>> 1 file changed, 23 insertions(+)
>>>>
>>>> diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
>>>> index adf50fbc4c13..49453690696d 100644
>>>> --- a/net/dsa/dsa2.c
>>>> +++ b/net/dsa/dsa2.c
>>>> @@ -270,7 +270,27 @@ static int dsa_port_setup(struct dsa_port *dp)
>>>> case DSA_PORT_TYPE_UNUSED:
>>>> break;
>>>> case DSA_PORT_TYPE_CPU:
>>>> + /* dp->index is used now as port_number. However
>>>> + * CPU ports should have separate numbering
>>>> + * independent from front panel port numbers.
>>>> + */
>>>> + devlink_port_attrs_set(&dp->devlink_port,
>>>> + DEVLINK_PORT_FLAVOUR_CPU,
>>>> + dp->index, false, 0);
>>>> + err = dsa_port_link_register_of(dp);
>>>> + if (err) {
>>>> + dev_err(ds->dev, "failed to setup link for port %d.%d\n",
>>>> + ds->index, dp->index);
>>>> + return err;
>>>> + }
>>>
>>> Ah, i get it. These used to be two case statements with one code
>>> block. But you split them apart, so needed to duplicate the
>>> dsa_port_link_register.
>>>
>>> Unfortunately, you forgot to add a 'break;', so it still falls
>>> through, and overwrites the port flavour to DSA.
>>
>> ah, crap. Don't have hw to test this :/
>> Will fix. Thanks!
>
>You don't need hardware, there is drivers/net/dsa/dsa_loop.c which will
>emulate a DSA switch. It won't create interconnect ports, since only one
Hmm, trying to use dsa_loop. Doing:
modprobe dsa_loop
modprobe fixed_phy
I don't see the netdevs. Any idea what am I doing wrong? Thanks!
>switch can be created with the method chosen, but this would have helped
>you catch the missing break since the "CPU" port would have been
>displayed as "DSA" anyway.
>
>If you need hardware, I am sure this can be somehow arranged. By that, I
>mean something on which you can run upstream Linux on without out of
>tree patches.
>--
>Florian
^ permalink raw reply
* Re: [PATCH net-next v3 1/3] ipv4: support sport, dport and ip_proto in RTM_GETROUTE
From: Roopa Prabhu @ 2018-05-17 13:58 UTC (permalink / raw)
To: David Miller; +Cc: netdev, David Ahern, Nikolay Aleksandrov, Ido Schimmel
In-Reply-To: <20180516.223649.1225994765125719685.davem@davemloft.net>
On Wed, May 16, 2018 at 7:36 PM, David Miller <davem@davemloft.net> wrote:
> From: Roopa Prabhu <roopa@cumulusnetworks.com>
> Date: Wed, 16 May 2018 13:30:28 -0700
>
>> yes, but we hold rcu read lock before calling the reply function for
>> fib result. I did consider allocating the skb before the read
>> lock..but then the refactoring (into a separate netlink reply func)
>> would seem unnecessary.
>>
>> I am fine with pre-allocating and undoing the refactoring if that works better.
>
> Hmmm... I also notice that with this change we end up doing the
> rtnl_unicast() under the RCU lock which is unnecessary too.
that was unintentional, it seemed like the previous code did that too..
and you are right it did not.
>
> So yes, please pull the "out_skb" allocation before the
> rcu_read_lock(), and push the rtnl_unicast() after the
> rcu_read_unlock().
agreed, will do.
>
> It really is a shame that sharing the ETH_P_IP skb between the route
> route lookup and the netlink response doesn't work properly.
I did try a few things before giving up on the same skb...since it
also seemed like
keeping the netlink code separate would be a good thing for the future.
>
> I was using RTM_GETROUTE at one point for route/fib lookup performance
> measurements. It never was great at that, but now that there is going
> to be two SKB allocations instead of one it is going to be even less
> useful for that kind of usage.
oh...did not realize this use of it. It certainly seems like we should
try to retain the
single skb in that case. let me see what i can do.
thanks.
^ permalink raw reply
* Re: [PATCH net-next] net/smc: init conn.tx_work & conn.send_lock sooner
From: Ursula Braun @ 2018-05-17 13:57 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, netdev, Eric Dumazet, linux-s390
In-Reply-To: <CANn89iJ7hMTjbz_-MbLt2TwsxYARKaov1MoiVMzx4jofsJrewA@mail.gmail.com>
On 05/17/2018 02:20 PM, Eric Dumazet wrote:
> On Thu, May 17, 2018 at 5:13 AM Ursula Braun <ubraun@linux.ibm.com> wrote:
>
>> This problem should no longer show up with yesterday's net-next commit
>> 569bc6436568 ("net/smc: no tx work trigger for fallback sockets").
>
> It definitely triggers on latest net-next, which includes 569bc6436568
>
> Thanks.
>
Sorry, my fault.
Your proposed patch solves the problem. On the other hand the purpose of
smc_tx_init() has been to cover tx-related socket initializations needed for
connection sockets only. tx_work is something that should be scheduled only
for active connection sockets in non-fallback mode.
Thus I prefer this alternate patch to solve the problem:
---
net/smc/af_smc.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
--- a/net/smc/af_smc.c
+++ b/net/smc/af_smc.c
@@ -1362,14 +1362,18 @@ static int smc_setsockopt(struct socket
}
break;
case TCP_NODELAY:
- if (sk->sk_state != SMC_INIT && sk->sk_state != SMC_LISTEN) {
+ if (sk->sk_state != SMC_INIT &&
+ sk->sk_state != SMC_LISTEN &&
+ sk->sk_state != SMC_CLOSED) {
if (val && !smc->use_fallback)
mod_delayed_work(system_wq, &smc->conn.tx_work,
0);
}
break;
case TCP_CORK:
- if (sk->sk_state != SMC_INIT && sk->sk_state != SMC_LISTEN) {
+ if (sk->sk_state != SMC_INIT &&
+ sk->sk_state != SMC_LISTEN &&
+ sk->sk_state != SMC_CLOSED) {
if (!val && !smc->use_fallback)
mod_delayed_work(system_wq, &smc->conn.tx_work,
0);
What do you think?
^ permalink raw reply
* KASAN: use-after-free Read in vhost_chr_write_iter
From: DaeRyong Jeong @ 2018-05-17 13:45 UTC (permalink / raw)
To: mst, jasowang
Cc: kvm, virtualization, netdev, linux-kernel, byoungyoung, kt0755,
bammanag
We report the crash: KASAN: use-after-free Read in vhost_chr_write_iter
This crash has been found in v4.17-rc1 using RaceFuzzer (a modified
version of Syzkaller), which we describe more at the end of this
report. Our analysis shows that the race occurs when invoking two
syscalls concurrently, write$vnet and ioctl$VHOST_RESET_OWNER.
Analysis:
We think the concurrent execution of vhost_process_iotlb_msg() and
vhost_dev_cleanup() causes the crash.
Both of functions can run concurrently (please see call sequence below),
and possibly, there is a race on dev->iotlb.
If the switch occurs right after vhost_dev_cleanup() frees
dev->iotlb, vhost_process_iotlb_msg() still sees the non-null value and it
keep executing without returning -EFAULT. Consequently, use-after-free
occures
Thread interleaving:
CPU0 (vhost_process_iotlb_msg) CPU1 (vhost_dev_cleanup)
(In the case of both VHOST_IOTLB_UPDATE and
VHOST_IOTLB_INVALIDATE)
===== =====
vhost_umem_clean(dev->iotlb);
if (!dev->iotlb) {
ret = -EFAULT;
break;
}
dev->iotlb = NULL;
Call Sequence:
CPU0
=====
vhost_net_chr_write_iter
vhost_chr_write_iter
vhost_process_iotlb_msg
CPU1
=====
vhost_net_ioctl
vhost_net_reset_owner
vhost_dev_reset_owner
vhost_dev_cleanup
==================================================================
BUG: KASAN: use-after-free in vhost_umem_interval_tree_iter_first drivers/vhost/vhost.c:52 [inline]
BUG: KASAN: use-after-free in vhost_del_umem_range drivers/vhost/vhost.c:936 [inline]
BUG: KASAN: use-after-free in vhost_process_iotlb_msg drivers/vhost/vhost.c:1010 [inline]
BUG: KASAN: use-after-free in vhost_chr_write_iter+0x44e/0xcd0 drivers/vhost/vhost.c:1037
Read of size 8 at addr ffff8801d9d7bc00 by task syz-executor0/4997
CPU: 0 PID: 4997 Comm: syz-executor0 Not tainted 4.17.0-rc1 #1
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.8.2-0-g33fbe13 by qemu-project.org 04/01/2014
Call Trace:
__dump_stack lib/dump_stack.c:77 [inline]
dump_stack+0x166/0x21c lib/dump_stack.c:113
print_address_description+0x73/0x250 mm/kasan/report.c:256
kasan_report_error mm/kasan/report.c:354 [inline]
kasan_report+0x23f/0x360 mm/kasan/report.c:412
check_memory_region_inline mm/kasan/kasan.c:260 [inline]
__asan_load8+0x54/0x90 mm/kasan/kasan.c:699
vhost_umem_interval_tree_iter_first drivers/vhost/vhost.c:52 [inline]
vhost_del_umem_range drivers/vhost/vhost.c:936 [inline]
vhost_process_iotlb_msg drivers/vhost/vhost.c:1010 [inline]
vhost_chr_write_iter+0x44e/0xcd0 drivers/vhost/vhost.c:1037
vhost_net_chr_write_iter+0x38/0x40 drivers/vhost/net.c:1380
call_write_iter include/linux/fs.h:1784 [inline]
new_sync_write fs/read_write.c:474 [inline]
__vfs_write+0x355/0x480 fs/read_write.c:487
vfs_write+0x12d/0x2d0 fs/read_write.c:549
ksys_write+0xca/0x190 fs/read_write.c:598
__do_sys_write fs/read_write.c:610 [inline]
__se_sys_write fs/read_write.c:607 [inline]
__x64_sys_write+0x43/0x50 fs/read_write.c:607
do_syscall_64+0x15f/0x4a0 arch/x86/entry/common.c:287
entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x4563f9
RSP: 002b:00007f4da7ce9b28 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
RAX: ffffffffffffffda RBX: 000000000072bee0 RCX: 00000000004563f9
RDX: 0000000000000068 RSI: 00000000200006c0 RDI: 0000000000000015
RBP: 0000000000000729 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 00007f4da7cea6d4
R13: 00000000ffffffff R14: 00000000006ffc78 R15: 0000000000000000
Allocated by task 4997:
save_stack+0x43/0xd0 mm/kasan/kasan.c:448
set_track mm/kasan/kasan.c:460 [inline]
kasan_kmalloc+0xae/0xe0 mm/kasan/kasan.c:553
__do_kmalloc_node mm/slab.c:3682 [inline]
__kmalloc_node+0x47/0x70 mm/slab.c:3689
kmalloc_node include/linux/slab.h:554 [inline]
kvmalloc_node+0x99/0xd0 mm/util.c:421
kvmalloc include/linux/mm.h:550 [inline]
kvzalloc include/linux/mm.h:558 [inline]
vhost_umem_alloc+0x72/0x120 drivers/vhost/vhost.c:1260
vhost_init_device_iotlb+0x1e/0x160 drivers/vhost/vhost.c:1548
vhost_net_set_features drivers/vhost/net.c:1273 [inline]
vhost_net_ioctl+0x849/0x1040 drivers/vhost/net.c:1338
vfs_ioctl fs/ioctl.c:46 [inline]
do_vfs_ioctl+0x145/0xd00 fs/ioctl.c:686
ksys_ioctl+0x94/0xb0 fs/ioctl.c:701
__do_sys_ioctl fs/ioctl.c:708 [inline]
__se_sys_ioctl fs/ioctl.c:706 [inline]
__x64_sys_ioctl+0x43/0x50 fs/ioctl.c:706
do_syscall_64+0x15f/0x4a0 arch/x86/entry/common.c:287
entry_SYSCALL_64_after_hwframe+0x49/0xbe
Freed by task 5000:
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]
kfree+0xd9/0x260 mm/slab.c:3813
kvfree+0x36/0x60 mm/util.c:440
vhost_umem_clean+0x82/0xa0 drivers/vhost/vhost.c:587
vhost_dev_cleanup+0x5f3/0xa50 drivers/vhost/vhost.c:629
vhost_dev_reset_owner+0x82/0x170 drivers/vhost/vhost.c:542
vhost_net_reset_owner drivers/vhost/net.c:1238 [inline]
vhost_net_ioctl+0x7e1/0x1040 drivers/vhost/net.c:1340
vfs_ioctl fs/ioctl.c:46 [inline]
do_vfs_ioctl+0x145/0xd00 fs/ioctl.c:686
ksys_ioctl+0x94/0xb0 fs/ioctl.c:701
__do_sys_ioctl fs/ioctl.c:708 [inline]
__se_sys_ioctl fs/ioctl.c:706 [inline]
__x64_sys_ioctl+0x43/0x50 fs/ioctl.c:706
do_syscall_64+0x15f/0x4a0 arch/x86/entry/common.c:287
entry_SYSCALL_64_after_hwframe+0x49/0xbe
The buggy address belongs to the object at ffff8801d9d7bc00
which belongs to the cache kmalloc-64 of size 64
The buggy address is located 0 bytes inside of
64-byte region [ffff8801d9d7bc00, ffff8801d9d7bc40)
The buggy address belongs to the page:
page:ffffea0007675ec0 count:1 mapcount:0 mapping:ffff8801d9d7b000 index:0x0
flags: 0x2fffc0000000100(slab)
raw: 02fffc0000000100 ffff8801d9d7b000 0000000000000000 0000000100000020
raw: ffffea000768df60 ffffea0007b58ee0 ffff8801f6800340 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff8801d9d7bb00: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
ffff8801d9d7bb80: 00 00 00 00 00 fc fc fc fc fc fc fc fc fc fc fc
>ffff8801d9d7bc00: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
^
ffff8801d9d7bc80: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
ffff8801d9d7bd00: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
==================================================================
= About RaceFuzzer
RaceFuzzer is a customized version of Syzkaller, specifically tailored
to find race condition bugs in the Linux kernel. While we leverage
many different technique, the notable feature of RaceFuzzer is in
leveraging a custom hypervisor (QEMU/KVM) to interleave the
scheduling. In particular, we modified the hypervisor to intentionally
stall a per-core execution, which is similar to supporting per-core
breakpoint functionality. This allows RaceFuzzer to force the kernel
to deterministically trigger racy condition (which may rarely happen
in practice due to randomness in scheduling).
RaceFuzzer's C repro always pinpoints two racy syscalls. Since C
repro's scheduling synchronization should be performed at the user
space, its reproducibility is limited (reproduction may take from 1
second to 10 minutes (or even more), depending on a bug). This is
because, while RaceFuzzer precisely interleaves the scheduling at the
kernel's instruction level when finding this bug, C repro cannot fully
utilize such a feature. Please disregard all code related to
"should_hypercall" in the C repro, as this is only for our debugging
purposes using our own hypervisor.
^ permalink raw reply
* Re: [PATCH v3 1/2] media: rc: introduce BPF_PROG_RAWIR_EVENT
From: Sean Young @ 2018-05-17 13:44 UTC (permalink / raw)
To: Quentin Monnet
Cc: linux-media, linux-kernel, Alexei Starovoitov,
Mauro Carvalho Chehab, Daniel Borkmann, netdev, Matthias Reichl,
Devin Heitmueller, Y Song
In-Reply-To: <592262ad-e92f-2b53-f6bb-086257c21db0@netronome.com>
Hi Quentin,
On Thu, May 17, 2018 at 01:10:56PM +0100, Quentin Monnet wrote:
> 2018-05-16 22:04 UTC+0100 ~ Sean Young <sean@mess.org>
> > Add support for BPF_PROG_RAWIR_EVENT. This type of BPF program can call
> > rc_keydown() to reported decoded IR scancodes, or rc_repeat() to report
> > that the last key should be repeated.
> >
> > The bpf program can be attached to using the bpf(BPF_PROG_ATTACH) syscall;
> > the target_fd must be the /dev/lircN device.
> >
> > Signed-off-by: Sean Young <sean@mess.org>
> > ---
> > drivers/media/rc/Kconfig | 13 ++
> > drivers/media/rc/Makefile | 1 +
> > drivers/media/rc/bpf-rawir-event.c | 363 +++++++++++++++++++++++++++++
> > drivers/media/rc/lirc_dev.c | 24 ++
> > drivers/media/rc/rc-core-priv.h | 24 ++
> > drivers/media/rc/rc-ir-raw.c | 14 +-
> > include/linux/bpf_rcdev.h | 30 +++
> > include/linux/bpf_types.h | 3 +
> > include/uapi/linux/bpf.h | 55 ++++-
> > kernel/bpf/syscall.c | 7 +
> > 10 files changed, 531 insertions(+), 3 deletions(-)
> > create mode 100644 drivers/media/rc/bpf-rawir-event.c
> > create mode 100644 include/linux/bpf_rcdev.h
> >
>
> [...]
>
> Hi Sean,
>
> Please find below some nitpicks on the documentation for the two helpers.
I agree with all your points. I will reword and fix this for v4.
Thanks,
Sean
>
> > diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
> > index d94d333a8225..243e141e8a5b 100644
> > --- a/include/uapi/linux/bpf.h
> > +++ b/include/uapi/linux/bpf.h
>
> [...]
>
> > @@ -1902,6 +1904,35 @@ union bpf_attr {
> > * egress otherwise). This is the only flag supported for now.
> > * Return
> > * **SK_PASS** on success, or **SK_DROP** on error.
> > + *
> > + * int bpf_rc_keydown(void *ctx, u32 protocol, u32 scancode, u32 toggle)
> > + * Description
> > + * Report decoded scancode with toggle value. For use in
> > + * BPF_PROG_TYPE_RAWIR_EVENT, to report a successfully
>
> Could you please use bold RST markup for constants and function names?
> Typically for BPF_PROG_TYPE_RAWIR_EVENT here and the enum below.
>
> > + * decoded scancode. This is will generate a keydown event,
>
> s/This is will/This will/?
>
> > + * and a keyup event once the scancode is no longer repeated.
> > + *
> > + * *ctx* pointer to bpf_rawir_event, *protocol* is decoded
> > + * protocol (see RC_PROTO_* enum).
>
> This documentation is intended to be compiled as a man page. Could you
> please use a complete sentence here?
> Also, this could do with additional markup as well: **struct
> bpf_rawir_event**.
>
> > + *
> > + * Some protocols include a toggle bit, in case the button
> > + * was released and pressed again between consecutive scancodes,
> > + * copy this bit into *toggle* if it exists, else set to 0.
> > + *
> > + * Return
>
> The "Return" lines here and in the second helper use space indent
> instead as tabs (as all other lines do). Would you mind fixing it for
> consistency?
>
> > + * Always return 0 (for now)
>
> Other helpers use just "0" in that case, but I do not really mind.
> Out of curiosity, do you have anything specific in mind for changing the
> return value here in the future?
I don't expect this is to change, so I should just "0".
>
> > + *
> > + * int bpf_rc_repeat(void *ctx)
> > + * Description
> > + * Repeat the last decoded scancode; some IR protocols like
> > + * NEC have a special IR message for repeat last button,
>
> s/repeat/repeating/?
>
> > + * in case user is holding a button down; the scancode is
> > + * not repeated.
> > + *
> > + * *ctx* pointer to bpf_rawir_event.
>
> Please use a complete sentence here as well, if you do not mind.
>
> > + *
> > + * Return
> > + * Always return 0 (for now)
> > */
> Thanks,
> Quentin
^ permalink raw reply
* [QUESTION] ehea memory notifier
From: David Hildenbrand @ 2018-05-17 13:38 UTC (permalink / raw)
To: Douglas Miller; +Cc: netdev, David S. Miller
Hi,
looking at the ehea_mem_notifier() and called functions, I wonder if
it can tolerate addresses and sizes that are not aligned to EHEA_SECTSIZE.
Looks like for MEM_ONLINE/MEM_GOING_OFFLINE ehea_update_busmap() will do
nothing in case we don't span at least one EHEA_SECTSIZE.
This implies, that for onlined/offlined memory with unaligned
address/size, we won't mark the usmap entry valid.
start_section = (pfn * PAGE_SIZE) / EHEA_SECTSIZE;
end_section = start_section + ((nr_pages * PAGE_SIZE) / EHEA_SECTSIZE)
...
for (i = start_section; i < end_section; i++) {
...
}
The other way around, if we onlined e.g. 16GB and marked the entry
valid, we won't mark it invalid if e.g. offlining 8GB of that.
Is this the right thing to do? Especially
- is "valid of partially online sections" bad?
- is "invalid of partially online sections" bad?
(working on paravirtualized memory devices that will be able to
online/offline things that would not be possible on real HW and checking
all memory notifiers)
Thanks!
--
Thanks,
David / dhildenb
^ permalink raw reply
* Re: [PATCH 00/14] Modify action API for implementing lockless actions
From: Vlad Buslov @ 2018-05-17 13:35 UTC (permalink / raw)
To: Jiri Pirko
Cc: Roman Mashak, Jamal Hadi Salim, Linux Kernel Network Developers,
David Miller, Cong Wang, pablo, kadlec, fw, ast, Daniel Borkmann,
Eric Dumazet, kliteyn
In-Reply-To: <20180516215101.GQ1972@nanopsycho>
On Wed 16 May 2018 at 21:51, Jiri Pirko <jiri@resnulli.us> wrote:
> Wed, May 16, 2018 at 11:23:41PM CEST, vladbu@mellanox.com wrote:
>>
>>On Wed 16 May 2018 at 17:36, Roman Mashak <mrv@mojatatu.com> wrote:
>>> Vlad Buslov <vladbu@mellanox.com> writes:
>>>
>>>> On Wed 16 May 2018 at 14:38, Roman Mashak <mrv@mojatatu.com> wrote:
>>>>> On Wed, May 16, 2018 at 2:43 AM, Vlad Buslov <vladbu@mellanox.com> wrote:
>>>>>>>>>> I'm trying to run tdc, but keep getting following error even on clean
>>>>>>>>>> branch without my patches:
>>>>>>>>>
>>>>>>>>> Vlad, not sure if you saw my email:
>>>>>>>>> Apply Roman's patch and try again
>>>>>>>>>
>>>>>>>>> https://marc.info/?l=linux-netdev&m=152639369112020&w=2
>>>>>>>>>
>>>>>>>>> cheers,
>>>>>>>>> jamal
>>>>>>>>
>>>>>>>> With patch applied I get following error:
>>>>>>>>
>>>>>>>> Test 7d50: Add skbmod action to set destination mac
>>>>>>>> exit: 255 0
>>>>>>>> dst MAC address <11:22:33:44:55:66>
>>>>>>>> RTNETLINK answers: No such file or directory
>>>>>>>> We have an error talking to the kernel
>>>>>>>>
>>>>>>>
>>>>>>> You may actually have broken something with your patches in this case.
>>>>>>
>>>>>> Results is for net-next without my patches.
>>>>>
>>>>> Do you have skbmod compiled in kernel or as a module?
>>>>
>>>> Thanks, already figured out that default config has some actions
>>>> disabled.
>>>> Have more errors now. Everything related to ife:
>>>>
>>>> Test 7682: Create valid ife encode action with mark and pass control
>>>> exit: 255 0
>>>> IFE type 0xED3E
>>>> RTNETLINK answers: No such file or directory
>>>> We have an error talking to the kernel
>>>>
>>>> Test ef47: Create valid ife encode action with mark and pipe control
>>>> exit: 255 0
>>>> IFE type 0xED3E
>>>> RTNETLINK answers: No space left on device
>>>> We have an error talking to the kernel
>>>>
>>>> Test df43: Create valid ife encode action with mark and continue control
>>>> exit: 255 0
>>>> IFE type 0xED3E
>>>> RTNETLINK answers: No space left on device
>>>> We have an error talking to the kernel
>>>>
>>>> Test e4cf: Create valid ife encode action with mark and drop control
>>>> exit: 255 0
>>>> IFE type 0xED3E
>>>> RTNETLINK answers: No space left on device
>>>> We have an error talking to the kernel
>>>>
>>>> Test ccba: Create valid ife encode action with mark and reclassify control
>>>> exit: 255 0
>>>> IFE type 0xED3E
>>>> RTNETLINK answers: No space left on device
>>>> We have an error talking to the kernel
>>>>
>>>> Test a1cf: Create valid ife encode action with mark and jump control
>>>> exit: 255 0
>>>> IFE type 0xED3E
>>>> RTNETLINK answers: No space left on device
>>>> We have an error talking to the kernel
>>>>
>>>> ...
>>>>
>>>>
>>>
>>> Please make sure you have these in your kernel config:
>>>
>>> CONFIG_NET_ACT_IFE=y
>>> CONFIG_NET_IFE_SKBMARK=m
>>> CONFIG_NET_IFE_SKBPRIO=m
>>> CONFIG_NET_IFE_SKBTCINDEX=m
>
> Roman, could you please add this to some file? Something similar to:
> tools/testing/selftests/net/forwarding/config
>
> Thanks!
>
>>>
>>> For tdc to run all the tests, it is assumed that all the supported tc
>>> actions/filters are enabled and compiled.
>>
>>Enabling these options allowed all ife tests to pass. Thanks!
>>
>>Error in u32 test still appears however:
>>
>>Test e9a3: Add u32 with source match
>>
>>-----> prepare stage *** Could not execute: "$TC qdisc add dev $DEV1 ingress"
>>
>>-----> prepare stage *** Error message: "Cannot find device "v0p1"
I investigated and was able to fix u32 problems.
First of all, u32 test requires having veth interfaces that are not
created by test infrastructure by default. Following command fixes the
issue:
sudo ip link add v0p0 type veth peer name v0p1
After executing this command test passes, however looking at test
definition itself it seems meaningless. It creates filter with match
source IP 127.0.0.1, then tests if filter with source IP 127.0.0.2
exists, but passes successfully because it actually expects to match
zero filters with such IP :)
I fixed it and it passed properly matching single filter with source IP
127.0.0.2.
After this flower test failed. The flower test expects that user
explicitly provide "-d" option with interface to use. With -d it failed
again. This time because it expects action to have 1m references, but
actual value was 1000001. I investigated it and found out that test
passed, if executed without running other tests first. So it seemed that
some other test was leaking reference to gact action. It turned out that
culprit was mirred test 6fb4, which created pipe action but didn't flush
it afterward.
With all tests passing on that particular version of net-next, I will
now rebase my changes on top of it and run them again.
Regards,
Vlad
^ permalink raw reply
* [PATCH iproute2-next 1/1] tc: add missing space symbol in ife output
From: Roman Mashak @ 2018-05-17 13:28 UTC (permalink / raw)
To: stephen; +Cc: netdev, kernel, jhs, xiyou.wangcong, jiri, Roman Mashak
In order to make TDC tests match the output patterns, the missing space
character must be added in the mode output string.
Signed-off-by: Roman Mashak <mrv@mojatatu.com>
---
tc/m_ife.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tc/m_ife.c b/tc/m_ife.c
index 5320e94dbd48..20e9c73d9a0e 100644
--- a/tc/m_ife.c
+++ b/tc/m_ife.c
@@ -240,7 +240,7 @@ static int print_ife(struct action_util *au, FILE *f, struct rtattr *arg)
p = RTA_DATA(tb[TCA_IFE_PARMS]);
print_string(PRINT_ANY, "kind", "%s ", "ife");
- print_string(PRINT_ANY, "mode", "%s",
+ print_string(PRINT_ANY, "mode", "%s ",
p->flags & IFE_ENCODE ? "encode" : "decode");
print_action_control(f, "action ", p->action, " ");
--
2.7.4
^ permalink raw reply related
* Re: [PATCH v2 net-next 00/12] net: stmmac: Clean-up and tune-up
From: Jose Abreu @ 2018-05-17 13:24 UTC (permalink / raw)
To: Florian Fainelli, David Miller, Jose.Abreu
Cc: netdev, Joao.Pinto, Vitor.Soares, peppe.cavallaro,
alexandre.torgue
In-Reply-To: <64edab6c-0bbf-fd8a-6be6-aaf802f6d12f@gmail.com>
Hi David, Florian,
Results of slowing down CPU follows bellow.
On 16-05-2018 20:01, Florian Fainelli wrote:
> On 05/16/2018 11:56 AM, David Miller wrote:
>> From: Jose Abreu <Jose.Abreu@synopsys.com>
>> Date: Wed, 16 May 2018 13:50:42 +0100
>>
>>> David raised some rightfull constrains about the use of indirect callbacks in
>>> the code. I did iperf tests with and without patches 3-12 and the performance
>>> remained equal. I guess for 1Gb/s and because my setup has a powerfull
>>> processor these patches don't affect the performance.
>> Does your cpu need Spectre v1 and v2 workarounds which cause indirect calls to
>> be extremely expensive?
> Given how widespread stmmac is within the ARM CPU's ecosystem, the
> answer is more than likely yes.
>
> To get a better feeling of whether your indirect branches introduce a
> difference, either don't run the CPU at full speed (e.g: use cpufreq to
> slow it down), and/or profile the number of cycles and instruction cache
> hits/miss ratio for the functions called in hot-path.
It turns out my CPU has every single vulnerability detected so far :D
---
# cat /sys/devices/system/cpu/vulnerabilities/meltdown
Mitigation: PTI
# cat /sys/devices/system/cpu/vulnerabilities/spectre_v1
Mitigation: __user pointer sanitization
# cat /sys/devices/system/cpu/vulnerabilities/spectre_v2
Vulnerable: Minimal generic ASM retpoline
---
I'm not sure if workaround is active for spectre_v2 though,
because it just says "vulnerable" ...
Now, I'm using an 8 core Intel running @ 3.4 GHz:
---
# cat /proc/cpuinfo | grep -i mhz
cpu MHz : 3988.358
cpu MHz : 3991.775
cpu MHz : 3995.003
cpu MHz : 3996.003
cpu MHz : 3995.113
cpu MHz : 3996.512
cpu MHz : 3954.454
cpu MHz : 3937.402
---
So, following Florian advice I turned off 7 cores and changed CPU
freq to the minimum allowed (800MHz):
---
# cat /sys/bus/cpu/devices/cpu0/cpufreq/scaling_min_freq
800000
---
---
# for file in /sys/bus/cpu/devices/cpu*/cpufreq/scaling_governor;
do echo userspace > $file; done
# for file in /sys/bus/cpu/devices/cpu*/cpufreq/scaling_setspeed;
do echo 800000 > $file; done
# echo 0 > /sys/devices/system/cpu/cpu1/online
# echo 0 > /sys/devices/system/cpu/cpu2/online
# echo 0 > /sys/devices/system/cpu/cpu3/online
# echo 0 > /sys/devices/system/cpu/cpu4/online
# echo 0 > /sys/devices/system/cpu/cpu5/online
# echo 0 > /sys/devices/system/cpu/cpu6/online
# echo 0 > /sys/devices/system/cpu/cpu7/online
---
---
# cat /proc/cpuinfo | grep -i mhz
cpu MHz : 900.076
---
And these are the iperf results:
---
*With* patches 3-12, 8xCPU @ 3.4GHz: iperf = 0.0-60.0 sec 6.62
GBytes 948 Mbits/sec 0.045 ms 37/4838564 (0.00076%)
*With* patches 3-12, 1xCPU @ 800MHz: iperf = 0.0-60.0 sec 6.62
GBytes 947 Mbits/sec 0.000 ms 18/4833009 (0%)
*Without* patches 3-12, 8xCPU @ 3.4GHz: iperf = 0.0-60.0 sec
6.60 GBytes 945 Mbits/sec 0.049 ms 31/4819455 (0.00064%)
*Without* patches 3-12, 1xCPU @ 800MHz: iperf = 0.0-60.0 sec
6.62 GBytes 948 Mbits/sec 0.000 ms 0/4837257 (0%)
---
Given that the difference between better/worst is < 1%, I think
we can conclude patches 3-13 don't affect the overall
performance. I didn't profile the cache hits/miss though ...
Any comments? Unfortunately I don't have access to an ARM board
to test this yet ...
Thanks and Best Regards,
Jose Miguel Abreu
^ permalink raw reply
* Re: [PATCH v2] netfilter: properly initialize xt_table_info structure
From: Greg Kroah-Hartman @ 2018-05-17 13:20 UTC (permalink / raw)
To: Jan Engelhardt
Cc: Eric Dumazet, Greg Hackmann, Pablo Neira Ayuso, Jozsef Kadlecsik,
Florian Westphal, Michal Kubecek, netfilter-devel, coreteam,
netdev
In-Reply-To: <alpine.LSU.2.20.1805171232210.30649@n3.vanv.qr>
On Thu, May 17, 2018 at 12:42:00PM +0200, Jan Engelhardt wrote:
>
> On Thursday 2018-05-17 12:09, Greg Kroah-Hartman wrote:
> >> > --- a/net/netfilter/x_tables.c
> >> > +++ b/net/netfilter/x_tables.c
> >> > @@ -1183,11 +1183,10 @@ struct xt_table_info *xt_alloc_table_info(unsigned int size)
> >> > * than shoot all processes down before realizing there is nothing
> >> > * more to reclaim.
> >> > */
> >> > - info = kvmalloc(sz, GFP_KERNEL | __GFP_NORETRY);
> >> > + info = kvzalloc(sz, GFP_KERNEL | __GFP_NORETRY);
> >> > if (!info)
> >> > return NULL;
> >>
> >> I am curious, what particular path does not later overwrite the whole zone ?
> >
> >In do_ipt_get_ctl, the IPT_SO_GET_ENTRIES: option uses a len value that
> >can be larger than the size of the structure itself.
> >
> >Then the data is copied to userspace in copy_entries_to_user() for ipv4
> >and v6, and that's where the "bad data"
>
> If the kernel incorrectly copies more bytes than it should, isn't that
> a sign that may be going going past the end of the info buffer?
> (And thus, zeroing won't truly fix the issue)
No, the buffer size is correct, we just aren't filling up the whole
buffer as the data requested is smaller than the buffer size.
thanks,
greg k-h
^ permalink raw reply
* Re: [PATCH net-next 1/2] net: phy: sfp: make the i2c-bus property really optional
From: Antoine Tenart @ 2018-05-17 13:13 UTC (permalink / raw)
To: Andrew Lunn
Cc: Antoine Tenart, davem, linux, netdev, linux-kernel,
thomas.petazzoni, maxime.chevallier, gregory.clement,
miquel.raynal, nadavh, stefanc, ymarkman, mw
In-Reply-To: <20180517130406.GH8547@lunn.ch>
On Thu, May 17, 2018 at 03:04:06PM +0200, Andrew Lunn wrote:
>
> I was thinking about how it reads the bit rate from the EEPROM. From
> that it determines what mode the MAC could use, 1000-Base-X,
> 2500-Base-X, etc. Can you still configure this correctly via ethtool,
> if you don't have the bitrate information?
I see. That's a very good question. When testing this, I used SFP cages
which were not wired *at all*. So it worked because the SFP module
injection never was seen by the kernel, which was then not calling
phylink_sfp_module_insert() and thus not calling sfp_parse_support().
But in cases where the module insertion can be detected, as you pointed
out, I'm not so sure it can work then. I'll wait for other answers, but
we may want to fail when probing such modules as you suggested.
Thanks!
Antoine
--
Antoine Ténart, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* [PATCH net-next 1/1] tc-testing: fixed copy-pasting error in ife tests
From: Roman Mashak @ 2018-05-17 13:12 UTC (permalink / raw)
To: davem; +Cc: netdev, kernel, jhs, xiyou.wangcong, jiri, Roman Mashak
Reported-by: Vlad Buslov <vladbu@mellanox.com>
Reported-by: Davide Caratti <dcaratti@redhat.com>
Signed-off-by: Roman Mashak <mrv@mojatatu.com>
---
.../selftests/tc-testing/tc-tests/actions/ife.json | 28 +++++++++++-----------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/ife.json b/tools/testing/selftests/tc-testing/tc-tests/actions/ife.json
index 03777730ef29..de97e4ff705c 100644
--- a/tools/testing/selftests/tc-testing/tc-tests/actions/ife.json
+++ b/tools/testing/selftests/tc-testing/tc-tests/actions/ife.json
@@ -20,7 +20,7 @@
"matchPattern": "action order [0-9]*: ife encode action pass.*type 0xED3E.*allow mark.*index 2",
"matchCount": "1",
"teardown": [
- "$TC actions flush action skbedit"
+ "$TC actions flush action ife"
]
},
{
@@ -44,7 +44,7 @@
"matchPattern": "action order [0-9]*: ife encode action pipe.*type 0xED3E.*use mark.*index 2",
"matchCount": "1",
"teardown": [
- "$TC actions flush action skbedit"
+ "$TC actions flush action ife"
]
},
{
@@ -68,7 +68,7 @@
"matchPattern": "action order [0-9]*: ife encode action continue.*type 0xED3E.*allow mark.*index 2",
"matchCount": "1",
"teardown": [
- "$TC actions flush action skbedit"
+ "$TC actions flush action ife"
]
},
{
@@ -92,7 +92,7 @@
"matchPattern": "action order [0-9]*: ife encode action drop.*type 0xED3E.*use mark 789.*index 2",
"matchCount": "1",
"teardown": [
- "$TC actions flush action skbedit"
+ "$TC actions flush action ife"
]
},
{
@@ -116,7 +116,7 @@
"matchPattern": "action order [0-9]*: ife encode action reclassify.*type 0xED3E.*use mark 656768.*index 2",
"matchCount": "1",
"teardown": [
- "$TC actions flush action skbedit"
+ "$TC actions flush action ife"
]
},
{
@@ -140,7 +140,7 @@
"matchPattern": "action order [0-9]*: ife encode action jump 1.*type 0xED3E.*use mark 65.*index 2",
"matchCount": "1",
"teardown": [
- "$TC actions flush action skbedit"
+ "$TC actions flush action ife"
]
},
{
@@ -164,7 +164,7 @@
"matchPattern": "action order [0-9]*: ife encode action reclassify.*type 0xED3E.*use mark 4294967295.*index 90",
"matchCount": "1",
"teardown": [
- "$TC actions flush action skbedit"
+ "$TC actions flush action ife"
]
},
{
@@ -210,7 +210,7 @@
"matchPattern": "action order [0-9]*: ife encode action pass.*type 0xED3E.*allow prio.*index 9",
"matchCount": "1",
"teardown": [
- "$TC actions flush action skbedit"
+ "$TC actions flush action ife"
]
},
{
@@ -234,7 +234,7 @@
"matchPattern": "action order [0-9]*: ife encode action pipe.*type 0xED3E.*use prio 7.*index 9",
"matchCount": "1",
"teardown": [
- "$TC actions flush action skbedit"
+ "$TC actions flush action ife"
]
},
{
@@ -258,7 +258,7 @@
"matchPattern": "action order [0-9]*: ife encode action continue.*type 0xED3E.*use prio 3.*index 9",
"matchCount": "1",
"teardown": [
- "$TC actions flush action skbedit"
+ "$TC actions flush action ife"
]
},
{
@@ -282,7 +282,7 @@
"matchPattern": "action order [0-9]*: ife encode action drop.*type 0xED3E.*allow prio.*index 9",
"matchCount": "1",
"teardown": [
- "$TC actions flush action skbedit"
+ "$TC actions flush action ife"
]
},
{
@@ -306,7 +306,7 @@
"matchPattern": "action order [0-9]*: ife encode action reclassify.*type 0xED3E.*use prio 998877.*index 9",
"matchCount": "1",
"teardown": [
- "$TC actions flush action skbedit"
+ "$TC actions flush action ife"
]
},
{
@@ -330,7 +330,7 @@
"matchPattern": "action order [0-9]*: ife encode action jump 10.*type 0xED3E.*use prio 998877.*index 9",
"matchCount": "1",
"teardown": [
- "$TC actions flush action skbedit"
+ "$TC actions flush action ife"
]
},
{
@@ -354,7 +354,7 @@
"matchPattern": "action order [0-9]*: ife encode action reclassify.*type 0xED3E.*use prio 4294967295.*index 99",
"matchCount": "1",
"teardown": [
- "$TC actions flush action skbedit"
+ "$TC actions flush action ife"
]
},
{
--
2.7.4
^ permalink raw reply related
* Re: [PATCH net-next v12 3/7] sch_cake: Add optional ACK filter
From: Toke Høiland-Jørgensen @ 2018-05-17 13:11 UTC (permalink / raw)
To: Eric Dumazet, netdev; +Cc: cake
In-Reply-To: <541d62af-3938-5fdc-666c-dd243fa465b5@gmail.com>
Eric Dumazet <eric.dumazet@gmail.com> writes:
> On 05/17/2018 04:23 AM, Toke Høiland-Jørgensen wrote:
>
>>
>> We don't do full parsing of SACKs, no; we were trying to keep things
>> simple... We do detect the presence of SACK options, though, and the
>> presence of SACK options on an ACK will make previous ACKs be considered
>> redundant.
>>
>
> But they are not redundant in some cases, particularly when reorders
> happen in the network.
Huh. I was under the impression that SACKs were basically cumulative
until cleared.
I.e., in packet sequence ABCDE where B and D are lost, C would have
SACK(B) and E would have SACK(B,D). Are you saying that E would only
have SACK(D)?
-Toke
^ permalink raw reply
* [PATCH 4/4] arcnet: com20020: Add ethtool support
From: Andrea Greco @ 2018-05-17 13:07 UTC (permalink / raw)
To: tobin
Cc: andrea.greco.gapmilano, Andrea Greco, Michael Grzeschik, netdev,
linux-kernel
From: Andrea Greco <a.greco@4sigma.it>
Setup ethtols for export com20020 diag register
Signed-off-by: Andrea Greco <a.greco@4sigma.it>
---
drivers/net/arcnet/com20020-io.c | 1 +
drivers/net/arcnet/com20020-isa.c | 1 +
drivers/net/arcnet/com20020.c | 24 ++++++++++++++++++++++++
drivers/net/arcnet/com20020.h | 1 +
drivers/net/arcnet/com20020_cs.c | 1 +
include/uapi/linux/if_arcnet.h | 6 ++++++
6 files changed, 34 insertions(+)
diff --git a/drivers/net/arcnet/com20020-io.c b/drivers/net/arcnet/com20020-io.c
index fce458242193..0d4355bcd873 100644
--- a/drivers/net/arcnet/com20020-io.c
+++ b/drivers/net/arcnet/com20020-io.c
@@ -183,6 +183,7 @@ static int com20020_probe(struct platform_device *pdev)
dev = alloc_arcdev(NULL);
dev->netdev_ops = &com20020_netdev_ops;
+ dev->ethtool_ops = &com20020_ethtool_ops;
lp = netdev_priv(dev);
lp->card_flags = ARC_CAN_10MBIT;
diff --git a/drivers/net/arcnet/com20020-isa.c b/drivers/net/arcnet/com20020-isa.c
index 38fa60ddaf2e..44ab6dcccb58 100644
--- a/drivers/net/arcnet/com20020-isa.c
+++ b/drivers/net/arcnet/com20020-isa.c
@@ -154,6 +154,7 @@ static int __init com20020_init(void)
dev->dev_addr[0] = node;
dev->netdev_ops = &com20020_netdev_ops;
+ dev->ethtool_ops = &com20020_ethtool_ops;
lp = netdev_priv(dev);
lp->backplane = backplane;
diff --git a/drivers/net/arcnet/com20020.c b/drivers/net/arcnet/com20020.c
index f1de02f05305..02dd93a18e53 100644
--- a/drivers/net/arcnet/com20020.c
+++ b/drivers/net/arcnet/com20020.c
@@ -201,6 +201,29 @@ const struct net_device_ops com20020_netdev_ops = {
.ndo_set_rx_mode = com20020_set_mc_list,
};
+static int com20020_ethtool_regs_len(struct net_device *netdev)
+{
+ return sizeof(struct com20020_ethtool_regs);
+}
+
+static void com20020_ethtool_regs_read(struct net_device *dev,
+ struct ethtool_regs *regs, void *p)
+{
+ struct arcnet_local *lp = netdev_priv(dev);
+ struct com20020_ethtool_regs *com_reg = p;
+
+ memset(p, 0, sizeof(struct com20020_ethtool_regs));
+
+ com_reg->status = lp->hw.status(dev) & 0xFF;
+ com_reg->diag_register = (lp->hw.status(dev) >> 8) & 0xFF;
+ com_reg->reconf_count = lp->num_recons;
+}
+
+const struct ethtool_ops com20020_ethtool_ops = {
+ .get_regs = com20020_ethtool_regs_read,
+ .get_regs_len = com20020_ethtool_regs_len,
+};
+
/* Set up the struct net_device associated with this card. Called after
* probing succeeds.
*/
@@ -402,6 +425,7 @@ static void com20020_set_mc_list(struct net_device *dev)
EXPORT_SYMBOL(com20020_check);
EXPORT_SYMBOL(com20020_found);
EXPORT_SYMBOL(com20020_netdev_ops);
+EXPORT_SYMBOL(com20020_ethtool_ops);
#endif
MODULE_LICENSE("GPL");
diff --git a/drivers/net/arcnet/com20020.h b/drivers/net/arcnet/com20020.h
index 0bcc5d0a6903..a1024c8f8a1f 100644
--- a/drivers/net/arcnet/com20020.h
+++ b/drivers/net/arcnet/com20020.h
@@ -31,6 +31,7 @@
int com20020_check(struct net_device *dev);
int com20020_found(struct net_device *dev, int shared);
extern const struct net_device_ops com20020_netdev_ops;
+extern const struct ethtool_ops com20020_ethtool_ops;
/* The number of low I/O ports used by the card. */
#define ARCNET_TOTAL_SIZE 8
diff --git a/drivers/net/arcnet/com20020_cs.c b/drivers/net/arcnet/com20020_cs.c
index cf607ffcf358..ae64f436fd54 100644
--- a/drivers/net/arcnet/com20020_cs.c
+++ b/drivers/net/arcnet/com20020_cs.c
@@ -233,6 +233,7 @@ static int com20020_config(struct pcmcia_device *link)
}
dev->irq = link->irq;
+ dev->ethtool_ops = &com20020_ethtool_ops;
ret = pcmcia_enable_device(link);
if (ret)
diff --git a/include/uapi/linux/if_arcnet.h b/include/uapi/linux/if_arcnet.h
index 683878036d76..790c0fa7386d 100644
--- a/include/uapi/linux/if_arcnet.h
+++ b/include/uapi/linux/if_arcnet.h
@@ -127,4 +127,10 @@ struct archdr {
} soft;
};
+struct com20020_ethtool_regs {
+ __u8 status;
+ __u8 diag_register;
+ __u32 reconf_count;
+};
+
#endif /* _LINUX_IF_ARCNET_H */
--
2.14.3
^ permalink raw reply related
* [PATCH 3/4] arcnet: com20020: Fixup missing SLOWARB bit
From: Andrea Greco @ 2018-05-17 13:07 UTC (permalink / raw)
To: tobin
Cc: andrea.greco.gapmilano, Andrea Greco, Michael Grzeschik, netdev,
linux-kernel
From: Andrea Greco <a.greco@4sigma.it>
If com20020 clock is major of 40Mhz SLOWARB bit is requested.
Signed-off-by: Andrea Greco <a.greco@4sigma.it>
---
drivers/net/arcnet/com20020.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/arcnet/com20020.c b/drivers/net/arcnet/com20020.c
index 2fd00d2dd6bf..f1de02f05305 100644
--- a/drivers/net/arcnet/com20020.c
+++ b/drivers/net/arcnet/com20020.c
@@ -102,6 +102,10 @@ int com20020_check(struct net_device *dev)
lp->setup = lp->clockm ? 0 : (lp->clockp << 1);
lp->setup2 = (lp->clockm << 4) | 8;
+ /* If clock is major of 40Mhz, SLOWARB bit must be set */
+ if (lp->clockm > 1)
+ lp->setup2 |= SLOWARB;
+
/* CHECK: should we do this for SOHARD cards ? */
/* Enable P1Mode for backplane mode */
lp->setup = lp->setup | P1MODE;
--
2.14.3
^ permalink raw reply related
* [PATCH 2/4] arcnet: com20020: bindings for smsc com20020
From: Andrea Greco @ 2018-05-17 13:06 UTC (permalink / raw)
To: tobin
Cc: andrea.greco.gapmilano, Andrea Greco, Rob Herring, Mark Rutland,
netdev, devicetree, linux-kernel
From: Andrea Greco <a.greco@4sigma.it>
Add devicetree bindings for smsc com20020
Signed-off-by: Andrea Greco <a.greco@4sigma.it>
---
.../devicetree/bindings/net/smsc-com20020.txt | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
create mode 100644 Documentation/devicetree/bindings/net/smsc-com20020.txt
diff --git a/Documentation/devicetree/bindings/net/smsc-com20020.txt b/Documentation/devicetree/bindings/net/smsc-com20020.txt
new file mode 100644
index 000000000000..92360b054873
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/smsc-com20020.txt
@@ -0,0 +1,21 @@
+SMSC com20020 Arcnet network controller
+
+Required propelty:
+- timeout-ns: Arcnet bus timeout, Idle Time (328000 - 20500)
+- bus-speed-bps: Arcnet bus speed (10000000 - 156250)
+- smsc,xtal-mhz: External oscillator frequency
+- smsc,backplane-enabled: Controller use backplane mode
+- reset-gpios: Chip reset pin
+- interrupts: Should contain controller interrupt
+
+arcnet@28000000 {
+ compatible = "smsc,com20020";
+
+ timeout-ns = <20500>;
+ bus-speed-bps = <10000000>;
+ smsc,xtal-mhz = <20>;
+ smsc,backplane-enabled;
+
+ reset-gpios = <&gpio3 21 GPIO_ACTIVE_LOW>;
+ interrupts = <&gpio2 10 GPIO_ACTIVE_LOW>;
+};
--
2.14.3
^ permalink raw reply related
* [PATCH 1/4] arcnet: com20020: Add com20020 io mapped version
From: Andrea Greco @ 2018-05-17 13:05 UTC (permalink / raw)
To: tobin
Cc: andrea.greco.gapmilano, Andrea Greco, Michael Grzeschik,
linux-kernel, netdev
From: Andrea Greco <a.greco@4sigma.it>
Add support for com20022I/com20020, io mapped.
Signed-off-by: Andrea Greco <a.greco@4sigma.it>
---
drivers/net/arcnet/Kconfig | 9 +-
drivers/net/arcnet/Makefile | 1 +
drivers/net/arcnet/arcdevice.h | 14 ++
drivers/net/arcnet/com20020-io.c | 287 +++++++++++++++++++++++++++++++++++++++
drivers/net/arcnet/com20020.c | 5 +-
5 files changed, 313 insertions(+), 3 deletions(-)
create mode 100644 drivers/net/arcnet/com20020-io.c
diff --git a/drivers/net/arcnet/Kconfig b/drivers/net/arcnet/Kconfig
index 39bd16f3f86d..85e60ed29fa8 100644
--- a/drivers/net/arcnet/Kconfig
+++ b/drivers/net/arcnet/Kconfig
@@ -3,7 +3,7 @@
#
menuconfig ARCNET
- depends on NETDEVICES && (ISA || PCI || PCMCIA)
+ depends on NETDEVICES
tristate "ARCnet support"
---help---
If you have a network card of this type, say Y and check out the
@@ -129,5 +129,12 @@ config ARCNET_COM20020_CS
To compile this driver as a module, choose M here: the module will be
called com20020_cs. If unsure, say N.
+config ARCNET_COM20020_IO
+ bool "Support for COM20020 (IO mapped)"
+ depends on ARCNET_COM20020 && !(ARCNET_COM20020_PCI || ARCNET_COM20020_ISA || ARCNET_COM20020_CS)
+ help
+ Say Y here if your custom board mount com20020 chipset or friends.
+ Supported Chipset: com20020, com20022, com20022I-3v3
+ If unsure, say N.
endif # ARCNET
diff --git a/drivers/net/arcnet/Makefile b/drivers/net/arcnet/Makefile
index 53525e8ea130..18da4341f404 100644
--- a/drivers/net/arcnet/Makefile
+++ b/drivers/net/arcnet/Makefile
@@ -14,3 +14,4 @@ obj-$(CONFIG_ARCNET_COM20020) += com20020.o
obj-$(CONFIG_ARCNET_COM20020_ISA) += com20020-isa.o
obj-$(CONFIG_ARCNET_COM20020_PCI) += com20020-pci.o
obj-$(CONFIG_ARCNET_COM20020_CS) += com20020_cs.o
+obj-$(CONFIG_ARCNET_COM20020_IO) += com20020-io.o
diff --git a/drivers/net/arcnet/arcdevice.h b/drivers/net/arcnet/arcdevice.h
index d09b2b46ab63..86c36d9b666b 100644
--- a/drivers/net/arcnet/arcdevice.h
+++ b/drivers/net/arcnet/arcdevice.h
@@ -371,6 +371,19 @@ void arcnet_timeout(struct net_device *dev);
#define BUS_ALIGN 1
#endif
+#ifdef CONFIG_ARCNET_COM20020_IO
+#define arcnet_inb(addr, offset) \
+ ioread8((void __iomem *)(addr) + BUS_ALIGN * offset)
+
+#define arcnet_outb(value, addr, offset) \
+ iowrite8(value, (void __iomem *)addr + BUS_ALIGN * offset)
+
+#define arcnet_insb(addr, offset, buffer, count) \
+ ioread8_rep((void __iomem *)addr + BUS_ALIGN * offset, buffer, count)
+
+#define arcnet_outsb(addr, offset, buffer, count) \
+ iowrite8_rep((void __iomem *)addr + BUS_ALIGN * offset, buffer, count)
+#else
/* addr and offset allow register like names to define the actual IO address.
* A configuration option multiplies the offset for alignment.
*/
@@ -388,6 +401,7 @@ void arcnet_timeout(struct net_device *dev);
readb((addr) + (offset))
#define arcnet_writeb(value, addr, offset) \
writeb(value, (addr) + (offset))
+#endif
#endif /* __KERNEL__ */
#endif /* _LINUX_ARCDEVICE_H */
diff --git a/drivers/net/arcnet/com20020-io.c b/drivers/net/arcnet/com20020-io.c
new file mode 100644
index 000000000000..fce458242193
--- /dev/null
+++ b/drivers/net/arcnet/com20020-io.c
@@ -0,0 +1,287 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/* Linux ARCnet driver for com 20020.
+ *
+ * datasheet:
+ * http://ww1.microchip.com/downloads/en/DeviceDoc/200223vrevc.pdf
+ * http://ww1.microchip.com/downloads/en/DeviceDoc/20020.pdf
+ *
+ * Supported chip version:
+ * - com20020
+ * - com20022
+ * - com20022I-3v3
+ */
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/platform_device.h>
+#include <linux/netdevice.h>
+#include <linux/of_address.h>
+#include <linux/of_gpio.h>
+#include <linux/sizes.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include "arcdevice.h"
+#include "com20020.h"
+
+/* Reset (5 * xTalFreq), minimal com20020 xTal is 10Mhz */
+#define RESET_DELAY 500
+
+enum com20020_xtal_freq {
+ freq_10Mhz = 10,
+ freq_20Mhz = 20,
+};
+
+enum com20020_arcnet_speed {
+ arc_speed_10M_bps = 10000000,
+ arc_speed_5M_bps = 5000000,
+ arc_speed_2M50_bps = 2500000,
+ arc_speed_1M25_bps = 1250000,
+ arc_speed_625K_bps = 625000,
+ arc_speed_312K5_bps = 312500,
+ arc_speed_156K25_bps = 156250,
+};
+
+enum com20020_timeout {
+ arc_timeout_328us = 328000,
+ arc_timeout_164us = 164000,
+ arc_timeout_82us = 82000,
+ arc_timeout_20u5s = 20500,
+};
+
+static int setup_clock(int *clockp, int *clockm, int xtal, int arcnet_speed)
+{
+ int pll_factor, req_clock_frq = 20;
+
+ switch (arcnet_speed) {
+ case arc_speed_10M_bps:
+ req_clock_frq = 80;
+ *clockp = 0;
+ break;
+ case arc_speed_5M_bps:
+ req_clock_frq = 40;
+ *clockp = 0;
+ break;
+ case arc_speed_2M50_bps:
+ *clockp = 0;
+ break;
+ case arc_speed_1M25_bps:
+ *clockp = 1;
+ break;
+ case arc_speed_625K_bps:
+ *clockp = 2;
+ break;
+ case arc_speed_312K5_bps:
+ *clockp = 3;
+ break;
+ case arc_speed_156K25_bps:
+ *clockp = 4;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (xtal != freq_10Mhz && xtal != freq_20Mhz)
+ return -EINVAL;
+
+ pll_factor = (unsigned int)req_clock_frq / xtal;
+
+ switch (pll_factor) {
+ case 1:
+ *clockm = 0;
+ break;
+ case 2:
+ *clockm = 1;
+ break;
+ case 4:
+ *clockm = 3;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int setup_timeout(int *timeout)
+{
+ switch (*timeout) {
+ case arc_timeout_328us:
+ *timeout = 0;
+ break;
+ case arc_timeout_164us:
+ *timeout = 1;
+ break;
+ case arc_timeout_82us:
+ *timeout = 2;
+ break;
+ case arc_timeout_20u5s:
+ *timeout = 3;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int com20020_probe(struct platform_device *pdev)
+{
+ struct device_node *np;
+ struct net_device *dev;
+ struct arcnet_local *lp;
+ struct resource res, *iores;
+ int ret, phy_reset;
+ u32 timeout, xtal, arc_speed;
+ int clockp, clockm;
+ void __iomem *ioaddr;
+ bool backplane = false;
+
+ np = pdev->dev.of_node;
+
+ iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ ret = of_address_to_resource(np, 0, &res);
+ if (ret)
+ return ret;
+
+ ret = of_property_read_u32(np, "timeout-ns", &timeout);
+ if (ret) {
+ dev_err(&pdev->dev, "timeout is required param");
+ return ret;
+ }
+
+ ret = of_property_read_u32(np, "smsc,xtal-mhz", &xtal);
+ if (ret) {
+ dev_err(&pdev->dev, "xtal-mhz is required param");
+ return ret;
+ }
+
+ ret = of_property_read_u32(np, "bus-speed-bps", &arc_speed);
+ if (ret) {
+ dev_err(&pdev->dev, "Bus speed is required param");
+ return ret;
+ }
+
+ if (of_property_read_bool(np, "smsc,backplane-enabled"))
+ backplane = true;
+
+ phy_reset = of_get_named_gpio(np, "reset-gpios", 0);
+ if (!gpio_is_valid(phy_reset)) {
+ dev_err(&pdev->dev, "reset gpio not valid");
+ return phy_reset;
+ }
+
+ ret = devm_gpio_request_one(&pdev->dev, phy_reset, GPIOF_OUT_INIT_LOW,
+ "arcnet-reset");
+ if (ret) {
+ dev_err(&pdev->dev, "failed to get phy reset gpio: %d\n", ret);
+ return ret;
+ }
+
+ dev = alloc_arcdev(NULL);
+ dev->netdev_ops = &com20020_netdev_ops;
+ lp = netdev_priv(dev);
+
+ lp->card_flags = ARC_CAN_10MBIT;
+
+ /* Will be set by userspace during if setup */
+ dev->dev_addr[0] = 0;
+
+ if (!devm_request_mem_region(&pdev->dev, res.start, resource_size(&res),
+ lp->card_name))
+ return -EBUSY;
+
+ ioaddr = devm_ioremap(&pdev->dev, iores->start, resource_size(iores));
+ if (!ioaddr) {
+ dev_err(&pdev->dev, "ioremap fallied\n");
+ return -ENOMEM;
+ }
+
+ gpio_set_value_cansleep(phy_reset, 0);
+ ndelay(RESET_DELAY);
+ gpio_set_value_cansleep(phy_reset, 1);
+
+ /* ARCNET controller needs this access to detect bustype */
+ arcnet_outb(0x00, ioaddr, COM20020_REG_W_COMMAND);
+ arcnet_inb(ioaddr, COM20020_REG_R_DIAGSTAT);
+
+ dev->base_addr = (unsigned long)ioaddr;
+
+ dev->irq = of_get_named_gpio(np, "interrupts", 0);
+ if (dev->irq == -EPROBE_DEFER) {
+ return dev->irq;
+ } else if (!gpio_is_valid(dev->irq)) {
+ dev_err(&pdev->dev, "irq-gpios not valid !");
+ return -EIO;
+ }
+ dev->irq = gpio_to_irq(dev->irq);
+
+ ret = setup_clock(&clockp, &clockm, xtal, arc_speed);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "Impossible use oscillator:%dMhz and arcnet bus speed:%dKbps",
+ xtal, arc_speed / 1000);
+ return ret;
+ }
+
+ ret = setup_timeout(&timeout);
+ if (ret) {
+ dev_err(&pdev->dev, "Timeout:%d is not valid value", timeout);
+ return ret;
+ }
+
+ lp->backplane = (int)backplane;
+ lp->timeout = timeout;
+ lp->clockm = clockm;
+ lp->clockp = clockp;
+ lp->hw.owner = THIS_MODULE;
+
+ if (arcnet_inb(ioaddr, COM20020_REG_R_STATUS) == 0xFF) {
+ ret = -EIO;
+ goto err_release_mem;
+ }
+
+ if (com20020_check(dev)) {
+ ret = -EIO;
+ goto err_release_mem;
+ }
+
+ ret = com20020_found(dev, IRQF_TRIGGER_FALLING);
+ if (ret)
+ goto err_release_mem;
+
+ dev_dbg(&pdev->dev, "probe Done\n");
+ return 0;
+
+err_release_mem:
+ devm_iounmap(&pdev->dev, (void __iomem *)ioaddr);
+ devm_release_mem_region(&pdev->dev, res.start, resource_size(&res));
+ dev_err(&pdev->dev, "probe failed!\n");
+ return ret;
+}
+
+static const struct of_device_id of_com20020_match[] = {
+ { .compatible = "smsc,com20020", },
+ { },
+};
+
+MODULE_DEVICE_TABLE(of, of_com20020_match);
+
+static struct platform_driver of_com20020_driver = {
+ .driver = {
+ .name = "com20020-memory-bus",
+ .of_match_table = of_com20020_match,
+ },
+ .probe = com20020_probe,
+};
+
+static int com20020_init(void)
+{
+ return platform_driver_register(&of_com20020_driver);
+}
+late_initcall(com20020_init);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/arcnet/com20020.c b/drivers/net/arcnet/com20020.c
index 78043a9c5981..2fd00d2dd6bf 100644
--- a/drivers/net/arcnet/com20020.c
+++ b/drivers/net/arcnet/com20020.c
@@ -43,7 +43,7 @@
#include "com20020.h"
static const char * const clockrates[] = {
- "XXXXXXX", "XXXXXXXX", "XXXXXX", "2.5 Mb/s",
+ "10 Mb/s", "XXXXXXXX", "XXXXXX", "2.5 Mb/s",
"1.25Mb/s", "625 Kb/s", "312.5 Kb/s", "156.25 Kb/s",
"Reserved", "Reserved", "Reserved"
};
@@ -393,7 +393,8 @@ static void com20020_set_mc_list(struct net_device *dev)
#if defined(CONFIG_ARCNET_COM20020_PCI_MODULE) || \
defined(CONFIG_ARCNET_COM20020_ISA_MODULE) || \
- defined(CONFIG_ARCNET_COM20020_CS_MODULE)
+ defined(CONFIG_ARCNET_COM20020_CS_MODULE) || \
+ defined(CONFIG_ARCNET_COM20020_IO)
EXPORT_SYMBOL(com20020_check);
EXPORT_SYMBOL(com20020_found);
EXPORT_SYMBOL(com20020_netdev_ops);
--
2.14.3
^ permalink raw reply related
* Re: [PATCH net-next 1/2] net: phy: sfp: make the i2c-bus property really optional
From: Andrew Lunn @ 2018-05-17 13:04 UTC (permalink / raw)
To: Antoine Tenart
Cc: davem, linux, netdev, linux-kernel, thomas.petazzoni,
maxime.chevallier, gregory.clement, miquel.raynal, nadavh,
stefanc, ymarkman, mw
In-Reply-To: <20180517125648.GM32746@kwain>
On Thu, May 17, 2018 at 02:56:48PM +0200, Antoine Tenart wrote:
> Hi Andrew,
>
> On Thu, May 17, 2018 at 02:41:28PM +0200, Andrew Lunn wrote:
> > On Thu, May 17, 2018 at 10:29:06AM +0200, Antoine Tenart wrote:
> > > The SFF,SFP documentation is clear about making all the DT properties,
> > > with the exception of the compatible, optional. In practice this is not
> > > the case and without an i2c-bus property provided the SFP code will
> > > throw NULL pointer exceptions.
> > >
> > > This patch is an attempt to fix this.
> >
> > How usable is an SFF/SFP module without access to the i2c EEPROM? I
> > guess this comes down to link speed. Can it be manually configured?
> >
> > I'm just wondering if we want to make this mandatory? Fail the probe
> > if it is not listed?
>
> Yes, the other option would be to fail when probing a cage missing the
> i2c description. I'd say a passive module can work without the i2c
> EEPROM accessible as it does not need to be configured. I don't know
> what would happen with active ones.
Hi Antoine
I was thinking about how it reads the bit rate from the EEPROM. From
that it determines what mode the MAC could use, 1000-Base-X,
2500-Base-X, etc. Can you still configure this correctly via ethtool,
if you don't have the bitrate information?
Andrew
^ permalink raw reply
* Re: [PATCH net-next 1/2] net: phy: sfp: make the i2c-bus property really optional
From: Antoine Tenart @ 2018-05-17 12:56 UTC (permalink / raw)
To: Andrew Lunn
Cc: Antoine Tenart, davem, linux, netdev, linux-kernel,
thomas.petazzoni, maxime.chevallier, gregory.clement,
miquel.raynal, nadavh, stefanc, ymarkman, mw
In-Reply-To: <20180517124127.GG8547@lunn.ch>
Hi Andrew,
On Thu, May 17, 2018 at 02:41:28PM +0200, Andrew Lunn wrote:
> On Thu, May 17, 2018 at 10:29:06AM +0200, Antoine Tenart wrote:
> > The SFF,SFP documentation is clear about making all the DT properties,
> > with the exception of the compatible, optional. In practice this is not
> > the case and without an i2c-bus property provided the SFP code will
> > throw NULL pointer exceptions.
> >
> > This patch is an attempt to fix this.
>
> How usable is an SFF/SFP module without access to the i2c EEPROM? I
> guess this comes down to link speed. Can it be manually configured?
>
> I'm just wondering if we want to make this mandatory? Fail the probe
> if it is not listed?
Yes, the other option would be to fail when probing a cage missing the
i2c description. I'd say a passive module can work without the i2c
EEPROM accessible as it does not need to be configured. I don't know
what would happen with active ones.
So the question is, do we want to enable partially working SFP cages
(ie. probably working with only a subset of SFP modules)?
Thanks!
Antoine
--
Antoine Ténart, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* [PATCH bpf-next] bpf: change eBPF helper doc parsing script to allow for smaller indent
From: Quentin Monnet @ 2018-05-17 12:43 UTC (permalink / raw)
To: daniel, ast; +Cc: netdev, oss-drivers, quentin.monnet
Documentation for eBPF helpers can be parsed from bpf.h and eventually
turned into a man page. Commit 6f96674dbd8c ("bpf: relax constraints on
formatting for eBPF helper documentation") changed the script used to
parse it, in order to allow for different indent style and to ease the
work for writing documentation for future helpers.
The script currently considers that the first tab can be replaced by 6
to 8 spaces. But the documentation for bpf_fib_lookup() uses a mix of
tabs (for the "Description" part) and of spaces ("Return" part), and
only has 5 space long indent for the latter.
We probably do not want to change the values accepted by the script each
time a new helper gets a new indent style. However, it is worth noting
that with those 5 spaces, the "Description" and "Return" part *look*
aligned in the generated patch and in `git show`, so it is likely other
helper authors will use the same length. Therefore, allow for helper
documentation to use 5 spaces only for the first indent level.
Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com>
---
scripts/bpf_helpers_doc.py | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/scripts/bpf_helpers_doc.py b/scripts/bpf_helpers_doc.py
index 8f59897fbda1..5010a4d5bfba 100755
--- a/scripts/bpf_helpers_doc.py
+++ b/scripts/bpf_helpers_doc.py
@@ -95,7 +95,7 @@ class HeaderParser(object):
return capture.group(1)
def parse_desc(self):
- p = re.compile(' \* ?(?:\t| {6,8})Description$')
+ p = re.compile(' \* ?(?:\t| {5,8})Description$')
capture = p.match(self.line)
if not capture:
# Helper can have empty description and we might be parsing another
@@ -109,7 +109,7 @@ class HeaderParser(object):
if self.line == ' *\n':
desc += '\n'
else:
- p = re.compile(' \* ?(?:\t| {6,8})(?:\t| {8})(.*)')
+ p = re.compile(' \* ?(?:\t| {5,8})(?:\t| {8})(.*)')
capture = p.match(self.line)
if capture:
desc += capture.group(1) + '\n'
@@ -118,7 +118,7 @@ class HeaderParser(object):
return desc
def parse_ret(self):
- p = re.compile(' \* ?(?:\t| {6,8})Return$')
+ p = re.compile(' \* ?(?:\t| {5,8})Return$')
capture = p.match(self.line)
if not capture:
# Helper can have empty retval and we might be parsing another
@@ -132,7 +132,7 @@ class HeaderParser(object):
if self.line == ' *\n':
ret += '\n'
else:
- p = re.compile(' \* ?(?:\t| {6,8})(?:\t| {8})(.*)')
+ p = re.compile(' \* ?(?:\t| {5,8})(?:\t| {8})(.*)')
capture = p.match(self.line)
if capture:
ret += capture.group(1) + '\n'
--
2.14.1
^ permalink raw reply related
* Re: [patch net-next] nfp: flower: set sysfs link to device for representors
From: Jiri Pirko @ 2018-05-17 12:42 UTC (permalink / raw)
To: Or Gerlitz
Cc: Linux Netdev List, David Miller, Jakub Kicinski, Simon Horman,
Dirk van der Merwe, John Hurley, Pieter Jansen van Vuuren,
oss-drivers
In-Reply-To: <CAJ3xEMgw0Ar4_Zvm4cirjf7XgaPf8Ufos+vEjRmMq5OM2yg_aw@mail.gmail.com>
Thu, May 17, 2018 at 02:25:14PM CEST, gerlitz.or@gmail.com wrote:
>On Thu, May 17, 2018 at 1:05 PM, Jiri Pirko <jiri@resnulli.us> wrote:
>> From: Jiri Pirko <jiri@mellanox.com>
>>
>> Do this so the sysfs has "device" link correctly set.
>
>please no
>
>This is likely to create bunch of issues with respect to how libvirt
>deals with the representors.
Once netdev is there because of some probed pci device, this link should
be set. That is one of the basics.
What "bunch of issues" are you talking about? Please be specific.
>
>We were discussing it off list between nfp and mlnx driver people. We
>need to put
>the open stack folks and kernel developers into the same thread. I can
>make a post
>on that next week
^ permalink raw reply
* Re: [PATCH net-next 1/2] net: phy: sfp: make the i2c-bus property really optional
From: Andrew Lunn @ 2018-05-17 12:41 UTC (permalink / raw)
To: Antoine Tenart
Cc: davem, linux, netdev, linux-kernel, thomas.petazzoni,
maxime.chevallier, gregory.clement, miquel.raynal, nadavh,
stefanc, ymarkman, mw
In-Reply-To: <20180517082907.14420-2-antoine.tenart@bootlin.com>
On Thu, May 17, 2018 at 10:29:06AM +0200, Antoine Tenart wrote:
> The SFF,SFP documentation is clear about making all the DT properties,
> with the exception of the compatible, optional. In practice this is not
> the case and without an i2c-bus property provided the SFP code will
> throw NULL pointer exceptions.
>
> This patch is an attempt to fix this.
Hi Antoine, Russell
How usable is an SFF/SFP module without access to the i2c EEPROM? I
guess this comes down to link speed. Can it be manually configured?
I'm just wondering if we want to make this mandatory? Fail the probe
if it is not listed?
Andrew
^ permalink raw reply
* Re: [PATCH V2 8/8] dt-bindings: stm32: add compatible for syscon
From: Rob Herring @ 2018-05-17 12:37 UTC (permalink / raw)
To: Christophe ROULLIER
Cc: mark.rutland@arm.com, mcoquelin.stm32@gmail.com, Alexandre TORGUE,
Peppe CAVALLARO, devicetree@vger.kernel.org, andrew@lunn.ch,
linux-arm-kernel@lists.infradead.org, netdev@vger.kernel.org
In-Reply-To: <d2b4cd1845b949a7bf9c42a17a5358a2@SFHDAG5NODE3.st.com>
On Tue, May 15, 2018 at 11:19 AM, Christophe ROULLIER
<christophe.roullier@st.com> wrote:
> Hi Rob,
Please don't top post to lists.
>
> I do not understand, so let me explain our status:
>
> We have syscfg IP Harware in our SOC.
Add a compatible string that uniquely identifies what the block is. So
something like "st,stm32f746-syscfg".
> But we do not have SoC specific driver to manage syscfg, we are using a generic driver "syscon".
That does not matter. We're talking about the binding. Design
decisions in the OS should not define the binding. It doesn't matter
that the OS currently doesn't use the compatible string.
> So can you tell me what you wish to describe this part in our SOC bindings ?
>
> Thanks for your help.
>
> Christophe.
>
> -----Original Message-----
> From: Rob Herring [mailto:robh@kernel.org]
> Sent: lundi 7 mai 2018 18:36
> To: Christophe ROULLIER <christophe.roullier@st.com>
> Cc: mark.rutland@arm.com; mcoquelin.stm32@gmail.com; Alexandre TORGUE <alexandre.torgue@st.com>; Peppe CAVALLARO <peppe.cavallaro@st.com>; devicetree@vger.kernel.org; andrew@lunn.ch; linux-arm-kernel@lists.infradead.org; netdev@vger.kernel.org
> Subject: Re: [PATCH V2 8/8] dt-bindings: stm32: add compatible for syscon
>
> On Wed, May 02, 2018 at 04:18:43PM +0200, Christophe Roullier wrote:
>> This patch describes syscon DT bindings.
>>
>> Signed-off-by: Christophe Roullier <christophe.roullier@st.com>
>> ---
>> Documentation/devicetree/bindings/arm/stm32.txt | 4 ++++
>> 1 file changed, 4 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/arm/stm32.txt
>> b/Documentation/devicetree/bindings/arm/stm32.txt
>> index 6808ed9..06e3834 100644
>> --- a/Documentation/devicetree/bindings/arm/stm32.txt
>> +++ b/Documentation/devicetree/bindings/arm/stm32.txt
>> @@ -8,3 +8,7 @@ using one of the following compatible strings:
>> st,stm32f746
>> st,stm32h743
>> st,stm32mp157
>> +
>> +Required nodes:
>> +- syscon: the soc bus node must have a system controller node
>> +pointing to the
>> + global control registers, with the compatible string "syscon";
>
> You misunderstood my prior comment. 'syscon' alone is not valid. You need SoC specific compatible string for it and 'stm32' is not SoC specific. IOW, the compatible property for a syscon should imply every single register field in the block.
>
> Rob
^ permalink raw reply
* [PATCH] net/ncsi: prevent a couple array underflows
From: Dan Carpenter @ 2018-05-17 12:33 UTC (permalink / raw)
To: David S. Miller, Samuel Mendoza-Jonas; +Cc: netdev, Gavin Shan, kernel-janitors
We recently refactored this code and introduced a static checker
warning. Smatch complains that if cmd->index is zero then we would
underflow the arrays. That's obviously true.
The question is whether we prevent cmd->index from being zero at a
different level. I've looked at the code and I don't immediately see
a check for that.
Fixes: 062b3e1b6d4f ("net/ncsi: Refactor MAC, VLAN filters")
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
diff --git a/net/ncsi/ncsi-rsp.c b/net/ncsi/ncsi-rsp.c
index ce9497966ebe..a6b7c7d5c829 100644
--- a/net/ncsi/ncsi-rsp.c
+++ b/net/ncsi/ncsi-rsp.c
@@ -347,7 +347,7 @@ static int ncsi_rsp_handler_svf(struct ncsi_request *nr)
cmd = (struct ncsi_cmd_svf_pkt *)skb_network_header(nr->cmd);
ncf = &nc->vlan_filter;
- if (cmd->index > ncf->n_vids)
+ if (cmd->index == 0 || cmd->index > ncf->n_vids)
return -ERANGE;
/* Add or remove the VLAN filter. Remember HW indexes from 1 */
@@ -445,7 +445,8 @@ static int ncsi_rsp_handler_sma(struct ncsi_request *nr)
ncf = &nc->mac_filter;
bitmap = &ncf->bitmap;
- if (cmd->index > ncf->n_uc + ncf->n_mc + ncf->n_mixed)
+ if (cmd->index == 0 ||
+ cmd->index > ncf->n_uc + ncf->n_mc + ncf->n_mixed)
return -ERANGE;
index = (cmd->index - 1) * ETH_ALEN;
^ permalink raw reply related
* [PATCH bpf-next v6 6/6] selftests/bpf: test for seg6local End.BPF action
From: Mathieu Xhonneux @ 2018-05-17 14:28 UTC (permalink / raw)
To: netdev; +Cc: daniel, dlebrun, alexei.starovoitov
In-Reply-To: <cover.1526565671.git.m.xhonneux@gmail.com>
Add a new test for the seg6local End.BPF action. The following helpers
are also tested:
- bpf_lwt_push_encap within the LWT BPF IN hook
- bpf_lwt_seg6_action
- bpf_lwt_seg6_adjust_srh
- bpf_lwt_seg6_store_bytes
A chain of End.BPF actions is built. The SRH is injected through a LWT
BPF IN hook before the chain. Each End.BPF action validates the previous
one, otherwise the packet is dropped.
The test succeeds if the last node in the chain receives the packet and
the UDP datagram contained can be retrieved from userspace.
Signed-off-by: Mathieu Xhonneux <m.xhonneux@gmail.com>
---
tools/include/uapi/linux/bpf.h | 97 ++++-
tools/testing/selftests/bpf/Makefile | 6 +-
tools/testing/selftests/bpf/bpf_helpers.h | 12 +
tools/testing/selftests/bpf/test_lwt_seg6local.c | 438 ++++++++++++++++++++++
tools/testing/selftests/bpf/test_lwt_seg6local.sh | 140 +++++++
5 files changed, 690 insertions(+), 3 deletions(-)
create mode 100644 tools/testing/selftests/bpf/test_lwt_seg6local.c
create mode 100755 tools/testing/selftests/bpf/test_lwt_seg6local.sh
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index d94d333a8225..e8efb12d0a7d 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -141,6 +141,7 @@ enum bpf_prog_type {
BPF_PROG_TYPE_SK_MSG,
BPF_PROG_TYPE_RAW_TRACEPOINT,
BPF_PROG_TYPE_CGROUP_SOCK_ADDR,
+ BPF_PROG_TYPE_LWT_SEG6LOCAL,
};
enum bpf_attach_type {
@@ -1902,6 +1903,90 @@ union bpf_attr {
* egress otherwise). This is the only flag supported for now.
* Return
* **SK_PASS** on success, or **SK_DROP** on error.
+ *
+ * int bpf_lwt_push_encap(struct sk_buff *skb, u32 type, void *hdr, u32 len)
+ * Description
+ * Encapsulate the packet associated to *skb* within a Layer 3
+ * protocol header. This header is provided in the buffer at
+ * address *hdr*, with *len* its size in bytes. *type* indicates
+ * the protocol of the header and can be one of:
+ *
+ * **BPF_LWT_ENCAP_SEG6**
+ * IPv6 encapsulation with Segment Routing Header
+ * (**struct ipv6_sr_hdr**). *hdr* only contains the SRH,
+ * the IPv6 header is computed by the kernel.
+ * **BPF_LWT_ENCAP_SEG6_INLINE**
+ * Only works if *skb* contains an IPv6 packet. Insert a
+ * Segment Routing Header (**struct ipv6_sr_hdr**) inside
+ * the IPv6 header.
+ *
+ * A call to this helper is susceptible to change the underlaying
+ * packet buffer. Therefore, at load time, all checks on pointers
+ * previously done by the verifier are invalidated and must be
+ * performed again, if the helper is used in combination with
+ * direct packet access.
+ * Return
+ * 0 on success, or a negative error in case of failure.
+ *
+ * int bpf_lwt_seg6_store_bytes(struct sk_buff *skb, u32 offset, const void *from, u32 len)
+ * Description
+ * Store *len* bytes from address *from* into the packet
+ * associated to *skb*, at *offset*. Only the flags, tag and TLVs
+ * inside the outermost IPv6 Segment Routing Header can be
+ * modified through this helper.
+ *
+ * A call to this helper is susceptible to change the underlaying
+ * packet buffer. Therefore, at load time, all checks on pointers
+ * previously done by the verifier are invalidated and must be
+ * performed again, if the helper is used in combination with
+ * direct packet access.
+ * Return
+ * 0 on success, or a negative error in case of failure.
+ *
+ * int bpf_lwt_seg6_adjust_srh(struct sk_buff *skb, u32 offset, s32 delta)
+ * Description
+ * Adjust the size allocated to TLVs in the outermost IPv6
+ * Segment Routing Header contained in the packet associated to
+ * *skb*, at position *offset* by *delta* bytes. Only offsets
+ * after the segments are accepted. *delta* can be as well
+ * positive (growing) as negative (shrinking).
+ *
+ * A call to this helper is susceptible to change the underlaying
+ * packet buffer. Therefore, at load time, all checks on pointers
+ * previously done by the verifier are invalidated and must be
+ * performed again, if the helper is used in combination with
+ * direct packet access.
+ * Return
+ * 0 on success, or a negative error in case of failure.
+ *
+ * int bpf_lwt_seg6_action(struct sk_buff *skb, u32 action, void *param, u32 param_len)
+ * Description
+ * Apply an IPv6 Segment Routing action of type *action* to the
+ * packet associated to *skb*. Each action takes a parameter
+ * contained at address *param*, and of length *param_len* bytes.
+ * *action* can be one of:
+ *
+ * **SEG6_LOCAL_ACTION_END_X**
+ * End.X action: Endpoint with Layer-3 cross-connect.
+ * Type of *param*: **struct in6_addr**.
+ * **SEG6_LOCAL_ACTION_END_T**
+ * End.T action: Endpoint with specific IPv6 table lookup.
+ * Type of *param*: **int**.
+ * **SEG6_LOCAL_ACTION_END_B6**
+ * End.B6 action: Endpoint bound to an SRv6 policy.
+ * Type of param: **struct ipv6_sr_hdr**.
+ * **SEG6_LOCAL_ACTION_END_B6_ENCAP**
+ * End.B6.Encap action: Endpoint bound to an SRv6
+ * encapsulation policy.
+ * Type of param: **struct ipv6_sr_hdr**.
+ *
+ * A call to this helper is susceptible to change the underlaying
+ * packet buffer. Therefore, at load time, all checks on pointers
+ * previously done by the verifier are invalidated and must be
+ * performed again, if the helper is used in combination with
+ * direct packet access.
+ * Return
+ * 0 on success, or a negative error in case of failure.
*/
#define __BPF_FUNC_MAPPER(FN) \
FN(unspec), \
@@ -1976,7 +2061,11 @@ union bpf_attr {
FN(fib_lookup), \
FN(sock_hash_update), \
FN(msg_redirect_hash), \
- FN(sk_redirect_hash),
+ FN(sk_redirect_hash), \
+ FN(lwt_push_encap), \
+ FN(lwt_seg6_store_bytes), \
+ FN(lwt_seg6_adjust_srh), \
+ FN(lwt_seg6_action),
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
* function eBPF program intends to call
@@ -2043,6 +2132,12 @@ enum bpf_hdr_start_off {
BPF_HDR_START_NET,
};
+/* Encapsulation type for BPF_FUNC_lwt_push_encap helper. */
+enum bpf_lwt_encap_mode {
+ BPF_LWT_ENCAP_SEG6,
+ BPF_LWT_ENCAP_SEG6_INLINE
+};
+
/* user accessible mirror of in-kernel sk_buff.
* new fields can only be added to the end of this structure
*/
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index 1eb0fa2aba92..b6222b3f8fab 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -33,7 +33,8 @@ TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o test_tcp_estats.o test
sample_map_ret0.o test_tcpbpf_kern.o test_stacktrace_build_id.o \
sockmap_tcp_msg_prog.o connect4_prog.o connect6_prog.o test_adjust_tail.o \
test_btf_haskv.o test_btf_nokv.o test_sockmap_kern.o test_tunnel_kern.o \
- test_get_stack_rawtp.o test_sockmap_kern.o test_sockhash_kern.o
+ test_get_stack_rawtp.o test_sockmap_kern.o test_sockhash_kern.o \
+ test_lwt_seg6local.o
# Order correspond to 'make run_tests' order
TEST_PROGS := test_kmod.sh \
@@ -42,7 +43,8 @@ TEST_PROGS := test_kmod.sh \
test_xdp_meta.sh \
test_offload.py \
test_sock_addr.sh \
- test_tunnel.sh
+ test_tunnel.sh \
+ test_lwt_seg6local.sh
# Compile but not part of 'make run_tests'
TEST_GEN_PROGS_EXTENDED = test_libbpf_open test_sock_addr
diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h
index 8f143dfb3700..334d3e8c5e89 100644
--- a/tools/testing/selftests/bpf/bpf_helpers.h
+++ b/tools/testing/selftests/bpf/bpf_helpers.h
@@ -114,6 +114,18 @@ static int (*bpf_get_stack)(void *ctx, void *buf, int size, int flags) =
static int (*bpf_fib_lookup)(void *ctx, struct bpf_fib_lookup *params,
int plen, __u32 flags) =
(void *) BPF_FUNC_fib_lookup;
+static int (*bpf_lwt_push_encap)(void *ctx, unsigned int type, void *hdr,
+ unsigned int len) =
+ (void *) BPF_FUNC_lwt_push_encap;
+static int (*bpf_lwt_seg6_store_bytes)(void *ctx, unsigned int offset,
+ void *from, unsigned int len) =
+ (void *) BPF_FUNC_lwt_seg6_store_bytes;
+static int (*bpf_lwt_seg6_action)(void *ctx, unsigned int action, void *param,
+ unsigned int param_len) =
+ (void *) BPF_FUNC_lwt_seg6_action;
+static int (*bpf_lwt_seg6_adjust_srh)(void *ctx, unsigned int offset,
+ unsigned int len) =
+ (void *) BPF_FUNC_lwt_seg6_adjust_srh;
/* llvm builtin functions that eBPF C program may use to
* emit BPF_LD_ABS and BPF_LD_IND instructions
diff --git a/tools/testing/selftests/bpf/test_lwt_seg6local.c b/tools/testing/selftests/bpf/test_lwt_seg6local.c
new file mode 100644
index 000000000000..d752bc1fe81c
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_lwt_seg6local.c
@@ -0,0 +1,438 @@
+#include <stddef.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <linux/seg6_local.h>
+#include <linux/bpf.h>
+#include "bpf_helpers.h"
+#include "bpf_endian.h"
+
+#define bpf_printk(fmt, ...) \
+({ \
+ char ____fmt[] = fmt; \
+ bpf_trace_printk(____fmt, sizeof(____fmt), \
+ ##__VA_ARGS__); \
+})
+
+/* Packet parsing state machine helpers. */
+#define cursor_advance(_cursor, _len) \
+ ({ void *_tmp = _cursor; _cursor += _len; _tmp; })
+
+#define SR6_FLAG_ALERT (1 << 4)
+
+#define htonll(x) ((bpf_htonl(1)) == 1 ? (x) : ((uint64_t)bpf_htonl((x) & \
+ 0xFFFFFFFF) << 32) | bpf_htonl((x) >> 32))
+#define ntohll(x) ((bpf_ntohl(1)) == 1 ? (x) : ((uint64_t)bpf_ntohl((x) & \
+ 0xFFFFFFFF) << 32) | bpf_ntohl((x) >> 32))
+#define BPF_PACKET_HEADER __attribute__((packed))
+
+struct ip6_t {
+ unsigned int ver:4;
+ unsigned int priority:8;
+ unsigned int flow_label:20;
+ unsigned short payload_len;
+ unsigned char next_header;
+ unsigned char hop_limit;
+ unsigned long long src_hi;
+ unsigned long long src_lo;
+ unsigned long long dst_hi;
+ unsigned long long dst_lo;
+} BPF_PACKET_HEADER;
+
+struct ip6_addr_t {
+ unsigned long long hi;
+ unsigned long long lo;
+} BPF_PACKET_HEADER;
+
+struct ip6_srh_t {
+ unsigned char nexthdr;
+ unsigned char hdrlen;
+ unsigned char type;
+ unsigned char segments_left;
+ unsigned char first_segment;
+ unsigned char flags;
+ unsigned short tag;
+
+ struct ip6_addr_t segments[0];
+} BPF_PACKET_HEADER;
+
+struct sr6_tlv_t {
+ unsigned char type;
+ unsigned char len;
+ unsigned char value[0];
+} BPF_PACKET_HEADER;
+
+__attribute__((always_inline)) struct ip6_srh_t *get_srh(struct __sk_buff *skb)
+{
+ void *cursor, *data_end;
+ struct ip6_srh_t *srh;
+ struct ip6_t *ip;
+ uint8_t *ipver;
+
+ data_end = (void *)(long)skb->data_end;
+ cursor = (void *)(long)skb->data;
+ ipver = (uint8_t *)cursor;
+
+ if ((void *)ipver + sizeof(*ipver) > data_end)
+ return NULL;
+
+ if ((*ipver >> 4) != 6)
+ return NULL;
+
+ ip = cursor_advance(cursor, sizeof(*ip));
+ if ((void *)ip + sizeof(*ip) > data_end)
+ return NULL;
+
+ if (ip->next_header != 43)
+ return NULL;
+
+ srh = cursor_advance(cursor, sizeof(*srh));
+ if ((void *)srh + sizeof(*srh) > data_end)
+ return NULL;
+
+ if (srh->type != 4)
+ return NULL;
+
+ return srh;
+}
+
+__attribute__((always_inline))
+int update_tlv_pad(struct __sk_buff *skb, uint32_t new_pad,
+ uint32_t old_pad, uint32_t pad_off)
+{
+ int err;
+
+ if (new_pad != old_pad) {
+ err = bpf_lwt_seg6_adjust_srh(skb, pad_off,
+ (int) new_pad - (int) old_pad);
+ if (err)
+ return err;
+ }
+
+ if (new_pad > 0) {
+ char pad_tlv_buf[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0};
+ struct sr6_tlv_t *pad_tlv = (struct sr6_tlv_t *) pad_tlv_buf;
+
+ pad_tlv->type = SR6_TLV_PADDING;
+ pad_tlv->len = new_pad - 2;
+
+ err = bpf_lwt_seg6_store_bytes(skb, pad_off,
+ (void *)pad_tlv_buf, new_pad);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+__attribute__((always_inline))
+int is_valid_tlv_boundary(struct __sk_buff *skb, struct ip6_srh_t *srh,
+ uint32_t *tlv_off, uint32_t *pad_size,
+ uint32_t *pad_off)
+{
+ uint32_t srh_off, cur_off;
+ int offset_valid = 0;
+ int err;
+
+ srh_off = (char *)srh - (char *)(long)skb->data;
+ // cur_off = end of segments, start of possible TLVs
+ cur_off = srh_off + sizeof(*srh) +
+ sizeof(struct ip6_addr_t) * (srh->first_segment + 1);
+
+ *pad_off = 0;
+
+ // we can only go as far as ~10 TLVs due to the BPF max stack size
+ #pragma clang loop unroll(full)
+ for (int i = 0; i < 10; i++) {
+ struct sr6_tlv_t tlv;
+
+ if (cur_off == *tlv_off)
+ offset_valid = 1;
+
+ if (cur_off >= srh_off + ((srh->hdrlen + 1) << 3))
+ break;
+
+ err = bpf_skb_load_bytes(skb, cur_off, &tlv, sizeof(tlv));
+ if (err)
+ return err;
+
+ if (tlv.type == SR6_TLV_PADDING) {
+ *pad_size = tlv.len + sizeof(tlv);
+ *pad_off = cur_off;
+
+ if (*tlv_off == srh_off) {
+ *tlv_off = cur_off;
+ offset_valid = 1;
+ }
+ break;
+
+ } else if (tlv.type == SR6_TLV_HMAC) {
+ break;
+ }
+
+ cur_off += sizeof(tlv) + tlv.len;
+ } // we reached the padding or HMAC TLVs, or the end of the SRH
+
+ if (*pad_off == 0)
+ *pad_off = cur_off;
+
+ if (*tlv_off == -1)
+ *tlv_off = cur_off;
+ else if (!offset_valid)
+ return -EINVAL;
+
+ return 0;
+}
+
+__attribute__((always_inline))
+int add_tlv(struct __sk_buff *skb, struct ip6_srh_t *srh, uint32_t tlv_off,
+ struct sr6_tlv_t *itlv, uint8_t tlv_size)
+{
+ uint32_t srh_off = (char *)srh - (char *)(long)skb->data;
+ uint8_t len_remaining, new_pad;
+ uint32_t pad_off = 0;
+ uint32_t pad_size = 0;
+ uint32_t partial_srh_len;
+ int err;
+
+ if (tlv_off != -1)
+ tlv_off += srh_off;
+
+ if (itlv->type == SR6_TLV_PADDING || itlv->type == SR6_TLV_HMAC)
+ return -EINVAL;
+
+ err = is_valid_tlv_boundary(skb, srh, &tlv_off, &pad_size, &pad_off);
+ if (err)
+ return err;
+
+ err = bpf_lwt_seg6_adjust_srh(skb, tlv_off, sizeof(*itlv) + itlv->len);
+ if (err)
+ return err;
+
+ err = bpf_lwt_seg6_store_bytes(skb, tlv_off, (void *)itlv, tlv_size);
+ if (err)
+ return err;
+
+ // the following can't be moved inside update_tlv_pad because the
+ // bpf verifier has some issues with it
+ pad_off += sizeof(*itlv) + itlv->len;
+ partial_srh_len = pad_off - srh_off;
+ len_remaining = partial_srh_len % 8;
+ new_pad = 8 - len_remaining;
+
+ if (new_pad == 1) // cannot pad for 1 byte only
+ new_pad = 9;
+ else if (new_pad == 8)
+ new_pad = 0;
+
+ return update_tlv_pad(skb, new_pad, pad_size, pad_off);
+}
+
+__attribute__((always_inline))
+int delete_tlv(struct __sk_buff *skb, struct ip6_srh_t *srh,
+ uint32_t tlv_off)
+{
+ uint32_t srh_off = (char *)srh - (char *)(long)skb->data;
+ uint8_t len_remaining, new_pad;
+ uint32_t partial_srh_len;
+ uint32_t pad_off = 0;
+ uint32_t pad_size = 0;
+ struct sr6_tlv_t tlv;
+ int err;
+
+ tlv_off += srh_off;
+
+ err = is_valid_tlv_boundary(skb, srh, &tlv_off, &pad_size, &pad_off);
+ if (err)
+ return err;
+
+ err = bpf_skb_load_bytes(skb, tlv_off, &tlv, sizeof(tlv));
+ if (err)
+ return err;
+
+ err = bpf_lwt_seg6_adjust_srh(skb, tlv_off, -(sizeof(tlv) + tlv.len));
+ if (err)
+ return err;
+
+ pad_off -= sizeof(tlv) + tlv.len;
+ partial_srh_len = pad_off - srh_off;
+ len_remaining = partial_srh_len % 8;
+ new_pad = 8 - len_remaining;
+ if (new_pad == 1) // cannot pad for 1 byte only
+ new_pad = 9;
+ else if (new_pad == 8)
+ new_pad = 0;
+
+ return update_tlv_pad(skb, new_pad, pad_size, pad_off);
+}
+
+__attribute__((always_inline))
+int has_egr_tlv(struct __sk_buff *skb, struct ip6_srh_t *srh)
+{
+ int tlv_offset = sizeof(struct ip6_t) + sizeof(struct ip6_srh_t) +
+ ((srh->first_segment + 1) << 4);
+ struct sr6_tlv_t tlv;
+
+ if (bpf_skb_load_bytes(skb, tlv_offset, &tlv, sizeof(struct sr6_tlv_t)))
+ return 0;
+
+ if (tlv.type == SR6_TLV_EGRESS && tlv.len == 18) {
+ struct ip6_addr_t egr_addr;
+
+ if (bpf_skb_load_bytes(skb, tlv_offset + 4, &egr_addr, 16))
+ return 0;
+
+ // check if egress TLV value is correct
+ if (ntohll(egr_addr.hi) == 0xfd00000000000000 &&
+ ntohll(egr_addr.lo) == 0x4)
+ return 1;
+ }
+
+ return 0;
+}
+
+// This function will push a SRH with segments fd00::1, fd00::2, fd00::3,
+// fd00::4
+SEC("encap_srh")
+int __encap_srh(struct __sk_buff *skb)
+{
+ bpf_printk("got pkt\n");
+ unsigned long long hi = 0xfd00000000000000;
+ struct ip6_addr_t *seg;
+ struct ip6_srh_t *srh;
+ char srh_buf[72]; // room for 4 segments
+ int err;
+
+ srh = (struct ip6_srh_t *)srh_buf;
+ srh->nexthdr = 0;
+ srh->hdrlen = 8;
+ srh->type = 4;
+ srh->segments_left = 3;
+ srh->first_segment = 3;
+ srh->flags = 0;
+ srh->tag = 0;
+
+ seg = (struct ip6_addr_t *)((char *)srh + sizeof(*srh));
+
+ #pragma clang loop unroll(full)
+ for (unsigned long long lo = 0; lo < 4; lo++) {
+ seg->lo = htonll(4 - lo);
+ seg->hi = htonll(hi);
+ seg = (struct ip6_addr_t *)((char *)seg + sizeof(*seg));
+ }
+
+ err = bpf_lwt_push_encap(skb, 0, (void *)srh, sizeof(srh_buf));
+ if (err)
+ return BPF_DROP;
+
+ return BPF_REDIRECT;
+}
+
+// Add an Egress TLV fc00::4, add the flag A,
+// and apply End.X action to fc42::1
+SEC("add_egr_x")
+int __add_egr_x(struct __sk_buff *skb)
+{
+ unsigned long long hi = 0xfc42000000000000;
+ unsigned long long lo = 0x1;
+ struct ip6_srh_t *srh = get_srh(skb);
+ uint8_t new_flags = SR6_FLAG_ALERT;
+ struct ip6_addr_t addr;
+ int err, offset;
+
+ if (srh == NULL)
+ return BPF_DROP;
+
+ uint8_t tlv[20] = {2, 18, 0, 0, 0xfd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4};
+
+ err = add_tlv(skb, srh, (srh->hdrlen+1) << 3,
+ (struct sr6_tlv_t *)&tlv, 20);
+ if (err)
+ return BPF_DROP;
+
+ offset = sizeof(struct ip6_t) + offsetof(struct ip6_srh_t, flags);
+ err = bpf_lwt_seg6_store_bytes(skb, offset,
+ (void *)&new_flags, sizeof(new_flags));
+ if (err)
+ return BPF_DROP;
+
+ addr.lo = htonll(lo);
+ addr.hi = htonll(hi);
+ err = bpf_lwt_seg6_action(skb, SEG6_LOCAL_ACTION_END_X,
+ (void *)&addr, sizeof(addr));
+ if (err)
+ return BPF_DROP;
+ return BPF_REDIRECT;
+}
+
+// Pop the Egress TLV, reset the flags, change the tag 2442 and finally do a
+// simple End action
+SEC("pop_egr")
+int __pop_egr(struct __sk_buff *skb)
+{
+ struct ip6_srh_t *srh = get_srh(skb);
+ uint16_t new_tag = bpf_htons(2442);
+ uint8_t new_flags = 0;
+ int err, offset;
+
+ if (srh == NULL)
+ return BPF_DROP;
+
+ if (srh->flags != SR6_FLAG_ALERT)
+ return BPF_DROP;
+
+ if (srh->hdrlen != 11) // 4 segments + Egress TLV + Padding TLV
+ return BPF_DROP;
+
+ if (!has_egr_tlv(skb, srh))
+ return BPF_DROP;
+
+ err = delete_tlv(skb, srh, 8 + (srh->first_segment + 1) * 16);
+ if (err)
+ return BPF_DROP;
+
+ offset = sizeof(struct ip6_t) + offsetof(struct ip6_srh_t, flags);
+ if (bpf_lwt_seg6_store_bytes(skb, offset, (void *)&new_flags,
+ sizeof(new_flags)))
+ return BPF_DROP;
+
+ offset = sizeof(struct ip6_t) + offsetof(struct ip6_srh_t, tag);
+ if (bpf_lwt_seg6_store_bytes(skb, offset, (void *)&new_tag,
+ sizeof(new_tag)))
+ return BPF_DROP;
+
+ return BPF_OK;
+}
+
+// Inspect if the Egress TLV and flag have been removed, if the tag is correct,
+// then apply a End.T action to reach the last segment
+SEC("inspect_t")
+int __inspect_t(struct __sk_buff *skb)
+{
+ struct ip6_srh_t *srh = get_srh(skb);
+ int table = 117;
+ int err;
+
+ if (srh == NULL)
+ return BPF_DROP;
+
+ if (srh->flags != 0)
+ return BPF_DROP;
+
+ if (srh->tag != bpf_htons(2442))
+ return BPF_DROP;
+
+ if (srh->hdrlen != 8) // 4 segments
+ return BPF_DROP;
+
+ err = bpf_lwt_seg6_action(skb, SEG6_LOCAL_ACTION_END_T,
+ (void *)&table, sizeof(table));
+
+ if (err)
+ return BPF_DROP;
+
+ return BPF_REDIRECT;
+}
+
+char __license[] SEC("license") = "GPL";
diff --git a/tools/testing/selftests/bpf/test_lwt_seg6local.sh b/tools/testing/selftests/bpf/test_lwt_seg6local.sh
new file mode 100755
index 000000000000..1c77994b5e71
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_lwt_seg6local.sh
@@ -0,0 +1,140 @@
+#!/bin/bash
+# Connects 6 network namespaces through veths.
+# Each NS may have different IPv6 global scope addresses :
+# NS1 ---- NS2 ---- NS3 ---- NS4 ---- NS5 ---- NS6
+# fb00::1 fd00::1 fd00::2 fd00::3 fb00::6
+# fc42::1 fd00::4
+#
+# All IPv6 packets going to fb00::/16 through NS2 will be encapsulated in a
+# IPv6 header with a Segment Routing Header, with segments :
+# fd00::1 -> fd00::2 -> fd00::3 -> fd00::4
+#
+# 3 fd00::/16 IPv6 addresses are binded to seg6local End.BPF actions :
+# - fd00::1 : add a TLV, change the flags and apply a End.X action to fc42::1
+# - fd00::2 : remove the TLV, change the flags, add a tag
+# - fd00::3 : apply an End.T action to fd00::4, through routing table 117
+#
+# fd00::4 is a simple Segment Routing node decapsulating the inner IPv6 packet.
+# Each End.BPF action will validate the operations applied on the SRH by the
+# previous BPF program in the chain, otherwise the packet is dropped.
+#
+# An UDP datagram is sent from fb00::1 to fb00::6. The test succeeds if this
+# datagram can be read on NS6 when binding to fb00::6.
+
+TMP_FILE="/tmp/selftest_lwt_seg6local.txt"
+
+cleanup()
+{
+ if [ "$?" = "0" ]; then
+ echo "selftests: test_lwt_seg6local [PASS]";
+ else
+ echo "selftests: test_lwt_seg6local [FAILED]";
+ fi
+
+ set +e
+ ip netns del ns1 2> /dev/null
+ ip netns del ns2 2> /dev/null
+ ip netns del ns3 2> /dev/null
+ ip netns del ns4 2> /dev/null
+ ip netns del ns5 2> /dev/null
+ ip netns del ns6 2> /dev/null
+ rm -f $TMP_FILE
+}
+
+set -e
+
+ip netns add ns1
+ip netns add ns2
+ip netns add ns3
+ip netns add ns4
+ip netns add ns5
+ip netns add ns6
+
+trap cleanup 0 2 3 6 9
+
+ip link add veth1 type veth peer name veth2
+ip link add veth3 type veth peer name veth4
+ip link add veth5 type veth peer name veth6
+ip link add veth7 type veth peer name veth8
+ip link add veth9 type veth peer name veth10
+
+ip link set veth1 netns ns1
+ip link set veth2 netns ns2
+ip link set veth3 netns ns2
+ip link set veth4 netns ns3
+ip link set veth5 netns ns3
+ip link set veth6 netns ns4
+ip link set veth7 netns ns4
+ip link set veth8 netns ns5
+ip link set veth9 netns ns5
+ip link set veth10 netns ns6
+
+ip netns exec ns1 ip link set dev veth1 up
+ip netns exec ns2 ip link set dev veth2 up
+ip netns exec ns2 ip link set dev veth3 up
+ip netns exec ns3 ip link set dev veth4 up
+ip netns exec ns3 ip link set dev veth5 up
+ip netns exec ns4 ip link set dev veth6 up
+ip netns exec ns4 ip link set dev veth7 up
+ip netns exec ns5 ip link set dev veth8 up
+ip netns exec ns5 ip link set dev veth9 up
+ip netns exec ns6 ip link set dev veth10 up
+ip netns exec ns6 ip link set dev lo up
+
+# All link scope addresses and routes required between veths
+ip netns exec ns1 ip -6 addr add fb00::12/16 dev veth1 scope link
+ip netns exec ns1 ip -6 route add fb00::21 dev veth1 scope link
+ip netns exec ns2 ip -6 addr add fb00::21/16 dev veth2 scope link
+ip netns exec ns2 ip -6 addr add fb00::34/16 dev veth3 scope link
+ip netns exec ns2 ip -6 route add fb00::43 dev veth3 scope link
+ip netns exec ns3 ip -6 route add fb00::65 dev veth5 scope link
+ip netns exec ns3 ip -6 addr add fb00::43/16 dev veth4 scope link
+ip netns exec ns3 ip -6 addr add fb00::56/16 dev veth5 scope link
+ip netns exec ns4 ip -6 addr add fb00::65/16 dev veth6 scope link
+ip netns exec ns4 ip -6 addr add fb00::78/16 dev veth7 scope link
+ip netns exec ns4 ip -6 route add fb00::87 dev veth7 scope link
+ip netns exec ns5 ip -6 addr add fb00::87/16 dev veth8 scope link
+ip netns exec ns5 ip -6 addr add fb00::910/16 dev veth9 scope link
+ip netns exec ns5 ip -6 route add fb00::109 dev veth9 scope link
+ip netns exec ns5 ip -6 route add fb00::109 table 117 dev veth9 scope link
+ip netns exec ns6 ip -6 addr add fb00::109/16 dev veth10 scope link
+
+ip netns exec ns1 ip -6 addr add fb00::1/16 dev lo
+ip netns exec ns1 ip -6 route add fb00::6 dev veth1 via fb00::21
+
+ip netns exec ns2 ip -6 route add fb00::6 encap bpf in obj test_lwt_seg6local.o sec encap_srh dev veth2
+ip netns exec ns2 ip -6 route add fd00::1 dev veth3 via fb00::43 scope link
+
+ip netns exec ns3 ip -6 route add fc42::1 dev veth5 via fb00::65
+ip netns exec ns3 ip -6 route add fd00::1 encap seg6local action End.BPF obj test_lwt_seg6local.o sec add_egr_x dev veth4
+
+ip netns exec ns4 ip -6 route add fd00::2 encap seg6local action End.BPF obj test_lwt_seg6local.o sec pop_egr dev veth6
+ip netns exec ns4 ip -6 addr add fc42::1 dev lo
+ip netns exec ns4 ip -6 route add fd00::3 dev veth7 via fb00::87
+
+ip netns exec ns5 ip -6 route add fd00::4 table 117 dev veth9 via fb00::109
+ip netns exec ns5 ip -6 route add fd00::3 encap seg6local action End.BPF obj test_lwt_seg6local.o sec inspect_t dev veth8
+
+ip netns exec ns6 ip -6 addr add fb00::6/16 dev lo
+ip netns exec ns6 ip -6 addr add fd00::4/16 dev lo
+
+ip netns exec ns1 sysctl net.ipv6.conf.all.forwarding=1 > /dev/null
+ip netns exec ns2 sysctl net.ipv6.conf.all.forwarding=1 > /dev/null
+ip netns exec ns3 sysctl net.ipv6.conf.all.forwarding=1 > /dev/null
+ip netns exec ns4 sysctl net.ipv6.conf.all.forwarding=1 > /dev/null
+ip netns exec ns5 sysctl net.ipv6.conf.all.forwarding=1 > /dev/null
+
+ip netns exec ns6 sysctl net.ipv6.conf.all.seg6_enabled=1 > /dev/null
+ip netns exec ns6 sysctl net.ipv6.conf.lo.seg6_enabled=1 > /dev/null
+ip netns exec ns6 sysctl net.ipv6.conf.veth10.seg6_enabled=1 > /dev/null
+
+ip netns exec ns6 nc -l -6 -u -d 7330 > $TMP_FILE &
+ip netns exec ns1 bash -c "echo 'foobar' | nc -w0 -6 -u -p 2121 -s fb00::1 fb00::6 7330"
+sleep 5 # wait enough time to ensure the UDP datagram arrived to the last segment
+kill -INT $!
+
+if [[ $(< $TMP_FILE) != "foobar" ]]; then
+ exit 1
+fi
+
+exit 0
--
2.16.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox