* Re: [PATCH net] net/xdp: Fix suspicious RCU usage warning
From: Daniel Borkmann @ 2018-08-12 23:04 UTC (permalink / raw)
To: Tariq Toukan, Alexei Starovoitov
Cc: David S. Miller, netdev, Eran Ben Elisha, Jesper Dangaard Brouer
In-Reply-To: <44cb66c6-2542-3f6a-c426-5b1d1665ea61@mellanox.com>
On 08/12/2018 10:45 AM, Tariq Toukan wrote:
>
>
> On 20/07/2018 12:36 AM, Alexei Starovoitov wrote:
>> On Wed, Jul 18, 2018 at 05:13:54PM +0300, Tariq Toukan wrote:
>>>
>>>
>>> On 17/07/2018 10:27 PM, Daniel Borkmann wrote:
>>>> On 07/17/2018 06:47 PM, Alexei Starovoitov wrote:
>>>>> On Tue, Jul 17, 2018 at 06:10:38PM +0300, Tariq Toukan wrote:
>>>>>> Fix the warning below by calling rhashtable_lookup under
>>>>>> RCU read lock.
>>>>>>
>>>
>>> ...
>>>
>>>>>> mutex_lock(&mem_id_lock);
>>>>>> + rcu_read_lock();
>>>>>> xa = rhashtable_lookup(mem_id_ht, &id, mem_id_rht_params);
>>>>>> + rcu_read_unlock();
>>>>>> if (!xa) {
>>>>>
>>>>> if it's an actual bug rcu_read_unlock seems to be misplaced.
>>>>> It silences the warn, but rcu section looks wrong.
>>>>
>>>> I think that whole piece in __xdp_rxq_info_unreg_mem_model() should be:
>>>>
>>>> mutex_lock(&mem_id_lock);
>>>> xa = rhashtable_lookup_fast(mem_id_ht, &id, mem_id_rht_params);
>>>> if (xa && rhashtable_remove_fast(mem_id_ht, &xa->node, mem_id_rht_params) == 0)
>>>> call_rcu(&xa->rcu, __xdp_mem_allocator_rcu_free);
>>>> mutex_unlock(&mem_id_lock);
>>>>
>>>> Technically the RCU read side plus rhashtable_lookup() is the same, but lets
>>>> use proper api. From the doc (https://lwn.net/Articles/751374/) object removal
>>>> is wrapped around the RCU read side additionally, but in our case we're behind
>>>> mem_id_lock for insertion/removal serialization.
>>>>
>>>> Cheers,
>>>> Daniel
>>>>
>>>
>>> Just as Daniel stated, I think there's no actual bug here, but we still want
>>> to silence the RCU warning.
>>>
>>> Alexei, did you mean getting the if statement into the RCU lock critical
>>> section?
>>
>> If what Daniel proposes silences the warn, I'd rather do that.
>> Pattern like:
>> rcu_lock;
>> val = lookup();
>> rcu_unlock;
>> if (val)
>> will cause people to question the quality of the code and whether
>> authors of the code understand rcu.
>> There should be a way to silence the warn without adding
>> "wrong on the first glance" code.
>
> I'm re-spinning this.
> Can it still go to net, or better send it to bpf-next ?
Please rebase against bpf-next and we route it to stable, thanks!
^ permalink raw reply
* Re: [V9fs-developer] [PATCH 2/2] 9p: Add refcount to p9_req_t
From: piaojun @ 2018-08-13 1:37 UTC (permalink / raw)
To: Tomas Bortoli, asmadeus, ericvh, rminnich, lucho
Cc: Dominique Martinet, netdev, linux-kernel, syzkaller,
v9fs-developer, davem
In-Reply-To: <20180811144254.23665-2-tomasbortoli@gmail.com>
Hi Tomas & Dominique,
Could you help paste the reason of the crash bug to help others understand
more clearly? And I have another question below.
On 2018/8/11 22:42, Tomas Bortoli wrote:
> To avoid use-after-free(s), use a refcount to keep track of the
> usable references to any instantiated struct p9_req_t.
>
> This commit adds p9_req_put(), p9_req_get() and p9_req_try_get() as
> wrappers to kref_put(), kref_get() and kref_get_unless_zero().
> These are used by the client and the transports to keep track of
> valid requests' references.
>
> p9_free_req() is added back and used as callback by kref_put().
>
> Add SLAB_TYPESAFE_BY_RCU as it ensures that the memory freed by
> kmem_cache_free() will not be reused for another type until the rcu
> synchronisation period is over, so an address gotten under rcu read
> lock is safe to inc_ref() without corrupting random memory while
> the lock is held.
>
> Co-developed-by: Dominique Martinet <dominique.martinet@cea.fr>
> Signed-off-by: Tomas Bortoli <tomasbortoli@gmail.com>
> Reported-by: syzbot+467050c1ce275af2a5b8@syzkaller.appspotmail.com
> Signed-off-by: Dominique Martinet <dominique.martinet@cea.fr>
> ---
> include/net/9p/client.h | 14 +++++++++++++
> net/9p/client.c | 54 +++++++++++++++++++++++++++++++++++++++++++------
> net/9p/trans_fd.c | 11 +++++++++-
> net/9p/trans_rdma.c | 1 +
> 4 files changed, 73 insertions(+), 7 deletions(-)
>
> diff --git a/include/net/9p/client.h b/include/net/9p/client.h
> index 735f3979d559..947a570307a6 100644
> --- a/include/net/9p/client.h
> +++ b/include/net/9p/client.h
> @@ -94,6 +94,7 @@ enum p9_req_status_t {
> struct p9_req_t {
> int status;
> int t_err;
> + struct kref refcount;
> wait_queue_head_t wq;
> struct p9_fcall tc;
> struct p9_fcall rc;
> @@ -233,6 +234,19 @@ int p9_client_lock_dotl(struct p9_fid *fid, struct p9_flock *flock, u8 *status);
> int p9_client_getlock_dotl(struct p9_fid *fid, struct p9_getlock *fl);
> void p9_fcall_fini(struct p9_fcall *fc);
> struct p9_req_t *p9_tag_lookup(struct p9_client *, u16);
> +
> +static inline void p9_req_get(struct p9_req_t *r)
> +{
> + kref_get(&r->refcount);
> +}
> +
> +static inline int p9_req_try_get(struct p9_req_t *r)
> +{
> + return kref_get_unless_zero(&r->refcount);
> +}
> +
> +int p9_req_put(struct p9_req_t *r);
> +
> void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status);
>
> int p9_parse_header(struct p9_fcall *, int32_t *, int8_t *, int16_t *, int);
> diff --git a/net/9p/client.c b/net/9p/client.c
> index 7942c0bfcc5b..83f2f0aadc14 100644
> --- a/net/9p/client.c
> +++ b/net/9p/client.c
> @@ -310,6 +310,18 @@ p9_tag_alloc(struct p9_client *c, int8_t type, unsigned int max_size)
> if (tag < 0)
> goto free;
>
> + /* Init ref to two because in the general case there is one ref
> + * that is put asynchronously by a writer thread, one ref
> + * temporarily given by p9_tag_lookup and put by p9_client_cb
> + * in the recv thread, and one ref put by p9_remove_tag in the
> + * main thread. The only exception is virtio that does not use
> + * p9_tag_lookup but does not have a writer thread either
> + * (the write happens synchronously in the request/zc_request
> + * callback), so p9_client_cb eats the second ref there
> + * as the pointer is duplicated directly by virtqueue_add_sgs()
> + */
> + refcount_set(&req->refcount.refcount, 2);
> +
> return req;
>
> free:
> @@ -333,10 +345,21 @@ struct p9_req_t *p9_tag_lookup(struct p9_client *c, u16 tag)
> struct p9_req_t *req;
>
> rcu_read_lock();
> +again:
> req = idr_find(&c->reqs, tag);
> - /* There's no refcount on the req; a malicious server could cause
> - * us to dereference a NULL pointer
> - */
> + if (req) {
> + /* We have to be careful with the req found under rcu_read_lock
> + * Thanks to SLAB_TYPESAFE_BY_RCU we can safely try to get the
> + * ref again without corrupting other data, then check again
> + * that the tag matches once we have the ref
> + */
> + if (!p9_req_try_get(req))
> + goto again;
> + if (req->tc.tag != tag) {
> + p9_req_put(req);
> + goto again;
> + }
> + }
> rcu_read_unlock();
>
> return req;
> @@ -350,7 +373,7 @@ EXPORT_SYMBOL(p9_tag_lookup);
> *
> * Context: Any context.
> */
> -static void p9_tag_remove(struct p9_client *c, struct p9_req_t *r)
> +static int p9_tag_remove(struct p9_client *c, struct p9_req_t *r)
> {
> unsigned long flags;
> u16 tag = r->tc.tag;
> @@ -359,11 +382,23 @@ static void p9_tag_remove(struct p9_client *c, struct p9_req_t *r)
> spin_lock_irqsave(&c->lock, flags);
> idr_remove(&c->reqs, tag);
> spin_unlock_irqrestore(&c->lock, flags);
> + return p9_req_put(r);
> +}
> +
> +static void p9_req_free(struct kref *ref)
> +{
> + struct p9_req_t *r = container_of(ref, struct p9_req_t, refcount);
> p9_fcall_fini(&r->tc);
> p9_fcall_fini(&r->rc);
> kmem_cache_free(p9_req_cache, r);
> }
>
> +int p9_req_put(struct p9_req_t *r)
> +{
> + return kref_put(&r->refcount, p9_req_free);
> +}
> +EXPORT_SYMBOL(p9_req_put);
> +
> /**
> * p9_tag_cleanup - cleans up tags structure and reclaims resources
> * @c: v9fs client struct
> @@ -379,7 +414,9 @@ static void p9_tag_cleanup(struct p9_client *c)
> rcu_read_lock();
> idr_for_each_entry(&c->reqs, req, id) {
> pr_info("Tag %d still in use\n", id);
> - p9_tag_remove(c, req);
> + if (p9_tag_remove(c, req) == 0)
> + pr_warn("Packet with tag %d has still references",
> + req->tc.tag);
> }
> rcu_read_unlock();
> }
> @@ -403,6 +440,7 @@ void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status)
>
> wake_up(&req->wq);
> p9_debug(P9_DEBUG_MUX, "wakeup: %d\n", req->tc.tag);
> + p9_req_put(req);
> }
> EXPORT_SYMBOL(p9_client_cb);
>
> @@ -682,6 +720,8 @@ static struct p9_req_t *p9_client_prepare_req(struct p9_client *c,
> return req;
> reterr:
> p9_tag_remove(c, req);
> + /* We have to put also the 2nd reference as it won't be used */
> + p9_req_put(req);
> return ERR_PTR(err);
> }
>
> @@ -716,6 +756,8 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
>
> err = c->trans_mod->request(c, req);
> if (err < 0) {
> + /* write won't happen */
> + p9_req_put(req);
> if (err != -ERESTARTSYS && err != -EFAULT)
> c->status = Disconnected;
> goto recalc_sigpending;
> @@ -2241,7 +2283,7 @@ EXPORT_SYMBOL(p9_client_readlink);
>
> int __init p9_client_init(void)
> {
> - p9_req_cache = KMEM_CACHE(p9_req_t, 0);
> + p9_req_cache = KMEM_CACHE(p9_req_t, SLAB_TYPESAFE_BY_RCU);
> return p9_req_cache ? 0 : -ENOMEM;
> }
>
> diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
> index 20f46f13fe83..686e24e355d0 100644
> --- a/net/9p/trans_fd.c
> +++ b/net/9p/trans_fd.c
> @@ -132,6 +132,7 @@ struct p9_conn {
> struct list_head req_list;
> struct list_head unsent_req_list;
> struct p9_req_t *req;
> + struct p9_req_t *wreq;
Why adding a wreq for write work? And I wonder we should rename req to
rreq?
> char tmp_buf[7];
> struct p9_fcall rc;
> int wpos;
> @@ -383,6 +384,7 @@ static void p9_read_work(struct work_struct *work)
> m->rc.sdata = NULL;
> m->rc.offset = 0;
> m->rc.capacity = 0;
> + p9_req_put(m->req);
> m->req = NULL;
> }
>
> @@ -472,6 +474,8 @@ static void p9_write_work(struct work_struct *work)
> m->wbuf = req->tc.sdata;
> m->wsize = req->tc.size;
> m->wpos = 0;
> + p9_req_get(req);
> + m->wreq = req;
> spin_unlock(&m->client->lock);
> }
>
> @@ -492,8 +496,11 @@ static void p9_write_work(struct work_struct *work)
> }
>
> m->wpos += err;
> - if (m->wpos == m->wsize)
> + if (m->wpos == m->wsize) {
> m->wpos = m->wsize = 0;
> + p9_req_put(m->wreq);
> + m->wreq = NULL;
> + }
>
> end_clear:
> clear_bit(Wworksched, &m->wsched);
> @@ -694,6 +701,7 @@ static int p9_fd_cancel(struct p9_client *client, struct p9_req_t *req)
> if (req->status == REQ_STATUS_UNSENT) {
> list_del(&req->req_list);
> req->status = REQ_STATUS_FLSHD;
> + p9_req_put(req);
> ret = 0;
> }
> spin_unlock(&client->lock);
> @@ -711,6 +719,7 @@ static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req)
> spin_lock(&client->lock);
> list_del(&req->req_list);
> spin_unlock(&client->lock);
> + p9_req_put(req);
>
> return 0;
> }
> diff --git a/net/9p/trans_rdma.c b/net/9p/trans_rdma.c
> index c60655c90c9e..8cff368a11e3 100644
> --- a/net/9p/trans_rdma.c
> +++ b/net/9p/trans_rdma.c
> @@ -365,6 +365,7 @@ send_done(struct ib_cq *cq, struct ib_wc *wc)
> c->busa, c->req->tc.size,
> DMA_TO_DEVICE);
> up(&rdma->sq_sem);
> + p9_req_put(c->req);
> kfree(c);
> }
>
>
^ permalink raw reply
* Re: The recvmsg() with IP_PKTINFO for local addresses returns various ipi_ifindex
From: David Ahern @ 2018-08-12 22:34 UTC (permalink / raw)
To: Damir Mansurov, netdev; +Cc: Alexandra N. Kossovsky
In-Reply-To: <e6e875ca-096f-924d-c1c6-f40339ae3a0c@oktetlabs.ru>
On 8/9/18 2:13 AM, Damir Mansurov wrote:
> Greetings,
>
> I use the IP_PKTINFO to detect ipi_ifindex from which the packet was
> arrived, it used to work for local addresses also.
>
> For local addresses ipi_ifindex always returned 1, but starting from
> Linux 4.14 ip_ifindex began to return various values.
>
> Example host configuration:
> 1: lo: 127.0.0.1
> 2: eth0: 192.168.3.45
> 3: eth1: 192.168.4.45
>
> I use sendto() with addresses {127.0.0.1, 192.168.3.45 and
> 192.168.4.45}, call recvmsg() and than use standard procedure to get
> ipi_ifindex, it shows results:
>
> | ipi_ifindex | ipi_ifindex
> sendto(address) | Linux ver < 4.14 | Linux ver >= 4.14
> ---------------------------------------------------------------
> 127.0.0.1 | 1 | 1
> ---------------------------------------------------------------
> 192.168.3.45 | 1 | 2
> ---------------------------------------------------------------
> 192.168.4.45 | 1 | 3
>
>
> It seems that this behavior depends from commit:
> net: ipv4: set orig_oif based on fib result for local traffic
>
> https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=linux-4.14.y&id=839da4d98960bcc68e6b7b945b33ad3916ec1e92
>
>
> I believe that ipi_ifindex for local addresses should be 1.
> Is there a Bug for Linux >= 4.14 or is this a valid behavior?
The index should be the device with the address. It was reporting
loopback prior to the mentioned commit because loopback is used for
packet Tx which is an implementation detail for sending packets locally.
^ permalink raw reply
* Re: [PATCH iproute2-next 3/3] q_netem: slotting with non-uniform distribution
From: David Ahern @ 2018-08-12 22:18 UTC (permalink / raw)
To: Yousuk Seung, netdev
Cc: Stephen Hemminger, Michael McLennan, Priyaranjan Jha,
Neal Cardwell, Dave Taht
In-Reply-To: <20180806170953.164776-4-ysseung@google.com>
On 8/6/18 11:09 AM, Yousuk Seung wrote:
> @@ -417,21 +421,53 @@ static int netem_parse_opt(struct qdisc_util *qu, int argc, char **argv,
> }
> }
> } else if (matches(*argv, "slot") == 0) {
> - NEXT_ARG();
> - present[TCA_NETEM_SLOT] = 1;
> - if (get_time64(&slot.min_delay, *argv)) {
> - explain1("slot min_delay");
> - return -1;
> - }
> if (NEXT_IS_NUMBER()) {
> NEXT_ARG();
> - if (get_time64(&slot.max_delay, *argv)) {
> - explain1("slot min_delay max_delay");
> + present[TCA_NETEM_SLOT] = 1;
> + if (get_time64(&slot.min_delay, *argv)) {
> + explain1("slot min_delay");
> + return -1;
> + }
> + if (NEXT_IS_NUMBER()) {
> + NEXT_ARG();
> + if (get_time64(&slot.max_delay, *argv)) {
> + explain1("slot min_delay max_delay");
> + return -1;
> + }
> + }
> + if (slot.max_delay < slot.min_delay)
> + slot.max_delay = slot.min_delay;
> + } else {
> + NEXT_ARG();
> + if (strcmp(*argv, "distribution") == 0) {
> + present[TCA_NETEM_SLOT] = 1;
> + NEXT_ARG();
> + slot_dist_data = calloc(sizeof(slot_dist_data[0]), MAX_DIST);
if (!slot_dist_data) ...
^ permalink raw reply
* Re: [PATCH iproute2-next 2/3] q_netem: support delivering packets in delayed time slots
From: David Ahern @ 2018-08-12 22:14 UTC (permalink / raw)
To: Yousuk Seung, netdev
Cc: Stephen Hemminger, Michael McLennan, Priyaranjan Jha, Dave Taht,
Neal Cardwell
In-Reply-To: <20180806170953.164776-3-ysseung@google.com>
On 8/6/18 11:09 AM, Yousuk Seung wrote:
> diff --git a/tc/q_netem.c b/tc/q_netem.c
> index 9f9a9b3df255..f52a36b6c31c 100644
> --- a/tc/q_netem.c
> +++ b/tc/q_netem.c
> @@ -40,7 +40,10 @@ static void explain(void)
> " [ loss gemodel PERCENT [R [1-H [1-K]]]\n" \
> " [ ecn ]\n" \
> " [ reorder PRECENT [CORRELATION] [ gap DISTANCE ]]\n" \
> -" [ rate RATE [PACKETOVERHEAD] [CELLSIZE] [CELLOVERHEAD]]\n");
> +" [ rate RATE [PACKETOVERHEAD] [CELLSIZE] [CELLOVERHEAD]]\n" \
> +" [ slot MIN_DELAY [MAX_DELAY] [packets MAX_PACKETS]" \
> +" [bytes MAX_BYTES]]\n" \
> + );
> }
>
> static void explain1(const char *arg)
> @@ -164,6 +167,7 @@ static int netem_parse_opt(struct qdisc_util *qu, int argc, char **argv,
> struct tc_netem_gimodel gimodel;
> struct tc_netem_gemodel gemodel;
> struct tc_netem_rate rate = {};
> + struct tc_netem_slot slot = {};
> __s16 *dist_data = NULL;
> __u16 loss_type = NETEM_LOSS_UNSPEC;
> int present[__TCA_NETEM_MAX] = {};
> @@ -412,6 +416,44 @@ static int netem_parse_opt(struct qdisc_util *qu, int argc, char **argv,
> return -1;
> }
> }
> + } else if (matches(*argv, "slot") == 0) {
> + NEXT_ARG();
> + present[TCA_NETEM_SLOT] = 1;
> + if (get_time64(&slot.min_delay, *argv)) {
> + explain1("slot min_delay");
> + return -1;
> + }
> + if (NEXT_IS_NUMBER()) {
> + NEXT_ARG();
> + if (get_time64(&slot.max_delay, *argv)) {
> + explain1("slot min_delay max_delay");
> + return -1;
> + }
> + }
> + if (slot.max_delay < slot.min_delay)
If max_delay is user specified, this should generate an error rather
than just overwriting the value.
> + slot.max_delay = slot.min_delay;
> + if (NEXT_ARG_OK() &&
> + matches(*(argv+1), "packets") == 0) {
> + NEXT_ARG();
> + if (!NEXT_ARG_OK() ||
> + get_s32(&slot.max_packets, *(argv+1), 0)) {
> + explain1("slot packets");
> + return -1;
> + }
> + NEXT_ARG();
> + }
> + if (NEXT_ARG_OK() &&
> + matches(*(argv+1), "bytes") == 0) {
> + unsigned int max_bytes;
> + NEXT_ARG();
> + if (!NEXT_ARG_OK() ||
> + get_size(&max_bytes, *(argv+1))) {
> + explain1("slot bytes");
> + return -1;
> + }
> + slot.max_bytes = (int) max_bytes;
> + NEXT_ARG();
> + }
> } else if (strcmp(*argv, "help") == 0) {
> explain();
> return -1;
^ permalink raw reply
* Re: [PATCH iproute2-next 1/3] tc: support conversions to or from 64 bit nanosecond-based time
From: David Ahern @ 2018-08-12 22:09 UTC (permalink / raw)
To: Yousuk Seung, netdev
Cc: Stephen Hemminger, Michael McLennan, Priyaranjan Jha, Dave Taht,
Neal Cardwell
In-Reply-To: <20180806170953.164776-2-ysseung@google.com>
On 8/6/18 11:09 AM, Yousuk Seung wrote:
> diff --git a/tc/tc_core.h b/tc/tc_core.h
> index 1dfa9a4f773b..a0fe0923d171 100644
> --- a/tc/tc_core.h
> +++ b/tc/tc_core.h
> @@ -7,6 +7,10 @@
>
> #define TIME_UNITS_PER_SEC 1000000
>
> +#define NSEC_PER_USEC 1000
> +#define NSEC_PER_MSEC 1000000
> +#define NSEC_PER_SEC 1000000000LL
> +
These are not specific to tc so a header in include is a better location
(utils.h or a new one)
> enum link_layer {
> LINKLAYER_UNSPEC,
> LINKLAYER_ETHERNET,
> diff --git a/tc/tc_util.c b/tc/tc_util.c
> index d7578528a31b..c39c9046dcae 100644
> --- a/tc/tc_util.c
> +++ b/tc/tc_util.c
Similarly for these time functions - not specific to tc so move to
lib/utils.c
> @@ -385,6 +385,61 @@ char *sprint_ticks(__u32 ticks, char *buf)
> return sprint_time(tc_core_tick2time(ticks), buf);
> }
>
> +/* 64 bit times are represented internally in nanoseconds */
> +int get_time64(__s64 *time, const char *str)
__u64 seems more appropriate than __s64
> +{
> + double nsec;
> + char *p;
> +
> + nsec = strtod(str, &p);
> + if (p == str)
> + return -1;
> +
> + if (*p) {
> + if (strcasecmp(p, "s") == 0 ||
> + strcasecmp(p, "sec") == 0 ||
> + strcasecmp(p, "secs") == 0)
> + nsec *= NSEC_PER_SEC;
> + else if (strcasecmp(p, "ms") == 0 ||
> + strcasecmp(p, "msec") == 0 ||
> + strcasecmp(p, "msecs") == 0)
> + nsec *= NSEC_PER_MSEC;
> + else if (strcasecmp(p, "us") == 0 ||
> + strcasecmp(p, "usec") == 0 ||
> + strcasecmp(p, "usecs") == 0)
> + nsec *= NSEC_PER_USEC;
> + else if (strcasecmp(p, "ns") == 0 ||
> + strcasecmp(p, "nsec") == 0 ||
> + strcasecmp(p, "nsecs") == 0)
strncasecmp would be more efficient
> + nsec *= 1;
> + else
> + return -1;
> + }
> +
> + *time = nsec;
> + return 0;
> +}
> +
> +void print_time64(char *buf, int len, __s64 time)
> +{
> + double nsec = time;
> +
> + if (time >= NSEC_PER_SEC)
> + snprintf(buf, len, "%.3fs", nsec/NSEC_PER_SEC);
> + else if (time >= NSEC_PER_MSEC)
> + snprintf(buf, len, "%.3fms", nsec/NSEC_PER_MSEC);
> + else if (time >= NSEC_PER_USEC)
> + snprintf(buf, len, "%.3fus", nsec/NSEC_PER_USEC);
> + else
> + snprintf(buf, len, "%lldns", time);
> +}
> +
> +char *sprint_time64(__s64 time, char *buf)
> +{
> + print_time64(buf, SPRINT_BSIZE-1, time);
> + return buf;
> +}
> +
> int get_size(unsigned int *size, const char *str)
> {
> double sz;
^ permalink raw reply
* Re: [PATCH iproute2-next] Add SKB Priority qdisc support in tc(8)
From: David Ahern @ 2018-08-12 21:45 UTC (permalink / raw)
To: Nishanth Devarajan, stephen; +Cc: netdev, doucette, michel
In-Reply-To: <20180808182440.GA5929@gmail.com>
On 8/8/18 12:24 PM, Nishanth Devarajan wrote:
> sch_skbprio is a qdisc that prioritizes packets according to their skb->priority
> field. Under congestion, it drops already-enqueued lower priority packets to
> make space available for higher priority packets. Skbprio was conceived as a
> solution for denial-of-service defenses that need to route packets with
> different priorities as a means to overcome DoS attacks.
>
> Signed-off-by: Nishanth Devarajan <ndev2021@gmail.com>
> Reviewed-by: Michel Machado <michel@digirati.com.br>
> ---
> include/uapi/linux/pkt_sched.h | 7 ++++
> man/man8/tc-skbprio.8 | 70 ++++++++++++++++++++++++++++++++++++
> tc/Makefile | 1 +
> tc/q_skbprio.c | 81 ++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 159 insertions(+)
> create mode 100644 man/man8/tc-skbprio.8
> create mode 100644 tc/q_skbprio.c
>
Does not apply cleanly to iproute2-next. Also, you have a couple of
lines > 80 columns that can be easily corrected.
^ permalink raw reply
* Re: [PATCHi iproute2-next] ip: show min and max mtu
From: David Ahern @ 2018-08-12 21:25 UTC (permalink / raw)
To: Stephen Hemminger, netdev; +Cc: Stephen Hemminger
In-Reply-To: <20180727204350.21799-1-stephen@networkplumber.org>
On 7/27/18 2:43 PM, Stephen Hemminger wrote:
> From: Stephen Hemminger <sthemmin@microsoft.com>
>
> Add min/max MTU to the link details
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
> include/uapi/linux/if_link.h | 2 ++
> ip/ipaddress.c | 10 ++++++++++
> 2 files changed, 12 insertions(+)
>
applied to iproute2-next. Thanks
^ permalink raw reply
* [PATCH net-next] ieee802154: hwsim: using right kind of iteration
From: Alexander Aring @ 2018-08-12 20:24 UTC (permalink / raw)
To: netdev; +Cc: linux-wpan, kernel, Alexander Aring, Stefan Schmidt
This patch fixes the error path to unsubscribe all other phy's from
current phy. The actually code using a wrong kind of list iteration may
copied from the case to unsubscribe the current phy from all other
phy's.
Cc: Stefan Schmidt <stefan@datenfreihafen.org>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Fixes: f25da51fdc38 ("ieee802154: hwsim: add replacement for fakelb")
Signed-off-by: Alexander Aring <aring@mojatatu.com>
---
drivers/net/ieee802154/mac802154_hwsim.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ieee802154/mac802154_hwsim.c b/drivers/net/ieee802154/mac802154_hwsim.c
index 07a493dea11e..bf70ab892e69 100644
--- a/drivers/net/ieee802154/mac802154_hwsim.c
+++ b/drivers/net/ieee802154/mac802154_hwsim.c
@@ -735,10 +735,12 @@ static int hwsim_subscribe_all_others(struct hwsim_phy *phy)
return 0;
me_fail:
- list_for_each_entry(phy, &hwsim_phys, list) {
+ rcu_read_lock();
+ list_for_each_entry_rcu(e, &phy->edges, list) {
list_del_rcu(&e->list);
hwsim_free_edge(e);
}
+ rcu_read_unlock();
sub_fail:
hwsim_edge_unsubscribe_me(phy);
return -ENOMEM;
--
2.11.0
^ permalink raw reply related
* Re: [PATCH] drivers/net/usb/r8152: change rtl8152_system_suspend to be void function
From: Dan Carpenter @ 2018-08-12 22:09 UTC (permalink / raw)
To: kbuild, zhong jiang; +Cc: netdev, edumazet, kbuild-all, linux-kernel, davem
In-Reply-To: <1533738407-10495-1-git-send-email-zhongjiang@huawei.com>
Hi zhong,
Thank you for the patch! Perhaps something to improve:
url: https://github.com/0day-ci/linux/commits/zhong-jiang/drivers-net-usb-r8152-change-rtl8152_system_suspend-to-be-void-function/20180809-111737
New smatch warnings:
drivers/net/usb/r8152.c:4447 rtl8152_suspend() error: uninitialized symbol 'ret'.
Old smatch warnings:
drivers/net/usb/r8152.c:4660 rtl8152_get_strings() error: memcpy() '*rtl8152_gstrings' too small (32 vs 416)
# https://github.com/0day-ci/linux/commit/31b61d6a0989c067332fa1ae07055b3e406c17cd
git remote add linux-review https://github.com/0day-ci/linux
git remote update linux-review
git checkout 31b61d6a0989c067332fa1ae07055b3e406c17cd
vim +/ret +4447 drivers/net/usb/r8152.c
8fb280616 hayeswang 2017-01-10 4432
8fb280616 hayeswang 2017-01-10 4433 static int rtl8152_suspend(struct usb_interface *intf, pm_message_t message)
8fb280616 hayeswang 2017-01-10 4434 {
8fb280616 hayeswang 2017-01-10 4435 struct r8152 *tp = usb_get_intfdata(intf);
8fb280616 hayeswang 2017-01-10 4436 int ret;
8fb280616 hayeswang 2017-01-10 4437
8fb280616 hayeswang 2017-01-10 4438 mutex_lock(&tp->control);
8fb280616 hayeswang 2017-01-10 4439
8fb280616 hayeswang 2017-01-10 4440 if (PMSG_IS_AUTO(message))
a9c54ad2c hayeswang 2017-01-25 4441 ret = rtl8152_runtime_suspend(tp);
8fb280616 hayeswang 2017-01-10 4442 else
31b61d6a0 zhong jiang 2018-08-08 4443 rtl8152_system_suspend(tp);
8fb280616 hayeswang 2017-01-10 4444
b54032736 hayeswang 2014-10-09 4445 mutex_unlock(&tp->control);
b54032736 hayeswang 2014-10-09 4446
6cc69f2a4 hayeswang 2014-10-17 @4447 return ret;
ac718b693 hayeswang 2013-05-02 4448 }
ac718b693 hayeswang 2013-05-02 4449
^ permalink raw reply
* Re: [RFC net-next 00/15] net: A socket API for LoRa
From: Andreas Färber @ 2018-08-12 17:59 UTC (permalink / raw)
To: Jian-Hong Pan, Alan Cox
Cc: netdev, linux-arm-kernel, linux-kernel, Jiri Pirko,
Marcel Holtmann, David S. Miller, Matthias Brugger, Janus Piwek,
Michael Röder, Dollar Chen, Ken Yu, Konstantin Böhm,
Jan Jongboom, Jon Ortego, contact@snootlab.com, Ben Whitten,
Brian Ray, lora, Alexander Graf, Michal Kubeček
In-Reply-To: <CAC=mGzhaLiSj5-+euM-YTRLwNDi8QJY0fAbiZbUadkPhZGRh_Q@mail.gmail.com>
Am 12.08.2018 um 18:37 schrieb Jian-Hong Pan:
> Alan Cox <gnomes@lxorguk.ukuu.org.uk> 於 2018年8月10日 週五 下午11:57寫道:
>>
>>> The sleep/idle/stop mitigate the unconcerned RF signals or messages.
>>
>> At the physical level it's irrelevant. If we are receiving then we might
>> hear more things we later discard. It's not running on a tiny
>> microcontroller so the extra CPU cycles are not going to kill us.
>
> According different power resource, LoRaWAN defines Class A, B and C.
> Class A is the basic and both Class B and C devices must also
> implement the feature of Class A.
[...]
> So, yes! Class C opens the RX windows almost all the time, except the TX time.
> And uses different channel to avoid the reflection noise (*).
>
> However, Class C must also implements Class A and C is more complex than A.
> I think starting from the simpler one and adding more features and
> complexity in the future will be a better practice.
Jian-Hong, you've failed to come up with any practical proposal or patch
how to implement what you are saying LoRaWAN requires. Doing the
impossible is never simpler!
Implementing a simple back-off timer sounds doable by comparison.
May I remind you, LoRa is the simpler step before LoRaWAN - if our
layering is done right, someone else might choose to implement LoRaWAN
in userspace based on PF_LORA. There is absolutely no reason to hardcode
any LoRaWAN settings at device driver level for e.g. SX1276.
>>>> How do you plan to deal with routing if you've got multiple devices ?
>>>
>>> For LoRaWAN, it is a star topology.
>>
>> No the question was much more how you plan to deal with it in the OS. If
>> for example I want to open a LORA connection to something, then there
>> needs to be a proper process to figure out where the target is and how to
>> get traffic to them.
>>
>> I guess it's best phrased as
>>
>> - What does a struct sockaddr_lora look like
>
> According to LoRaWAN spec, the Data Message only has the device's
> DevAddr (the device's address in 4 bytes) field related to "address".
> The device just sends the uplink Data Message through the interface
> and does not know the destination. Then, a LoRaWAN gateway receives
> the uplink Data Message and forwards to the designated network server.
> So, end device does not care about the destination. It only knows
> there is a gateway will forward its message to some where.
> Therefore, only the DevAddr as the source address will be meaningful
> for uplink Data Message.
Note that he was asking about sockaddr_lora, not LoRaWAN.
The simple answer is that, inspired by CAN, it uses an ifindex to select
the interface the user asked to use. That then also answers Alan's next
question: This ifindex determines which interface it goes out to.
sockaddr_lora was in patch 02/15, latest code here:
https://git.kernel.org/pub/scm/linux/kernel/git/afaerber/linux-lora.git/tree/include/uapi/linux/lora.h?h=lora-next
>> - How does the kernel decide which interface it goes out of (if any), and
>> if it loops back
>
> There is the MAC Header in the Data Message which is one byte.
> Bits 5 to 7 indicate which kind of type the message is.
> 000: Join Request
> 001: Join Accept
> 010: Unconfirmed Data Up
> 011: Unconfirmed Data Down
> 100: Confirmed Data Up
> 101: Confirmed Data Down
> 110: RFU
> 111: Proprietary
>
> So, end device only accepts the types of downlink and the matched
> DevAddr (the device's address) in downlink Data Message for RX.
LoRaWAN is an entirely different story, therefore my agreement that we
need a separate PF_LORAWAN and sockaddr_lorawan for EUI addressing.
I still think the user will need to explicitly say which interface they
want to bind their socket to. AFAIU the device EUI is more comparable to
an Ethernet MAC address than to an IP address that the user would
configure routes for. If you have e.g. four SX1301 devices then they may
be configured for different frequencies, bandwidths, etc. but unlikely
for certain destination/source addresses. So either all that data comes
via sockaddr (which I was discussing in the FSK/OOK part of this thread)
or the user needs to make the interface choice for us.
Loopback mode would require a separate virtual device driver such as
fakelr or vlora.
Regards,
Andreas
--
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
^ permalink raw reply
* [PATCH v2 bpf-next 1/4] bpf: Introduce bpf_skb_ancestor_cgroup_id helper
From: Andrey Ignatov @ 2018-08-12 17:49 UTC (permalink / raw)
To: netdev; +Cc: Andrey Ignatov, ast, daniel, tj, guro, yhs, kernel-team
In-Reply-To: <cover.1534095926.git.rdna@fb.com>
== Problem description ==
It's useful to be able to identify cgroup associated with skb in TC so
that a policy can be applied to this skb, and existing bpf_skb_cgroup_id
helper can help with this.
Though in real life cgroup hierarchy and hierarchy to apply a policy to
don't map 1:1.
It's often the case that there is a container and corresponding cgroup,
but there are many more sub-cgroups inside container, e.g. because it's
delegated to containerized application to control resources for its
subsystems, or to separate application inside container from infra that
belongs to containerization system (e.g. sshd).
At the same time it may be useful to apply a policy to container as a
whole.
If multiple containers like this are run on a host (what is often the
case) and many of them have sub-cgroups, it may not be possible to apply
per-container policy in TC with existing helpers such as
bpf_skb_under_cgroup or bpf_skb_cgroup_id:
* bpf_skb_cgroup_id will return id of immediate cgroup associated with
skb, i.e. if it's a sub-cgroup inside container, it can't be used to
identify container's cgroup;
* bpf_skb_under_cgroup can work only with one cgroup and doesn't scale,
i.e. if there are N containers on a host and a policy has to be
applied to M of them (0 <= M <= N), it'd require M calls to
bpf_skb_under_cgroup, and, if M changes, it'd require to rebuild &
load new BPF program.
== Solution ==
The patch introduces new helper bpf_skb_ancestor_cgroup_id that can be
used to get id of cgroup v2 that is an ancestor of cgroup associated
with skb at specified level of cgroup hierarchy.
That way admin can place all containers on one level of cgroup hierarchy
(what is a good practice in general and already used in many
configurations) and identify specific cgroup on this level no matter
what sub-cgroup skb is associated with.
E.g. if there is a cgroup hierarchy:
root/
root/container1/
root/container1/app11/
root/container1/app11/sub-app-a/
root/container1/app12/
root/container2/
root/container2/app21/
root/container2/app22/
root/container2/app22/sub-app-b/
, then having skb associated with root/container1/app11/sub-app-a/ it's
possible to get ancestor at level 1, what is container1 and apply policy
for this container, or apply another policy if it's container2.
Policies can be kept e.g. in a hash map where key is a container cgroup
id and value is an action.
Levels where container cgroups are created are usually known in advance
whether cgroup hierarchy inside container may be hard to predict
especially in case when its creation is delegated to containerized
application.
== Implementation details ==
The helper gets ancestor by walking parents up to specified level.
Another option would be to get different kind of "id" from
cgroup->ancestor_ids[level] and use it with idr_find() to get struct
cgroup for ancestor. But that would require radix lookup what doesn't
seem to be better (at least it's not obviously better).
Format of return value of the new helper is same as that of
bpf_skb_cgroup_id.
Signed-off-by: Andrey Ignatov <rdna@fb.com>
---
include/linux/cgroup.h | 30 ++++++++++++++++++++++++++++++
include/uapi/linux/bpf.h | 21 ++++++++++++++++++++-
net/core/filter.c | 28 ++++++++++++++++++++++++++++
3 files changed, 78 insertions(+), 1 deletion(-)
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index c9fdf6f57913..32c553556bbd 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -553,6 +553,36 @@ static inline bool cgroup_is_descendant(struct cgroup *cgrp,
return cgrp->ancestor_ids[ancestor->level] == ancestor->id;
}
+/**
+ * cgroup_ancestor - find ancestor of cgroup
+ * @cgrp: cgroup to find ancestor of
+ * @ancestor_level: level of ancestor to find starting from root
+ *
+ * Find ancestor of cgroup at specified level starting from root if it exists
+ * and return pointer to it. Return NULL if @cgrp doesn't have ancestor at
+ * @ancestor_level.
+ *
+ * This function is safe to call as long as @cgrp is accessible.
+ */
+static inline struct cgroup *cgroup_ancestor(struct cgroup *cgrp,
+ int ancestor_level)
+{
+ struct cgroup *ptr;
+
+ if (cgrp->level < ancestor_level)
+ return NULL;
+
+ for (ptr = cgrp;
+ ptr && ptr->level > ancestor_level;
+ ptr = cgroup_parent(ptr))
+ ;
+
+ if (ptr && ptr->level == ancestor_level)
+ return ptr;
+
+ return NULL;
+}
+
/**
* task_under_cgroup_hierarchy - test task's membership of cgroup ancestry
* @task: the task to be tested
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 3102a2a23c31..66917a4eba27 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -2093,6 +2093,24 @@ union bpf_attr {
* Return
* The id is returned or 0 in case the id could not be retrieved.
*
+ * u64 bpf_skb_ancestor_cgroup_id(struct sk_buff *skb, int ancestor_level)
+ * Description
+ * Return id of cgroup v2 that is ancestor of cgroup associated
+ * with the *skb* at the *ancestor_level*. The root cgroup is at
+ * *ancestor_level* zero and each step down the hierarchy
+ * increments the level. If *ancestor_level* == level of cgroup
+ * associated with *skb*, then return value will be same as that
+ * of **bpf_skb_cgroup_id**\ ().
+ *
+ * The helper is useful to implement policies based on cgroups
+ * that are upper in hierarchy than immediate cgroup associated
+ * with *skb*.
+ *
+ * The format of returned id and helper limitations are same as in
+ * **bpf_skb_cgroup_id**\ ().
+ * Return
+ * The id is returned or 0 in case the id could not be retrieved.
+ *
* u64 bpf_get_current_cgroup_id(void)
* Return
* A 64-bit integer containing the current cgroup id based
@@ -2207,7 +2225,8 @@ union bpf_attr {
FN(skb_cgroup_id), \
FN(get_current_cgroup_id), \
FN(get_local_storage), \
- FN(sk_select_reuseport),
+ FN(sk_select_reuseport), \
+ FN(skb_ancestor_cgroup_id),
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
* function eBPF program intends to call
diff --git a/net/core/filter.c b/net/core/filter.c
index 22906b31d43f..15b9d2df92ca 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -3778,6 +3778,32 @@ static const struct bpf_func_proto bpf_skb_cgroup_id_proto = {
.ret_type = RET_INTEGER,
.arg1_type = ARG_PTR_TO_CTX,
};
+
+BPF_CALL_2(bpf_skb_ancestor_cgroup_id, const struct sk_buff *, skb, int,
+ ancestor_level)
+{
+ struct sock *sk = skb_to_full_sk(skb);
+ struct cgroup *ancestor;
+ struct cgroup *cgrp;
+
+ if (!sk || !sk_fullsock(sk))
+ return 0;
+
+ cgrp = sock_cgroup_ptr(&sk->sk_cgrp_data);
+ ancestor = cgroup_ancestor(cgrp, ancestor_level);
+ if (!ancestor)
+ return 0;
+
+ return ancestor->kn->id.id;
+}
+
+static const struct bpf_func_proto bpf_skb_ancestor_cgroup_id_proto = {
+ .func = bpf_skb_ancestor_cgroup_id,
+ .gpl_only = false,
+ .ret_type = RET_INTEGER,
+ .arg1_type = ARG_PTR_TO_CTX,
+ .arg2_type = ARG_ANYTHING,
+};
#endif
static unsigned long bpf_xdp_copy(void *dst_buff, const void *src_buff,
@@ -4966,6 +4992,8 @@ tc_cls_act_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
#ifdef CONFIG_SOCK_CGROUP_DATA
case BPF_FUNC_skb_cgroup_id:
return &bpf_skb_cgroup_id_proto;
+ case BPF_FUNC_skb_ancestor_cgroup_id:
+ return &bpf_skb_ancestor_cgroup_id_proto;
#endif
default:
return bpf_base_func_proto(func_id);
--
2.17.1
^ permalink raw reply related
* [PATCH v2 bpf-next 3/4] selftests/bpf: Add cgroup id helpers to bpf_helpers.h
From: Andrey Ignatov @ 2018-08-12 17:49 UTC (permalink / raw)
To: netdev; +Cc: Andrey Ignatov, ast, daniel, tj, guro, yhs, kernel-team
In-Reply-To: <cover.1534095926.git.rdna@fb.com>
Add bpf_skb_cgroup_id and bpf_skb_ancestor_cgroup_id helpers to
bpf_helpers.h to use them in tests and samples.
Signed-off-by: Andrey Ignatov <rdna@fb.com>
---
tools/testing/selftests/bpf/bpf_helpers.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h
index 5c32266c2c38..e4be7730222d 100644
--- a/tools/testing/selftests/bpf/bpf_helpers.h
+++ b/tools/testing/selftests/bpf/bpf_helpers.h
@@ -139,6 +139,10 @@ static unsigned long long (*bpf_get_current_cgroup_id)(void) =
(void *) BPF_FUNC_get_current_cgroup_id;
static void *(*bpf_get_local_storage)(void *map, unsigned long long flags) =
(void *) BPF_FUNC_get_local_storage;
+static unsigned long long (*bpf_skb_cgroup_id)(void *ctx) =
+ (void *) BPF_FUNC_skb_cgroup_id;
+static unsigned long long (*bpf_skb_ancestor_cgroup_id)(void *ctx, int level) =
+ (void *) BPF_FUNC_skb_ancestor_cgroup_id;
/* llvm builtin functions that eBPF C program may use to
* emit BPF_LD_ABS and BPF_LD_IND instructions
--
2.17.1
^ permalink raw reply related
* [PATCH v2 bpf-next 4/4] selftests/bpf: Selftest for bpf_skb_ancestor_cgroup_id
From: Andrey Ignatov @ 2018-08-12 17:49 UTC (permalink / raw)
To: netdev; +Cc: Andrey Ignatov, ast, daniel, tj, guro, yhs, kernel-team
In-Reply-To: <cover.1534095926.git.rdna@fb.com>
Add selftests for bpf_skb_ancestor_cgroup_id helper.
test_skb_cgroup_id.sh prepares testing interface and adds tc qdisc and
filter for it using BPF object compiled from test_skb_cgroup_id_kern.c
program.
BPF program in test_skb_cgroup_id_kern.c gets ancestor cgroup id using
the new helper at different levels of cgroup hierarchy that skb belongs
to, including root level and non-existing level, and saves it to the map
where the key is the level of corresponding cgroup and the value is its
id.
To trigger BPF program, user space program test_skb_cgroup_id_user is
run. It adds itself into testing cgroup and sends UDP datagram to
link-local multicast address of testing interface. Then it reads cgroup
ids saved in kernel for different levels from the BPF map and compares
them with those in user space. They must be equal for every level of
ancestry.
Example of run:
# ./test_skb_cgroup_id.sh
Wait for testing link-local IP to become available ... OK
Note: 8 bytes struct bpf_elf_map fixup performed due to size mismatch!
[PASS]
Signed-off-by: Andrey Ignatov <rdna@fb.com>
---
tools/testing/selftests/bpf/Makefile | 9 +-
.../selftests/bpf/test_skb_cgroup_id.sh | 62 ++++++
.../selftests/bpf/test_skb_cgroup_id_kern.c | 47 +++++
.../selftests/bpf/test_skb_cgroup_id_user.c | 187 ++++++++++++++++++
4 files changed, 302 insertions(+), 3 deletions(-)
create mode 100755 tools/testing/selftests/bpf/test_skb_cgroup_id.sh
create mode 100644 tools/testing/selftests/bpf/test_skb_cgroup_id_kern.c
create mode 100644 tools/testing/selftests/bpf/test_skb_cgroup_id_user.c
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index daed162043c2..fff7fb1285fc 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -34,7 +34,8 @@ TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o test_tcp_estats.o test
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_lwt_seg6local.o sendmsg4_prog.o sendmsg6_prog.o test_lirc_mode2_kern.o \
- get_cgroup_id_kern.o socket_cookie_prog.o test_select_reuseport_kern.o
+ get_cgroup_id_kern.o socket_cookie_prog.o test_select_reuseport_kern.o \
+ test_skb_cgroup_id_kern.o
# Order correspond to 'make run_tests' order
TEST_PROGS := test_kmod.sh \
@@ -45,10 +46,11 @@ TEST_PROGS := test_kmod.sh \
test_sock_addr.sh \
test_tunnel.sh \
test_lwt_seg6local.sh \
- test_lirc_mode2.sh
+ test_lirc_mode2.sh \
+ test_skb_cgroup_id.sh
# Compile but not part of 'make run_tests'
-TEST_GEN_PROGS_EXTENDED = test_libbpf_open test_sock_addr
+TEST_GEN_PROGS_EXTENDED = test_libbpf_open test_sock_addr test_skb_cgroup_id_user
include ../lib.mk
@@ -59,6 +61,7 @@ $(TEST_GEN_PROGS): $(BPFOBJ)
$(TEST_GEN_PROGS_EXTENDED): $(OUTPUT)/libbpf.a
$(OUTPUT)/test_dev_cgroup: cgroup_helpers.c
+$(OUTPUT)/test_skb_cgroup_id_user: cgroup_helpers.c
$(OUTPUT)/test_sock: cgroup_helpers.c
$(OUTPUT)/test_sock_addr: cgroup_helpers.c
$(OUTPUT)/test_socket_cookie: cgroup_helpers.c
diff --git a/tools/testing/selftests/bpf/test_skb_cgroup_id.sh b/tools/testing/selftests/bpf/test_skb_cgroup_id.sh
new file mode 100755
index 000000000000..42544a969abc
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_skb_cgroup_id.sh
@@ -0,0 +1,62 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2018 Facebook
+
+set -eu
+
+wait_for_ip()
+{
+ local _i
+ echo -n "Wait for testing link-local IP to become available "
+ for _i in $(seq ${MAX_PING_TRIES}); do
+ echo -n "."
+ if ping -6 -q -c 1 -W 1 ff02::1%${TEST_IF} >/dev/null 2>&1; then
+ echo " OK"
+ return
+ fi
+ sleep 1
+ done
+ echo 1>&2 "ERROR: Timeout waiting for test IP to become available."
+ exit 1
+}
+
+setup()
+{
+ # Create testing interfaces not to interfere with current environment.
+ ip link add dev ${TEST_IF} type veth peer name ${TEST_IF_PEER}
+ ip link set ${TEST_IF} up
+ ip link set ${TEST_IF_PEER} up
+
+ wait_for_ip
+
+ tc qdisc add dev ${TEST_IF} clsact
+ tc filter add dev ${TEST_IF} egress bpf obj ${BPF_PROG_OBJ} \
+ sec ${BPF_PROG_SECTION} da
+
+ BPF_PROG_ID=$(tc filter show dev ${TEST_IF} egress | \
+ awk '/ id / {sub(/.* id /, "", $0); print($1)}')
+}
+
+cleanup()
+{
+ ip link del ${TEST_IF} 2>/dev/null || :
+ ip link del ${TEST_IF_PEER} 2>/dev/null || :
+}
+
+main()
+{
+ trap cleanup EXIT 2 3 6 15
+ setup
+ ${PROG} ${TEST_IF} ${BPF_PROG_ID}
+}
+
+DIR=$(dirname $0)
+TEST_IF="test_cgid_1"
+TEST_IF_PEER="test_cgid_2"
+MAX_PING_TRIES=5
+BPF_PROG_OBJ="${DIR}/test_skb_cgroup_id_kern.o"
+BPF_PROG_SECTION="cgroup_id_logger"
+BPF_PROG_ID=0
+PROG="${DIR}/test_skb_cgroup_id_user"
+
+main
diff --git a/tools/testing/selftests/bpf/test_skb_cgroup_id_kern.c b/tools/testing/selftests/bpf/test_skb_cgroup_id_kern.c
new file mode 100644
index 000000000000..68cf9829f5a7
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_skb_cgroup_id_kern.c
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2018 Facebook
+
+#include <linux/bpf.h>
+#include <linux/pkt_cls.h>
+
+#include <string.h>
+
+#include "bpf_helpers.h"
+
+#define NUM_CGROUP_LEVELS 4
+
+struct bpf_map_def SEC("maps") cgroup_ids = {
+ .type = BPF_MAP_TYPE_ARRAY,
+ .key_size = sizeof(__u32),
+ .value_size = sizeof(__u64),
+ .max_entries = NUM_CGROUP_LEVELS,
+};
+
+static __always_inline void log_nth_level(struct __sk_buff *skb, __u32 level)
+{
+ __u64 id;
+
+ /* [1] &level passed to external function that may change it, it's
+ * incompatible with loop unroll.
+ */
+ id = bpf_skb_ancestor_cgroup_id(skb, level);
+ bpf_map_update_elem(&cgroup_ids, &level, &id, 0);
+}
+
+SEC("cgroup_id_logger")
+int log_cgroup_id(struct __sk_buff *skb)
+{
+ /* Loop unroll can't be used here due to [1]. Unrolling manually.
+ * Number of calls should be in sync with NUM_CGROUP_LEVELS.
+ */
+ log_nth_level(skb, 0);
+ log_nth_level(skb, 1);
+ log_nth_level(skb, 2);
+ log_nth_level(skb, 3);
+
+ return TC_ACT_OK;
+}
+
+int _version SEC("version") = 1;
+
+char _license[] SEC("license") = "GPL";
diff --git a/tools/testing/selftests/bpf/test_skb_cgroup_id_user.c b/tools/testing/selftests/bpf/test_skb_cgroup_id_user.c
new file mode 100644
index 000000000000..c121cc59f314
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_skb_cgroup_id_user.c
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2018 Facebook
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <arpa/inet.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+
+
+#include <bpf/bpf.h>
+#include <bpf/libbpf.h>
+
+#include "bpf_rlimit.h"
+#include "cgroup_helpers.h"
+
+#define CGROUP_PATH "/skb_cgroup_test"
+#define NUM_CGROUP_LEVELS 4
+
+/* RFC 4291, Section 2.7.1 */
+#define LINKLOCAL_MULTICAST "ff02::1"
+
+static int mk_dst_addr(const char *ip, const char *iface,
+ struct sockaddr_in6 *dst)
+{
+ memset(dst, 0, sizeof(*dst));
+
+ dst->sin6_family = AF_INET6;
+ dst->sin6_port = htons(1025);
+
+ if (inet_pton(AF_INET6, ip, &dst->sin6_addr) != 1) {
+ log_err("Invalid IPv6: %s", ip);
+ return -1;
+ }
+
+ dst->sin6_scope_id = if_nametoindex(iface);
+ if (!dst->sin6_scope_id) {
+ log_err("Failed to get index of iface: %s", iface);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int send_packet(const char *iface)
+{
+ struct sockaddr_in6 dst;
+ char msg[] = "msg";
+ int err = 0;
+ int fd = -1;
+
+ if (mk_dst_addr(LINKLOCAL_MULTICAST, iface, &dst))
+ goto err;
+
+ fd = socket(AF_INET6, SOCK_DGRAM, 0);
+ if (fd == -1) {
+ log_err("Failed to create UDP socket");
+ goto err;
+ }
+
+ if (sendto(fd, &msg, sizeof(msg), 0, (const struct sockaddr *)&dst,
+ sizeof(dst)) == -1) {
+ log_err("Failed to send datagram");
+ goto err;
+ }
+
+ goto out;
+err:
+ err = -1;
+out:
+ if (fd >= 0)
+ close(fd);
+ return err;
+}
+
+int get_map_fd_by_prog_id(int prog_id)
+{
+ struct bpf_prog_info info = {};
+ __u32 info_len = sizeof(info);
+ __u32 map_ids[1];
+ int prog_fd = -1;
+ int map_fd = -1;
+
+ prog_fd = bpf_prog_get_fd_by_id(prog_id);
+ if (prog_fd < 0) {
+ log_err("Failed to get fd by prog id %d", prog_id);
+ goto err;
+ }
+
+ info.nr_map_ids = 1;
+ info.map_ids = (__u64) (unsigned long) map_ids;
+
+ if (bpf_obj_get_info_by_fd(prog_fd, &info, &info_len)) {
+ log_err("Failed to get info by prog fd %d", prog_fd);
+ goto err;
+ }
+
+ if (!info.nr_map_ids) {
+ log_err("No maps found for prog fd %d", prog_fd);
+ goto err;
+ }
+
+ map_fd = bpf_map_get_fd_by_id(map_ids[0]);
+ if (map_fd < 0)
+ log_err("Failed to get fd by map id %d", map_ids[0]);
+err:
+ if (prog_fd >= 0)
+ close(prog_fd);
+ return map_fd;
+}
+
+int check_ancestor_cgroup_ids(int prog_id)
+{
+ __u64 actual_ids[NUM_CGROUP_LEVELS], expected_ids[NUM_CGROUP_LEVELS];
+ __u32 level;
+ int err = 0;
+ int map_fd;
+
+ expected_ids[0] = 0x100000001; /* root cgroup */
+ expected_ids[1] = get_cgroup_id("");
+ expected_ids[2] = get_cgroup_id(CGROUP_PATH);
+ expected_ids[3] = 0; /* non-existent cgroup */
+
+ map_fd = get_map_fd_by_prog_id(prog_id);
+ if (map_fd < 0)
+ goto err;
+
+ for (level = 0; level < NUM_CGROUP_LEVELS; ++level) {
+ if (bpf_map_lookup_elem(map_fd, &level, &actual_ids[level])) {
+ log_err("Failed to lookup key %d", level);
+ goto err;
+ }
+ if (actual_ids[level] != expected_ids[level]) {
+ log_err("%llx (actual) != %llx (expected), level: %u\n",
+ actual_ids[level], expected_ids[level], level);
+ goto err;
+ }
+ }
+
+ goto out;
+err:
+ err = -1;
+out:
+ if (map_fd >= 0)
+ close(map_fd);
+ return err;
+}
+
+int main(int argc, char **argv)
+{
+ int cgfd = -1;
+ int err = 0;
+
+ if (argc < 3) {
+ fprintf(stderr, "Usage: %s iface prog_id\n", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ if (setup_cgroup_environment())
+ goto err;
+
+ cgfd = create_and_get_cgroup(CGROUP_PATH);
+ if (!cgfd)
+ goto err;
+
+ if (join_cgroup(CGROUP_PATH))
+ goto err;
+
+ if (send_packet(argv[1]))
+ goto err;
+
+ if (check_ancestor_cgroup_ids(atoi(argv[2])))
+ goto err;
+
+ goto out;
+err:
+ err = -1;
+out:
+ close(cgfd);
+ cleanup_cgroup_environment();
+ printf("[%s]\n", err ? "FAIL" : "PASS");
+ return err;
+}
--
2.17.1
^ permalink raw reply related
* [PATCH v2 bpf-next 2/4] bpf: Sync bpf.h to tools/
From: Andrey Ignatov @ 2018-08-12 17:49 UTC (permalink / raw)
To: netdev; +Cc: Andrey Ignatov, ast, daniel, tj, guro, yhs, kernel-team
In-Reply-To: <cover.1534095926.git.rdna@fb.com>
Sync skb_ancestor_cgroup_id() related bpf UAPI changes to tools/.
Signed-off-by: Andrey Ignatov <rdna@fb.com>
---
tools/include/uapi/linux/bpf.h | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 3102a2a23c31..66917a4eba27 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -2093,6 +2093,24 @@ union bpf_attr {
* Return
* The id is returned or 0 in case the id could not be retrieved.
*
+ * u64 bpf_skb_ancestor_cgroup_id(struct sk_buff *skb, int ancestor_level)
+ * Description
+ * Return id of cgroup v2 that is ancestor of cgroup associated
+ * with the *skb* at the *ancestor_level*. The root cgroup is at
+ * *ancestor_level* zero and each step down the hierarchy
+ * increments the level. If *ancestor_level* == level of cgroup
+ * associated with *skb*, then return value will be same as that
+ * of **bpf_skb_cgroup_id**\ ().
+ *
+ * The helper is useful to implement policies based on cgroups
+ * that are upper in hierarchy than immediate cgroup associated
+ * with *skb*.
+ *
+ * The format of returned id and helper limitations are same as in
+ * **bpf_skb_cgroup_id**\ ().
+ * Return
+ * The id is returned or 0 in case the id could not be retrieved.
+ *
* u64 bpf_get_current_cgroup_id(void)
* Return
* A 64-bit integer containing the current cgroup id based
@@ -2207,7 +2225,8 @@ union bpf_attr {
FN(skb_cgroup_id), \
FN(get_current_cgroup_id), \
FN(get_local_storage), \
- FN(sk_select_reuseport),
+ FN(sk_select_reuseport), \
+ FN(skb_ancestor_cgroup_id),
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
* function eBPF program intends to call
--
2.17.1
^ permalink raw reply related
* [PATCH v2 bpf-next 0/4] bpf_skb_ancestor_cgroup_id helper
From: Andrey Ignatov @ 2018-08-12 17:49 UTC (permalink / raw)
To: netdev; +Cc: Andrey Ignatov, ast, daniel, tj, guro, yhs, kernel-team
v1->v2:
- more reliable check for testing IPv6 to become ready in selftest.
This patch set adds new BPF helper bpf_skb_ancestor_cgroup_id that returns
id of cgroup v2 that is ancestor of cgroup associated with the skb at the
ancestor_level.
The helper is useful to implement policies in TC based on cgroups that are
upper in hierarchy than immediate cgroup associated with skb.
Patch 0001 provides more details and describes use-cases.
Patch 0002 syncs UAPI changes to tools/.
Patch 0003 adds skb*cgroup_id helpers to bpf_helper.h header.
Patch 0004 adds selftest for the new helper and is an example of usage.
Andrey Ignatov (4):
bpf: Introduce bpf_skb_ancestor_cgroup_id helper
bpf: Sync bpf.h to tools/
selftests/bpf: Add cgroup id helpers to bpf_helpers.h
selftests/bpf: Selftest for bpf_skb_ancestor_cgroup_id
include/linux/cgroup.h | 30 +++
include/uapi/linux/bpf.h | 21 +-
net/core/filter.c | 28 +++
tools/include/uapi/linux/bpf.h | 21 +-
tools/testing/selftests/bpf/Makefile | 9 +-
tools/testing/selftests/bpf/bpf_helpers.h | 4 +
.../selftests/bpf/test_skb_cgroup_id.sh | 62 ++++++
.../selftests/bpf/test_skb_cgroup_id_kern.c | 47 +++++
.../selftests/bpf/test_skb_cgroup_id_user.c | 187 ++++++++++++++++++
9 files changed, 404 insertions(+), 5 deletions(-)
create mode 100755 tools/testing/selftests/bpf/test_skb_cgroup_id.sh
create mode 100644 tools/testing/selftests/bpf/test_skb_cgroup_id_kern.c
create mode 100644 tools/testing/selftests/bpf/test_skb_cgroup_id_user.c
--
2.17.1
^ permalink raw reply
* Re: [PATCH bpf-next 4/4] selftests/bpf: Selftest for bpf_skb_ancestor_cgroup_id
From: Andrey Ignatov @ 2018-08-12 17:41 UTC (permalink / raw)
To: Yonghong Song; +Cc: netdev, ast, daniel, tj, guro, kernel-team
In-Reply-To: <976998cf-c7a8-878c-eb16-8ea479ed8e9d@fb.com>
Yonghong Song <yhs@fb.com> [Sat, 2018-08-11 23:59 -0700]:
>
>
> On 8/10/18 10:35 PM, Andrey Ignatov wrote:
> > Add selftests for bpf_skb_ancestor_cgroup_id helper.
> >
> > test_skb_cgroup_id.sh prepares testing interface and adds tc qdisc and
> > filter for it using BPF object compiled from test_skb_cgroup_id_kern.c
> > program.
> >
> > BPF program in test_skb_cgroup_id_kern.c gets ancestor cgroup id using
> > the new helper at different levels of cgroup hierarchy that skb belongs
> > to, including root level and non-existing level, and saves it to the map
> > where the key is the level of corresponding cgroup and the value is its
> > id.
> >
> > To trigger BPF program, user space program test_skb_cgroup_id_user is
> > run. It adds itself into testing cgroup and sends UDP datagram to
> > link-local multicast address of testing interface. Then it reads cgroup
> > ids saved in kernel for different levels from the BPF map and compares
> > them with those in user space. They must be equal for every level of
> > ancestry.
> >
> > Example of run:
> > # ./test_skb_cgroup_id.sh
> > Wait for testing link-local IP to become available ... OK
> > Note: 8 bytes struct bpf_elf_map fixup performed due to size mismatch!
> > [PASS]
>
> I am not able to run the test on my FC27 based VM with the latest bpf-next
> and the patch set.
>
> [yhs@localhost bpf]$ sudo ./test_skb_cgroup_id.sh
> Wait for testing link-local IP to become available .....ERROR: Timeout
> waiting for test IP to become available.
> [yhs@localhost bpf]$
>
> I am able to run test_sock_addr.sh successfully.
> $ sudo ./test_sock_addr.sh
> Wait for testing IPv4/IPv6 to become available .
> .. OK
> Test case: bind4: load prog with wrong expected attach type .. [PASS]
> Test case: bind4: attach prog with wrong attach type .. [PASS]
> ...
> Test case: sendmsg6: deny call .. [PASS]
> Summary: 27 PASSED, 0 FAILED
>
> Maybe some issues in this addr ff02::1%${TEST_IF}?
Thank you for checking it Yonghong!
I was able to repro it on a host different from where I tested
initially.
The problem is ping fails immediately due to link-local IPv6 being
tentative and all MAX_PING_TRIES happen very fast, w/o a chance for the
IPv6 to pass DAD and become ready.
On my original VM IPv6 was becoming ready much faster so even those 5
tries w/o a sleep between them were enough.
The fix is very simple: add `sleep 1` between iterations so there there
is enough time for IPv6 to pass DAD.
I'll send v2 with the fix.
> > Signed-off-by: Andrey Ignatov <rdna@fb.com>
> > ---
> > tools/testing/selftests/bpf/Makefile | 9 +-
> > .../selftests/bpf/test_skb_cgroup_id.sh | 61 ++++++
> > .../selftests/bpf/test_skb_cgroup_id_kern.c | 47 +++++
> > .../selftests/bpf/test_skb_cgroup_id_user.c | 187 ++++++++++++++++++
> > 4 files changed, 301 insertions(+), 3 deletions(-)
> > create mode 100755 tools/testing/selftests/bpf/test_skb_cgroup_id.sh
> > create mode 100644 tools/testing/selftests/bpf/test_skb_cgroup_id_kern.c
> > create mode 100644 tools/testing/selftests/bpf/test_skb_cgroup_id_user.c
> >
> > diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
> > index daed162043c2..fff7fb1285fc 100644
> > --- a/tools/testing/selftests/bpf/Makefile
> > +++ b/tools/testing/selftests/bpf/Makefile
> > @@ -34,7 +34,8 @@ TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o test_tcp_estats.o test
> > 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_lwt_seg6local.o sendmsg4_prog.o sendmsg6_prog.o test_lirc_mode2_kern.o \
> > - get_cgroup_id_kern.o socket_cookie_prog.o test_select_reuseport_kern.o
> > + get_cgroup_id_kern.o socket_cookie_prog.o test_select_reuseport_kern.o \
> > + test_skb_cgroup_id_kern.o
> > # Order correspond to 'make run_tests' order
> > TEST_PROGS := test_kmod.sh \
> > @@ -45,10 +46,11 @@ TEST_PROGS := test_kmod.sh \
> > test_sock_addr.sh \
> > test_tunnel.sh \
> > test_lwt_seg6local.sh \
> > - test_lirc_mode2.sh
> > + test_lirc_mode2.sh \
> > + test_skb_cgroup_id.sh
> > # Compile but not part of 'make run_tests'
> > -TEST_GEN_PROGS_EXTENDED = test_libbpf_open test_sock_addr
> > +TEST_GEN_PROGS_EXTENDED = test_libbpf_open test_sock_addr test_skb_cgroup_id_user
> > include ../lib.mk
> > @@ -59,6 +61,7 @@ $(TEST_GEN_PROGS): $(BPFOBJ)
> > $(TEST_GEN_PROGS_EXTENDED): $(OUTPUT)/libbpf.a
> > $(OUTPUT)/test_dev_cgroup: cgroup_helpers.c
> > +$(OUTPUT)/test_skb_cgroup_id_user: cgroup_helpers.c
> > $(OUTPUT)/test_sock: cgroup_helpers.c
> > $(OUTPUT)/test_sock_addr: cgroup_helpers.c
> > $(OUTPUT)/test_socket_cookie: cgroup_helpers.c
> > diff --git a/tools/testing/selftests/bpf/test_skb_cgroup_id.sh b/tools/testing/selftests/bpf/test_skb_cgroup_id.sh
> > new file mode 100755
> > index 000000000000..b75e9b52f06f
> > --- /dev/null
> > +++ b/tools/testing/selftests/bpf/test_skb_cgroup_id.sh
> > @@ -0,0 +1,61 @@
> > +#!/bin/sh
> > +# SPDX-License-Identifier: GPL-2.0
> > +# Copyright (c) 2018 Facebook
> > +
> > +set -eu
> > +
> > +wait_for_ip()
> > +{
> > + local _i
> > + echo -n "Wait for testing link-local IP to become available "
> > + for _i in $(seq ${MAX_PING_TRIES}); do
> > + echo -n "."
> > + if ping -6 -q -c 1 -W 1 ff02::1%${TEST_IF} >/dev/null 2>&1; then
> > + echo " OK"
> > + return
> > + fi
> > + done
> > + echo 1>&2 "ERROR: Timeout waiting for test IP to become available."
> > + exit 1
> > +}
> > +
> > +setup()
> > +{
> > + # Create testing interfaces not to interfere with current environment.
> > + ip link add dev ${TEST_IF} type veth peer name ${TEST_IF_PEER}
> > + ip link set ${TEST_IF} up
> > + ip link set ${TEST_IF_PEER} up
> > +
> > + wait_for_ip
> > +
> > + tc qdisc add dev ${TEST_IF} clsact
> > + tc filter add dev ${TEST_IF} egress bpf obj ${BPF_PROG_OBJ} \
> > + sec ${BPF_PROG_SECTION} da
> > +
> > + BPF_PROG_ID=$(tc filter show dev ${TEST_IF} egress | \
> > + awk '/ id / {sub(/.* id /, "", $0); print($1)}')
> > +}
> > +
> > +cleanup()
> > +{
> > + ip link del ${TEST_IF} 2>/dev/null || :
> > + ip link del ${TEST_IF_PEER} 2>/dev/null || :
> > +}
> > +
> > +main()
> > +{
> > + trap cleanup EXIT 2 3 6 15
> > + setup
> > + ${PROG} ${TEST_IF} ${BPF_PROG_ID}
> > +}
> > +
> > +DIR=$(dirname $0)
> > +TEST_IF="test_cgid_1"
> > +TEST_IF_PEER="test_cgid_2"
> > +MAX_PING_TRIES=5
> > +BPF_PROG_OBJ="${DIR}/test_skb_cgroup_id_kern.o"
> > +BPF_PROG_SECTION="cgroup_id_logger"
> > +BPF_PROG_ID=0
> > +PROG="${DIR}/test_skb_cgroup_id_user"
> > +
> > +main
> > diff --git a/tools/testing/selftests/bpf/test_skb_cgroup_id_kern.c b/tools/testing/selftests/bpf/test_skb_cgroup_id_kern.c
> > new file mode 100644
> > index 000000000000..68cf9829f5a7
> > --- /dev/null
> > +++ b/tools/testing/selftests/bpf/test_skb_cgroup_id_kern.c
> > @@ -0,0 +1,47 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +// Copyright (c) 2018 Facebook
> > +
> > +#include <linux/bpf.h>
> > +#include <linux/pkt_cls.h>
> > +
> > +#include <string.h>
> > +
> > +#include "bpf_helpers.h"
> > +
> > +#define NUM_CGROUP_LEVELS 4
> > +
> > +struct bpf_map_def SEC("maps") cgroup_ids = {
> > + .type = BPF_MAP_TYPE_ARRAY,
> > + .key_size = sizeof(__u32),
> > + .value_size = sizeof(__u64),
> > + .max_entries = NUM_CGROUP_LEVELS,
> > +};
> > +
> > +static __always_inline void log_nth_level(struct __sk_buff *skb, __u32 level)
> > +{
> > + __u64 id;
> > +
> > + /* [1] &level passed to external function that may change it, it's
> > + * incompatible with loop unroll.
> > + */
> > + id = bpf_skb_ancestor_cgroup_id(skb, level);
> > + bpf_map_update_elem(&cgroup_ids, &level, &id, 0);
> > +}
> > +
> > +SEC("cgroup_id_logger")
> > +int log_cgroup_id(struct __sk_buff *skb)
> > +{
> > + /* Loop unroll can't be used here due to [1]. Unrolling manually.
> > + * Number of calls should be in sync with NUM_CGROUP_LEVELS.
> > + */
> > + log_nth_level(skb, 0);
> > + log_nth_level(skb, 1);
> > + log_nth_level(skb, 2);
> > + log_nth_level(skb, 3);
> > +
> > + return TC_ACT_OK;
> > +}
> > +
> > +int _version SEC("version") = 1;
> > +
> > +char _license[] SEC("license") = "GPL";
> > diff --git a/tools/testing/selftests/bpf/test_skb_cgroup_id_user.c b/tools/testing/selftests/bpf/test_skb_cgroup_id_user.c
> > new file mode 100644
> > index 000000000000..c121cc59f314
> > --- /dev/null
> > +++ b/tools/testing/selftests/bpf/test_skb_cgroup_id_user.c
> > @@ -0,0 +1,187 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +// Copyright (c) 2018 Facebook
> > +
> > +#include <stdlib.h>
> > +#include <string.h>
> > +#include <unistd.h>
> > +
> > +#include <arpa/inet.h>
> > +#include <net/if.h>
> > +#include <netinet/in.h>
> > +#include <sys/socket.h>
> > +#include <sys/types.h>
> > +
> > +
> > +#include <bpf/bpf.h>
> > +#include <bpf/libbpf.h>
> > +
> > +#include "bpf_rlimit.h"
> > +#include "cgroup_helpers.h"
> > +
> > +#define CGROUP_PATH "/skb_cgroup_test"
> > +#define NUM_CGROUP_LEVELS 4
> > +
> > +/* RFC 4291, Section 2.7.1 */
> > +#define LINKLOCAL_MULTICAST "ff02::1"
> > +
> > +static int mk_dst_addr(const char *ip, const char *iface,
> > + struct sockaddr_in6 *dst)
> > +{
> > + memset(dst, 0, sizeof(*dst));
> > +
> > + dst->sin6_family = AF_INET6;
> > + dst->sin6_port = htons(1025);
> > +
> > + if (inet_pton(AF_INET6, ip, &dst->sin6_addr) != 1) {
> > + log_err("Invalid IPv6: %s", ip);
> > + return -1;
> > + }
> > +
> > + dst->sin6_scope_id = if_nametoindex(iface);
> > + if (!dst->sin6_scope_id) {
> > + log_err("Failed to get index of iface: %s", iface);
> > + return -1;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static int send_packet(const char *iface)
> > +{
> > + struct sockaddr_in6 dst;
> > + char msg[] = "msg";
> > + int err = 0;
> > + int fd = -1;
> > +
> > + if (mk_dst_addr(LINKLOCAL_MULTICAST, iface, &dst))
> > + goto err;
> > +
> > + fd = socket(AF_INET6, SOCK_DGRAM, 0);
> > + if (fd == -1) {
> > + log_err("Failed to create UDP socket");
> > + goto err;
> > + }
> > +
> > + if (sendto(fd, &msg, sizeof(msg), 0, (const struct sockaddr *)&dst,
> > + sizeof(dst)) == -1) {
> > + log_err("Failed to send datagram");
> > + goto err;
> > + }
> > +
> > + goto out;
> > +err:
> > + err = -1;
> > +out:
> > + if (fd >= 0)
> > + close(fd);
> > + return err;
> > +}
> > +
> > +int get_map_fd_by_prog_id(int prog_id)
> > +{
> > + struct bpf_prog_info info = {};
> > + __u32 info_len = sizeof(info);
> > + __u32 map_ids[1];
> > + int prog_fd = -1;
> > + int map_fd = -1;
> > +
> > + prog_fd = bpf_prog_get_fd_by_id(prog_id);
> > + if (prog_fd < 0) {
> > + log_err("Failed to get fd by prog id %d", prog_id);
> > + goto err;
> > + }
> > +
> > + info.nr_map_ids = 1;
> > + info.map_ids = (__u64) (unsigned long) map_ids;
> > +
> > + if (bpf_obj_get_info_by_fd(prog_fd, &info, &info_len)) {
> > + log_err("Failed to get info by prog fd %d", prog_fd);
> > + goto err;
> > + }
> > +
> > + if (!info.nr_map_ids) {
> > + log_err("No maps found for prog fd %d", prog_fd);
> > + goto err;
> > + }
> > +
> > + map_fd = bpf_map_get_fd_by_id(map_ids[0]);
> > + if (map_fd < 0)
> > + log_err("Failed to get fd by map id %d", map_ids[0]);
> > +err:
> > + if (prog_fd >= 0)
> > + close(prog_fd);
> > + return map_fd;
> > +}
> > +
> > +int check_ancestor_cgroup_ids(int prog_id)
> > +{
> > + __u64 actual_ids[NUM_CGROUP_LEVELS], expected_ids[NUM_CGROUP_LEVELS];
> > + __u32 level;
> > + int err = 0;
> > + int map_fd;
> > +
> > + expected_ids[0] = 0x100000001; /* root cgroup */
> > + expected_ids[1] = get_cgroup_id("");
> > + expected_ids[2] = get_cgroup_id(CGROUP_PATH);
> > + expected_ids[3] = 0; /* non-existent cgroup */
> > +
> > + map_fd = get_map_fd_by_prog_id(prog_id);
> > + if (map_fd < 0)
> > + goto err;
> > +
> > + for (level = 0; level < NUM_CGROUP_LEVELS; ++level) {
> > + if (bpf_map_lookup_elem(map_fd, &level, &actual_ids[level])) {
> > + log_err("Failed to lookup key %d", level);
> > + goto err;
> > + }
> > + if (actual_ids[level] != expected_ids[level]) {
> > + log_err("%llx (actual) != %llx (expected), level: %u\n",
> > + actual_ids[level], expected_ids[level], level);
> > + goto err;
> > + }
> > + }
> > +
> > + goto out;
> > +err:
> > + err = -1;
> > +out:
> > + if (map_fd >= 0)
> > + close(map_fd);
> > + return err;
> > +}
> > +
> > +int main(int argc, char **argv)
> > +{
> > + int cgfd = -1;
> > + int err = 0;
> > +
> > + if (argc < 3) {
> > + fprintf(stderr, "Usage: %s iface prog_id\n", argv[0]);
> > + exit(EXIT_FAILURE);
> > + }
> > +
> > + if (setup_cgroup_environment())
> > + goto err;
> > +
> > + cgfd = create_and_get_cgroup(CGROUP_PATH);
> > + if (!cgfd)
> > + goto err;
> > +
> > + if (join_cgroup(CGROUP_PATH))
> > + goto err;
> > +
> > + if (send_packet(argv[1]))
> > + goto err;
> > +
> > + if (check_ancestor_cgroup_ids(atoi(argv[2])))
> > + goto err;
> > +
> > + goto out;
> > +err:
> > + err = -1;
> > +out:
> > + close(cgfd);
> > + cleanup_cgroup_environment();
> > + printf("[%s]\n", err ? "FAIL" : "PASS");
> > + return err;
> > +}
> >
--
Andrey Ignatov
^ permalink raw reply
* Re: [PATCH net-next] net: add an empty __netif_set_xps_queue() stab in the !CONFIG_XPS case
From: kbuild test robot @ 2018-08-12 17:25 UTC (permalink / raw)
To: Andrei Vagin; +Cc: kbuild-all, David S. Miller, netdev, Andrei Vagin
In-Reply-To: <20180810010428.6096-1-avagin@openvz.org>
[-- Attachment #1: Type: text/plain, Size: 2264 bytes --]
Hi Andrei,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on net-next/master]
url: https://github.com/0day-ci/linux/commits/Andrei-Vagin/net-add-an-empty-__netif_set_xps_queue-stab-in-the-CONFIG_XPS-case/20180813-001123
config: i386-tinyconfig (attached as .config)
compiler: gcc-7 (Debian 7.3.0-16) 7.3.0
reproduce:
# save the attached .config to linux build tree
make ARCH=i386
All errors (new ones prefixed by >>):
In file included from include/linux/icmpv6.h:13:0,
from include/linux/ipv6.h:86,
from include/net/ipv6.h:16,
from include/linux/sunrpc/clnt.h:28,
from include/linux/nfs_fs.h:32,
from init/do_mounts.c:32:
>> include/linux/netdevice.h:3423:19: error: redefinition of '__netif_set_xps_queue'
static inline int __netif_set_xps_queue(struct net_device *dev,
^~~~~~~~~~~~~~~~~~~~~
include/linux/netdevice.h:3409:19: note: previous definition of '__netif_set_xps_queue' was here
static inline int __netif_set_xps_queue(struct net_device *dev,
^~~~~~~~~~~~~~~~~~~~~
vim +/__netif_set_xps_queue +3423 include/linux/netdevice.h
c9fbb2d2 Krzysztof Kozlowski 2018-08-10 3422
c9fbb2d2 Krzysztof Kozlowski 2018-08-10 @3423 static inline int __netif_set_xps_queue(struct net_device *dev,
c9fbb2d2 Krzysztof Kozlowski 2018-08-10 3424 const unsigned long *mask,
c9fbb2d2 Krzysztof Kozlowski 2018-08-10 3425 u16 index, bool is_rxqs_map)
c9fbb2d2 Krzysztof Kozlowski 2018-08-10 3426 {
c9fbb2d2 Krzysztof Kozlowski 2018-08-10 3427 return 0;
c9fbb2d2 Krzysztof Kozlowski 2018-08-10 3428 }
537c00de Alexander Duyck 2013-01-10 3429 #endif
537c00de Alexander Duyck 2013-01-10 3430
:::::: The code at line 3423 was first introduced by commit
:::::: c9fbb2d25295a566b97d62e6904741e8e1702d83 net: Provide stub for __netif_set_xps_queue if there is no CONFIG_XPS
:::::: TO: Krzysztof Kozlowski <krzk@kernel.org>
:::::: CC: David S. Miller <davem@davemloft.net>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 6369 bytes --]
^ permalink raw reply
* Re: [PATCH] of: mdio: Support fixed links in of_phy_get_and_connect()
From: Andrew Lunn @ 2018-08-12 17:24 UTC (permalink / raw)
To: Linus Walleij; +Cc: Florian Fainelli, David S. Miller, netdev, Laurent Pinchart
In-Reply-To: <CACRpkdb_moz2076y2Wcu88BqEOuKkKvj4seZt+-1v0+LYbaW8w@mail.gmail.com>
> It's confusing, I guess these PHY's don't come and go
> very much so the plug/play part isn't really exercised.
Very true. We sometimes need to handle -EPROBE_DEFER, which is not too
different from hot-plugging PHYs. Also, SFP modules are hot-pluggable,
and can contain a copper PHY. However, SFP modules don't have a
traditional MIDO bus. MDIO is tunnelled over i2c. So when a copper SFP
module is hotplugged, the MDIO bus is hot plugged as well.
If you do decided to make any changes here, please ask Russell King to
test, otherwise you might break this use case.
Andrew
^ permalink raw reply
* Re: [PATCH] mt76: Enable NL80211_EXT_FEATURE_CQM_RSSI_LIST
From: Arend van Spriel @ 2018-08-12 18:44 UTC (permalink / raw)
To: Kalle Valo, Kristian Evensen
Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <871sb3zc3v.fsf-HodKDYzPHsUD5k0oWYwrnHL1okKdlPRT@public.gmane.org>
On 8/12/2018 8:14 PM, Kalle Valo wrote:
> Kristian Evensen <kristian.evensen-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> writes:
>
>> Enable the use of CQM with mt76-devices.
>>
>> Signed-off-by: Kristian Evensen <kristian.evensen-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>> ---
>> drivers/net/wireless/mediatek/mt76/mac80211.c | 2 ++
>> 1 file changed, 2 insertions(+)
>>
>> diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c
>> index 029d54bc..3eb328ff 100644
>> --- a/drivers/net/wireless/mediatek/mt76/mac80211.c
>> +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
>> @@ -305,6 +305,8 @@ int mt76_register_device(struct mt76_dev *dev, bool vht,
>>
>> wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR;
>>
>> + wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
>
> So have you tested this and with what devices? For example, does it work
> with recently added USB devices?
I was looking into this as it looks suspicious to me. From reading the
description of this ext_feature flag it seems this is an extention of CQM:
"""
* @NL80211_EXT_FEATURE_CQM_RSSI_LIST: With this driver the
* %NL80211_ATTR_CQM_RSSI_THOLD attribute accepts a list of zero or more
* RSSI threshold values to monitor rather than exactly one threshold.
"""
Also looking at mt76x2_bss_info_changed() it does not handle
BSS_CHANGED_CQM so I doubt it has support for it (yet). The driver does
not use IEEE80211_VIF_SUPPORTS_CQM_RSSI which is a requirement for it.
Regards,
Arend
https://elixir.bootlin.com/linux/latest/source/drivers/net/wireless/mediatek/mt76/mt76x2_main.c#L223
^ permalink raw reply
* pull-request: wireless-drivers-next 2018-08-12
From: Kalle Valo @ 2018-08-12 18:34 UTC (permalink / raw)
To: David Miller; +Cc: linux-wireless, netdev, linux-kernel
Hi Dave,
one more request to net-next for 4.19. I hope I'm not too late with
this. These have been in linux-next since Friday so I'm hoping there are
no surprises. Please let me know if you have any problems.
Kalle
The following changes since commit 981467033a37d916649647fa3afe1fe99bba1817:
tc-testing: remove duplicate spaces in skbedit match patterns (2018-08-05 17:39:24 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git tags/wireless-drivers-next-for-davem-2018-08-12
for you to fetch changes up to 209b43759d65b2cc99ce7757249aacc82b03c4e2:
ssb: Remove SSB_WARN_ON, SSB_BUG_ON and SSB_DEBUG (2018-08-09 18:47:47 +0300)
----------------------------------------------------------------
wireless-drivers-next patches for 4.19
Last set of new features for 4.19. Most notable is simplifying SSB
debugging code with two Kconfig option removals and fixing mt76 USB
build problems.
Major changes:
ath10k
* add debugfs file warm_hw_reset
wil6210
* add debugfs files tx_latency, link_stats and link_stats_global
* add 3-MSI support
* allow scan on AP interface
* support max aggregation window size 64
ssb
* remove CONFIG_SSB_SILENT and CONFIG_SSB_DEBUG Kconfig options
mt76
* fix build problems with recently added USB support
----------------------------------------------------------------
Ahmad Masri (3):
wil6210: allow scan on AP interface
wil6210: align to latest auto generated wmi.h
wil6210: off channel transmit management frames in AP mode
Alexei Avshalom Lazar (3):
wil6210: add 3-MSI support
wil6210: fix min() compilation errors
wil6210: set default 3-MSI
Colin Ian King (5):
ath10k: remove redundant pointers 'dev' and 'noa'
ath5k: remove redundant pointer rf
ath6kl: remove redundant variables netlen, orig_buf, orig_len, dropped and stats
rsi: remove redundant variables bss, wh and temp_flash_content
iwlegacy: fix spelling mistake "acumulative" -> "accumulative"
Dedy Lansky (6):
wil6210: Rx multicast packets duplicate detection
wil6210: drop Rx packets with L2 error indication from HW
wil6210: add TX latency statistics
wil6210: fix temperature debugfs
wil6210: align to latest auto generated wmi.h
wil6210: add support for link statistics
Felix Fietkau (8):
ath9k_hw: set spectral scan enable bit on trigger for AR9003+
ath9k: don't run periodic and nf calibation at the same time
ath9k: fix moredata bit in PS buffered frame release
ath9k: clear potentially stale EOSP status bit in intermediate queues
ath9k: report tx status on EOSP
ath9k: fix block-ack window tracking issues
ath9k_hw: fix channel maximum power level test
ath9k: fix more-data flag for buffered multicast packets
Gustavo A. R. Silva (1):
ssb: driver_gige: use true and false for boolean values
Hamad Kadmany (1):
wil6210: increase firmware ready timeout
Jia-Ju Bai (1):
ath6kl: replace GFP_ATOMIC with GFP_KERNEL in ath6kl_bmi_init()
Kalle Valo (3):
ath10k: fix open brace location in ath10k_wmi_tlv_op_gen_dbglog_cfg()
ath10k: fix parenthesis alignment
Merge ath-next from git://git.kernel.org/.../kvalo/ath.git
Kees Cook (1):
mt76x0: Remove VLA usage
Maharaja Kennadyrajan (1):
ath10k: add debugfs file warm_hw_reset
Maya Erez (6):
wil6210: fix RX checksum report to network stack
wil6210: support Talyn specific FW file
wil6210: support max aggregation window size 64
wil6210: support Talyn specific board file
wil6210: prevent FW download if HW is configured for secured boot
wil6210: fix eDMA RX chaining
Michael Buesch (4):
b43/leds: Ensure NUL-termination of LED name string
b43legacy/leds: Ensure NUL-termination of LED name string
ssb: Remove home-grown printk wrappers
ssb: Remove SSB_WARN_ON, SSB_BUG_ON and SSB_DEBUG
Nicholas Mc Guire (1):
ath10k: htt_tx: move lock into id_get function
Pradeep Kumar Chitrapu (1):
ath10k: support for multicast rate control
Rakesh Pillai (1):
ath10k: handle mgmt tx completion event
Stanislaw Gruszka (2):
mt76x0: correct type for eeprom gain value
mt76x0: perform mt76x0_mac_set_ampdu_factor
Surabhi Vishnoi (1):
ath10k: disable bundle mgmt tx completion event support
Sven Eckelmann (1):
ath10k: prevent active scans on potential unusable channels
Valdis Kletnieks (1):
mt76: fix build for MediaTek MT7610U USB wireless dongle
Winnie Chang (1):
brcmfmac: fix brcmf_wiphy_wowl_params() NULL pointer dereference
YueHaibing (1):
rtlwifi: btcoex: Fix if == else warnings in halbtc8723b2ant.c
arch/mips/configs/bcm47xx_defconfig | 1 -
arch/powerpc/configs/wii_defconfig | 1 -
drivers/net/wireless/ath/ath10k/ahb.c | 5 -
drivers/net/wireless/ath/ath10k/core.c | 1 +
drivers/net/wireless/ath/ath10k/core.h | 5 +
drivers/net/wireless/ath/ath10k/debug.c | 49 ++
drivers/net/wireless/ath/ath10k/htt_tx.c | 10 +-
drivers/net/wireless/ath/ath10k/hw.h | 1 +
drivers/net/wireless/ath/ath10k/mac.c | 67 +-
drivers/net/wireless/ath/ath10k/wmi-ops.h | 12 +
drivers/net/wireless/ath/ath10k/wmi-tlv.c | 75 ++-
drivers/net/wireless/ath/ath10k/wmi-tlv.h | 17 +
drivers/net/wireless/ath/ath10k/wmi.c | 87 ++-
drivers/net/wireless/ath/ath10k/wmi.h | 23 +-
drivers/net/wireless/ath/ath5k/phy.c | 5 -
drivers/net/wireless/ath/ath6kl/bmi.c | 2 +-
drivers/net/wireless/ath/ath6kl/htc_pipe.c | 10 +-
drivers/net/wireless/ath/ath6kl/main.c | 3 +-
drivers/net/wireless/ath/ath6kl/txrx.c | 2 -
drivers/net/wireless/ath/ath9k/ar9002_calib.c | 6 +-
drivers/net/wireless/ath/ath9k/ar9003_phy.c | 2 +
drivers/net/wireless/ath/ath9k/hw.c | 7 +-
drivers/net/wireless/ath/ath9k/xmit.c | 67 +-
drivers/net/wireless/ath/wil6210/cfg80211.c | 50 +-
drivers/net/wireless/ath/wil6210/debugfs.c | 371 ++++++++++-
drivers/net/wireless/ath/wil6210/fw.c | 3 +
drivers/net/wireless/ath/wil6210/fw_inc.c | 2 +-
drivers/net/wireless/ath/wil6210/interrupt.c | 64 +-
drivers/net/wireless/ath/wil6210/main.c | 65 +-
drivers/net/wireless/ath/wil6210/pcie_bus.c | 70 ++-
drivers/net/wireless/ath/wil6210/rx_reorder.c | 31 +-
drivers/net/wireless/ath/wil6210/txrx.c | 71 ++-
drivers/net/wireless/ath/wil6210/txrx.h | 7 +
drivers/net/wireless/ath/wil6210/txrx_edma.c | 48 +-
drivers/net/wireless/ath/wil6210/txrx_edma.h | 6 +
drivers/net/wireless/ath/wil6210/wil6210.h | 96 ++-
drivers/net/wireless/ath/wil6210/wil_platform.h | 1 +
drivers/net/wireless/ath/wil6210/wmi.c | 221 +++++++
drivers/net/wireless/ath/wil6210/wmi.h | 685 ++++++++++++++++++++-
drivers/net/wireless/broadcom/b43/leds.c | 2 +-
drivers/net/wireless/broadcom/b43legacy/leds.c | 2 +-
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 8 +-
drivers/net/wireless/intel/iwlegacy/3945-debug.c | 2 +-
drivers/net/wireless/mediatek/mt76/Kconfig | 1 +
drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c | 8 +-
drivers/net/wireless/mediatek/mt76/mt76x0/mac.c | 2 -
.../realtek/rtlwifi/btcoexist/halbtc8723b2ant.c | 180 ++----
drivers/net/wireless/rsi/rsi_91x_hal.c | 10 +-
drivers/ssb/Kconfig | 21 -
drivers/ssb/b43_pci_bridge.c | 4 +-
drivers/ssb/bridge_pcmcia_80211.c | 6 +-
drivers/ssb/driver_chipcommon.c | 14 +-
drivers/ssb/driver_chipcommon_pmu.c | 40 +-
drivers/ssb/driver_chipcommon_sflash.c | 6 +-
drivers/ssb/driver_extif.c | 4 +-
drivers/ssb/driver_gige.c | 2 +-
drivers/ssb/driver_gpio.c | 8 +-
drivers/ssb/driver_mipscore.c | 17 +-
drivers/ssb/driver_pcicore.c | 23 +-
drivers/ssb/embedded.c | 18 +-
drivers/ssb/host_soc.c | 16 +-
drivers/ssb/main.c | 83 +--
drivers/ssb/pci.c | 75 +--
drivers/ssb/pcmcia.c | 62 +-
drivers/ssb/scan.c | 38 +-
drivers/ssb/sdio.c | 16 +-
drivers/ssb/sprom.c | 4 +-
drivers/ssb/ssb_private.h | 39 +-
include/linux/ssb/ssb.h | 2 -
69 files changed, 2308 insertions(+), 654 deletions(-)
^ permalink raw reply
* Re: [PATCH] mt76: Enable NL80211_EXT_FEATURE_CQM_RSSI_LIST
From: Kalle Valo @ 2018-08-12 18:14 UTC (permalink / raw)
To: Kristian Evensen; +Cc: linux-wireless, netdev, linux-kernel
In-Reply-To: <20180812145207.11395-1-kristian.evensen@gmail.com>
Kristian Evensen <kristian.evensen@gmail.com> writes:
> Enable the use of CQM with mt76-devices.
>
> Signed-off-by: Kristian Evensen <kristian.evensen@gmail.com>
> ---
> drivers/net/wireless/mediatek/mt76/mac80211.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c
> index 029d54bc..3eb328ff 100644
> --- a/drivers/net/wireless/mediatek/mt76/mac80211.c
> +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
> @@ -305,6 +305,8 @@ int mt76_register_device(struct mt76_dev *dev, bool vht,
>
> wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR;
>
> + wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
So have you tested this and with what devices? For example, does it work
with recently added USB devices?
--
Kalle Valo
^ permalink raw reply
* Re: [RFC/RFT, net-next, 00/17] net: Convert neighbor tables to per-namespace
From: David Ahern @ 2018-08-12 17:37 UTC (permalink / raw)
To: Vasily Averin, dsahern, netdev
Cc: nikita.leshchenko, roopa, stephen, idosch, jiri, saeedm,
alex.aring, linux-wpan, netfilter-devel, linux-kernel
In-Reply-To: <dc9cd93c-61d4-dc8c-9ba1-cd8584908ba2@virtuozzo.com>
On 8/12/18 12:46 AM, Vasily Averin wrote:
> On 07/17/2018 03:06 PM, dsahern@kernel.org wrote:
>> From: David Ahern <dsahern@gmail.com>
>>
>> Nikita Leshenko reported that neighbor entries in one namespace can
>> evict neighbor entries in another. The problem is that the neighbor
>> tables have entries across all namespaces without separate accounting
>> and with global limits on when to scan for entries to evict.
>>
>> Resolve by making the neighbor tables for ipv4, ipv6 and decnet per
>> namespace and making the accounting and threshold limits per namespace.
>
> Dear David,
> I prepared own patch set to fix this problem and found your one.
> It looks perfect for me, and I hope David Miller will merge it soon,
> however I have found a few drawbacks:
>
Hi:
I just returned from an extended vacation. I will revive this topic in
the next few days.
Thanks for the comments. I will address in the next version.
^ permalink raw reply
* Re: [RFC net-next 00/15] net: A socket API for LoRa
From: Andreas Färber @ 2018-08-12 16:49 UTC (permalink / raw)
To: Stefan Schmidt, Alan Cox
Cc: Jian-Hong Pan, netdev, linux-arm-kernel, linux-kernel, Jiri Pirko,
Marcel Holtmann, David S. Miller, Matthias Brugger, Janus Piwek,
Michael Röder, Dollar Chen, Ken Yu, Konstantin Böhm,
Jan Jongboom, Jon Ortego, contact, Ben Whitten, Brian Ray, lora,
Alexander Graf, mkubecek
In-Reply-To: <e703bd38-f45d-6dda-b0e3-404598fd4bab@datenfreihafen.org>
Hi,
Am 11.08.2018 um 20:30 schrieb Stefan Schmidt:
> On 08/10/2018 05:57 PM, Alan Cox wrote:
>>
>> Long term yes I think Alexander is right the inevitable fate of all
>> networks is to become a link layer in order to transmit IP frames 8)
>
> There should be a niche for both at the same time. LoRaWAN is relevant
> right now and we should aim for making it possible to run a native Linux
> gateway for it.
+1
> As for IP for long range low power there is the static context header
> compression draft to adapt IPv6 to the characteristics for some use
> cases of such networks. Implementing it within the existing 6lwopan
> subsystem should be possible.
>
> https://tools.ietf.org/html/draft-ietf-lpwan-ipv6-static-context-hc-16
I'm open to supporting by appropriate design all kinds of upper layers
people want to experiment with. Review feedback for that is welcome.
However I don't intend to implement each of those myself, and hardcoding
them is not really an option so they must be in appropriate modules.
Do keep in mind that depending on vendor implementation we have between
26 and 2048 bytes MTU available, less based on regulatory requirements,
often below 256 bytes. The more space we take away for frame headers
just because they're somehow standardized will make it less useful.
Regards,
Andreas
--
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
^ permalink raw reply
* Re: [RFC net-next 00/15] net: A socket API for LoRa
From: Jian-Hong Pan @ 2018-08-12 16:37 UTC (permalink / raw)
To: Alan Cox
Cc: Andreas Färber, netdev,
<linux-arm-kernel@lists.infradead.org\,
linux-kernel@vger.kernel.org>,, Jiri Pirko, Marcel Holtmann,
David S. Miller, Matthias Brugger, Janus Piwek,
Michael Röder, Dollar Chen, Ken Yu, Konstantin Böhm,
Jan Jongboom, Jon Ortego, linux-kernel@vger.kernel.org>,,
Ben Whitten
In-Reply-To: <20180810165711.59bf26f7@alans-desktop>
Alan Cox <gnomes@lxorguk.ukuu.org.uk> 於 2018年8月10日 週五 下午11:57寫道:
>
> > Except saving power, mitigating the wireless signal conflict on the
> > air is one of the reasons.
>
> If the device level is always receiving when not transmitting it has no
> effect on this. The act of listening does not harm other traffic.
My friend had tested practically:
If he changes the LoRa interface to RX mode after TX completes
immediately, he will receive the signals like reflection echo some
times.
That is interesting!
There is a paper "Exploring LoRa and LoRaWAN A suitable protocol for
IoT weather stations?" by Kristoffer Olsson & Sveinn Finnsson
http://publications.lib.chalmers.se/records/fulltext/252610/252610.pdf
In chapter 3.2 Chirp Spread Spectrum, it describes the reflection echo
phenomenon.
I think that is why LoRaWAN places the RX delay time which avoids
receiving the reflection noise.
> > The sleep/idle/stop mitigate the unconcerned RF signals or messages.
>
> At the physical level it's irrelevant. If we are receiving then we might
> hear more things we later discard. It's not running on a tiny
> microcontroller so the extra CPU cycles are not going to kill us.
According different power resource, LoRaWAN defines Class A, B and C.
Class A is the basic and both Class B and C devices must also
implement the feature of Class A.
If the end device has sufficient power available, it can also
implement the Class C: Continuously listening end-device.
Here are the descriptions in LoRaWAN spec. for Class C:
- The Class C end-device will listen with RX2 windows parameters as
often as possible.
- The end-device listens on RX2 when it is not either (a) sending or
(b) receiving on RX1, according to Class A definition.
- 1. It will open a short window on RX2 parameters between the end of
the uplink transmission and the beginning of the RX1 reception window.
(*)
2. It will switch to RX2 reception parameters as soon as the RX1
reception window is closed; the RX2 reception window will remain open
until the end-device has to send another message.
According to the LoRaWAN Regional Parameters, the DataRate (including
spreading factor and bandwidth) and frequency channel of RX1 and RX2
windows may be different.(*)
So, yes! Class C opens the RX windows almost all the time, except the TX time.
And uses different channel to avoid the reflection noise (*).
However, Class C must also implements Class A and C is more complex than A.
I think starting from the simpler one and adding more features and
complexity in the future will be a better practice.
> > > How do you plan to deal with routing if you've got multiple devices ?
> >
> > For LoRaWAN, it is a star topology.
>
> No the question was much more how you plan to deal with it in the OS. If
> for example I want to open a LORA connection to something, then there
> needs to be a proper process to figure out where the target is and how to
> get traffic to them.
>
> I guess it's best phrased as
>
> - What does a struct sockaddr_lora look like
According to LoRaWAN spec, the Data Message only has the device's
DevAddr (the device's address in 4 bytes) field related to "address".
The device just sends the uplink Data Message through the interface
and does not know the destination. Then, a LoRaWAN gateway receives
the uplink Data Message and forwards to the designated network server.
So, end device does not care about the destination. It only knows
there is a gateway will forward its message to some where.
Therefore, only the DevAddr as the source address will be meaningful
for uplink Data Message.
> - How does the kernel decide which interface it goes out of (if any), and
> if it loops back
There is the MAC Header in the Data Message which is one byte.
Bits 5 to 7 indicate which kind of type the message is.
000: Join Request
001: Join Accept
010: Unconfirmed Data Up
011: Unconfirmed Data Down
100: Confirmed Data Up
101: Confirmed Data Down
110: RFU
111: Proprietary
So, end device only accepts the types of downlink and the matched
DevAddr (the device's address) in downlink Data Message for RX.
> remembering we might only be talking to a hub, or we might even be a
> virtualized LORA interface where we are pretending to be some kind of
> sensor and feeding it back.
>
> Long term yes I think Alexander is right the inevitable fate of all
> networks is to become a link layer in order to transmit IP frames 8)
Yeah, maybe. It will be easier for life.
But I have not seen the formal standard for that yet or I missed it.
If the standard appears, we can try to implement it.
Jian-Hong Pan
^ 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