VPP-286: Add CLI Command documentation via doxygen comments for vnet/vnet/ip. 93/3393/1
authorBilly McFall <bmcfall@redhat.com>
Thu, 13 Oct 2016 12:27:31 +0000 (08:27 -0400)
committerBilly McFall <bmcfall@redhat.com>
Thu, 13 Oct 2016 12:29:02 +0000 (08:29 -0400)
Change-Id: Ie1be9dc057d07c250852952ea159ed3c44c25f5f
Signed-off-by: Billy McFall <bmcfall@redhat.com>
14 files changed:
vnet/vnet/fib/ip4_fib.c
vnet/vnet/fib/ip6_fib.c
vnet/vnet/ip/dir.dox [new file with mode: 0644]
vnet/vnet/ip/ip46_cli.c
vnet/vnet/ip/ip4_forward.c
vnet/vnet/ip/ip4_source_and_port_range_check.c
vnet/vnet/ip/ip4_source_check.c
vnet/vnet/ip/ip4_test.c
vnet/vnet/ip/ip6_forward.c
vnet/vnet/ip/ip6_hop_by_hop.c
vnet/vnet/ip/ip6_neighbor.c
vnet/vnet/ip/ip_feature_registration.c
vnet/vnet/ip/lookup.c
vnet/vnet/ip/ping.c

index 21ebb7a..17d0a54 100644 (file)
@@ -512,31 +512,60 @@ ip4_show_fib (vlib_main_t * vm,
 }
 
 /*?
- * Show FIB/route entries
+ * This command displays the IPv4 FIB Tables (VRF Tables) and the route
+ * entries for each table.
+ *
+ * @note This command will run for a long time when the FIB tables are
+ * comprised of millions of entries. For those senarios, consider displaying
+ * a single table or summary mode.
  *
  * @cliexpar
+ * Example of how to display all the IPv4 FIB tables:
  * @cliexstart{show ip fib}
- * Display the IPv4 FIB.
- * This command will run for a long time when the FIBs comprise millions of entries.
- *   vpp# sh ip fib
- *   Table 0
- *   Destination         Packets          Bytes         Adjacency
- *   6.0.0.0/8                          0               0 weight 1, index 3
- *                                                       arp fake-eth0 6.0.0.1/8
- *   6.0.0.1/32                         0               0 weight 1, index 4
- *                                                        local 6.0.0.1/8
- *
- *  And so forth. Use 'show ip fib summary' for a summary:
- *
- *   vpp# sh ip fib summary
- *   Table 0
- *   Prefix length         Count
- *         8               1
- *        32               4
+ * Table 0, fib_index 0, flow hash: src dst sport dport proto
+ *      Destination         Packets          Bytes         Adjacency
+ * 172.16.2.0/24                      0               0 weight 1, index 5
+ *                                                       172.16.2.1/24
+ * 172.16.2.1/32                      0               0 weight 1, index 6
+ *                                                       172.16.2.1/24
+ * Table 7, fib_index 1, flow hash: dst sport dport proto
+ *      Destination         Packets          Bytes         Adjacency
+ * 172.16.1.0/24                      0               0 weight 1, index 3
+ *                                                       172.16.1.1/24
+ * 172.16.1.1/32                      1              98 weight 1, index 4
+ *                                                       172.16.1.1/24
+ * 172.16.1.2/32                      0               0 weight 1, index 7
+ *                                                      GigabitEthernet2/0/0
+ *                                                      IP4: 02:fe:6a:07:39:6f -> 16:d9:e0:91:79:86
+ * @cliexend
+ * Example of how to display a single IPv4 FIB table:
+ * @cliexstart{show ip fib table 7}
+ * Table 7, fib_index 1, flow hash: dst sport dport proto
+ *      Destination         Packets          Bytes         Adjacency
+ * 172.16.1.0/24                      0               0 weight 1, index 3
+ *                                                       172.16.1.1/24
+ * 172.16.1.1/32                      1              98 weight 1, index 4
+ *                                                       172.16.1.1/24
+ * 172.16.1.2/32                      0               0 weight 1, index 7
+ *                                                      GigabitEthernet2/0/0
+ *                                                      IP4: 02:fe:6a:07:39:6f -> 16:d9:e0:91:79:86
+ * @cliexend
+ * Example of how to display a summary of all IPv4 FIB tables:
+ * @cliexstart{show ip fib summary}
+ * Table 0, fib_index 0, flow hash: src dst sport dport proto
+ *     Prefix length         Count
+ *                   24               1
+ *                   32               1
+ * Table 7, fib_index 1, flow hash: dst sport dport proto
+ *     Prefix length         Count
+ *                   24               1
+ *                   32               2
  * @cliexend
  ?*/
+/* *INDENT-OFF* */
 VLIB_CLI_COMMAND (ip4_show_fib_command, static) = {
     .path = "show ip fib",
     .short_help = "show ip fib [mtrie] [summary] [table <n>] [<ip4-addr>] [clear] [include-empty]",
     .function = ip4_show_fib,
 };
+/* *INDENT-ON* */
index 772ce74..8e3c7cc 100644 (file)
@@ -682,17 +682,71 @@ ip6_show_fib (vlib_main_t * vm,
 }
 
 /*?
- * Show FIB6/route entries
+ * This command displays the IPv6 FIB Tables (VRF Tables) and the route
+ * entries for each table.
+ *
+ * @note This command will run for a long time when the FIB tables are
+ * comprised of millions of entries. For those senarios, consider displaying
+ * in summary mode.
  *
  * @cliexpar
- * @cliexstart{show ip fib}
- * Display the IPv6 FIB.
- * This command will run for a long time when the FIBs comprise millions of entries.
- * See 'show ip fib'
+ * @parblock
+ * Example of how to display all the IPv6 FIB tables:
+ * @cliexstart{show ip6 fib}
+ *  FIB lookup table: 65536 buckets, 32 MB heap
+ * 15 objects, 513k of 516k used, 600 free, 0 reclaimed, 2k overhead, 32764k capacity
+ *
+ * VRF 0, fib_index 0, flow hash: src dst sport dport proto
+ *                  Destination                      Packets          Bytes         Adjacency
+ * ff02::1/128                                                 0               0 weight 1, index 5
+ *
+ * ff02::2/128                                                 0               0 weight 1, index 4
+ *
+ * ff02::16/128                                                0               0 weight 1, index 6
+ *
+ * ff02::1:ff00:0/104                                          0               0 weight 1, index 3
+ *
+ *
+ * VRF 8, fib_index 1, flow hash: src dst sport dport proto
+ *                  Destination                      Packets          Bytes         Adjacency
+ * ::a:1:1:0:4/126                                             0               0 weight 1, index 11
+ *                                                                                ::a:1:1:0:7/126
+ * ::a:1:1:0:7/128                                             0               0 weight 1, index 12
+ *                                                                                ::a:1:1:0:7/126
+ * fe80::/64                                                   0               0 weight 1, index 16
+ *                                                                                fe80::fe:68ff:fe72:a773/64
+ * fe80::fe:68ff:fe72:a773/128                                 0               0 weight 1, index 17
+ *                                                                                fe80::fe:68ff:fe72:a773/64
+ * ff02::1/128                                                 0               0 weight 1, index 9
+ *
+ * ff02::2/128                                                 0               0 weight 1, index 8
+ *
+ * ff02::16/128                                                0               0 weight 1, index 10
+ *
+ * ff02::1:ff00:0/104                                          0               0 weight 1, index 7
+ * @cliexend
+ * Example of how to display a summary of all IPv6 FIB tables:
+ * @cliexstart{show ip6 fib summary}
+ * FIB lookup table: 65536 buckets, 32 MB heap
+ * 15 objects, 513k of 516k used, 600 free, 0 reclaimed, 2k overhead, 32764k capacity
+ *
+ * VRF 0, fib_index 0, flow hash: src dst sport dport proto
+ *     Prefix length         Count
+ *          128                3
+ *          104                1
+ * VRF 8, fib_index 1, flow hash: src dst sport dport proto
+ *     Prefix length         Count
+ *          128                5
+ *          126                1
+ *          104                1
+ *          64                 1
  * @cliexend
+ * @endparblock
  ?*/
+/* *INDENT-OFF* */
 VLIB_CLI_COMMAND (ip6_show_fib_command, static) = {
     .path = "show ip6 fib",
-    .short_help = "show ip6 fib [summary] [table <n>] [<ip6-addr>] [verboase]",
+    .short_help = "show ip6 fib [summary] [table <table-id>] [index <fib-id>] [<ip6-addr>[/<width>]]",
     .function = ip6_show_fib,
 };
+/* *INDENT-ON* */
diff --git a/vnet/vnet/ip/dir.dox b/vnet/vnet/ip/dir.dox
new file mode 100644 (file)
index 0000000..a4eb733
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* Doxygen directory documentation */
+
+/**
+@dir
+@brief Layer 3 IP Code.
+
+This directory contains the source code for IP routing.
+
+*/
+/*? %%clicmd:group_label Layer 3 IP CLI %% ?*/
index 0b598c6..01b1892 100644 (file)
 
 #include <vnet/ip/ip.h>
 
+/**
+ * @file
+ * @brief Set IP Address.
+ *
+ * Configure an IPv4 or IPv6 address for on an interface.
+ */
+
+
 int ip4_address_compare (ip4_address_t * a1, ip4_address_t * a2)
 { return clib_net_to_host_u32 (a1->data_u32) - clib_net_to_host_u32 (a2->data_u32); }
 
@@ -54,10 +62,12 @@ int ip6_address_compare (ip6_address_t * a1, ip6_address_t * a2)
   return 0;
 }
 
+/* *INDENT-OFF* */
 VLIB_CLI_COMMAND (set_interface_ip_command, static) = {
   .path = "set interface ip",
   .short_help = "IP4/IP6 commands",
 };
+/* *INDENT-ON* */
 
 void ip_del_all_interface_addresses (vlib_main_t *vm, u32 sw_if_index)
 {
@@ -161,27 +171,41 @@ add_del_ip_address (vlib_main_t * vm,
  done:
   return error;
 }
+
 /*?
- * To set an interface ip address, use "set interface ip address":
+ * Add an IP Address to an interface or remove and IP Address from an interface.
+ * The IP Address can be an IPv4 or an IPv6 address. Interfaces may have multiple
+ * IPv4 and IPv6 addresses. There is no concept of primary vs. secondary
+ * interface addresses; they're just addresses.
+ *
+ * To display the addresses associated with a given interface, use the command
+ * '<em>show interface address <interface></em>'.
+ *
+ * Note that the debug CLI does not enforce classful mask-width / addressing
+ * constraints.
  *
  * @cliexpar
- * @cliexstart{set interface ip address}
-
- *  vpp# set interface ip address GigabitEthernet2/0/0 db01::1/64
- * Note that the debug CLI does not enforce classful mask-width / addressing constraints.
- * Interfaces may have multiple ip4 and ip6 addresses.
- * There is no concept of primary vs. secondary interface addresses; they're just addresses.
- * To delete a specific interface ip address, use "set interface ip address del":
- *  vpp# set interface ip address del GigabitEthernet2/0/0 6.0.0.2/24
- * To delete all interfaces addresses (ip4+ip6), use "set interface ip address del <intfc> all"
- *  vpp# set interface ip address del GigabitEthernet2/0/0 all
- * @cliexend
+ * @parblock
+ * An example of how to add an IPv4 address to an interface:
+ * @cliexcmd{set interface ip address GigabitEthernet2/0/0 172.16.2.12/24}
+ *
+ * An example of how to add an IPv6 address to an interface:
+ * @cliexcmd{set interface ip address GigabitEthernet2/0/0 @::a:1:1:0:7/126}
+ *
+ * To delete a specific interface ip address:
+ * @cliexcmd{set interface ip address GigabitEthernet2/0/0 172.16.2.12/24 del}
+ *
+ * To delete all interfaces addresses (IPv4 and IPv6):
+ * @cliexcmd{set interface ip address GigabitEthernet2/0/0 del all}
+ * @endparblock
  ?*/
+/* *INDENT-OFF* */
 VLIB_CLI_COMMAND (set_interface_ip_address_command, static) = {
   .path = "set interface ip address",
   .function = add_del_ip_address,
-  .short_help = "Add/delete IP4/IP6 address for interface",
+  .short_help = "set interface ip address <interface> [<ip-addr>/<mask> [del]] | [del all]",
 };
+/* *INDENT-ON* */
 
 /* Dummy init function to get us linked in. */
 static clib_error_t * ip4_cli_init (vlib_main_t * vm)
index c6a6c72..2197345 100644 (file)
 #include <vnet/dpo/load_balance.h>
 #include <vnet/dpo/classify_dpo.h>
 
+/**
+ * @file
+ * @brief IPv4 Forwarding.
+ *
+ * This file contains the source code for IPv4 forwarding.
+ */
+
 void
 ip4_forward_next_trace (vlib_main_t * vm,
                         vlib_node_runtime_t * node,
@@ -1760,11 +1767,25 @@ show_ip_local_command_fn (vlib_main_t * vm,
 
 
 
+/*?
+ * Display the set of protocols handled by the local IPv4 stack.
+ *
+ * @cliexpar
+ * Example of how to display local protocol table:
+ * @cliexstart{show ip local}
+ * Protocols handled by ip4_local
+ * 1
+ * 17
+ * 47
+ * @cliexend
+?*/
+/* *INDENT-OFF* */
 VLIB_CLI_COMMAND (show_ip_local, static) = {
   .path = "show ip local",
   .function = show_ip_local_command_fn,
-  .short_help = "Show ip local protocol table",
+  .short_help = "show ip local",
 };
+/* *INDENT-ON* */
 
 always_inline uword
 ip4_arp_inline (vlib_main_t * vm,
@@ -2667,24 +2688,32 @@ add_del_interface_table (vlib_main_t * vm,
 }
 
 /*?
- * Place the indicated interface into the supplied VRF
- *
- * @cliexpar
- * @cliexstart{set interface ip table}
+ * Place the indicated interface into the supplied IPv4 FIB table (also known
+ * as a VRF). If the FIB table does not exist, this command creates it. To
+ * display the current IPv4 FIB table, use the command '<em>show ip fib</em>'.
+ * FIB table will only be displayed if a route has been added to the table, or
+ * an IP Address is assigned to an interface in the table (which adds a route
+ * automatically), or '<em>include-empty</em>' is included.
  *
- *  vpp# set interface ip table GigabitEthernet2/0/0 2
+ * @note IP addresses added after setting the interface IP table end up in
+ * the indicated FIB table. If the IP address is added prior to adding the
+ * interface to the FIB table, it will NOT be part of the FIB table. Predictable
+ * but potentially counter-intuitive results occur if you provision interface
+ * addresses in multiple FIBs. Upon RX, packets will be processed in the last
+ * IP table ID provisioned. It might be marginally useful to evade source RPF
+ * drops to put an interface address into multiple FIBs.
  *
- * Interface addresses added after setting the interface IP table end up in the indicated VRF table.
- * Predictable but potentially counter-intuitive results occur if you provision interface addresses in multiple FIBs.
- * Upon RX, packets will be processed in the last IP table ID provisioned.
- * It might be marginally useful to evade source RPF drops to put an interface address into multiple FIBs.
- * @cliexend
+ * @cliexpar
+ * Example of how to add an interface to an IPv4 FIB table (where 2 is the table-id):
+ * @cliexcmd{set interface ip table GigabitEthernet2/0/0 2}
  ?*/
+/* *INDENT-OFF* */
 VLIB_CLI_COMMAND (set_interface_ip_table_command, static) = {
   .path = "set interface ip table",
   .function = add_del_interface_table,
-  .short_help = "Add/delete FIB table id for interface",
+  .short_help = "set interface ip table <interface> <table-id>",
 };
+/* *INDENT-ON* */
 
 
 static uword
@@ -2994,11 +3023,30 @@ test_lookup_command_fn (vlib_main_t * vm,
   return 0;
 }
 
+/*?
+ * Perform a lookup of an IPv4 Address (or range of addresses) in the
+ * given FIB table to determine if there is a conflict with the
+ * adjacency table. The fib-id can be determined by using the
+ * '<em>show ip fib</em>' command. If fib-id is not entered, default value
+ * of 0 is used.
+ *
+ * @todo This command uses fib-id, other commands use table-id (not
+ * just a name, they are different indexes). Would like to change this
+ * to table-id for consistency.
+ *
+ * @cliexpar
+ * Example of how to run the test lookup command:
+ * @cliexstart{test lookup 172.16.1.1 table 1 count 2}
+ * No errors in 2 lookups
+ * @cliexend
+?*/
+/* *INDENT-OFF* */
 VLIB_CLI_COMMAND (lookup_test_command, static) = {
     .path = "test lookup",
-    .short_help = "test lookup",
+    .short_help = "test lookup <ipv4-addr> [table <fib-id>] [count <nn>]",
     .function = test_lookup_command_fn,
 };
+/* *INDENT-ON* */
 
 int vnet_set_ip4_flow_hash (u32 table_id, u32 flow_hash_config)
 {
@@ -3056,12 +3104,39 @@ set_ip_flow_hash_command_fn (vlib_main_t * vm,
   return 0;
 }
 
+/*?
+ * Configure the set of IPv4 fields used by the flow hash.
+ *
+ * @cliexpar
+ * Example of how to set the flow hash on a given table:
+ * @cliexcmd{set ip flow-hash table 7 dst sport dport proto}
+ * Example of display the configured flow hash:
+ * @cliexstart{show ip fib}
+ * Table 0, fib_index 0, flow hash: src dst sport dport proto
+ *      Destination         Packets          Bytes         Adjacency
+ * 172.16.2.0/24                      0               0 weight 1, index 5
+ *                                                       172.16.2.1/24
+ * 172.16.2.1/32                      0               0 weight 1, index 6
+ *                                                       172.16.2.1/24
+ * Table 7, fib_index 1, flow hash: dst sport dport proto
+ *      Destination         Packets          Bytes         Adjacency
+ * 172.16.1.0/24                      0               0 weight 1, index 3
+ *                                                       172.16.1.1/24
+ * 172.16.1.1/32                      1              98 weight 1, index 4
+ *                                                       172.16.1.1/24
+ * 172.16.1.2/32                      0               0 weight 1, index 7
+ *                                                      GigabitEthernet2/0/0
+ *                                                      IP4: 02:fe:6a:07:39:6f -> 16:d9:e0:91:79:86
+ * @cliexend
+?*/
+/* *INDENT-OFF* */
 VLIB_CLI_COMMAND (set_ip_flow_hash_command, static) = {
   .path = "set ip flow-hash",
   .short_help =
-  "set ip table flow-hash table <fib-id> src dst sport dport proto reverse",
+  "set ip flow-hash table <table-id> [src] [dst] [sport] [dport] [proto] [reverse]",
   .function = set_ip_flow_hash_command_fn,
 };
+/* *INDENT-ON* */
 
 int vnet_set_ip4_classify_intfc (vlib_main_t * vm, u32 sw_if_index,
                                  u32 table_index)
@@ -3167,10 +3242,22 @@ set_ip_classify_command_fn (vlib_main_t * vm,
   return 0;
 }
 
+/*?
+ * Assign a classification table to an interface. The classification
+ * table is created using the '<em>classify table</em>' and '<em>classify session</em>'
+ * commands. Once the table is create, use this command to filter packets
+ * on an interface.
+ *
+ * @cliexpar
+ * Example of how to assign a classification table to an interface:
+ * @cliexcmd{set ip classify intfc GigabitEthernet2/0/0 table-index 1}
+?*/
+/* *INDENT-OFF* */
 VLIB_CLI_COMMAND (set_ip_classify_command, static) = {
     .path = "set ip classify",
     .short_help =
-    "set ip classify intfc <int> table-index <index>",
+    "set ip classify intfc <interface> table-index <classify-idx>",
     .function = set_ip_classify_command_fn,
 };
+/* *INDENT-ON* */
 
index 8a469ba..c6037c4 100644 (file)
 #include <vnet/fib/fib_table.h>
 #include <vnet/fib/ip4_fib.h>
 
+/**
+ * @file
+ * @brief IPv4 Source and Port Range Checking.
+ *
+ * This file contains the source code for IPv4 source and port range
+ * checking.
+ */
+
+
 /**
  * @brief The pool of range chack DPOs
  */
@@ -781,12 +790,74 @@ set_ip_source_and_port_range_check_fn (vlib_main_t * vm,
   return error;
 }
 
+/*?
+ * Add the 'ip4-source-and-port-range-check-rx' or
+ * 'ip4-source-and-port-range-check-tx' graph node for a given
+ * interface. 'tcp-out-vrf' and 'udp-out-vrf' will add to
+ * the RX path. 'tcp-in-vrf' and 'udp-in-vrf' will add to
+ * the TX path. A graph node will be inserted into the chain when
+ * the range check is added to the first interface. It will not
+ * be removed from when range check is removed from the last
+ * interface.
+ *
+ * By adding the range check graph node to the interface, incoming
+ * or outgoing TCP/UDP packets will be validated using the
+ * provided IPv4 FIB table (VRF).
+ *
+ * @note 'ip4-source-and-port-range-check-rx' and
+ * 'ip4-source-and-port-range-check-tx' strings are too long, so
+ * they are truncated on the 'show vlib graph' output.
+ *
+ * @todo This content needs to be validated and potentially more detail added.
+ *
+ * @cliexpar
+ * @parblock
+ * Example of graph node before range checking is enabled:
+ * @cliexstart{show vlib graph ip4-source-and-port-range-check-tx}
+ *            Name                      Next                    Previous
+ * ip4-source-and-port-range-      error-drop [0]
+ * @cliexend
+ *
+ * Example of how to enable range checking on TX:
+ * @cliexcmd{set interface ip source-and-port-range-check GigabitEthernet2/0/0 udp-in-vrf 7}
+ *
+ * Example of graph node after range checking is enabled:
+ * @cliexstart{show vlib graph ip4-source-and-port-range-check-tx}
+ *            Name                      Next                    Previous
+ * ip4-source-and-port-range-      error-drop [0]           ip4-rewrite-local
+ *                              interface-output [1]       ip4-rewrite-transit
+ * @cliexend
+ *
+ * Example of how to display the features enabed on an interface:
+ * @cliexstart{show ip interface features GigabitEthernet2/0/0}
+ * IP feature paths configured on GigabitEthernet2/0/0...
+ *
+ * ipv4 unicast:
+ *   ip4-source-and-port-range-check-rx
+ *   ip4-lookup
+ *
+ * ipv4 multicast:
+ *   ip4-lookup-multicast
+ *
+ * ipv4 multicast:
+ *   interface-output
+ *
+ * ipv6 unicast:
+ *   ip6-lookup
+ *
+ * ipv6 multicast:
+ *   ip6-lookup
+ *
+ * ipv6 multicast:
+ *   interface-output
+ * @cliexend
+ * @endparblock
+?*/
 /* *INDENT-OFF* */
-VLIB_CLI_COMMAND (set_interface_ip_source_and_port_range_check_command,
-                  static) = {
+VLIB_CLI_COMMAND (set_interface_ip_source_and_port_range_check_command, static) = {
   .path = "set interface ip source-and-port-range-check",
   .function = set_ip_source_and_port_range_check_fn,
-  .short_help = "set int ip source-and-port-range-check <intfc> [tcp-out-vrf <n>] [udp-out-vrf <n>] [tcp-in-vrf <n>] [udp-in-vrf <n>] [del]",
+  .short_help = "set interface ip source-and-port-range-check <interface> [tcp-out-vrf <table-id>] [udp-out-vrf <table-id>] [tcp-in-vrf <table-id>] [udp-in-vrf <table-id>] [del]",
 };
 /* *INDENT-ON* */
 
@@ -1223,12 +1294,29 @@ ip_source_and_port_range_check_command_fn (vlib_main_t * vm,
   return 0;
 }
 
+/*?
+ * This command adds an IP Subnet and range of ports to be validated
+ * by an IP FIB table (VRF).
+ *
+ * @todo This is incomplete. This needs a detailed description and a
+ * practical example.
+ *
+ * @cliexpar
+ * Example of how to add an IPv4 subnet and single port to an IPv4 FIB table:
+ * @cliexcmd{set ip source-and-port-range-check vrf 7 172.16.1.0/24 port 23}
+ * Example of how to add an IPv4 subnet and range of ports to an IPv4 FIB table:
+ * @cliexcmd{set ip source-and-port-range-check vrf 7 172.16.1.0/24 range 23 - 100}
+ * Example of how to delete an IPv4 subnet and single port from an IPv4 FIB table:
+ * @cliexcmd{set ip source-and-port-range-check vrf 7 172.16.1.0/24 port 23 del}
+ * Example of how to delete an IPv4 subnet and range of ports from an IPv4 FIB table:
+ * @cliexcmd{set ip source-and-port-range-check vrf 7 172.16.1.0/24 range 23 - 100 del}
+?*/
 /* *INDENT-OFF* */
 VLIB_CLI_COMMAND (ip_source_and_port_range_check_command, static) = {
   .path = "set ip source-and-port-range-check",
   .function = ip_source_and_port_range_check_command_fn,
   .short_help =
-  "set ip source-and-port-range-check <ip-addr>/<mask> [range <nn> - <nn>] [vrf <id>] [del]",
+  "set ip source-and-port-range-check vrf <table-id> <ip-addr>/<mask> {port nn | range <nn> - <nn>} [del]",
 };
 /* *INDENT-ON* */
 
@@ -1327,12 +1415,34 @@ show_source_and_port_range_check_fn (vlib_main_t * vm,
   return 0;
 }
 
+/*?
+ * Display the range of ports being validated by an IPv4 FIB for a given
+ * IP or subnet, or test if a given IP and port are being validated.
+ *
+ * @todo This is incomplete. This needs a detailed description and a
+ * practical example.
+ *
+ * @cliexpar
+ * Example of how to display the set of ports being validated for a given
+ * IPv4 subnet:
+ * @cliexstart{show ip source-and-port-range-check vrf 7 172.16.2.0}
+ * 172.16.2.0: 23 - 101
+ * @cliexend
+ * Example of how to test to determine of a given Pv4 address and port
+ * are being validated:
+ * @cliexstart{show ip source-and-port-range-check vrf 7 172.16.2.2 port 23}
+ * 172.16.2.2 port 23 PASS
+ * @cliexend
+ * @cliexstart{show ip source-and-port-range-check vrf 7 172.16.2.2 port 250}
+ * 172.16.2.2 port 250 FAIL
+ * @cliexend
+ ?*/
 /* *INDENT-OFF* */
 VLIB_CLI_COMMAND (show_source_and_port_range_check, static) = {
   .path = "show ip source-and-port-range-check",
   .function = show_source_and_port_range_check_fn,
   .short_help =
-  "show ip source-and-port-range-check vrf <nn> <ip-addr> <port>",
+  "show ip source-and-port-range-check vrf <table-id> <ip-addr> [port <n>]",
 };
 /* *INDENT-ON* */
 
index 97d4703..b791384 100644 (file)
 #include <vnet/fib/fib_urpf_list.h>
 #include <vnet/dpo/load_balance.h>
 
+/**
+ * @file
+ * @brief IPv4 Unicast Source Check.
+ *
+ * This file contains the IPv4 interface unicast source check.
+ */
+
+
 typedef struct {
   u8 packet_data[64];
     index_t urpf;
@@ -380,25 +388,68 @@ set_ip_source_check (vlib_main_t * vm,
   return error;
 }
 
-/* *INDENT-OFF* */
 /*?
- * Add the unicast RPF check feature to an input interface
- *
- * @cliexpar
- * @cliexstart{set interface ip source-check}
- * Two flavours are supported;
- *  loose: accept ingress packet if there is a route to reach the source
- *  strict: accept ingress packet if it arrived on an interface which
+ * This command adds the 'ip4-source-check-via-rx' graph node for
+ * a given interface. By adding the IPv4 source check graph node to
+ * an interface, the code verifies that the source address of incoming
+ * unicast packets are reachable over the incoming interface. Two flavours
+ * are supported (the default is strict):
+ * - loose: accept ingress packet if there is a route to reach the source
+ * - strict: accept ingress packet if it arrived on an interface which
  *          the route to the source uses. i.e. an interface that the source
  *          is reachable via.
- * the deafult is strict.
  *
+ * @cliexpar
+ * @parblock
+ * Example of graph node before range checking is enabled:
+ * @cliexstart{show vlib graph ip4-source-check-via-rx}
+ *            Name                      Next                    Previous
+ * ip4-source-check-via-rx         error-drop [0]
+ * @cliexend
+ *
+ * Example of how to enable unicast source checking on an interface:
+ * @cliexcmd{set interface ip source-check GigabitEthernet2/0/0 loose}
+ *
+ * Example of graph node after range checking is enabled:
+ * @cliexstart{show vlib graph ip4-source-check-via-rx}
+ *            Name                      Next                    Previous
+ * ip4-source-check-via-rx         error-drop [0]         ip4-input-no-checksum
+ *                           ip4-source-and-port-range-         ip4-input
  * @cliexend
+ *
+ * Example of how to display the feature enabed on an interface:
+ * @cliexstart{show ip interface features GigabitEthernet2/0/0}
+ * IP feature paths configured on GigabitEthernet2/0/0...
+ *
+ * ipv4 unicast:
+ *   ip4-source-check-via-rx
+ *   ip4-lookup
+ *
+ * ipv4 multicast:
+ *   ip4-lookup-multicast
+ *
+ * ipv4 multicast:
+ *   interface-output
+ *
+ * ipv6 unicast:
+ *   ip6-lookup
+ *
+ * ipv6 multicast:
+ *   ip6-lookup
+ *
+ * ipv6 multicast:
+ *   interface-output
+ * @cliexend
+ *
+ * Example of how to disable unicast source checking on an interface:
+ * @cliexcmd{set interface ip source-check GigabitEthernet2/0/0 del}
+ * @endparblock
 ?*/
+/* *INDENT-OFF* */
 VLIB_CLI_COMMAND (set_interface_ip_source_check_command, static) = {
   .path = "set interface ip source-check",
   .function = set_ip_source_check,
-  .short_help = "Set IP4/IP6 interface unicast source check",
+  .short_help = "set interface ip source-check <interface> [strict|loose] [del]",
 };
 /* *INDENT-ON* */
 
@@ -476,22 +527,23 @@ done:
   return (error);
 }
 
-/* *INDENT-OFF* */
 /*?
- * Add an exemption for a prefix to pass the uRPF loose check. Testing purposes only.
+ * Add an exemption for a prefix to pass the Unicast Reverse Path
+ * Forwarding (uRPF) loose check. This is for testing purposes only.
+ * If the '<em>table</em>' is not enter it is defaulted to 0. Default
+ * is to '<em>add</em>'. VPP always performs a loose uRPF check for
+ * for-us traffic.
  *
  * @cliexpar
- * @cliexstart{ip rpf-accept}
- *
- * Add an exception for a prefix to pass the loose RPF tests. This is usefull
- * for testing purposes.
- * VPP always performs a loose uRPF check for for-us traffic.
- * @cliexend
+ * Example of how to add a uRPF exception to a FIB table to pass the
+ * loose RPF tests:
+ * @cliexcmd{ip urpf-accept table 7 add}
 ?*/
+/* *INDENT-OFF* */
 VLIB_CLI_COMMAND (ip_source_check_accept_command, static) = {
   .path = "ip urpf-accept",
   .function = ip_source_check_accept,
-  .short_help = "Add a loose uRPF check exemption",
+  .short_help = "ip urpf-accept [table <table-id>] [add|del]",
 };
 /* *INDENT-ON* */
 
index b76a719..f97a065 100644 (file)
 #include <vnet/ip/ip.h>
 #include <vnet/ethernet/ethernet.h>
 
-/* 
- * ip4 FIB tester. Add, probe, delete a bunch of
+/**
+ * @file
+ * @brief IPv4 FIB Tester.
+ *
+ * Not compiled in by default. IPv4 FIB tester. Add, probe, delete a bunch of
  * random routes / masks and make sure that the mtrie agrees with
  * the hash-table FIB.
  * 
@@ -298,11 +301,31 @@ thrash (vlib_main_t * vm,
   return 0;
 }
 
+/*?
+ * This command in not in the build by default. It is an internal
+ * command used to test the route functonality.
+ *
+ * Create test routes on IPv4 FIB table 11. Table will be created if it
+ * does not exist.
+ *
+ * There are several optional attributes:
+ * - If not provided, <seed> defaults to 0xdeaddabe.
+ * - If not provided, <num-iter> defaults to 10.
+ * - If not provided, <num-iface> defaults to 4.
+ * - If not provided, <min-mask> defaults to 7.0.
+ * - If not provided, <max-mask> defaults to 32.0.
+ *
+ * @cliexpar
+ * Example of how to run:
+ * @cliexcmd{test route}
+?*/
+/* *INDENT-OFF* */
 VLIB_CLI_COMMAND (test_route_command, static) = {
     .path = "test route",
-    .short_help = "test route",
+    .short_help = "test route [seed <seed-num>] [niter <num-iter>] [ninterfaces <num-iface>] [min-mask-bits <min-mask>] [max-mask-bits <max-mask>] [verbose]",    .function = thrash,
     .function = thrash,
 };
+/* *INDENT-ON* */
 
 clib_error_t *test_route_init (vlib_main_t *vm)
 {
index 23f0088..d48ccad 100644 (file)
 
 #include <vppinfra/bihash_template.c>
 
+/**
+ * @file
+ * @brief IPv6 Forwarding.
+ *
+ * This file contains the source code for IPv6 forwarding.
+ */
+
 void
 ip6_forward_next_trace (vlib_main_t * vm,
                         vlib_node_runtime_t * node,
@@ -2755,11 +2762,33 @@ add_del_ip6_interface_table (vlib_main_t * vm,
   return error;
 }
 
+/*?
+ * Place the indicated interface into the supplied IPv6 FIB table (also known
+ * as a VRF). If the FIB table does not exist, this command creates it. To
+ * display the current IPv6 FIB table, use the command '<em>show ip6 fib</em>'.
+ * FIB table will only be displayed if a route has been added to the table, or
+ * an IP Address is assigned to an interface in the table (which adds a route
+ * automatically).
+ *
+ * @note IP addresses added after setting the interface IP table end up in
+ * the indicated FIB table. If the IP address is added prior to adding the
+ * interface to the FIB table, it will NOT be part of the FIB table. Predictable
+ * but potentially counter-intuitive results occur if you provision interface
+ * addresses in multiple FIBs. Upon RX, packets will be processed in the last
+ * IP table ID provisioned. It might be marginally useful to evade source RPF
+ * drops to put an interface address into multiple FIBs.
+ *
+ * @cliexpar
+ * Example of how to add an interface to an IPv6 FIB table (where 2 is the table-id):
+ * @cliexcmd{set interface ip6 table GigabitEthernet2/0/0 2}
+ ?*/
+/* *INDENT-OFF* */
 VLIB_CLI_COMMAND (set_interface_ip6_table_command, static) = {
   .path = "set interface ip6 table",
   .function = add_del_ip6_interface_table,
-  .short_help = "set interface ip6 table <intfc> <table-id>"
+  .short_help = "set interface ip6 table <interface> <table-id>"
 };
+/* *INDENT-ON* */
 
 void
 ip6_link_local_address_from_ethernet_mac_address (ip6_address_t *ip,
@@ -2811,11 +2840,24 @@ test_ip6_link_command_fn (vlib_main_t * vm,
   return 0;
 }
 
+/*?
+ * This command converts the given MAC Address into an IPv6 link-local
+ * address.
+ *
+ * @cliexpar
+ * Example of how to create an IPv6 link-local address:
+ * @cliexstart{test ip6 link 16:d9:e0:91:79:86}
+ * Link local address: fe80::14d9:e0ff:fe91:7986
+ * Original MAC address: 16:d9:e0:91:79:86
+ * @cliexend
+?*/
+/* *INDENT-OFF* */
 VLIB_CLI_COMMAND (test_link_command, static) = {
   .path = "test ip6 link",
   .function = test_ip6_link_command_fn,
   .short_help = "test ip6 link <mac-address>",
 };
+/* *INDENT-ON* */
 
 int vnet_set_ip6_flow_hash (u32 table_id, u32 flow_hash_config)
 {
@@ -2873,12 +2915,49 @@ set_ip6_flow_hash_command_fn (vlib_main_t * vm,
   return 0;
 }
 
+/*?
+ * Configure the set of IPv6 fields used by the flow hash.
+ *
+ * @cliexpar
+ * @parblock
+ * Example of how to set the flow hash on a given table:
+ * @cliexcmd{set ip6 flow-hash table 12 dst sport dport proto}
+ * Example of display the configured flow hash:
+ * @cliexstart{show ip6 fib}
+ * FIB lookup table: 65536 buckets, 32 MB heap
+ * 11 objects, 513k of 515k used, 424 free, 0 reclaimed, 2k overhead, 32764k capacity
+ *
+ * VRF 0, fib_index 0, flow hash: src dst sport dport proto
+ *                  Destination                      Packets          Bytes         Adjacency
+ * ff02::1/128                                                 0               0 weight 1, index 5
+ *
+ * ff02::2/128                                                 0               0 weight 1, index 4
+ *
+ * ff02::16/128                                                0               0 weight 1, index 6
+ *
+ * ff02::1:ff00:0/104                                          0               0 weight 1, index 3
+ *
+ *
+ * VRF 12, fib_index 1, flow hash: dst sport dport proto
+ *                  Destination                      Packets          Bytes         Adjacency
+ * ff02::1/128                                                 0               0 weight 1, index 9
+ *
+ * ff02::2/128                                                 0               0 weight 1, index 8
+ *
+ * ff02::16/128                                                0               0 weight 1, index 10
+ *
+ * ff02::1:ff00:0/104                                          0               0 weight 1, index 7
+ * @cliexend
+ * @endparblock
+?*/
+/* *INDENT-OFF* */
 VLIB_CLI_COMMAND (set_ip6_flow_hash_command, static) = {
     .path = "set ip6 flow-hash",
     .short_help =
-    "set ip table flow-hash table <fib-id> src dst sport dport proto reverse",
+    "set ip6 flow-hash table <table-id> [src] [dst] [sport] [dport] [proto] [reverse]",
     .function = set_ip6_flow_hash_command_fn,
 };
+/* *INDENT-ON* */
 
 static clib_error_t *
 show_ip6_local_command_fn (vlib_main_t * vm,
@@ -2900,11 +2979,26 @@ show_ip6_local_command_fn (vlib_main_t * vm,
 
 
 
+/*?
+ * Display the set of protocols handled by the local IPv6 stack.
+ *
+ * @cliexpar
+ * Example of how to display local protocol table:
+ * @cliexstart{show ip6 local}
+ * Protocols handled by ip6_local
+ * 17
+ * 43
+ * 58
+ * 115
+ * @cliexend
+?*/
+/* *INDENT-OFF* */
 VLIB_CLI_COMMAND (show_ip6_local, static) = {
   .path = "show ip6 local",
   .function = show_ip6_local_command_fn,
-  .short_help = "Show ip6 local protocol table",
+  .short_help = "show ip6 local",
 };
+/* *INDENT-ON* */
 
 int vnet_set_ip6_classify_intfc (vlib_main_t * vm, u32 sw_if_index,
                                  u32 table_index)
@@ -3010,12 +3104,24 @@ set_ip6_classify_command_fn (vlib_main_t * vm,
   return 0;
 }
 
+/*?
+ * Assign a classification table to an interface. The classification
+ * table is created using the '<em>classify table</em>' and '<em>classify session</em>'
+ * commands. Once the table is create, use this command to filter packets
+ * on an interface.
+ *
+ * @cliexpar
+ * Example of how to assign a classification table to an interface:
+ * @cliexcmd{set ip6 classify intfc GigabitEthernet2/0/0 table-index 1}
+?*/
+/* *INDENT-OFF* */
 VLIB_CLI_COMMAND (set_ip6_classify_command, static) = {
     .path = "set ip6 classify",
     .short_help =
-    "set ip6 classify intfc <int> table-index <index>",
+    "set ip6 classify intfc <interface> table-index <classify-idx>",
     .function = set_ip6_classify_command_fn,
 };
+/* *INDENT-ON* */
 
 static clib_error_t *
 ip6_config (vlib_main_t * vm, unformat_input_t * input)
@@ -3083,9 +3189,23 @@ set_interface_ip6_output_feature_command_fn (vlib_main_t * vm,
   return 0;
 }
 
+/*?
+ * Enable or disable the output feature on an interface.
+ *
+ * @todo Need a more detailed description.
+ *
+ * @cliexpar
+ * Example of how to enable the output feature on an interface:
+ * @cliexcmd{set interface ip6 output feature GigabitEthernet2/0/0}
+ * Example of how to disable the output feature on an interface:
+ * @cliexcmd{set interface ip6 output feature GigabitEthernet2/0/0 del}
+?*/
+/* *INDENT-OFF* */
 VLIB_CLI_COMMAND (set_interface_ip6_output_feature, static) = {
   .path = "set interface ip6 output feature",
   .function = set_interface_ip6_output_feature_command_fn,
-  .short_help = "set interface output feature <intfc>",
+  .short_help = "set interface ip6 output feature <interface> [del]",
 };
+/* *INDENT-ON* */
+
 #endif /* TEST_CODE */
index d927d27..5769d7c 100644 (file)
 #include <vnet/ip/ip6_hop_by_hop.h>
 #include <vnet/fib/ip6_fib.h>
 
+/**
+ * @file
+ * @brief In-band OAM (iOAM).
+ *
+ * In-band OAM (iOAM) is an implementation study to record operational
+ * information in the packet while the packet traverses a path between
+ * two points in the network.
+ *
+ * VPP can function as in-band OAM encapsulating, transit and
+ * decapsulating node. In this version of VPP in-band OAM data is
+ * transported as options in an IPv6 hop-by-hop extension header. Hence
+ * in-band OAM can be enabled for IPv6 traffic.
+ */
+
 char *ppc_state[] = { "None", "Encap", "Decap" };
 
 ip6_hop_by_hop_ioam_main_t ip6_hop_by_hop_ioam_main;
@@ -793,11 +807,21 @@ clear_ioam_rewrite_command_fn (vlib_main_t * vm,
   return (clear_ioam_rewrite_fn ());
 }
 
+/*?
+ * This command clears all the In-band OAM (iOAM) features enabled by
+ * the '<em>set ioam rewrite</em>' command. Use '<em>show ioam summary</em>' to
+ * verify the configured settings cleared.
+ *
+ * @cliexpar
+ * Example of how to clear iOAM features:
+ * @cliexcmd{clear ioam rewrite}
+?*/
 /* *INDENT-OFF* */
-VLIB_CLI_COMMAND (ip6_clear_ioam_rewrite_cmd, static) =
-{
-.path = "clear ioam rewrite",.short_help = "clear ioam rewrite",.function =
-    clear_ioam_rewrite_command_fn,};
+VLIB_CLI_COMMAND (ip6_clear_ioam_rewrite_cmd, static) = {
+  .path = "clear ioam rewrite",
+  .short_help = "clear ioam rewrite",
+  .function = clear_ioam_rewrite_command_fn,
+};
 /* *INDENT-ON* */
 
 clib_error_t *
@@ -857,12 +881,30 @@ ip6_set_ioam_rewrite_command_fn (vlib_main_t * vm,
   return rv;
 }
 
+/*?
+ * This command is used to enable In-band OAM (iOAM) features on IPv6.
+ * '<em>trace</em>' is used to enable iOAM trace feature. '<em>pot</em>' is used to
+ * enable the Proof Of Transit feature. '<em>ppc</em>' is used to indicate the
+ * Per Packet Counter feature for Edge to Edge processing. '<em>ppc</em>' is
+ * used to indicate if this node is an '<em>encap</em>' node (iOAM edge node
+ * where packet enters iOAM domain), a '<em>decap</em>' node (iOAM edge node
+ * where packet leaves iOAM domain) or '<em>none</em>' (iOAM node where packet
+ * is in-transit through the iOAM domain). '<em>ppc</em>' can only be set if
+ * '<em>trace</em>' or '<em>pot</em>' is enabled.
+ *
+ * Use '<em>clear ioam rewrite</em>' to disable all features enabled by this
+ * command. Use '<em>show ioam summary</em>' to verify the configured settings.
+ *
+ * @cliexpar
+ * Example of how to enable trace and pot with ppc set to encap:
+ * @cliexcmd{set ioam rewrite trace pot ppc encap}
+?*/
 /* *INDENT-OFF* */
-VLIB_CLI_COMMAND (ip6_set_ioam_rewrite_cmd, static) =
-{
-.path = "set ioam rewrite",.short_help =
-    "set ioam [trace] [pot] [ppc <encap|decap>]",.function =
-    ip6_set_ioam_rewrite_command_fn,};
+VLIB_CLI_COMMAND (ip6_set_ioam_rewrite_cmd, static) = {
+  .path = "set ioam rewrite",
+  .short_help = "set ioam rewrite [trace] [pot] [ppc <encap|decap|none>]",
+  .function = ip6_set_ioam_rewrite_command_fn,
+};
 /* *INDENT-ON* */
 
 static clib_error_t *
@@ -911,20 +953,41 @@ ip6_show_ioam_summary_cmd_fn (vlib_main_t * vm,
 
   s = format (s, "         EDGE TO EDGE - PPC OPTION - %d (%s)\n",
              hm->has_ppc_option, ppc_state[hm->has_ppc_option]);
+#if 0
+  /* 'show ioam ppc' command does not exist. Not sure if it was removed */
+  /* or yet to be added. Comment out for now. */
   if (hm->has_ppc_option)
     s = format (s, "Try 'show ioam ppc' for more information\n");
+#endif
 
   vlib_cli_output (vm, "%v", s);
   vec_free (s);
   return 0;
 }
 
+/*?
+ * This command displays the current configuration data for In-band
+ * OAM (iOAM).
+ *
+ * @cliexpar
+ * Example to show the iOAM configuration:
+ * @cliexstart{show ioam summary}
+ *               REWRITE FLOW CONFIGS -
+ *                Destination Address : ff02::1
+ *                     Flow operation : 2 (Pop)
+ *                         TRACE OPTION - 1 (Enabled)
+ * Try 'show ioam trace and show ioam-trace profile' for more information
+ *                         POT OPTION - 1 (Enabled)
+ * Try 'show ioam pot and show pot profile' for more information
+ *          EDGE TO EDGE - PPC OPTION - 1 (Encap)
+ * @cliexend
+?*/
 /* *INDENT-OFF* */
-VLIB_CLI_COMMAND (ip6_show_ioam_run_cmd, static) =
-{
-.path = "show ioam summary",.short_help =
-    "Summary of IOAM configuration",.function =
-    ip6_show_ioam_summary_cmd_fn,};
+VLIB_CLI_COMMAND (ip6_show_ioam_run_cmd, static) = {
+  .path = "show ioam summary",
+  .short_help = "show ioam summary",
+  .function = ip6_show_ioam_summary_cmd_fn,
+};
 /* *INDENT-ON* */
 
 int
@@ -1032,12 +1095,26 @@ ip6_set_ioam_destination_command_fn (vlib_main_t * vm,
                            1);
 }
 
+/*?
+ * This command sets the In-band OAM (iOAM) destination IPv6 address
+ * subnet. An action is required (add, pop or none).  Optionally, an IPv6
+ * FIB table (aka VRF Table) can be provided. If not provided, table 0
+ * used.
+ *
+ * Use '<em>show ioam summary</em>' to verify the configured settings.
+ *
+ * @todo This content needs to be validated and potentially more detail added.
+ *
+ * @cliexpar
+ * Example of how to set the iOAM destination:
+ * @cliexcmd{set ioam destination ff02::1/128 pop vrf-id 8}
+?*/
 /* *INDENT-OFF* */
-VLIB_CLI_COMMAND (ip6_set_ioam_destination_cmd, static) =
-{
-.path = "set ioam destination",.short_help =
-    "set ioam destination <ip6-address>/<width> add | pop | none",.function
-    = ip6_set_ioam_destination_command_fn,};
+VLIB_CLI_COMMAND (ip6_set_ioam_destination_cmd, static) = {
+  .path = "set ioam destination",
+  .short_help = "set ioam destination <ip6-address>/<width> {add|pop|none} [vrf-id <table-id>]",
+  .function = ip6_set_ioam_destination_command_fn,
+};
 /* *INDENT-ON* */
 
 
index 97e7e84..e042385 100644 (file)
 #include <vnet/devices/dpdk/dpdk.h>
 #endif
 
+/**
+ * @file
+ * @brief IPv6 Neighbor Adjacency and Neighbor Discovery.
+ *
+ * The files contains the API and CLI code for managing IPv6 neighbor
+ * adjacency tables and neighbor discovery logic.
+ */
+
 typedef struct {
   ip6_address_t ip6_address;
   u32 sw_if_index;
@@ -639,11 +647,33 @@ show_ip6_neighbors (vlib_main_t * vm,
   return error;
 }
 
+/*?
+ * This command is used to display the adjacent IPv6 hosts found via
+ * neighbor discovery. Optionally, limit the output to the specified
+ * interface.
+ *
+ * @cliexpar
+ * Example of how to display the IPv6 neighbor adjacency table:
+ * @cliexstart{show ip6 neighbors}
+ *     Time           Address       Flags     Link layer                     Interface
+ *      34.0910     ::a:1:1:0:7            02:fe:6a:07:39:6f                GigabitEthernet2/0/0
+ *     173.2916     ::b:5:1:c:2            02:fe:50:62:3a:94                GigabitEthernet2/0/0
+ *     886.6654     ::1:1:c:0:9       S    02:fe:e4:45:27:5b                GigabitEthernet3/0/0
+ * @cliexend
+ * Example of how to display the IPv6 neighbor adjacency table for given interface:
+ * @cliexstart{show ip6 neighbors GigabitEthernet2/0/0}
+ *     Time           Address       Flags     Link layer                     Interface
+ *      34.0910     ::a:1:1:0:7            02:fe:6a:07:39:6f                GigabitEthernet2/0/0
+ *     173.2916     ::b:5:1:c:2            02:fe:50:62:3a:94                GigabitEthernet2/0/0
+ * @cliexend
+?*/
+/* *INDENT-OFF* */
 VLIB_CLI_COMMAND (show_ip6_neighbors_command, static) = {
   .path = "show ip6 neighbors",
   .function = show_ip6_neighbors,
-  .short_help = "Show ip6 neighbors",
+  .short_help = "show ip6 neighbors [<interface>]",
 };
+/* *INDENT-ON* */
 
 static clib_error_t *
 set_ip6_neighbor (vlib_main_t * vm,
@@ -687,11 +717,25 @@ set_ip6_neighbor (vlib_main_t * vm,
   return 0;
 }
 
+/*?
+ * This command is used to manually add an entry to the IPv6 neighbor
+ * adjacency table. Optionally, the entry can be added as static. It is
+ * also used to remove an entry from the table. Use the '<em>show ip6
+ * neighbors</em>' command to display all learned and manually entered entries.
+ *
+ * @cliexpar
+ * Example of how to add a static entry to the IPv6 neighbor adjacency table:
+ * @cliexcmd{set ip6 neighbor GigabitEthernet2/0/0 ::1:1:c:0:9 02:fe:e4:45:27:5b static}
+ * Example of how to delete an entry from the IPv6 neighbor adjacency table:
+ * @cliexcmd{set ip6 neighbor del GigabitEthernet2/0/0 ::1:1:c:0:9 02:fe:e4:45:27:5b}
+?*/
+/* *INDENT-OFF* */
 VLIB_CLI_COMMAND (set_ip6_neighbor_command, static) = {
   .path = "set ip6 neighbor",
   .function = set_ip6_neighbor,
-  .short_help = "set ip6 neighbor [del] <intfc> <ip6-address> <mac-address> [static]",
+  .short_help = "set ip6 neighbor [del] <interface> <ip6-address> <mac-address> [static]",
 };
+/* *INDENT-ON* */
 
 typedef enum {
   ICMP6_NEIGHBOR_SOLICITATION_NEXT_DROP,
@@ -2817,11 +2861,49 @@ show_ip6_interface_cmd (vlib_main_t * vm,
   return error;
 }
 
+/*?
+ * This command is used to display various IPv6 attributes on a given
+ * interface.
+ *
+ * @cliexpar
+ * Example of how to display IPv6 settings:
+ * @cliexstart{show ip6 interface GigabitEthernet2/0/0}
+ * GigabitEthernet2/0/0 is admin up
+ *         Link-local address(es):
+ *                 fe80::ab8/64
+ *         Joined group address(es):
+ *                 ff02::1
+ *                 ff02::2
+ *                 ff02::16
+ *                 ff02::1:ff00:ab8
+ *         Advertised Prefixes:
+ *                 prefix fe80::fe:28ff:fe9c:75b3,  length 64
+ *         MTU is 1500
+ *         ICMP error messages are unlimited
+ *         ICMP redirects are disabled
+ *         ICMP unreachables are not sent
+ *         ND DAD is disabled
+ *         ND advertised reachable time is 0
+ *         ND advertised retransmit interval is 0 (msec)
+ *         ND router advertisements are sent every 200 seconds (min interval is 150)
+ *         ND router advertisements live for 600 seconds
+ *         Hosts use stateless autoconfig for addresses
+ *         ND router advertisements sent 19336
+ *         ND router solicitations received 0
+ *         ND router solicitations dropped 0
+ * @cliexend
+ * Example of output if IPv6 is not enabled on the interface:
+ * @cliexstart{show ip6 interface GigabitEthernet2/0/0}
+ * show ip6 interface: IPv6 not enabled on interface
+ * @cliexend
+?*/
+/* *INDENT-OFF* */
 VLIB_CLI_COMMAND (show_ip6_interface_command, static) = {
   .path = "show ip6 interface",
   .function = show_ip6_interface_cmd,
-  .short_help = "show ip6 interface <iface name>",
+  .short_help = "show ip6 interface <interface>",
 };
+/* *INDENT-ON* */
 
 clib_error_t *
 disable_ip6_interface(vlib_main_t * vm,
@@ -2981,11 +3063,20 @@ enable_ip6_interface_cmd (vlib_main_t * vm,
   return error;
 }
 
+/*?
+ * This command is used to enable IPv6 on a given interface.
+ *
+ * @cliexpar
+ * Example of how enable IPv6 on a given interface:
+ * @cliexcmd{enable ip6 interface GigabitEthernet2/0/0}
+?*/
+/* *INDENT-OFF* */
 VLIB_CLI_COMMAND (enable_ip6_interface_command, static) = {
   .path = "enable ip6 interface",
   .function = enable_ip6_interface_cmd,
-  .short_help = "enable ip6 interface <iface name>",
+  .short_help = "enable ip6 interface <interface>",
 };
+/* *INDENT-ON* */
 
 static clib_error_t *
 disable_ip6_interface_cmd (vlib_main_t * vm,
@@ -3012,17 +3103,143 @@ disable_ip6_interface_cmd (vlib_main_t * vm,
   return error;
 }
 
+/*?
+ * This command is used to disable IPv6 on a given interface.
+ *
+ * @cliexpar
+ * Example of how disable IPv6 on a given interface:
+ * @cliexcmd{disable ip6 interface GigabitEthernet2/0/0}
+?*/
+/* *INDENT-OFF* */
 VLIB_CLI_COMMAND (disable_ip6_interface_command, static) = {
-  .path = "disable  ip6 interface",
+  .path = "disable ip6 interface",
   .function = disable_ip6_interface_cmd,
-  .short_help = "disable ip6 interface <iface name>",
+  .short_help = "disable ip6 interface <interface>",
 };
+/* *INDENT-ON* */
 
+/*?
+ * This command is used to configure the neighbor discovery
+ * parameters on a given interface. Use the '<em>show ip6 interface</em>'
+ * command to display some of the current neighbor discovery parameters
+ * on a given interface. This command has three formats:
+ *
+ *
+ * <b>Format 1 - Router Advertisement Options:</b> (Only one can be entered in a single command)
+ *
+ * '<em><b>ip6 nd <interface> [no] [ra-managed-config-flag] | [ra-other-config-flag] | [ra-suppress] | [ra-suppress-link-layer] | [ra-send-unicast] | [ra-lifetime <lifetime>] | [ra-initial <cnt> <interval>] | [ra-interval <max-interval> [<min-interval>]] | [ra-cease]</b></em>'
+ *
+ * Where:
+ *
+ * <em>[no] ra-managed-config-flag</em> - Advertises in ICMPv6
+ * router-advertisement messages to use stateful address
+ * auto-configuration to obtain address information (sets the M-bit).
+ * Default is the M-bit is not set and the '<em>no</em>' option
+ * returns it to this default state.
+ *
+ * <em>[no] ra-other-config-flag</em> - Indicates in ICMPv6
+ * router-advertisement messages that hosts use stateful auto
+ * configuration to obtain nonaddress related information (sets
+ * the O-bit). Default is the O-bit is not set and the '<em>no</em>'
+ * option returns it to this default state.
+ *
+ * <em>[no] ra-suppress</em> - Disables sending ICMPv6 router-advertisement
+ * messages. The '<em>no</em>' option implies to enable sending ICMPv6
+ * router-advertisement messages.
+ *
+ * <em>[no] ra-suppress-link-layer</em> - Indicates not to include the
+ * optional source link-layer address in the ICMPv6 router-advertisement
+ * messages. Default is to include the optional source link-layer address
+ * and the '<em>no</em>' option returns it to this default state.
+ *
+ * <em>[no] ra-send-unicast</em> - Use the source address of the
+ * router-solicitation message if availiable. The default is to use
+ * multicast address of all nodes, and the '<em>no</em>' option returns
+ * it to this default state.
+ *
+ * <em>[no] ra-lifetime <lifetime></em> - Advertises the lifetime of a
+ * default router in ICMPv6 router-advertisement messages. The range is
+ * from 0 to 9000 seconds. '<em><lifetime></em>' must be greater than
+ * '<em><max-interval></em>'. The default value is 600 seconds and the
+ * '<em>no</em>' option returns it to this default value.
+ *
+ * <em>[no] ra-initial <cnt> <interval></em> - Number of initial ICMPv6
+ * router-advertisement messages sent and the interval between each
+ * message. Range for count is 1 - 3 and default is 3. Range for interval
+ * is 1 to 16 seconds, and default is 16 seconds. The '<em>no</em>' option
+ * returns both to their default value.
+ *
+ * <em>[no] ra-interval <max-interval> [<min-interval>]</em> - Configures the
+ * interval between sending ICMPv6 router-advertisement messages. The
+ * range for max-interval is from 4 to 200 seconds. min-interval can not
+ * be more than 75% of max-interval. If not set, min-interval will be
+ * set to 75% of max-interval. The range for min-interval is from 3 to
+ * 150 seconds.  The '<em>no</em>' option returns both to their default
+ * value.
+ *
+ * <em>[no] ra-cease</em> - Cease sending ICMPv6 router-advertisement messages.
+ * The '<em>no</em>' options implies to start (or restart) sending
+ * ICMPv6 router-advertisement messages.
+ *
+ *
+ * <b>Format 2 - Prefix Options:</b>
+ *
+ * '<em><b>ip6 nd <interface> [no] prefix <ip6-address>/<width> [<valid-lifetime> <pref-lifetime> | infinite] [no-advertise] [off-link] [no-autoconfig] [no-onlink]</b></em>'
+ *
+ * Where:
+ *
+ * <em>no</em> - All additional flags are ignored and the prefix is deleted.
+ *
+ * <em><valid-lifetime> <pref-lifetime></em> - '<em><valid-lifetime></em>' is the
+ * length of time in seconds during what the prefix is valid for the purpose of
+ * on-link determination. Range is 7203 to 2592000 seconds and default is 2592000
+ * seconds (30 days). '<em><pref-lifetime></em>' is the prefered-lifetime and is the
+ * length of time in seconds during what addresses generated from the prefix remain
+ * preferred. Range is 0 to 604800 seconds and default is 604800 seconds (7 days).
+ *
+ * <em>infinite</em> - Both '<em><valid-lifetime></em>' and '<em><<pref-lifetime></em>'
+ * are inifinte, no timeout.
+ *
+ * <em>no-advertise</em> - Do not send full router address in prefix
+ * advertisement. Default is to advertise (i.e. - This flag is off by default).
+ *
+ * <em>off-link</em> - Prefix is off-link, clear L-bit in packet. Default is on-link
+ * (i.e. - This flag is off and L-bit in packet is set by default and this prefix can
+ * be used for on-link determination). '<em>no-onlink</em>' also controls the L-bit.
+ *
+ * <em>no-autoconfig</em> - Do not use prefix for autoconfiguration, clear A-bit in packet.
+ * Default is autoconfig (i.e. - This flag is off and A-bit in packet is set by default.
+ *
+ * <em>no-onlink</em> - Do not use prefix for onlink determination, clear L-bit in packet.
+ * Default is on-link (i.e. - This flag is off and L-bit in packet is set by default and
+ * this prefix can be used for on-link determination). '<em>off-link</em>' also controls
+ * the L-bit.
+ *
+ *
+ * <b>Format 3: - Default of Prefix:</b>
+ *
+ * '<em><b>ip6 nd <interface> [no] prefix <ip6-address>/<width> default</b></em>'
+ *
+ * When a new prefix is added (or existing one is being overwritten) <em>default</em>
+ * uses default values for the prefix. If <em>no</em> is used, the <em>default</em>
+ * is ignored and the prefix is deleted.
+ *
+ *
+ * @cliexpar
+ * Example of how set a router advertisement option:
+ * @cliexcmd{ip6 nd GigabitEthernet2/0/0 ra-interval 100 20}
+ * Example of how to add a prefix:
+ * @cliexcmd{ip6 nd GigabitEthernet2/0/0 prefix fe80::fe:28ff:fe9c:75b3/64 infinite no-advertise}
+ * Example of how to delete a prefix:
+ * @cliexcmd{ip6 nd GigabitEthernet2/0/0 no prefix fe80::fe:28ff:fe9c:75b3/64}
+?*/
+/* *INDENT-OFF* */
 VLIB_CLI_COMMAND (ip6_nd_command, static) = {
   .path = "ip6 nd",
-  .short_help = "Set ip6 neighbor discovery parameters",
+  .short_help = "ip6 nd <interface> ...",
   .function = ip6_neighbor_cmd,
 };
+/* *INDENT-ON* */
 
 clib_error_t *
 set_ip6_link_local_address(vlib_main_t * vm,
@@ -3116,11 +3333,23 @@ set_ip6_link_local_address_cmd (vlib_main_t * vm,
   return error;
 }
 
+/*?
+ * This command is used to assign an IPv6 Link-local address to an
+ * interface. This command will enable IPv6 on an interface if it
+ * is not already enabled. Use the '<em>show ip6 interface</em>' command
+ * to display the assigned Link-local address.
+ *
+ * @cliexpar
+ * Example of how to assign an IPv6 Link-local address to an interface:
+ * @cliexcmd{set ip6 link-local address GigabitEthernet2/0/0 FE80::AB8/64}
+?*/
+/* *INDENT-OFF* */
 VLIB_CLI_COMMAND (set_ip6_link_local_address_command, static) = {
   .path = "set ip6 link-local address",
-  .short_help = "Set ip6 interface link-local address <intfc> <address.>",
+  .short_help = "set ip6 link-local address <interface> <ip6-address>/<width>",
   .function = set_ip6_link_local_address_cmd,
 };
+/* *INDENT-ON* */
 
 /* callback when an interface address is added or deleted */
 static void
index 7ea5e79..54d6c31 100644 (file)
@@ -17,7 +17,9 @@
 #include <vnet/ip/ip.h>
 #include <vnet/mpls/mpls.h>
 
-/** \file
+/**
+ * @file
+ * @brief IP Feature Subgraph Ordering.
 
     Dynamically compute IP feature subgraph ordering by performing a
     topological sort across a set of "feature A before feature B" and
@@ -359,13 +361,44 @@ show_ip_features_command_fn (vlib_main_t * vm,
 }
 
 /*?
- * Display the set of available ip features
+ * This command is used to display the set of available IP features.
+ * This can be useful for verifying that expected features are present.
  *
  * @cliexpar
- * Example:
- * @cliexcmd{show ip features}
+ * Example of how to display the set of available IP features:
+ * @cliexstart{show ip features}
+ * Available IP feature nodes
+ * ip4 unicast:
+ *   ip4-inacl
+ *   ip4-source-check-via-rx
+ *   ip4-source-check-via-any
+ *   ip4-source-and-port-range-check-rx
+ *   ip4-policer-classify
+ *   ipsec-input-ip4
+ *   vpath-input-ip4
+ *   snat-in2out
+ *   snat-out2in
+ *   ip4-lookup
+ * ip4 multicast:
+ *   vpath-input-ip4
+ *   ip4-lookup-multicast
+ * ip4 output:
+ *   ip4-source-and-port-range-check-tx
+ *   interface-output
+ * ip6 unicast:
+ *   ip6-inacl
+ *   ip6-policer-classify
+ *   ipsec-input-ip6
+ *   l2tp-decap
+ *   vpath-input-ip6
+ *   sir-to-ila
+ *   ip6-lookup
+ * ip6 multicast:
+ *   vpath-input-ip6
+ *   ip6-lookup
+ * ip6 output:
+ *   interface-output
  * @cliexend
- * @endparblock
 ?*/
 /* *INDENT-OFF* */
 VLIB_CLI_COMMAND (show_ip_features_command, static) = {
@@ -463,18 +496,31 @@ show_ip_interface_features_command_fn (vlib_main_t * vm,
 }
 
 /*?
- * Display the ip features configured on a specific interface
+ * This command is used to display the set of IP features configured
+ * on a specific interface
  *
  * @cliexpar
- * Example:
- * @cliexcmd{show ip interface features GigabitEthernet2/0/0}
+ * Example of how to display the set of available IP features on an interface:
+ * @cliexstart{show ip interface features GigabitEthernet2/0/0}
+ * IP feature paths configured on GigabitEthernet2/0/0...
+ * ipv4 unicast:
+ *   ip4-lookup
+ * ipv4 multicast:
+ *   ip4-lookup-multicast
+ * ipv4 multicast:
+ *   interface-output
+ * ipv6 unicast:
+ *   ip6-lookup
+ * ipv6 multicast:
+ *   ip6-lookup
+ * ipv6 multicast:
+ *   interface-output
  * @cliexend
- * @endparblock
 ?*/
 /* *INDENT-OFF* */
 VLIB_CLI_COMMAND (show_ip_interface_features_command, static) = {
   .path = "show ip interface features",
-  .short_help = "show ip interface features <intfc>",
+  .short_help = "show ip interface features <interface>",
   .function = show_ip_interface_features_command_fn,
 };
 /* *INDENT-ON* */
index 384e389..1f8735b 100644 (file)
 #include <vnet/dpo/punt_dpo.h>
 #include <vnet/dpo/receive_dpo.h>
 
+/**
+ * @file
+ * @brief IPv4 and IPv6 adjacency and lookup table managment.
+ *
+ */
+
 clib_error_t *
 ip_interface_address_add_del (ip_lookup_main_t * lm,
                              u32 sw_if_index,
@@ -672,54 +678,56 @@ VLIB_CLI_COMMAND (vlib_cli_ip_command, static) = {
   .short_help = "Internet protocol (IP) commands",
 };
 
+VLIB_CLI_COMMAND (vlib_cli_ip6_command, static) = {
+  .path = "ip6",
+  .short_help = "Internet protocol version 6 (IPv6) commands",
+};
+
 VLIB_CLI_COMMAND (vlib_cli_show_ip_command, static) = {
   .path = "show ip",
   .short_help = "Internet protocol (IP) show commands",
 };
 
-VLIB_CLI_COMMAND (vlib_cli_show_ip4_command, static) = {
-  .path = "show ip4",
-  .short_help = "Internet protocol version 4 (IP4) show commands",
-};
-
 VLIB_CLI_COMMAND (vlib_cli_show_ip6_command, static) = {
   .path = "show ip6",
-  .short_help = "Internet protocol version 6 (IP6) show commands",
+  .short_help = "Internet protocol version 6 (IPv6) show commands",
 };
 
 /*?
- * To add or delete routes, use ip route add / del
- * @cliexpar
- * @cliexstart{ip route}
- * To add or delete straightforward static routes, use ip route add / del:
- *  vpp# ip route add 6.0.1.2/32 via 6.0.0.1 GigabitEthernet2/0/0
- *  vpp# ip route del 6.0.1.2/32 via 6.0.0.1 GigabitEthernet2/0/0
- *
- * Multiple routes
+ * This command is used to add or delete IPv4 or IPv6 routes. All
+ * IP Addresses ('<em><dst-ip-addr>/<width></em>',
+ * '<em><next-hop-ip-addr></em>' and '<em><adj-hop-ip-addr></em>')
+ * can be IPv4 or IPv6, but all must be of the same form in a single
+ * command. To display the current set of routes, use the commands
+ * '<em>show ip fib</em>' and '<em>show ip6 fib</em>'.
  *
+ * @cliexpar
+ * Example of how to add a straight forward static route:
+ * @cliexcmd{ip route add 6.0.1.2/32 via 6.0.0.1 GigabitEthernet2/0/0}
+ * Example of how to delete a straight forward static route:
+ * @cliexcmd{ip route del 6.0.1.2/32 via 6.0.0.1 GigabitEthernet2/0/0}
  * Mainly for route add/del performance testing, one can add or delete
  * multiple routes by adding 'count N' to the previous item:
- *  vpp# ip route add count 10 7.0.0.0/24 via 6.0.0.1 GigabitEthernet2/0/0
- *
- * Multipath
- *
+ * @cliexcmd{ip route add count 10 7.0.0.0/24 via 6.0.0.1 GigabitEthernet2/0/0}
  * Add multiple routes for the same destination to create equal-cost multipath:
- *  vpp# ip route add 7.0.0.1/32 via 6.0.0.1 GigabitEthernet2/0/0
- *  vpp# ip route add 7.0.0.1/32 via 6.0.0.2 GigabitEthernet2/0/0
- *
- * For unequal-cost multipath, specify the desired weights:
- *  vpp# ip route add 7.0.0.1/32 via 6.0.0.1 GigabitEthernet2/0/0 weight 1
- *  vpp# ip route add 7.0.0.1/32 via 6.0.0.2 GigabitEthernet2/0/0 weight 3
- *
- * This combination of weights results in 3/4 of the traffic following the second path, 1/4 following the first path.
- * @cliexend
+ * @cliexcmd{ip route add 7.0.0.1/32 via 6.0.0.1 GigabitEthernet2/0/0}
+ * @cliexcmd{ip route add 7.0.0.1/32 via 6.0.0.2 GigabitEthernet2/0/0}
+ * For unequal-cost multipath, specify the desired weights. This
+ * combination of weights results in 3/4 of the traffic following the
+ * second path, 1/4 following the first path:
+ * @cliexcmd{ip route add 7.0.0.1/32 via 6.0.0.1 GigabitEthernet2/0/0 weight 1}
+ * @cliexcmd{ip route add 7.0.0.1/32 via 6.0.0.2 GigabitEthernet2/0/0 weight 3}
+ * To add a route to a particular FIB table (VRF), use:
+ * @cliexcmd{ip route add 172.16.24.0/24 table 7 via GigabitEthernet2/0/0}
  ?*/
+/* *INDENT-OFF* */
 VLIB_CLI_COMMAND (ip_route_command, static) = {
   .path = "ip route",
-  .short_help = "Add/delete IP routes",
+  .short_help = "ip route [add|del] [count <n>] <dst-ip-addr>/<width> [table <table-id>] [via <next-hop-ip-addr> [<interface>] [weight <weight>]] | [via arp <interface> <adj-hop-ip-addr>] | [via drop|punt|local<id>|arp|classify <classify-idx>] [lookup in table <out-table-id>]",
   .function = vnet_ip_route_cmd,
   .is_mp_safe = 1,
 };
+/* *INDENT-ON* */
 
 /*
  * The next two routines address a longstanding script hemorrhoid.
@@ -890,9 +898,27 @@ probe_neighbor_address (vlib_main_t * vm,
   return error;
 }
 
+/*?
+ * The '<em>ip probe-neighbor</em>' command ARPs for IPv4 addresses or
+ * attempts IPv6 neighbor discovery depending on the supplied IP address
+ * format.
+ *
+ * @note This command will not immediately affect the indicated FIB; it
+ * is not suitable for use in establishing a FIB entry prior to adding
+ * recursive FIB entries. As in: don't use it in a script to probe a
+ * gateway prior to adding a default route. It won't work. Instead,
+ * configure a static ARP cache entry [see '<em>set ip arp</em>'], or
+ * a static IPv6 neighbor [see '<em>set ip6 neighbor</em>'].
+ *
+ * @cliexpar
+ * Example of probe for an IPv4 address:
+ * @cliexcmd{ip probe-neighbor GigabitEthernet2/0/0 172.16.1.2}
+?*/
+/* *INDENT-OFF* */
 VLIB_CLI_COMMAND (ip_probe_neighbor_command, static) = {
   .path = "ip probe-neighbor",
   .function = probe_neighbor_address,
-  .short_help = "ip probe-neighbor <intfc> <ip4-addr> | <ip6-addr> [retry nn]",
+  .short_help = "ip probe-neighbor <interface> <ip4-addr> | <ip6-addr> [retry nn]",
   .is_mp_safe = 1,
 };
+/* *INDENT-ON* */
index 3bc4da8..bd714f1 100644 (file)
 #include <vnet/fib/ip4_fib.h>
 #include <vnet/fib/fib_entry.h>
 
+/**
+ * @file
+ * @brief IPv4 and IPv6 ICMP Ping.
+ *
+ * This file contains code to suppport IPv4 or IPv6 ICMP ECHO_REQUEST to
+ * network hosts.
+ *
+ */
+
+
 u8 *
 format_icmp4_input_trace (u8 * s, va_list * va)
 {
@@ -765,25 +775,53 @@ done:
   return error;
 }
 
+/*?
+ * This command sends an ICMP ECHO_REQUEST to network hosts. The address
+ * can be an IPv4 or IPv6 address (or both at the same time).
+ *
+ * @cliexpar
+ * @parblock
+ * Example of how ping an IPv4 address:
+ * @cliexstart{ping 172.16.1.2 source GigabitEthernet2/0/0 repeat 2}
+ * 64 bytes from 172.16.1.2: icmp_seq=1 ttl=64 time=.1090 ms
+ * 64 bytes from 172.16.1.2: icmp_seq=2 ttl=64 time=.0914 ms
+ *
+ * Statistics: 2 sent, 2 received, 0% packet loss
+ * @cliexend
+ *
+ * Example of how ping both an IPv4 address and IPv6 address at the same time:
+ * @cliexstart{ping 172.16.1.2 ipv6 fe80::24a5:f6ff:fe9c:3a36 source GigabitEthernet2/0/0 repeat 2 verbose}
+ * Adjacency index: 10, sw_if_index: 1
+ * Adj: ip6-discover-neighbor
+ * Adj Interface: 0
+ * Forced set interface: 1
+ * Adjacency index: 0, sw_if_index: 4294967295
+ * Adj: ip4-miss
+ * Adj Interface: 0
+ * Forced set interface: 1
+ * Source address: 172.16.1.1
+ * 64 bytes from 172.16.1.2: icmp_seq=1 ttl=64 time=.1899 ms
+ * Adjacency index: 10, sw_if_index: 1
+ * Adj: ip6-discover-neighbor
+ * Adj Interface: 0
+ * Forced set interface: 1
+ * Adjacency index: 0, sw_if_index: 4294967295
+ * Adj: ip4-miss
+ * Adj Interface: 0
+ * Forced set interface: 1
+ * Source address: 172.16.1.1
+ * 64 bytes from 172.16.1.2: icmp_seq=2 ttl=64 time=.0910 ms
+ *
+ * Statistics: 4 sent, 2 received, 50% packet loss
+ * @cliexend
+ * @endparblock
+?*/
 /* *INDENT-OFF* */
 VLIB_CLI_COMMAND (ping_command, static) =
 {
   .path = "ping",
   .function = ping_ip_address,
-  .short_help = "Ping IP4/IP6 address from interface",
-  .long_help =
-  "Ping IPv4/IPv6 address (or both at the same time)\n"
-  "\n"
-  "Arguments:\n"
-  "\n"
-  "ADDRESS              target (IPv4/IPv6)\n"
-  "ipv4 ADDRESS         target IPv4 address\n"
-  "ipv6 ADDRESS         target IPv6 address\n"
-  "interface STRING     interface for the source address\n"
-  "size NUMBER          size to send\n"
-  "repeat NUMBER        how many echo requests to send\n"
-  "interval NUMBER      interval between echo requests, in seconds (integer or fractional)\n"
-  "verbose              print various low-level information\n"
+  .short_help = "ping {<ip-addr> | ipv4 <ip4-addr> | ipv6 <ip6-addr>} [ipv4 <ip4-addr> | ipv6 <ip6-addr>] [source <interface>] [size <pktsize>] [interval <sec>] [repeat <cnt>] [verbose]",
 };
 /* *INDENT-ON* */