return error;
}
+#define POLICE_ADD_CMD "/sbin/tc qdisc add dev %s handle ffff: ingress"
+#define POLICE_CONFIG_CMD "/sbin/tc filter add dev %s parent ffff: protocol ip prio 50 u32 match ip src 0.0.0.0/0 police rate %dkbit burst %dk drop flowid :1"
+#define POLICE_DEL_CMD "/sbin/tc qdisc del dev %s handle ffff: ingress"
+
+/* Attempts to set input rate limiting (policing) policy. */
+int
+netdev_nodev_set_policing(const char *netdev_name, uint32_t kbits_rate,
+ uint32_t kbits_burst)
+{
+ char command[1024];
+
+ init_netdev();
+
+ if (kbits_rate) {
+ if (!kbits_burst) {
+ /* Default to 10 kilobits if not specified. */
+ kbits_burst = 10;
+ }
+
+ /* xxx This should be more careful about only adding if it
+ * xxx actually exists, as opposed to always deleting it. */
+ snprintf(command, sizeof(command), POLICE_DEL_CMD, netdev_name);
+ system(command);
+
+ snprintf(command, sizeof(command), POLICE_ADD_CMD, netdev_name);
+ if (system(command) != 0) {
+ VLOG_WARN_RL(&rl, "%s: problem adding policing", netdev_name);
+ return -1;
+ }
+
+ snprintf(command, sizeof(command), POLICE_CONFIG_CMD, netdev_name,
+ kbits_rate, kbits_burst);
+ if (system(command) != 0) {
+ VLOG_WARN_RL(&rl, "%s: problem configuring policing",
+ netdev_name);
+ return -1;
+ }
+ } else {
+ snprintf(command, sizeof(command), POLICE_DEL_CMD, netdev_name);
+ if (system(command) != 0) {
+ VLOG_WARN_RL(&rl, "%s: problem removing policing", netdev_name);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+int
+netdev_set_policing(struct netdev *netdev, uint32_t kbits_rate,
+ uint32_t kbits_burst)
+{
+ return netdev_nodev_set_policing(netdev->name, kbits_rate, kbits_burst);
+}
+
/* Initializes 'svec' with a list of the names of all known network devices. */
void
netdev_enumerate(struct svec *svec)
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_get_stats(const struct netdev *, struct netdev_stats *);
+int netdev_set_policing(struct netdev *, uint32_t kbits_rate,
+ uint32_t kbits_burst);
void netdev_enumerate(struct svec *);
int netdev_nodev_get_flags(const char *netdev_name, enum netdev_flags *);
int netdev_nodev_set_etheraddr(const char *name, const uint8_t mac[6]);
int netdev_nodev_get_etheraddr(const char *netdev_name, uint8_t mac[6]);
+int netdev_nodev_set_policing(const char *netdev_name, uint32_t kbits_rate,
+ uint32_t kbits_burst);
int netdev_get_vlan_vid(const char *netdev_name, int *vlan_vid);
vswitchd/bridge.h \
vswitchd/mgmt.c \
vswitchd/mgmt.h \
+ vswitchd/port.c \
+ vswitchd/port.h \
vswitchd/vswitchd.c \
vswitchd/vswitchd.h \
vswitchd/xenserver.c \
--- /dev/null
+/* Copyright (c) 2009 Nicira Networks
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * In addition, as a special exception, Nicira Networks gives permission
+ * to link the code of its release of vswitchd with the OpenSSL project's
+ * "OpenSSL" library (or with modified versions of it that use the same
+ * license as the "OpenSSL" library), and distribute the linked
+ * executables. You must obey the GNU General Public License in all
+ * respects for all of the code used other than "OpenSSL". If you modify
+ * this file, you may extend this exception to your version of the file,
+ * but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version.
+ *
+ */
+
+#include <config.h>
+
+#include "cfg.h"
+#include "netdev.h"
+#include "port.h"
+#include "svec.h"
+#include "vswitchd.h"
+
+#define THIS_MODULE VLM_port
+#include "vlog.h"
+
+static struct svec port_cfg = SVEC_EMPTY_INITIALIZER;
+static struct svec all_ports = SVEC_EMPTY_INITIALIZER;
+
+
+static int
+set_ingress_policing(const char *port_name)
+{
+ int kbits_rate = cfg_get_int(0, "port.%s.ingress.policing_rate",
+ port_name);
+ int kbits_burst = cfg_get_int(0, "port.%s.ingress.policing_burst",
+ port_name);
+
+ return netdev_nodev_set_policing(port_name, kbits_rate, kbits_burst);
+}
+
+static int
+set_port_config(const char *port_name)
+{
+ set_ingress_policing(port_name);
+
+ return 0;
+}
+
+static void
+strip_port_config(const char *port_name)
+{
+ netdev_nodev_set_policing(port_name, 0, 0);
+}
+
+void
+port_init(void)
+{
+ port_reconfigure();
+}
+
+void
+port_reconfigure(void)
+{
+ struct svec new_cfg;
+ struct svec new_ports;
+ int i;
+
+ svec_init(&new_cfg);
+ cfg_get_section(&new_cfg, "port");
+ svec_sort(&new_cfg);
+
+ if (svec_equal(&port_cfg, &new_cfg)) {
+ svec_destroy(&new_cfg);
+ return;
+ }
+
+ svec_init(&new_ports);
+ cfg_get_subsections(&new_ports, "port");
+ for (i=0; i<all_ports.n; i++) {
+ if (!svec_contains(&new_ports, all_ports.names[i])) {
+ strip_port_config(all_ports.names[i]);
+ }
+ }
+
+ for (i=0; i<new_ports.n; i++) {
+ set_port_config(new_ports.names[i]);
+ }
+
+ svec_swap(&new_cfg, &port_cfg);
+ svec_destroy(&new_cfg);
+
+ svec_swap(&new_ports, &all_ports);
+ svec_destroy(&new_ports);
+}
--- /dev/null
+/* Copyright (c) 2009 Nicira Networks
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * In addition, as a special exception, Nicira Networks gives permission
+ * to link the code of its release of vswitchd with the OpenSSL project's
+ * "OpenSSL" library (or with modified versions of it that use the same
+ * license as the "OpenSSL" library), and distribute the linked
+ * executables. You must obey the GNU General Public License in all
+ * respects for all of the code used other than "OpenSSL". If you modify
+ * this file, you may extend this exception to your version of the file,
+ * but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version.
+ */
+
+#ifndef VSWITCHD_PORT_H
+#define VSWITCHD_PORT_H 1
+
+void port_init(void);
+void port_reconfigure(void);
+
+#endif /* port.h */
#include "leak-checker.h"
#include "mgmt.h"
#include "poll-loop.h"
+#include "port.h"
#include "process.h"
#include "signals.h"
#include "svec.h"
cfg_read();
mgmt_init();
bridge_init();
+ port_init();
mgmt_reconfigure();
need_reconfigure = false;
cfg_read();
bridge_reconfigure();
mgmt_reconfigure();
+ port_reconfigure();
}
static void
select.src-port = eth2
output.port = eth3
+.fi
+.RE
+.SS "Port Rate-Limiting"
+Traffic policing and shaping are configured on physical ports. Policing
+defines a hard limit at which traffic that exceeds the specified rate is
+dropped. Shaping uses queues to delay packets so that egress traffic
+leaves at the specified rate.
+
+.ST "Ingress Policing"
+The rate at which traffic is allowed to enter through a particular
+physical port can be configured with ingress policing. The rate is
+specified in kilobits (1000 bits) per second with a maximum burst size
+specified in kilobits (1000 bits). The burst size should be at least
+the size of the port's MTU.
+
+A port may be configured to enforce ingress policing by defining the
+key \fBport.\fIname\fB.ingress.policing_rate\fR with an integer
+indicating the rate. The port \fIname\fR will only allow traffic to be
+received at the rate specified in kilobits per second. If the rate is zero
+or the key is not defined, then ingress policing is disabled.
+
+If ingress policing is enabled, then the burst rate may be set by defining
+the key \fBport.\fIname\fB.ingress.policing_burst\fR with an integer
+indicating the burst rate in kilobits. If a key is not supplied or is
+zero, then the default burst is 10 kilobits.
+
+.PP
+The following syntax limits port \fBeth1\fR to receiving traffic at
+\fB512\fR kilobits per second with a burst of \fB20\fR kilobits:
+.PP
+.RS
+.nf
+
+port.eth1.ingress.policing_rate=512
+port.eth1.ingress.policing_burst=20
+
.fi
.SS "IEEE 802.1D-1998 Spanning Tree Support"
.PP
connection attempts starts at 1 second and doubles on each failing
attempt until it reaches the maximum. The default maximum backoff
time is taken from \fBmgmt.max-backoff\fR.
-.ST "Rate Limit Settings"
+.ST "Controller Rate-Limiting"
These settings configure how the virtual switch applies a ``token
bucket'' to limit the rate at which packets in unknown flows are
forwarded to the OpenFlow controller for flow-setup processing. This
allow to accumulate during time in which no packets are being
forwarded to the OpenFlow controller to \fIburst\fR (measured in
packets). The default \fIburst\fR is one-quarter of the \fIrate\fR
-specified in the rate limit setting.
+specified in the rate-limit setting.
.IP
The first of these that is set takes effect. This option takes effect
-only when a rate limit is specified.
+only when a rate-limit is specified.
.ST "Remote Command Execution Settings"
These settings configure the commands that remote OpenFlow connections
are allowed to invoke using (e.g.) \fBdpctl execute\fR. To be