Bug Summary

File:net/pf_lb.c
Warning:line 626, column 4
2nd function call argument is an uninitialized value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name pf_lb.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -D CONFIG_DRM_AMD_DC_DCN3_0 -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /usr/obj/sys/arch/amd64/compile/GENERIC.MP/scan-build/2022-01-12-131800-47421-1 -x c /usr/src/sys/net/pf_lb.c
1/* $OpenBSD: pf_lb.c,v 1.69 2021/12/16 02:01:59 sashan Exp $ */
2
3/*
4 * Copyright (c) 2001 Daniel Hartmeier
5 * Copyright (c) 2002 - 2008 Henning Brauer
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * - Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * - Redistributions in binary form must reproduce the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer in the documentation and/or other materials provided
17 * with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 *
32 * Effort sponsored in part by the Defense Advanced Research Projects
33 * Agency (DARPA) and Air Force Research Laboratory, Air Force
34 * Materiel Command, USAF, under agreement number F30602-01-2-0537.
35 *
36 */
37
38#include "bpfilter.h"
39#include "pflog.h"
40#include "pfsync.h"
41#include "pflow.h"
42
43#include <sys/param.h>
44#include <sys/systm.h>
45#include <sys/mbuf.h>
46#include <sys/filio.h>
47#include <sys/socket.h>
48#include <sys/socketvar.h>
49#include <sys/kernel.h>
50#include <sys/time.h>
51#include <sys/pool.h>
52#include <sys/rwlock.h>
53#include <sys/syslog.h>
54#include <sys/stdint.h>
55
56#include <crypto/siphash.h>
57
58#include <net/if.h>
59#include <net/bpf.h>
60#include <net/route.h>
61
62#include <netinet/in.h>
63#include <netinet/ip.h>
64#include <netinet/in_pcb.h>
65#include <netinet/ip_var.h>
66#include <netinet/ip_icmp.h>
67#include <netinet/icmp_var.h>
68#include <netinet/tcp.h>
69#include <netinet/tcp_seq.h>
70#include <netinet/tcp_timer.h>
71#include <netinet/udp.h>
72#include <netinet/udp_var.h>
73#include <netinet/if_ether.h>
74
75#ifdef INET61
76#include <netinet/ip6.h>
77#include <netinet/icmp6.h>
78#endif /* INET6 */
79
80#include <net/pfvar.h>
81#include <net/pfvar_priv.h>
82
83#if NPFLOG1 > 0
84#include <net/if_pflog.h>
85#endif /* NPFLOG > 0 */
86
87#if NPFLOW1 > 0
88#include <net/if_pflow.h>
89#endif /* NPFLOW > 0 */
90
91#if NPFSYNC1 > 0
92#include <net/if_pfsync.h>
93#endif /* NPFSYNC > 0 */
94
95u_int64_t pf_hash(struct pf_addr *, struct pf_addr *,
96 struct pf_poolhashkey *, sa_family_t);
97int pf_get_sport(struct pf_pdesc *, struct pf_rule *,
98 struct pf_addr *, u_int16_t *, u_int16_t,
99 u_int16_t, struct pf_src_node **);
100int pf_map_addr_states_increase(sa_family_t,
101 struct pf_pool *, struct pf_addr *);
102int pf_get_transaddr_af(struct pf_rule *,
103 struct pf_pdesc *, struct pf_src_node **);
104int pf_map_addr_sticky(sa_family_t, struct pf_rule *,
105 struct pf_addr *, struct pf_addr *,
106 struct pf_src_node **, struct pf_pool *,
107 enum pf_sn_types);
108
109u_int64_t
110pf_hash(struct pf_addr *inaddr, struct pf_addr *hash,
111 struct pf_poolhashkey *key, sa_family_t af)
112{
113 uint64_t res = 0;
114#ifdef INET61
115 union {
116 uint64_t hash64;
117 uint32_t hash32[2];
118 } h;
119#endif /* INET6 */
120
121 switch (af) {
122 case AF_INET2:
123 res = SipHash24((SIPHASH_KEY *)key,SipHash(((SIPHASH_KEY *)key), 2, 4, (&inaddr->pfa.addr32
[0]), (sizeof(inaddr->pfa.addr32[0])))
124 &inaddr->addr32[0], sizeof(inaddr->addr32[0]))SipHash(((SIPHASH_KEY *)key), 2, 4, (&inaddr->pfa.addr32
[0]), (sizeof(inaddr->pfa.addr32[0])))
;
125 hash->addr32pfa.addr32[0] = res;
126 break;
127#ifdef INET61
128 case AF_INET624:
129 res = SipHash24((SIPHASH_KEY *)key, &inaddr->addr32[0],SipHash(((SIPHASH_KEY *)key), 2, 4, (&inaddr->pfa.addr32
[0]), (4 * sizeof(inaddr->pfa.addr32[0])))
130 4 * sizeof(inaddr->addr32[0]))SipHash(((SIPHASH_KEY *)key), 2, 4, (&inaddr->pfa.addr32
[0]), (4 * sizeof(inaddr->pfa.addr32[0])))
;
131 h.hash64 = res;
132 hash->addr32pfa.addr32[0] = h.hash32[0];
133 hash->addr32pfa.addr32[1] = h.hash32[1];
134 /*
135 * siphash isn't big enough, but flipping it around is
136 * good enough here.
137 */
138 hash->addr32pfa.addr32[2] = ~h.hash32[1];
139 hash->addr32pfa.addr32[3] = ~h.hash32[0];
140 break;
141#endif /* INET6 */
142 default:
143 unhandled_af(af);
144 }
145 return (res);
146}
147
148int
149pf_get_sport(struct pf_pdesc *pd, struct pf_rule *r,
150 struct pf_addr *naddr, u_int16_t *nport, u_int16_t low, u_int16_t high,
151 struct pf_src_node **sn)
152{
153 struct pf_state_key_cmp key;
154 struct pf_addr init_addr;
155 u_int16_t cut;
156 int dir = (pd->dir == PF_IN) ? PF_OUT : PF_IN;
157 int sidx = pd->sidx;
158 int didx = pd->didx;
159
160 memset(&init_addr, 0, sizeof(init_addr))__builtin_memset((&init_addr), (0), (sizeof(init_addr)));
161 if (pf_map_addr(pd->naf, r, &pd->nsaddr, naddr, &init_addr, sn, &r->nat,
162 PF_SN_NAT))
163 return (1);
164
165 if (pd->proto == IPPROTO_ICMP1) {
166 if (pd->ndport == htons(ICMP_ECHO)(__uint16_t)(__builtin_constant_p(8) ? (__uint16_t)(((__uint16_t
)(8) & 0xffU) << 8 | ((__uint16_t)(8) & 0xff00U
) >> 8) : __swap16md(8))
) {
167 low = 1;
168 high = 65535;
169 } else
170 return (0); /* Don't try to modify non-echo ICMP */
171 }
172#ifdef INET61
173 if (pd->proto == IPPROTO_ICMPV658) {
174 if (pd->ndport == htons(ICMP6_ECHO_REQUEST)(__uint16_t)(__builtin_constant_p(128) ? (__uint16_t)(((__uint16_t
)(128) & 0xffU) << 8 | ((__uint16_t)(128) & 0xff00U
) >> 8) : __swap16md(128))
) {
175 low = 1;
176 high = 65535;
177 } else
178 return (0); /* Don't try to modify non-echo ICMP */
179 }
180#endif /* INET6 */
181
182 do {
183 key.af = pd->naf;
184 key.proto = pd->proto;
185 key.rdomain = pd->rdomain;
186 pf_addrcpy(&key.addr[didx], &pd->ndaddr, key.af);
187 pf_addrcpy(&key.addr[sidx], naddr, key.af);
188 key.port[didx] = pd->ndport;
189
190 /*
191 * port search; start random, step;
192 * similar 2 portloop in in_pcbbind
193 */
194 if (!(pd->proto == IPPROTO_TCP6 || pd->proto == IPPROTO_UDP17 ||
195 pd->proto == IPPROTO_ICMP1 || pd->proto == IPPROTO_ICMPV658)) {
196 /* XXX bug: icmp states dont use the id on both
197 * XXX sides (traceroute -I through nat) */
198 key.port[sidx] = pd->nsport;
199 if (pf_find_state_all(&key, dir, NULL((void *)0)) == NULL((void *)0)) {
200 *nport = pd->nsport;
201 return (0);
202 }
203 } else if (low == 0 && high == 0) {
204 key.port[sidx] = pd->nsport;
205 if (pf_find_state_all(&key, dir, NULL((void *)0)) == NULL((void *)0)) {
206 *nport = pd->nsport;
207 return (0);
208 }
209 } else if (low == high) {
210 key.port[sidx] = htons(low)(__uint16_t)(__builtin_constant_p(low) ? (__uint16_t)(((__uint16_t
)(low) & 0xffU) << 8 | ((__uint16_t)(low) & 0xff00U
) >> 8) : __swap16md(low))
;
211 if (pf_find_state_all(&key, dir, NULL((void *)0)) == NULL((void *)0)) {
212 *nport = htons(low)(__uint16_t)(__builtin_constant_p(low) ? (__uint16_t)(((__uint16_t
)(low) & 0xffU) << 8 | ((__uint16_t)(low) & 0xff00U
) >> 8) : __swap16md(low))
;
213 return (0);
214 }
215 } else {
216 u_int32_t tmp;
217
218 if (low > high) {
219 tmp = low;
220 low = high;
221 high = tmp;
222 }
223 /* low < high */
224 cut = arc4random_uniform(1 + high - low) + low;
225 /* low <= cut <= high */
226 for (tmp = cut; tmp <= high && tmp <= 0xffff; ++tmp) {
227 key.port[sidx] = htons(tmp)(__uint16_t)(__builtin_constant_p(tmp) ? (__uint16_t)(((__uint16_t
)(tmp) & 0xffU) << 8 | ((__uint16_t)(tmp) & 0xff00U
) >> 8) : __swap16md(tmp))
;
228 if (pf_find_state_all(&key, dir, NULL((void *)0)) ==
229 NULL((void *)0) && !in_baddynamic(tmp, pd->proto)) {
230 *nport = htons(tmp)(__uint16_t)(__builtin_constant_p(tmp) ? (__uint16_t)(((__uint16_t
)(tmp) & 0xffU) << 8 | ((__uint16_t)(tmp) & 0xff00U
) >> 8) : __swap16md(tmp))
;
231 return (0);
232 }
233 }
234 tmp = cut;
235 for (tmp -= 1; tmp >= low && tmp <= 0xffff; --tmp) {
236 key.port[sidx] = htons(tmp)(__uint16_t)(__builtin_constant_p(tmp) ? (__uint16_t)(((__uint16_t
)(tmp) & 0xffU) << 8 | ((__uint16_t)(tmp) & 0xff00U
) >> 8) : __swap16md(tmp))
;
237 if (pf_find_state_all(&key, dir, NULL((void *)0)) ==
238 NULL((void *)0) && !in_baddynamic(tmp, pd->proto)) {
239 *nport = htons(tmp)(__uint16_t)(__builtin_constant_p(tmp) ? (__uint16_t)(((__uint16_t
)(tmp) & 0xffU) << 8 | ((__uint16_t)(tmp) & 0xff00U
) >> 8) : __swap16md(tmp))
;
240 return (0);
241 }
242 }
243 }
244
245 switch (r->nat.opts & PF_POOL_TYPEMASK0x0f) {
246 case PF_POOL_RANDOM:
247 case PF_POOL_ROUNDROBIN:
248 case PF_POOL_LEASTSTATES:
249 /*
250 * pick a different source address since we're out
251 * of free port choices for the current one.
252 */
253 if (pf_map_addr(pd->naf, r, &pd->nsaddr, naddr,
254 &init_addr, sn, &r->nat, PF_SN_NAT))
255 return (1);
256 break;
257 case PF_POOL_NONE:
258 case PF_POOL_SRCHASH:
259 case PF_POOL_BITMASK:
260 default:
261 return (1);
262 }
263 } while (! PF_AEQ(&init_addr, naddr, pd->naf)((pd->naf == 2 && (&init_addr)->pfa.addr32[
0] == (naddr)->pfa.addr32[0]) || (pd->naf == 24 &&
(&init_addr)->pfa.addr32[3] == (naddr)->pfa.addr32
[3] && (&init_addr)->pfa.addr32[2] == (naddr)->
pfa.addr32[2] && (&init_addr)->pfa.addr32[1] ==
(naddr)->pfa.addr32[1] && (&init_addr)->pfa
.addr32[0] == (naddr)->pfa.addr32[0]))
);
264 return (1); /* none available */
265}
266
267int
268pf_map_addr_sticky(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
269 struct pf_addr *naddr, struct pf_src_node **sns, struct pf_pool *rpool,
270 enum pf_sn_types type)
271{
272 struct pf_addr *raddr, *rmask, *cached;
273 struct pf_state *s;
274 struct pf_src_node k;
275 int valid;
276
277 k.af = af;
278 k.type = type;
279 pf_addrcpy(&k.addr, saddr, af);
280 k.rule.ptr = r;
281 pf_status.scounters[SCNT_SRC_NODE_SEARCH0]++;
282 sns[type] = RB_FIND(pf_src_tree, &tree_src_tracking, &k)pf_src_tree_RB_FIND(&tree_src_tracking, &k);
283 if (sns[type] == NULL((void *)0))
284 return (-1);
285
286 /* check if the cached entry is still valid */
287 cached = &(sns[type])->raddr;
288 valid = 0;
289 if (PF_AZERO(cached, af)((af == 2 && !(cached)->pfa.addr32[0]) || (af == 24
&& !(cached)->pfa.addr32[0] && !(cached)->
pfa.addr32[1] && !(cached)->pfa.addr32[2] &&
!(cached)->pfa.addr32[3] ))
) {
290 valid = 1;
291 } else if (rpool->addr.type == PF_ADDR_DYNIFTL) {
292 if (pfr_kentry_byaddr(rpool->addr.p.dyn->pfid_kt, cached,
293 af, 0))
294 valid = 1;
295 } else if (rpool->addr.type == PF_ADDR_TABLE) {
296 if (pfr_kentry_byaddr(rpool->addr.p.tbl, cached, af, 0))
297 valid = 1;
298 } else if (rpool->addr.type != PF_ADDR_NOROUTE) {
299 raddr = &rpool->addr.v.a.addr;
300 rmask = &rpool->addr.v.a.mask;
301 valid = pf_match_addr(0, raddr, rmask, cached, af);
302 }
303 if (!valid) {
304 if (pf_status.debug >= LOG_DEBUG7) {
305 log(LOG_DEBUG7, "pf: pf_map_addr: "
306 "stale src tracking (%u) ", type);
307 pf_print_host(&k.addr, 0, af);
308 addlog(" to ");
309 pf_print_host(cached, 0, af);
310 addlog("\n");
311 }
312 if (sns[type]->states != 0) {
313 /* XXX expensive */
314 RB_FOREACH(s, pf_state_tree_id,for ((s) = pf_state_tree_id_RB_MINMAX(&tree_id, -1); (s) !=
((void *)0); (s) = pf_state_tree_id_RB_NEXT(s))
315 &tree_id)for ((s) = pf_state_tree_id_RB_MINMAX(&tree_id, -1); (s) !=
((void *)0); (s) = pf_state_tree_id_RB_NEXT(s))
316 pf_state_rm_src_node(s,
317 sns[type]);
318 }
319 sns[type]->expire = 1;
320 pf_remove_src_node(sns[type]);
321 sns[type] = NULL((void *)0);
322 return (-1);
323 }
324
325
326 if (!PF_AZERO(cached, af)((af == 2 && !(cached)->pfa.addr32[0]) || (af == 24
&& !(cached)->pfa.addr32[0] && !(cached)->
pfa.addr32[1] && !(cached)->pfa.addr32[2] &&
!(cached)->pfa.addr32[3] ))
) {
327 pf_addrcpy(naddr, cached, af);
328 if ((rpool->opts & PF_POOL_TYPEMASK0x0f) == PF_POOL_LEASTSTATES &&
329 pf_map_addr_states_increase(af, rpool, cached) == -1)
330 return (-1);
331 }
332 if (pf_status.debug >= LOG_DEBUG7) {
333 log(LOG_DEBUG7, "pf: pf_map_addr: "
334 "src tracking (%u) maps ", type);
335 pf_print_host(&k.addr, 0, af);
336 addlog(" to ");
337 pf_print_host(naddr, 0, af);
338 addlog("\n");
339 }
340
341 if (sns[type]->kif != NULL((void *)0))
342 rpool->kif = sns[type]->kif;
343
344 return (0);
345}
346
347int
348pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
349 struct pf_addr *naddr, struct pf_addr *init_addr, struct pf_src_node **sns,
350 struct pf_pool *rpool, enum pf_sn_types type)
351{
352 struct pf_addr hash;
353 struct pf_addr faddr;
354 struct pf_addr *raddr = &rpool->addr.v.a.addr;
355 struct pf_addr *rmask = &rpool->addr.v.a.mask;
356 struct pfr_ktable *kt;
357 struct pfi_kif *kif;
358 u_int64_t states;
1
'states' declared without an initial value
359 u_int16_t weight;
360 u_int64_t load;
361 u_int64_t cload;
362 u_int64_t hashidx;
363 int cnt;
364
365 if (sns[type] == NULL((void *)0) && rpool->opts & PF_POOL_STICKYADDR0x20 &&
2
Assuming the condition is false
366 (rpool->opts & PF_POOL_TYPEMASK0x0f) != PF_POOL_NONE &&
367 pf_map_addr_sticky(af, r, saddr, naddr, sns, rpool, type) == 0)
368 return (0);
369
370 if (rpool->addr.type == PF_ADDR_NOROUTE)
3
Assuming field 'type' is not equal to PF_ADDR_NOROUTE
4
Taking false branch
371 return (1);
372 if (rpool->addr.type == PF_ADDR_DYNIFTL) {
5
Assuming field 'type' is not equal to PF_ADDR_DYNIFTL
6
Taking false branch
373 switch (af) {
374 case AF_INET2:
375 if (rpool->addr.p.dyn->pfid_acnt4 < 1 &&
376 !PF_POOL_DYNTYPE(rpool->opts)((((rpool->opts) & 0x0f) == PF_POOL_ROUNDROBIN) || (((
rpool->opts) & 0x0f) == PF_POOL_LEASTSTATES) || (((rpool
->opts) & 0x0f) == PF_POOL_RANDOM) || (((rpool->opts
) & 0x0f) == PF_POOL_SRCHASH))
)
377 return (1);
378 raddr = &rpool->addr.p.dyn->pfid_addr4;
379 rmask = &rpool->addr.p.dyn->pfid_mask4;
380 break;
381#ifdef INET61
382 case AF_INET624:
383 if (rpool->addr.p.dyn->pfid_acnt6 < 1 &&
384 !PF_POOL_DYNTYPE(rpool->opts)((((rpool->opts) & 0x0f) == PF_POOL_ROUNDROBIN) || (((
rpool->opts) & 0x0f) == PF_POOL_LEASTSTATES) || (((rpool
->opts) & 0x0f) == PF_POOL_RANDOM) || (((rpool->opts
) & 0x0f) == PF_POOL_SRCHASH))
)
385 return (1);
386 raddr = &rpool->addr.p.dyn->pfid_addr6;
387 rmask = &rpool->addr.p.dyn->pfid_mask6;
388 break;
389#endif /* INET6 */
390 default:
391 unhandled_af(af);
392 }
393 } else if (rpool->addr.type == PF_ADDR_TABLE) {
7
Assuming field 'type' is not equal to PF_ADDR_TABLE
8
Taking false branch
394 if (!PF_POOL_DYNTYPE(rpool->opts)((((rpool->opts) & 0x0f) == PF_POOL_ROUNDROBIN) || (((
rpool->opts) & 0x0f) == PF_POOL_LEASTSTATES) || (((rpool
->opts) & 0x0f) == PF_POOL_RANDOM) || (((rpool->opts
) & 0x0f) == PF_POOL_SRCHASH))
)
395 return (1); /* unsupported */
396 } else {
397 raddr = &rpool->addr.v.a.addr;
398 rmask = &rpool->addr.v.a.mask;
399 }
400
401 switch (rpool->opts & PF_POOL_TYPEMASK0x0f) {
9
Control jumps to 'case PF_POOL_NONE:' at line 402
402 case PF_POOL_NONE:
403 pf_addrcpy(naddr, raddr, af);
404 break;
10
Execution continues on line 610
405 case PF_POOL_BITMASK:
406 pf_poolmask(naddr, raddr, rmask, saddr, af);
407 break;
408 case PF_POOL_RANDOM:
409 if (rpool->addr.type == PF_ADDR_TABLE ||
410 rpool->addr.type == PF_ADDR_DYNIFTL) {
411 if (rpool->addr.type == PF_ADDR_TABLE)
412 kt = rpool->addr.p.tbl;
413 else
414 kt = rpool->addr.p.dyn->pfid_kt;
415 kt = pfr_ktable_select_active(kt);
416 if (kt == NULL((void *)0))
417 return (1);
418
419 cnt = kt->pfrkt_cntpfrkt_ts.pfrts_cnt;
420 if (cnt == 0)
421 rpool->tblidx = 0;
422 else
423 rpool->tblidx = (int)arc4random_uniform(cnt);
424 memset(&rpool->counter, 0, sizeof(rpool->counter))__builtin_memset((&rpool->counter), (0), (sizeof(rpool
->counter)))
;
425 if (pfr_pool_get(rpool, &raddr, &rmask, af))
426 return (1);
427 pf_addrcpy(naddr, &rpool->counter, af);
428 } else if (init_addr != NULL((void *)0) && PF_AZERO(init_addr, af)((af == 2 && !(init_addr)->pfa.addr32[0]) || (af ==
24 && !(init_addr)->pfa.addr32[0] && !(init_addr
)->pfa.addr32[1] && !(init_addr)->pfa.addr32[2]
&& !(init_addr)->pfa.addr32[3] ))
) {
429 switch (af) {
430 case AF_INET2:
431 rpool->counter.addr32pfa.addr32[0] = arc4random();
432 break;
433#ifdef INET61
434 case AF_INET624:
435 if (rmask->addr32pfa.addr32[3] != 0xffffffff)
436 rpool->counter.addr32pfa.addr32[3] = arc4random();
437 else
438 break;
439 if (rmask->addr32pfa.addr32[2] != 0xffffffff)
440 rpool->counter.addr32pfa.addr32[2] = arc4random();
441 else
442 break;
443 if (rmask->addr32pfa.addr32[1] != 0xffffffff)
444 rpool->counter.addr32pfa.addr32[1] = arc4random();
445 else
446 break;
447 if (rmask->addr32pfa.addr32[0] != 0xffffffff)
448 rpool->counter.addr32pfa.addr32[0] = arc4random();
449 break;
450#endif /* INET6 */
451 default:
452 unhandled_af(af);
453 }
454 pf_poolmask(naddr, raddr, rmask, &rpool->counter, af);
455 pf_addrcpy(init_addr, naddr, af);
456
457 } else {
458 pf_addr_inc(&rpool->counter, af);
459 pf_poolmask(naddr, raddr, rmask, &rpool->counter, af);
460 }
461 break;
462 case PF_POOL_SRCHASH:
463 hashidx = pf_hash(saddr, &hash, &rpool->key, af);
464
465 if (rpool->addr.type == PF_ADDR_TABLE ||
466 rpool->addr.type == PF_ADDR_DYNIFTL) {
467 if (rpool->addr.type == PF_ADDR_TABLE)
468 kt = rpool->addr.p.tbl;
469 else
470 kt = rpool->addr.p.dyn->pfid_kt;
471 kt = pfr_ktable_select_active(kt);
472 if (kt == NULL((void *)0))
473 return (1);
474
475 cnt = kt->pfrkt_cntpfrkt_ts.pfrts_cnt;
476 if (cnt == 0)
477 rpool->tblidx = 0;
478 else
479 rpool->tblidx = (int)(hashidx % cnt);
480 memset(&rpool->counter, 0, sizeof(rpool->counter))__builtin_memset((&rpool->counter), (0), (sizeof(rpool
->counter)))
;
481 if (pfr_pool_get(rpool, &raddr, &rmask, af))
482 return (1);
483 pf_addrcpy(naddr, &rpool->counter, af);
484 } else {
485 pf_poolmask(naddr, raddr, rmask, &hash, af);
486 }
487 break;
488 case PF_POOL_ROUNDROBIN:
489 if (rpool->addr.type == PF_ADDR_TABLE ||
490 rpool->addr.type == PF_ADDR_DYNIFTL) {
491 if (pfr_pool_get(rpool, &raddr, &rmask, af)) {
492 /*
493 * reset counter in case its value
494 * has been removed from the pool.
495 */
496 memset(&rpool->counter, 0,__builtin_memset((&rpool->counter), (0), (sizeof(rpool
->counter)))
497 sizeof(rpool->counter))__builtin_memset((&rpool->counter), (0), (sizeof(rpool
->counter)))
;
498 if (pfr_pool_get(rpool, &raddr, &rmask, af))
499 return (1);
500 }
501 } else if (pf_match_addr(0, raddr, rmask, &rpool->counter, af))
502 return (1);
503
504 /* iterate over table if it contains entries which are weighted */
505 if ((rpool->addr.type == PF_ADDR_TABLE &&
506 rpool->addr.p.tbl->pfrkt_refcntcost > 0) ||
507 (rpool->addr.type == PF_ADDR_DYNIFTL &&
508 rpool->addr.p.dyn->pfid_kt->pfrkt_refcntcost > 0)) {
509 do {
510 if (rpool->addr.type == PF_ADDR_TABLE ||
511 rpool->addr.type == PF_ADDR_DYNIFTL) {
512 if (pfr_pool_get(rpool,
513 &raddr, &rmask, af))
514 return (1);
515 } else {
516 log(LOG_ERR3, "pf: pf_map_addr: "
517 "weighted RR failure");
518 return (1);
519 }
520 if (rpool->weight >= rpool->curweight)
521 break;
522 pf_addr_inc(&rpool->counter, af);
523 } while (1);
524
525 weight = rpool->weight;
526 }
527
528 pf_addrcpy(naddr, &rpool->counter, af);
529 if (init_addr != NULL((void *)0) && PF_AZERO(init_addr, af)((af == 2 && !(init_addr)->pfa.addr32[0]) || (af ==
24 && !(init_addr)->pfa.addr32[0] && !(init_addr
)->pfa.addr32[1] && !(init_addr)->pfa.addr32[2]
&& !(init_addr)->pfa.addr32[3] ))
)
530 pf_addrcpy(init_addr, naddr, af);
531 pf_addr_inc(&rpool->counter, af);
532 break;
533 case PF_POOL_LEASTSTATES:
534 /* retrieve an address first */
535 if (rpool->addr.type == PF_ADDR_TABLE ||
536 rpool->addr.type == PF_ADDR_DYNIFTL) {
537 if (pfr_pool_get(rpool, &raddr, &rmask, af)) {
538 /* see PF_POOL_ROUNDROBIN */
539 memset(&rpool->counter, 0,__builtin_memset((&rpool->counter), (0), (sizeof(rpool
->counter)))
540 sizeof(rpool->counter))__builtin_memset((&rpool->counter), (0), (sizeof(rpool
->counter)))
;
541 if (pfr_pool_get(rpool, &raddr, &rmask, af))
542 return (1);
543 }
544 } else if (pf_match_addr(0, raddr, rmask, &rpool->counter, af))
545 return (1);
546
547 states = rpool->states;
548 weight = rpool->weight;
549 kif = rpool->kif;
550
551 if ((rpool->addr.type == PF_ADDR_TABLE &&
552 rpool->addr.p.tbl->pfrkt_refcntcost > 0) ||
553 (rpool->addr.type == PF_ADDR_DYNIFTL &&
554 rpool->addr.p.dyn->pfid_kt->pfrkt_refcntcost > 0))
555 load = ((UINT16_MAX0xffff * rpool->states) / rpool->weight);
556 else
557 load = states;
558
559 pf_addrcpy(&faddr, &rpool->counter, af);
560
561 pf_addrcpy(naddr, &rpool->counter, af);
562 if (init_addr != NULL((void *)0) && PF_AZERO(init_addr, af)((af == 2 && !(init_addr)->pfa.addr32[0]) || (af ==
24 && !(init_addr)->pfa.addr32[0] && !(init_addr
)->pfa.addr32[1] && !(init_addr)->pfa.addr32[2]
&& !(init_addr)->pfa.addr32[3] ))
)
563 pf_addrcpy(init_addr, naddr, af);
564
565 /*
566 * iterate *once* over whole table and find destination with
567 * least connection
568 */
569 do {
570 pf_addr_inc(&rpool->counter, af);
571 if (rpool->addr.type == PF_ADDR_TABLE ||
572 rpool->addr.type == PF_ADDR_DYNIFTL) {
573 if (pfr_pool_get(rpool, &raddr, &rmask, af))
574 return (1);
575 } else if (pf_match_addr(0, raddr, rmask,
576 &rpool->counter, af))
577 return (1);
578
579 if ((rpool->addr.type == PF_ADDR_TABLE &&
580 rpool->addr.p.tbl->pfrkt_refcntcost > 0) ||
581 (rpool->addr.type == PF_ADDR_DYNIFTL &&
582 rpool->addr.p.dyn->pfid_kt->pfrkt_refcntcost > 0))
583 cload = ((UINT16_MAX0xffff * rpool->states)
584 / rpool->weight);
585 else
586 cload = rpool->states;
587
588 /* find lc minimum */
589 if (cload < load) {
590 states = rpool->states;
591 weight = rpool->weight;
592 kif = rpool->kif;
593 load = cload;
594
595 pf_addrcpy(naddr, &rpool->counter, af);
596 if (init_addr != NULL((void *)0) &&
597 PF_AZERO(init_addr, af)((af == 2 && !(init_addr)->pfa.addr32[0]) || (af ==
24 && !(init_addr)->pfa.addr32[0] && !(init_addr
)->pfa.addr32[1] && !(init_addr)->pfa.addr32[2]
&& !(init_addr)->pfa.addr32[3] ))
)
598 pf_addrcpy(init_addr, naddr, af);
599 }
600 } while (pf_match_addr(1, &faddr, rmask, &rpool->counter, af) &&
601 (states > 0));
602
603 if (pf_map_addr_states_increase(af, rpool, naddr) == -1)
604 return (1);
605 /* revert the kif which was set by pfr_pool_get() */
606 rpool->kif = kif;
607 break;
608 }
609
610 if (rpool->opts & PF_POOL_STICKYADDR0x20) {
11
Assuming the condition is false
12
Taking false branch
611 if (sns[type] != NULL((void *)0)) {
612 pf_remove_src_node(sns[type]);
613 sns[type] = NULL((void *)0);
614 }
615 if (pf_insert_src_node(&sns[type], r, type, af, saddr, naddr,
616 rpool->kif))
617 return (1);
618 }
619
620 if (pf_status.debug >= LOG_INFO6 &&
13
Assuming field 'debug' is >= LOG_INFO
15
Taking true branch
621 (rpool->opts & PF_POOL_TYPEMASK0x0f) != PF_POOL_NONE) {
14
Assuming the condition is true
622 log(LOG_INFO6, "pf: pf_map_addr: selected address ");
623 pf_print_host(naddr, 0, af);
624 if ((rpool->opts & PF_POOL_TYPEMASK0x0f) ==
16
Assuming the condition is true
17
Taking true branch
625 PF_POOL_LEASTSTATES)
626 addlog(" with state count %llu", states);
18
2nd function call argument is an uninitialized value
627 if ((rpool->addr.type == PF_ADDR_TABLE &&
628 rpool->addr.p.tbl->pfrkt_refcntcost > 0) ||
629 (rpool->addr.type == PF_ADDR_DYNIFTL &&
630 rpool->addr.p.dyn->pfid_kt->pfrkt_refcntcost > 0))
631 addlog(" with weight %u", weight);
632 addlog("\n");
633 }
634
635 return (0);
636}
637
638int
639pf_map_addr_states_increase(sa_family_t af, struct pf_pool *rpool,
640 struct pf_addr *naddr)
641{
642 if (rpool->addr.type == PF_ADDR_TABLE) {
643 if (pfr_states_increase(rpool->addr.p.tbl,
644 naddr, af) == -1) {
645 if (pf_status.debug >= LOG_DEBUG7) {
646 log(LOG_DEBUG7,
647 "pf: pf_map_addr_states_increase: "
648 "selected address ");
649 pf_print_host(naddr, 0, af);
650 addlog(". Failed to increase count!\n");
651 }
652 return (-1);
653 }
654 } else if (rpool->addr.type == PF_ADDR_DYNIFTL) {
655 if (pfr_states_increase(rpool->addr.p.dyn->pfid_kt,
656 naddr, af) == -1) {
657 if (pf_status.debug >= LOG_DEBUG7) {
658 log(LOG_DEBUG7,
659 "pf: pf_map_addr_states_increase: "
660 "selected address ");
661 pf_print_host(naddr, 0, af);
662 addlog(". Failed to increase count!\n");
663 }
664 return (-1);
665 }
666 }
667 return (0);
668}
669
670int
671pf_get_transaddr(struct pf_rule *r, struct pf_pdesc *pd,
672 struct pf_src_node **sns, struct pf_rule **nr)
673{
674 struct pf_addr naddr;
675 u_int16_t nport;
676
677#ifdef INET61
678 if (pd->af != pd->naf)
679 return (pf_get_transaddr_af(r, pd, sns));
680#endif /* INET6 */
681
682 if (r->nat.addr.type != PF_ADDR_NONE) {
683 /* XXX is this right? what if rtable is changed at the same
684 * XXX time? where do I need to figure out the sport? */
685 nport = 0;
686 if (pf_get_sport(pd, r, &naddr, &nport,
687 r->nat.proxy_port[0], r->nat.proxy_port[1], sns)) {
688 DPFPRINTF(LOG_NOTICE,do { if (pf_status.debug >= (5)) { log(5, "pf: "); addlog(
"pf: NAT proxy port allocation (%u-%u) failed", r->nat.proxy_port
[0], r->nat.proxy_port[1]); addlog("\n"); } } while (0)
689 "pf: NAT proxy port allocation (%u-%u) failed",do { if (pf_status.debug >= (5)) { log(5, "pf: "); addlog(
"pf: NAT proxy port allocation (%u-%u) failed", r->nat.proxy_port
[0], r->nat.proxy_port[1]); addlog("\n"); } } while (0)
690 r->nat.proxy_port[0],do { if (pf_status.debug >= (5)) { log(5, "pf: "); addlog(
"pf: NAT proxy port allocation (%u-%u) failed", r->nat.proxy_port
[0], r->nat.proxy_port[1]); addlog("\n"); } } while (0)
691 r->nat.proxy_port[1])do { if (pf_status.debug >= (5)) { log(5, "pf: "); addlog(
"pf: NAT proxy port allocation (%u-%u) failed", r->nat.proxy_port
[0], r->nat.proxy_port[1]); addlog("\n"); } } while (0)
;
692 return (-1);
693 }
694 *nr = r;
695 pf_addrcpy(&pd->nsaddr, &naddr, pd->af);
696 pd->nsport = nport;
697 }
698 if (r->rdr.addr.type != PF_ADDR_NONE) {
699 if (pf_map_addr(pd->af, r, &pd->nsaddr, &naddr, NULL((void *)0), sns,
700 &r->rdr, PF_SN_RDR))
701 return (-1);
702 if ((r->rdr.opts & PF_POOL_TYPEMASK0x0f) == PF_POOL_BITMASK)
703 pf_poolmask(&naddr, &naddr, &r->rdr.addr.v.a.mask,
704 &pd->ndaddr, pd->af);
705
706 nport = 0;
707 if (r->rdr.proxy_port[1]) {
708 u_int32_t tmp_nport;
709 u_int16_t div;
710
711 div = r->rdr.proxy_port[1] - r->rdr.proxy_port[0] + 1;
712 div = (div == 0) ? 1 : div;
713
714 tmp_nport = ((ntohs(pd->ndport)(__uint16_t)(__builtin_constant_p(pd->ndport) ? (__uint16_t
)(((__uint16_t)(pd->ndport) & 0xffU) << 8 | ((__uint16_t
)(pd->ndport) & 0xff00U) >> 8) : __swap16md(pd->
ndport))
- ntohs(r->dst.port[0])(__uint16_t)(__builtin_constant_p(r->dst.port[0]) ? (__uint16_t
)(((__uint16_t)(r->dst.port[0]) & 0xffU) << 8 | (
(__uint16_t)(r->dst.port[0]) & 0xff00U) >> 8) : __swap16md
(r->dst.port[0]))
) % div) +
715 r->rdr.proxy_port[0];
716
717 /* wrap around if necessary */
718 if (tmp_nport > 65535)
719 tmp_nport -= 65535;
720 nport = htons((u_int16_t)tmp_nport)(__uint16_t)(__builtin_constant_p((u_int16_t)tmp_nport) ? (__uint16_t
)(((__uint16_t)((u_int16_t)tmp_nport) & 0xffU) << 8
| ((__uint16_t)((u_int16_t)tmp_nport) & 0xff00U) >>
8) : __swap16md((u_int16_t)tmp_nport))
;
721 } else if (r->rdr.proxy_port[0])
722 nport = htons(r->rdr.proxy_port[0])(__uint16_t)(__builtin_constant_p(r->rdr.proxy_port[0]) ? (
__uint16_t)(((__uint16_t)(r->rdr.proxy_port[0]) & 0xffU
) << 8 | ((__uint16_t)(r->rdr.proxy_port[0]) & 0xff00U
) >> 8) : __swap16md(r->rdr.proxy_port[0]))
;
723 *nr = r;
724 pf_addrcpy(&pd->ndaddr, &naddr, pd->af);
725 if (nport)
726 pd->ndport = nport;
727 }
728
729 return (0);
730}
731
732#ifdef INET61
733int
734pf_get_transaddr_af(struct pf_rule *r, struct pf_pdesc *pd,
735 struct pf_src_node **sns)
736{
737 struct pf_addr ndaddr, nsaddr, naddr;
738 u_int16_t nport;
739 int prefixlen = 96;
740
741 if (pf_status.debug >= LOG_INFO6) {
742 log(LOG_INFO6, "pf: af-to %s %s, ",
743 pd->naf == AF_INET2 ? "inet" : "inet6",
744 r->rdr.addr.type == PF_ADDR_NONE ? "nat" : "rdr");
745 pf_print_host(&pd->nsaddr, pd->nsport, pd->af);
746 addlog(" -> ");
747 pf_print_host(&pd->ndaddr, pd->ndport, pd->af);
748 addlog("\n");
749 }
750
751 if (r->nat.addr.type == PF_ADDR_NONE)
752 panic("pf_get_transaddr_af: no nat pool for source address");
753
754 /* get source address and port */
755 nport = 0;
756 if (pf_get_sport(pd, r, &nsaddr, &nport,
757 r->nat.proxy_port[0], r->nat.proxy_port[1], sns)) {
758 DPFPRINTF(LOG_NOTICE,do { if (pf_status.debug >= (5)) { log(5, "pf: "); addlog(
"pf: af-to NAT proxy port allocation (%u-%u) failed", r->nat
.proxy_port[0], r->nat.proxy_port[1]); addlog("\n"); } } while
(0)
759 "pf: af-to NAT proxy port allocation (%u-%u) failed",do { if (pf_status.debug >= (5)) { log(5, "pf: "); addlog(
"pf: af-to NAT proxy port allocation (%u-%u) failed", r->nat
.proxy_port[0], r->nat.proxy_port[1]); addlog("\n"); } } while
(0)
760 r->nat.proxy_port[0],do { if (pf_status.debug >= (5)) { log(5, "pf: "); addlog(
"pf: af-to NAT proxy port allocation (%u-%u) failed", r->nat
.proxy_port[0], r->nat.proxy_port[1]); addlog("\n"); } } while
(0)
761 r->nat.proxy_port[1])do { if (pf_status.debug >= (5)) { log(5, "pf: "); addlog(
"pf: af-to NAT proxy port allocation (%u-%u) failed", r->nat
.proxy_port[0], r->nat.proxy_port[1]); addlog("\n"); } } while
(0)
;
762 return (-1);
763 }
764 pd->nsport = nport;
765
766 if (pd->proto == IPPROTO_ICMPV658 && pd->naf == AF_INET2) {
767 if (pd->dir == PF_IN) {
768 pd->ndport = ntohs(pd->ndport)(__uint16_t)(__builtin_constant_p(pd->ndport) ? (__uint16_t
)(((__uint16_t)(pd->ndport) & 0xffU) << 8 | ((__uint16_t
)(pd->ndport) & 0xff00U) >> 8) : __swap16md(pd->
ndport))
;
769 if (pd->ndport == ICMP6_ECHO_REQUEST128)
770 pd->ndport = ICMP_ECHO8;
771 else if (pd->ndport == ICMP6_ECHO_REPLY129)
772 pd->ndport = ICMP_ECHOREPLY0;
773 pd->ndport = htons(pd->ndport)(__uint16_t)(__builtin_constant_p(pd->ndport) ? (__uint16_t
)(((__uint16_t)(pd->ndport) & 0xffU) << 8 | ((__uint16_t
)(pd->ndport) & 0xff00U) >> 8) : __swap16md(pd->
ndport))
;
774 } else {
775 pd->nsport = ntohs(pd->nsport)(__uint16_t)(__builtin_constant_p(pd->nsport) ? (__uint16_t
)(((__uint16_t)(pd->nsport) & 0xffU) << 8 | ((__uint16_t
)(pd->nsport) & 0xff00U) >> 8) : __swap16md(pd->
nsport))
;
776 if (pd->nsport == ICMP6_ECHO_REQUEST128)
777 pd->nsport = ICMP_ECHO8;
778 else if (pd->nsport == ICMP6_ECHO_REPLY129)
779 pd->nsport = ICMP_ECHOREPLY0;
780 pd->nsport = htons(pd->nsport)(__uint16_t)(__builtin_constant_p(pd->nsport) ? (__uint16_t
)(((__uint16_t)(pd->nsport) & 0xffU) << 8 | ((__uint16_t
)(pd->nsport) & 0xff00U) >> 8) : __swap16md(pd->
nsport))
;
781 }
782 } else if (pd->proto == IPPROTO_ICMP1 && pd->naf == AF_INET624) {
783 if (pd->dir == PF_IN) {
784 pd->ndport = ntohs(pd->ndport)(__uint16_t)(__builtin_constant_p(pd->ndport) ? (__uint16_t
)(((__uint16_t)(pd->ndport) & 0xffU) << 8 | ((__uint16_t
)(pd->ndport) & 0xff00U) >> 8) : __swap16md(pd->
ndport))
;
785 if (pd->ndport == ICMP_ECHO8)
786 pd->ndport = ICMP6_ECHO_REQUEST128;
787 else if (pd->ndport == ICMP_ECHOREPLY0)
788 pd->ndport = ICMP6_ECHO_REPLY129;
789 pd->ndport = htons(pd->ndport)(__uint16_t)(__builtin_constant_p(pd->ndport) ? (__uint16_t
)(((__uint16_t)(pd->ndport) & 0xffU) << 8 | ((__uint16_t
)(pd->ndport) & 0xff00U) >> 8) : __swap16md(pd->
ndport))
;
790 } else {
791 pd->nsport = ntohs(pd->nsport)(__uint16_t)(__builtin_constant_p(pd->nsport) ? (__uint16_t
)(((__uint16_t)(pd->nsport) & 0xffU) << 8 | ((__uint16_t
)(pd->nsport) & 0xff00U) >> 8) : __swap16md(pd->
nsport))
;
792 if (pd->nsport == ICMP_ECHO8)
793 pd->nsport = ICMP6_ECHO_REQUEST128;
794 else if (pd->nsport == ICMP_ECHOREPLY0)
795 pd->nsport = ICMP6_ECHO_REPLY129;
796 pd->nsport = htons(pd->nsport)(__uint16_t)(__builtin_constant_p(pd->nsport) ? (__uint16_t
)(((__uint16_t)(pd->nsport) & 0xffU) << 8 | ((__uint16_t
)(pd->nsport) & 0xff00U) >> 8) : __swap16md(pd->
nsport))
;
797 }
798 }
799
800 /* get the destination address and port */
801 if (r->rdr.addr.type != PF_ADDR_NONE) {
802 if (pf_map_addr(pd->naf, r, &nsaddr, &naddr, NULL((void *)0), sns,
803 &r->rdr, PF_SN_RDR))
804 return (-1);
805 if (r->rdr.proxy_port[0])
806 pd->ndport = htons(r->rdr.proxy_port[0])(__uint16_t)(__builtin_constant_p(r->rdr.proxy_port[0]) ? (
__uint16_t)(((__uint16_t)(r->rdr.proxy_port[0]) & 0xffU
) << 8 | ((__uint16_t)(r->rdr.proxy_port[0]) & 0xff00U
) >> 8) : __swap16md(r->rdr.proxy_port[0]))
;
807
808 if (pd->naf == AF_INET2) {
809 /* The prefix is the IPv4 rdr address */
810 prefixlen = in_mask2len((struct in_addr *)
811 &r->rdr.addr.v.a.mask);
812 inet_nat46(pd->naf, &pd->ndaddr,
813 &ndaddr, &naddr, prefixlen);
814 } else {
815 /* The prefix is the IPv6 rdr address */
816 prefixlen =
817 in6_mask2len((struct in6_addr *)
818 &r->rdr.addr.v.a.mask, NULL((void *)0));
819 inet_nat64(pd->naf, &pd->ndaddr,
820 &ndaddr, &naddr, prefixlen);
821 }
822 } else {
823 if (pd->naf == AF_INET2) {
824 /* The prefix is the IPv6 dst address */
825 prefixlen =
826 in6_mask2len((struct in6_addr *)
827 &r->dst.addr.v.a.mask, NULL((void *)0));
828 if (prefixlen < 32)
829 prefixlen = 96;
830 inet_nat64(pd->naf, &pd->ndaddr,
831 &ndaddr, &pd->ndaddr, prefixlen);
832 } else {
833 /*
834 * The prefix is the IPv6 nat address
835 * (that was stored in pd->nsaddr)
836 */
837 prefixlen = in6_mask2len((struct in6_addr *)
838 &r->nat.addr.v.a.mask, NULL((void *)0));
839 if (prefixlen > 96)
840 prefixlen = 96;
841 inet_nat64(pd->naf, &pd->ndaddr,
842 &ndaddr, &nsaddr, prefixlen);
843 }
844 }
845
846 pf_addrcpy(&pd->nsaddr, &nsaddr, pd->naf);
847 pf_addrcpy(&pd->ndaddr, &ndaddr, pd->naf);
848
849 if (pf_status.debug >= LOG_INFO6) {
850 log(LOG_INFO6, "pf: af-to %s %s done, prefixlen %d, ",
851 pd->naf == AF_INET2 ? "inet" : "inet6",
852 r->rdr.addr.type == PF_ADDR_NONE ? "nat" : "rdr",
853 prefixlen);
854 pf_print_host(&pd->nsaddr, pd->nsport, pd->naf);
855 addlog(" -> ");
856 pf_print_host(&pd->ndaddr, pd->ndport, pd->naf);
857 addlog("\n");
858 }
859
860 return (0);
861}
862#endif /* INET6 */
863
864int
865pf_postprocess_addr(struct pf_state *cur)
866{
867 struct pf_rule *nr;
868 struct pf_state_key *sks;
869 struct pf_pool rpool;
870 struct pf_addr lookup_addr;
871 int slbcount = -1;
872
873 nr = cur->natrule.ptr;
874
875 if (nr == NULL((void *)0))
876 return (0);
877
878 /* decrease counter */
879
880 sks = cur->key[PF_SK_STACK];
881
882 /* check for outgoing or ingoing balancing */
883 if (nr->rt == PF_ROUTETO)
884 lookup_addr = cur->rt_addr;
885 else if (sks != NULL((void *)0))
886 lookup_addr = sks->addr[1];
887 else {
888 if (pf_status.debug >= LOG_DEBUG7) {
889 log(LOG_DEBUG7, "pf: %s: unable to obtain address",
890 __func__);
891 }
892 return (1);
893 }
894
895 /* check for appropriate pool */
896 if (nr->rdr.addr.type != PF_ADDR_NONE)
897 rpool = nr->rdr;
898 else if (nr->nat.addr.type != PF_ADDR_NONE)
899 rpool = nr->nat;
900 else if (nr->route.addr.type != PF_ADDR_NONE)
901 rpool = nr->route;
902 else
903 return (0);
904
905 if (((rpool.opts & PF_POOL_TYPEMASK0x0f) != PF_POOL_LEASTSTATES))
906 return (0);
907
908 if (rpool.addr.type == PF_ADDR_TABLE) {
909 if ((slbcount = pfr_states_decrease(
910 rpool.addr.p.tbl,
911 &lookup_addr, sks->af)) == -1) {
912 if (pf_status.debug >= LOG_DEBUG7) {
913 log(LOG_DEBUG7, "pf: %s: selected address ",
914 __func__);
915 pf_print_host(&lookup_addr,
916 sks->port[0], sks->af);
917 addlog(". Failed to "
918 "decrease count!\n");
919 }
920 return (1);
921 }
922 } else if (rpool.addr.type == PF_ADDR_DYNIFTL) {
923 if ((slbcount = pfr_states_decrease(
924 rpool.addr.p.dyn->pfid_kt,
925 &lookup_addr, sks->af)) == -1) {
926 if (pf_status.debug >= LOG_DEBUG7) {
927 log(LOG_DEBUG7, "pf: %s: selected address ",
928 __func__);
929 pf_print_host(&lookup_addr,
930 sks->port[0], sks->af);
931 addlog(". Failed to "
932 "decrease count!\n");
933 }
934 return (1);
935 }
936 }
937 if (slbcount > -1) {
938 if (pf_status.debug >= LOG_INFO6) {
939 log(LOG_INFO6, "pf: %s: selected address ", __func__);
940 pf_print_host(&lookup_addr, sks->port[0],
941 sks->af);
942 addlog(" decreased state count to %u\n",
943 slbcount);
944 }
945 }
946 return (0);
947}