X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=utilities%2Fovs-controller.c;h=40e2a801da63ca01f3d37d062655f262f5147fdf;hb=adf7cfd851c3d9d6f1ad74653cbd2fecce8c3ba9;hp=30acc8ba46e97288f7968a89bb7cd1cdab4a3ed3;hpb=b66bdf3032561157c66c81e1f9f1e05aec18ede7;p=openvswitch diff --git a/utilities/ovs-controller.c b/utilities/ovs-controller.c index 30acc8ba..40e2a801 100644 --- a/utilities/ovs-controller.c +++ b/utilities/ovs-controller.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include "command-line.h" @@ -36,9 +37,9 @@ #include "unixctl.h" #include "util.h" #include "vconn.h" - #include "vlog.h" -#define THIS_MODULE VLM_controller + +VLOG_DEFINE_THIS_MODULE(controller) #define MAX_SWITCHES 16 #define MAX_LISTENERS 16 @@ -67,11 +68,18 @@ static int max_idle = 60; * of their messages (for debugging fail-open mode). */ static bool mute = false; +/* -q, --queue: OpenFlow queue to use, or the default queue if UINT32_MAX. */ +static uint32_t queue_id = UINT32_MAX; + +/* --with-flows: File with flows to send to switch, or null to not load + * any default flows. */ +static FILE *flow_file = NULL; + /* --unixctl: Name of unixctl socket, or null to use the default. */ static char *unixctl_path = NULL; static int do_switching(struct switch_ *); -static void new_switch(struct switch_ *, struct vconn *, const char *name); +static void new_switch(struct switch_ *, struct vconn *); static void parse_options(int argc, char *argv[]); static void usage(void) NO_RETURN; @@ -87,8 +95,6 @@ main(int argc, char *argv[]) proctitle_init(argc, argv); set_program_name(argv[0]); - time_init(); - vlog_init(); parse_options(argc, argv); signal(SIGPIPE, SIG_IGN); @@ -101,14 +107,13 @@ main(int argc, char *argv[]) for (i = optind; i < argc; i++) { const char *name = argv[i]; struct vconn *vconn; - int retval; retval = vconn_open(name, OFP_VERSION, &vconn); if (!retval) { if (n_switches >= MAX_SWITCHES) { ovs_fatal(0, "max %d switch connections", n_switches); } - new_switch(&switches[n_switches++], vconn, name); + new_switch(&switches[n_switches++], vconn); continue; } else if (retval == EAFNOSUPPORT) { struct pvconn *pvconn; @@ -140,17 +145,15 @@ main(int argc, char *argv[]) while (n_switches > 0 || n_listeners > 0) { int iteration; - int i; /* Accept connections on listening vconns. */ for (i = 0; i < n_listeners && n_switches < MAX_SWITCHES; ) { struct vconn *new_vconn; - int retval; retval = pvconn_accept(listeners[i], OFP_VERSION, &new_vconn); if (!retval || retval == EAGAIN) { if (!retval) { - new_switch(&switches[n_switches++], new_vconn, "tcp"); + new_switch(&switches[n_switches++], new_vconn); } i++; } else { @@ -165,7 +168,8 @@ main(int argc, char *argv[]) bool progress = false; for (i = 0; i < n_switches; ) { struct switch_ *this = &switches[i]; - int retval = do_switching(this); + + retval = do_switching(this); if (!retval || retval == EAGAIN) { if (!retval) { progress = true; @@ -183,7 +187,7 @@ main(int argc, char *argv[]) } for (i = 0; i < n_switches; i++) { struct switch_ *this = &switches[i]; - lswitch_run(this->lswitch, this->rconn); + lswitch_run(this->lswitch); } unixctl_server_run(unixctl); @@ -208,12 +212,22 @@ main(int argc, char *argv[]) } static void -new_switch(struct switch_ *sw, struct vconn *vconn, const char *name) +new_switch(struct switch_ *sw, struct vconn *vconn) { - sw->rconn = rconn_new_from_vconn(name, vconn); + sw->rconn = rconn_create(60, 0); + rconn_connect_unreliably(sw->rconn, vconn, NULL); + + /* If it was set, rewind 'flow_file' to the beginning, since a + * previous call to lswitch_create() will leave the stream at the + * end. */ + if (flow_file) { + rewind(flow_file); + } sw->lswitch = lswitch_create(sw->rconn, learn_macs, exact_flows, set_up_flows ? max_idle : -1, - action_normal); + action_normal, flow_file); + + lswitch_set_queue(sw->lswitch, queue_id); } static int @@ -245,6 +259,7 @@ parse_options(int argc, char *argv[]) OPT_MAX_IDLE = UCHAR_MAX + 1, OPT_PEER_CA_CERT, OPT_MUTE, + OPT_WITH_FLOWS, OPT_UNIXCTL, VLOG_OPTION_ENUMS }; @@ -255,6 +270,8 @@ parse_options(int argc, char *argv[]) {"wildcard", no_argument, 0, 'w'}, {"max-idle", required_argument, 0, OPT_MAX_IDLE}, {"mute", no_argument, 0, OPT_MUTE}, + {"queue", required_argument, 0, 'q'}, + {"with-flows", required_argument, 0, OPT_WITH_FLOWS}, {"unixctl", required_argument, 0, OPT_UNIXCTL}, {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, @@ -310,6 +327,17 @@ parse_options(int argc, char *argv[]) } break; + case 'q': + queue_id = atoi(optarg); + break; + + case OPT_WITH_FLOWS: + flow_file = fopen(optarg, "r"); + if (flow_file == NULL) { + ovs_fatal(errno, "%s: open", optarg); + } + break; + case OPT_UNIXCTL: unixctl_path = optarg; break; @@ -358,6 +386,8 @@ usage(void) " --max-idle=SECS max idle time for new flows\n" " -N, --normal use OFPAT_NORMAL action\n" " -w, --wildcard use wildcards, not exact-match rules\n" + " -q, --queue=QUEUE OpenFlow queue ID to use for output\n" + " --with-flows FILE use the flows from FILE\n" " --unixctl=SOCKET override default control socket name\n" " -h, --help display this help message\n" " -V, --version display version information\n");