On Tue, Aug 06, 2019 at 05:57:50PM -0700, Dirk Morris wrote:
> On 8/6/19 5:34 PM, Florian Westphal wrote:
>
> >
> > This is unexpected, as the id function is only supposed to be called
> > once the conntrack has been confirmed, at which point all NAT side
> > effects are supposed to be done.
> >
> > In which case(s) does that assumption not hold?
> >
>
> Yeah, I figured that might be the reasoning.
>
> In my case either from a queue event or log event in userspace.
> Which is always pre-confirmation for the first packet of any connection until
> late.
>
> psuedo-code:
>
> nft add table inet foo
> nft add chain inet foo prerouting "{ type filter hook prerouting priority
> -123 ; }"
> nft add chain inet foo postrouting "{ type filter hook postrouting priority
> -123 ; }"
> nft add rule inet foo prerouting queue num 1234
> nft add rule inet foo postrouting queue num 1234
>
> or
>
> nft add table inet foo
> nft add chain inet foo prerouting "{ type filter hook prerouting priority
> -123 ; }"
> nft add chain inet foo postrouting "{ type filter hook postrouting priority
> -123 ; }"
> nft add rule inet foo prerouting log prefix "prerouting" group 0
> nft add rule inet foo postrouting log prefix "postrouting" group 0
>
> and then in some userspace daemon something like:
>
> ct_len = nfq_get_ct_info(nfad, &ct_data);
> nfct_payload_parse((void *)ct_data,ct_len,l3num,ct)
> id = nfct_get_attr_u32(ct,ATTR_ID);
>
> or
>
> *data = nfnl_get_pointer_to_data(nfa->nfa,NFULA_CT,char)
> nfct_payload_parse((void *)data,ct_len,l3num,ct )
> id = nfct_get_attr_u32(ct,ATTR_ID);
>
> Its just a convenience to have it not change if possible (assuming the
> proposal
> maintains the same level of uniqueness - not 100% sure on that).
>
> Listening to the conntrack events this does not happen, as you get the NEW
> event
> only after the ct is confirmed, but unfortunately you get the packet from
> queue
> and the log messages well before that.
ct->ext also might change while packet is in transit, since new
extension can be added too.
&ct->tuplehash was not good either for event retransmission, since
hnnode might change (when moving the object to the dying list), so
ct->tuplehash[x].tuple looks good to me.
@Florian: by mangling this patch not to use ct->ext, including Dirk's
update, conntrackd works again (remember that bug we discussed during
NFWS).
@@ -470,8 +470,8 @@ u32 nf_ct_get_id(const struct nf_conn *ct)
a = (unsigned long)ct;
b = (unsigned long)ct->master ^ net_hash_mix(nf_ct_net(ct));
- c = (unsigned long)ct->ext;
- d = (unsigned long)siphash(&ct->tuplehash[IP_CT_DIR_ORIGINAL],
sizeof(ct->tuplehash[IP_CT_DIR_ORIGINAL]),
+ c = (unsigned long)0;
+ d = (unsigned long)siphash(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
sizeof(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
I think it's safe to turn this into:
a = (unsigned long)ct;
b = (unsigned long)ct->master;
c = (unsigned long)nf_ct_net(ct));
d = (unsigned long)siphash(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
sizeof(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);