Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ET2500/vpp-24.02/src/vnet/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1495,5 +1495,6 @@ if (${ASROUTER_NAME} MATCHES "octeon10")
add_compile_definitions(ET2500_IPFIX)
add_compile_definitions(CLEAR_L2FIB_DISABLE)
add_compile_definitions(ARP_FAIL_PUNT)
add_compile_definitions(ASTERFUSION_VERIFY_L3_DMAC)
endif()

13 changes: 13 additions & 0 deletions ET2500/vpp-24.02/src/vnet/ip/ip.api
Original file line number Diff line number Diff line change
Expand Up @@ -1066,6 +1066,12 @@ counters ip4 {
units "packets";
description "ip4 IHL < 5";
};
bad_l3_mac {
severity error;
type counter64;
units "packets";
description "ipv4 bad l3 mac address";
};

/* Errors signalled by ip4-rewrite. */
mtu_exceeded {
Expand Down Expand Up @@ -1320,6 +1326,13 @@ counters ip6 {
description "ip6 punt";
};

bad_l3_mac {
severity error;
type counter64;
units "packets";
description "ipv6 bad l3 mac address";
};

/* errors signalled by ip6-local. */
unknown_protocol {
severity error;
Expand Down
54 changes: 54 additions & 0 deletions ET2500/vpp-24.02/src/vnet/ip/ip4_input.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,44 @@ typedef enum
IP4_INPUT_N_NEXT,
} ip4_input_next_t;

#ifdef ASTERFUSION_VERIFY_L3_DMAC
static_always_inline void
check_verify_l3_dmac_v4(vlib_buffer_t * p, ip4_header_t * ip, u8 *error)
{
if (!(p->flags & VNET_BUFFER_F_L2_HDR_OFFSET_VALID))
return;

ethernet_header_t *e = ethernet_buffer_get_header(p);

if (ethernet_address_cast(e->dst_address))
{
if (ethernet_address_is_broadcast(e->dst_address))
{
if (!(ip4_address_is_multicast (&ip->dst_address)) &&
!(ip4_address_is_global_broadcast(&ip->dst_address)))
{
*error = IP4_ERROR_BAD_L3_MAC;
return;
}
}
else
{
if (e->dst_address[0] != 0x01 ||
e->dst_address[1] != 0x00 ||
e->dst_address[2] != 0x5e ||
e->dst_address[3] != (ip->dst_address.as_u8[1] & 0x7f) ||
e->dst_address[4] != ip->dst_address.as_u8[2] ||
e->dst_address[5] != ip->dst_address.as_u8[3])
{
*error = IP4_ERROR_BAD_L3_MAC;
return;
}
}
}
}

#endif

static_always_inline void
check_ver_opt_csum (ip4_header_t * ip, u8 * error, int verify_checksum)
{
Expand Down Expand Up @@ -93,6 +131,13 @@ ip4_input_check_x4 (vlib_main_t * vm,

error0 = error1 = error2 = error3 = IP4_ERROR_NONE;

#ifdef ASTERFUSION_VERIFY_L3_DMAC
check_verify_l3_dmac_v4 (p[0], ip[0], &error0);
check_verify_l3_dmac_v4 (p[1], ip[1], &error1);
check_verify_l3_dmac_v4 (p[2], ip[2], &error2);
check_verify_l3_dmac_v4 (p[3], ip[3], &error3);
#endif

check_ver_opt_csum (ip[0], &error0, verify_checksum);
check_ver_opt_csum (ip[1], &error1, verify_checksum);
check_ver_opt_csum (ip[2], &error2, verify_checksum);
Expand Down Expand Up @@ -216,6 +261,11 @@ ip4_input_check_x2 (vlib_main_t * vm,

error0 = error1 = IP4_ERROR_NONE;

#ifdef ASTERFUSION_VERIFY_L3_DMAC
check_verify_l3_dmac_v4 (p0, ip0, &error0);
check_verify_l3_dmac_v4 (p1, ip1, &error1);
#endif

check_ver_opt_csum (ip0, &error0, verify_checksum);
check_ver_opt_csum (ip1, &error1, verify_checksum);

Expand Down Expand Up @@ -289,6 +339,10 @@ ip4_input_check_x1 (vlib_main_t * vm,

error0 = IP4_ERROR_NONE;

#ifdef ASTERFUSION_VERIFY_L3_DMAC
check_verify_l3_dmac_v4 (p0, ip0, &error0);
#endif

check_ver_opt_csum (ip0, &error0, verify_checksum);

if (PREDICT_FALSE (ip0->ttl < 1))
Expand Down
49 changes: 49 additions & 0 deletions ET2500/vpp-24.02/src/vnet/ip/ip6_input.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@
#include <vnet/ip/ip.h>
#include <vnet/ip/icmp6.h>

#ifdef ASTERFUSION_VERIFY_L3_DMAC
#include <vnet/ethernet/ethernet.h>
#endif

typedef enum
{
IP6_INPUT_NEXT_DROP,
Expand All @@ -52,6 +56,42 @@ typedef enum
IP6_INPUT_N_NEXT,
} ip6_input_next_t;

#ifdef ASTERFUSION_VERIFY_L3_DMAC
static_always_inline void
check_verify_l3_dmac_v6(vlib_buffer_t * p, ip6_header_t * ip, u8 *error)
{
if (!(p->flags & VNET_BUFFER_F_L2_HDR_OFFSET_VALID))
return;

ethernet_header_t *e = ethernet_buffer_get_header(p);

if (ethernet_address_cast(e->dst_address))
{
if (ethernet_address_is_broadcast(e->dst_address))
{
if (!(ip6_address_is_multicast (&ip->dst_address)))
{
*error = IP6_ERROR_BAD_L3_MAC;
return;
}
}
else
{
if (e->dst_address[0] != 0x33 ||
e->dst_address[1] != 0x33 ||
e->dst_address[2] != ip->dst_address.as_u8[12] ||
e->dst_address[3] != ip->dst_address.as_u8[13] ||
e->dst_address[4] != ip->dst_address.as_u8[14] ||
e->dst_address[5] != ip->dst_address.as_u8[15])
{
*error = IP6_ERROR_BAD_L3_MAC;
return;
}
}
}
}
#endif

always_inline void
ip6_input_check_x2 (vlib_main_t * vm,
vlib_node_runtime_t * error_node,
Expand All @@ -73,6 +113,11 @@ ip6_input_check_x2 (vlib_main_t * vm,
(ip1->ip_version_traffic_class_and_flow_label) >> 28) !=
6 ? IP6_ERROR_VERSION : error1;

#ifdef ASTERFUSION_VERIFY_L3_DMAC
check_verify_l3_dmac_v6 (p0, ip0, &error0);
check_verify_l3_dmac_v6 (p1, ip1, &error1);
#endif

/* hop limit < 1? Drop it. for link-local broadcast packets,
* like dhcpv6 packets from client has hop-limit 1, which should not
* be dropped.
Expand Down Expand Up @@ -131,6 +176,10 @@ ip6_input_check_x1 (vlib_main_t * vm,
(ip0->ip_version_traffic_class_and_flow_label) >> 28) !=
6 ? IP6_ERROR_VERSION : error0;

#ifdef ASTERFUSION_VERIFY_L3_DMAC
check_verify_l3_dmac_v6 (p0, ip0, &error0);
#endif

/* hop limit < 1? Drop it. for link-local broadcast packets,
* like dhcpv6 packets from client has hop-limit 1, which should not
* be dropped.
Expand Down