capsule-rs / capsule

A framework for network function development. Written in Rust, inspired by NetBricks and built on DPDK.
Apache License 2.0
393 stars 35 forks source link

add support for tunneling protocols #147

Open drunkirishcoder opened 2 years ago

drunkirishcoder commented 2 years ago

Description

Feature support for type safe tunnel protocol modeling. This pattern can be applied to tunnels such as various IP in IP, GRE, and VXLAN etc.

The general design is tunnels can be codified into structs by implementing the Tunnel trait. Tunnel is defined by the delivery (outer) protocol and payload (inner) protocol. For example GRE header can be used in many tunneling methods. The specific use of GRE in tunneling any layer-3 packets inside a IPv4 packet is implemented by the Ip4Gre tunnel. Two tunnels can have the same delivery and payload protocols but modify the protocol stack differently, for example both Ip4Gre and IpIp can tunnel IPv4 packets in IPv4.

On entry to a tunnel, the payload packet should be constructed first then encapsulated,

let packet = Mbuf::new()?;
let ethernet = packet.push::<Ethernet>()?;
let ip6 = ethernet.push::<Ipv6>()?;
let mut payload = ip6.push::<EchoReply>()?.deparse();

// construct the payload in its entirety
payload.set_src(src);
payload.set_dst(dst);
payload.reconcile();

// encap the payload in the tunnel
let delivery = payload.encap::<Ip4Gre<Ipv6>>()?;
delivery.set_src(tunnel_entry);
delivery.set_dst(tunnel_exit);

// after encap, the original payload can't be parsed or modified
let gre = delivery.parse::<Gre<Ipv4>>()?; // can look at the GRE header
let original = gre.parse::<Ipv6>()?; // won't compile

on tunnel exit, decap to access and modify the payload again

let ethernet = packet.parse::<Ethernet>()?;
let delivery = ethernet.parse::<Ipv4>()?;
let payload = delivery.decap::<Ip4Gre<Ipv6>>()?;
let echo = payload.parse::<EchoReply>()?;

Type of change

Checklist

codecov[bot] commented 2 years ago

Codecov Report

Merging #147 (a9001f4) into djin/datalink (b1e9b9d) will increase coverage by 0.87%. The diff coverage is 91.86%.

:exclamation: Current head a9001f4 differs from pull request most recent head 6ab3d83. Consider uploading reports for the commit 6ab3d83 to get more accurate results Impacted file tree graph

@@                Coverage Diff                @@
##           djin/datalink     #147      +/-   ##
=================================================
+ Coverage          76.44%   77.32%   +0.87%     
=================================================
  Files                 50       54       +4     
  Lines               5048     5292     +244     
=================================================
+ Hits                3859     4092     +233     
- Misses              1189     1200      +11     
Impacted Files Coverage Δ
core/src/packets/icmp/v6/ndp/mod.rs 85.11% <ø> (ø)
core/src/packets/gre/mod.rs 74.68% <74.68%> (ø)
core/src/packets/gre/ip4gre.rs 100.00% <100.00%> (ø)
core/src/packets/ip/mod.rs 57.81% <100.00%> (+4.36%) :arrow_up:
core/src/packets/ip/tunnels/ip6in4.rs 100.00% <100.00%> (ø)
core/src/packets/ip/tunnels/ipip.rs 100.00% <100.00%> (ø)
core/src/packets/mod.rs 93.67% <100.00%> (+0.33%) :arrow_up:
core/src/testils/proptest/strategy.rs 81.39% <0.00%> (-0.47%) :arrow_down:
core/src/net/cidr/v6.rs 95.03% <0.00%> (+0.70%) :arrow_up:
core/src/packets/icmp/v6/echo_reply.rs 73.33% <0.00%> (+2.66%) :arrow_up:
... and 1 more

Continue to review full report at Codecov.

Legend - Click here to learn more Δ = absolute <relative> (impact), ø = not affected, ? = missing data Powered by Codecov. Last update b1e9b9d...6ab3d83. Read the comment docs.

sbuzzard commented 2 years ago

Nice. One of the things we're looking to do is to provide an application that has as input ipv4 multicast and as one or more outputs in ipv6 multicast in a DOCSIS Downstream External-PHY Interface (DEPI) tunnel, which uses a layer 2 tunneling protocol to add a session id and sequence number to the multicast ipv6 packet. Sets next header to 115 (L2TP) and sets up the ethernet packet appropriately. We're looking to use DPDK due to performance requirements of this app.

zeeshanlakhani commented 2 years ago

Yeah, @sbuzzard, this should start getting us on the way there; @drunkirishcoder, you, and I should chat more.

sbuzzard commented 2 years ago

agree - can do whenever convenient for you guys (in discord or otherwise)

skeggse commented 2 years ago

As a user here, I'd like to throw in that it feels like this might interact with Geneve encapsulation (or maybe not!) and that it'd be neat to have capsule support Geneve formats natively.

drunkirishcoder commented 2 years ago

@skeggse yep, the goal of this approach is to allow for an implementation of Geneve possible, it should be pretty similar to GRE.