1

My objective is to have an array or list in kernel memory at all times, so that it is always accessible from kernel-space. To do this, I am using netlink sockets as recommended here. I follow this example, which shows how to send a string. I am not sure as to how to send an array of struct or list of structs in sockets.

typedef struct {
    int fiveDollarBills;
    int denDollarBills;
} Bills;

Is it possible to send a list or array using netlink?

Community
  • 1
  • 1
Alkesh
  • 61
  • 1
  • 3
  • 9
  • If all else fails, you can serialize your data and send the string – pmg Dec 14 '10 at 15:21
  • hmm...didn't think of that. Does C support serializing? Also, if i send the string, is string.h lib available in kernel space to do string comparisons? – Alkesh Dec 14 '10 at 15:42
  • I don't think, you need any special serialization support, you can just copy the contents of the structure. Both sides of the netlink socket always run on the same system, so the binary layout is more or less irrelevant. –  Dec 14 '10 at 16:57
  • @lunaryorn: Except when the kernel is 64-bit and userspace is 32-bit. – ephemient Dec 14 '10 at 19:14
  • @ephemient: Of course, I did't admittedly not think of this. But I think, we can agree, that it is a rather silly idea to build kernel-tools using another architecture than the kernel itself. –  Dec 14 '10 at 19:45
  • @lunaryorn: I disagree. And what OP is building isn't necessarily a "kernel tool". – ephemient Dec 14 '10 at 20:13
  • @ephemient: What else if not a kernel-related tool would one write atop of netlink?! After all, netlink is an IPC API between the userspace and the *kernel* ... –  Dec 14 '10 at 20:57
  • @lunaryorn: So are `open` and `read` and `write` and `ioctl`, and you don't call any random program using those to be a kernel-related tool, do you? Regardless, 32-bit `mount` and `ifconfig` and all these real "kernel-related" tools *do* work on 64-bit kernels, and I feel that is is completely reasonable to carry this level of compatibility over to any new ABIs introduced. – ephemient Dec 14 '10 at 21:52

1 Answers1

1

NetLink itself doesn't care whether the data is a string, an integer, a struct, etc. It just takes a void* and a length and copy's the data without looking at it. You can cast your struct to a void* and use sizeof to determine the length and send that data over netlink.

On the other end, you just need to get the void* and length, verify the length is what it is supposed to be, and cast the void* back to a pointer to your struct. The two important things to verify are:

  1. Both the UserSpace and KernelSpace code agree on the memory layout of the structure. This means compiling both against the same .h and making sure that the compile options are such that memory layout and alignment are the same.

  2. The Struct will be transferred as just a raw memory copy, theres no intelligence for fixing up pointers, so your struct can not contain any pointers, etc.

The other option is rather than sending the raw data accross, to "serialize" the data yourself by converting it to, from a string in a known format. This would allow you to handle more complex data structures at the expense of extra CPU and memory overhead

bdk
  • 4,769
  • 29
  • 33