VPP-163 "show ip6 interface" ignores many addresses 62/1762/3
authorChris Luke <chrisy@flirble.org>
Sat, 25 Jun 2016 00:38:06 +0000 (20:38 -0400)
committerFlorin Coras <florin.coras@gmail.com>
Thu, 30 Jun 2016 15:19:27 +0000 (15:19 +0000)
The output of the CLI command "show ip6 interface" shows only the first
link-local address and any globally-scoped addresses. It ignores all
other valid address scopes.

This patch reworks that routine to cover the three main address scopes
("link-local", "global" and "local") and anything else it finds is
grouped under "other").

Rationale for this final grouping is that these other addresses fall under
ranges currently either "reserved" or "multicast" in scope. Whilst it's
good to show if these are present, they are not normally found as link
addresses.

DBGvpp# sh ip6 int tap-0
tap-0 is admin down
Link-local address(es):
fe80::e857:7fff:fe77:c1a9/64
Local unicast address(es):
fd50:7389:246b:4321::2/64
Joined group address(es):
ff02::1
ff02::2
ff02::16
ff02::1:ff77:c1a9
ff02::1:ff00:2
...

Change-Id: I1d750b3b39c54aa4eb75632d53089640601bcba5
Signed-off-by: Chris Luke <chrisy@flirble.org>
vnet/vnet/ip/ip6_neighbor.c
vnet/vnet/ip/ip6_packet.h

index 0fe3346..888baff 100644 (file)
@@ -2658,6 +2658,24 @@ ip6_neighbor_cmd(vlib_main_t * vm, unformat_input_t * main_input, vlib_cli_comma
   return error;
 }
 
+static void
+ip6_print_addrs(vlib_main_t * vm,
+                u32 *addrs)
+{
+  ip_lookup_main_t * lm = &ip6_main.lookup_main;
+  u32 i;
+
+  for (i = 0; i < vec_len (addrs); i++)
+    {
+      ip_interface_address_t * a = pool_elt_at_index(lm->if_address_pool, addrs[i]);
+      ip6_address_t * address = ip_interface_address_get_address (lm, a);
+
+      vlib_cli_output (vm, "\t\t%U/%d",
+                       format_ip6_address, address,
+                       a->address_length);
+    }
+}
+
 static clib_error_t *
 show_ip6_interface_cmd (vlib_main_t * vm,
                    unformat_input_t * input,
@@ -2690,8 +2708,9 @@ show_ip6_interface_cmd (vlib_main_t * vm,
                           vnet_get_sw_interface (vnm, sw_if_index),
                           (vnet_sw_interface_is_admin_up (vnm, sw_if_index) ? "up" : "down"));
       
-         u32 ai; 
-         u32 *global_scope = 0,i;
+         u32 ai;
+         u32 *link_scope = 0, *global_scope = 0;
+         u32 *local_scope = 0, *unknown_scope = 0;
          ip_interface_address_t * a;
 
          vec_validate_init_empty (lm->if_address_pool_index_by_sw_if_index, sw_if_index, ~0);
@@ -2702,33 +2721,46 @@ show_ip6_interface_cmd (vlib_main_t * vm,
              a = pool_elt_at_index(lm->if_address_pool, ai);
              ip6_address_t * address = ip_interface_address_get_address (lm, a);
 
-             if( ip6_address_is_link_local_unicast (address))
-               vlib_cli_output (vm, "\tIPv6 is enabled, link-local address is %U\n", format_ip6_address, 
-                                address);
-
-             if((address->as_u8[0] & 0xe0) == 0x20)
+             if (ip6_address_is_link_local_unicast (address))
+               vec_add1 (link_scope, ai);
+             else if(ip6_address_is_global_unicast (address))
                vec_add1 (global_scope, ai);
+             else if(ip6_address_is_local_unicast (address))
+               vec_add1 (local_scope, ai);
+             else
+               vec_add1 (unknown_scope, ai);
 
              ai = a->next_this_sw_interface;
            }
 
-         vlib_cli_output (vm, "\tGlobal unicast address(es):\n");
-         for (i = 0; i < vec_len (global_scope); i++)
-           { 
-             a = pool_elt_at_index(lm->if_address_pool, global_scope[i]);
-             ip6_address_t * address = ip_interface_address_get_address (lm, a);
-             ip6_address_t mask, subnet;
+          if (vec_len (link_scope))
+            {
+              vlib_cli_output (vm, "\tLink-local address(es):\n");
+              ip6_print_addrs (vm, link_scope);
+              vec_free (link_scope);
+            }
 
-             subnet = *address;
-             ip6_address_mask_from_width(&mask, a->address_length);
-             ip6_address_mask(&subnet, &mask);
+          if (vec_len (local_scope))
+            {
+              vlib_cli_output (vm, "\tLocal unicast address(es):\n");
+              ip6_print_addrs (vm, local_scope);
+              vec_free (local_scope);
+            }
+
+          if (vec_len (global_scope))
+            {
+              vlib_cli_output (vm, "\tGlobal unicast address(es):\n");
+              ip6_print_addrs (vm, global_scope);
+              vec_free (global_scope);
+            }
+
+          if (vec_len (unknown_scope))
+            {
+              vlib_cli_output (vm, "\tOther-scope address(es):\n");
+              ip6_print_addrs (vm, unknown_scope);
+              vec_free (unknown_scope);
+            }
 
-             vlib_cli_output (vm, "\t\t%U, subnet is %U/%d", 
-                              format_ip6_address, address, 
-                              format_ip6_address,&subnet,
-                              a->address_length);
-           }
-         vec_free (global_scope);
          vlib_cli_output (vm, "\tJoined group address(es):\n");
          ip6_mldp_group_t *m;
          pool_foreach (m, radv_info->mldp_group_pool, ({
@@ -2767,7 +2799,7 @@ show_ip6_interface_cmd (vlib_main_t * vm,
        }
       else
        {
-         error = clib_error_return (0, "Ipv6 not enabled on interface",
+         error = clib_error_return (0, "IPv6 not enabled on interface",
                                     format_unformat_error, input);
 
        }
@@ -2778,7 +2810,7 @@ show_ip6_interface_cmd (vlib_main_t * vm,
 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 <iface name>",
 };
 
 clib_error_t *
index 876ffac..c83e576 100644 (file)
@@ -265,6 +265,11 @@ always_inline uword
 ip6_address_is_local_unicast (ip6_address_t * a)
 { return (a->as_u8[0] & 0xfe) == 0xfc; }
 
+/* Check for unique global unicast 2000::/3. */
+always_inline uword
+ip6_address_is_global_unicast (ip6_address_t * a)
+{ return (a->as_u8[0] & 0xe0) == 0x20; }
+
 /* Check for solicited node multicast 0xff02::1:ff00:0/104 */
 always_inline uword
 ip6_is_solicited_node_multicast_address (ip6_address_t * a)