]>
git.ipfire.org Git - people/ms/network.git/blob - src/networkd/links.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 <sys/queue.h>
31 struct nw_links_entry
{
34 // Link to the other entries
35 STAILQ_ENTRY(nw_links_entry
) nodes
;
43 STAILQ_HEAD(entries
, nw_links_entry
) entries
;
45 // A counter of the link entries
49 int nw_links_create(nw_links
** links
, nw_daemon
* daemon
) {
50 nw_links
* l
= calloc(1, sizeof(*l
));
54 // Store a reference to the daemon
55 l
->daemon
= nw_daemon_ref(daemon
);
57 // Initialize the reference counter
61 STAILQ_INIT(&l
->entries
);
63 // Reference the pointer
69 static void nw_links_free(nw_links
* links
) {
70 struct nw_links_entry
* entry
= NULL
;
72 while (!STAILQ_EMPTY(&links
->entries
)) {
73 entry
= STAILQ_FIRST(&links
->entries
);
75 // Dereference the zone
76 nw_link_unref(entry
->link
);
78 // Remove the entry from the list
79 STAILQ_REMOVE_HEAD(&links
->entries
, nodes
);
86 nw_daemon_unref(links
->daemon
);
89 nw_links
* nw_links_ref(nw_links
* links
) {
95 nw_links
* nw_links_unref(nw_links
* links
) {
96 if (--links
->nrefs
> 0)
103 static struct nw_links_entry
* nw_links_find_link(nw_links
* links
, const int ifindex
) {
104 struct nw_links_entry
* entry
= NULL
;
106 STAILQ_FOREACH(entry
, &links
->entries
, nodes
) {
107 if (nw_link_ifindex(entry
->link
) == ifindex
)
115 int nw_links_add_link(nw_links
* links
, struct nw_link
* link
) {
116 // Allocate a new entry
117 struct nw_links_entry
* entry
= calloc(1, sizeof(*entry
));
121 // Reference the link
122 entry
->link
= nw_link_ref(link
);
124 // Add it to the list
125 STAILQ_INSERT_TAIL(&links
->entries
, entry
, nodes
);
127 // Increment the counter
133 void nw_links_drop_link(nw_links
* links
, struct nw_link
* link
) {
134 struct nw_links_entry
* entry
= NULL
;
136 entry
= nw_links_find_link(links
, nw_link_ifindex(link
));
140 DEBUG("Dropping link %d\n", nw_link_ifindex(entry
->link
));
142 STAILQ_REMOVE(&links
->entries
, entry
, nw_links_entry
, nodes
);
145 // Drop link from all ports
146 nw_daemon_ports_walk(links
->daemon
, __nw_port_drop_link
, link
);
148 // Drop link from all zones
149 nw_daemon_zones_walk(links
->daemon
, __nw_zone_drop_link
, link
);
152 int nw_links_enumerate(nw_links
* links
) {
153 sd_netlink_message
* req
= NULL
;
154 sd_netlink_message
* res
= NULL
;
157 sd_netlink
* rtnl
= nw_daemon_get_rtnl(links
->daemon
);
161 r
= sd_rtnl_message_new_link(rtnl
, &req
, RTM_GETLINK
, 0);
165 r
= sd_netlink_message_set_request_dump(req
, 1);
169 r
= sd_netlink_call(rtnl
, req
, 0, &res
);
173 sd_netlink_message
* m
= res
;
175 // Iterate through all replies
177 r
= nw_link_process(rtnl
, m
, links
->daemon
);
180 } while ((m
= sd_netlink_message_next(m
)));
184 sd_netlink_message_unref(m
);
186 sd_netlink_message_unref(req
);
188 sd_netlink_message_unref(res
);
193 nw_link
* nw_links_get_by_ifindex(nw_links
* links
, int ifindex
) {
194 struct nw_links_entry
* entry
= NULL
;
196 entry
= nw_links_find_link(links
, ifindex
);
200 return nw_link_ref(entry
->link
);
203 nw_link
* nw_links_get_by_name(nw_links
* links
, const char* name
) {
204 struct nw_links_entry
* entry
= NULL
;
206 STAILQ_FOREACH(entry
, &links
->entries
, nodes
) {
207 const char* n
= nw_link_ifname(entry
->link
);
209 if (strcmp(name
, n
) == 0)
210 return nw_link_ref(entry
->link
);