From 4a53e14a2dc72a8a71bbca20ecf6bc85cf684e9b Mon Sep 17 00:00:00 2001 From: Yiannis Yiakoumis Date: Tue, 8 Dec 2009 15:17:51 -0800 Subject: [PATCH] Introduce --no-slicing option. Enable ofdatapath to run without slicing. When the related dependencies are not met, using the --no-slicing runtime option, ofdatapath can run without tc backend/frontend support (and therefore without slicing support). --- lib/netdev.c | 23 ++++++++--------------- lib/netdev.h | 2 +- udatapath/datapath.c | 26 ++++++++++++++++---------- udatapath/datapath.h | 5 +++-- udatapath/of_ext_msg.c | 2 +- udatapath/udatapath.c | 18 +++++++++++++----- 6 files changed, 42 insertions(+), 34 deletions(-) diff --git a/lib/netdev.c b/lib/netdev.c index ba664cc..20f38be 100644 --- a/lib/netdev.c +++ b/lib/netdev.c @@ -106,7 +106,8 @@ struct netdev { * network device. */ /* one socket per queue.These are valid only for ordinary network devices*/ - int queue_fd[NETDEV_MAX_QUEUES]; + int queue_fd[NETDEV_MAX_QUEUES + 1]; + uint16_t num_queues; /* Cached network device information. */ int ifindex; @@ -402,19 +403,13 @@ do_remove_qdisc(const char *netdev_name) * @return 0 on success */ int -netdev_setup_slicing(struct netdev *netdev) +netdev_setup_slicing(struct netdev *netdev, uint16_t num_queues) { int i; int * fd; int error; - /* tap (local) device should not have - * queue configuration - just set the - * default socket to tap_fd */ - if (!strncmp(netdev->name, "tap", 3)) { - netdev->queue_fd[0] = netdev->tap_fd; - return 0; - } + netdev->num_queues = num_queues; /* remove any previous queue configuration for this device */ error = do_remove_qdisc(netdev->name); @@ -455,11 +450,7 @@ netdev_setup_slicing(struct netdev *netdev) * SO_PRIORITY option of the socket. This dictates the usage of one socket * per queue. */ - /* the first socket is the default. non-sense, but makes life easier when - * start enumerating - * from one. */ - netdev->queue_fd[0] = netdev->tap_fd; - for (i=1; i <= NETDEV_MAX_QUEUES; i++) { + for (i=1; i <= netdev->num_queues; i++) { fd = &netdev->queue_fd[i]; error = open_queue_socket(netdev->name,i,fd); if (error) { @@ -767,9 +758,11 @@ do_open_netdev(const char *name, int ethertype, int tap_fd, netdev->hwaddr_family = hwaddr_family; netdev->netdev_fd = netdev_fd; netdev->tap_fd = tap_fd < 0 ? netdev_fd : tap_fd; + netdev->queue_fd[0] = netdev->tap_fd; memcpy(netdev->etheraddr, etheraddr, sizeof etheraddr); netdev->mtu = mtu; netdev->in6 = in6; + netdev->num_queues = 0; /* Get speed, features. */ do_ethtool(netdev); @@ -824,7 +817,7 @@ netdev_close(struct netdev *netdev) close(netdev->tap_fd); } - for (i =1; i<= NETDEV_MAX_QUEUES; i++) { + for (i =1; i <= netdev->num_queues; i++) { close(netdev->queue_fd[i]); } free(netdev); diff --git a/lib/netdev.h b/lib/netdev.h index bbfb01a..2d0e840 100644 --- a/lib/netdev.h +++ b/lib/netdev.h @@ -95,7 +95,7 @@ int netdev_set_flags(struct netdev *, enum netdev_flags, bool permanent); int netdev_turn_flags_on(struct netdev *, enum netdev_flags, bool permanent); int netdev_turn_flags_off(struct netdev *, enum netdev_flags, bool permanent); int netdev_arp_lookup(const struct netdev *, uint32_t ip, uint8_t mac[6]); -int netdev_setup_slicing(struct netdev *); +int netdev_setup_slicing(struct netdev *, uint16_t); int netdev_setup_class(const struct netdev *, uint16_t , uint16_t); int netdev_change_class(const struct netdev *, uint16_t , uint16_t); diff --git a/udatapath/datapath.c b/udatapath/datapath.c index 8a6491f..422a594 100644 --- a/udatapath/datapath.c +++ b/udatapath/datapath.c @@ -205,7 +205,7 @@ dp_new(struct datapath **dp_, uint64_t dpid) static int new_port(struct datapath *dp, struct sw_port *port, uint16_t port_no, - const char *netdev_name, const uint8_t *new_mac) + const char *netdev_name, const uint8_t *new_mac, uint16_t num_queues) { struct netdev *netdev; struct in6_addr in6; @@ -245,11 +245,16 @@ new_port(struct datapath *dp, struct sw_port *port, uint16_t port_no, netdev_name, in6_name); } - error = netdev_setup_slicing(netdev); - if (error) { - VLOG_ERR("failed to configure slicing on %s device",netdev_name); - netdev_close(netdev); - return error; + if (num_queues > 0) { + error = netdev_setup_slicing(netdev, num_queues); + if (error) { + VLOG_ERR("failed to configure slicing on %s device: "\ + "check INSTALL for dependencies, or rerun "\ + "using --no-slicing option to disable slicing", + netdev_name); + netdev_close(netdev); + return error; + } } memset(port, '\0', sizeof *port); @@ -258,6 +263,7 @@ new_port(struct datapath *dp, struct sw_port *port, uint16_t port_no, port->dp = dp; port->netdev = netdev; port->port_no = port_no; + port->num_queues = num_queues; list_push_back(&dp->port_list, &port->node); /* Notify the ctlpath that this port has been added */ @@ -267,20 +273,20 @@ new_port(struct datapath *dp, struct sw_port *port, uint16_t port_no, } int -dp_add_port(struct datapath *dp, const char *netdev) +dp_add_port(struct datapath *dp, const char *netdev, uint16_t num_queues) { int port_no; for (port_no = 1; port_no < DP_MAX_PORTS; port_no++) { struct sw_port *port = &dp->ports[port_no]; if (!port->netdev) { - return new_port(dp, port, port_no, netdev, NULL); + return new_port(dp, port, port_no, netdev, NULL, num_queues); } } return EXFULL; } int -dp_add_local_port(struct datapath *dp, const char *netdev) +dp_add_local_port(struct datapath *dp, const char *netdev, uint16_t num_queues) { if (!dp->local_port) { uint8_t ea[ETH_ADDR_LEN]; @@ -289,7 +295,7 @@ dp_add_local_port(struct datapath *dp, const char *netdev) port = xcalloc(1, sizeof *port); eth_addr_from_uint64(dp->id, ea); - error = new_port(dp, port, OFPP_LOCAL, netdev, ea); + error = new_port(dp, port, OFPP_LOCAL, netdev, ea, num_queues); if (!error) { dp->local_port = port; } else { diff --git a/udatapath/datapath.h b/udatapath/datapath.h index 113604f..70ecb62 100644 --- a/udatapath/datapath.h +++ b/udatapath/datapath.h @@ -73,6 +73,7 @@ struct sw_port { unsigned long long int tx_dropped; uint16_t port_no; /* port queues */ + uint16_t num_queues; struct sw_queue queues[NETDEV_MAX_QUEUES]; struct list queue_list; /* list of all queues for this port */ }; @@ -106,8 +107,8 @@ struct datapath { }; int dp_new(struct datapath **, uint64_t dpid); -int dp_add_port(struct datapath *, const char *netdev); -int dp_add_local_port(struct datapath *, const char *netdev); +int dp_add_port(struct datapath *, const char *netdev, uint16_t); +int dp_add_local_port(struct datapath *, const char *netdev, uint16_t); void dp_add_pvconn(struct datapath *, struct pvconn *); void dp_run(struct datapath *); void dp_wait(struct datapath *); diff --git a/udatapath/of_ext_msg.c b/udatapath/of_ext_msg.c index 0040f2a..a822824 100644 --- a/udatapath/of_ext_msg.c +++ b/udatapath/of_ext_msg.c @@ -68,7 +68,7 @@ port_add_queue(struct sw_port *p, uint32_t queue_id, struct ofp_queue_prop_min_rate * mr) { int queue_no; - for (queue_no = 1; queue_no < NETDEV_MAX_QUEUES; queue_no++) { + for (queue_no = 1; queue_no < p->num_queues; queue_no++) { struct sw_queue *q = &p->queues[queue_no]; if (!q->port) { return new_queue(p,q,queue_id,queue_no,mr); diff --git a/udatapath/udatapath.c b/udatapath/udatapath.c index 1e66974..2e88dea 100644 --- a/udatapath/udatapath.c +++ b/udatapath/udatapath.c @@ -72,6 +72,7 @@ static struct datapath *dp; static uint64_t dpid = UINT64_MAX; static char *port_list; static char *local_port = "tap:"; +static uint16_t num_queues = NETDEV_MAX_QUEUES; static void add_ports(struct datapath *dp, char *port_list); @@ -91,7 +92,7 @@ main(int argc, char *argv[]) if (argc - optind < 1) { ofp_fatal(0, "at least one listener argument is required; " - "use --help for usage"); + "use --help for usage"); } error = dp_new(&dp, dpid); @@ -118,7 +119,7 @@ main(int argc, char *argv[]) add_ports(dp, port_list); } if (local_port) { - error = dp_add_local_port(dp, local_port); + error = dp_add_local_port(dp, local_port, 0); if (error) { ofp_fatal(error, "failed to add local port %s", local_port); } @@ -152,7 +153,7 @@ add_ports(struct datapath *dp, char *port_list) * Using ",," instead of the obvious "," works around it. */ for (port = strtok_r(port_list, ",,", &save_ptr); port; port = strtok_r(NULL, ",,", &save_ptr)) { - int error = dp_add_port(dp, port); + int error = dp_add_port(dp, port, num_queues); if (error) { ofp_fatal(error, "failed to add port %s", port); } @@ -168,7 +169,8 @@ parse_options(int argc, char *argv[]) OPT_SW_DESC, OPT_SERIAL_NUM, OPT_BOOTSTRAP_CA_CERT, - OPT_NO_LOCAL_PORT + OPT_NO_LOCAL_PORT, + OPT_NO_SLICING }; static struct option long_options[] = { @@ -179,6 +181,7 @@ parse_options(int argc, char *argv[]) {"verbose", optional_argument, 0, 'v'}, {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, + {"no-slicing", no_argument, 0, OPT_NO_SLICING}, {"mfr-desc", required_argument, 0, OPT_MFR_DESC}, {"hw-desc", required_argument, 0, OPT_HW_DESC}, {"sw-desc", required_argument, 0, OPT_SW_DESC}, @@ -259,6 +262,10 @@ parse_options(int argc, char *argv[]) strncpy(serial_num, optarg, sizeof serial_num); break; + case OPT_NO_SLICING: + num_queues = 0; + break; + DAEMON_OPTION_HANDLERS #ifdef HAVE_OPENSSL @@ -285,7 +292,7 @@ usage(void) printf("%s: userspace OpenFlow datapath\n" "usage: %s [OPTIONS] LISTEN...\n" "where LISTEN is a passive OpenFlow connection method on which\n" - "to listen for incoming connections from the secure channel.\n", + "to listen for incoming connections from the secure channel.\n", program_name, program_name); vconn_usage(false, true, false); printf("\nConfiguration options:\n" @@ -295,6 +302,7 @@ usage(void) " --no-local-port disable local port\n" " -d, --datapath-id=ID Use ID as the OpenFlow switch ID\n" " (ID must consist of 12 hex digits)\n" + " --no-slicing disable slicing\n" "\nOther options:\n" " -D, --detach run in background as daemon\n" " -P, --pidfile[=FILE] create pidfile (default: %s/udatapath.pid)\n"