Skip to content

Commit 06bd2bd

Browse files
YiHungWeidavem330
authored andcommitted
openvswitch: Add timeout support to ct action
Add support for fine-grain timeout support to conntrack action. The new OVS_CT_ATTR_TIMEOUT attribute of the conntrack action specifies a timeout to be associated with this connection. If no timeout is specified, it acts as is, that is the default timeout for the connection will be automatically applied. Example usage: $ nfct timeout add timeout_1 inet tcp syn_sent 100 established 200 $ ovs-ofctl add-flow br0 in_port=1,ip,tcp,action=ct(commit,timeout=timeout_1) CC: Pravin Shelar <[email protected]> CC: Pablo Neira Ayuso <[email protected]> Signed-off-by: Yi-Hung Wei <[email protected]> Acked-by: Pravin B Shelar <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 717700d commit 06bd2bd

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

include/uapi/linux/openvswitch.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,7 @@ struct ovs_action_hash {
734734
* be received on NFNLGRP_CONNTRACK_NEW and NFNLGRP_CONNTRACK_DESTROY groups,
735735
* respectively. Remaining bits control the changes for which an event is
736736
* delivered on the NFNLGRP_CONNTRACK_UPDATE group.
737+
* @OVS_CT_ATTR_TIMEOUT: Variable length string defining conntrack timeout.
737738
*/
738739
enum ovs_ct_attr {
739740
OVS_CT_ATTR_UNSPEC,
@@ -746,6 +747,8 @@ enum ovs_ct_attr {
746747
OVS_CT_ATTR_NAT, /* Nested OVS_NAT_ATTR_* */
747748
OVS_CT_ATTR_FORCE_COMMIT, /* No argument */
748749
OVS_CT_ATTR_EVENTMASK, /* u32 mask of IPCT_* events. */
750+
OVS_CT_ATTR_TIMEOUT, /* Associate timeout with this connection for
751+
* fine-grain timeout tuning. */
749752
__OVS_CT_ATTR_MAX
750753
};
751754

net/openvswitch/conntrack.c

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <net/netfilter/nf_conntrack_helper.h>
2525
#include <net/netfilter/nf_conntrack_labels.h>
2626
#include <net/netfilter/nf_conntrack_seqadj.h>
27+
#include <net/netfilter/nf_conntrack_timeout.h>
2728
#include <net/netfilter/nf_conntrack_zones.h>
2829
#include <net/netfilter/ipv6/nf_defrag_ipv6.h>
2930
#include <net/ipv6_frag.h>
@@ -73,6 +74,7 @@ struct ovs_conntrack_info {
7374
u32 eventmask; /* Mask of 1 << IPCT_*. */
7475
struct md_mark mark;
7576
struct md_labels labels;
77+
char timeout[CTNL_TIMEOUT_NAME_MAX];
7678
#ifdef CONFIG_NF_NAT_NEEDED
7779
struct nf_nat_range2 range; /* Only present for SRC NAT and DST NAT. */
7880
#endif
@@ -1471,6 +1473,8 @@ static const struct ovs_ct_len_tbl ovs_ct_attr_lens[OVS_CT_ATTR_MAX + 1] = {
14711473
#endif
14721474
[OVS_CT_ATTR_EVENTMASK] = { .minlen = sizeof(u32),
14731475
.maxlen = sizeof(u32) },
1476+
[OVS_CT_ATTR_TIMEOUT] = { .minlen = 1,
1477+
.maxlen = CTNL_TIMEOUT_NAME_MAX },
14741478
};
14751479

14761480
static int parse_ct(const struct nlattr *attr, struct ovs_conntrack_info *info,
@@ -1556,6 +1560,15 @@ static int parse_ct(const struct nlattr *attr, struct ovs_conntrack_info *info,
15561560
info->have_eventmask = true;
15571561
info->eventmask = nla_get_u32(a);
15581562
break;
1563+
#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
1564+
case OVS_CT_ATTR_TIMEOUT:
1565+
memcpy(info->timeout, nla_data(a), nla_len(a));
1566+
if (!memchr(info->timeout, '\0', nla_len(a))) {
1567+
OVS_NLERR(log, "Invalid conntrack helper");
1568+
return -EINVAL;
1569+
}
1570+
break;
1571+
#endif
15591572

15601573
default:
15611574
OVS_NLERR(log, "Unknown conntrack attr (%d)",
@@ -1637,6 +1650,14 @@ int ovs_ct_copy_action(struct net *net, const struct nlattr *attr,
16371650
OVS_NLERR(log, "Failed to allocate conntrack template");
16381651
return -ENOMEM;
16391652
}
1653+
1654+
if (ct_info.timeout[0]) {
1655+
if (nf_ct_set_timeout(net, ct_info.ct, family, key->ip.proto,
1656+
ct_info.timeout))
1657+
pr_info_ratelimited("Failed to associated timeout "
1658+
"policy `%s'\n", ct_info.timeout);
1659+
}
1660+
16401661
if (helper) {
16411662
err = ovs_ct_add_helper(&ct_info, helper, key, log);
16421663
if (err)
@@ -1757,6 +1778,10 @@ int ovs_ct_action_to_attr(const struct ovs_conntrack_info *ct_info,
17571778
if (ct_info->have_eventmask &&
17581779
nla_put_u32(skb, OVS_CT_ATTR_EVENTMASK, ct_info->eventmask))
17591780
return -EMSGSIZE;
1781+
if (ct_info->timeout[0]) {
1782+
if (nla_put_string(skb, OVS_CT_ATTR_TIMEOUT, ct_info->timeout))
1783+
return -EMSGSIZE;
1784+
}
17601785

17611786
#ifdef CONFIG_NF_NAT_NEEDED
17621787
if (ct_info->nat && !ovs_ct_nat_to_attr(ct_info, skb))
@@ -1778,8 +1803,11 @@ static void __ovs_ct_free_action(struct ovs_conntrack_info *ct_info)
17781803
{
17791804
if (ct_info->helper)
17801805
nf_conntrack_helper_put(ct_info->helper);
1781-
if (ct_info->ct)
1806+
if (ct_info->ct) {
17821807
nf_ct_tmpl_free(ct_info->ct);
1808+
if (ct_info->timeout[0])
1809+
nf_ct_destroy_timeout(ct_info->ct);
1810+
}
17831811
}
17841812

17851813
#if IS_ENABLED(CONFIG_NETFILTER_CONNCOUNT)

0 commit comments

Comments
 (0)