Comments (16)
Thank you for your prompt reply.
Yes, I can see the contents of ebpf_outTable generated by xdp5.p4 with command :
bpftool map dump pinned /sys/fs/bpf/xdp/globals/ebpf_outTable
the output is
key:
00 00 00 00
value (CPU 00): 00 00 00 00
value (CPU 01): 01 00 00 00
value (CPU 02): 00 00 00 00
value (CPU 03): 00 00 00 00
value (CPU 04): 00 00 00 00
value (CPU 05): 00 00 00 00
value (CPU 06): 00 00 00 00
value (CPU 07): 00 00 00 00
Found 1 element
Do you have any simple examples that using TC cooperating with xdp program generated by P4C-XDP to send raw packets from one NIC to another . The xdp program just pass packets. Then TC receives the packets and send to another NIC.
Really appreciate your help!
from p4c-xdp.
The work in the compiler to support XDP_REDIRECT is very simple.
At the time we implemented this it wasn't supported by the kernel. Maybe this has changed.
@williamtu : do you know how one has to proceed to use XDP_REDIRECT?
from p4c-xdp.
In fact, no work in the compiler is needed. You can just add XDP_REDIRECT to the p4include/xdp_model.p4 file and it will produce the right C. I will submit a PR. However, I still don't know how you should use it.
from p4c-xdp.
Thank you for your prompt reply.
After I add XDP_REDIRECT to the xdp_model.p4 , I can successfully compile the xdp program with XDP_REDIRECT .
I guess the xout.output_port is related to different NICs. For example , output_port set to 0 corresponds to eth1 and 1 corresponds to eth2. Then I still set output_port as 0 and output_action as XDP_REDIRECT to implement the same function of XDP_TX transmitting received packets to the same NIC eth0.
if(hd.ipv4.isValid())
{
dstmactable.apply();
xout.output_port = 0;
xout.output_action = xoutdrop ? xdp_action.XDP_DROP : xdp_action.XDP_REDIRECT;
}
and the generated xdp5.c file :
xout.output_port = 0;
if (xoutdrop_0)
tmp = XDP_DROP;
else
tmp = XDP_REDIRECT;
xout.output_action = tmp;
However, I cannot capture any transmitted packets . And then I did another test to set the out_port as 1 and output_action as XDP_REDIRECT to see if I can capture packets in the eth1. Unfortunately still cannot.
So how to implement sending packets to different NIC using XDP_REDIRECT and how to specify the NIC id ? Is it the output_port to specify which NIC to redirect to ?
I see there is a map, called ebpf_outTable, only has one max_entries in /sys/fs/bpf/xdp/ . Is this map used to specify different NICs cooperating with XDP_REDIRECT ?
Thank you for your attention to this matter. It would be nice if you could provide a bit more information on this question.
from p4c-xdp.
Hi,
XDP_REDIRECT requires using a map, ebpf_outTable, to lookup the output port.
And the now we send packet using TC, not XDP, by calling a bpf helper function called bpf_clone_redirect.
For example, if you want to send to eth8, eth8's ifindex should be programmed into the value of the map.
Are you able to see the contents in the ebpf_outTable? ex: by using the bpftool?
Thanks
from p4c-xdp.
Actually the ebpf_outTable only has one entry in the xdp.c file. And how to specify the max_entries of this map in P4 program? Do you know how to specify which NIC to send packets in P4 program ?
I guess maybe the xout.output_port in P4 program is the ebpf_outTable's key and NIC's ifindex is the value ?
It would be nice if you could provide a bit more information on this question.
from p4c-xdp.
So looking into more details, XDP_REDIRECT is not fully supported now.
The way p4c-xdp implemented redirect or send to another port is to use TC.
So idea is that the XDP program always return XDP_PASS, and the packet will
go to the TC layer.
At the TC layer, we have to insert another ebpf program to forward this packet,
based on the lookup result of ebpf_outTable.
So in your case, it doesn't work because you need another ebpf program attached to TC.
The reason we did this is because at the time we started the project, there is no XDP_REDIRECT support.
Now the right way to do XDP_REDIRECT is through BPF_MAP_TYPE_DEVMAP
see this slide for more details
http://people.netfilter.org/hawk/presentations/LLC2018/XDP_LLC2018_redirect.pdf
In this way, we don't need TC to send packet, the packet will be handled at XDP layer.
from p4c-xdp.
Actually the ebpf_outTable only has one entry in the xdp.c file. And how to specify the max_entries of this map in P4 program? Do you know how to specify which NIC to send packets in P4 program ?
hash_table(64), example below:
table dstmactable {
key = { hd.ethernet.protocol : exact; }
actions = {
Fallback_action;
Drop_action;
}
default_action = Fallback_action;
implementation = hash_table(64);
}
to send to a nic, get the nic's ifindex, and program the <key, value> to <port, ifindex> into the
ebpf_outTable.
I guess maybe the xout.output_port in P4 program is the ebpf_outTable's key and NIC's ifindex is the value ?
Yes, that's right
from p4c-xdp.
Hi,
Thanks a lot for your help. Do you have any simple ebpf program attched to TC which uses ebpf_outTable to send raw packets from one NIC to another ?
from p4c-xdp.
Yes, the hash_table(64) can appoint the dstmactable's max entries. Actually I want to specify the max entries of ebpf_outTable. However, it seems that there is no method to specify this in P4 program .
And as for the forwarding workflow , I guess it's maybe like this:
First, user knows which packet should be passed to the TC layer to be forwarded. For example , user wants the packet , which dst IP address is 10.0.0.1 , received from eth0 to be passed to TC and forwarded to eth8. So the P4 table might like this :
action Fallback_action {
xout.output_port = 8;
xout.output_action = XDP_PASS;
}
table dstmactable {
key = { hd.ipv4.dstAddr : exact; }
actions = {
Fallback_action;
Drop_action;
}
default_action = Drop_action;
implementation = hash_table(64);
}
the table entry is
key | actions |
---|---|
10.0.0.1 | Fallback_action |
It means that once a packet whose dst IP address is 10.0.0.1 from eth0 arrives at XDP layer, the XDP program will match the first entry of dstmactable and set output_port = 8 and pass the packet to TC layer. And all this actions don't have effect on the ebpf_outTable.
Second, user knows that once TC layer receives a packet , that packet must be the one which user wants to forward. In this case , only packet of which the dst ip address is equal to 10.0.0.1 will be passed to TC.
So , user updates the ebpf_outTable by adding <output_port , ifindex > to ebpf_outTable:
key | value |
---|---|
8 | 666 |
the 8 is the output port number which P4 program sets. And 666 is the eth8's ifindex.
Third, user writes another ebpf program to attach to TC layer. Once TC gets packets, it looks up the ebpf_outTable by using output port 8 as key which assigned in P4 program and gets the ifindex of NIC . After that , TC calls bpf_clone_redirect helper function to forward this packet to the eth8's egress.
And here is the question:
How would TC know the output port is 8 . I mean, in TC layer , TC only gets the raw packets and no other information. And how the P4 program transfer the output port information to TC . Or the user just knows it and sets the output port as a static number in TC's ebpf program ? But in this way, it seems the output_port field belongs to struct xout
in P4 program is no use. User could assign any number as key because only the ifindex is valuable . And what if user wants to forward to a third interface, the method of setting the output port as a static number won't work well.
What I think is that if TC wants to know which interface egress should be selected to forward packets , TC must parse the packet and get the dst IP address. But that might seem like overkill.
from p4c-xdp.
Hi,
Thanks a lot for your help. Do you have any simple ebpf program attched to TC which uses ebpf_outTable to send raw packets from one NIC to another ?
I don't have an exactly working example, but you can follow this sample code
https://elixir.bootlin.com/linux/latest/source/samples/bpf/tcbpf1_kern.c
which uses bpf_clone_redirect and specify ifindex for output packet
from p4c-xdp.
And here is the question:
How would TC know the output port is 8 . I mean, in TC layer , TC only gets the raw packets and no other information. And how the P4 program transfer the output port information to TC . Or the user just knows it and sets the output port as a static number in TC's ebpf program ? But in this way, it seems the output_port field belongs tostruct xout
in P4 program is no use. User could assign any number as key because only the ifindex is valuable . And what if user wants to forward to a third interface, the method of setting the output port as a static number won't work well.
What I think is that if TC wants to know which interface egress should be selected to forward packets , TC must parse the packet and get the dst IP address. But that might seem like overkill.
TC doesn't need to know key is 8, all TC does is to get the first entry in the map and output the packet to the ifindex 888.
And every time before the packet pass XDP layer, the map entry will be updated for the coming packet arriving at TC layer. So we don't need to parse the packet again at the TC layer.
from p4c-xdp.
Hi,
Is there any update on doing XDP_REDIRECT without using TC?
from p4c-xdp.
Technically I don't think any changes need to be made in the compiler; it's probably just the control-plane setup that needs to be adapted. I personally don't have a machine where I can test XDP; I don't know if @williamtu has time to build an example.
from p4c-xdp.
Using code generated by p4c-xdp, I was not able to redirect.
Used redirect_map helper inside XDP code to redirect packets successfully.
from p4c-xdp.
Can you contribute an example?
from p4c-xdp.
Related Issues (20)
- Unexpected behavior when running xdp3.o HOT 6
- how to implement a forwoading function using XDP_TX based on xdp7.p4 HOT 1
- What is the difference between bpf_obj_get() in libbpf.h and BPF_OBJ_GET() in init_tables() HOT 3
- changing reject to accept introduce stack increaseing HOT 9
- compiler support for lpm HOT 5
- compiler support for range lookup HOT 10
- invalid indirect read from stack off HOT 3
- ebpf_ipv4_checksum Not working HOT 1
- Compiler support for htons, htonl, htonll HOT 2
- Compiler support for registers and hash functions HOT 3
- [doc] Vagrant image name HOT 2
- [Q] Vagrant image HOT 1
- Resource Leak
- Using XDP with clang/llvm version 9 HOT 3
- How to include ebpf_xdp.h HOT 3
- Adding PERCPU_ARRAY Question HOT 2
- p4x-xdp support for PSA HOT 9
- Test 17 fails HOT 1
- XDP metadata support HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from p4c-xdp.