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:
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
15 #ifndef __included_vnet_bonding_node_h__
16 #define __included_vnet_bonding_node_h__
18 #include <vlib/vlib.h>
19 #include <vlib/unix/unix.h>
20 #include <vppinfra/format.h>
21 #include <vppinfra/hash.h>
22 #include <vnet/ethernet/ethernet.h>
23 #include <vnet/interface.h>
25 #define LACP_FAST_PERIODIC_TIMER 1.0
26 #define LACP_SHORT_TIMOUT_TIME (LACP_FAST_PERIODIC_TIMER * 3)
27 #define LACP_SLOW_PERIODIC_TIMER 30.0
28 #define LACP_LONG_TIMOUT_TIME (LACP_SLOW_PERIODIC_TIMER * 3)
31 #define MIN(x,y) (((x)<(y))?(x):(y))
34 #define foreach_bond_mode \
35 _ (1, ROUND_ROBIN, "round-robin") \
36 _ (2, ACTIVE_BACKUP, "active-backup") \
38 _ (4, BROADCAST, "broadcast") \
43 #define _(v, f, s) BOND_MODE_##f = v,
48 /* configurable load-balances */
49 #define foreach_bond_lb \
50 _ (2, L23, "l23", l23) \
51 _ (1, l34 , "l34", l34) \
54 /* load-balance functions implemented in bond-output */
55 #define foreach_bond_lb_algo \
57 _ (1, l34 , "l34", l34) \
58 _ (2, L23, "l23", l23) \
59 _ (3, RR, "round-robin", round_robin) \
60 _ (4, BC, "broadcast", broadcast) \
61 _ (5, AB, "active-backup", active_backup)
65 #define _(v, f, s, p) BOND_LB_##f = v,
68 } bond_load_balance_t;
80 } bond_create_if_args_t;
84 /* slave's sw_if_index */
86 /* bond's sw_if_index */
93 } bond_enslave_args_t;
101 } bond_detach_slave_args_t;
103 /** BOND interface details struct */
107 u8 interface_name[64];
112 } bond_interface_details_t;
114 /** slave interface details struct */
118 u8 interface_name[64];
122 } slave_interface_details_t;
124 typedef CLIB_PACKED (struct
128 u16 key; u16 port_priority; u16 port_number;
138 /* the last slave index for the rr lb */
139 u32 lb_rr_last_index;
145 /* Configured slaves */
148 /* Slaves that are in DISTRIBUTING state */
151 /* rapidly find an active slave */
152 uword *active_slave_by_sw_if_index;
154 lacp_port_info_t partner;
155 lacp_port_info_t actor;
156 u8 individual_aggregator;
159 uword *port_number_bitmap;
166 u8 persistent_hw_address[6];
168 /* neighbor's vlib software interface index */
171 /* Neighbor time-to-live (usually 3s) */
174 /* 1 = interface is configured with long timeout (60s) */
177 /* 1 = debug is on; 0 = debug is off */
180 /* tx packet template id for this neighbor */
181 u8 packet_template_index;
183 /* Info we actually keep about each neighbor */
185 /* Jenkins hash optimization: avoid tlv scan, send short keepalive msg */
186 u8 last_packet_signature_valid;
187 uword last_packet_signature;
189 /* last received lacp packet, for the J-hash optimization */
192 /* last marker packet */
195 /* neighbor vlib hw_if_index */
198 /* actor does not initiate the protocol exchange */
201 /* Partner port information */
202 lacp_port_info_t partner;
203 lacp_port_info_t partner_admin;;
205 /* Partner port information */
206 lacp_port_info_t actor;
207 lacp_port_info_t actor_admin;
209 /* Need To Transmit flag */
212 /* Link has been established and Aggregate Port is operable */
215 /* Initialization or reinitialization of the lacp protocol entity */
218 /* Aggregation Port is operating the lacp */
221 /* MUX to indicate to the Selection Logic wait_while_timer expired */
224 /* Selection Logic indicates al Aggregation Ports attached */
227 /* Selection Logic selected an Aggregator */
230 /* RX machine indicates an Aggregation Port in PORT_DISABLED state */
233 /* timer used to detect whether received protocol information has expired */
234 f64 current_while_timer;
236 /* timer used to detect actor churn states */
237 f64 actor_churn_timer;
239 /* time last lacpdu was sent */
240 f64 last_lacpdu_time;
242 /* timer used to generate periodic transmission */
245 /* timer used to detect partner churn states */
246 f64 partner_churn_timer;
248 /* provides hysteresis before performing an aggregation change */
249 f64 wait_while_timer;
251 /* Implemention variables, not in the spec */
257 /* actor admin key */
262 u32 bif_dev_instance;
269 clib_spinlock_t lockp;
272 typedef void (*lacp_enable_disable_func) (vlib_main_t * vm, bond_if_t * bif,
273 slave_if_t * sif, u8 enable);
277 /* pool of bonding interfaces */
278 bond_if_t *interfaces;
280 /* pool of lacp neighbors */
281 slave_if_t *neighbors;
283 /* rapidly find a neighbor by vlib software interface index */
284 uword *neighbor_by_sw_if_index;
286 /* rapidly find a bond by vlib software interface index */
287 uword *bond_by_sw_if_index;
289 /* convenience variables */
290 vlib_main_t *vlib_main;
291 vnet_main_t *vnet_main;
293 /* lacp plugin is loaded */
294 u8 lacp_plugin_loaded;
296 lacp_enable_disable_func lacp_enable_disable;
299 /* bond packet trace capture */
302 ethernet_header_t ethernet;
304 u32 bond_sw_if_index;
305 } bond_packet_trace_t;
307 typedef u32 (*load_balance_func) (vlib_main_t * vm,
308 vlib_node_runtime_t * node, bond_if_t * bif,
313 load_balance_func load_balance;
314 } bond_load_balance_func_t;
316 extern vlib_node_registration_t bond_input_node;
317 extern vnet_device_class_t bond_dev_class;
318 extern bond_main_t bond_main;
320 void bond_disable_collecting_distributing (vlib_main_t * vm,
322 void bond_enable_collecting_distributing (vlib_main_t * vm, slave_if_t * sif);
323 u8 *format_bond_interface_name (u8 * s, va_list * args);
325 void bond_create_if (vlib_main_t * vm, bond_create_if_args_t * args);
326 int bond_delete_if (vlib_main_t * vm, u32 sw_if_index);
327 void bond_enslave (vlib_main_t * vm, bond_enslave_args_t * args);
328 void bond_detach_slave (vlib_main_t * vm, bond_detach_slave_args_t * args);
329 int bond_dump_ifs (bond_interface_details_t ** out_bondids);
330 int bond_dump_slave_ifs (slave_interface_details_t ** out_slaveids,
331 u32 bond_sw_if_index);
334 unformat_bond_mode (unformat_input_t * input, va_list * args)
336 u8 *r = va_arg (*args, u8 *);
339 #define _(v, f, s) else if (unformat (input, s)) *r = BOND_MODE_##f;
349 format_bond_mode (u8 * s, va_list * args)
351 u32 i = va_arg (*args, u32);
356 #define _(v, f, s) case BOND_MODE_##f: t = (u8 *) s; break;
360 return format (s, "unknown");
362 return format (s, "%s", t);
366 unformat_bond_load_balance (unformat_input_t * input, va_list * args)
368 u8 *r = va_arg (*args, u8 *);
371 #define _(v, f, s, p) else if (unformat (input, s)) *r = BOND_LB_##f;
381 format_bond_load_balance (u8 * s, va_list * args)
383 u32 i = va_arg (*args, u32);
388 #define _(v, f, s, p) case BOND_LB_##f: t = (u8 *) s; break;
392 return format (s, "unknown");
394 return format (s, "%s", t);
398 bond_register_callback (lacp_enable_disable_func func)
400 bond_main_t *bm = &bond_main;
402 bm->lacp_plugin_loaded = 1;
403 bm->lacp_enable_disable = func;
406 static inline bond_if_t *
407 bond_get_master_by_sw_if_index (u32 sw_if_index)
409 bond_main_t *bm = &bond_main;
412 p = hash_get (bm->bond_by_sw_if_index, sw_if_index);
417 return pool_elt_at_index (bm->interfaces, p[0]);
420 static inline bond_if_t *
421 bond_get_master_by_dev_instance (u32 dev_instance)
423 bond_main_t *bm = &bond_main;
425 return pool_elt_at_index (bm->interfaces, dev_instance);
428 static inline slave_if_t *
429 bond_get_slave_by_sw_if_index (u32 sw_if_index)
431 bond_main_t *bm = &bond_main;
435 p = hash_get (bm->neighbor_by_sw_if_index, sw_if_index);
438 sif = pool_elt_at_index (bm->neighbors, p[0]);
443 #endif /* __included_vnet_bonding_node_h__ */
446 * fd.io coding-style-patch-verification: ON
449 * eval: (c-set-style "gnu")