The SNAT extension wants to know which protocol is used. We need
to pass in a valid ipt_entry with the protocol set for this reason.

The parser is keept minimal, which means it does not support
all fancy features as iptables offers. Though for our main
purposes is it enough which is

iptables-test -t nat -A POSTROUTING -o enp0s20u2u1 -j SNAT --to-source 
192.168.101.6
---
 src/iptables.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/src/iptables.c b/src/iptables.c
index 2602dfd..08fd99a 100644
--- a/src/iptables.c
+++ b/src/iptables.c
@@ -1765,6 +1765,7 @@ struct parse_context {
        struct xtables_target *xt_t;
        GList *xt_m;
        struct xtables_rule_match *xt_rm;
+       int proto;
 };
 
 static int prepare_getopt_args(const char *str, struct parse_context *ctx)
@@ -1804,6 +1805,12 @@ static int parse_xt_modules(int c, bool invert,
 {
        struct xtables_match *m;
        struct xtables_rule_match *rm;
+       struct ipt_entry fw = { 0, };
+
+       /* The SNAT parser wants to know the protocol. */
+       if (ctx->proto == 0)
+               ctx->proto = IPPROTO_IP;
+       fw.ip.proto = ctx->proto;
 
        for (rm = ctx->xt_rm; rm; rm = rm->next) {
                if (rm->completed != 0)
@@ -1819,7 +1826,7 @@ static int parse_xt_modules(int c, bool invert,
                                        + XT_OPTION_OFFSET_SCALE)
                        continue;
 
-               xtables_option_mpcall(c, ctx->argv, invert, m, NULL);
+               xtables_option_mpcall(c, ctx->argv, invert, m, &fw);
        }
 
        if (!ctx->xt_t)
@@ -1833,7 +1840,7 @@ static int parse_xt_modules(int c, bool invert,
                                        + XT_OPTION_OFFSET_SCALE)
                return 0;
 
-       xtables_option_tpcall(c, ctx->argv, invert, ctx->xt_t, NULL);
+       xtables_option_tpcall(c, ctx->argv, invert, ctx->xt_t, &fw);
 
        return 0;
 }
@@ -2008,6 +2015,9 @@ static int parse_rule_spec(struct connman_iptables *table,
                        ctx->xt_m = g_list_append(ctx->xt_m, xt_m);
 
                        break;
+               case 'p':
+                       ctx->proto = xtables_parse_protocol(optarg);
+                       break;
                case 'j':
                        /* Target */
                        ctx->xt_t = prepare_target(table, optarg);
-- 
2.4.3

_______________________________________________
connman mailing list
connman@connman.net
https://lists.connman.net/mailman/listinfo/connman

Reply via email to