aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet
diff options
context:
space:
mode:
authorNeale Ranns <nranns@cisco.com>2017-03-15 04:22:25 -0700
committerFlorin Coras <florin.coras@gmail.com>2017-03-27 17:45:06 +0000
commit2e7fbcc08152da5c6a17ed80ba08cd37edec6c8c (patch)
tree09e4f98dcc45d4105c04f2ba4a5fbae2cc63ff7d /src/vnet
parent70efbfcd49aaee207ff3d33ac60083fedd9f1eec (diff)
Mcast rewrite no memcpy
use a 32bit mask in the adjacency to AND with the IP address and OR into the rewrite. Change-Id: I80b0f246c18fd74f3e43c5d49e25833412f34665 Signed-off-by: Neale Ranns <nranns@cisco.com>
Diffstat (limited to 'src/vnet')
-rw-r--r--src/vnet/adj/adj.c2
-rw-r--r--src/vnet/adj/adj_mcast.c11
-rw-r--r--src/vnet/adj/adj_mcast.h11
-rw-r--r--src/vnet/ethernet/arp.c44
-rw-r--r--src/vnet/hdlc/hdlc.h4
-rw-r--r--src/vnet/ip/ip4_forward.c6
-rw-r--r--src/vnet/ip/ip6_forward.c6
-rw-r--r--src/vnet/ip/ip6_neighbor.c43
-rw-r--r--src/vnet/ip/lookup.h1
-rw-r--r--src/vnet/llc/llc.h3
-rw-r--r--src/vnet/osi/osi.h3
-rw-r--r--src/vnet/ppp/ppp.h3
-rw-r--r--src/vnet/rewrite.h42
-rw-r--r--src/vnet/snap/snap.h3
-rw-r--r--src/vnet/vnet.h1
15 files changed, 93 insertions, 90 deletions
diff --git a/src/vnet/adj/adj.c b/src/vnet/adj/adj.c
index f3d483ac13f..9a01e89d660 100644
--- a/src/vnet/adj/adj.c
+++ b/src/vnet/adj/adj.c
@@ -360,7 +360,7 @@ adj_get_sw_if_index (adj_index_t ai)
}
/**
- * @brief Return the link type of the adjacency
+ * @brief Return the rewrite string of the adjacency
*/
const u8*
adj_get_rewrite (adj_index_t ai)
diff --git a/src/vnet/adj/adj_mcast.c b/src/vnet/adj/adj_mcast.c
index a3ba4d6ab18..4f678e43e80 100644
--- a/src/vnet/adj/adj_mcast.c
+++ b/src/vnet/adj/adj_mcast.c
@@ -100,7 +100,9 @@ adj_mcast_add_or_lock (fib_protocol_t proto,
*/
void
adj_mcast_update_rewrite (adj_index_t adj_index,
- u8 *rewrite)
+ u8 *rewrite,
+ u8 offset,
+ u32 mask)
{
ip_adjacency_t *adj;
@@ -118,6 +120,13 @@ adj_mcast_update_rewrite (adj_index_t adj_index,
vnet_get_main(),
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 21c5a1417dd..40d44313357 100644
--- a/src/vnet/adj/adj_mcast.h
+++ b/src/vnet/adj/adj_mcast.h
@@ -55,9 +55,18 @@ extern adj_index_t adj_mcast_add_or_lock(fib_protocol_t proto,
*
* @param
* The new rewrite
+ *
+ * @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 *rewrite,
+ u8 offset,
+ u32 mask);
/**
* @brief Format/display a mcast adjacency.
diff --git a/src/vnet/ethernet/arp.c b/src/vnet/ethernet/arp.c
index 75c7e20372a..2f81da32400 100644
--- a/src/vnet/ethernet/arp.c
+++ b/src/vnet/ethernet/arp.c
@@ -479,28 +479,30 @@ arp_update_adjacency (vnet_main_t * vnm, u32 sw_if_index, u32 ai)
}
break;
case IP_LOOKUP_NEXT_MCAST:
- /*
- * Construct a partial rewrite from the known ethernet mcast dest MAC
- */
- adj_mcast_update_rewrite
- (ai,
- ethernet_build_rewrite (vnm,
- sw_if_index,
- adj->ia_link,
- ethernet_ip4_mcast_dst_addr ()));
-
- /*
- * 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 11 bytes from the end of the MAC header - which is three
- * bytes into the desintation address. And we write 3 bytes.
- */
- adj->rewrite_header.dst_mcast_offset = 11;
- adj->rewrite_header.dst_mcast_n_bytes = 3;
-
- break;
+ {
+ /*
+ * Construct a partial rewrite from the known ethernet mcast dest MAC
+ */
+ u8 *rewrite;
+ u8 offset;
+
+ rewrite = ethernet_build_rewrite (vnm,
+ sw_if_index,
+ adj->ia_link,
+ ethernet_ip4_mcast_dst_addr ());
+ offset = vec_len (rewrite) - 2;
+
+ /*
+ * 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.
+ */
+ adj_mcast_update_rewrite (ai, rewrite, offset, 0x007fffff);
+ break;
+ }
case IP_LOOKUP_NEXT_DROP:
case IP_LOOKUP_NEXT_PUNT:
case IP_LOOKUP_NEXT_LOCAL:
diff --git a/src/vnet/hdlc/hdlc.h b/src/vnet/hdlc/hdlc.h
index 73b15c2fac7..8407d39dda7 100644
--- a/src/vnet/hdlc/hdlc.h
+++ b/src/vnet/hdlc/hdlc.h
@@ -91,10 +91,6 @@ hdlc_register_input_type (vlib_main_t * vm,
hdlc_protocol_t protocol,
u32 node_index);
-void hdlc_set_adjacency (vnet_rewrite_header_t * rw,
- uword max_data_bytes,
- hdlc_protocol_t protocol);
-
format_function_t format_hdlc_protocol;
format_function_t format_hdlc_header;
format_function_t format_hdlc_header_with_length;
diff --git a/src/vnet/ip/ip4_forward.c b/src/vnet/ip/ip4_forward.c
index 7352c2e718d..f2bc2a71851 100644
--- a/src/vnet/ip/ip4_forward.c
+++ b/src/vnet/ip/ip4_forward.c
@@ -2553,8 +2553,8 @@ 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, 1);
- vnet_fixup_one_header (adj1[0], &ip1->dst_address, ip1, 1);
+ vnet_fixup_one_header (adj0[0], &ip0->dst_address, ip0);
+ vnet_fixup_one_header (adj1[0], &ip1->dst_address, ip1);
}
vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
@@ -2635,7 +2635,7 @@ 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, 1);
+ vnet_fixup_one_header (adj0[0], &ip0->dst_address, 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 0b8691bf3dd..ecc3bd2cc6e 100644
--- a/src/vnet/ip/ip6_forward.c
+++ b/src/vnet/ip/ip6_forward.c
@@ -2087,8 +2087,8 @@ 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, 0);
- vnet_fixup_one_header (adj1[0], &ip1->dst_address, ip1, 0);
+ vnet_fixup_one_header (adj0[0], &ip0->dst_address, ip0);
+ vnet_fixup_one_header (adj1[0], &ip1->dst_address, ip1);
}
vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
@@ -2197,7 +2197,7 @@ ip6_rewrite_inline (vlib_main_t * vm,
}
if (is_mcast)
{
- vnet_fixup_one_header (adj0[0], &ip0->dst_address, ip0, 0);
+ vnet_fixup_one_header (adj0[0], &ip0->dst_address, ip0);
}
p0->error = error_node->errors[error0];
diff --git a/src/vnet/ip/ip6_neighbor.c b/src/vnet/ip/ip6_neighbor.c
index 8d355ab2d2c..9b616630a71 100644
--- a/src/vnet/ip/ip6_neighbor.c
+++ b/src/vnet/ip/ip6_neighbor.c
@@ -530,28 +530,29 @@ ip6_ethernet_update_adjacency (vnet_main_t * vnm, u32 sw_if_index, u32 ai)
}
break;
case IP_LOOKUP_NEXT_MCAST:
- /*
- * Construct a partial rewrite from the known ethernet mcast dest MAC
- */
- adj_mcast_update_rewrite
- (ai,
- ethernet_build_rewrite (vnm,
- sw_if_index,
- adj->ia_link,
- ethernet_ip6_mcast_dst_addr ()));
-
- /*
- * 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 12 bytes from the end of the MAC header - which is 2
- * bytes into the desintation address. And we write 4 bytes.
- */
- adj->rewrite_header.dst_mcast_offset = 12;
- adj->rewrite_header.dst_mcast_n_bytes = 4;
-
- break;
+ {
+ /*
+ * Construct a partial rewrite from the known ethernet mcast dest MAC
+ */
+ u8 *rewrite;
+ u8 offset;
+
+ rewrite = ethernet_build_rewrite (vnm,
+ sw_if_index,
+ adj->ia_link,
+ ethernet_ip6_mcast_dst_addr ());
+
+ /*
+ * 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.
+ */
+ offset = vec_len (rewrite) - 2;
+ adj_mcast_update_rewrite (ai, rewrite, offset, 0xffffffff);
+ break;
+ }
case IP_LOOKUP_NEXT_DROP:
case IP_LOOKUP_NEXT_PUNT:
case IP_LOOKUP_NEXT_LOCAL:
diff --git a/src/vnet/ip/lookup.h b/src/vnet/ip/lookup.h
index 48360b5b41f..f76ddb37863 100644
--- a/src/vnet/ip/lookup.h
+++ b/src/vnet/ip/lookup.h
@@ -55,6 +55,7 @@
#include <vnet/fib/fib_node.h>
#include <vnet/dpo/dpo.h>
#include <vnet/feature/feature.h>
+#include <vnet/rewrite.h>
/** @brief Common (IP4/IP6) next index stored in adjacency. */
typedef enum
diff --git a/src/vnet/llc/llc.h b/src/vnet/llc/llc.h
index 0b85f5d8a8b..990a581db7b 100644
--- a/src/vnet/llc/llc.h
+++ b/src/vnet/llc/llc.h
@@ -158,9 +158,6 @@ void
llc_register_input_protocol (vlib_main_t * vm,
llc_protocol_t protocol, u32 node_index);
-void llc_set_adjacency (vnet_rewrite_header_t * rw,
- uword max_data_bytes, llc_protocol_t protocol);
-
format_function_t format_llc_protocol;
format_function_t format_llc_header;
format_function_t format_llc_header_with_length;
diff --git a/src/vnet/osi/osi.h b/src/vnet/osi/osi.h
index ee21f0c3d68..0ff267a330b 100644
--- a/src/vnet/osi/osi.h
+++ b/src/vnet/osi/osi.h
@@ -131,9 +131,6 @@ extern osi_main_t osi_main;
/* Register given node index to take input for given osi type. */
void osi_register_input_protocol (osi_protocol_t protocol, u32 node_index);
-void osi_set_adjacency (vnet_rewrite_header_t * rw,
- uword max_data_bytes, osi_protocol_t protocol);
-
format_function_t format_osi_protocol;
format_function_t format_osi_header;
format_function_t format_osi_header_with_length;
diff --git a/src/vnet/ppp/ppp.h b/src/vnet/ppp/ppp.h
index fdc205b61e7..726eca66835 100644
--- a/src/vnet/ppp/ppp.h
+++ b/src/vnet/ppp/ppp.h
@@ -93,9 +93,6 @@ void
ppp_register_input_type (vlib_main_t * vm,
ppp_protocol_t protocol, u32 node_index);
-void ppp_set_adjacency (vnet_rewrite_header_t * rw,
- uword max_data_bytes, ppp_protocol_t protocol);
-
format_function_t format_ppp_protocol;
format_function_t format_ppp_header;
format_function_t format_ppp_header_with_length;
diff --git a/src/vnet/rewrite.h b/src/vnet/rewrite.h
index 8435a726553..1dea72f5ed8 100644
--- a/src/vnet/rewrite.h
+++ b/src/vnet/rewrite.h
@@ -72,20 +72,18 @@ typedef CLIB_PACKED (struct {
Used for MTU check after packet rewrite. */
u16 max_l3_packet_bytes;
- u16 unused1;
- u8 unused2;
-
+ /* Data-plane flags on the adjacency/rewrite */
vnet_rewrite_flags_t flags;
/* When dynamically writing a multicast destination L2 addresss
- * this is the offset within the address to start writing n
- * bytes of the IP mcast address */
+ * this is the offset from the IP address at which to write in the
+ * IP->MAC address translation.
+ */
u8 dst_mcast_offset;
- /* When dynamically writing a multicast destination L2 addresss
- * this is the number of bytes of the dest IP address to write into
- * the MAC rewrite */
- u8 dst_mcast_n_bytes;
+ /* 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];
@@ -293,24 +291,24 @@ _vnet_rewrite_two_headers (vnet_rewrite_header_t * h0,
always_inline void
_vnet_fixup_one_header (vnet_rewrite_header_t * h0,
- u8 * addr, u32 addr_len,
- u8 * packet0, int clear_first_bit)
+ u8 * addr, u32 addr_len, u8 * packet0)
{
- /* location to write to in the packet */
- u8 *p0 = packet0 - h0->dst_mcast_offset;
- u8 *p1 = p0;
- /* location to write from in the L3 dest address */
- u8 *a0 = addr + addr_len - h0->dst_mcast_n_bytes;
-
- clib_memcpy (p0, a0, h0->dst_mcast_n_bytes);
- if (clear_first_bit)
- *p1 &= 0x7f;
+ if (PREDICT_TRUE (h0->dst_mcast_mask))
+ {
+ /* location to write to in the packet */
+ u8 *p0 = packet0 - h0->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);
+ }
}
-#define vnet_fixup_one_header(rw0,addr,p0,clear_first_bit) \
+#define vnet_fixup_one_header(rw0,addr,p0) \
_vnet_fixup_one_header (&((rw0).rewrite_header), \
(u8*)(addr), sizeof((*addr)), \
- (u8*)(p0), (clear_first_bit))
+ (u8*)(p0))
#define VNET_REWRITE_FOR_SW_INTERFACE_ADDRESS_BROADCAST ((void *) 0)
/** Deprecated */
diff --git a/src/vnet/snap/snap.h b/src/vnet/snap/snap.h
index dbba15bf3f7..7cd453e7a97 100644
--- a/src/vnet/snap/snap.h
+++ b/src/vnet/snap/snap.h
@@ -173,9 +173,6 @@ snap_register_input_protocol (vlib_main_t * vm,
char *name,
u32 ieee_oui, u16 protocol, u32 node_index);
-void snap_set_adjacency (vnet_rewrite_header_t * rw,
- uword max_data_bytes, u32 ieee_oui, u16 protocol);
-
format_function_t format_snap_protocol;
format_function_t format_snap_header;
format_function_t format_snap_header_with_length;
diff --git a/src/vnet/vnet.h b/src/vnet/vnet.h
index 5a8ae858678..8405f61b3c3 100644
--- a/src/vnet/vnet.h
+++ b/src/vnet/vnet.h
@@ -46,7 +46,6 @@
#include <vnet/buffer.h>
#include <vnet/config.h>
#include <vnet/interface.h>
-#include <vnet/rewrite.h>
#include <vnet/api_errno.h>
typedef struct vnet_main_t