LCOV - code coverage report
Current view: top level - plugins/snort - main.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 148 297 49.8 %
Date: 2023-10-26 01:39:38 Functions: 14 20 70.0 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: Apache-2.0
       2             :  * Copyright(c) 2021 Cisco Systems, Inc.
       3             :  */
       4             : 
       5             : #include <vlib/vlib.h>
       6             : #include <vnet/plugin/plugin.h>
       7             : #include <vpp/app/version.h>
       8             : #include <snort/snort.h>
       9             : 
      10             : #include <sys/eventfd.h>
      11             : 
      12             : snort_main_t snort_main;
      13             : 
      14         575 : VLIB_REGISTER_LOG_CLASS (snort_log, static) = {
      15             :   .class_name = "snort",
      16             : };
      17             : 
      18             : #define log_debug(fmt, ...) vlib_log_debug (snort_log.class, fmt, __VA_ARGS__)
      19             : #define log_err(fmt, ...)   vlib_log_err (snort_log.class, fmt, __VA_ARGS__)
      20             : 
      21             : static void
      22           0 : snort_client_disconnect (clib_file_t *uf)
      23             : {
      24           0 :   vlib_main_t *vm = vlib_get_main ();
      25             :   snort_qpair_t *qp;
      26           0 :   snort_main_t *sm = &snort_main;
      27           0 :   snort_client_t *c = pool_elt_at_index (sm->clients, uf->private_data);
      28             : 
      29           0 :   if (c->instance_index != ~0)
      30             :     {
      31           0 :       snort_per_thread_data_t *ptd =
      32           0 :         vec_elt_at_index (sm->per_thread_data, vm->thread_index);
      33           0 :       snort_instance_t *si =
      34           0 :         pool_elt_at_index (sm->instances, c->instance_index);
      35           0 :       vec_foreach (qp, si->qpairs)
      36           0 :         __atomic_store_n (&qp->ready, 1, __ATOMIC_RELEASE);
      37             : 
      38           0 :       si->client_index = ~0;
      39           0 :       clib_interrupt_set (ptd->interrupts, uf->private_data);
      40           0 :       vlib_node_set_interrupt_pending (vm, snort_deq_node.index);
      41             :     }
      42             : 
      43           0 :   clib_file_del (&file_main, uf);
      44           0 :   clib_socket_close (&c->socket);
      45           0 :   pool_put (sm->clients, c);
      46           0 : }
      47             : 
      48             : static snort_instance_t *
      49           4 : snort_get_instance_by_name (char *name)
      50             : {
      51           4 :   snort_main_t *sm = &snort_main;
      52             :   uword *p;
      53           4 :   if ((p = hash_get_mem (sm->instance_by_name, name)) == 0)
      54           2 :     return 0;
      55             : 
      56           2 :   return vec_elt_at_index (sm->instances, p[0]);
      57             :   ;
      58             : }
      59             : 
      60             : static clib_error_t *
      61           0 : snort_conn_fd_read_ready (clib_file_t *uf)
      62             : {
      63           0 :   vlib_main_t *vm = vlib_get_main ();
      64           0 :   snort_main_t *sm = &snort_main;
      65           0 :   snort_client_t *c = pool_elt_at_index (sm->clients, uf->private_data);
      66             :   vlib_buffer_pool_t *bp;
      67             :   snort_instance_t *si;
      68             :   snort_qpair_t *qp;
      69             :   snort_client_msg_queue_elt *e;
      70             :   clib_error_t *err;
      71             :   daq_vpp_msg_t msg;
      72             :   char *name;
      73             :   u8 *base;
      74             : 
      75           0 :   log_debug ("fd_read_ready: client %u", uf->private_data);
      76             : 
      77           0 :   if ((err = clib_socket_recvmsg (&c->socket, &msg, sizeof (msg), 0, 0)))
      78             :     {
      79           0 :       log_err ("client recvmsg error: %U", format_clib_error, err);
      80           0 :       snort_client_disconnect (uf);
      81           0 :       clib_error_free (err);
      82           0 :       return 0;
      83             :     }
      84             : 
      85           0 :   if (msg.type != DAQ_VPP_MSG_TYPE_HELLO)
      86             :     {
      87           0 :       log_err ("unexpeced message recieved from client", 0);
      88           0 :       snort_client_disconnect (uf);
      89           0 :       return 0;
      90             :     }
      91             : 
      92           0 :   msg.hello.inst_name[DAQ_VPP_INST_NAME_LEN - 1] = 0;
      93           0 :   name = msg.hello.inst_name;
      94             : 
      95           0 :   log_debug ("fd_read_ready: connect instance %s", name);
      96             : 
      97           0 :   if ((si = snort_get_instance_by_name (name)) == 0)
      98             :     {
      99           0 :       log_err ("unknown instance '%s' requested by client", name);
     100           0 :       snort_client_disconnect (uf);
     101           0 :       return 0;
     102             :     }
     103             : 
     104           0 :   vec_foreach (qp, si->qpairs)
     105             :     {
     106           0 :       u32 ready = __atomic_load_n (&qp->ready, __ATOMIC_ACQUIRE);
     107           0 :       if (!ready)
     108             :         {
     109           0 :           log_err ("instance '%s' is not ready to accept connections", name);
     110           0 :           snort_client_disconnect (uf);
     111           0 :           return 0;
     112             :         }
     113             :     }
     114             : 
     115           0 :   base = (u8 *) si->shm_base;
     116             : 
     117           0 :   if (si->client_index != ~0)
     118             :     {
     119           0 :       log_err ("client already connected to instance '%s'", name);
     120           0 :       snort_client_disconnect (uf);
     121           0 :       return 0;
     122             :     }
     123           0 :   si->client_index = uf->private_data;
     124           0 :   c->instance_index = si->index;
     125             : 
     126           0 :   log_debug ("fd_read_ready: connect instance index %u", si->index);
     127             : 
     128           0 :   clib_fifo_add2 (c->msg_queue, e);
     129           0 :   e->msg.type = DAQ_VPP_MSG_TYPE_CONFIG;
     130           0 :   e->msg.config.num_bpools = vec_len (vm->buffer_main->buffer_pools);
     131           0 :   e->msg.config.num_qpairs = vec_len (si->qpairs);
     132           0 :   e->msg.config.shm_size = si->shm_size;
     133           0 :   e->fds[0] = si->shm_fd;
     134           0 :   e->n_fds = 1;
     135             : 
     136           0 :   vec_foreach (bp, vm->buffer_main->buffer_pools)
     137             :     {
     138             :       vlib_physmem_map_t *pm;
     139           0 :       pm = vlib_physmem_get_map (vm, bp->physmem_map_index);
     140           0 :       clib_fifo_add2 (c->msg_queue, e);
     141           0 :       e->msg.type = DAQ_VPP_MSG_TYPE_BPOOL;
     142           0 :       e->msg.bpool.size = pm->n_pages << pm->log2_page_size;
     143           0 :       e->fds[0] = pm->fd;
     144           0 :       e->n_fds = 1;
     145             :     }
     146             : 
     147           0 :   vec_foreach (qp, si->qpairs)
     148             :     {
     149           0 :       clib_fifo_add2 (c->msg_queue, e);
     150           0 :       e->msg.type = DAQ_VPP_MSG_TYPE_QPAIR;
     151           0 :       e->msg.qpair.log2_queue_size = qp->log2_queue_size;
     152           0 :       e->msg.qpair.desc_table_offset = (u8 *) qp->descriptors - base;
     153           0 :       e->msg.qpair.enq_ring_offset = (u8 *) qp->enq_ring - base;
     154           0 :       e->msg.qpair.deq_ring_offset = (u8 *) qp->deq_ring - base;
     155           0 :       e->msg.qpair.enq_head_offset = (u8 *) qp->enq_head - base;
     156           0 :       e->msg.qpair.deq_head_offset = (u8 *) qp->deq_head - base;
     157           0 :       e->fds[0] = qp->enq_fd;
     158           0 :       e->fds[1] = qp->deq_fd;
     159           0 :       e->n_fds = 2;
     160             :     }
     161             : 
     162           0 :   clib_file_set_data_available_to_write (&file_main, c->file_index, 1);
     163           0 :   return 0;
     164             : }
     165             : 
     166             : static clib_error_t *
     167           0 : snort_conn_fd_write_ready (clib_file_t *uf)
     168             : {
     169           0 :   snort_main_t *sm = &snort_main;
     170           0 :   snort_client_t *c = pool_elt_at_index (sm->clients, uf->private_data);
     171             :   snort_client_msg_queue_elt *e;
     172             : 
     173           0 :   log_debug ("fd_write_ready: client %u", uf->private_data);
     174           0 :   clib_fifo_sub2 (c->msg_queue, e);
     175             : 
     176           0 :   if (clib_fifo_elts (c->msg_queue) == 0)
     177           0 :     clib_file_set_data_available_to_write (&file_main, c->file_index, 0);
     178             : 
     179           0 :   return clib_socket_sendmsg (&c->socket, &e->msg, sizeof (*e), e->fds,
     180             :                               e->n_fds);
     181             : }
     182             : 
     183             : clib_error_t *
     184           0 : snort_conn_fd_error (clib_file_t *uf)
     185             : {
     186           0 :   log_debug ("fd_error: client %u", uf->private_data);
     187           0 :   return 0;
     188             : }
     189             : 
     190             : static clib_error_t *
     191           0 : snort_deq_ready (clib_file_t *uf)
     192             : {
     193           0 :   vlib_main_t *vm = vlib_get_main ();
     194           0 :   snort_main_t *sm = &snort_main;
     195           0 :   snort_per_thread_data_t *ptd =
     196           0 :     vec_elt_at_index (sm->per_thread_data, vm->thread_index);
     197             :   u64 counter;
     198             :   ssize_t bytes_read;
     199             : 
     200           0 :   bytes_read = read (uf->file_descriptor, &counter, sizeof (counter));
     201           0 :   if (bytes_read < 0)
     202             :     {
     203           0 :       return clib_error_return (0, "client closed socket");
     204             :     }
     205             : 
     206           0 :   if (bytes_read < sizeof (counter))
     207             :     {
     208           0 :       return clib_error_return (0, "unexpected truncated read");
     209             :     }
     210             : 
     211           0 :   clib_interrupt_set (ptd->interrupts, uf->private_data);
     212           0 :   vlib_node_set_interrupt_pending (vm, snort_deq_node.index);
     213           0 :   return 0;
     214             : }
     215             : 
     216             : static clib_error_t *
     217           0 : snort_conn_fd_accept_ready (clib_file_t *uf)
     218             : {
     219           0 :   snort_main_t *sm = &snort_main;
     220             :   snort_client_t *c;
     221             :   clib_socket_t *s;
     222           0 :   clib_error_t *err = 0;
     223           0 :   clib_file_t t = { 0 };
     224             : 
     225           0 :   pool_get_zero (sm->clients, c);
     226           0 :   c->instance_index = ~0;
     227           0 :   s = &c->socket;
     228             : 
     229           0 :   if ((err = clib_socket_accept (sm->listener, s)))
     230             :     {
     231           0 :       log_err ("%U", format_clib_error, err);
     232           0 :       pool_put (sm->clients, c);
     233           0 :       return err;
     234             :     }
     235             : 
     236           0 :   t.read_function = snort_conn_fd_read_ready;
     237           0 :   t.write_function = snort_conn_fd_write_ready;
     238           0 :   t.error_function = snort_conn_fd_error;
     239           0 :   t.file_descriptor = s->fd;
     240           0 :   t.private_data = c - sm->clients;
     241           0 :   t.description = format (0, "snort client");
     242           0 :   c->file_index = clib_file_add (&file_main, &t);
     243             : 
     244           0 :   log_debug ("snort_conn_fd_accept_ready: client %u", t.private_data);
     245           0 :   return 0;
     246             : }
     247             : 
     248             : static clib_error_t *
     249         575 : snort_listener_init (vlib_main_t *vm)
     250             : {
     251         575 :   snort_main_t *sm = &snort_main;
     252             :   clib_error_t *err;
     253         575 :   clib_file_t t = { 0 };
     254             :   clib_socket_t *s;
     255             : 
     256         575 :   if (sm->listener)
     257           0 :     return 0;
     258             : 
     259         575 :   s = clib_mem_alloc (sizeof (clib_socket_t));
     260         575 :   clib_memset (s, 0, sizeof (clib_socket_t));
     261         575 :   s->config = (char *) sm->socket_name;
     262         575 :   s->is_server = 1;
     263         575 :   s->allow_group_write = 1;
     264         575 :   s->is_seqpacket = 1;
     265         575 :   s->passcred = 1;
     266             : 
     267         575 :   if ((err = clib_socket_init (s)))
     268             :     {
     269           0 :       clib_mem_free (s);
     270           0 :       return err;
     271             :     }
     272             : 
     273         575 :   t.read_function = snort_conn_fd_accept_ready;
     274         575 :   t.file_descriptor = s->fd;
     275         575 :   t.description = format (0, "snort listener %s", s->config);
     276         575 :   log_debug ("%v", t.description);
     277         575 :   clib_file_add (&file_main, &t);
     278             : 
     279         575 :   sm->listener = s;
     280             : 
     281         575 :   return 0;
     282             : }
     283             : 
     284             : clib_error_t *
     285           2 : snort_instance_create (vlib_main_t *vm, char *name, u8 log2_queue_sz,
     286             :                        u8 drop_on_disconnect)
     287             : {
     288           2 :   vlib_thread_main_t *tm = vlib_get_thread_main ();
     289           2 :   snort_main_t *sm = &snort_main;
     290             :   snort_instance_t *si;
     291           2 :   clib_error_t *err = 0;
     292             :   u32 index, i;
     293           2 :   u8 *base = CLIB_MEM_VM_MAP_FAILED;
     294             :   u32 size;
     295           2 :   int fd = -1;
     296           2 :   u32 qpair_mem_sz = 0;
     297           2 :   u32 qsz = 1 << log2_queue_sz;
     298           2 :   u8 align = CLIB_CACHE_LINE_BYTES;
     299             : 
     300           2 :   if (snort_get_instance_by_name (name))
     301           0 :     return clib_error_return (0, "instance already exists");
     302             : 
     303             :   /* descriptor table */
     304           2 :   qpair_mem_sz += round_pow2 (qsz * sizeof (daq_vpp_desc_t), align);
     305             : 
     306             :   /* enq and deq ring */
     307           2 :   qpair_mem_sz += 2 * round_pow2 (qsz * sizeof (u32), align);
     308             : 
     309             :   /* enq and deq head pointer */
     310           2 :   qpair_mem_sz += 2 * round_pow2 (sizeof (u32), align);
     311             : 
     312           2 :   size = round_pow2 ((uword) tm->n_vlib_mains * qpair_mem_sz,
     313             :                      clib_mem_get_page_size ());
     314           2 :   fd = clib_mem_vm_create_fd (CLIB_MEM_PAGE_SZ_DEFAULT, "snort instance %s",
     315             :                               name);
     316             : 
     317           2 :   if (fd == -1)
     318             :     {
     319           0 :       err = clib_error_return (0, "memory fd failure: %U", format_clib_error,
     320             :                                clib_mem_get_last_error ());
     321           0 :       goto done;
     322             :     }
     323             : 
     324           2 :   if ((ftruncate (fd, size)) == -1)
     325             :     {
     326           0 :       err = clib_error_return (0, "ftruncate failure");
     327           0 :       goto done;
     328             :     }
     329             : 
     330           2 :   base = clib_mem_vm_map_shared (0, size, fd, 0, "snort instance %s", name);
     331             : 
     332           2 :   if (base == CLIB_MEM_VM_MAP_FAILED)
     333             :     {
     334           0 :       err = clib_error_return (0, "mmap failure");
     335           0 :       goto done;
     336             :     }
     337             : 
     338           2 :   pool_get_zero (sm->instances, si);
     339           2 :   si->index = si - sm->instances;
     340           2 :   si->client_index = ~0;
     341           2 :   si->shm_base = base;
     342           2 :   si->shm_fd = fd;
     343           2 :   si->shm_size = size;
     344           2 :   si->name = format (0, "%s%c", name, 0);
     345           2 :   si->drop_on_disconnect = drop_on_disconnect;
     346           2 :   index = si - sm->instances;
     347           4 :   hash_set_mem (sm->instance_by_name, si->name, index);
     348             : 
     349           2 :   log_debug ("instnce '%s' createed with fd %d at %p, len %u", name, fd, base,
     350             :              size);
     351             : 
     352           2 :   vec_validate_aligned (sm->per_thread_data, tm->n_vlib_mains - 1,
     353             :                         CLIB_CACHE_LINE_BYTES);
     354           2 :   vec_validate_aligned (si->qpairs, tm->n_vlib_mains - 1,
     355             :                         CLIB_CACHE_LINE_BYTES);
     356             : 
     357           4 :   for (int i = 0; i < tm->n_vlib_mains; i++)
     358             :     {
     359           2 :       snort_qpair_t *qp = vec_elt_at_index (si->qpairs, i);
     360           2 :       snort_per_thread_data_t *ptd = vec_elt_at_index (sm->per_thread_data, i);
     361           2 :       clib_file_t t = { 0 };
     362             : 
     363           2 :       qp->log2_queue_size = log2_queue_sz;
     364           2 :       qp->descriptors = (void *) base;
     365           2 :       base += round_pow2 (qsz * sizeof (daq_vpp_desc_t), align);
     366           2 :       qp->enq_ring = (void *) base;
     367           2 :       base += round_pow2 (qsz * sizeof (u32), align);
     368           2 :       qp->deq_ring = (void *) base;
     369           2 :       base += round_pow2 (qsz * sizeof (u32), align);
     370           2 :       qp->enq_head = (void *) base;
     371           2 :       base += round_pow2 (sizeof (u32), align);
     372           2 :       qp->deq_head = (void *) base;
     373           2 :       base += round_pow2 (sizeof (u32), align);
     374           2 :       qp->enq_fd = eventfd (0, EFD_NONBLOCK);
     375           2 :       qp->deq_fd = eventfd (0, EFD_NONBLOCK);
     376           2 :       vec_validate_aligned (qp->buffer_indices, qsz - 1,
     377             :                             CLIB_CACHE_LINE_BYTES);
     378           2 :       vec_validate_aligned (qp->next_indices, qsz - 1, CLIB_CACHE_LINE_BYTES);
     379           2 :       clib_memset_u32 (qp->buffer_indices, ~0, qsz);
     380             : 
     381             :       /* pre-populate freelist */
     382           2 :       vec_validate_aligned (qp->freelist, qsz - 1, CLIB_CACHE_LINE_BYTES);
     383           2 :       snort_freelist_init (qp->freelist);
     384             : 
     385             :       /* listen on dequeue events */
     386           2 :       t.read_function = snort_deq_ready;
     387           2 :       t.file_descriptor = qp->deq_fd;
     388           2 :       t.private_data = si->index;
     389           2 :       t.description =
     390           2 :         format (0, "snort dequeue for instance '%s' qpair %u", si->name, i);
     391           2 :       qp->deq_fd_file_index = clib_file_add (&file_main, &t);
     392           2 :       qp->ready = 1;
     393           2 :       clib_file_set_polling_thread (&file_main, qp->deq_fd_file_index, i);
     394           2 :       clib_interrupt_resize (&ptd->interrupts, vec_len (sm->instances));
     395             :     }
     396             : 
     397           4 :   for (i = 0; i < vlib_get_n_threads (); i++)
     398           2 :     vlib_node_set_state (vlib_get_main_by_index (i), snort_deq_node.index,
     399           2 :                          sm->input_mode);
     400             : 
     401           2 : done:
     402           2 :   if (err)
     403             :     {
     404           0 :       if (base != CLIB_MEM_VM_MAP_FAILED)
     405           0 :         clib_mem_vm_unmap (base);
     406           0 :       if (fd != -1)
     407           0 :         close (fd);
     408             :     }
     409           2 :   return err;
     410             : }
     411             : 
     412             : clib_error_t *
     413           4 : snort_interface_enable_disable (vlib_main_t *vm, char *instance_name,
     414             :                                 u32 sw_if_index, int is_enable,
     415             :                                 snort_attach_dir_t snort_dir)
     416             : {
     417           4 :   snort_main_t *sm = &snort_main;
     418           4 :   vnet_main_t *vnm = vnet_get_main ();
     419             :   snort_instance_t *si;
     420           4 :   clib_error_t *err = 0;
     421             :   u64 fa_data;
     422             :   u32 index;
     423             : 
     424           4 :   if (is_enable)
     425             :     {
     426           2 :       if ((si = snort_get_instance_by_name (instance_name)) == 0)
     427             :         {
     428           0 :           err = clib_error_return (0, "unknown instance '%s'", instance_name);
     429           0 :           goto done;
     430             :         }
     431             : 
     432           5 :       vec_validate_init_empty (sm->instance_by_sw_if_index, sw_if_index, ~0);
     433             : 
     434           2 :       index = sm->instance_by_sw_if_index[sw_if_index];
     435           2 :       if (index != ~0)
     436             :         {
     437           0 :           si = vec_elt_at_index (sm->instances, index);
     438           0 :           err = clib_error_return (0,
     439             :                                    "interface %U already assgined to "
     440             :                                    "instance '%s'",
     441             :                                    format_vnet_sw_if_index_name, vnm,
     442             :                                    sw_if_index, si->name);
     443           0 :           goto done;
     444             :         }
     445             : 
     446           2 :       index = sm->instance_by_sw_if_index[sw_if_index] = si->index;
     447           2 :       if (snort_dir & SNORT_INPUT)
     448             :         {
     449           1 :           fa_data = (u64) index;
     450           1 :           vnet_feature_enable_disable ("ip4-unicast", "snort-enq", sw_if_index,
     451             :                                        1, &fa_data, sizeof (fa_data));
     452             :         }
     453           2 :       if (snort_dir & SNORT_OUTPUT)
     454             :         {
     455           1 :           fa_data = (1LL << 32 | index);
     456           1 :           vnet_feature_enable_disable ("ip4-output", "snort-enq", sw_if_index,
     457             :                                        1, &fa_data, sizeof (fa_data));
     458             :         }
     459             :     }
     460             :   else
     461             :     {
     462           2 :       if (sw_if_index >= vec_len (sm->instance_by_sw_if_index) ||
     463           2 :           sm->instance_by_sw_if_index[sw_if_index] == ~0)
     464             :         {
     465             :           err =
     466           0 :             clib_error_return (0,
     467             :                                "interface %U is not assigned to snort "
     468             :                                "instance!",
     469             :                                format_vnet_sw_if_index_name, vnm, sw_if_index);
     470           0 :           goto done;
     471             :         }
     472           2 :       index = sm->instance_by_sw_if_index[sw_if_index];
     473           2 :       si = vec_elt_at_index (sm->instances, index);
     474             : 
     475           2 :       sm->instance_by_sw_if_index[sw_if_index] = ~0;
     476           2 :       if (snort_dir & SNORT_INPUT)
     477             :         {
     478           2 :           fa_data = (u64) index;
     479           2 :           vnet_feature_enable_disable ("ip4-unicast", "snort-enq", sw_if_index,
     480             :                                        0, &fa_data, sizeof (fa_data));
     481             :         }
     482           2 :       if (snort_dir & SNORT_OUTPUT)
     483             :         {
     484           2 :           fa_data = (1LL << 32 | index);
     485           2 :           vnet_feature_enable_disable ("ip4-output", "snort-enq", sw_if_index,
     486             :                                        0, &fa_data, sizeof (fa_data));
     487             :         }
     488             :     }
     489             : 
     490           0 : done:
     491           4 :   if (err)
     492           0 :     log_err ("%U", format_clib_error, err);
     493           4 :   return 0;
     494             : }
     495             : 
     496             : clib_error_t *
     497           2 : snort_set_node_mode (vlib_main_t *vm, u32 mode)
     498             : {
     499             :   int i;
     500           2 :   snort_main.input_mode = mode;
     501           4 :   for (i = 0; i < vlib_get_n_threads (); i++)
     502           2 :     vlib_node_set_state (vlib_get_main_by_index (i), snort_deq_node.index,
     503             :                          mode);
     504           2 :   return 0;
     505             : }
     506             : 
     507             : static void
     508         575 : snort_set_default_socket (snort_main_t *sm, u8 *socket_name)
     509             : {
     510         575 :   if (sm->socket_name)
     511           0 :     return;
     512             : 
     513         575 :   if (!socket_name)
     514         575 :     socket_name = (u8 *) DAQ_VPP_DEFAULT_SOCKET_FILE;
     515             : 
     516         575 :   sm->socket_name =
     517         575 :     format (0, "%s/%s", vlib_unix_get_runtime_dir (), socket_name);
     518         575 :   vec_terminate_c_string (sm->socket_name);
     519             : }
     520             : 
     521             : static clib_error_t *
     522         575 : snort_init (vlib_main_t *vm)
     523             : {
     524         575 :   snort_main_t *sm = &snort_main;
     525         575 :   sm->input_mode = VLIB_NODE_STATE_INTERRUPT;
     526         575 :   sm->instance_by_name = hash_create_string (0, sizeof (uword));
     527             :   vlib_buffer_pool_t *bp;
     528             : 
     529        1150 :   vec_foreach (bp, vm->buffer_main->buffer_pools)
     530             :     {
     531             :       vlib_physmem_map_t *pm =
     532         575 :         vlib_physmem_get_map (vm, bp->physmem_map_index);
     533         575 :       vec_add1 (sm->buffer_pool_base_addrs, pm->base);
     534             :     }
     535             : 
     536         575 :   if (!sm->socket_name)
     537         575 :     snort_set_default_socket (sm, 0);
     538             : 
     539         575 :   return snort_listener_init (vm);
     540             : }
     541             : 
     542        1151 : VLIB_INIT_FUNCTION (snort_init);
     543             : 
     544             : VLIB_PLUGIN_REGISTER () = {
     545             :   .version = VPP_BUILD_VER,
     546             :   .description = "Snort",
     547             : };
     548             : 
     549       23615 : VNET_FEATURE_INIT (snort_enq, static) = {
     550             :   .arc_name = "ip4-unicast",
     551             :   .node_name = "snort-enq",
     552             :   .runs_before = VNET_FEATURES ("ip4-lookup"),
     553             : };
     554             : 
     555       23615 : VNET_FEATURE_INIT (snort_enq_out, static) = {
     556             :   .arc_name = "ip4-output",
     557             :   .node_name = "snort-enq",
     558             :   .runs_before = VNET_FEATURES ("interface-output"),
     559             : };

Generated by: LCOV version 1.14