Netlink : Multicast
In this program, you are going to learn
How to communication between kernel and user space ?
How to use user space APIs ?
How to use kernel space APIs ?
Topics in this section,
To create a socket with
socket()
,
sock_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_USER);
bind()
is used to bind a name to a socket
retval = bind(sock_fd, (struct sockaddr * )&src_addr, sizeof(src_addr));
nl_pid field of the sockaddr_nl can be filled with the calling process’ own pid.
struct sockaddr_nl src_addr;
src_addr.nl_pid = getpid();
Sending a Netlink Message
In order to send a netlink message to the kernel or other user-space processes, another struct sockaddr_nl dest_addr needs to be supplied as the destination address, the same as sending a packet with sendmsg(). If the message is destined for the kernel, both nl_pid and nl_groups should be supplied with 0.
struct sockaddr_nl dest_addr;
dest_addr.nl_pid = 0;
dest_addr.nl_groups = 0;
struct msghdr msg;
msg.msg_name = (void * )&dest_addr;
msg.msg_namelen = sizeof(dest_addr);
The netlink socket requires its own message header as well. This is for providing a common ground for netlink messages of all protocol types. Because the Linux kernel netlink core assumes the existence of the following header in each netlink message, an application must supply this header in each netlink message it sends:
struct nlmsghdr * nlh;
nlh = (struct nlmsghdr * )malloc(NLMSG_SPACE(256));
nlh->nlmsg_len = NLMSG_SPACE(256);
nlh->nlmsg_pid = getpid();
nlh->nlmsg_flags = 0;
A netlink message thus consists of nlmsghdr and the message payload. Once a message has been entered, it enters a buffer pointed to by the nlh pointer. We also can send the message to the struct msghdr msg:
struct iovec iov;
iov.iov_base = (void * )nlh;
iov.iov_len = nlh->nlmsg_len;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
After the above steps, a call to
sendmsg()
kicks out the netlink message:
retval = sendmsg(sock_fd, &msg, 0);
recvmsg
used for Receiving Netlink Messages,
retval = recvmsg(sock_fd, &msg, 0);
select()
function indicates which of the specified file descriptors is ready for reading, ready for writing, or has an error condition pending. If the specified condition is false for all of the specified file descriptors, select() blocks, up to the specified timeout interval, until the specified condition is true for at least one of the specified file descriptors or until a signal arrives that needs to be delivered.
retval = select(sock_fd + 1, &read_fds, NULL, NULL, NULL);
FD_ZERO
initializes the file descriptor set fdset to have zero bits for all file descriptors.
FD_ZERO(&read_fds);
FD_SET
sets the bit for the file descriptor fd in the file descriptor set fdset.
FD_SET(sock_fd, &read_fds);
FD_ISSET
returns a non-zero value if the bit for the file descriptor fd is set in the file descriptor set pointed to by fdset, and 0 otherwise.
FD_ISSET(sock_fd, &read_fds);
See the full program below,
1#include <linux/netlink.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <unistd.h>
5#include <string.h>
6#include <sys/types.h>
7#include <sys/socket.h>
8#include <sys/select.h>
9
10#define NETLINK_USER 25
11#define MAX_COUNT 40
12
13int main(void)
14{
15 struct sockaddr_nl src_addr, dest_addr;
16 struct nlmsghdr *nlh;
17 struct msghdr msg;
18 struct iovec iov;
19 char recv_buff[256];
20 int sock_fd, retval, count;
21
22 sock_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_USER);
23 if (sock_fd < 0) {
24 perror("socket");
25 return -1;
26 }
27
28 memset(&src_addr, 0, sizeof(src_addr));
29 src_addr.nl_family = AF_NETLINK;
30 src_addr.nl_pid = getpid(); // User-space process PID
31 src_addr.nl_groups = 0; // Unicast
32
33 retval = bind(sock_fd, (struct sockaddr *)&src_addr, sizeof(src_addr));
34 if (retval < 0) {
35 perror("bind");
36 close(sock_fd);
37 return -1;
38 }
39
40 memset(&dest_addr, 0, sizeof(dest_addr));
41 memset(&msg, 0, sizeof(msg));
42
43 dest_addr.nl_family = AF_NETLINK;
44 dest_addr.nl_pid = 0; // To kernel
45 dest_addr.nl_groups = 0;
46
47
48 fd_set read_fds;
49
50 FD_ZERO(&read_fds);
51 FD_SET(sock_fd, &read_fds);
52
53 count = 0;
54 while (count < MAX_COUNT) {
55 nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(256));
56 if (!nlh) {
57 perror("malloc");
58 close(sock_fd);
59 return -1;
60 }
61
62 nlh->nlmsg_len = NLMSG_SPACE(256);
63 nlh->nlmsg_pid = getpid();
64 nlh->nlmsg_flags = 0;
65
66 iov.iov_base = (void *)nlh;
67 iov.iov_len = nlh->nlmsg_len;
68 msg.msg_name = (void *)&dest_addr;
69 msg.msg_namelen = sizeof(dest_addr);
70 msg.msg_iov = &iov;
71 msg.msg_iovlen = 1;
72
73
74 snprintf(NLMSG_DATA(nlh), 256, "Message from user (send) %d", count);
75
76 retval = sendmsg(sock_fd, &msg, 0);
77 if (retval == -1) {
78 perror("sendmsg");
79 break;
80 }
81
82 retval = select(sock_fd + 1, &read_fds, NULL, NULL, NULL);
83 if (retval == -1) {
84 perror("select");
85 break;
86 } else if (retval) {
87 if (FD_ISSET(sock_fd, &read_fds)) {
88 memset(recv_buff, 0, sizeof(recv_buff));
89 retval = recvmsg(sock_fd, &msg, 0);
90 if (retval == -1) {
91 perror("recv");
92 break;
93 }
94 printf("Received from kernel: %s\n", (char *) NLMSG_DATA(nlh));
95 }
96 }
97 count++;
98 }
99
100 free(nlh);
101 close(sock_fd);
102
103 return 0;
104}
init_waitqueue_head
are declared and initialized.
init_waitqueue_head(&wq_r);
init_waitqueue_head(&wq_s);
wait_event_interruptible
is put to sleep (TASK_INTERRUPTIBLE) until the condition evaluates to true.
wait_event_interruptible(wq_s, wq_flag != 0);
wait_event_interruptible(wq_r, wq_flag != 0);
wake_up_interruptible
wakes up only the processes that are in interruptible sleeps. Any process that sleeps on the wait queue using a noninterruptible function or macro will continue to sleep.
wake_up_interruptible(&wq_s);
wake_up_interruptible(&wq_r);
kthread_run
is used to create and start a kernel thread.
thread = kthread_run(recv_netlink_msg_thread, NULL, "netlink_kthread");
send_thread = kthread_run(send_netlink_msg_thread, NULL, "netlink_send_kthread");
kthread_stop
is used to stop and clean up a kernel thread created with kthread_run.
kthread_stop(thread);
kthread_stop(send_thread);
kthread_should_stop
is to determine when thread should exit.
while (!kthread_should_stop())
INIT_LIST_HEAD
is used to initialize a list_head structure.
INIT_LIST_HEAD(&mesg->list);
INIT_LIST_HEAD(&msg->list);
INIT_LIST_HEAD(&send_list);
list_head
is used to initialize the list.
struct list_head(msg_list);
struct list_head(send_list);
list_for_each_entry
is used to iterate over list of given type.
list_for_each_entry(new_node, &send_list, list)
list_for_each_entry(mesg, &send_list, list)
list_for_each_entry(new_node, &msg_list, list)
list_for_each_entry(msg, &msg_list, list)
list_for_each_entry_safe
is used to iterate over list of given type safe against removal of list entry.
list_for_each_entry_safe(curr_node, next_node, &msg_list, list)
list_for_each_entry_safe(curr_node, next_node, &send_list, list)
list_add_tail
is used to add a new entry.
list_add_tail(&mesg->list, &send_list);
list_add_tail(&msg->list, &msg_list);
list_del
is used to delete entry from list.
list_del(&mesg->list);
list_del(&msg->list);
list_del(&curr_node->list);
list_del(&curr_node->list);
nlmsg_new
using this create a netlink message.
skb_out = nlmsg_new(msg_size, 0);
nlmsg_put
used to populate the message with data.
nlh = nlmsg_put(skb_out, 0, 0, NLMSG_DONE, msg_size, 0);
nlmsg_unicast
used to send the message to the user space application.
res = nlmsg_unicast(socket, skb_out, pid);
netlink_kernel_release
used to release the netlink socket created withnetlink_kernel_create
.
netlink_kernel_release(socket);
See the full program below,
1#include <linux/module.h>
2#include <linux/init.h>
3#include <linux/skbuff.h>
4#include <linux/kthread.h>
5#include <linux/sched.h>
6#include <linux/delay.h>
7#include <linux/netlink.h>
8#include <net/netlink.h>
9#include <net/net_namespace.h>
10#include <linux/list.h>
11#include <linux/slab.h>
12
13#define NETLINK_TESTFAMILY 25
14#define MAX_PAYLOAD 1024
15
16struct message {
17 char data[MAX_PAYLOAD];
18 struct list_head list;
19};
20
21struct list_head(msg_list);
22struct list_head(send_list);
23
24wait_queue_head_t wq_r;
25wait_queue_head_t wq_s;
26
27int wq_flag;
28
29static struct task_struct *thread;
30static struct task_struct *send_thread;
31struct sock *socket;
32
33static int send_netlink_msg_thread(void *arg)
34{
35 struct message *new_node;
36
37 while (!kthread_should_stop()) {
38 wait_event_interruptible(wq_s, wq_flag != 0);
39 if (wq_flag == 1) {
40 list_for_each_entry(new_node, &send_list, list) {
41 pr_info("kernel thread-1 : Sent message : %s\n", new_node->data);
42 }
43 }
44
45 if (wq_flag == 2) {
46 pr_info("Event came from exit function\n");
47 return 0;
48 }
49 wq_flag = 0;
50 msleep(5000);
51 }
52 return 0;
53}
54
55int send_netlink_msg(int pid, char *msg, int msg_size)
56{
57 struct sk_buff *skb_out;
58 struct nlmsghdr *nlh;
59 int res;
60 struct message *mesg;
61 int count = 0;
62
63 skb_out = nlmsg_new(msg_size, 0);
64 if (!skb_out) {
65 pr_err("Failed to allocate new skb\n");
66 return -1;
67 }
68
69 nlh = nlmsg_put(skb_out, 0, 0, NLMSG_DONE, msg_size, 0);
70 if (nlh == NULL) {
71 pr_err("nlmsg_put failaure\n");
72 nlmsg_free(skb_out);
73 return -1;
74 }
75
76 NETLINK_CB(skb_out).dst_group = 0;
77 strncpy(nlmsg_data(nlh), msg, msg_size);
78
79 res = nlmsg_unicast(socket, skb_out, pid);
80 if (res < 0) {
81 pr_err("Error while sending the netlink msg to the user\n");
82 return res;
83 }
84
85 mesg = kmalloc(sizeof(struct message), GFP_KERNEL);
86
87 strncpy(mesg->data, nlmsg_data(nlh), MAX_PAYLOAD);
88
89 INIT_LIST_HEAD(&mesg->list);
90 list_add_tail(&mesg->list, &send_list);
91
92 list_for_each_entry(mesg, &send_list, list) {
93 count++;
94 if (count > 50) {
95 list_del(&mesg->list);
96 kfree(mesg);
97 }
98 }
99
100 wq_flag = 2;
101 wake_up_interruptible(&wq_s);
102
103 return 0;
104}
105
106
107static int recv_netlink_msg_thread(void *arg)
108{
109 struct message *new_node;
110
111 while (!kthread_should_stop()) {
112 wait_event_interruptible(wq_r, wq_flag != 0);
113 if (wq_flag == 1) {
114 list_for_each_entry(new_node, &msg_list, list) {
115 pr_info("kernel thread-1 : Received message : %s\n", new_node->data);
116 }
117 }
118
119 if (wq_flag == 2) {
120 pr_info("Event came from exit function\n");
121 return 0;
122 }
123 wq_flag = 0;
124 msleep(5000);
125 }
126 return 0;
127}
128
129
130static void recv_netlink_msg(struct sk_buff *skb)
131{
132 struct nlmsghdr *nlh;
133 struct message *msg;
134 int pid;
135 int count = 0;
136
137 nlh = (struct nlmsghdr *) skb->data;
138 msg = kmalloc(sizeof(struct message), GFP_KERNEL);
139 if (!msg) {
140 pr_err("Failed to allocate memory\n");
141 return;
142 }
143 pid = nlh->nlmsg_pid;
144 strscpy(msg->data, nlmsg_data(nlh), MAX_PAYLOAD);
145
146 INIT_LIST_HEAD(&msg->list);
147 list_add_tail(&msg->list, &msg_list);
148
149 list_for_each_entry(msg, &msg_list, list) {
150 count++;
151 if (count > 50) {
152 list_del(&msg->list);
153 kfree(msg);
154 }
155 }
156
157 send_netlink_msg(pid, "Hello from kernel", strlen("Hello from kernel"));
158 wq_flag = 1;
159 wake_up_interruptible(&wq_r);
160
161}
162
163
164static int __init netlink_init(void)
165{
166 struct netlink_kernel_cfg cfg = {
167 .input = recv_netlink_msg,
168 };
169
170 INIT_LIST_HEAD(&msg_list);
171 INIT_LIST_HEAD(&send_list);
172
173 socket = netlink_kernel_create(&init_net, NETLINK_TESTFAMILY, &cfg);
174 if (socket == NULL)
175 return -1;
176
177 init_waitqueue_head(&wq_r);
178 init_waitqueue_head(&wq_s);
179
180 thread = kthread_run(recv_netlink_msg_thread, NULL, "netlink_kthread");
181 if (IS_ERR(thread)) {
182 pr_alert("Error in creating kernel thread\n");
183 netlink_kernel_release(socket);
184 return PTR_ERR(thread);
185 }
186
187 send_thread = kthread_run(send_netlink_msg_thread, NULL, "netlink_send_kthread");
188 if (IS_ERR(send_thread)) {
189 pr_alert("Error in creating kernel thread\n");
190 netlink_kernel_release(socket);
191 return PTR_ERR(send_thread);
192 }
193
194 pr_info("Netlink kernel module initialized\n");
195 return 0;
196}
197
198static void __exit netlink_exit(void)
199{
200 struct message *curr_node, *next_node;
201
202 wq_flag = 2;
203 wake_up_interruptible(&wq_r);
204 wake_up_interruptible(&wq_s);
205
206 if (thread) {
207 kthread_stop(thread);
208 thread = NULL;
209 }
210
211 if (send_thread) {
212 kthread_stop(send_thread);
213 send_thread = NULL;
214 }
215
216 list_for_each_entry_safe(curr_node, next_node, &msg_list, list) {
217 list_del(&curr_node->list);
218 kfree(curr_node);
219 }
220
221 list_for_each_entry_safe(curr_node, next_node, &send_list, list) {
222 list_del(&curr_node->list);
223 kfree(curr_node);
224 }
225
226 if (socket)
227 netlink_kernel_release(socket);
228
229 pr_info("Netlink kernel module exited\n");
230}
231
232module_init(netlink_init);
233module_exit(netlink_exit);
234
235MODULE_LICENSE("GPL");
236MODULE_AUTHOR("Linux_usr");
237MODULE_DESCRIPTION("Netlink");
1obj-m += nl_kernel.o
2all:
3 make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
4
5client:
6 gcc nl_user.c -o nl_user
7
8clean:
9 make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
10 rm nl_user
1$ make all
2
3$ sudo insmod ./nl_kernel.ko
4
5$ ./nl_user
6Received from kernel: Hello from kernel
7Received from kernel: Hello from kernel
8Received from kernel: Hello from kernel
9Received from kernel: Hello from kernel
10Received from kernel: Hello from kernel
11Received from kernel: Hello from kernel
12Received from kernel: Hello from kernel
13Received from kernel: Hello from kernel
14Received from kernel: Hello from kernel
15Received from kernel: Hello from kernel
16Received from kernel: Hello from kernel
17Received from kernel: Hello from kernel
18Received from kernel: Hello from kernel
19Received from kernel: Hello from kernel
20Received from kernel: Hello from kernel
21Received from kernel: Hello from kernel
22Received from kernel: Hello from kernel
23Received from kernel: Hello from kernel
24Received from kernel: Hello from kernel
25Received from kernel: Hello from kernel
26Received from kernel: Hello from kernel
27Received from kernel: Hello from kernel
28Received from kernel: Hello from kernel
29Received from kernel: Hello from kernel
30Received from kernel: Hello from kernel
31Received from kernel: Hello from kernel
32Received from kernel: Hello from kernel
33Received from kernel: Hello from kernel
34Received from kernel: Hello from kernel
35Received from kernel: Hello from kernel
36Received from kernel: Hello from kernel
37Received from kernel: Hello from kernel
38Received from kernel: Hello from kernel
39Received from kernel: Hello from kernel
40Received from kernel: Hello from kernel
41Received from kernel: Hello from kernel
42Received from kernel: Hello from kernel
43Received from kernel: Hello from kernel
44Received from kernel: Hello from kernel
45Received from kernel: Hello from kernel
46
47$ sudo rmmod nl_kernel
48
49$ dmesg
50[ 2066.487382] Netlink kernel module initialized
51[ 2079.443801] kernel thread-1 : Sent message : Hello from kernel
52[ 2079.443900] kernel thread-1 : Received message : Message from user (send) 0
53[ 2079.443904] kernel thread-1 : Received message : Message from user (send) 1
54[ 2084.449653] kernel thread-1 : Sent message : Hello from kernel
55[ 2084.449656] kernel thread-1 : Received message : Message from user (send) 0
56[ 2084.449659] kernel thread-1 : Received message : Message from user (send) 1
57[ 2084.449660] kernel thread-1 : Sent message : Hello from kernel
58[ 2084.449662] kernel thread-1 : Sent message : Hello from kernel
59[ 2084.449663] kernel thread-1 : Received message : Message from user (send) 2
60[ 2084.449665] kernel thread-1 : Received message : Message from user (send) 3
61[ 2084.449667] kernel thread-1 : Sent message : Hello from kernel
62[ 2084.449668] kernel thread-1 : Received message : Message from user (send) 4
63[ 2084.449670] kernel thread-1 : Received message : Message from user (send) 5
64[ 2084.449672] kernel thread-1 : Sent message : Hello from kernel
65[ 2084.449673] kernel thread-1 : Received message : Message from user (send) 6
66[ 2084.449675] kernel thread-1 : Sent message : Hello from kernel
67[ 2084.449677] kernel thread-1 : Received message : Message from user (send) 7
68[ 2084.449679] kernel thread-1 : Sent message : Hello from kernel
69[ 2084.449681] kernel thread-1 : Received message : Message from user (send) 8
70[ 2084.449683] kernel thread-1 : Sent message : Hello from kernel
71[ 2084.449685] kernel thread-1 : Received message : Message from user (send) 9
72[ 2084.449686] kernel thread-1 : Sent message : Hello from kernel
73[ 2084.449688] kernel thread-1 : Received message : Message from user (send) 10
74[ 2084.449690] kernel thread-1 : Sent message : Hello from kernel
75[ 2084.449692] kernel thread-1 : Received message : Message from user (send) 11
76[ 2084.449694] kernel thread-1 : Sent message : Hello from kernel
77[ 2084.449696] kernel thread-1 : Received message : Message from user (send) 12
78[ 2084.449698] kernel thread-1 : Sent message : Hello from kernel
79[ 2084.449699] kernel thread-1 : Received message : Message from user (send) 13
80[ 2084.449701] kernel thread-1 : Sent message : Hello from kernel
81[ 2084.449703] kernel thread-1 : Received message : Message from user (send) 14
82[ 2084.449704] kernel thread-1 : Sent message : Hello from kernel
83[ 2084.449706] kernel thread-1 : Sent message : Hello from kernel
84[ 2084.449708] kernel thread-1 : Received message : Message from user (send) 15
85[ 2084.449710] kernel thread-1 : Sent message : Hello from kernel
86[ 2084.449712] kernel thread-1 : Received message : Message from user (send) 16
87[ 2084.449714] kernel thread-1 : Sent message : Hello from kernel
88[ 2084.449716] kernel thread-1 : Received message : Message from user (send) 17
89[ 2084.449717] kernel thread-1 : Received message : Message from user (send) 18
90[ 2084.449719] kernel thread-1 : Sent message : Hello from kernel
91[ 2084.449721] kernel thread-1 : Received message : Message from user (send) 19
92[ 2084.449723] kernel thread-1 : Sent message : Hello from kernel
93[ 2084.449725] kernel thread-1 : Received message : Message from user (send) 20
94[ 2084.449726] kernel thread-1 : Sent message : Hello from kernel
95[ 2084.449728] kernel thread-1 : Received message : Message from user (send) 21
96[ 2084.449730] kernel thread-1 : Sent message : Hello from kernel
97[ 2084.449732] kernel thread-1 : Received message : Message from user (send) 22
98[ 2084.449733] kernel thread-1 : Sent message : Hello from kernel
99[ 2084.449735] kernel thread-1 : Received message : Message from user (send) 23
100[ 2084.449737] kernel thread-1 : Sent message : Hello from kernel
101[ 2084.449739] kernel thread-1 : Received message : Message from user (send) 24
102[ 2084.449741] kernel thread-1 : Sent message : Hello from kernel
103[ 2084.449743] kernel thread-1 : Received message : Message from user (send) 25
104[ 2084.449745] kernel thread-1 : Sent message : Hello from kernel
105[ 2084.449746] kernel thread-1 : Received message : Message from user (send) 26
106[ 2084.449748] kernel thread-1 : Sent message : Hello from kernel
107[ 2084.449750] kernel thread-1 : Received message : Message from user (send) 27
108[ 2084.449752] kernel thread-1 : Sent message : Hello from kernel
109[ 2084.449754] kernel thread-1 : Received message : Message from user (send) 28
110[ 2084.449756] kernel thread-1 : Sent message : Hello from kernel
111[ 2084.449758] kernel thread-1 : Received message : Message from user (send) 29
112[ 2084.449760] kernel thread-1 : Sent message : Hello from kernel
113[ 2084.449762] kernel thread-1 : Received message : Message from user (send) 30
114[ 2084.449764] kernel thread-1 : Sent message : Hello from kernel
115[ 2084.449766] kernel thread-1 : Received message : Message from user (send) 31
116[ 2084.449767] kernel thread-1 : Sent message : Hello from kernel
117[ 2084.449769] kernel thread-1 : Received message : Message from user (send) 32
118[ 2084.449771] kernel thread-1 : Sent message : Hello from kernel
119[ 2084.449773] kernel thread-1 : Received message : Message from user (send) 33
120[ 2084.449774] kernel thread-1 : Sent message : Hello from kernel
121[ 2084.449776] kernel thread-1 : Received message : Message from user (send) 34
122[ 2084.449778] kernel thread-1 : Sent message : Hello from kernel
123[ 2084.449780] kernel thread-1 : Received message : Message from user (send) 35
124[ 2084.449781] kernel thread-1 : Sent message : Hello from kernel
125[ 2084.449784] kernel thread-1 : Received message : Message from user (send) 36
126[ 2084.449786] kernel thread-1 : Sent message : Hello from kernel
127[ 2084.449787] kernel thread-1 : Received message : Message from user (send) 37
128[ 2084.449789] kernel thread-1 : Sent message : Hello from kernel
129[ 2084.449791] kernel thread-1 : Received message : Message from user (send) 38
130[ 2084.449793] kernel thread-1 : Sent message : Hello from kernel
131[ 2084.449795] kernel thread-1 : Received message : Message from user (send) 39
132[ 2084.449796] kernel thread-1 : Sent message : Hello from kernel
133[ 2084.449798] kernel thread-1 : Sent message : Hello from kernel
User Space API |
Learning |
---|---|
socket |
To create a socket |
bind |
To bind a name to a socket |
select |
To monitor the activity on a set of sockets looking for sockets ready for reading, writing, or with an exception condition pending |
FD_ZERO |
To initialize the file descriptor set fdset to have zero bits for all file descriptors |
FD_SET |
To set the bit for the file descriptor fd in the file descriptor set fdset |
FD_ISSET |
It returns a non-zero value if the bit for the file descriptor fd is set in the file descriptor set pointed to by fdset, and 0 otherwise |
sendmsg |
To send netlink message |
recvmsg |
To receive netlink message |
Kernel Space API |
Learning |
---|---|
init_waitqueue_head |
To declare and initialize |
wait_event_interruptible |
It sleep until a condition gets true |
wake_up_interruptible |
It wakes up only the processes that are in interruptible sleeps |
kthread_run |
To create and start a kernel thread |
kthread_stop |
To stop and clean up a kernel thread created with kthread_run |
kthread_should_stop |
To determine when thread should exit |
INIT_LIST_HEAD |
To initialize a list_head structure |
list_head |
To initialize the list |
list_for_each_entry |
To iterate over list of given type |
list_for_each_entry_safe |
To iterate over list of given type safe against removal of list entry |
list_add_tail |
To add a new entry |
list_del |
To delete entry from list |
nlmsg_new |
To create a netlink message |
nlmsg_put |
TO populate the message |
nlmsg_unicast |
To send the message to the user space application |
netlink_kernel_release |
To release the netlink socket |
Previous Chapters
Other Netlink topic