3 * The olsr.org Optimized Link-State Routing daemon version 2 (olsrd2)
4 * Copyright (c) 2004-2015, the olsr.org team - see HISTORY file
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of olsr.org, olsrd nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
34 * Visit http://www.olsr.org for more information.
36 * If you find this software useful feel free to make a donation
37 * to the project. For more information see the website or contact
38 * the copyright holders.
46 #include <oonf/libcommon/avl.h>
47 #include <oonf/libcommon/avl_comp.h>
48 #include <oonf/libcommon/netaddr.h>
50 #include <oonf/base/oonf_class.h>
51 #include <oonf/base/oonf_packet_socket.h>
52 #include <oonf/base/oonf_stream_socket.h>
53 #include <oonf/base/oonf_timer.h>
55 #include <oonf/generic/dlep/dlep_extension.h>
56 #include <oonf/generic/dlep/dlep_iana.h>
57 #include <oonf/generic/dlep/dlep_session.h>
58 #include <oonf/generic/dlep/dlep_writer.h>
60 #include <oonf/generic/dlep/radio/dlep_radio.h>
61 #include <oonf/generic/dlep/radio/dlep_radio_interface.h>
63 #include <oonf/generic/dlep/ext_base_ip/ip.h>
64 #include <oonf/generic/dlep/ext_base_metric/metric.h>
65 #include <oonf/generic/dlep/ext_base_proto/proto_radio.h>
66 #include <oonf/generic/dlep/ext_l1_statistics/l1_statistics.h>
67 #include <oonf/generic/dlep/ext_l2_statistics/l2_statistics.h>
68 #include <oonf/generic/dlep/ext_radio_attributes/radio_attributes.h>
69 #include <oonf/generic/dlep/ext_lid/lid.h>
70 #include <oonf/generic/dlep/radio/dlep_radio_internal.h>
71 #include <oonf/generic/dlep/radio/dlep_radio_session.h>
73 static void _cleanup_interface(struct dlep_radio_if *interface);
76 static struct oonf_class _interface_class = {
77 .name = "DLEP radio interface",
78 .size = sizeof(struct dlep_radio_if),
81 static bool _shutting_down;
83 static struct oonf_layer2_origin _l2_origin = {
86 .priority = OONF_LAYER2_ORIGIN_RELIABLE,
89 static struct oonf_layer2_origin _l2_default_origin = {
90 .name = "dlep radio defaults",
92 .priority = OONF_LAYER2_ORIGIN_DEFAULT,
96 * Initialize everything for dlep radio interfaces. This function also
97 * initializes the dlep sessions.
98 * @return -1 if an error happened, 0 otherwise
101 dlep_radio_interface_init(void) {
102 oonf_class_add(&_interface_class);
104 dlep_extension_init();
106 dlep_radio_session_init();
107 dlep_base_proto_radio_init();
109 dlep_base_metric_init();
110 dlep_l1_statistics_init();
111 dlep_l2_statistics_init();
112 dlep_radio_attributes_init();
115 _shutting_down = false;
120 * Cleanup everything allocated for dlep radio interfaces. This will
121 * also clean up all dlep sessions.
124 dlep_radio_interface_cleanup(void) {
125 struct dlep_radio_if *interf, *it;
127 avl_for_each_element_safe(dlep_if_get_tree(true), interf, interf._node, it) {
128 dlep_radio_remove_interface(interf);
131 oonf_class_remove(&_interface_class);
132 dlep_radio_session_cleanup();
133 dlep_extension_cleanup();
137 * Get a dlep radio interface by layer2 interface name
138 * @param l2_ifname interface name
139 * @return dlep radio interface, NULL if not found
141 struct dlep_radio_if *
142 dlep_radio_get_by_layer2_if(const char *l2_ifname) {
143 struct dlep_radio_if *interf;
145 return avl_find_element(dlep_if_get_tree(true), l2_ifname, interf, interf._node);
149 * Get a dlep radio interface by dlep datapath name
150 * @param ifname interface name
151 * @return dlep radio interface, NULL if not found
153 struct dlep_radio_if *
154 dlep_radio_get_by_datapath_if(const char *ifname) {
155 struct dlep_radio_if *interf;
157 avl_for_each_element(dlep_if_get_tree(true), interf, interf._node) {
158 if (strcmp(interf->interf.udp_config.interface, ifname) == 0) {
166 * Add a new dlep radio interface to the database
167 * (keep existing one if already there).
168 * @param ifname interface name
169 * @return dlep radio interface, NULL if allocation failed
171 struct dlep_radio_if *
172 dlep_radio_add_interface(const char *ifname) {
173 struct dlep_radio_if *interface;
175 interface = dlep_radio_get_by_layer2_if(ifname);
180 interface = oonf_class_malloc(&_interface_class);
185 if (dlep_if_add(&interface->interf, ifname, &_l2_origin, &_l2_default_origin, NULL, LOG_DLEP_RADIO, true)) {
186 oonf_class_free(&_interface_class, interface);
190 /* configure TCP server socket */
191 interface->tcp.config.session_timeout = 120000; /* 120 seconds */
192 interface->tcp.config.maximum_input_buffer = 4096;
193 interface->tcp.config.allowed_sessions = 3;
194 dlep_radio_session_initialize_tcp_callbacks(&interface->tcp.config);
196 oonf_stream_add_managed(&interface->tcp);
202 * Remove a dlep radio interface
203 * @param interface dlep radio interface
206 dlep_radio_remove_interface(struct dlep_radio_if *interface) {
207 /* close all sessions */
208 _cleanup_interface(interface);
210 /* cleanup tcp socket */
211 oonf_stream_remove_managed(&interface->tcp, true);
213 /* cleanup generic interface */
214 dlep_if_remove(&interface->interf);
217 oonf_stream_free_managed_config(&interface->tcp_config);
218 free(interface->interf.session.cfg.peer_type);
219 abuf_free(&interface->interf.udp_out);
220 oonf_class_free(&_interface_class, interface);
224 * Apply settings for dlep radio interface
225 * @param interface dlep radio interface
228 dlep_radio_apply_interface_settings(struct dlep_radio_if *interface) {
229 struct dlep_extension *ext;
231 oonf_packet_apply_managed(&interface->interf.udp, &interface->interf.udp_config);
232 oonf_stream_apply_managed(&interface->tcp, &interface->tcp_config);
234 avl_for_each_element(dlep_extension_get_tree(), ext, _node) {
235 if (ext->cb_session_apply_radio) {
236 ext->cb_session_apply_radio(&interface->interf.session);
242 * Send all active sessions a Peer Terminate signal
245 dlep_radio_terminate_all_sessions(void) {
246 struct dlep_radio_if *interf;
247 struct dlep_radio_session *radio_session;
249 _shutting_down = true;
251 avl_for_each_element(dlep_if_get_tree(true), interf, interf._node) {
252 avl_for_each_element(&interf->interf.session_tree, radio_session, _node) {
253 dlep_session_terminate(&radio_session->session, DLEP_STATUS_OKAY, "DLEP radio is shutting down");
259 * Close all existing dlep sessions of a dlep interface
260 * @param interface dlep router interface
263 _cleanup_interface(struct dlep_radio_if *interface) {
264 struct dlep_radio_session *stream, *it;
266 /* close TCP connection and socket */
267 avl_for_each_element_safe(&interface->interf.session_tree, stream, _node, it) {
268 dlep_radio_remove_session(stream);