]> git.ipfire.org Git - people/ms/network.git/blob - src/networkd/port.c
aff79a532a46bd35cdfdf16200298797539343ae
[people/ms/network.git] / src / networkd / port.c
1 /*#############################################################################
2 # #
3 # IPFire.org - A linux based firewall #
4 # Copyright (C) 2023 IPFire Network Development Team #
5 # #
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. #
10 # #
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. #
15 # #
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/>. #
18 # #
19 #############################################################################*/
20
21 #include <limits.h>
22 #include <net/if.h>
23 #include <stdint.h>
24 #include <stdlib.h>
25
26 #include "address.h"
27 #include "config.h"
28 #include "logging.h"
29 #include "string.h"
30 #include "port.h"
31
32 struct nw_port {
33 int nrefs;
34
35 char name[IF_NAMESIZE];
36 nw_port_type_t type;
37
38 // Configuration
39 struct nw_config *config;
40
41 // Common attributes
42 nw_address_t address;
43 };
44
45 static const struct nw_port_type_map {
46 nw_port_type_t type;
47 const char* name;
48 } nw_port_type_map[] = {
49 { NW_PORT_DUMMY, "dummy" },
50 { NW_PORT_UNKNOWN, NULL },
51 };
52
53 static nw_port_type_t nw_port_type_from_string(const char* s) {
54 const struct nw_port_type_map* map = NULL;
55
56 for (map = nw_port_type_map; *map->name; map++) {
57 if (strcmp(map->name, s) == 0)
58 return map->type;
59 }
60
61 return NW_PORT_UNKNOWN;
62 }
63
64 static void nw_port_free(struct nw_port* port) {
65 if (port->config)
66 nw_config_unref(port->config);
67
68 free(port);
69 }
70
71 static int nw_port_setup_address(struct nw_port* port) {
72 int r;
73
74 // Read ADDRESS from configuration
75 const char* s = nw_config_get(port->config, "ADDRESS");
76 if (!s) {
77 ERROR("Port %s: Address isn't set\n", port->name);
78 return 1;
79 }
80
81 // Parse the address
82 r = nw_address_from_string(&port->address, s);
83 if (r) {
84 ERROR("Port %s: Could not parse address: %m\n", port->name);
85 return r;
86 }
87
88 // XXX Do we need to check for multicast here?
89
90 return 0;
91 }
92
93 static int nw_port_setup_common(struct nw_port* port) {
94 int r;
95
96 // Address
97 r = nw_port_setup_address(port);
98 if (r)
99 return r;
100
101 return 0;
102 }
103
104 static nw_port_type_t nw_port_setup_type(struct nw_port* port) {
105 const char* type = nw_config_get(port->config, "TYPE");
106 if (!type)
107 return NW_PORT_UNKNOWN;
108
109 return nw_port_type_from_string(type);
110 }
111
112 static int nw_port_setup(struct nw_port* port) {
113 char path[PATH_MAX];
114 int r;
115
116 // Compose the path to the main configuration file
117 r = nw_path_join(path, PORT_CONFIG_DIR, port->name);
118 if (r)
119 return r;
120
121 // Initialize the configuration
122 r = nw_config_create(&port->config, path);
123 if (r)
124 return r;
125
126 // Determine type
127 port->type = nw_port_setup_type(port);
128 if (!port->type) {
129 ERROR("Could not determine type of port %s\n", port->name);
130 return 0;
131 }
132
133 // Perform some common initialization
134 r = nw_port_setup_common(port);
135 if (r)
136 return r;
137
138 // Call any custom initialization
139 switch (port->type) {
140 // These do not need any special initialization
141 case NW_PORT_DUMMY:
142 case NW_PORT_UNKNOWN:
143 break;
144 }
145
146 return 0;
147 }
148
149 int nw_port_create(struct nw_port** port, const char* name) {
150 int r;
151
152 // Allocate a new object
153 struct nw_port* p = calloc(1, sizeof(*p));
154 if (!p)
155 return 1;
156
157 // Initialize reference counter
158 p->nrefs = 1;
159
160 // Store the name
161 r = nw_string_set(p->name, name);
162 if (r)
163 goto ERROR;
164
165 // Setup the port
166 r = nw_port_setup(p);
167 if (r)
168 goto ERROR;
169
170 *port = p;
171 return 0;
172
173 ERROR:
174 nw_port_free(p);
175 return r;
176 }
177
178 struct nw_port* nw_port_ref(struct nw_port* port) {
179 port->nrefs++;
180
181 return port;
182 }
183
184 struct nw_port* nw_port_unref(struct nw_port* port) {
185 if (--port->nrefs > 0)
186 return port;
187
188 nw_port_free(port);
189 return NULL;
190 }
191
192 const char* nw_port_name(struct nw_port* port) {
193 return port->name;
194 }