" benchmark TARGET N COUNT bandwidth of COUNT N-byte echos\n"
"SWITCH or TARGET is an active OpenFlow connection method.\n"
"\nOther commands:\n"
- " ofp-parse FILE print messages read from FILE\n",
+ " ofp-parse FILE print messages read from FILE\n"
+ " ofp-parse-pcap PCAP print OpenFlow read from PCAP\n",
program_name, program_name);
vconn_usage(true, false, false);
daemon_usage();
case OFP13_VERSION:
break;
default:
- NOT_REACHED();
+ OVS_NOT_REACHED();
}
}
struct vconn *vconn;
char *error;
int i;
- enum ofputil_protocol usable_protocols; /* TODO: Use in proto selection */
+ enum ofputil_protocol usable_protocols; /* XXX: Use in proto selection */
ofpbuf_init(&ofpacts, 64);
error = parse_ofpacts(argv[3], &ofpacts, &usable_protocols);
}
}
+static bool
+is_openflow_port(ovs_be16 port_, char *ports[])
+{
+ uint16_t port = ntohs(port_);
+ if (ports[0]) {
+ int i;
+
+ for (i = 0; ports[i]; i++) {
+ if (port == atoi(ports[i])) {
+ return true;
+ }
+ }
+ return false;
+ } else {
+ return port == OFP_PORT || port == OFP_OLD_PORT;
+ }
+}
+
+static void
+ofctl_ofp_parse_pcap(int argc OVS_UNUSED, char *argv[])
+{
+ struct tcp_reader *reader;
+ FILE *file;
+ int error;
+ bool first;
+
+ file = pcap_open(argv[1], "rb");
+ if (!file) {
+ ovs_fatal(errno, "%s: open failed", argv[1]);
+ }
+
+ reader = tcp_reader_open();
+ first = true;
+ for (;;) {
+ struct ofpbuf *packet;
+ long long int when;
+ struct flow flow;
+
+ error = pcap_read(file, &packet, &when);
+ if (error) {
+ break;
+ }
+ flow_extract(packet, 0, 0, NULL, NULL, &flow);
+ if (flow.dl_type == htons(ETH_TYPE_IP)
+ && flow.nw_proto == IPPROTO_TCP
+ && (is_openflow_port(flow.tp_src, argv + 2) ||
+ is_openflow_port(flow.tp_dst, argv + 2))) {
+ struct ofpbuf *payload = tcp_reader_run(reader, &flow, packet);
+ if (payload) {
+ while (payload->size >= sizeof(struct ofp_header)) {
+ const struct ofp_header *oh;
+ int length;
+
+ /* Align OpenFlow on 8-byte boundary for safe access. */
+ ofpbuf_shift(payload, -((intptr_t) payload->data & 7));
+
+ oh = payload->data;
+ length = ntohs(oh->length);
+ if (payload->size < length) {
+ break;
+ }
+
+ if (!first) {
+ putchar('\n');
+ }
+ first = false;
+
+ if (timestamp) {
+ char *s = xastrftime_msec("%H:%M:%S.### ", when, true);
+ fputs(s, stdout);
+ free(s);
+ }
+
+ printf(IP_FMT".%"PRIu16" > "IP_FMT".%"PRIu16":\n",
+ IP_ARGS(flow.nw_src), ntohs(flow.tp_src),
+ IP_ARGS(flow.nw_dst), ntohs(flow.tp_dst));
+ ofp_print(stdout, payload->data, length, verbosity + 1);
+ ofpbuf_pull(payload, length);
+ }
+ }
+ }
+ ofpbuf_delete(packet);
+ }
+ tcp_reader_close(reader);
+}
+
static void
ofctl_ping(int argc, char *argv[])
{
struct cls_cursor cursor;
struct fte *fte, *next;
- ovs_rwlock_wrlock(&cls->rwlock);
+ fat_rwlock_wrlock(&cls->rwlock);
cls_cursor_init(&cursor, cls, NULL);
CLS_CURSOR_FOR_EACH_SAFE (fte, next, rule, &cursor) {
classifier_remove(cls, &fte->rule);
fte_free(fte);
}
- ovs_rwlock_unlock(&cls->rwlock);
+ fat_rwlock_unlock(&cls->rwlock);
classifier_destroy(cls);
}
cls_rule_init(&fte->rule, match, priority);
fte->versions[index] = version;
- ovs_rwlock_wrlock(&cls->rwlock);
+ fat_rwlock_wrlock(&cls->rwlock);
old = fte_from_cls_rule(classifier_replace(cls, &fte->rule));
- ovs_rwlock_unlock(&cls->rwlock);
+ fat_rwlock_unlock(&cls->rwlock);
if (old) {
fte_version_free(old->versions[index]);
fte->versions[!index] = old->versions[!index];
list_init(&requests);
/* Delete flows that exist on the switch but not in the file. */
- ovs_rwlock_rdlock(&cls.rwlock);
+ fat_rwlock_rdlock(&cls.rwlock);
cls_cursor_init(&cursor, &cls, NULL);
CLS_CURSOR_FOR_EACH (fte, rule, &cursor) {
struct fte_version *file_ver = fte->versions[FILE_IDX];
fte_make_flow_mod(fte, FILE_IDX, OFPFC_ADD, protocol, &requests);
}
}
- ovs_rwlock_unlock(&cls.rwlock);
+ fat_rwlock_unlock(&cls.rwlock);
transact_multiple_noreply(vconn, &requests);
vconn_close(vconn);
ds_init(&a_s);
ds_init(&b_s);
- ovs_rwlock_rdlock(&cls.rwlock);
+ fat_rwlock_rdlock(&cls.rwlock);
cls_cursor_init(&cursor, &cls, NULL);
CLS_CURSOR_FOR_EACH (fte, rule, &cursor) {
struct fte_version *a = fte->versions[0];
}
}
}
- ovs_rwlock_unlock(&cls.rwlock);
+ fat_rwlock_unlock(&cls.rwlock);
ds_destroy(&a_s);
ds_destroy(&b_s);
struct flow flow;
int error;
- error = pcap_read(pcap, &packet);
+ error = pcap_read(pcap, &packet, NULL);
if (error == EOF) {
break;
} else if (error) {
{ "mod-table", 3, 3, ofctl_mod_table },
{ "get-frags", 1, 1, ofctl_get_frags },
{ "set-frags", 2, 2, ofctl_set_frags },
- { "ofp-parse", 1, 1, ofctl_ofp_parse },
{ "probe", 1, 1, ofctl_probe },
{ "ping", 1, 2, ofctl_ping },
{ "benchmark", 3, 3, ofctl_benchmark },
+ { "ofp-parse", 1, 1, ofctl_ofp_parse },
+ { "ofp-parse-pcap", 1, INT_MAX, ofctl_ofp_parse_pcap },
+
{ "add-group", 1, 2, ofctl_add_group },
{ "add-groups", 1, 2, ofctl_add_groups },
{ "mod-group", 1, 2, ofctl_mod_group },