+do_mod_port(const struct settings *s, int argc, char *argv[])
+{
+ struct ofpbuf *request, *reply;
+ struct ofp_switch_features *osf;
+ struct ofp_port_mod *opm;
+ struct vconn *vconn;
+ char *endptr;
+ int n_ports;
+ int port_idx;
+ int port_no;
+
+
+ /* Check if the argument is a port index. Otherwise, treat it as
+ * the port name. */
+ port_no = strtol(argv[2], &endptr, 10);
+ if (port_no == 0 && endptr == argv[2]) {
+ port_no = -1;
+ }
+
+ /* Send a "Features Request" to get the information we need in order
+ * to modify the port. */
+ make_openflow(sizeof(struct ofp_header), OFPT_FEATURES_REQUEST, &request);
+ open_vconn(argv[1], &vconn);
+ run(vconn_transact(vconn, request, &reply), "talking to %s", argv[1]);
+
+ osf = reply->data;
+ n_ports = (reply->size - sizeof *osf) / sizeof *osf->ports;
+
+ for (port_idx = 0; port_idx < n_ports; port_idx++) {
+ if (port_no != -1) {
+ /* Check argument as a port index */
+ if (osf->ports[port_idx].port_no == htons(port_no)) {
+ break;
+ }
+ } else {
+ /* Check argument as an interface name */
+ if (!strncmp((char *)osf->ports[port_idx].name, argv[2],
+ sizeof osf->ports[0].name)) {
+ break;
+ }
+
+ }
+ }
+ if (port_idx == n_ports) {
+ ofp_fatal(0, "couldn't find monitored port: %s", argv[2]);
+ }
+
+ opm = make_openflow(sizeof(struct ofp_port_mod), OFPT_PORT_MOD, &request);
+ opm->port_no = osf->ports[port_idx].port_no;
+ memcpy(opm->hw_addr, osf->ports[port_idx].hw_addr, sizeof opm->hw_addr);
+ opm->config = htonl(0);
+ opm->mask = htonl(0);
+ opm->advertise = htonl(0);
+
+ printf("modifying port: %s\n", osf->ports[port_idx].name);
+
+ if (!strncasecmp(argv[3], MOD_PORT_CMD_UP, sizeof MOD_PORT_CMD_UP)) {
+ opm->mask |= htonl(OFPPC_PORT_DOWN);
+ } else if (!strncasecmp(argv[3], MOD_PORT_CMD_DOWN,
+ sizeof MOD_PORT_CMD_DOWN)) {
+ opm->mask |= htonl(OFPPC_PORT_DOWN);
+ opm->config |= htonl(OFPPC_PORT_DOWN);
+ } else if (!strncasecmp(argv[3], MOD_PORT_CMD_FLOOD,
+ sizeof MOD_PORT_CMD_FLOOD)) {
+ opm->mask |= htonl(OFPPC_NO_FLOOD);
+ } else if (!strncasecmp(argv[3], MOD_PORT_CMD_NOFLOOD,
+ sizeof MOD_PORT_CMD_NOFLOOD)) {
+ opm->mask |= htonl(OFPPC_NO_FLOOD);
+ opm->config |= htonl(OFPPC_NO_FLOOD);
+ } else {
+ ofp_fatal(0, "unknown mod-port command '%s'", argv[3]);
+ }
+
+ send_openflow_buffer(vconn, request);
+
+ ofpbuf_delete(reply);
+ vconn_close(vconn);
+}
+
+static void
+do_ping(const struct settings *s, int argc, char *argv[])