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.
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.
14 The feature arc implementation solves the problem of creating graph arcs
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.
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.
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
30 Adding a feature to an existing feature arc
31 -------------------------------------------
33 To nobody's great surprise, we set up feature arcs using the typical
34 "macro -> constructor function -> list of declarations" pattern:
37 VNET_FEATURE_INIT (mactime, static) =
39 .arc_name = "device-input",
40 .node_name = "mactime",
41 .runs_before = VNET_FEATURES ("ethernet-input"),
45 This creates a "mactime" feature on the "device-input" arc.
47 Once per frame, dig up the vnet\_feature\_config\_main\_t corresponding
48 to the "device-input" feature arc:
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;
56 fcm = vnet_feature_get_config_main (arc);
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
64 Per packet, set next0 to steer packets to the next node they should
68 vnet_get_config_data (&fcm->config_main,
69 &b0->current_config_index /* value-result */,
70 &next0, 0 /* # bytes of config data */);
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
78 next0 = MACTIME_NEXT_DROP;
79 b0->error = node->errors[DROP_CAUSE];
82 Creating a feature arc
83 ----------------------
85 Once again, we create feature arcs using constructor macros:
88 VNET_FEATURE_ARC_INIT (ip4_unicast, static) =
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,
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.
100 In the head-of-arc node, do the following to send packets along the
104 ip_lookup_main_t *lm = &im->lookup_main;
105 arc = lm->ucast_feature_arc_index;
108 Once per packet, initialize packet metadata to walk the feature arc:
111 vnet_feature_arc_start (arc, sw_if_index0, &next, b0);
114 Enabling / Disabling features
115 -----------------------------
117 Simply call vnet_feature_enable_disable to enable or disable a specific
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 */);
129 The feature_configuration opaque is seldom used.
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.
135 Related "show" commands
136 -----------------------
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
142 $ vppctl show features verbose
143 Available feature paths
146 [ 0]: nat64-out2in-handoff
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
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
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
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.
185 To display the features currently active on a specific interface,
186 use "show interface <name> features":
189 $ vppctl show interface GigabitEthernet3/0/0 features
190 Feature paths configured on GigabitEthernet3/0/0...
197 Table of Feature Arcs
198 ---------------------
200 Simply search for name-strings to track down the arc definition, location of