aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/cdp/cdp_test.c
blob: 33b54498f7f891066306794cca1b001ddafce1e3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/*
 * cdp.c - vpp-api-test cdp protocol plug-in
 *
 * Copyright (c) 2011-2018 by Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <vat/vat.h>
#include <vlibapi/api.h>
#include <vlibmemory/api.h>
#include <vppinfra/error.h>

uword unformat_sw_if_index (unformat_input_t * input, va_list * args);

/* Declare message IDs */
#include <cdp/cdp_msg_enum.h>

/* define message structures */
#define vl_typedefs
#include <cdp/cdp_all_api_h.h>
#undef vl_typedefs

/* declare message handlers for each api */

#define vl_endianfun		/* define message structures */
#include <cdp/cdp_all_api_h.h>
#undef vl_endianfun

/* instantiate all the print functions we know about */
#define vl_print(handle, ...)
#define vl_printfun
#include <cdp/cdp_all_api_h.h>
#undef vl_printfun

/* Get the API version number. */
#define vl_api_version(n,v) static u32 api_version=(v);
#include <cdp/cdp_all_api_h.h>
#undef vl_api_version


typedef struct
{
  /* API message ID base */
  u16 msg_id_base;
  vat_main_t *vat_main;
} cdp_test_main_t;

cdp_test_main_t cdp_test_main;

#define __plugin_msg_base cdp_test_main.msg_id_base
#include <vlibapi/vat_helper_macros.h>

#define foreach_standard_reply_retval_handler   \
_(cdp_enable_disable_reply)

#define _(n)                                            \
    static void vl_api_##n##_t_handler                  \
    (vl_api_##n##_t * mp)                               \
    {                                                   \
        vat_main_t * vam = cdp_test_main.vat_main;   \
        i32 retval = ntohl(mp->retval);                 \
        if (vam->async_mode) {                          \
            vam->async_errors += (retval < 0);          \
        } else {                                        \
            vam->retval = retval;                       \
            vam->result_ready = 1;                      \
        }                                               \
    }
foreach_standard_reply_retval_handler;
#undef _

/*
 * Table of message reply handlers, must include boilerplate handlers
 * we just generated
 */
#define foreach_vpe_api_reply_msg                                       \
_(CDP_ENABLE_DISABLE_REPLY, cdp_enable_disable_reply)

static int
api_cdp_enable_disable (vat_main_t * vam)
{
  unformat_input_t *i = vam->input;
  int enable_disable = 1;
  vl_api_cdp_enable_disable_t *mp;
  int ret;

  /* Parse args required to build the message */
  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (i, "disable"))
	enable_disable = 0;
      else if (unformat (i, "enable"))
	enable_disable = 1;
      else
	break;
    }

  /* Construct the API message */
  M (CDP_ENABLE_DISABLE, mp);
  mp->enable_disable = enable_disable;

  /* send it... */
  S (mp);

  /* Wait for a reply... */
  W (ret);
  return ret;
}

/*
 * List of messages that the api test plugin sends,
 * and that the data plane plugin processes
 */
#define foreach_vpe_api_msg \
_(cdp_enable_disable, "enable | disable")

static void
cdp_api_hookup (vat_main_t * vam)
{
  cdp_test_main_t *sm = &cdp_test_main;
  /* Hook up handlers for replies from the data plane plug-in */
#define _(N,n)                                                  \
    vl_msg_api_set_handlers((VL_API_##N + sm->msg_id_base),     \
                           #n,                                  \
                           vl_api_##n##_t_handler,              \
                           vl_noop_handler,                     \
                           vl_api_##n##_t_endian,               \
                           vl_api_##n##_t_print,                \
                           sizeof(vl_api_##n##_t), 1);
  foreach_vpe_api_reply_msg;
#undef _

  /* API messages we can send */
#define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
  foreach_vpe_api_msg;
#undef _

  /* Help strings */
#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
  foreach_vpe_api_msg;
#undef _
}

clib_error_t *
vat_plugin_register (vat_main_t * vam)
{
  cdp_test_main_t *sm = &cdp_test_main;
  u8 *name;

  sm->vat_main = vam;

  /* Ask the vpp engine for the first assigned message-id */
  name = format (0, "cdp_%08x%c", api_version, 0);
  sm->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name);

  if (sm->msg_id_base != (u16) ~ 0)
    cdp_api_hookup (vam);

  vec_free (name);

  return 0;
}

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
e_size); int vl_client_connect_to_vlib_no_rx_pthread (const char *svm_name, const char *client_name, int rx_queue_size); int vl_client_connect_to_vlib_no_map (const char *svm_name, const char *client_name, int rx_queue_size); u16 vl_client_get_first_plugin_msg_id (const char *plugin_name); void vl_api_rpc_call_main_thread (void *fp, u8 * data, u32 data_length); u32 vl_api_memclnt_create_internal (char *, unix_shared_memory_queue_t *); void vl_init_shmem (svm_region_t * vlib_rp, int is_vlib, int is_private_region); void vl_client_install_client_message_handlers (void); /* API messages over sockets */ extern vlib_node_registration_t memclnt_node; extern volatile int **vl_api_queue_cursizes; /* Events sent to the memclnt process */ #define QUEUE_SIGNAL_EVENT 1 #define SOCKET_READ_EVENT 2 #define API_SOCKET_FILE "/run/vpp-api.sock" typedef struct { clib_file_t *clib_file; vl_api_registration_t *regp; u8 *data; } vl_socket_args_for_process_t; typedef struct { /* Server port number */ u8 *socket_name; /* By default, localhost... */ u32 bind_address; /* * (listen, server, client) registrations. Shared memory * registrations are in shared memory */ vl_api_registration_t *registration_pool; /* * Chain-drag variables, so message API handlers * (generally) don't know whether they're talking to a socket * or to a shared-memory connection. */ vl_api_registration_t *current_rp; clib_file_t *current_uf; /* One input buffer, shared across all sockets */ i8 *input_buffer; /* pool of process args for socket clients */ vl_socket_args_for_process_t *process_args; /* Listen for API connections here */ clib_socket_t socksvr_listen_socket; } socket_main_t; extern socket_main_t socket_main; typedef struct { int socket_fd; /* Temporarily disable the connection, so we can keep it around... */ int socket_enable; clib_socket_t client_socket; u32 socket_buffer_size; u8 *socket_tx_buffer; u8 *socket_rx_buffer; u32 socket_tx_nbytes; int control_pings_outstanding; } socket_client_main_t; extern socket_client_main_t socket_client_main; #define SOCKET_CLIENT_DEFAULT_BUFFER_SIZE 4096 void socksvr_add_pending_output (struct clib_file *uf, struct vl_api_registration_ *cf, u8 * buffer, uword buffer_bytes); void vl_free_socket_registration_index (u32 pool_index); void vl_socket_process_msg (struct clib_file *uf, struct vl_api_registration_ *rp, i8 * input_v); clib_error_t *vl_socket_read_ready (struct clib_file *uf); void vl_socket_add_pending_output (struct clib_file *uf, struct vl_api_registration_ *rp, u8 * buffer, uword buffer_bytes); void vl_socket_add_pending_output_no_flush (struct clib_file *uf, struct vl_api_registration_ *rp, u8 * buffer, uword buffer_bytes); clib_error_t *vl_socket_write_ready (struct clib_file *uf); void vl_socket_api_send (vl_api_registration_t * rp, u8 * elem); u32 sockclnt_open_index (char *client_name, char *hostname, int port); void sockclnt_close_index (u32 index); void vl_client_msg_api_send (vl_api_registration_t * cm, u8 * elem); vl_api_registration_t *sockclnt_get_registration (u32 index); void vl_api_socket_process_msg (clib_file_t * uf, vl_api_registration_t * rp, i8 * input_v); int vl_socket_client_connect (socket_client_main_t * scm, char *socket_path, char *client_name, u32 socket_buffer_size); void vl_socket_client_read_reply (socket_client_main_t * scm); void vl_socket_client_enable_disable (socket_client_main_t * scm, int enable); #endif /* included_vlibmemory_api_common_h */ /* * fd.io coding-style-patch-verification: ON * * Local Variables: * eval: (c-set-style "gnu") * End: */