QoS recording and marking
[vpp.git] / src / vnet / ip / lookup.c
index 9bb53f5..3bbf2ab 100644 (file)
@@ -230,6 +230,8 @@ ip_lookup_init (ip_lookup_main_t * lm, u32 is_ip6)
       }
 
     lm->local_next_by_ip_protocol[IP_PROTOCOL_UDP] = IP_LOCAL_NEXT_UDP_LOOKUP;
+    lm->local_next_by_ip_protocol[IP_PROTOCOL_VPP_FRAGMENTATION] =
+      IP_LOCAL_NEXT_REASSEMBLY;
     lm->local_next_by_ip_protocol[is_ip6 ? IP_PROTOCOL_ICMP6 :
                                  IP_PROTOCOL_ICMP] = IP_LOCAL_NEXT_ICMP;
     lm->builtin_protocol_by_ip_protocol[IP_PROTOCOL_UDP] =
@@ -252,47 +254,6 @@ format_ip_flow_hash_config (u8 * s, va_list * args)
   return s;
 }
 
-u8 *
-format_ip_lookup_next (u8 * s, va_list * args)
-{
-  /* int promotion of ip_lookup_next_t */
-  ip_lookup_next_t n = va_arg (*args, int);
-  char *t = 0;
-
-  switch (n)
-    {
-    default:
-      s = format (s, "unknown %d", n);
-      return s;
-
-    case IP_LOOKUP_NEXT_DROP:
-      t = "drop";
-      break;
-    case IP_LOOKUP_NEXT_PUNT:
-      t = "punt";
-      break;
-    case IP_LOOKUP_NEXT_ARP:
-      t = "arp";
-      break;
-    case IP_LOOKUP_NEXT_MIDCHAIN:
-      t = "midchain";
-      break;
-    case IP_LOOKUP_NEXT_GLEAN:
-      t = "glean";
-      break;
-    case IP_LOOKUP_NEXT_MCAST:
-      t = "mcast";
-      break;
-    case IP_LOOKUP_NEXT_REWRITE:
-      break;
-    }
-
-  if (t)
-    vec_add (s, t, strlen (t));
-
-  return s;
-}
-
 u8 *
 format_ip_adjacency_packet_data (u8 * s, va_list * args)
 {
@@ -361,29 +322,23 @@ const ip46_address_t zero_addr = {
             0, 0},
 };
 
-clib_error_t *
+static clib_error_t *
 vnet_ip_route_cmd (vlib_main_t * vm,
                   unformat_input_t * main_input, vlib_cli_command_t * cmd)
 {
   unformat_input_t _line_input, *line_input = &_line_input;
-  fib_route_path_t *rpaths = NULL, rpath;
+  u32 table_id, is_del, fib_index, payload_proto;
   dpo_id_t dpo = DPO_INVALID, *dpos = NULL;
-  u32 table_id, is_del, udp_encap_id;
+  fib_route_path_t *rpaths = NULL, rpath;
   fib_prefix_t *prefixs = NULL, pfx;
-  mpls_label_t out_label, via_label;
   clib_error_t *error = NULL;
-  u32 weight, preference;
-  vnet_main_t *vnm;
-  u32 fib_index;
   f64 count;
   int i;
 
-  vnm = vnet_get_main ();
   is_del = 0;
   table_id = 0;
   count = 1;
   memset (&pfx, 0, sizeof (pfx));
-  out_label = via_label = MPLS_LABEL_INVALID;
 
   /* Get a line of input. */
   if (!unformat_user (main_input, unformat_line_input, line_input))
@@ -395,159 +350,24 @@ vnet_ip_route_cmd (vlib_main_t * vm,
 
       if (unformat (line_input, "table %d", &table_id))
        ;
-      else if (unformat (line_input, "resolve-via-host"))
-       {
-         if (vec_len (rpaths) == 0)
-           {
-             error = clib_error_return (0, "Paths then flags");
-             goto done;
-           }
-         rpaths[vec_len (rpaths) - 1].frp_flags |=
-           FIB_ROUTE_PATH_RESOLVE_VIA_HOST;
-       }
-      else if (unformat (line_input, "resolve-via-attached"))
-       {
-         if (vec_len (rpaths) == 0)
-           {
-             error = clib_error_return (0, "Paths then flags");
-             goto done;
-           }
-         rpaths[vec_len (rpaths) - 1].frp_flags |=
-           FIB_ROUTE_PATH_RESOLVE_VIA_ATTACHED;
-       }
-      else if (unformat (line_input, "out-labels"))
-       {
-         if (vec_len (rpaths) == 0)
-           {
-             error = clib_error_return (0, "Paths then labels");
-             goto done;
-           }
-         else
-           {
-             while (unformat (line_input, "%U",
-                              unformat_mpls_unicast_label, &out_label))
-               {
-                 vec_add1 (rpaths[vec_len (rpaths) - 1].frp_label_stack,
-                           out_label);
-               }
-           }
-       }
-      else if (unformat (line_input, "via-label %U",
-                        unformat_mpls_unicast_label, &rpath.frp_local_label))
-       {
-         rpath.frp_weight = 1;
-         rpath.frp_eos = MPLS_NON_EOS;
-         rpath.frp_proto = DPO_PROTO_MPLS;
-         rpath.frp_sw_if_index = ~0;
-         vec_add1 (rpaths, rpath);
-       }
       else if (unformat (line_input, "count %f", &count))
        ;
 
       else if (unformat (line_input, "%U/%d",
                         unformat_ip4_address, &pfx.fp_addr.ip4, &pfx.fp_len))
        {
-         pfx.fp_proto = FIB_PROTOCOL_IP4;
+         payload_proto = pfx.fp_proto = FIB_PROTOCOL_IP4;
          vec_add1 (prefixs, pfx);
        }
       else if (unformat (line_input, "%U/%d",
                         unformat_ip6_address, &pfx.fp_addr.ip6, &pfx.fp_len))
        {
-         pfx.fp_proto = FIB_PROTOCOL_IP6;
+         payload_proto = pfx.fp_proto = FIB_PROTOCOL_IP6;
          vec_add1 (prefixs, pfx);
        }
-      else if (unformat (line_input, "via %U %U",
-                        unformat_ip4_address,
-                        &rpath.frp_addr.ip4,
-                        unformat_vnet_sw_interface, vnm,
-                        &rpath.frp_sw_if_index))
-       {
-         rpath.frp_weight = 1;
-         rpath.frp_proto = DPO_PROTO_IP4;
-         vec_add1 (rpaths, rpath);
-       }
-
-      else if (unformat (line_input, "via %U %U",
-                        unformat_ip6_address,
-                        &rpath.frp_addr.ip6,
-                        unformat_vnet_sw_interface, vnm,
-                        &rpath.frp_sw_if_index))
-       {
-         rpath.frp_weight = 1;
-         rpath.frp_proto = DPO_PROTO_IP6;
-         vec_add1 (rpaths, rpath);
-       }
-      else if (unformat (line_input, "weight %u", &weight))
-       {
-         ASSERT (vec_len (rpaths));
-         rpaths[vec_len (rpaths) - 1].frp_weight = weight;
-       }
-      else if (unformat (line_input, "preference %u", &preference))
-       {
-         ASSERT (vec_len (rpaths));
-         rpaths[vec_len (rpaths) - 1].frp_preference = preference;
-       }
-      else if (unformat (line_input, "via %U next-hop-table %d",
-                        unformat_ip4_address,
-                        &rpath.frp_addr.ip4, &rpath.frp_fib_index))
-       {
-         rpath.frp_weight = 1;
-         rpath.frp_sw_if_index = ~0;
-         rpath.frp_proto = DPO_PROTO_IP4;
-         vec_add1 (rpaths, rpath);
-       }
-      else if (unformat (line_input, "via %U next-hop-table %d",
-                        unformat_ip6_address,
-                        &rpath.frp_addr.ip6, &rpath.frp_fib_index))
-       {
-         rpath.frp_weight = 1;
-         rpath.frp_sw_if_index = ~0;
-         rpath.frp_proto = DPO_PROTO_IP6;
-         vec_add1 (rpaths, rpath);
-       }
       else if (unformat (line_input, "via %U",
-                        unformat_ip4_address, &rpath.frp_addr.ip4))
+                        unformat_fib_route_path, &rpath, &payload_proto))
        {
-         /*
-          * the recursive next-hops are by default in the same table
-          * as the prefix
-          */
-         rpath.frp_fib_index = table_id;
-         rpath.frp_weight = 1;
-         rpath.frp_sw_if_index = ~0;
-         rpath.frp_proto = DPO_PROTO_IP4;
-         vec_add1 (rpaths, rpath);
-       }
-      else if (unformat (line_input, "via %U",
-                        unformat_ip6_address, &rpath.frp_addr.ip6))
-       {
-         rpath.frp_fib_index = table_id;
-         rpath.frp_weight = 1;
-         rpath.frp_sw_if_index = ~0;
-         rpath.frp_proto = DPO_PROTO_IP6;
-         vec_add1 (rpaths, rpath);
-       }
-      else if (unformat (line_input, "via udp-encap %d", &udp_encap_id))
-       {
-         rpath.frp_udp_encap_id = udp_encap_id;
-         rpath.frp_flags |= FIB_ROUTE_PATH_UDP_ENCAP;
-         rpath.frp_proto = fib_proto_to_dpo (pfx.fp_proto);
-         vec_add1 (rpaths, rpath);
-       }
-      else if (unformat (line_input,
-                        "lookup in table %d", &rpath.frp_fib_index))
-       {
-         rpath.frp_proto = fib_proto_to_dpo (pfx.fp_proto);
-         rpath.frp_sw_if_index = ~0;
-         vec_add1 (rpaths, rpath);
-       }
-      else if (vec_len (prefixs) > 0 &&
-              unformat (line_input, "via %U",
-                        unformat_vnet_sw_interface, vnm,
-                        &rpath.frp_sw_if_index))
-       {
-         rpath.frp_weight = 1;
-         rpath.frp_proto = fib_proto_to_dpo (prefixs[0].fp_proto);
          vec_add1 (rpaths, rpath);
        }
       else if (vec_len (prefixs) > 0 &&
@@ -838,7 +658,7 @@ VLIB_CLI_COMMAND (vlib_cli_show_ip6_command, static) = {
 /* *INDENT-OFF* */
 VLIB_CLI_COMMAND (ip_route_command, static) = {
   .path = "ip route",
-  .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>]",
+  .short_help = "ip route [add|del] [count <n>] <dst-ip-addr>/<width> [table <table-id>] via [next-hop-address] [next-hop-interface] [next-hop-table <value>] [weight <value>] [preference <value>] [udp-encap-id <value>] [ip4-lookup-in-table <value>] [ip6-lookup-in-table <value>] [mpls-lookup-in-table <value>] [resolve-via-host] [resolve-via-connected] [rx-ip4 <interface>] [out-labels <value value value>]",
   .function = vnet_ip_route_cmd,
   .is_mp_safe = 1,
 };
@@ -1539,12 +1359,16 @@ ip_container_cmd (vlib_main_t * vm,
       else if (unformat (line_input, "del"))
        is_del = 1;
       else
-       return (clib_error_return (0, "unknown input '%U'",
-                                  format_unformat_error, line_input));
+       {
+         unformat_free (line_input);
+         return (clib_error_return (0, "unknown input '%U'",
+                                    format_unformat_error, line_input));
+       }
     }
 
   if (~0 == sw_if_index || !addr_set)
     {
+      unformat_free (line_input);
       vlib_cli_output (vm, "interface and address must be set");
       return 0;
     }
@@ -1597,12 +1421,16 @@ show_ip_container_cmd_fn (vlib_main_t * vm, unformat_input_t * main_input,
                         unformat_vnet_sw_interface, vnm, &sw_if_index))
        ;
       else
-       return (clib_error_return (0, "unknown input '%U'",
-                                  format_unformat_error, line_input));
+       {
+         unformat_free (line_input);
+         return (clib_error_return (0, "unknown input '%U'",
+                                    format_unformat_error, line_input));
+       }
     }
 
   if (~0 == sw_if_index)
     {
+      unformat_free (line_input);
       vlib_cli_output (vm, "no interface");
       return (clib_error_return (0, "no interface"));
     }