Rename "subsystems" directory to "base"
[oonf.git] / include / oonf / base / os_interface.h
1
2 /*
3  * The olsr.org Optimized Link-State Routing daemon version 2 (olsrd2)
4  * Copyright (c) 2004-2015, the olsr.org team - see HISTORY file
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
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
16  *   distribution.
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.
20  *
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.
33  *
34  * Visit http://www.olsr.org for more information.
35  *
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.
39  *
40  */
41
42 /**
43  * @file
44  */
45
46 #ifndef OS_INTERFACE_H_
47 #define OS_INTERFACE_H_
48
49 #include <stdio.h>
50 #include <sys/time.h>
51
52 #include <oonf/oonf.h>
53 #include <oonf/libcommon/list.h>
54 #include <oonf/libcore/oonf_logging.h>
55 #include <oonf/base/oonf_timer.h>
56 #include <oonf/base/os_interface.h>
57
58 /*! subsystem identifier */
59 #define OONF_OS_INTERFACE_SUBSYSTEM "os_interface"
60
61 /*! interface configuration section name */
62 #define CFG_OSIF_SCHEMA_INTERFACE_SECTION_INIT .type = "interface", .mode = CFG_SSMODE_NAMED
63
64 /* include os-specific headers */
65 #if defined(__linux__)
66 #include <oonf/base/os_linux/os_interface_linux_internal.h>
67 #else
68 #error "Unknown operation system"
69 #endif
70
71 /**
72  * Handler for changing an interface address
73  */
74 struct os_interface_ip_change {
75   /*! operation system specific data */
76   struct os_interface_address_change_internal _internal;
77
78   /*! interface address */
79   struct netaddr address;
80
81   /*! index of interface */
82   unsigned int if_index;
83
84   /*! address scope */
85   enum os_addr_scope scope;
86
87   /*! set or reset address */
88   bool set;
89
90   /**
91    * Callback triggered when interface address has been changed
92    * @param addr this interface address object
93    * @param error error code, 0 if everything is fine
94    */
95   void (*cb_finished)(struct os_interface_ip_change *addr, int error);
96 };
97
98 struct os_interface_flags {
99   /*! true if the interface exists and is up */
100   bool up;
101
102   /*! true if the interface is in promiscious mode */
103   bool promisc;
104
105   /*! true if the interface is point to point */
106   bool pointtopoint;
107
108   /*! true if the interface is a loopback one */
109   bool loopback;
110
111   /*! true if interface is the wildcard interface */
112   bool any;
113
114   /*! true if interface supports no multicast */
115   bool unicast_only;
116
117   /*! true if interface is used for meshing */
118   bool mesh;
119 };
120
121 /**
122  * Representation of an operation system interface
123  */
124 struct os_interface {
125   /*! operation system specific data */
126   struct os_interface_internal _internal;
127
128   /*! interface name */
129   char name[IF_NAMESIZE];
130
131   /*! interface index */
132   unsigned index;
133
134   /**
135    * interface index of base interface (for vlan),
136    * same for normal interface
137    */
138   unsigned base_index;
139
140   /*! boolean flags of interface */
141   struct os_interface_flags flags;
142
143   /*! mac address of interface */
144   struct netaddr mac;
145
146   /**
147    * point to one (mesh scope) IPv4 address of the interface
148    * (or to NETADDR_UNSPEC if none available)
149    */
150   const struct netaddr *if_v4;
151
152   /**
153    * point to one (mesh scope) IPv4 address of the interface
154    * (or to NETADDR_UNSPEC if none available)
155    */
156   const struct netaddr *if_v6;
157
158   /**
159    * point to one (linklocal scope) IPv4 address of the interface
160    * (or to NETADDR_UNSPEC if none available)
161    */
162   const struct netaddr *if_linklocal_v4;
163
164   /**
165    * point to one (linklocal scope) IPv6 address of the interface
166    * (or to NETADDR_UNSPEC if none available)
167    */
168   const struct netaddr *if_linklocal_v6;
169
170   /*! tree of all addresses/prefixes of this interface */
171   struct avl_tree addresses;
172
173   /*! tree of all peer addresses/prefixes of this interface */
174   struct avl_tree peers;
175
176   /*! listeners to be informed when an interface changes */
177   struct list_entity _listeners;
178
179   /**
180    * When an interface change handler triggers a 'interface not ready'
181    * error the interface should be triggered again. The variable stores
182    * the last interval until the next trigger.
183    */
184   uint64_t retrigger_timeout;
185
186   /*! hook interfaces into global tree */
187   struct avl_node _node;
188
189   /*! timer for lazy interface change handling */
190   struct oonf_timer_instance _change_timer;
191
192   /*! remember if we already initialized the link data */
193   bool _link_initialized;
194
195   /*! remember if we already initialized the address data */
196   bool _addr_initialized;
197 };
198
199 /**
200  * Representation of an IP address/prefix of a network interface of
201  * the operation system
202  */
203 struct os_interface_ip {
204   struct avl_node _node;
205
206   struct netaddr prefixed_addr;
207   struct netaddr address;
208   struct netaddr prefix;
209
210   struct os_interface *interf;
211 };
212
213 /**
214  * operation system listener for interface events
215  */
216 struct os_interface_listener {
217   /*! name of the interface this listener is interested in */
218   const char *name;
219
220   /*! true if this interface needs to be a mesh interface */
221   bool mesh;
222
223   /**
224    * Callback triggered when the interface changed
225    * @param listener pointer to this listener
226    * @return -1 if an error happened, and the listener should be
227    *   triggered again later, 0 if everything was fine
228    */
229   int (*if_changed)(struct os_interface_listener *);
230
231   /*! pointer to interface data */
232   struct os_interface *data;
233
234   /*! true if this listener still needs to process a change */
235   bool _dirty;
236
237   /*! hook to global list of listeners */
238   struct list_entity _node;
239 };
240
241 /* include os-specific headers */
242 #if defined(__linux__)
243 #include <oonf/base/os_linux/os_interface_linux.h>
244 #else
245 #error "Unknown operation system"
246 #endif
247
248 /* prototypes for all os_system functions */
249 static INLINE struct os_interface *os_interface_add(struct os_interface_listener *);
250 static INLINE void os_interface_remove(struct os_interface_listener *);
251 static INLINE struct avl_tree *os_interface_get_tree(void);
252
253 static INLINE void os_interface_trigger_handler(struct os_interface_listener *);
254
255 static INLINE int os_interface_state_set(struct os_interface *, bool up);
256 static INLINE int os_interface_mac_set(struct os_interface *interf, struct netaddr *mac);
257
258 static INLINE int os_interface_address_set(struct os_interface_ip_change *addr);
259 static INLINE void os_interface_address_interrupt(struct os_interface_ip_change *addr);
260
261 static INLINE struct os_interface *os_interface_get_data_by_ifindex(unsigned ifindex);
262 static INLINE struct os_interface *os_interface_get_data_by_ifbaseindex(unsigned ifindex);
263 static INLINE const struct netaddr *os_interface_get_bindaddress(
264   int af_type, struct netaddr_acl *filter, struct os_interface *ifdata);
265 static INLINE const struct os_interface_ip *os_interface_get_prefix_from_dst(
266   struct netaddr *destination, struct os_interface *ifdata);
267
268 /**
269  * @param ifname name of an interface
270  * @return os interface instance, NULL if not registered
271  */
272 static INLINE struct os_interface *
273 os_interface_get(const char *ifname) {
274   struct os_interface *interf;
275   return avl_find_element(os_interface_get_tree(), ifname, interf, _node);
276 }
277
278 #endif /* OS_INTERFACE_H_ */