]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/network/networkd-queue.c
network: use request queue to configure bridge MDB
[thirdparty/systemd.git] / src / network / networkd-queue.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include "networkd-address.h"
4 #include "networkd-bridge-fdb.h"
5 #include "networkd-bridge-mdb.h"
6 #include "networkd-dhcp-server.h"
7 #include "networkd-manager.h"
8 #include "networkd-neighbor.h"
9 #include "networkd-nexthop.h"
10 #include "networkd-route.h"
11 #include "networkd-routing-policy-rule.h"
12 #include "networkd-queue.h"
13
14 static void request_free_object(RequestType type, void *object) {
15 switch(type) {
16 case REQUEST_TYPE_ADDRESS:
17 address_free(object);
18 break;
19 case REQUEST_TYPE_BRIDGE_FDB:
20 bridge_fdb_free(object);
21 break;
22 case REQUEST_TYPE_BRIDGE_MDB:
23 bridge_mdb_free(object);
24 break;
25 case REQUEST_TYPE_DHCP_SERVER:
26 break;
27 case REQUEST_TYPE_NEIGHBOR:
28 neighbor_free(object);
29 break;
30 case REQUEST_TYPE_NEXTHOP:
31 nexthop_free(object);
32 break;
33 case REQUEST_TYPE_ROUTE:
34 route_free(object);
35 break;
36 case REQUEST_TYPE_ROUTING_POLICY_RULE:
37 routing_policy_rule_free(object);
38 break;
39 default:
40 assert_not_reached("invalid request type.");
41 }
42 }
43
44 Request *request_free(Request *req) {
45 if (!req)
46 return NULL;
47
48 if (req->on_free)
49 req->on_free(req);
50 if (req->consume_object)
51 request_free_object(req->type, req->object);
52 if (req->link && req->link->manager)
53 ordered_set_remove(req->link->manager->request_queue, req);
54 link_unref(req->link);
55
56 return mfree(req);
57 }
58
59 DEFINE_TRIVIAL_CLEANUP_FUNC(Request*, request_free);
60
61 void request_drop(Request *req) {
62 if (req->message_counter)
63 (*req->message_counter)--;
64
65 request_free(req);
66 }
67
68 int link_queue_request(
69 Link *link,
70 RequestType type,
71 void *object,
72 bool consume_object,
73 unsigned *message_counter,
74 link_netlink_message_handler_t netlink_handler,
75 Request **ret) {
76
77 _cleanup_(request_freep) Request *req = NULL;
78 int r;
79
80 assert(link);
81 assert(link->manager);
82 assert(type >= 0 && type < _REQUEST_TYPE_MAX);
83 if (type != REQUEST_TYPE_DHCP_SERVER) {
84 assert(object);
85 assert(netlink_handler);
86 }
87
88 req = new(Request, 1);
89 if (!req) {
90 if (consume_object)
91 request_free_object(type, object);
92 return -ENOMEM;
93 }
94
95 *req = (Request) {
96 .link = link,
97 .type = type,
98 .object = object,
99 .consume_object = consume_object,
100 .message_counter = message_counter,
101 .netlink_handler = netlink_handler,
102 };
103
104 link_ref(link);
105
106 r = ordered_set_ensure_put(&link->manager->request_queue, NULL, req);
107 if (r < 0)
108 return r;
109
110 if (req->message_counter)
111 (*req->message_counter)++;
112
113 if (ret)
114 *ret = req;
115
116 TAKE_PTR(req);
117 return 0;
118 }
119
120 int manager_process_requests(sd_event_source *s, void *userdata) {
121 Manager *manager = userdata;
122 int r;
123
124 assert(manager);
125
126 for (;;) {
127 bool processed = false;
128 Request *req;
129
130 ORDERED_SET_FOREACH(req, manager->request_queue) {
131 switch(req->type) {
132 case REQUEST_TYPE_ADDRESS:
133 r = request_process_address(req);
134 break;
135 case REQUEST_TYPE_BRIDGE_FDB:
136 r = request_process_bridge_fdb(req);
137 break;
138 case REQUEST_TYPE_BRIDGE_MDB:
139 r = request_process_bridge_mdb(req);
140 break;
141 case REQUEST_TYPE_DHCP_SERVER:
142 r = request_process_dhcp_server(req);
143 break;
144 case REQUEST_TYPE_NEIGHBOR:
145 r = request_process_neighbor(req);
146 break;
147 case REQUEST_TYPE_NEXTHOP:
148 r = request_process_nexthop(req);
149 break;
150 case REQUEST_TYPE_ROUTE:
151 r = request_process_route(req);
152 break;
153 case REQUEST_TYPE_ROUTING_POLICY_RULE:
154 r = request_process_routing_policy_rule(req);
155 break;
156 default:
157 return -EINVAL;
158 }
159 if (r < 0)
160 link_enter_failed(req->link);
161 if (r > 0) {
162 ordered_set_remove(manager->request_queue, req);
163 request_free(req);
164 processed = true;
165 }
166 }
167
168 if (!processed)
169 break;
170 }
171
172 return 0;
173 }