Line data Source code
1 : /*
2 : * Copyright (c) 2017 Cisco and/or its affiliates.
3 : * Licensed under the Apache License, Version 2.0 (the "License");
4 : * you may not use this file except in compliance with the License.
5 : * You may obtain a copy of the License at:
6 : *
7 : * http://www.apache.org/licenses/LICENSE-2.0
8 : *
9 : * Unless required by applicable law or agreed to in writing, software
10 : * distributed under the License is distributed on an "AS IS" BASIS,
11 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : * See the License for the specific language governing permissions and
13 : * limitations under the License.
14 : */
15 : #ifndef __included_lacp_node_h__
16 : #define __included_lacp_node_h__
17 :
18 : #include <vlib/vlib.h>
19 : #include <vlib/unix/unix.h>
20 : #include <vppinfra/format.h>
21 : #include <vppinfra/hash.h>
22 : #include <lacp/protocol.h>
23 : #include <lacp/rx_machine.h>
24 : #include <lacp/tx_machine.h>
25 : #include <lacp/mux_machine.h>
26 : #include <lacp/ptx_machine.h>
27 :
28 : typedef enum
29 : {
30 : LACP_PACKET_TEMPLATE_ETHERNET,
31 : LACP_N_PACKET_TEMPLATES,
32 : } lacp_packet_template_id_t;
33 :
34 : typedef enum
35 : {
36 : MARKER_PACKET_TEMPLATE_ETHERNET,
37 : MARKER_N_PACKET_TEMPLATES,
38 : } marker_packet_template_id_t;
39 :
40 : typedef enum
41 : {
42 : LACP_PROCESS_EVENT_START = 1,
43 : LACP_PROCESS_EVENT_STOP = 2,
44 : } lacp_process_event_t;
45 :
46 : #define LACP_DBG(n, args...) \
47 : { \
48 : lacp_main_t *_lm = &lacp_main; \
49 : if (_lm->debug || n->debug) \
50 : clib_warning (args); \
51 : }
52 :
53 : #define LACP_DBG2(n, e, s, m, t) \
54 : { \
55 : lacp_main_t *_lm = &lacp_main; \
56 : if ((m)->debug && (_lm->debug || (n)->debug)) \
57 : (*m->debug)(n, e, s, t); \
58 : }
59 :
60 : /* Packet counters */
61 : #define foreach_lacp_error \
62 : _ (NONE, "good lacp packets -- consumed") \
63 : _ (CACHE_HIT, "good lacp packets -- cache hit") \
64 : _ (UNSUPPORTED, "unsupported slow protocol packets") \
65 : _ (TOO_SMALL, "bad lacp packets -- packet too small") \
66 : _ (BAD_TLV, "bad lacp packets -- bad TLV length") \
67 : _ (BAD_KEY, "Bad key") \
68 : _ (LOOPBACK_PORT, "loopback port") \
69 : _ (DISABLED, "lacp packets received on disabled interfaces")
70 :
71 : typedef enum
72 : {
73 : #define _(sym,str) LACP_ERROR_##sym,
74 : foreach_lacp_error
75 : #undef _
76 : LACP_N_ERROR,
77 : } lacp_error_t;
78 :
79 : #define SECS_IN_A_DAY 86400.0
80 :
81 : /* lacp packet trace capture */
82 : typedef struct
83 : {
84 : u32 sw_if_index;
85 : u32 len;
86 : union
87 : {
88 : marker_pdu_t marker;
89 : lacp_pdu_t lacpdu;
90 : } pkt;
91 : } lacp_input_trace_t;
92 :
93 : /** LACP interface details struct */
94 : typedef struct
95 : {
96 : u32 sw_if_index;
97 : u8 interface_name[64];
98 : u32 rx_state;
99 : u32 tx_state;
100 : u32 mux_state;
101 : u32 ptx_state;
102 : u8 bond_interface_name[64];
103 : u16 actor_system_priority;
104 : u8 actor_system[6];
105 : u16 actor_key;
106 : u16 actor_port_priority;
107 : u16 actor_port_number;
108 : u8 actor_state;
109 : u16 partner_system_priority;
110 : u8 partner_system[6];
111 : u16 partner_key;
112 : u16 partner_port_priority;
113 : u16 partner_port_number;
114 : u8 partner_state;
115 : } lacp_interface_details_t;
116 :
117 : typedef struct
118 : {
119 : /** API message ID base */
120 : u16 msg_id_base;
121 :
122 : /* convenience variables */
123 : vlib_main_t *vlib_main;
124 : vnet_main_t *vnet_main;
125 :
126 : /* Background process node index */
127 : u32 lacp_process_node_index;
128 :
129 : /* Packet templates for different encap types */
130 : vlib_packet_template_t packet_templates[LACP_N_PACKET_TEMPLATES];
131 :
132 : /* Packet templates for different encap types */
133 : vlib_packet_template_t marker_packet_templates[MARKER_N_PACKET_TEMPLATES];
134 :
135 : /* LACP interface count */
136 : volatile u32 lacp_int;
137 :
138 : /* debug is on or off */
139 : u8 debug;
140 : } lacp_main_t;
141 :
142 : extern lacp_state_struct lacp_state_array[];
143 : extern lacp_main_t lacp_main;
144 :
145 : void lacp_create_periodic_process (void);
146 : clib_error_t *lacp_plugin_api_hookup (vlib_main_t * vm);
147 : int lacp_dump_ifs (lacp_interface_details_t ** out_bondids);
148 : lacp_error_t lacp_input (vlib_main_t * vm, vlib_buffer_t * b0, u32 bi0);
149 : void lacp_periodic (vlib_main_t * vm);
150 : u8 *lacp_input_format_trace (u8 * s, va_list * args);
151 : void lacp_init_neighbor (member_if_t * mif, u8 * hw_address,
152 : u16 port_number, u32 group);
153 : void lacp_init_state_machines (vlib_main_t * vm, member_if_t * mif);
154 : void lacp_init_rx_machine (vlib_main_t * vm, member_if_t * mif);
155 : void lacp_init_tx_machine (vlib_main_t * vm, member_if_t * mif);
156 : void lacp_init_ptx_machine (vlib_main_t * vm, member_if_t * mif);
157 : void lacp_init_mux_machine (vlib_main_t * vm, member_if_t * mif);
158 : int lacp_selection_logic (vlib_main_t *vm, member_if_t *mif);
159 : void lacp_send_lacp_pdu (vlib_main_t * vm, member_if_t * mif);
160 :
161 : static inline void
162 114 : lacp_stop_timer (f64 * timer)
163 : {
164 114 : *timer = 0.0;
165 114 : }
166 :
167 : static inline u8
168 297 : lacp_timer_is_running (f64 timer)
169 : {
170 297 : return (timer != 0.0);
171 : }
172 :
173 : static inline u8
174 177 : lacp_timer_is_expired (vlib_main_t * vm, f64 timer)
175 : {
176 177 : f64 now = vlib_time_now (vm);
177 :
178 177 : return (now >= timer);
179 : }
180 :
181 : static inline u8 *
182 68 : format_rx_sm_state (u8 * s, va_list * args)
183 : {
184 68 : lacp_state_struct lacp_rx_sm_state_array[] = {
185 : #define _(b, s, n) {.bit = b, .str = #s, },
186 : foreach_lacp_rx_sm_state
187 : #undef _
188 : {.str = NULL}
189 : };
190 68 : int state = va_arg (*args, int);
191 68 : lacp_state_struct *state_entry = lacp_rx_sm_state_array;
192 :
193 68 : if (state >= (sizeof (lacp_rx_sm_state_array) / sizeof (*state_entry)))
194 0 : s = format (s, "Bad state %d", state);
195 : else
196 68 : s = format (s, "%s", state_entry[state].str);
197 :
198 68 : return s;
199 : }
200 :
201 : static inline u8 *
202 68 : format_tx_sm_state (u8 * s, va_list * args)
203 : {
204 68 : lacp_state_struct lacp_tx_sm_state_array[] = {
205 : #define _(b, s, n) {.bit = b, .str = #s, },
206 : foreach_lacp_tx_sm_state
207 : #undef _
208 : {.str = NULL}
209 : };
210 68 : int state = va_arg (*args, int);
211 68 : lacp_state_struct *state_entry = lacp_tx_sm_state_array;
212 :
213 68 : if (state >= (sizeof (lacp_tx_sm_state_array) / sizeof (*state_entry)))
214 0 : s = format (s, "Bad state %d", state);
215 : else
216 68 : s = format (s, "%s", state_entry[state].str);
217 :
218 68 : return s;
219 : }
220 :
221 : static inline u8 *
222 78 : format_mux_sm_state (u8 * s, va_list * args)
223 : {
224 78 : lacp_state_struct lacp_mux_sm_state_array[] = {
225 : #define _(b, s, n) {.bit = b, .str = #s, },
226 : foreach_lacp_mux_sm_state
227 : #undef _
228 : {.str = NULL}
229 : };
230 78 : int state = va_arg (*args, int);
231 78 : lacp_state_struct *state_entry = lacp_mux_sm_state_array;
232 :
233 78 : if (state >= (sizeof (lacp_mux_sm_state_array) / sizeof (*state_entry)))
234 0 : s = format (s, "Bad state %d", state);
235 : else
236 78 : s = format (s, "%s", state_entry[state].str);
237 :
238 78 : return s;
239 : }
240 :
241 : static inline u8 *
242 148 : format_ptx_sm_state (u8 * s, va_list * args)
243 : {
244 148 : lacp_state_struct lacp_ptx_sm_state_array[] = {
245 : #define _(b, s, n) {.bit = b, .str = #s, },
246 : foreach_lacp_ptx_sm_state
247 : #undef _
248 : {.str = NULL}
249 : };
250 148 : int state = va_arg (*args, int);
251 148 : lacp_state_struct *state_entry = lacp_ptx_sm_state_array;
252 :
253 148 : if (state >= (sizeof (lacp_ptx_sm_state_array) / sizeof (*state_entry)))
254 0 : s = format (s, "Bad state %d", state);
255 : else
256 148 : s = format (s, "%s", state_entry[state].str);
257 :
258 148 : return s;
259 : }
260 :
261 : static inline int
262 64 : lacp_bit_test (u8 val, u8 bit)
263 : {
264 64 : if (val & (1 << bit))
265 48 : return 1;
266 : else
267 16 : return 0;
268 : }
269 :
270 : #endif /* __included_lacp_node_h__ */
271 :
272 : /*
273 : * fd.io coding-style-patch-verification: ON
274 : *
275 : * Local Variables:
276 : * eval: (c-set-style "gnu")
277 : * End:
278 : */
|