vom: Add support for redirect contracts in gbp
[vpp.git] / src / plugins / cdp / cdp.c
1 /*
2  * cdp.c - cdp protocol plug-in
3  *
4  * Copyright (c) 2011-2018 by Cisco and/or its affiliates.
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include <vnet/vnet.h>
19 #include <vnet/plugin/plugin.h>
20 #include <cdp/cdp.h>
21
22 #include <vlibapi/api.h>
23 #include <vlibmemory/api.h>
24 #include <vpp/app/version.h>
25
26 /* define message IDs */
27 #include <cdp/cdp_msg_enum.h>
28
29 /* define message structures */
30 #define vl_typedefs
31 #include <cdp/cdp_all_api_h.h>
32 #undef vl_typedefs
33
34 /* define generated endian-swappers */
35 #define vl_endianfun
36 #include <cdp/cdp_all_api_h.h>
37 #undef vl_endianfun
38
39 /* instantiate all the print functions we know about */
40 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
41 #define vl_printfun
42 #include <cdp/cdp_all_api_h.h>
43 #undef vl_printfun
44
45 /* Get the API version number */
46 #define vl_api_version(n,v) static u32 api_version=(v);
47 #include <cdp/cdp_all_api_h.h>
48 #undef vl_api_version
49
50 /*
51  * A handy macro to set up a message reply.
52  * Assumes that the following variables are available:
53  * mp - pointer to request message
54  * rmp - pointer to reply message type
55  * rv - return value
56  */
57
58 #define REPLY_MACRO(t)                                          \
59 do {                                                            \
60     unix_shared_memory_queue_t * q =                            \
61     vl_api_client_index_to_input_queue (mp->client_index);      \
62     if (!q)                                                     \
63         return;                                                 \
64                                                                 \
65     rmp = vl_msg_api_alloc (sizeof (*rmp));                     \
66     rmp->_vl_msg_id = ntohs((t)+cm->msg_id_base);               \
67     rmp->context = mp->context;                                 \
68     rmp->retval = ntohl(rv);                                    \
69                                                                 \
70     vl_msg_api_send_shmem (q, (u8 *)&rmp);                      \
71 } while(0);
72
73
74 /* List of message types that this plugin understands */
75
76 #define foreach_cdp_plugin_api_msg                           \
77 _(CDP_ENABLE_DISABLE, cdp_enable_disable)
78
79 /* Action function shared between message handler and debug CLI */
80
81 int
82 cdp_enable_disable (cdp_main_t * cm, int enable_disable)
83 {
84   int rv = 0;
85
86   if (enable_disable)
87     vlib_process_signal_event (cm->vlib_main, cdp_process_node.index,
88                                CDP_EVENT_ENABLE, 0);
89   else
90     vlib_process_signal_event (cm->vlib_main, cdp_process_node.index,
91                                CDP_EVENT_DISABLE, 0);
92   cm->enabled = enable_disable;
93
94   return rv;
95 }
96
97 static clib_error_t *
98 cdp_command_fn (vlib_main_t * vm,
99                 unformat_input_t * input, vlib_cli_command_t * cmd)
100 {
101   cdp_main_t *cm = &cdp_main;
102   int enable_disable = 1;
103
104   int rv;
105
106   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
107     {
108       if (unformat (input, "disable"))
109         enable_disable = 0;
110       else if (unformat (input, "enable"))
111         enable_disable = 1;
112       else
113         break;
114     }
115
116   rv = cdp_enable_disable (cm, enable_disable);
117
118   switch (rv)
119     {
120     case 0:
121       break;
122
123     default:
124       return clib_error_return (0, "cdp_enable_disable returned %d", rv);
125     }
126   return 0;
127 }
128
129 /* *INDENT-OFF* */
130 VLIB_CLI_COMMAND (cdp_command, static) =
131 {
132   .path = "cdp",
133   .short_help = "cdp enable | disable",
134   .function = cdp_command_fn,
135 };
136 /* *INDENT-ON* */
137
138 /* API message handler */
139 static void vl_api_cdp_enable_disable_t_handler
140   (vl_api_cdp_enable_disable_t * mp)
141 {
142   vl_api_cdp_enable_disable_reply_t *rmp;
143   cdp_main_t *cm = &cdp_main;
144   int rv;
145
146   rv = cdp_enable_disable (cm, (int) (mp->enable_disable));
147
148   REPLY_MACRO (VL_API_CDP_ENABLE_DISABLE_REPLY);
149 }
150
151 /* Set up the API message handling tables */
152 static clib_error_t *
153 cdp_plugin_api_hookup (vlib_main_t * vm)
154 {
155   cdp_main_t *cm = &cdp_main;
156 #define _(N,n)                                                  \
157     vl_msg_api_set_handlers((VL_API_##N + cm->msg_id_base),     \
158                            #n,                                  \
159                            vl_api_##n##_t_handler,              \
160                            vl_noop_handler,                     \
161                            vl_api_##n##_t_endian,               \
162                            vl_api_##n##_t_print,                \
163                            sizeof(vl_api_##n##_t), 1);
164   foreach_cdp_plugin_api_msg;
165 #undef _
166
167   return 0;
168 }
169
170 #define vl_msg_name_crc_list
171 #include <cdp/cdp_all_api_h.h>
172 #undef vl_msg_name_crc_list
173
174 static void
175 setup_message_id_table (cdp_main_t * cm, api_main_t * am)
176 {
177 #define _(id,n,crc)   vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id + cm->msg_id_base);
178   foreach_vl_msg_name_crc_cdp;
179 #undef _
180 }
181
182 static clib_error_t *
183 cdp_init (vlib_main_t * vm)
184 {
185   cdp_main_t *cm = &cdp_main;
186   clib_error_t *error = 0;
187   u8 *name;
188
189   cm->vlib_main = vm;
190
191   name = format (0, "cdp_%08x%c", api_version, 0);
192
193   /* Ask for a correctly-sized block of API message decode slots */
194   cm->msg_id_base = vl_msg_api_get_msg_ids
195     ((char *) name, VL_MSG_FIRST_AVAILABLE);
196
197   error = cdp_plugin_api_hookup (vm);
198
199   /* Add our API messages to the global name_crc hash table */
200   setup_message_id_table (cm, &api_main);
201
202   vec_free (name);
203
204   return error;
205 }
206
207 VLIB_INIT_FUNCTION (cdp_init);
208
209 /* *INDENT-OFF* */
210 VLIB_PLUGIN_REGISTER () =
211 {
212   .version = VPP_BUILD_VER,
213 };
214 /* *INDENT-ON* */
215
216 /*
217  * fd.io coding-style-patch-verification: ON
218  *
219  * Local Variables:
220  * eval: (c-set-style "gnu")
221  * End:
222  */