On Wed, Nov 16, 2022 at 4:54 PM Pablo Neira Ayuso <[email protected]> wrote: > > On Tue, Nov 15, 2022 at 10:50:57AM -0500, Xin Long wrote: > > diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c > > index e29e4ccb5c5a..1c72b8caa24e 100644 > > --- a/net/netfilter/nf_nat_core.c > > +++ b/net/netfilter/nf_nat_core.c > > @@ -784,6 +784,137 @@ nf_nat_inet_fn(void *priv, struct sk_buff *skb, > > } > > EXPORT_SYMBOL_GPL(nf_nat_inet_fn); > > > > +/* Modelled after nf_nat_ipv[46]_fn(). > > + * range is only used for new, uninitialized NAT state. > > + * Returns either NF_ACCEPT or NF_DROP. > > + */ > > +static int nf_ct_nat_execute(struct sk_buff *skb, struct nf_conn *ct, > > + enum ip_conntrack_info ctinfo, int *action, > > + const struct nf_nat_range2 *range, > > + enum nf_nat_manip_type maniptype) > > +{ > > + __be16 proto = skb_protocol(skb, true); > > + int hooknum, err = NF_ACCEPT; > > + > > + /* See HOOK2MANIP(). */ > > + if (maniptype == NF_NAT_MANIP_SRC) > > + hooknum = NF_INET_LOCAL_IN; /* Source NAT */ > > + else > > + hooknum = NF_INET_LOCAL_OUT; /* Destination NAT */ > > + > > + switch (ctinfo) { > > + case IP_CT_RELATED: > > + case IP_CT_RELATED_REPLY: > > + if (proto == htons(ETH_P_IP) && > > + ip_hdr(skb)->protocol == IPPROTO_ICMP) { > > + if (!nf_nat_icmp_reply_translation(skb, ct, ctinfo, > > + hooknum)) > > + err = NF_DROP; > > + goto out; > > + } else if (IS_ENABLED(CONFIG_IPV6) && proto == > > htons(ETH_P_IPV6)) { > > + __be16 frag_off; > > + u8 nexthdr = ipv6_hdr(skb)->nexthdr; > > + int hdrlen = ipv6_skip_exthdr(skb, > > + sizeof(struct ipv6hdr), > > + &nexthdr, &frag_off); > > + > > + if (hdrlen >= 0 && nexthdr == IPPROTO_ICMPV6) { > > + if (!nf_nat_icmpv6_reply_translation(skb, ct, > > + ctinfo, > > + hooknum, > > + hdrlen)) > > + err = NF_DROP; > > + goto out; > > + } > > + } > > + /* Non-ICMP, fall thru to initialize if needed. */ > > + fallthrough; > > + case IP_CT_NEW: > > + /* Seen it before? This can happen for loopback, retrans, > > + * or local packets. > > + */ > > + if (!nf_nat_initialized(ct, maniptype)) { > > + /* Initialize according to the NAT action. */ > > + err = (range && range->flags & NF_NAT_RANGE_MAP_IPS) > > + /* Action is set up to establish a new > > + * mapping. > > + */ > > + ? nf_nat_setup_info(ct, range, maniptype) > > + : nf_nat_alloc_null_binding(ct, hooknum); > > + if (err != NF_ACCEPT) > > + goto out; > > + } > > + break; > > + > > + case IP_CT_ESTABLISHED: > > + case IP_CT_ESTABLISHED_REPLY: > > + break; > > + > > + default: > > + err = NF_DROP; > > + goto out; > > + } > > + > > + err = nf_nat_packet(ct, ctinfo, hooknum, skb); > > + if (err == NF_ACCEPT) > > + *action |= (1 << maniptype); > > +out: > > + return err; > > +} > > + > > +int nf_ct_nat(struct sk_buff *skb, struct nf_conn *ct, > > + enum ip_conntrack_info ctinfo, int *action, > > + const struct nf_nat_range2 *range, bool commit) > > +{ > > + enum nf_nat_manip_type maniptype; > > + int err, ct_action = *action; > > + > > + *action = 0; > > + > > + /* Add NAT extension if not confirmed yet. */ > > + if (!nf_ct_is_confirmed(ct) && !nf_ct_nat_ext_add(ct)) > > + return NF_ACCEPT; /* Can't NAT. */ > > + > > + if (ctinfo != IP_CT_NEW && (ct->status & IPS_NAT_MASK) && > > + (ctinfo != IP_CT_RELATED || commit)) { > > + /* NAT an established or related connection like before. */ > > + if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) > > + /* This is the REPLY direction for a connection > > + * for which NAT was applied in the forward > > + * direction. Do the reverse NAT. > > + */ > > + maniptype = ct->status & IPS_SRC_NAT > > + ? NF_NAT_MANIP_DST : NF_NAT_MANIP_SRC; > > + else > > + maniptype = ct->status & IPS_SRC_NAT > > + ? NF_NAT_MANIP_SRC : NF_NAT_MANIP_DST; > > + } else if (ct_action & (1 << NF_NAT_MANIP_SRC)) { > > + maniptype = NF_NAT_MANIP_SRC; > > + } else if (ct_action & (1 << NF_NAT_MANIP_DST)) { > > + maniptype = NF_NAT_MANIP_DST; > > + } else { > > + return NF_ACCEPT; > > + } > > + > > + err = nf_ct_nat_execute(skb, ct, ctinfo, action, range, maniptype); > > + if (err == NF_ACCEPT && ct->status & IPS_DST_NAT) { > > + if (ct->status & IPS_SRC_NAT) { > > + if (maniptype == NF_NAT_MANIP_SRC) > > + maniptype = NF_NAT_MANIP_DST; > > + else > > + maniptype = NF_NAT_MANIP_SRC; > > + > > + err = nf_ct_nat_execute(skb, ct, ctinfo, action, > > range, > > + maniptype); > > + } else if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) { > > + err = nf_ct_nat_execute(skb, ct, ctinfo, action, NULL, > > + NF_NAT_MANIP_SRC); > > + } > > + } > > + return err; > > +} > > +EXPORT_SYMBOL_GPL(nf_ct_nat); > > I'd suggest you move this code to nf_nat_ovs.c or such so we remember > these symbols are used by act_ct.c and ovs. Good idea, do you think we should also create nf_conntrack_ovs.c to have nf_ct_helper() and nf_ct_add_helper()? which were added by:
https://lore.kernel.org/netdev/[email protected]/T/ thanks. _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
