diff mbox

[V11,8/9] filter-rewriter: track connection and parse packet

Message ID 1469700748-19754-9-git-send-email-zhangchen.fnst@cn.fujitsu.com
State New
Headers show

Commit Message

Zhang Chen July 28, 2016, 10:12 a.m. UTC
We use colo-base.h to track connection and parse packet

Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
---
 net/colo-base.c       | 14 ++++++++++++++
 net/colo-base.h       |  1 +
 net/filter-rewriter.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 65 insertions(+)

Comments

Jason Wang Aug. 2, 2016, 8:23 a.m. UTC | #1
On 2016年07月28日 18:12, Zhang Chen wrote:
> We use colo-base.h to track connection and parse packet
>
> Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
> Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
> Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
> ---
>   net/colo-base.c       | 14 ++++++++++++++
>   net/colo-base.h       |  1 +
>   net/filter-rewriter.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
>   3 files changed, 65 insertions(+)
>
> diff --git a/net/colo-base.c b/net/colo-base.c
> index eb1b631..20797b5 100644
> --- a/net/colo-base.c
> +++ b/net/colo-base.c
> @@ -103,6 +103,20 @@ void fill_connection_key(Packet *pkt, ConnectionKey *key)
>       }
>   }
>   
> +void reverse_connection_key(ConnectionKey *key)
> +{
> +    struct in_addr tmp_ip;
> +    uint16_t tmp_port;
> +
> +    tmp_ip = key->src;
> +    key->src = key->dst;
> +    key->dst = tmp_ip;
> +
> +    tmp_port = key->src_port;
> +    key->src_port = key->dst_port;
> +    key->dst_port = tmp_port;
> +}
> +
>   Connection *connection_new(ConnectionKey *key)
>   {
>       Connection *conn = g_slice_new(Connection);
> diff --git a/net/colo-base.h b/net/colo-base.h
> index 860a148..8d402a3 100644
> --- a/net/colo-base.h
> +++ b/net/colo-base.h
> @@ -56,6 +56,7 @@ uint32_t connection_key_hash(const void *opaque);
>   int connection_key_equal(const void *opaque1, const void *opaque2);
>   int parse_packet_early(Packet *pkt);
>   void fill_connection_key(Packet *pkt, ConnectionKey *key);
> +void reverse_connection_key(ConnectionKey *key);
>   Connection *connection_new(ConnectionKey *key);
>   void connection_destroy(void *opaque);
>   Connection *connection_get(GHashTable *connection_track_table,
> diff --git a/net/filter-rewriter.c b/net/filter-rewriter.c
> index 3a39f52..6350080 100644
> --- a/net/filter-rewriter.c
> +++ b/net/filter-rewriter.c
> @@ -51,6 +51,20 @@ static void filter_rewriter_flush(NetFilterState *nf)
>       }
>   }
>   
> +/*
> + * Return 1 on success, if return 0 means the pkt
> + * is not TCP packet
> + */
> +static int is_tcp_packet(Packet *pkt)
> +{
> +    if (!parse_packet_early(pkt) &&
> +        pkt->ip->ip_p == IPPROTO_TCP) {
> +        return 1;
> +    } else {
> +        return 0;
> +    }
> +}
> +
>   static ssize_t colo_rewriter_receive_iov(NetFilterState *nf,
>                                            NetClientState *sender,
>                                            unsigned flags,
> @@ -58,11 +72,47 @@ static ssize_t colo_rewriter_receive_iov(NetFilterState *nf,
>                                            int iovcnt,
>                                            NetPacketSent *sent_cb)
>   {
> +    RewriterState *s = FILTER_COLO_REWRITER(nf);
> +    Connection *conn;
> +    ConnectionKey key = {{ 0 } };
> +    Packet *pkt;
> +    ssize_t size = iov_size(iov, iovcnt);
> +    char *buf = g_malloc0(size);
> +
> +    iov_to_buf(iov, iovcnt, 0, buf, size);
> +    pkt = packet_new(buf, size);
> +
>       /*
>        * if we get tcp packet
>        * we will rewrite it to make secondary guest's
>        * connection established successfully
>        */
> +    if (is_tcp_packet(pkt)) {
> +
> +        fill_connection_key(pkt, &key);
> +
> +        if (sender == nf->netdev) {
> +            /*
> +             * We need make tcp TX and RX packet
> +             * into one connection.
> +             */
> +            reverse_connection_key(&key);

Why not simply do the comparing and swap in fill_connection_key()?

> +        }
> +        conn = connection_get(s->connection_track_table,
> +                              &key,
> +                              &s->hashtable_size);
> +
> +        if (sender == nf->netdev) {
> +            /* NET_FILTER_DIRECTION_TX */
> +            /* handle_primary_tcp_pkt */
> +        } else {
> +            /* NET_FILTER_DIRECTION_RX */
> +            /* handle_secondary_tcp_pkt */
> +        }
> +    }
> +
> +    packet_destroy(pkt, NULL);
> +    pkt = NULL;
>       return 0;
>   }
>
Zhang Chen Aug. 2, 2016, 10:38 a.m. UTC | #2
On 08/02/2016 04:23 PM, Jason Wang wrote:
>
>
> On 2016年07月28日 18:12, Zhang Chen wrote:
>> We use colo-base.h to track connection and parse packet
>>
>> Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
>> Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
>> Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
>> ---
>>   net/colo-base.c       | 14 ++++++++++++++
>>   net/colo-base.h       |  1 +
>>   net/filter-rewriter.c | 50 
>> ++++++++++++++++++++++++++++++++++++++++++++++++++
>>   3 files changed, 65 insertions(+)
>>
>> diff --git a/net/colo-base.c b/net/colo-base.c
>> index eb1b631..20797b5 100644
>> --- a/net/colo-base.c
>> +++ b/net/colo-base.c
>> @@ -103,6 +103,20 @@ void fill_connection_key(Packet *pkt, 
>> ConnectionKey *key)
>>       }
>>   }
>>   +void reverse_connection_key(ConnectionKey *key)
>> +{
>> +    struct in_addr tmp_ip;
>> +    uint16_t tmp_port;
>> +
>> +    tmp_ip = key->src;
>> +    key->src = key->dst;
>> +    key->dst = tmp_ip;
>> +
>> +    tmp_port = key->src_port;
>> +    key->src_port = key->dst_port;
>> +    key->dst_port = tmp_port;
>> +}
>> +
>>   Connection *connection_new(ConnectionKey *key)
>>   {
>>       Connection *conn = g_slice_new(Connection);
>> diff --git a/net/colo-base.h b/net/colo-base.h
>> index 860a148..8d402a3 100644
>> --- a/net/colo-base.h
>> +++ b/net/colo-base.h
>> @@ -56,6 +56,7 @@ uint32_t connection_key_hash(const void *opaque);
>>   int connection_key_equal(const void *opaque1, const void *opaque2);
>>   int parse_packet_early(Packet *pkt);
>>   void fill_connection_key(Packet *pkt, ConnectionKey *key);
>> +void reverse_connection_key(ConnectionKey *key);
>>   Connection *connection_new(ConnectionKey *key);
>>   void connection_destroy(void *opaque);
>>   Connection *connection_get(GHashTable *connection_track_table,
>> diff --git a/net/filter-rewriter.c b/net/filter-rewriter.c
>> index 3a39f52..6350080 100644
>> --- a/net/filter-rewriter.c
>> +++ b/net/filter-rewriter.c
>> @@ -51,6 +51,20 @@ static void filter_rewriter_flush(NetFilterState *nf)
>>       }
>>   }
>>   +/*
>> + * Return 1 on success, if return 0 means the pkt
>> + * is not TCP packet
>> + */
>> +static int is_tcp_packet(Packet *pkt)
>> +{
>> +    if (!parse_packet_early(pkt) &&
>> +        pkt->ip->ip_p == IPPROTO_TCP) {
>> +        return 1;
>> +    } else {
>> +        return 0;
>> +    }
>> +}
>> +
>>   static ssize_t colo_rewriter_receive_iov(NetFilterState *nf,
>>                                            NetClientState *sender,
>>                                            unsigned flags,
>> @@ -58,11 +72,47 @@ static ssize_t 
>> colo_rewriter_receive_iov(NetFilterState *nf,
>>                                            int iovcnt,
>>                                            NetPacketSent *sent_cb)
>>   {
>> +    RewriterState *s = FILTER_COLO_REWRITER(nf);
>> +    Connection *conn;
>> +    ConnectionKey key = {{ 0 } };
>> +    Packet *pkt;
>> +    ssize_t size = iov_size(iov, iovcnt);
>> +    char *buf = g_malloc0(size);
>> +
>> +    iov_to_buf(iov, iovcnt, 0, buf, size);
>> +    pkt = packet_new(buf, size);
>> +
>>       /*
>>        * if we get tcp packet
>>        * we will rewrite it to make secondary guest's
>>        * connection established successfully
>>        */
>> +    if (is_tcp_packet(pkt)) {
>> +
>> +        fill_connection_key(pkt, &key);
>> +
>> +        if (sender == nf->netdev) {
>> +            /*
>> +             * We need make tcp TX and RX packet
>> +             * into one connection.
>> +             */
>> +            reverse_connection_key(&key);
>
> Why not simply do the comparing and swap in fill_connection_key()?

Because we need use conn->offset in both TX and RX, so,we make
TX and RX packet in same connection.

Thanks
ZhangChen


>
>> +        }
>> +        conn = connection_get(s->connection_track_table,
>> +                              &key,
>> +                              &s->hashtable_size);
>> +
>> +        if (sender == nf->netdev) {
>> +            /* NET_FILTER_DIRECTION_TX */
>> +            /* handle_primary_tcp_pkt */
>> +        } else {
>> +            /* NET_FILTER_DIRECTION_RX */
>> +            /* handle_secondary_tcp_pkt */
>> +        }
>> +    }
>> +
>> +    packet_destroy(pkt, NULL);
>> +    pkt = NULL;
>>       return 0;
>>   }
>
>
>
> .
>
diff mbox

Patch

diff --git a/net/colo-base.c b/net/colo-base.c
index eb1b631..20797b5 100644
--- a/net/colo-base.c
+++ b/net/colo-base.c
@@ -103,6 +103,20 @@  void fill_connection_key(Packet *pkt, ConnectionKey *key)
     }
 }
 
+void reverse_connection_key(ConnectionKey *key)
+{
+    struct in_addr tmp_ip;
+    uint16_t tmp_port;
+
+    tmp_ip = key->src;
+    key->src = key->dst;
+    key->dst = tmp_ip;
+
+    tmp_port = key->src_port;
+    key->src_port = key->dst_port;
+    key->dst_port = tmp_port;
+}
+
 Connection *connection_new(ConnectionKey *key)
 {
     Connection *conn = g_slice_new(Connection);
diff --git a/net/colo-base.h b/net/colo-base.h
index 860a148..8d402a3 100644
--- a/net/colo-base.h
+++ b/net/colo-base.h
@@ -56,6 +56,7 @@  uint32_t connection_key_hash(const void *opaque);
 int connection_key_equal(const void *opaque1, const void *opaque2);
 int parse_packet_early(Packet *pkt);
 void fill_connection_key(Packet *pkt, ConnectionKey *key);
+void reverse_connection_key(ConnectionKey *key);
 Connection *connection_new(ConnectionKey *key);
 void connection_destroy(void *opaque);
 Connection *connection_get(GHashTable *connection_track_table,
diff --git a/net/filter-rewriter.c b/net/filter-rewriter.c
index 3a39f52..6350080 100644
--- a/net/filter-rewriter.c
+++ b/net/filter-rewriter.c
@@ -51,6 +51,20 @@  static void filter_rewriter_flush(NetFilterState *nf)
     }
 }
 
+/*
+ * Return 1 on success, if return 0 means the pkt
+ * is not TCP packet
+ */
+static int is_tcp_packet(Packet *pkt)
+{
+    if (!parse_packet_early(pkt) &&
+        pkt->ip->ip_p == IPPROTO_TCP) {
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
 static ssize_t colo_rewriter_receive_iov(NetFilterState *nf,
                                          NetClientState *sender,
                                          unsigned flags,
@@ -58,11 +72,47 @@  static ssize_t colo_rewriter_receive_iov(NetFilterState *nf,
                                          int iovcnt,
                                          NetPacketSent *sent_cb)
 {
+    RewriterState *s = FILTER_COLO_REWRITER(nf);
+    Connection *conn;
+    ConnectionKey key = {{ 0 } };
+    Packet *pkt;
+    ssize_t size = iov_size(iov, iovcnt);
+    char *buf = g_malloc0(size);
+
+    iov_to_buf(iov, iovcnt, 0, buf, size);
+    pkt = packet_new(buf, size);
+
     /*
      * if we get tcp packet
      * we will rewrite it to make secondary guest's
      * connection established successfully
      */
+    if (is_tcp_packet(pkt)) {
+
+        fill_connection_key(pkt, &key);
+
+        if (sender == nf->netdev) {
+            /*
+             * We need make tcp TX and RX packet
+             * into one connection.
+             */
+            reverse_connection_key(&key);
+        }
+        conn = connection_get(s->connection_track_table,
+                              &key,
+                              &s->hashtable_size);
+
+        if (sender == nf->netdev) {
+            /* NET_FILTER_DIRECTION_TX */
+            /* handle_primary_tcp_pkt */
+        } else {
+            /* NET_FILTER_DIRECTION_RX */
+            /* handle_secondary_tcp_pkt */
+        }
+    }
+
+    packet_destroy(pkt, NULL);
+    pkt = NULL;
     return 0;
 }