1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
7 #include "alloc-util.h"
8 #include "firewall-util.h"
9 #include "firewall-util-private.h"
11 #include "string-table.h"
13 static const char * const firewall_backend_table
[_FW_BACKEND_MAX
] = {
14 [FW_BACKEND_NONE
] = "none",
16 [FW_BACKEND_IPTABLES
] = "iptables",
18 [FW_BACKEND_NFTABLES
] = "nftables",
21 DEFINE_STRING_TABLE_LOOKUP_TO_STRING(firewall_backend
, FirewallBackend
);
23 static void firewall_backend_probe(FirewallContext
*ctx
) {
26 if (ctx
->backend
!= _FW_BACKEND_INVALID
)
29 if (fw_nftables_init(ctx
) >= 0)
30 ctx
->backend
= FW_BACKEND_NFTABLES
;
33 ctx
->backend
= FW_BACKEND_IPTABLES
;
35 ctx
->backend
= FW_BACKEND_NONE
;
38 if (ctx
->backend
!= FW_BACKEND_NONE
)
39 log_debug("Using %s as firewall backend.", firewall_backend_to_string(ctx
->backend
));
41 log_debug("No firewall backend found.");
44 int fw_ctx_new(FirewallContext
**ret
) {
45 _cleanup_free_ FirewallContext
*ctx
= NULL
;
47 ctx
= new(FirewallContext
, 1);
51 *ctx
= (FirewallContext
) {
52 .backend
= _FW_BACKEND_INVALID
,
55 firewall_backend_probe(ctx
);
61 FirewallContext
*fw_ctx_free(FirewallContext
*ctx
) {
65 fw_nftables_exit(ctx
);
70 int fw_add_masquerade(
71 FirewallContext
**ctx
,
74 const union in_addr_union
*source
,
75 unsigned source_prefixlen
) {
87 switch ((*ctx
)->backend
) {
89 case FW_BACKEND_IPTABLES
:
90 return fw_iptables_add_masquerade(add
, af
, source
, source_prefixlen
);
92 case FW_BACKEND_NFTABLES
:
93 return fw_nftables_add_masquerade(*ctx
, add
, af
, source
, source_prefixlen
);
99 int fw_add_local_dnat(
100 FirewallContext
**ctx
,
105 const union in_addr_union
*remote
,
106 uint16_t remote_port
,
107 const union in_addr_union
*previous_remote
) {
119 switch ((*ctx
)->backend
) {
121 case FW_BACKEND_IPTABLES
:
122 return fw_iptables_add_local_dnat(add
, af
, protocol
, local_port
, remote
, remote_port
, previous_remote
);
124 case FW_BACKEND_NFTABLES
:
125 return fw_nftables_add_local_dnat(*ctx
, add
, af
, protocol
, local_port
, remote
, remote_port
, previous_remote
);