From: wenxu <[email protected]>

Now, the default timeout policy for netdev datapath is hard codeing. In
some case show or modify is needed.
Add command for get/set default timeout policy. Using like this:

ovs-appctl dpctl/ct-get-default-tp [dp]
ovs-appctl dpctl/ct-set-default-tp [dp] policies

Signed-off-by: wenxu <[email protected]>
---
 NEWS                             |   4 ++
 lib/conntrack-tp.c               |  45 +---------------
 lib/ct-dpif.c                    | 107 +++++++++++++++++++++++++++++++++++++++
 lib/ct-dpif.h                    |  12 +++++
 lib/dpctl.c                      |  70 +++++++++++++++++++++++++
 lib/dpif-netdev.c                |  20 ++++++++
 lib/dpif-netlink.c               |   2 +
 lib/dpif-provider.h              |   7 +++
 tests/system-kmod-macros.at      |  10 ++++
 tests/system-traffic.at          |  67 ++++++++++++++++++++++++
 tests/system-userspace-macros.at |   7 +++
 11 files changed, 308 insertions(+), 43 deletions(-)

diff --git a/NEWS b/NEWS
index 2a4856c..dea1044 100644
--- a/NEWS
+++ b/NEWS
@@ -23,6 +23,10 @@ Post-v2.16.0
      * Default selection method for select groups with up to 256 buckets is
        now dp_hash.  Previously this was limited to 64 buckets.  This change
        is mainly for the benefit of OVN load balancing configurations.
+   - ovs-appctl dpctl/:
+     * New commands 'ct-set-default-tp' and
+       'ct-set-default-tp' that allows to get or configure
+       netdev datapath ct default timeout policy.
 
 
 v2.16.0 - 16 Aug 2021
diff --git a/lib/conntrack-tp.c b/lib/conntrack-tp.c
index a586d3a..9988327 100644
--- a/lib/conntrack-tp.c
+++ b/lib/conntrack-tp.c
@@ -25,12 +25,6 @@
 VLOG_DEFINE_THIS_MODULE(conntrack_tp);
 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
 
-static const char *ct_timeout_str[] = {
-#define CT_TIMEOUT(NAME) #NAME,
-    CT_TIMEOUTS
-#undef CT_TIMEOUT
-};
-
 /* Default timeout policy in seconds. */
 static unsigned int ct_dpif_netdev_tp_def[] = {
     [CT_DPIF_TP_ATTR_TCP_SYN_SENT] = 30,
@@ -195,41 +189,6 @@ timeout_policy_update(struct conntrack *ct,
     return err;
 }
 
-static enum ct_dpif_tp_attr
-tm_to_ct_dpif_tp(enum ct_timeout tm)
-{
-    switch (tm) {
-    case CT_TM_TCP_FIRST_PACKET:
-        return CT_DPIF_TP_ATTR_TCP_SYN_SENT;
-    case CT_TM_TCP_OPENING:
-        return CT_DPIF_TP_ATTR_TCP_SYN_RECV;
-    case CT_TM_TCP_ESTABLISHED:
-        return CT_DPIF_TP_ATTR_TCP_ESTABLISHED;
-    case CT_TM_TCP_CLOSING:
-        return CT_DPIF_TP_ATTR_TCP_FIN_WAIT;
-    case CT_TM_TCP_FIN_WAIT:
-        return CT_DPIF_TP_ATTR_TCP_TIME_WAIT;
-    case CT_TM_TCP_CLOSED:
-        return CT_DPIF_TP_ATTR_TCP_CLOSE;
-    case CT_TM_OTHER_FIRST:
-        return CT_DPIF_TP_ATTR_UDP_FIRST;
-    case CT_TM_OTHER_BIDIR:
-        return CT_DPIF_TP_ATTR_UDP_MULTIPLE;
-    case CT_TM_OTHER_MULTIPLE:
-        return CT_DPIF_TP_ATTR_UDP_SINGLE;
-    case CT_TM_ICMP_FIRST:
-        return CT_DPIF_TP_ATTR_ICMP_FIRST;
-    case CT_TM_ICMP_REPLY:
-        return CT_DPIF_TP_ATTR_ICMP_REPLY;
-    case N_CT_TM:
-    default:
-        OVS_NOT_REACHED();
-        break;
-    }
-    OVS_NOT_REACHED();
-    return CT_DPIF_TP_ATTR_MAX;
-}
-
 static void
 conn_update_expiration__(struct conntrack *ct, struct conn *conn,
                          enum ct_timeout tm, long long now,
@@ -276,7 +235,7 @@ conn_update_expiration(struct conntrack *ct, struct conn 
*conn,
     ovs_mutex_lock(&conn->lock);
     VLOG_DBG_RL(&rl, "Update timeout %s zone=%u with policy id=%d "
                 "val=%u sec.",
-                ct_timeout_str[tm], conn->key.zone, conn->tp_id, val);
+                ct_dpif_timeout_string[tm], conn->key.zone, conn->tp_id, val);
 
     conn_update_expiration__(ct, conn, tm, now, val);
 }
@@ -307,7 +266,7 @@ conn_init_expiration(struct conntrack *ct, struct conn 
*conn,
     }
 
     VLOG_DBG_RL(&rl, "Init timeout %s zone=%u with policy id=%d val=%u sec.",
-                ct_timeout_str[tm], conn->key.zone, conn->tp_id, val);
+                ct_dpif_timeout_string[tm], conn->key.zone, conn->tp_id, val);
 
     conn_init_expiration__(ct, conn, tm, now, val);
 }
diff --git a/lib/ct-dpif.c b/lib/ct-dpif.c
index cfc2315..986f7fb 100644
--- a/lib/ct-dpif.c
+++ b/lib/ct-dpif.c
@@ -20,6 +20,7 @@
 #include <errno.h>
 
 #include "ct-dpif.h"
+#include "conntrack-private.h"
 #include "openvswitch/ofp-parse.h"
 #include "openvswitch/vlog.h"
 
@@ -180,6 +181,24 @@ ct_dpif_get_tcp_seq_chk(struct dpif *dpif, bool *enabled)
 }
 
 int
+ct_dpif_set_default_timeout_policy(struct dpif *dpif,
+                                   struct ct_dpif_timeout_policy *tp)
+{
+    return (dpif->dpif_class->ct_set_timeout_policy
+            ? dpif->dpif_class->ct_set_default_timeout_policy(dpif, tp)
+            : EOPNOTSUPP);
+}
+
+int
+ct_dpif_get_default_timeout_policy(struct dpif *dpif,
+                                   struct ct_dpif_timeout_policy *tp)
+{
+    return (dpif->dpif_class->ct_get_timeout_policy
+            ? dpif->dpif_class->ct_get_default_timeout_policy(dpif, tp)
+            : EOPNOTSUPP);
+}
+
+int
 ct_dpif_set_limits(struct dpif *dpif, const uint32_t *default_limit,
                    const struct ovs_list *zone_limits)
 {
@@ -710,6 +729,43 @@ ct_dpif_free_zone_limits(struct ovs_list *zone_limits)
     }
 }
 
+
+/* Parses a specification of a timeout policy from 's' into '*tp'
+ * .  Returns true on success.  Otherwise, returns false and
+ * and puts the error message in 'ds'. */
+bool
+ct_dpif_parse_timeout_policy_tuple(const char *s, struct ds *ds,
+                                   struct ct_dpif_timeout_policy *tp)
+{
+    char *pos, *key, *value, *copy, *err;
+
+    pos = copy = xstrdup(s);
+    while (ofputil_parse_key_value(&pos, &key, &value)) {
+        uint32_t tmp;
+
+        if (!*value) {
+            ds_put_format(ds, "field %s missing value", key);
+            goto error;
+        }
+
+        err = str_to_u32(value, &tmp);
+        if (err) {
+          free(err);
+          goto error_with_msg;
+        }
+
+        ct_dpif_set_timeout_policy_attr_by_name(tp, key, tmp);
+    }
+    free(copy);
+
+    return true;
+
+error_with_msg:
+    ds_put_format(ds, "failed to parse field %s", key);
+error:
+    free(copy);
+    return false;
+}
 /* Parses a specification of a conntrack zone limit from 's' into '*pzone'
  * and '*plimit'.  Returns true on success.  Otherwise, returns false and
  * and puts the error message in 'ds'. */
@@ -792,6 +848,57 @@ static const char *const ct_dpif_tp_attr_string[] = {
 #undef CT_DPIF_TP_ICMP_ATTR
 };
 
+enum ct_dpif_tp_attr
+tm_to_ct_dpif_tp(enum ct_timeout tm)
+{
+    switch (tm) {
+    case CT_TM_TCP_FIRST_PACKET:
+        return CT_DPIF_TP_ATTR_TCP_SYN_SENT;
+    case CT_TM_TCP_OPENING:
+        return CT_DPIF_TP_ATTR_TCP_SYN_RECV;
+    case CT_TM_TCP_ESTABLISHED:
+        return CT_DPIF_TP_ATTR_TCP_ESTABLISHED;
+    case CT_TM_TCP_CLOSING:
+        return CT_DPIF_TP_ATTR_TCP_FIN_WAIT;
+    case CT_TM_TCP_FIN_WAIT:
+        return CT_DPIF_TP_ATTR_TCP_TIME_WAIT;
+    case CT_TM_TCP_CLOSED:
+        return CT_DPIF_TP_ATTR_TCP_CLOSE;
+    case CT_TM_OTHER_FIRST:
+        return CT_DPIF_TP_ATTR_UDP_FIRST;
+    case CT_TM_OTHER_BIDIR:
+        return CT_DPIF_TP_ATTR_UDP_MULTIPLE;
+    case CT_TM_OTHER_MULTIPLE:
+        return CT_DPIF_TP_ATTR_UDP_SINGLE;
+    case CT_TM_ICMP_FIRST:
+        return CT_DPIF_TP_ATTR_ICMP_FIRST;
+    case CT_TM_ICMP_REPLY:
+        return CT_DPIF_TP_ATTR_ICMP_REPLY;
+    case N_CT_TM:
+    default:
+        OVS_NOT_REACHED();
+        break;
+    }
+    OVS_NOT_REACHED();
+    return CT_DPIF_TP_ATTR_MAX;
+}
+
+const char *ct_dpif_timeout_string[] = {
+#define CT_TIMEOUT(NAME) #NAME,
+    CT_TIMEOUTS
+#undef CT_TIMEOUT
+};
+
+void
+ct_dpif_format_timeout_policy(const struct ct_dpif_timeout_policy *tp,
+                              struct ds *ds)
+{
+    for (unsigned i = 0; i < N_CT_TM; i++) {
+        ds_put_format(ds, "\n\t%s = %"PRIu32, ct_dpif_timeout_string[i],
+                      tp->attrs[tm_to_ct_dpif_tp(i)]);
+    }
+}
+
 static bool
 ct_dpif_set_timeout_policy_attr(struct ct_dpif_timeout_policy *tp,
                                 uint32_t attr, uint32_t value)
diff --git a/lib/ct-dpif.h b/lib/ct-dpif.h
index b59cba9..5a03883 100644
--- a/lib/ct-dpif.h
+++ b/lib/ct-dpif.h
@@ -271,6 +271,8 @@ struct ct_dpif_timeout_policy {
                                                  * timeout attribute values */
 };
 
+extern const char *ct_dpif_timeout_string[];
+
 /* Conntrack Features. */
 enum ct_features {
     CONNTRACK_F_ZERO_SNAT = 1 << 0,  /* All-zero SNAT support. */
@@ -292,6 +294,12 @@ int ct_dpif_set_limits(struct dpif *dpif, const uint32_t 
*default_limit,
 int ct_dpif_get_limits(struct dpif *dpif, uint32_t *default_limit,
                        const struct ovs_list *, struct ovs_list *);
 int ct_dpif_del_limits(struct dpif *dpif, const struct ovs_list *);
+int ct_dpif_set_default_timeout_policy(struct dpif *dpif,
+                                       struct ct_dpif_timeout_policy *);
+int ct_dpif_get_default_timeout_policy(struct dpif *dpif,
+                                       struct ct_dpif_timeout_policy *tp);
+bool ct_dpif_parse_timeout_policy_tuple(const char *s, struct ds *ds,
+                                        struct ct_dpif_timeout_policy *);
 int ct_dpif_ipf_set_enabled(struct dpif *, bool v6, bool enable);
 int ct_dpif_ipf_set_min_frag(struct dpif *, bool v6, uint32_t min_frag);
 int ct_dpif_ipf_set_max_nfrags(struct dpif *, uint32_t max_frags);
@@ -315,6 +323,10 @@ bool ct_dpif_parse_zone_limit_tuple(const char *s, 
uint16_t *pzone,
                                     uint32_t *plimit, struct ds *);
 void ct_dpif_format_zone_limits(uint32_t default_limit,
                                 const struct ovs_list *, struct ds *);
+void ct_dpif_format_timeout_policy(const struct ct_dpif_timeout_policy *tp,
+                                   struct ds *ds);
+enum ct_timeout;
+enum ct_dpif_tp_attr tm_to_ct_dpif_tp(enum ct_timeout tm);
 bool ct_dpif_set_timeout_policy_attr_by_name(struct ct_dpif_timeout_policy *tp,
                                              const char *key, uint32_t value);
 bool ct_dpif_timeout_policy_support_ipproto(uint8_t ipproto);
diff --git a/lib/dpctl.c b/lib/dpctl.c
index 1ba1a96..13118a8 100644
--- a/lib/dpctl.c
+++ b/lib/dpctl.c
@@ -2074,6 +2074,72 @@ dpctl_ct_get_tcp_seq_chk(int argc, const char *argv[],
 }
 
 static int
+dpctl_ct_set_default_timeout_policy(int argc, const char *argv[],
+                                    struct dpctl_params *dpctl_p)
+{
+    int i =  dp_arg_exists(argc, argv) ? 2 : 1;
+    struct ds ds = DS_EMPTY_INITIALIZER;
+    struct ct_dpif_timeout_policy tp;
+    struct dpif *dpif;
+
+    int error = opt_dpif_open(argc, argv, dpctl_p, 3, &dpif);
+    if (error) {
+        return error;
+    }
+
+    memset(&tp, 0, sizeof tp);
+    tp.id = DEFAULT_TP_ID;
+
+    /* Parse timeout policy tuples */
+    if (!ct_dpif_parse_timeout_policy_tuple(argv[i], &ds, &tp)) {
+        error = EINVAL;
+        goto error;
+    }
+
+    error = ct_dpif_set_default_timeout_policy(dpif, &tp);
+    if (!error) {
+        dpif_close(dpif);
+        return 0;
+    } else {
+        ds_put_cstr(&ds, "failed to set timeout policy");
+    }
+
+error:
+    dpctl_error(dpctl_p, error, "%s", ds_cstr(&ds));
+    ds_destroy(&ds);
+    dpif_close(dpif);
+    return error;
+}
+
+static int
+dpctl_ct_get_default_timeout_policy(int argc, const char *argv[],
+                                    struct dpctl_params *dpctl_p)
+{
+    struct ds ds = DS_EMPTY_INITIALIZER;
+    struct ct_dpif_timeout_policy tp;
+    struct dpif *dpif;
+
+    int error = opt_dpif_open(argc, argv, dpctl_p, INT_MAX, &dpif);
+    if (error) {
+        return error;
+    }
+
+    error = ct_dpif_get_default_timeout_policy(dpif, &tp);
+    if (!error) {
+        ds_put_format(&ds, "default timeout policy (s): ");
+        ct_dpif_format_timeout_policy(&tp, &ds);
+        dpctl_print(dpctl_p, "%s\n", ds_cstr(&ds));
+    } else {
+        ds_put_format(&ds, "failed to get conntrack timeout policy %s",
+                      ovs_strerror(error));
+    }
+
+    ds_destroy(&ds);
+    dpif_close(dpif);
+    return error;
+}
+
+static int
 dpctl_ct_set_limits(int argc, const char *argv[],
                     struct dpctl_params *dpctl_p)
 {
@@ -2842,6 +2908,10 @@ static const struct dpctl_command all_commands[] = {
     { "ct-disable-tcp-seq-chk", "[dp]", 0, 1, dpctl_ct_disable_tcp_seq_chk,
        DP_RW },
     { "ct-get-tcp-seq-chk", "[dp]", 0, 1, dpctl_ct_get_tcp_seq_chk, DP_RO },
+    { "ct-set-default-tp", "[dp]", 1, 2,
+       dpctl_ct_set_default_timeout_policy, DP_RW },
+    { "ct-get-default-tp", "[dp]", 0, 1,
+       dpctl_ct_get_default_timeout_policy, DP_RO },
     { "ct-set-limits", "[dp] [default=L] [zone=N,limit=L]...", 1, INT_MAX,
         dpctl_ct_set_limits, DP_RO },
     { "ct-del-limits", "[dp] zone=N1[,N2]...", 1, 2, dpctl_ct_del_limits,
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index a790df5..dffac54 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -8615,6 +8615,24 @@ dpif_netdev_ct_get_timeout_policy_name(struct dpif *dpif 
OVS_UNUSED,
 }
 
 static int
+dpif_netdev_ct_set_default_timeout_policy(struct dpif *dpif,
+                                          struct ct_dpif_timeout_policy *tp)
+{
+    if (tp->id != DEFAULT_TP_ID) {
+        return EINVAL;
+    }
+
+    return dpif_netdev_ct_set_timeout_policy(dpif, tp);
+}
+
+static int
+dpif_netdev_ct_get_default_timeout_policy(struct dpif *dpif,
+                                          struct ct_dpif_timeout_policy *tp)
+{
+    return dpif_netdev_ct_get_timeout_policy(dpif, DEFAULT_TP_ID, tp);
+}
+
+static int
 dpif_netdev_ipf_set_enabled(struct dpif *dpif, bool v6, bool enable)
 {
     struct dp_netdev *dp = get_dp_netdev(dpif);
@@ -8824,6 +8842,8 @@ const struct dpif_class dpif_netdev_class = {
     NULL,                       /* ct_timeout_policy_dump_next */
     NULL,                       /* ct_timeout_policy_dump_done */
     dpif_netdev_ct_get_timeout_policy_name,
+    dpif_netdev_ct_set_default_timeout_policy,
+    dpif_netdev_ct_get_default_timeout_policy,
     dpif_netdev_ct_get_features,
     dpif_netdev_ipf_set_enabled,
     dpif_netdev_ipf_set_min_frag,
diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c
index 424a284..39c559a 100644
--- a/lib/dpif-netlink.c
+++ b/lib/dpif-netlink.c
@@ -4460,6 +4460,8 @@ const struct dpif_class dpif_netlink_class = {
     dpif_netlink_ct_timeout_policy_dump_next,
     dpif_netlink_ct_timeout_policy_dump_done,
     dpif_netlink_ct_get_timeout_policy_name,
+    NULL,                       /* ct_set_default_timeout_policy */
+    NULL,                       /* ct_get_default_timeout_policy */
     dpif_netlink_ct_get_features,
     NULL,                       /* ipf_set_enabled */
     NULL,                       /* ipf_set_min_frag */
diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h
index 27e3a76..e8be2bb 100644
--- a/lib/dpif-provider.h
+++ b/lib/dpif-provider.h
@@ -565,6 +565,13 @@ struct dpif_class {
                                       uint16_t dl_type, uint8_t nw_proto,
                                       char **tp_name, bool *is_generic);
 
+    /* Sets default timeout policy '*tp' into the datapath. */
+    int (*ct_set_default_timeout_policy)(struct dpif *,
+                                         struct ct_dpif_timeout_policy *);
+    /* Gets the default timeout policy and stores it into '*tp'. */
+    int (*ct_get_default_timeout_policy)(struct dpif *,
+                                         struct ct_dpif_timeout_policy *);
+
     /* Stores the conntrack features supported by 'dpif' into features.
      * The value is a bitmap of CONNTRACK_F_* bits. */
     int (*ct_get_features)(struct dpif *, enum ct_features *features);
diff --git a/tests/system-kmod-macros.at b/tests/system-kmod-macros.at
index 86d633a..21fb259 100644
--- a/tests/system-kmod-macros.at
+++ b/tests/system-kmod-macros.at
@@ -121,6 +121,16 @@ m4_define([CHECK_CONNTRACK_TIMEOUT],
     on_exit 'modprobe -r nfnetlink_cttimeout'
 ])
 
+# CHECK_CONNTRACK_DEFAULT_TIMEOUT()
+#
+# Perform requirements checks for running ovs-dpctl ct-set-default-tp or
+# ovs-dpctl ct-get-default-tp. The kernel datapath does not support this
+# feature.
+m4_define([CHECK_CONNTRACK_DEFAULT_TIMEOUT],
+[
+    AT_SKIP_IF([:])
+])
+
 # CHECK_CT_DPIF_SET_GET_MAXCONNS()
 #
 # Perform requirements checks for running ovs-dpctl ct-set-maxconns or
diff --git a/tests/system-traffic.at b/tests/system-traffic.at
index d79753a..6744ce2 100644
--- a/tests/system-traffic.at
+++ b/tests/system-traffic.at
@@ -3632,6 +3632,73 @@ 
udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=<cleared>,dport=<cleared>),reply=(src=
 OVS_TRAFFIC_VSWITCHD_STOP
 AT_CLEANUP
 
+AT_SETUP([conntrack - default timeout policy])
+CHECK_CONNTRACK()
+CHECK_CONNTRACK_DEFAULT_TIMEOUT()
+OVS_TRAFFIC_VSWITCHD_START()
+
+ADD_NAMESPACES(at_ns0, at_ns1)
+
+ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24")
+ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24")
+
+AT_DATA([flows.txt], [dnl
+priority=1,action=drop
+priority=10,arp,action=normal
+priority=100,in_port=1,ip,action=ct(zone=5, table=1)
+priority=100,in_port=2,ip,action=ct(zone=5, table=1)
+table=1,in_port=2,ip,ct_state=+trk+est,action=1
+table=1,in_port=1,ip,ct_state=+trk+new,action=ct(commit,zone=5),2
+table=1,in_port=1,ip,ct_state=+trk+est,action=2
+])
+
+AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt])
+
+dnl Test with origin default timeout
+
+dnl Send ICMP and UDP traffic
+NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 2 10.1.1.2 | FORMAT_PING], 
[0], [dnl
+3 packets transmitted, 3 received, 0% packet loss, time 0ms
+])
+AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=1 
packet=50540000000a50540000000908004500001c000000000011a4cd0a0101010a0101020001000200080000
 actions=resubmit(,0)"])
+
+sleep 4
+
+AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2) | sort], [0], 
[dnl
+icmp,orig=(src=10.1.1.1,dst=10.1.1.2,id=<cleared>,type=8,code=0),reply=(src=10.1.1.2,dst=10.1.1.1,id=<cleared>,type=0,code=0),zone=5
+udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=<cleared>,dport=<cleared>),reply=(src=10.1.1.2,dst=10.1.1.1,sport=<cleared>,dport=<cleared>),zone=5
+])
+
+AT_CHECK([ovs-appctl dpctl/flush-conntrack])
+
+dnl Shorten the udp_first udp_single and
+dnl icmp_first icmp_reply default timeout
+VSCTL_ADD_DATAPATH_TABLE()
+
+dnl Modifing default timeout policies
+AT_CHECK([ovs-appctl dpctl/ct-set-default-tp 
"udp_first=1,udp_single=1,icmp_first=1,icmp_reply=1"])
+
+dnl Send ICMP and UDP traffic
+NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 2 10.1.1.2 | FORMAT_PING], 
[0], [dnl
+3 packets transmitted, 3 received, 0% packet loss, time 0ms
+])
+AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=1 
packet=50540000000a50540000000908004500001c000000000011a4cd0a0101010a0101020001000200080000
 actions=resubmit(,0)"])
+
+AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2) | sort], [0], 
[dnl
+icmp,orig=(src=10.1.1.1,dst=10.1.1.2,id=<cleared>,type=8,code=0),reply=(src=10.1.1.2,dst=10.1.1.1,id=<cleared>,type=0,code=0),zone=5
+udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=<cleared>,dport=<cleared>),reply=(src=10.1.1.2,dst=10.1.1.1,sport=<cleared>,dport=<cleared>),zone=5
+])
+
+dnl Wait until the timeout expire.
+dnl We intend to wait a bit longer, because conntrack does not recycle the 
entry right after it is expired.
+sleep 6
+
+AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2)], [0], [dnl
+])
+
+OVS_TRAFFIC_VSWITCHD_STOP
+AT_CLEANUP
+
 dnl Check kernel datapath to make sure conntrack fills in L3 and L4
 dnl protocol information
 AT_SETUP([conntrack - fragment reassembly with L3 L4 protocol information])
diff --git a/tests/system-userspace-macros.at b/tests/system-userspace-macros.at
index f639ba5..acd9643 100644
--- a/tests/system-userspace-macros.at
+++ b/tests/system-userspace-macros.at
@@ -110,6 +110,13 @@ m4_define([CHECK_CONNTRACK_ZEROIP_SNAT])
 #
 m4_define([CHECK_CONNTRACK_TIMEOUT])
 
+# CHECK_CONNTRACK_DEFAULT_TIMEOUT()
+#
+# Perform requirements checks for running conntrack customized
+# default timeout tests.
+#
+m4_define([CHECK_CONNTRACK_DEFAULT_TIMEOUT])
+
 # CHECK_CT_DPIF_SET_GET_MAXCONNS()
 #
 # Perform requirements checks for running ovs-dpctl ct-set-maxconns or
-- 
1.8.3.1

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to