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 ? > + } > +