diff options
Diffstat (limited to 'src/plugins/snort')
-rw-r--r-- | src/plugins/snort/cli.c | 15 | ||||
-rw-r--r-- | src/plugins/snort/daq_vpp.c | 3 | ||||
-rw-r--r-- | src/plugins/snort/daq_vpp.h | 2 | ||||
-rw-r--r-- | src/plugins/snort/dequeue.c | 4 | ||||
-rw-r--r-- | src/plugins/snort/enqueue.c | 15 | ||||
-rw-r--r-- | src/plugins/snort/main.c | 65 | ||||
-rw-r--r-- | src/plugins/snort/snort.h | 10 |
7 files changed, 88 insertions, 26 deletions
diff --git a/src/plugins/snort/cli.c b/src/plugins/snort/cli.c index cbb33c7abe8..08740f41b37 100644 --- a/src/plugins/snort/cli.c +++ b/src/plugins/snort/cli.c @@ -85,6 +85,7 @@ snort_attach_command_fn (vlib_main_t *vm, unformat_input_t *input, clib_error_t *err = 0; u8 *name = 0; u32 sw_if_index = ~0; + snort_attach_dir_t dir = SNORT_INOUT; /* Get a line of input. */ if (!unformat_user (input, unformat_line_input, line_input)) @@ -97,6 +98,12 @@ snort_attach_command_fn (vlib_main_t *vm, unformat_input_t *input, ; else if (unformat (line_input, "instance %s", &name)) ; + else if (unformat (line_input, "input")) + dir = SNORT_INPUT; + else if (unformat (line_input, "output")) + dir = SNORT_OUTPUT; + else if (unformat (line_input, "inout")) + dir = SNORT_INOUT; else { err = clib_error_return (0, "unknown input `%U'", @@ -117,7 +124,8 @@ snort_attach_command_fn (vlib_main_t *vm, unformat_input_t *input, goto done; } - err = snort_interface_enable_disable (vm, (char *) name, sw_if_index, 1); + err = + snort_interface_enable_disable (vm, (char *) name, sw_if_index, 1, dir); done: vec_free (name); @@ -127,7 +135,8 @@ done: VLIB_CLI_COMMAND (snort_attach_command, static) = { .path = "snort attach", - .short_help = "snort attach instance <name> interface <if-name>", + .short_help = "snort attach instance <name> interface <if-name> " + "[input|ouput|inout]", .function = snort_attach_command_fn, }; @@ -163,7 +172,7 @@ snort_detach_command_fn (vlib_main_t *vm, unformat_input_t *input, goto done; } - err = snort_interface_enable_disable (vm, 0, sw_if_index, 0); + err = snort_interface_enable_disable (vm, 0, sw_if_index, 0, SNORT_INOUT); done: unformat_free (line_input); diff --git a/src/plugins/snort/daq_vpp.c b/src/plugins/snort/daq_vpp.c index e9d7523a986..386092a0382 100644 --- a/src/plugins/snort/daq_vpp.c +++ b/src/plugins/snort/daq_vpp.c @@ -628,8 +628,7 @@ vpp_daq_msg_receive (void *handle, const unsigned max_recv, msgs += n; n_recv += n; } - - (void) read (qp->enq_fd, &ctr, sizeof (ctr)); + ssize_t __clib_unused size = read (qp->enq_fd, &ctr, sizeof (ctr)); } *rstat = DAQ_RSTAT_OK; diff --git a/src/plugins/snort/daq_vpp.h b/src/plugins/snort/daq_vpp.h index 3b875aa15ad..ebec55435f3 100644 --- a/src/plugins/snort/daq_vpp.h +++ b/src/plugins/snort/daq_vpp.h @@ -67,7 +67,7 @@ typedef enum typedef struct { - uint32_t offset; + uint64_t offset; uint16_t length; uint16_t address_space_id; uint8_t buffer_pool; diff --git a/src/plugins/snort/dequeue.c b/src/plugins/snort/dequeue.c index d597b88f7a8..31745de404c 100644 --- a/src/plugins/snort/dequeue.c +++ b/src/plugins/snort/dequeue.c @@ -187,9 +187,9 @@ snort_deq_node_interrupt (vlib_main_t *vm, vlib_node_runtime_t *node, snort_instance_t *si; int inst = -1; - while ((inst = clib_interrupt_get_next (ptd->interrupts, inst)) != -1) + while ((inst = clib_interrupt_get_next_and_clear (ptd->interrupts, inst)) != + -1) { - clib_interrupt_clear (ptd->interrupts, inst); si = vec_elt_at_index (sm->instances, inst); qp = vec_elt_at_index (si->qpairs, vm->thread_index); u32 ready = __atomic_load_n (&qp->ready, __ATOMIC_ACQUIRE); diff --git a/src/plugins/snort/enqueue.c b/src/plugins/snort/enqueue.c index 3f44e8013fd..409c0e49078 100644 --- a/src/plugins/snort/enqueue.c +++ b/src/plugins/snort/enqueue.c @@ -75,9 +75,16 @@ snort_enq_node_inline (vlib_main_t *vm, vlib_node_runtime_t *node, while (n_left) { + u64 fa_data; u32 instance_index, next_index, n; - instance_index = - *(u32 *) vnet_feature_next_with_data (&next_index, b[0], sizeof (u32)); + u32 l3_offset; + + fa_data = + *(u64 *) vnet_feature_next_with_data (&next_index, b[0], sizeof (u64)); + + instance_index = (u32) (fa_data & 0xffffffff); + l3_offset = + (fa_data >> 32) ? vnet_buffer (b[0])->ip.save_rewrite_length : 0; si = vec_elt_at_index (sm->instances, instance_index); /* if client isn't connected skip enqueue and take default action */ @@ -108,7 +115,7 @@ snort_enq_node_inline (vlib_main_t *vm, vlib_node_runtime_t *node, /* fill descriptor */ d->buffer_pool = b[0]->buffer_pool_index; d->length = b[0]->current_length; - d->offset = (u8 *) b[0]->data + b[0]->current_data - + d->offset = (u8 *) b[0]->data + b[0]->current_data + l3_offset - sm->buffer_pool_base_addrs[d->buffer_pool]; d->address_space_id = vnet_buffer (b[0])->sw_if_index[VLIB_RX]; } @@ -190,7 +197,7 @@ snort_enq_node_inline (vlib_main_t *vm, vlib_node_runtime_t *node, } __atomic_store_n (qp->enq_head, head, __ATOMIC_RELEASE); - _vec_len (qp->freelist) = freelist_len; + vec_set_len (qp->freelist, freelist_len); if (sm->input_mode == VLIB_NODE_STATE_INTERRUPT) { if (write (qp->enq_fd, &ctr, sizeof (ctr)) < 0) diff --git a/src/plugins/snort/main.c b/src/plugins/snort/main.c index 37b517215bc..2430fcdc5c2 100644 --- a/src/plugins/snort/main.c +++ b/src/plugins/snort/main.c @@ -13,7 +13,6 @@ snort_main_t snort_main; VLIB_REGISTER_LOG_CLASS (snort_log, static) = { .class_name = "snort", - .default_syslog_level = VLIB_LOG_LEVEL_DEBUG, }; #define log_debug(fmt, ...) vlib_log_debug (snort_log.class, fmt, __VA_ARGS__) @@ -196,9 +195,18 @@ snort_deq_ready (clib_file_t *uf) snort_per_thread_data_t *ptd = vec_elt_at_index (sm->per_thread_data, vm->thread_index); u64 counter; + ssize_t bytes_read; - if (read (uf->file_descriptor, &counter, sizeof (counter)) < 0) - return clib_error_return (0, "client closed socket"); + bytes_read = read (uf->file_descriptor, &counter, sizeof (counter)); + if (bytes_read < 0) + { + return clib_error_return (0, "client closed socket"); + } + + if (bytes_read < sizeof (counter)) + { + return clib_error_return (0, "unexpected truncated read"); + } clib_interrupt_set (ptd->interrupts, uf->private_data); vlib_node_set_interrupt_pending (vm, snort_deq_node.index); @@ -251,8 +259,10 @@ snort_listener_init (vlib_main_t *vm) s = clib_mem_alloc (sizeof (clib_socket_t)); clib_memset (s, 0, sizeof (clib_socket_t)); s->config = (char *) sm->socket_name; - s->flags = CLIB_SOCKET_F_IS_SERVER | CLIB_SOCKET_F_ALLOW_GROUP_WRITE | - CLIB_SOCKET_F_SEQPACKET | CLIB_SOCKET_F_PASSCRED; + s->is_server = 1; + s->allow_group_write = 1; + s->is_seqpacket = 1; + s->passcred = 1; if ((err = clib_socket_init (s))) { @@ -299,8 +309,8 @@ snort_instance_create (vlib_main_t *vm, char *name, u8 log2_queue_sz, /* enq and deq head pointer */ qpair_mem_sz += 2 * round_pow2 (sizeof (u32), align); - size = - round_pow2 (tm->n_vlib_mains * qpair_mem_sz, clib_mem_get_page_size ()); + size = round_pow2 ((uword) tm->n_vlib_mains * qpair_mem_sz, + clib_mem_get_page_size ()); fd = clib_mem_vm_create_fd (CLIB_MEM_PAGE_SZ_DEFAULT, "snort instance %s", name); @@ -386,7 +396,7 @@ snort_instance_create (vlib_main_t *vm, char *name, u8 log2_queue_sz, for (i = 0; i < vlib_get_n_threads (); i++) vlib_node_set_state (vlib_get_main_by_index (i), snort_deq_node.index, - VLIB_NODE_STATE_INTERRUPT); + sm->input_mode); done: if (err) @@ -401,12 +411,14 @@ done: clib_error_t * snort_interface_enable_disable (vlib_main_t *vm, char *instance_name, - u32 sw_if_index, int is_enable) + u32 sw_if_index, int is_enable, + snort_attach_dir_t snort_dir) { snort_main_t *sm = &snort_main; vnet_main_t *vnm = vnet_get_main (); snort_instance_t *si; clib_error_t *err = 0; + u64 fa_data; u32 index; if (is_enable) @@ -432,8 +444,18 @@ snort_interface_enable_disable (vlib_main_t *vm, char *instance_name, } index = sm->instance_by_sw_if_index[sw_if_index] = si->index; - vnet_feature_enable_disable ("ip4-unicast", "snort-enq", sw_if_index, 1, - &index, sizeof (index)); + if (snort_dir & SNORT_INPUT) + { + fa_data = (u64) index; + vnet_feature_enable_disable ("ip4-unicast", "snort-enq", sw_if_index, + 1, &fa_data, sizeof (fa_data)); + } + if (snort_dir & SNORT_OUTPUT) + { + fa_data = (1LL << 32 | index); + vnet_feature_enable_disable ("ip4-output", "snort-enq", sw_if_index, + 1, &fa_data, sizeof (fa_data)); + } } else { @@ -451,8 +473,18 @@ snort_interface_enable_disable (vlib_main_t *vm, char *instance_name, si = vec_elt_at_index (sm->instances, index); sm->instance_by_sw_if_index[sw_if_index] = ~0; - vnet_feature_enable_disable ("ip4-unicast", "snort-enq", sw_if_index, 0, - &index, sizeof (index)); + if (snort_dir & SNORT_INPUT) + { + fa_data = (u64) index; + vnet_feature_enable_disable ("ip4-unicast", "snort-enq", sw_if_index, + 0, &fa_data, sizeof (fa_data)); + } + if (snort_dir & SNORT_OUTPUT) + { + fa_data = (1LL << 32 | index); + vnet_feature_enable_disable ("ip4-output", "snort-enq", sw_if_index, + 0, &fa_data, sizeof (fa_data)); + } } done: @@ -490,6 +522,7 @@ static clib_error_t * snort_init (vlib_main_t *vm) { snort_main_t *sm = &snort_main; + sm->input_mode = VLIB_NODE_STATE_INTERRUPT; sm->instance_by_name = hash_create_string (0, sizeof (uword)); vlib_buffer_pool_t *bp; @@ -518,3 +551,9 @@ VNET_FEATURE_INIT (snort_enq, static) = { .node_name = "snort-enq", .runs_before = VNET_FEATURES ("ip4-lookup"), }; + +VNET_FEATURE_INIT (snort_enq_out, static) = { + .arc_name = "ip4-output", + .node_name = "snort-enq", + .runs_before = VNET_FEATURES ("interface-output"), +}; diff --git a/src/plugins/snort/snort.h b/src/plugins/snort/snort.h index d069fa01661..79299aa6d91 100644 --- a/src/plugins/snort/snort.h +++ b/src/plugins/snort/snort.h @@ -90,6 +90,13 @@ typedef enum SNORT_ENQ_N_NEXT_NODES, } snort_enq_next_t; +typedef enum +{ + SNORT_INPUT = 1, + SNORT_OUTPUT = 2, + SNORT_INOUT = 3 +} snort_attach_dir_t; + #define SNORT_ENQ_NEXT_NODES \ { \ [SNORT_ENQ_NEXT_DROP] = "error-drop", \ @@ -100,7 +107,8 @@ clib_error_t *snort_instance_create (vlib_main_t *vm, char *name, u8 log2_queue_sz, u8 drop_on_disconnect); clib_error_t *snort_interface_enable_disable (vlib_main_t *vm, char *instance_name, - u32 sw_if_index, int is_enable); + u32 sw_if_index, int is_enable, + snort_attach_dir_t dir); clib_error_t *snort_set_node_mode (vlib_main_t *vm, u32 mode); always_inline void |