diff options
Diffstat (limited to 'utilities')
-rw-r--r-- | utilities/ovs-dpctl.c | 9 | ||||
-rw-r--r-- | utilities/ovs-ofctl.8.in | 54 | ||||
-rw-r--r-- | utilities/ovs-ofctl.c | 105 |
3 files changed, 154 insertions, 14 deletions
diff --git a/utilities/ovs-dpctl.c b/utilities/ovs-dpctl.c index 4d0d3c2d..d78fb317 100644 --- a/utilities/ovs-dpctl.c +++ b/utilities/ovs-dpctl.c @@ -371,12 +371,9 @@ show_dpif(struct dpif *dpif) printf("%s:\n", dpif_name(dpif)); if (!dpif_get_dp_stats(dpif, &stats)) { - printf("\tlookups: frags:%"PRIu64, stats.n_frags); - printf(" hit:%"PRIu64, stats.n_hit); - printf(" missed:%"PRIu64, stats.n_missed); - printf(" lost:%"PRIu64"\n", stats.n_lost); - - printf("\tflows: %"PRIu64"\n", stats.n_flows); + printf("\tlookups: hit:%"PRIu64" missed:%"PRIu64" lost:%"PRIu64"\n" + "\tflows: %"PRIu64"\n", + stats.n_hit, stats.n_missed, stats.n_lost, stats.n_flows); } DPIF_PORT_FOR_EACH (&dpif_port, &dump, dpif) { printf("\tport %u: %s", dpif_port.port_no, dpif_port.name); diff --git a/utilities/ovs-ofctl.8.in b/utilities/ovs-ofctl.8.in index f2ed8a48..215f8f92 100644 --- a/utilities/ovs-ofctl.8.in +++ b/utilities/ovs-ofctl.8.in @@ -92,6 +92,39 @@ spanning tree protocol is not in use. . .RE . +.IP "\fBget\-frags \fIswitch\fR" +Prints \fIswitch\fR's fragment handling mode. See \fBset\-frags\fR, +below, for a description of each fragment handling mode. +.IP +The \fBshow\fR command also prints the fragment handling mode among +its other output. +. +.IP "\fBset\-frags \fIswitch frag_mode\fR" +Configures \fIswitch\fR's treatment of IPv4 and IPv6 fragments. The +choices for \fIfrag_mode\fR are: +.RS +.IP "\fBnormal\fR" +Fragments pass through the flow table like non-fragmented packets. +The TCP ports, UDP ports, and ICMP type and code fields are always set +to 0, even for fragments where that information would otherwise be +available (fragments with offset 0). This is the default fragment +handling mode for an OpenFlow switch. +.IP "\fBdrop\fR" +Fragments are dropped without passing through the flow table. +.IP "\fBreassemble\fR" +The switch reassembles fragments into full IP packets before passing +them through the flow table. Open vSwitch does not implement this +fragment handling mode. +.IP "\fBnx\-match\fR" +Fragments pass through the flow table like non-fragmented packets. +The TCP ports, UDP ports, and ICMP type and code fields are available +for matching for fragments with offset 0, and set to 0 in fragments +with nonzero offset. This mode is a Nicira extension. +.RE +.IP +See the description of \fBip_frag\fR, below, for a way to match on +whether a packet is a fragment and on its fragment offset. +. .TP \fBdump\-flows \fIswitch \fR[\fIflows\fR] Prints to the console all flow entries in \fIswitch\fR's @@ -476,6 +509,27 @@ Match packets with no 802.1Q header or tagged with VLAN 0 and priority Some of these matching possibilities can also be achieved with \fBdl_vlan\fR and \fBdl_vlan_pcp\fR. . +.IP \fBip_frag=\fIfrag_type\fR +When \fBdl_type\fR specifies IP or IPv6, \fIfrag_type\fR +specifies what kind of IP fragments or non-fragments to match. The +following values of \fIfrag_type\fR are supported: +.RS +.IP "\fBno\fR" +Matches only non-fragmented packets. +.IP "\fByes\fR" +Matches all fragments. +.IP "\fBfirst\fR" +Matches only fragments with offset 0. +.IP "\fBlater\fR" +Matches only fragments with nonzero offset. +.IP "\fBnot_later\fR" +Matches non-fragmented packets and fragments with zero offset. +.RE +.IP +The \fBip_frag\fR match type is likely to be most useful in +\fBnx\-match\fR mode. See the description of the \fBset\-frags\fR +command, above, for more details. +. .IP \fBarp_sha=\fIxx\fB:\fIxx\fB:\fIxx\fB:\fIxx\fB:\fIxx\fB:\fIxx\fR .IQ \fBarp_tha=\fIxx\fB:\fIxx\fB:\fIxx\fB:\fIxx\fB:\fIxx\fB:\fIxx\fR When \fBdl_type\fR specifies ARP, \fBarp_sha\fR and \fBarp_tha\fR match diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c index 164d0830..ce9723b9 100644 --- a/utilities/ovs-ofctl.c +++ b/utilities/ovs-ofctl.c @@ -172,6 +172,8 @@ usage(void) " dump-desc SWITCH print switch description\n" " dump-tables SWITCH print table stats\n" " mod-port SWITCH IFACE ACT modify port behavior\n" + " get-frags SWITCH print fragment handling behavior\n" + " set-frags SWITCH FRAG_MODE set fragment handling behavior\n" " dump-ports SWITCH [PORT] print port statistics\n" " dump-flows SWITCH print all flow entries\n" " dump-flows SWITCH FLOW print matching FLOWs\n" @@ -351,7 +353,9 @@ dump_trivial_stats_transaction(const char *vconn_name, uint8_t stats_type) /* Sends 'request', which should be a request that only has a reply if an error * occurs, and waits for it to succeed or fail. If an error does occur, prints - * it and exits with an error. */ + * it and exits with an error. + * + * Destroys all of the 'requests'. */ static void transact_multiple_noreply(struct vconn *vconn, struct list *requests) { @@ -372,7 +376,9 @@ transact_multiple_noreply(struct vconn *vconn, struct list *requests) /* Sends 'request', which should be a request that only has a reply if an error * occurs, and waits for it to succeed or fail. If an error does occur, prints - * it and exits with an error. */ + * it and exits with an error. + * + * Destroys 'request'. */ static void transact_noreply(struct vconn *vconn, struct ofpbuf *request) { @@ -384,6 +390,44 @@ transact_noreply(struct vconn *vconn, struct ofpbuf *request) } static void +fetch_switch_config(struct vconn *vconn, struct ofp_switch_config *config_) +{ + struct ofp_switch_config *config; + struct ofp_header *header; + struct ofpbuf *request; + struct ofpbuf *reply; + + make_openflow(sizeof(struct ofp_header), OFPT_GET_CONFIG_REQUEST, + &request); + run(vconn_transact(vconn, request, &reply), + "talking to %s", vconn_get_name(vconn)); + + header = reply->data; + if (header->type != OFPT_GET_CONFIG_REPLY || + header->length != htons(sizeof *config)) { + ovs_fatal(0, "%s: bad reply to config request", vconn_get_name(vconn)); + } + + config = reply->data; + *config_ = *config; +} + +static void +set_switch_config(struct vconn *vconn, struct ofp_switch_config *config_) +{ + struct ofp_switch_config *config; + struct ofp_header save_header; + struct ofpbuf *request; + + config = make_openflow(sizeof *config, OFPT_SET_CONFIG, &request); + save_header = config->header; + *config = *config_; + config->header = save_header; + + transact_noreply(vconn, request); +} + +static void do_show(int argc OVS_UNUSED, char *argv[]) { dump_trivial_transaction(argv[1], OFPT_FEATURES_REQUEST); @@ -720,13 +764,11 @@ do_monitor(int argc, char *argv[]) open_vconn(argv[1], &vconn); if (argc > 2) { - int miss_send_len = atoi(argv[2]); - struct ofp_switch_config *osc; - struct ofpbuf *buf; + struct ofp_switch_config config; - osc = make_openflow(sizeof *osc, OFPT_SET_CONFIG, &buf); - osc->miss_send_len = htons(miss_send_len); - transact_noreply(vconn, buf); + fetch_switch_config(vconn, &config); + config.miss_send_len = htons(atoi(argv[2])); + set_switch_config(vconn, &config); } monitor_vconn(vconn); } @@ -807,6 +849,51 @@ do_mod_port(int argc OVS_UNUSED, char *argv[]) } static void +do_get_frags(int argc OVS_UNUSED, char *argv[]) +{ + struct ofp_switch_config config; + struct vconn *vconn; + + open_vconn(argv[1], &vconn); + fetch_switch_config(vconn, &config); + puts(ofputil_frag_handling_to_string(ntohs(config.flags))); + vconn_close(vconn); +} + +static void +do_set_frags(int argc OVS_UNUSED, char *argv[]) +{ + struct ofp_switch_config config; + enum ofp_config_flags mode; + struct vconn *vconn; + ovs_be16 flags; + + if (!ofputil_frag_handling_from_string(argv[2], &mode)) { + ovs_fatal(0, "%s: unknown fragment handling mode", argv[2]); + } + + open_vconn(argv[1], &vconn); + fetch_switch_config(vconn, &config); + flags = htons(mode) | (config.flags & htons(~OFPC_FRAG_MASK)); + if (flags != config.flags) { + /* Set the configuration. */ + config.flags = flags; + set_switch_config(vconn, &config); + + /* Then retrieve the configuration to see if it really took. OpenFlow + * doesn't define error reporting for bad modes, so this is all we can + * do. */ + fetch_switch_config(vconn, &config); + if (flags != config.flags) { + ovs_fatal(0, "%s: setting fragment handling mode failed (this " + "switch probably doesn't support mode \"%s\")", + argv[1], ofputil_frag_handling_to_string(mode)); + } + } + vconn_close(vconn); +} + +static void do_ping(int argc, char *argv[]) { size_t max_payload = 65535 - sizeof(struct ofp_header); @@ -1442,6 +1529,8 @@ static const struct command all_commands[] = { { "diff-flows", 2, 2, do_diff_flows }, { "dump-ports", 1, 2, do_dump_ports }, { "mod-port", 3, 3, do_mod_port }, + { "get-frags", 1, 1, do_get_frags }, + { "set-frags", 2, 2, do_set_frags }, { "probe", 1, 1, do_probe }, { "ping", 1, 2, do_ping }, { "benchmark", 3, 3, do_benchmark }, |