OpenVPN / ovpn-dco

OpenVPN Data Channel Offload in the linux kernel
107 stars 27 forks source link

How do you build this module in-tree? #69

Closed tabletseeker closed 1 month ago

tabletseeker commented 1 month ago

This is how it normally works, but I get compilation errors.

drivers/net/ovpn-dco/netlink.c:42:42: error: implicit declaration of function ‘NLA_POLICY_MAX_LEN’; did you mean ‘NLA_POLICY_MIN_LEN’? [-Werror=implicit-function-declaration]
   42 |         [OVPN_KEY_DIR_ATTR_CIPHER_KEY] = NLA_POLICY_MAX_LEN(U8_MAX),
      |                                          ^~~~~~~~~~~~~~~~~~
      |                                          NLA_POLICY_MIN_LEN
drivers/net/ovpn-dco/netlink.c:42:42: error: initializer element is not constant
drivers/net/ovpn-dco/netlink.c:42:42: note: (near initialization for ‘ovpn_netlink_policy_key_dir[1].type’)
drivers/net/ovpn-dco/netlink.c:41:89: warning: missing braces around initializer [-Wmissing-braces]
   41 | static const struct nla_policy ovpn_netlink_policy_key_dir[OVPN_KEY_DIR_ATTR_MAX + 1] = {
      |                                                                                         ^
drivers/net/ovpn-dco/netlink.c:76:41: error: initializer element is not constant
   76 |         [OVPN_NEW_PEER_ATTR_LOCAL_IP] = NLA_POLICY_MAX_LEN(sizeof(struct in6_addr)),
      |                                         ^~~~~~~~~~~~~~~~~~
drivers/net/ovpn-dco/netlink.c:76:41: note: (near initialization for ‘ovpn_netlink_policy_new_peer[6].type’)
drivers/net/ovpn-dco/netlink.c:70:91: warning: missing braces around initializer [-Wmissing-braces]
   70 | static const struct nla_policy ovpn_netlink_policy_new_peer[OVPN_NEW_PEER_ATTR_MAX + 1] = {
      |                                                                                           ^
  CC [M]  drivers/net/ovpn-dco/udp.o
cc1: some warnings being treated as errors
make[8]: *** [scripts/Makefile.build:244: drivers/net/ovpn-dco/netlink.o] Error 1
make[8]: *** Waiting for unfinished jobs....
drivers/net/ovpn-dco/tcp.c:180:5: warning: "LINUX_VERSION_CODE" is not defined, evaluates to 0 [-Wundef]
  180 | #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0) && RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(9, 0) && SUSE_PRODUCT_CODE < SUSE_PRODUCT(1, 15, 5, 0)
      |     ^~~~~~~~~~~~~~~~~~
drivers/net/ovpn-dco/tcp.c:180:26: warning: "KERNEL_VERSION" is not defined, evaluates to 0 [-Wundef]
  180 | #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0) && RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(9, 0) && SUSE_PRODUCT_CODE < SUSE_PRODUCT(1, 15, 5, 0)
      |                          ^~~~~~~~~~~~~~
drivers/net/ovpn-dco/tcp.c:180:40: error: missing binary operator before token "("
  180 | #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0) && RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(9, 0) && SUSE_PRODUCT_CODE < SUSE_PRODUCT(1, 15, 5, 0)
      |                                        ^
drivers/net/ovpn-dco/tcp.c:201:5: warning: "LINUX_VERSION_CODE" is not defined, evaluates to 0 [-Wundef]
  201 | #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 19, 0)
      |     ^~~~~~~~~~~~~~~~~~
drivers/net/ovpn-dco/tcp.c:201:26: warning: "KERNEL_VERSION" is not defined, evaluates to 0 [-Wundef]
  201 | #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 19, 0)
      |                          ^~~~~~~~~~~~~~
drivers/net/ovpn-dco/tcp.c:201:40: error: missing binary operator before token "("
  201 | #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 19, 0)
      |                                        ^
drivers/net/ovpn-dco/tcp.c: In function ‘ovpn_tcp_recvmsg’:
drivers/net/ovpn-dco/tcp.c:213:5: warning: "LINUX_VERSION_CODE" is not defined, evaluates to 0 [-Wundef]
  213 | #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 19, 0)
      |     ^~~~~~~~~~~~~~~~~~
drivers/net/ovpn-dco/tcp.c:213:26: warning: "KERNEL_VERSION" is not defined, evaluates to 0 [-Wundef]
  213 | #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 19, 0)
      |                          ^~~~~~~~~~~~~~
drivers/net/ovpn-dco/tcp.c:213:40: error: missing binary operator before token "("
  213 | #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 19, 0)

What's missing here?

ordex commented 1 month ago

This is an out-of-tree kernel module with some (ugly) backwards compatibility tricks applied to compiled on older kernels. It is not expected to be copied and compiled "in-tree".

Why do you want to do that? What problem are you trying to solve?

tabletseeker commented 1 month ago

Hello @ordex , thanks for the reply!

I redistribute a range of different kernels with specific in-built modules and settings for a local laptop manufacturer who ships their own version of Kali Linux. The goals are minimum size and maximum efficiency, with power management and battery life in mind.

They've been using Wireguard, but I managed to convince the owner that dco clearly offers superior performance and power efficiency. Their Li-Ion batteries come in sizes between 6000 - 9000 mAh. I've been comparing regular and heavy use graphs and (as expected) was able to achieve a 16 - 21% better battery discharge rate, which resulted in ~ 1.5 - 2 hours of additional battery life while using dco with AES-256-GCM cipher.

You guys have produced an absolutely brilliant piece of software here that finally shuts up wg users about efficiency.

I could of course build the module against every version/flavor, but hoped that it might be possible to simply include it in-tree.

ordex commented 1 month ago

I may speculate that battery efficiency probably comes from AES acceleration being implemented in HW and thus more efficient than CHACHAPOLY. But it's just a shot in the dark.

This said, the module is not shaped to be copied in tree - the idea is to build it against the kernel you want and then ship the ovpn-dco-v2.ko file along with the system.

If you truly want to do built-in, then the code needs to be massaged a bit (i.e. remove all those kernel-version dependent hacks, move missing definition directly to some header like main.h, etc..)

tabletseeker commented 1 month ago

I may speculate that battery efficiency probably comes from AES acceleration being implemented in HW and thus more efficient than CHACHAPOLY. But it's just a shot in the dark.

Yeah I've read a bunch of ChaCha vs AES articles and opinions seem to differ quite a bit. Personally, I've never really noticed a substantial real world difference until DCO. I should've mentioned that tools were used to throttle CPU frequencies and disable boost in order to preserve battery life. AES would probably still be more efficient because of native implementation, but just saying that at crawling speeds like .5 - 1.5GHZ the playing field was maybe a little more even. Without a desktop environment, power-profiles-daemon and custom tlp presets I was able to squeeze almost 20 hours of regular use with vpn enabled out of a 7000mAh laptop. That's absolutely insane.

If you truly want to do built-in, then the code needs to be massaged a bit (i.e. remove all those kernel-version dependent hacks, move missing definition directly to some header like main.h, etc..)

Thank you for the tips, I'll read up on some documentation to get a deeper understanding of the subject matter. I've already managed to compile without errors, it's just modprobe that's acting up now.

Many thanks and sorry for posting this as an issue, I wasn't aware that it was never intended to be built this way. Closing for now.

ordex commented 4 weeks ago

it's just modprobe that's acting up now

not sure why you're playing with modprobe if DCO is built-in?

In any case, I can provide some extra help if you possibly join another channel like IRC (#openvpn-devel @ libera.chat)

tabletseeker commented 4 weeks ago

Sure, thanks man!

Yeah built-in still doesn't work, but setting CONFIG_OVPN_DCO_V2=m in the config builds without errors for some reason.

make deb-pkg is needed in this case anyway, but apparently that's the only way I can make it work (so far).

Then I just run a script that inserts one of the various .config files and adds/removes stuff after every build.

I was getting this warning in the beginning after loading the module.

ovpn_dco_v2: loading out of tree module taints kernel
ovpn_dco_v2: module verification failed: signature and/or required key missing - tainting kernel

However, CONFIG_MODULE_SIG=n in the Makefile seems to fix that.

modprobe ovpn_dco_v2 does not produce any errors or warnings now.

Openvpn log shows net_iface_new: add tun0 type ovpn-dco so I'm assuming it's working, but I'm sure something will fail, since I built it, haha.

ordex commented 4 weeks ago

If you build it with '=m', why not just building with the out-of-tree repo without messing the code up? The signature thing seems to be just a warning, but it loaded. In any case, that's not something ovpn-dco-v2 specific.

tabletseeker commented 4 weeks ago

Right, I originally just wanted it in-built so that all files could be in the kernel tree, because I store them as tarballs. Building with =m or =y was both fine as long as all net modules were located in-tree at linux/drivers/net. Also makes repeated building easier without having to modify our scripts.

But.... now my curiosity has taken over and I can't sleep before figuring out why it's not compiling in-built. >.> I've been reading a bunch of documentation and think I've isolated the problem. Gonna do some trial & error runs today and report back, haha. If I figure it out I'll upload my findings so that others looking for a solution can find it here.

ordex commented 4 weeks ago

@tabletseeker I suggest to continue on IRC or on the mailing list :)