From 889fe948df5d53c6210b4db402b8c07d3e45d680 Mon Sep 17 00:00:00 2001 From: Neale Ranns Date: Thu, 1 Jun 2017 05:43:19 -0400 Subject: [PATCH] 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 --- src/vnet/adj/adj_mcast.c | 14 ++------------ src/vnet/adj/adj_mcast.h | 6 +----- src/vnet/adj/rewrite.h | 21 +++++---------------- src/vnet/ethernet/arp.c | 5 ++--- src/vnet/interface.c | 2 +- src/vnet/ip/ip4_forward.c | 28 +++++++++++++++++++++++++--- src/vnet/ip/ip6_forward.c | 24 +++++++++++++++++++++--- src/vnet/ip/ip6_neighbor.c | 4 ++-- 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; } -- 2.16.6