openvswitch: Allow attaching helper in later commit

This patch allows to attach conntrack helper to a confirmed conntrack
entry.  Currently, we can only attach alg helper to a conntrack entry
when it is in the unconfirmed state.  This patch enables an use case
that we can firstly commit a conntrack entry after it passed some
initial conditions.  After that the processing pipeline will further
check a couple of packets to determine if the connection belongs to
a particular application, and attach alg helper to the connection
in a later stage.

Signed-off-by: Yi-Hung Wei <yihung.wei@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Yi-Hung Wei 2019-10-04 09:26:44 -07:00 committed by David S. Miller
parent fbe3d0c77c
commit 248d45f1e1

View File

@ -971,6 +971,8 @@ static int __ovs_ct_lookup(struct net *net, struct sw_flow_key *key,
ct = nf_ct_get(skb, &ctinfo); ct = nf_ct_get(skb, &ctinfo);
if (ct) { if (ct) {
bool add_helper = false;
/* Packets starting a new connection must be NATted before the /* Packets starting a new connection must be NATted before the
* helper, so that the helper knows about the NAT. We enforce * helper, so that the helper knows about the NAT. We enforce
* this by delaying both NAT and helper calls for unconfirmed * this by delaying both NAT and helper calls for unconfirmed
@ -988,16 +990,17 @@ static int __ovs_ct_lookup(struct net *net, struct sw_flow_key *key,
} }
/* Userspace may decide to perform a ct lookup without a helper /* Userspace may decide to perform a ct lookup without a helper
* specified followed by a (recirculate and) commit with one. * specified followed by a (recirculate and) commit with one,
* Therefore, for unconfirmed connections which we will commit, * or attach a helper in a later commit. Therefore, for
* we need to attach the helper here. * connections which we will commit, we may need to attach
* the helper here.
*/ */
if (!nf_ct_is_confirmed(ct) && info->commit && if (info->commit && info->helper && !nfct_help(ct)) {
info->helper && !nfct_help(ct)) {
int err = __nf_ct_try_assign_helper(ct, info->ct, int err = __nf_ct_try_assign_helper(ct, info->ct,
GFP_ATOMIC); GFP_ATOMIC);
if (err) if (err)
return err; return err;
add_helper = true;
/* helper installed, add seqadj if NAT is required */ /* helper installed, add seqadj if NAT is required */
if (info->nat && !nfct_seqadj(ct)) { if (info->nat && !nfct_seqadj(ct)) {
@ -1007,11 +1010,13 @@ static int __ovs_ct_lookup(struct net *net, struct sw_flow_key *key,
} }
/* Call the helper only if: /* Call the helper only if:
* - nf_conntrack_in() was executed above ("!cached") for a * - nf_conntrack_in() was executed above ("!cached") or a
* confirmed connection, or * helper was just attached ("add_helper") for a confirmed
* connection, or
* - When committing an unconfirmed connection. * - When committing an unconfirmed connection.
*/ */
if ((nf_ct_is_confirmed(ct) ? !cached : info->commit) && if ((nf_ct_is_confirmed(ct) ? !cached || add_helper :
info->commit) &&
ovs_ct_helper(skb, info->family) != NF_ACCEPT) { ovs_ct_helper(skb, info->family) != NF_ACCEPT) {
return -EINVAL; return -EINVAL;
} }