summaryrefslogtreecommitdiff
path: root/shaping/include/shaper.h
blob: 8aabc422d258f361b14abdf0c3475eb48cba0665 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
#pragma once
#include <sched.h>
#include <sys/queue.h>
#include <marsio.h>
#include "uthash.h"
#include "session_table.h"
#include "utils.h"
#include "shaper_stat.h"
#include "shaper_global_stat.h"
#include "shaper_aqm.h"
extern "C" {
#include "timeout.h"
}

#define SHAPING_RULE_NUM_MAX 8
#define SHAPING_REF_PROFILE_NUM_MAX 8
#define SHAPING_PRIORITY_NUM_MAX 10
#define SHAPER_FLOW_POP_NUM_MAX 10

#define SESSION_CLOSE 0x1

#define CONFIRM_PRIORITY_PKTS 20

#define SHAPING_WROK_THREAD_NUM_MAX 256

#define SHAPING_STAT_REFRESH_INTERVAL_SEC 2
#define SHAPING_STAT_REFRESH_MAX_PER_POLLING 5

#define NANO_SECONDS_PER_MICRO_SEC 1000
#define MICRO_SECONDS_PER_SEC 1000000
#define NANO_SECONDS_PER_SEC 1000000000

#define NANO_SECONDS_PER_MILLI_SEC 1000000
#define MILLI_SECONDS_PER_SEC 1000

#define SHAPING_GLOBAL_CONF_FILE "./conf/shaping.conf"

struct shaping_system_conf {
    unsigned int session_queue_len_max;
    unsigned int priority_queue_len_max;
    unsigned int pkt_max_delay_time_us;
    int token_multiple_min;
    int token_multiple_max;
    int polling_node_num_max[SHAPING_PRIORITY_NUM_MAX];
    int work_thread_num;
    int cpu_affinity_enable;
    int firewall_sid;
    cpu_set_t cpu_affinity_mask;
    int check_rule_enable_interval_sec;
};

struct shaping_thread_ctx {
    pthread_t tid;
    int thread_index;
    struct shaping_global_stat_data thread_global_stat;
    struct shaping_ctx *ref_ctx;
    struct shaper *sp;
    struct shaping_stat *stat;
    struct shaping_marsio_info *marsio_info;
    struct swarmkv *swarmkv_db;//handle of swarmkv 
    struct shaping_maat_info *maat_info;
    struct session_table *session_table;
    struct timeouts *expires;
    time_t last_update_timeout_sec;
    int session_need_reset;
    struct shaping_system_conf conf;
};

struct shaping_ctx {
    int thread_num;
    struct swarmkv *swarmkv_db;//handle of swarmkv 
    struct shaping_maat_info *maat_info;
    struct shaping_marsio_info *marsio_info;
    struct shaping_stat *stat;
    struct shaping_global_stat *global_stat;
    struct shaping_thread_ctx *thread_ctx;
};

enum shaping_packet_dir {
    SHAPING_DIR_IN = 0,
    SHAPING_DIR_OUT,
    SHAPING_DIR_MAX
};

enum shaping_packet_action {
    SHAPING_FORWARD = 0,
    SHAPING_QUEUED,
    SHAPING_DROP
};

enum shaping_profile_type_in_rule {
    PROFILE_IN_RULE_TYPE_PRIMARY = 0,
    PROFILE_IN_RULE_TYPE_BORROW
};

enum shaping_profile_type {
    PROFILE_TYPE_GENERIC,
    PROFILE_TYPE_HOST_FARINESS,
    PROFILE_TYPE_MAX_MIN_HOST_FAIRNESS,
    PROFILE_TYPE_SPLIT_BY_LOCAL_HOST
};

enum shaping_profile_limit_direction {
    PROFILE_LIMIT_DIRECTION_BIDIRECTION,
    PROFILE_LIMIT_DIRECTION_INCOMING_OUTGOING,
};

struct shaper_token_multiple {
    int token_get_multiple;
    unsigned char token_not_enough;
    unsigned char has_failed_get_token;
    time_t token_multiple_update_time_s;
};

struct shaping_profile_hash_node {
    int id;
    enum shaper_aqm_type aqm_type;
    enum shaping_profile_limit_direction limit_direction;
    long long in_deposit_token_bits[SHAPING_PRIORITY_NUM_MAX];
    long long out_deposit_token_bits[SHAPING_PRIORITY_NUM_MAX];
    long long bidirection_deposit_token_bits[SHAPING_PRIORITY_NUM_MAX];
    long long last_failed_get_token_ms[SHAPING_DIR_MAX];
    long long last_hmget_ms;
    long long queue_len[SHAPING_PRIORITY_NUM_MAX];
    long long local_queue_len[SHAPING_PRIORITY_NUM_MAX];
    long long local_queue_len_update_time_us[SHAPING_PRIORITY_NUM_MAX];
    long long priority_blocked_time_ms[SHAPING_PRIORITY_NUM_MAX];
    int hmget_ref_cnt;
    int tconsume_ref_cnt;
    unsigned long long last_refresh_time_ms;
    struct shaper_token_multiple token_multiple;
    struct shaper_aqm_blue_para aqm_blue_para;
    struct shaper_aqm_codel_para aqm_codel_para;
    unsigned char is_invalid;
    unsigned char async_pass[SHAPING_PRIORITY_NUM_MAX][SHAPING_DIR_MAX];
    struct timeout timeout_handle;
    UT_hash_handle hh;
};

struct shaping_profile_info {
    int id;//profile_id
    enum shaping_profile_type type;
    int priority;
    unsigned char async_pass[SHAPING_DIR_MAX];
    long long in_deposit_token_bits;
    long long out_deposit_token_bits;
    long long bidirection_deposit_token_bits;
    long long last_failed_get_token_ms[SHAPING_DIR_MAX];
    unsigned long long enqueue_time_us;//to calculate max latency
    struct shaping_stat_for_profile stat;
    struct shaping_profile_hash_node *hash_node;
};

struct shaping_rule_info {
    int vsys_id;
    int id;//rule_id
    int fair_factor;
    struct shaping_profile_info primary;
    struct shaping_profile_info borrowing[SHAPING_REF_PROFILE_NUM_MAX - 1];
    int borrowing_num;
    int is_enabled;
};

struct shaping_packet_wrapper {
    void *pkt_buff;
    unsigned long long income_time_ns;
    unsigned long long enqueue_time_us;//first enqueue time
    unsigned int length;
    int rule_anchor;
    int aqm_processed_pf_ids[SHAPING_REF_PROFILE_NUM_MAX];
    unsigned char direction;
    TAILQ_ENTRY(shaping_packet_wrapper) node;
};
TAILQ_HEAD(delay_queue, shaping_packet_wrapper);

struct metadata
{
    uint64_t session_id;
    char *raw_data;
    int raw_len;
    int dir;
    int is_tcp_pure_ctrl;
    int is_ctrl_pkt;
    uint16_t l7_offset;       // only control packet set l7_offset
    struct sids sids;
    struct route_ctx route_ctx;
};

struct shaping_flow {
    char *src_ip_str;
    size_t src_ip_str_len;
    struct delay_queue packet_queue;
    int rule_num;
    struct shaping_rule_info matched_rule_infos[SHAPING_RULE_NUM_MAX];
    int priority;
    unsigned char dscp_enable;
    unsigned char dscp_value;
    struct addr_tuple4 tuple4;
    int anchor;//rule_idx
    int ref_cnt;
    unsigned int queue_len;
    unsigned int flag;
    struct metadata ctrl_meta;
    unsigned long long processed_pkts;
    unsigned long long stat_update_time_us;
    time_t check_rule_time;
};

struct shaper_flow_instance {
    struct shaping_flow *sf;
    int priority;
};

struct shaping_tconsume_cb_arg {
    struct shaping_thread_ctx *ctx;
    struct shaping_profile_info *profile;
    struct shaping_flow *sf;
    unsigned char direction;
    long long start_time_us;
};

struct shaping_hmget_cb_arg {
    struct shaping_thread_ctx *ctx;
    struct shaping_profile_hash_node *pf_hash_node;
    long long start_time_us;
};

struct shaping_hincrby_cb_arg {
    struct shaping_thread_ctx *ctx;
    long long start_time_us;
    long long queue_len;
    int profile_id;
    int priority;
    int retry_cnt;
};

struct shaper;//instance of shaping, thread unsafe

struct shaping_flow* shaping_flow_new(struct shaping_thread_ctx *ctx);
void shaping_flow_free(struct shaping_thread_ctx *ctx, struct shaping_flow *sf);
struct shaper* shaper_new(unsigned int priority_queue_len_max);
void shaper_free(struct shaper *sp);

bool shaper_queue_empty(struct shaping_flow *sf);
void shaper_packet_dequeue(struct shaping_flow *sf);
struct shaping_packet_wrapper* shaper_first_pkt_get(struct shaping_flow *sf);
void shaper_queue_clear(struct shaping_flow *sf, struct shaping_thread_ctx *ctx);

int shaper_flow_in_order_get(struct shaper *sp, struct shaper_flow_instance sf_ins[], int priority, int max_sf_num);
void shaper_profile_hash_node_set(struct shaping_thread_ctx *ctx, struct shaping_profile_info *profile);

int shaper_global_conf_init(struct shaping_system_conf *conf);

void shaper_packet_recv_and_process(struct shaping_thread_ctx *ctx);
void shaping_packet_process(struct shaping_thread_ctx *ctx, marsio_buff_t *rx_buff, struct metadata *meta, struct shaping_flow *sf);

struct shaping_ctx *shaping_engine_init();
void shaping_engine_destroy(struct shaping_ctx *ctx);
void shaper_thread_resource_clear();