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 :
16 : #define _GNU_SOURCE
17 :
18 : #include <vnet/bonding/node.h>
19 : #include <lacp/node.h>
20 :
21 : /*
22 : * LACP State = TRANSMIT
23 : */
24 : static lacp_fsm_state_t lacp_tx_state_transmit[] = {
25 : {LACP_ACTION_TRANSMIT, LACP_TX_STATE_TRANSMIT}, // event 0 BEGIN
26 : {LACP_ACTION_TRANSMIT, LACP_TX_STATE_TRANSMIT}, // event 1 NTT
27 : };
28 :
29 : static lacp_fsm_machine_t lacp_tx_fsm_table[] = {
30 : {lacp_tx_state_transmit},
31 : };
32 :
33 : lacp_machine_t lacp_tx_machine = {
34 : lacp_tx_fsm_table,
35 : lacp_tx_debug_func,
36 : };
37 :
38 : int
39 44 : lacp_tx_action_transmit (void *p1, void *p2)
40 : {
41 44 : vlib_main_t *vm = p1;
42 44 : member_if_t *mif = p2;
43 44 : f64 now = vlib_time_now (vm);
44 :
45 44 : if (!lacp_timer_is_running (mif->periodic_timer))
46 11 : return 0;
47 :
48 : // No more than 3 LACPDUs per fast interval
49 33 : if (now <= (mif->last_lacpdu_sent_time + 0.333))
50 5 : return 0;
51 :
52 28 : if (mif->ntt)
53 : {
54 28 : lacp_send_lacp_pdu (vm, mif);
55 28 : lacp_schedule_periodic_timer (vm, mif);
56 : }
57 28 : mif->ntt = 0;
58 :
59 28 : return 0;
60 : }
61 :
62 : static u8 *
63 30 : format_tx_event (u8 * s, va_list * args)
64 : {
65 : static lacp_event_struct lacp_tx_event_array[] = {
66 : #define _(b, s, n) {.bit = b, .str = #s, },
67 : foreach_lacp_tx_event
68 : #undef _
69 : {.str = NULL}
70 : };
71 30 : int e = va_arg (*args, int);
72 30 : lacp_event_struct *event_entry = lacp_tx_event_array;
73 :
74 30 : if (e >= (sizeof (lacp_tx_event_array) / sizeof (*event_entry)))
75 0 : s = format (s, "Bad event %d", e);
76 : else
77 30 : s = format (s, "%s", event_entry[e].str);
78 :
79 30 : return s;
80 : }
81 :
82 : void
83 30 : lacp_tx_debug_func (member_if_t * mif, int event, int state,
84 : lacp_fsm_state_t * transition)
85 : {
86 30 : vlib_worker_thread_t *w = vlib_worker_threads + os_get_thread_index ();
87 : /* *INDENT-OFF* */
88 : ELOG_TYPE_DECLARE (e) =
89 : {
90 : .format = "%s",
91 : .format_args = "T4",
92 : };
93 : /* *INDENT-ON* */
94 : struct
95 : {
96 : u32 event;
97 30 : } *ed = 0;
98 :
99 30 : ed = ELOG_TRACK_DATA (&vlib_global_main.elog_main, e, w->elog_track);
100 30 : ed->event = elog_string (&vlib_global_main.elog_main, "%U-TX: %U, %U->%U%c",
101 : format_vnet_sw_if_index_name, vnet_get_main (),
102 : mif->sw_if_index, format_tx_event, event,
103 : format_tx_sm_state, state, format_tx_sm_state,
104 : transition->next_state, 0);
105 30 : }
106 :
107 : void
108 11 : lacp_init_tx_machine (vlib_main_t * vm, member_if_t * mif)
109 : {
110 11 : lacp_machine_dispatch (&lacp_tx_machine, vm, mif, LACP_TX_EVENT_BEGIN,
111 : &mif->tx_state);
112 11 : }
113 :
114 : /*
115 : * fd.io coding-style-patch-verification: ON
116 : *
117 : * Local Variables:
118 : * eval: (c-set-style "gnu")
119 : * End:
120 : */
|