1

is using struct pernet_operations and register_pernet_subsys(..) the correct way to have a state per network namespace in a Linux kernel module?

Or is there a way just mark a kernel module and it will have an independent state in each network namespace?

mwarning
  • 721
  • 5
  • 22

1 Answers1

1

Linux Kernel modules have only one state. Network namespaces need to be explicitly handled in the kernel module.

The key methods to use are register_pernet_subsys, unregister_pernet_subsys and net_generic.

Here is an example kernel module:

#include <net/sock.h>
#include <net/netns/generic.h>
#include <net/net_namespace.h>
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/pid_namespace.h>

/*
 * Per network namespace data
 */
struct ns_data {
  struct sock *sk;
};

/*
 * Index to store custom data for each network namespace.
 */
static unsigned int net_id;

/*
 * Called for every existing and added network namespaces
 */
static int __net_init ns_test_init(struct net *net)
{
  // create (if not present) and access data item in network namespace (net) using the id (net_id) 
  struct ns_data *data = net_generic(net, net_id);
  data->sk = -1; // initialize or example socket

  // ...

  return 0;
}

static void __net_exit ns_test_exit(struct net *net)
{
  // called when the network namespace is removed
  struct ns_data *data = net_generic(net, net_id);

  // close socket
  netlink_kernel_release(data->sk);
}

// callback to make the module network namespace aware
static struct pernet_operations net_ops __net_initdata = {
  .init = ns_test_init,
  .exit = ns_test_exit,
  .id = &net_id,
  .size = sizeof(struct ns_data),
};

static int __init netlink_test_init(void)
{
  printk(KERN_INFO "netlink_test: Init module\n");

  register_pernet_subsys(&net_ops);

  return 0;
}

static void __exit netlink_test_exit(void)
{
  printk(KERN_INFO "netlink_test: Exit module\n");

  unregister_pernet_subsys(&net_ops);
}

module_init(netlink_test_init);
module_exit(netlink_test_exit);

MODULE_LICENSE("GPL");
mwarning
  • 721
  • 5
  • 22