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>
This commit is contained in:

committed by
Florin Coras

parent
70efbfcd49
commit
2e7fbcc081
@ -42,7 +42,7 @@ libvnet_la_SOURCES += \
|
||||
vnet/interface_format.c \
|
||||
vnet/interface_output.c \
|
||||
vnet/misc.c \
|
||||
vnet/replication.c \
|
||||
vnet/replication.c \
|
||||
vnet/rewrite.c
|
||||
|
||||
nobase_include_HEADERS += \
|
||||
@ -58,7 +58,6 @@ nobase_include_HEADERS += \
|
||||
vnet/l3_types.h \
|
||||
vnet/pipeline.h \
|
||||
vnet/replication.h \
|
||||
vnet/rewrite.h \
|
||||
vnet/vnet.h \
|
||||
vnet/vnet_all_api_h.h \
|
||||
vnet/vnet_msg_enum.h \
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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 ()));
|
||||
{
|
||||
/*
|
||||
* Construct a partial rewrite from the known ethernet mcast dest MAC
|
||||
*/
|
||||
u8 *rewrite;
|
||||
u8 offset;
|
||||
|
||||
/*
|
||||
* 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;
|
||||
rewrite = ethernet_build_rewrite (vnm,
|
||||
sw_if_index,
|
||||
adj->ia_link,
|
||||
ethernet_ip4_mcast_dst_addr ());
|
||||
offset = vec_len (rewrite) - 2;
|
||||
|
||||
break;
|
||||
/*
|
||||
* 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:
|
||||
|
@ -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;
|
||||
|
@ -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. */
|
||||
|
@ -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];
|
||||
|
@ -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 ()));
|
||||
{
|
||||
/*
|
||||
* Construct a partial rewrite from the known ethernet mcast dest MAC
|
||||
*/
|
||||
u8 *rewrite;
|
||||
u8 offset;
|
||||
|
||||
/*
|
||||
* 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;
|
||||
rewrite = ethernet_build_rewrite (vnm,
|
||||
sw_if_index,
|
||||
adj->ia_link,
|
||||
ethernet_ip6_mcast_dst_addr ());
|
||||
|
||||
break;
|
||||
/*
|
||||
* 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:
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
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));
|
||||
|
||||
clib_memcpy (p0, a0, h0->dst_mcast_n_bytes);
|
||||
if (clear_first_bit)
|
||||
*p1 &= 0x7f;
|
||||
*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 */
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -101,7 +101,6 @@ class TestIPMcast(VppTestCase):
|
||||
tx = sent[i]
|
||||
rx = capture[i]
|
||||
|
||||
# the rx'd packet has the MPLS label popped
|
||||
eth = rx[Ether]
|
||||
self.assertEqual(eth.type, 0x800)
|
||||
|
||||
@ -128,7 +127,6 @@ class TestIPMcast(VppTestCase):
|
||||
tx = sent[i]
|
||||
rx = capture[i]
|
||||
|
||||
# the rx'd packet has the MPLS label popped
|
||||
eth = rx[Ether]
|
||||
self.assertEqual(eth.type, 0x86DD)
|
||||
|
||||
|
Reference in New Issue
Block a user