[ovs-dev] [PATCH v2 08/15] conntrack: Implement dumping to ct_entry.
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.
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.
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.
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