#include <vlib/vlib.h>
#include <vlibapi/api.h>
#include <vlibmemory/api.h>
-#include <vlibsocket/api.h>
+
#include <vnet/ip/ip.h>
#include <vnet/ip/ip6_hop_by_hop.h>
#include <ioam/encap/ip6_ioam_trace.h>
#include <ioam/udp-ping/udp_ping_packet.h>
#include <ioam/udp-ping/udp_ping.h>
#include <ioam/udp-ping/udp_ping_util.h>
-#include <vnet/sr/sr_packet.h>
+#include <vnet/srv6/sr_packet.h>
typedef enum
{
UDP_PING_N_NEXT,
} udp_ping_next_t;
+#define foreach_udp_ping_error \
+_(BADHBH, "Malformed hop-by-hop header")
+
+typedef enum
+{
+#define _(sym,str) UDP_PING_ERROR_##sym,
+ foreach_udp_ping_error
+#undef _
+ UDP_PING_N_ERROR,
+} udp_ping_error_t;
+
+static char *udp_ping_error_strings[] = {
+#define _(sym,string) string,
+ foreach_udp_ping_error
+#undef _
+};
+
udp_ping_main_t udp_ping_main;
uword
ioam_e2e_option_t *e2e;
ioam_trace_option_t *trace;
+ /* If the packet doesnt match UDP session then return */
+ if (PREDICT_FALSE (pool_is_free_index (udp_ping_main.ip46_flow, flow_id)))
+ return;
+
ip46_flow = udp_ping_main.ip46_flow + flow_id;
+ /* Check port is within range */
+ if (PREDICT_FALSE ((src_port < ip46_flow->udp_data.start_src_port) ||
+ (src_port > ip46_flow->udp_data.end_src_port) ||
+ (dst_port < ip46_flow->udp_data.start_dst_port) ||
+ (dst_port > ip46_flow->udp_data.end_dst_port)))
+ return;
+
flow_index = (src_port - ip46_flow->udp_data.start_src_port) *
(ip46_flow->udp_data.end_dst_port - ip46_flow->udp_data.start_dst_port +
1);
*
*/
void
-udp_ping_local_analyse (vlib_buffer_t * b0,
- ip6_header_t * ip0,
- ip6_hop_by_hop_header_t * hbh0, u16 * next0)
+udp_ping_local_analyse (vlib_node_runtime_t * node, vlib_buffer_t * b0,
+ ip6_header_t * ip0, ip6_hop_by_hop_header_t * hbh0,
+ u16 * next0)
{
ip6_main_t *im = &ip6_main;
ip_lookup_main_t *lm = &im->lookup_main;
*next0 = UDP_PING_NEXT_IP6_DROP;
+ /*
+ * Sanity check: hbh header length must be less than
+ * b0->current_length.
+ */
+ if (PREDICT_FALSE ((hbh0->length + 1) << 3) >= b0->current_length)
+ {
+ *next0 = UDP_PING_NEXT_DROP;
+ b0->error = node->errors[UDP_PING_ERROR_BADHBH];
+ return;
+ }
+
if (PREDICT_TRUE (hbh0->protocol == IP_PROTOCOL_UDP))
{
ip6_hop_by_hop_option_t *opt0;
* @par Graph mechanics: buffer, next index usage
*
* <em>Uses:</em>
- * - <code>udp_ping_local_analyse(p0, ip0, hbh0, &next0)</code>
+ * - <code>udp_ping_local_analyse(node, p0, ip0, hbh0, &next0)</code>
* - Checks packet type - request/respnse and process them.
*
* <em>Next Index:</em>
hbh0 = (ip6_hop_by_hop_header_t *) (ip0 + 1);
hbh1 = (ip6_hop_by_hop_header_t *) (ip1 + 1);
- udp_ping_local_analyse (p0, ip0, hbh0, &next0);
- udp_ping_local_analyse (p1, ip1, hbh1, &next1);
+ udp_ping_local_analyse (node, p0, ip0, hbh0, &next0);
+ udp_ping_local_analyse (node, p1, ip1, hbh1, &next1);
if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)))
{
ip0 = vlib_buffer_get_current (p0);
hbh0 = (ip6_hop_by_hop_header_t *) (ip0 + 1);
- udp_ping_local_analyse (p0, ip0, hbh0, &next0);
+ udp_ping_local_analyse (node, p0, ip0, hbh0, &next0);
if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)))
{
.format_trace = format_udp_ping_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
.n_next_nodes = UDP_PING_N_NEXT,
+ .n_errors = UDP_PING_N_ERROR,
+ .error_strings = udp_ping_error_strings,
.next_nodes =
{
[UDP_PING_NEXT_DROP] = "error-drop",
static clib_error_t *
udp_ping_init (vlib_main_t * vm)
{
- clib_error_t *error = 0;
-
udp_ping_main.vlib_main = vm;
udp_ping_main.vnet_main = vnet_get_main ();
udp_ping_main.timer_interval = 1e9;
- if ((error = vlib_call_init_function (vm, ip_main_init)))
- return (error);
-
- ip6_register_protocol (IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS,
- udp_ping_local.index);
+ ip6_local_hop_by_hop_register_protocol (IP_PROTOCOL_UDP,
+ udp_ping_local.index);
return 0;
}
-VLIB_INIT_FUNCTION (udp_ping_init);
+/* *INDENT-OFF* */
+VLIB_INIT_FUNCTION (udp_ping_init) =
+{
+ .runs_after = VLIB_INITS("ip_main_init"),
+};
+/* *INDENT-ON* */
/*
* fd.io coding-style-patch-verification: ON