summaryrefslogtreecommitdiff
path: root/lib/ofp-util.c
diff options
context:
space:
mode:
authorBen Pfaff <blp@nicira.com>2010-06-17 15:04:12 -0700
committerBen Pfaff <blp@nicira.com>2010-06-17 15:04:12 -0700
commitc1c9c9c4b636ab2acf2f75024c282a9a497ca9a9 (patch)
tree02d8e5c448f1b75126f965ee5173ddde5111d63c /lib/ofp-util.c
parenta90b56b7708a17e8bd689d4a3558348f04cb8dcb (diff)
downloadopenvswitch-c1c9c9c4b636ab2acf2f75024c282a9a497ca9a9.tar.gz
Implement QoS framework.
ovs-vswitchd doesn't declare its QoS capabilities in the database yet, so the controller has to know what they are. We can add that later. The linux-htb QoS class has been tested to the extent that I can see that it sets up the queues I expect when I run "tc qdisc show" and "tc class show". I haven't tested that the effects on flows are what we expect them to be. I am sure that there will be problems in that area that we will have to fix.
Diffstat (limited to 'lib/ofp-util.c')
-rw-r--r--lib/ofp-util.c58
1 files changed, 54 insertions, 4 deletions
diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index d773a3fa9..e990f0f44 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -22,6 +22,7 @@
#include "ofpbuf.h"
#include "packets.h"
#include "random.h"
+#include "xtoxll.h"
#define THIS_MODULE VLM_ofp_util
#include "vlog.h"
@@ -489,8 +490,11 @@ check_action_exact_len(const union ofp_action *a, unsigned int len,
return 0;
}
+/* Checks that 'port' is a valid output port for the OFPAT_OUTPUT action, given
+ * that the switch will never have more than 'max_ports' ports. Returns 0 if
+ * 'port' is valid, otherwise an ofp_mkerr() return code. */
static int
-check_action_port(int port, int max_ports)
+check_output_port(uint16_t port, int max_ports)
{
switch (port) {
case OFPP_IN_PORT:
@@ -503,7 +507,7 @@ check_action_port(int port, int max_ports)
return 0;
default:
- if (port >= 0 && port < max_ports) {
+ if (port < max_ports) {
return 0;
}
VLOG_WARN_RL(&bad_ofmsg_rl, "unknown output port %x", port);
@@ -511,6 +515,31 @@ check_action_port(int port, int max_ports)
}
}
+/* Checks that 'action' is a valid OFPAT_ENQUEUE action, given that the switch
+ * will never have more than 'max_ports' ports. Returns 0 if 'port' is valid,
+ * otherwise an ofp_mkerr() return code. */
+static int
+check_enqueue_action(const union ofp_action *a, unsigned int len,
+ int max_ports)
+{
+ const struct ofp_action_enqueue *oae;
+ uint16_t port;
+ int error;
+
+ error = check_action_exact_len(a, len, 16);
+ if (error) {
+ return error;
+ }
+
+ oae = (const struct ofp_action_enqueue *) a;
+ port = ntohs(oae->port);
+ if (port < max_ports || port == OFPP_IN_PORT) {
+ return 0;
+ }
+ VLOG_WARN_RL(&bad_ofmsg_rl, "unknown enqueue port %x", port);
+ return ofp_mkerr(OFPET_BAD_ACTION, OFPBAC_BAD_OUT_PORT);
+}
+
static int
check_nicira_action(const union ofp_action *a, unsigned int len)
{
@@ -539,8 +568,11 @@ check_action(const union ofp_action *a, unsigned int len, int max_ports)
switch (ntohs(a->type)) {
case OFPAT_OUTPUT:
- error = check_action_port(ntohs(a->output.port), max_ports);
- return error ? error : check_action_exact_len(a, len, 8);
+ error = check_action_exact_len(a, len, 8);
+ if (error) {
+ return error;
+ }
+ return check_output_port(ntohs(a->output.port), max_ports);
case OFPAT_SET_VLAN_VID:
case OFPAT_SET_VLAN_PCP:
@@ -561,6 +593,9 @@ check_action(const union ofp_action *a, unsigned int len, int max_ports)
? check_nicira_action(a, len)
: ofp_mkerr(OFPET_BAD_ACTION, OFPBAC_BAD_VENDOR));
+ case OFPAT_ENQUEUE:
+ return check_enqueue_action(a, len, max_ports);
+
default:
VLOG_WARN_RL(&bad_ofmsg_rl, "unknown action type %"PRIu16,
ntohs(a->type));
@@ -603,6 +638,21 @@ validate_actions(const union ofp_action *actions, size_t n_actions,
return 0;
}
+/* Returns true if 'action' outputs to 'port' (which must be in network byte
+ * order), false otherwise. */
+bool
+action_outputs_to_port(const union ofp_action *action, uint16_t port)
+{
+ switch (ntohs(action->type)) {
+ case OFPAT_OUTPUT:
+ return action->output.port == port;
+ case OFPAT_ENQUEUE:
+ return ((const struct ofp_action_enqueue *) action)->port == port;
+ default:
+ return false;
+ }
+}
+
/* The set of actions must either come from a trusted source or have been
* previously validated with validate_actions(). */
const union ofp_action *