+ struct fw3_ipt_rule *r;
+ struct fw3_address *src, *dst;
+ struct fw3_port *spt, *dpt;
+
+ switch (h->table)
+ {
+ case FW3_TABLE_NAT:
+ src = &redir->ip_src;
+ dst = &redir->ip_dest;
+ spt = &redir->port_src;
+ dpt = &redir->port_dest;
+
+ if (redir->target == FW3_FLAG_SNAT)
+ {
+ dst = &redir->ip_redir;
+ dpt = &redir->port_redir;
+ }
+
+ r = fw3_ipt_rule_create(h, proto, NULL, NULL, src, dst);
+ fw3_ipt_rule_sport_dport(r, spt, dpt);
+ fw3_ipt_rule_mac(r, mac);
+ fw3_ipt_rule_ipset(r, &redir->ipset);
+ fw3_ipt_rule_helper(r, &redir->helper);
+ fw3_ipt_rule_limit(r, &redir->limit);
+ fw3_ipt_rule_time(r, &redir->time);
+ fw3_ipt_rule_mark(r, &redir->mark);
+ set_target_nat(r, redir);
+ fw3_ipt_rule_extra(r, redir->extra);
+ set_comment(r, redir->name, num, NULL);
+ append_chain_nat(r, redir);
+ break;
+
+ case FW3_TABLE_RAW:
+ if (redir->target == FW3_FLAG_DNAT && redir->helper.ptr)
+ {
+ if (!fw3_cthelper_check_proto(redir->helper.ptr, proto))
+ {
+ info(" ! Skipping protocol %s since helper '%s' does not support it",
+ fw3_protoname(proto), redir->helper.ptr->name);
+ return;
+ }
+
+ if (!redir->helper.set)
+ info(" - Auto-selected conntrack helper '%s' based on proto/port",
+ redir->helper.ptr->name);
+
+ r = fw3_ipt_rule_create(h, proto, NULL, NULL, &redir->ip_src, &redir->ip_redir);
+ fw3_ipt_rule_sport_dport(r, &redir->port_src, &redir->port_redir);
+ fw3_ipt_rule_mac(r, mac);
+ fw3_ipt_rule_ipset(r, &redir->ipset);
+ fw3_ipt_rule_limit(r, &redir->limit);
+ fw3_ipt_rule_time(r, &redir->time);
+ fw3_ipt_rule_mark(r, &redir->mark);
+ fw3_ipt_rule_addarg(r, false, "-m", "conntrack");
+ fw3_ipt_rule_addarg(r, false, "--ctstate", "DNAT");
+ fw3_ipt_rule_target(r, "CT");
+ fw3_ipt_rule_addarg(r, false, "--helper", redir->helper.ptr->name);
+ set_comment(r, redir->name, num, "CT helper");
+ fw3_ipt_rule_append(r, "zone_%s_helper", redir->_src->name);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void
+print_reflection(struct fw3_ipt_handle *h, struct fw3_state *state,
+ struct fw3_redirect *redir, int num,
+ struct fw3_protocol *proto, struct fw3_address *ra,
+ struct fw3_address *ia, struct fw3_address *ea, struct fw3_device *rz)
+{
+ struct fw3_ipt_rule *r;
+
+ switch (h->table)
+ {
+ case FW3_TABLE_NAT:
+ r = fw3_ipt_rule_create(h, proto, NULL, NULL, ia, ea);
+ fw3_ipt_rule_sport_dport(r, NULL, &redir->port_dest);
+ fw3_ipt_rule_limit(r, &redir->limit);
+ fw3_ipt_rule_time(r, &redir->time);
+ set_comment(r, redir->name, num, "reflection");
+ set_snat_dnat(r, FW3_FLAG_DNAT, &redir->ip_redir, &redir->port_redir);
+ fw3_ipt_rule_replace(r, "zone_%s_prerouting", rz->name);
+
+ r = fw3_ipt_rule_create(h, proto, NULL, NULL, ia, &redir->ip_redir);
+ fw3_ipt_rule_sport_dport(r, NULL, &redir->port_redir);
+ fw3_ipt_rule_limit(r, &redir->limit);
+ fw3_ipt_rule_time(r, &redir->time);
+ set_comment(r, redir->name, num, "reflection");
+ set_snat_dnat(r, FW3_FLAG_SNAT, ra, NULL);
+ fw3_ipt_rule_replace(r, "zone_%s_postrouting", rz->name);
+ break;
+
+ default:
+ break;
+ }