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