Implement flow cookies in user datapath.

This commit is contained in:
Justin Pettit authored and Glen Gibb committed 2009-12-11 15:43:36 -08:00
1 parent d216ae2782
commit 1936cc1c68
5 files changed
+39 -19

No files matched your search

+2 -1
View File
@@ -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
View File
@@ -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));
+4
View File
@@ -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;
+1
View File
@@ -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
View File
@@ -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);