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 
223  snprintf(tt->dco.ifname, IFNAMSIZ, "%s", ifr.ifr_data);
224 
225  ret = ioctl(tt->dco.fd, SIOCSIFNAME, &ifr);
226  if (ret)
227  {
228  ret = -errno;
229  /* Delete the created interface again. */
230  (void)ioctl(tt->dco.fd, SIOCIFDESTROY, &ifr);
231  msg(M_WARN|M_ERRNO, "Failed to create interface %s (SIOCSIFNAME)", ifr.ifr_data);
232  return ret;
233  }
234 
235  return 0;
236 }
237 
238 static int
239 remove_interface(struct tuntap *tt)
240 {
241  int ret;
242  struct ifreq ifr;
243 
244  CLEAR(ifr);
245  snprintf(ifr.ifr_name, IFNAMSIZ, "%s", tt->dco.ifname);
246 
247  ret = ioctl(tt->dco.fd, SIOCIFDESTROY, &ifr);
248  if (ret)
249  {
250  msg(M_ERR | M_ERRNO, "Failed to remove interface %s", ifr.ifr_name);
251  }
252 
253  tt->dco.ifname[0] = 0;
254 
255  return ret;
256 }
257 
258 int
259 open_tun_dco(struct tuntap *tt, openvpn_net_ctx_t *ctx, const char *dev)
260 {
261  int ret = create_interface(tt, dev);
262 
263  if (ret >= 0 || ret == -EEXIST)
264  {
265  /* see "Interface Flags" in ifnet(9) */
266  int i = IFF_POINTOPOINT | IFF_MULTICAST;
267  if (tt->topology == TOP_SUBNET)
268  {
269  i = IFF_BROADCAST | IFF_MULTICAST;
270  }
271  dco_set_ifmode(&tt->dco, i);
272  }
273 
274  return ret;
275 }
276 
277 void
278 close_tun_dco(struct tuntap *tt, openvpn_net_ctx_t *ctx)
279 {
280  remove_interface(tt);
281  close_fd(&tt->dco);
282 }
283 
284 int
285 dco_swap_keys(dco_context_t *dco, unsigned int peerid)
286 {
287  struct ifdrv drv;
288  nvlist_t *nvl;
289  int ret;
290 
291  msg(D_DCO_DEBUG, "%s: peer-id %d", __func__, peerid);
292 
293  nvl = nvlist_create(0);
294  nvlist_add_number(nvl, "peerid", peerid);
295 
296  CLEAR(drv);
297  snprintf(drv.ifd_name, IFNAMSIZ, "%s", dco->ifname);
298  drv.ifd_cmd = OVPN_SWAP_KEYS;
299  drv.ifd_data = nvlist_pack(nvl, &drv.ifd_len);
300 
301  ret = ioctl(dco->fd, SIOCSDRVSPEC, &drv);
302  if (ret)
303  {
304  msg(M_WARN | M_ERRNO, "Failed to swap keys");
305  }
306 
307  free(drv.ifd_data);
308  nvlist_destroy(nvl);
309 
310  return ret;
311 }
312 
313 int
314 dco_del_peer(dco_context_t *dco, unsigned int peerid)
315 {
316  struct ifdrv drv;
317  nvlist_t *nvl;
318  int ret;
319 
320  msg(D_DCO_DEBUG, "%s: peer-id %d", __func__, peerid);
321 
322  nvl = nvlist_create(0);
323  nvlist_add_number(nvl, "peerid", peerid);
324 
325  CLEAR(drv);
326  snprintf(drv.ifd_name, IFNAMSIZ, "%s", dco->ifname);
327  drv.ifd_cmd = OVPN_DEL_PEER;
328  drv.ifd_data = nvlist_pack(nvl, &drv.ifd_len);
329 
330  ret = ioctl(dco->fd, SIOCSDRVSPEC, &drv);
331  if (ret)
332  {
333  msg(M_WARN | M_ERRNO, "Failed to delete peer");
334  }
335 
336  free(drv.ifd_data);
337  nvlist_destroy(nvl);
338 
339  return ret;
340 }
341 
342 int
343 dco_del_key(dco_context_t *dco, unsigned int peerid,
344  dco_key_slot_t slot)
345 {
346  struct ifdrv drv;
347  nvlist_t *nvl;
348  int ret;
349 
350  msg(D_DCO_DEBUG, "%s: peer-id %d, slot %d", __func__, peerid, slot);
351 
352  nvl = nvlist_create(0);
353  nvlist_add_number(nvl, "slot", slot);
354  nvlist_add_number(nvl, "peerid", peerid);
355 
356  CLEAR(drv);
357  snprintf(drv.ifd_name, IFNAMSIZ, "%s", dco->ifname);
358  drv.ifd_cmd = OVPN_DEL_KEY;
359  drv.ifd_data = nvlist_pack(nvl, &drv.ifd_len);
360 
361  ret = ioctl(dco->fd, SIOCSDRVSPEC, &drv);
362  if (ret)
363  {
364  msg(M_WARN | M_ERRNO, "Failed to delete key");
365  }
366 
367  free(drv.ifd_data);
368  nvlist_destroy(nvl);
369 
370  return ret;
371 }
372 
373 static nvlist_t *
374 key_to_nvlist(const uint8_t *key, const uint8_t *implicit_iv, const char *ciphername)
375 {
376  nvlist_t *nvl;
377  size_t key_len;
378 
379  nvl = nvlist_create(0);
380 
381  nvlist_add_string(nvl, "cipher", ciphername);
382 
383  if (strcmp(ciphername, "none") != 0)
384  {
385  key_len = cipher_kt_key_size(ciphername);
386 
387  nvlist_add_binary(nvl, "key", key, key_len);
388  nvlist_add_binary(nvl, "iv", implicit_iv, 8);
389  }
390 
391  return (nvl);
392 }
393 
394 static int
395 start_tun(dco_context_t *dco)
396 {
397  struct ifdrv drv;
398  int ret;
399 
400  CLEAR(drv);
401  snprintf(drv.ifd_name, IFNAMSIZ, "%s", dco->ifname);
402  drv.ifd_cmd = OVPN_START_VPN;
403 
404  ret = ioctl(dco->fd, SIOCSDRVSPEC, &drv);
405  if (ret)
406  {
407  msg(M_ERR | M_ERRNO, "Failed to start vpn");
408  }
409 
410  return ret;
411 }
412 
413 int
414 dco_new_key(dco_context_t *dco, unsigned int peerid, int keyid,
415  dco_key_slot_t slot,
416  const uint8_t *encrypt_key, const uint8_t *encrypt_iv,
417  const uint8_t *decrypt_key, const uint8_t *decrypt_iv,
418  const char *ciphername)
419 {
420  struct ifdrv drv;
421  nvlist_t *nvl;
422  int ret;
423 
424  msg(D_DCO_DEBUG, "%s: slot %d, key-id %d, peer-id %d, cipher %s",
425  __func__, slot, keyid, peerid, ciphername);
426 
427  nvl = nvlist_create(0);
428 
429  nvlist_add_number(nvl, "slot", slot);
430  nvlist_add_number(nvl, "keyid", keyid);
431  nvlist_add_number(nvl, "peerid", peerid);
432 
433  nvlist_add_nvlist(nvl, "encrypt",
434  key_to_nvlist(encrypt_key, encrypt_iv, ciphername));
435  nvlist_add_nvlist(nvl, "decrypt",
436  key_to_nvlist(decrypt_key, decrypt_iv, ciphername));
437 
438  CLEAR(drv);
439  snprintf(drv.ifd_name, IFNAMSIZ, "%s", dco->ifname);
440  drv.ifd_cmd = OVPN_NEW_KEY;
441  drv.ifd_data = nvlist_pack(nvl, &drv.ifd_len);
442 
443  ret = ioctl(dco->fd, SIOCSDRVSPEC, &drv);
444  if (ret)
445  {
446  msg(M_ERR | M_ERRNO, "Failed to set key");
447  }
448  else
449  {
450  ret = start_tun(dco);
451  }
452 
453  free(drv.ifd_data);
454  nvlist_destroy(nvl);
455 
456  return ret;
457 }
458 
459 int
460 dco_set_peer(dco_context_t *dco, unsigned int peerid,
461  int keepalive_interval, int keepalive_timeout,
462  int mss)
463 {
464  struct ifdrv drv;
465  nvlist_t *nvl;
466  int ret;
467 
468  msg(D_DCO_DEBUG, "%s: peer-id %d, ping interval %d, ping timeout %d",
469  __func__, peerid, keepalive_interval, keepalive_timeout);
470 
471  nvl = nvlist_create(0);
472  nvlist_add_number(nvl, "peerid", peerid);
473  nvlist_add_number(nvl, "interval", keepalive_interval);
474  nvlist_add_number(nvl, "timeout", keepalive_timeout);
475 
476  CLEAR(drv);
477  snprintf(drv.ifd_name, IFNAMSIZ, "%s", dco->ifname);
478  drv.ifd_cmd = OVPN_SET_PEER;
479  drv.ifd_data = nvlist_pack(nvl, &drv.ifd_len);
480 
481  ret = ioctl(dco->fd, SIOCSDRVSPEC, &drv);
482  if (ret)
483  {
484  msg(M_WARN | M_ERRNO, "Failed to set keepalive");
485  }
486 
487  free(drv.ifd_data);
488  nvlist_destroy(nvl);
489 
490  return ret;
491 }
492 
493 int
495 {
496  struct ifdrv drv;
497  uint8_t buf[4096];
498  nvlist_t *nvl;
499  enum ovpn_notif_type type;
500  int ret;
501 
502  /* Flush any pending data from the pipe. */
503  (void)read(dco->pipefd[1], buf, sizeof(buf));
504 
505  CLEAR(drv);
506  snprintf(drv.ifd_name, IFNAMSIZ, "%s", dco->ifname);
507  drv.ifd_cmd = OVPN_GET_PKT;
508  drv.ifd_data = buf;
509  drv.ifd_len = sizeof(buf);
510 
511  ret = ioctl(dco->fd, SIOCGDRVSPEC, &drv);
512  if (ret)
513  {
514  msg(M_WARN | M_ERRNO, "Failed to read control packet");
515  return -errno;
516  }
517 
518  nvl = nvlist_unpack(buf, drv.ifd_len, 0);
519  if (!nvl)
520  {
521  msg(M_WARN, "Failed to unpack nvlist");
522  return -EINVAL;
523  }
524 
525  dco->dco_message_peer_id = nvlist_get_number(nvl, "peerid");
526 
527  type = nvlist_get_number(nvl, "notification");
528  switch (type)
529  {
530  case OVPN_NOTIF_DEL_PEER:
531  dco->dco_del_peer_reason = OVPN_DEL_PEER_REASON_EXPIRED;
532 
533  if (nvlist_exists_number(nvl, "del_reason"))
534  {
535  uint32_t reason = nvlist_get_number(nvl, "del_reason");
536  if (reason == OVPN_DEL_REASON_TIMEOUT)
537  {
538  dco->dco_del_peer_reason = OVPN_DEL_PEER_REASON_EXPIRED;
539  }
540  else
541  {
542  dco->dco_del_peer_reason = OVPN_DEL_PEER_REASON_USERSPACE;
543  }
544  }
545 
546  if (nvlist_exists_nvlist(nvl, "bytes"))
547  {
548  const nvlist_t *bytes = nvlist_get_nvlist(nvl, "bytes");
549 
550  dco->dco_read_bytes = nvlist_get_number(bytes, "in");
551  dco->dco_write_bytes = nvlist_get_number(bytes, "out");
552  }
553 
554  dco->dco_message_type = OVPN_CMD_DEL_PEER;
555  break;
556 
558  dco->dco_message_type = OVPN_CMD_SWAP_KEYS;
559  break;
560 
561  default:
562  msg(M_WARN, "Unknown kernel notification %d", type);
563  break;
564  }
565 
566  nvlist_destroy(nvl);
567 
568  return 0;
569 }
570 
571 bool
572 dco_available(int msglevel)
573 {
574  struct if_clonereq ifcr;
575  char *buf = NULL;
576  int fd;
577  int ret;
578  bool available = false;
579 
580  /* Attempt to load the module. Ignore errors, because it might already be
581  * loaded, or built into the kernel. */
582  (void)kldload("if_ovpn");
583 
584  fd = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
585  if (fd < 0)
586  {
587  return false;
588  }
589 
590  CLEAR(ifcr);
591 
592  /* List cloners and check if openvpn is there. That tells us if this kernel
593  * supports if_ovpn (i.e. DCO) or not. */
594  ret = ioctl(fd, SIOCIFGCLONERS, &ifcr);
595  if (ret != 0)
596  {
597  goto out;
598  }
599 
600  buf = malloc(ifcr.ifcr_total * IFNAMSIZ);
601  if (!buf)
602  {
603  goto out;
604  }
605 
606  ifcr.ifcr_count = ifcr.ifcr_total;
607  ifcr.ifcr_buffer = buf;
608  ret = ioctl(fd, SIOCIFGCLONERS, &ifcr);
609  if (ret != 0)
610  {
611  goto out;
612  }
613 
614  for (int i = 0; i < ifcr.ifcr_total; i++)
615  {
616  if (strcmp(buf + (i * IFNAMSIZ), "openvpn") == 0)
617  {
618  available = true;
619  goto out;
620  }
621  }
622 
623 out:
624  free(buf);
625  close(fd);
626 
627  return available;
628 }
629 
630 const char *
631 dco_version_string(struct gc_arena *gc)
632 {
633  struct utsname *uts;
634  ALLOC_OBJ_GC(uts, struct utsname, gc);
635 
636  if (uname(uts) != 0)
637  {
638  return "N/A";
639  }
640 
641  return uts->version;
642 }
643 
644 void
645 dco_event_set(dco_context_t *dco, struct event_set *es, void *arg)
646 {
647  struct ifdrv drv;
648  nvlist_t *nvl;
649  uint8_t buf[128];
650  int ret;
651 
652  if (!dco || !dco->open)
653  {
654  return;
655  }
656 
657  CLEAR(drv);
658  snprintf(drv.ifd_name, IFNAMSIZ, "%s", dco->ifname);
659  drv.ifd_cmd = OVPN_POLL_PKT;
660  drv.ifd_len = sizeof(buf);
661  drv.ifd_data = buf;
662 
663  ret = ioctl(dco->fd, SIOCGDRVSPEC, &drv);
664  if (ret)
665  {
666  msg(M_WARN | M_ERRNO, "Failed to poll for packets");
667  return;
668  }
669 
670  nvl = nvlist_unpack(buf, drv.ifd_len, 0);
671  if (!nvl)
672  {
673  msg(M_WARN, "Failed to unpack nvlist");
674  return;
675  }
676 
677  if (nvlist_get_number(nvl, "pending") > 0)
678  {
679  (void)write(dco->pipefd[0], " ", 1);
680  event_ctl(es, dco->pipefd[1], EVENT_READ, arg);
681  }
682 
683  nvlist_destroy(nvl);
684 }
685 
686 static void
687 dco_update_peer_stat(struct multi_context *m, uint32_t peerid, const nvlist_t *nvl)
688 {
689 
690  if (peerid >= m->max_clients || !m->instances[peerid])
691  {
692  msg(M_WARN, "dco_update_peer_stat: invalid peer ID %d returned by kernel", peerid);
693  return;
694  }
695 
696  struct multi_instance *mi = m->instances[peerid];
697 
698  mi->context.c2.dco_read_bytes = nvlist_get_number(nvl, "in");
699  mi->context.c2.dco_write_bytes = nvlist_get_number(nvl, "out");
700 }
701 
702 int
704 {
705 
706  struct ifdrv drv;
707  uint8_t *buf = NULL;
708  size_t buf_size = 4096;
709  nvlist_t *nvl;
710  const nvlist_t *const *nvpeers;
711  size_t npeers;
712  int ret;
713 
714  if (!dco || !dco->open)
715  {
716  return 0;
717  }
718 
719  CLEAR(drv);
720  snprintf(drv.ifd_name, IFNAMSIZ, "%s", dco->ifname);
721  drv.ifd_cmd = OVPN_GET_PEER_STATS;
722 
723 retry:
724  buf = realloc(buf, buf_size);
725  drv.ifd_len = buf_size;
726  drv.ifd_data = buf;
727 
728  ret = ioctl(dco->fd, SIOCGDRVSPEC, &drv);
729  if (ret && errno == ENOSPC)
730  {
731  buf_size *= 2;
732  goto retry;
733  }
734 
735  if (ret)
736  {
737  free(buf);
738  msg(M_WARN | M_ERRNO, "Failed to get peer stats");
739  return -EINVAL;
740  }
741 
742  nvl = nvlist_unpack(buf, drv.ifd_len, 0);
743  free(buf);
744  if (!nvl)
745  {
746  msg(M_WARN, "Failed to unpack nvlist");
747  return -EINVAL;
748  }
749 
750  if (!nvlist_exists_nvlist_array(nvl, "peers"))
751  {
752  /* no peers */
753  return 0;
754  }
755 
756  nvpeers = nvlist_get_nvlist_array(nvl, "peers", &npeers);
757  for (size_t i = 0; i < npeers; i++)
758  {
759  const nvlist_t *peer = nvpeers[i];
760  uint32_t peerid = nvlist_get_number(peer, "peerid");
761 
762  dco_update_peer_stat(m, peerid, nvlist_get_nvlist(peer, "bytes"));
763  }
764 
765  return 0;
766 }
767 
768 int
769 dco_get_peer_stats(struct context *c)
770 {
771  /* Not implemented. */
772  return 0;
773 }
774 
775 const char *
777 {
778  return "none:AES-256-GCM:AES-192-GCM:AES-128-GCM:CHACHA20-POLY1305";
779 }
780 
781 #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:94
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:195
read
@ read
Definition: interactive.c:218
tun.h
OVPN_GET_PEER_STATS
#define OVPN_GET_PEER_STATS
Definition: ovpn_dco_freebsd.h:70
write
@ write
Definition: interactive.c:219
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:91
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:105
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:679
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:144
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:1097
OVPN_NOTIF_DEL_PEER
@ OVPN_NOTIF_DEL_PEER
Definition: ovpn_dco_freebsd.h:38