aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNeale Ranns <nranns@cisco.com>2017-06-01 05:43:19 -0400
committerDamjan Marion <dmarion.lists@gmail.com>2018-04-18 16:19:03 +0000
commit889fe948df5d53c6210b4db402b8c07d3e45d680 (patch)
tree1ae3609ebd9bae146fe53060f53430cfbab404ac /src
parent6c354941602df78f4c3bd78aa3b21fe447e3173d (diff)
Mcast rewrite optimisations
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>
Diffstat (limited to 'src')
-rw-r--r--src/vnet/adj/adj_mcast.c14
-rw-r--r--src/vnet/adj/adj_mcast.h6
-rw-r--r--src/vnet/adj/rewrite.h21
-rw-r--r--src/vnet/ethernet/arp.c5
-rw-r--r--src/vnet/interface.c2
-rw-r--r--src/vnet/ip/ip4_forward.c28
-rw-r--r--src/vnet/ip/ip6_forward.c24
-rw-r--r--src/vnet/ip/ip6_neighbor.c4
8 files changed, 59 insertions, 45 deletions
diff --git a/src/vnet/adj/adj_mcast.c b/src/vnet/adj/adj_mcast.c
index efc781de989..deaa7fcffa4 100644
--- a/src/vnet/adj/adj_mcast.c
+++ b/src/vnet/adj/adj_mcast.c
@@ -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
diff --git a/src/vnet/adj/adj_mcast.h b/src/vnet/adj/adj_mcast.h
index 55e2ec03d09..286901d24a1 100644
--- a/src/vnet/adj/adj_mcast.h
+++ b/src/vnet/adj/adj_mcast.h
@@ -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
diff --git a/src/vnet/adj/rewrite.h b/src/vnet/adj/rewrite.h
index 005ac41fe72..712f686f4ae 100644
--- a/src/vnet/adj/rewrite.h
+++ b/src/vnet/adj/rewrite.h
@@ -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,
diff --git a/src/vnet/ethernet/arp.c b/src/vnet/ethernet/arp.c
index 9114d7a90f3..0d692cc1070 100644
--- a/src/vnet/ethernet/arp.c
+++ b/src/vnet/ethernet/arp.c
@@ -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;
}
diff --git a/src/vnet/interface.c b/src/vnet/interface.c
index b07a9ba7553..13ad65ee2db 100644
--- a/src/vnet/interface.c
+++ b/src/vnet/interface.c
@@ -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:
diff --git a/src/vnet/ip/ip4_forward.c b/src/vnet/ip/ip4_forward.c
index 7c56a294436..28b6203c0fb 100644
--- a/src/vnet/ip/ip4_forward.c
+++ b/src/vnet/ip/ip4_forward.c
@@ -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. */
diff --git a/src/vnet/ip/ip6_forward.c b/src/vnet/ip/ip6_forward.c
index 588cd0675a4..f4e45a4702a 100644
--- a/src/vnet/ip/ip6_forward.c
+++ b/src/vnet/ip/ip6_forward.c
@@ -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];
diff --git a/src/vnet/ip/ip6_neighbor.c b/src/vnet/ip/ip6_neighbor.c
index fee4356f5e0..8e444024c44 100644
--- a/src/vnet/ip/ip6_neighbor.c
+++ b/src/vnet/ip/ip6_neighbor.c
@@ -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;
}