[ovs-dev] [PATCH v2 08/15] conntrack: Implement dumping to ct_entry.

2016-04-15 Thread Daniele Di Proietto
Signed-off-by: Daniele Di Proietto 
---
 lib/conntrack-private.h |   3 ++
 lib/conntrack-tcp.c |  34 +
 lib/conntrack.c | 125 
 lib/conntrack.h |  16 +++
 4 files changed, 178 insertions(+)

diff --git a/lib/conntrack-private.h b/lib/conntrack-private.h
index e668c44..1f04dc2 100644
--- a/lib/conntrack-private.h
+++ b/lib/conntrack-private.h
@@ -21,6 +21,7 @@
 #include 
 #include 
 
+#include "ct-dpif.h"
 #include "hmap.h"
 #include "openvswitch/types.h"
 #include "packets.h"
@@ -69,6 +70,8 @@ struct ct_l4_proto {
 bool (*valid_new)(struct dp_packet *pkt);
 enum ct_update_res (*conn_update)(struct conn *conn, struct dp_packet *pkt,
   bool reply, long long now);
+void (*conn_get_protoinfo)(const struct conn *,
+   struct ct_dpif_protoinfo *);
 };
 
 extern struct ct_l4_proto ct_proto_tcp;
diff --git a/lib/conntrack-tcp.c b/lib/conntrack-tcp.c
index 4d80038..f723fb2 100644
--- a/lib/conntrack-tcp.c
+++ b/lib/conntrack-tcp.c
@@ -469,8 +469,42 @@ tcp_new_conn(struct dp_packet *pkt, long long now)
 return &newconn->up;
 }
 
+static uint8_t
+tcp_peer_to_protoinfo_flags(const struct tcp_peer *peer)
+{
+uint8_t res = 0;
+
+if (peer->wscale & CT_WSCALE_FLAG) {
+res |= CT_DPIF_TCPF_WINDOW_SCALE;
+}
+
+if (peer->wscale & CT_WSCALE_UNKNOWN) {
+res |= CT_DPIF_TCPF_BE_LIBERAL;
+}
+
+return res;
+}
+
+static void
+tcp_conn_get_protoinfo(const struct conn *conn_,
+   struct ct_dpif_protoinfo *protoinfo)
+{
+const struct conn_tcp *conn = conn_tcp_cast(conn_);
+
+protoinfo->proto = IPPROTO_TCP;
+protoinfo->tcp.state_orig = conn->peer[0].state;
+protoinfo->tcp.state_reply = conn->peer[1].state;
+
+protoinfo->tcp.wscale_orig = conn->peer[0].wscale & CT_WSCALE_MASK;
+protoinfo->tcp.wscale_reply = conn->peer[1].wscale & CT_WSCALE_MASK;
+
+protoinfo->tcp.flags_orig = tcp_peer_to_protoinfo_flags(&conn->peer[0]);
+protoinfo->tcp.flags_reply = tcp_peer_to_protoinfo_flags(&conn->peer[0]);
+}
+
 struct ct_l4_proto ct_proto_tcp = {
 .new_conn = tcp_new_conn,
 .valid_new = tcp_valid_new,
 .conn_update = tcp_conn_update,
+.conn_get_protoinfo = tcp_conn_get_protoinfo,
 };
diff --git a/lib/conntrack.c b/lib/conntrack.c
index 7913e76..7dc896d 100644
--- a/lib/conntrack.c
+++ b/lib/conntrack.c
@@ -24,6 +24,7 @@
 
 #include "bitmap.h"
 #include "conntrack-private.h"
+#include "ct-dpif.h"
 #include "dp-packet.h"
 #include "flow.h"
 #include "hmap.h"
@@ -850,6 +851,130 @@ delete_conn(struct conn *conn)
 free(conn);
 }
 
+static void
+ct_endpoint_to_ct_dpif_inet_addr(const struct ct_addr *a,
+ union ct_dpif_inet_addr *b,
+ ovs_be16 dl_type)
+{
+if (dl_type == htons(ETH_TYPE_IP)) {
+b->ip = a->ipv4_aligned;
+} else if (dl_type == htons(ETH_TYPE_IPV6)){
+b->in6 = a->ipv6_aligned;
+}
+}
+
+static void
+conn_key_to_tuple(const struct conn_key *key, struct ct_dpif_tuple *tuple)
+{
+if (key->dl_type == htons(ETH_TYPE_IP)) {
+tuple->l3_type = AF_INET;
+} else if (key->dl_type == htons(ETH_TYPE_IPV6)) {
+tuple->l3_type = AF_INET6;
+}
+tuple->ip_proto = key->nw_proto;
+ct_endpoint_to_ct_dpif_inet_addr(&key->src.addr, &tuple->src,
+ key->dl_type);
+ct_endpoint_to_ct_dpif_inet_addr(&key->dst.addr, &tuple->dst,
+ key->dl_type);
+
+if (key->nw_proto == IPPROTO_ICMP) {
+tuple->icmp_id = key->src.port;
+/* ICMP type and code are not tracked */
+tuple->icmp_type = 0;
+tuple->icmp_code = 0;
+} else {
+tuple->src_port = key->src.port;
+tuple->dst_port = key->dst.port;
+}
+}
+
+static void
+conn_to_ct_dpif_entry(const struct conn *conn, struct ct_dpif_entry *entry,
+  long long now)
+{
+struct ct_l4_proto *class;
+long long expiration;
+memset(entry, 0, sizeof *entry);
+conn_key_to_tuple(&conn->key, &entry->tuple_orig);
+conn_key_to_tuple(&conn->rev_key, &entry->tuple_reply);
+
+entry->zone = conn->key.zone;
+entry->mark = conn->mark;
+
+memcpy(&entry->labels, &conn->label, sizeof(entry->labels));
+/* Not implemented yet */
+entry->timestamp.start = 0;
+entry->timestamp.stop = 0;
+
+expiration = conn->expiration - now;
+entry->timeout = (expiration > 0) ? expiration / 1000: 0;
+
+class = l4_protos[conn->key.nw_proto];
+if (class->conn_get_protoinfo) {
+class->conn_get_protoinfo(conn, &entry->protoinfo);
+}
+}
+
+int
+conntrack_dump_start(struct conntrack *ct, struct conntrack_dump *dump,
+ const uint16_t *pzone)
+{
+memset(dump, 0, sizeof(*dump));
+if (pzone) {
+dump->zone = *pzone;
+dump->filter_z

Re: [ovs-dev] [PATCH v2 08/15] conntrack: Implement dumping to ct_entry.

2016-04-19 Thread Joe Stringer
On 15 April 2016 at 17:02, Daniele Di Proietto  wrote:
> Signed-off-by: Daniele Di Proietto 



> +static void
> +conn_key_to_tuple(const struct conn_key *key, struct ct_dpif_tuple *tuple)
> +{
> +if (key->dl_type == htons(ETH_TYPE_IP)) {
> +tuple->l3_type = AF_INET;
> +} else if (key->dl_type == htons(ETH_TYPE_IPV6)) {
> +tuple->l3_type = AF_INET6;
> +}
> +tuple->ip_proto = key->nw_proto;
> +ct_endpoint_to_ct_dpif_inet_addr(&key->src.addr, &tuple->src,
> + key->dl_type);
> +ct_endpoint_to_ct_dpif_inet_addr(&key->dst.addr, &tuple->dst,
> + key->dl_type);
> +
> +if (key->nw_proto == IPPROTO_ICMP) {
> +tuple->icmp_id = key->src.port;
> +/* ICMP type and code are not tracked */
> +tuple->icmp_type = 0;
> +tuple->icmp_code = 0;
> +} else {
> +tuple->src_port = key->src.port;
> +tuple->dst_port = key->dst.port;
> +}

I think in the Linux implementation, the original ICMP message's icmp
type/code are stored/provided here. Might be a behaviour parity
question.

> +}
> +
> +static void
> +conn_to_ct_dpif_entry(const struct conn *conn, struct ct_dpif_entry *entry,
> +  long long now)
> +{
> +struct ct_l4_proto *class;
> +long long expiration;
> +memset(entry, 0, sizeof *entry);
> +conn_key_to_tuple(&conn->key, &entry->tuple_orig);
> +conn_key_to_tuple(&conn->rev_key, &entry->tuple_reply);
> +
> +entry->zone = conn->key.zone;
> +entry->mark = conn->mark;
> +
> +memcpy(&entry->labels, &conn->label, sizeof(entry->labels));
> +/* Not implemented yet */
> +entry->timestamp.start = 0;
> +entry->timestamp.stop = 0;

Is it better to reflect that timestamps are unsupported up to the user
or simply report 0 when it's unsupported? (I don't have a particular
preference, just asking the question)
___
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev


Re: [ovs-dev] [PATCH v2 08/15] conntrack: Implement dumping to ct_entry.

2016-04-26 Thread Flavio Leitner
On Fri, Apr 15, 2016 at 05:02:40PM -0700, Daniele Di Proietto wrote:
> Signed-off-by: Daniele Di Proietto 
> ---

Acked-by: Flavio Leitner 


___
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev


Re: [ovs-dev] [PATCH v2 08/15] conntrack: Implement dumping to ct_entry.

2016-04-26 Thread Daniele Di Proietto





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

>On 15 April 2016 at 17:02, Daniele Di Proietto  wrote:
>> Signed-off-by: Daniele Di Proietto 
>
>
>
>> +static void
>> +conn_key_to_tuple(const struct conn_key *key, struct ct_dpif_tuple *tuple)
>> +{
>> +if (key->dl_type == htons(ETH_TYPE_IP)) {
>> +tuple->l3_type = AF_INET;
>> +} else if (key->dl_type == htons(ETH_TYPE_IPV6)) {
>> +tuple->l3_type = AF_INET6;
>> +}
>> +tuple->ip_proto = key->nw_proto;
>> +ct_endpoint_to_ct_dpif_inet_addr(&key->src.addr, &tuple->src,
>> + key->dl_type);
>> +ct_endpoint_to_ct_dpif_inet_addr(&key->dst.addr, &tuple->dst,
>> + key->dl_type);
>> +
>> +if (key->nw_proto == IPPROTO_ICMP) {
>> +tuple->icmp_id = key->src.port;
>> +/* ICMP type and code are not tracked */
>> +tuple->icmp_type = 0;
>> +tuple->icmp_code = 0;
>> +} else {
>> +tuple->src_port = key->src.port;
>> +tuple->dst_port = key->dst.port;
>> +}
>
>I think in the Linux implementation, the original ICMP message's icmp
>type/code are stored/provided here. Might be a behaviour parity
>question.

Yes, but they're not part of the key.  I guess they could be tracked separately
with a conntrack-icmp module.

>
>> +}
>> +
>> +static void
>> +conn_to_ct_dpif_entry(const struct conn *conn, struct ct_dpif_entry *entry,
>> +  long long now)
>> +{
>> +struct ct_l4_proto *class;
>> +long long expiration;
>> +memset(entry, 0, sizeof *entry);
>> +conn_key_to_tuple(&conn->key, &entry->tuple_orig);
>> +conn_key_to_tuple(&conn->rev_key, &entry->tuple_reply);
>> +
>> +entry->zone = conn->key.zone;
>> +entry->mark = conn->mark;
>> +
>> +memcpy(&entry->labels, &conn->label, sizeof(entry->labels));
>> +/* Not implemented yet */
>> +entry->timestamp.start = 0;
>> +entry->timestamp.stop = 0;
>
>Is it better to reflect that timestamps are unsupported up to the user
>or simply report 0 when it's unsupported? (I don't have a particular
>preference, just asking the question)

I was leaning towards setting them to 0.  It is a special value which
will not be printed in ct_dpif_format_timestamp().
___
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev