ethernet: add sanity checks to p2p_ethernet_add/del
[vpp.git] / src / vnet / ethernet / packet.h
index 964cf63..13d7daf 100644 (file)
@@ -40,6 +40,8 @@
 #ifndef included_ethernet_packet_h
 #define included_ethernet_packet_h
 
+#include <vnet/interface.h>
+
 typedef enum
 {
 #define ethernet_type(n,s) ETHERNET_TYPE_##s = n,
@@ -67,6 +69,13 @@ ethernet_address_cast (u8 * a)
   return (a[0] >> 0) & 1;
 }
 
+always_inline int
+ethernet_address_is_broadcast (u8 * a)
+{
+  return clib_mem_unaligned (a, u32) == 0xffffffff &&
+    clib_mem_unaligned (a + 4, u16) == 0xffff;
+}
+
 always_inline uword
 ethernet_address_is_locally_administered (u8 * a)
 {
@@ -79,6 +88,42 @@ ethernet_address_set_locally_administered (u8 * a)
   a[0] |= 1 << 1;
 }
 
+always_inline int
+eh_dst_addr_to_rx_ctype (ethernet_header_t * eh)
+{
+  if (PREDICT_TRUE (ethernet_address_cast (eh->dst_address) ==
+                   ETHERNET_ADDRESS_UNICAST))
+    {
+      return VNET_INTERFACE_COUNTER_RX_UNICAST;
+    }
+  else if (ethernet_address_is_broadcast (eh->dst_address))
+    {
+      return VNET_INTERFACE_COUNTER_RX_BROADCAST;
+    }
+  else
+    {
+      return VNET_INTERFACE_COUNTER_RX_MULTICAST;
+    }
+}
+
+always_inline int
+eh_dst_addr_to_tx_ctype (ethernet_header_t * eh)
+{
+  if (PREDICT_TRUE (ethernet_address_cast (eh->dst_address) ==
+                   ETHERNET_ADDRESS_UNICAST))
+    {
+      return VNET_INTERFACE_COUNTER_TX_UNICAST;
+    }
+  else if (ethernet_address_is_broadcast (eh->dst_address))
+    {
+      return VNET_INTERFACE_COUNTER_TX_BROADCAST;
+    }
+  else
+    {
+      return VNET_INTERFACE_COUNTER_TX_MULTICAST;
+    }
+}
+
 /* For VLAN ethernet type. */
 typedef struct
 {
@@ -91,6 +136,23 @@ typedef struct
   u16 type;
 } ethernet_vlan_header_t;
 
+always_inline void
+ethernet_vlan_header_set_priority_net_order (ethernet_vlan_header_t * h,
+                                            u8 prio)
+{
+  u8 *bytes = (u8 *) (&h->priority_cfi_and_id);
+
+  bytes[0] &= 0x0f;
+  bytes[0] |= (prio & 0xf) << 4;
+}
+
+always_inline u8
+ethernet_vlan_header_get_priority_net_order (ethernet_vlan_header_t * h)
+{
+  u8 *bytes = (u8 *) (&h->priority_cfi_and_id);
+
+  return (bytes[0] >> 4);
+}
 
 /* VLAN with ethertype first and vlan id second */
 typedef struct