diff options
Diffstat (limited to 'net/openvswitch/conntrack.c')
-rw-r--r-- | net/openvswitch/conntrack.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c index 848c6eb55064..05249eb45082 100644 --- a/net/openvswitch/conntrack.c +++ b/net/openvswitch/conntrack.c | |||
@@ -67,6 +67,7 @@ struct ovs_conntrack_info { | |||
67 | struct md_mark mark; | 67 | struct md_mark mark; |
68 | struct md_labels labels; | 68 | struct md_labels labels; |
69 | char timeout[CTNL_TIMEOUT_NAME_MAX]; | 69 | char timeout[CTNL_TIMEOUT_NAME_MAX]; |
70 | struct nf_ct_timeout *nf_ct_timeout; | ||
70 | #if IS_ENABLED(CONFIG_NF_NAT) | 71 | #if IS_ENABLED(CONFIG_NF_NAT) |
71 | struct nf_nat_range2 range; /* Only present for SRC NAT and DST NAT. */ | 72 | struct nf_nat_range2 range; /* Only present for SRC NAT and DST NAT. */ |
72 | #endif | 73 | #endif |
@@ -524,6 +525,11 @@ static int handle_fragments(struct net *net, struct sw_flow_key *key, | |||
524 | return -EPFNOSUPPORT; | 525 | return -EPFNOSUPPORT; |
525 | } | 526 | } |
526 | 527 | ||
528 | /* The key extracted from the fragment that completed this datagram | ||
529 | * likely didn't have an L4 header, so regenerate it. | ||
530 | */ | ||
531 | ovs_flow_key_update_l3l4(skb, key); | ||
532 | |||
527 | key->ip.frag = OVS_FRAG_TYPE_NONE; | 533 | key->ip.frag = OVS_FRAG_TYPE_NONE; |
528 | skb_clear_hash(skb); | 534 | skb_clear_hash(skb); |
529 | skb->ignore_df = 1; | 535 | skb->ignore_df = 1; |
@@ -697,6 +703,14 @@ static bool skb_nfct_cached(struct net *net, | |||
697 | if (help && rcu_access_pointer(help->helper) != info->helper) | 703 | if (help && rcu_access_pointer(help->helper) != info->helper) |
698 | return false; | 704 | return false; |
699 | } | 705 | } |
706 | if (info->nf_ct_timeout) { | ||
707 | struct nf_conn_timeout *timeout_ext; | ||
708 | |||
709 | timeout_ext = nf_ct_timeout_find(ct); | ||
710 | if (!timeout_ext || info->nf_ct_timeout != | ||
711 | rcu_dereference(timeout_ext->timeout)) | ||
712 | return false; | ||
713 | } | ||
700 | /* Force conntrack entry direction to the current packet? */ | 714 | /* Force conntrack entry direction to the current packet? */ |
701 | if (info->force && CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) { | 715 | if (info->force && CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) { |
702 | /* Delete the conntrack entry if confirmed, else just release | 716 | /* Delete the conntrack entry if confirmed, else just release |
@@ -1565,7 +1579,7 @@ static int parse_ct(const struct nlattr *attr, struct ovs_conntrack_info *info, | |||
1565 | case OVS_CT_ATTR_TIMEOUT: | 1579 | case OVS_CT_ATTR_TIMEOUT: |
1566 | memcpy(info->timeout, nla_data(a), nla_len(a)); | 1580 | memcpy(info->timeout, nla_data(a), nla_len(a)); |
1567 | if (!memchr(info->timeout, '\0', nla_len(a))) { | 1581 | if (!memchr(info->timeout, '\0', nla_len(a))) { |
1568 | OVS_NLERR(log, "Invalid conntrack helper"); | 1582 | OVS_NLERR(log, "Invalid conntrack timeout"); |
1569 | return -EINVAL; | 1583 | return -EINVAL; |
1570 | } | 1584 | } |
1571 | break; | 1585 | break; |
@@ -1657,6 +1671,10 @@ int ovs_ct_copy_action(struct net *net, const struct nlattr *attr, | |||
1657 | ct_info.timeout)) | 1671 | ct_info.timeout)) |
1658 | pr_info_ratelimited("Failed to associated timeout " | 1672 | pr_info_ratelimited("Failed to associated timeout " |
1659 | "policy `%s'\n", ct_info.timeout); | 1673 | "policy `%s'\n", ct_info.timeout); |
1674 | else | ||
1675 | ct_info.nf_ct_timeout = rcu_dereference( | ||
1676 | nf_ct_timeout_find(ct_info.ct)->timeout); | ||
1677 | |||
1660 | } | 1678 | } |
1661 | 1679 | ||
1662 | if (helper) { | 1680 | if (helper) { |