Skip to content

Commit fdf26dc

Browse files
committed
Initial netlink support
We now are able to know when a device is going down, handling that event is further work.
1 parent d9deae6 commit fdf26dc

File tree

4 files changed

+96
-3
lines changed

4 files changed

+96
-3
lines changed

Makefile

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
OBJ=main.o ddhcp.o netsock.o packet.o dhcp.o dhcp_packet.o dhcp_options.o tools.o block.o control.o hook.o logger.o statistics.o epoll.o
1+
OBJ=main.o ddhcp.o netsock.o packet.o dhcp.o dhcp_packet.o dhcp_options.o tools.o block.o control.o hook.o logger.o statistics.o epoll.o netlink.o
22
OBJCTL=ddhcpctl.o netsock.o packet.o dhcp.o dhcp_packet.o dhcp_options.o tools.o block.o hook.o logger.o
33
HDRS=$(wildcard *.h)
44

@@ -26,7 +26,8 @@ CFLAGS+= \
2626
-Wswitch-default \
2727
-Wswitch-enum \
2828
-Wunreachable-code \
29-
-Winit-self
29+
-Winit-self \
30+
`pkg-config --cflags libnl-3.0`
3031

3132
CXXFLAGS+= \
3233
${CFLAGS} \
@@ -36,7 +37,8 @@ CXXFLAGS+= \
3637

3738
LFLAGS+= \
3839
-flto \
39-
-lm
40+
-lm \
41+
`pkg-config --libs libnl-3.0`
4042

4143
ifeq ($(DEBUG),1)
4244
CFLAGS+= \

main.c

+4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "epoll.h"
2222
#include "hook.h"
2323
#include "logger.h"
24+
#include "netlink.h"
2425
#include "netsock.h"
2526
#include "packet.h"
2627
#include "statistics.h"
@@ -469,11 +470,13 @@ int main(int argc, char** argv) {
469470
config.sockets[SKT_MCAST] = epoll_data_new(interface, netsock_multicast_init, hdl_ddhcp_block, NULL);
470471
config.sockets[SKT_SERVER] = epoll_data_new(interface, netsock_server_init, hdl_ddhcp_dhcp, NULL);
471472
config.sockets[SKT_CONTROL] = epoll_data_new(config.control_path, netsock_control_init, hdl_ctrl_new, NULL);
473+
ddhcp_epoll_data* netlink = epoll_data_new(NULL, netlink_init, netlink_in, netlink_close);
472474

473475
// Trigger socket initializing and register to EPOLL
474476
epoll_add_fd(config.epoll_fd, config.sockets[SKT_MCAST], EPOLLIN | EPOLLET,&config);
475477
epoll_add_fd(config.epoll_fd, config.sockets[SKT_SERVER], EPOLLIN | EPOLLET,&config);
476478
epoll_add_fd(config.epoll_fd, config.sockets[SKT_CONTROL], EPOLLIN | EPOLLET,&config);
479+
epoll_add_fd(config.epoll_fd, netlink, EPOLLIN | EPOLLET,&config);
477480

478481
if (config.disable_dhcp == 0) {
479482
config.sockets[SKT_DHCP] = epoll_data_new(interface_client, netsock_dhcp_init, hdl_dhcp, NULL);
@@ -577,6 +580,7 @@ int main(int argc, char** argv) {
577580
//close(config.mcast_socket);
578581
//close(config.client_socket);
579582
//close(config.control_socket);
583+
epoll_data_call(netlink,epollhup,(&config));
580584

581585
remove(config.control_path);
582586

netlink.c

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#include <net/if.h>
2+
#include <netlink/msg.h>
3+
#include <netlink/netlink.h>
4+
#include <netlink/socket.h>
5+
6+
#include "epoll.h"
7+
#include "logger.h"
8+
#include "tools.h"
9+
#include "types.h"
10+
11+
static int callback(struct nl_msg *msg, void* vcfg) {
12+
ddhcp_config *config = (ddhcp_config*) vcfg;
13+
struct nlmsghdr* hdr = nlmsg_hdr(msg);
14+
15+
DEBUG("netlink_callback(...): callback triggered\n");
16+
17+
if (hdr->nlmsg_type == RTM_NEWLINK) {
18+
struct ifinfomsg* data = NLMSG_DATA(hdr);
19+
if (DDHCP_SKT_SERVER(config)->interface_id == data->ifi_index) {
20+
DEBUG("netlink_callback(...): action on server interface\n");
21+
}
22+
if (data->ifi_flags & IFF_UP) {
23+
DEBUG("netlink_callback(...): iface(%i) up\n",data->ifi_index);
24+
} else {
25+
DEBUG("netlink_callback(...): iface(%i) down\n",data->ifi_index);
26+
}
27+
}
28+
29+
if (hdr->nlmsg_type == RTM_DELLINK) {
30+
struct ifinfomsg* data = NLMSG_DATA(hdr);
31+
DEBUG("netlink_callback(...): iface(%i) deleted\n",data->ifi_index);
32+
}
33+
34+
return 0;
35+
}
36+
37+
ATTR_NONNULL_ALL int netlink_in(epoll_data_t data,ddhcp_config* config) {
38+
UNUSED(config);
39+
ddhcp_epoll_data* ptr = (ddhcp_epoll_data*) data.ptr;
40+
return nl_recvmsgs_default((struct nl_sock*) ptr->data);
41+
}
42+
43+
ATTR_NONNULL_ALL int netlink_init(epoll_data_t data,ddhcp_config* config) {
44+
ddhcp_epoll_data* ptr = (ddhcp_epoll_data*) data.ptr;
45+
DEBUG("netlink_init(config)\n");
46+
struct nl_sock *sock;
47+
48+
sock = nl_socket_alloc();
49+
50+
if (sock == NULL) {
51+
FATAL("netlink_init(...): Unable to open netlink socket\n");
52+
return -1;
53+
}
54+
55+
nl_socket_disable_seq_check(sock);
56+
nl_socket_set_nonblocking(sock);
57+
nl_socket_modify_cb(sock,NL_CB_VALID,NL_CB_CUSTOM,callback,(void*) config);
58+
59+
if (nl_connect(sock, NETLINK_ROUTE) < 0) {
60+
FATAL("netlink_init(...): Unable to connect to netlink route module");
61+
return -1;
62+
} else {
63+
ptr->fd = nl_socket_get_fd(sock);
64+
ptr->data = (void*) sock;
65+
}
66+
67+
nl_socket_add_memberships(sock, RTNLGRP_LINK, 0);
68+
69+
return 0;
70+
}
71+
72+
ATTR_NONNULL_ALL int netlink_close(epoll_data_t data, ddhcp_config* config) {
73+
UNUSED(config);
74+
ddhcp_epoll_data* ptr = (ddhcp_epoll_data*) data.ptr;
75+
nl_socket_free((struct nl_sock*) ptr->data);
76+
return 0;
77+
}

netlink.h

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#ifndef _NETLINK_H
2+
#define _NETLINK_H
3+
4+
#include "types.h"
5+
#include "epoll.h"
6+
7+
ATTR_NONNULL_ALL int netlink_init(epoll_data_t data,ddhcp_config* config);
8+
ATTR_NONNULL_ALL int netlink_in(epoll_data_t data,ddhcp_config* config);
9+
ATTR_NONNULL_ALL int netlink_close(epoll_data_t,ddhcp_config* config);
10+
#endif

0 commit comments

Comments
 (0)