Trivial: Clean up some typos.
[vpp.git] / src / vnet / qos / qos_record.c
index 7181e3b..0395634 100644 (file)
@@ -18,6 +18,8 @@
 #include <vnet/ip/ip6_to_ip4.h>
 #include <vnet/feature/feature.h>
 #include <vnet/qos/qos_types.h>
+#include <vnet/l2/l2_input.h>
+#include <vnet/l2/feat_bitmap.h>
 
 /**
  * Per-interface, per-protocol vector of feature on/off configurations
@@ -44,9 +46,23 @@ qos_record_feature_config (u32 sw_if_index,
                                  enable);
       break;
     case QOS_SOURCE_MPLS:
+      vnet_feature_enable_disable ("mpls-input", "mpls-qos-record",
+                                  sw_if_index, enable, NULL, 0);
+      break;
     case QOS_SOURCE_VLAN:
+      vnet_feature_enable_disable ("ip6-unicast", "vlan-ip6-qos-record",
+                                  sw_if_index, enable, NULL, 0);
+      vnet_feature_enable_disable ("ip6-multicast", "vlan-ip6-qos-record",
+                                  sw_if_index, enable, NULL, 0);
+      vnet_feature_enable_disable ("ip4-unicast", "vlan-ip4-qos-record",
+                                  sw_if_index, enable, NULL, 0);
+      vnet_feature_enable_disable ("ip4-multicast", "vlan-ip4-qos-record",
+                                  sw_if_index, enable, NULL, 0);
+      vnet_feature_enable_disable ("mpls-input", "vlan-mpls-qos-record",
+                                  sw_if_index, enable, NULL, 0);
+      break;
     case QOS_SOURCE_EXT:
-      // not implemented yet
+      /* not a valid option for recording */
       break;
     }
 }
@@ -85,7 +101,7 @@ qos_record_disable (u32 sw_if_index, qos_source_t input_source)
 }
 
 /*
- * Disable recording feautre for all protocols when the interface
+ * Disable recording feature for all protocols when the interface
  * is deleted
  */
 static clib_error_t *
@@ -98,7 +114,7 @@ qos_record_ip_interface_add_del (vnet_main_t * vnm,
 
       FOR_EACH_QOS_SOURCE (qs)
       {
-       qos_record_disable (sw_if_index, qs);
+       while (qos_record_disable (sw_if_index, qs) == 0);
       }
     }
 
@@ -119,7 +135,7 @@ typedef struct qos_record_trace_t_
 static inline uword
 qos_record_inline (vlib_main_t * vm,
                   vlib_node_runtime_t * node,
-                  vlib_frame_t * frame, int is_ip6, int is_l2)
+                  vlib_frame_t * frame, dpo_proto_t dproto, int is_l2)
 {
   u32 n_left_from, *from, *to_next, next_index;
 
@@ -138,7 +154,7 @@ qos_record_inline (vlib_main_t * vm,
          ip4_header_t *ip4_0;
          ip6_header_t *ip6_0;
          vlib_buffer_t *b0;
-         u32 sw_if_index0, next0, bi0;
+         u32 next0, bi0;
          qos_bits_t qos0;
          u8 l2_len;
 
@@ -164,27 +180,45 @@ qos_record_inline (vlib_main_t * vm,
              ethertype = clib_net_to_host_u16 (*(u16 *) (l3h - 2));
 
              if (ethertype == ETHERNET_TYPE_IP4)
-               is_ip6 = 0;
+               dproto = DPO_PROTO_IP4;
              else if (ethertype == ETHERNET_TYPE_IP6)
-               is_ip6 = 1;
+               dproto = DPO_PROTO_IP6;
+             else if (ethertype == ETHERNET_TYPE_MPLS)
+               dproto = DPO_PROTO_MPLS;
              else
                goto non_ip;
            }
 
-         if (is_ip6)
+         if (DPO_PROTO_IP6 == dproto)
            {
              ip6_0 = vlib_buffer_get_current (b0);
              qos0 = ip6_traffic_class_network_order (ip6_0);
            }
-         else
+         else if (DPO_PROTO_IP4 == dproto)
            {
              ip4_0 = vlib_buffer_get_current (b0);
              qos0 = ip4_0->tos;
            }
+         else if (DPO_PROTO_ETHERNET == dproto)
+           {
+             ethernet_vlan_header_t *vlan0;
+
+             vlan0 = (vlib_buffer_get_current (b0) -
+                      sizeof (ethernet_vlan_header_t));
+
+             qos0 = ethernet_vlan_header_get_priority_net_order (vlan0);
+           }
+         else if (DPO_PROTO_MPLS)
+           {
+             mpls_unicast_header_t *mh;
+
+             mh = vlib_buffer_get_current (b0);
+             qos0 = vnet_mpls_uc_get_exp (mh->label_exp_s_ttl);
+           }
+
          vnet_buffer2 (b0)->qos.bits = qos0;
          vnet_buffer2 (b0)->qos.source = QOS_SOURCE_IP;
          b0->flags |= VNET_BUFFER_F_QOS_DATA_VALID;
-         sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
 
          if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
                             (b0->flags & VLIB_BUFFER_IS_TRACED)))
@@ -203,7 +237,7 @@ qos_record_inline (vlib_main_t * vm,
                                            L2INPUT_FEAT_L2_IP_QOS_RECORD);
            }
          else
-           vnet_feature_next (sw_if_index0, &next0, b0);
+           vnet_feature_next (&next0, b0);
 
          /* verify speculative enqueue, maybe switch current next frame */
          vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
@@ -234,14 +268,42 @@ static inline uword
 ip4_qos_record (vlib_main_t * vm, vlib_node_runtime_t * node,
                vlib_frame_t * frame)
 {
-  return (qos_record_inline (vm, node, frame, 0, 0));
+  return (qos_record_inline (vm, node, frame, DPO_PROTO_IP4, 0));
 }
 
 static inline uword
 ip6_qos_record (vlib_main_t * vm, vlib_node_runtime_t * node,
                vlib_frame_t * frame)
 {
-  return (qos_record_inline (vm, node, frame, 1, 0));
+  return (qos_record_inline (vm, node, frame, DPO_PROTO_IP6, 0));
+}
+
+static inline uword
+mpls_qos_record (vlib_main_t * vm, vlib_node_runtime_t * node,
+                vlib_frame_t * frame)
+{
+  return (qos_record_inline (vm, node, frame, DPO_PROTO_MPLS, 0));
+}
+
+static inline uword
+vlan_ip4_qos_record (vlib_main_t * vm, vlib_node_runtime_t * node,
+                    vlib_frame_t * frame)
+{
+  return (qos_record_inline (vm, node, frame, DPO_PROTO_ETHERNET, 0));
+}
+
+static inline uword
+vlan_ip6_qos_record (vlib_main_t * vm, vlib_node_runtime_t * node,
+                    vlib_frame_t * frame)
+{
+  return (qos_record_inline (vm, node, frame, DPO_PROTO_ETHERNET, 0));
+}
+
+static inline uword
+vlan_mpls_qos_record (vlib_main_t * vm, vlib_node_runtime_t * node,
+                     vlib_frame_t * frame)
+{
+  return (qos_record_inline (vm, node, frame, DPO_PROTO_ETHERNET, 0));
 }
 
 static inline uword
@@ -273,6 +335,10 @@ VNET_FEATURE_INIT (ip4_qos_record_node, static) = {
     .arc_name = "ip4-unicast",
     .node_name = "ip4-qos-record",
 };
+VNET_FEATURE_INIT (ip4m_qos_record_node, static) = {
+    .arc_name = "ip4-multicast",
+    .node_name = "ip4-qos-record",
+};
 
 VLIB_REGISTER_NODE (ip6_qos_record_node) = {
   .function = ip6_qos_record,
@@ -295,6 +361,111 @@ VNET_FEATURE_INIT (ip6_qos_record_node, static) = {
     .arc_name = "ip6-unicast",
     .node_name = "ip6-qos-record",
 };
+VNET_FEATURE_INIT (ip6m_qos_record_node, static) = {
+    .arc_name = "ip6-multicast",
+    .node_name = "ip6-qos-record",
+};
+
+VLIB_REGISTER_NODE (mpls_qos_record_node) = {
+  .function = mpls_qos_record,
+  .name = "mpls-qos-record",
+  .vector_size = sizeof (u32),
+  .format_trace = format_qos_record_trace,
+  .type = VLIB_NODE_TYPE_INTERNAL,
+
+  .n_errors = 0,
+  .n_next_nodes = 1,
+
+  .next_nodes = {
+    [0] = "mpls-drop",
+  },
+};
+
+VLIB_NODE_FUNCTION_MULTIARCH (mpls_qos_record_node, mpls_qos_record);
+
+VNET_FEATURE_INIT (mpls_qos_record_node, static) = {
+    .arc_name = "mpls-input",
+    .node_name = "mpls-qos-record",
+};
+
+VLIB_REGISTER_NODE (vlan_mpls_qos_record_node) = {
+  .function = vlan_mpls_qos_record,
+  .name = "vlan-mpls-qos-record",
+  .vector_size = sizeof (u32),
+  .format_trace = format_qos_record_trace,
+  .type = VLIB_NODE_TYPE_INTERNAL,
+
+  .n_errors = 0,
+  .n_next_nodes = 1,
+
+  .next_nodes = {
+    [0] = "mpls-drop",
+  },
+};
+
+VLIB_NODE_FUNCTION_MULTIARCH (vlan_mpls_qos_record_node, vlan_mpls_qos_record);
+
+VNET_FEATURE_INIT (vlan_mpls_qos_record_node, static) = {
+    .arc_name = "mpls-input",
+    .node_name = "vlan-mpls-qos-record",
+    .runs_before = VNET_FEATURES ("mpls-qos-record"),
+};
+
+VLIB_REGISTER_NODE (vlan_ip4_qos_record_node) = {
+  .function = vlan_ip4_qos_record,
+  .name = "vlan-ip4-qos-record",
+  .vector_size = sizeof (u32),
+  .format_trace = format_qos_record_trace,
+  .type = VLIB_NODE_TYPE_INTERNAL,
+
+  .n_errors = 0,
+  .n_next_nodes = 1,
+
+  .next_nodes = {
+    [0] = "ip4-drop",
+  },
+};
+
+VLIB_NODE_FUNCTION_MULTIARCH (vlan_ip4_qos_record_node, vlan_ip4_qos_record);
+
+VNET_FEATURE_INIT (vlan_ip4_qos_record_node, static) = {
+    .arc_name = "ip4-unicast",
+    .node_name = "vlan-ip4-qos-record",
+    .runs_before = VNET_FEATURES ("ip4-qos-record"),
+};
+VNET_FEATURE_INIT (vlan_ip4m_qos_record_node, static) = {
+    .arc_name = "ip4-multicast",
+    .node_name = "vlan-ip4-qos-record",
+    .runs_before = VNET_FEATURES ("ip4-qos-record"),
+};
+
+VLIB_REGISTER_NODE (vlan_ip6_qos_record_node) = {
+  .function = vlan_ip6_qos_record,
+  .name = "vlan-ip6-qos-record",
+  .vector_size = sizeof (u32),
+  .format_trace = format_qos_record_trace,
+  .type = VLIB_NODE_TYPE_INTERNAL,
+
+  .n_errors = 0,
+  .n_next_nodes = 1,
+
+  .next_nodes = {
+    [0] = "ip6-drop",
+  },
+};
+
+VLIB_NODE_FUNCTION_MULTIARCH (vlan_ip6_qos_record_node, vlan_ip6_qos_record);
+
+VNET_FEATURE_INIT (vlan_ip6_qos_record_node, static) = {
+    .arc_name = "ip6-unicast",
+    .node_name = "vlan-ip6-qos-record",
+    .runs_before = VNET_FEATURES ("ip6-qos-record"),
+};
+VNET_FEATURE_INIT (vlan_ip6m_qos_record_node, static) = {
+    .arc_name = "ip6-multicast",
+    .node_name = "vlan-ip6-qos-record",
+    .runs_before = VNET_FEATURES ("ip6-qos-record"),
+};
 
 VLIB_REGISTER_NODE (l2_ip_qos_record_node, static) = {
   .function = l2_ip_qos_record,
@@ -313,6 +484,7 @@ VLIB_REGISTER_NODE (l2_ip_qos_record_node, static) = {
 };
 
 VLIB_NODE_FUNCTION_MULTIARCH (l2_ip_qos_record_node, l2_ip_qos_record);
+
 /* *INDENT-ON* */
 
 clib_error_t *
@@ -372,7 +544,7 @@ qos_record_cli (vlib_main_t * vm,
 /*?
  * Enable QoS bit recording on an interface using the packet's input DSCP bits
  * Which input QoS bits to use are either; IP, MPLS or VLAN. If more than
- * one protocol is chosen (which is foolish) the higer layers override the
+ * one protocol is chosen (which is foolish) the higher layers override the
  * lower.
  *
  * @cliexpar