mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-01 10:45:49 +00:00
openvswitch: set IPS_CONFIRMED in tmpl status only when commit is set in conntrack
By not setting IPS_CONFIRMED in tmpl that allows the exp not to be removed from the hashtable when lookup, we can simplify the exp processing code a lot in openvswitch conntrack. Signed-off-by: Xin Long <lucien.xin@gmail.com> Acked-by: Aaron Conole <aconole@redhat.com> Acked-by: Florian Westphal <fw@strlen.de> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
parent
76622ced50
commit
8c8b733208
@ -455,45 +455,6 @@ static int ovs_ct_handle_fragments(struct net *net, struct sw_flow_key *key,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct nf_conntrack_expect *
|
|
||||||
ovs_ct_expect_find(struct net *net, const struct nf_conntrack_zone *zone,
|
|
||||||
u16 proto, const struct sk_buff *skb)
|
|
||||||
{
|
|
||||||
struct nf_conntrack_tuple tuple;
|
|
||||||
struct nf_conntrack_expect *exp;
|
|
||||||
|
|
||||||
if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), proto, net, &tuple))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
exp = __nf_ct_expect_find(net, zone, &tuple);
|
|
||||||
if (exp) {
|
|
||||||
struct nf_conntrack_tuple_hash *h;
|
|
||||||
|
|
||||||
/* Delete existing conntrack entry, if it clashes with the
|
|
||||||
* expectation. This can happen since conntrack ALGs do not
|
|
||||||
* check for clashes between (new) expectations and existing
|
|
||||||
* conntrack entries. nf_conntrack_in() will check the
|
|
||||||
* expectations only if a conntrack entry can not be found,
|
|
||||||
* which can lead to OVS finding the expectation (here) in the
|
|
||||||
* init direction, but which will not be removed by the
|
|
||||||
* nf_conntrack_in() call, if a matching conntrack entry is
|
|
||||||
* found instead. In this case all init direction packets
|
|
||||||
* would be reported as new related packets, while reply
|
|
||||||
* direction packets would be reported as un-related
|
|
||||||
* established packets.
|
|
||||||
*/
|
|
||||||
h = nf_conntrack_find_get(net, zone, &tuple);
|
|
||||||
if (h) {
|
|
||||||
struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h);
|
|
||||||
|
|
||||||
nf_ct_delete(ct, 0, 0);
|
|
||||||
nf_ct_put(ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return exp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This replicates logic from nf_conntrack_core.c that is not exported. */
|
/* This replicates logic from nf_conntrack_core.c that is not exported. */
|
||||||
static enum ip_conntrack_info
|
static enum ip_conntrack_info
|
||||||
ovs_ct_get_info(const struct nf_conntrack_tuple_hash *h)
|
ovs_ct_get_info(const struct nf_conntrack_tuple_hash *h)
|
||||||
@ -852,36 +813,16 @@ static int ovs_ct_lookup(struct net *net, struct sw_flow_key *key,
|
|||||||
const struct ovs_conntrack_info *info,
|
const struct ovs_conntrack_info *info,
|
||||||
struct sk_buff *skb)
|
struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct nf_conntrack_expect *exp;
|
struct nf_conn *ct;
|
||||||
|
int err;
|
||||||
|
|
||||||
/* If we pass an expected packet through nf_conntrack_in() the
|
err = __ovs_ct_lookup(net, key, info, skb);
|
||||||
* expectation is typically removed, but the packet could still be
|
if (err)
|
||||||
* lost in upcall processing. To prevent this from happening we
|
return err;
|
||||||
* perform an explicit expectation lookup. Expected connections are
|
|
||||||
* always new, and will be passed through conntrack only when they are
|
|
||||||
* committed, as it is OK to remove the expectation at that time.
|
|
||||||
*/
|
|
||||||
exp = ovs_ct_expect_find(net, &info->zone, info->family, skb);
|
|
||||||
if (exp) {
|
|
||||||
u8 state;
|
|
||||||
|
|
||||||
/* NOTE: New connections are NATted and Helped only when
|
ct = (struct nf_conn *)skb_nfct(skb);
|
||||||
* committed, so we are not calling into NAT here.
|
if (ct)
|
||||||
*/
|
nf_ct_deliver_cached_events(ct);
|
||||||
state = OVS_CS_F_TRACKED | OVS_CS_F_NEW | OVS_CS_F_RELATED;
|
|
||||||
__ovs_ct_update_key(key, state, &info->zone, exp->master);
|
|
||||||
} else {
|
|
||||||
struct nf_conn *ct;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
err = __ovs_ct_lookup(net, key, info, skb);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
ct = (struct nf_conn *)skb_nfct(skb);
|
|
||||||
if (ct)
|
|
||||||
nf_ct_deliver_cached_events(ct);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1460,7 +1401,8 @@ int ovs_ct_copy_action(struct net *net, const struct nlattr *attr,
|
|||||||
if (err)
|
if (err)
|
||||||
goto err_free_ct;
|
goto err_free_ct;
|
||||||
|
|
||||||
__set_bit(IPS_CONFIRMED_BIT, &ct_info.ct->status);
|
if (ct_info.commit)
|
||||||
|
__set_bit(IPS_CONFIRMED_BIT, &ct_info.ct->status);
|
||||||
return 0;
|
return 0;
|
||||||
err_free_ct:
|
err_free_ct:
|
||||||
__ovs_ct_free_action(&ct_info);
|
__ovs_ct_free_action(&ct_info);
|
||||||
|
Loading…
Reference in New Issue
Block a user