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" 21*3772cf0dSZhang Chen #include "standard-headers/linux/virtio_net.h" 2259509ec1SZhang Chen 2359509ec1SZhang Chen #define HASHTABLE_MAX_SIZE 16384 2459509ec1SZhang Chen 25b6540d40SZhang Chen #ifndef IPPROTO_DCCP 26b6540d40SZhang Chen #define IPPROTO_DCCP 33 27b6540d40SZhang Chen #endif 28b6540d40SZhang Chen 29b6540d40SZhang Chen #ifndef IPPROTO_SCTP 30b6540d40SZhang Chen #define IPPROTO_SCTP 132 31b6540d40SZhang Chen #endif 32b6540d40SZhang Chen 33b6540d40SZhang Chen #ifndef IPPROTO_UDPLITE 34b6540d40SZhang Chen #define IPPROTO_UDPLITE 136 35b6540d40SZhang Chen #endif 36b6540d40SZhang Chen 3759509ec1SZhang Chen typedef struct Packet { 3859509ec1SZhang Chen void *data; 3959509ec1SZhang Chen union { 4059509ec1SZhang Chen uint8_t *network_header; 4159509ec1SZhang Chen struct ip *ip; 4259509ec1SZhang Chen }; 4359509ec1SZhang Chen uint8_t *transport_header; 4459509ec1SZhang Chen int size; 450682e15bSZhang Chen /* Time of packet creation, in wall clock ms */ 460682e15bSZhang Chen int64_t creation_ms; 47ada1a33fSZhang Chen /* Get vnet_hdr_len from filter */ 48ada1a33fSZhang Chen uint32_t vnet_hdr_len; 49f449c9e5SMao Zhongyi uint32_t tcp_seq; /* sequence number */ 50f449c9e5SMao Zhongyi uint32_t tcp_ack; /* acknowledgement number */ 51f449c9e5SMao Zhongyi /* the sequence number of the last byte of the packet */ 52f449c9e5SMao Zhongyi uint32_t seq_end; 53f449c9e5SMao Zhongyi uint8_t header_size; /* the header length */ 54f449c9e5SMao Zhongyi uint16_t payload_size; /* the payload length */ 55f449c9e5SMao Zhongyi /* record the payload offset(the length that has been compared) */ 56f449c9e5SMao Zhongyi uint16_t offset; 57f449c9e5SMao Zhongyi uint8_t flags; /* Flags(aka Control bits) */ 5859509ec1SZhang Chen } Packet; 5959509ec1SZhang Chen 60b6540d40SZhang Chen typedef struct ConnectionKey { 61b6540d40SZhang Chen /* (src, dst) must be grouped, in the same way than in IP header */ 62b6540d40SZhang Chen struct in_addr src; 63b6540d40SZhang Chen struct in_addr dst; 64b6540d40SZhang Chen uint16_t src_port; 65b6540d40SZhang Chen uint16_t dst_port; 66b6540d40SZhang Chen uint8_t ip_proto; 67b6540d40SZhang Chen } QEMU_PACKED ConnectionKey; 68b6540d40SZhang Chen 69b6540d40SZhang Chen typedef struct Connection { 70b6540d40SZhang Chen /* connection primary send queue: element type: Packet */ 71b6540d40SZhang Chen GQueue primary_list; 72b6540d40SZhang Chen /* connection secondary send queue: element type: Packet */ 73b6540d40SZhang Chen GQueue secondary_list; 74b6540d40SZhang Chen /* flag to enqueue unprocessed_connections */ 75b6540d40SZhang Chen bool processing; 76b6540d40SZhang Chen uint8_t ip_proto; 77f449c9e5SMao Zhongyi /* record the sequence number that has been compared */ 78f449c9e5SMao Zhongyi uint32_t compare_seq; 79f449c9e5SMao Zhongyi /* the maximum of acknowledgement number in primary_list queue */ 80f449c9e5SMao Zhongyi uint32_t pack; 81f449c9e5SMao Zhongyi /* the maximum of acknowledgement number in secondary_list queue */ 82f449c9e5SMao Zhongyi uint32_t sack; 8330656b09SZhang Chen /* offset = secondary_seq - primary_seq */ 84e05ae1d9SMarc-André Lureau uint32_t offset; 856214231aSZhang Chen 866214231aSZhang Chen int tcp_state; /* TCP FSM state */ 87e05ae1d9SMarc-André Lureau uint32_t fin_ack_seq; /* the seq of 'fin=1,ack=1' */ 88b6540d40SZhang Chen } Connection; 89b6540d40SZhang Chen 90b6540d40SZhang Chen uint32_t connection_key_hash(const void *opaque); 91b6540d40SZhang Chen int connection_key_equal(const void *opaque1, const void *opaque2); 9259509ec1SZhang Chen int parse_packet_early(Packet *pkt); 9364153ca6SRao, Lei void extract_ip_and_port(uint32_t tmp_ports, ConnectionKey *key, 9464153ca6SRao, Lei Packet *pkt, bool reverse); 9564153ca6SRao, Lei void fill_connection_key(Packet *pkt, ConnectionKey *key, bool reverse); 96b6540d40SZhang Chen Connection *connection_new(ConnectionKey *key); 97b6540d40SZhang Chen void connection_destroy(void *opaque); 98b6540d40SZhang Chen Connection *connection_get(GHashTable *connection_track_table, 99b6540d40SZhang Chen ConnectionKey *key, 100b6540d40SZhang Chen GQueue *conn_list); 10124525e93SZhang Chen bool connection_has_tracked(GHashTable *connection_track_table, 10224525e93SZhang Chen ConnectionKey *key); 10359509ec1SZhang Chen void connection_hashtable_reset(GHashTable *connection_track_table); 104ada1a33fSZhang Chen Packet *packet_new(const void *data, int size, int vnet_hdr_len); 1059b492719SRao, Lei Packet *packet_new_nocopy(void *data, int size, int vnet_hdr_len); 10659509ec1SZhang Chen void packet_destroy(void *opaque, void *user_data); 1079c55fe94SLukas Straub void packet_destroy_partial(void *opaque, void *user_data); 10859509ec1SZhang Chen 10958ea30f5SMarkus Armbruster #endif /* NET_COLO_H */ 110