platform: add genl socket support for events and genl family

For generic netlink, the family-id is important. It changes when
loading/unloading a module, so we should not cache it indefinitely.
To get this right, takes some effort. For "nl80211", "nl802154"
and "wireguard", we only cache the family ID in relation to an
interface. If the module gets unloaded, the family ID also becomes
irrelevant and we need to re-fetch it the next time.

For generic families like "mptcp_pm" or "ethtool", they are commonly not
kernel modules and cannot be unloaded. So caching them would be
(probably) fine.

Still. Some generic netlink families emit notifications, and it will
be interesting to be able to handle them. Since that will be useful later,
start by doing something simple: let the generic netlink family also be
cached this way. Generic netlink will send notifications when a family gets
added/deleted, and we can use that to reliably cache the family ID.

We only care about a well-known set of generic families. Unlike libnl
(which has "struct genl_family" object to handle any family), we can hard
code the few we care about (NMPGenlFamilyType).

This adds the necessary infrastructure of NMLinuxPlatform to listen to
events on the generic netlink socket.
This commit is contained in:
Thomas Haller
2022-06-21 22:01:28 +02:00
parent 355331b779
commit 3d4906a3da
3 changed files with 672 additions and 333 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -9045,6 +9045,19 @@ nm_platform_ip_address_cmp_expiry(const NMPlatformIPAddress *a, const NMPlatform
/*****************************************************************************/
guint16
nm_platform_genl_get_family_id(NMPlatform *self, NMPGenlFamilyType family_type)
{
_CHECK_SELF(self, klass, 0);
if (!_NM_INT_NOT_NEGATIVE(family_type) || family_type >= _NMP_GENL_FAMILY_TYPE_NUM)
g_return_val_if_reached(0);
return klass->genl_get_family_id(self, family_type);
}
/*****************************************************************************/
GHashTable *
nm_platform_ip4_address_addr_to_hash(NMPlatform *self, int ifindex)
{

View File

@@ -1328,6 +1328,9 @@ typedef struct {
int (*tfilter_add)(NMPlatform *self, NMPNlmFlags flags, const NMPlatformTfilter *tfilter);
int (*tfilter_delete)(NMPlatform *self, int ifindex, guint32 parent, gboolean log_error);
guint16 (*genl_get_family_id)(NMPlatform *platform, NMPGenlFamilyType family_type);
} NMPlatformClass;
/* NMPlatform signals
@@ -2531,4 +2534,8 @@ gboolean nm_platform_ip_address_match(int addr_family,
const NMPlatformIPAddress *addr,
NMPlatformMatchFlags match_flag);
/*****************************************************************************/
guint16 nm_platform_genl_get_family_id(NMPlatform *self, NMPGenlFamilyType family_type);
#endif /* __NETWORKMANAGER_PLATFORM_H__ */