docs: convert plugins doc md->rst
[vpp.git] / docs / gettingstarted / developers / featurearcs.md
1 Feature Arcs
2 ============
3
4 A significant number of vpp features are configurable on a per-interface
5 or per-system basis. Rather than ask feature coders to manually
6 construct the required graph arcs, we built a general mechanism to
7 manage these mechanics.
8
9 Specifically, feature arcs comprise ordered sets of graph nodes. Each
10 feature node in an arc is independently controlled. Feature arc nodes
11 are generally unaware of each other. Handing a packet to "the next
12 feature node" is quite inexpensive.
13
14 The feature arc implementation solves the problem of creating graph arcs
15 used for steering.
16
17 At the beginning of a feature arc, a bit of setup work is needed, but
18 only if at least one feature is enabled on the arc.
19
20 On a per-arc basis, individual feature definitions create a set of
21 ordering dependencies. Feature infrastructure performs a topological
22 sort of the ordering dependencies, to determine the actual feature
23 order. Missing dependencies **will** lead to runtime disorder. See
24 <https://gerrit.fd.io/r/#/c/12753> for an example.
25
26 If no partial order exists, vpp will refuse to run. Circular dependency
27 loops of the form "a then b, b then c, c then a" are impossible to
28 satisfy.
29
30 Adding a feature to an existing feature arc
31 -------------------------------------------
32
33 To nobody's great surprise, we set up feature arcs using the typical
34 "macro -> constructor function -> list of declarations" pattern:
35
36 ```c
37     VNET_FEATURE_INIT (mactime, static) =
38     {
39       .arc_name = "device-input",
40       .node_name = "mactime",
41       .runs_before = VNET_FEATURES ("ethernet-input"),
42     };  
43 ```
44
45 This creates a "mactime" feature on the "device-input" arc.
46
47 Once per frame, dig up the vnet\_feature\_config\_main\_t corresponding
48 to the "device-input" feature arc:
49
50 ```c
51     vnet_main_t *vnm = vnet_get_main ();
52     vnet_interface_main_t *im = &vnm->interface_main;
53     u8 arc = im->output_feature_arc_index;
54     vnet_feature_config_main_t *fcm;
55
56     fcm = vnet_feature_get_config_main (arc);
57 ```
58
59 Note that in this case, we've stored the required arc index - assigned
60 by the feature infrastructure - in the vnet\_interface\_main\_t. Where
61 to put the arc index is a programmer's decision when creating a feature
62 arc.
63
64 Per packet, set next0 to steer packets to the next node they should
65 visit:
66
67 ```c
68     vnet_get_config_data (&fcm->config_main,
69                           &b0->current_config_index /* value-result */, 
70                           &next0, 0 /* # bytes of config data */);
71 ```
72
73 Configuration data is per-feature arc, and is often unused. Note that
74 it's normal to reset next0 to divert packets elsewhere; often, to drop
75 them for cause:
76
77 ```c
78     next0 = MACTIME_NEXT_DROP;
79     b0->error = node->errors[DROP_CAUSE];
80 ```
81
82 Creating a feature arc
83 ----------------------
84
85 Once again, we create feature arcs using constructor macros:
86
87 ```c
88     VNET_FEATURE_ARC_INIT (ip4_unicast, static) =
89     {
90       .arc_name = "ip4-unicast",
91       .start_nodes = VNET_FEATURES ("ip4-input", "ip4-input-no-checksum"),
92       .arc_index_ptr = &ip4_main.lookup_main.ucast_feature_arc_index,
93     };  
94 ```
95
96 In this case, we configure two arc start nodes to handle the
97 "hardware-verified ip checksum or not" cases. During initialization,
98 the feature infrastructure stores the arc index as shown.
99
100 In the head-of-arc node, do the following to send packets along the
101 feature arc:
102
103 ```c
104     ip_lookup_main_t *lm = &im->lookup_main;
105     arc = lm->ucast_feature_arc_index;
106 ```
107
108 Once per packet, initialize packet metadata to walk the feature arc:
109
110 ```c
111 vnet_feature_arc_start (arc, sw_if_index0, &next, b0);
112 ```
113
114 Enabling / Disabling features
115 -----------------------------
116
117 Simply call vnet_feature_enable_disable to enable or disable a specific
118 feature:
119
120 ```c
121     vnet_feature_enable_disable ("device-input", /* arc name */
122                                  "mactime",      /* feature name */
123                                      sw_if_index,    /* Interface sw_if_index */
124                                  enable_disable, /* 1 => enable */
125                                  0 /* (void *) feature_configuration */, 
126                                  0 /* feature_configuration_nbytes */);
127 ```
128
129 The feature_configuration opaque is seldom used. 
130
131 If you wish to make a feature a _de facto_ system-level concept, pass
132 sw_if_index=0 at all times. Sw_if_index 0 is always valid, and
133 corresponds to the "local" interface.
134
135 Related "show" commands
136 -----------------------
137
138 To display the entire set of features, use "show features [verbose]". The
139 verbose form displays arc indices, and feature indicies within the arcs
140
141 ```
142 $ vppctl show features verbose
143 Available feature paths
144 <snip>
145 [14] ip4-unicast:
146   [ 0]: nat64-out2in-handoff
147   [ 1]: nat64-out2in
148   [ 2]: nat44-ed-hairpin-dst
149   [ 3]: nat44-hairpin-dst
150   [ 4]: ip4-dhcp-client-detect
151   [ 5]: nat44-out2in-fast
152   [ 6]: nat44-in2out-fast
153   [ 7]: nat44-handoff-classify
154   [ 8]: nat44-out2in-worker-handoff
155   [ 9]: nat44-in2out-worker-handoff
156   [10]: nat44-ed-classify
157   [11]: nat44-ed-out2in
158   [12]: nat44-ed-in2out
159   [13]: nat44-det-classify
160   [14]: nat44-det-out2in
161   [15]: nat44-det-in2out
162   [16]: nat44-classify
163   [17]: nat44-out2in
164   [18]: nat44-in2out
165   [19]: ip4-qos-record
166   [20]: ip4-vxlan-gpe-bypass
167   [21]: ip4-reassembly-feature
168   [22]: ip4-not-enabled
169   [23]: ip4-source-and-port-range-check-rx
170   [24]: ip4-flow-classify
171   [25]: ip4-inacl
172   [26]: ip4-source-check-via-rx
173   [27]: ip4-source-check-via-any
174   [28]: ip4-policer-classify
175   [29]: ipsec-input-ip4
176   [30]: vpath-input-ip4
177   [31]: ip4-vxlan-bypass
178   [32]: ip4-lookup
179 <snip>
180 ```
181
182 Here, we learn that the ip4-unicast feature arc has index 14, and that
183 e.g. ip4-inacl is the 25th feature in the generated partial order.
184
185 To display the features currently active on a specific interface,
186 use "show interface <name> features":
187
188 ```
189 $ vppctl show interface GigabitEthernet3/0/0 features
190 Feature paths configured on GigabitEthernet3/0/0...
191 <snip>
192 ip4-unicast:
193   nat44-out2in
194 <snip>
195 ```
196
197 Table of Feature Arcs
198 ---------------------
199
200 Simply search for name-strings to track down the arc definition, location of
201 the arc index, etc.
202
203 ```
204             |    Arc Name      |
205             |------------------|
206             | device-input     |
207             | ethernet-output  |
208             | interface-output |
209             | ip4-drop         |
210             | ip4-local        |
211             | ip4-multicast    |
212             | ip4-output       |
213             | ip4-punt         |
214             | ip4-unicast      |
215             | ip6-drop         |
216             | ip6-local        |
217             | ip6-multicast    |
218             | ip6-output       |
219             | ip6-punt         |
220             | ip6-unicast      |
221             | mpls-input       |
222             | mpls-output      |
223             | nsh-output       |
224 ```