--- openvpn-2.4.7/src/openvpn/init.c.orig	2019-02-20 12:28:23 UTC
+++ openvpn-2.4.7/src/openvpn/init.c	2019-04-10 20:25:23 UTC
@@ -3296,6 +3296,9 @@
 #endif
                             c->options.ce.bind_local,
                             c->options.ce.remote_float,
+#if defined(TARGET_FREEBSD)
+                            c->options.ce.fib,
+#endif
                             c->options.inetd,
                             &c->c1.link_socket_addr,
                             c->options.ipchange,
--- openvpn-2.4.7/src/openvpn/options.c.orig	2019-02-20 12:28:23 UTC
+++ openvpn-2.4.7/src/openvpn/options.c	2019-04-10 20:25:23 UTC
@@ -169,6 +169,9 @@
     " or --socks-proxy"
     " is used).\n"
     "--nobind        : Do not bind to local address and port.\n"
+#if defined(TARGET_FREEBSD)
+    "--fib n         : Set specific forwarding information base (FreeBSD).\n"
+#endif
     "--dev tunX|tapX : tun/tap device (X can be omitted for dynamic device.\n"
     "--dev-type dt   : Which device type are we using? (dt = tun or tap) Use\n"
     "                  this option only if the tun/tap device used with --dev\n"
@@ -1446,6 +1449,9 @@
 
     SHOW_INT(mtu_discover_type);
 
+#if defined(TARGET_FREEBSD)
+    SHOW_INT(fib);
+#endif
 #ifdef ENABLE_FRAGMENT
     SHOW_INT(fragment);
 #endif
@@ -5887,6 +5893,13 @@
         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_CONNECTION);
         options->ce.bind_local = false;
     }
+#if defined(TARGET_FREEBSD)
+    else if (streq(p[0], "fib") && p[1] && !p[2])
+    {
+        VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_CONNECTION);
+        options->ce.fib = atoi(p[1]);
+    }
+#endif
     else if (streq(p[0], "fast-io") && !p[1])
     {
         VERIFY_PERMISSION(OPT_P_GENERAL);
--- openvpn-2.4.7/src/openvpn/options.h.orig	2019-02-20 12:28:23 UTC
+++ openvpn-2.4.7/src/openvpn/options.h	2019-04-10 20:25:23 UTC
@@ -116,6 +116,9 @@
     /* Advanced MTU negotiation and datagram fragmentation options */
     int mtu_discover_type; /* used if OS supports setting Path MTU discovery options on socket */
 
+#if defined(TARGET_FREEBSD)
+    int fib;
+#endif
     int fragment;        /* internal fragmentation size */
     int mssfix;          /* Upper bound on TCP MSS */
     bool mssfix_default; /* true if --mssfix was supplied without a parameter */
@@ -308,6 +311,10 @@
     int gremlin;
 #endif
 
+#if defined(TARGET_FREEBSD)
+    int fib;
+#endif
+
     const char *status_file;
     int status_file_version;
     int status_file_update_freq;
--- openvpn-2.4.7/src/openvpn/socket.c.orig	2019-02-20 12:28:23 UTC
+++ openvpn-2.4.7/src/openvpn/socket.c	2019-04-10 20:25:23 UTC
@@ -1127,6 +1127,21 @@
     {
         ASSERT(0);
     }
+#if defined(TARGET_FREEBSD)
+    if (sock->fib)
+    {
+        /* Bind to more specific forwarding information base */
+        if (setsockopt (sock->sd, SOL_SOCKET, SO_SETFIB,
+                       &sock->fib, sizeof(sock->fib)) < 0)
+        {
+            msg(M_ERR, "ERROR: FreeBSD failed to fib %d", sock->fib);
+        }
+        else
+        {
+            msg(D_SOCKET_DEBUG, "FreeBSD fib: %d", sock->fib);
+        }
+    }
+#endif
     /* set socket buffers based on --sndbuf and --rcvbuf options */
     socket_set_buffers(sock->sd, &sock->socket_buffer_sizes);
 
@@ -1850,6 +1865,9 @@
 #endif
                         bool bind_local,
                         bool remote_float,
+#if defined(TARGET_FREEBSD)
+                        int fib,
+#endif
                         int inetd,
                         struct link_socket_addr *lsa,
                         const char *ipchange_command,
@@ -1880,6 +1898,10 @@
     sock->gremlin = gremlin;
 #endif
 
+#if defined(TARGET_FREEBSD)
+    sock->fib = fib;
+#endif
+
     sock->socket_buffer_sizes.rcvbuf = rcvbuf;
     sock->socket_buffer_sizes.sndbuf = sndbuf;
 
--- openvpn-2.4.7/src/openvpn/socket.h.orig	2019-02-20 12:28:23 UTC
+++ openvpn-2.4.7/src/openvpn/socket.h	2019-04-10 20:25:23 UTC
@@ -204,6 +204,9 @@
     struct socket_buffer_size socket_buffer_sizes;
 
     int mtu;                    /* OS discovered MTU, or 0 if unknown */
+#if defined(TARGET_FREEBSD)
+    int fib;
+#endif
 
 #define SF_USE_IP_PKTINFO (1<<0)
 #define SF_TCP_NODELAY (1<<1)
@@ -316,6 +319,9 @@
 #endif
                         bool bind_local,
                         bool remote_float,
+#if defined(TARGET_FREEBSD)
+                        int fib,
+#endif
                         int inetd,
                         struct link_socket_addr *lsa,
                         const char *ipchange_command,
