]>
git.ipfire.org Git - people/ms/network.git/blob - src/networkd/port.c
ec40830fe11405b8585e4de652a6e5024704971a
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 #############################################################################*/
26 #include <systemd/sd-bus.h>
42 char name
[IF_NAMESIZE
];
52 static const struct nw_port_type_map
{
55 } nw_port_type_map
[] = {
56 { NW_PORT_DUMMY
, "dummy" },
57 { NW_PORT_UNKNOWN
, NULL
},
60 static nw_port_type_t
nw_port_type_from_string(const char* s
) {
61 const struct nw_port_type_map
* map
= NULL
;
63 for (map
= nw_port_type_map
; *map
->name
; map
++) {
64 if (strcmp(map
->name
, s
) == 0)
68 return NW_PORT_UNKNOWN
;
71 static void nw_port_free(nw_port
* port
) {
73 nw_link_unref(port
->link
);
75 nw_config_unref(port
->config
);
77 nw_daemon_unref(port
->daemon
);
82 static int nw_port_setup_address(nw_port
* port
) {
85 // Read ADDRESS from configuration
86 const char* s
= nw_config_get(port
->config
, "ADDRESS");
88 ERROR("Port %s: Address isn't set\n", port
->name
);
93 r
= nw_address_from_string(&port
->address
, s
);
95 ERROR("Port %s: Could not parse address: %m\n", port
->name
);
99 // Check if this address is usable
100 r
= nw_address_is_multicast(&port
->address
);
102 DEBUG("Port %s: Multicast bit is set on Ethernet address\n", port
->name
);
109 // Generate a random Ethernet address
110 r
= nw_address_generate(&port
->address
);
112 ERROR("Could not generate a random Ethernet address: %m\n");
119 static int nw_port_setup_common(nw_port
* port
) {
123 r
= nw_port_setup_address(port
);
130 static nw_port_type_t
nw_port_setup_type(nw_port
* port
) {
131 const char* type
= nw_config_get(port
->config
, "TYPE");
133 return NW_PORT_UNKNOWN
;
135 return nw_port_type_from_string(type
);
138 static int nw_port_setup(nw_port
* port
) {
143 port
->link
= nw_daemon_get_link_by_name(port
->daemon
, port
->name
);
145 DEBUG("%s: Found matching link %d\n", port
->name
, nw_link_ifindex(port
->link
));
147 DEBUG("%s: Could not find matching link\n", port
->name
);
150 // Compose the path to the main configuration file
151 r
= nw_path_join(path
, PORT_CONFIG_DIR
, port
->name
);
155 // Initialize the configuration
156 r
= nw_config_create(&port
->config
, path
);
161 port
->type
= nw_port_setup_type(port
);
163 ERROR("Could not determine type of port %s\n", port
->name
);
167 // Perform some common initialization
168 r
= nw_port_setup_common(port
);
172 // Call any custom initialization
173 switch (port
->type
) {
174 // These do not need any special initialization
176 case NW_PORT_UNKNOWN
:
183 int nw_port_create(nw_port
** port
, nw_daemon
* daemon
, const char* name
) {
186 // Allocate a new object
187 nw_port
* p
= calloc(1, sizeof(*p
));
191 // Store a reference to the daemon
192 p
->daemon
= nw_daemon_ref(daemon
);
194 // Initialize reference counter
198 r
= nw_string_set(p
->name
, name
);
203 r
= nw_port_setup(p
);
215 nw_port
* nw_port_ref(nw_port
* port
) {
221 nw_port
* nw_port_unref(nw_port
* port
) {
222 if (--port
->nrefs
> 0)
229 int nw_port_save(nw_port
* port
) {
232 r
= nw_config_write(port
->config
);
239 const char* nw_port_name(nw_port
* port
) {
243 char* nw_port_bus_path(nw_port
* port
) {
247 // Encode the bus path
248 r
= sd_bus_path_encode("/org/ipfire/network1/port", port
->name
, &p
);
255 static nw_link
* nw_port_get_link(nw_port
* port
) {
259 return nw_link_ref(port
->link
);
262 const nw_address_t
* nw_port_get_address(nw_port
* port
) {
263 return &port
->address
;
266 int nw_port_reconfigure(nw_port
* port
) {
267 return 0; // XXX TODO
270 int nw_port_has_carrier(nw_port
* port
) {
274 return nw_link_has_carrier(port
->link
);