+ msrc->invert = false;
+ r = fw3_ipt_rule_new(handle);
+ fw3_ipt_rule_src_dest(r, msrc, NULL);
+ fw3_ipt_rule_target(r, "RETURN");
+ fw3_ipt_rule_append(r, "zone_%s_postrouting", zone->name);
+ msrc->invert = true;
+ }
+
+ /* for any negated masq_dest ip, emit -d addr -j RETURN rules */
+ for (mdest = NULL;
+ (mdest = next_addr(mdest, &zone->masq_dest,
+ handle->family, true)) != NULL; )
+ {
+ mdest->invert = false;
+ r = fw3_ipt_rule_new(handle);
+ fw3_ipt_rule_src_dest(r, NULL, mdest);
+ fw3_ipt_rule_target(r, "RETURN");
+ fw3_ipt_rule_append(r, "zone_%s_postrouting", zone->name);
+ mdest->invert = true;
+ }
+
+ /* emit masquerading entries for non-negated addresses
+ and ensure that both src and dest loops run at least once,
+ even if there are no relevant addresses */
+ for (first_src = true, msrc = NULL;
+ (msrc = next_addr(msrc, &zone->masq_src,
+ handle->family, false)) || first_src;
+ first_src = false)
+ {
+ for (first_dest = true, mdest = NULL;
+ (mdest = next_addr(mdest, &zone->masq_dest,
+ handle->family, false)) || first_dest;
+ first_dest = false)
+ {
+ r = fw3_ipt_rule_new(handle);
+ fw3_ipt_rule_src_dest(r, msrc, mdest);
+ fw3_ipt_rule_target(r, "MASQUERADE");
+ fw3_ipt_rule_append(r, "zone_%s_postrouting", zone->name);
+ }