159509ec1SZhang Chen /* 259509ec1SZhang Chen * COarse-grain LOck-stepping Virtual Machines for Non-stop Service (COLO) 359509ec1SZhang Chen * (a.k.a. Fault Tolerance or Continuous Replication) 459509ec1SZhang Chen * 559509ec1SZhang Chen * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD. 659509ec1SZhang Chen * Copyright (c) 2016 FUJITSU LIMITED 759509ec1SZhang Chen * Copyright (c) 2016 Intel Corporation 859509ec1SZhang Chen * 959509ec1SZhang Chen * Author: Zhang Chen <zhangchen.fnst@cn.fujitsu.com> 1059509ec1SZhang Chen * 1159509ec1SZhang Chen * This work is licensed under the terms of the GNU GPL, version 2 or 1259509ec1SZhang Chen * later. See the COPYING file in the top-level directory. 1359509ec1SZhang Chen */ 1459509ec1SZhang Chen 1558ea30f5SMarkus Armbruster #ifndef NET_COLO_H 1658ea30f5SMarkus Armbruster #define NET_COLO_H 1759509ec1SZhang Chen 18ccf0426cSZhang Chen #include "qemu/jhash.h" 190682e15bSZhang Chen #include "qemu/timer.h" 20e05ae1d9SMarc-André Lureau #include "net/eth.h" 2159509ec1SZhang Chen 2259509ec1SZhang Chen #define HASHTABLE_MAX_SIZE 16384 2359509ec1SZhang Chen 24b6540d40SZhang Chen #ifndef IPPROTO_DCCP 25b6540d40SZhang Chen #define IPPROTO_DCCP 33 26b6540d40SZhang Chen #endif 27b6540d40SZhang Chen 28b6540d40SZhang Chen #ifndef IPPROTO_SCTP 29b6540d40SZhang Chen #define IPPROTO_SCTP 132 30b6540d40SZhang Chen #endif 31b6540d40SZhang Chen 32b6540d40SZhang Chen #ifndef IPPROTO_UDPLITE 33b6540d40SZhang Chen #define IPPROTO_UDPLITE 136 34b6540d40SZhang Chen #endif 35b6540d40SZhang Chen 3659509ec1SZhang Chen typedef struct Packet { 3759509ec1SZhang Chen void *data; 3859509ec1SZhang Chen union { 3959509ec1SZhang Chen uint8_t *network_header; 4059509ec1SZhang Chen struct ip *ip; 4159509ec1SZhang Chen }; 4259509ec1SZhang Chen uint8_t *transport_header; 4359509ec1SZhang Chen int size; 440682e15bSZhang Chen /* Time of packet creation, in wall clock ms */ 450682e15bSZhang Chen int64_t creation_ms; 46ada1a33fSZhang Chen /* Get vnet_hdr_len from filter */ 47ada1a33fSZhang Chen uint32_t vnet_hdr_len; 48f449c9e5SMao Zhongyi uint32_t tcp_seq; /* sequence number */ 49f449c9e5SMao Zhongyi uint32_t tcp_ack; /* acknowledgement number */ 50f449c9e5SMao Zhongyi /* the sequence number of the last byte of the packet */ 51f449c9e5SMao Zhongyi uint32_t seq_end; 52f449c9e5SMao Zhongyi uint8_t header_size; /* the header length */ 53f449c9e5SMao Zhongyi uint16_t payload_size; /* the payload length */ 54f449c9e5SMao Zhongyi /* record the payload offset(the length that has been compared) */ 55f449c9e5SMao Zhongyi uint16_t offset; 56f449c9e5SMao Zhongyi uint8_t flags; /* Flags(aka Control bits) */ 5759509ec1SZhang Chen } Packet; 5859509ec1SZhang Chen 59b6540d40SZhang Chen typedef struct ConnectionKey { 60b6540d40SZhang Chen /* (src, dst) must be grouped, in the same way than in IP header */ 61b6540d40SZhang Chen struct in_addr src; 62b6540d40SZhang Chen struct in_addr dst; 63b6540d40SZhang Chen uint16_t src_port; 64b6540d40SZhang Chen uint16_t dst_port; 65b6540d40SZhang Chen uint8_t ip_proto; 66b6540d40SZhang Chen } QEMU_PACKED ConnectionKey; 67b6540d40SZhang Chen 68b6540d40SZhang Chen typedef struct Connection { 69b6540d40SZhang Chen /* connection primary send queue: element type: Packet */ 70b6540d40SZhang Chen GQueue primary_list; 71b6540d40SZhang Chen /* connection secondary send queue: element type: Packet */ 72b6540d40SZhang Chen GQueue secondary_list; 73b6540d40SZhang Chen /* flag to enqueue unprocessed_connections */ 74b6540d40SZhang Chen bool processing; 75b6540d40SZhang Chen uint8_t ip_proto; 76f449c9e5SMao Zhongyi /* record the sequence number that has been compared */ 77f449c9e5SMao Zhongyi uint32_t compare_seq; 78f449c9e5SMao Zhongyi /* the maximum of acknowledgement number in primary_list queue */ 79f449c9e5SMao Zhongyi uint32_t pack; 80f449c9e5SMao Zhongyi /* the maximum of acknowledgement number in secondary_list queue */ 81f449c9e5SMao Zhongyi uint32_t sack; 8230656b09SZhang Chen /* offset = secondary_seq - primary_seq */ 83e05ae1d9SMarc-André Lureau uint32_t offset; 846214231aSZhang Chen 856214231aSZhang Chen int tcp_state; /* TCP FSM state */ 86e05ae1d9SMarc-André Lureau uint32_t fin_ack_seq; /* the seq of 'fin=1,ack=1' */ 87b6540d40SZhang Chen } Connection; 88b6540d40SZhang Chen 89b6540d40SZhang Chen uint32_t connection_key_hash(const void *opaque); 90b6540d40SZhang Chen int connection_key_equal(const void *opaque1, const void *opaque2); 9159509ec1SZhang Chen int parse_packet_early(Packet *pkt); 92*64153ca6SRao, Lei void extract_ip_and_port(uint32_t tmp_ports, ConnectionKey *key, 93*64153ca6SRao, Lei Packet *pkt, bool reverse); 94*64153ca6SRao, Lei void fill_connection_key(Packet *pkt, ConnectionKey *key, bool reverse); 95b6540d40SZhang Chen Connection *connection_new(ConnectionKey *key); 96b6540d40SZhang Chen void connection_destroy(void *opaque); 97b6540d40SZhang Chen Connection *connection_get(GHashTable *connection_track_table, 98b6540d40SZhang Chen ConnectionKey *key, 99b6540d40SZhang Chen GQueue *conn_list); 10024525e93SZhang Chen bool connection_has_tracked(GHashTable *connection_track_table, 10124525e93SZhang Chen ConnectionKey *key); 10259509ec1SZhang Chen void connection_hashtable_reset(GHashTable *connection_track_table); 103ada1a33fSZhang Chen Packet *packet_new(const void *data, int size, int vnet_hdr_len); 1049b492719SRao, Lei Packet *packet_new_nocopy(void *data, int size, int vnet_hdr_len); 10559509ec1SZhang Chen void packet_destroy(void *opaque, void *user_data); 1069c55fe94SLukas Straub void packet_destroy_partial(void *opaque, void *user_data); 10759509ec1SZhang Chen 10858ea30f5SMarkus Armbruster #endif /* NET_COLO_H */ 109