Linux, Netlink, and Go — Part 2: generic netlink

What is generic netlink?

Generic netlink messages

  • Command (8 bits): specifies which command to issue to a generic netlink family.
  • Version (8 bits): the version of a command to issue to generic netlink.

Generic netlink families

  • nlctrl: the generic netlink controller, used to determine which generic netlink families are available. Present on all systems where generic netlink is available.
  • TASKSTATS: provides per-task and per-process statistics from the kernel to userspace.
  • nl80211: provides access to IEEE 802.11 WiFi device statistics and interactions.

nlctrl: the generic netlink controller

msg := netlink.Message{
Header: netlink.Header{
// Specify nlctrl's type (0x10) to communicate with it.
Type: genetlink.Controller,
Flags: netlink.HeaderFlagsRequest | netlink.HeaderFlagsDump,
// Some fields omitted for brevity.
// The generic netlink header and data are wrapped in a
// netlink message, marshaled into byte form.
Data: marshal(genetlink.Message{
Header: genetlink.Header{
Command: ctrlCommandGetFamily,
Version: ctrlVersion,
// Used in Data field of genetlink.Message.
b := netlink.MarshalAttributes([]netlink.Attribute{{
Type: attrFamilyName,
// Null-terminated string in byte form.
Data: nlenc.Bytes("nl80211"),

Generic netlink family attributes

  • ID (16 bits): unique identifier for family. Note: ID may change between reboots or if certain kernel modules are loaded or unloaded. Always perform a lookup by name to retrieve a family’s ID!
  • Name (null-terminated string): human-readable name for the family, like “nlctrl”, “TASKSTATS”, or “nl80211”.
  • Version (32 bits): version of generic netlink family. Oddly, this field is 32 bits while the version field in the generic netlink header is 8 bits. I have never seen this value occupy more than 8 bits.
  • Multicast groups (nested attributes): netlink attribute “array” with attribute type incremented by one for each element. Contains additional nested attributes with multicast group name (null-terminated string) and ID (32 bits).


$ genl-ctrl-list
0x0010 nlctrl version 2
0x0011 VFS_DQUOT version 1
0x0013 NLBL_MGMT version 3
0x0014 NLBL_CIPSOv4 version 3
0x0015 NLBL_UNLBL version 3
0x0016 acpi_event version 1
0x0017 thermal_event version 1
0x0018 tcp_metrics version 1
0x0019 TASKSTATS version 1
0x001a nl80211 version 1





No longer active here, please see Thanks!

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Basics of Gradle DSL with Kotlin

{UPDATE} Escape Race EDM Hack Free Resources Generator

Is Test Case Obsolete In Modern Testing — Tentamen Software Testing Blog

Day 15 — Determining How Long Power-up Effects Should Last

Why I Decided to Study Software Engineering.

Our journey from Rails to React, part 1: Atomic Design (ubiquitous language in the frontend)

A dog in a lab doing some science experiments

Converting a video to a GIF on a local machine

Photo by Daria Shevtsova from Pexels

Metarun Game Update: Alpha Build v.1.01 is Here

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Matt Layher

Matt Layher

No longer active here, please see Thanks!

More from Medium

Webapp + Nginx and SSL in Docker Compose

Efficient ways to call .env

Binary protection using go embed and plugins

File-Driven API testing in Golang, the unconventional way