3f8c76610ce714aae595a447e60b50751f533409
[dpdk.git] / fib.spec
1 ; SPDX-License-Identifier: BSD-3-Clause
2 ; Copyright(c) 2021 Intel Corporation
3
4 ; This example illustrates a FIB [1] with VRF [2] and ECMP [3] support. A FIB essentially is the
5 ; data plane copy of the routing table. The VRF support allows for multiple logical routing tables
6 ; to co-exist as part of the same "physical" routing table; the VRF ID typically identifies the
7 ; logical table to provide the matching route for the IP destination address of the input packet.
8 ; The ECMP provides a load balancing mechanism for the packet forwarding by allowing for multiple
9 ; next hops (of equal or different weights, in case of WCMP [4]) to be provided for each route.
10 ;
11 ; In this example, the VRF ID is read from the IP source address of the input packet as opposed to a
12 ; more complex classification scheme being used. The routing table produces the ID of the group of
13 ; next hops associated with the current route, out of which a single next hop is selected based on a
14 ; hashing scheme that preserves the packet order within each flow (with the flow defined here by a
15 ; typical 3-tuple) by always selecting the same next hop for packets that are part of the same flow.
16 ; The next hop provides the Ethernet header and the output port for the outgoing packet.
17 ;
18 ; [1] Forwarding Information Base (FIB):
19 ;        https://en.wikipedia.org/wiki/Forwarding_information_base
20 ; [2] Virtual Routing and Forwarding (VRF):
21 ;        https://en.wikipedia.org/wiki/Virtual_routing_and_forwarding
22 ; [3] Equal-Cost Multi-Path (ECMP) routing:
23 ;        https://en.wikipedia.org/wiki/Equal-cost_multi-path_routing
24 ; [4] Weighted-Cost Multi-Path (WCMP) routing.
25
26 //
27 // Headers
28 //
29 struct ethernet_h {
30         bit<48> dst_addr
31         bit<48> src_addr
32         bit<16> ethertype
33 }
34
35 struct ipv4_h {
36         bit<8> ver_ihl
37         bit<8> diffserv
38         bit<16> total_len
39         bit<16> identification
40         bit<16> flags_offset
41         bit<8> ttl
42         bit<8> protocol
43         bit<16> hdr_checksum
44         bit<32> src_addr
45         bit<32> dst_addr
46 }
47
48 header ethernet instanceof ethernet_h
49 header ipv4 instanceof ipv4_h
50
51 //
52 // Meta-data
53 //
54 struct metadata_t {
55         bit<32> port_in
56         bit<32> port_out
57         bit<32> vrf_id
58         bit<32> dst_addr
59         bit<32> nexthop_group_id
60         bit<32> nexthop_id
61 }
62
63 metadata instanceof metadata_t
64
65 //
66 // Actions
67 //
68 struct nexthop_group_action_args_t {
69         bit<32> nexthop_group_id
70 }
71
72 action nexthop_group_action args instanceof nexthop_group_action_args_t {
73         mov m.nexthop_group_id t.nexthop_group_id
74         return
75 }
76
77 struct nexthop_action_args_t {
78         bit<48> ethernet_dst_addr
79         bit<48> ethernet_src_addr
80         bit<16> ethernet_ethertype
81         bit<32> port_out
82 }
83
84 action nexthop_action args instanceof nexthop_action_args_t {
85         //Set Ethernet header.
86         mov h.ethernet.dst_addr t.ethernet_dst_addr
87         mov h.ethernet.src_addr t.ethernet_src_addr
88         mov h.ethernet.ethertype t.ethernet_ethertype
89         validate h.ethernet
90
91         //Decrement the TTL and update the checksum within the IPv4 header.
92         cksub h.ipv4.hdr_checksum h.ipv4.ttl
93         sub h.ipv4.ttl 0x1
94         ckadd h.ipv4.hdr_checksum h.ipv4.ttl
95
96         //Set the output port.
97         mov m.port_out t.port_out
98
99         return
100 }
101
102 action drop args none {
103         drop
104 }
105
106 //
107 // Tables
108 //
109 table routing_table {
110         key {
111                 m.vrf_id exact
112                 m.dst_addr lpm
113         }
114
115         actions {
116                 nexthop_group_action
117                 drop
118         }
119
120         default_action drop args none
121
122         size 1048576
123 }
124
125 selector nexthop_group_table {
126         group_id m.nexthop_group_id
127
128         selector {
129                 h.ipv4.protocol
130                 h.ipv4.src_addr
131                 h.ipv4.dst_addr
132         }
133
134         member_id m.nexthop_id
135
136         n_groups_max 65536
137
138         n_members_per_group_max 64
139 }
140
141 table nexthop_table {
142         key {
143                 m.nexthop_id exact
144         }
145
146         actions {
147                 nexthop_action
148                 drop
149         }
150
151         default_action drop args none
152
153         size 1048576
154 }
155
156 //
157 // Pipeline
158 //
159 apply {
160         rx m.port_in
161         extract h.ethernet
162         extract h.ipv4
163         mov m.vrf_id h.ipv4.src_addr
164         mov m.dst_addr h.ipv4.dst_addr
165         table routing_table
166         table nexthop_group_table
167         table nexthop_table
168         emit h.ethernet
169         emit h.ipv4
170         tx m.port_out
171 }