On 6/19/2019 9:33 PM, Marcelo Ricardo Leitner wrote: > On Tue, Jun 11, 2019 at 04:28:31PM +0300, Paul Blakey wrote: > ... >> +static int tcf_ct_fill_params_nat(struct tcf_ct_params *p, >> + struct tc_ct *parm, >> + struct nlattr **tb, >> + struct netlink_ext_ack *extack) >> +{ >> + struct nf_nat_range2 *range; >> + >> + if (!(p->ct_action & TCA_CT_ACT_NAT)) >> + return 0; >> + >> + if (!IS_ENABLED(CONFIG_NF_NAT)) { >> + NL_SET_ERR_MSG_MOD(extack, "Netfilter nat isn't enabled in >> kernel"); >> + return -EOPNOTSUPP; >> + } >> + >> + if (!(p->ct_action & (TCA_CT_ACT_NAT_SRC | TCA_CT_ACT_NAT_DST))) >> + return 0; >> + >> + if ((p->ct_action & TCA_CT_ACT_NAT_SRC) && >> + (p->ct_action & TCA_CT_ACT_NAT_DST)) { >> + NL_SET_ERR_MSG_MOD(extack, "dnat and snat can't be enabled at >> the same time"); >> + return -EOPNOTSUPP; >> + } >> + >> + range = &p->range; >> + if (tb[TCA_CT_NAT_IPV4_MIN]) { >> + range->min_addr.ip = >> + nla_get_in_addr(tb[TCA_CT_NAT_IPV4_MIN]); >> + range->flags |= NF_NAT_RANGE_MAP_IPS; >> + p->ipv4_range = true; >> + } >> + if (tb[TCA_CT_NAT_IPV4_MAX]) { >> + range->max_addr.ip = >> + nla_get_in_addr(tb[TCA_CT_NAT_IPV4_MAX]); >> + range->flags |= NF_NAT_RANGE_MAP_IPS; >> + p->ipv4_range = true; >> + } else if (range->min_addr.ip) { >> + range->max_addr.ip = range->min_addr.ip; >> + } >> + >> + if (tb[TCA_CT_NAT_IPV6_MIN]) { >> + range->min_addr.in6 = >> + nla_get_in6_addr(tb[TCA_CT_NAT_IPV6_MIN]); >> + range->flags |= NF_NAT_RANGE_MAP_IPS; >> + p->ipv4_range = false; >> + } >> + if (tb[TCA_CT_NAT_IPV6_MAX]) { >> + range->max_addr.in6 = >> + nla_get_in6_addr(tb[TCA_CT_NAT_IPV6_MAX]); >> + range->flags |= NF_NAT_RANGE_MAP_IPS; >> + p->ipv4_range = false; >> + } else if (memchr_inv(&range->min_addr.in6, 0, >> + sizeof(range->min_addr.in6))) { >> + range->max_addr.in6 = range->min_addr.in6; > This will overwrite ipv4_max if it was used, as min/max_addr are > unions. > What about having the _MAX handling (for both ipv4/6) inside the > if (.._MIN) { } block ?
Yes that what I planned on doing: range = &p->range; if (tb[TCA_CT_NAT_IPV4_MIN]) { p->ipv4_range = true; range->flags |= NF_NAT_RANGE_MAP_IPS; range->min_addr.ip = nla_get_in_addr(tb[TCA_CT_NAT_IPV4_MIN]); range->max_addr.ip = tb[TCA_CT_NAT_IPV4_MAX] ? nla_get_in_addr(tb[TCA_CT_NAT_IPV4_MAX]) : range->min_addr.ip; } else if (tb[TCA_CT_NAT_IPV6_MIN]) { p->ipv4_range = false; range->flags |= NF_NAT_RANGE_MAP_IPS; range->min_addr.in6 = nla_get_in6_addr(tb[TCA_CT_NAT_IPV6_MIN]); range->max_addr.in6 = tb[TCA_CT_NAT_IPV6_MAX] ? nla_get_in6_addr(tb[TCA_CT_NAT_IPV6_MAX]) : range->min_addr.in6; } if (tb[TCA_CT_NAT_PORT_MIN]) { range->flags |= NF_NAT_RANGE_PROTO_SPECIFIED; range->min_proto.all = nla_get_be16(tb[TCA_CT_NAT_PORT_MIN]); range->max_proto.all = tb[TCA_CT_NAT_PORT_MAX]? nla_get_be16(tb[TCA_CT_NAT_PORT_MAX]) : range->min_proto.all; >> + } >> +