STRUCT GENL_FAMILY(9)
π struct genl_family β the generic netlink family glow-up π
okay so this is the Kernel API Manual page for struct genl_family, and bestie it's literally the blueprint for your generic netlink family. think of it as the main-character struct β it holds all the metadata, callbacks, and policy info the core needs to know about your family. no cap, it's iconic.
β¨ SYNOPSIS β¨
here's the whole struct, exactly as it lives in the header β don't touch the formatting, she's perfect:
struct genl_family {
unsigned int hdrsize;
char name[GENL_NAMSIZ];
unsigned int version;
unsigned int maxattr;
u8 netnsok:1;
u8 parallel_ops:1;
u8 n_ops;
u8 n_small_ops;
u8 n_split_ops;
u8 n_mcgrps;
u8 resv_start_op;
const struct nla_policy *policy;
int (*pre_doit)(const struct genl_split_ops *ops, struct sk_buff
*skb, struct genl_info *info);
void (*post_doit)(const struct genl_split_ops *ops, struct sk_buff
*skb, struct genl_info *info);
int (*bind)(int mcgrp);
void (*unbind)(int mcgrp);
const struct genl_ops * ops;
const struct genl_small_ops *small_ops;
const struct genl_split_ops *split_ops;
const struct genl_multicast_group *mcgrps;
struct module *module;
size_t sock_priv_size;
void (*sock_priv_init)(void *priv);
void (*sock_priv_destroy)(void *priv);
};
πΈ MEMBERS πΈ
every field gets its moment, so let's go through them one by one:
hdrsizeβ how many bytes of user-specific header you're rocking at the front of every message. just the length, no drama.nameβ the name of your family, stored in achar[GENL_NAMSIZ]. pick something cute but permanent.versionβ the protocol version. yes, you have to version your family. yes, it matters.maxattrβ the maximum number of attributes you support. literally the ceiling.netnsokβ set this to true if your family can handle network namespaces and should show up in all of them. one bit, big responsibility.parallel_opsβ set to true if your operations can be called in parallel and aren't synchronized by the core genetlink code. highkey a flex if you can handle it.n_opsβ the number of operations your family supports.n_small_opsβ the number of small-struct operations your family supports.n_split_opsβ the number of entries insplit_ops. heads up: with split do/dump ops, this is not the same as the number of commands. don't get it twisted.n_mcgrpsβ the number of multicast groups. count them carefully, bestie.resv_start_opβ the first operation for which reserved fields of the header can be validated and policies are required (see the description below for the full tea). new families should leave this field at zero. periodt.policyβ the netlink policy. the vibe check for your attributes.pre_doitβ this callback gets called before an operation'sdoitcallback. it can do additional, common filtering and return an error if something's off. think of it as the bouncer at the club.post_doitβ called after an operation'sdoitcallback. it may undo whateverpre_doitdid β for example, release locks. the cleanup crew. π§Ήbindβ called when a family multicast group is added to a netlink socket. it takes anint mcgrp.unbindβ called when a family multicast group is removed from a netlink socket. also takes anint mcgrp. the sad goodbye.opsβ the operations supported by this family. the classic full-struct form.small_opsβ the small-struct operations supported by this family. lean and mean.split_opsβ the split do/dump form of operation definition. very fancy, very modern.mcgrpsβ the multicast groups used by this family. where the group chat actually happens.moduleβ pointer to the owning module β set it toTHIS_MODULE. don't forget or the kernel will be confused.sock_priv_sizeβ the size of per-socket private memory. how much room your family gets to keep its own little secrets per socket.sock_priv_initβ the per-socket private memory initializer. runs when that memory gets set up.sock_priv_destroyβ the per-socket private memory destructor. runs when it's time to let go. π
π¦ DESCRIPTION π¦
okay so here's the part where it gets real. attribute policies β that's the combination of the policy and maxattr fields β can be attached at the family level or at the operation level. if both are present, the per-operation policy takes precedence. like, operation-level always wins the argument.
for operations before resv_start_op, lack of policy means the core will perform no attribute parsing or validation. literally zero. the wild west.
for newer operations, if policy is not provided, the core will reject all TLV attributes. so likeβ¦ provide a policy, bestie. unless you want your attributes to get ghosted. π»
β οΈ also: new families should leave resv_start_op at zero. that's not a suggestion, that's the instruction. don't come for me, I'm just the messenger.
π₯ SEE ALSO π₯
the whole extended fam β check out the kernel file ./include/net and these iconic structs/functions:
struct genl_multicast_group(9)struct genl_info(9)struct genl_small_ops(9)struct genl_ops(9)struct genl_split_ops(9)struct genl_dumpit_info(9)genl_info_init_ntf(9)genlmsg_iput(9)genlmsg_nlhdr(9)genlmsg_parse_deprecated(9)genlmsg_parse(9)genl_dump_check_consistent(9)genlmsg_put_reply(9)genlmsg_end(9)genlmsg_cancel(9)genlmsg_multicast_netns_filtered(9)genlmsg_multicast_netns(9)genlmsg_multicast(9)genlmsg_multicast_allns(9)genlmsg_unicast(9)genlmsg_reply(9)genlmsg_data(9)genlmsg_len(9)genlmsg_msg_size(9)genlmsg_total_size(9)genlmsg_new(9)genl_set_err(9)
source: ./include/net β’ October 2026 β’ struct genl_family(9)
and that's the page, bestie. now go build your family, set module to THIS_MODULE, and don't forget your policy. mwah. π
β¨
π¦ where this page comes from
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms