-
Notifications
You must be signed in to change notification settings - Fork 4
/
serialize.h
216 lines (190 loc) · 5.29 KB
/
serialize.h
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
/*
* CCP Datapath Message Serialization
*
* Serializes and deserializes messages for communication with userspace CCP.
*/
#ifndef CCP_SERIALIZE_H
#define CCP_SERIALIZE_H
#include "types.h"
#include "ccp.h"
#ifdef __cplusplus
extern "C" {
#endif
struct __attribute__((packed, aligned(4))) CcpMsgHeader {
u16 Type;
u16 Len;
u32 SocketId;
};
/* return: sizeof(struct CcpMsgHeader) on success, -1 otherwise.
*/
int read_header(struct CcpMsgHeader *hdr, char *buf);
/* return: sizeof(struct CcpMsgHeader) on success, -1 otherwise.
*/
int serialize_header(char *buf, int bufsize, struct CcpMsgHeader *hdr);
/* There are 4 message types (Type field in header)
* CREATE and MEASURE are written from datapath to CCP
* PATTERN and INSTALL_FOLD are received in datapath from CCP
*
* Messages start with the header, then
* 1. fixed number of u32
* 2. fixed number of u64
* 3. bytes blob, flexible length
*/
#define CREATE 0
#define MEASURE 1
#define INSTALL_EXPR 2
#define UPDATE_FIELDS 3
#define CHANGE_PROG 4
#define READY 5
// Some messages contain strings.
#define BIGGEST_MSG_SIZE 32678
// create messages are fixed length: header + 4 * 6 + 32
#define CREATE_MSG_SIZE 96
// size of report msg is approx MAX_REPORT_REG * 8 + 4 + 4
#define REPORT_MSG_SIZE 900
// ready message is just a u32.
#define READY_MSG_SIZE 12
// Some messages contain serialized fold instructions.
#define MAX_EXPRESSIONS 256 // arbitrary TODO: make configurable
#define MAX_INSTRUCTIONS 256 // arbitrary, TODO: make configurable
#define MAX_IMPLICIT_REG 6 // fixed number of implicit registers
#define MAX_REPORT_REG 110 // measure msg 110 * 8 + 4 + 4
#define MAX_CONTROL_REG 110 // arbitrary
#define MAX_TMP_REG 8
#define MAX_LOCAL_REG 8
#define MAX_MUTABLE_REG 222 // # report + # control + cwnd, rate registers
struct __attribute__((packed, aligned(4))) ReadyMsg {
u32 id;
};
/* READY
* id: The unique id of this datapath.
*/
int write_ready_msg(
char *buf,
int bufsize,
u32 id
);
/* CREATE
* congAlg: the datapath's requested congestion control algorithm (could be overridden)
*/
struct __attribute__((packed, aligned(4))) CreateMsg {
u32 init_cwnd;
u32 mss;
u32 src_ip;
u32 src_port;
u32 dst_ip;
u32 dst_port;
char congAlg[MAX_CONG_ALG_SIZE];
};
/* Write cr: CreateMsg into buf with socketid sid.
* buf should be preallocated, and bufsize should be its size.
*/
int write_create_msg(
char *buf,
int bufsize,
u32 sid,
struct CreateMsg cr
);
/* MEASURE
* program_uid: unique id for the datapath program that generated this report,
* so that the ccp can use the corresponding scope
* num_fields: number of returned fields,
* bytes: the return registers of the installed fold function ([]uint64).
* there will be at most MAX_PERM_REG returned registers
*/
struct __attribute__((packed, aligned(4))) MeasureMsg {
u32 program_uid;
u32 num_fields;
u64 fields[MAX_REPORT_REG];
};
/* Write ms: MeasureMsg into buf with socketid sid.
* buf should be preallocated, and bufsize should be its size.
*/
int write_measure_msg(
char *buf,
int bufsize,
u32 sid,
u32 program_uid,
u64 *msg_fields,
u8 num_fields
);
/* INSTRUCTION
* 1 u8 for opcode
* 3 sets of {u8, u32} for each of the result register, left register and right register
*/
struct __attribute__((packed, aligned(4))) InstructionMsg {
u8 opcode;
u8 result_reg_type;
u32 result_register;
u8 left_reg_type;
u32 left_register;
u8 right_reg_type;
u32 right_register;
};
/* ExpressionMsg: 4 u32s
* start of expression condition instr ID
* number of expression condition instrs
* start of event body instr ID
* number of event body instrs
*/
struct __attribute__((packed, aligned(4))) ExpressionMsg {
u32 cond_start_idx;
u32 num_cond_instrs;
u32 event_start_idx;
u32 num_event_instrs;
};
struct __attribute__((packed, aligned(4))) InstallExpressionMsgHdr {
u32 program_uid;
u32 num_expressions;
u32 num_instructions;
};
/* return: size of InstallExpressionMsgHeader
* copies from buffer into InstallExpressionMsgHdr struct.
* also checks whether the number of instructions or expressions is too large.
* InstallExprMessage:
* {
* struct InstallExpressionMsgHeader (3 u32s)
* ExpressionMsg[num_expressions]
* InstructionMsg[num_instructions]
* }
*/
int read_install_expr_msg_hdr(
struct ccp_datapath *datapath,
struct CcpMsgHeader *hdr,
struct InstallExpressionMsgHdr *expr_msg_info,
char *buf
);
struct __attribute__((packed, aligned(1))) UpdateField {
u8 reg_type;
u32 reg_index;
u64 new_value;
};
/* Fills in number of updates.
* Check whether number of updates is too large.
* Returns size of update field header: 1 u32
* UpdateFieldsMsg:
* {
* 1 u32: num_updates
* UpdateField[num_updates]
* }
*/
int check_update_fields_msg(
struct ccp_datapath *datapath,
struct CcpMsgHeader *hdr,
u32 *num_updates,
char *buf
);
struct __attribute__((packed, aligned(1))) ChangeProgMsg {
u32 program_uid;
u32 num_updates;
};
int read_change_prog_msg(
struct ccp_datapath *datapath,
struct CcpMsgHeader *hdr,
struct ChangeProgMsg *change_prog,
char *buf
);
#ifdef __cplusplus
} // extern "C"
#endif
#endif