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_main_t *pm = &punt_main;
|
||||||
punt_client_t *c;
|
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)
|
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);
|
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.protocol = protocol;
|
||||||
c->reg.punt.l4.af = af;
|
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);
|
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 udp6_punt_node;
|
||||||
extern vlib_node_registration_t udp4_punt_socket_node;
|
extern vlib_node_registration_t udp4_punt_socket_node;
|
||||||
extern vlib_node_registration_t udp6_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 ip4_proto_punt_socket_node;
|
||||||
extern vlib_node_registration_t ip6_proto_punt_socket_node;
|
extern vlib_node_registration_t ip6_proto_punt_socket_node;
|
||||||
extern vlib_node_registration_t punt_socket_rx_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
|
always_inline uword
|
||||||
punt_socket_inline (vlib_main_t * vm,
|
punt_socket_inline2 (vlib_main_t *vm, vlib_node_runtime_t *node,
|
||||||
vlib_node_runtime_t * node,
|
vlib_frame_t *frame, punt_type_t pt,
|
||||||
vlib_frame_t * frame,
|
ip_address_family_t af, ip_protocol_t protocol)
|
||||||
punt_type_t pt, ip_address_family_t af)
|
|
||||||
{
|
{
|
||||||
u32 *buffers = vlib_frame_vector_args (frame);
|
u32 *buffers = vlib_frame_vector_args (frame);
|
||||||
u32 thread_index = vm->thread_index;
|
u32 thread_index = vm->thread_index;
|
||||||
@ -267,33 +266,42 @@ punt_socket_inline (vlib_main_t * vm,
|
|||||||
uword l;
|
uword l;
|
||||||
punt_packetdesc_t packetdesc;
|
punt_packetdesc_t packetdesc;
|
||||||
punt_client_t *c;
|
punt_client_t *c;
|
||||||
|
u16 port = 0;
|
||||||
b = vlib_get_buffer (vm, buffers[i]);
|
b = vlib_get_buffer (vm, buffers[i]);
|
||||||
|
|
||||||
if (PUNT_TYPE_L4 == pt)
|
if (PUNT_TYPE_L4 == pt)
|
||||||
{
|
{
|
||||||
/* Reverse UDP Punt advance */
|
if (protocol == IP_PROTOCOL_UDP)
|
||||||
udp_header_t *udp;
|
|
||||||
if (AF_IP4 == af)
|
|
||||||
{
|
{
|
||||||
vlib_buffer_advance (b, -(sizeof (ip4_header_t) +
|
/* Reverse UDP Punt advance */
|
||||||
sizeof (udp_header_t)));
|
udp_header_t *udp;
|
||||||
ip4_header_t *ip = vlib_buffer_get_current (b);
|
if (AF_IP4 == af)
|
||||||
udp = (udp_header_t *) (ip + 1);
|
{
|
||||||
|
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);
|
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
|
* Find registerered client
|
||||||
* If no registered client, drop packet and count
|
* 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)
|
else if (PUNT_TYPE_IP_PROTO == pt)
|
||||||
{
|
{
|
||||||
@ -397,6 +405,14 @@ error:
|
|||||||
return n_packets;
|
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
|
static uword
|
||||||
udp4_punt_socket (vlib_main_t * vm,
|
udp4_punt_socket (vlib_main_t * vm,
|
||||||
vlib_node_runtime_t * node, vlib_frame_t * from_frame)
|
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);
|
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
|
static uword
|
||||||
exception_punt_socket (vlib_main_t * vm,
|
exception_punt_socket (vlib_main_t * vm,
|
||||||
vlib_node_runtime_t * node, vlib_frame_t * from_frame)
|
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,
|
.n_errors = PUNT_N_ERROR,
|
||||||
.error_strings = punt_error_strings,
|
.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* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
Reference in New Issue
Block a user