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