Browse code

dco: pass control packets through the socket on FreeBSD

FreeBSD allows packets to be sent through the socket even when the
if_dco driver is active, so prefer that path.

Also remove the FreeBSD dco_do_write() implementation, as this function
will never be called any more on FreeBSD. Assert this.

Signed-off-by: Kristof Provost <kprovost@netgate.com>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <20221126090851.8656-1-kprovost@netgate.com>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg25542.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>

Kristof Provost authored on 2022/11/26 18:08:51
Showing 2 changed files
... ...
@@ -536,35 +536,10 @@ dco_do_read(dco_context_t *dco)
536 536
 int
537 537
 dco_do_write(dco_context_t *dco, int peer_id, struct buffer *buf)
538 538
 {
539
-    struct ifdrv drv;
540
-    nvlist_t *nvl;
541
-    int ret;
542
-
543
-    nvl = nvlist_create(0);
544
-
545
-    nvlist_add_binary(nvl, "packet", BSTR(buf), BLEN(buf));
546
-    nvlist_add_number(nvl, "peerid", peer_id);
547
-
548
-    CLEAR(drv);
549
-    snprintf(drv.ifd_name, IFNAMSIZ, "%s", dco->ifname);
550
-    drv.ifd_cmd = OVPN_SEND_PKT;
551
-    drv.ifd_data = nvlist_pack(nvl, &drv.ifd_len);
552
-
553
-    ret = ioctl(dco->fd, SIOCSDRVSPEC, &drv);
554
-    if (ret)
555
-    {
556
-        msg(M_WARN | M_ERRNO, "Failed to send control packet");
557
-        ret = -errno;
558
-    }
559
-    else
560
-    {
561
-        ret = BLEN(buf);
562
-    }
563
-
564
-    free(drv.ifd_data);
565
-    nvlist_destroy(nvl);
566
-
567
-    return ret;
539
+    /* Control packets are passed through the socket, so this should never get
540
+     * called. See should_use_dco_socket(). */
541
+    ASSERT(0);
542
+    return -EINVAL;
568 543
 }
569 544
 
570 545
 bool
... ...
@@ -1635,20 +1635,23 @@ process_ip_header(struct context *c, unsigned int flags, struct buffer *buf)
1635 1635
     }
1636 1636
 }
1637 1637
 
1638
-/* Linux-like DCO implementations pass the socket to the kernel and
1638
+/* Linux DCO implementations pass the socket to the kernel and
1639 1639
  * disallow usage of it from userland, so (control) packets sent and
1640 1640
  * received by OpenVPN need to go through the DCO interface.
1641 1641
  *
1642 1642
  * Windows DCO needs control packets to be sent via the normal
1643 1643
  * standard Overlapped I/O.
1644 1644
  *
1645
+ * FreeBSD DCO allows control packets to pass through the socket in both
1646
+ * directions.
1647
+ *
1645 1648
  * Hide that complexity (...especially if more platforms show up
1646 1649
  * in the future...) in a small inline function.
1647 1650
  */
1648 1651
 static inline bool
1649 1652
 should_use_dco_socket(struct link_socket_actual *actual)
1650 1653
 {
1651
-#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
1654
+#if defined(TARGET_LINUX)
1652 1655
     return actual->dco_installed;
1653 1656
 #else
1654 1657
     return false;