9ee2cc4f9fcf779e97b74ecc1c821335fba048b5
[vpp.git] / src / vnet / ip / ip.api
1 /* Hey Emacs use -*- mode: C -*- */
2 /*
3  * Copyright (c) 2018 Cisco and/or its affiliates.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /** \file
18
19     This file defines vpp IP control-plane API messages which are generally
20     called through a shared memory interface.
21 */
22
23 option version = "3.2.0";
24
25 import "vnet/interface_types.api";
26 import "vnet/fib/fib_types.api";
27 import "vnet/ethernet/ethernet_types.api";
28 import "vnet/mfib/mfib_types.api";
29 import "vnet/interface_types.api";
30
31 /** \brief An IP table
32     @param is_ipv6 - V4 or V6 table
33     @param table_id - table ID associated with the route
34                      This table ID will apply to both the unicast
35                       and multicast FIBs
36     @param name - A client provided name/tag for the table. If this is
37                   not set by the client, then VPP will generate something
38                   meaningful.
39 */
40 typedef ip_table
41 {
42   u32 table_id;
43   bool is_ip6;
44   string name[64];
45 };
46
47 /** \brief Add / del table request
48            A table can be added multiple times, but need be deleted only once.
49     @param client_index - opaque cookie to identify the sender
50     @param context - sender context, to match reply w/ request
51 */
52 autoreply define ip_table_add_del
53 {
54   u32 client_index;
55   u32 context;
56   bool is_add [default=true];
57   vl_api_ip_table_t table;
58 };
59
60 /** \brief Allocate an unused table
61            A table can be added multiple times.
62            If a large number of tables are in use (millions), this API might
63            fail to find a free ID with very low probability, and will return
64            EAGAIN. A subsequent attempt may be successful.
65   @param client_index - opaque cookie to identify the sender
66   @param context - sender context, to match reply w/ request
67   @param table - if table.table_id == ~0, vpp allocates an unused table_id and
68                     proceeds as in ip_table_add_del with is_add = true
69                  if table.table_id != ~0, vpp uses the table.table_id and
70                     proceeds as in ip_table_add_del with is_add = true
71                  table.table_id should never be 0
72 */
73 define ip_table_allocate
74 {
75   u32 client_index;
76   u32 context;
77
78   vl_api_ip_table_t table;
79 };
80
81 define ip_table_allocate_reply
82 {
83   u32 context;
84   i32 retval;
85
86   vl_api_ip_table_t table;
87 };
88
89 /** \brief Dump IP all fib tables
90     @param client_index - opaque cookie to identify the sender
91     @param context - sender context, to match reply w/ request
92 */
93 define ip_table_dump
94 {
95   u32 client_index;
96   u32 context;
97 };
98
99 /** \brief IP table replace being
100
101     The use-case is that, for some unspecified reason, the control plane
102     has a very different set of entries it wants in the table than VPP
103     currently has. The CP would thus like to 'replace' VPP's current table
104     only by specifying what the new set of entries shall be, i.e. it is not
105     going to delete anything that already exists.
106     the CP declares the start of this procedure with this begin_replace
107     API Call, and when it has populated all the entries it wants, it calls
108     the below end_replace API. From this point on it is of course free
109     to add and delete entries as usual.
110     The underlying mechanism by which VPP implements this replace is
111     purposefully left unspecified.
112
113     @param client_index - opaque cookie to identify the sender
114     @param context - sender context, to match reply w/ request
115     @param table - The table to resync
116 */
117 autoreply define ip_table_replace_begin
118 {
119   u32 client_index;
120   u32 context;
121   vl_api_ip_table_t table;
122 };
123
124 /** \brief IP table replace end
125
126     see replace start/
127
128     @param client_index - opaque cookie to identify the sender
129     @param context - sender context, to match reply w/ request
130     @param table - The table that has converged
131 */
132 autoreply define ip_table_replace_end
133 {
134   u32 client_index;
135   u32 context;
136   vl_api_ip_table_t table;
137 };
138
139 /** \brief IP table flush
140     Flush a table of all routes
141     @param client_index - opaque cookie to identify the sender
142     @param context - sender context, to match reply w/ request
143     @param table - The table to flush
144 */
145 autoreply define ip_table_flush
146 {
147   u32 client_index;
148   u32 context;
149   vl_api_ip_table_t table;
150 };
151
152 /** \brief IP FIB table response
153     @param context - sender context
154     @param table - description of the table
155 */
156 define ip_table_details
157 {
158   u32 context;
159   vl_api_ip_table_t table;
160 };
161
162 /** \brief An IP route
163   @param table_id The IP table the route is in
164   @param stats_index The index of the route in the stats segment
165   @param prefix the prefix for the route
166   @param n_paths The number of paths the route has
167   @param src The entity adding the route. either 0 for default
168              or a value returned from fib_source_sdd.
169   @param paths The paths of the route
170 */
171 typedef ip_route
172 {
173   u32 table_id;
174   u32 stats_index;
175   vl_api_prefix_t prefix;
176   u8 n_paths;
177   vl_api_fib_path_t paths[n_paths];
178 };
179 typedef ip_route_v2
180 {
181   u32 table_id;
182   u32 stats_index;
183   vl_api_prefix_t prefix;
184   u8 n_paths;
185   u8 src;
186   vl_api_fib_path_t paths[n_paths];
187 };
188
189 /** \brief Add / del route request
190     @param client_index - opaque cookie to identify the sender
191     @param context - sender context, to match reply w/ request
192     @param is_multipath - Set to 1 if these paths will be added/removed
193                           to/from the existing set, or 0 to replace
194                           the existing set.
195                           is_add=0 & is_multipath=0 implies delete all paths
196     @param is_add - Are the paths being added or removed
197 */
198 define ip_route_add_del
199 {
200   u32 client_index;
201   u32 context;
202   bool is_add [default=true];
203   bool is_multipath;
204   vl_api_ip_route_t route;
205 };
206 define ip_route_add_del_v2
207 {
208   option in_progress;
209   u32 client_index;
210   u32 context;
211   bool is_add [default=true];
212   bool is_multipath;
213   vl_api_ip_route_v2_t route;
214 };
215 define ip_route_add_del_reply
216 {
217   u32 context;
218   i32 retval;
219   u32 stats_index;
220 };
221 define ip_route_add_del_v2_reply
222 {
223   option in_progress;
224   u32 context;
225   i32 retval;
226   u32 stats_index;
227 };
228
229 /** \brief Dump IP routes from a table
230     @param client_index - opaque cookie to identify the sender
231     @param src The entity adding the route. either 0 for default
232                or a value returned from fib_source_sdd.
233     @param table - The table from which to dump routes (ony ID an AF are needed)
234 */
235 define ip_route_dump
236 {
237   u32 client_index;
238   u32 context;
239   vl_api_ip_table_t table;
240 };
241 define ip_route_v2_dump
242 {
243   option in_progress;
244   u32 client_index;
245   u32 context;
246   /* vl_api_fib_source_t src; */
247   u8 src;
248   vl_api_ip_table_t table;
249 };
250
251 /** \brief IP FIB table entry response
252     @param route The route entry in the table
253 */
254 define ip_route_details
255 {
256   u32 context;
257   vl_api_ip_route_t route;
258 };
259 define ip_route_v2_details
260 {
261   option in_progress;
262   u32 context;
263   vl_api_ip_route_v2_t route;
264 };
265
266 /** \brief Lookup IP route from a table
267     @param client_index - opaque cookie to identify the sender
268     @param table_id - The IP table to look the route up in
269     @param exact - 0 for normal route lookup, 1 for exact match only
270     @param prefix - The prefix (or host) for route lookup.
271 */
272 define ip_route_lookup
273 {
274   u32 client_index;
275   u32 context;
276   u32 table_id;
277   u8 exact;
278   vl_api_prefix_t prefix;
279 };
280 define ip_route_lookup_v2
281 {
282   option in_progress;
283   u32 client_index;
284   u32 context;
285   u32 table_id;
286   u8 exact;
287   vl_api_prefix_t prefix;
288 };
289
290 /** \brief IP FIB table lookup response
291     @param retval - return code of the lookup
292     @param route - The route entry in the table if found
293 */
294 define ip_route_lookup_reply
295 {
296   u32 context;
297   i32 retval;
298   vl_api_ip_route_t route;
299 };
300 define ip_route_lookup_v2_reply
301 {
302   option in_progress;
303   u32 context;
304   i32 retval;
305   vl_api_ip_route_v2_t route;
306 };
307
308 /** \brief Set the ip flow hash config for a fib request
309     @param client_index - opaque cookie to identify the sender
310     @param context - sender context, to match reply w/ request
311     @param vrf_id - vrf/fib id
312     @param is_ipv6 - if non-zero the fib is ip6, else ip4
313     @param src - if non-zero include src in flow hash
314     @param dst - if non-zero include dst in flow hash
315     @param sport - if non-zero include sport in flow hash
316     @param dport - if non-zero include dport in flow hash
317     @param proto -if non-zero include proto in flow hash
318     @param reverse - if non-zero include reverse in flow hash
319     @param symmetric - if non-zero include symmetry in flow hash
320 */
321 autoreply define set_ip_flow_hash
322 {
323   option deprecated;
324   u32 client_index;
325   u32 context;
326   u32 vrf_id;
327   bool is_ipv6;
328   bool src;
329   bool dst;
330   bool sport;
331   bool dport;
332   bool proto;
333   bool reverse;
334   bool symmetric;
335 };
336
337 /**
338     @brief flow hash settings for an IP table
339     @param src - include src in flow hash
340     @param dst - include dst in flow hash
341     @param sport - include sport in flow hash
342     @param dport - include dport in flow hash
343     @param proto - include proto in flow hash
344     @param reverse - include reverse in flow hash
345     @param symmetric - include symmetry in flow hash
346     @param flowlabel - include flowlabel in flow hash
347 */
348 enumflag ip_flow_hash_config
349 {
350   IP_API_FLOW_HASH_SRC_IP = 0x01,
351   IP_API_FLOW_HASH_DST_IP = 0x02,
352   IP_API_FLOW_HASH_SRC_PORT = 0x04,
353   IP_API_FLOW_HASH_DST_PORT = 0x08,
354   IP_API_FLOW_HASH_PROTO = 0x10,
355   IP_API_FLOW_HASH_REVERSE = 0x20,
356   IP_API_FLOW_HASH_SYMETRIC = 0x40,
357   IP_API_FLOW_HASH_FLOW_LABEL = 0x80,
358 };
359
360 autoreply define set_ip_flow_hash_v2
361 {
362   u32 client_index;
363   u32 context;
364   u32 table_id;
365   vl_api_address_family_t af;
366   vl_api_ip_flow_hash_config_t flow_hash_config;
367 };
368
369 /**
370     @brief flow hash settings for an IP table
371     @param src - include src in flow hash
372     @param dst - include dst in flow hash
373     @param sport - include sport in flow hash
374     @param dport - include dport in flow hash
375     @param proto - include proto in flow hash
376     @param reverse - include reverse in flow hash
377     @param symmetric - include symmetry in flow hash
378     @param flowlabel - include flowlabel in flow hash
379     @param gtpv1teid - include gtpv1teid in flow hash
380 */
381 enumflag ip_flow_hash_config_v2
382 {
383   IP_API_V2_FLOW_HASH_SRC_IP = 0x01,
384   IP_API_V2_FLOW_HASH_DST_IP = 0x02,
385   IP_API_V2_FLOW_HASH_SRC_PORT = 0x04,
386   IP_API_V2_FLOW_HASH_DST_PORT = 0x08,
387   IP_API_V2_FLOW_HASH_PROTO = 0x10,
388   IP_API_V2_FLOW_HASH_REVERSE = 0x20,
389   IP_API_V2_FLOW_HASH_SYMETRIC = 0x40,
390   IP_API_V2_FLOW_HASH_FLOW_LABEL = 0x80,
391   IP_API_V2_FLOW_HASH_GTPV1_TEID = 0x100,
392 };
393
394 autoreply define set_ip_flow_hash_v3
395 {
396   u32 client_index;
397   u32 context;
398   u32 table_id;
399   vl_api_address_family_t af;
400   vl_api_ip_flow_hash_config_v2_t flow_hash_config;
401   option status="in_progress";
402 };
403
404 /** \brief Set the ip flow hash router ID
405     @param client_index - opaque cookie to identify the sender
406     @param context - sender context, to match reply w/ request
407     @param router_id - The ID of the router. Mixed into the hash.
408                        Used to prevent polarisation across a network,
409                        since each router is assumed to have a different ID
410 */
411 autoreply define set_ip_flow_hash_router_id
412 {
413   u32 client_index;
414   u32 context;
415   u32 router_id;
416 };
417
418 /** \brief IPv6 interface enable / disable request
419     @param client_index - opaque cookie to identify the sender
420     @param context - sender context, to match reply w/ request
421     @param sw_if_index - interface used to reach neighbor
422     @param enable - if non-zero enable ip6 on interface, else disable
423 */
424 autoreply define sw_interface_ip6_enable_disable
425 {
426   u32 client_index;
427   u32 context;
428   vl_api_interface_index_t sw_if_index;
429   bool enable;                  /* set to true if enable */
430 };
431
432 /** \brief Dump IP multicast fib table
433     @param client_index - opaque cookie to identify the sender
434 */
435 define ip_mtable_dump
436 {
437   u32 client_index;
438   u32 context;
439 };
440 define ip_mtable_details
441 {
442   u32 client_index;
443   u32 context;
444   vl_api_ip_table_t table;
445 };
446
447 /** \brief Add / del route request
448
449     Adds a route, consisting both of the MFIB entry to match packets
450     (which may already exist) and a path to send those packets down.
451     Routes can be entered repeatedly to add multiple paths.  Deletions are
452     per-path.
453
454     @param client_index - opaque cookie to identify the sender
455     @param context - sender context, to match reply w/ request
456     @param table_id - fib table /vrf associated with the route
457     @param is_add - true if adding a route; false if deleting one
458     @param is_ipv6 - true iff all the addresses are v6
459     @param entry_flags - see fib_entry_flag_t
460     @param itf_flags - see mfib_entry_flags_t
461     @param next_hop_afi - see dpo_proto_t; the type of destination description
462     @param src_address - the source of the packet
463     @param grp_address - the group the packet is destined to
464     @param nh_address - the nexthop to forward the packet to
465     @param next_hop_sw_if_index - interface to emit packet on
466
467     BIER AFIs use the BIER imposition ID.  v4 and v6 AFIs use either the
468     interface or the nexthop address.
469
470     Note that if the route is source-specific (S is supplied, not all 0s),
471     the prefix match is treated as exact (prefixlen /32 or /128).
472
473     FIXME not complete yet
474 */
475 typedef ip_mroute
476 {
477   u32 table_id;
478   vl_api_mfib_entry_flags_t entry_flags;
479   u32 rpf_id;
480   vl_api_mprefix_t prefix;
481   u8 n_paths;
482   vl_api_mfib_path_t paths[n_paths];
483 };
484
485 define ip_mroute_add_del
486 {
487   u32 client_index;
488   u32 context;
489   bool is_add [default=true];
490   bool is_multipath;
491   vl_api_ip_mroute_t route;
492 };
493 define ip_mroute_add_del_reply
494 {
495   u32 context;
496   i32 retval;
497   u32 stats_index;
498 };
499
500 /** \brief Dump IP multicast fib table
501     @param table - The table from which to dump routes (ony ID an AF are needed)
502 */
503 define ip_mroute_dump
504 {
505   u32 client_index;
506   u32 context;
507   vl_api_ip_table_t table;
508 };
509
510 /** \brief IP Multicast Route Details
511     @param route - Details of the route
512 */
513 define ip_mroute_details
514 {
515   u32 context;
516   vl_api_ip_mroute_t route;
517 };
518
519 define ip_address_details
520 {
521   u32 context;
522   vl_api_interface_index_t sw_if_index;
523   vl_api_address_with_prefix_t prefix;
524 };
525
526 define ip_address_dump
527 {
528   u32 client_index;
529   u32 context;
530   vl_api_interface_index_t sw_if_index;
531   bool is_ipv6;
532 };
533
534 /** \brief IP unnumbered configurations
535     @param sw_if_index The interface that has unnumbered configuration
536     @param ip_sw_if_index The IP interface that it is unnumbered to
537 */
538 define ip_unnumbered_details
539 {
540   u32 context;
541   vl_api_interface_index_t sw_if_index;
542   vl_api_interface_index_t ip_sw_if_index;
543 };
544
545 /** \brief Dump IP unnumbered configurations
546     @param sw_if_index ~0 for all interfaces, else the interface desired
547 */
548 define ip_unnumbered_dump
549 {
550   u32 client_index;
551   u32 context;
552   vl_api_interface_index_t sw_if_index [default=0xffffffff];
553 };
554
555 define ip_details
556 {
557   u32 context;
558   vl_api_interface_index_t sw_if_index;
559   bool is_ipv6;
560 };
561
562 define ip_dump
563 {
564   u32 client_index;
565   u32 context;
566   bool is_ipv6;
567 };
568
569 define mfib_signal_dump
570 {
571   u32 client_index;
572   u32 context;
573 };
574
575 define mfib_signal_details
576 {
577   u32 context;
578   vl_api_interface_index_t sw_if_index;
579   u32 table_id;
580   vl_api_mprefix_t prefix;
581   u16 ip_packet_len;
582   u8 ip_packet_data[256];
583 };
584
585 /** \brief IP punt policer
586     @param client_index - opaque cookie to identify the sender
587     @param context - sender context, to match reply w/ request
588     @param is_add - 1 to add neighbor, 0 to delete
589     @param is_ipv6 - 1 for IPv6 neighbor, 0 for IPv4
590     @param policer_index - Index of policer to use
591 */
592 autoreply define ip_punt_police
593 {
594   u32 client_index;
595   u32 context;
596   u32 policer_index;
597   bool is_add [default=true];
598   bool is_ip6;
599 };
600
601 /** \brief Punt redirect type
602     @param rx_sw_if_index - specify the original RX interface of traffic
603                             that should be redirected. ~0 means any interface.
604     @param tx_sw_if_index - the TX interface to which traffic should be
605                             redirected.
606     @param nh - the next-hop to redirect the traffic to.
607     @param is_ipv6 - 1 for IPv6 neighbor, 0 for IPv4
608 */
609 typedef punt_redirect
610 {
611   vl_api_interface_index_t rx_sw_if_index;
612   vl_api_interface_index_t tx_sw_if_index;
613   vl_api_address_t nh;
614 };
615
616 /** \brief IP punt redirect
617     @param client_index - opaque cookie to identify the sender
618     @param context - sender context, to match reply w/ request
619     @param punt - punt definition
620     @param is_add - 1 to add neighbor, 0 to delete
621 */
622 autoreply define ip_punt_redirect
623 {
624   option deprecated;
625   u32 client_index;
626   u32 context;
627   vl_api_punt_redirect_t punt;
628   bool is_add [default=true];
629 };
630
631 define ip_punt_redirect_dump
632 {
633   u32 client_index;
634   u32 context;
635   vl_api_interface_index_t sw_if_index;
636   bool is_ipv6;
637 };
638
639 define ip_punt_redirect_details
640 {
641   u32 context;
642   vl_api_punt_redirect_t punt;
643 };
644
645 /** \brief Punt redirect type
646     @param rx_sw_if_index - specify the original RX interface of traffic
647                             that should be redirected. ~0 means any interface.
648     @param af - Address family (ip4 or ip6)
649     @param paths - the TX paths to which traffic should be redirected.
650 */
651 typedef punt_redirect_v2
652 {
653   vl_api_interface_index_t rx_sw_if_index [default=0xffffffff];
654   vl_api_address_family_t af;
655   u32 n_paths;
656   vl_api_fib_path_t paths[n_paths];
657 };
658
659 /** \brief Add IP punt redirect rule
660     @param client_index - opaque cookie to identify the sender
661     @param context - sender context, to match reply w/ request
662     @param punt - punt definition
663     @param is_add - 1 to add punt_redirect rule, 0 to delete
664 */
665 autoreply define add_del_ip_punt_redirect_v2
666 {
667   u32 client_index;
668   u32 context;
669   bool is_add [default=true];
670   vl_api_punt_redirect_v2_t punt;
671 };
672
673 define ip_punt_redirect_v2_dump
674 {
675   u32 client_index;
676   u32 context;
677   vl_api_interface_index_t sw_if_index;
678   vl_api_address_family_t af;
679 };
680
681 define ip_punt_redirect_v2_details
682 {
683   u32 context;
684   vl_api_punt_redirect_v2_t punt;
685 };
686
687 autoreply define ip_container_proxy_add_del
688 {
689   u32 client_index;
690   u32 context;
691   vl_api_prefix_t pfx;
692   vl_api_interface_index_t sw_if_index;
693   bool is_add [default=true];
694 };
695
696 define ip_container_proxy_dump
697 {
698   u32 client_index;
699   u32 context;
700 };
701
702 define ip_container_proxy_details
703 {
704   u32 context;
705   vl_api_interface_index_t sw_if_index;
706   vl_api_prefix_t prefix;
707 };
708
709 /** \brief Configure IP source and L4 port-range check
710     @param client_index - opaque cookie to identify the sender
711     @param context - sender context, to match reply w/ request
712     @param is_ip6 - 1 if source address type is IPv6
713     @param is_add - 1 if add, 0 if delete
714     @param ip - prefix to match
715     @param number_of_ranges - length of low_port and high_port arrays (must match)
716     @param low_ports[32] - up to 32 low end of port range entries (must have corresponding high_ports entry)
717     @param high_ports[32] - up to 32 high end of port range entries (must have corresponding low_ports entry)
718     @param vrf_id - fib table/vrf id to associate the source and port-range check with
719     @note To specify a single port set low_port and high_port entry the same
720 */
721 autoreply define ip_source_and_port_range_check_add_del
722 {
723   u32 client_index;
724   u32 context;
725   bool is_add [default=true];
726   vl_api_prefix_t prefix;
727   u8 number_of_ranges;
728   u16 low_ports[32];
729   u16 high_ports[32];
730   u32 vrf_id;
731 };
732
733 /** \brief Set interface source and L4 port-range request
734     @param client_index - opaque cookie to identify the sender
735     @param context - sender context, to match reply w/ request
736     @param interface_id - interface index
737     @param tcp_vrf_id - VRF associated with source and TCP port-range check
738     @param udp_vrf_id - VRF associated with source and TCP port-range check
739 */
740 autoreply define ip_source_and_port_range_check_interface_add_del
741 {
742   u32 client_index;
743   u32 context;
744   bool is_add [default=true];
745   vl_api_interface_index_t sw_if_index;
746   u32 tcp_in_vrf_id;
747   u32 tcp_out_vrf_id;
748   u32 udp_in_vrf_id;
749   u32 udp_out_vrf_id;
750 };
751
752 /** \brief IPv6 set link local address on interface request
753     @param client_index - opaque cookie to identify the sender
754     @param context - sender context, to match reply w/ request
755     @param sw_if_index - interface to set link local on
756     @param ip - the new link local address
757 */
758 autoreply define sw_interface_ip6_set_link_local_address
759 {
760   u32 client_index;
761   u32 context;
762   vl_api_interface_index_t sw_if_index;
763   vl_api_ip6_address_t ip;
764 };
765
766 /** \brief IPv6 get link local address on interface request
767     @param client_index - opaque cookie to identify the sender
768     @param context - sender context, to match reply w/ request
769     @param sw_if_index - interface to set link local on
770 */
771 define sw_interface_ip6_get_link_local_address
772 {
773   u32 client_index;
774   u32 context;
775   vl_api_interface_index_t sw_if_index;
776 };
777
778 /** \brief IPv6 link local address detail
779     @param context - sender context, to match reply w/ request
780     @param ip - the link local address
781 */
782 define sw_interface_ip6_get_link_local_address_reply
783 {
784   u32 context;
785   i32 retval;
786   vl_api_ip6_address_t ip;
787 };
788
789 /** \brief IOAM enable : Enable in-band OAM
790     @param id - profile id
791     @param seqno - To enable Seqno Processing
792     @param analyse - Enabling analysis of iOAM at decap node
793     @param pow_enable - Proof of Work enabled or not flag
794     @param trace_enable - iOAM Trace enabled or not flag
795 */
796 autoreply define ioam_enable
797 {
798   u32 client_index;
799   u32 context;
800   u16 id;
801   bool seqno;
802   bool analyse;
803   bool pot_enable;
804   bool trace_enable;
805   u32 node_id;
806 };
807
808 /** \brief iOAM disable
809     @param client_index - opaque cookie to identify the sender
810     @param context - sender context, to match reply w/ request
811     @param index - MAP Domain index
812 */
813 autoreply define ioam_disable
814 {
815   u32 client_index;
816   u32 context;
817   u16 id;
818 };
819
820 enum ip_reass_type
821 {
822   IP_REASS_TYPE_FULL = 0,
823   IP_REASS_TYPE_SHALLOW_VIRTUAL = 0x1,
824 };
825
826 autoreply define ip_reassembly_set
827 {
828   u32 client_index;
829   u32 context;
830   u32 timeout_ms;
831   u32 max_reassemblies;
832   u32 max_reassembly_length;
833   u32 expire_walk_interval_ms;
834   bool is_ip6;
835   vl_api_ip_reass_type_t type;
836 };
837
838 define ip_reassembly_get
839 {
840   u32 client_index;
841   u32 context;
842   bool is_ip6;
843   vl_api_ip_reass_type_t type;
844 };
845
846 define ip_reassembly_get_reply
847 {
848   u32 context;
849   i32 retval;
850   u32 timeout_ms;
851   u32 max_reassemblies;
852   u32 max_reassembly_length;
853   u32 expire_walk_interval_ms;
854   bool is_ip6;
855 };
856
857 /** \brief Enable/disable reassembly feature
858     @param client_index - opaque cookie to identify the sender
859     @param context - sender context, to match reply w/ request
860     @param sw_if_index - interface to enable/disable feature on
861     @param enable_ip4 - enable ip4 reassembly if non-zero, disable if 0
862     @param enable_ip6 - enable ip6 reassembly if non-zero, disable if 0
863 */
864 autoreply define ip_reassembly_enable_disable
865 {
866   u32 client_index;
867   u32 context;
868   vl_api_interface_index_t sw_if_index;
869   bool enable_ip4;
870   bool enable_ip6;
871   vl_api_ip_reass_type_t type;
872 };
873
874 /** enable/disable full reassembly of packets aimed at our addresses */
875 autoreply define ip_local_reass_enable_disable
876 {
877   u32 client_index;
878   u32 context;
879   bool enable_ip4;
880   bool enable_ip6;
881 };
882
883 /** get status of local reassembly */
884 define ip_local_reass_get
885 {
886   u32 client_index;
887   u32 context;
888 };
889
890 define ip_local_reass_get_reply
891 {
892   u32 context;
893   i32 retval;
894   bool ip4_is_enabled;
895   bool ip6_is_enabled;
896 };
897
898 /**
899     @brief Set a Path MTU value. i.e. a MTU value for a given neighbour.
900            The neighbour can be described as attached (w/ interface and next-hop)
901            or remote (w/ table_id and next-hop);
902     @param client_index - opaque cookie to identify the sender
903     @param context - sender context, to match reply w/ request
904     @param table_id - table-ID for next-hop
905     @param nh - Next hop
906     @param path_mtu - value to set, 0 is disable.
907 */
908 typedef ip_path_mtu
909 {
910   u32 client_index;
911   u32 context;
912   u32 table_id;
913   vl_api_address_t nh;
914   u16 path_mtu;
915 };
916 autoreply define ip_path_mtu_update
917 {
918   u32 client_index;
919   u32 context;
920   vl_api_ip_path_mtu_t pmtu;
921 };
922 define ip_path_mtu_get
923 {
924   u32 client_index;
925   u32 context;
926   u32 cursor;
927 };
928 define ip_path_mtu_get_reply
929 {
930   u32 context;
931   i32 retval;
932   u32 cursor;
933 };
934 define ip_path_mtu_details
935 {
936   u32 context;
937   vl_api_ip_path_mtu_t pmtu;
938 };
939 service {
940   rpc ip_path_mtu_get returns ip_path_mtu_get_reply
941     stream ip_path_mtu_details;
942 };
943
944 autoreply define ip_path_mtu_replace_begin
945 {
946   u32 client_index;
947   u32 context;
948 };
949 autoreply define ip_path_mtu_replace_end
950 {
951   u32 client_index;
952   u32 context;
953 };
954
955 counters ip_frag {
956   none {
957     severity info;
958     type counter64;
959     units "packets";
960     description "packet fragmented";
961   };
962   small_packet {
963     severity error;
964     type counter64;
965     units "packets";
966     description "packet smaller than MTU";
967   };
968   fragment_sent {
969     severity info;
970     type counter64;
971     units "packets";
972     description "number of sent fragments";
973   };
974   cant_fragment_header {
975     severity error;
976     type counter64;
977     units "packets";
978     description "can't fragment header";
979   };
980   dont_fragment_set {
981     severity error;
982     type counter64;
983     units "packets";
984     description "can't fragment this packet";
985   };
986   malformed {
987     severity error;
988     type counter64;
989     units "packets";
990     description "malformed packet";
991   };
992   memory {
993     severity error;
994     type counter64;
995     units "packets";
996     description "could not allocate buffer";
997   };
998   unknown {
999     severity error;
1000     type counter64;
1001     units "packets";
1002     description "unknown error";
1003   };
1004 };
1005
1006 counters ip4 {
1007   /* Must be first. */
1008   none {
1009     severity info;
1010     type counter64;
1011     units "packets";
1012     description "valid ip4 packets";
1013   };
1014
1015   /* Errors signalled by ip4-input */
1016   too_short {
1017     severity error;
1018     type counter64;
1019     units "packets";
1020     description "ip4 length < 20 bytes";
1021   };
1022   bad_length {
1023     severity error;
1024     type counter64;
1025     units "packets";
1026     description "ip4 length > l2 length";
1027   };
1028   bad_checksum {
1029     severity error;
1030     type counter64;
1031     units "packets";
1032     description "bad ip4 checksum";
1033   };
1034   version {
1035     severity error;
1036     type counter64;
1037     units "packets";
1038     description "ip4 version != 4";
1039   };
1040   options {
1041     severity info;
1042     type counter64;
1043     units "packets";
1044     description "ip4 options present";
1045   };
1046   fragment_offset_one {
1047     severity error;
1048     type counter64;
1049     units "packets";
1050     description "ip4 fragment offset == 1";
1051   };
1052   time_expired {
1053     severity error;
1054     type counter64;
1055     units "packets";
1056     description "ip4 ttl <= 1";
1057   };
1058   hdr_too_short {
1059     severity error;
1060     type counter64;
1061     units "packets";
1062     description "ip4 IHL < 5";
1063   };
1064
1065   /* Errors signalled by ip4-rewrite. */
1066   mtu_exceeded {
1067     severity error;
1068     type counter64;
1069     units "packets";
1070     description "ip4 MTU exceeded and DF set";
1071   };
1072   dst_lookup_miss {
1073     severity error;
1074     type counter64;
1075     units "packets";
1076     description "ip4 destination lookup miss";
1077   };
1078   src_lookup_miss {
1079     severity error;
1080     type counter64;
1081     units "packets";
1082     description "ip4 source lookup miss";
1083   };
1084   drop {
1085     severity error;
1086     type counter64;
1087     units "packets";
1088     description "ip4 drop";
1089   };
1090   punt {
1091     severity error;
1092     type counter64;
1093     units "packets";
1094     description "ip4 punt";
1095   };
1096   same_interface {
1097     severity error;
1098     type counter64;
1099     units "packets";
1100     description "ip4 egress interface same as ingress";
1101   };
1102
1103   /* errors signalled by ip4-local. */
1104   unknown_protocol {
1105     severity error;
1106     type counter64;
1107     units "packets";
1108     description "unknown ip protocol";
1109   };
1110   tcp_checksum {
1111     severity error;
1112     type counter64;
1113     units "packets";
1114     description "bad tcp checksum";
1115   };
1116   udp_checksum {
1117     severity error;
1118     type counter64;
1119     units "packets";
1120     description "bad udp checksum";
1121   };
1122   udp_length {
1123     severity error;
1124     type counter64;
1125     units "packets";
1126     description "inconsistent udp/ip lengths";
1127   };
1128
1129   /* spoofed packets in ip4-rewrite-local */
1130   spoofed_local_packets {
1131     severity error;
1132     type counter64;
1133     units "packets";
1134     description "ip4 spoofed local-address packet drops";
1135   };
1136
1137   /* Errors signalled by ip4-inacl */
1138   inacl_table_miss {
1139     severity error;
1140     type counter64;
1141     units "packets";
1142     description "input ACL table-miss drops";
1143   };
1144   inacl_session_deny {
1145     severity error;
1146     type counter64;
1147     units "packets";
1148     description "input ACL session deny drops";
1149   };
1150
1151   /* Errors singalled by ip4-outacl */
1152   outacl_table_miss {
1153     severity error;
1154     type counter64;
1155     units "packets";
1156     description "output ACL table-miss drops";
1157   };
1158   outacl_session_deny {
1159     severity error;
1160     type counter64;
1161     units "packets";
1162     description "output ACL session deny drops";
1163   };
1164
1165   /* Errors from mfib-forward */
1166   rpf_failure {
1167     severity error;
1168     type counter64;
1169     units "packets";
1170     description "Multicast RPF check failed";
1171   };
1172
1173   /* Errors signalled by ip4-reassembly */
1174   reass_duplicate_fragment {
1175     severity error;
1176     type counter64;
1177     units "packets";
1178     description "duplicate/overlapping fragments";
1179   };
1180   reass_limit_reached {
1181     severity error;
1182     type counter64;
1183     units "packets";
1184     description "drops due to concurrent reassemblies limit";
1185   };
1186   reass_fragment_chain_too_long {
1187     severity error;
1188     type counter64;
1189     units "packets";
1190     description "fragment chain too long (drop)";
1191   };
1192   reass_no_buf {
1193     severity error;
1194     type counter64;
1195     units "packets";
1196     description "out of buffers (drop)";
1197   };
1198   reass_malformed_packet {
1199     severity error;
1200     type counter64;
1201     units "packets";
1202     description "malformed packets";
1203   };
1204   reass_internal_error {
1205     severity error;
1206     type counter64;
1207     units "packets";
1208     description "drops due to internal reassembly error";
1209   };
1210   reass_timeout {
1211     severity error;
1212     type counter64;
1213     units "packets";
1214     description "fragments dropped due to reassembly timeout";
1215   };
1216   reass_to_custom_app {
1217     severity error;
1218     type counter64;
1219     units "packets";
1220     description "send to custom drop app";
1221   };
1222   reass_success {
1223     severity info;
1224     type counter64;
1225     units "packets";
1226     description "successful reassemblies";
1227   };
1228   reass_fragments_reassembled {
1229     severity info;
1230     type counter64;
1231     units "packets";
1232     description "fragments reassembled";
1233   };
1234   reass_fragments_rcvd {
1235     severity info;
1236     type counter64;
1237     units "packets";
1238     description "fragments received";
1239   };
1240   reass_unsupp_ip_prot {
1241     severity error;
1242     type counter64;
1243     units "packets";
1244     description "unsupported ip protocol";
1245   };
1246 };
1247
1248 /**
1249  * IPv6 Error/info counters
1250  */
1251 counters ip6 {
1252   /* Must be first. */
1253   none {
1254     severity info;
1255     type counter64;
1256     units "packets";
1257     description "valid ip6 packets";
1258   };
1259
1260   /* Errors signalled by ip6-input */
1261   too_short {
1262     severity error;
1263     type counter64;
1264     units "packets";
1265     description "ip6 length < 40 bytes";
1266   };
1267   bad_length {
1268     severity error;
1269     type counter64;
1270     units "packets";
1271     description "ip6 length > l2 length";
1272   };
1273   version {
1274     severity error;
1275     type counter64;
1276     units "packets";
1277     description "ip6 version != 6";
1278   };
1279   time_expired {
1280     severity error;
1281     type counter64;
1282     units "packets";
1283     description "ip6 ttl <= 1";
1284   };
1285
1286   /* Errors signalled by ip6-rewrite. */
1287   mtu_exceeded {
1288     severity error;
1289     type counter64;
1290     units "packets";
1291     description "ip6 MTU exceeded";
1292   };
1293   dst_lookup_miss {
1294     severity error;
1295     type counter64;
1296     units "packets";
1297     description "ip6 destination lookup miss";
1298   };
1299   src_lookup_miss {
1300     severity error;
1301     type counter64;
1302     units "packets";
1303     description "ip6 source lookup miss";
1304   };
1305   drop {
1306     severity error;
1307     type counter64;
1308     units "packets";
1309     description "ip6 drop";
1310   };
1311   punt {
1312     severity error;
1313     type counter64;
1314     units "packets";
1315     description "ip6 punt";
1316   };
1317
1318   /* errors signalled by ip6-local. */
1319   unknown_protocol {
1320     severity error;
1321     type counter64;
1322     units "packets";
1323     description "unknown ip protocol";
1324   };
1325   udp_checksum {
1326     severity error;
1327     type counter64;
1328     units "packets";
1329     description "bad udp checksum";
1330   };
1331   icmp_checksum {
1332     severity error;
1333     type counter64;
1334     units "packets";
1335     description "bad icmp checksum";
1336   };
1337   udp_length {
1338     severity error;
1339     type counter64;
1340     units "packets";
1341     description "inconsistent udp/ip lengths";
1342   };
1343   /* Errors signalled by udp6-lookup. */
1344   unknown_udp_port {
1345     severity error;
1346     type counter64;
1347     units "packets";
1348     description "no listener for udp port";
1349   };
1350
1351   /* spoofed packets in ip6-rewrite-local */
1352   spoofed_local_packets {
1353     severity error;
1354     type counter64;
1355     units "packets";
1356     description "ip6 spoofed local-address packet drops";
1357   };
1358
1359   /* Errors signalled by ip6-inacl */
1360   inacl_table_miss {
1361     severity error;
1362     type counter64;
1363     units "packets";
1364     description "input ACL table-miss drops";
1365   };
1366   inacl_session_deny {
1367     severity error;
1368     type counter64;
1369     units "packets";
1370     description "input ACL session deny drops";
1371   };
1372
1373   /* Errors singalled by ip6-outacl */
1374   outacl_table_miss {
1375     severity error;
1376     type counter64;
1377     units "packets";
1378     description "output ACL table-miss drops";
1379   };
1380   outacl_session_deny {
1381     severity error;
1382     type counter64;
1383     units "packets";
1384     description "output ACL session deny drops";
1385   };
1386
1387   /* Errors from mfib-forward */
1388   rpf_failure {
1389     severity error;
1390     type counter64;
1391     units "packets";
1392     description "Multicast RPF check failed";
1393   };
1394
1395   /* Errors signalled by ip6-reassembly */
1396   reass_missing_upper {
1397     severity error;
1398     type counter64;
1399     units "packets";
1400     description "missing-upper layer drops";
1401   };
1402   reass_duplicate_fragment {
1403     severity error;
1404     type counter64;
1405     units "packets";
1406     description "duplicate fragments";
1407   };
1408   reass_overlapping_fragment {
1409     severity error;
1410     type counter64;
1411     units "packets";
1412     description "overlapping fragments";
1413   };
1414   reass_limit_reached {
1415     severity error;
1416     type counter64;
1417     units "packets";
1418     description "drops due to concurrent reassemblies limit";
1419   };
1420   reass_fragment_chain_too_long {
1421     severity error;
1422     type counter64;
1423     units "packets";
1424     description "fragment chain too long (drop)";
1425   };
1426   reass_no_buf {
1427     severity error;
1428     type counter64;
1429     units "packets";
1430     description "out of buffers (drop)";
1431   };
1432   reass_timeout {
1433     severity error;
1434     type counter64;
1435     units "packets";
1436     description "fragments dropped due to reassembly timeout";
1437   };
1438   reass_internal_error {
1439     severity error;
1440     type counter64;
1441     units "packets";
1442     description "drops due to internal reassembly error";
1443   };
1444   reass_invalid_frag_len {
1445     severity error;
1446     type counter64;
1447     units "packets";
1448     description "invalid fragment length";
1449   };
1450   reass_to_custom_app {
1451     severity error;
1452     type counter64;
1453     units "packets";
1454     description "send to custom drop app";
1455   };
1456   reass_no_frag_hdr {
1457     severity error;
1458     type counter64;
1459     units "packets";
1460     description "no fragmentation header";
1461   };
1462   reass_invalid_frag_size {
1463     severity error;
1464     type counter64;
1465     units "packets";
1466     description "drop due to invalid fragment size";
1467   };
1468   reass_success {
1469     severity info;
1470     type counter64;
1471     units "packets";
1472     description "successful reassemblies";
1473   };
1474   reass_fragments_reassembled {
1475     severity info;
1476     type counter64;
1477     units "packets";
1478     description "fragments reassembled";
1479   };
1480   reass_fragments_rcvd {
1481     severity info;
1482     type counter64;
1483     units "packets";
1484     description "fragments received";
1485   };
1486   reass_unsupp_ip_proto {
1487     severity error;
1488     type counter64;
1489     units "packets";
1490     description "unsupported ip protocol";
1491   };
1492 };
1493
1494 counters icmp4 {
1495   none {
1496     severity info;
1497     type counter64;
1498     units "packets";
1499     description "valid packets";
1500   };
1501   unknown_type {
1502     severity error;
1503     type counter64;
1504     units "packets";
1505     description "unknown type";
1506   };
1507   invalid_code_for_type {
1508     severity error;
1509     type counter64;
1510     units "packets";
1511     description "invalid code for type";
1512   };
1513   invalid_hop_limit_for_type {
1514     severity error;
1515     type counter64;
1516     units "packets";
1517     description "hop_limit != 255";
1518   };
1519   length_too_small_for_type {
1520     severity error;
1521     type counter64;
1522     units "packets";
1523     description "payload length too small for type";
1524   };
1525   options_with_odd_length {
1526     severity error;
1527     type counter64;
1528     units "packets";
1529     description "total option length not multiple of 8 bytes";
1530   };
1531   option_with_zero_length {
1532     severity error;
1533     type counter64;
1534     units "packets";
1535     description "option has zero length";
1536   };
1537   echo_replies_sent {
1538     severity info;
1539     type counter64;
1540     units "packets";
1541     description "echo replies sent";
1542   };
1543   dst_lookup_miss {
1544     severity error;
1545     type counter64;
1546     units "packets";
1547     description "icmp6 dst address lookup misses";
1548   };
1549   dest_unreach_sent {
1550     severity info;
1551     type counter64;
1552     units "packets";
1553     description "destination unreachable response sent";
1554   };
1555   ttl_expire_sent {
1556     severity info;
1557     type counter64;
1558     units "packets";
1559     description "hop limit exceeded response sent";
1560   };
1561   param_problem_sent {
1562     severity info;
1563     type counter64;
1564     units "packets";
1565     description "parameter problem response sent";
1566   };
1567   drop {
1568     severity error;
1569     type counter64;
1570     units "packets";
1571     description "error message dropped";
1572   };
1573 };
1574
1575 counters icmp6 {
1576   none {
1577     severity info;
1578     type counter64;
1579     units "packets";
1580     description "valid packets";
1581   };
1582   unknown_type {
1583     severity error;
1584     type counter64;
1585     units "packets";
1586     description "unknown type";
1587   };
1588   invalid_code_for_type {
1589     severity error;
1590     type counter64;
1591     units "packets";
1592     description "invalid code for type";
1593   };
1594   invalid_hop_limit_for_type {
1595     severity error;
1596     type counter64;
1597     units "packets";
1598     description "hop_limit != 255";
1599   };
1600   length_too_small_for_type {
1601     severity error;
1602     type counter64;
1603     units "packets";
1604     description "payload length too small for type";
1605   };
1606   options_with_odd_length {
1607     severity error;
1608     type counter64;
1609     units "packets";
1610     description "total option length not multiple of 8 bytes";
1611   };
1612   option_with_zero_length {
1613     severity error;
1614     type counter64;
1615     units "packets";
1616     description "option has zero length";
1617   };
1618   echo_replies_sent {
1619     severity info;
1620     type counter64;
1621     units "packets";
1622     description "echo replies sent";
1623   };
1624   neighbor_solicitation_source_not_on_link {
1625     severity error;
1626     type counter64;
1627     units "packets";
1628     description "neighbor solicitations from source not on link";
1629   };
1630   neighbor_solicitation_source_unknown {
1631     severity error;
1632     type counter64;
1633     units "packets";
1634     description "neighbor solicitations for unknown targets";
1635   };
1636   neighbor_advertisements_tx {
1637     severity info;
1638     type counter64;
1639     units "packets";
1640     description "neighbor advertisements sent";
1641   };
1642   neighbor_advertisements_rx {
1643     severity info;
1644     type counter64;
1645     units "packets";
1646     description "neighbor advertisements received";
1647   };
1648   router_solicitation_source_not_on_link {
1649     severity error;
1650     type counter64;
1651     units "packets";
1652     description "router solicitations from source not on link";
1653   };
1654   router_solicitation_unsupported_intf {
1655     severity error;
1656     type counter64;
1657     units "packets";
1658     description "neighbor discovery unsupported interface";
1659   };
1660   router_solicitation_radv_not_config {
1661     severity error;
1662     type counter64;
1663     units "packets";
1664     description "neighbor discovery not configured";
1665   };
1666   router_advertisement_source_not_link_local {
1667     severity error;
1668     type counter64;
1669     units "packets";
1670     description "router advertisement source not link local";
1671   };
1672   router_advertisements_tx {
1673     severity info;
1674     type counter64;
1675     units "packets";
1676     description "router advertisements sent";
1677   };
1678   router_advertisements_rx {
1679     severity info;
1680     type counter64;
1681     units "packets";
1682     description "router advertisements received";
1683   };
1684   dst_lookup_miss {
1685     severity error;
1686     type counter64;
1687     units "packets";
1688     description "icmp6 dst address lookup misses";
1689   };
1690   dest_unreach_sent {
1691     severity info;
1692     type counter64;
1693     units "packets";
1694     description "destination unreachable response sent";
1695   };
1696   packet_too_big_sent {
1697     severity info;
1698     type counter64;
1699     units "packets";
1700     description "packet too big response sent";
1701   };
1702   ttl_expire_sent {
1703     severity info;
1704     type counter64;
1705     units "packets";
1706     description "hop limit exceeded response sent";
1707   };
1708   param_problem_sent {
1709     severity info;
1710     type counter64;
1711     units "packets";
1712     description "parameter problem response sent";
1713   };
1714   drop {
1715     severity error;
1716     type counter64;
1717     units "packets";
1718     description "error message dropped";
1719   };
1720   alloc_failure {
1721     severity error;
1722     type counter64;
1723     units "packets";
1724     description "buffer allocation failure";
1725   };
1726 };
1727
1728 paths {
1729   "/err/ip-frag" "ip_frag";
1730   "/err/mpls-frag" "ip_frag";
1731   "/err/ip4-mpls-label-disposition-pipe" "ip4";
1732   "/err/ip4-mpls-label-disposition-uniform" "ip4";
1733   "/err/ip4-local" "ip4";
1734   "/err/ip4-input" "ip4";
1735   "/err/ip4-full-reassembly" "ip4";
1736   "/err/ip4-local-full-reassembly" "ip4";
1737   "/err/ip4-full-reassembly-feature" "ip4";
1738   "/err/ip4-full-reassembly-custom" "ip4";
1739   "/err/ip4-full-reassembly-expire-walk" "ip4";
1740   "/err/ip4-sv-reassembly" "ip4";
1741   "/err/ip4-sv-reassembly-feature" "ip4";
1742   "/err/ip4-sv-reassembly-output-feature" "ip4";
1743   "/err/ip4-sv-reassembly-custom-next" "ip4";
1744   "/err/ip4-sv-reassembly-expire-walk" "ip4";
1745   "/err/ip6-mpls-label-disposition-pipe" "ip6";
1746   "/err/ip6-mpls-label-disposition-uniform" "ip6";
1747   "/err/ip6-local" "ip6";
1748   "/err/ip6-input" "ip6";
1749   "/err/ip6-full-reassembly" "ip6";
1750   "/err/ip6-local-full-reassembly" "ip6";
1751   "/err/ip6-full-reassembly-feature" "ip6";
1752   "/err/ip6-full-reassembly-custom" "ip6";
1753   "/err/ip6-full-reassembly-expire-walk" "ip6";
1754   "/err/ip6-sv-reassembly" "ip6";
1755   "/err/ip6-sv-reassembly-feature" "ip6";
1756   "/err/ip6-sv-reassembly-output-feature" "ip6";
1757   "/err/ip6-sv-reassembly-custom-next" "ip6";
1758   "/err/ip6-sv-reassembly-expire-walk" "ip6";
1759   "/err/ip4-icmp-input" "icmp4";
1760   "/err/ip4-icmp-error" "icmp4";
1761   "/err/ip6-icmp-input" "icmp6";
1762   "/err/ip6-icmp-error" "icmp6";
1763 };
1764
1765 /*
1766  * Local Variables:
1767  * eval: (c-set-style "gnu")
1768  * End:
1769  */