Implement flow cookies in user datapath.
This commit is contained in:
1 parent
d216ae2782
commit
1936cc1c68
5 files changed
+39
-19
No files matched your search
@@ -171,6 +171,7 @@ OFP_ASSERT(sizeof(struct nx_flow_end_config) == 20);
|
||||
struct nx_flow_end {
|
||||
struct nicira_header header;
|
||||
struct ofp_match match; /* Description of fields. */
|
||||
uint64_t cookie; /* Opaque controller-issued identifier. */
|
||||
|
||||
uint16_t priority; /* Priority level of flow entry. */
|
||||
uint8_t reason; /* One of NXFER_*. */
|
||||
@@ -189,6 +190,6 @@ struct nx_flow_end {
|
||||
uint64_t packet_count;
|
||||
uint64_t byte_count;
|
||||
};
|
||||
OFP_ASSERT(sizeof(struct nx_flow_end) == 104);
|
||||
OFP_ASSERT(sizeof(struct nx_flow_end) == 112);
|
||||
|
||||
#endif /* openflow/nicira-ext.h */
|
||||
+10
-7
@@ -749,8 +749,9 @@ ofp_print_flow_mod(struct ds *string, const void *oh, size_t len,
|
||||
default:
|
||||
ds_put_format(string, " cmd:%d ", ntohs(ofm->command));
|
||||
}
|
||||
ds_put_format(string, "idle:%d hard:%d pri:%d buf:%#x flg:%#x ",
|
||||
ntohs(ofm->idle_timeout), ntohs(ofm->hard_timeout),
|
||||
ds_put_format(string, "cookie:%"PRIu64" idle:%d hard:%d pri:%d buf:%#x flg:%#x ",
|
||||
ntohll(ofm->cookie), ntohs(ofm->idle_timeout),
|
||||
ntohs(ofm->hard_timeout),
|
||||
ofm->match.wildcards ? ntohs(ofm->priority) : (uint16_t)-1,
|
||||
ntohl(ofm->buffer_id), ntohs(ofm->flags));
|
||||
ofp_print_actions(string, ofm->actions,
|
||||
@@ -783,12 +784,13 @@ ofp_print_flow_removed(struct ds *string, const void *oh, size_t len UNUSED,
|
||||
break;
|
||||
}
|
||||
ds_put_format(string,
|
||||
" pri%"PRIu16" secs%"PRIu32" nsecs%"PRIu32" idle%"PRIu16"",
|
||||
" cookie%"PRIu64" pri%"PRIu16" secs%"PRIu32" nsecs%"PRIu32""
|
||||
" idle%"PRIu16" pkts%"PRIu64" bytes%"PRIu64"\n",
|
||||
ntohll(ofe->cookie),
|
||||
ofe->match.wildcards ? ntohs(ofe->priority) : (uint16_t)-1,
|
||||
ntohl(ofe->duration_sec), ntohl(ofe->duration_nsec),
|
||||
ntohs(ofe->idle_timeout));
|
||||
ds_put_format(string,
|
||||
" pkts%"PRIu64" bytes%"PRIu64"\n", ntohll(ofe->packet_count),
|
||||
ntohs(ofe->idle_timeout),
|
||||
ntohll(ofe->packet_count),
|
||||
ntohll(ofe->byte_count));
|
||||
}
|
||||
|
||||
@@ -991,7 +993,8 @@ ofp_flow_stats_reply(struct ds *string, const void *body_, size_t len,
|
||||
break;
|
||||
}
|
||||
|
||||
ds_put_format(string, " duration_sec=%"PRIu32"s, ",
|
||||
ds_put_format(string, " cookie=%"PRIu64", ", ntohll(fs->cookie));
|
||||
ds_put_format(string, "duration_sec=%"PRIu32"s, ",
|
||||
ntohl(fs->duration_sec));
|
||||
ds_put_format(string, "duration_nsec=%"PRIu32"s, ",
|
||||
ntohl(fs->duration_nsec));
|
||||
|
||||
@@ -762,6 +762,7 @@ dp_send_flow_end(struct datapath *dp, struct sw_flow *flow,
|
||||
|
||||
flow_fill_match(&ofr->match, &flow->key.flow, flow->key.wildcards);
|
||||
|
||||
ofr->cookie = htonll(flow->cookie);
|
||||
ofr->priority = htons(flow->priority);
|
||||
ofr->reason = reason;
|
||||
|
||||
@@ -815,6 +816,7 @@ fill_flow_stats(struct ofpbuf *buffer, struct sw_flow *flow,
|
||||
ofs->match.tp_dst = flow->key.flow.tp_dst;
|
||||
ofs->duration_sec = htonl(sec);
|
||||
ofs->duration_nsec = htonl((tdiff - (sec * 1000)) * 1000000);
|
||||
ofs->cookie = htonll(flow->cookie);
|
||||
ofs->priority = htons(flow->priority);
|
||||
ofs->idle_timeout = htons(flow->idle_timeout);
|
||||
ofs->hard_timeout = htons(flow->hard_timeout);
|
||||
@@ -1036,6 +1038,7 @@ add_flow(struct datapath *dp, const struct sender *sender,
|
||||
}
|
||||
|
||||
/* Fill out flow. */
|
||||
flow->cookie = ntohll(ofm->cookie);
|
||||
flow->idle_timeout = ntohs(ofm->idle_timeout);
|
||||
flow->hard_timeout = ntohs(ofm->hard_timeout);
|
||||
flow->send_flow_rem = (ntohs(ofm->flags) & OFPFF_SEND_FLOW_REM) ? 1 : 0;
|
||||
@@ -1110,6 +1113,7 @@ mod_flow(struct datapath *dp, const struct sender *sender,
|
||||
strict, ofm->actions, actions_len,
|
||||
(ntohs(ofm->flags) & OFPFF_EMERG) ? 1 : 0)) {
|
||||
/* Fill out flow. */
|
||||
flow->cookie = ntohll(ofm->cookie);
|
||||
flow->idle_timeout = ntohs(ofm->idle_timeout);
|
||||
flow->hard_timeout = ntohs(ofm->hard_timeout);
|
||||
flow->send_flow_rem = (ntohs(ofm->flags) & OFPFF_SEND_FLOW_REM) ? 1 : 0;
|
||||
|
||||
@@ -57,6 +57,7 @@ struct sw_flow_actions {
|
||||
struct sw_flow {
|
||||
struct sw_flow_key key;
|
||||
|
||||
uint64_t cookie; /* Opaque controller-issued identifier. */
|
||||
uint16_t priority; /* Only used on entries with wildcards. */
|
||||
uint16_t idle_timeout; /* Idle time before discarding (seconds). */
|
||||
uint16_t hard_timeout; /* Hard expiration time (seconds) */
|
||||
|
||||
+22
-11
@@ -938,7 +938,8 @@ parse_field(const char *name, const struct field **f_out)
|
||||
static void
|
||||
str_to_flow(char *string, struct ofp_match *match, struct ofpbuf *actions,
|
||||
uint8_t *table_idx, uint16_t *out_port, uint16_t *priority,
|
||||
uint16_t *idle_timeout, uint16_t *hard_timeout)
|
||||
uint16_t *idle_timeout, uint16_t *hard_timeout,
|
||||
uint64_t *cookie)
|
||||
{
|
||||
char *save_ptr = NULL;
|
||||
char *name;
|
||||
@@ -959,6 +960,9 @@ str_to_flow(char *string, struct ofp_match *match, struct ofpbuf *actions,
|
||||
if (hard_timeout) {
|
||||
*hard_timeout = OFP_FLOW_PERMANENT;
|
||||
}
|
||||
if (cookie) {
|
||||
*cookie = 0;
|
||||
}
|
||||
if (actions) {
|
||||
char *act_str = strstr(string, "actions");
|
||||
if (!act_str) {
|
||||
@@ -1007,6 +1011,8 @@ str_to_flow(char *string, struct ofp_match *match, struct ofpbuf *actions,
|
||||
*idle_timeout = atoi(value);
|
||||
} else if (hard_timeout && !strcmp(name, "hard_timeout")) {
|
||||
*hard_timeout = atoi(value);
|
||||
} else if (cookie && !strcmp(name, "cookie")) {
|
||||
*cookie = atoi(value);
|
||||
} else if (parse_field(name, &f)) {
|
||||
void *data = (char *) match + f->offset;
|
||||
if (!strcmp(value, "*") || !strcmp(value, "ANY")) {
|
||||
@@ -1042,7 +1048,7 @@ do_dump_flows(const struct settings *s UNUSED, int argc, char *argv[])
|
||||
|
||||
req = alloc_stats_request(sizeof *req, OFPST_FLOW, &request);
|
||||
str_to_flow(argc > 2 ? argv[2] : "", &req->match, NULL,
|
||||
&req->table_id, &out_port, NULL, NULL, NULL);
|
||||
&req->table_id, &out_port, NULL, NULL, NULL, NULL);
|
||||
memset(&req->pad, 0, sizeof req->pad);
|
||||
req->out_port = htons(out_port);
|
||||
|
||||
@@ -1058,7 +1064,7 @@ do_dump_aggregate(const struct settings *s UNUSED, int argc, char *argv[])
|
||||
|
||||
req = alloc_stats_request(sizeof *req, OFPST_AGGREGATE, &request);
|
||||
str_to_flow(argc > 2 ? argv[2] : "", &req->match, NULL,
|
||||
&req->table_id, &out_port, NULL, NULL, NULL);
|
||||
&req->table_id, &out_port, NULL, NULL, NULL, NULL);
|
||||
memset(&req->pad, 0, sizeof req->pad);
|
||||
req->out_port = htons(out_port);
|
||||
|
||||
@@ -1074,6 +1080,7 @@ do_add_flow(const struct settings *s UNUSED, int argc UNUSED, char *argv[])
|
||||
struct ofpbuf *buffer;
|
||||
struct ofp_flow_mod *ofm;
|
||||
uint16_t priority, idle_timeout, hard_timeout;
|
||||
uint64_t cookie;
|
||||
uint8_t table_id;
|
||||
struct ofp_match match;
|
||||
|
||||
@@ -1081,10 +1088,12 @@ do_add_flow(const struct settings *s UNUSED, int argc UNUSED, char *argv[])
|
||||
* 'buffer', so we can't keep pointers to across the str_to_flow() call. */
|
||||
make_openflow(sizeof *ofm, OFPT_FLOW_MOD, &buffer);
|
||||
str_to_flow(argv[2], &match, buffer,
|
||||
&table_id, NULL, &priority, &idle_timeout, &hard_timeout);
|
||||
&table_id, NULL, &priority, &idle_timeout, &hard_timeout,
|
||||
&cookie);
|
||||
ofm = buffer->data;
|
||||
ofm->match = match;
|
||||
ofm->command = htons(OFPFC_ADD);
|
||||
ofm->cookie = htonll(cookie);
|
||||
ofm->idle_timeout = table_id == EMERG_TABLE_ID ? 0 : htons(idle_timeout);
|
||||
ofm->hard_timeout = table_id == EMERG_TABLE_ID ? 0 : htons(hard_timeout);
|
||||
ofm->buffer_id = htonl(UINT32_MAX);
|
||||
@@ -1092,7 +1101,6 @@ do_add_flow(const struct settings *s UNUSED, int argc UNUSED, char *argv[])
|
||||
ofm->flags = htons(OFPFF_SEND_FLOW_REM);
|
||||
if (table_id == EMERG_TABLE_ID)
|
||||
ofm->flags |= htons(OFPFF_EMERG);
|
||||
ofm->reserved = htonl(0);
|
||||
|
||||
open_vconn(argv[1], &vconn);
|
||||
send_openflow_buffer(vconn, buffer);
|
||||
@@ -1116,6 +1124,7 @@ do_add_flows(const struct settings *s UNUSED, int argc UNUSED, char *argv[])
|
||||
struct ofpbuf *buffer;
|
||||
struct ofp_flow_mod *ofm;
|
||||
uint16_t priority, idle_timeout, hard_timeout;
|
||||
uint64_t cookie;
|
||||
uint8_t table_id;
|
||||
struct ofp_match match;
|
||||
|
||||
@@ -1137,10 +1146,12 @@ do_add_flows(const struct settings *s UNUSED, int argc UNUSED, char *argv[])
|
||||
* call. */
|
||||
ofm = make_openflow(sizeof *ofm, OFPT_FLOW_MOD, &buffer);
|
||||
str_to_flow(line, &match, buffer,
|
||||
&table_id, NULL, &priority, &idle_timeout, &hard_timeout);
|
||||
&table_id, NULL, &priority, &idle_timeout, &hard_timeout,
|
||||
&cookie);
|
||||
ofm = buffer->data;
|
||||
ofm->match = match;
|
||||
ofm->command = htons(OFPFC_ADD);
|
||||
ofm->cookie = htonll(cookie);
|
||||
ofm->idle_timeout = table_id == EMERG_TABLE_ID ? 0 : htons(idle_timeout);
|
||||
ofm->hard_timeout = table_id == EMERG_TABLE_ID ? 0 : htons(hard_timeout);
|
||||
ofm->buffer_id = htonl(UINT32_MAX);
|
||||
@@ -1148,7 +1159,6 @@ do_add_flows(const struct settings *s UNUSED, int argc UNUSED, char *argv[])
|
||||
ofm->flags = htons(OFPFF_SEND_FLOW_REM);
|
||||
if (table_id == EMERG_TABLE_ID)
|
||||
ofm->flags |= htons(OFPFF_EMERG);
|
||||
ofm->reserved = htonl(0);
|
||||
|
||||
send_openflow_buffer(vconn, buffer);
|
||||
}
|
||||
@@ -1160,6 +1170,7 @@ static void
|
||||
do_mod_flows(const struct settings *s, int argc UNUSED, char *argv[])
|
||||
{
|
||||
uint16_t priority, idle_timeout, hard_timeout;
|
||||
uint64_t cookie;
|
||||
uint8_t table_id;
|
||||
struct vconn *vconn;
|
||||
struct ofpbuf *buffer;
|
||||
@@ -1168,19 +1179,20 @@ do_mod_flows(const struct settings *s, int argc UNUSED, char *argv[])
|
||||
/* Parse and send. */
|
||||
ofm = make_openflow(sizeof *ofm, OFPT_FLOW_MOD, &buffer);
|
||||
str_to_flow(argv[2], &ofm->match, buffer,
|
||||
&table_id, NULL, &priority, &idle_timeout, &hard_timeout);
|
||||
&table_id, NULL, &priority, &idle_timeout, &hard_timeout,
|
||||
&cookie);
|
||||
if (s->strict) {
|
||||
ofm->command = htons(OFPFC_MODIFY_STRICT);
|
||||
} else {
|
||||
ofm->command = htons(OFPFC_MODIFY);
|
||||
}
|
||||
ofm->cookie = htonll(cookie);
|
||||
ofm->idle_timeout = table_id == EMERG_TABLE_ID ? 0 : htons(idle_timeout);
|
||||
ofm->hard_timeout = table_id == EMERG_TABLE_ID ? 0 : htons(hard_timeout);
|
||||
ofm->buffer_id = htonl(UINT32_MAX);
|
||||
if (table_id == EMERG_TABLE_ID)
|
||||
ofm->flags = htons(OFPFF_EMERG);
|
||||
ofm->priority = htons(priority);
|
||||
ofm->reserved = htonl(0);
|
||||
|
||||
open_vconn(argv[1], &vconn);
|
||||
send_openflow_buffer(vconn, buffer);
|
||||
@@ -1199,7 +1211,7 @@ static void do_del_flows(const struct settings *s, int argc, char *argv[])
|
||||
/* Parse and send. */
|
||||
ofm = make_openflow(sizeof *ofm, OFPT_FLOW_MOD, &buffer);
|
||||
str_to_flow(argc > 2 ? argv[2] : "", &ofm->match, NULL,
|
||||
&table_id, &out_port, &priority, NULL, NULL);
|
||||
&table_id, &out_port, &priority, NULL, NULL, NULL);
|
||||
if (s->strict) {
|
||||
ofm->command = htons(OFPFC_DELETE_STRICT);
|
||||
} else {
|
||||
@@ -1212,7 +1224,6 @@ static void do_del_flows(const struct settings *s, int argc, char *argv[])
|
||||
ofm->flags = htons(OFPFF_EMERG);
|
||||
ofm->out_port = htons(out_port);
|
||||
ofm->priority = htons(priority);
|
||||
ofm->reserved = htonl(0);
|
||||
|
||||
open_vconn(argv[1], &vconn);
|
||||
send_openflow_buffer(vconn, buffer);
|
||||
|
||||
Reference in new issue
Block a user