Line data Source code
1 : /*
2 : * Copyright (c) 2019 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 : #include <stdio.h>
17 : #include <signal.h>
18 :
19 : #include <hs_apps/sapi/vpp_echo_common.h>
20 :
21 : static void
22 0 : udp_echo_cleanup_cb (echo_session_t * s, u8 parent_died)
23 : {
24 0 : echo_main_t *em = &echo_main;
25 : echo_session_t *ls;
26 0 : ASSERT (s->session_state < ECHO_SESSION_STATE_CLOSED);
27 0 : if (parent_died)
28 0 : clib_atomic_fetch_add (&em->stats.clean_count.s, 1);
29 0 : else if (s->listener_index != SESSION_INVALID_INDEX)
30 : {
31 0 : ls = pool_elt_at_index (em->sessions, s->listener_index);
32 0 : clib_atomic_sub_fetch (&ls->accepted_session_count, 1);
33 : }
34 :
35 0 : clib_atomic_sub_fetch (&em->n_clients_connected, 1);
36 0 : s->session_state = ECHO_SESSION_STATE_CLOSED;
37 0 : if (!em->n_clients_connected)
38 0 : em->state = STATE_DATA_DONE;
39 0 : }
40 :
41 : static void
42 0 : udp_echo_connected_cb (session_connected_bundled_msg_t * mp,
43 : u32 session_index, u8 is_failed)
44 : {
45 : static u32 client_index = 0;
46 0 : echo_main_t *em = &echo_main;
47 0 : echo_session_t *session = pool_elt_at_index (em->sessions, session_index);
48 0 : if (is_failed)
49 : {
50 0 : ECHO_FAIL (ECHO_FAIL_UDP_BAPI_CONNECT,
51 : "Bapi connect errored on session %u", session_index);
52 0 : return; /* Dont handle bapi connect errors for now */
53 : }
54 :
55 0 : session->accepted_session_count = 0;
56 0 : session->session_type = ECHO_SESSION_TYPE_STREAM;
57 :
58 0 : session->bytes_to_send = em->bytes_to_send;
59 0 : session->bytes_to_receive = em->bytes_to_receive;
60 0 : session->session_state = ECHO_SESSION_STATE_READY;
61 0 : session->is_dgram = 1;
62 :
63 0 : em->data_thread_args[client_index++] = session->session_index;
64 :
65 0 : clib_atomic_fetch_add (&em->n_clients_connected, 1);
66 0 : if (em->n_clients_connected == em->n_clients && em->state < STATE_READY)
67 : {
68 0 : echo_notify_event (em, ECHO_EVT_LAST_SCONNECTED);
69 0 : em->state = STATE_READY;
70 : }
71 : }
72 :
73 : static void
74 0 : udp_echo_accepted_cb (session_accepted_msg_t * mp, echo_session_t * session)
75 : {
76 : static u32 client_index = 0;
77 0 : echo_main_t *em = &echo_main;
78 : echo_session_t *ls;
79 :
80 0 : echo_notify_event (em, ECHO_EVT_FIRST_QCONNECT);
81 0 : ls = pool_elt_at_index (em->sessions, session->listener_index);
82 0 : session->session_type = ECHO_SESSION_TYPE_STREAM;
83 0 : echo_notify_event (em, ECHO_EVT_FIRST_SCONNECT);
84 0 : clib_atomic_fetch_add (&ls->accepted_session_count, 1);
85 0 : clib_atomic_fetch_add (&em->n_clients_connected, 1);
86 :
87 0 : session->bytes_to_send = em->bytes_to_send;
88 0 : session->bytes_to_receive = em->bytes_to_receive;
89 0 : session->is_dgram = 1;
90 0 : em->data_thread_args[client_index++] = session->session_index;
91 0 : session->session_state = ECHO_SESSION_STATE_READY;
92 :
93 0 : if (em->n_clients_connected == em->n_clients && em->state < STATE_READY)
94 : {
95 0 : echo_notify_event (em, ECHO_EVT_LAST_SCONNECTED);
96 0 : em->state = STATE_READY;
97 : }
98 0 : }
99 :
100 : static void
101 0 : udp_echo_sent_disconnect_cb (echo_session_t * s)
102 : {
103 0 : s->session_state = ECHO_SESSION_STATE_CLOSING;
104 0 : }
105 :
106 : static void
107 0 : udp_echo_disconnected_cb (session_disconnected_msg_t * mp, echo_session_t * s)
108 : {
109 0 : echo_main_t *em = &echo_main;
110 0 : echo_session_print_stats (em, s);
111 0 : if (s->bytes_to_receive || s->bytes_to_send)
112 0 : s->session_state = ECHO_SESSION_STATE_AWAIT_DATA;
113 : else
114 0 : s->session_state = ECHO_SESSION_STATE_CLOSING;
115 0 : clib_atomic_fetch_add (&em->stats.close_count.s, 1);
116 0 : }
117 :
118 : static void
119 0 : udp_echo_reset_cb (session_reset_msg_t * mp, echo_session_t * s)
120 : {
121 0 : echo_main_t *em = &echo_main;
122 0 : clib_atomic_fetch_add (&em->stats.reset_count.s, 1);
123 0 : s->session_state = ECHO_SESSION_STATE_CLOSING;
124 0 : }
125 :
126 : static void
127 0 : udp_echo_bound_uri_cb (session_bound_msg_t * mp, echo_session_t * session)
128 : {
129 0 : echo_main_t *em = &echo_main;
130 0 : u32 session_index = session->session_index;
131 0 : if (!em->i_am_master || em->uri_elts.transport_proto != TRANSPORT_PROTO_UDP)
132 0 : return;
133 :
134 0 : if (echo_attach_session (mp->segment_handle, mp->rx_fifo, mp->tx_fifo,
135 : mp->vpp_evt_q, session))
136 : {
137 0 : ECHO_FAIL (ECHO_FAIL_ACCEPTED_WAIT_FOR_SEG_ALLOC,
138 : "accepted wait_for_segment_allocation errored");
139 0 : return;
140 : }
141 :
142 0 : session->transport.is_ip4 = mp->lcl_is_ip4;
143 0 : clib_memcpy_fast (&session->transport.lcl_ip, mp->lcl_ip,
144 : sizeof (ip46_address_t));
145 0 : session->transport.lcl_port = mp->lcl_port;
146 :
147 0 : echo_notify_event (em, ECHO_EVT_FIRST_QCONNECT);
148 0 : session->session_type = ECHO_SESSION_TYPE_STREAM;
149 0 : echo_notify_event (em, ECHO_EVT_FIRST_SCONNECT);
150 0 : clib_atomic_fetch_add (&em->n_clients_connected, 1);
151 :
152 0 : session->bytes_to_send = em->bytes_to_send;
153 0 : session->bytes_to_receive = em->bytes_to_receive;
154 0 : session->is_dgram = 1;
155 0 : em->data_thread_args[0] = session_index;
156 0 : session->session_state = ECHO_SESSION_STATE_READY;
157 :
158 0 : echo_notify_event (em, ECHO_EVT_LAST_SCONNECTED);
159 0 : em->state = STATE_READY;
160 : }
161 :
162 :
163 : echo_proto_cb_vft_t echo_udp_proto_cb_vft = {
164 : .disconnected_cb = udp_echo_disconnected_cb,
165 : .connected_cb = udp_echo_connected_cb,
166 : .accepted_cb = udp_echo_accepted_cb,
167 : .reset_cb = udp_echo_reset_cb,
168 : .sent_disconnect_cb = udp_echo_sent_disconnect_cb,
169 : .cleanup_cb = udp_echo_cleanup_cb,
170 : .bound_uri_cb = udp_echo_bound_uri_cb,
171 : };
172 :
173 4 : ECHO_REGISTER_PROTO (TRANSPORT_PROTO_UDP, echo_udp_proto_cb_vft);
174 :
175 : /*
176 : * fd.io coding-style-patch-verification: ON
177 : *
178 : * Local Variables:
179 : * eval: (c-set-style "gnu")
180 : * End:
181 : */
|