Blame


1 6b5c4000 2026-03-02 rsadowski /* $OpenBSD: pfe_filter.c,v 1.67 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 41042ecc 2006-12-16 reyk #include <sys/types.h>
20 41042ecc 2006-12-16 reyk #include <sys/queue.h>
21 41042ecc 2006-12-16 reyk #include <sys/socket.h>
22 d93c36af 2015-01-22 reyk #include <sys/time.h>
23 41042ecc 2006-12-16 reyk #include <sys/ioctl.h>
24 41042ecc 2006-12-16 reyk
25 d93c36af 2015-01-22 reyk #include <net/if.h>
26 41042ecc 2006-12-16 reyk #include <netinet/in.h>
27 05fcbce7 2009-09-01 reyk #include <netinet/tcp.h>
28 41042ecc 2006-12-16 reyk #include <arpa/inet.h>
29 24b53830 2015-01-21 deraadt #include <net/pfvar.h>
30 41042ecc 2006-12-16 reyk
31 41042ecc 2006-12-16 reyk #include <limits.h>
32 41042ecc 2006-12-16 reyk #include <string.h>
33 41042ecc 2006-12-16 reyk #include <stdio.h>
34 41042ecc 2006-12-16 reyk #include <stdlib.h>
35 591e6ab5 2011-05-19 reyk #include <unistd.h>
36 41042ecc 2006-12-16 reyk #include <errno.h>
37 41042ecc 2006-12-16 reyk
38 2f6ec04d 2015-01-16 deraadt #define MINIMUM(a, b) (((a) < (b)) ? (a) : (b))
39 2f6ec04d 2015-01-16 deraadt
40 6d0767ae 2007-12-07 reyk #include "relayd.h"
41 6b5c4000 2026-03-02 rsadowski #include "log.h"
42 41042ecc 2006-12-16 reyk
43 6d0767ae 2007-12-07 reyk int transaction_init(struct relayd *, const char *);
44 6d0767ae 2007-12-07 reyk int transaction_commit(struct relayd *);
45 6d0767ae 2007-12-07 reyk void kill_tables(struct relayd *);
46 bba2fc1f 2008-12-08 reyk int kill_srcnodes(struct relayd *, struct table *);
47 41042ecc 2006-12-16 reyk
48 41042ecc 2006-12-16 reyk void
49 6d0767ae 2007-12-07 reyk init_tables(struct relayd *env)
50 41042ecc 2006-12-16 reyk {
51 41042ecc 2006-12-16 reyk int i;
52 c8f9d8e3 2007-12-08 pyr struct rdr *rdr;
53 41042ecc 2006-12-16 reyk struct pfr_table *tables;
54 41042ecc 2006-12-16 reyk struct pfioc_table io;
55 41042ecc 2006-12-16 reyk
56 58fc320c 2016-09-02 reyk if (!(env->sc_conf.flags & F_NEEDPF))
57 982e86f7 2008-05-06 pyr return;
58 982e86f7 2008-05-06 pyr
59 23fba4ad 2008-01-31 reyk if ((tables = calloc(env->sc_rdrcount, sizeof(*tables))) == NULL)
60 41042ecc 2006-12-16 reyk fatal("calloc");
61 41042ecc 2006-12-16 reyk i = 0;
62 4ab45c57 2006-12-16 reyk
63 23fba4ad 2008-01-31 reyk TAILQ_FOREACH(rdr, env->sc_rdrs, entry) {
64 6d0767ae 2007-12-07 reyk if (strlcpy(tables[i].pfrt_anchor, RELAYD_ANCHOR "/",
65 1ad64381 2007-02-08 reyk sizeof(tables[i].pfrt_anchor)) >= PF_ANCHOR_NAME_SIZE)
66 1ad64381 2007-02-08 reyk goto toolong;
67 c8f9d8e3 2007-12-08 pyr if (strlcat(tables[i].pfrt_anchor, rdr->conf.name,
68 1ad64381 2007-02-08 reyk sizeof(tables[i].pfrt_anchor)) >= PF_ANCHOR_NAME_SIZE)
69 1ad64381 2007-02-08 reyk goto toolong;
70 c8f9d8e3 2007-12-08 pyr if (strlcpy(tables[i].pfrt_name, rdr->conf.name,
71 1ad64381 2007-02-08 reyk sizeof(tables[i].pfrt_name)) >=
72 1ad64381 2007-02-08 reyk sizeof(tables[i].pfrt_name))
73 1ad64381 2007-02-08 reyk goto toolong;
74 41042ecc 2006-12-16 reyk tables[i].pfrt_flags |= PFR_TFLAG_PERSIST;
75 41042ecc 2006-12-16 reyk i++;
76 41042ecc 2006-12-16 reyk }
77 23fba4ad 2008-01-31 reyk if (i != env->sc_rdrcount)
78 09e53fee 2017-05-28 benno fatalx("%s: table count modified", __func__);
79 41042ecc 2006-12-16 reyk
80 41042ecc 2006-12-16 reyk memset(&io, 0, sizeof(io));
81 23fba4ad 2008-01-31 reyk io.pfrio_size = env->sc_rdrcount;
82 41042ecc 2006-12-16 reyk io.pfrio_esize = sizeof(*tables);
83 41042ecc 2006-12-16 reyk io.pfrio_buffer = tables;
84 41042ecc 2006-12-16 reyk
85 23fba4ad 2008-01-31 reyk if (ioctl(env->sc_pf->dev, DIOCRADDTABLES, &io) == -1)
86 09e53fee 2017-05-28 benno fatal("%s: cannot create tables", __func__);
87 666bd316 2011-05-05 reyk log_debug("%s: created %d tables", __func__, io.pfrio_nadd);
88 41042ecc 2006-12-16 reyk
89 01ac6a2e 2007-01-05 reyk free(tables);
90 01ac6a2e 2007-01-05 reyk
91 23fba4ad 2008-01-31 reyk if (io.pfrio_nadd == env->sc_rdrcount)
92 41042ecc 2006-12-16 reyk return;
93 41042ecc 2006-12-16 reyk
94 41042ecc 2006-12-16 reyk /*
95 41042ecc 2006-12-16 reyk * clear all tables, since some already existed
96 41042ecc 2006-12-16 reyk */
97 23fba4ad 2008-01-31 reyk TAILQ_FOREACH(rdr, env->sc_rdrs, entry)
98 c8f9d8e3 2007-12-08 pyr flush_table(env, rdr);
99 1ad64381 2007-02-08 reyk
100 1ad64381 2007-02-08 reyk return;
101 1ad64381 2007-02-08 reyk
102 1ad64381 2007-02-08 reyk toolong:
103 09e53fee 2017-05-28 benno fatal("%s: name too long", __func__);
104 41042ecc 2006-12-16 reyk }
105 41042ecc 2006-12-16 reyk
106 41042ecc 2006-12-16 reyk void
107 30c938cd 2009-04-01 reyk kill_tables(struct relayd *env)
108 30c938cd 2009-04-01 reyk {
109 41042ecc 2006-12-16 reyk struct pfioc_table io;
110 c8f9d8e3 2007-12-08 pyr struct rdr *rdr;
111 30c938cd 2009-04-01 reyk int cnt = 0;
112 41042ecc 2006-12-16 reyk
113 58fc320c 2016-09-02 reyk if (!(env->sc_conf.flags & F_NEEDPF))
114 982e86f7 2008-05-06 pyr return;
115 982e86f7 2008-05-06 pyr
116 23fba4ad 2008-01-31 reyk TAILQ_FOREACH(rdr, env->sc_rdrs, entry) {
117 30c938cd 2009-04-01 reyk memset(&io, 0, sizeof(io));
118 6d0767ae 2007-12-07 reyk if (strlcpy(io.pfrio_table.pfrt_anchor, RELAYD_ANCHOR "/",
119 1ad64381 2007-02-08 reyk sizeof(io.pfrio_table.pfrt_anchor)) >= PF_ANCHOR_NAME_SIZE)
120 1ad64381 2007-02-08 reyk goto toolong;
121 c8f9d8e3 2007-12-08 pyr if (strlcat(io.pfrio_table.pfrt_anchor, rdr->conf.name,
122 1ad64381 2007-02-08 reyk sizeof(io.pfrio_table.pfrt_anchor)) >= PF_ANCHOR_NAME_SIZE)
123 1ad64381 2007-02-08 reyk goto toolong;
124 23fba4ad 2008-01-31 reyk if (ioctl(env->sc_pf->dev, DIOCRCLRTABLES, &io) == -1)
125 09e53fee 2017-05-28 benno fatal("%s: ioctl failed", __func__);
126 30c938cd 2009-04-01 reyk cnt += io.pfrio_ndel;
127 41042ecc 2006-12-16 reyk }
128 666bd316 2011-05-05 reyk log_debug("%s: deleted %d tables", __func__, cnt);
129 1ad64381 2007-02-08 reyk return;
130 1ad64381 2007-02-08 reyk
131 1ad64381 2007-02-08 reyk toolong:
132 09e53fee 2017-05-28 benno fatal("%s: name too long", __func__);
133 41042ecc 2006-12-16 reyk }
134 41042ecc 2006-12-16 reyk
135 41042ecc 2006-12-16 reyk void
136 c8f9d8e3 2007-12-08 pyr sync_table(struct relayd *env, struct rdr *rdr, struct table *table)
137 41042ecc 2006-12-16 reyk {
138 bba2fc1f 2008-12-08 reyk int i, cnt = 0;
139 41042ecc 2006-12-16 reyk struct pfioc_table io;
140 41042ecc 2006-12-16 reyk struct pfr_addr *addlist;
141 41042ecc 2006-12-16 reyk struct sockaddr_in *sain;
142 41042ecc 2006-12-16 reyk struct sockaddr_in6 *sain6;
143 41042ecc 2006-12-16 reyk struct host *host;
144 41042ecc 2006-12-16 reyk
145 58fc320c 2016-09-02 reyk if (!(env->sc_conf.flags & F_NEEDPF))
146 982e86f7 2008-05-06 pyr return;
147 982e86f7 2008-05-06 pyr
148 41042ecc 2006-12-16 reyk if (table == NULL)
149 41042ecc 2006-12-16 reyk return;
150 41042ecc 2006-12-16 reyk
151 41042ecc 2006-12-16 reyk if (table->up == 0) {
152 c8f9d8e3 2007-12-08 pyr flush_table(env, rdr);
153 41042ecc 2006-12-16 reyk return;
154 41042ecc 2006-12-16 reyk }
155 41042ecc 2006-12-16 reyk
156 41042ecc 2006-12-16 reyk if ((addlist = calloc(table->up, sizeof(*addlist))) == NULL)
157 41042ecc 2006-12-16 reyk fatal("calloc");
158 41042ecc 2006-12-16 reyk
159 41042ecc 2006-12-16 reyk memset(&io, 0, sizeof(io));
160 41042ecc 2006-12-16 reyk io.pfrio_esize = sizeof(struct pfr_addr);
161 41042ecc 2006-12-16 reyk io.pfrio_size = table->up;
162 41042ecc 2006-12-16 reyk io.pfrio_size2 = 0;
163 41042ecc 2006-12-16 reyk io.pfrio_buffer = addlist;
164 6d0767ae 2007-12-07 reyk if (strlcpy(io.pfrio_table.pfrt_anchor, RELAYD_ANCHOR "/",
165 1ad64381 2007-02-08 reyk sizeof(io.pfrio_table.pfrt_anchor)) >= PF_ANCHOR_NAME_SIZE)
166 1ad64381 2007-02-08 reyk goto toolong;
167 c8f9d8e3 2007-12-08 pyr if (strlcat(io.pfrio_table.pfrt_anchor, rdr->conf.name,
168 1ad64381 2007-02-08 reyk sizeof(io.pfrio_table.pfrt_anchor)) >= PF_ANCHOR_NAME_SIZE)
169 1ad64381 2007-02-08 reyk goto toolong;
170 c8f9d8e3 2007-12-08 pyr if (strlcpy(io.pfrio_table.pfrt_name, rdr->conf.name,
171 1ad64381 2007-02-08 reyk sizeof(io.pfrio_table.pfrt_name)) >=
172 1ad64381 2007-02-08 reyk sizeof(io.pfrio_table.pfrt_name))
173 1ad64381 2007-02-08 reyk goto toolong;
174 41042ecc 2006-12-16 reyk
175 41042ecc 2006-12-16 reyk i = 0;
176 41042ecc 2006-12-16 reyk TAILQ_FOREACH(host, &table->hosts, entry) {
177 b78c9b16 2007-02-20 reyk if (host->up != HOST_UP)
178 41042ecc 2006-12-16 reyk continue;
179 41042ecc 2006-12-16 reyk memset(&(addlist[i]), 0, sizeof(addlist[i]));
180 87178699 2007-05-27 pyr switch (host->conf.ss.ss_family) {
181 41042ecc 2006-12-16 reyk case AF_INET:
182 87178699 2007-05-27 pyr sain = (struct sockaddr_in *)&host->conf.ss;
183 41042ecc 2006-12-16 reyk addlist[i].pfra_af = AF_INET;
184 41042ecc 2006-12-16 reyk memcpy(&(addlist[i].pfra_ip4addr), &sain->sin_addr,
185 4ab45c57 2006-12-16 reyk sizeof(sain->sin_addr));
186 41042ecc 2006-12-16 reyk addlist[i].pfra_net = 32;
187 41042ecc 2006-12-16 reyk break;
188 41042ecc 2006-12-16 reyk case AF_INET6:
189 87178699 2007-05-27 pyr sain6 = (struct sockaddr_in6 *)&host->conf.ss;
190 41042ecc 2006-12-16 reyk addlist[i].pfra_af = AF_INET6;
191 41042ecc 2006-12-16 reyk memcpy(&(addlist[i].pfra_ip6addr), &sain6->sin6_addr,
192 4ab45c57 2006-12-16 reyk sizeof(sain6->sin6_addr));
193 41042ecc 2006-12-16 reyk addlist[i].pfra_net = 128;
194 41042ecc 2006-12-16 reyk break;
195 41042ecc 2006-12-16 reyk default:
196 09e53fee 2017-05-28 benno fatalx("%s: unknown address family", __func__);
197 41042ecc 2006-12-16 reyk break;
198 41042ecc 2006-12-16 reyk }
199 41042ecc 2006-12-16 reyk i++;
200 41042ecc 2006-12-16 reyk }
201 41042ecc 2006-12-16 reyk if (i != table->up)
202 09e53fee 2017-05-28 benno fatalx("%s: desynchronized", __func__);
203 41042ecc 2006-12-16 reyk
204 23fba4ad 2008-01-31 reyk if (ioctl(env->sc_pf->dev, DIOCRSETADDRS, &io) == -1)
205 09e53fee 2017-05-28 benno fatal("%s: cannot set address list", __func__);
206 bba2fc1f 2008-12-08 reyk if (rdr->conf.flags & F_STICKY)
207 bba2fc1f 2008-12-08 reyk cnt = kill_srcnodes(env, table);
208 01ac6a2e 2007-01-05 reyk free(addlist);
209 01ac6a2e 2007-01-05 reyk
210 58fc320c 2016-09-02 reyk if (env->sc_conf.opts & RELAYD_OPT_LOGUPDATE)
211 3d01a58f 2008-12-04 reyk log_info("table %s: %d added, %d deleted, "
212 bba2fc1f 2008-12-08 reyk "%d changed, %d killed", io.pfrio_table.pfrt_name,
213 bba2fc1f 2008-12-08 reyk io.pfrio_nadd, io.pfrio_ndel, io.pfrio_nchange, cnt);
214 1ad64381 2007-02-08 reyk return;
215 1ad64381 2007-02-08 reyk
216 1ad64381 2007-02-08 reyk toolong:
217 09e53fee 2017-05-28 benno fatal("%s: name too long", __func__);
218 41042ecc 2006-12-16 reyk }
219 41042ecc 2006-12-16 reyk
220 bba2fc1f 2008-12-08 reyk int
221 bba2fc1f 2008-12-08 reyk kill_srcnodes(struct relayd *env, struct table *table)
222 bba2fc1f 2008-12-08 reyk {
223 bba2fc1f 2008-12-08 reyk struct host *host;
224 bba2fc1f 2008-12-08 reyk struct pfioc_src_node_kill psnk;
225 bba2fc1f 2008-12-08 reyk int cnt = 0;
226 bba2fc1f 2008-12-08 reyk struct sockaddr_in *sain;
227 bba2fc1f 2008-12-08 reyk struct sockaddr_in6 *sain6;
228 bba2fc1f 2008-12-08 reyk
229 bba2fc1f 2008-12-08 reyk bzero(&psnk, sizeof(psnk));
230 bba2fc1f 2008-12-08 reyk
231 bba2fc1f 2008-12-08 reyk /* Only match the destination address, source mask will be zero */
232 bba2fc1f 2008-12-08 reyk memset(&psnk.psnk_dst.addr.v.a.mask, 0xff,
233 bba2fc1f 2008-12-08 reyk sizeof(psnk.psnk_dst.addr.v.a.mask));
234 bba2fc1f 2008-12-08 reyk
235 bba2fc1f 2008-12-08 reyk TAILQ_FOREACH(host, &table->hosts, entry) {
236 bba2fc1f 2008-12-08 reyk if (host->up != HOST_DOWN)
237 bba2fc1f 2008-12-08 reyk continue;
238 bba2fc1f 2008-12-08 reyk
239 bba2fc1f 2008-12-08 reyk switch (host->conf.ss.ss_family) {
240 bba2fc1f 2008-12-08 reyk case AF_INET:
241 2e6003cf 2010-09-02 sobrado sain = (struct sockaddr_in *)&host->conf.ss;
242 bba2fc1f 2008-12-08 reyk bcopy(&sain->sin_addr,
243 2e6003cf 2010-09-02 sobrado &psnk.psnk_dst.addr.v.a.addr.v4,
244 bba2fc1f 2008-12-08 reyk sizeof(psnk.psnk_dst.addr.v.a.addr.v4));
245 bba2fc1f 2008-12-08 reyk break;
246 bba2fc1f 2008-12-08 reyk case AF_INET6:
247 bba2fc1f 2008-12-08 reyk sain6 = (struct sockaddr_in6 *)&host->conf.ss;
248 bba2fc1f 2008-12-08 reyk bcopy(&sain6->sin6_addr,
249 bba2fc1f 2008-12-08 reyk &psnk.psnk_dst.addr.v.a.addr.v6,
250 bba2fc1f 2008-12-08 reyk sizeof(psnk.psnk_dst.addr.v.a.addr.v6));
251 2e6003cf 2010-09-02 sobrado break;
252 bba2fc1f 2008-12-08 reyk default:
253 09e53fee 2017-05-28 benno fatalx("%s: unknown address family", __func__);
254 bba2fc1f 2008-12-08 reyk break;
255 bba2fc1f 2008-12-08 reyk }
256 2e6003cf 2010-09-02 sobrado
257 bba2fc1f 2008-12-08 reyk psnk.psnk_af = host->conf.ss.ss_family;
258 bba2fc1f 2008-12-08 reyk psnk.psnk_killed = 0;
259 bba2fc1f 2008-12-08 reyk
260 bba2fc1f 2008-12-08 reyk if (ioctl(env->sc_pf->dev,
261 bba2fc1f 2008-12-08 reyk DIOCKILLSRCNODES, &psnk) == -1)
262 09e53fee 2017-05-28 benno fatal("%s: cannot kill src nodes", __func__);
263 bba2fc1f 2008-12-08 reyk cnt += psnk.psnk_killed;
264 bba2fc1f 2008-12-08 reyk }
265 bba2fc1f 2008-12-08 reyk
266 bba2fc1f 2008-12-08 reyk return (cnt);
267 bba2fc1f 2008-12-08 reyk }
268 bba2fc1f 2008-12-08 reyk
269 41042ecc 2006-12-16 reyk void
270 c8f9d8e3 2007-12-08 pyr flush_table(struct relayd *env, struct rdr *rdr)
271 41042ecc 2006-12-16 reyk {
272 41042ecc 2006-12-16 reyk struct pfioc_table io;
273 41042ecc 2006-12-16 reyk
274 58fc320c 2016-09-02 reyk if (!(env->sc_conf.flags & F_NEEDPF))
275 982e86f7 2008-05-06 pyr return;
276 982e86f7 2008-05-06 pyr
277 41042ecc 2006-12-16 reyk memset(&io, 0, sizeof(io));
278 6d0767ae 2007-12-07 reyk if (strlcpy(io.pfrio_table.pfrt_anchor, RELAYD_ANCHOR "/",
279 1ad64381 2007-02-08 reyk sizeof(io.pfrio_table.pfrt_anchor)) >= PF_ANCHOR_NAME_SIZE)
280 1ad64381 2007-02-08 reyk goto toolong;
281 c8f9d8e3 2007-12-08 pyr if (strlcat(io.pfrio_table.pfrt_anchor, rdr->conf.name,
282 1ad64381 2007-02-08 reyk sizeof(io.pfrio_table.pfrt_anchor)) >= PF_ANCHOR_NAME_SIZE)
283 1ad64381 2007-02-08 reyk goto toolong;
284 c8f9d8e3 2007-12-08 pyr if (strlcpy(io.pfrio_table.pfrt_name, rdr->conf.name,
285 1ad64381 2007-02-08 reyk sizeof(io.pfrio_table.pfrt_name)) >=
286 3e2ddb06 2007-02-22 reyk sizeof(io.pfrio_table.pfrt_name))
287 1ad64381 2007-02-08 reyk goto toolong;
288 23fba4ad 2008-01-31 reyk if (ioctl(env->sc_pf->dev, DIOCRCLRADDRS, &io) == -1)
289 09e53fee 2017-05-28 benno fatal("%s: cannot flush table addresses", __func__);
290 c56f873b 2008-05-06 reyk
291 c56f873b 2008-05-06 reyk io.pfrio_esize = sizeof(io.pfrio_table);
292 c56f873b 2008-05-06 reyk io.pfrio_size = 1;
293 c56f873b 2008-05-06 reyk io.pfrio_buffer = &io.pfrio_table;
294 23fba4ad 2008-01-31 reyk if (ioctl(env->sc_pf->dev, DIOCRCLRTSTATS, &io) == -1)
295 09e53fee 2017-05-28 benno fatal("%s: cannot flush table stats", __func__);
296 c56f873b 2008-05-06 reyk
297 666bd316 2011-05-05 reyk log_debug("%s: flushed table %s", __func__, rdr->conf.name);
298 41042ecc 2006-12-16 reyk return;
299 1ad64381 2007-02-08 reyk
300 1ad64381 2007-02-08 reyk toolong:
301 09e53fee 2017-05-28 benno fatal("%s: name too long", __func__);
302 41042ecc 2006-12-16 reyk }
303 41042ecc 2006-12-16 reyk
304 41042ecc 2006-12-16 reyk int
305 6d0767ae 2007-12-07 reyk transaction_init(struct relayd *env, const char *anchor)
306 41042ecc 2006-12-16 reyk {
307 05fcbce7 2009-09-01 reyk env->sc_pf->pft.size = 1;
308 05fcbce7 2009-09-01 reyk env->sc_pf->pft.esize = sizeof(env->sc_pf->pfte);
309 05fcbce7 2009-09-01 reyk env->sc_pf->pft.array = &env->sc_pf->pfte;
310 41042ecc 2006-12-16 reyk
311 05fcbce7 2009-09-01 reyk bzero(&env->sc_pf->pfte, sizeof(env->sc_pf->pfte));
312 05fcbce7 2009-09-01 reyk (void)strlcpy(env->sc_pf->pfte.anchor,
313 05fcbce7 2009-09-01 reyk anchor, PF_ANCHOR_NAME_SIZE);
314 8eb742e1 2009-11-23 claudio env->sc_pf->pfte.type = PF_TRANS_RULESET;
315 e8962295 2008-09-29 reyk
316 05fcbce7 2009-09-01 reyk if (ioctl(env->sc_pf->dev, DIOCXBEGIN,
317 05fcbce7 2009-09-01 reyk &env->sc_pf->pft) == -1)
318 05fcbce7 2009-09-01 reyk return (-1);
319 41042ecc 2006-12-16 reyk
320 4ab45c57 2006-12-16 reyk return (0);
321 41042ecc 2006-12-16 reyk }
322 41042ecc 2006-12-16 reyk
323 41042ecc 2006-12-16 reyk int
324 6d0767ae 2007-12-07 reyk transaction_commit(struct relayd *env)
325 41042ecc 2006-12-16 reyk {
326 05fcbce7 2009-09-01 reyk if (ioctl(env->sc_pf->dev, DIOCXCOMMIT,
327 05fcbce7 2009-09-01 reyk &env->sc_pf->pft) == -1)
328 05fcbce7 2009-09-01 reyk return (-1);
329 2ac5660d 2008-05-07 reyk
330 41042ecc 2006-12-16 reyk return (0);
331 41042ecc 2006-12-16 reyk }
332 41042ecc 2006-12-16 reyk
333 41042ecc 2006-12-16 reyk void
334 c8f9d8e3 2007-12-08 pyr sync_ruleset(struct relayd *env, struct rdr *rdr, int enable)
335 41042ecc 2006-12-16 reyk {
336 41042ecc 2006-12-16 reyk struct pfioc_rule rio;
337 41042ecc 2006-12-16 reyk struct sockaddr_in *sain;
338 41042ecc 2006-12-16 reyk struct sockaddr_in6 *sain6;
339 41042ecc 2006-12-16 reyk struct address *address;
340 41042ecc 2006-12-16 reyk char anchor[PF_ANCHOR_NAME_SIZE];
341 2ac5660d 2008-05-07 reyk struct table *t = rdr->table;
342 41042ecc 2006-12-16 reyk
343 58fc320c 2016-09-02 reyk if ((env->sc_conf.flags & F_NEEDPF) == 0)
344 982e86f7 2008-05-06 pyr return;
345 982e86f7 2008-05-06 pyr
346 41042ecc 2006-12-16 reyk bzero(anchor, sizeof(anchor));
347 6d0767ae 2007-12-07 reyk if (strlcpy(anchor, RELAYD_ANCHOR "/", sizeof(anchor)) >=
348 1ad64381 2007-02-08 reyk PF_ANCHOR_NAME_SIZE)
349 1ad64381 2007-02-08 reyk goto toolong;
350 c8f9d8e3 2007-12-08 pyr if (strlcat(anchor, rdr->conf.name, sizeof(anchor)) >=
351 1ad64381 2007-02-08 reyk PF_ANCHOR_NAME_SIZE)
352 1ad64381 2007-02-08 reyk goto toolong;
353 1ad64381 2007-02-08 reyk if (transaction_init(env, anchor) == -1) {
354 666bd316 2011-05-05 reyk log_warn("%s: transaction init failed", __func__);
355 1ad64381 2007-02-08 reyk return;
356 1ad64381 2007-02-08 reyk }
357 41042ecc 2006-12-16 reyk
358 41042ecc 2006-12-16 reyk if (!enable) {
359 1ad64381 2007-02-08 reyk if (transaction_commit(env) == -1)
360 666bd316 2011-05-05 reyk log_warn("%s: remove rules transaction failed",
361 666bd316 2011-05-05 reyk __func__);
362 1ad64381 2007-02-08 reyk else
363 666bd316 2011-05-05 reyk log_debug("%s: rules removed", __func__);
364 41042ecc 2006-12-16 reyk return;
365 41042ecc 2006-12-16 reyk }
366 41042ecc 2006-12-16 reyk
367 c8f9d8e3 2007-12-08 pyr TAILQ_FOREACH(address, &rdr->virts, entry) {
368 41042ecc 2006-12-16 reyk memset(&rio, 0, sizeof(rio));
369 41042ecc 2006-12-16 reyk (void)strlcpy(rio.anchor, anchor, sizeof(rio.anchor));
370 41042ecc 2006-12-16 reyk
371 9832d300 2010-10-26 reyk if (rdr->conf.flags & F_MATCH) {
372 9832d300 2010-10-26 reyk rio.rule.action = PF_MATCH;
373 9832d300 2010-10-26 reyk rio.rule.quick = 0;
374 9832d300 2010-10-26 reyk } else {
375 9832d300 2010-10-26 reyk rio.rule.action = PF_PASS;
376 9832d300 2010-10-26 reyk rio.rule.quick = 1; /* force first match */
377 9832d300 2010-10-26 reyk }
378 05fcbce7 2009-09-01 reyk rio.rule.direction = PF_IN;
379 05fcbce7 2009-09-01 reyk rio.rule.keep_state = PF_STATE_NORMAL;
380 05fcbce7 2009-09-01 reyk
381 199fb283 2024-06-17 sashan if (rdr->conf.flags & F_PFLOG)
382 199fb283 2024-06-17 sashan rio.rule.log = 1;
383 199fb283 2024-06-17 sashan else
384 199fb283 2024-06-17 sashan rio.rule.log = 0; /* allow change via reload */
385 199fb283 2024-06-17 sashan
386 6d5340e6 2008-06-11 reyk switch (t->conf.fwdmode) {
387 6d5340e6 2008-06-11 reyk case FWD_NORMAL:
388 05fcbce7 2009-09-01 reyk /* traditional redirection */
389 05fcbce7 2009-09-01 reyk if (address->ipproto == IPPROTO_TCP) {
390 05fcbce7 2009-09-01 reyk rio.rule.flags = TH_SYN;
391 05fcbce7 2009-09-01 reyk rio.rule.flagset = (TH_SYN|TH_ACK);
392 05fcbce7 2009-09-01 reyk }
393 6d5340e6 2008-06-11 reyk break;
394 6d5340e6 2008-06-11 reyk case FWD_ROUTE:
395 2ac5660d 2008-05-07 reyk /* re-route with pf for DSR (direct server return) */
396 2ac5660d 2008-05-07 reyk rio.rule.rt = PF_ROUTETO;
397 2ac5660d 2008-05-07 reyk
398 8626b048 2008-06-10 reyk /* Use sloppy state handling for half connections */
399 8626b048 2008-06-10 reyk rio.rule.rule_flag = PFRULE_STATESLOPPY;
400 6d5340e6 2008-06-11 reyk break;
401 6d5340e6 2008-06-11 reyk default:
402 09e53fee 2017-05-28 benno fatalx("%s: invalid forward mode", __func__);
403 6d5340e6 2008-06-11 reyk /* NOTREACHED */
404 2ac5660d 2008-05-07 reyk }
405 2ac5660d 2008-05-07 reyk
406 05fcbce7 2009-09-01 reyk rio.ticket = env->sc_pf->pfte.ticket;
407 41042ecc 2006-12-16 reyk
408 41042ecc 2006-12-16 reyk rio.rule.af = address->ss.ss_family;
409 d250825b 2009-04-24 reyk rio.rule.proto = address->ipproto;
410 41042ecc 2006-12-16 reyk rio.rule.src.addr.type = PF_ADDR_ADDRMASK;
411 41042ecc 2006-12-16 reyk rio.rule.dst.addr.type = PF_ADDR_ADDRMASK;
412 09913286 2008-09-29 reyk rio.rule.dst.port_op = address->port.op;
413 09913286 2008-09-29 reyk rio.rule.dst.port[0] = address->port.val[0];
414 09913286 2008-09-29 reyk rio.rule.dst.port[1] = address->port.val[1];
415 41042ecc 2006-12-16 reyk rio.rule.rtableid = -1; /* stay in the main routing table */
416 3a342b20 2015-11-29 benno rio.rule.onrdomain = env->sc_rtable;
417 3a342b20 2015-11-29 benno DPRINTF("%s rtable %d",__func__,env->sc_rtable);
418 2ac5660d 2008-05-07 reyk
419 d250825b 2009-04-24 reyk if (rio.rule.proto == IPPROTO_TCP)
420 d250825b 2009-04-24 reyk rio.rule.timeout[PFTM_TCP_ESTABLISHED] =
421 63e504f7 2015-01-22 reyk (u_int32_t)MINIMUM(rdr->conf.timeout.tv_sec,
422 63e504f7 2015-01-22 reyk INT_MAX);
423 d250825b 2009-04-24 reyk
424 c8f9d8e3 2007-12-08 pyr if (strlen(rdr->conf.tag))
425 c8f9d8e3 2007-12-08 pyr (void)strlcpy(rio.rule.tagname, rdr->conf.tag,
426 4ab45c57 2006-12-16 reyk sizeof(rio.rule.tagname));
427 41042ecc 2006-12-16 reyk if (strlen(address->ifname))
428 41042ecc 2006-12-16 reyk (void)strlcpy(rio.rule.ifname, address->ifname,
429 4ab45c57 2006-12-16 reyk sizeof(rio.rule.ifname));
430 41042ecc 2006-12-16 reyk
431 41042ecc 2006-12-16 reyk if (address->ss.ss_family == AF_INET) {
432 41042ecc 2006-12-16 reyk sain = (struct sockaddr_in *)&address->ss;
433 4ab45c57 2006-12-16 reyk
434 4ab45c57 2006-12-16 reyk rio.rule.dst.addr.v.a.addr.addr32[0] =
435 4ab45c57 2006-12-16 reyk sain->sin_addr.s_addr;
436 41042ecc 2006-12-16 reyk rio.rule.dst.addr.v.a.mask.addr32[0] = 0xffffffff;
437 41042ecc 2006-12-16 reyk } else {
438 41042ecc 2006-12-16 reyk sain6 = (struct sockaddr_in6 *)&address->ss;
439 4ab45c57 2006-12-16 reyk
440 41042ecc 2006-12-16 reyk memcpy(&rio.rule.dst.addr.v.a.addr.v6,
441 4ab45c57 2006-12-16 reyk &sain6->sin6_addr.s6_addr,
442 4ab45c57 2006-12-16 reyk sizeof(sain6->sin6_addr.s6_addr));
443 41042ecc 2006-12-16 reyk memset(&rio.rule.dst.addr.v.a.mask.addr8, 0xff, 16);
444 41042ecc 2006-12-16 reyk }
445 41042ecc 2006-12-16 reyk
446 4943c162 2010-01-12 dlg rio.rule.nat.addr.type = PF_ADDR_NONE;
447 552acc99 2010-01-12 mcbride rio.rule.rdr.addr.type = PF_ADDR_TABLE;
448 2ac5660d 2008-05-07 reyk if (strlen(t->conf.ifname))
449 552acc99 2010-01-12 mcbride (void)strlcpy(rio.rule.rdr.ifname, t->conf.ifname,
450 552acc99 2010-01-12 mcbride sizeof(rio.rule.rdr.ifname));
451 552acc99 2010-01-12 mcbride if (strlcpy(rio.rule.rdr.addr.v.tblname, rdr->conf.name,
452 552acc99 2010-01-12 mcbride sizeof(rio.rule.rdr.addr.v.tblname)) >=
453 552acc99 2010-01-12 mcbride sizeof(rio.rule.rdr.addr.v.tblname))
454 09e53fee 2017-05-28 benno fatal("%s: table name too long", __func__);
455 41042ecc 2006-12-16 reyk
456 09913286 2008-09-29 reyk if (address->port.op == PF_OP_EQ ||
457 09913286 2008-09-29 reyk rdr->table->conf.flags & F_PORT) {
458 05fcbce7 2009-09-01 reyk rio.rule.rdr.proxy_port[0] =
459 09913286 2008-09-29 reyk ntohs(rdr->table->conf.port);
460 05fcbce7 2009-09-01 reyk rio.rule.rdr.port_op = PF_OP_EQ;
461 09913286 2008-09-29 reyk }
462 d6c9879f 2012-10-19 reyk
463 d6c9879f 2012-10-19 reyk switch (rdr->conf.mode) {
464 10638510 2014-12-23 reyk case RELAY_DSTMODE_RANDOM:
465 10638510 2014-12-23 reyk rio.rule.rdr.opts = PF_POOL_RANDOM;
466 10638510 2014-12-23 reyk break;
467 d6c9879f 2012-10-19 reyk case RELAY_DSTMODE_ROUNDROBIN:
468 d6c9879f 2012-10-19 reyk rio.rule.rdr.opts = PF_POOL_ROUNDROBIN;
469 d6c9879f 2012-10-19 reyk break;
470 10638510 2014-12-23 reyk case RELAY_DSTMODE_SRCHASH:
471 10638510 2014-12-23 reyk rio.rule.rdr.opts = PF_POOL_SRCHASH;
472 10638510 2014-12-23 reyk break;
473 d6c9879f 2012-10-19 reyk case RELAY_DSTMODE_LEASTSTATES:
474 d6c9879f 2012-10-19 reyk rio.rule.rdr.opts = PF_POOL_LEASTSTATES;
475 d6c9879f 2012-10-19 reyk break;
476 d6c9879f 2012-10-19 reyk default:
477 09e53fee 2017-05-28 benno fatalx("%s: unsupported mode", __func__);
478 d6c9879f 2012-10-19 reyk /* NOTREACHED */
479 d6c9879f 2012-10-19 reyk }
480 c8f9d8e3 2007-12-08 pyr if (rdr->conf.flags & F_STICKY)
481 05fcbce7 2009-09-01 reyk rio.rule.rdr.opts |= PF_POOL_STICKYADDR;
482 10638510 2014-12-23 reyk if (rdr->conf.flags & F_HASHKEY)
483 10638510 2014-12-23 reyk memcpy(rio.rule.rdr.key.key32, rdr->conf.key.data,
484 10638510 2014-12-23 reyk sizeof(rio.rule.rdr.key.key32));
485 41042ecc 2006-12-16 reyk
486 1b676997 2010-03-24 pyr if (rio.rule.rt == PF_ROUTETO) {
487 1b676997 2010-03-24 pyr memcpy(&rio.rule.route, &rio.rule.rdr,
488 3a75ae45 2012-10-04 reyk sizeof(rio.rule.route));
489 1b676997 2010-03-24 pyr rio.rule.rdr.addr.type = PF_ADDR_NONE;
490 1b676997 2010-03-24 pyr }
491 1b676997 2010-03-24 pyr
492 23fba4ad 2008-01-31 reyk if (ioctl(env->sc_pf->dev, DIOCADDRULE, &rio) == -1)
493 41042ecc 2006-12-16 reyk fatal("cannot add rule");
494 666bd316 2011-05-05 reyk log_debug("%s: rule added to anchor \"%s\"", __func__, anchor);
495 41042ecc 2006-12-16 reyk }
496 1ad64381 2007-02-08 reyk if (transaction_commit(env) == -1)
497 666bd316 2011-05-05 reyk log_warn("%s: add rules transaction failed", __func__);
498 1ad64381 2007-02-08 reyk return;
499 1ad64381 2007-02-08 reyk
500 1ad64381 2007-02-08 reyk toolong:
501 09e53fee 2017-05-28 benno fatal("%s: name too long", __func__);
502 41042ecc 2006-12-16 reyk }
503 41042ecc 2006-12-16 reyk
504 41042ecc 2006-12-16 reyk void
505 6d0767ae 2007-12-07 reyk flush_rulesets(struct relayd *env)
506 41042ecc 2006-12-16 reyk {
507 c8f9d8e3 2007-12-08 pyr struct rdr *rdr;
508 41042ecc 2006-12-16 reyk char anchor[PF_ANCHOR_NAME_SIZE];
509 41042ecc 2006-12-16 reyk
510 58fc320c 2016-09-02 reyk if (!(env->sc_conf.flags & F_NEEDPF))
511 982e86f7 2008-05-06 pyr return;
512 982e86f7 2008-05-06 pyr
513 41042ecc 2006-12-16 reyk kill_tables(env);
514 23fba4ad 2008-01-31 reyk TAILQ_FOREACH(rdr, env->sc_rdrs, entry) {
515 6d0767ae 2007-12-07 reyk if (strlcpy(anchor, RELAYD_ANCHOR "/", sizeof(anchor)) >=
516 1ad64381 2007-02-08 reyk PF_ANCHOR_NAME_SIZE)
517 1ad64381 2007-02-08 reyk goto toolong;
518 c8f9d8e3 2007-12-08 pyr if (strlcat(anchor, rdr->conf.name, sizeof(anchor)) >=
519 1ad64381 2007-02-08 reyk PF_ANCHOR_NAME_SIZE)
520 1ad64381 2007-02-08 reyk goto toolong;
521 1ad64381 2007-02-08 reyk if (transaction_init(env, anchor) == -1 ||
522 1ad64381 2007-02-08 reyk transaction_commit(env) == -1)
523 666bd316 2011-05-05 reyk log_warn("%s: transaction for %s/ failed", __func__,
524 6d0767ae 2007-12-07 reyk RELAYD_ANCHOR);
525 4ab45c57 2006-12-16 reyk }
526 6d0767ae 2007-12-07 reyk if (strlcpy(anchor, RELAYD_ANCHOR, sizeof(anchor)) >=
527 1ad64381 2007-02-08 reyk PF_ANCHOR_NAME_SIZE)
528 1ad64381 2007-02-08 reyk goto toolong;
529 1ad64381 2007-02-08 reyk if (transaction_init(env, anchor) == -1 ||
530 1ad64381 2007-02-08 reyk transaction_commit(env) == -1)
531 666bd316 2011-05-05 reyk log_warn("%s: transaction for %s failed", __func__,
532 6d0767ae 2007-12-07 reyk RELAYD_ANCHOR);
533 666bd316 2011-05-05 reyk log_debug("%s: flushed rules", __func__);
534 3e2ddb06 2007-02-22 reyk return;
535 1ad64381 2007-02-08 reyk
536 1ad64381 2007-02-08 reyk toolong:
537 09e53fee 2017-05-28 benno fatal("%s: name too long", __func__);
538 41042ecc 2006-12-16 reyk }
539 30640247 2007-02-22 reyk
540 30640247 2007-02-22 reyk int
541 6d0767ae 2007-12-07 reyk natlook(struct relayd *env, struct ctl_natlook *cnl)
542 30640247 2007-02-22 reyk {
543 30640247 2007-02-22 reyk struct pfioc_natlook pnl;
544 30640247 2007-02-22 reyk struct sockaddr_in *in, *out;
545 30640247 2007-02-22 reyk struct sockaddr_in6 *in6, *out6;
546 30640247 2007-02-22 reyk char ibuf[BUFSIZ], obuf[BUFSIZ];
547 30640247 2007-02-22 reyk
548 58fc320c 2016-09-02 reyk if (!(env->sc_conf.flags & F_NEEDPF))
549 982e86f7 2008-05-06 pyr return (0);
550 982e86f7 2008-05-06 pyr
551 30640247 2007-02-22 reyk bzero(&pnl, sizeof(pnl));
552 30640247 2007-02-22 reyk
553 30640247 2007-02-22 reyk if ((pnl.af = cnl->src.ss_family) != cnl->dst.ss_family)
554 09e53fee 2017-05-28 benno fatalx("%s: illegal address families", __func__);
555 30640247 2007-02-22 reyk switch (pnl.af) {
556 30640247 2007-02-22 reyk case AF_INET:
557 30640247 2007-02-22 reyk in = (struct sockaddr_in *)&cnl->src;
558 30640247 2007-02-22 reyk out = (struct sockaddr_in *)&cnl->dst;
559 a279f7ce 2008-07-16 reyk bcopy(&in->sin_addr, &pnl.saddr.v4, sizeof(pnl.saddr.v4));
560 30640247 2007-02-22 reyk pnl.sport = in->sin_port;
561 a279f7ce 2008-07-16 reyk bcopy(&out->sin_addr, &pnl.daddr.v4, sizeof(pnl.daddr.v4));
562 30640247 2007-02-22 reyk pnl.dport = out->sin_port;
563 30640247 2007-02-22 reyk break;
564 30640247 2007-02-22 reyk case AF_INET6:
565 30640247 2007-02-22 reyk in6 = (struct sockaddr_in6 *)&cnl->src;
566 30640247 2007-02-22 reyk out6 = (struct sockaddr_in6 *)&cnl->dst;
567 a279f7ce 2008-07-16 reyk bcopy(&in6->sin6_addr, &pnl.saddr.v6, sizeof(pnl.saddr.v6));
568 30640247 2007-02-22 reyk pnl.sport = in6->sin6_port;
569 a279f7ce 2008-07-16 reyk bcopy(&out6->sin6_addr, &pnl.daddr.v6, sizeof(pnl.daddr.v6));
570 30640247 2007-02-22 reyk pnl.dport = out6->sin6_port;
571 30640247 2007-02-22 reyk }
572 555b1b20 2008-07-09 reyk pnl.proto = cnl->proto;
573 30640247 2007-02-22 reyk pnl.direction = PF_IN;
574 30640247 2007-02-22 reyk cnl->in = 1;
575 30640247 2007-02-22 reyk
576 23fba4ad 2008-01-31 reyk if (ioctl(env->sc_pf->dev, DIOCNATLOOK, &pnl) == -1) {
577 30640247 2007-02-22 reyk pnl.direction = PF_OUT;
578 30640247 2007-02-22 reyk cnl->in = 0;
579 23fba4ad 2008-01-31 reyk if (ioctl(env->sc_pf->dev, DIOCNATLOOK, &pnl) == -1) {
580 666bd316 2011-05-05 reyk log_debug("%s: ioctl: %s", __func__, strerror(errno));
581 30640247 2007-02-22 reyk return (-1);
582 30640247 2007-02-22 reyk }
583 30640247 2007-02-22 reyk }
584 30640247 2007-02-22 reyk
585 30640247 2007-02-22 reyk inet_ntop(pnl.af, &pnl.rsaddr, ibuf, sizeof(ibuf));
586 30640247 2007-02-22 reyk inet_ntop(pnl.af, &pnl.rdaddr, obuf, sizeof(obuf));
587 666bd316 2011-05-05 reyk log_debug("%s: %s %s:%d -> %s:%d", __func__,
588 30640247 2007-02-22 reyk pnl.direction == PF_IN ? "in" : "out",
589 30640247 2007-02-22 reyk ibuf, ntohs(pnl.rsport), obuf, ntohs(pnl.rdport));
590 30640247 2007-02-22 reyk
591 30640247 2007-02-22 reyk switch (pnl.af) {
592 30640247 2007-02-22 reyk case AF_INET:
593 30640247 2007-02-22 reyk in = (struct sockaddr_in *)&cnl->rsrc;
594 30640247 2007-02-22 reyk out = (struct sockaddr_in *)&cnl->rdst;
595 a279f7ce 2008-07-16 reyk bcopy(&pnl.rsaddr.v4, &in->sin_addr, sizeof(in->sin_addr));
596 30640247 2007-02-22 reyk in->sin_port = pnl.rsport;
597 a279f7ce 2008-07-16 reyk bcopy(&pnl.rdaddr.v4, &out->sin_addr, sizeof(out->sin_addr));
598 30640247 2007-02-22 reyk out->sin_port = pnl.rdport;
599 30640247 2007-02-22 reyk break;
600 30640247 2007-02-22 reyk case AF_INET6:
601 30640247 2007-02-22 reyk in6 = (struct sockaddr_in6 *)&cnl->rsrc;
602 30640247 2007-02-22 reyk out6 = (struct sockaddr_in6 *)&cnl->rdst;
603 a279f7ce 2008-07-16 reyk bcopy(&pnl.rsaddr.v6, &in6->sin6_addr, sizeof(in6->sin6_addr));
604 a279f7ce 2008-07-16 reyk bcopy(&pnl.rdaddr.v6, &out6->sin6_addr,
605 3e2ddb06 2007-02-22 reyk sizeof(out6->sin6_addr));
606 30640247 2007-02-22 reyk break;
607 30640247 2007-02-22 reyk }
608 30640247 2007-02-22 reyk cnl->rsrc.ss_family = pnl.af;
609 30640247 2007-02-22 reyk cnl->rdst.ss_family = pnl.af;
610 30640247 2007-02-22 reyk cnl->rsport = pnl.rsport;
611 30640247 2007-02-22 reyk cnl->rdport = pnl.rdport;
612 30640247 2007-02-22 reyk
613 30640247 2007-02-22 reyk return (0);
614 30640247 2007-02-22 reyk }
615 90f6aaca 2007-12-20 reyk
616 90f6aaca 2007-12-20 reyk u_int64_t
617 90f6aaca 2007-12-20 reyk check_table(struct relayd *env, struct rdr *rdr, struct table *table)
618 90f6aaca 2007-12-20 reyk {
619 90f6aaca 2007-12-20 reyk struct pfioc_table io;
620 90f6aaca 2007-12-20 reyk struct pfr_tstats tstats;
621 90f6aaca 2007-12-20 reyk
622 90f6aaca 2007-12-20 reyk if (table == NULL)
623 90f6aaca 2007-12-20 reyk return (0);
624 90f6aaca 2007-12-20 reyk
625 90f6aaca 2007-12-20 reyk bzero(&io, sizeof(io));
626 90f6aaca 2007-12-20 reyk io.pfrio_esize = sizeof(struct pfr_tstats);
627 90f6aaca 2007-12-20 reyk io.pfrio_size = 1;
628 90f6aaca 2007-12-20 reyk io.pfrio_buffer = &tstats;
629 90f6aaca 2007-12-20 reyk if (strlcpy(io.pfrio_table.pfrt_anchor, RELAYD_ANCHOR "/",
630 90f6aaca 2007-12-20 reyk sizeof(io.pfrio_table.pfrt_anchor)) >= PF_ANCHOR_NAME_SIZE)
631 90f6aaca 2007-12-20 reyk goto toolong;
632 90f6aaca 2007-12-20 reyk if (strlcat(io.pfrio_table.pfrt_anchor, rdr->conf.name,
633 90f6aaca 2007-12-20 reyk sizeof(io.pfrio_table.pfrt_anchor)) >= PF_ANCHOR_NAME_SIZE)
634 90f6aaca 2007-12-20 reyk goto toolong;
635 90f6aaca 2007-12-20 reyk if (strlcpy(io.pfrio_table.pfrt_name, rdr->conf.name,
636 90f6aaca 2007-12-20 reyk sizeof(io.pfrio_table.pfrt_name)) >=
637 90f6aaca 2007-12-20 reyk sizeof(io.pfrio_table.pfrt_name))
638 90f6aaca 2007-12-20 reyk goto toolong;
639 90f6aaca 2007-12-20 reyk
640 23fba4ad 2008-01-31 reyk if (ioctl(env->sc_pf->dev, DIOCRGETTSTATS, &io) == -1)
641 a02f2cfd 2023-06-30 sashan fatal("%s: cannot get table stats for %s@%s", __func__,
642 a02f2cfd 2023-06-30 sashan io.pfrio_table.pfrt_name, io.pfrio_table.pfrt_anchor);
643 90f6aaca 2007-12-20 reyk
644 90f6aaca 2007-12-20 reyk return (tstats.pfrts_match);
645 90f6aaca 2007-12-20 reyk
646 90f6aaca 2007-12-20 reyk toolong:
647 09e53fee 2017-05-28 benno fatal("%s: name too long", __func__);
648 90f6aaca 2007-12-20 reyk return (0);
649 90f6aaca 2007-12-20 reyk }