#include <vnet/pg/pg.h>
#include <vnet/udp/udp.h>
#include <vnet/tcp/tcp.h>
+#include <vnet/sctp/sctp.h>
#include <vnet/ip/punt.h>
#include <vppinfra/sparse_vec.h>
#include <vlib/unix/unix.h>
#include <stdbool.h>
#define foreach_punt_next \
- _ (PUNT, "error-punt")
+ _ (PUNT4, "ip4-punt") \
+ _ (PUNT6, "ip6-punt")
typedef enum
{
PUNT_SOCKET_RX_N_NEXT
};
+#define punt_next_punt(is_ip4) (is_ip4 ? PUNT_NEXT_PUNT4 : PUNT_NEXT_PUNT6)
+
vlib_node_registration_t udp4_punt_node;
vlib_node_registration_t udp6_punt_node;
vlib_node_registration_t udp4_punt_socket_node;
{
u32 n_left_to_next;
- vlib_get_next_frame (vm, node, PUNT_NEXT_PUNT, to_next, n_left_to_next);
+ vlib_get_next_frame (vm, node, punt_next_punt (is_ip4), to_next,
+ n_left_to_next);
while (n_left_from > 0 && n_left_to_next > 0)
{
b0->error = node->errors[PUNT_ERROR_UDP_PORT];
}
- vlib_put_next_frame (vm, node, PUNT_NEXT_PUNT, n_left_to_next);
+ vlib_put_next_frame (vm, node, punt_next_punt (is_ip4), n_left_to_next);
}
return from_frame->n_vectors;
punt_client_t *c = NULL;
if (PREDICT_FALSE (b->flags & VLIB_BUFFER_IS_TRACED))
{
- if (!c)
- {
- c = punt_client_get (is_ip4, port);
- }
+ c = punt_client_get (is_ip4, port);
udp_punt_trace_t *t;
t = vlib_add_trace (vm, node, b, sizeof (t[0]));
clib_memcpy (&t->client, c, sizeof (t->client));
b = vlib_get_buffer (vm, b->next_buffer);
if (PREDICT_FALSE (b->flags & VLIB_BUFFER_IS_TRACED))
{
+ if (PREDICT_FALSE (!c))
+ {
+ c = punt_client_get (is_ip4, port);
+ }
udp_punt_trace_t *t;
t = vlib_add_trace (vm, node, b, sizeof (t[0]));
clib_memcpy (&t->client, c, sizeof (t->client));
bool is_add)
{
- /* For now we only support UDP punt */
- if (protocol != IP_PROTOCOL_UDP && protocol != IP_PROTOCOL_TCP)
+ /* For now we only support TCP, UDP and SCTP punt */
+ if (protocol != IP_PROTOCOL_UDP &&
+ protocol != IP_PROTOCOL_TCP && protocol != IP_PROTOCOL_SCTP)
return clib_error_return (0,
- "only UDP (%d) and TCP (%d) protocols are supported, got %d",
- IP_PROTOCOL_UDP, IP_PROTOCOL_TCP, protocol);
+ "only UDP (%d), TCP (%d) and SCTP (%d) protocols are supported, got %d",
+ IP_PROTOCOL_UDP, IP_PROTOCOL_TCP,
+ IP_PROTOCOL_SCTP, protocol);
if (ipv != (u8) ~ 0 && ipv != 4 && ipv != 6)
return clib_error_return (0, "IP version must be 4 or 6, got %d", ipv);
udp_punt_unknown (vm, 1, is_add);
else if (protocol == IP_PROTOCOL_TCP)
tcp_punt_unknown (vm, 1, is_add);
+ else if (protocol == IP_PROTOCOL_SCTP)
+ sctp_punt_unknown (vm, 1, is_add);
}
if ((ipv == 6) || (ipv == (u8) ~ 0))
udp_punt_unknown (vm, 0, is_add);
else if (protocol == IP_PROTOCOL_TCP)
tcp_punt_unknown (vm, 0, is_add);
+ else if (protocol == IP_PROTOCOL_SCTP)
+ sctp_punt_unknown (vm, 0, is_add);
}
return 0;
else if (is_add)
{
- if (protocol == IP_PROTOCOL_TCP)
- return clib_error_return (0, "punt TCP ports is not supported yet");
+ if (protocol == IP_PROTOCOL_TCP || protocol == IP_PROTOCOL_SCTP)
+ return clib_error_return (0,
+ "punt TCP/SCTP ports is not supported yet");
if (ipv == 4 || ipv == (u8) ~ 0)
udp_register_dst_port (vm, port, udp4_punt_node.index, 1);
u32 port;
bool is_add = true;
u32 protocol = ~0;
- clib_error_t *error;
+ clib_error_t *error = NULL;
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
{
/* punt both IPv6 and IPv4 when used in CLI */
error = vnet_punt_add_del (vm, ~0, protocol, ~0, is_add);
if (error)
- clib_error_report (error);
+ {
+ clib_error_report (error);
+ goto done;
+ }
}
else if (unformat (input, "%d", &port))
{
/* punt both IPv6 and IPv4 when used in CLI */
error = vnet_punt_add_del (vm, ~0, protocol, port, is_add);
if (error)
- clib_error_report (error);
+ {
+ clib_error_report (error);
+ goto done;
+ }
}
else if (unformat (input, "udp"))
protocol = IP_PROTOCOL_UDP;
else if (unformat (input, "tcp"))
protocol = IP_PROTOCOL_TCP;
+ else
+ {
+ error = clib_error_return (0, "parse error: '%U'",
+ format_unformat_error, input);
+ goto done;
+ }
}
-
- return 0;
+done:
+ return error;
}
/*?
clib_file_t template = { 0 };
template.read_function = punt_socket_read_ready;
template.file_descriptor = pm->socket_fd;
+ template.description = format (0, "%s", socket_path);
pm->clib_file_index = clib_file_add (fm, &template);
pm->is_configured = true;