]>
git.ipfire.org Git - people/ms/network.git/blob - src/networkd/link.c
1 /*#############################################################################
3 # IPFire.org - A linux based firewall #
4 # Copyright (C) 2023 IPFire Network Development Team #
6 # This program is free software: you can redistribute it and/or modify #
7 # it under the terms of the GNU General Public License as published by #
8 # the Free Software Foundation, either version 3 of the License, or #
9 # (at your option) any later version. #
11 # This program is distributed in the hope that it will be useful, #
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
14 # GNU General Public License for more details. #
16 # You should have received a copy of the GNU General Public License #
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
19 #############################################################################*/
24 #include <systemd/sd-netlink.h>
32 struct nw_daemon
* daemon
;
39 int nw_link_create(struct nw_link
** link
, struct nw_daemon
* daemon
, int ifindex
) {
40 // Allocate a new object
41 struct nw_link
* l
= calloc(1, sizeof(*l
));
45 // Store a reference to the daemon
46 l
->daemon
= nw_daemon_ref(daemon
);
48 // Initialize the reference counter
54 DEBUG("New link allocated (ifindex = %d)\n", l
->ifindex
);
61 static void nw_link_free(struct nw_link
* link
) {
62 DEBUG("Freeing link (ifindex = %d)\n", link
->ifindex
);
65 nw_daemon_unref(link
->daemon
);
68 struct nw_link
* nw_link_ref(struct nw_link
* link
) {
74 struct nw_link
* nw_link_unref(struct nw_link
* link
) {
75 if (--link
->nrefs
> 0)
82 int nw_link_ifindex(struct nw_link
* link
) {
86 int nw_link_process(sd_netlink
* rtnl
, sd_netlink_message
* message
, void* data
) {
87 struct nw_links
* links
= NULL
;
88 struct nw_link
* link
= NULL
;
89 const char* ifname
= NULL
;
94 struct nw_daemon
* daemon
= (struct nw_daemon
*)data
;
97 links
= nw_daemon_links(daemon
);
103 // Check if this message could be received
104 if (sd_netlink_message_is_error(message
)) {
105 r
= sd_netlink_message_get_errno(message
);
107 ERROR("Could not receive link message: %m\n");
112 // Fetch the message type
113 r
= sd_netlink_message_get_type(message
, &type
);
115 ERROR("Could not fetch message type: %m\n");
126 ERROR("Received an unexpected message (type %u)\n", type
);
130 // Fetch the interface index
131 r
= sd_rtnl_message_link_get_ifindex(message
, &ifindex
);
133 ERROR("Could not fetch ifindex: %m\n");
137 // Check interface index
139 ERROR("Received an invalid ifindex\n");
143 // Fetch the interface name
144 r
= sd_netlink_message_read_string(message
, IFLA_IFNAME
, &ifname
);
146 ERROR("Received a netlink message without interface name: %m\n");
150 // Try finding an existing link
151 link
= nw_daemon_get_link_by_ifindex(daemon
, ifindex
);
155 // If the link doesn't exist, create it
157 r
= nw_link_create(&link
, daemon
, ifindex
);
159 ERROR("Could not create link: %m\n");
163 // Add it to the list
164 r
= nw_links_add_link(links
, link
);
169 // TODO Import any data from the netlink message
175 nw_links_drop_link(links
, link
);
185 nw_links_unref(links
);