diff options
author | Yi-Hung Wei <yihung.wei@gmail.com> | 2019-08-28 15:14:29 -0700 |
---|---|---|
committer | Justin Pettit <jpettit@ovn.org> | 2019-09-26 13:51:04 -0700 |
commit | 187bb41fbf447acf9fb6ac117dc923bbe649e78c (patch) | |
tree | f11eb9504e45897e7cb73065bf542e74cae8f05f /ofproto/ofproto-dpif.c | |
parent | ebe62ec1b9157bfdcc13288e38e67c05a41dc293 (diff) | |
download | openvswitch-187bb41fbf447acf9fb6ac117dc923bbe649e78c.tar.gz |
ofproto-dpif-xlate: Translate timeout policy in ct action
This patch derives the timeout policy based on ct zone from the
internal data structure that we maintain on dpif layer.
It also adds a system traffic test to verify the zone-based conntrack
timeout feature. The test uses ovs-vsctl commands to configure
the customized ICMP and UDP timeout on zone 5 to a shorter period.
It then injects ICMP and UDP traffic to conntrack, and checks if the
corresponding conntrack entry expires after the predefined timeout.
Signed-off-by: Yi-Hung Wei <yihung.wei@gmail.com>
ofproto-dpif: Checks if datapath supports OVS_CT_ATTR_TIMEOUT
This patch checks whether datapath supports OVS_CT_ATTR_TIMEOUT. With this
check, ofproto-dpif-xlate can use this information to decide whether to
translate the ct timeout policy.
Signed-off-by: Yi-Hung Wei <yihung.wei@gmail.com>
Signed-off-by: Justin Pettit <jpettit@ovn.org>
Diffstat (limited to 'ofproto/ofproto-dpif.c')
-rw-r--r-- | ofproto/ofproto-dpif.c | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index e120d9ecd..496a16c8a 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -1323,6 +1323,67 @@ check_ct_clear(struct dpif_backer *backer) return supported; } +/* Tests whether 'backer''s datapath supports the OVS_CT_ATTR_TIMEOUT + * attribute in OVS_ACTION_ATTR_CT. */ +static bool +check_ct_timeout_policy(struct dpif_backer *backer) +{ + struct dpif_execute execute; + struct dp_packet packet; + struct ofpbuf actions; + struct flow flow = { + .dl_type = CONSTANT_HTONS(ETH_TYPE_IP), + .nw_proto = IPPROTO_UDP, + .nw_ttl = 64, + /* Use the broadcast address on the loopback address range 127/8 to + * avoid hitting any real conntrack entries. We leave the UDP ports to + * zeroes for the same purpose. */ + .nw_src = CONSTANT_HTONL(0x7fffffff), + .nw_dst = CONSTANT_HTONL(0x7fffffff), + }; + size_t ct_start; + int error; + + /* Compose CT action with timeout policy attribute and check if datapath + * can decode the message. */ + ofpbuf_init(&actions, 64); + ct_start = nl_msg_start_nested(&actions, OVS_ACTION_ATTR_CT); + /* Timeout policy has no effect without the commit flag, but currently the + * datapath will accept a timeout policy even without commit. This is + * useful as we do not want to persist the probe connection in the + * conntrack table. */ + nl_msg_put_string(&actions, OVS_CT_ATTR_TIMEOUT, "ovs_test_tp"); + nl_msg_end_nested(&actions, ct_start); + + /* Compose a dummy UDP packet. */ + dp_packet_init(&packet, 0); + flow_compose(&packet, &flow, NULL, 64); + + /* Execute the actions. On older datapaths this fails with EINVAL, on + * newer datapaths it succeeds. */ + execute.actions = actions.data; + execute.actions_len = actions.size; + execute.packet = &packet; + execute.flow = &flow; + execute.needs_help = false; + execute.probe = true; + execute.mtu = 0; + + error = dpif_execute(backer->dpif, &execute); + + dp_packet_uninit(&packet); + ofpbuf_uninit(&actions); + + if (error) { + VLOG_INFO("%s: Datapath does not support timeout policy in conntrack " + "action", dpif_name(backer->dpif)); + } else { + VLOG_INFO("%s: Datapath supports timeout policy in conntrack action", + dpif_name(backer->dpif)); + } + + return !error; +} /* Tests whether 'backer''s datapath supports the * OVS_ACTION_ATTR_CHECK_PKT_LEN action. */ @@ -1473,6 +1534,7 @@ check_support(struct dpif_backer *backer) backer->rt_support.ct_clear = check_ct_clear(backer); backer->rt_support.max_hash_alg = check_max_dp_hash_alg(backer); backer->rt_support.check_pkt_len = check_check_pkt_len(backer); + backer->rt_support.ct_timeout = check_ct_timeout_policy(backer); /* Flow fields. */ backer->rt_support.odp.ct_state = check_ct_state(backer); @@ -5378,6 +5440,41 @@ ct_del_zone_timeout_policy(const char *datapath_type, uint16_t zone_id) } } +/* Gets timeout policy name in 'backer' based on 'zone', 'dl_type' and + * 'nw_proto'. Returns true if the zone-based timeout policy is configured. + * On success, stores the timeout policy name in 'tp_name', and sets + * 'unwildcard' based on the dpif implementation. If 'unwildcard' is true, + * the returned timeout policy is 'dl_type' and 'nw_proto' specific, and OVS + * needs to unwildcard the datapath flow for this timeout policy in flow + * translation. + * + * The caller is responsible for freeing 'tp_name'. */ +bool +ofproto_dpif_ct_zone_timeout_policy_get_name( + const struct dpif_backer *backer, uint16_t zone, uint16_t dl_type, + uint8_t nw_proto, char **tp_name, bool *unwildcard) +{ + if (!ct_dpif_timeout_policy_support_ipproto(nw_proto)) { + return false; + } + + struct ct_zone *ct_zone = ct_zone_lookup(&backer->ct_zones, zone); + if (!ct_zone) { + return false; + } + + bool is_generic; + if (ct_dpif_get_timeout_policy_name(backer->dpif, + ct_zone->ct_tp->tp_id, dl_type, + nw_proto, tp_name, &is_generic)) { + return false; + } + + /* Unwildcard datapath flow if it is not a generic timeout policy. */ + *unwildcard = !is_generic; + return true; +} + static bool set_frag_handling(struct ofproto *ofproto_, enum ofputil_frag_handling frag_handling) |