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);