Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable tunneling/encapsulation #1

Open
mscastanho opened this issue Apr 11, 2018 · 5 comments
Open

Enable tunneling/encapsulation #1

mscastanho opened this issue Apr 11, 2018 · 5 comments

Comments

@mscastanho
Copy link

Hi, I wanted to use BPFabric to create a switch capable of performing encapsulation using a custom-made protocol. For this to happen, I would need to add a new protocol header between existing headers (ex. after Ethernet and before IP). But by the examples provided I'm actually having a hard time figuring out how I could accomplish that.

I know I can get the packet's length from the packet's metadata. From there, I would need to allocate a new buffer to fit the original packet + the new header (since there probably won't be enough space left in the original buffer). But from this point on, I don't see a way to pass this new buffer back to the switch so this new modified packet is sent.

Is it even possible? If so, what are my options? Could I make any changes to the source code to allow this?

Thank you in advance.

@simon-jouet
Copy link
Contributor

Hi @mscastanho,

The tunneling/encapsulation is not implemented in the current version of BPFabric, that was something planned for a future phase. However getting it implemented is probably fairly straightforward.

Are you using the softswitch implementation or the DPDK implementation? In either case the easiest approach would be to define a new function available in BPF to push or pop a header from the front of the packet and then implement it in the softswitch or DPDK.

In DPDK it would likely be a call to something like rte_pktmbuf_prepend to allocate some space at the front of the packet (on push) and rte_pktmbuf_adj (on pop).

In the softswitch implementation the implementation would likely allocate/remove some space after/before the ethernet header (at the moment the frame is metadata + ethernet and when sending the metadata is stripped away https://github.com/UofG-netlab/BPFabric/blob/master/softswitch/main.c#L332)

@mscastanho
Copy link
Author

Thanks for the prompt response @simon-jouet,

I'm working on the changes as of now. For now I'll be focusing on the softswitch. It took me a while to get around the code, but now I'm starting to grasp it. These are the steps I'm planning on taking to implement it:

ebpf_functions.h

  1. Add bpf_push and bpf_pop operations to ebpf_functions.h

softswitch/main.c

  1. Create a structure to hold data length (push/pop) and pointer (push) if we need to perform either operation on the next packet.
  2. Implement functions bpf_push and bpf_pop , which fill the pushpop structure with appropriate data to be checked later by function transmit.
  3. Inside transmit, before checking the port, check pushpop struct to check whether a push/pop request was made for this packet. If pop, increase data pointer by pushpop.len. If push, allocate more space and copy the data pointed by pushpop.data to the new free space. If nothing, continue normally.
  4. Still inside transmit, after packet transmission, clear pushpop data so next packet don't get changed inadvertently.

A few questions, though:

  1. Am I on the right track? Does anything seem off?
  2. I will need to pass pointers to bpf_push and bpf_pop to the agent as well, right? From what I saw, the agent is the one who actually registers the bpf functions on the ubpf vm to allow code generation when programs are installed later.
  3. To perform a push, I think I'll probably need to allocate new memory dynamically with a bigger length to fit the new header + packet and pass this new data down to be transmitted. I don't really like this idea, since dynamic allocation + data copying will probably affect performance, but I don't see a way around it. Is there a better way?

Thank you again

@simon-jouet
Copy link
Contributor

Hi @mscastanho

  1. Looks like you're on the right track :). You might also need to add some extra checks depending on the size of the data you want to send (no to excess 1 MTU)

  2. Yes you would just to register it (https://github.com/UofG-netlab/BPFabric/blob/master/agent/agent.c#L554) . The main reason for that is that in BPFabric the dataplane shouldn't really be aware of BPF, just run the appropriate dataplane function and use the returned value to make a forwarding decision

  3. Each frame in the ring is 2048bytes already so it's likely that you will have enough space already without the need to reallocate (well depending on what you want to add but I very much doubt it will be many bytes) https://github.com/UofG-netlab/BPFabric/blob/master/softswitch/main.c#L85

@mscastanho
Copy link
Author

Hi @simon-jouet

I successfully implemented the functionality, sorry for not returning earlier.

I might make a pull request in the following weeks, after I test it a little bit further and make sure it is fully functional.

Thank you for the help!

@pezaros
Copy link

pezaros commented Apr 26, 2018

That's good to hear, @mscastanho - well done!

It would be good if you had any performance figures / testing of your module to feed back - e.g., any bench-marking or any comparative measurement against alternative ways of achieving the same thing.
We have documented the other example programs we have tried in pp. 9-11 of the below:
http://eprints.gla.ac.uk/138952/13/138952.pdf

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants