* Re: [PATCH bpf] xdp: add NULL pointer check in __xdp_return()
From: Martin KaFai Lau @ 2018-07-20 17:18 UTC (permalink / raw)
To: Taehee Yoo; +Cc: daniel, ast, bjorn.topel, brouer, netdev
In-Reply-To: <20180720160445.17475-1-ap420073@gmail.com>
On Sat, Jul 21, 2018 at 01:04:45AM +0900, Taehee Yoo wrote:
> rhashtable_lookup() can return NULL. so that NULL pointer
> check routine should be added.
>
> Fixes: 02b55e5657c3 ("xdp: add MEM_TYPE_ZERO_COPY")
> Signed-off-by: Taehee Yoo <ap420073@gmail.com>
> ---
> net/core/xdp.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/net/core/xdp.c b/net/core/xdp.c
> index 9d1f220..1c12bc7 100644
> --- a/net/core/xdp.c
> +++ b/net/core/xdp.c
> @@ -345,7 +345,8 @@ static void __xdp_return(void *data, struct xdp_mem_info *mem, bool napi_direct,
> rcu_read_lock();
> /* mem->id is valid, checked in xdp_rxq_info_reg_mem_model() */
> xa = rhashtable_lookup(mem_id_ht, &mem->id, mem_id_rht_params);
> - xa->zc_alloc->free(xa->zc_alloc, handle);
> + if (xa)
> + xa->zc_alloc->free(xa->zc_alloc, handle);
hmm...It is not clear to me the "!xa" case don't have to be handled?
> rcu_read_unlock();
> default:
> /* Not possible, checked in xdp_rxq_info_reg_mem_model() */
> --
> 2.9.3
>
^ permalink raw reply
* Re: [PATCH net-next 1/2] net: bridge: add support for raw sysfs port options
From: Nikolay Aleksandrov @ 2018-07-20 17:26 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev, roopa, anuradhak, bridge, wkok, davem
In-Reply-To: <20180720102044.16b92166@xeon-e3>
On July 20, 2018 8:20:44 PM GMT+03:00, Stephen Hemminger <stephen@networkplumber.org> wrote:
>On Fri, 20 Jul 2018 20:14:43 +0300
>Nikolay Aleksandrov <nikolay@cumulusnetworks.com> wrote:
>
>> >Casting away the const on the buf variable is going to cause
>warnings
>> >and should not be necessary.
>> >
>>
>> It doesn't when it's casted like that, the new line is changed to
>null byte so we need to drop
>> the const.
>
>Then change store function to take a char *?
Sure, will do.
^ permalink raw reply
* Re: [PATCH net-next,v2] net: rename ndo_setup_tc to ndo_setup_offload
From: Daniel Borkmann @ 2018-07-20 17:28 UTC (permalink / raw)
To: Roopa Prabhu, Pablo Neira Ayuso
Cc: netdev, Jiří Pírko, thomas.lendacky,
Florian Fainelli, Elior, Ariel, Michael Chan, Santosh Rastapur,
madalin.bucur, yisen.zhuang, salil.mehta, Jeff Kirsher, tariqt,
Saeed Mahameed, Jiri Pirko, Ido Schimmel, Ganesh GR,
Jakub Kicinski, linux-net-drivers, peppe.cavallaro,
alexandre.torgue, joabreu, grygorii.strashko, Andrew Lunn
In-Reply-To: <CAJieiUjhw4B7YdKPyf5B11KY+gDb7YFT_Hxpk7QfGx6eBqCbCA@mail.gmail.com>
On 07/20/2018 04:37 PM, Roopa Prabhu wrote:
> On Wed, Jul 18, 2018 at 5:11 PM, Pablo Neira Ayuso <pablo@netfilter.org> wrote:
>> One of the recurring complaints is that we do not have, as a driver
>> writer, a central location from which we would be fed offloading rules
>> into a NIC. This was brought up again during Netconf'18 in Boston.
>>
>> This patch just renames ndo_setup_tc to ndo_setup_offload as a very
>> early initial work to prepare for follow up patch that discuss unified
>> flow representation for the existing offload programming APIs.
>>
>> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
>> Acked-by: Jiri Pirko <jiri@mellanox.com>
>> Acked-by: Jakub Kicinski <jakub.kicinski@netronome.com>
>
> ok with a rename,...but this seems to be going from a very specific to
> a completely generic name.
> maybe ndo_setup_flow_offload or ndo_setup_rule_offload might be better ?.
This might be fine as new ndo depending on the use case this will have (?),
but fwiw the term 'flow' or 'rule' would be misleading for what tc offload
would be doing today (e.g. to name one, there's no notion of 'flow' in BPF
offload). Given today this interface is deeply baked into tc, just a rename
might not suffice but should probably move the whole handling around it such
as assembling the offload info into generic net/core/netdev.c as well if this
is the way to go.
> (or maybe i am missing some context and this is really for setting up
> every possible hardware offload ?)
^ permalink raw reply
* [PATCH net] atl1c: reserve min skb headroom
From: Florian Westphal @ 2018-07-20 17:30 UTC (permalink / raw)
To: netdev; +Cc: eric.dumazet, Florian Westphal
Got crash report with following backtrace:
BUG: unable to handle kernel paging request at ffff8801869daffe
RIP: 0010:[<ffffffff816429c4>] [<ffffffff816429c4>] ip6_finish_output2+0x394/0x4c0
RSP: 0018:ffff880186c83a98 EFLAGS: 00010283
RAX: ffff8801869db00e ...
[<ffffffff81644cdc>] ip6_finish_output+0x8c/0xf0
[<ffffffff81644d97>] ip6_output+0x57/0x100
[<ffffffff81643dc9>] ip6_forward+0x4b9/0x840
[<ffffffff81645566>] ip6_rcv_finish+0x66/0xc0
[<ffffffff81645db9>] ipv6_rcv+0x319/0x530
[<ffffffff815892ac>] netif_receive_skb+0x1c/0x70
[<ffffffffc0060bec>] atl1c_clean+0x1ec/0x310 [atl1c]
...
The bad access is in neigh_hh_output(), at skb->data - 16 (HH_DATA_MOD).
atl1c driver provided skb with no headroom, so 14 bytes (ethernet
header) got pulled, but then 16 are copied.
Reserve NET_SKB_PAD bytes headroom, like netdev_alloc_skb().
Compile tested only; I lack hardware.
Fixes: 7b7017642199 ("atl1c: Fix misuse of netdev_alloc_skb in refilling rx ring")
Signed-off-by: Florian Westphal <fw@strlen.de>
---
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
index 94270f654b3b..7087b88550db 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
@@ -1686,6 +1686,7 @@ static struct sk_buff *atl1c_alloc_skb(struct atl1c_adapter *adapter)
skb = build_skb(page_address(page) + adapter->rx_page_offset,
adapter->rx_frag_size);
if (likely(skb)) {
+ skb_reserve(skb, NET_SKB_PAD);
adapter->rx_page_offset += adapter->rx_frag_size;
if (adapter->rx_page_offset >= PAGE_SIZE)
adapter->rx_page = NULL;
--
2.16.4
^ permalink raw reply related
* Re: [RFC PATCH] ip: re-introduce fragments cache worker
From: Paolo Abeni @ 2018-07-20 17:31 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Eric Dumazet, netdev, David Miller, Florian Westphal, neilb
In-Reply-To: <CANn89iLgdmR_=SVeuf1wD79jUrgaRo8P3xXYcFLJESzGL4VVUg@mail.gmail.com>
On Fri, 2018-07-20 at 08:58 -0700, Eric Dumazet wrote:
> On Fri, Jul 20, 2018 at 7:48 AM Paolo Abeni <pabeni@redhat.com> wrote:
> >
> > Hi,
> >
> > On Mon, 2018-07-09 at 05:50 -0700, Eric Dumazet wrote:
> > > On 07/09/2018 04:39 AM, Eric Dumazet wrote:
> > >
> > > > Alternatively, you could try to patch fq_codel to drop all frags of one UDP datagram
> > > > instead of few of them.
> > >
> > > A first step would be to make sure fq_codel_hash() (using skb_get_hash(skb)) selects
> > > the same bucket for all frags of a datagram :/
> >
> > I gave the above a shot and I have some non upstream ready but somewhat
> > working code. Anyway it has some issues I'm unable to solve:
> > * it's very invasive for fq_codel, because I need to parse each packet
> > looking for the fragment id
> > * the parsing overhead can't be easily avoided for non fragments
>
> Have you tried using ip_defrag(net, skb, IP_DEFRAG_QDISC) from fq_codel ?
> (adding a new value in ip_defrag_users enum)
>
> if (skb->protocol == htons(ETH_P_IP) {
> if (ip_is_fragment(ip_hdr(skb))) {
> if ((ip_defrag(net, skb, IP_DEFRAG_QDISC))
> return 0;
> ...
Thank you for the feedback. I must admit this quite in the opposite
direction of what I have attempted so far. I'll try that.
Thanks.
Still for ipv6 it will require a litte more work inside fq_codel.
> > I tried also something hopefully along the same lines of your other
> > suggestion (drop eariler the fragment queues when above low threshold):
> > when allocating a new frag queue and the ipfrag mem is above the low
> > th, another frag queue is selected in a pseudorandom way and dropped.
>
> The problem with any strategy like that, is that forthcoming fragments
> for this frag queue
> will create another frag queue, that will never have a chance to complete.
>
> Some workloads might benefit, others might not.
Yes, of course: is an heuristic, but is cheap code-wise, and it can be
disabled setting low th >= high th, so that the kernel will behave
exactly as it does now, and the kind of workloads we could cope with
will increase without adding new knobs.
Cheers,
Paolo
^ permalink raw reply
* Re: [RFC PATCH] ip: re-introduce fragments cache worker
From: Eric Dumazet @ 2018-07-20 17:37 UTC (permalink / raw)
To: Paolo Abeni; +Cc: Eric Dumazet, netdev, David Miller, Florian Westphal, neilb
In-Reply-To: <0419d5f8f551e481603b34f162299cc9961694fc.camel@redhat.com>
On Fri, Jul 20, 2018 at 10:32 AM Paolo Abeni <pabeni@redhat.com> wrote:
> Thank you for the feedback. I must admit this quite in the opposite
> direction of what I have attempted so far. I'll try that.
> Thanks.
> Still for ipv6 it will require a litte more work inside fq_codel.
IPv6 packets would use nf_ct_frag6_gather(), I gave you hint about IPv4 only ;)
^ permalink raw reply
* [PATCH v3 bpf-next 06/14] bpf/verifier: introduce BPF_PTR_TO_MAP_VALUE
From: Roman Gushchin @ 2018-07-20 17:45 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel-team, Roman Gushchin, Alexei Starovoitov,
Daniel Borkmann
In-Reply-To: <20180720174558.5829-1-guro@fb.com>
BPF_MAP_TYPE_CGROUP_STORAGE maps are special in a way
that the access from the bpf program side is lookup-free.
That means the result is guaranteed to be a valid
pointer to the cgroup storage; no NULL-check is required.
This patch introduces BPF_PTR_TO_MAP_VALUE return type,
which is required to cause the verifier accept programs,
which are not checking the map value pointer for being NULL.
Signed-off-by: Roman Gushchin <guro@fb.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Martin KaFai Lau <kafai@fb.com>
---
include/linux/bpf.h | 1 +
kernel/bpf/verifier.c | 8 ++++++--
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 16be67888c30..ca4ac2a39def 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -155,6 +155,7 @@ enum bpf_arg_type {
enum bpf_return_type {
RET_INTEGER, /* function returns integer */
RET_VOID, /* function doesn't return anything */
+ RET_PTR_TO_MAP_VALUE, /* returns a pointer to map elem value */
RET_PTR_TO_MAP_VALUE_OR_NULL, /* returns a pointer to map elem value or NULL */
};
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 0b089ba4595d..8098e39f825e 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -2545,8 +2545,12 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn
mark_reg_unknown(env, regs, BPF_REG_0);
} else if (fn->ret_type == RET_VOID) {
regs[BPF_REG_0].type = NOT_INIT;
- } else if (fn->ret_type == RET_PTR_TO_MAP_VALUE_OR_NULL) {
- regs[BPF_REG_0].type = PTR_TO_MAP_VALUE_OR_NULL;
+ } else if (fn->ret_type == RET_PTR_TO_MAP_VALUE_OR_NULL ||
+ fn->ret_type == RET_PTR_TO_MAP_VALUE) {
+ if (fn->ret_type == RET_PTR_TO_MAP_VALUE)
+ regs[BPF_REG_0].type = PTR_TO_MAP_VALUE;
+ else
+ regs[BPF_REG_0].type = PTR_TO_MAP_VALUE_OR_NULL;
/* There is no offset yet applied, variable or fixed */
mark_reg_known_zero(env, regs, BPF_REG_0);
regs[BPF_REG_0].off = 0;
--
2.14.4
^ permalink raw reply related
* [PATCH v3 bpf-next 05/14] bpf: extend bpf_prog_array to store pointers to the cgroup storage
From: Roman Gushchin @ 2018-07-20 17:45 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel-team, Roman Gushchin, Alexei Starovoitov,
Daniel Borkmann
In-Reply-To: <20180720174558.5829-1-guro@fb.com>
This patch converts bpf_prog_array from an array of prog pointers
to the array of struct bpf_prog_array_item elements.
This allows to save a cgroup storage pointer for each bpf program
efficiently attached to a cgroup.
Signed-off-by: Roman Gushchin <guro@fb.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Martin KaFai Lau <kafai@fb.com>
---
drivers/media/rc/bpf-lirc.c | 10 +++---
include/linux/bpf.h | 19 ++++++++----
kernel/bpf/cgroup.c | 21 +++++++------
kernel/bpf/core.c | 76 +++++++++++++++++++++++----------------------
4 files changed, 70 insertions(+), 56 deletions(-)
diff --git a/drivers/media/rc/bpf-lirc.c b/drivers/media/rc/bpf-lirc.c
index fcfab6635f9c..8c26df9b96c1 100644
--- a/drivers/media/rc/bpf-lirc.c
+++ b/drivers/media/rc/bpf-lirc.c
@@ -195,14 +195,16 @@ void lirc_bpf_run(struct rc_dev *rcdev, u32 sample)
*/
void lirc_bpf_free(struct rc_dev *rcdev)
{
- struct bpf_prog **progs;
+ struct bpf_prog_array_item *item;
if (!rcdev->raw->progs)
return;
- progs = rcu_dereference(rcdev->raw->progs)->progs;
- while (*progs)
- bpf_prog_put(*progs++);
+ item = rcu_dereference(rcdev->raw->progs)->items;
+ while (item->prog) {
+ bpf_prog_put(item->prog);
+ item++;
+ }
bpf_prog_array_free(rcdev->raw->progs);
}
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 9d1e4727495e..16be67888c30 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -349,9 +349,14 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
* The 'struct bpf_prog_array *' should only be replaced with xchg()
* since other cpus are walking the array of pointers in parallel.
*/
+struct bpf_prog_array_item {
+ struct bpf_prog *prog;
+ struct bpf_cgroup_storage *cgroup_storage;
+};
+
struct bpf_prog_array {
struct rcu_head rcu;
- struct bpf_prog *progs[0];
+ struct bpf_prog_array_item items[0];
};
struct bpf_prog_array *bpf_prog_array_alloc(u32 prog_cnt, gfp_t flags);
@@ -372,7 +377,8 @@ int bpf_prog_array_copy(struct bpf_prog_array __rcu *old_array,
#define __BPF_PROG_RUN_ARRAY(array, ctx, func, check_non_null) \
({ \
- struct bpf_prog **_prog, *__prog; \
+ struct bpf_prog_array_item *_item; \
+ struct bpf_prog *_prog; \
struct bpf_prog_array *_array; \
u32 _ret = 1; \
preempt_disable(); \
@@ -380,10 +386,11 @@ int bpf_prog_array_copy(struct bpf_prog_array __rcu *old_array,
_array = rcu_dereference(array); \
if (unlikely(check_non_null && !_array))\
goto _out; \
- _prog = _array->progs; \
- while ((__prog = READ_ONCE(*_prog))) { \
- _ret &= func(__prog, ctx); \
- _prog++; \
+ _item = &_array->items[0]; \
+ while ((_prog = READ_ONCE(_item->prog))) { \
+ bpf_cgroup_storage_set(_item->cgroup_storage); \
+ _ret &= func(_prog, ctx); \
+ _item++; \
} \
_out: \
rcu_read_unlock(); \
diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
index 986ff18ef92e..ac480086effd 100644
--- a/kernel/bpf/cgroup.c
+++ b/kernel/bpf/cgroup.c
@@ -117,15 +117,18 @@ static int compute_effective_progs(struct cgroup *cgrp,
cnt = 0;
p = cgrp;
do {
- if (cnt == 0 || (p->bpf.flags[type] & BPF_F_ALLOW_MULTI))
- list_for_each_entry(pl,
- &p->bpf.progs[type], node) {
- if (!pl->prog)
- continue;
- progs->progs[cnt++] = pl->prog;
- }
- p = cgroup_parent(p);
- } while (p);
+ if (cnt > 0 && !(p->bpf.flags[type] & BPF_F_ALLOW_MULTI))
+ continue;
+
+ list_for_each_entry(pl, &p->bpf.progs[type], node) {
+ if (!pl->prog)
+ continue;
+
+ progs->items[cnt].prog = pl->prog;
+ progs->items[cnt].cgroup_storage = pl->storage;
+ cnt++;
+ }
+ } while ((p = cgroup_parent(p)));
rcu_assign_pointer(*array, progs);
return 0;
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index 253aa8e79c7b..9abcf25ebf9f 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -1542,7 +1542,8 @@ struct bpf_prog_array *bpf_prog_array_alloc(u32 prog_cnt, gfp_t flags)
{
if (prog_cnt)
return kzalloc(sizeof(struct bpf_prog_array) +
- sizeof(struct bpf_prog *) * (prog_cnt + 1),
+ sizeof(struct bpf_prog_array_item) *
+ (prog_cnt + 1),
flags);
return &empty_prog_array.hdr;
@@ -1556,43 +1557,45 @@ void bpf_prog_array_free(struct bpf_prog_array __rcu *progs)
kfree_rcu(progs, rcu);
}
-int bpf_prog_array_length(struct bpf_prog_array __rcu *progs)
+int bpf_prog_array_length(struct bpf_prog_array __rcu *array)
{
- struct bpf_prog **prog;
+ struct bpf_prog_array_item *item;
u32 cnt = 0;
rcu_read_lock();
- prog = rcu_dereference(progs)->progs;
- for (; *prog; prog++)
- if (*prog != &dummy_bpf_prog.prog)
+ item = rcu_dereference(array)->items;
+ for (; item->prog; item++)
+ if (item->prog != &dummy_bpf_prog.prog)
cnt++;
rcu_read_unlock();
return cnt;
}
-static bool bpf_prog_array_copy_core(struct bpf_prog **prog,
+
+static bool bpf_prog_array_copy_core(struct bpf_prog_array __rcu *array,
u32 *prog_ids,
u32 request_cnt)
{
+ struct bpf_prog_array_item *item;
int i = 0;
- for (; *prog; prog++) {
- if (*prog == &dummy_bpf_prog.prog)
+ item = rcu_dereference(array)->items;
+ for (; item->prog; item++) {
+ if (item->prog == &dummy_bpf_prog.prog)
continue;
- prog_ids[i] = (*prog)->aux->id;
+ prog_ids[i] = item->prog->aux->id;
if (++i == request_cnt) {
- prog++;
+ item++;
break;
}
}
- return !!(*prog);
+ return !!(item->prog);
}
-int bpf_prog_array_copy_to_user(struct bpf_prog_array __rcu *progs,
+int bpf_prog_array_copy_to_user(struct bpf_prog_array __rcu *array,
__u32 __user *prog_ids, u32 cnt)
{
- struct bpf_prog **prog;
unsigned long err = 0;
bool nospc;
u32 *ids;
@@ -1611,8 +1614,7 @@ int bpf_prog_array_copy_to_user(struct bpf_prog_array __rcu *progs,
if (!ids)
return -ENOMEM;
rcu_read_lock();
- prog = rcu_dereference(progs)->progs;
- nospc = bpf_prog_array_copy_core(prog, ids, cnt);
+ nospc = bpf_prog_array_copy_core(array, ids, cnt);
rcu_read_unlock();
err = copy_to_user(prog_ids, ids, cnt * sizeof(u32));
kfree(ids);
@@ -1623,14 +1625,14 @@ int bpf_prog_array_copy_to_user(struct bpf_prog_array __rcu *progs,
return 0;
}
-void bpf_prog_array_delete_safe(struct bpf_prog_array __rcu *progs,
+void bpf_prog_array_delete_safe(struct bpf_prog_array __rcu *array,
struct bpf_prog *old_prog)
{
- struct bpf_prog **prog = progs->progs;
+ struct bpf_prog_array_item *item = array->items;
- for (; *prog; prog++)
- if (*prog == old_prog) {
- WRITE_ONCE(*prog, &dummy_bpf_prog.prog);
+ for (; item->prog; item++)
+ if (item->prog == old_prog) {
+ WRITE_ONCE(item->prog, &dummy_bpf_prog.prog);
break;
}
}
@@ -1641,7 +1643,7 @@ int bpf_prog_array_copy(struct bpf_prog_array __rcu *old_array,
struct bpf_prog_array **new_array)
{
int new_prog_cnt, carry_prog_cnt = 0;
- struct bpf_prog **existing_prog;
+ struct bpf_prog_array_item *existing;
struct bpf_prog_array *array;
bool found_exclude = false;
int new_prog_idx = 0;
@@ -1650,15 +1652,15 @@ int bpf_prog_array_copy(struct bpf_prog_array __rcu *old_array,
* the new array.
*/
if (old_array) {
- existing_prog = old_array->progs;
- for (; *existing_prog; existing_prog++) {
- if (*existing_prog == exclude_prog) {
+ existing = old_array->items;
+ for (; existing->prog; existing++) {
+ if (existing->prog == exclude_prog) {
found_exclude = true;
continue;
}
- if (*existing_prog != &dummy_bpf_prog.prog)
+ if (existing->prog != &dummy_bpf_prog.prog)
carry_prog_cnt++;
- if (*existing_prog == include_prog)
+ if (existing->prog == include_prog)
return -EEXIST;
}
}
@@ -1684,15 +1686,17 @@ int bpf_prog_array_copy(struct bpf_prog_array __rcu *old_array,
/* Fill in the new prog array */
if (carry_prog_cnt) {
- existing_prog = old_array->progs;
- for (; *existing_prog; existing_prog++)
- if (*existing_prog != exclude_prog &&
- *existing_prog != &dummy_bpf_prog.prog)
- array->progs[new_prog_idx++] = *existing_prog;
+ existing = old_array->items;
+ for (; existing->prog; existing++)
+ if (existing->prog != exclude_prog &&
+ existing->prog != &dummy_bpf_prog.prog) {
+ array->items[new_prog_idx++].prog =
+ existing->prog;
+ }
}
if (include_prog)
- array->progs[new_prog_idx++] = include_prog;
- array->progs[new_prog_idx] = NULL;
+ array->items[new_prog_idx++].prog = include_prog;
+ array->items[new_prog_idx].prog = NULL;
*new_array = array;
return 0;
}
@@ -1701,7 +1705,6 @@ int bpf_prog_array_copy_info(struct bpf_prog_array __rcu *array,
u32 *prog_ids, u32 request_cnt,
u32 *prog_cnt)
{
- struct bpf_prog **prog;
u32 cnt = 0;
if (array)
@@ -1714,8 +1717,7 @@ int bpf_prog_array_copy_info(struct bpf_prog_array __rcu *array,
return 0;
/* this function is called under trace/bpf_trace.c: bpf_event_mutex */
- prog = rcu_dereference_check(array, 1)->progs;
- return bpf_prog_array_copy_core(prog, prog_ids, request_cnt) ? -ENOSPC
+ return bpf_prog_array_copy_core(array, prog_ids, request_cnt) ? -ENOSPC
: 0;
}
--
2.14.4
^ permalink raw reply related
* [PATCH v3 bpf-next 13/14] selftests/bpf: add a cgroup storage test
From: Roman Gushchin @ 2018-07-20 17:45 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel-team, Roman Gushchin, Alexei Starovoitov,
Daniel Borkmann
In-Reply-To: <20180720174558.5829-1-guro@fb.com>
Implement a test to cover the cgroup storage functionality.
The test implements a bpf program which drops every second packet
by using the cgroup storage as a persistent storage.
The test also use the userspace API to check the data
in the cgroup storage, alter it, and check that the loaded
and attached bpf program sees the update.
Expected output:
$ ./test_cgroup_storage
test_cgroup_storage:PASS
Signed-off-by: Roman Gushchin <guro@fb.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Martin KaFai Lau <kafai@fb.com>
---
tools/testing/selftests/bpf/Makefile | 4 +-
tools/testing/selftests/bpf/test_cgroup_storage.c | 130 ++++++++++++++++++++++
2 files changed, 133 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/bpf/test_cgroup_storage.c
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index 478bf1bcbbf5..8f466af33e09 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -22,7 +22,8 @@ $(TEST_CUSTOM_PROGS): $(OUTPUT)/%: %.c
# Order correspond to 'make run_tests' order
TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test_progs \
test_align test_verifier_log test_dev_cgroup test_tcpbpf_user \
- test_sock test_btf test_sockmap test_lirc_mode2_user get_cgroup_id_user
+ test_sock test_btf test_sockmap test_lirc_mode2_user get_cgroup_id_user \
+ test_cgroup_storage
TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o test_tcp_estats.o test_obj_id.o \
test_pkt_md_access.o test_xdp_redirect.o test_xdp_meta.o sockmap_parse_prog.o \
@@ -64,6 +65,7 @@ $(OUTPUT)/test_sockmap: cgroup_helpers.c
$(OUTPUT)/test_tcpbpf_user: cgroup_helpers.c
$(OUTPUT)/test_progs: trace_helpers.c
$(OUTPUT)/get_cgroup_id_user: cgroup_helpers.c
+$(OUTPUT)/test_cgroup_storage: cgroup_helpers.c
.PHONY: force
diff --git a/tools/testing/selftests/bpf/test_cgroup_storage.c b/tools/testing/selftests/bpf/test_cgroup_storage.c
new file mode 100644
index 000000000000..0597943ce34b
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_cgroup_storage.c
@@ -0,0 +1,130 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <assert.h>
+#include <bpf/bpf.h>
+#include <linux/filter.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "cgroup_helpers.h"
+
+char bpf_log_buf[BPF_LOG_BUF_SIZE];
+
+#define TEST_CGROUP "/test-bpf-cgroup-storage-buf/"
+
+int main(int argc, char **argv)
+{
+ struct bpf_insn prog[] = {
+ BPF_LD_MAP_FD(BPF_REG_1, 0), /* map fd */
+ BPF_MOV64_IMM(BPF_REG_2, 0), /* flags, not used */
+ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+ BPF_FUNC_get_local_storage),
+ BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
+ BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
+ BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0x1),
+ BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
+ BPF_EXIT_INSN(),
+ };
+ size_t insns_cnt = sizeof(prog) / sizeof(struct bpf_insn);
+ int error = EXIT_FAILURE;
+ int map_fd, prog_fd, cgroup_fd;
+ struct bpf_cgroup_storage_key key;
+ unsigned long long value;
+
+ map_fd = bpf_create_map(BPF_MAP_TYPE_CGROUP_STORAGE, sizeof(key),
+ sizeof(value), 0, 0);
+ if (map_fd < 0) {
+ printf("Failed to create map: %s\n", strerror(errno));
+ goto out;
+ }
+
+ prog[0].imm = map_fd;
+ prog_fd = bpf_load_program(BPF_PROG_TYPE_CGROUP_SKB,
+ prog, insns_cnt, "GPL", 0,
+ bpf_log_buf, BPF_LOG_BUF_SIZE);
+ if (prog_fd < 0) {
+ printf("Failed to load bpf program: %s\n", bpf_log_buf);
+ goto out;
+ }
+
+ if (setup_cgroup_environment()) {
+ printf("Failed to setup cgroup environment\n");
+ goto err;
+ }
+
+ /* Create a cgroup, get fd, and join it */
+ cgroup_fd = create_and_get_cgroup(TEST_CGROUP);
+ if (!cgroup_fd) {
+ printf("Failed to create test cgroup\n");
+ goto err;
+ }
+
+ if (join_cgroup(TEST_CGROUP)) {
+ printf("Failed to join cgroup\n");
+ goto err;
+ }
+
+ /* Attach the bpf program */
+ if (bpf_prog_attach(prog_fd, cgroup_fd, BPF_CGROUP_INET_EGRESS, 0)) {
+ printf("Failed to attach bpf program\n");
+ goto err;
+ }
+
+ if (bpf_map_get_next_key(map_fd, NULL, &key)) {
+ printf("Failed to get the first key in cgroup storage\n");
+ goto err;
+ }
+
+ if (bpf_map_lookup_elem(map_fd, &key, &value)) {
+ printf("Failed to lookup cgroup storage\n");
+ goto err;
+ }
+
+ /* Every second packet should be dropped */
+ assert(system("ping localhost -c 1 -W 1 -q > /dev/null") == 0);
+ assert(system("ping localhost -c 1 -W 1 -q > /dev/null"));
+ assert(system("ping localhost -c 1 -W 1 -q > /dev/null") == 0);
+
+ /* Check the counter in the cgroup local storage */
+ if (bpf_map_lookup_elem(map_fd, &key, &value)) {
+ printf("Failed to lookup cgroup storage\n");
+ goto err;
+ }
+
+ if (value != 3) {
+ printf("Unexpected data in the cgroup storage: %llu\n", value);
+ goto err;
+ }
+
+ /* Bump the counter in the cgroup local storage */
+ value++;
+ if (bpf_map_update_elem(map_fd, &key, &value, 0)) {
+ printf("Failed to update the data in the cgroup storage\n");
+ goto err;
+ }
+
+ /* Every second packet should be dropped */
+ assert(system("ping localhost -c 1 -W 1 -q > /dev/null") == 0);
+ assert(system("ping localhost -c 1 -W 1 -q > /dev/null"));
+ assert(system("ping localhost -c 1 -W 1 -q > /dev/null") == 0);
+
+ /* Check the final value of the counter in the cgroup local storage */
+ if (bpf_map_lookup_elem(map_fd, &key, &value)) {
+ printf("Failed to lookup the cgroup storage\n");
+ goto err;
+ }
+
+ if (value != 7) {
+ printf("Unexpected data in the cgroup storage: %llu\n", value);
+ goto err;
+ }
+
+ error = 0;
+ printf("test_cgroup_storage:PASS\n");
+
+err:
+ cleanup_cgroup_environment();
+
+out:
+ return error;
+}
--
2.14.4
^ permalink raw reply related
* Re: [PATCH net] atl1c: reserve min skb headroom
From: Eric Dumazet @ 2018-07-20 17:48 UTC (permalink / raw)
To: Florian Westphal, netdev; +Cc: eric.dumazet
In-Reply-To: <20180720173057.11365-1-fw@strlen.de>
On 07/20/2018 10:30 AM, Florian Westphal wrote:
> Got crash report with following backtrace:
> BUG: unable to handle kernel paging request at ffff8801869daffe
> RIP: 0010:[<ffffffff816429c4>] [<ffffffff816429c4>] ip6_finish_output2+0x394/0x4c0
> RSP: 0018:ffff880186c83a98 EFLAGS: 00010283
> RAX: ffff8801869db00e ...
> [<ffffffff81644cdc>] ip6_finish_output+0x8c/0xf0
> [<ffffffff81644d97>] ip6_output+0x57/0x100
> [<ffffffff81643dc9>] ip6_forward+0x4b9/0x840
> [<ffffffff81645566>] ip6_rcv_finish+0x66/0xc0
> [<ffffffff81645db9>] ipv6_rcv+0x319/0x530
> [<ffffffff815892ac>] netif_receive_skb+0x1c/0x70
> [<ffffffffc0060bec>] atl1c_clean+0x1ec/0x310 [atl1c]
> ...
>
> The bad access is in neigh_hh_output(), at skb->data - 16 (HH_DATA_MOD).
> atl1c driver provided skb with no headroom, so 14 bytes (ethernet
> header) got pulled, but then 16 are copied.
>
> Reserve NET_SKB_PAD bytes headroom, like netdev_alloc_skb().
>
> Compile tested only; I lack hardware.
>
> Fixes: 7b7017642199 ("atl1c: Fix misuse of netdev_alloc_skb in refilling rx ring")
> Signed-off-by: Florian Westphal <fw@strlen.de>
> ---
> diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
> index 94270f654b3b..7087b88550db 100644
> --- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
> +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
> @@ -1686,6 +1686,7 @@ static struct sk_buff *atl1c_alloc_skb(struct atl1c_adapter *adapter)
> skb = build_skb(page_address(page) + adapter->rx_page_offset,
> adapter->rx_frag_size);
> if (likely(skb)) {
> + skb_reserve(skb, NET_SKB_PAD);
> adapter->rx_page_offset += adapter->rx_frag_size;
> if (adapter->rx_page_offset >= PAGE_SIZE)
> adapter->rx_page = NULL;
>
Yes, it is interesting IPv4 has code to deal with that( in ip_finish_output2()),
not IPv6 :/
Reviewed-by: Eric Dumazet <edumazet@google.com>
^ permalink raw reply
* [PATCH v3 bpf-next 03/14] bpf: pass a pointer to a cgroup storage using pcpu variable
From: Roman Gushchin @ 2018-07-20 17:45 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel-team, Roman Gushchin, Alexei Starovoitov,
Daniel Borkmann
In-Reply-To: <20180720174558.5829-1-guro@fb.com>
This commit introduces the bpf_cgroup_storage_set() helper,
which will be used to pass a pointer to a cgroup storage
to the bpf helper.
Signed-off-by: Roman Gushchin <guro@fb.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Martin KaFai Lau <kafai@fb.com>
---
include/linux/bpf-cgroup.h | 15 +++++++++++++++
kernel/bpf/local_storage.c | 2 ++
2 files changed, 17 insertions(+)
diff --git a/include/linux/bpf-cgroup.h b/include/linux/bpf-cgroup.h
index 6b0e7bd4b154..1b1b4e94d77d 100644
--- a/include/linux/bpf-cgroup.h
+++ b/include/linux/bpf-cgroup.h
@@ -3,6 +3,7 @@
#define _BPF_CGROUP_H
#include <linux/jump_label.h>
+#include <linux/percpu.h>
#include <linux/rbtree.h>
#include <uapi/linux/bpf.h>
@@ -20,6 +21,8 @@ struct bpf_cgroup_storage;
extern struct static_key_false cgroup_bpf_enabled_key;
#define cgroup_bpf_enabled static_branch_unlikely(&cgroup_bpf_enabled_key)
+DECLARE_PER_CPU(void*, bpf_cgroup_storage);
+
struct bpf_cgroup_storage_map;
struct bpf_storage_buffer {
@@ -96,6 +99,17 @@ int __cgroup_bpf_run_filter_sock_ops(struct sock *sk,
int __cgroup_bpf_check_dev_permission(short dev_type, u32 major, u32 minor,
short access, enum bpf_attach_type type);
+static inline void bpf_cgroup_storage_set(struct bpf_cgroup_storage *storage)
+{
+ struct bpf_storage_buffer *buf;
+
+ if (!storage)
+ return;
+
+ buf = READ_ONCE(storage->buf);
+ this_cpu_write(bpf_cgroup_storage, &buf->data[0]);
+}
+
struct bpf_cgroup_storage *bpf_cgroup_storage_alloc(struct bpf_prog *prog);
void bpf_cgroup_storage_free(struct bpf_cgroup_storage *storage);
void bpf_cgroup_storage_link(struct bpf_cgroup_storage *storage,
@@ -249,6 +263,7 @@ static inline int cgroup_bpf_prog_query(const union bpf_attr *attr,
return -EINVAL;
}
+static inline void bpf_cgroup_storage_set(struct bpf_cgroup_storage *storage) {}
static inline int bpf_cgroup_storage_assign(struct bpf_prog *prog,
struct bpf_map *map) { return 0; }
static inline void bpf_cgroup_storage_release(struct bpf_prog *prog,
diff --git a/kernel/bpf/local_storage.c b/kernel/bpf/local_storage.c
index 940889eda2c7..38810a712971 100644
--- a/kernel/bpf/local_storage.c
+++ b/kernel/bpf/local_storage.c
@@ -7,6 +7,8 @@
#include <linux/rbtree.h>
#include <linux/slab.h>
+DEFINE_PER_CPU(void*, bpf_cgroup_storage);
+
#ifdef CONFIG_CGROUP_BPF
struct bpf_cgroup_storage_map {
--
2.14.4
^ permalink raw reply related
* WARNING: ODEBUG bug in __queue_work (2)
From: syzbot @ 2018-07-20 18:44 UTC (permalink / raw)
To: davem, ericvh, linux-kernel, lucho, netdev, rminnich,
syzkaller-bugs, v9fs-developer
Hello,
syzbot found the following crash on:
HEAD commit: 28c20cc73b9c Merge tag 'drm-fixes-2018-07-20' of git://ano..
git tree: upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=160da9a4400000
kernel config: https://syzkaller.appspot.com/x/.config?x=c0bdc4175608181c
dashboard link: https://syzkaller.appspot.com/bug?extid=562fd7e5ae89576bbe7c
compiler: gcc (GCC) 8.0.1 20180413 (experimental)
Unfortunately, I don't have any reproducer for this crash yet.
IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+562fd7e5ae89576bbe7c@syzkaller.appspotmail.com
------------[ cut here ]------------
ODEBUG: activate not available (active state 0) object type: work_struct
hint: p9_read_work+0x0/0x1060 net/9p/trans_fd.c:208
WARNING: CPU: 1 PID: 5207 at lib/debugobjects.c:329
debug_print_object+0x16a/0x210 lib/debugobjects.c:326
Kernel panic - not syncing: panic_on_warn set ...
CPU: 1 PID: 5207 Comm: kworker/1:3 Not tainted 4.18.0-rc5+ #156
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
Google 01/01/2011
Workqueue: events p9_poll_workfn
Call Trace:
__dump_stack lib/dump_stack.c:77 [inline]
dump_stack+0x1c9/0x2b4 lib/dump_stack.c:113
panic+0x238/0x4e7 kernel/panic.c:184
__warn.cold.8+0x163/0x1ba kernel/panic.c:536
report_bug+0x252/0x2d0 lib/bug.c:186
fixup_bug arch/x86/kernel/traps.c:178 [inline]
do_error_trap+0x1fc/0x4d0 arch/x86/kernel/traps.c:296
do_invalid_op+0x1b/0x20 arch/x86/kernel/traps.c:316
invalid_op+0x14/0x20 arch/x86/entry/entry_64.S:992
RIP: 0010:debug_print_object+0x16a/0x210 lib/debugobjects.c:326
Code: 1a 88 48 89 fa 48 c1 ea 03 80 3c 02 00 0f 85 92 00 00 00 48 8b 14 dd
e0 72 1a 88 4c 89 f6 48 c7 c7 80 68 1a 88 e8 96 a5 e6 fd <0f> 0b 83 05 09
74 3e 06 01 48 83 c4 18 5b 41 5c 41 5d 41 5e 41 5f
RSP: 0018:ffff880194a9f1d0 EFLAGS: 00010082
RAX: 0000000000000000 RBX: 0000000000000005 RCX: 0000000000000000
RDX: 0000000000000000 RSI: ffffffff81631861 RDI: 0000000000000001
RBP: ffff880194a9f210 R08: ffff8801bfbe4280 R09: ffffed003b5e3ec2
R10: ffffed003b5e3ec2 R11: ffff8801daf1f617 R12: 0000000000000001
R13: ffffffff88f63860 R14: ffffffff881a6f00 R15: ffffffff814eaa00
debug_object_activate+0x359/0x690 lib/debugobjects.c:513
debug_work_activate kernel/workqueue.c:491 [inline]
__queue_work+0x1ca/0x1410 kernel/workqueue.c:1380
queue_work_on+0x19a/0x1e0 kernel/workqueue.c:1486
queue_work include/linux/workqueue.h:512 [inline]
schedule_work include/linux/workqueue.h:570 [inline]
p9_poll_mux net/9p/trans_fd.c:628 [inline]
p9_poll_workfn+0x55e/0x6d0 net/9p/trans_fd.c:1107
process_one_work+0xc73/0x1ba0 kernel/workqueue.c:2153
worker_thread+0x189/0x13c0 kernel/workqueue.c:2296
kthread+0x345/0x410 kernel/kthread.c:246
ret_from_fork+0x3a/0x50 arch/x86/entry/entry_64.S:412
Dumping ftrace buffer:
(ftrace buffer empty)
Kernel Offset: disabled
Rebooting in 86400 seconds..
---
This bug is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.
syzbot will keep track of this bug report. See:
https://goo.gl/tpsmEJ#bug-status-tracking for how to communicate with
syzbot.
^ permalink raw reply
* [PATCH net-next] tls: Skip zerocopy path for ITER_KVEC
From: Doron Roberts-Kedes @ 2018-07-20 18:19 UTC (permalink / raw)
To: David S . Miller; +Cc: Dave Watson, netdev, Doron Roberts-Kedes
The zerocopy path ultimately calls iov_iter_get_pages, which defines the
step function for ITER_KVECs as simply, return -EFAULT. Taking the
non-zerocopy path for ITER_KVECs avoids the unnecessary fallback.
See https://lore.kernel.org/lkml/20150401023311.GL29656@ZenIV.linux.org.uk/T/#u
for a discussion of why zerocopy for vmalloc data is not a good idea.
Discovered while testing NBD traffic encrypted with ktls.
Fixes: c46234ebb4d1 ("tls: RX path for ktls")
Signed-off-by: Doron Roberts-Kedes <doronrk@fb.com>
---
net/tls/tls_sw.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
index 4618f1c31137..ef15e35232dd 100644
--- a/net/tls/tls_sw.c
+++ b/net/tls/tls_sw.c
@@ -426,7 +426,8 @@ int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
full_record = true;
}
- if (full_record || eor) {
+ bool iskvec = msg->msg_iter.type & ITER_KVEC;
+ if (!iskvec && (full_record || eor)) {
ret = zerocopy_from_iter(sk, &msg->msg_iter,
try_to_copy, &ctx->sg_plaintext_num_elem,
&ctx->sg_plaintext_size,
@@ -804,7 +805,8 @@ int tls_sw_recvmsg(struct sock *sk,
page_count = iov_iter_npages(&msg->msg_iter,
MAX_SKB_FRAGS);
to_copy = rxm->full_len - tls_ctx->rx.overhead_size;
- if (to_copy <= len && page_count < MAX_SKB_FRAGS &&
+ bool iskvec = msg->msg_iter.type & ITER_KVEC;
+ if (!iskvec && to_copy <= len && page_count < MAX_SKB_FRAGS &&
likely(!(flags & MSG_PEEK))) {
struct scatterlist sgin[MAX_SKB_FRAGS + 1];
int pages = 0;
--
2.17.1
^ permalink raw reply related
* Re: [PATCH] tls: Fix copy-paste error in tls_device_reencrypt
From: David Miller @ 2018-07-20 19:13 UTC (permalink / raw)
To: gustavo; +Cc: borisp, aviadye, davejwatson, netdev, linux-kernel
In-Reply-To: <20180718132741.GA9480@embeddedor.com>
From: "Gustavo A. R. Silva" <gustavo@embeddedor.com>
Date: Wed, 18 Jul 2018 08:27:41 -0500
> It seems that the proper structure to use in this particular
> case is *skb_iter* instead of skb.
>
> Addresses-Coverity-ID: 1471906 ("Copy-paste error")
> Fixes: 4799ac81e52a ("tls: Add rx inline crypto offload")
> Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
Applied, thank you.
^ permalink raw reply
* Re: [**EXTERNAL**] Re: VRF with enslaved L3 enabled bridge
From: D'Souza, Nelson @ 2018-07-20 19:03 UTC (permalink / raw)
To: David Ahern, netdev@vger.kernel.org
In-Reply-To: <03a5d61d-32eb-e329-a12c-59e3594e1b51@cumulusnetworks.com>
Hi Dave,
It is good to know that this works in your case. However, I'm not able to pinpoint what the issue is and looking for a way to narrow down to the root cause.
Do you know if this has been an issue in the past and resolved in Linux kernel versions after 4.14.52?
I have the same setup as you and tcpdump works at all levels (eth, bridge, vrf).
Setup is as follows:
ethUSB(ingress port) -> mgmtbr0 (bridge) -> mgmtvrf (vrf)
Logs from my setup:
b) ethUSB is enslaved to mgmtbr0 (bridge)
root@x10sdv-4c-tln4f:~# ip link show master mgmtbr0
6: ethUSB: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master mgmtbr0 state UNKNOWN mode DEFAULT group default qlen 1000
link/ether c0:56:27:90:4f:75 brd ff:ff:ff:ff:ff:ff
b) mgmtbr0 bridge is enslaved to mgmtvrf (vrf)
root@x10sdv-4c-tln4f:~# ip link show master mgmtvrf
16: mgmtbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master mgmtvrf state UP mode DEFAULT group default qlen 1000
link/ether c0:56:27:90:4f:75 brd ff:ff:ff:ff:ff:ff
c) ip address configured on mgmtbr0
root@x10sdv-4c-tln4f:~# ip addr show dev mgmtbr0
16: mgmtbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master mgmtvrf state UP group default qlen 1000
link/ether c0:56:27:90:4f:75 brd ff:ff:ff:ff:ff:ff
inet 10.33.96.131/24 brd 10.33.96.255 scope global mgmtbr0
valid_lft forever preferred_lft forever
inet6 fe80::c256:27ff:fe90:4f75/64 scope link
valid_lft forever preferred_lft forever
d) tcpdump on ethUSB successful, but ping fails
root@x10sdv-4c-tln4f:~# ping 10.32.8.135 -I mgmtvrf -c1 -w1
PING 10.32.8.135 (10.32.8.135): 56 data bytes
--- 10.32.8.135 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss
root@x10sdv-4c-tln4f:~# tcpdump -i ethUSB icmp
11:38:37.169678 IP 10.33.96.131 > 10.32.8.135: ICMP echo request, id 62312, seq 0, length 64
11:38:37.170906 IP 10.32.8.135 > 10.33.96.131: ICMP echo reply, id 62312, seq 0, length 64
e) tcpdump on mgmtbr0 successful, but ping fails
root@x10sdv-4c-tln4f:~# ping 10.32.8.135 -I mgmtvrf -c1 -w1
PING 10.32.8.135 (10.32.8.135): 56 data bytes
--- 10.32.8.135 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss
root@x10sdv-4c-tln4f:~# tcpdump -i mgmtbr0 icmp
11:46:21.566739 IP 10.33.96.131 > 10.32.8.135: ICMP echo request, id 617, seq 0, length 64
11:46:21.567982 IP 10.32.8.135 > 10.33.96.131: ICMP echo reply, id 617, seq 0, length 64
f) tcpdump on mgmtvrf successful, but ping fails
root@x10sdv-4c-tln4f:~# ping 10.32.8.135 -I mgmtvrf -c1 -w1
PING 10.32.8.135 (10.32.8.135): 56 data bytes
--- 10.32.8.135 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss
root@x10sdv-4c-tln4f:~# tcpdump -i mgmtvrf icmp
11:50:24.155706 IP 10.33.96.131 > 10.32.8.135: ICMP echo request, id 2153, seq 0, length 64
11:50:24.156977 IP 10.32.8.135 > 10.33.96.131: ICMP echo reply, id 2153, seq 0, length 64
f) Netfilter prerouting rules added to the raw table, only sees packets ingressing on mgmtbr0, not mgmtvrf.
root@x10sdv-4c-tln4f:~# iptables -t raw -nvL PREROUTING
Chain PREROUTING (policy ACCEPT 3 packets, 252 bytes)
pkts bytes target prot opt in out source destination
3 252 LOG all -- mgmtbr0 * 10.32.8.135 0.0.0.0/0 LOG flags 0 level 4
0 0 LOG all -- mgmtvrf * 10.32.8.135 0.0.0.0/0 LOG flags 0 level 4
It's strange that while the tcpdump works at the mgmtvrf level, netfilter prerouting rules do not match on the mgmtvrf level.
Appreciate the help, please let me know if you need additional logs.
Thanks,
Nelson
On 7/19/18, 8:37 PM, "David Ahern" <dsa@cumulusnetworks.com> wrote:
On 7/19/18 8:19 PM, D'Souza, Nelson wrote:
> Hi,
>
>
>
> I'm seeing the following issue on a system running a 4.14.52 Linux kernel.
>
>
>
> With an eth interface enslaved to a VRF device, pings sent out on the
> VRF to an neighboring host are successful. But, with an eth interface
> enslaved to a L3 enabled bridge (mgmtbr0), and the bridge enslaved to a
> l3mdev VRF (mgmtvrf), the pings sent out on the VRF are not received
> back at the application level.
you mean this setup:
eth1 (ingress port) -> br0 (bridge) -> red (vrf)
IP address on br0:
9: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master
red state UP group default qlen 1000
link/ether 02:e0:f9:1c:00:37 brd ff:ff:ff:ff:ff:ff
inet 10.100.1.4/24 scope global br0
valid_lft forever preferred_lft forever
inet6 fe80::e0:f9ff:fe1c:37/64 scope link
valid_lft forever preferred_lft forever
And then ping a neighbor:
# ping -I red -c1 -w1 10.100.1.254
ping: Warning: source address might be selected on device other than red.
PING 10.100.1.254 (10.100.1.254) from 10.100.1.4 red: 56(84) bytes of data.
64 bytes from 10.100.1.254: icmp_seq=1 ttl=64 time=0.810 ms
--- 10.100.1.254 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.810/0.810/0.810/0.000 ms
>
>
>
> ICMP Echo requests are successfully sent out on the mgmtvrf device to a
> neighboring host. However, ICMP echo replies that are received back from
> the neighboring host via the eth and mgmtbr0 interfaces are not seen at
> the vrf device level and therefore fail to be delivered locally to the
> ping application.
Does tcpdump on each level show the response? tcpdump on eth, tcpdump on
bridge and tcpdump on the vrf device?
>
>
>
> The following LOG rules were added to the raw table, prerouting chain
> and the filter table, OUTPUT chains:
>
>
>
> root@x10sdv-4c-tln4f:~# iptables -t raw -S PREROUTING
>
> -P PREROUTING ACCEPT
>
> -A PREROUTING -s 10.32.8.135/32 -i mgmtbr0 -j LOG
>
> -A PREROUTING -s 10.32.8.135/32 -i mgmtvrf -j LOG
>
>
>
> root@x10sdv-4c-tln4f:~# iptables -S OUTPUT
>
> -P OUTPUT ACCEPT
>
> -A OUTPUT -o mgmtvrf -j LOG
>
> -A OUTPUT -o mgmtbr0 -j LOG
>
>
>
> Pings are sent on the management VRF to a neighboring host (10.32.8.135)
> and the netfilter logs included below:
>
> Note, that in the logs, ICMP echo requests are sent out on the mgmtvrf
> and match the output rules for mgmvrf and mgmtbr0, but the ICMP echo
> replies are only seen on mgmtbr0, not on mgmtvrf
>
>
>
> root@x10sdv-4c-tln4f:~# ping 10.32.8.135 -I mgmtvrf -c 1
>
> PING 10.32.8.135 (10.32.8.135):
>
> 56 data bytes
>
> [ 2679.683027] IN= OUT=mgmtvrf SRC=10.33.96.131 DST=10.32.8.135 LEN=84
> TOS=0x00 PREC=0x00 TTL=64 ID=23921 DF PROTO=ICMP TYPE=8 CODE=0 ID=32610
> SEQ=0 <<< ICMP echo sent on mgmtvrf
>
> [ 2679.697560] IN= OUT=mgmtbr0 SRC=10.33.96.131 DST=10.32.8.135 LEN=84
> TOS=0x00 PREC=0x00 TTL=64 ID=23921 DF PROTO=ICMP TYPE=8 CODE=0 ID=32610
> SEQ=0 <<< ICMP echo sent on mgmtbr0
>
> [ 2679.713312] IN=mgmtbr0 OUT= PHYSIN=ethUSB
> MAC=c0:56:27:90:4f:75:c4:7d:4f:bb:02:e7:08:00 SRC=10.32.8.135
> DST=10.33.96.131 LEN=84 TOS=0x00 PREC=0x00 TTL=62 ID=64949 PROTO=ICMP
> TYPE=0 CODE=0 ID=32610 SEQ=0 <<< ICMP echo reply rcvd on mgmtbr0,
> but not on mgmtvrf
>
>
>
> --- 10.32.8.135 ping statistics ---
>
> 1 packets transmitted, 0 packets received, 100% packet loss <<<<
> ping failed
>
>
>
> I’d like to know if this is an outstanding/resolved issue.
>
This one works (see above), so I suspect it is something with your setup.
^ permalink raw reply
* Re: [PATCH net-next,v2] net: rename ndo_setup_tc to ndo_setup_offload
From: David Miller @ 2018-07-20 19:07 UTC (permalink / raw)
To: daniel
Cc: roopa, pablo, netdev, jiri, thomas.lendacky, f.fainelli,
ariel.elior, michael.chan, santosh, madalin.bucur, yisen.zhuang,
salil.mehta, jeffrey.t.kirsher, tariqt, saeedm, jiri, idosch,
ganeshgr, jakub.kicinski, linux-net-drivers, peppe.cavallaro,
alexandre.torgue, joabreu, grygorii.strashko, andrew,
vivien.didelot
In-Reply-To: <6aea27f3-4ce1-135e-e753-66965f50c5cb@iogearbox.net>
From: Daniel Borkmann <daniel@iogearbox.net>
Date: Fri, 20 Jul 2018 19:28:23 +0200
> This might be fine as new ndo depending on the use case this will have (?),
> but fwiw the term 'flow' or 'rule' would be misleading for what tc offload
> would be doing today (e.g. to name one, there's no notion of 'flow' in BPF
> offload). Given today this interface is deeply baked into tc, just a rename
> might not suffice but should probably move the whole handling around it such
> as assembling the offload info into generic net/core/netdev.c as well if this
> is the way to go.
I would much rather see a new NDO for handling a new offload. That is
consistent with our overall game plan of the past few years ever since
this TC offload NDO went in.
We can't pretend to be able to predict the future and know that these
various things can be consolidated into a single interface beforehand.
It is important to see what implementing a new offload looks like, in
a couple of drivers, first. And then we can have something to look
at, and discuss, with respect to NDO consolidation.
What is happening with this patch is you are brute force making this
NDO generic, and then saying "I will show you how it can be generic."
Sorry, that's the wrong way around. Make a new NDO op for your flow
offloading, show how it works and is implemented in a few drivers,
and then (and only then) can you talk about whether consolidating
is possible or appropriate.
Thank you.
^ permalink raw reply
* Deck of Mr. Reyan Roger.
From: Mr Ryan Roger @ 2018-07-20 18:51 UTC (permalink / raw)
Attention: Beneficiary,
Due to the Federal Government new Policy to fight corruption. I want to bring to your Notice that the President of the Federal Republic of Nigeria, Muhammadu Buhari, has Mandated that all the Overdue Foreign Payment should be Paid to the Beneficiary.
We are very sorry for all the stress/Fees you spent to the Fraudulent Officials who claim to be a Good Nigeria,
Nigerian Image has been tarnished in the eye of the International communities, the reason Mr President Promised the International communities on 31st Session of African Union (AU) summit held in Nouakchott, Mauritania on sunday 1st of july 2018.
He promised to make sure all the payment owed by Nigerian Government will be paid to the foreign beneficiary without any further delay.
I want to Inform you that A Certified Draft of ( USD 2 MILLION) or ATM Card will be Made available to you,
therefore we Request you to Reconfirm the Information as stated Bellow:
(1) YOUR FULL NAME / ADDRESS
(2) YOUR DIRECT TEL/FAX NUMBER
(3) YOUR NATIONALITY / IDENTITY CARD
(4) YOUR AGE
(5) YOUR OCCUPATION.
(6) MODE OF PAYMENT
(ATM CARD OR CERTIFIED DRAFT) Choose one Mode of Payment.
You should reply Immediately with the Information if you want to receive this Certified Draft or ATM Card before the Closing Date,
reply directly to the Bellow Email Address: (reyanroger@yahoo.com) and Let Me Know Your Stands as well as sending the Information.
Best Regard,
Mr Ryan Roger.
^ permalink raw reply
* Re: VRF with enslaved L3 enabled bridge
From: David Ahern @ 2018-07-20 19:11 UTC (permalink / raw)
To: D'Souza, Nelson, netdev@vger.kernel.org
In-Reply-To: <F8810C2E-7791-43B8-AB64-6FC843431FEA@ciena.com>
On 7/20/18 1:03 PM, D'Souza, Nelson wrote:
> Hi Dave,
>
> It is good to know that this works in your case. However, I'm not able to pinpoint what the issue is and looking for a way to narrow down to the root cause.
> Do you know if this has been an issue in the past and resolved in Linux kernel versions after 4.14.52?
It has always worked as far as I recall.
>
> I have the same setup as you and tcpdump works at all levels (eth, bridge, vrf).
>
> Setup is as follows:
>
> ethUSB(ingress port) -> mgmtbr0 (bridge) -> mgmtvrf (vrf)
>
> Logs from my setup:
>
> b) ethUSB is enslaved to mgmtbr0 (bridge)
>
> root@x10sdv-4c-tln4f:~# ip link show master mgmtbr0
> 6: ethUSB: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master mgmtbr0 state UNKNOWN mode DEFAULT group default qlen 1000
> link/ether c0:56:27:90:4f:75 brd ff:ff:ff:ff:ff:ff
>
> b) mgmtbr0 bridge is enslaved to mgmtvrf (vrf)
>
> root@x10sdv-4c-tln4f:~# ip link show master mgmtvrf
> 16: mgmtbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master mgmtvrf state UP mode DEFAULT group default qlen 1000
> link/ether c0:56:27:90:4f:75 brd ff:ff:ff:ff:ff:ff
>
> c) ip address configured on mgmtbr0
>
> root@x10sdv-4c-tln4f:~# ip addr show dev mgmtbr0
> 16: mgmtbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master mgmtvrf state UP group default qlen 1000
> link/ether c0:56:27:90:4f:75 brd ff:ff:ff:ff:ff:ff
> inet 10.33.96.131/24 brd 10.33.96.255 scope global mgmtbr0
> valid_lft forever preferred_lft forever
> inet6 fe80::c256:27ff:fe90:4f75/64 scope link
> valid_lft forever preferred_lft forever
>
> d) tcpdump on ethUSB successful, but ping fails
> root@x10sdv-4c-tln4f:~# ping 10.32.8.135 -I mgmtvrf -c1 -w1
> PING 10.32.8.135 (10.32.8.135): 56 data bytes
> --- 10.32.8.135 ping statistics ---
> 1 packets transmitted, 0 packets received, 100% packet loss
>
> root@x10sdv-4c-tln4f:~# tcpdump -i ethUSB icmp
> 11:38:37.169678 IP 10.33.96.131 > 10.32.8.135: ICMP echo request, id 62312, seq 0, length 64
> 11:38:37.170906 IP 10.32.8.135 > 10.33.96.131: ICMP echo reply, id 62312, seq 0, length 64
First, is this a modified kernel?
What does the following show?
$ ip ru ls
$ ip route ls vrf mgmt
$ ip li sh vrf mgmt
Try perf:
perf record -e fib:* -a -g -- sleep 3
(run ping during record)
perf script
Look at the table used for lookups. Is the correct one for the mgmt vrf?
^ permalink raw reply
* Re: [PATCH net 0/2] openvswitch tests for nla_nest_start
From: David Miller @ 2018-07-20 19:15 UTC (permalink / raw)
To: stephen; +Cc: pshelar, netdev, dev, sthemmin
In-Reply-To: <20180718161216.27820-1-sthemmin@microsoft.com>
From: Stephen Hemminger <stephen@networkplumber.org>
Date: Wed, 18 Jul 2018 09:12:14 -0700
> Coverity is looking for bugs here, and a couple of new bugzilla
> reports showed up where nla_nest_start return is not checked
> for NULL.
Series applied and patch #2 queued up for -stable, thanks Stephen.
^ permalink raw reply
* Re: [PATCH net 0/2] openvswitch tests for nla_nest_start
From: David Miller @ 2018-07-20 19:19 UTC (permalink / raw)
To: stephen; +Cc: pshelar, netdev, dev, sthemmin
In-Reply-To: <20180720.121536.612580141999331732.davem@davemloft.net>
From: David Miller <davem@davemloft.net>
Date: Fri, 20 Jul 2018 12:15:36 -0700 (PDT)
> From: Stephen Hemminger <stephen@networkplumber.org>
> Date: Wed, 18 Jul 2018 09:12:14 -0700
>
>> Coverity is looking for bugs here, and a couple of new bugzilla
>> reports showed up where nla_nest_start return is not checked
>> for NULL.
>
> Series applied and patch #2 queued up for -stable, thanks Stephen.
Actually, this wasn't compile tested and fails to build. :-/
Please fix this and resubmit.
Thanks.
^ permalink raw reply
* Re: [PATCH -next] net/dsa/realtek: add MODULE_LICENSE()
From: Linus Walleij @ 2018-07-20 20:23 UTC (permalink / raw)
To: Randy Dunlap; +Cc: netdev, David S. Miller, linux-kernel@vger.kernel.org
In-Reply-To: <3502c393-e098-241b-c361-4e5069486d71@infradead.org>
On Fri, Jul 20, 2018 at 6:16 PM Randy Dunlap <rdunlap@infradead.org> wrote:
> From: Randy Dunlap <rdunlap@infradead.org>
>
> Add MODULE_LICENSE() to net/dsa/realtek.o to fix build warning message.
>
> WARNING: modpost: missing MODULE_LICENSE() in drivers/net/dsa/realtek.o
>
> Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
> Cc: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH net-next 0/2] constify nla_policy
From: David Miller @ 2018-07-20 19:34 UTC (permalink / raw)
To: stephen
Cc: josef, axboe, pablo, laforge, linux-block, nbd, osmocom-net-gprs,
netdev, sthemmin
In-Reply-To: <20180718163244.1590-1-sthemmin@microsoft.com>
From: Stephen Hemminger <stephen@networkplumber.org>
Date: Wed, 18 Jul 2018 09:32:42 -0700
> Almost all places that use nla_policy declare it const.
> A couple of drivers didn't but that is fixable.
Series applied, thanks Stephen.
^ permalink raw reply
* Re: [net-next 1/1] tipc: make link capability update thread safe
From: David Miller @ 2018-07-20 19:36 UTC (permalink / raw)
To: jon.maloy
Cc: netdev, gordan.mihaljevic, tung.q.nguyen, hoang.h.le, canh.d.luu,
ying.xue, tipc-discussion
In-Reply-To: <1531936206-3118-1-git-send-email-jon.maloy@ericsson.com>
From: Jon Maloy <jon.maloy@ericsson.com>
Date: Wed, 18 Jul 2018 19:50:06 +0200
> The commit referred to below introduced an update of the link
> capabilities field that is not safe. Given the recently added
> feature to remove idle node and link items after 5 minutes, there
> is a small risk that the update will happen at the very moment the
> targeted link is being removed. To avoid this we have to perform
> the update inside the node item's write lock protection.
>
> Fixes: 9012de508956 ("tipc: add sequence number check for link STATE messages")
> Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Applied, thanks Jon.
^ permalink raw reply
* Re: linux-next: build warning after merge of the net-next tree
From: Linus Walleij @ 2018-07-20 20:31 UTC (permalink / raw)
To: Stephen Rothwell
Cc: David S. Miller, netdev, Linux-Next Mailing List,
linux-kernel@vger.kernel.org
In-Reply-To: <20180719114027.2722d075@canb.auug.org.au>
On Thu, Jul 19, 2018 at 3:40 AM Stephen Rothwell <sfr@canb.auug.org.au> wrote:
> After merging the net-next tree, today's linux-next build (x86_64
> allmodconfig) produced this warning:
>
> WARNING: modpost: missing MODULE_LICENSE() in drivers/net/dsa/realtek.o
> see include/linux/module.h for more information
>
> Introduced by commit
>
> d8652956cf37 ("net: dsa: realtek-smi: Add Realtek SMI driver")
Thanks, there is already a patch for it.
I'm pretty grateful that this was the worst the integration testing
could find :) new drivers always make me nervous.
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH] bpf: Add Python 3 support to selftests scripts for bpf
From: Daniel Borkmann @ 2018-07-20 20:45 UTC (permalink / raw)
To: Jeremy Cline, Alexei Starovoitov, Shuah Khan
Cc: netdev, linux-kernel, linux-kselftest, Lawrence Brakmo,
jakub.kicinski
In-Reply-To: <20180718213610.19618-1-jcline@redhat.com>
On 07/18/2018 11:36 PM, Jeremy Cline wrote:
> Adjust tcp_client.py and tcp_server.py to work with Python 3 by using
> the print function, marking string literals as bytes, and using the
> newer exception syntax. This should be functionally equivalent and
> support Python 2.6 through Python 3.7.
>
> Signed-off-by: Jeremy Cline <jcline@redhat.com>
Thanks for the patch, Jeremy! Given we also have test_offload.py in BPF
kselftests and it is written for python 3 only, it would probably make
sense to adapt the tcp_{client,server}.py towards python 3 as well, so
we wouldn't need to keep extra compat for 2 and have a consistent version
dependency. Lawrence / Jeremy, any objections?
> tools/testing/selftests/bpf/tcp_client.py | 12 ++++++------
> tools/testing/selftests/bpf/tcp_server.py | 17 +++++++++--------
> 2 files changed, 15 insertions(+), 14 deletions(-)
>
> diff --git a/tools/testing/selftests/bpf/tcp_client.py b/tools/testing/selftests/bpf/tcp_client.py
> index 481dccdf140c..9fe5f1b5c020 100755
> --- a/tools/testing/selftests/bpf/tcp_client.py
> +++ b/tools/testing/selftests/bpf/tcp_client.py
> @@ -1,4 +1,4 @@
> -#!/usr/bin/env python2
> +#!/usr/bin/env python
> #
> # SPDX-License-Identifier: GPL-2.0
> #
> @@ -9,11 +9,11 @@ import subprocess
> import select
>
> def read(sock, n):
> - buf = ''
> + buf = b''
> while len(buf) < n:
> rem = n - len(buf)
> try: s = sock.recv(rem)
> - except (socket.error), e: return ''
> + except (socket.error) as e: return b''
> buf += s
> return buf
>
> @@ -22,7 +22,7 @@ def send(sock, s):
> count = 0
> while count < total:
> try: n = sock.send(s)
> - except (socket.error), e: n = 0
> + except (socket.error) as e: n = 0
> if n == 0:
> return count;
> count += n
> @@ -39,10 +39,10 @@ try:
> except socket.error as e:
> sys.exit(1)
>
> -buf = ''
> +buf = b''
> n = 0
> while n < 1000:
> - buf += '+'
> + buf += b'+'
> n += 1
>
> sock.settimeout(1);
> diff --git a/tools/testing/selftests/bpf/tcp_server.py b/tools/testing/selftests/bpf/tcp_server.py
> index bc454d7d0be2..1d4a40a6584b 100755
> --- a/tools/testing/selftests/bpf/tcp_server.py
> +++ b/tools/testing/selftests/bpf/tcp_server.py
> @@ -1,7 +1,8 @@
> -#!/usr/bin/env python2
> +#!/usr/bin/env python
> #
> # SPDX-License-Identifier: GPL-2.0
> #
> +from __future__ import print_function
>
> import sys, os, os.path, getopt
> import socket, time
> @@ -9,11 +10,11 @@ import subprocess
> import select
>
> def read(sock, n):
> - buf = ''
> + buf = b''
> while len(buf) < n:
> rem = n - len(buf)
> try: s = sock.recv(rem)
> - except (socket.error), e: return ''
> + except (socket.error) as e: return b''
> buf += s
> return buf
>
> @@ -22,7 +23,7 @@ def send(sock, s):
> count = 0
> while count < total:
> try: n = sock.send(s)
> - except (socket.error), e: n = 0
> + except (socket.error) as e: n = 0
> if n == 0:
> return count;
> count += n
> @@ -43,7 +44,7 @@ host = socket.gethostname()
>
> try: serverSocket.bind((host, 0))
> except socket.error as msg:
> - print 'bind fails: ', msg
> + print('bind fails: ' + str(msg))
>
> sn = serverSocket.getsockname()
> serverPort = sn[1]
> @@ -51,10 +52,10 @@ serverPort = sn[1]
> cmdStr = ("./tcp_client.py %d &") % (serverPort)
> os.system(cmdStr)
>
> -buf = ''
> +buf = b''
> n = 0
> while n < 500:
> - buf += '.'
> + buf += b'.'
> n += 1
>
> serverSocket.listen(MAX_PORTS)
> @@ -79,5 +80,5 @@ while True:
> serverSocket.close()
> sys.exit(0)
> else:
> - print 'Select timeout!'
> + print('Select timeout!')
> sys.exit(1)
>
^ 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