Start the cdp period process on demand
[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 #define REPLY_MSG_ID_BASE cm->msg_id_base
51 #include <vlibapi/api_helper_macros.h>
52
53 /* List of message types that this plugin understands */
54
55 #define foreach_cdp_plugin_api_msg                           \
56 _(CDP_ENABLE_DISABLE, cdp_enable_disable)
57
58 /* Action function shared between message handler and debug CLI */
59
60 int
61 cdp_enable_disable (cdp_main_t * cm, int enable_disable)
62 {
63   int rv = 0;
64
65   if (enable_disable)
66     {
67       vnet_cdp_create_periodic_process (cm);
68       vlib_process_signal_event (cm->vlib_main, cm->cdp_process_node_index,
69                                  CDP_EVENT_ENABLE, 0);
70     }
71   else
72     {
73       vnet_cdp_create_periodic_process (cm);
74       vlib_process_signal_event (cm->vlib_main, cm->cdp_process_node_index,
75                                  CDP_EVENT_DISABLE, 0);
76     }
77   cm->enabled = enable_disable;
78
79   return rv;
80 }
81
82 static clib_error_t *
83 cdp_command_fn (vlib_main_t * vm,
84                 unformat_input_t * input, vlib_cli_command_t * cmd)
85 {
86   cdp_main_t *cm = &cdp_main;
87   int enable_disable = 1;
88
89   int rv;
90
91   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
92     {
93       if (unformat (input, "disable"))
94         enable_disable = 0;
95       else if (unformat (input, "enable"))
96         enable_disable = 1;
97       else
98         break;
99     }
100
101   rv = cdp_enable_disable (cm, enable_disable);
102
103   switch (rv)
104     {
105     case 0:
106       break;
107
108     default:
109       return clib_error_return (0, "cdp_enable_disable returned %d", rv);
110     }
111   return 0;
112 }
113
114 /* *INDENT-OFF* */
115 VLIB_CLI_COMMAND (cdp_command, static) =
116 {
117   .path = "cdp",
118   .short_help = "cdp enable | disable",
119   .function = cdp_command_fn,
120 };
121 /* *INDENT-ON* */
122
123 /* API message handler */
124 static void vl_api_cdp_enable_disable_t_handler
125   (vl_api_cdp_enable_disable_t * mp)
126 {
127   vl_api_cdp_enable_disable_reply_t *rmp;
128   cdp_main_t *cm = &cdp_main;
129   int rv;
130
131   rv = cdp_enable_disable (cm, (int) (mp->enable_disable));
132
133   REPLY_MACRO (VL_API_CDP_ENABLE_DISABLE_REPLY);
134 }
135
136 /* Set up the API message handling tables */
137 static clib_error_t *
138 cdp_plugin_api_hookup (vlib_main_t * vm)
139 {
140   cdp_main_t *cm = &cdp_main;
141 #define _(N,n)                                                  \
142     vl_msg_api_set_handlers((VL_API_##N + cm->msg_id_base),     \
143                            #n,                                  \
144                            vl_api_##n##_t_handler,              \
145                            vl_noop_handler,                     \
146                            vl_api_##n##_t_endian,               \
147                            vl_api_##n##_t_print,                \
148                            sizeof(vl_api_##n##_t), 1);
149   foreach_cdp_plugin_api_msg;
150 #undef _
151
152   return 0;
153 }
154
155 #define vl_msg_name_crc_list
156 #include <cdp/cdp_all_api_h.h>
157 #undef vl_msg_name_crc_list
158
159 static void
160 setup_message_id_table (cdp_main_t * cm, api_main_t * am)
161 {
162 #define _(id,n,crc)   vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id + cm->msg_id_base);
163   foreach_vl_msg_name_crc_cdp;
164 #undef _
165 }
166
167 static clib_error_t *
168 cdp_init (vlib_main_t * vm)
169 {
170   cdp_main_t *cm = &cdp_main;
171   clib_error_t *error = 0;
172   u8 *name;
173
174   cm->vlib_main = vm;
175
176   name = format (0, "cdp_%08x%c", api_version, 0);
177
178   /* Ask for a correctly-sized block of API message decode slots */
179   cm->msg_id_base = vl_msg_api_get_msg_ids
180     ((char *) name, VL_MSG_FIRST_AVAILABLE);
181
182   error = cdp_plugin_api_hookup (vm);
183
184   /* Add our API messages to the global name_crc hash table */
185   setup_message_id_table (cm, &api_main);
186
187   vec_free (name);
188
189   return error;
190 }
191
192 VLIB_INIT_FUNCTION (cdp_init);
193
194 /* *INDENT-OFF* */
195 VLIB_PLUGIN_REGISTER () =
196 {
197   .version = VPP_BUILD_VER,
198   .description = "Cisco Discovery Protocol (CDP)",
199 };
200 /* *INDENT-ON* */
201
202 /*
203  * fd.io coding-style-patch-verification: ON
204  *
205  * Local Variables:
206  * eval: (c-set-style "gnu")
207  * End:
208  */