-
Notifications
You must be signed in to change notification settings - Fork 713
VPP Introduction_To_IP_Adjacency
Each adjacency contains two "next index" fields. You can manipulate those fields to achieve different effects. Every adjacency represents an opportunity to divert traffic into an arbitrary subgraph.
Each successful ipv4 / ipv6 lookup yields an ip adjacency. Ipv4 and ipv6 adjacencies are identical, of type "ip_adjacency_t."
Ip4/6-lookup pushes matching traffic forward in the node graph via the graph arc given by adj->lookup_next_index. Typical ip4/6 rewrite adjacencies have adj->lookup_next_index = IP_LOOKUP_NEXT_REWRITE.
ip4/6-rewrite uses data from the ip_adjacency_t's vnet_rewrite_header to actually rewrite the packet. The rewrite header itself has a next_index, which tells ip4/6-rewrite where to send packets next. In the case of a typical rewrite adjacency, the rewrite header next index directs packets to the appropriate physical interface output node.
It's easy to add a tunnel encapsulation by constructing an appropriate adjacency. We typically let adj->lookup_next_index = IP_LOOKUP_NEXT_REWRITE, set up the rewrite string to encapsulate the tunneled packet with the appropriate ip4/6 header, and use the rewrite header next_index to send packets to a "fixup" node - for example, to set the outer-ip packet length or fix the outer ipv4 header checksum. As of this writing, mpls-o-gre encapsulation works this way.
The fixup node sets outer-IP packet lengths, and fixes ip(v4) header checksums.
Here's a quick sketch of how to drive the internal APIs used to construct an ipv4 tunnel adjacency.
ip_adjacency_t adj;
u8 * rewrite_data;
ip4_address_t target_address;
ip4_address_t zero;
u32 adj_index;
u32 inner_fib_index, outer_fib_index;
zero.as_u32 = 0;
/* Construct an adjacency template */
memset(&adj, 0, sizeof (adj));
adj.explicit_fib_index = ~0;
adj.lookup_next_index = IP_LOOKUP_NEXT_REWRITE;
/*
* Construct the rewrite string in a u8 * vector
*
* The rewrite string begins with 0x45000000 - an unrouted ip4
* datagram with no options and a length of zero. Compute the
* ip4 checksum with length = 0, and use the standard incremental
* checksum fandango to adjust it in my_post_rewrite...
*
* my_post_rewrite is expected to send traffic to ip4-lookup.
*/
rewrite_data = my_tunnel_rewrite (mm, tp);
/* Add rewrite header data to the template */
vnet_rewrite_for_tunnel
(vnm,
outer_fib_index /* rewrite sets tx_sw_if_index => outer fib index */,
ip4_rewrite_node.index, /* vanilla rewrite */
my_post_rewrite_node.index, /* tunnel-specific post-rewrite node */
&adj.rewrite_header,
rewrite_data, vec_len(rewrite_data));
/* Create an adjacency from the adjacency template */
ip_add_adjacency (lm, &adj, 1 /* one adj */,
&adj_index);
/* Add the adjacency to the indicated FIB */
ip4_add_del_route_next_hop
(im, IP4_ROUTE_FLAG_ADD, &target_address,
mask_width,
&zero /* no next hop */,
(u32)~0 /* next_hop_sw_if_index */,
1 /* weight */,
adj_index /* our new adjacency */,
inner_fib_index /* lookup FIB index, 0 is the default FIB */);
Note that if you follow the "typical" tunnel encapsulation process, you won't deal with these mechanics directly. The example shown above will help create completely arbitrary Forwarding Information Base (FIB) lookup / ip adjacency-based behaviors.
The tunnel encap use-case more or less follows the standard "lookup, rewrite, ship-it" pattern. We can achieve many other effects by using the degrees of freedom built into the underlying scheme.
Let's say that we want to build a plug-in to inspect traffic sent to a particular subnet. At plugin init time - using VLIB_INIT_FUNCTION - we add a graph arc from ip4_lookup_node to my_plugin_node:
node_index = vlib_node_add_next (vm, ip4_lookup_node.index, my_plugin_node.index);
An adjacency with adj->lookup_next_index = node_index will divert traffic to my_plugin_node as desired.
My_plugin_node can return traffic to its regularly-scheduled graph trajectory by enqueueing to ip4/6-rewrite, or not.
Note that the plug-in can track down and patch existing adjacencies by performing an FIB lookup, and then assigning the following setting:
adj->lookup_next_index = my_plugin_node.index
Depending on how "my_plugin_node" works - and where it sends packets in the graph - one can use the remainder of the ip_adjacency_t object in arbitrary ways. Burying object indicies in unused rewrite space could work, as well as other uses.
- VPP-ABF
- VPP API Concepts
- VPP API Versioning
- VPP-ApiChangeProcess
- VPP-ArtifactVersioning
- VPP-BIER
- VPP-Bihash
- VPP-BugReports
- VPP Build System Deep Dive
- VPP Build, Install, And Test Images
- VPP-BuildArtifactRetentionPolicy
- VPP-c2cpel
- VPP-CodingTips
- VPP Command Line Arguments
- VPP Command Line Interface CLI Guide
- VPP-CommitMessages
- VPP-CommitterTasks-ApiFreeze
- VPP CommitterTasks Compare API Changes
- VPP-CommitterTasks-CutPointRelease
- VPP-CommitterTasks-CutRelease
- VPP-CommitterTasks-FinalReleaseCandidate
- VPP-CommitterTasks-PullThrottleBranch
- VPP-CommitterTasks-ReleasePlan
- VPP Configure An LW46 MAP E Terminator
- VPP Configure VPP As A Router Between Namespaces
- VPP Configure VPP TAP Interfaces For Container Routing
- VPP-CoreFileMismatch
- VPP-cpel
- VPP-cpeldump
- VPP-DHCPv6
- VPP-DistributedOwnership
- VPP DPOs And Feature Arcs
- VPP EC2 Instance With SRIOV
- VPP-elog
- VPP-FAQ
- VPP Feature Arcs
- VPP-g2
- VPP-HA
- VPP-HostStack
- VPP-HostStack-BuiltinEchoClientServer
- VPP-HostStack-EchoClientServer
- VPP-HostStack-ExternalEchoClientServer
- VPP HostStack Hs Test
- VPP-HostStack-LDP-iperf
- VPP-HostStack-LDP-nginx
- VPP-HostStack-LDP-sshd
- VPP-HostStack-nginx
- VPP-HostStack-SessionLayerArchitecture
- VPP-HostStack-TestHttpServer
- VPP-HostStack-TestProxy
- VPP-HostStack-TLS
- VPP-HostStack-VCL
- VPP-HostStack-VclEchoClientServer
- VPP How To Add A Tunnel Encapsulation
- VPP How To Build The Sample Plugin
- VPP How To Connect A PCI Interface To VPP
- VPP How To Create A VPP Binary Control Plane API
- VPP How To Deploy VPP In EC2 Instance And Use It To Connect Two Different VPCs
- VPP How To Optimize Performance %28System Tuning%29
- VPP How To Use The API Trace Tools
- VPP How To Use The C API
- VPP How To Use The Packet Generator And Packet Tracer
- VPP-Howtos
- VPP Installing VPP Binaries From Packages
- VPP Interconnecting vRouters With VPP
- VPP Introduction To IP Adjacency
- VPP Introduction To N Tuple Classifiers
- VPP-IPFIX
- VPP-IPSec
- VPP IPSec And IKEv2
- VPP-Macswapplugin
- VPP-Meeting
- VPP-MFIB
- VPP Missing Prefetches
- VPP Modifying The Packet Processing Directed Graph
- VPP MPLS FIB
- VPP-NAT
- VPP Per Feature Notes
- VPP Performance Analysis Tools
- VPP-perftop
- VPP Project Meeting Minutes
- VPP Pulling, Building, Running, Hacking And Pushing VPP Code
- VPP Pure L3 Between Namespaces With 32s
- VPP Pure L3 Container Networking
- VPP Pushing And Testing A Tag
- VPP Python API
- VPP-QuickTrexSetup
- VPP Random Hints And Kinks For KVM Usage
- VPP Release Plans Release Plan 26.06
- VPP-RM
- VPP-SecurityGroups
- VPP Segment Routing For IPv6
- VPP Segment Routing For MPLS
- VPP Setting Up Your Dev Environment
- VPP-SNAT
- VPP Software Architecture
- VPP STN Testing
- VPP The VPP API
- VPP Training Events
- VPP-Troubleshooting
- VPP-Troubleshooting-BuildIssues
- VPP-Troubleshooting-Vagrant
- VPP Tutorial DPDK And MacSwap
- VPP-Tutorials
- VPP Use VPP To Chain VMs Using Vhost User Interface
- VPP Use VPP To Connect VMs Using Vhost User Interface
- VPP Using mTCP User Mode TCP Stack With VPP
- VPP Using VPP As A VXLAN Tunnel Terminator
- VPP VPP BFD Nexus
- VPP VPP Home Gateway
- VPP-VPPCommunicationsLibrary
- VPP What Is VPP
- VPP Working With The 16.06 Throttle Branch