Re: [ovs-dev] [PATCH v2 09/15] dpif-netdev: Execute conntrack action.

2016-04-26 Thread Daniele Di Proietto





On 26/04/2016 16:37, "Flavio Leitner"  wrote:

>On Fri, Apr 15, 2016 at 05:02:41PM -0700, Daniele Di Proietto wrote:
>> This commit implements the OVS_ACTION_ATTR_CT action in dpif-netdev.
>> 
>> To allow ofproto-dpif to detect the conntrack feature, flow_put will not
>> discard anymore flows with ct_* fields set. We still shouldn't allow
>> flows with NAT bits set, since there is no support for NAT.
>> 
>> Signed-off-by: Daniele Di Proietto 
>> ---
>>  lib/dpif-netdev.c | 68 
>> +--
>>  tests/dpif-netdev.at  | 14 +--
>>  tests/ofproto-dpif.at | 20 +++
>>  3 files changed, 77 insertions(+), 25 deletions(-)
>> 
>> diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
>> index 1e8a37c..436359a 100644
>> --- a/lib/dpif-netdev.c
>> +++ b/lib/dpif-netdev.c
>> @@ -33,6 +33,7 @@
>>  
>>  #include "bitmap.h"
>>  #include "cmap.h"
>> +#include "conntrack.h"
>>  #include "coverage.h"
>>  #include "csum.h"
>>  #include "dp-packet.h"
>> @@ -89,9 +90,17 @@ static struct shash dp_netdevs 
>> OVS_GUARDED_BY(dp_netdev_mutex)
>>  
>>  static struct vlog_rate_limit upcall_rl = VLOG_RATE_LIMIT_INIT(600, 600);
>>  
>> +#define DP_NETDEV_CS_SUPPORTED_MASK (CS_NEW | CS_ESTABLISHED | CS_RELATED \
>> + | CS_INVALID | CS_REPLY_DIR | 
>> CS_TRACKED)
>> +#define DP_NETDEV_CS_UNSUPPORTED_MASK 
>> (~(uint32_t)DP_NETDEV_CS_SUPPORTED_MASK)
>> +
>>  static struct odp_support dp_netdev_support = {
>>  .max_mpls_depth = SIZE_MAX,
>>  .recirc = true,
>> +.ct_state = true,
>> +.ct_zone = true,
>> +.ct_mark = true,
>> +.ct_label = true,
>>  };
>>  
>>  /* Stores a miniflow with inline values */
>> @@ -224,6 +233,8 @@ struct dp_netdev {
>>  /* Cpu mask for pin of pmd threads. */
>>  char *pmd_cmask;
>>  uint64_t last_tnl_conf_seq;
>> +
>> +struct conntrack conntrack;
>>  };
>>  
>>  static struct dp_netdev_port *dp_netdev_lookup_port(const struct dp_netdev 
>> *dp,
>> @@ -906,6 +917,8 @@ create_dp_netdev(const char *name, const struct 
>> dpif_class *class,
>>  dp->upcall_aux = NULL;
>>  dp->upcall_cb = NULL;
>>  
>> +conntrack_init(&dp->conntrack);
>> +
>>  cmap_init(&dp->poll_threads);
>>  ovs_mutex_init_recursive(&dp->non_pmd_mutex);
>>  ovsthread_key_create(&dp->per_pmd_key, NULL);
>> @@ -976,6 +989,8 @@ dp_netdev_free(struct dp_netdev *dp)
>>  ovs_mutex_destroy(&dp->non_pmd_mutex);
>>  ovsthread_key_delete(dp->per_pmd_key);
>>  
>> +conntrack_destroy(&dp->conntrack);
>> +
>>  ovs_mutex_lock(&dp->port_mutex);
>>  CMAP_FOR_EACH (port, node, &dp->ports) {
>>  /* PMD threads are destroyed here. do_del_port() cannot quiesce */
>> @@ -1965,9 +1980,7 @@ dpif_netdev_flow_from_nlattrs(const struct nlattr 
>> *key, uint32_t key_len,
>>  return EINVAL;
>>  }
>>  
>> -/* Userspace datapath doesn't support conntrack. */
>> -if (flow->ct_state || flow->ct_zone || flow->ct_mark
>> -|| !ovs_u128_is_zero(&flow->ct_label)) {
>> +if (flow->ct_state & DP_NETDEV_CS_UNSUPPORTED_MASK) {
>>  return EINVAL;
>>  }
>>  
>> @@ -2604,6 +2617,9 @@ dpif_netdev_run(struct dpif *dpif)
>>  ovs_mutex_unlock(&dp->non_pmd_mutex);
>>  dp_netdev_pmd_unref(non_pmd);
>>  
>> +/* XXX: If workload is too heavy we could add a separate thread. */
>> +conntrack_run(&dp->conntrack);
>> +
>
>Do you have any results to share? Just curious.
>
>Acked-by: Flavio Leitner 

As also pointed out by Joe this probably need to be revisited.

I'll do more testing. Thanks!

>
>>  tnl_neigh_cache_run();
>>  tnl_port_map_run();
>>  new_tnl_seq = seq_read(tnl_conf_seq);
>> @@ -3850,12 +3866,48 @@ dp_execute_cb(void *aux_, struct dp_packet 
>> **packets, int cnt,
>>  VLOG_WARN("Packet dropped. Max recirculation depth exceeded.");
>>  break;
>>  
>> -case OVS_ACTION_ATTR_CT:
>> -/* If a flow with this action is slow-pathed, datapath assistance is
>> - * required to implement it. However, we don't support this action
>> - * in the userspace datapath. */
>> -VLOG_WARN("Cannot execute conntrack action in userspace.");
>> +case OVS_ACTION_ATTR_CT: {
>> +const struct nlattr *b;
>> +bool commit = false;
>> +unsigned int left;
>> +uint16_t zone = 0;
>> +const char *helper = NULL;
>> +const uint32_t *setmark = NULL;
>> +const struct ovs_key_ct_labels *setlabel = NULL;
>> +
>> +
>> +/* XXX parsing this everytime is expensive.  We should do like 
>> kernel
>> + * does and create a structure. */
>> +NL_ATTR_FOR_EACH_UNSAFE (b, left, nl_attr_get(a), 
>> nl_attr_get_size(a)) {
>> +enum ovs_ct_attr sub_type = nl_attr_type(b);
>> +
>> +switch(sub_type) {
>> +case OVS_CT_ATTR_COMMIT:
>> +commit = true;
>> +break;
>> +case OVS_CT_ATTR_ZONE

Re: [ovs-dev] [PATCH v2 09/15] dpif-netdev: Execute conntrack action.

2016-04-26 Thread Daniele Di Proietto





On 19/04/2016 14:52, "Joe Stringer"  wrote:

>On 15 April 2016 at 17:02, Daniele Di Proietto  wrote:
>> This commit implements the OVS_ACTION_ATTR_CT action in dpif-netdev.
>>
>> To allow ofproto-dpif to detect the conntrack feature, flow_put will not
>> discard anymore flows with ct_* fields set. We still shouldn't allow
>> flows with NAT bits set, since there is no support for NAT.
>>
>> Signed-off-by: Daniele Di Proietto 
>> ---
>
>...
>
>> @@ -2604,6 +2617,9 @@ dpif_netdev_run(struct dpif *dpif)
>>  ovs_mutex_unlock(&dp->non_pmd_mutex);
>>  dp_netdev_pmd_unref(non_pmd);
>>
>> +/* XXX: If workload is too heavy we could add a separate thread. */
>> +conntrack_run(&dp->conntrack);
>> +
>
>Have you tried, eg, portscanning with several threads against the
>implementation to see how bad it gets?

Good point, I'm doing some testing and I'll revisit this.

>
>
>> @@ -3850,12 +3866,48 @@ dp_execute_cb(void *aux_, struct dp_packet 
>> **packets, int cnt,
>>  VLOG_WARN("Packet dropped. Max recirculation depth exceeded.");
>>  break;
>>
>> -case OVS_ACTION_ATTR_CT:
>> -/* If a flow with this action is slow-pathed, datapath assistance is
>> - * required to implement it. However, we don't support this action
>> - * in the userspace datapath. */
>> -VLOG_WARN("Cannot execute conntrack action in userspace.");
>> +case OVS_ACTION_ATTR_CT: {
>> +const struct nlattr *b;
>> +bool commit = false;
>> +unsigned int left;
>> +uint16_t zone = 0;
>> +const char *helper = NULL;
>> +const uint32_t *setmark = NULL;
>> +const struct ovs_key_ct_labels *setlabel = NULL;
>> +
>> +
>> +/* XXX parsing this everytime is expensive.  We should do like 
>> kernel
>> + * does and create a structure. */
>
>Seems reasonable. You say it's expensive (how expensive?), but it also
>seems a little cleaner to store it in a more accessible manner.

I tried creating a structure, but it doesn't seem to make a difference in
performance.  It is a little cleaner, but the I guess the complexity of
maintaining a (not so different) action format doesn't seem worth for now.

I think I'll remove this comment.
___
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev


Re: [ovs-dev] [PATCH v2 09/15] dpif-netdev: Execute conntrack action.

2016-04-26 Thread Flavio Leitner
On Fri, Apr 15, 2016 at 05:02:41PM -0700, Daniele Di Proietto wrote:
> This commit implements the OVS_ACTION_ATTR_CT action in dpif-netdev.
> 
> To allow ofproto-dpif to detect the conntrack feature, flow_put will not
> discard anymore flows with ct_* fields set. We still shouldn't allow
> flows with NAT bits set, since there is no support for NAT.
> 
> Signed-off-by: Daniele Di Proietto 
> ---
>  lib/dpif-netdev.c | 68 
> +--
>  tests/dpif-netdev.at  | 14 +--
>  tests/ofproto-dpif.at | 20 +++
>  3 files changed, 77 insertions(+), 25 deletions(-)
> 
> diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
> index 1e8a37c..436359a 100644
> --- a/lib/dpif-netdev.c
> +++ b/lib/dpif-netdev.c
> @@ -33,6 +33,7 @@
>  
>  #include "bitmap.h"
>  #include "cmap.h"
> +#include "conntrack.h"
>  #include "coverage.h"
>  #include "csum.h"
>  #include "dp-packet.h"
> @@ -89,9 +90,17 @@ static struct shash dp_netdevs 
> OVS_GUARDED_BY(dp_netdev_mutex)
>  
>  static struct vlog_rate_limit upcall_rl = VLOG_RATE_LIMIT_INIT(600, 600);
>  
> +#define DP_NETDEV_CS_SUPPORTED_MASK (CS_NEW | CS_ESTABLISHED | CS_RELATED \
> + | CS_INVALID | CS_REPLY_DIR | 
> CS_TRACKED)
> +#define DP_NETDEV_CS_UNSUPPORTED_MASK 
> (~(uint32_t)DP_NETDEV_CS_SUPPORTED_MASK)
> +
>  static struct odp_support dp_netdev_support = {
>  .max_mpls_depth = SIZE_MAX,
>  .recirc = true,
> +.ct_state = true,
> +.ct_zone = true,
> +.ct_mark = true,
> +.ct_label = true,
>  };
>  
>  /* Stores a miniflow with inline values */
> @@ -224,6 +233,8 @@ struct dp_netdev {
>  /* Cpu mask for pin of pmd threads. */
>  char *pmd_cmask;
>  uint64_t last_tnl_conf_seq;
> +
> +struct conntrack conntrack;
>  };
>  
>  static struct dp_netdev_port *dp_netdev_lookup_port(const struct dp_netdev 
> *dp,
> @@ -906,6 +917,8 @@ create_dp_netdev(const char *name, const struct 
> dpif_class *class,
>  dp->upcall_aux = NULL;
>  dp->upcall_cb = NULL;
>  
> +conntrack_init(&dp->conntrack);
> +
>  cmap_init(&dp->poll_threads);
>  ovs_mutex_init_recursive(&dp->non_pmd_mutex);
>  ovsthread_key_create(&dp->per_pmd_key, NULL);
> @@ -976,6 +989,8 @@ dp_netdev_free(struct dp_netdev *dp)
>  ovs_mutex_destroy(&dp->non_pmd_mutex);
>  ovsthread_key_delete(dp->per_pmd_key);
>  
> +conntrack_destroy(&dp->conntrack);
> +
>  ovs_mutex_lock(&dp->port_mutex);
>  CMAP_FOR_EACH (port, node, &dp->ports) {
>  /* PMD threads are destroyed here. do_del_port() cannot quiesce */
> @@ -1965,9 +1980,7 @@ dpif_netdev_flow_from_nlattrs(const struct nlattr *key, 
> uint32_t key_len,
>  return EINVAL;
>  }
>  
> -/* Userspace datapath doesn't support conntrack. */
> -if (flow->ct_state || flow->ct_zone || flow->ct_mark
> -|| !ovs_u128_is_zero(&flow->ct_label)) {
> +if (flow->ct_state & DP_NETDEV_CS_UNSUPPORTED_MASK) {
>  return EINVAL;
>  }
>  
> @@ -2604,6 +2617,9 @@ dpif_netdev_run(struct dpif *dpif)
>  ovs_mutex_unlock(&dp->non_pmd_mutex);
>  dp_netdev_pmd_unref(non_pmd);
>  
> +/* XXX: If workload is too heavy we could add a separate thread. */
> +conntrack_run(&dp->conntrack);
> +

Do you have any results to share? Just curious.

Acked-by: Flavio Leitner 

>  tnl_neigh_cache_run();
>  tnl_port_map_run();
>  new_tnl_seq = seq_read(tnl_conf_seq);
> @@ -3850,12 +3866,48 @@ dp_execute_cb(void *aux_, struct dp_packet **packets, 
> int cnt,
>  VLOG_WARN("Packet dropped. Max recirculation depth exceeded.");
>  break;
>  
> -case OVS_ACTION_ATTR_CT:
> -/* If a flow with this action is slow-pathed, datapath assistance is
> - * required to implement it. However, we don't support this action
> - * in the userspace datapath. */
> -VLOG_WARN("Cannot execute conntrack action in userspace.");
> +case OVS_ACTION_ATTR_CT: {
> +const struct nlattr *b;
> +bool commit = false;
> +unsigned int left;
> +uint16_t zone = 0;
> +const char *helper = NULL;
> +const uint32_t *setmark = NULL;
> +const struct ovs_key_ct_labels *setlabel = NULL;
> +
> +
> +/* XXX parsing this everytime is expensive.  We should do like kernel
> + * does and create a structure. */
> +NL_ATTR_FOR_EACH_UNSAFE (b, left, nl_attr_get(a), 
> nl_attr_get_size(a)) {
> +enum ovs_ct_attr sub_type = nl_attr_type(b);
> +
> +switch(sub_type) {
> +case OVS_CT_ATTR_COMMIT:
> +commit = true;
> +break;
> +case OVS_CT_ATTR_ZONE:
> +zone = nl_attr_get_u16(b);
> +break;
> +case OVS_CT_ATTR_HELPER:
> +helper = nl_attr_get_string(b);
> +break;
> +case OVS_CT_ATTR_MARK:
> +setmark = nl_attr_get(b);
> +  

Re: [ovs-dev] [PATCH v2 09/15] dpif-netdev: Execute conntrack action.

2016-04-19 Thread Joe Stringer
On 15 April 2016 at 17:02, Daniele Di Proietto  wrote:
> This commit implements the OVS_ACTION_ATTR_CT action in dpif-netdev.
>
> To allow ofproto-dpif to detect the conntrack feature, flow_put will not
> discard anymore flows with ct_* fields set. We still shouldn't allow
> flows with NAT bits set, since there is no support for NAT.
>
> Signed-off-by: Daniele Di Proietto 
> ---

...

> @@ -2604,6 +2617,9 @@ dpif_netdev_run(struct dpif *dpif)
>  ovs_mutex_unlock(&dp->non_pmd_mutex);
>  dp_netdev_pmd_unref(non_pmd);
>
> +/* XXX: If workload is too heavy we could add a separate thread. */
> +conntrack_run(&dp->conntrack);
> +

Have you tried, eg, portscanning with several threads against the
implementation to see how bad it gets?


> @@ -3850,12 +3866,48 @@ dp_execute_cb(void *aux_, struct dp_packet **packets, 
> int cnt,
>  VLOG_WARN("Packet dropped. Max recirculation depth exceeded.");
>  break;
>
> -case OVS_ACTION_ATTR_CT:
> -/* If a flow with this action is slow-pathed, datapath assistance is
> - * required to implement it. However, we don't support this action
> - * in the userspace datapath. */
> -VLOG_WARN("Cannot execute conntrack action in userspace.");
> +case OVS_ACTION_ATTR_CT: {
> +const struct nlattr *b;
> +bool commit = false;
> +unsigned int left;
> +uint16_t zone = 0;
> +const char *helper = NULL;
> +const uint32_t *setmark = NULL;
> +const struct ovs_key_ct_labels *setlabel = NULL;
> +
> +
> +/* XXX parsing this everytime is expensive.  We should do like kernel
> + * does and create a structure. */

Seems reasonable. You say it's expensive (how expensive?), but it also
seems a little cleaner to store it in a more accessible manner.
___
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev


[ovs-dev] [PATCH v2 09/15] dpif-netdev: Execute conntrack action.

2016-04-15 Thread Daniele Di Proietto
This commit implements the OVS_ACTION_ATTR_CT action in dpif-netdev.

To allow ofproto-dpif to detect the conntrack feature, flow_put will not
discard anymore flows with ct_* fields set. We still shouldn't allow
flows with NAT bits set, since there is no support for NAT.

Signed-off-by: Daniele Di Proietto 
---
 lib/dpif-netdev.c | 68 +--
 tests/dpif-netdev.at  | 14 +--
 tests/ofproto-dpif.at | 20 +++
 3 files changed, 77 insertions(+), 25 deletions(-)

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 1e8a37c..436359a 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -33,6 +33,7 @@
 
 #include "bitmap.h"
 #include "cmap.h"
+#include "conntrack.h"
 #include "coverage.h"
 #include "csum.h"
 #include "dp-packet.h"
@@ -89,9 +90,17 @@ static struct shash dp_netdevs 
OVS_GUARDED_BY(dp_netdev_mutex)
 
 static struct vlog_rate_limit upcall_rl = VLOG_RATE_LIMIT_INIT(600, 600);
 
+#define DP_NETDEV_CS_SUPPORTED_MASK (CS_NEW | CS_ESTABLISHED | CS_RELATED \
+ | CS_INVALID | CS_REPLY_DIR | CS_TRACKED)
+#define DP_NETDEV_CS_UNSUPPORTED_MASK (~(uint32_t)DP_NETDEV_CS_SUPPORTED_MASK)
+
 static struct odp_support dp_netdev_support = {
 .max_mpls_depth = SIZE_MAX,
 .recirc = true,
+.ct_state = true,
+.ct_zone = true,
+.ct_mark = true,
+.ct_label = true,
 };
 
 /* Stores a miniflow with inline values */
@@ -224,6 +233,8 @@ struct dp_netdev {
 /* Cpu mask for pin of pmd threads. */
 char *pmd_cmask;
 uint64_t last_tnl_conf_seq;
+
+struct conntrack conntrack;
 };
 
 static struct dp_netdev_port *dp_netdev_lookup_port(const struct dp_netdev *dp,
@@ -906,6 +917,8 @@ create_dp_netdev(const char *name, const struct dpif_class 
*class,
 dp->upcall_aux = NULL;
 dp->upcall_cb = NULL;
 
+conntrack_init(&dp->conntrack);
+
 cmap_init(&dp->poll_threads);
 ovs_mutex_init_recursive(&dp->non_pmd_mutex);
 ovsthread_key_create(&dp->per_pmd_key, NULL);
@@ -976,6 +989,8 @@ dp_netdev_free(struct dp_netdev *dp)
 ovs_mutex_destroy(&dp->non_pmd_mutex);
 ovsthread_key_delete(dp->per_pmd_key);
 
+conntrack_destroy(&dp->conntrack);
+
 ovs_mutex_lock(&dp->port_mutex);
 CMAP_FOR_EACH (port, node, &dp->ports) {
 /* PMD threads are destroyed here. do_del_port() cannot quiesce */
@@ -1965,9 +1980,7 @@ dpif_netdev_flow_from_nlattrs(const struct nlattr *key, 
uint32_t key_len,
 return EINVAL;
 }
 
-/* Userspace datapath doesn't support conntrack. */
-if (flow->ct_state || flow->ct_zone || flow->ct_mark
-|| !ovs_u128_is_zero(&flow->ct_label)) {
+if (flow->ct_state & DP_NETDEV_CS_UNSUPPORTED_MASK) {
 return EINVAL;
 }
 
@@ -2604,6 +2617,9 @@ dpif_netdev_run(struct dpif *dpif)
 ovs_mutex_unlock(&dp->non_pmd_mutex);
 dp_netdev_pmd_unref(non_pmd);
 
+/* XXX: If workload is too heavy we could add a separate thread. */
+conntrack_run(&dp->conntrack);
+
 tnl_neigh_cache_run();
 tnl_port_map_run();
 new_tnl_seq = seq_read(tnl_conf_seq);
@@ -3850,12 +3866,48 @@ dp_execute_cb(void *aux_, struct dp_packet **packets, 
int cnt,
 VLOG_WARN("Packet dropped. Max recirculation depth exceeded.");
 break;
 
-case OVS_ACTION_ATTR_CT:
-/* If a flow with this action is slow-pathed, datapath assistance is
- * required to implement it. However, we don't support this action
- * in the userspace datapath. */
-VLOG_WARN("Cannot execute conntrack action in userspace.");
+case OVS_ACTION_ATTR_CT: {
+const struct nlattr *b;
+bool commit = false;
+unsigned int left;
+uint16_t zone = 0;
+const char *helper = NULL;
+const uint32_t *setmark = NULL;
+const struct ovs_key_ct_labels *setlabel = NULL;
+
+
+/* XXX parsing this everytime is expensive.  We should do like kernel
+ * does and create a structure. */
+NL_ATTR_FOR_EACH_UNSAFE (b, left, nl_attr_get(a), nl_attr_get_size(a)) 
{
+enum ovs_ct_attr sub_type = nl_attr_type(b);
+
+switch(sub_type) {
+case OVS_CT_ATTR_COMMIT:
+commit = true;
+break;
+case OVS_CT_ATTR_ZONE:
+zone = nl_attr_get_u16(b);
+break;
+case OVS_CT_ATTR_HELPER:
+helper = nl_attr_get_string(b);
+break;
+case OVS_CT_ATTR_MARK:
+setmark = nl_attr_get(b);
+break;
+case OVS_CT_ATTR_LABELS:
+setlabel = nl_attr_get(b);
+break;
+case OVS_CT_ATTR_NAT:
+case OVS_CT_ATTR_UNSPEC:
+case __OVS_CT_ATTR_MAX:
+OVS_NOT_REACHED();
+}
+}
+
+conntrack_execute(&dp->conntrack, packets, cnt, commit, zone,
+  setmark, setlabel, helper);