Blame


1 6b5c4000 2026-03-02 rsadowski /* $OpenBSD: pfe.c,v 1.92 2026/03/02 19:28:01 rsadowski Exp $ */
2 41042ecc 2006-12-16 reyk
3 41042ecc 2006-12-16 reyk /*
4 8c736326 2007-09-28 pyr * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org>
5 41042ecc 2006-12-16 reyk *
6 41042ecc 2006-12-16 reyk * Permission to use, copy, modify, and distribute this software for any
7 41042ecc 2006-12-16 reyk * purpose with or without fee is hereby granted, provided that the above
8 41042ecc 2006-12-16 reyk * copyright notice and this permission notice appear in all copies.
9 41042ecc 2006-12-16 reyk *
10 41042ecc 2006-12-16 reyk * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 41042ecc 2006-12-16 reyk * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 41042ecc 2006-12-16 reyk * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 41042ecc 2006-12-16 reyk * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 41042ecc 2006-12-16 reyk * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 41042ecc 2006-12-16 reyk * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 41042ecc 2006-12-16 reyk * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 41042ecc 2006-12-16 reyk */
18 41042ecc 2006-12-16 reyk
19 d93c36af 2015-01-22 reyk #include <sys/types.h>
20 d93c36af 2015-01-22 reyk #include <sys/queue.h>
21 73162055 2017-01-24 benno #include <sys/socket.h>
22 d93c36af 2015-01-22 reyk #include <sys/time.h>
23 d93c36af 2015-01-22 reyk #include <sys/uio.h>
24 73162055 2017-01-24 benno #include <sys/ioctl.h>
25 73162055 2017-01-24 benno #include <net/if.h>
26 73162055 2017-01-24 benno #include <net/pfvar.h>
27 e1f9d231 2007-11-24 reyk
28 41042ecc 2006-12-16 reyk #include <event.h>
29 73162055 2017-01-24 benno #include <fcntl.h>
30 41042ecc 2006-12-16 reyk #include <stdlib.h>
31 41042ecc 2006-12-16 reyk #include <string.h>
32 3a342b20 2015-11-29 benno #include <unistd.h>
33 d93c36af 2015-01-22 reyk #include <imsg.h>
34 41042ecc 2006-12-16 reyk
35 6d0767ae 2007-12-07 reyk #include "relayd.h"
36 6b5c4000 2026-03-02 rsadowski #include "log.h"
37 41042ecc 2006-12-16 reyk
38 dbef7d4f 2011-05-09 reyk void pfe_init(struct privsep *, struct privsep_proc *p, void *);
39 dbef7d4f 2011-05-09 reyk void pfe_shutdown(void);
40 dbef7d4f 2011-05-09 reyk void pfe_setup_events(void);
41 dbef7d4f 2011-05-09 reyk void pfe_disable_events(void);
42 dbef7d4f 2011-05-09 reyk void pfe_sync(void);
43 dbef7d4f 2011-05-09 reyk void pfe_statistics(int, short, void *);
44 41042ecc 2006-12-16 reyk
45 dbef7d4f 2011-05-09 reyk int pfe_dispatch_parent(int, struct privsep_proc *, struct imsg *);
46 dbef7d4f 2011-05-09 reyk int pfe_dispatch_hce(int, struct privsep_proc *, struct imsg *);
47 dbef7d4f 2011-05-09 reyk int pfe_dispatch_relay(int, struct privsep_proc *, struct imsg *);
48 dbef7d4f 2011-05-09 reyk
49 591e6ab5 2011-05-19 reyk static struct relayd *env = NULL;
50 41042ecc 2006-12-16 reyk
51 dbef7d4f 2011-05-09 reyk static struct privsep_proc procs[] = {
52 dbef7d4f 2011-05-09 reyk { "parent", PROC_PARENT, pfe_dispatch_parent },
53 dbef7d4f 2011-05-09 reyk { "relay", PROC_RELAY, pfe_dispatch_relay },
54 dbef7d4f 2011-05-09 reyk { "hce", PROC_HCE, pfe_dispatch_hce }
55 dbef7d4f 2011-05-09 reyk };
56 41042ecc 2006-12-16 reyk
57 94404df8 2016-09-02 reyk void
58 dbef7d4f 2011-05-09 reyk pfe(struct privsep *ps, struct privsep_proc *p)
59 41042ecc 2006-12-16 reyk {
60 09e53fee 2017-05-28 benno int s;
61 73162055 2017-01-24 benno struct pf_status status;
62 73162055 2017-01-24 benno
63 dbef7d4f 2011-05-09 reyk env = ps->ps_env;
64 41042ecc 2006-12-16 reyk
65 73162055 2017-01-24 benno if ((s = open(PF_SOCKET, O_RDWR)) == -1) {
66 73162055 2017-01-24 benno fatal("%s: cannot open pf socket", __func__);
67 73162055 2017-01-24 benno }
68 73162055 2017-01-24 benno if (env->sc_pf == NULL) {
69 73162055 2017-01-24 benno if ((env->sc_pf = calloc(1, sizeof(*(env->sc_pf)))) == NULL)
70 73162055 2017-01-24 benno fatal("calloc");
71 73162055 2017-01-24 benno env->sc_pf->dev = s;
72 73162055 2017-01-24 benno }
73 73162055 2017-01-24 benno if (ioctl(env->sc_pf->dev, DIOCGETSTATUS, &status) == -1)
74 09e53fee 2017-05-28 benno fatal("%s: DIOCGETSTATUS", __func__);
75 73162055 2017-01-24 benno if (!status.running)
76 09e53fee 2017-05-28 benno fatalx("%s: pf is disabled", __func__);
77 73162055 2017-01-24 benno log_debug("%s: filter init done", __func__);
78 73162055 2017-01-24 benno
79 94404df8 2016-09-02 reyk proc_run(ps, p, procs, nitems(procs), pfe_init, NULL);
80 dbef7d4f 2011-05-09 reyk }
81 41042ecc 2006-12-16 reyk
82 dbef7d4f 2011-05-09 reyk void
83 dbef7d4f 2011-05-09 reyk pfe_init(struct privsep *ps, struct privsep_proc *p, void *arg)
84 dbef7d4f 2011-05-09 reyk {
85 591e6ab5 2011-05-19 reyk if (config_init(ps->ps_env) == -1)
86 591e6ab5 2011-05-19 reyk fatal("failed to initialize configuration");
87 591e6ab5 2011-05-19 reyk
88 3a342b20 2015-11-29 benno if (pledge("stdio recvfd unix pf", NULL) == -1)
89 3a342b20 2015-11-29 benno fatal("pledge");
90 3a342b20 2015-11-29 benno
91 dbef7d4f 2011-05-09 reyk p->p_shutdown = pfe_shutdown;
92 41042ecc 2006-12-16 reyk }
93 41042ecc 2006-12-16 reyk
94 41042ecc 2006-12-16 reyk void
95 41042ecc 2006-12-16 reyk pfe_shutdown(void)
96 41042ecc 2006-12-16 reyk {
97 41042ecc 2006-12-16 reyk flush_rulesets(env);
98 591e6ab5 2011-05-19 reyk config_purge(env, CONFIG_ALL);
99 41042ecc 2006-12-16 reyk }
100 41042ecc 2006-12-16 reyk
101 41042ecc 2006-12-16 reyk void
102 1c5b5a62 2007-05-31 pyr pfe_setup_events(void)
103 1c5b5a62 2007-05-31 pyr {
104 90f6aaca 2007-12-20 reyk struct timeval tv;
105 1c5b5a62 2007-05-31 pyr
106 90f6aaca 2007-12-20 reyk /* Schedule statistics timer */
107 591e6ab5 2011-05-19 reyk if (!event_initialized(&env->sc_statev)) {
108 591e6ab5 2011-05-19 reyk evtimer_set(&env->sc_statev, pfe_statistics, NULL);
109 58fc320c 2016-09-02 reyk bcopy(&env->sc_conf.statinterval, &tv, sizeof(tv));
110 591e6ab5 2011-05-19 reyk evtimer_add(&env->sc_statev, &tv);
111 591e6ab5 2011-05-19 reyk }
112 1c5b5a62 2007-05-31 pyr }
113 1c5b5a62 2007-05-31 pyr
114 1c5b5a62 2007-05-31 pyr void
115 1c5b5a62 2007-05-31 pyr pfe_disable_events(void)
116 1c5b5a62 2007-05-31 pyr {
117 23fba4ad 2008-01-31 reyk event_del(&env->sc_statev);
118 1c5b5a62 2007-05-31 pyr }
119 1c5b5a62 2007-05-31 pyr
120 dbef7d4f 2011-05-09 reyk int
121 dbef7d4f 2011-05-09 reyk pfe_dispatch_hce(int fd, struct privsep_proc *p, struct imsg *imsg)
122 41042ecc 2006-12-16 reyk {
123 41042ecc 2006-12-16 reyk struct host *host;
124 41042ecc 2006-12-16 reyk struct table *table;
125 41042ecc 2006-12-16 reyk struct ctl_status st;
126 41042ecc 2006-12-16 reyk
127 3b28f64e 2016-09-02 reyk control_imsg_forward(p->p_ps, imsg);
128 650b98e6 2009-06-02 reyk
129 dbef7d4f 2011-05-09 reyk switch (imsg->hdr.type) {
130 dbef7d4f 2011-05-09 reyk case IMSG_HOST_STATUS:
131 dbef7d4f 2011-05-09 reyk IMSG_SIZE_CHECK(imsg, &st);
132 dbef7d4f 2011-05-09 reyk memcpy(&st, imsg->data, sizeof(st));
133 dbef7d4f 2011-05-09 reyk if ((host = host_find(env, st.id)) == NULL)
134 09e53fee 2017-05-28 benno fatalx("%s: invalid host id", __func__);
135 dbef7d4f 2011-05-09 reyk host->he = st.he;
136 dbef7d4f 2011-05-09 reyk if (host->flags & F_DISABLE)
137 dbef7d4f 2011-05-09 reyk break;
138 dbef7d4f 2011-05-09 reyk host->retry_cnt = st.retry_cnt;
139 dbef7d4f 2011-05-09 reyk if (st.up != HOST_UNKNOWN) {
140 dbef7d4f 2011-05-09 reyk host->check_cnt++;
141 dbef7d4f 2011-05-09 reyk if (st.up == HOST_UP)
142 dbef7d4f 2011-05-09 reyk host->up_cnt++;
143 66c9127d 2007-06-19 pyr }
144 dbef7d4f 2011-05-09 reyk if (host->check_cnt != st.check_cnt) {
145 dbef7d4f 2011-05-09 reyk log_debug("%s: host %d => %d", __func__,
146 dbef7d4f 2011-05-09 reyk host->conf.id, host->up);
147 09e53fee 2017-05-28 benno fatalx("%s: desynchronized", __func__);
148 dbef7d4f 2011-05-09 reyk }
149 650b98e6 2009-06-02 reyk
150 dbef7d4f 2011-05-09 reyk if (host->up == st.up)
151 41042ecc 2006-12-16 reyk break;
152 41042ecc 2006-12-16 reyk
153 dbef7d4f 2011-05-09 reyk /* Forward to relay engine(s) */
154 141b9058 2015-12-02 reyk proc_compose(env->sc_ps, PROC_RELAY,
155 141b9058 2015-12-02 reyk IMSG_HOST_STATUS, &st, sizeof(st));
156 41042ecc 2006-12-16 reyk
157 dbef7d4f 2011-05-09 reyk if ((table = table_find(env, host->conf.tableid))
158 dbef7d4f 2011-05-09 reyk == NULL)
159 09e53fee 2017-05-28 benno fatalx("%s: invalid table id", __func__);
160 30640247 2007-02-22 reyk
161 dbef7d4f 2011-05-09 reyk log_debug("%s: state %d for host %u %s", __func__,
162 dbef7d4f 2011-05-09 reyk st.up, host->conf.id, host->conf.name);
163 30640247 2007-02-22 reyk
164 04a2f953 2020-09-14 martijn /* XXX Readd hosttrap code later */
165 04a2f953 2020-09-14 martijn #if 0
166 28bd28ce 2014-11-19 blambert snmp_hosttrap(env, table, host);
167 04a2f953 2020-09-14 martijn #endif
168 28bd28ce 2014-11-19 blambert
169 dbef7d4f 2011-05-09 reyk /*
170 dbef7d4f 2011-05-09 reyk * Do not change the table state when the host
171 dbef7d4f 2011-05-09 reyk * state switches between UNKNOWN and DOWN.
172 dbef7d4f 2011-05-09 reyk */
173 dbef7d4f 2011-05-09 reyk if (HOST_ISUP(st.up)) {
174 dbef7d4f 2011-05-09 reyk table->conf.flags |= F_CHANGED;
175 dbef7d4f 2011-05-09 reyk table->up++;
176 dbef7d4f 2011-05-09 reyk host->flags |= F_ADD;
177 dbef7d4f 2011-05-09 reyk host->flags &= ~(F_DEL);
178 dbef7d4f 2011-05-09 reyk } else if (HOST_ISUP(host->up)) {
179 dbef7d4f 2011-05-09 reyk table->up--;
180 dbef7d4f 2011-05-09 reyk table->conf.flags |= F_CHANGED;
181 dbef7d4f 2011-05-09 reyk host->flags |= F_DEL;
182 dbef7d4f 2011-05-09 reyk host->flags &= ~(F_ADD);
183 0cf1873e 2015-12-03 benno host->up = st.up;
184 0cf1873e 2015-12-03 benno pfe_sync();
185 41042ecc 2006-12-16 reyk }
186 dbef7d4f 2011-05-09 reyk
187 dbef7d4f 2011-05-09 reyk host->up = st.up;
188 dbef7d4f 2011-05-09 reyk break;
189 dbef7d4f 2011-05-09 reyk case IMSG_SYNC:
190 dbef7d4f 2011-05-09 reyk pfe_sync();
191 dbef7d4f 2011-05-09 reyk break;
192 dbef7d4f 2011-05-09 reyk default:
193 dbef7d4f 2011-05-09 reyk return (-1);
194 41042ecc 2006-12-16 reyk }
195 dbef7d4f 2011-05-09 reyk
196 dbef7d4f 2011-05-09 reyk return (0);
197 41042ecc 2006-12-16 reyk }
198 41042ecc 2006-12-16 reyk
199 dbef7d4f 2011-05-09 reyk int
200 dbef7d4f 2011-05-09 reyk pfe_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
201 41042ecc 2006-12-16 reyk {
202 dbef7d4f 2011-05-09 reyk switch (imsg->hdr.type) {
203 591e6ab5 2011-05-19 reyk case IMSG_CFG_TABLE:
204 591e6ab5 2011-05-19 reyk config_gettable(env, imsg);
205 dbef7d4f 2011-05-09 reyk break;
206 591e6ab5 2011-05-19 reyk case IMSG_CFG_HOST:
207 591e6ab5 2011-05-19 reyk config_gethost(env, imsg);
208 dbef7d4f 2011-05-09 reyk break;
209 591e6ab5 2011-05-19 reyk case IMSG_CFG_RDR:
210 591e6ab5 2011-05-19 reyk config_getrdr(env, imsg);
211 dbef7d4f 2011-05-09 reyk break;
212 591e6ab5 2011-05-19 reyk case IMSG_CFG_VIRT:
213 591e6ab5 2011-05-19 reyk config_getvirt(env, imsg);
214 dbef7d4f 2011-05-09 reyk break;
215 591e6ab5 2011-05-19 reyk case IMSG_CFG_ROUTER:
216 591e6ab5 2011-05-19 reyk config_getrt(env, imsg);
217 dbef7d4f 2011-05-09 reyk break;
218 591e6ab5 2011-05-19 reyk case IMSG_CFG_ROUTE:
219 591e6ab5 2011-05-19 reyk config_getroute(env, imsg);
220 591e6ab5 2011-05-19 reyk break;
221 591e6ab5 2011-05-19 reyk case IMSG_CFG_PROTO:
222 591e6ab5 2011-05-19 reyk config_getproto(env, imsg);
223 591e6ab5 2011-05-19 reyk break;
224 591e6ab5 2011-05-19 reyk case IMSG_CFG_RELAY:
225 591e6ab5 2011-05-19 reyk config_getrelay(env, imsg);
226 591e6ab5 2011-05-19 reyk break;
227 0f7a5e2e 2012-10-03 reyk case IMSG_CFG_RELAY_TABLE:
228 0f7a5e2e 2012-10-03 reyk config_getrelaytable(env, imsg);
229 0f7a5e2e 2012-10-03 reyk break;
230 591e6ab5 2011-05-19 reyk case IMSG_CFG_DONE:
231 591e6ab5 2011-05-19 reyk config_getcfg(env, imsg);
232 dbef7d4f 2011-05-09 reyk init_tables(env);
233 04a2f953 2020-09-14 martijn agentx_init(env);
234 996c1f22 2012-01-21 camield break;
235 996c1f22 2012-01-21 camield case IMSG_CTL_START:
236 dbef7d4f 2011-05-09 reyk pfe_setup_events();
237 dbef7d4f 2011-05-09 reyk pfe_sync();
238 dbef7d4f 2011-05-09 reyk break;
239 591e6ab5 2011-05-19 reyk case IMSG_CTL_RESET:
240 591e6ab5 2011-05-19 reyk config_getreset(env, imsg);
241 591e6ab5 2011-05-19 reyk break;
242 04a2f953 2020-09-14 martijn case IMSG_AGENTXSOCK:
243 04a2f953 2020-09-14 martijn agentx_getsock(imsg);
244 28bd28ce 2014-11-19 blambert break;
245 dbef7d4f 2011-05-09 reyk default:
246 dbef7d4f 2011-05-09 reyk return (-1);
247 4ab45c57 2006-12-16 reyk }
248 dbef7d4f 2011-05-09 reyk
249 dbef7d4f 2011-05-09 reyk return (0);
250 41042ecc 2006-12-16 reyk }
251 41042ecc 2006-12-16 reyk
252 dbef7d4f 2011-05-09 reyk int
253 dbef7d4f 2011-05-09 reyk pfe_dispatch_relay(int fd, struct privsep_proc *p, struct imsg *imsg)
254 30640247 2007-02-22 reyk {
255 30640247 2007-02-22 reyk struct ctl_natlook cnl;
256 30640247 2007-02-22 reyk struct ctl_stats crs;
257 30640247 2007-02-22 reyk struct relay *rlay;
258 f55b0941 2011-05-20 reyk struct ctl_conn *c;
259 28bd28ce 2014-11-19 blambert struct rsession con, *s, *t;
260 f55b0941 2011-05-20 reyk int cid;
261 28bd28ce 2014-11-19 blambert objid_t sid;
262 30640247 2007-02-22 reyk
263 dbef7d4f 2011-05-09 reyk switch (imsg->hdr.type) {
264 dbef7d4f 2011-05-09 reyk case IMSG_NATLOOK:
265 dbef7d4f 2011-05-09 reyk IMSG_SIZE_CHECK(imsg, &cnl);
266 dbef7d4f 2011-05-09 reyk bcopy(imsg->data, &cnl, sizeof(cnl));
267 58fc320c 2016-09-02 reyk if (cnl.proc > env->sc_conf.prefork_relay)
268 09e53fee 2017-05-28 benno fatalx("%s: invalid relay proc", __func__);
269 dbef7d4f 2011-05-09 reyk if (natlook(env, &cnl) != 0)
270 dbef7d4f 2011-05-09 reyk cnl.in = -1;
271 dbef7d4f 2011-05-09 reyk proc_compose_imsg(env->sc_ps, PROC_RELAY, cnl.proc,
272 141b9058 2015-12-02 reyk IMSG_NATLOOK, -1, -1, &cnl, sizeof(cnl));
273 dbef7d4f 2011-05-09 reyk break;
274 dbef7d4f 2011-05-09 reyk case IMSG_STATISTICS:
275 dbef7d4f 2011-05-09 reyk IMSG_SIZE_CHECK(imsg, &crs);
276 dbef7d4f 2011-05-09 reyk bcopy(imsg->data, &crs, sizeof(crs));
277 58fc320c 2016-09-02 reyk if (crs.proc > env->sc_conf.prefork_relay)
278 09e53fee 2017-05-28 benno fatalx("%s: invalid relay proc", __func__);
279 dbef7d4f 2011-05-09 reyk if ((rlay = relay_find(env, crs.id)) == NULL)
280 09e53fee 2017-05-28 benno fatalx("%s: invalid relay id", __func__);
281 dbef7d4f 2011-05-09 reyk bcopy(&crs, &rlay->rl_stats[crs.proc], sizeof(crs));
282 dbef7d4f 2011-05-09 reyk rlay->rl_stats[crs.proc].interval =
283 58fc320c 2016-09-02 reyk env->sc_conf.statinterval.tv_sec;
284 dbef7d4f 2011-05-09 reyk break;
285 f55b0941 2011-05-20 reyk case IMSG_CTL_SESSION:
286 f55b0941 2011-05-20 reyk IMSG_SIZE_CHECK(imsg, &con);
287 f55b0941 2011-05-20 reyk memcpy(&con, imsg->data, sizeof(con));
288 f55b0941 2011-05-20 reyk if ((c = control_connbyfd(con.se_cid)) == NULL) {
289 f55b0941 2011-05-20 reyk log_debug("%s: control connection %d not found",
290 f55b0941 2011-05-20 reyk __func__, con.se_cid);
291 f55b0941 2011-05-20 reyk return (0);
292 f55b0941 2011-05-20 reyk }
293 f55b0941 2011-05-20 reyk imsg_compose_event(&c->iev,
294 f55b0941 2011-05-20 reyk IMSG_CTL_SESSION, 0, 0, -1,
295 f55b0941 2011-05-20 reyk &con, sizeof(con));
296 f55b0941 2011-05-20 reyk break;
297 f55b0941 2011-05-20 reyk case IMSG_CTL_END:
298 f55b0941 2011-05-20 reyk IMSG_SIZE_CHECK(imsg, &cid);
299 f55b0941 2011-05-20 reyk memcpy(&cid, imsg->data, sizeof(cid));
300 f55b0941 2011-05-20 reyk if ((c = control_connbyfd(cid)) == NULL) {
301 f55b0941 2011-05-20 reyk log_debug("%s: control connection %d not found",
302 f55b0941 2011-05-20 reyk __func__, cid);
303 f55b0941 2011-05-20 reyk return (0);
304 f55b0941 2011-05-20 reyk }
305 f55b0941 2011-05-20 reyk if (c->waiting == 0) {
306 f55b0941 2011-05-20 reyk log_debug("%s: no pending control requests", __func__);
307 f55b0941 2011-05-20 reyk return (0);
308 f55b0941 2011-05-20 reyk } else if (--c->waiting == 0) {
309 f55b0941 2011-05-20 reyk /* Last ack for a previous request */
310 f55b0941 2011-05-20 reyk imsg_compose_event(&c->iev, IMSG_CTL_END,
311 f55b0941 2011-05-20 reyk 0, 0, -1, NULL, 0);
312 f55b0941 2011-05-20 reyk }
313 f55b0941 2011-05-20 reyk break;
314 28bd28ce 2014-11-19 blambert case IMSG_SESS_PUBLISH:
315 28bd28ce 2014-11-19 blambert IMSG_SIZE_CHECK(imsg, s);
316 28bd28ce 2014-11-19 blambert if ((s = calloc(1, sizeof(*s))) == NULL)
317 28bd28ce 2014-11-19 blambert return (0); /* XXX */
318 28bd28ce 2014-11-19 blambert memcpy(s, imsg->data, sizeof(*s));
319 28bd28ce 2014-11-19 blambert TAILQ_FOREACH(t, &env->sc_sessions, se_entry) {
320 220afe36 2015-04-21 jsg /* duplicate registration */
321 220afe36 2015-04-21 jsg if (t->se_id == s->se_id) {
322 220afe36 2015-04-21 jsg free(s);
323 28bd28ce 2014-11-19 blambert return (0);
324 220afe36 2015-04-21 jsg }
325 28bd28ce 2014-11-19 blambert if (t->se_id > s->se_id)
326 28bd28ce 2014-11-19 blambert break;
327 28bd28ce 2014-11-19 blambert }
328 28bd28ce 2014-11-19 blambert if (t)
329 28bd28ce 2014-11-19 blambert TAILQ_INSERT_BEFORE(t, s, se_entry);
330 28bd28ce 2014-11-19 blambert else
331 28bd28ce 2014-11-19 blambert TAILQ_INSERT_TAIL(&env->sc_sessions, s, se_entry);
332 28bd28ce 2014-11-19 blambert break;
333 28bd28ce 2014-11-19 blambert case IMSG_SESS_UNPUBLISH:
334 28bd28ce 2014-11-19 blambert IMSG_SIZE_CHECK(imsg, &sid);
335 28bd28ce 2014-11-19 blambert memcpy(&sid, imsg->data, sizeof(sid));
336 28bd28ce 2014-11-19 blambert TAILQ_FOREACH(s, &env->sc_sessions, se_entry)
337 28bd28ce 2014-11-19 blambert if (s->se_id == sid)
338 28bd28ce 2014-11-19 blambert break;
339 28bd28ce 2014-11-19 blambert if (s) {
340 28bd28ce 2014-11-19 blambert TAILQ_REMOVE(&env->sc_sessions, s, se_entry);
341 28bd28ce 2014-11-19 blambert free(s);
342 02c2c4e4 2015-02-08 blambert } else {
343 02c2c4e4 2015-02-08 blambert DPRINTF("removal of unpublished session %i", sid);
344 02c2c4e4 2015-02-08 blambert }
345 28bd28ce 2014-11-19 blambert break;
346 dbef7d4f 2011-05-09 reyk default:
347 dbef7d4f 2011-05-09 reyk return (-1);
348 650b98e6 2009-06-02 reyk }
349 650b98e6 2009-06-02 reyk
350 dbef7d4f 2011-05-09 reyk return (0);
351 30640247 2007-02-22 reyk }
352 30640247 2007-02-22 reyk
353 30640247 2007-02-22 reyk void
354 41042ecc 2006-12-16 reyk show(struct ctl_conn *c)
355 41042ecc 2006-12-16 reyk {
356 0f7a5e2e 2012-10-03 reyk struct rdr *rdr;
357 0f7a5e2e 2012-10-03 reyk struct host *host;
358 0f7a5e2e 2012-10-03 reyk struct relay *rlay;
359 0f7a5e2e 2012-10-03 reyk struct router *rt;
360 0f7a5e2e 2012-10-03 reyk struct netroute *nr;
361 0f7a5e2e 2012-10-03 reyk struct relay_table *rlt;
362 41042ecc 2006-12-16 reyk
363 23fba4ad 2008-01-31 reyk if (env->sc_rdrs == NULL)
364 db441530 2007-11-14 pyr goto relays;
365 23fba4ad 2008-01-31 reyk TAILQ_FOREACH(rdr, env->sc_rdrs, entry) {
366 eabfa908 2009-06-05 pyr imsg_compose_event(&c->iev, IMSG_CTL_RDR, 0, 0, -1,
367 c8f9d8e3 2007-12-08 pyr rdr, sizeof(*rdr));
368 c8f9d8e3 2007-12-08 pyr if (rdr->conf.flags & F_DISABLE)
369 41042ecc 2006-12-16 reyk continue;
370 41042ecc 2006-12-16 reyk
371 eabfa908 2009-06-05 pyr imsg_compose_event(&c->iev, IMSG_CTL_RDR_STATS, 0, 0, -1,
372 90f6aaca 2007-12-20 reyk &rdr->stats, sizeof(rdr->stats));
373 90f6aaca 2007-12-20 reyk
374 eabfa908 2009-06-05 pyr imsg_compose_event(&c->iev, IMSG_CTL_TABLE, 0, 0, -1,
375 c8f9d8e3 2007-12-08 pyr rdr->table, sizeof(*rdr->table));
376 c8f9d8e3 2007-12-08 pyr if (!(rdr->table->conf.flags & F_DISABLE))
377 c8f9d8e3 2007-12-08 pyr TAILQ_FOREACH(host, &rdr->table->hosts, entry)
378 eabfa908 2009-06-05 pyr imsg_compose_event(&c->iev, IMSG_CTL_HOST,
379 6f81a163 2009-06-05 pyr 0, 0, -1, host, sizeof(*host));
380 41042ecc 2006-12-16 reyk
381 c8f9d8e3 2007-12-08 pyr if (rdr->backup->conf.id == EMPTY_TABLE)
382 41042ecc 2006-12-16 reyk continue;
383 eabfa908 2009-06-05 pyr imsg_compose_event(&c->iev, IMSG_CTL_TABLE, 0, 0, -1,
384 c8f9d8e3 2007-12-08 pyr rdr->backup, sizeof(*rdr->backup));
385 c8f9d8e3 2007-12-08 pyr if (!(rdr->backup->conf.flags & F_DISABLE))
386 c8f9d8e3 2007-12-08 pyr TAILQ_FOREACH(host, &rdr->backup->hosts, entry)
387 eabfa908 2009-06-05 pyr imsg_compose_event(&c->iev, IMSG_CTL_HOST,
388 6f81a163 2009-06-05 pyr 0, 0, -1, host, sizeof(*host));
389 41042ecc 2006-12-16 reyk }
390 db441530 2007-11-14 pyr relays:
391 23fba4ad 2008-01-31 reyk if (env->sc_relays == NULL)
392 a2fb091d 2009-08-17 reyk goto routers;
393 146643ba 2008-01-31 reyk TAILQ_FOREACH(rlay, env->sc_relays, rl_entry) {
394 58fc320c 2016-09-02 reyk rlay->rl_stats[env->sc_conf.prefork_relay].id = EMPTY_ID;
395 eabfa908 2009-06-05 pyr imsg_compose_event(&c->iev, IMSG_CTL_RELAY, 0, 0, -1,
396 30640247 2007-02-22 reyk rlay, sizeof(*rlay));
397 eabfa908 2009-06-05 pyr imsg_compose_event(&c->iev, IMSG_CTL_RELAY_STATS, 0, 0, -1,
398 146643ba 2008-01-31 reyk &rlay->rl_stats, sizeof(rlay->rl_stats));
399 589fbb6f 2007-03-07 reyk
400 0f7a5e2e 2012-10-03 reyk TAILQ_FOREACH(rlt, &rlay->rl_tables, rlt_entry) {
401 0f7a5e2e 2012-10-03 reyk imsg_compose_event(&c->iev, IMSG_CTL_TABLE, 0, 0, -1,
402 0f7a5e2e 2012-10-03 reyk rlt->rlt_table, sizeof(*rlt->rlt_table));
403 0f7a5e2e 2012-10-03 reyk if (!(rlt->rlt_table->conf.flags & F_DISABLE))
404 0f7a5e2e 2012-10-03 reyk TAILQ_FOREACH(host,
405 0f7a5e2e 2012-10-03 reyk &rlt->rlt_table->hosts, entry)
406 0f7a5e2e 2012-10-03 reyk imsg_compose_event(&c->iev,
407 0f7a5e2e 2012-10-03 reyk IMSG_CTL_HOST, 0, 0, -1,
408 0f7a5e2e 2012-10-03 reyk host, sizeof(*host));
409 0f7a5e2e 2012-10-03 reyk }
410 30640247 2007-02-22 reyk }
411 a2fb091d 2009-08-17 reyk
412 a2fb091d 2009-08-17 reyk routers:
413 a2fb091d 2009-08-17 reyk if (env->sc_rts == NULL)
414 a2fb091d 2009-08-17 reyk goto end;
415 a2fb091d 2009-08-17 reyk TAILQ_FOREACH(rt, env->sc_rts, rt_entry) {
416 a2fb091d 2009-08-17 reyk imsg_compose_event(&c->iev, IMSG_CTL_ROUTER, 0, 0, -1,
417 a2fb091d 2009-08-17 reyk rt, sizeof(*rt));
418 a2fb091d 2009-08-17 reyk if (rt->rt_conf.flags & F_DISABLE)
419 a2fb091d 2009-08-17 reyk continue;
420 a2fb091d 2009-08-17 reyk
421 a2fb091d 2009-08-17 reyk TAILQ_FOREACH(nr, &rt->rt_netroutes, nr_entry)
422 a2fb091d 2009-08-17 reyk imsg_compose_event(&c->iev, IMSG_CTL_NETROUTE,
423 a2fb091d 2009-08-17 reyk 0, 0, -1, nr, sizeof(*nr));
424 a2fb091d 2009-08-17 reyk imsg_compose_event(&c->iev, IMSG_CTL_TABLE, 0, 0, -1,
425 a2fb091d 2009-08-17 reyk rt->rt_gwtable, sizeof(*rt->rt_gwtable));
426 a2fb091d 2009-08-17 reyk if (!(rt->rt_gwtable->conf.flags & F_DISABLE))
427 a2fb091d 2009-08-17 reyk TAILQ_FOREACH(host, &rt->rt_gwtable->hosts, entry)
428 a2fb091d 2009-08-17 reyk imsg_compose_event(&c->iev, IMSG_CTL_HOST,
429 a2fb091d 2009-08-17 reyk 0, 0, -1, host, sizeof(*host));
430 a2fb091d 2009-08-17 reyk }
431 a2fb091d 2009-08-17 reyk
432 db441530 2007-11-14 pyr end:
433 eabfa908 2009-06-05 pyr imsg_compose_event(&c->iev, IMSG_CTL_END, 0, 0, -1, NULL, 0);
434 41042ecc 2006-12-16 reyk }
435 41042ecc 2006-12-16 reyk
436 41b83bb1 2007-09-07 reyk void
437 41b83bb1 2007-09-07 reyk show_sessions(struct ctl_conn *c)
438 41b83bb1 2007-09-07 reyk {
439 f55b0941 2011-05-20 reyk int proc, cid;
440 41042ecc 2006-12-16 reyk
441 58fc320c 2016-09-02 reyk for (proc = 0; proc < env->sc_conf.prefork_relay; proc++) {
442 f55b0941 2011-05-20 reyk cid = c->iev.ibuf.fd;
443 dbef7d4f 2011-05-09 reyk
444 41b83bb1 2007-09-07 reyk /*
445 41b83bb1 2007-09-07 reyk * Request all the running sessions from the process
446 41b83bb1 2007-09-07 reyk */
447 dbef7d4f 2011-05-09 reyk proc_compose_imsg(env->sc_ps, PROC_RELAY, proc,
448 141b9058 2015-12-02 reyk IMSG_CTL_SESSION, -1, -1, &cid, sizeof(cid));
449 f55b0941 2011-05-20 reyk c->waiting++;
450 41b83bb1 2007-09-07 reyk }
451 41b83bb1 2007-09-07 reyk }
452 41b83bb1 2007-09-07 reyk
453 41042ecc 2006-12-16 reyk int
454 c8f9d8e3 2007-12-08 pyr disable_rdr(struct ctl_conn *c, struct ctl_id *id)
455 41042ecc 2006-12-16 reyk {
456 c8f9d8e3 2007-12-08 pyr struct rdr *rdr;
457 41042ecc 2006-12-16 reyk
458 d2170f6d 2006-12-16 reyk if (id->id == EMPTY_ID)
459 c8f9d8e3 2007-12-08 pyr rdr = rdr_findbyname(env, id->name);
460 d2170f6d 2006-12-16 reyk else
461 c8f9d8e3 2007-12-08 pyr rdr = rdr_find(env, id->id);
462 c8f9d8e3 2007-12-08 pyr if (rdr == NULL)
463 41042ecc 2006-12-16 reyk return (-1);
464 c8f9d8e3 2007-12-08 pyr id->id = rdr->conf.id;
465 41042ecc 2006-12-16 reyk
466 c8f9d8e3 2007-12-08 pyr if (rdr->conf.flags & F_DISABLE)
467 41042ecc 2006-12-16 reyk return (0);
468 41042ecc 2006-12-16 reyk
469 c8f9d8e3 2007-12-08 pyr rdr->conf.flags |= F_DISABLE;
470 c8f9d8e3 2007-12-08 pyr rdr->conf.flags &= ~(F_ADD);
471 c8f9d8e3 2007-12-08 pyr rdr->conf.flags |= F_DEL;
472 c8f9d8e3 2007-12-08 pyr rdr->table->conf.flags |= F_DISABLE;
473 666bd316 2011-05-05 reyk log_debug("%s: redirect %d", __func__, rdr->conf.id);
474 41042ecc 2006-12-16 reyk pfe_sync();
475 41042ecc 2006-12-16 reyk return (0);
476 41042ecc 2006-12-16 reyk }
477 41042ecc 2006-12-16 reyk
478 41042ecc 2006-12-16 reyk int
479 c8f9d8e3 2007-12-08 pyr enable_rdr(struct ctl_conn *c, struct ctl_id *id)
480 41042ecc 2006-12-16 reyk {
481 c8f9d8e3 2007-12-08 pyr struct rdr *rdr;
482 d2170f6d 2006-12-16 reyk struct ctl_id eid;
483 41042ecc 2006-12-16 reyk
484 d2170f6d 2006-12-16 reyk if (id->id == EMPTY_ID)
485 c8f9d8e3 2007-12-08 pyr rdr = rdr_findbyname(env, id->name);
486 d2170f6d 2006-12-16 reyk else
487 c8f9d8e3 2007-12-08 pyr rdr = rdr_find(env, id->id);
488 c8f9d8e3 2007-12-08 pyr if (rdr == NULL)
489 41042ecc 2006-12-16 reyk return (-1);
490 c8f9d8e3 2007-12-08 pyr id->id = rdr->conf.id;
491 41042ecc 2006-12-16 reyk
492 c8f9d8e3 2007-12-08 pyr if (!(rdr->conf.flags & F_DISABLE))
493 41042ecc 2006-12-16 reyk return (0);
494 41042ecc 2006-12-16 reyk
495 c8f9d8e3 2007-12-08 pyr rdr->conf.flags &= ~(F_DISABLE);
496 c8f9d8e3 2007-12-08 pyr rdr->conf.flags &= ~(F_DEL);
497 c8f9d8e3 2007-12-08 pyr rdr->conf.flags |= F_ADD;
498 666bd316 2011-05-05 reyk log_debug("%s: redirect %d", __func__, rdr->conf.id);
499 41042ecc 2006-12-16 reyk
500 d2170f6d 2006-12-16 reyk bzero(&eid, sizeof(eid));
501 d2170f6d 2006-12-16 reyk
502 41042ecc 2006-12-16 reyk /* XXX: we're syncing twice */
503 c8f9d8e3 2007-12-08 pyr eid.id = rdr->table->conf.id;
504 d2170f6d 2006-12-16 reyk if (enable_table(c, &eid) == -1)
505 41042ecc 2006-12-16 reyk return (-1);
506 c8f9d8e3 2007-12-08 pyr if (rdr->backup->conf.id == EMPTY_ID)
507 aeba0aa5 2007-02-06 pyr return (0);
508 c8f9d8e3 2007-12-08 pyr eid.id = rdr->backup->conf.id;
509 d2170f6d 2006-12-16 reyk if (enable_table(c, &eid) == -1)
510 41042ecc 2006-12-16 reyk return (-1);
511 41042ecc 2006-12-16 reyk return (0);
512 41042ecc 2006-12-16 reyk }
513 41042ecc 2006-12-16 reyk
514 41042ecc 2006-12-16 reyk int
515 d2170f6d 2006-12-16 reyk disable_table(struct ctl_conn *c, struct ctl_id *id)
516 41042ecc 2006-12-16 reyk {
517 41042ecc 2006-12-16 reyk struct table *table;
518 41042ecc 2006-12-16 reyk struct host *host;
519 41042ecc 2006-12-16 reyk
520 d2170f6d 2006-12-16 reyk if (id->id == EMPTY_ID)
521 d2170f6d 2006-12-16 reyk table = table_findbyname(env, id->name);
522 d2170f6d 2006-12-16 reyk else
523 d2170f6d 2006-12-16 reyk table = table_find(env, id->id);
524 d2170f6d 2006-12-16 reyk if (table == NULL)
525 41042ecc 2006-12-16 reyk return (-1);
526 87178699 2007-05-27 pyr id->id = table->conf.id;
527 1e01606f 2010-11-16 jsg if (table->conf.rdrid > 0 && rdr_find(env, table->conf.rdrid) == NULL)
528 09e53fee 2017-05-28 benno fatalx("%s: desynchronised", __func__);
529 41042ecc 2006-12-16 reyk
530 87178699 2007-05-27 pyr if (table->conf.flags & F_DISABLE)
531 41042ecc 2006-12-16 reyk return (0);
532 87178699 2007-05-27 pyr table->conf.flags |= (F_DISABLE|F_CHANGED);
533 41042ecc 2006-12-16 reyk table->up = 0;
534 41042ecc 2006-12-16 reyk TAILQ_FOREACH(host, &table->hosts, entry)
535 41042ecc 2006-12-16 reyk host->up = HOST_UNKNOWN;
536 141b9058 2015-12-02 reyk proc_compose(env->sc_ps, PROC_HCE, IMSG_TABLE_DISABLE,
537 87178699 2007-05-27 pyr &table->conf.id, sizeof(table->conf.id));
538 dbef7d4f 2011-05-09 reyk
539 1e01606f 2010-11-16 jsg /* Forward to relay engine(s) */
540 141b9058 2015-12-02 reyk proc_compose(env->sc_ps, PROC_RELAY, IMSG_TABLE_DISABLE,
541 dbef7d4f 2011-05-09 reyk &table->conf.id, sizeof(table->conf.id));
542 dbef7d4f 2011-05-09 reyk
543 666bd316 2011-05-05 reyk log_debug("%s: table %d", __func__, table->conf.id);
544 41042ecc 2006-12-16 reyk pfe_sync();
545 41042ecc 2006-12-16 reyk return (0);
546 41042ecc 2006-12-16 reyk }
547 41042ecc 2006-12-16 reyk
548 41042ecc 2006-12-16 reyk int
549 d2170f6d 2006-12-16 reyk enable_table(struct ctl_conn *c, struct ctl_id *id)
550 41042ecc 2006-12-16 reyk {
551 41042ecc 2006-12-16 reyk struct table *table;
552 41042ecc 2006-12-16 reyk struct host *host;
553 41042ecc 2006-12-16 reyk
554 d2170f6d 2006-12-16 reyk if (id->id == EMPTY_ID)
555 d2170f6d 2006-12-16 reyk table = table_findbyname(env, id->name);
556 d2170f6d 2006-12-16 reyk else
557 d2170f6d 2006-12-16 reyk table = table_find(env, id->id);
558 d2170f6d 2006-12-16 reyk if (table == NULL)
559 41042ecc 2006-12-16 reyk return (-1);
560 87178699 2007-05-27 pyr id->id = table->conf.id;
561 d2170f6d 2006-12-16 reyk
562 1e01606f 2010-11-16 jsg if (table->conf.rdrid > 0 && rdr_find(env, table->conf.rdrid) == NULL)
563 09e53fee 2017-05-28 benno fatalx("%s: desynchronised", __func__);
564 41042ecc 2006-12-16 reyk
565 87178699 2007-05-27 pyr if (!(table->conf.flags & F_DISABLE))
566 41042ecc 2006-12-16 reyk return (0);
567 87178699 2007-05-27 pyr table->conf.flags &= ~(F_DISABLE);
568 87178699 2007-05-27 pyr table->conf.flags |= F_CHANGED;
569 41042ecc 2006-12-16 reyk table->up = 0;
570 41042ecc 2006-12-16 reyk TAILQ_FOREACH(host, &table->hosts, entry)
571 41042ecc 2006-12-16 reyk host->up = HOST_UNKNOWN;
572 141b9058 2015-12-02 reyk proc_compose(env->sc_ps, PROC_HCE, IMSG_TABLE_ENABLE,
573 87178699 2007-05-27 pyr &table->conf.id, sizeof(table->conf.id));
574 dbef7d4f 2011-05-09 reyk
575 1e01606f 2010-11-16 jsg /* Forward to relay engine(s) */
576 141b9058 2015-12-02 reyk proc_compose(env->sc_ps, PROC_RELAY, IMSG_TABLE_ENABLE,
577 dbef7d4f 2011-05-09 reyk &table->conf.id, sizeof(table->conf.id));
578 dbef7d4f 2011-05-09 reyk
579 666bd316 2011-05-05 reyk log_debug("%s: table %d", __func__, table->conf.id);
580 41042ecc 2006-12-16 reyk pfe_sync();
581 41042ecc 2006-12-16 reyk return (0);
582 41042ecc 2006-12-16 reyk }
583 41042ecc 2006-12-16 reyk
584 41042ecc 2006-12-16 reyk int
585 17acabee 2008-07-19 reyk disable_host(struct ctl_conn *c, struct ctl_id *id, struct host *host)
586 41042ecc 2006-12-16 reyk {
587 17acabee 2008-07-19 reyk struct host *h;
588 42a9e5ca 2024-06-17 sashan struct table *table, *t;
589 42a9e5ca 2024-06-17 sashan int host_byname = 0;
590 41042ecc 2006-12-16 reyk
591 17acabee 2008-07-19 reyk if (host == NULL) {
592 42a9e5ca 2024-06-17 sashan if (id->id == EMPTY_ID) {
593 17acabee 2008-07-19 reyk host = host_findbyname(env, id->name);
594 42a9e5ca 2024-06-17 sashan host_byname = 1;
595 42a9e5ca 2024-06-17 sashan }
596 17acabee 2008-07-19 reyk else
597 17acabee 2008-07-19 reyk host = host_find(env, id->id);
598 17acabee 2008-07-19 reyk if (host == NULL || host->conf.parentid)
599 17acabee 2008-07-19 reyk return (-1);
600 17acabee 2008-07-19 reyk }
601 87178699 2007-05-27 pyr id->id = host->conf.id;
602 41042ecc 2006-12-16 reyk
603 41042ecc 2006-12-16 reyk if (host->flags & F_DISABLE)
604 41042ecc 2006-12-16 reyk return (0);
605 41042ecc 2006-12-16 reyk
606 41042ecc 2006-12-16 reyk if (host->up == HOST_UP) {
607 87178699 2007-05-27 pyr if ((table = table_find(env, host->conf.tableid)) == NULL)
608 09e53fee 2017-05-28 benno fatalx("%s: invalid table id", __func__);
609 41042ecc 2006-12-16 reyk table->up--;
610 87178699 2007-05-27 pyr table->conf.flags |= F_CHANGED;
611 41042ecc 2006-12-16 reyk }
612 41042ecc 2006-12-16 reyk
613 41042ecc 2006-12-16 reyk host->up = HOST_UNKNOWN;
614 41042ecc 2006-12-16 reyk host->flags |= F_DISABLE;
615 41042ecc 2006-12-16 reyk host->flags |= F_DEL;
616 41042ecc 2006-12-16 reyk host->flags &= ~(F_ADD);
617 30640247 2007-02-22 reyk host->check_cnt = 0;
618 30640247 2007-02-22 reyk host->up_cnt = 0;
619 41042ecc 2006-12-16 reyk
620 141b9058 2015-12-02 reyk proc_compose(env->sc_ps, PROC_HCE, IMSG_HOST_DISABLE,
621 87178699 2007-05-27 pyr &host->conf.id, sizeof(host->conf.id));
622 dbef7d4f 2011-05-09 reyk
623 589fbb6f 2007-03-07 reyk /* Forward to relay engine(s) */
624 141b9058 2015-12-02 reyk proc_compose(env->sc_ps, PROC_RELAY, IMSG_HOST_DISABLE,
625 dbef7d4f 2011-05-09 reyk &host->conf.id, sizeof(host->conf.id));
626 666bd316 2011-05-05 reyk log_debug("%s: host %d", __func__, host->conf.id);
627 17acabee 2008-07-19 reyk
628 aebf7fd4 2008-07-19 reyk if (!host->conf.parentid) {
629 aebf7fd4 2008-07-19 reyk /* Disable all children */
630 aebf7fd4 2008-07-19 reyk SLIST_FOREACH(h, &host->children, child)
631 aebf7fd4 2008-07-19 reyk disable_host(c, id, h);
632 42a9e5ca 2024-06-17 sashan
633 42a9e5ca 2024-06-17 sashan /* Disable hosts with same name on all tables */
634 42a9e5ca 2024-06-17 sashan if (host_byname)
635 42a9e5ca 2024-06-17 sashan TAILQ_FOREACH(t, env->sc_tables, entry)
636 42a9e5ca 2024-06-17 sashan TAILQ_FOREACH(h, &t->hosts, entry)
637 42a9e5ca 2024-06-17 sashan if (strcmp(h->conf.name,
638 42a9e5ca 2024-06-17 sashan host->conf.name) == 0 &&
639 42a9e5ca 2024-06-17 sashan h->conf.id != host->conf.id &&
640 42a9e5ca 2024-06-17 sashan !h->conf.parentid)
641 42a9e5ca 2024-06-17 sashan disable_host(c, id, h);
642 17acabee 2008-07-19 reyk pfe_sync();
643 aebf7fd4 2008-07-19 reyk }
644 41042ecc 2006-12-16 reyk return (0);
645 41042ecc 2006-12-16 reyk }
646 41042ecc 2006-12-16 reyk
647 41042ecc 2006-12-16 reyk int
648 17acabee 2008-07-19 reyk enable_host(struct ctl_conn *c, struct ctl_id *id, struct host *host)
649 41042ecc 2006-12-16 reyk {
650 17acabee 2008-07-19 reyk struct host *h;
651 42a9e5ca 2024-06-17 sashan struct table *t;
652 42a9e5ca 2024-06-17 sashan int host_byname = 0;
653 41042ecc 2006-12-16 reyk
654 42a9e5ca 2024-06-17 sashan
655 17acabee 2008-07-19 reyk if (host == NULL) {
656 42a9e5ca 2024-06-17 sashan if (id->id == EMPTY_ID) {
657 17acabee 2008-07-19 reyk host = host_findbyname(env, id->name);
658 42a9e5ca 2024-06-17 sashan host_byname = 1;
659 42a9e5ca 2024-06-17 sashan }
660 17acabee 2008-07-19 reyk else
661 17acabee 2008-07-19 reyk host = host_find(env, id->id);
662 17acabee 2008-07-19 reyk if (host == NULL || host->conf.parentid)
663 17acabee 2008-07-19 reyk return (-1);
664 17acabee 2008-07-19 reyk }
665 87178699 2007-05-27 pyr id->id = host->conf.id;
666 41042ecc 2006-12-16 reyk
667 41042ecc 2006-12-16 reyk if (!(host->flags & F_DISABLE))
668 41042ecc 2006-12-16 reyk return (0);
669 41042ecc 2006-12-16 reyk
670 41042ecc 2006-12-16 reyk host->up = HOST_UNKNOWN;
671 41042ecc 2006-12-16 reyk host->flags &= ~(F_DISABLE);
672 41042ecc 2006-12-16 reyk host->flags &= ~(F_DEL);
673 41042ecc 2006-12-16 reyk host->flags &= ~(F_ADD);
674 41042ecc 2006-12-16 reyk
675 141b9058 2015-12-02 reyk proc_compose(env->sc_ps, PROC_HCE, IMSG_HOST_ENABLE,
676 87178699 2007-05-27 pyr &host->conf.id, sizeof (host->conf.id));
677 dbef7d4f 2011-05-09 reyk
678 589fbb6f 2007-03-07 reyk /* Forward to relay engine(s) */
679 141b9058 2015-12-02 reyk proc_compose(env->sc_ps, PROC_RELAY, IMSG_HOST_ENABLE,
680 dbef7d4f 2011-05-09 reyk &host->conf.id, sizeof(host->conf.id));
681 dbef7d4f 2011-05-09 reyk
682 666bd316 2011-05-05 reyk log_debug("%s: host %d", __func__, host->conf.id);
683 17acabee 2008-07-19 reyk
684 aebf7fd4 2008-07-19 reyk if (!host->conf.parentid) {
685 aebf7fd4 2008-07-19 reyk /* Enable all children */
686 aebf7fd4 2008-07-19 reyk SLIST_FOREACH(h, &host->children, child)
687 aebf7fd4 2008-07-19 reyk enable_host(c, id, h);
688 42a9e5ca 2024-06-17 sashan
689 42a9e5ca 2024-06-17 sashan /* Enable hosts with same name on all tables */
690 42a9e5ca 2024-06-17 sashan if (host_byname)
691 42a9e5ca 2024-06-17 sashan TAILQ_FOREACH(t, env->sc_tables, entry)
692 42a9e5ca 2024-06-17 sashan TAILQ_FOREACH(h, &t->hosts, entry)
693 42a9e5ca 2024-06-17 sashan if (strcmp(h->conf.name,
694 42a9e5ca 2024-06-17 sashan host->conf.name) == 0 &&
695 42a9e5ca 2024-06-17 sashan h->conf.id != host->conf.id &&
696 42a9e5ca 2024-06-17 sashan !h->conf.parentid)
697 42a9e5ca 2024-06-17 sashan enable_host(c, id, h);
698 17acabee 2008-07-19 reyk pfe_sync();
699 aebf7fd4 2008-07-19 reyk }
700 41042ecc 2006-12-16 reyk return (0);
701 41042ecc 2006-12-16 reyk }
702 41042ecc 2006-12-16 reyk
703 41042ecc 2006-12-16 reyk void
704 41042ecc 2006-12-16 reyk pfe_sync(void)
705 41042ecc 2006-12-16 reyk {
706 c8f9d8e3 2007-12-08 pyr struct rdr *rdr;
707 30640247 2007-02-22 reyk struct table *active;
708 30640247 2007-02-22 reyk struct table *table;
709 3e2ddb06 2007-02-22 reyk struct ctl_id id;
710 3e2ddb06 2007-02-22 reyk struct imsg imsg;
711 30640247 2007-02-22 reyk struct ctl_demote demote;
712 39bc6125 2009-08-13 reyk struct router *rt;
713 41042ecc 2006-12-16 reyk
714 1235c2ca 2007-02-06 pyr bzero(&id, sizeof(id));
715 1235c2ca 2007-02-06 pyr bzero(&imsg, sizeof(imsg));
716 23fba4ad 2008-01-31 reyk TAILQ_FOREACH(rdr, env->sc_rdrs, entry) {
717 c8f9d8e3 2007-12-08 pyr rdr->conf.flags &= ~(F_BACKUP);
718 c8f9d8e3 2007-12-08 pyr rdr->conf.flags &= ~(F_DOWN);
719 41042ecc 2006-12-16 reyk
720 c8f9d8e3 2007-12-08 pyr if (rdr->conf.flags & F_DISABLE ||
721 c8f9d8e3 2007-12-08 pyr (rdr->table->up == 0 && rdr->backup->up == 0)) {
722 c8f9d8e3 2007-12-08 pyr rdr->conf.flags |= F_DOWN;
723 41042ecc 2006-12-16 reyk active = NULL;
724 c8f9d8e3 2007-12-08 pyr } else if (rdr->table->up == 0 && rdr->backup->up > 0) {
725 c8f9d8e3 2007-12-08 pyr rdr->conf.flags |= F_BACKUP;
726 c8f9d8e3 2007-12-08 pyr active = rdr->backup;
727 87178699 2007-05-27 pyr active->conf.flags |=
728 c8f9d8e3 2007-12-08 pyr rdr->table->conf.flags & F_CHANGED;
729 87178699 2007-05-27 pyr active->conf.flags |=
730 c8f9d8e3 2007-12-08 pyr rdr->backup->conf.flags & F_CHANGED;
731 41042ecc 2006-12-16 reyk } else
732 c8f9d8e3 2007-12-08 pyr active = rdr->table;
733 41042ecc 2006-12-16 reyk
734 87178699 2007-05-27 pyr if (active != NULL && active->conf.flags & F_CHANGED) {
735 87178699 2007-05-27 pyr id.id = active->conf.id;
736 1235c2ca 2007-02-06 pyr imsg.hdr.type = IMSG_CTL_TABLE_CHANGED;
737 1235c2ca 2007-02-06 pyr imsg.hdr.len = sizeof(id) + IMSG_HEADER_SIZE;
738 1235c2ca 2007-02-06 pyr imsg.data = &id;
739 c8f9d8e3 2007-12-08 pyr sync_table(env, rdr, active);
740 3b28f64e 2016-09-02 reyk control_imsg_forward(env->sc_ps, &imsg);
741 1235c2ca 2007-02-06 pyr }
742 41042ecc 2006-12-16 reyk
743 c8f9d8e3 2007-12-08 pyr if (rdr->conf.flags & F_DOWN) {
744 c8f9d8e3 2007-12-08 pyr if (rdr->conf.flags & F_ACTIVE_RULESET) {
745 c8f9d8e3 2007-12-08 pyr flush_table(env, rdr);
746 666bd316 2011-05-05 reyk log_debug("%s: disabling ruleset", __func__);
747 c8f9d8e3 2007-12-08 pyr rdr->conf.flags &= ~(F_ACTIVE_RULESET);
748 c8f9d8e3 2007-12-08 pyr id.id = rdr->conf.id;
749 1235c2ca 2007-02-06 pyr imsg.hdr.type = IMSG_CTL_PULL_RULESET;
750 1235c2ca 2007-02-06 pyr imsg.hdr.len = sizeof(id) + IMSG_HEADER_SIZE;
751 1235c2ca 2007-02-06 pyr imsg.data = &id;
752 c8f9d8e3 2007-12-08 pyr sync_ruleset(env, rdr, 0);
753 3b28f64e 2016-09-02 reyk control_imsg_forward(env->sc_ps, &imsg);
754 41042ecc 2006-12-16 reyk }
755 c8f9d8e3 2007-12-08 pyr } else if (!(rdr->conf.flags & F_ACTIVE_RULESET)) {
756 666bd316 2011-05-05 reyk log_debug("%s: enabling ruleset", __func__);
757 c8f9d8e3 2007-12-08 pyr rdr->conf.flags |= F_ACTIVE_RULESET;
758 c8f9d8e3 2007-12-08 pyr id.id = rdr->conf.id;
759 1235c2ca 2007-02-06 pyr imsg.hdr.type = IMSG_CTL_PUSH_RULESET;
760 1235c2ca 2007-02-06 pyr imsg.hdr.len = sizeof(id) + IMSG_HEADER_SIZE;
761 1235c2ca 2007-02-06 pyr imsg.data = &id;
762 c8f9d8e3 2007-12-08 pyr sync_ruleset(env, rdr, 1);
763 3b28f64e 2016-09-02 reyk control_imsg_forward(env->sc_ps, &imsg);
764 41042ecc 2006-12-16 reyk }
765 41042ecc 2006-12-16 reyk }
766 30640247 2007-02-22 reyk
767 39bc6125 2009-08-13 reyk TAILQ_FOREACH(rt, env->sc_rts, rt_entry) {
768 39bc6125 2009-08-13 reyk rt->rt_conf.flags &= ~(F_BACKUP);
769 39bc6125 2009-08-13 reyk rt->rt_conf.flags &= ~(F_DOWN);
770 39bc6125 2009-08-13 reyk
771 39bc6125 2009-08-13 reyk if ((rt->rt_gwtable->conf.flags & F_CHANGED))
772 39bc6125 2009-08-13 reyk sync_routes(env, rt);
773 39bc6125 2009-08-13 reyk }
774 39bc6125 2009-08-13 reyk
775 23fba4ad 2008-01-31 reyk TAILQ_FOREACH(table, env->sc_tables, entry) {
776 591e6ab5 2011-05-19 reyk if (table->conf.check == CHECK_NOCHECK)
777 591e6ab5 2011-05-19 reyk continue;
778 591e6ab5 2011-05-19 reyk
779 caa869c1 2007-09-27 pyr /*
780 caa869c1 2007-09-27 pyr * clean up change flag.
781 caa869c1 2007-09-27 pyr */
782 caa869c1 2007-09-27 pyr table->conf.flags &= ~(F_CHANGED);
783 ab7af3ec 2007-11-19 reyk
784 caa869c1 2007-09-27 pyr /*
785 caa869c1 2007-09-27 pyr * handle demotion.
786 caa869c1 2007-09-27 pyr */
787 87178699 2007-05-27 pyr if ((table->conf.flags & F_DEMOTE) == 0)
788 30640247 2007-02-22 reyk continue;
789 30640247 2007-02-22 reyk demote.level = 0;
790 87178699 2007-05-27 pyr if (table->up && table->conf.flags & F_DEMOTED) {
791 30640247 2007-02-22 reyk demote.level = -1;
792 87178699 2007-05-27 pyr table->conf.flags &= ~F_DEMOTED;
793 30640247 2007-02-22 reyk }
794 87178699 2007-05-27 pyr else if (!table->up && !(table->conf.flags & F_DEMOTED)) {
795 30640247 2007-02-22 reyk demote.level = 1;
796 87178699 2007-05-27 pyr table->conf.flags |= F_DEMOTED;
797 30640247 2007-02-22 reyk }
798 30640247 2007-02-22 reyk if (demote.level == 0)
799 30640247 2007-02-22 reyk continue;
800 666bd316 2011-05-05 reyk log_debug("%s: demote %d table '%s' group '%s'", __func__,
801 87178699 2007-05-27 pyr demote.level, table->conf.name, table->conf.demote_group);
802 87178699 2007-05-27 pyr (void)strlcpy(demote.group, table->conf.demote_group,
803 30640247 2007-02-22 reyk sizeof(demote.group));
804 141b9058 2015-12-02 reyk proc_compose(env->sc_ps, PROC_PARENT, IMSG_DEMOTE,
805 30640247 2007-02-22 reyk &demote, sizeof(demote));
806 30640247 2007-02-22 reyk }
807 41042ecc 2006-12-16 reyk }
808 90f6aaca 2007-12-20 reyk
809 90f6aaca 2007-12-20 reyk void
810 90f6aaca 2007-12-20 reyk pfe_statistics(int fd, short events, void *arg)
811 90f6aaca 2007-12-20 reyk {
812 90f6aaca 2007-12-20 reyk struct rdr *rdr;
813 90f6aaca 2007-12-20 reyk struct ctl_stats *cur;
814 90f6aaca 2007-12-20 reyk struct timeval tv, tv_now;
815 90f6aaca 2007-12-20 reyk int resethour, resetday;
816 90f6aaca 2007-12-20 reyk u_long cnt;
817 90f6aaca 2007-12-20 reyk
818 90f6aaca 2007-12-20 reyk timerclear(&tv);
819 b7f7a948 2013-03-10 reyk getmonotime(&tv_now);
820 90f6aaca 2007-12-20 reyk
821 23fba4ad 2008-01-31 reyk TAILQ_FOREACH(rdr, env->sc_rdrs, entry) {
822 90f6aaca 2007-12-20 reyk cnt = check_table(env, rdr, rdr->table);
823 90f6aaca 2007-12-20 reyk if (rdr->conf.backup_id != EMPTY_TABLE)
824 90f6aaca 2007-12-20 reyk cnt += check_table(env, rdr, rdr->backup);
825 90f6aaca 2007-12-20 reyk
826 90f6aaca 2007-12-20 reyk resethour = resetday = 0;
827 90f6aaca 2007-12-20 reyk
828 90f6aaca 2007-12-20 reyk cur = &rdr->stats;
829 90f6aaca 2007-12-20 reyk cur->last = cnt > cur->cnt ? cnt - cur->cnt : 0;
830 90f6aaca 2007-12-20 reyk
831 90f6aaca 2007-12-20 reyk cur->cnt = cnt;
832 90f6aaca 2007-12-20 reyk cur->tick++;
833 90f6aaca 2007-12-20 reyk cur->avg = (cur->last + cur->avg) / 2;
834 90f6aaca 2007-12-20 reyk cur->last_hour += cur->last;
835 58fc320c 2016-09-02 reyk if ((cur->tick %
836 58fc320c 2016-09-02 reyk (3600 / env->sc_conf.statinterval.tv_sec)) == 0) {
837 90f6aaca 2007-12-20 reyk cur->avg_hour = (cur->last_hour + cur->avg_hour) / 2;
838 90f6aaca 2007-12-20 reyk resethour++;
839 90f6aaca 2007-12-20 reyk }
840 90f6aaca 2007-12-20 reyk cur->last_day += cur->last;
841 58fc320c 2016-09-02 reyk if ((cur->tick %
842 58fc320c 2016-09-02 reyk (86400 / env->sc_conf.statinterval.tv_sec)) == 0) {
843 90f6aaca 2007-12-20 reyk cur->avg_day = (cur->last_day + cur->avg_day) / 2;
844 90f6aaca 2007-12-20 reyk resethour++;
845 90f6aaca 2007-12-20 reyk }
846 90f6aaca 2007-12-20 reyk if (resethour)
847 90f6aaca 2007-12-20 reyk cur->last_hour = 0;
848 90f6aaca 2007-12-20 reyk if (resetday)
849 90f6aaca 2007-12-20 reyk cur->last_day = 0;
850 90f6aaca 2007-12-20 reyk
851 58fc320c 2016-09-02 reyk rdr->stats.interval = env->sc_conf.statinterval.tv_sec;
852 90f6aaca 2007-12-20 reyk }
853 90f6aaca 2007-12-20 reyk
854 90f6aaca 2007-12-20 reyk /* Schedule statistics timer */
855 23fba4ad 2008-01-31 reyk evtimer_set(&env->sc_statev, pfe_statistics, NULL);
856 58fc320c 2016-09-02 reyk bcopy(&env->sc_conf.statinterval, &tv, sizeof(tv));
857 23fba4ad 2008-01-31 reyk evtimer_add(&env->sc_statev, &tv);
858 90f6aaca 2007-12-20 reyk }