" dump-flows SWITCH FLOW print matching FLOWs\n"
" dump-aggregate SWITCH print aggregate flow statistics\n"
" dump-aggregate SWITCH FLOW print aggregate stats for FLOWs\n"
+#ifdef SUPPORT_SNAT
+ " add-snat SWITCH IFACE IP add SNAT config to IFACE\n"
+ " del-snat SWITCH IFACE delete SNAT config on IFACE\n"
+#endif
" add-flow SWITCH FLOW add flow described by FLOW\n"
" add-flows SWITCH FILE add flows from FILE\n"
" mod-flows SWITCH FLOW modify actions of matching FLOWs\n"
"where each SWITCH is an active OpenFlow connection method.\n",
program_name, program_name);
vconn_usage(true, false, false);
- printf("\nOptions:\n"
+ vlog_usage();
+ printf("\nOther options:\n"
" --strict use strict match for flow commands\n"
" -t, --timeout=SECS give up after SECS seconds\n"
- " -v, --verbose=MODULE[:FACILITY[:LEVEL]] set logging levels\n"
- " -v, --verbose set maximum verbosity level\n"
" -h, --help display this help message\n"
" -V, --version display version information\n");
exit(EXIT_SUCCESS);
struct ofpbuf *b;
request = make_openflow(sizeof *request, OFPT_VENDOR, &b);
- request->vendor_id = htonl(NX_VENDOR_ID);
+ request->vendor = htonl(NX_VENDOR_ID);
request->subtype = htonl(NXT_STATUS_REQUEST);
if (argc > 2) {
ofpbuf_put(b, argv[2], strlen(argv[2]));
}
reply = b->data;
if (reply->header.type != OFPT_VENDOR
- || reply->vendor_id != ntohl(NX_VENDOR_ID)
+ || reply->vendor != ntohl(NX_VENDOR_ID)
|| reply->subtype != ntohl(NXT_STATUS_REPLY)) {
ofp_print(stderr, b->data, b->size, 2);
ofp_fatal(0, "bad reply");
ah->type = htons(OFPAT_STRIP_VLAN);
} else if (!strcasecmp(act, "output")) {
port = str_to_int(arg);
+#ifdef SUPPORT_SNAT
+ } else if (!strcasecmp(act, "nat")) {
+ struct nx_action_snat *sa = (struct nx_action_snat *)ah;
+
+ if (len < sizeof *sa) {
+ ofp_fatal(0, "Insufficient room for SNAT action\n");
+ }
+
+ if (str_to_int(arg) > OFPP_MAX) {
+ ofp_fatal(0, "Invalid nat port: %s\n", arg);
+ }
+
+ act_len = sizeof *sa;
+ sa->type = htons(OFPAT_VENDOR);
+ sa->vendor = htonl(NX_VENDOR_ID);
+ sa->subtype = htons(NXAST_SNAT);
+ sa->port = htons(str_to_int(arg));
+#endif
} else if (!strcasecmp(act, "TABLE")) {
port = OFPP_TABLE;
} else if (!strcasecmp(act, "NORMAL")) {
dump_stats_transaction(argv[1], request);
}
+#ifdef SUPPORT_SNAT
+static void do_add_snat(const struct settings *s, int argc, char *argv[])
+{
+ struct vconn *vconn;
+ struct ofpbuf *buffer;
+ struct nx_act_config *nac;
+ size_t size;
+
+ /* Parse and send. */
+ size = sizeof *nac + sizeof nac->snat[0];
+ nac = make_openflow(size, OFPT_VENDOR, &buffer);
+
+ nac->header.vendor = htonl(NX_VENDOR_ID);
+ nac->header.subtype = htonl(NXT_ACT_SET_CONFIG);
+
+ nac->type = htons(NXAST_SNAT);
+ nac->snat[0].command = NXSC_ADD;
+ nac->snat[0].port = htons(str_to_int(argv[2]));
+ nac->snat[0].mac_timeout = htons(0);
+ str_to_ip(argv[3], &nac->snat[0].ip_addr_start);
+ str_to_ip(argv[3], &nac->snat[0].ip_addr_end);
+
+ open_vconn(argv[1], &vconn);
+ send_openflow_buffer(vconn, buffer);
+ vconn_close(vconn);
+}
+
+static void do_del_snat(const struct settings *s, int argc, char *argv[])
+{
+ struct vconn *vconn;
+ struct ofpbuf *buffer;
+ struct nx_act_config *nac;
+ size_t size;
+
+ /* Parse and send. */
+ size = sizeof *nac + sizeof nac->snat[0];
+ nac = make_openflow(size, OFPT_VENDOR, &buffer);
+
+ nac->header.vendor = htonl(NX_VENDOR_ID);
+ nac->header.subtype = htonl(NXT_ACT_SET_CONFIG);
+
+ nac->type = htons(NXAST_SNAT);
+ nac->snat[0].command = NXSC_DELETE;
+ nac->snat[0].port = htons(str_to_int(argv[2]));
+ nac->snat[0].mac_timeout = htons(0);
+
+ open_vconn(argv[1], &vconn);
+ send_openflow_buffer(vconn, buffer);
+ vconn_close(vconn);
+}
+#endif /* SUPPORT_SNAT */
+
static void do_add_flow(const struct settings *s, int argc, char *argv[])
{
struct vconn *vconn;
{ "dump-tables", 1, 1, do_dump_tables },
{ "dump-flows", 1, 2, do_dump_flows },
{ "dump-aggregate", 1, 2, do_dump_aggregate },
+#ifdef SUPPORT_SNAT
+ { "add-snat", 3, 3, do_add_snat },
+ { "del-snat", 2, 2, do_del_snat },
+#endif
{ "add-flow", 2, 2, do_add_flow },
{ "add-flows", 2, 2, do_add_flows },
{ "mod-flows", 2, 2, do_mod_flows },