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.
49 #include <oonf/libcommon/avl.h>
50 #include <oonf/libcommon/avl_comp.h>
51 #include <oonf/oonf.h>
52 #include <oonf/libcommon/netaddr.h>
54 #include <oonf/libconfig/cfg_schema.h>
55 #include <oonf/libcore/oonf_subsystem.h>
56 #include <oonf/base/oonf_class.h>
57 #include <oonf/base/oonf_layer2.h>
58 #include <oonf/base/oonf_packet_socket.h>
59 #include <oonf/base/oonf_stream_socket.h>
60 #include <oonf/base/oonf_timer.h>
62 #include <oonf/generic/dlep/dlep_iana.h>
63 #include <oonf/generic/dlep/dlep_writer.h>
64 #include <oonf/generic/dlep/radio/dlep_radio.h>
65 #include <oonf/generic/dlep/radio/dlep_radio_interface.h>
66 #include <oonf/generic/dlep/radio/dlep_radio_internal.h>
69 static void _early_cfg_init(void);
70 static int _init(void);
71 static void _cleanup(void);
72 static void _initiate_shutdown(void);
74 static void _cb_config_changed(void);
77 static const char *_UDP_MODE[] = {
78 [DLEP_IF_UDP_NONE] = DLEP_IF_UDP_NONE_STR,
79 [DLEP_IF_UDP_SINGLE_SESSION] = DLEP_IF_UDP_SINGLE_SESSION_STR,
80 [DLEP_IF_UDP_ALWAYS] = DLEP_IF_UDP_ALWAYS_STR,
83 static struct cfg_schema_entry _radio_entries[] = {
84 CFG_MAP_STRING_ARRAY(dlep_radio_if, interf.udp_config.interface, "datapath_if", "",
85 "Name of interface to talk to dlep router (default is section name)", IF_NAMESIZE),
87 CFG_MAP_STRING(dlep_radio_if, interf.session.cfg.peer_type, "peer_type", "OONF DLEP Radio",
88 "Identification string of DLEP radio endpoint"),
90 CFG_MAP_NETADDR_V4(dlep_radio_if, interf.udp_config.multicast_v4, "discovery_mc_v4",
91 DLEP_WELL_KNOWN_MULTICAST_ADDRESS, "IPv4 address to send discovery UDP packet to", false, false),
92 CFG_MAP_NETADDR_V6(dlep_radio_if, interf.udp_config.multicast_v6, "discovery_mc_v6",
93 DLEP_WELL_KNOWN_MULTICAST_ADDRESS_6, "IPv6 address to send discovery UDP packet to", false, false),
94 CFG_MAP_INT32_MINMAX(dlep_radio_if, interf.udp_config.port, "discovery_port", DLEP_WELL_KNOWN_MULTICAST_PORT_TXT,
95 "UDP port for discovery packets", 0, 1, 65535),
96 CFG_MAP_ACL_V46(dlep_radio_if, interf.udp_config.bindto, "discovery_bindto", "fe80::/64",
97 "Filter to determine the binding of the UDP discovery socket"),
99 CFG_MAP_INT32_MINMAX(dlep_radio_if, tcp_config.port, "session_port", DLEP_WELL_KNOWN_SESSION_PORT_TXT,
100 "Server port for DLEP tcp sessions", 0, 1, 65535),
101 CFG_MAP_ACL_V46(dlep_radio_if, tcp_config.bindto, "session_bindto", "169.254.0.0/16\0fe80::/10",
102 "Filter to determine the binding of the TCP server socket"),
103 CFG_MAP_CLOCK_MINMAX(dlep_radio_if, interf.session.cfg.heartbeat_interval, "heartbeat_interval", "1.000",
104 "Interval in seconds between two heartbeat signals", 1000, 65535 * 1000),
106 CFG_MAP_CHOICE(dlep_radio_if, interf.udp_mode, "udp_mode", DLEP_IF_UDP_SINGLE_SESSION_STR,
107 "Determines the UDP behavior of the radio. 'none' never sends/processes UDP, 'single_session' only does"
108 " if no DLEP session is active and 'always' always sends/processes UDP and allows multiple sessions",
111 CFG_MAP_BOOL(dlep_radio_if, interf.session.cfg.send_proxied, "proxied", "true",
112 "Report 802.11s proxied mac address for neighbors"),
113 CFG_MAP_BOOL(dlep_radio_if, interf.session.cfg.send_neighbors, "not_proxied", "false", "Report direct neighbors"),
115 CFG_MAP_INT32_MINMAX(dlep_radio_if, interf.session.cfg.lid_length, "lid_length", DLEP_DEFAULT_LID_LENGTH_TXT,
116 "Link-ID length in octets that can be used to communicate with router", 0, 0, OONF_LAYER2_MAX_LINK_ID-1),
119 static struct cfg_schema_section _radio_section = {
120 .type = OONF_DLEP_RADIO_SUBSYSTEM,
121 .mode = CFG_SSMODE_NAMED,
123 .help = "name of the layer2 interface DLEP radio will take its data from",
125 .cb_delta_handler = _cb_config_changed,
127 .entries = _radio_entries,
128 .entry_count = ARRAYSIZE(_radio_entries),
131 /* subsystem declaration */
132 static const char *_dependencies[] = {
133 OONF_CLASS_SUBSYSTEM,
134 OONF_LAYER2_SUBSYSTEM,
135 OONF_PACKET_SUBSYSTEM,
136 OONF_STREAM_SUBSYSTEM,
137 OONF_TIMER_SUBSYSTEM,
139 static struct oonf_subsystem _dlep_radio_subsystem = {
140 .name = OONF_DLEP_RADIO_SUBSYSTEM,
141 .dependencies = _dependencies,
142 .dependencies_count = ARRAYSIZE(_dependencies),
143 .descr = "OONF DLEP radio plugin",
144 .author = "Henning Rogge",
146 .cfg_section = &_radio_section,
148 .early_cfg_init = _early_cfg_init,
150 .initiate_shutdown = _initiate_shutdown,
153 DECLARE_OONF_PLUGIN(_dlep_radio_subsystem);
156 enum oonf_log_source LOG_DLEP_RADIO;
159 _early_cfg_init(void) {
160 LOG_DLEP_RADIO = _dlep_radio_subsystem.logging;
164 * Plugin constructor for dlep radio
165 * @return -1 if an error happened, 0 otherwise
169 dlep_radio_interface_init();
174 * Send a clean Peer Terminate before we drop the session to shutdown
177 _initiate_shutdown(void) {
178 dlep_radio_terminate_all_sessions();
182 * Plugin destructor for dlep radio
186 dlep_radio_interface_cleanup();
190 * Callback for configuration changes
193 _cb_config_changed(void) {
194 struct dlep_radio_if *interface;
196 char ifbuf[IF_NAMESIZE];
199 ifname = cfg_get_phy_if(ifbuf, _radio_section.section_name);
201 if (!_radio_section.post) {
202 /* remove old interface object */
203 interface = dlep_radio_get_by_layer2_if(ifname);
205 dlep_radio_remove_interface(interface);
210 /* get interface object or create one */
211 interface = dlep_radio_add_interface(ifname);
216 /* read configuration */
217 error = cfg_schema_tobin(interface, _radio_section.post, _radio_entries, ARRAYSIZE(_radio_entries));
219 OONF_WARN(LOG_DLEP_RADIO, "Could not convert " OONF_DLEP_RADIO_SUBSYSTEM " config to bin (%d)", error);
223 if (!interface->interf.udp_config.interface[0]) {
224 strscpy(interface->interf.udp_config.interface, ifname, IF_NAMESIZE);
227 cfg_get_phy_if(interface->interf.udp_config.interface, interface->interf.udp_config.interface);
229 /* apply interface name also to TCP socket */
230 strscpy(interface->tcp_config.interface, interface->interf.udp_config.interface, IF_NAMESIZE);
233 dlep_radio_apply_interface_settings(interface);