Skip to content
  • Thomas Haller's avatar
    core/platform: add support for TUN/TAP netlink support and various cleanup · 39ab38a0
    Thomas Haller authored
    Kernel recently got support for exposing TUN/TAP information on netlink
    [1], [2], [3]. Add support for it to the platform cache.
    
    The advantage of using netlink is that querying sysctl bypasses the
    order of events of the netlink socket. It is out of sync and racy. For
    example, platform cache might still think that a tun device exists, but
    a subsequent lookup at sysfs might fail because the device was deleted
    in the meantime. Another point is, that we don't get change
    notifications via sysctl and that it requires various extra syscalls
    to read the device information. If the tun information is present on
    netlink, put it into the cache. This bypasses checking sysctl while
    we keep looking at sysctl for backward compatibility until we require
    support from kernel.
    
    Notes:
    
    - we had two link types NM_LINK_TYPE_TAP and NM_LINK_TYPE_TUN. This
      deviates from the model of how kernel treats TUN/TAP devices, which
      makes it more complicated. The link type of a NMPlatformLink instance
      should match what kernel thinks about the device. Point in case,
      when parsing RTM_NETLINK messages, we very early need to determine
      the link type (_linktype_get_type()). However, to determine the
      type of a TUN/TAP at that point, we need to look into nested
      netlink attributes which in turn depend on the type (IFLA_INFO_KIND
      and IFLA_INFO_DATA), or even worse, we would need to look into
      sysctl for older kernel vesions. Now, the TUN/TAP type is a property
      of the link type NM_LINK_TYPE_TUN, instead of determining two
      different link types.
    
    - various parts of the API (both kernel's sysctl vs. netlink) and
      NMDeviceTun vs. NMSettingTun disagree whether the PI is positive
      (NM_SETTING_TUN_PI, IFLA_TUN_PI, NMPlatformLnkTun.pi) or inverted
      (NM_DEVICE_TUN_NO_PI, IFF_NO_PI). There is no consistent way,
      but prefer the positive form for internal API at NMPlatformLnkTun.pi.
    
    - previously NMDeviceTun.mode could not change after initializing
      the object. Allow for that to happen, because forcing some properties
      that are reported by kernel to not change is wrong, in case they
      might change. Of course, in practice kernel doesn't allow the device
      to ever change its type, but the type property of the NMDeviceTun
      should not make that assumption, because, if it actually changes, what
      would it mean?
    
    - note that as of now, new netlink API is not yet merged to mainline Linus
      tree. Shortcut _parse_lnk_tun() to not accidentally use unstable API
      for now.
    
    [1] https://bugzilla.redhat.com/show_bug.cgi?id=1277457
    [2] https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git/commit/?id=1ec010e705934c8acbe7dbf31afc81e60e3d828b
    [3] https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=118eda77d6602616bc523a17ee45171e879d1818
    
    https://bugzilla.redhat.com/show_bug.cgi?id=1547213
    https://github.com/NetworkManager/NetworkManager/pull/77
    39ab38a0