ip: punt add punt socket support for icmp6
Punt support for ICMP6 messages allows for an external IPv6 RA advertisement agent. Type: feature Change-Id: I0cc928b747ac1f8335ee9f7c42a3231424825dbc Signed-off-by: Ole Troan <otroan@employees.org>
This commit is contained in:
@ -148,14 +148,31 @@ punt_socket_register_l4 (vlib_main_t * vm,
|
||||
punt_main_t *pm = &punt_main;
|
||||
punt_client_t *c;
|
||||
|
||||
/* For now we only support UDP punt */
|
||||
if (protocol != IP_PROTOCOL_UDP)
|
||||
return clib_error_return (0,
|
||||
"only UDP protocol (%d) is supported, got %d",
|
||||
IP_PROTOCOL_UDP, protocol);
|
||||
|
||||
if (port == (u16) ~ 0)
|
||||
return clib_error_return (0, "UDP port number required");
|
||||
return clib_error_return (0, "Port number required");
|
||||
|
||||
u32 node_index;
|
||||
switch (protocol)
|
||||
{
|
||||
case IP_PROTOCOL_UDP:
|
||||
node_index = (af == AF_IP4 ? udp4_punt_socket_node.index :
|
||||
udp6_punt_socket_node.index);
|
||||
udp_register_dst_port (vm, port, node_index, af == AF_IP4);
|
||||
break;
|
||||
case IP_PROTOCOL_ICMP6:
|
||||
if (af != AF_IP6)
|
||||
return clib_error_return (
|
||||
0, "only UDP or ICMP6 protocol (%d, %d) is supported, got %d",
|
||||
IP_PROTOCOL_UDP, IP_PROTOCOL_ICMP6, protocol);
|
||||
|
||||
node_index = icmp6_punt_socket_node.index;
|
||||
icmp6_register_type (vm, port, node_index);
|
||||
break;
|
||||
default:
|
||||
return clib_error_return (
|
||||
0, "only UDP or ICMP6 protocol (%d) is supported, got %d",
|
||||
IP_PROTOCOL_UDP, protocol);
|
||||
}
|
||||
|
||||
c = punt_client_l4_get (af, port);
|
||||
|
||||
@ -173,12 +190,6 @@ punt_socket_register_l4 (vlib_main_t * vm,
|
||||
c->reg.punt.l4.protocol = protocol;
|
||||
c->reg.punt.l4.af = af;
|
||||
|
||||
u32 node_index = (af == AF_IP4 ?
|
||||
udp4_punt_socket_node.index :
|
||||
udp6_punt_socket_node.index);
|
||||
|
||||
udp_register_dst_port (vm, port, node_index, af == AF_IP4);
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
@ -239,6 +239,7 @@ extern vlib_node_registration_t udp4_punt_node;
|
||||
extern vlib_node_registration_t udp6_punt_node;
|
||||
extern vlib_node_registration_t udp4_punt_socket_node;
|
||||
extern vlib_node_registration_t udp6_punt_socket_node;
|
||||
extern vlib_node_registration_t icmp6_punt_socket_node;
|
||||
extern vlib_node_registration_t ip4_proto_punt_socket_node;
|
||||
extern vlib_node_registration_t ip6_proto_punt_socket_node;
|
||||
extern vlib_node_registration_t punt_socket_rx_node;
|
||||
|
@ -244,10 +244,9 @@ format_udp_punt_trace (u8 * s, va_list * args)
|
||||
}
|
||||
|
||||
always_inline uword
|
||||
punt_socket_inline (vlib_main_t * vm,
|
||||
vlib_node_runtime_t * node,
|
||||
vlib_frame_t * frame,
|
||||
punt_type_t pt, ip_address_family_t af)
|
||||
punt_socket_inline2 (vlib_main_t *vm, vlib_node_runtime_t *node,
|
||||
vlib_frame_t *frame, punt_type_t pt,
|
||||
ip_address_family_t af, ip_protocol_t protocol)
|
||||
{
|
||||
u32 *buffers = vlib_frame_vector_args (frame);
|
||||
u32 thread_index = vm->thread_index;
|
||||
@ -267,33 +266,42 @@ punt_socket_inline (vlib_main_t * vm,
|
||||
uword l;
|
||||
punt_packetdesc_t packetdesc;
|
||||
punt_client_t *c;
|
||||
|
||||
u16 port = 0;
|
||||
b = vlib_get_buffer (vm, buffers[i]);
|
||||
|
||||
if (PUNT_TYPE_L4 == pt)
|
||||
{
|
||||
/* Reverse UDP Punt advance */
|
||||
udp_header_t *udp;
|
||||
if (AF_IP4 == af)
|
||||
if (protocol == IP_PROTOCOL_UDP)
|
||||
{
|
||||
vlib_buffer_advance (b, -(sizeof (ip4_header_t) +
|
||||
sizeof (udp_header_t)));
|
||||
ip4_header_t *ip = vlib_buffer_get_current (b);
|
||||
udp = (udp_header_t *) (ip + 1);
|
||||
/* Reverse UDP Punt advance */
|
||||
udp_header_t *udp;
|
||||
if (AF_IP4 == af)
|
||||
{
|
||||
vlib_buffer_advance (
|
||||
b, -(sizeof (ip4_header_t) + sizeof (udp_header_t)));
|
||||
ip4_header_t *ip = vlib_buffer_get_current (b);
|
||||
udp = (udp_header_t *) (ip + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
vlib_buffer_advance (
|
||||
b, -(sizeof (ip6_header_t) + sizeof (udp_header_t)));
|
||||
ip6_header_t *ip = vlib_buffer_get_current (b);
|
||||
udp = (udp_header_t *) (ip + 1);
|
||||
}
|
||||
port = clib_net_to_host_u16 (udp->dst_port);
|
||||
}
|
||||
else
|
||||
else if (protocol == IP_PROTOCOL_ICMP6)
|
||||
{
|
||||
vlib_buffer_advance (b, -(sizeof (ip6_header_t) +
|
||||
sizeof (udp_header_t)));
|
||||
ip6_header_t *ip = vlib_buffer_get_current (b);
|
||||
udp = (udp_header_t *) (ip + 1);
|
||||
icmp46_header_t *icmp = ip6_next_header (ip);
|
||||
port = icmp->type;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find registerered client
|
||||
* If no registered client, drop packet and count
|
||||
*/
|
||||
c = punt_client_l4_get (af, clib_net_to_host_u16 (udp->dst_port));
|
||||
c = punt_client_l4_get (af, port);
|
||||
}
|
||||
else if (PUNT_TYPE_IP_PROTO == pt)
|
||||
{
|
||||
@ -397,6 +405,14 @@ error:
|
||||
return n_packets;
|
||||
}
|
||||
|
||||
always_inline uword
|
||||
punt_socket_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
|
||||
vlib_frame_t *frame, punt_type_t pt,
|
||||
ip_address_family_t af)
|
||||
{
|
||||
return punt_socket_inline2 (vm, node, frame, pt, af, IP_PROTOCOL_UDP);
|
||||
}
|
||||
|
||||
static uword
|
||||
udp4_punt_socket (vlib_main_t * vm,
|
||||
vlib_node_runtime_t * node, vlib_frame_t * from_frame)
|
||||
@ -427,6 +443,14 @@ ip6_proto_punt_socket (vlib_main_t * vm,
|
||||
PUNT_TYPE_IP_PROTO, AF_IP6);
|
||||
}
|
||||
|
||||
static uword
|
||||
icmp6_punt_socket (vlib_main_t *vm, vlib_node_runtime_t *node,
|
||||
vlib_frame_t *from_frame)
|
||||
{
|
||||
return punt_socket_inline2 (vm, node, from_frame, PUNT_TYPE_L4, AF_IP6,
|
||||
IP_PROTOCOL_ICMP6);
|
||||
}
|
||||
|
||||
static uword
|
||||
exception_punt_socket (vlib_main_t * vm,
|
||||
vlib_node_runtime_t * node, vlib_frame_t * from_frame)
|
||||
@ -484,6 +508,16 @@ VLIB_REGISTER_NODE (exception_punt_socket_node) = {
|
||||
.n_errors = PUNT_N_ERROR,
|
||||
.error_strings = punt_error_strings,
|
||||
};
|
||||
VLIB_REGISTER_NODE (icmp6_punt_socket_node) = {
|
||||
.function = icmp6_punt_socket,
|
||||
.name = "ip6-icmp-punt-socket",
|
||||
.format_trace = format_udp_punt_trace,
|
||||
.flags = VLIB_NODE_FLAG_IS_DROP,
|
||||
.vector_size = sizeof (u32),
|
||||
.n_errors = PUNT_N_ERROR,
|
||||
.error_strings = punt_error_strings,
|
||||
};
|
||||
|
||||
/* *INDENT-ON* */
|
||||
|
||||
typedef struct
|
||||
|
Reference in New Issue
Block a user