OpenVPN
mroute.c
Go to the documentation of this file.
1 /*
2  * OpenVPN -- An application to securely tunnel IP networks
3  * over a single TCP/UDP port, with support for SSL/TLS-based
4  * session authentication and key exchange,
5  * packet encryption, packet authentication, and
6  * packet compression.
7  *
8  * Copyright (C) 2002-2024 OpenVPN Inc <sales@openvpn.net>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2
12  * as published by the Free Software Foundation.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23 
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27 
28 #include "syshead.h"
29 
30 
31 #include "mroute.h"
32 #include "proto.h"
33 #include "error.h"
34 #include "socket.h"
35 
36 #include "memdbg.h"
37 
38 void
40 {
41  CLEAR(*addr);
42 }
43 
44 /*
45  * Ethernet multicast addresses.
46  */
47 
48 static inline bool
49 is_mac_mcast_addr(const uint8_t *mac)
50 {
51  return (bool) (mac[0] & 1);
52 }
53 
54 static inline bool
55 is_mac_mcast_maddr(const struct mroute_addr *addr)
56 {
57  return (addr->type & MR_ADDR_MASK) == MR_ADDR_ETHER
58  && is_mac_mcast_addr(addr->ether.addr);
59 }
60 
61 /*
62  * Don't learn certain addresses.
63  */
64 bool
65 mroute_learnable_address(const struct mroute_addr *addr, struct gc_arena *gc)
66 {
67  int i;
68  bool all_zeros = true;
69  bool all_ones = true;
70 
71  for (i = 0; i < addr->len; ++i)
72  {
73  int b = addr->raw_addr[i];
74  if (b != 0x00)
75  {
76  all_zeros = false;
77  }
78  if (b != 0xFF)
79  {
80  all_ones = false;
81  }
82  }
83 
84  /* only networkss shorter than 8 bits are allowed to be all 0s. */
85  if (all_zeros
86  && !((addr->type & MR_WITH_NETBITS) && (addr->netbits < 8)))
87  {
88  msg(D_MULTI_LOW, "Can't learn %s: network is all 0s, but netbits >= 8",
89  mroute_addr_print(addr, gc));
90  return false;
91  }
92 
93  if (all_ones)
94  {
95  msg(D_MULTI_LOW, "Can't learn %s: network is all 1s",
96  mroute_addr_print(addr, gc));
97  return false;
98  }
99 
100  if (is_mac_mcast_maddr(addr))
101  {
102  msg(D_MULTI_LOW, "Can't learn %s: network is a multicast address",
103  mroute_addr_print(addr, gc));
104  return false;
105  }
106 
107  return true;
108 }
109 
110 static inline void
111 mroute_get_in_addr_t(struct mroute_addr *ma, const in_addr_t src, unsigned int mask)
112 {
113  if (ma)
114  {
115  ma->type = MR_ADDR_IPV4 | mask;
116  ma->netbits = 0;
117  ma->len = 4;
118  ma->v4.addr = src;
119  }
120 }
121 
122 static inline void
123 mroute_get_in6_addr(struct mroute_addr *ma, const struct in6_addr src, unsigned int mask)
124 {
125  if (ma)
126  {
127  ma->type = MR_ADDR_IPV6 | mask;
128  ma->netbits = 0;
129  ma->len = 16;
130  ma->v6.addr = src;
131  }
132 }
133 
134 static inline bool
135 mroute_is_mcast(const in_addr_t addr)
136 {
137  return ((addr & htonl(IP_MCAST_SUBNET_MASK)) == htonl(IP_MCAST_NETWORK));
138 }
139 
140 /* RFC 4291, 2.7, "binary 11111111 at the start of an address identifies
141  * the address as being a multicast address"
142  */
143 static inline bool
144 mroute_is_mcast_ipv6(const struct in6_addr addr)
145 {
146  return (addr.s6_addr[0] == 0xff);
147 }
148 
149 
150 unsigned int
152  const struct buffer *buf)
153 {
154  unsigned int ret = 0;
155  if (BLEN(buf) >= 1)
156  {
157  switch (OPENVPN_IPH_GET_VER(*BPTR(buf)))
158  {
159  case 4:
160  if (BLEN(buf) >= (int) sizeof(struct openvpn_iphdr))
161  {
162  const struct openvpn_iphdr *ip = (const struct openvpn_iphdr *) BPTR(buf);
163 
164  mroute_get_in_addr_t(src, ip->saddr, 0);
165  mroute_get_in_addr_t(dest, ip->daddr, 0);
166 
167  /* multicast packet? */
168  if (mroute_is_mcast(ip->daddr))
169  {
170  ret |= MROUTE_EXTRACT_MCAST;
171  }
172 
173  /* IGMP message? */
174  if (ip->protocol == OPENVPN_IPPROTO_IGMP)
175  {
176  ret |= MROUTE_EXTRACT_IGMP;
177  }
178 
180  }
181  break;
182 
183  case 6:
184  if (BLEN(buf) >= (int) sizeof(struct openvpn_ipv6hdr))
185  {
186  const struct openvpn_ipv6hdr *ipv6 = (const struct openvpn_ipv6hdr *) BPTR(buf);
187 #if 0 /* very basic debug */
188  struct gc_arena gc = gc_new();
189  msg( M_INFO, "IPv6 packet! src=%s, dst=%s",
190  print_in6_addr( ipv6->saddr, 0, &gc ),
191  print_in6_addr( ipv6->daddr, 0, &gc ));
192  gc_free(&gc);
193 #endif
194 
195  mroute_get_in6_addr(src, ipv6->saddr, 0);
196  mroute_get_in6_addr(dest, ipv6->daddr, 0);
197 
198  if (mroute_is_mcast_ipv6(ipv6->daddr))
199  {
200  ret |= MROUTE_EXTRACT_MCAST;
201  }
202 
204  }
205  break;
206 
207  default:
208  msg(M_WARN, "IP packet with unknown IP version=%d seen",
209  OPENVPN_IPH_GET_VER(*BPTR(buf)));
210  }
211  }
212  return ret;
213 }
214 
215 static void
217  const uint8_t *ether_addr,
218  uint16_t vid)
219 {
220  maddr->type = MR_ADDR_ETHER;
221  maddr->netbits = 0;
222  maddr->len = OPENVPN_ETH_ALEN;
223  memcpy(maddr->ether.addr, ether_addr, OPENVPN_ETH_ALEN);
224  maddr->len += sizeof(vid);
225  maddr->ether.vid = vid;
226 }
227 
228 unsigned int
230  struct mroute_addr *dest,
231  uint16_t vid,
232  const struct buffer *buf)
233 {
234  unsigned int ret = 0;
235  if (BLEN(buf) >= (int) sizeof(struct openvpn_ethhdr))
236  {
237  const struct openvpn_ethhdr *eth = (const struct openvpn_ethhdr *) BPTR(buf);
238  if (src)
239  {
240  mroute_copy_ether_to_addr(src, eth->source, vid);
241  }
242  if (dest)
243  {
244  mroute_copy_ether_to_addr(dest, eth->dest, vid);
245 
246  /* ethernet broadcast/multicast packet? */
247  if (is_mac_mcast_addr(eth->dest))
248  {
249  ret |= MROUTE_EXTRACT_BCAST;
250  }
251  }
252 
254 
255  }
256  return ret;
257 }
258 
259 /*
260  * Translate a struct openvpn_sockaddr (osaddr)
261  * to a struct mroute_addr (addr).
262  */
263 bool
265  const struct openvpn_sockaddr *osaddr,
266  bool use_port)
267 {
268  switch (osaddr->addr.sa.sa_family)
269  {
270  case AF_INET:
271  {
272  if (use_port)
273  {
274  addr->type = MR_ADDR_IPV4 | MR_WITH_PORT;
275  addr->netbits = 0;
276  addr->len = 6;
277  addr->v4.addr = osaddr->addr.in4.sin_addr.s_addr;
278  addr->v4.port = osaddr->addr.in4.sin_port;
279  }
280  else
281  {
282  addr->type = MR_ADDR_IPV4;
283  addr->netbits = 0;
284  addr->len = 4;
285  addr->v4.addr = osaddr->addr.in4.sin_addr.s_addr;
286  }
287  return true;
288  }
289 
290  case AF_INET6:
291  if (use_port)
292  {
293  addr->type = MR_ADDR_IPV6 | MR_WITH_PORT;
294  addr->netbits = 0;
295  addr->len = 18;
296  addr->v6.addr = osaddr->addr.in6.sin6_addr;
297  addr->v6.port = osaddr->addr.in6.sin6_port;
298  }
299  else
300  {
301  addr->type = MR_ADDR_IPV6;
302  addr->netbits = 0;
303  addr->len = 16;
304  addr->v6.addr = osaddr->addr.in6.sin6_addr;
305  }
306  return true;
307  }
308  return false;
309 }
310 
311 /*
312  * Zero off the host bits in an address, leaving
313  * only the network bits, using the netbits member of
314  * struct mroute_addr as the controlling parameter.
315  *
316  * TODO: this is called for route-lookup for every yet-unhashed
317  * destination address, so for lots of active net-iroutes, this
318  * might benefit from some "zeroize 32 bit at a time" improvements
319  */
320 void
322 {
323  if ((ma->type & MR_ADDR_MASK) == MR_ADDR_IPV4)
324  {
325  in_addr_t addr = ntohl(ma->v4.addr);
326  addr &= netbits_to_netmask(ma->netbits);
327  ma->v4.addr = htonl(addr);
328  }
329  else if ((ma->type & MR_ADDR_MASK) == MR_ADDR_IPV6)
330  {
331  int byte = sizeof(ma->v6.addr) - 1; /* rightmost byte in address */
332  int bits_to_clear = 128 - ma->netbits;
333 
334  while (byte >= 0 && bits_to_clear > 0)
335  {
336  if (bits_to_clear >= 8)
337  {
338  ma->v6.addr.s6_addr[byte--] = 0;
339  bits_to_clear -= 8;
340  }
341  else
342  {
343  ma->v6.addr.s6_addr[byte--] &= (IPV4_NETMASK_HOST << bits_to_clear);
344  bits_to_clear = 0;
345  }
346  }
347  ASSERT( bits_to_clear == 0 );
348  }
349  else
350  {
351  ASSERT(0);
352  }
353 }
354 
355 /*
356  * The mroute_addr hash function takes into account the
357  * address type, number of bits in the network address,
358  * and the actual address.
359  */
360 uint32_t
361 mroute_addr_hash_function(const void *key, uint32_t iv)
362 {
363  return hash_func(mroute_addr_hash_ptr((const struct mroute_addr *) key),
364  mroute_addr_hash_len((const struct mroute_addr *) key),
365  iv);
366 }
367 
368 bool
369 mroute_addr_compare_function(const void *key1, const void *key2)
370 {
371  return mroute_addr_equal((const struct mroute_addr *) key1,
372  (const struct mroute_addr *) key2);
373 }
374 
375 const char *
377  struct gc_arena *gc)
378 {
380 }
381 
382 const char *
384  const unsigned int flags,
385  struct gc_arena *gc)
386 {
387  struct buffer out = alloc_buf_gc(64, gc);
388  if (ma)
389  {
390  struct mroute_addr maddr = *ma;
391 
392  switch (maddr.type & MR_ADDR_MASK)
393  {
394  case MR_ADDR_ETHER:
395  buf_printf(&out, "%s", format_hex_ex(ma->ether.addr,
396  sizeof(ma->ether.addr), 0, 1, ":", gc));
397  buf_printf(&out, "@%hu", ma->ether.vid);
398  break;
399 
400  case MR_ADDR_IPV4:
401  {
402  if ((flags & MAPF_SHOW_ARP) && (maddr.type & MR_ARP))
403  {
404  buf_printf(&out, "ARP/");
405  }
406  buf_printf(&out, "%s", print_in_addr_t(ntohl(maddr.v4.addr),
407  (flags & MAPF_IA_EMPTY_IF_UNDEF) ? IA_EMPTY_IF_UNDEF : 0, gc));
408  if (maddr.type & MR_WITH_NETBITS)
409  {
410  if (flags & MAPF_SUBNET)
411  {
412  const in_addr_t netmask = netbits_to_netmask(maddr.netbits);
413  buf_printf(&out, "/%s", print_in_addr_t(netmask, 0, gc));
414  }
415  else
416  {
417  buf_printf(&out, "/%d", maddr.netbits);
418  }
419  }
420  if (maddr.type & MR_WITH_PORT)
421  {
422  buf_printf(&out, ":%d", ntohs(maddr.v4.port));
423  }
424  }
425  break;
426 
427  case MR_ADDR_IPV6:
428  {
429  if (IN6_IS_ADDR_V4MAPPED( &maddr.v6.addr ) )
430  {
431  buf_printf(&out, "%s", print_in_addr_t(maddr.v4mappedv6.addr,
432  IA_NET_ORDER, gc));
433  /* we only print port numbers for v4mapped v6 as of
434  * today, because "v6addr:port" is too ambiguous
435  */
436  if (maddr.type & MR_WITH_PORT)
437  {
438  buf_printf(&out, ":%d", ntohs(maddr.v6.port));
439  }
440  }
441  else
442  {
443  buf_printf(&out, "%s", print_in6_addr(maddr.v6.addr, 0, gc));
444  }
445  if (maddr.type & MR_WITH_NETBITS)
446  {
447  buf_printf(&out, "/%d", maddr.netbits);
448  }
449  }
450  break;
451 
452  default:
453  buf_printf(&out, "UNKNOWN");
454  break;
455  }
456  return BSTR(&out);
457  }
458  else
459  {
460  return "[NULL]";
461  }
462 }
463 
464 /*
465  * mroute_helper's main job is keeping track of
466  * currently used CIDR netlengths, so we don't
467  * have to cycle through all 33.
468  */
469 
470 struct mroute_helper *
472 {
473  struct mroute_helper *mh;
474  ALLOC_OBJ_CLEAR(mh, struct mroute_helper);
476  return mh;
477 }
478 
479 static void
481 {
482  int i, j = 0;
483  for (i = MR_HELPER_NET_LEN - 1; i >= 0; --i)
484  {
485  if (mh->net_len_refcount[i] > 0)
486  {
487  mh->net_len[j++] = (uint8_t) i;
488  }
489  }
490  mh->n_net_len = j;
491 
492 #ifdef ENABLE_DEBUG
494  {
495  struct gc_arena gc = gc_new();
496  struct buffer out = alloc_buf_gc(256, &gc);
497  buf_printf(&out, "MROUTE CIDR netlen:");
498  for (i = 0; i < mh->n_net_len; ++i)
499  {
500  buf_printf(&out, " /%d", mh->net_len[i]);
501  }
502  dmsg(D_MULTI_DEBUG, "%s", BSTR(&out));
503  gc_free(&gc);
504  }
505 #endif
506 }
507 
508 void
510 {
511  if (netbits >= 0)
512  {
513  ASSERT(netbits < MR_HELPER_NET_LEN);
514  ++mh->cache_generation;
515  ++mh->net_len_refcount[netbits];
516  if (mh->net_len_refcount[netbits] == 1)
517  {
519  }
520  }
521 }
522 
523 void
525 {
526  if (netbits >= 0)
527  {
528  ASSERT(netbits < MR_HELPER_NET_LEN);
529  ++mh->cache_generation;
530  --mh->net_len_refcount[netbits];
531  ASSERT(mh->net_len_refcount[netbits] >= 0);
532  if (!mh->net_len_refcount[netbits])
533  {
535  }
536  }
537 }
538 
539 void
541 {
542  free(mh);
543 }
mroute_helper_regenerate
static void mroute_helper_regenerate(struct mroute_helper *mh)
Definition: mroute.c:480
mroute_helper_init
struct mroute_helper * mroute_helper_init(int ageable_ttl_secs)
Definition: mroute.c:471
MR_ADDR_MASK
#define MR_ADDR_MASK
Definition: mroute.h:64
openvpn_sockaddr::addr
union openvpn_sockaddr::@14 addr
M_INFO
#define M_INFO
Definition: errlevel.h:55
error.h
MAPF_IA_EMPTY_IF_UNDEF
#define MAPF_IA_EMPTY_IF_UNDEF
Definition: mroute.h:158
gc_new
static struct gc_arena gc_new(void)
Definition: buffer.h:1030
IP_MCAST_NETWORK
#define IP_MCAST_NETWORK
Definition: mroute.h:34
mroute_is_mcast
static bool mroute_is_mcast(const in_addr_t addr)
Definition: mroute.c:135
key1
static const char *const key1
Definition: cert_data.h:56
BSTR
#define BSTR(buf)
Definition: buffer.h:129
alloc_buf_gc
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition: buffer.c:88
mroute_helper::net_len_refcount
int net_len_refcount[MR_HELPER_NET_LEN]
Definition: mroute.h:136
dmsg
#define dmsg(flags,...)
Definition: error.h:148
format_hex_ex
char * format_hex_ex(const uint8_t *data, int size, int maxoutput, unsigned int space_break_flags, const char *separator, struct gc_arena *gc)
Definition: buffer.c:501
openvpn_sockaddr
Definition: socket.h:65
IA_NET_ORDER
#define IA_NET_ORDER
Definition: socket.h:389
mroute_addr::ether
struct mroute_addr::@1::@2 ether
mroute_addr::netbits
uint8_t netbits
Definition: mroute.h:79
mroute_addr_hash_function
uint32_t mroute_addr_hash_function(const void *key, uint32_t iv)
Definition: mroute.c:361
mroute_extract_addr_ether
unsigned int mroute_extract_addr_ether(struct mroute_addr *src, struct mroute_addr *dest, uint16_t vid, const struct buffer *buf)
Definition: mroute.c:229
mroute_helper::net_len
uint8_t net_len[MR_HELPER_NET_LEN]
Definition: mroute.h:135
openvpn_sockaddr::in6
struct sockaddr_in6 in6
Definition: socket.h:71
openvpn_iphdr::daddr
uint32_t daddr
Definition: proto.h:128
key
Container for unidirectional cipher and HMAC key material.
Definition: crypto.h:149
mroute_get_in6_addr
static void mroute_get_in6_addr(struct mroute_addr *ma, const struct in6_addr src, unsigned int mask)
Definition: mroute.c:123
CLEAR
#define CLEAR(x)
Definition: basic.h:33
MR_HELPER_NET_LEN
#define MR_HELPER_NET_LEN
Definition: mroute.h:126
MR_ADDR_IPV6
#define MR_ADDR_IPV6
Definition: mroute.h:63
mroute_helper_free
void mroute_helper_free(struct mroute_helper *mh)
Definition: mroute.c:540
openvpn_ipv6hdr::daddr
struct in6_addr daddr
Definition: proto.h:143
MAPF_SHOW_ARP
#define MAPF_SHOW_ARP
Definition: mroute.h:159
mroute_helper_del_iroute46
void mroute_helper_del_iroute46(struct mroute_helper *mh, int netbits)
Definition: mroute.c:524
MR_ADDR_ETHER
#define MR_ADDR_ETHER
Definition: mroute.h:61
mroute_addr::v4
struct mroute_addr::@1::@3 v4
ASSERT
#define ASSERT(x)
Definition: error.h:195
print_in6_addr
const char * print_in6_addr(struct in6_addr a6, unsigned int flags, struct gc_arena *gc)
Definition: socket.c:2924
openvpn_iphdr::protocol
uint8_t protocol
Definition: proto.h:124
mroute_addr_hash_len
static uint32_t mroute_addr_hash_len(const struct mroute_addr *a)
Definition: mroute.h:233
openvpn_iphdr::saddr
uint32_t saddr
Definition: proto.h:127
MR_WITH_PORT
#define MR_WITH_PORT
Definition: mroute.h:67
openvpn_sockaddr::sa
struct sockaddr sa
Definition: socket.h:69
BLEN
#define BLEN(buf)
Definition: buffer.h:127
proto.h
openvpn_sockaddr::in4
struct sockaddr_in in4
Definition: socket.h:70
mroute_addr_init
void mroute_addr_init(struct mroute_addr *addr)
Definition: mroute.c:39
MROUTE_EXTRACT_IGMP
#define MROUTE_EXTRACT_IGMP
Definition: mroute.h:41
mroute_get_in_addr_t
static void mroute_get_in_addr_t(struct mroute_addr *ma, const in_addr_t src, unsigned int mask)
Definition: mroute.c:111
M_WARN
#define M_WARN
Definition: error.h:91
MR_ADDR_IPV4
#define MR_ADDR_IPV4
Definition: mroute.h:62
D_MULTI_LOW
#define D_MULTI_LOW
Definition: errlevel.h:86
mroute_addr::len
uint8_t len
Definition: mroute.h:76
mroute_helper::cache_generation
unsigned int cache_generation
Definition: mroute.h:132
mroute_addr::v4mappedv6
struct mroute_addr::@1::@5 v4mappedv6
is_mac_mcast_maddr
static bool is_mac_mcast_maddr(const struct mroute_addr *addr)
Definition: mroute.c:55
mroute_extract_openvpn_sockaddr
bool mroute_extract_openvpn_sockaddr(struct mroute_addr *addr, const struct openvpn_sockaddr *osaddr, bool use_port)
Definition: mroute.c:264
buffer
Wrapper structure for dynamically allocated memory.
Definition: buffer.h:60
openvpn_ethhdr::source
uint8_t source[OPENVPN_ETH_ALEN]
Definition: proto.h:58
IPV4_NETMASK_HOST
#define IPV4_NETMASK_HOST
Definition: basic.h:35
openvpn_ethhdr::dest
uint8_t dest[OPENVPN_ETH_ALEN]
Definition: proto.h:57
print_in_addr_t
const char * print_in_addr_t(in_addr_t addr, unsigned int flags, struct gc_arena *gc)
Definition: socket.c:2904
is_mac_mcast_addr
static bool is_mac_mcast_addr(const uint8_t *mac)
Definition: mroute.c:49
mroute_addr
Definition: mroute.h:75
mroute_helper::ageable_ttl_secs
int ageable_ttl_secs
Definition: mroute.h:133
syshead.h
BPTR
#define BPTR(buf)
Definition: buffer.h:124
gc_arena
Garbage collection arena used to keep track of dynamically allocated memory.
Definition: buffer.h:116
mroute_addr_print
const char * mroute_addr_print(const struct mroute_addr *ma, struct gc_arena *gc)
Definition: mroute.c:376
openvpn_ipv6hdr
Definition: proto.h:135
IP_MCAST_SUBNET_MASK
#define IP_MCAST_SUBNET_MASK
Definition: mroute.h:33
mroute.h
mroute_addr_print_ex
const char * mroute_addr_print_ex(const struct mroute_addr *ma, const unsigned int flags, struct gc_arena *gc)
Definition: mroute.c:383
MR_ARP
#define MR_ARP
Definition: mroute.h:73
check_debug_level
static bool check_debug_level(unsigned int level)
Definition: error.h:220
openvpn_ipv6hdr::saddr
struct in6_addr saddr
Definition: proto.h:142
mroute_addr::v6
struct mroute_addr::@1::@4 v6
openvpn_ethhdr
Definition: proto.h:55
mroute_helper_add_iroute46
void mroute_helper_add_iroute46(struct mroute_helper *mh, int netbits)
Definition: mroute.c:509
netbits_to_netmask
static in_addr_t netbits_to_netmask(const int netbits)
Definition: route.h:379
OPENVPN_ETH_ALEN
#define OPENVPN_ETH_ALEN
Definition: proto.h:54
OPENVPN_IPH_GET_VER
#define OPENVPN_IPH_GET_VER(v)
Definition: proto.h:107
mroute_extract_addr_ip
unsigned int mroute_extract_addr_ip(struct mroute_addr *src, struct mroute_addr *dest, const struct buffer *buf)
Definition: mroute.c:151
mroute_helper
Definition: mroute.h:131
gc_free
static void gc_free(struct gc_arena *a)
Definition: buffer.h:1038
mroute_addr::type
uint8_t type
Definition: mroute.h:78
mroute_addr_compare_function
bool mroute_addr_compare_function(const void *key1, const void *key2)
Definition: mroute.c:369
MR_WITH_NETBITS
#define MR_WITH_NETBITS
Definition: mroute.h:70
socket.h
mroute_copy_ether_to_addr
static void mroute_copy_ether_to_addr(struct mroute_addr *maddr, const uint8_t *ether_addr, uint16_t vid)
Definition: mroute.c:216
ALLOC_OBJ_CLEAR
#define ALLOC_OBJ_CLEAR(dptr, type)
Definition: buffer.h:1065
mroute_learnable_address
bool mroute_learnable_address(const struct mroute_addr *addr, struct gc_arena *gc)
Definition: mroute.c:65
config.h
MROUTE_EXTRACT_BCAST
#define MROUTE_EXTRACT_BCAST
Definition: mroute.h:39
MAPF_SUBNET
#define MAPF_SUBNET
Definition: mroute.h:157
key2
Container for bidirectional cipher and HMAC key material.
Definition: crypto.h:179
IA_EMPTY_IF_UNDEF
#define IA_EMPTY_IF_UNDEF
Definition: socket.h:388
MROUTE_EXTRACT_MCAST
#define MROUTE_EXTRACT_MCAST
Definition: mroute.h:40
mroute_addr_mask_host_bits
void mroute_addr_mask_host_bits(struct mroute_addr *ma)
Definition: mroute.c:321
OPENVPN_IPPROTO_IGMP
#define OPENVPN_IPPROTO_IGMP
Definition: proto.h:120
openvpn_iphdr
Definition: proto.h:106
mroute_addr::raw_addr
uint8_t raw_addr[MR_MAX_ADDR_LEN]
Definition: mroute.h:82
MROUTE_EXTRACT_SUCCEEDED
#define MROUTE_EXTRACT_SUCCEEDED
Definition: mroute.h:38
mroute_is_mcast_ipv6
static bool mroute_is_mcast_ipv6(const struct in6_addr addr)
Definition: mroute.c:144
memdbg.h
msg
#define msg(flags,...)
Definition: error.h:144
hash_func
uint32_t hash_func(const uint8_t *k, uint32_t length, uint32_t initval)
Definition: list.c:408
mroute_addr_hash_ptr
static const uint8_t * mroute_addr_hash_ptr(const struct mroute_addr *a)
Definition: mroute.h:226
buf_printf
bool buf_printf(struct buffer *buf, const char *format,...)
Definition: buffer.c:240
D_MULTI_DEBUG
#define D_MULTI_DEBUG
Definition: errlevel.h:127
mroute_helper::n_net_len
int n_net_len
Definition: mroute.h:134
mroute_addr_equal
static bool mroute_addr_equal(const struct mroute_addr *a1, const struct mroute_addr *a2)
Definition: mroute.h:208