Hello,
I have a problem with relayd and redirects. If I disable a table, redirect
stays down only for a while.
After a few seconds, redirect gets active again and forwards to the disabled
table.
Same happens for redirect with a backup forward table.
Redirect points momentarily to backup table but after a while forwards to the
disabled table.
This happens only with a combination of a table with parent hosts.
patch at bottom
regards,
Giannis
table <dir> { dir1 retry 2, dir2 retry 2 }
table <dir_> { dir1 parent 1 retry 2, dir2 parent 2 retry 2 }
table <dir_backup> { foo1 retry 2, foo2 retry 2 }
redirect dir-imap {
listen on $dir_addr port imaps
pftag RELAYD_dir
sticky-address
forward to <dir> port 993 mode least-states check icmp
}
redirect dir-pop {
listen on $dir_addr port pop3s
pftag RELAYD_dir
sticky-address
forward to <dir_> port 995 mode least-states check icmp
}
redirect dir-lmtp {
listen on $dir_addr port 24
pftag RELAYD_dir
sticky-address
forward to <dir_> port 24 mode least-states check icmp
forward to <dir_backup> port 24 mode least-states check icmp
}
# relayctl show sum
Id Type Name Avlblty Status
1 redirect dir-imap active
1 table dir:993 active (2 hosts)
1 host dir1 100.00% up
2 host dir2 100.00% up
2 redirect dir-pop active
2 table dir_:995 active (2 hosts)
3 host dir1 parent 1 100.00% up
4 host dir2 parent 2 100.00% up
3 redirect dir-lmtp active
3 table dir_:24 active (2 hosts)
5 host dir1 parent 1 100.00% up
6 host dir2 parent 2 100.00% up
4 table dir_backup:24 active (2 hosts)
7 host foo1 100.00% up
8 host foo2 100.00% up
# relayctl table dis dir_:995
disable_table: table 2
flush_table: flushed table dir-pop
pfe_sync: disabling ruleset
sync_ruleset: rules removed
pfe_dispatch_hce: state 1 for host 4 dir2
pfe_dispatch_hce: state 1 for host 3 dir1
# relayctl show sum
Id Type Name Avlblty Status
2 redirect dir-pop down
2 table dir_:995 disabled
# pfctl -a 'relayd/*' -sr
anchor "dir-pop" all {
} // empty as it should
But after a while:
table dir-pop: 2 added, 0 deleted, 0 changed, 0 killed
pfe_sync: enabling ruleset
sync_ruleset: rule added to anchor "relayd/dir-pop"
# relayctl show sum
Id Type Name Avlblty Status
2 redirect dir-pop active
2 table dir_:995 disabled
Although table is disabled, redirect comes active,
pf rule in anchor is active and <dir-pop> table has dir1 and dir2 inside.
# pfctl -a 'relayd/*' -sr
anchor "dir-pop" all {
pass in quick on rdomain 0 inet proto tcp from any to $dir_addr port = 995
flags S/SA keep state (tcp.established 600) tag RELAYD_dir rdr-to <dir-pop>
port 995 least-states sticky-address
}
Same happens with the backup table on last dir-lmtp redirect.
Table is updated momentarily with the backup hosts,
but after a while traffic is forwarded back to primary hosts although their
table is disabled.
# relayctl show sum
Id Type Name Avlblty Status
3 redirect dir-lmtp active
3 table dir_:24 active (2 hosts)
5 host dir1 parent 1 100.00% up
6 host dir2 parent 2 100.00% up
4 table dir_backup:24 active (2 hosts)
7 host foo1 100.00% up
8 host foo2 100.00% up
# relayctl table dis dir_:24
disable_table: table 3
table dir-lmtp: 2 added, 2 deleted, 0 changed, 0 killed
pfe_dispatch_hce: state 1 for host 6 dir2
pfe_dispatch_hce: state 1 for host 5 dir1
# relayctl show sum
Id Type Name Avlblty Status
3 redirect dir-lmtp active (using
backup table)
3 table dir_:24 disabled
4 table dir_backup:24 active (2 hosts)
7 host foo1 100.00% up
8 host foo2 100.00% up
# pfctl -a relayd/dir-lmtp -t dir-lmtp -vTshow
lists correctly foo1 and foo2 which are the backup hosts.
But after a while:
table dir-lmtp: 2 added, 2 deleted, 0 changed, 0 killed
# relayctl show sum
Id Type Name Avlblty Status
3 redirect dir-lmtp active
3 table dir_:24 disabled
4 table dir_backup:24 active (2 hosts)
7 host foo1 100.00% up
8 host foo2 100.00% up
# pfctl -a relayd/dir-lmtp -t dir-lmtp -vTshow
lists dir1 and dir2 and NOT foo1, foo2
I believe the following diff fixes this problem:
Index: pfe.c
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/pfe.c,v
retrieving revision 1.90
diff -u -p -r1.90 pfe.c
--- pfe.c 14 Sep 2020 11:30:25 -0000 1.90
+++ pfe.c 10 Jul 2023 13:39:44 -0000
@@ -171,7 +171,8 @@ pfe_dispatch_hce(int fd, struct privsep_
*/
if (HOST_ISUP(st.up)) {
table->conf.flags |= F_CHANGED;
- table->up++;
+ if (!(table->conf.flags & F_DISABLE))
+ table->up++;
host->flags |= F_ADD;
host->flags &= ~(F_DEL);
} else if (HOST_ISUP(host->up)) {