Date   

Re: Helper functions available for XDP?

Yonghong Song
 

On Tue, Jul 24, 2018 at 1:54 AM, François <fser@...> wrote:
On Mon, Jul 23, 2018 at 10:08:08PM +0200, Paul Chaignon wrote:
On Mon, Jul 23, 2018 at 02:21:05PM -0400, Andrew Wang wrote:
Hi

I am writing a bpf program for packet processing and have loaded my ingress
function at BPF.XDP.

I'm updating the destination IPv6 address and want to update the TCP
checksum, but when I try to call the helper functions "bpf_csum_diff" or
"bpf_l4_csum_replace", I get a "unknown func <function name>". Are these
functions not available for XDP program types?
XDP programs cannot use bpf_l4_csum_replace, but they can use
bpf_csum_diff since commit 205c380 ("bpf: add csum_diff helper to xdp as
well") which landed in v4.16-rc1.
I was thinking maybe those helpers were not available because no skb
was construct. But after checking, the helper you're mentionning is in
the tc_cls. Also, the csum_diff helper lies in the same switch
statement as l4_csum_replace.

Can you elaborate on why one can be used and not the other?
bpf_csum_diff only accesses packet data and can be used in both cls_act and xdp.
bpf_l4_csum_replace accesses skb data structure, e.g., it needs to
replace the csum
and hence needs to test whether skb is writable. It also different
calculation based on
the existing checksum state (skb->ip_summed), so bpf_l4_csum_replace cannot be
used in xdp.


Thanks!



Re: Helper functions available for XDP?

François
 

On Mon, Jul 23, 2018 at 10:08:08PM +0200, Paul Chaignon wrote:
On Mon, Jul 23, 2018 at 02:21:05PM -0400, Andrew Wang wrote:
Hi

I am writing a bpf program for packet processing and have loaded my ingress
function at BPF.XDP.

I'm updating the destination IPv6 address and want to update the TCP
checksum, but when I try to call the helper functions "bpf_csum_diff" or
"bpf_l4_csum_replace", I get a "unknown func <function name>". Are these
functions not available for XDP program types?
XDP programs cannot use bpf_l4_csum_replace, but they can use
bpf_csum_diff since commit 205c380 ("bpf: add csum_diff helper to xdp as
well") which landed in v4.16-rc1.
I was thinking maybe those helpers were not available because no skb
was construct. But after checking, the helper you're mentionning is in
the tc_cls. Also, the csum_diff helper lies in the same switch
statement as l4_csum_replace.

Can you elaborate on why one can be used and not the other?

Thanks!


Re: Helper functions available for XDP?

Paul Chaignon
 

On Mon, Jul 23, 2018 at 02:21:05PM -0400, Andrew Wang wrote:
Hi

I am writing a bpf program for packet processing and have loaded my ingress
function at BPF.XDP.

I'm updating the destination IPv6 address and want to update the TCP
checksum, but when I try to call the helper functions "bpf_csum_diff" or
"bpf_l4_csum_replace", I get a "unknown func <function name>". Are these
functions not available for XDP program types?
XDP programs cannot use bpf_l4_csum_replace, but they can use
bpf_csum_diff since commit 205c380 ("bpf: add csum_diff helper to xdp as
well") which landed in v4.16-rc1.


Is there a way to tell what helper functions are available to what program
types?
The list of helpers available to XDP programs is defined in function
xdp_func_proto in file net/core/filter.c of the Linux source code.
You might also want to check out pull request #1881 [1], which will
document helpers available to each program type in file kernel-versions.md
of bcc [2].

1 - https://github.com/iovisor/bcc/pull/1881
2 - https://github.com/iovisor/bcc/blob/master/docs/kernel-versions.md


Thanks
Andrew


Helper functions available for XDP?

Andrew Wang
 

Hi

I am writing a bpf program for packet processing and have loaded my ingress function at BPF.XDP. 

I'm updating the destination IPv6 address and want to update the TCP checksum, but when I try to call the helper functions "bpf_csum_diff" or "bpf_l4_csum_replace", I get a "unknown func <function name>". Are these functions not available for XDP program types? 

Is there a way to tell what helper functions are available to what program types?

Thanks
Andrew


Re: Fixing stack trace function names by argument introspection

Yonghong Song
 

On Sun, Jul 22, 2018 at 3:00 PM, marko@... <marko@...> wrote:
Hi!

Imagine I have an interpreter that runs some program in some custom
language. If I were to get a stack trace, it would look like:

sys_read() [k]
read()
execute_fn()
execute_fn()
execute_fn()
execute_fn()
main()

These execute_fn() functions execute functions defined in my custom
language. Such stack trace is not very helpful.

But I know that I can get to real function name through execute_fn()
arguments. Imagine it is as simple as execute_fn(char *real_fn_name).

I know I can trace execute_fn() invocations and get to this function name
through BCC/eBPF. But I would like to have tool similar to profile.py to be
able to profile my programs written in my custom language.

So I need to get stack traces periodically (49 Hz say) and I need to
substitute name of a function from execute_fn() to the real one from
arguments.

Can you give me some pointers how to do that or if it is possible at all.
I couldn't find any example that walks stack trace. All of the examples just
record them.
We did not have such an example in BCC. In Facebook, we have a bpf
program to catch
stack traces for python programs. It is very similar to what you want
to achieve in the above.
Basically, you need to walk the stack by yourself. Since verifier do
not support unbounded loops,
you need to have a fully-unrollable loop with progma unroll.

During each loop iteration, you can access the frame pointer, you need
some mechanism to
get the real function name based on that level frame pointer and then
you move on
to the next. In bpf program, you can access current task structure,
which contains some
data related to TLS which could be used by the bpf program.


Thanks!
Marko.


Fixing stack trace function names by argument introspection

marko@kevac.org
 

Hi!

Imagine I have an interpreter that runs some program in some custom language. If I were to get a stack trace, it would look like:

sys_read() [k]
read()
execute_fn()
execute_fn()
execute_fn()
execute_fn()
main()

These execute_fn() functions execute functions defined in my custom language. Such stack trace is not very helpful.

But I know that I can get to real function name through execute_fn() arguments. Imagine it is as simple as execute_fn(char *real_fn_name).

I know I can trace execute_fn() invocations and get to this function name through BCC/eBPF. But I would like to have tool similar to profile.py to be able to profile my programs written in my custom language.

So I need to get stack traces periodically (49 Hz say) and I need to substitute name of a function from execute_fn() to the real one from arguments.

Can you give me some pointers how to do that or if it is possible at all.
I couldn't find any example that walks stack trace. All of the examples just record them.

Thanks!
Marko.


Re: Accessing pinned eBPF map from the kernel

Yonghong Song
 

On Thu, Jul 19, 2018 at 2:49 PM, Hyunseok <hyunseok@...> wrote:
Thanks for your reply.

BPF_TABLE("extern") seems to work only if the eBPF program is loaded by the
same userspace process which creates the map, like in this example.
No. The example uses a locally-created map to illustrate the process,
but a pinned map
works in a similar way.

The user space application:
. using bpf_obj_get to get a FD for the pinned map.
. create TableDesc with the FD.
. Add TableDesc to the local_ts.
. Create a BPF object with the local_ts.
. ...

In the bpf program itself, declare the pinned map with "extern" type.


But, what if a map is created (and pinned) by process A, and an eBPF program
is loaded by another process B?
Is there any way for the eBPF program to access the pinned map?
Just follow the above process, it should work. Facebook has used the
same mechanism for a while to access externally-pinned maps.


bpf_obj_get cannot be used by eBPF programs as it is a userspace API.
bpf_obj_get() intends to be used in userspace, not kernel.



On Thu, Jul 19, 2018 at 3:33 PM, Y Song <ys114321@...> wrote:

The following is an example in C++ to import an external map to BPF
modules.
https://github.com/iovisor/bcc/blob/master/examples/cpp/UseExternalMap.cc
You can use libbpf function `bpf_obj_get` to get a map fd in the above
example.

On Wed, Jul 18, 2018 at 11:48 AM, <hyunseok@...> wrote:
Hi,

I have an eBPF map created and pinned by a userspace process.

Now I would like several eBPF programs to access this pinned eBPF map.

Is there any bcc APIs that can be used?

BPF_TABLE(), etc creates a new eBPF map, not loads an existing pinned
map.

Thanks,
-hs


Re: Accessing pinned eBPF map from the kernel

Hyunseok
 

Thanks for your reply.

BPF_TABLE("extern") seems to work only if the eBPF program is loaded by the same userspace process which creates the map, like in this example.

But, what if a map is created (and pinned) by process A, and an eBPF program is loaded by another process B?
Is there any way for the eBPF program to access the pinned map?

bpf_obj_get cannot be used by eBPF programs as it is a userspace API.


On Thu, Jul 19, 2018 at 3:33 PM, Y Song <ys114321@...> wrote:
The following is an example in C++ to import an external map to BPF modules.
https://github.com/iovisor/bcc/blob/master/examples/cpp/UseExternalMap.cc
You can use libbpf function `bpf_obj_get` to get a map fd in the above example.

On Wed, Jul 18, 2018 at 11:48 AM,  <hyunseok@...> wrote:
> Hi,
>
> I have an eBPF map created and pinned by a userspace process.
>
> Now I would like several eBPF programs to access this pinned eBPF map.
>
> Is there any bcc APIs that can be used?
>
> BPF_TABLE(), etc creates a new eBPF map, not loads an existing pinned map.
>
> Thanks,
> -hs


Re: problems with __sync_add_and_fetch in BPF code

Yonghong Song
 

On Wed, Jul 18, 2018 at 8:01 AM, Pablo Alvarez via Lists.Iovisor.Org
<palvarez=akamai.com@...> wrote:
Hi Daniel,

Yes. If you look at the bug report, you will see that what it actually
returns is some form of the increment. that is,

__sync_add_and_fetch(myptr, increment)

returns either increment or (increment * 2) (I am not sure which right now)

The fact that other builtins don't compile with LLVM is not too
surprising, given that it's a very restricted subset of C. The fact that
something does compile but then does not produce the promised result...
that's a little more of an issue!

Are there people on this list who have worked on the LLVM BPF compiler?
I might be willing to try to tackle fixing the bug, but I would need
some guidance...
Pablo,

I added the below comment in the bug report:

===

The table description for bpf_xadd operation is at BPFInstrInfo.td:

// Atomics
class XADD<BPFWidthModifer SizeOp, string OpcodeStr, PatFrag OpNode>
: TYPE_LD_ST<BPF_XADD.Value, SizeOp.Value,
(outs GPR:$dst),
(ins MEMri:$addr, GPR:$val),
"lock *("#OpcodeStr#" *)($addr) += $val",
[(set GPR:$dst, (OpNode ADDRri:$addr, GPR:$val))]> {
bits<4> dst;
bits<20> addr;

let Inst{51-48} = addr{19-16}; // base reg
let Inst{55-52} = dst;
let Inst{47-32} = addr{15-0}; // offset
let BPFClass = BPF_STX;
}

let Constraints = "$dst = $val" in {
def XADD32 : XADD<BPF_W, "u32", atomic_load_add_32>;
def XADD64 : XADD<BPF_DW, "u64", atomic_load_add_64>;
// undefined def XADD16 : XADD<1, "xadd16", atomic_load_add_16>;
// undefined def XADD8 : XADD<2, "xadd8", atomic_load_add_8>;
}
===

Please feel free to take a look how to address this issue.
I can help discussion/review along the way.

Thanks!

Yonghong



Best

Pablo Alvarez

On 07/18/18 09:27, Daniel Zozin wrote:
Hi Pablo,
I'm facing the same problem by compiling and running on kernel 4.15.
Calls to __sync_fetch_and_add keeps returning the same value while the
actual value has been incremented.
Also I add __sync_val_compare_and_swap to your list of primitives
generating compiling errors.

I Investigated a bit but I have no clue on how this can be fixed.

Daniel

On Wed, Jul 18, 2018 at 1:46 PM, Pablo Alvarez via Lists.Iovisor.Org
<https://urldefense.proofpoint.com/v2/url?u=http-3A__Lists.Iovisor.Org&d=DwMFaQ&c=96ZbZZcaMF4w0F4jpN6LZg&r=5x4K78Gqgp18NTNSXDzYVtGgk-aFnm2lzGr5F5OlXNo&m=OAuCIM_YEJpjFDD-bT0wDxmA_cUJTH23eKW9r-qXzPs&s=0Y4-Ozye8rzL2OdOod5_xTXo5tWHsrs0CqSpjE-K1PQ&e=>
<palvarez=akamai.com@...
<mailto:palvarez=akamai.com@...>> wrote:

Hi all,

A while ago, I filed a bug with LLVM about __sync_add_and_fetch as
compiled into eBPF code.

https://bugs.llvm.org/show_bug.cgi?id=36573
<https://urldefense.proofpoint.com/v2/url?u=https-3A__bugs.llvm.org_show-5Fbug.cgi-3Fid-3D36573&d=DwMFaQ&c=96ZbZZcaMF4w0F4jpN6LZg&r=5x4K78Gqgp18NTNSXDzYVtGgk-aFnm2lzGr5F5OlXNo&m=OAuCIM_YEJpjFDD-bT0wDxmA_cUJTH23eKW9r-qXzPs&s=A4pMWnUIf29oD7glNQD3MEAAX27WhbV-L7TCaM9koNk&e=>

Both it and __sync_fetch_and_add fail to return the correct value of
the item being incremented, returning instead the increment (or
double the increment). This means I end up with race conditions. Has
anyone else run into this, and do you have a workaround for it?

The bug report, sadly, has not been touched by anyone else.

Best

Pablo Alvarez






--
Daniel Zozin, Dr.
Research Engineer
RiSING - Robust and Secure Distributed Computing
----------------------------------------
CREATE-NET Research Center
Fondazione Bruno Kessler (FBK)
via alla Cascata 56D
<https://urldefense.proofpoint.com/v2/url?u=https-3A__www.openstreetmap.org_search-3Fquery-3D46.07056-252C11.15092-23map-3D19_46.07056_11.15092-26layers-3DN&d=DwMFaQ&c=96ZbZZcaMF4w0F4jpN6LZg&r=5x4K78Gqgp18NTNSXDzYVtGgk-aFnm2lzGr5F5OlXNo&m=OAuCIM_YEJpjFDD-bT0wDxmA_cUJTH23eKW9r-qXzPs&s=dk6ixv2SUmNaTT-TrXohRsrqnojkqI89jO8eHVMFhbM&e=>
38123 Povo, Trento (Italy)
Tel.: +39 0461 312480
e-mail: d.zozin@... <mailto:d.zozin@...>
www: https://create-net.fbk.eu/
<https://urldefense.proofpoint.com/v2/url?u=https-3A__create-2Dnet.fbk.eu_&d=DwMFaQ&c=96ZbZZcaMF4w0F4jpN6LZg&r=5x4K78Gqgp18NTNSXDzYVtGgk-aFnm2lzGr5F5OlXNo&m=OAuCIM_YEJpjFDD-bT0wDxmA_cUJTH23eKW9r-qXzPs&s=HU2BzKZl_Wb0rxi6vLbplXVWa-e4N2f1PD3e82TAk28&e=>
GPG KEY: 0x6F66193EC7034588

--
Le informazioni contenute nella presente comunicazione sono di
natura privata e come tali sono da considerarsi riservate ed
indirizzate esclusivamente ai destinatari indicati e per le finalità
strettamente legate al relativo contenuto. Se avete ricevuto questo
messaggio per errore, vi preghiamo di eliminarlo e di inviare una
comunicazione all’indirizzo e-mail del mittente.
--
The information transmitted is intended only for the person or entity to
which it is addressed and may contain confidential and/or privileged
material. If you received this in error, please contact the sender and
delete the material.


Re: Accessing pinned eBPF map from the kernel

Yonghong Song
 

The following is an example in C++ to import an external map to BPF modules.
https://github.com/iovisor/bcc/blob/master/examples/cpp/UseExternalMap.cc
You can use libbpf function `bpf_obj_get` to get a map fd in the above example.

On Wed, Jul 18, 2018 at 11:48 AM, <hyunseok@...> wrote:
Hi,

I have an eBPF map created and pinned by a userspace process.

Now I would like several eBPF programs to access this pinned eBPF map.

Is there any bcc APIs that can be used?

BPF_TABLE(), etc creates a new eBPF map, not loads an existing pinned map.

Thanks,
-hs


Re: Verifier error: variable stack access var_off

Yonghong Song
 

The kernel needs to a constant offset from the stack for write. The
corresponding kernel verifier code below:

/* stack accesses must be at a fixed offset, so that we can
* determine what type of data were returned.
* See check_stack_read().
*/
if (!tnum_is_const(reg->var_off)) {
char tn_buf[48];

tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off);
verbose(env, "variable stack access var_off=%s
off=%d size=%d",
tn_buf, off, size);
return -EACCES;
}

You can initialize the array with ' ' to workaround the issue:
struct data_t data;
uint64_t max = sizeof(data.argv);
const char *argp = NULL;
memset(&data, ' ', sizeof(data));
bpf_probe_read(&argp, sizeof(argp), (void *)&__argv[0]);
uint64_t len = bpf_probe_read_str(&data.argv, max, argp);
len &= 0xffffffff; // to avoid: "math between fp pointer and register errs"
bpf_trace_printk("len: %d\\n", len); // sanity check: len is indeed valid

// data.argv[len] = ' ';

On Sun, Jul 1, 2018 at 6:20 PM, Teng Qin <palmtenor@...> wrote:
Firstly, note that bpf_probe_read_str adds an extra \0 to the read string.
So your max should be sizeof(data.argv) - 1 instead in order for
data.argv[len] = ' ' to work (from Verifier's perspective, logically you
don't need that extra delimiter~)

Then, Yonghong had a patch a few month ago addressing very similar issue.
See the example in patch series
bpf: improve verifier ARG_CONST_SIZE_OR_ZERO semantics
Does your Kernel have those patches?

However, even with all those the data.argv[len] = ' ' part still fails with
something about stack offset not being fixed. I will try debug more to see
how to fix that. For now, you can use a per-CPU array of size 1 for the data
instead of allocating it on the stack. The following works for me:
#include <uapi/linux/ptrace.h>
#include <linux/sched.h>
#include <linux/fs.h>

#define ARGSIZE 128

struct data_t {
char argv[ARGSIZE];
};

BPF_PERF_OUTPUT(events);
BPF_PERCPU_ARRAY(mem, struct data_t, 1);
//
// Here's what I'm trying to do. Let's say this has:
// __argv[0] = "ls"
// __argv[1] = "-l"
// I'm trying to create a buffer with "ls -l", by doing bpf_probe_read_str()
for
// each element into the buffer, while keeping track of the length of
// the previous read so I can insert a space delimiter at that offset,
// and begin the next read after the delimiter.
//
int on_event(struct pt_regs *ctx,
const char __user *filename,
const char __user *const __user *__argv,
const char __user *const __user *__envp)
{
int zero = 0;
struct data_t* data = mem.lookup(&zero);
if (!data)
return 0;

uint64_t max = sizeof(data->argv) - 1;
const char *argp = NULL;
bpf_probe_read(&argp, sizeof(argp), (void *)&__argv[0]);
uint64_t len = bpf_probe_read_str(&(data->argv), max, argp);
len &= 0xffffffff; // to avoid: "math between fp pointer and register
errs"
bpf_trace_printk("len: %d\\n", len); // sanity check: len is indeed
valid

data->argv[len] = ' ';

events.perf_submit(ctx, data, len);
out:
return 0;
}


Accessing pinned eBPF map from the kernel

Hyunseok
 

Hi,

I have an eBPF map created and pinned by a userspace process.

Now I would like several eBPF programs to access this pinned eBPF map.

Is there any bcc APIs that can be used?

BPF_TABLE(), etc creates a new eBPF map, not loads an existing pinned map.

Thanks,
-hs


Re: problems with __sync_add_and_fetch in BPF code

Alexei Starovoitov
 

On Wed, Jul 18, 2018 at 8:01 AM, Pablo Alvarez via Lists.Iovisor.Org
<palvarez=akamai.com@...> wrote:
Hi Daniel,

Yes. If you look at the bug report, you will see that what it actually
returns is some form of the increment. that is,

__sync_add_and_fetch(myptr, increment)
I added a comment to bugzilla.
Thank you for bringing it up.
It was considered a known quirk before, but we should improve it.
__sync_add_and_fetch semantics are cleaner and more useful
than what we have today.


Re: problems with __sync_add_and_fetch in BPF code

Pablo Alvarez
 

Hi Daniel,

Yes. If you look at the bug report, you will see that what it actually
returns is some form of the increment. that is,

__sync_add_and_fetch(myptr, increment)

returns either increment or (increment * 2) (I am not sure which right now)

The fact that other builtins don't compile with LLVM is not too
surprising, given that it's a very restricted subset of C. The fact that
something does compile but then does not produce the promised result...
that's a little more of an issue!

Are there people on this list who have worked on the LLVM BPF compiler?
I might be willing to try to tackle fixing the bug, but I would need
some guidance...

Best

Pablo Alvarez

On 07/18/18 09:27, Daniel Zozin wrote:
Hi Pablo,
I'm facing the same problem by compiling and running on kernel 4.15.
Calls to __sync_fetch_and_add keeps returning the same value while the
actual value has been incremented.
Also I add __sync_val_compare_and_swap to your list of primitives
generating compiling errors.

I Investigated a bit but I have no clue on how this can be fixed.

Daniel

On Wed, Jul 18, 2018 at 1:46 PM, Pablo Alvarez via Lists.Iovisor.Org
<https://urldefense.proofpoint.com/v2/url?u=http-3A__Lists.Iovisor.Org&d=DwMFaQ&c=96ZbZZcaMF4w0F4jpN6LZg&r=5x4K78Gqgp18NTNSXDzYVtGgk-aFnm2lzGr5F5OlXNo&m=OAuCIM_YEJpjFDD-bT0wDxmA_cUJTH23eKW9r-qXzPs&s=0Y4-Ozye8rzL2OdOod5_xTXo5tWHsrs0CqSpjE-K1PQ&e=>
<palvarez=akamai.com@...
<mailto:palvarez=akamai.com@...>> wrote:

Hi all,

A while ago, I filed a bug with LLVM about __sync_add_and_fetch as
compiled into eBPF code.

https://bugs.llvm.org/show_bug.cgi?id=36573
<https://urldefense.proofpoint.com/v2/url?u=https-3A__bugs.llvm.org_show-5Fbug.cgi-3Fid-3D36573&d=DwMFaQ&c=96ZbZZcaMF4w0F4jpN6LZg&r=5x4K78Gqgp18NTNSXDzYVtGgk-aFnm2lzGr5F5OlXNo&m=OAuCIM_YEJpjFDD-bT0wDxmA_cUJTH23eKW9r-qXzPs&s=A4pMWnUIf29oD7glNQD3MEAAX27WhbV-L7TCaM9koNk&e=>

Both it and __sync_fetch_and_add fail to return the correct value of
the item being incremented, returning instead the increment (or
double the increment). This means I end up with race conditions. Has
anyone else run into this, and do you have a workaround for it?

The bug report, sadly, has not been touched by anyone else.

Best

Pablo Alvarez






--
Daniel Zozin, Dr.
Research Engineer
RiSING - Robust and Secure Distributed Computing
---------------------------------------- 
CREATE-NET Research Center
Fondazione Bruno Kessler (FBK)
via alla Cascata 56D
<https://urldefense.proofpoint.com/v2/url?u=https-3A__www.openstreetmap.org_search-3Fquery-3D46.07056-252C11.15092-23map-3D19_46.07056_11.15092-26layers-3DN&d=DwMFaQ&c=96ZbZZcaMF4w0F4jpN6LZg&r=5x4K78Gqgp18NTNSXDzYVtGgk-aFnm2lzGr5F5OlXNo&m=OAuCIM_YEJpjFDD-bT0wDxmA_cUJTH23eKW9r-qXzPs&s=dk6ixv2SUmNaTT-TrXohRsrqnojkqI89jO8eHVMFhbM&e=>
38123 Povo, Trento (Italy)
Tel.: +39 0461 31​2480
e-mail: d.zozin@... <mailto:d.zozin@...>
www: https://create-net.fbk.eu/
<https://urldefense.proofpoint.com/v2/url?u=https-3A__create-2Dnet.fbk.eu_&d=DwMFaQ&c=96ZbZZcaMF4w0F4jpN6LZg&r=5x4K78Gqgp18NTNSXDzYVtGgk-aFnm2lzGr5F5OlXNo&m=OAuCIM_YEJpjFDD-bT0wDxmA_cUJTH23eKW9r-qXzPs&s=HU2BzKZl_Wb0rxi6vLbplXVWa-e4N2f1PD3e82TAk28&e=>
GPG KEY: 0x6F66193EC7034588

--
Le informazioni contenute nella presente comunicazione sono di
natura privata e come tali sono da considerarsi riservate ed
indirizzate esclusivamente ai destinatari indicati e per le finalità
strettamente legate al relativo contenuto. Se avete ricevuto questo
messaggio per errore, vi preghiamo di eliminarlo e di inviare una
comunicazione all’indirizzo e-mail del mittente.
--
The information transmitted is intended only for the person or entity to
which it is addressed and may contain confidential and/or privileged
material. If you received this in error, please contact the sender and
delete the material.


Re: problems with __sync_add_and_fetch in BPF code

Daniel Zozin
 

Hi Pablo,
I'm facing the same problem by compiling and running on kernel 4.15.
Calls to __sync_fetch_and_add keeps returning the same value while the actual value has been incremented.
Also I add __sync_val_compare_and_swap to your list of primitives generating compiling errors.

I Investigated a bit but I have no clue on how this can be fixed.

Daniel

On Wed, Jul 18, 2018 at 1:46 PM, Pablo Alvarez via Lists.Iovisor.Org <palvarez=akamai.com@...> wrote:
Hi all,

A while ago, I filed a bug with LLVM about __sync_add_and_fetch as compiled into eBPF code.

https://bugs.llvm.org/show_bug.cgi?id=36573

Both it and __sync_fetch_and_add fail to return the correct value of the item being incremented, returning instead the increment (or double the increment). This means I end up with race conditions. Has anyone else run into this, and do you have a workaround for it?

The bug report, sadly, has not been touched by anyone else.

Best

Pablo Alvarez






--
Daniel Zozin, Dr.
Research Engineer
RiSING - Robust and Secure Distributed Computing
---------------------------------------- 
CREATE-NET Research Center
Fondazione Bruno Kessler (FBK)
38123 Povo, Trento (Italy)
Tel.: +39 0461 31​2480
e-mail: d.zozin@...
GPG KEY: 0x6F66193EC7034588

--
Le informazioni contenute nella presente comunicazione sono di natura privata e come tali sono da considerarsi riservate ed indirizzate esclusivamente ai destinatari indicati e per le finalità strettamente legate al relativo contenuto. Se avete ricevuto questo messaggio per errore, vi preghiamo di eliminarlo e di inviare una comunicazione all’indirizzo e-mail del mittente.
--
The information transmitted is intended only for the person or entity to which it is addressed and may contain confidential and/or privileged material. If you received this in error, please contact the sender and delete the material.


problems with __sync_add_and_fetch in BPF code

Pablo Alvarez
 

Hi all,

A while ago, I filed a bug with LLVM about __sync_add_and_fetch as compiled into eBPF code.

https://bugs.llvm.org/show_bug.cgi?id=36573

Both it and __sync_fetch_and_add fail to return the correct value of the item being incremented, returning instead the increment (or double the increment). This means I end up with race conditions. Has anyone else run into this, and do you have a workaround for it?

The bug report, sadly, has not been touched by anyone else.

Best

Pablo Alvarez


[RFC PATCHv2 13/13] xdp: early drop ipv6 packet.

William Tu
 

If not using ipv6, drop it in XDP.

Signed-off-by: William Tu <u9012063@...>
---
bpf/xdp.h | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)

diff --git a/bpf/xdp.h b/bpf/xdp.h
index 2d2102a6ba28..e71b268370c6 100644
--- a/bpf/xdp.h
+++ b/bpf/xdp.h
@@ -23,8 +23,26 @@ __section("xdp")
static int xdp_ingress(struct xdp_md *ctx OVS_UNUSED)
{
/* TODO: see p4c-xdp project */
+#ifdef BPF_ENABLE_IPV6
printt("return XDP_PASS\n");
return XDP_PASS;
+#else
+ /* Early drop ipv6 */
+ void *data_end = (void *)(long)ctx->data_end;
+ void *data = (void *)(long)ctx->data;
+ struct ethhdr *eth = data;
+ __u16 h_proto;
+
+ if ((char *)eth + 14 > (char *)data_end)
+ return XDP_DROP;
+
+ h_proto = eth->h_proto;
+
+ if (h_proto == bpf_htons(ETH_P_IPV6)) {
+ printt("drop ipv6\n");
+ return XDP_DROP;
+ }
+#endif
}

__section("af_xdp")
--
2.7.4


[RFC PATCHv2 12/13] ofproto: disable megaflow for bpf datapath.

William Tu
 

BPF datapath is always exact match.

Signed-off-by: William Tu <u9012063@...>
---
ofproto/ofproto-dpif-upcall.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c
index 4f696fdca7f6..92a55d0b7768 100644
--- a/ofproto/ofproto-dpif-upcall.c
+++ b/ofproto/ofproto-dpif-upcall.c
@@ -388,7 +388,11 @@ static void upcall_uninit(struct upcall *);
static upcall_callback upcall_cb;
static dp_purge_callback dp_purge_cb;

+#ifdef HAVE_BPF
+static atomic_bool enable_megaflows = ATOMIC_VAR_INIT(false);
+#else
static atomic_bool enable_megaflows = ATOMIC_VAR_INIT(true);
+#endif
static atomic_bool enable_ufid = ATOMIC_VAR_INIT(true);

void
--
2.7.4


[RFC PATCHv2 10/13] tests: Add "make check-bpf" traffic target.

William Tu
 

Add a separate test file tests/system-bpf-traffic.at for
bpf testing. The test cases are a subset of the existing
system-traffic.at, and with additional bpf-specific tests.
When test passes, the log file is saved under:
tests/system-bpf-testsuite.dir/<ID>/

Signed-off-by: William Tu <u9012063@...>
Signed-off-by: Yifeng Sun <pkusunyifeng@...>
Signed-off-by: Joe Stringer <joe@...>
Signed-off-by: Yi-Hung Wei <yihung.wei@...>
Co-authored-by: Joe Stringer <joe@...>
Co-authored-by: Yifeng Sun <pkusunyifeng@...>
Co-authored-by: Yi-Hung Wei <yihung.wei@...>
---
tests/.gitignore | 1 +
tests/automake.mk | 31 +-
tests/ofproto-macros.at | 7 +
tests/system-bpf-macros.at | 112 ++++++
tests/system-bpf-testsuite.at | 25 ++
tests/system-bpf-testsuite.patch | 10 +
tests/system-bpf-traffic.at | 851 +++++++++++++++++++++++++++++++++++++++
7 files changed, 1036 insertions(+), 1 deletion(-)
create mode 100644 tests/system-bpf-macros.at
create mode 100644 tests/system-bpf-testsuite.at
create mode 100644 tests/system-bpf-testsuite.patch
create mode 100644 tests/system-bpf-traffic.at

diff --git a/tests/.gitignore b/tests/.gitignore
index 3e2ddf2e9e5d..98890e011afc 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -11,6 +11,7 @@
/ovs-pki.log
/pki/
/system-kmod-testsuite
+/system-bpf-testsuite
/system-userspace-testsuite
/system-offloads-testsuite
/test-aes128
diff --git a/tests/automake.mk b/tests/automake.mk
index 52ed53fd16d4..732dc4ab9bdc 100644
--- a/tests/automake.mk
+++ b/tests/automake.mk
@@ -4,15 +4,18 @@ EXTRA_DIST += \
$(SYSTEM_TESTSUITE_AT) \
$(SYSTEM_KMOD_TESTSUITE_AT) \
$(SYSTEM_USERSPACE_TESTSUITE_AT) \
+ $(SYSTEM_BPF_TESTSUITE_AT) \
$(SYSTEM_OFFLOADS_TESTSUITE_AT) \
$(TESTSUITE) \
$(SYSTEM_KMOD_TESTSUITE) \
$(SYSTEM_USERSPACE_TESTSUITE) \
+ $(SYSTEM_BPF_TESTSUITE) \
$(SYSTEM_OFFLOADS_TESTSUITE) \
tests/atlocal.in \
$(srcdir)/package.m4 \
$(srcdir)/tests/testsuite \
- $(srcdir)/tests/testsuite.patch
+ $(srcdir)/tests/testsuite.patch \
+ $(srcdir)/tests/system-bpf-testsuite.patch

COMMON_MACROS_AT = \
tests/ovsdb-macros.at \
@@ -110,6 +113,11 @@ SYSTEM_KMOD_TESTSUITE_AT = \
tests/system-kmod-testsuite.at \
tests/system-kmod-macros.at

+SYSTEM_BPF_TESTSUITE_AT = \
+ tests/system-bpf-testsuite.at \
+ tests/system-bpf-macros.at \
+ tests/system-bpf-traffic.at
+
SYSTEM_USERSPACE_TESTSUITE_AT = \
tests/system-userspace-testsuite.at \
tests/system-ovn.at \
@@ -134,6 +142,8 @@ TESTSUITE = $(srcdir)/tests/testsuite
TESTSUITE_PATCH = $(srcdir)/tests/testsuite.patch
SYSTEM_KMOD_TESTSUITE = $(srcdir)/tests/system-kmod-testsuite
SYSTEM_USERSPACE_TESTSUITE = $(srcdir)/tests/system-userspace-testsuite
+SYSTEM_BPF_TESTSUITE = $(srcdir)/tests/system-bpf-testsuite
+BPF_TESTSUITE_PATCH = $(srcdir)/tests/system-bpf-testsuite.patch
SYSTEM_OFFLOADS_TESTSUITE = $(srcdir)/tests/system-offloads-testsuite
DISTCLEANFILES += tests/atconfig tests/atlocal

@@ -174,6 +184,15 @@ check-lcov: all $(check_DATA) clean-lcov
lcov $(LCOV_OPTS) -o tests/lcov/coverage.info
genhtml $(GENHTML_OPTS) -o tests/lcov tests/lcov/coverage.info
@echo "coverage report generated at tests/lcov/index.html"
+
+check-bpf-lcov: all $(check_DATA) clean-lcov
+ find . -name '*.gcda' | xargs -n1 rm -f
+ -set $(SHELL) '$(SYSTEM_BPF_TESTSUITE)' -C tests AUTOTEST_PATH=$(AUTOTEST_PATH) $(TESTSUITEFLAGS); \
+ "$$@" || (test X'$(RECHECK)' = Xyes && "$$@" --recheck)
+ $(MKDIR_P) tests/lcov
+ lcov $(LCOV_OPTS) -o tests/lcov/coverage.info
+ genhtml $(GENHTML_OPTS) -o tests/lcov tests/lcov/coverage.info
+ @echo "coverage report generated at tests/lcov/index.html"

# valgrind support

@@ -254,6 +273,11 @@ check-system-userspace: all
set $(SHELL) '$(SYSTEM_USERSPACE_TESTSUITE)' -C tests AUTOTEST_PATH='$(AUTOTEST_PATH)' $(TESTSUITEFLAGS) -j1; \
"$$@" || (test X'$(RECHECK)' = Xyes && "$$@" --recheck)

+check-bpf: all
+ $(MAKE) install
+ set $(SHELL) '$(SYSTEM_BPF_TESTSUITE)' -C tests AUTOTEST_PATH='$(AUTOTEST_PATH)' $(TESTSUITEFLAGS) -j1; \
+ "$$@" || (test X'$(RECHECK)' = Xyes && "$$@" --recheck)
+
check-offloads: all
set $(SHELL) '$(SYSTEM_OFFLOADS_TESTSUITE)' -C tests AUTOTEST_PATH='$(AUTOTEST_PATH)' $(TESTSUITEFLAGS) -j1; \
"$$@" || (test X'$(RECHECK)' = Xyes && "$$@" --recheck)
@@ -282,6 +306,11 @@ $(SYSTEM_USERSPACE_TESTSUITE): package.m4 $(SYSTEM_TESTSUITE_AT) $(SYSTEM_USERSP
$(AM_V_GEN)$(AUTOTEST) -I '$(srcdir)' -o $@.tmp $@.at
$(AM_V_at)mv $@.tmp $@

+$(SYSTEM_BPF_TESTSUITE): package.m4 $(SYSTEM_TESTSUITE_AT) $(SYSTEM_BPF_TESTSUITE_AT) $(BPF_TESTSUITE_PATCH) $(COMMON_MACROS_AT)
+ $(AM_V_GEN)$(AUTOTEST) -I '$(srcdir)' -o $@.tmp $@.at
+ $(AM_V_at)mv $@.tmp $@
+ $(AM_V_at)patch -p1 $@ tests/system-bpf-testsuite.patch
+
$(SYSTEM_OFFLOADS_TESTSUITE): package.m4 $(SYSTEM_TESTSUITE_AT) $(SYSTEM_OFFLOADS_TESTSUITE_AT) $(COMMON_MACROS_AT)
$(AM_V_GEN)$(AUTOTEST) -I '$(srcdir)' -o $@.tmp $@.at
$(AM_V_at)mv $@.tmp $@
diff --git a/tests/ofproto-macros.at b/tests/ofproto-macros.at
index c8bfe5b5c262..487e40cc8ef2 100644
--- a/tests/ofproto-macros.at
+++ b/tests/ofproto-macros.at
@@ -335,6 +335,7 @@ m4_define([_OVS_VSWITCHD_START],
AT_CAPTURE_FILE([ovs-vswitchd.log])
on_exit "kill_ovs_vswitchd `cat ovs-vswitchd.pid`"
AT_CHECK([[sed < stderr '
+/bpf|INFO|/d
/ovs_numa|INFO|Discovered /d
/vlog|INFO|opened log file/d
/vswitchd|INFO|ovs-vswitchd (Open vSwitch)/d
@@ -344,6 +345,7 @@ m4_define([_OVS_VSWITCHD_START],
/ofproto|INFO|datapath ID changed to fedcba9876543210/d
/dpdk|INFO|DPDK Disabled - Use other_config:dpdk-init to enable/d
/netdev: Flow API/d
+/Re-using preloaded BPF datapath/d
/tc: Using policy/d']])
])

@@ -395,6 +397,11 @@ check_logs () {
sed -n "$1
/reset by peer/d
/Broken pipe/d
+/bpf.*|WARN/d
+/dpif.*|WARN/d
+/bpf.*revalidator.*|ERR/d
+/odp_util.*revalidator.*|ERR/d
+/ofproto_dpif_upcall.*|WARN/d
/timeval.*Unreasonably long [[0-9]]*ms poll interval/d
/timeval.*faults: [[0-9]]* minor, [[0-9]]* major/d
/timeval.*disk: [[0-9]]* reads, [[0-9]]* writes/d
diff --git a/tests/system-bpf-macros.at b/tests/system-bpf-macros.at
new file mode 100644
index 000000000000..23c170d73119
--- /dev/null
+++ b/tests/system-bpf-macros.at
@@ -0,0 +1,112 @@
+# _ADD_BR([name])
+#
+# Expands into the proper ovs-vsctl commands to create a bridge with the
+# appropriate type and properties
+m4_define([_ADD_BR], [[add-br $1 -- set Bridge $1 datapath_type="bpf" protocols=OpenFlow10,OpenFlow11,OpenFlow12,OpenFlow13,OpenFlow14,OpenFlow15 fail-mode=secure ]])
+
+# OVS_TRAFFIC_VSWITCHD_START([vsctl-args], [vsctl-output], [=override])
+#
+# Creates a database and starts ovsdb-server, starts ovs-vswitchd
+# connected to that database, calls ovs-vsctl to create a bridge named
+# br0 with predictable settings, passing 'vsctl-args' as additional
+# commands to ovs-vsctl. If 'vsctl-args' causes ovs-vsctl to provide
+# output (e.g. because it includes "create" commands) then 'vsctl-output'
+# specifies the expected output after filtering through uuidfilt.pl.
+m4_define([OVS_TRAFFIC_VSWITCHD_START],
+ [
+ export OVS_PKGDATADIR=$(`pwd`)
+ #OVS_WAIT_WHILE([ip link show ovs-system])
+ umount /sys/fs/bpf/
+ AT_CHECK([mount -t bpf none /sys/fs/bpf])
+ AT_CHECK([mkdir -p /sys/fs/bpf/ovs])
+ _OVS_VSWITCHD_START([--disable-system])
+ dnl Add bridges, ports, etc.
+ ip link del br0
+ #OVS_WAIT_WHILE([ip link show br0])
+ AT_CHECK([ovs-vsctl -- _ADD_BR([br0]) -- $1 m4_if([$2], [], [], [| ${PERL} $srcdir/uuidfilt.pl])], [0], [$2])
+ on_exit 'ovs-vsctl del-br br0'
+ on_exit 'ip link del ovs-system'
+ on_exit 'tail -500 /sys/kernel/debug/tracing/trace > trace'
+])
+
+# OVS_TRAFFIC_VSWITCHD_STOP([WHITELIST], [extra_cmds])
+#
+# Gracefully stops ovs-vswitchd and ovsdb-server, checking their log files
+# for messages with severity WARN or higher and signaling an error if any
+# is present. The optional WHITELIST may contain shell-quoted "sed"
+# commands to delete any warnings that are actually expected, e.g.:
+#
+# OVS_TRAFFIC_VSWITCHD_STOP(["/expected error/d"])
+#
+# 'extra_cmds' are shell commands to be executed afte OVS_VSWITCHD_STOP() is
+# invoked. They can be used to perform additional cleanups such as name space
+# removal.
+m4_define([OVS_TRAFFIC_VSWITCHD_STOP],
+ [OVS_VSWITCHD_STOP([$1])
+ AT_CHECK([:; $2])
+ AT_CHECK([umount /sys/fs/bpf])
+ AT_CAPTURE_FILE([trace])
+ ])
+
+# CONFIGURE_VETH_OFFLOADS([VETH])
+#
+# Disable TX offloads for veths. The userspace datapath uses the AF_PACKET
+# socket to receive packets for veths. Unfortunately, the AF_PACKET socket
+# doesn't play well with offloads:
+# 1. GSO packets are received without segmentation and therefore discarded.
+# 2. Packets with offloaded partial checksum are received with the wrong
+# checksum, therefore discarded by the receiver.
+#
+# By disabling tx offloads in the non-OVS side of the veth peer we make sure
+# that the AF_PACKET socket will not receive bad packets.
+#
+# This is a workaround, and should be removed when offloads are properly
+# supported in netdev-linux.
+m4_define([CONFIGURE_VETH_OFFLOADS],
+ [AT_CHECK([ethtool -K $1 tx off], [0], [ignore], [ignore])]
+)
+
+# CHECK_CONNTRACK()
+#
+# Perform requirements checks for running conntrack tests.
+#
+m4_define([CHECK_CONNTRACK],
+ [AT_SKIP_IF([test $HAVE_PYTHON = no])]
+)
+
+# CHECK_CONNTRACK_ALG()
+#
+# Perform requirements checks for running conntrack ALG tests. The userspace
+# doesn't support ALGs yet, so skip the tests
+#
+m4_define([CHECK_CONNTRACK_ALG],
+[
+ AT_SKIP_IF([:])
+])
+
+# CHECK_CONNTRACK_FRAG()
+#
+# Perform requirements checks for running conntrack fragmentations tests.
+# The userspace doesn't support fragmentation yet, so skip the tests.
+m4_define([CHECK_CONNTRACK_FRAG],
+[
+ AT_SKIP_IF([:])
+])
+
+# CHECK_CONNTRACK_LOCAL_STACK()
+#
+# Perform requirements checks for running conntrack tests with local stack.
+# While the kernel connection tracker automatically passes all the connection
+# tracking state from an internal port to the OpenvSwitch kernel module, there
+# is simply no way of doing that with the userspace, so skip the tests.
+m4_define([CHECK_CONNTRACK_LOCAL_STACK],
+[
+ AT_SKIP_IF([:])
+])
+
+# CHECK_CONNTRACK_NAT()
+#
+# Perform requirements checks for running conntrack NAT tests. The userspace
+# datapath supports NAT.
+#
+m4_define([CHECK_CONNTRACK_NAT])
diff --git a/tests/system-bpf-testsuite.at b/tests/system-bpf-testsuite.at
new file mode 100644
index 000000000000..54ebbcba17dc
--- /dev/null
+++ b/tests/system-bpf-testsuite.at
@@ -0,0 +1,25 @@
+AT_INIT
+
+AT_COPYRIGHT([Copyright (c) 2015 Nicira, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at:
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.])
+
+m4_ifdef([AT_COLOR_TESTS], [AT_COLOR_TESTS])
+
+m4_include([tests/ovs-macros.at])
+m4_include([tests/ovsdb-macros.at])
+m4_include([tests/ofproto-macros.at])
+m4_include([tests/system-bpf-macros.at])
+m4_include([tests/system-common-macros.at])
+
+m4_include([tests/system-bpf-traffic.at])
diff --git a/tests/system-bpf-testsuite.patch b/tests/system-bpf-testsuite.patch
new file mode 100644
index 000000000000..94f3771d4ee9
--- /dev/null
+++ b/tests/system-bpf-testsuite.patch
@@ -0,0 +1,10 @@
+--- system-bpf-testsuite 2018-05-31 05:10:16.425135086 -0700
++++ system-bpf-testsuite 2018-05-31 05:13:46.556051030 -0700
+@@ -2369,7 +2369,6 @@
+ else
+ if test -d "$at_group_dir"; then
+ find "$at_group_dir" -type d ! -perm -700 -exec chmod u+rwx \{\} \;
+- rm -fr "$at_group_dir"
+ fi
+ rm -f "$at_test_source"
+ fi
diff --git a/tests/system-bpf-traffic.at b/tests/system-bpf-traffic.at
new file mode 100644
index 000000000000..29bb80b5d954
--- /dev/null
+++ b/tests/system-bpf-traffic.at
@@ -0,0 +1,851 @@
+AT_BANNER([BPF datapath-sanity])
+
+AT_SETUP([datapath - basic BPF commands])
+OVS_TRAFFIC_VSWITCHD_START()
+
+AT_CHECK([ovs-appctl dpif/dump-dps], [0], [dnl
+bpf@br0
+])
+AT_CHECK([ovs-appctl dpif/show], [0], [dnl
+bpf@ovs-bpf: hit:0 missed:0
+ br0:
+ br0 65534/1: (tap)
+])
+AT_CHECK([ovs-appctl dpctl/dump-flows bpf@ovs-bpf], [0], [dnl
+])
+AT_CHECK([ovs-appctl dpif/dump-flows br0], [0], [dnl
+])
+AT_CHECK([ovs-bpfctl show], [0], [stdout])
+
+dnl NOTE: BPF datapath does not support megaflow, so the
+dnl rules below won't match any packet
+AT_CHECK([ovs-appctl dpctl/add-flow bpf@ovs-bpf "in_port(1),eth(),eth_type(0x0806),arp()" 2], [0], [stdout])
+
+AT_CHECK([ovs-appctl dpctl/add-flow bpf@ovs-bpf "in_port(1),eth(src=00:01:02:03:04:05,dst=10:11:12:13:14:15),eth_type(0x0800),ipv4(src=35.8.2.41,dst=172.16.0.20,proto=5,tos=0x80,ttl=128,frag=no)" 2], [0], [stdout])
+
+AT_CHECK([ovs-appctl dpctl/add-flow bpf@ovs-bpf "in_port(1),eth(src=00:01:02:03:04:05,dst=10:11:12:13:14:15),eth_type(0x86dd),ipv6(src=::1,dst=::2,label=0,proto=6,tclass=0,hlimit=128,frag=no),tcp(src=80,dst=8080)" 2], [0], [stdout])
+
+dnl this will print "receive tunnel port not found" and cause failure
+dnl AT_CHECK([ovs-appctl dpctl/add-flow bpf@ovs-bpf "skb_priority(0),tunnel(tun_id=0x7f10354,src=10.10.10.10,dst=20.20.20.20,ttl=64,flags(csum|key)),skb_mark(0x1234),recirc_id(0),dp_hash(0),in_port(1),eth(src=00:01:02:03:04:05,dst=10:11:12:13:14:15)" 2], [0], [stdout])
+
+dnl AT_CHECK([ovs-appctl dpctl/add-flow bpf@ovs-bpf "skb_priority(0x1234),tunnel(tun_id=0xfedcba9876543210,src=10.10.10.10,dst=20.20.20.20,tos=0x8,ttl=64,flags(key)),skb_mark(0),recirc_id(0),dp_hash(0),in_port(1),eth(src=00:01:02:03:04:05,dst=10:11:12:13:14:15),eth_type(0x8100),vlan(vid=99,pcp=7),encap(eth_type(0x86dd),ipv6(src=::1,dst=::2,label=0,proto=58,tclass=0,hlimit=128,frag=no),icmpv6(type=136,code=0),nd(target=::3,sll=00:05:06:07:08:09,tll=00:0a:0b:0c:0d:0e))" 2],[0], [stdout])
+
+dnl AT_CHECK([ovs-appctl dpif/del-flows br0], [0], [dnl
+dnl ])
+
+dnl AT_CHECK([ovs-dpctl add-flow bpf@ovs-bpf "in_port(1),eth(src=00:01:02:03:04:05,dst=10:11:12:13:14:15),eth_type(0x0800),ipv4(src=35.8.2.41,dst=172.16.0.20,proto=5,tos=0x80,ttl=128,frag=no)" 2], [0], [dnl
+dnl ])
+
+
+OVS_TRAFFIC_VSWITCHD_STOP
+AT_CLEANUP
+
+AT_SETUP([datapath - ping between two ports])
+OVS_TRAFFIC_VSWITCHD_START()
+
+AT_CHECK([ovs-ofctl add-flow br0 "actions=normal"])
+
+ADD_NAMESPACES(at_ns0, at_ns1)
+
+ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24")
+ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24")
+
+NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 2 10.1.1.2 | FORMAT_PING], [0], [dnl
+3 packets transmitted, 3 received, 0% packet loss, time 0ms
+])
+NS_CHECK_EXEC([at_ns0], [ping -s 1600 -q -c 3 -i 0.3 -w 2 10.1.1.2 | FORMAT_PING], [0], [dnl
+3 packets transmitted, 3 received, 0% packet loss, time 0ms
+])
+NS_CHECK_EXEC([at_ns0], [ping -s 3200 -q -c 3 -i 0.3 -w 2 10.1.1.2 | FORMAT_PING], [0], [dnl
+3 packets transmitted, 3 received, 0% packet loss, time 0ms
+])
+
+OVS_TRAFFIC_VSWITCHD_STOP
+AT_CLEANUP
+
+AT_SETUP([datapath - http between two ports])
+OVS_TRAFFIC_VSWITCHD_START()
+
+AT_CHECK([ovs-ofctl add-flow br0 "actions=normal"])
+
+ADD_NAMESPACES(at_ns0, at_ns1)
+
+ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24")
+ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24")
+
+NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 2 10.1.1.2 | FORMAT_PING], [0], [dnl
+3 packets transmitted, 3 received, 0% packet loss, time 0ms
+])
+
+OVS_START_L7([at_ns1], [http])
+NS_CHECK_EXEC([at_ns0], [wget 10.1.1.2 -t 3 -T 1 --retry-connrefused -v -o wget0.log])
+
+OVS_TRAFFIC_VSWITCHD_STOP
+AT_CLEANUP
+
+AT_SETUP([datapath - ping between two ports on vlan])
+OVS_TRAFFIC_VSWITCHD_START()
+
+AT_CHECK([ovs-ofctl add-flow br0 "actions=normal"])
+
+ADD_NAMESPACES(at_ns0, at_ns1)
+
+ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24")
+ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24")
+
+ADD_VLAN(p0, at_ns0, 100, "10.2.2.1/24")
+ADD_VLAN(p1, at_ns1, 100, "10.2.2.2/24")
+
+NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 2 10.2.2.2 | FORMAT_PING], [0], [dnl
+3 packets transmitted, 3 received, 0% packet loss, time 0ms
+])
+
+OVS_TRAFFIC_VSWITCHD_STOP
+AT_CLEANUP
+
+AT_SETUP([datapath - ping between two ports on cvlan])
+OVS_TRAFFIC_VSWITCHD_START()
+
+AT_CHECK([ovs-ofctl add-flow br0 "actions=normal"])
+
+ADD_NAMESPACES(at_ns0, at_ns1)
+
+ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24")
+ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24")
+
+ADD_SVLAN(p0, at_ns0, 4094, "10.255.2.1/24")
+ADD_SVLAN(p1, at_ns1, 4094, "10.255.2.2/24")
+
+ADD_CVLAN(p0.4094, at_ns0, 100, "10.2.2.1/24")
+ADD_CVLAN(p1.4094, at_ns1, 100, "10.2.2.2/24")
+
+OVS_WAIT_UNTIL([ip netns exec at_ns0 ping -c 1 10.2.2.2])
+
+NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 2 10.2.2.2 | FORMAT_PING], [0], [dnl
+3 packets transmitted, 3 received, 0% packet loss, time 0ms
+])
+
+OVS_TRAFFIC_VSWITCHD_STOP
+AT_CLEANUP
+
+AT_SETUP([datapath - ping6 between two ports])
+OVS_TRAFFIC_VSWITCHD_START()
+
+AT_CHECK([ovs-ofctl add-flow br0 "actions=normal"])
+
+ADD_NAMESPACES(at_ns0, at_ns1)
+
+ADD_VETH(p0, at_ns0, br0, "fc00::1/96")
+ADD_VETH(p1, at_ns1, br0, "fc00::2/96")
+
+dnl Linux seems to take a little time to get its IPv6 stack in order. Without
+dnl waiting, we get occasional failures due to the following error:
+dnl "connect: Cannot assign requested address"
+OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00::2])
+
+NS_CHECK_EXEC([at_ns0], [ping6 -q -c 3 -i 0.3 -w 6 fc00::2 | FORMAT_PING], [0], [dnl
+3 packets transmitted, 3 received, 0% packet loss, time 0ms
+])
+
+OVS_TRAFFIC_VSWITCHD_STOP
+AT_CLEANUP
+
+AT_SETUP([datapath - ping6 between two ports on vlan])
+OVS_TRAFFIC_VSWITCHD_START()
+
+AT_CHECK([ovs-ofctl add-flow br0 "actions=normal"])
+
+ADD_NAMESPACES(at_ns0, at_ns1)
+
+ADD_VETH(p0, at_ns0, br0, "fc00::1/96")
+ADD_VETH(p1, at_ns1, br0, "fc00::2/96")
+
+ADD_VLAN(p0, at_ns0, 100, "fc00:1::1/96")
+ADD_VLAN(p1, at_ns1, 100, "fc00:1::2/96")
+
+dnl Linux seems to take a little time to get its IPv6 stack in order. Without
+dnl waiting, we get occasional failures due to the following error:
+dnl "connect: Cannot assign requested address"
+OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00:1::2])
+
+NS_CHECK_EXEC([at_ns0], [ping6 -q -c 3 -i 0.3 -w 6 fc00:1::2 | FORMAT_PING], [0], [dnl
+3 packets transmitted, 3 received, 0% packet loss, time 0ms
+])
+
+OVS_TRAFFIC_VSWITCHD_STOP
+AT_CLEANUP
+
+AT_SETUP([datapath - ping6 between two ports on cvlan])
+OVS_TRAFFIC_VSWITCHD_START()
+
+AT_CHECK([ovs-ofctl add-flow br0 "actions=normal"])
+
+ADD_NAMESPACES(at_ns0, at_ns1)
+
+ADD_VETH(p0, at_ns0, br0, "fc00::1/96")
+ADD_VETH(p1, at_ns1, br0, "fc00::2/96")
+
+ADD_SVLAN(p0, at_ns0, 4094, "fc00:ffff::1/96")
+ADD_SVLAN(p1, at_ns1, 4094, "fc00:ffff::2/96")
+
+ADD_CVLAN(p0.4094, at_ns0, 100, "fc00:1::1/96")
+ADD_CVLAN(p1.4094, at_ns1, 100, "fc00:1::2/96")
+
+OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00:1::2])
+
+NS_CHECK_EXEC([at_ns0], [ping6 -q -c 3 -i 0.3 -w 2 fc00:1::2 | FORMAT_PING], [0], [dnl
+3 packets transmitted, 3 received, 0% packet loss, time 0ms
+])
+dnl NS_CHECK_EXEC([at_ns0], [ping6 -s 1600 -q -c 3 -i 0.3 -w 6 fc00:1::2 | FORMAT_PING], [0], [dnl
+dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms
+dnl ])
+dnl NS_CHECK_EXEC([at_ns0], [ping6 -s 3200 -q -c 3 -i 0.3 -w 6 fc00:1::2 | FORMAT_PING], [0], [dnl
+dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms
+dnl ])
+
+OVS_TRAFFIC_VSWITCHD_STOP
+AT_CLEANUP
+
+AT_SETUP([datapath - ping over bond])
+AT_SKIP_IF([echo > /dev/null])
+OVS_TRAFFIC_VSWITCHD_START()
+
+AT_CHECK([ovs-ofctl add-flow br0 "actions=normal"])
+
+ADD_NAMESPACES(at_ns0, at_ns1)
+
+ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24")
+ADD_VETH_BOND(p1 p2, at_ns1, br0, bond0, lacp=active bond_mode=balance-tcp, "10.1.1.2/24")
+
+OVS_WAIT_UNTIL([ip netns exec at_ns0 ping -c 1 10.1.1.2])
+
+NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 2 10.1.1.2 | FORMAT_PING], [0], [dnl
+3 packets transmitted, 3 received, 0% packet loss, time 0ms
+])
+NS_CHECK_EXEC([at_ns0], [ping -s 1600 -q -c 3 -i 0.3 -w 2 10.1.1.2 | FORMAT_PING], [0], [dnl
+3 packets transmitted, 3 received, 0% packet loss, time 0ms
+])
+NS_CHECK_EXEC([at_ns0], [ping -s 3200 -q -c 3 -i 0.3 -w 2 10.1.1.2 | FORMAT_PING], [0], [dnl
+3 packets transmitted, 3 received, 0% packet loss, time 0ms
+])
+
+OVS_TRAFFIC_VSWITCHD_STOP
+AT_CLEANUP
+
+AT_SETUP([datapath - ping over vxlan tunnel])
+OVS_CHECK_VXLAN()
+
+OVS_TRAFFIC_VSWITCHD_START()
+ADD_BR([br-underlay])
+
+AT_CHECK([ovs-ofctl add-flow br0 "actions=normal"])
+AT_CHECK([ovs-ofctl add-flow br-underlay "actions=normal"])
+
+ADD_NAMESPACES(at_ns0)
+
+ip link del vxlan_sys_4789
+on_exit 'ip link del vxlan_sys_4789'
+on_exit 'ip link del br-underlay'
+
+dnl Set up underlay link from host into the namespace using veth pair.
+ADD_VETH(p0, at_ns0, br-underlay, "172.31.1.1/24")
+AT_CHECK([ip addr add dev br-underlay "172.31.1.100/24"])
+AT_CHECK([ip link set dev br-underlay up])
+
+dnl Set up tunnel endpoints on OVS outside the namespace and with a native
+dnl linux device inside the namespace.
+ADD_OVS_TUNNEL([vxlan], [br0], [at_vxlan0], [172.31.1.1], [10.1.1.100/24])
+ADD_NATIVE_TUNNEL([vxlan], [at_vxlan1], [at_ns0], [172.31.1.100], [10.1.1.1/24],
+ [id 0 dstport 4789])
+
+dnl First, check the underlay
+NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 6 172.31.1.100 | FORMAT_PING], [0], [dnl
+3 packets transmitted, 3 received, 0% packet loss, time 0ms
+])
+
+dnl Okay, now check the overlay with different packet sizes
+NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 6 10.1.1.100 | FORMAT_PING], [0], [dnl
+3 packets transmitted, 3 received, 0% packet loss, time 0ms
+])
+
+OVS_TRAFFIC_VSWITCHD_STOP
+AT_CLEANUP
+
+AT_SETUP([datapath - ping over vxlan6 tunnel])
+OVS_CHECK_VXLAN_UDP6ZEROCSUM()
+
+OVS_TRAFFIC_VSWITCHD_START()
+ADD_BR([br-underlay])
+
+AT_CHECK([ovs-ofctl add-flow br0 "actions=normal"])
+AT_CHECK([ovs-ofctl add-flow br-underlay "actions=normal"])
+
+ADD_NAMESPACES(at_ns0)
+
+ip link del vxlan_sys_4789
+
+on_exit 'ip link del vxlan_sys_4789'
+on_exit 'ip link del br-underlay'
+
+dnl Set up underlay link from host into the namespace using veth pair.
+ADD_VETH(p0, at_ns0, br-underlay, "fc00::1/64", [], [], "nodad")
+AT_CHECK([ip addr add dev br-underlay "fc00::100/64" nodad])
+AT_CHECK([ip link set dev br-underlay up])
+
+dnl Set up tunnel endpoints on OVS outside the namespace and with a native
+dnl linux device inside the namespace.
+ADD_OVS_TUNNEL6([vxlan], [br0], [at_vxlan0], [fc00::1], [10.1.1.100/24])
+ADD_NATIVE_TUNNEL6([vxlan], [at_vxlan1], [at_ns0], [fc00::100], [10.1.1.1/24],
+ [id 0 dstport 4789 udp6zerocsumtx udp6zerocsumrx])
+
+OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00::100])
+
+dnl First, check the underlay
+NS_CHECK_EXEC([at_ns0], [ping6 -q -c 3 -i 0.3 -w 6 fc00::100 | FORMAT_PING], [0], [dnl
+3 packets transmitted, 3 received, 0% packet loss, time 0ms
+])
+
+dnl Okay, now check the overlay with different packet sizes
+NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 6 10.1.1.100 | FORMAT_PING], [0], [dnl
+3 packets transmitted, 3 received, 0% packet loss, time 0ms
+])
+
+OVS_TRAFFIC_VSWITCHD_STOP
+AT_CLEANUP
+
+AT_SETUP([datapath - ping over gre tunnel])
+OVS_CHECK_GRE()
+
+OVS_TRAFFIC_VSWITCHD_START()
+ADD_BR([br-underlay])
+on_exit 'ip link del br-underlay'
+
+AT_CHECK([ovs-ofctl add-flow br0 "actions=normal"])
+AT_CHECK([ovs-ofctl add-flow br-underlay "actions=normal"])
+
+ADD_NAMESPACES(at_ns0)
+
+dnl Set up underlay link from host into the namespace using veth pair.
+ADD_VETH(p0, at_ns0, br-underlay, "172.31.1.1/24")
+AT_CHECK([ip addr add dev br-underlay "172.31.1.100/24"])
+AT_CHECK([ip link set dev br-underlay up])
+
+dnl Set up tunnel endpoints on OVS outside the namespace and with a native
+dnl linux device inside the namespace.
+ADD_OVS_TUNNEL([gre], [br0], [at_gre0], [172.31.1.1], [10.1.1.100/24], [options:key=100])
+ADD_NATIVE_TUNNEL([gretap], [ns_gre0], [at_ns0], [172.31.1.100], [10.1.1.1/24], [key 100])
+
+dnl First, check the underlay
+NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 6 172.31.1.100 | FORMAT_PING], [0], [dnl
+3 packets transmitted, 3 received, 0% packet loss, time 0ms
+])
+
+dnl Okay, now check the overlay with different packet sizes
+NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 6 10.1.1.100 | FORMAT_PING], [0], [dnl
+3 packets transmitted, 3 received, 0% packet loss, time 0ms
+])
+
+OVS_TRAFFIC_VSWITCHD_STOP
+AT_CLEANUP
+
+AT_SETUP([datapath - ping over geneve tunnel])
+OVS_CHECK_GENEVE()
+
+OVS_TRAFFIC_VSWITCHD_START()
+ADD_BR([br-underlay])
+
+AT_CHECK([ovs-ofctl add-flow br0 "actions=normal"])
+AT_CHECK([ovs-ofctl add-flow br-underlay "actions=normal"])
+
+ADD_NAMESPACES(at_ns0)
+
+ip link del genev_sys_6081
+on_exit 'ip link del genev_sys_6081'
+on_exit 'ip link del br-underlay'
+
+dnl Set up underlay link from host into the namespace using veth pair.
+ADD_VETH(p0, at_ns0, br-underlay, "172.31.1.1/24")
+AT_CHECK([ip addr add dev br-underlay "172.31.1.100/24"])
+AT_CHECK([ip link set dev br-underlay up])
+
+dnl Set up tunnel endpoints on OVS outside the namespace and with a native
+dnl linux device inside the namespace.
+ADD_OVS_TUNNEL([geneve], [br0], [at_gnv0], [172.31.1.1], [10.1.1.100/24], [options:key=22])
+ADD_NATIVE_TUNNEL([geneve], [ns_gnv0], [at_ns0], [172.31.1.100], [10.1.1.1/24],
+ [vni 22])
+
+dnl First, check the underlay
+NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 2 172.31.1.100 | FORMAT_PING], [0], [dnl
+3 packets transmitted, 3 received, 0% packet loss, time 0ms
+])
+
+dnl Okay, now check the overlay with different packet sizes
+NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 6 10.1.1.100 | FORMAT_PING], [0], [dnl
+3 packets transmitted, 3 received, 0% packet loss, time 0ms
+])
+
+OVS_TRAFFIC_VSWITCHD_STOP
+AT_CLEANUP
+
+AT_SETUP([datapath - ping over geneve tunnel with TLV])
+OVS_CHECK_GENEVE()
+
+OVS_TRAFFIC_VSWITCHD_START()
+ADD_BR([br-underlay])
+
+AT_CHECK([ovs-ofctl add-tlv-map br0 "{class=0xffff,type=0,len=4}->tun_metadata0"])
+AT_CHECK([ovs-ofctl --protocols=OpenFlow15 add-flow br0 "actions=set_field:0xfaceb001->tun_metadata0, normal"])
+AT_CHECK([ovs-ofctl add-flow br-underlay "actions=normal"])
+
+ADD_NAMESPACES(at_ns0)
+
+ip link del genev_sys_6081
+on_exit 'ip link del genev_sys_6081'
+on_exit 'ip link del br-underlay'
+
+dnl Set up underlay link from host into the namespace using veth pair.
+ADD_VETH(p0, at_ns0, br-underlay, "172.31.1.1/24")
+AT_CHECK([ip addr add dev br-underlay "172.31.1.100/24"])
+AT_CHECK([ip link set dev br-underlay up])
+
+dnl Set up tunnel endpoints on OVS outside the namespace and with a native
+dnl linux device inside the namespace.
+ADD_OVS_TUNNEL([geneve], [br0], [at_gnv0], [172.31.1.1], [10.1.1.100/24], [options:key=22])
+ADD_NATIVE_TUNNEL([geneve], [ns_gnv0], [at_ns0], [172.31.1.100], [10.1.1.1/24],
+ [vni 22])
+
+dnl First, check the underlay
+NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 2 172.31.1.100 | FORMAT_PING], [0], [dnl
+3 packets transmitted, 3 received, 0% packet loss, time 0ms
+])
+
+dnl Okay, now check the overlay with different packet sizes
+NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 6 10.1.1.100 | FORMAT_PING], [0], [dnl
+3 packets transmitted, 3 received, 0% packet loss, time 0ms
+])
+
+OVS_TRAFFIC_VSWITCHD_STOP
+AT_CLEANUP
+
+
+AT_SETUP([datapath - ping over geneve6 tunnel])
+OVS_CHECK_GENEVE_UDP6ZEROCSUM()
+
+OVS_TRAFFIC_VSWITCHD_START()
+ADD_BR([br-underlay])
+
+AT_CHECK([ovs-ofctl add-flow br0 "actions=normal"])
+AT_CHECK([ovs-ofctl add-flow br-underlay "actions=normal"])
+
+ADD_NAMESPACES(at_ns0)
+
+dnl Set up underlay link from host into the namespace using veth pair.
+ADD_VETH(p0, at_ns0, br-underlay, "fc00::1/64", [], [], "nodad")
+AT_CHECK([ip addr add dev br-underlay "fc00::100/64" nodad])
+AT_CHECK([ip link set dev br-underlay up])
+
+dnl Set up tunnel endpoints on OVS outside the namespace and with a native
+dnl linux device inside the namespace.
+ADD_OVS_TUNNEL6([geneve], [br0], [at_gnv0], [fc00::1], [10.1.1.100/24])
+ADD_NATIVE_TUNNEL6([geneve], [ns_gnv0], [at_ns0], [fc00::100], [10.1.1.1/24],
+ [vni 0 udp6zerocsumtx udp6zerocsumrx])
+
+OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00::100])
+
+dnl First, check the underlay
+NS_CHECK_EXEC([at_ns0], [ping6 -q -c 3 -i 0.3 -w 2 fc00::100 | FORMAT_PING], [0], [dnl
+3 packets transmitted, 3 received, 0% packet loss, time 0ms
+])
+
+dnl Okay, now check the overlay with different packet sizes
+NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 6 10.1.1.100 | FORMAT_PING], [0], [dnl
+3 packets transmitted, 3 received, 0% packet loss, time 0ms
+])
+
+OVS_TRAFFIC_VSWITCHD_STOP
+AT_CLEANUP
+
+AT_SETUP([datapath - clone action])
+OVS_TRAFFIC_VSWITCHD_START()
+
+ADD_NAMESPACES(at_ns0, at_ns1, at_ns2)
+
+ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24")
+ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24")
+
+AT_CHECK([ovs-vsctl -- set interface ovs-p0 ofport_request=1 \
+ -- set interface ovs-p1 ofport_request=2])
+
+AT_DATA([flows.txt], [dnl
+priority=1 actions=NORMAL
+priority=10 in_port=1,ip,actions=clone(mod_dl_dst(50:54:00:00:00:0a),set_field:192.168.3.3->ip_dst), output:2
+priority=10 in_port=2,ip,actions=clone(mod_dl_src(ae:c6:7e:54:8d:4d),mod_dl_dst(50:54:00:00:00:0b),set_field:192.168.4.4->ip_dst, controller), output:1
+])
+AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
+
+AT_CHECK([ovs-ofctl monitor br0 65534 invalid_ttl --detach --no-chdir --pidfile 2> ofctl_monitor.log])
+NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 6 10.1.1.2 | FORMAT_PING], [0], [dnl
+3 packets transmitted, 3 received, 0% packet loss, time 0ms
+])
+
+AT_CHECK([cat ofctl_monitor.log | STRIP_MONITOR_CSUM], [0], [dnl
+icmp,vlan_tci=0x0000,dl_src=ae:c6:7e:54:8d:4d,dl_dst=50:54:00:00:00:0b,nw_src=10.1.1.2,nw_dst=192.168.4.4,nw_tos=0,nw_ecn=0,nw_ttl=64,icmp_type=0,icmp_code=0 icmp_csum: <skip>
+icmp,vlan_tci=0x0000,dl_src=ae:c6:7e:54:8d:4d,dl_dst=50:54:00:00:00:0b,nw_src=10.1.1.2,nw_dst=192.168.4.4,nw_tos=0,nw_ecn=0,nw_ttl=64,icmp_type=0,icmp_code=0 icmp_csum: <skip>
+icmp,vlan_tci=0x0000,dl_src=ae:c6:7e:54:8d:4d,dl_dst=50:54:00:00:00:0b,nw_src=10.1.1.2,nw_dst=192.168.4.4,nw_tos=0,nw_ecn=0,nw_ttl=64,icmp_type=0,icmp_code=0 icmp_csum: <skip>
+])
+
+OVS_TRAFFIC_VSWITCHD_STOP
+AT_CLEANUP
+
+AT_SETUP([datapath - mpls actions])
+OVS_TRAFFIC_VSWITCHD_START([_ADD_BR([br1])])
+
+ADD_NAMESPACES(at_ns0, at_ns1)
+
+ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24")
+ADD_VETH(p1, at_ns1, br1, "10.1.1.2/24")
+
+AT_CHECK([ip link add patch0 type veth peer name patch1])
+on_exit 'ip link del patch0'
+
+AT_CHECK([ip link set dev patch0 up])
+AT_CHECK([ip link set dev patch1 up])
+AT_CHECK([ovs-vsctl add-port br0 patch0])
+AT_CHECK([ovs-vsctl add-port br1 patch1])
+
+AT_DATA([flows.txt], [dnl
+table=0,priority=100,dl_type=0x0800 actions=push_mpls:0x8847,set_mpls_label:3,resubmit(,1)
+table=0,priority=100,dl_type=0x8847,mpls_label=3 actions=pop_mpls:0x0800,resubmit(,1)
+table=0,priority=10 actions=resubmit(,1)
+table=1,priority=10 actions=normal
+])
+
+AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
+AT_CHECK([ovs-ofctl add-flows br1 flows.txt])
+
+NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 6 10.1.1.2 | FORMAT_PING], [0], [dnl
+3 packets transmitted, 3 received, 0% packet loss, time 0ms
+])
+
+NS_CHECK_EXEC([at_ns1], [ping -q -c 3 -i 0.3 -w 6 10.1.1.1 | FORMAT_PING], [0], [dnl
+3 packets transmitted, 3 received, 0% packet loss, time 0ms
+])
+
+OVS_TRAFFIC_VSWITCHD_STOP
+AT_CLEANUP
+AT_SETUP([datapath - basic truncate action])
+AT_SKIP_IF([test $HAVE_NC = no])
+OVS_TRAFFIC_VSWITCHD_START()
+AT_CHECK([ovs-ofctl del-flows br0])
+
+dnl Create p0 and ovs-p0(1)
+ADD_NAMESPACES(at_ns0)
+ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24")
+NS_CHECK_EXEC([at_ns0], [ip link set dev p0 address e6:66:c1:11:11:11])
+NS_CHECK_EXEC([at_ns0], [arp -s 10.1.1.2 e6:66:c1:22:22:22])
+
+dnl Create p1(3) and ovs-p1(2), packets received from ovs-p1 will appear in p1
+AT_CHECK([ip link add p1 type veth peer name ovs-p1])
+on_exit 'ip link del ovs-p1'
+AT_CHECK([ip link set dev ovs-p1 up])
+AT_CHECK([ip link set dev p1 up])
+AT_CHECK([ovs-vsctl add-port br0 ovs-p1 -- set interface ovs-p1 ofport_request=2])
+dnl Use p1 to check the truncated packet
+AT_CHECK([ovs-vsctl add-port br0 p1 -- set interface p1 ofport_request=3])
+
+dnl Create p2(5) and ovs-p2(4)
+AT_CHECK([ip link add p2 type veth peer name ovs-p2])
+on_exit 'ip link del ovs-p2'
+AT_CHECK([ip link set dev ovs-p2 up])
+AT_CHECK([ip link set dev p2 up])
+AT_CHECK([ovs-vsctl add-port br0 ovs-p2 -- set interface ovs-p2 ofport_request=4])
+dnl Use p2 to check the truncated packet
+AT_CHECK([ovs-vsctl add-port br0 p2 -- set interface p2 ofport_request=5])
+
+dnl basic test
+AT_CHECK([ovs-ofctl del-flows br0])
+AT_DATA([flows.txt], [dnl
+in_port=3 dl_dst=e6:66:c1:22:22:22 actions=drop
+in_port=5 dl_dst=e6:66:c1:22:22:22 actions=drop
+in_port=1 dl_dst=e6:66:c1:22:22:22 actions=output(port=2,max_len=100),output:4
+])
+AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
+
+dnl use this file as payload file for ncat
+AT_CHECK([dd if=/dev/urandom of=payload200.bin bs=200 count=1 2> /dev/null])
+on_exit 'rm -f payload200.bin'
+NS_CHECK_EXEC([at_ns0], [nc $NC_EOF_OPT -u 10.1.1.2 1234 < payload200.bin])
+
+dnl packet with truncated size
+AT_CHECK([ovs-appctl revalidator/purge], [0])
+AT_CHECK([ovs-ofctl dump-flows br0 table=0 | grep "in_port=3" | sed -n 's/.*\(n\_bytes=[[0-9]]*\).*/\1/p'], [0], [dnl
+n_bytes=100
+])
+dnl packet with original size
+AT_CHECK([ovs-appctl revalidator/purge], [0])
+AT_CHECK([ovs-ofctl dump-flows br0 table=0 | grep "in_port=5" | sed -n 's/.*\(n\_bytes=[[0-9]]*\).*/\1/p'], [0], [dnl
+n_bytes=242
+])
+
+dnl more complicated output actions
+AT_CHECK([ovs-ofctl del-flows br0])
+AT_DATA([flows.txt], [dnl
+in_port=3 dl_dst=e6:66:c1:22:22:22 actions=drop
+in_port=5 dl_dst=e6:66:c1:22:22:22 actions=drop
+in_port=1 dl_dst=e6:66:c1:22:22:22 actions=output(port=2,max_len=100),output:4,output(port=2,max_len=100),output(port=4,max_len=100),output:2,output(port=4,max_len=200),output(port=2,max_len=65535)
+])
+AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
+
+NS_CHECK_EXEC([at_ns0], [nc $NC_EOF_OPT -u 10.1.1.2 1234 < payload200.bin])
+
+dnl 100 + 100 + 242 + min(65535,242) = 684
+AT_CHECK([ovs-appctl revalidator/purge], [0])
+AT_CHECK([ovs-ofctl dump-flows br0 table=0 | grep "in_port=3" | sed -n 's/.*\(n\_bytes=[[0-9]]*\).*/\1/p'], [0], [dnl
+n_bytes=684
+])
+dnl 242 + 100 + min(242,200) = 542
+AT_CHECK([ovs-ofctl dump-flows br0 table=0 | grep "in_port=5" | sed -n 's/.*\(n\_bytes=[[0-9]]*\).*/\1/p'], [0], [dnl
+n_bytes=542
+])
+
+dnl SLOW_ACTION: disable kernel datapath truncate support
+dnl Repeat the test above, but exercise the SLOW_ACTION code path
+AT_CHECK([ovs-appctl dpif/set-dp-features br0 trunc false], [0])
+
+dnl SLOW_ACTION test1: check datapatch actions
+AT_CHECK([ovs-ofctl del-flows br0])
+AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
+
+AT_CHECK([ovs-appctl ofproto/trace br0 "in_port=1,dl_type=0x800,dl_src=e6:66:c1:11:11:11,dl_dst=e6:66:c1:22:22:22,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=6,tp_src=8,tp_dst=9"], [0], [stdout])
+AT_CHECK([tail -3 stdout], [0],
+[Datapath actions: trunc(100),3,5,trunc(100),3,trunc(100),5,3,trunc(200),5,trunc(65535),3
+This flow is handled by the userspace slow path because it:
+ - Uses action(s) not supported by datapath.
+])
+
+dnl SLOW_ACTION test2: check actual packet truncate
+AT_CHECK([ovs-ofctl del-flows br0])
+AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
+NS_CHECK_EXEC([at_ns0], [nc $NC_EOF_OPT -u 10.1.1.2 1234 < payload200.bin])
+
+dnl 100 + 100 + 242 + min(65535,242) = 684
+AT_CHECK([ovs-appctl revalidator/purge], [0])
+AT_CHECK([ovs-ofctl dump-flows br0 table=0 | grep "in_port=3" | sed -n 's/.*\(n\_bytes=[[0-9]]*\).*/\1/p'], [0], [dnl
+n_bytes=684
+])
+
+dnl 242 + 100 + min(242,200) = 542
+AT_CHECK([ovs-ofctl dump-flows br0 table=0 | grep "in_port=5" | sed -n 's/.*\(n\_bytes=[[0-9]]*\).*/\1/p'], [0], [dnl
+n_bytes=542
+])
+
+OVS_TRAFFIC_VSWITCHD_STOP
+AT_CLEANUP
+
+dnl Create 2 bridges and 2 namespaces to test truncate over
+dnl GRE tunnel:
+dnl br0: overlay bridge
+dnl ns1: connect to br0, with IP:10.1.1.2
+dnl br-underlay: with IP: 172.31.1.100
+dnl ns0: connect to br-underlay, with IP: 10.1.1.1
+AT_SETUP([datapath - truncate and output to gre tunnel])
+AT_SKIP_IF([test $HAVE_NC = no])
+OVS_CHECK_GRE()
+OVS_TRAFFIC_VSWITCHD_START()
+
+ADD_BR([br-underlay])
+ADD_NAMESPACES(at_ns0)
+ADD_NAMESPACES(at_ns1)
+AT_CHECK([ovs-ofctl add-flow br0 "actions=normal"])
+AT_CHECK([ovs-ofctl add-flow br-underlay "actions=normal"])
+
+dnl Set up underlay link from host into the namespace using veth pair.
+ADD_VETH(p0, at_ns0, br-underlay, "172.31.1.1/24")
+AT_CHECK([ip addr add dev br-underlay "172.31.1.100/24"])
+AT_CHECK([ip link set dev br-underlay up])
+
+dnl Set up tunnel endpoints on OVS outside the namespace and with a native
+dnl linux device inside the namespace.
+ADD_OVS_TUNNEL([gre], [br0], [at_gre0], [172.31.1.1], [10.1.1.100/24])
+ADD_NATIVE_TUNNEL([gretap], [ns_gre0], [at_ns0], [172.31.1.100], [10.1.1.1/24],
+ [], [address e6:66:c1:11:11:11])
+AT_CHECK([ovs-vsctl -- set interface at_gre0 ofport_request=1])
+NS_CHECK_EXEC([at_ns0], [arp -s 10.1.1.2 e6:66:c1:22:22:22])
+
+dnl Set up (p1 and ovs-p1) at br0
+ADD_VETH(p1, at_ns1, br0, '10.1.1.2/24')
+AT_CHECK([ovs-vsctl -- set interface ovs-p1 ofport_request=2])
+NS_CHECK_EXEC([at_ns1], [ip link set dev p1 address e6:66:c1:22:22:22])
+NS_CHECK_EXEC([at_ns1], [arp -s 10.1.1.1 e6:66:c1:11:11:11])
+
+dnl Set up (p2 and ovs-p2) as loopback for verifying packet size
+AT_CHECK([ip link add p2 type veth peer name ovs-p2])
+on_exit 'ip link del ovs-p2'
+AT_CHECK([ip link set dev ovs-p2 up])
+AT_CHECK([ip link set dev p2 up])
+AT_CHECK([ovs-vsctl add-port br0 ovs-p2 -- set interface ovs-p2 ofport_request=3])
+AT_CHECK([ovs-vsctl add-port br0 p2 -- set interface p2 ofport_request=4])
+
+dnl use this file as payload file for ncat
+AT_CHECK([dd if=/dev/urandom of=payload200.bin bs=200 count=1 2> /dev/null])
+on_exit 'rm -f payload200.bin'
+
+AT_CHECK([ovs-ofctl del-flows br0])
+AT_DATA([flows.txt], [dnl
+priority=99,in_port=1,actions=output(port=2,max_len=100),output(port=3,max_len=100)
+priority=99,in_port=2,udp,actions=output(port=1,max_len=100)
+priority=1,in_port=4,ip,actions=drop
+priority=1,actions=drop
+])
+AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
+
+AT_CHECK([ovs-ofctl del-flows br-underlay])
+AT_DATA([flows-underlay.txt], [dnl
+priority=99,dl_type=0x0800,nw_proto=47,in_port=1,actions=LOCAL
+priority=99,dl_type=0x0800,nw_proto=47,in_port=LOCAL,ip_dst=172.31.1.1/24,actions=1
+priority=1,actions=drop
+])
+
+AT_CHECK([ovs-ofctl add-flows br-underlay flows-underlay.txt])
+
+dnl check tunnel push path, from at_ns1 to at_ns0
+NS_CHECK_EXEC([at_ns1], [nc $NC_EOF_OPT -u 10.1.1.1 1234 < payload200.bin])
+AT_CHECK([ovs-appctl revalidator/purge], [0])
+
+dnl Before truncation = ETH(14) + IP(20) + UDP(8) + 200 = 242B
+AT_CHECK([ovs-ofctl dump-flows br0 | grep "in_port=2" | sed -n 's/.*\(n\_bytes=[[0-9]]*\).*/\1/p'], [0], [dnl
+n_bytes=242
+])
+dnl After truncation = outer ETH(14) + outer IP(20) + GRE(4) + 100 = 138B
+AT_CHECK([ovs-ofctl dump-flows br-underlay | grep "in_port=LOCAL" | sed -n 's/.*\(n\_bytes=[[0-9]]*\).*/\1/p'], [0], [dnl
+n_bytes=138
+])
+
+dnl check tunnel pop path, from at_ns0 to at_ns1
+NS_CHECK_EXEC([at_ns0], [nc $NC_EOF_OPT -u 10.1.1.2 5678 < payload200.bin])
+dnl After truncation = 100 byte at loopback device p2(4)
+AT_CHECK([ovs-appctl revalidator/purge], [0])
+AT_CHECK([ovs-ofctl dump-flows br0 | grep "in_port=4" | ofctl_strip], [0], [dnl
+ n_packets=1, n_bytes=100, priority=1,ip,in_port=4 actions=drop
+])
+
+dnl SLOW_ACTION: disable datapath truncate support
+dnl Repeat the test above, but exercise the SLOW_ACTION code path
+AT_CHECK([ovs-appctl dpif/set-dp-features br0 trunc false], [0])
+
+dnl SLOW_ACTION test1: check datapatch actions
+AT_CHECK([ovs-ofctl del-flows br0])
+AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
+
+dnl SLOW_ACTION test2: check actual packet truncate
+AT_CHECK([ovs-ofctl del-flows br0])
+AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
+AT_CHECK([ovs-ofctl del-flows br-underlay])
+AT_CHECK([ovs-ofctl add-flows br-underlay flows-underlay.txt])
+
+dnl check tunnel push path, from at_ns1 to at_ns0
+NS_CHECK_EXEC([at_ns1], [nc $NC_EOF_OPT -u 10.1.1.1 1234 < payload200.bin])
+AT_CHECK([ovs-appctl revalidator/purge], [0])
+
+dnl Before truncation = ETH(14) + IP(20) + UDP(8) + 200 = 242B
+AT_CHECK([ovs-ofctl dump-flows br0 | grep "in_port=2" | sed -n 's/.*\(n\_bytes=[[0-9]]*\).*/\1/p'], [0], [dnl
+n_bytes=242
+])
+dnl After truncation = outer ETH(14) + outer IP(20) + GRE(4) + 100 = 138B
+AT_CHECK([ovs-ofctl dump-flows br-underlay | grep "in_port=LOCAL" | sed -n 's/.*\(n\_bytes=[[0-9]]*\).*/\1/p'], [0], [dnl
+n_bytes=138
+])
+
+dnl check tunnel pop path, from at_ns0 to at_ns1
+NS_CHECK_EXEC([at_ns0], [nc $NC_EOF_OPT -u 10.1.1.2 5678 < payload200.bin])
+dnl After truncation = 100 byte at loopback device p2(4)
+AT_CHECK([ovs-appctl revalidator/purge], [0])
+AT_CHECK([ovs-ofctl dump-flows br0 | grep "in_port=4" | ofctl_strip], [0], [dnl
+ n_packets=1, n_bytes=100, priority=1,ip,in_port=4 actions=drop
+])
+
+OVS_TRAFFIC_VSWITCHD_STOP
+AT_CLEANUP
+
+
+dnl simple test case for BPF
+AT_SETUP([ovn -- 1 LR connects 2 LSes])
+AT_KEYWORDS([ovnbpf])
+
+ovn_start
+OVS_TRAFFIC_VSWITCHD_START()
+ADD_BR([br-int])
+
+# Set external-ids in br-int needed for ovn-controller
+# Use vxlan here
+ovs-vsctl \
+ -- set Open_vSwitch . external-ids:system-id=hv1 \
+ -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
+ -- set Open_vSwitch . external-ids:ovn-encap-type=vxlan \
+ -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
+ -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
+
+# Start ovn-controller
+start_daemon ovn-controller
+
+# Logical network:
+# 1 LR - R1 and 2 LSes foo and bar R1 has switchess foo (192.168.1.0/24)
+# and # bar (192.168.2.0/24) connected to it.
+#
+# foo ------- R1 ------- bar
+# 192.168.1.0/24 192.168.2.0/24
+#
+
+ovn-nbctl create Logical_Router name=R1
+
+ovn-nbctl ls-add foo
+ovn-nbctl ls-add bar
+
+# Connect foo to R1
+ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
+ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
+ type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
+
+# Connect bar to R1
+ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
+ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
+ type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
+
+# Logical port 'foo1' in switch 'foo'.
+ADD_NAMESPACES(foo1)
+ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
+ "192.168.1.1")
+ovn-nbctl lsp-add foo foo1 \
+ -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
+
+ADD_NAMESPACES(bar1)
+ADD_VETH(bar1, bar1, br-int, "192.168.2.2/24", "f0:00:00:01:02:05", \
+"192.168.2.1")
+ovn-nbctl lsp-add bar bar1 \
+ -- lsp-set-addresses bar1 "f0:00:00:01:02:05 192.168.2.2"
+
+# wait for ovn-controller to catch up.
+ovn-nbctl --wait=hv sync
+
+# 'bar1' should be able to ping 'foo1' directly.
+NS_CHECK_EXEC([bar1], [ping -q -c 3 -i 0.3 -w 8 192.168.1.2 | FORMAT_PING], \
+[0], [dnl
+3 packets transmitted, 3 received, 0% packet loss, time 0ms
+])
+
+OVS_APP_EXIT_AND_WAIT([ovn-controller])
+
+as ovn-sb
+OVS_APP_EXIT_AND_WAIT([ovsdb-server])
+
+as ovn-nb
+OVS_APP_EXIT_AND_WAIT([ovsdb-server])
+
+as northd
+OVS_APP_EXIT_AND_WAIT([ovn-northd])
+
+as
+OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
+/connection dropped.*/d"])
+AT_CLEANUP
+
--
2.7.4


[RFC PATCHv2 11/13] vagrant: add ebpf support using ubuntu/bionic

William Tu
 

VAGRANT_VAGRANTFILE=Vagrantfile-eBPF vagrant up

Signed-off-by: William Tu <u9012063@...>
Signed-off-by: Yifeng Sun <pkusunyifeng@...>
---
Makefile.am | 1 +
Vagrantfile-eBPF | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 100 insertions(+)
create mode 100644 Vagrantfile-eBPF

diff --git a/Makefile.am b/Makefile.am
index ec1fc53b1060..d26c765a285a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -86,6 +86,7 @@ EXTRA_DIST = \
$(MAN_ROOTS) \
Vagrantfile \
Vagrantfile-FreeBSD \
+ Vagrantfile-eBPF \
.mailmap
bin_PROGRAMS =
sbin_PROGRAMS =
diff --git a/Vagrantfile-eBPF b/Vagrantfile-eBPF
new file mode 100644
index 000000000000..7b9be32b8f03
--- /dev/null
+++ b/Vagrantfile-eBPF
@@ -0,0 +1,99 @@
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+
+$bootstrap = <<SCRIPT
+ pwd
+ apt-get update
+ apt-get -y install \
+ build-essential dpkg-dev lintian devscripts fakeroot \
+ debhelper dh-autoreconf uuid-runtime \
+ autoconf automake libtool \
+ python-all python-twisted-core python-twisted-conch \
+ xdg-utils groff graphviz netcat curl \
+ wget python-six ethtool \
+ libcap-ng-dev libssl-dev python-dev openssl \
+ python-pyftpdlib python-flake8 python-tftpy \
+ linux-headers-`uname -r`
+ apt-get install -y cmake libbison-dev bison flex bc libelf-dev
+ apt-get install -y libmnl-dev gcc-multilib libc6-dev-i386 pkg-config
+SCRIPT
+
+$install_iproute2 = <<SCRIPT
+ pwd
+ mkdir -p build
+ cd build
+ rm -rf iproute2
+ git clone git://git.kernel.org/pub/scm/network/iproute2/iproute2.git && \
+ cd iproute2 && \
+ ./configure && \
+ make -j `getconf _NPROCESSORS_ONLN` && make install
+SCRIPT
+
+$install_llvm = <<SCRIPT
+ pwd
+ cd build
+ curl -Ssl -o clang+llvm.tar.xz http://releases.llvm.org/3.8.1/clang+llvm-3.8.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz
+ tar -C /usr/local -xJf ./clang+llvm.tar.xz || true
+ mv /usr/local/clang+llvm-3.8.1-x86_64-linux-gnu-ubuntu-16.04 /usr/local/clang+llvm || true
+ rm -f clang+llvm.tar.xz
+ export PATH="/usr/local/clang+llvm/bin:$PATH"
+ llc --version
+ clang --version
+SCRIPT
+
+$install_libbpf = <<SCRIPT
+ pwd
+ cd build
+ rm -rf linux
+ git clone --branch v4.15 --depth 1 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
+ cd linux && make defconfig && make -C tools/lib/bpf/ && cd tools/lib/bpf/ && make install
+SCRIPT
+
+$build_ovs = <<SCRIPT
+ cd /home/vagrant/ovs
+ pwd
+ export PATH="/usr/local/clang+llvm/bin:$PATH"
+ which clang
+ which llc
+ pwd
+ make distclean
+ ./boot.sh
+ sudo ./configure --with-bpf=/home/vagrant/build/linux/tools/
+ make
+SCRIPT
+
+$ovs_check = <<SCRIPT
+ pwd
+ cd /home/vagrant/ovs
+ sudo make check TESTSUITEFLAGS='1'
+SCRIPT
+
+$sparse_check = <<SCRIPT
+ pwd
+ cd /home/vagrant/ovs
+ touch lib/dpif-bpf-odp.c
+ touch lib/dpif-bpf.c
+ make C=1 CF="-Wsparse-all -D__CHECKER__ -D__CHECK_ENDIAN__ -Wbitwise" lib/dpif-bpf-odp.o
+ make C=1 CF="-Wsparse-all -D__CHECKER__ -D__CHECK_ENDIAN__ -Wbitwise" lib/dpif-bpf.o
+SCRIPT
+
+$ovs_check_bpf = <<SCRIPT
+ pwd
+ cd /home/vagrant/ovs
+ export LD_LIBRARY_PATH=/home/vagrant/build/linux/tools/lib/bpf/:$LD_LIBRARY_PATH
+ export PATH="/usr/local/clang+llvm/bin:$PATH"
+ objdump -h /home/vagrant/ovs/bpf/datapath.o
+ sudo make check-bpf TESTSUITEFLAGS='1'
+SCRIPT
+
+Vagrant.configure("2") do |config|
+ config.vm.box = "ubuntu/bionic64"
+ config.vm.synced_folder ".", "/home/vagrant/ovs"
+
+ config.vm.provision "bootstrap", type: "shell", inline: $bootstrap
+ config.vm.provision "install_iproute2", type: "shell", inline: $install_iproute2
+ config.vm.provision "install_llvm", type: "shell", inline: $install_llvm
+ config.vm.provision "install_libbpf", type: "shell", inline: $install_libbpf
+ config.vm.provision "build_ovs", type: "shell", inline: $build_ovs
+ config.vm.provision "ovs_check", type: "shell", inline: $ovs_check
+end
--
2.7.4

621 - 640 of 2015