OpenVPN
dco_freebsd.c
Go to the documentation of this file.
1 /*
2  * Interface to FreeBSD dco networking code
3  *
4  * Copyright (C) 2022 Rubicon Communications, LLC (Netgate). All Rights Reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program (see the file COPYING included with this
17  * distribution); if not, write to the Free Software Foundation, Inc.,
18  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  */
20 
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 
25 #if defined(ENABLE_DCO) && defined(TARGET_FREEBSD)
26 
27 #include "syshead.h"
28 
29 #include <sys/param.h>
30 #include <sys/linker.h>
31 #include <sys/nv.h>
32 #include <sys/utsname.h>
33 
34 #include <netinet/in.h>
35 
36 #include "dco_freebsd.h"
37 #include "dco.h"
38 #include "tun.h"
39 #include "crypto.h"
40 #include "multi.h"
41 #include "ssl_common.h"
42 
43 static nvlist_t *
44 sockaddr_to_nvlist(const struct sockaddr *sa)
45 {
46  nvlist_t *nvl = nvlist_create(0);
47 
48  nvlist_add_number(nvl, "af", sa->sa_family);
49 
50  switch (sa->sa_family)
51  {
52  case AF_INET:
53  {
54  const struct sockaddr_in *in = (const struct sockaddr_in *)sa;
55  nvlist_add_binary(nvl, "address", &in->sin_addr, sizeof(in->sin_addr));
56  nvlist_add_number(nvl, "port", in->sin_port);
57  break;
58  }
59 
60  case AF_INET6:
61  {
62  const struct sockaddr_in6 *in6 = (const struct sockaddr_in6 *)sa;
63  nvlist_add_binary(nvl, "address", &in6->sin6_addr, sizeof(in6->sin6_addr));
64  nvlist_add_number(nvl, "port", in6->sin6_port);
65  break;
66  }
67 
68  default:
69  ASSERT(0);
70  }
71 
72  return (nvl);
73 }
74 
75 int
76 dco_new_peer(dco_context_t *dco, unsigned int peerid, int sd,
77  struct sockaddr *localaddr, struct sockaddr *remoteaddr,
78  struct in_addr *remote_in4, struct in6_addr *remote_in6)
79 {
80  struct ifdrv drv;
81  nvlist_t *nvl;
82  int ret;
83 
84  nvl = nvlist_create(0);
85 
86  msg(D_DCO_DEBUG, "%s: peer-id %d, fd %d", __func__, peerid, sd);
87 
88  if (localaddr)
89  {
90  nvlist_add_nvlist(nvl, "local", sockaddr_to_nvlist(localaddr));
91  }
92 
93  if (remoteaddr)
94  {
95  nvlist_add_nvlist(nvl, "remote", sockaddr_to_nvlist(remoteaddr));
96  }
97 
98  if (remote_in4)
99  {
100  nvlist_add_binary(nvl, "vpn_ipv4", &remote_in4->s_addr,
101  sizeof(remote_in4->s_addr));
102  }
103 
104  if (remote_in6)
105  {
106  nvlist_add_binary(nvl, "vpn_ipv6", remote_in6, sizeof(*remote_in6));
107  }
108 
109  nvlist_add_number(nvl, "fd", sd);
110  nvlist_add_number(nvl, "peerid", peerid);
111 
112  CLEAR(drv);
113  snprintf(drv.ifd_name, IFNAMSIZ, "%s", dco->ifname);
114  drv.ifd_cmd = OVPN_NEW_PEER;
115  drv.ifd_data = nvlist_pack(nvl, &drv.ifd_len);
116 
117  ret = ioctl(dco->fd, SIOCSDRVSPEC, &drv);
118  if (ret)
119  {
120  msg(M_ERR | M_ERRNO, "Failed to create new peer");
121  }
122 
123  free(drv.ifd_data);
124  nvlist_destroy(nvl);
125 
126  return ret;
127 }
128 
129 static int
130 open_fd(dco_context_t *dco)
131 {
132  int ret;
133 
134  ret = pipe2(dco->pipefd, O_CLOEXEC | O_NONBLOCK);
135  if (ret != 0)
136  {
137  return -1;
138  }
139 
140  dco->fd = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
141  if (dco->fd != -1)
142  {
143  dco->open = true;
144  }
145 
146  return dco->fd;
147 }
148 
149 static void
150 close_fd(dco_context_t *dco)
151 {
152  close(dco->pipefd[0]);
153  close(dco->pipefd[1]);
154  close(dco->fd);
155 }
156 
157 bool
158 ovpn_dco_init(int mode, dco_context_t *dco)
159 {
160  if (open_fd(dco) < 0)
161  {
162  msg(M_ERR, "Failed to open socket");
163  return false;
164  }
165  return true;
166 }
167 
168 static int
169 dco_set_ifmode(dco_context_t *dco, int ifmode)
170 {
171  struct ifdrv drv;
172  nvlist_t *nvl;
173  int ret;
174 
175  nvl = nvlist_create(0);
176  nvlist_add_number(nvl, "ifmode", ifmode);
177 
178  CLEAR(drv);
179  snprintf(drv.ifd_name, IFNAMSIZ, "%s", dco->ifname);
180  drv.ifd_cmd = OVPN_SET_IFMODE;
181  drv.ifd_data = nvlist_pack(nvl, &drv.ifd_len);
182 
183  ret = ioctl(dco->fd, SIOCSDRVSPEC, &drv);
184  if (ret)
185  {
186  msg(M_WARN | M_ERRNO, "dco_set_ifmode: failed to set ifmode=%08x", ifmode);
187  }
188 
189  free(drv.ifd_data);
190  nvlist_destroy(nvl);
191 
192  return ret;
193 }
194 
195 static int
196 create_interface(struct tuntap *tt, const char *dev)
197 {
198  int ret;
199  struct ifreq ifr;
200 
201  CLEAR(ifr);
202 
203  /* Create ovpnx first, then rename it. */
204  snprintf(ifr.ifr_name, IFNAMSIZ, "ovpn");
205  ret = ioctl(tt->dco.fd, SIOCIFCREATE2, &ifr);
206  if (ret)
207  {
208  ret = -errno;
209  msg(M_WARN|M_ERRNO, "Failed to create interface %s (SIOCIFCREATE2)", ifr.ifr_name);
210  return ret;
211  }
212 
213  /* Rename */
214  if (!strcmp(dev, "tun"))
215  {
216  ifr.ifr_data = "ovpn";
217  }
218  else
219  {
220  ifr.ifr_data = (char *)dev;
221  }
222  ret = ioctl(tt->dco.fd, SIOCSIFNAME, &ifr);
223  if (ret)
224  {
225  ret = -errno;
226  /* Delete the created interface again. */
227  (void)ioctl(tt->dco.fd, SIOCIFDESTROY, &ifr);
228  msg(M_WARN|M_ERRNO, "Failed to create interface %s (SIOCSIFNAME)", ifr.ifr_data);
229  return ret;
230  }
231 
232  snprintf(tt->dco.ifname, IFNAMSIZ, "%s", ifr.ifr_data);
233 
234  /* see "Interface Flags" in ifnet(9) */
235  int i = IFF_POINTOPOINT | IFF_MULTICAST;
236  if (tt->topology == TOP_SUBNET)
237  {
238  i = IFF_BROADCAST | IFF_MULTICAST;
239  }
240  dco_set_ifmode(&tt->dco, i);
241 
242  return 0;
243 }
244 
245 static int
246 remove_interface(struct tuntap *tt)
247 {
248  int ret;
249  struct ifreq ifr;
250 
251  CLEAR(ifr);
252  snprintf(ifr.ifr_name, IFNAMSIZ, "%s", tt->dco.ifname);
253 
254  ret = ioctl(tt->dco.fd, SIOCIFDESTROY, &ifr);
255  if (ret)
256  {
257  msg(M_ERR | M_ERRNO, "Failed to remove interface %s", ifr.ifr_name);
258  }
259 
260  tt->dco.ifname[0] = 0;
261 
262  return ret;
263 }
264 
265 int
266 open_tun_dco(struct tuntap *tt, openvpn_net_ctx_t *ctx, const char *dev)
267 {
268  return create_interface(tt, dev);
269 }
270 
271 void
272 close_tun_dco(struct tuntap *tt, openvpn_net_ctx_t *ctx)
273 {
274  remove_interface(tt);
275  close_fd(&tt->dco);
276 }
277 
278 int
279 dco_swap_keys(dco_context_t *dco, unsigned int peerid)
280 {
281  struct ifdrv drv;
282  nvlist_t *nvl;
283  int ret;
284 
285  msg(D_DCO_DEBUG, "%s: peer-id %d", __func__, peerid);
286 
287  nvl = nvlist_create(0);
288  nvlist_add_number(nvl, "peerid", peerid);
289 
290  CLEAR(drv);
291  snprintf(drv.ifd_name, IFNAMSIZ, "%s", dco->ifname);
292  drv.ifd_cmd = OVPN_SWAP_KEYS;
293  drv.ifd_data = nvlist_pack(nvl, &drv.ifd_len);
294 
295  ret = ioctl(dco->fd, SIOCSDRVSPEC, &drv);
296  if (ret)
297  {
298  msg(M_WARN | M_ERRNO, "Failed to swap keys");
299  }
300 
301  free(drv.ifd_data);
302  nvlist_destroy(nvl);
303 
304  return ret;
305 }
306 
307 int
308 dco_del_peer(dco_context_t *dco, unsigned int peerid)
309 {
310  struct ifdrv drv;
311  nvlist_t *nvl;
312  int ret;
313 
314  msg(D_DCO_DEBUG, "%s: peer-id %d", __func__, peerid);
315 
316  nvl = nvlist_create(0);
317  nvlist_add_number(nvl, "peerid", peerid);
318 
319  CLEAR(drv);
320  snprintf(drv.ifd_name, IFNAMSIZ, "%s", dco->ifname);
321  drv.ifd_cmd = OVPN_DEL_PEER;
322  drv.ifd_data = nvlist_pack(nvl, &drv.ifd_len);
323 
324  ret = ioctl(dco->fd, SIOCSDRVSPEC, &drv);
325  if (ret)
326  {
327  msg(M_WARN | M_ERRNO, "Failed to delete peer");
328  }
329 
330  free(drv.ifd_data);
331  nvlist_destroy(nvl);
332 
333  return ret;
334 }
335 
336 int
337 dco_del_key(dco_context_t *dco, unsigned int peerid,
338  dco_key_slot_t slot)
339 {
340  struct ifdrv drv;
341  nvlist_t *nvl;
342  int ret;
343 
344  msg(D_DCO_DEBUG, "%s: peer-id %d, slot %d", __func__, peerid, slot);
345 
346  nvl = nvlist_create(0);
347  nvlist_add_number(nvl, "slot", slot);
348  nvlist_add_number(nvl, "peerid", peerid);
349 
350  CLEAR(drv);
351  snprintf(drv.ifd_name, IFNAMSIZ, "%s", dco->ifname);
352  drv.ifd_cmd = OVPN_DEL_KEY;
353  drv.ifd_data = nvlist_pack(nvl, &drv.ifd_len);
354 
355  ret = ioctl(dco->fd, SIOCSDRVSPEC, &drv);
356  if (ret)
357  {
358  msg(M_WARN | M_ERRNO, "Failed to delete key");
359  }
360 
361  free(drv.ifd_data);
362  nvlist_destroy(nvl);
363 
364  return ret;
365 }
366 
367 static nvlist_t *
368 key_to_nvlist(const uint8_t *key, const uint8_t *implicit_iv, const char *ciphername)
369 {
370  nvlist_t *nvl;
371  size_t key_len;
372 
373  nvl = nvlist_create(0);
374 
375  nvlist_add_string(nvl, "cipher", ciphername);
376 
377  if (strcmp(ciphername, "none") != 0)
378  {
379  key_len = cipher_kt_key_size(ciphername);
380 
381  nvlist_add_binary(nvl, "key", key, key_len);
382  nvlist_add_binary(nvl, "iv", implicit_iv, 8);
383  }
384 
385  return (nvl);
386 }
387 
388 static int
389 start_tun(dco_context_t *dco)
390 {
391  struct ifdrv drv;
392  int ret;
393 
394  CLEAR(drv);
395  snprintf(drv.ifd_name, IFNAMSIZ, "%s", dco->ifname);
396  drv.ifd_cmd = OVPN_START_VPN;
397 
398  ret = ioctl(dco->fd, SIOCSDRVSPEC, &drv);
399  if (ret)
400  {
401  msg(M_ERR | M_ERRNO, "Failed to start vpn");
402  }
403 
404  return ret;
405 }
406 
407 int
408 dco_new_key(dco_context_t *dco, unsigned int peerid, int keyid,
409  dco_key_slot_t slot,
410  const uint8_t *encrypt_key, const uint8_t *encrypt_iv,
411  const uint8_t *decrypt_key, const uint8_t *decrypt_iv,
412  const char *ciphername)
413 {
414  struct ifdrv drv;
415  nvlist_t *nvl;
416  int ret;
417 
418  msg(D_DCO_DEBUG, "%s: slot %d, key-id %d, peer-id %d, cipher %s",
419  __func__, slot, keyid, peerid, ciphername);
420 
421  nvl = nvlist_create(0);
422 
423  nvlist_add_number(nvl, "slot", slot);
424  nvlist_add_number(nvl, "keyid", keyid);
425  nvlist_add_number(nvl, "peerid", peerid);
426 
427  nvlist_add_nvlist(nvl, "encrypt",
428  key_to_nvlist(encrypt_key, encrypt_iv, ciphername));
429  nvlist_add_nvlist(nvl, "decrypt",
430  key_to_nvlist(decrypt_key, decrypt_iv, ciphername));
431 
432  CLEAR(drv);
433  snprintf(drv.ifd_name, IFNAMSIZ, "%s", dco->ifname);
434  drv.ifd_cmd = OVPN_NEW_KEY;
435  drv.ifd_data = nvlist_pack(nvl, &drv.ifd_len);
436 
437  ret = ioctl(dco->fd, SIOCSDRVSPEC, &drv);
438  if (ret)
439  {
440  msg(M_ERR | M_ERRNO, "Failed to set key");
441  }
442  else
443  {
444  ret = start_tun(dco);
445  }
446 
447  free(drv.ifd_data);
448  nvlist_destroy(nvl);
449 
450  return ret;
451 }
452 
453 int
454 dco_set_peer(dco_context_t *dco, unsigned int peerid,
455  int keepalive_interval, int keepalive_timeout,
456  int mss)
457 {
458  struct ifdrv drv;
459  nvlist_t *nvl;
460  int ret;
461 
462  msg(D_DCO_DEBUG, "%s: peer-id %d, ping interval %d, ping timeout %d",
463  __func__, peerid, keepalive_interval, keepalive_timeout);
464 
465  nvl = nvlist_create(0);
466  nvlist_add_number(nvl, "peerid", peerid);
467  nvlist_add_number(nvl, "interval", keepalive_interval);
468  nvlist_add_number(nvl, "timeout", keepalive_timeout);
469 
470  CLEAR(drv);
471  snprintf(drv.ifd_name, IFNAMSIZ, "%s", dco->ifname);
472  drv.ifd_cmd = OVPN_SET_PEER;
473  drv.ifd_data = nvlist_pack(nvl, &drv.ifd_len);
474 
475  ret = ioctl(dco->fd, SIOCSDRVSPEC, &drv);
476  if (ret)
477  {
478  msg(M_WARN | M_ERRNO, "Failed to set keepalive");
479  }
480 
481  free(drv.ifd_data);
482  nvlist_destroy(nvl);
483 
484  return ret;
485 }
486 
487 int
489 {
490  struct ifdrv drv;
491  uint8_t buf[4096];
492  nvlist_t *nvl;
493  enum ovpn_notif_type type;
494  int ret;
495 
496  /* Flush any pending data from the pipe. */
497  (void)read(dco->pipefd[1], buf, sizeof(buf));
498 
499  CLEAR(drv);
500  snprintf(drv.ifd_name, IFNAMSIZ, "%s", dco->ifname);
501  drv.ifd_cmd = OVPN_GET_PKT;
502  drv.ifd_data = buf;
503  drv.ifd_len = sizeof(buf);
504 
505  ret = ioctl(dco->fd, SIOCGDRVSPEC, &drv);
506  if (ret)
507  {
508  msg(M_WARN | M_ERRNO, "Failed to read control packet");
509  return -errno;
510  }
511 
512  nvl = nvlist_unpack(buf, drv.ifd_len, 0);
513  if (!nvl)
514  {
515  msg(M_WARN, "Failed to unpack nvlist");
516  return -EINVAL;
517  }
518 
519  dco->dco_message_peer_id = nvlist_get_number(nvl, "peerid");
520 
521  type = nvlist_get_number(nvl, "notification");
522  switch (type)
523  {
524  case OVPN_NOTIF_DEL_PEER:
525  dco->dco_del_peer_reason = OVPN_DEL_PEER_REASON_EXPIRED;
526 
527  if (nvlist_exists_number(nvl, "del_reason"))
528  {
529  uint32_t reason = nvlist_get_number(nvl, "del_reason");
530  if (reason == OVPN_DEL_REASON_TIMEOUT)
531  {
532  dco->dco_del_peer_reason = OVPN_DEL_PEER_REASON_EXPIRED;
533  }
534  else
535  {
536  dco->dco_del_peer_reason = OVPN_DEL_PEER_REASON_USERSPACE;
537  }
538  }
539 
540  if (nvlist_exists_nvlist(nvl, "bytes"))
541  {
542  const nvlist_t *bytes = nvlist_get_nvlist(nvl, "bytes");
543 
544  dco->dco_read_bytes = nvlist_get_number(bytes, "in");
545  dco->dco_write_bytes = nvlist_get_number(bytes, "out");
546  }
547 
548  dco->dco_message_type = OVPN_CMD_DEL_PEER;
549  break;
550 
552  dco->dco_message_type = OVPN_CMD_SWAP_KEYS;
553  break;
554 
555  default:
556  msg(M_WARN, "Unknown kernel notification %d", type);
557  break;
558  }
559 
560  nvlist_destroy(nvl);
561 
562  return 0;
563 }
564 
565 bool
566 dco_available(int msglevel)
567 {
568  struct if_clonereq ifcr;
569  char *buf = NULL;
570  int fd;
571  int ret;
572  bool available = false;
573 
574  /* Attempt to load the module. Ignore errors, because it might already be
575  * loaded, or built into the kernel. */
576  (void)kldload("if_ovpn");
577 
578  fd = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
579  if (fd < 0)
580  {
581  return false;
582  }
583 
584  CLEAR(ifcr);
585 
586  /* List cloners and check if openvpn is there. That tells us if this kernel
587  * supports if_ovpn (i.e. DCO) or not. */
588  ret = ioctl(fd, SIOCIFGCLONERS, &ifcr);
589  if (ret != 0)
590  {
591  goto out;
592  }
593 
594  buf = malloc(ifcr.ifcr_total * IFNAMSIZ);
595  if (!buf)
596  {
597  goto out;
598  }
599 
600  ifcr.ifcr_count = ifcr.ifcr_total;
601  ifcr.ifcr_buffer = buf;
602  ret = ioctl(fd, SIOCIFGCLONERS, &ifcr);
603  if (ret != 0)
604  {
605  goto out;
606  }
607 
608  for (int i = 0; i < ifcr.ifcr_total; i++)
609  {
610  if (strcmp(buf + (i * IFNAMSIZ), "openvpn") == 0)
611  {
612  available = true;
613  goto out;
614  }
615  }
616 
617 out:
618  free(buf);
619  close(fd);
620 
621  return available;
622 }
623 
624 const char *
625 dco_version_string(struct gc_arena *gc)
626 {
627  struct utsname *uts;
628  ALLOC_OBJ_GC(uts, struct utsname, gc);
629 
630  if (uname(uts) != 0)
631  {
632  return "N/A";
633  }
634 
635  return uts->version;
636 }
637 
638 void
639 dco_event_set(dco_context_t *dco, struct event_set *es, void *arg)
640 {
641  struct ifdrv drv;
642  nvlist_t *nvl;
643  uint8_t buf[128];
644  int ret;
645 
646  if (!dco || !dco->open)
647  {
648  return;
649  }
650 
651  CLEAR(drv);
652  snprintf(drv.ifd_name, IFNAMSIZ, "%s", dco->ifname);
653  drv.ifd_cmd = OVPN_POLL_PKT;
654  drv.ifd_len = sizeof(buf);
655  drv.ifd_data = buf;
656 
657  ret = ioctl(dco->fd, SIOCGDRVSPEC, &drv);
658  if (ret)
659  {
660  msg(M_WARN | M_ERRNO, "Failed to poll for packets");
661  return;
662  }
663 
664  nvl = nvlist_unpack(buf, drv.ifd_len, 0);
665  if (!nvl)
666  {
667  msg(M_WARN, "Failed to unpack nvlist");
668  return;
669  }
670 
671  if (nvlist_get_number(nvl, "pending") > 0)
672  {
673  (void)write(dco->pipefd[0], " ", 1);
674  event_ctl(es, dco->pipefd[1], EVENT_READ, arg);
675  }
676 
677  nvlist_destroy(nvl);
678 }
679 
680 static void
681 dco_update_peer_stat(struct multi_context *m, uint32_t peerid, const nvlist_t *nvl)
682 {
683 
684  if (peerid >= m->max_clients || !m->instances[peerid])
685  {
686  msg(M_WARN, "dco_update_peer_stat: invalid peer ID %d returned by kernel", peerid);
687  return;
688  }
689 
690  struct multi_instance *mi = m->instances[peerid];
691 
692  mi->context.c2.dco_read_bytes = nvlist_get_number(nvl, "in");
693  mi->context.c2.dco_write_bytes = nvlist_get_number(nvl, "out");
694 }
695 
696 int
698 {
699 
700  struct ifdrv drv;
701  uint8_t *buf = NULL;
702  size_t buf_size = 4096;
703  nvlist_t *nvl;
704  const nvlist_t *const *nvpeers;
705  size_t npeers;
706  int ret;
707 
708  if (!dco || !dco->open)
709  {
710  return 0;
711  }
712 
713  CLEAR(drv);
714  snprintf(drv.ifd_name, IFNAMSIZ, "%s", dco->ifname);
715  drv.ifd_cmd = OVPN_GET_PEER_STATS;
716 
717 retry:
718  buf = realloc(buf, buf_size);
719  drv.ifd_len = buf_size;
720  drv.ifd_data = buf;
721 
722  ret = ioctl(dco->fd, SIOCGDRVSPEC, &drv);
723  if (ret && errno == ENOSPC)
724  {
725  buf_size *= 2;
726  goto retry;
727  }
728 
729  if (ret)
730  {
731  free(buf);
732  msg(M_WARN | M_ERRNO, "Failed to get peer stats");
733  return -EINVAL;
734  }
735 
736  nvl = nvlist_unpack(buf, drv.ifd_len, 0);
737  free(buf);
738  if (!nvl)
739  {
740  msg(M_WARN, "Failed to unpack nvlist");
741  return -EINVAL;
742  }
743 
744  if (!nvlist_exists_nvlist_array(nvl, "peers"))
745  {
746  /* no peers */
747  return 0;
748  }
749 
750  nvpeers = nvlist_get_nvlist_array(nvl, "peers", &npeers);
751  for (size_t i = 0; i < npeers; i++)
752  {
753  const nvlist_t *peer = nvpeers[i];
754  uint32_t peerid = nvlist_get_number(peer, "peerid");
755 
756  dco_update_peer_stat(m, peerid, nvlist_get_nvlist(peer, "bytes"));
757  }
758 
759  return 0;
760 }
761 
762 int
763 dco_get_peer_stats(struct context *c)
764 {
765  /* Not implemented. */
766  return 0;
767 }
768 
769 const char *
771 {
772  return "none:AES-256-GCM:AES-192-GCM:AES-128-GCM:CHACHA20-POLY1305";
773 }
774 
775 #endif /* defined(ENABLE_DCO) && defined(TARGET_FREEBSD) */
OVPN_CMD_DEL_PEER
@ OVPN_CMD_DEL_PEER
@OVPN_CMD_DEL_PEER: Remove peer from internal table
Definition: ovpn_dco_linux.h:40
OVPN_START_VPN
#define OVPN_START_VPN
Definition: ovpn_dco_freebsd.h:65
multi_instance
Server-mode state structure for one single VPN tunnel.
Definition: multi.h:101
D_DCO_DEBUG
#define D_DCO_DEBUG
Definition: errlevel.h:118
dco_new_key
int dco_new_key(dco_context_t *dco, unsigned int peerid, int keyid, dco_key_slot_t slot, const uint8_t *encrypt_key, const uint8_t *encrypt_iv, const uint8_t *decrypt_key, const uint8_t *decrypt_iv, const char *ciphername)
Definition: dco_win.c:295
M_ERRNO
#define M_ERRNO
Definition: error.h:100
dco_get_supported_ciphers
const char * dco_get_supported_ciphers()
Definition: dco_win.c:469
OVPN_SWAP_KEYS
#define OVPN_SWAP_KEYS
Definition: ovpn_dco_freebsd.h:62
OVPN_NOTIF_ROTATE_KEY
@ OVPN_NOTIF_ROTATE_KEY
Definition: ovpn_dco_freebsd.h:39
OVPN_POLL_PKT
#define OVPN_POLL_PKT
Definition: ovpn_dco_freebsd.h:67
dco_version_string
const char * dco_version_string(struct gc_arena *gc)
Definition: dco_win.c:387
context
Contains all state information for one tunnel.
Definition: openvpn.h:476
es
struct env_set * es
Definition: test_pkcs11.c:133
open_tun_dco
int open_tun_dco(struct tuntap *tt, openvpn_net_ctx_t *ctx, const char *dev)
Definition: dco_win.c:62
close_tun_dco
static void close_tun_dco(struct tuntap *tt, openvpn_net_ctx_t *ctx)
Definition: dco.h:299
openvpn_net_ctx_t
void * openvpn_net_ctx_t
Definition: networking.h:28
dco_get_peer_stats
int dco_get_peer_stats(struct context *c)
Definition: dco_win.c:433
TOP_SUBNET
#define TOP_SUBNET
Definition: proto.h:45
EVENT_READ
#define EVENT_READ
Definition: event.h:39
dco_new_peer
int dco_new_peer(dco_context_t *dco, unsigned int peerid, int sd, struct sockaddr *localaddr, struct sockaddr *remoteaddr, struct in_addr *remote_in4, struct in6_addr *remote_in6)
Definition: dco_win.c:248
dco_do_read
int dco_do_read(dco_context_t *dco)
Definition: dco_win.c:418
key
Container for unidirectional cipher and HMAC key material.
Definition: crypto.h:149
multi_context::max_clients
int max_clients
Definition: multi.h:179
OVPN_NEW_KEY
#define OVPN_NEW_KEY
Definition: ovpn_dco_freebsd.h:61
CLEAR
#define CLEAR(x)
Definition: basic.h:33
event_ctl
static void event_ctl(struct event_set *es, event_t event, unsigned int rwflags, void *arg)
Definition: event.h:160
context::c2
struct context_2 c2
Level 2 context.
Definition: openvpn.h:517
multi_context::instances
struct multi_instance ** instances
Array of multi_instances.
Definition: multi.h:156
OVPN_GET_PKT
#define OVPN_GET_PKT
Definition: ovpn_dco_freebsd.h:68
ASSERT
#define ASSERT(x)
Definition: error.h:201
read
@ read
Definition: interactive.c:205
tun.h
OVPN_GET_PEER_STATS
#define OVPN_GET_PEER_STATS
Definition: ovpn_dco_freebsd.h:70
write
@ write
Definition: interactive.c:206
ovpn_dco_init
bool ovpn_dco_init(int mode, dco_context_t *dco)
Definition: dco_win.c:56
context_2::dco_write_bytes
counter_type dco_write_bytes
Definition: openvpn.h:273
M_WARN
#define M_WARN
Definition: error.h:97
dco_event_set
void dco_event_set(dco_context_t *dco, struct event_set *es, void *arg)
Definition: dco_win.c:462
crypto.h
OVPN_DEL_KEY
#define OVPN_DEL_KEY
Definition: ovpn_dco_freebsd.h:63
multi.h
M_ERR
#define M_ERR
Definition: error.h:111
dco_context_t
void * dco_context_t
Definition: dco.h:254
dco_available
bool dco_available(int msglevel)
Definition: dco_win.c:360
OVPN_DEL_PEER_REASON_USERSPACE
@ OVPN_DEL_PEER_REASON_USERSPACE
Definition: ovpn_dco_linux.h:72
dco_set_peer
int dco_set_peer(dco_context_t *dco, unsigned int peerid, int keepalive_interval, int keepalive_timeout, int mss)
Definition: dco_win.c:272
OVPN_SET_PEER
struct _OVPN_SET_PEER OVPN_SET_PEER
OVPN_DEL_PEER_REASON_EXPIRED
@ OVPN_DEL_PEER_REASON_EXPIRED
Definition: ovpn_dco_linux.h:73
ovpn_notif_type
ovpn_notif_type
Definition: ovpn_dco_freebsd.h:37
syshead.h
gc_arena
Garbage collection arena used to keep track of dynamically allocated memory.
Definition: buffer.h:116
dco_del_peer
int dco_del_peer(dco_context_t *dco, unsigned int peerid)
Definition: dco_win.c:257
multi_context
Main OpenVPN server state structure.
Definition: multi.h:155
cipher_kt_key_size
int cipher_kt_key_size(const char *ciphername)
Returns the size of keys used by the cipher, in bytes.
Definition: crypto_openssl.c:658
dco.h
event_set
Definition: event.h:124
dco_del_key
int dco_del_key(dco_context_t *dco, unsigned int peerid, dco_key_slot_t slot)
Definition: dco_win.c:336
dco_swap_keys
int dco_swap_keys(dco_context_t *dco, unsigned int peer_id)
Definition: dco_win.c:345
dco_freebsd.h
tuntap::dco
dco_context_t dco
Definition: tun.h:234
OVPN_DEL_PEER
#define OVPN_DEL_PEER
Definition: ovpn_dco_freebsd.h:59
context_2::dco_read_bytes
counter_type dco_read_bytes
Definition: openvpn.h:270
OVPN_DEL_REASON_TIMEOUT
@ OVPN_DEL_REASON_TIMEOUT
Definition: ovpn_dco_freebsd.h:44
tuntap
Definition: tun.h:171
config.h
ssl_common.h
OVPN_CMD_SWAP_KEYS
@ OVPN_CMD_SWAP_KEYS
Definition: ovpn_dco_linux.h:44
dco_get_peer_stats_multi
int dco_get_peer_stats_multi(dco_context_t *dco, struct multi_context *m)
Definition: dco_win.c:426
OVPN_SET_IFMODE
#define OVPN_SET_IFMODE
Definition: ovpn_dco_freebsd.h:69
OVPN_NEW_PEER
struct _OVPN_NEW_PEER OVPN_NEW_PEER
msg
#define msg(flags,...)
Definition: error.h:150
tuntap::topology
int topology
Definition: tun.h:177
multi_instance::context
struct context context
The context structure storing state for this VPN tunnel.
Definition: multi.h:136
ALLOC_OBJ_GC
#define ALLOC_OBJ_GC(dptr, type, gc)
Definition: buffer.h:1098
OVPN_NOTIF_DEL_PEER
@ OVPN_NOTIF_DEL_PEER
Definition: ovpn_dco_freebsd.h:38