Skip to content

Commit

Permalink
dpvs: Split all the members of dpvs connection into two groups for its
Browse files Browse the repository at this point in the history
initialization for the benefit of CPS.

- Remove the operation of bezeroing all the members of dpvs connection within
  dp_vs_conn_alloc().
- Each member of dpvs connection is initialized ONCE via dp_vs_conn_pre_init()
  or dp_vs_conn_new().
- dp_vs_conn_pre_init() initializes all the member of one group as 0, but
  ack_mbuf.
- dp_vs_conn_new() initializes all the members of the other group with the
  specific value.
  • Loading branch information
zhuangyan committed Aug 10, 2020
1 parent 22946ee commit e4afc47
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 66 deletions.
151 changes: 85 additions & 66 deletions include/ipvs/conn.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,27 +47,26 @@ enum {
};

struct dp_vs_conn_param {
int af;
uint16_t proto;
const union inet_addr *caddr;
const union inet_addr *vaddr;
uint16_t cport;
uint16_t vport;
uint16_t ct_dport; /* RS port for template connection */
bool outwall;
uint8_t af;
bool outwall;
uint16_t proto;
uint16_t cport;
uint16_t vport;
const union inet_addr *caddr;
const union inet_addr *vaddr;
uint16_t ct_dport; /* RS port for template connection */
};

struct conn_tuple_hash {
struct list_head list;
int direct; /* inbound/outbound */

/* tuple info */
int af;
uint16_t proto;
union inet_addr saddr; /* pkt's source addr */
union inet_addr daddr; /* pkt's dest addr */
uint8_t af;
uint8_t proto;
uint8_t direct; /* inbound/outbound */
uint8_t padding;
uint16_t sport;
uint16_t dport;
union inet_addr saddr; /* pkt's source addr */
union inet_addr daddr; /* pkt's dest addr */
} __rte_cache_aligned;

struct dp_vs_conn_stats {
Expand All @@ -80,85 +79,105 @@ struct dp_vs_conn_stats {
struct dp_vs_fdir_filt;
struct dp_vs_proto;

/*
* All the members of dp_vs_conn are classified into two groups, A and B to
* which a new member must be added.
*
* Additionally, we need to ensure dp_vs_conn is of 8 bytes alignment.
*/
struct dp_vs_conn {
int af;
/*
* Group A: the below members are initialized in dp_vs_conn_new().
*/
struct conn_tuple_hash tuplehash[DPVS_CONN_DIR_MAX];

uint8_t af;
uint8_t proto;
union inet_addr caddr; /* Client address */
union inet_addr vaddr; /* Virtual address */
union inet_addr laddr; /* director Local address */
union inet_addr daddr; /* Destination (RS) address */
lcoreid_t lcore;
bool outwall; /* flag for gfwip */

uint16_t cport;
uint16_t vport;
uint16_t lport;
uint16_t dport;

struct rte_mempool *connpool;
struct conn_tuple_hash tuplehash[DPVS_CONN_DIR_MAX];
union inet_addr caddr; /* Client address */
union inet_addr vaddr; /* Virtual address */
union inet_addr laddr; /* director Local address */
union inet_addr daddr; /* Destination (RS) address */

rte_atomic32_t refcnt;
struct dpvs_timer timer;
struct timeval timeout;
lcoreid_t lcore;
struct dp_vs_dest *dest; /* real server */
void *prot_data; /* protocol specific data */
volatile uint16_t flags;
struct dp_vs_dest *dest; /* real server */

int (*packet_xmit)(struct dp_vs_proto *prot,
struct dp_vs_conn *conn, struct rte_mbuf *mbuf);
int (*packet_out_xmit)(struct dp_vs_proto *prot,
struct dp_vs_conn *conn, struct rte_mbuf *mbuf);

/* for FNAT */
struct dp_vs_laddr *local; /* local address */
struct dp_vs_seq fnat_seq;
struct dp_vs_laddr *local; /* local address */

/* save last SEQ/ACK from RS for RST when conn expire*/
uint32_t rs_end_seq;
uint32_t rs_end_ack;
struct timeval timeout;

int (*packet_xmit)(struct dp_vs_proto *prot,
struct dp_vs_conn *conn,
struct rte_mbuf *mbuf);
int (*packet_out_xmit)(struct dp_vs_proto *prot,
struct dp_vs_conn *conn,
struct rte_mbuf *mbuf);
#ifdef CONFIG_DPVS_IPVS_STATS_DEBUG
uint64_t ctime; /* create time */
#endif

/*
* Group B: the below members are initialized in dp_vs_conn_pre_init().
*/
/* L2 fast xmit */
struct ether_addr in_smac;
struct ether_addr in_dmac;
struct ether_addr out_smac;
struct ether_addr out_dmac;

/* route for neigbour */
struct netif_port *in_dev; /* inside to rs*/
struct netif_port *out_dev; /* outside to client*/
union inet_addr in_nexthop; /* to rs*/
union inet_addr out_nexthop; /* to client*/
struct netif_port *in_dev; /* inside to rs */
struct netif_port *out_dev; /* outside to client */
union inet_addr in_nexthop; /* to rs*/
union inet_addr out_nexthop; /* to client*/

/* statistics */
struct dp_vs_conn_stats stats;
/* for FNAT */
struct dp_vs_seq fnat_seq;

/* synproxy related members */
struct dp_vs_seq syn_proxy_seq; /* seq used in synproxy */
struct list_head ack_mbuf; /* ack mbuf saved in step2 */
uint32_t ack_num; /* ack mbuf number stored */
struct rte_mbuf *syn_mbuf; /* saved rs syn packet for retransmition */
rte_atomic32_t syn_retry_max; /* syn retransmition max packets */
struct dp_vs_seq syn_proxy_seq; /* seq used in synproxy */
struct list_head ack_mbuf; /* ack mbuf saved in step2 */
struct rte_mbuf *syn_mbuf; /* saved rs syn packet for
retransmition */
uint32_t ack_num; /* ack mbuf number stored */
rte_atomic32_t syn_retry_max; /* syn retransmition max packets */

/* save last SEQ/ACK from RS for RST when conn expire */
uint32_t rs_end_seq;
uint32_t rs_end_ack;

/* add for stopping ack storm */
uint32_t last_seq; /* seq of the last ack packet */
uint32_t last_ack_seq; /* ack seq of the last ack packet */
rte_atomic32_t dup_ack_cnt; /* count of repeated ack packets */
uint32_t last_seq; /* seq of the last ack packet */
uint32_t last_ack_seq; /* ack seq of the last ack packet */
rte_atomic32_t dup_ack_cnt; /* count of repeated ack packets */

/* flags and state transition */
volatile uint16_t flags;
volatile uint16_t state;
volatile uint16_t old_state; /* old state, to be used for state transition
triggered synchronization */
/* controll members */
struct dp_vs_conn *control; /* master who controlls me */
rte_atomic32_t n_control; /* number of connections controlled by me*/
uint64_t ctime; /* create time */

/* connection redirect in fnat/snat/nat modes */
struct dp_vs_redirect *redirect;
/* control members */
rte_atomic32_t n_control; /* number of connections controlled
by me */
struct dp_vs_conn *control; /* master who controlls me */

/* flag for gfwip */
bool outwall;
void *prot_data; /* protocol specific data */
struct dp_vs_conn_stats stats; /* statistics */
struct dpvs_timer timer;

/* state transition */
volatile uint16_t state;
volatile uint16_t old_state; /* used for state transition
triggered synchronization */

/*
* the below member is initialized in dp_vs_conn_alloc().
*/
struct rte_mempool *connpool;
struct dp_vs_redirect *redirect; /* used in fnat/snat/nat modes */
} __rte_cache_aligned;

/* for syn-proxy to save all ack packet in conn before rs's syn-ack arrives */
Expand Down
14 changes: 14 additions & 0 deletions src/ipvs/ip_vs_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,18 @@ static void conn_flush(void)
#endif
}

static inline void dp_vs_conn_pre_init(struct dp_vs_conn *new)
{
size_t len;

len = offsetof(struct dp_vs_conn, connpool)
- offsetof(struct dp_vs_conn, in_smac);

memset(&new->in_smac, 0, len);

INIT_LIST_HEAD(&new->ack_mbuf);
}

struct dp_vs_conn *dp_vs_conn_new(struct rte_mbuf *mbuf,
const struct dp_vs_iphdr *iph,
struct dp_vs_conn_param *param,
Expand All @@ -801,6 +813,8 @@ struct dp_vs_conn *dp_vs_conn_new(struct rte_mbuf *mbuf,
if (unlikely(!new))
return NULL;

dp_vs_conn_pre_init(new);

new->flags = flags;

/* set proper RS port */
Expand Down

0 comments on commit e4afc47

Please sign in to comment.