docs: better docs, mv doxygen to sphinx
[vpp.git] / docs / developer / corearchitecture / featurearcs.rst
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 .. code:: c
37
38        VNET_FEATURE_INIT (mactime, static) =
39        {
40          .arc_name = "device-input",
41          .node_name = "mactime",
42          .runs_before = VNET_FEATURES ("ethernet-input"),
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 to
48 the “device-input” feature arc:
49
50 .. code:: c
51
52        vnet_main_t *vnm = vnet_get_main ();
53        vnet_interface_main_t *im = &vnm->interface_main;
54        u8 arc = im->output_feature_arc_index;
55        vnet_feature_config_main_t *fcm;
56
57        fcm = vnet_feature_get_config_main (arc);
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 to
61 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 .. code:: c
68
69        vnet_get_config_data (&fcm->config_main,
70                              &b0->current_config_index /* value-result */,
71                              &next0, 0 /* # bytes of config data */);
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 .. code:: c
78
79        next0 = MACTIME_NEXT_DROP;
80        b0->error = node->errors[DROP_CAUSE];
81
82 Creating a feature arc
83 ----------------------
84
85 Once again, we create feature arcs using constructor macros:
86
87 .. code:: c
88
89        VNET_FEATURE_ARC_INIT (ip4_unicast, static) =
90        {
91          .arc_name = "ip4-unicast",
92          .start_nodes = VNET_FEATURES ("ip4-input", "ip4-input-no-checksum"),
93          .arc_index_ptr = &ip4_main.lookup_main.ucast_feature_arc_index,
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, the
98 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 .. code:: c
104
105        ip_lookup_main_t *lm = &im->lookup_main;
106        arc = lm->ucast_feature_arc_index;
107
108 Once per packet, initialize packet metadata to walk the feature arc:
109
110 .. code:: c
111
112    vnet_feature_arc_start (arc, sw_if_index0, &next, b0);
113
114 Enabling / Disabling features
115 -----------------------------
116
117 Simply call vnet_feature_enable_disable to enable or disable a specific
118 feature:
119
120 .. code:: c
121
122        vnet_feature_enable_disable ("device-input", /* arc name */
123                                     "mactime",      /* feature name */
124                                 sw_if_index,    /* Interface sw_if_index */
125                                     enable_disable, /* 1 => enable */
126                                     0 /* (void *) feature_configuration */,
127                                     0 /* feature_configuration_nbytes */);
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]”.
139 The verbose form displays arc indices, and feature indicies within the
140 arcs
141
142 ::
143
144    $ vppctl show features verbose
145    Available feature paths
146    <snip>
147    [14] ip4-unicast:
148      [ 0]: nat64-out2in-handoff
149      [ 1]: nat64-out2in
150      [ 2]: nat44-ed-hairpin-dst
151      [ 3]: nat44-hairpin-dst
152      [ 4]: ip4-dhcp-client-detect
153      [ 5]: nat44-out2in-fast
154      [ 6]: nat44-in2out-fast
155      [ 7]: nat44-handoff-classify
156      [ 8]: nat44-out2in-worker-handoff
157      [ 9]: nat44-in2out-worker-handoff
158      [10]: nat44-ed-classify
159      [11]: nat44-ed-out2in
160      [12]: nat44-ed-in2out
161      [13]: nat44-det-classify
162      [14]: nat44-det-out2in
163      [15]: nat44-det-in2out
164      [16]: nat44-classify
165      [17]: nat44-out2in
166      [18]: nat44-in2out
167      [19]: ip4-qos-record
168      [20]: ip4-vxlan-gpe-bypass
169      [21]: ip4-reassembly-feature
170      [22]: ip4-not-enabled
171      [23]: ip4-source-and-port-range-check-rx
172      [24]: ip4-flow-classify
173      [25]: ip4-inacl
174      [26]: ip4-source-check-via-rx
175      [27]: ip4-source-check-via-any
176      [28]: ip4-policer-classify
177      [29]: ipsec-input-ip4
178      [30]: vpath-input-ip4
179      [31]: ip4-vxlan-bypass
180      [32]: ip4-lookup
181    <snip>
182
183 Here, we learn that the ip4-unicast feature arc has index 14, and that
184 e.g. ip4-inacl is the 25th feature in the generated partial order.
185
186 To display the features currently active on a specific interface, use
187 “show interface features”:
188
189 ::
190
191    $ vppctl show interface GigabitEthernet3/0/0 features
192    Feature paths configured on GigabitEthernet3/0/0...
193    <snip>
194    ip4-unicast:
195      nat44-out2in
196    <snip>
197
198 Table of Feature Arcs
199 ---------------------
200
201 Simply search for name-strings to track down the arc definition,
202 location of the arc index, etc.
203
204 ::
205
206                |    Arc Name      |
207                |------------------|
208                | device-input     |
209                | ethernet-output  |
210                | interface-output |
211                | ip4-drop         |
212                | ip4-local        |
213                | ip4-multicast    |
214                | ip4-output       |
215                | ip4-punt         |
216                | ip4-unicast      |
217                | ip6-drop         |
218                | ip6-local        |
219                | ip6-multicast    |
220                | ip6-output       |
221                | ip6-punt         |
222                | ip6-unicast      |
223                | mpls-input       |
224                | mpls-output      |
225                | nsh-output       |