Mcast rewrite optimisations 17/8017/3
authorNeale Ranns <nranns@cisco.com>
Thu, 1 Jun 2017 09:43:19 +0000 (05:43 -0400)
committerDamjan Marion <dmarion.lists@gmail.com>
Wed, 18 Apr 2018 16:19:03 +0000 (16:19 +0000)
hard code the address mask offsets. This are protocol specific and only used on ethernet when used at all.

Change-Id: Ib1f6f33682f53254ffbb5a241a1583e65420e0c7
Signed-off-by: Neale Ranns <nranns@cisco.com>
src/vnet/adj/adj_mcast.c
src/vnet/adj/adj_mcast.h
src/vnet/adj/rewrite.h
src/vnet/ethernet/arp.c
src/vnet/interface.c
src/vnet/ip/ip4_forward.c
src/vnet/ip/ip6_forward.c
src/vnet/ip/ip6_neighbor.c

index efc781d..deaa7fc 100644 (file)
@@ -101,8 +101,7 @@ adj_mcast_add_or_lock (fib_protocol_t proto,
 void
 adj_mcast_update_rewrite (adj_index_t adj_index,
                           u8 *rewrite,
-                          u8 offset,
-                          u32 mask)
+                          u8 offset)
 {
     ip_adjacency_t *adj;
 
@@ -121,12 +120,9 @@ adj_mcast_update_rewrite (adj_index_t adj_index,
                                         adj->rewrite_header.sw_if_index),
                                     rewrite);
     /*
-     * set the fields corresponding to the mcast IP address rewrite
-     * The mask must be stored in network byte order, since the packet's
-     * IP address will also be in network order.
+     * set the offset corresponding to the mcast IP address rewrite
      */
     adj->rewrite_header.dst_mcast_offset = offset;
-    adj->rewrite_header.dst_mcast_mask = clib_host_to_net_u32(mask);
 }
 
 /**
@@ -174,13 +170,7 @@ adj_mcast_midchain_update_rewrite (adj_index_t adj_index,
                                         adj->rewrite_header.sw_if_index),
                                     rewrite);
 
-    /*
-     * set the fields corresponding to the mcast IP address rewrite
-     * The mask must be stored in network byte order, since the packet's
-     * IP address will also be in network order.
-     */
     adj->rewrite_header.dst_mcast_offset = offset;
-    adj->rewrite_header.dst_mcast_mask = clib_host_to_net_u32(mask);
 }
 
 void
index 55e2ec0..286901d 100644 (file)
@@ -60,14 +60,10 @@ extern adj_index_t adj_mcast_add_or_lock(fib_protocol_t proto,
  * @param
  *  The offset in the rewrite a which to write in packet's
  *  IP Address
- *
- * @param
- *  The mask to apply to the packet berfore the rewrite.
  */
 extern void adj_mcast_update_rewrite(adj_index_t adj_index,
                                      u8 *rewrite,
-                                     u8 offset,
-                                     u32 mask);
+                                     u8 offset);
 
 /**
  * @brief
index 005ac41..712f686 100644 (file)
@@ -81,10 +81,6 @@ typedef CLIB_PACKED (struct {
    */
   u8 dst_mcast_offset;
 
-  /* The mask to apply to the lower 4 bytes of the IP address before ORing
-   * into the destinaiton MAC address */
-  u32 dst_mcast_mask;
-
   /* Rewrite string starting at end and going backwards. */
   u8 data[0];
 }) vnet_rewrite_header_t;
@@ -290,26 +286,19 @@ _vnet_rewrite_two_headers (vnet_rewrite_header_t * h0,
                             (most_likely_size))
 
 always_inline void
-_vnet_fixup_one_header (vnet_rewrite_header_t * h0,
-                       u8 * addr, u32 addr_len, u8 * packet0)
+vnet_ip_mcast_fixup_header (u32 dst_mcast_mask,
+                           u32 dst_mcast_offset, u32 * addr, u8 * packet0)
 {
-  if (PREDICT_TRUE (h0->dst_mcast_mask))
+  if (PREDICT_TRUE (0 != dst_mcast_offset))
     {
       /* location to write to in the packet */
-      u8 *p0 = packet0 - h0->dst_mcast_offset;
+      u8 *p0 = packet0 - dst_mcast_offset;
       u32 *p1 = (u32 *) p0;
-      /* location to copy from in the L3 dest address */
-      u32 *a0 = (u32 *) (addr + addr_len - sizeof (h0->dst_mcast_mask));
 
-      *p1 |= (*a0 & h0->dst_mcast_mask);
+      *p1 |= (*addr & dst_mcast_mask);
     }
 }
 
-#define vnet_fixup_one_header(rw0,addr,p0)              \
-  _vnet_fixup_one_header (&((rw0).rewrite_header),                      \
-                          (u8*)(addr), sizeof((*addr)),                 \
-                          (u8*)(p0))
-
 #define VNET_REWRITE_FOR_SW_INTERFACE_ADDRESS_BROADCAST ((void *) 0)
 /** Deprecated */
 void vnet_rewrite_for_sw_interface (struct vnet_main_t *vnm,
index 9114d7a..0d692cc 100644 (file)
@@ -508,10 +508,9 @@ arp_update_adjacency (vnet_main_t * vnm, u32 sw_if_index, u32 ai)
         * Complete the remaining fields of the adj's rewrite to direct the
         * complete of the rewrite at switch time by copying in the IP
         * dst address's bytes.
-        * Ofset is 2 bytes into the MAC desintation address. And we copy 23 bits
-        * from the address.
+        * Ofset is 2 bytes into the MAC desintation address.
         */
-       adj_mcast_update_rewrite (ai, rewrite, offset, 0x007fffff);
+       adj_mcast_update_rewrite (ai, rewrite, offset);
 
        break;
       }
index b07a9ba..13ad65e 100644 (file)
@@ -1534,7 +1534,7 @@ default_update_adjacency (vnet_main_t * vnm, u32 sw_if_index, u32 ai)
         vnet_build_rewrite_for_sw_interface (vnm,
                                              sw_if_index,
                                              adj_get_link_type (ai),
-                                             NULL), 0, 0);
+                                             NULL), 0);
       break;
     case IP_LOOKUP_NEXT_DROP:
     case IP_LOOKUP_NEXT_PUNT:
index 7c56a29..28b6203 100644 (file)
@@ -1940,6 +1940,16 @@ typedef enum
   IP4_REWRITE_NEXT_ICMP_ERROR,
 } ip4_rewrite_next_t;
 
+/**
+ * This bits of an IPv4 address to mask to construct a multicast
+ * MAC address
+ */
+#if CLIB_ARCH_IS_BIG_ENDIAN
+#define IP4_MCAST_ADDR_MASK 0x007fffff
+#else
+#define IP4_MCAST_ADDR_MASK 0xffff7f00
+#endif
+
 always_inline uword
 ip4_rewrite_inline (vlib_main_t * vm,
                    vlib_node_runtime_t * node,
@@ -2197,8 +2207,16 @@ ip4_rewrite_inline (vlib_main_t * vm,
              /*
               * copy bytes from the IP address into the MAC rewrite
               */
-             vnet_fixup_one_header (adj0[0], &ip0->dst_address, ip0);
-             vnet_fixup_one_header (adj1[0], &ip1->dst_address, ip1);
+             vnet_ip_mcast_fixup_header (IP4_MCAST_ADDR_MASK,
+                                         adj0->
+                                         rewrite_header.dst_mcast_offset,
+                                         &ip0->dst_address.as_u32,
+                                         (u8 *) ip0);
+             vnet_ip_mcast_fixup_header (IP4_MCAST_ADDR_MASK,
+                                         adj0->
+                                         rewrite_header.dst_mcast_offset,
+                                         &ip1->dst_address.as_u32,
+                                         (u8 *) ip1);
            }
 
          vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
@@ -2277,7 +2295,11 @@ ip4_rewrite_inline (vlib_main_t * vm,
              /*
               * copy bytes from the IP address into the MAC rewrite
               */
-             vnet_fixup_one_header (adj0[0], &ip0->dst_address, ip0);
+             vnet_ip_mcast_fixup_header (IP4_MCAST_ADDR_MASK,
+                                         adj0->
+                                         rewrite_header.dst_mcast_offset,
+                                         &ip0->dst_address.as_u32,
+                                         (u8 *) ip0);
            }
 
          /* Update packet buffer attributes/set output interface. */
index 588cd06..f4e45a4 100644 (file)
@@ -1774,6 +1774,12 @@ typedef enum
   IP6_REWRITE_NEXT_ICMP_ERROR,
 } ip6_rewrite_next_t;
 
+/**
+ * This bits of an IPv6 address to mask to construct a multicast
+ * MAC address
+ */
+#define IP6_MCAST_ADDR_MASK 0xffffffff
+
 always_inline uword
 ip6_rewrite_inline (vlib_main_t * vm,
                    vlib_node_runtime_t * node,
@@ -1977,8 +1983,16 @@ ip6_rewrite_inline (vlib_main_t * vm,
              /*
               * copy bytes from the IP address into the MAC rewrite
               */
-             vnet_fixup_one_header (adj0[0], &ip0->dst_address, ip0);
-             vnet_fixup_one_header (adj1[0], &ip1->dst_address, ip1);
+             vnet_ip_mcast_fixup_header (IP6_MCAST_ADDR_MASK,
+                                         adj0->
+                                         rewrite_header.dst_mcast_offset,
+                                         &ip0->dst_address.as_u32[3],
+                                         (u8 *) ip0);
+             vnet_ip_mcast_fixup_header (IP6_MCAST_ADDR_MASK,
+                                         adj1->
+                                         rewrite_header.dst_mcast_offset,
+                                         &ip1->dst_address.as_u32[3],
+                                         (u8 *) ip1);
            }
 
          vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
@@ -2085,7 +2099,11 @@ ip6_rewrite_inline (vlib_main_t * vm,
            }
          if (is_mcast)
            {
-             vnet_fixup_one_header (adj0[0], &ip0->dst_address, ip0);
+             vnet_ip_mcast_fixup_header (IP6_MCAST_ADDR_MASK,
+                                         adj0->
+                                         rewrite_header.dst_mcast_offset,
+                                         &ip0->dst_address.as_u32[3],
+                                         (u8 *) ip0);
            }
 
          p0->error = error_node->errors[error0];
index fee4356..8e44402 100644 (file)
@@ -672,10 +672,10 @@ ip6_ethernet_update_adjacency (vnet_main_t * vnm, u32 sw_if_index, u32 ai)
         * Complete the remaining fields of the adj's rewrite to direct the
         * complete of the rewrite at switch time by copying in the IP
         * dst address's bytes.
-        * Ofset is 2 bytes into the desintation address. And we write 4 bytes.
+        * Ofset is 2 bytes into the desintation address.
         */
        offset = vec_len (rewrite) - 2;
-       adj_mcast_update_rewrite (ai, rewrite, offset, 0xffffffff);
+       adj_mcast_update_rewrite (ai, rewrite, offset);
 
        break;
       }