[ovs-dev] [PATCH 2/3] datapath: Validate ToS when flow is added.

Jesse Gross jesse at nicira.com
Fri Mar 12 21:57:03 UTC 2010


Check that the ToS is valid when the flow is added, not every time
it is used.
---
 datapath/actions.c  |    2 +-
 datapath/datapath.c |    6 +++++
 datapath/flow.c     |    1 +
 lib/dpif-netdev.c   |   58 ++++++++++++++++++++++++++++----------------------
 4 files changed, 40 insertions(+), 27 deletions(-)

diff --git a/datapath/actions.c b/datapath/actions.c
index b6d5488..4767862 100644
--- a/datapath/actions.c
+++ b/datapath/actions.c
@@ -292,7 +292,7 @@ static struct sk_buff *set_nw_tos(struct sk_buff *skb,
 		u8 new;
 
 		/* Set the DSCP bits and preserve the ECN bits. */
-		new = (a->nw_tos & ~INET_ECN_MASK) | (nh->tos & INET_ECN_MASK);
+		new = a->nw_tos | (nh->tos & INET_ECN_MASK);
 		update_csum(&nh->check, skb, htons((uint16_t)old),
 				htons((uint16_t)new), 0);
 		*f = new;
diff --git a/datapath/datapath.c b/datapath/datapath.c
index f8a2aa3..6365f94 100644
--- a/datapath/datapath.c
+++ b/datapath/datapath.c
@@ -41,6 +41,7 @@
 #include <linux/rculist.h>
 #include <linux/workqueue.h>
 #include <linux/dmi.h>
+#include <net/inet_ecn.h>
 #include <net/llc.h>
 
 #include "openvswitch/datapath-protocol.h"
@@ -930,6 +931,11 @@ static int validate_actions(const struct sw_flow_actions *actions)
 				return -EINVAL;
 			break;
 
+		case ODPAT_SET_NW_TOS:
+			if (a->nw_tos.nw_tos & INET_ECN_MASK)
+				return -EINVAL;
+			break;
+
 		default:
 			if (a->type >= ODPAT_N_ACTIONS)
 				return -EOPNOTSUPP;
diff --git a/datapath/flow.c b/datapath/flow.c
index 3b95e3b..9a94d0b 100644
--- a/datapath/flow.c
+++ b/datapath/flow.c
@@ -25,6 +25,7 @@
 #include <linux/tcp.h>
 #include <linux/udp.h>
 #include <linux/icmp.h>
+#include <net/inet_ecn.h>
 #include <net/ip.h>
 
 #include "compat.h"
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index e19cb34..365b78a 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -720,58 +720,64 @@ static int
 dpif_netdev_validate_actions(const union odp_action *actions, int n_actions,
                              bool *mutates)
 {
-	unsigned int i;
+    unsigned int i;
 
     *mutates = false;
-	for (i = 0; i < n_actions; i++) {
-		const union odp_action *a = &actions[i];
-		switch (a->type) {
-		case ODPAT_OUTPUT:
-			if (a->output.port >= MAX_PORTS) {
-				return EINVAL;
+    for (i = 0; i < n_actions; i++) {
+        const union odp_action *a = &actions[i];
+        switch (a->type) {
+        case ODPAT_OUTPUT:
+            if (a->output.port >= MAX_PORTS) {
+                return EINVAL;
             }
-			break;
+            break;
 
-		case ODPAT_OUTPUT_GROUP:
+        case ODPAT_OUTPUT_GROUP:
             *mutates = true;
-			if (a->output_group.group >= N_GROUPS) {
-				return EINVAL;
+            if (a->output_group.group >= N_GROUPS) {
+                return EINVAL;
             }
-			break;
+            break;
 
         case ODPAT_CONTROLLER:
             break;
 
-		case ODPAT_SET_VLAN_VID:
+        case ODPAT_SET_VLAN_VID:
             *mutates = true;
-			if (a->vlan_vid.vlan_vid & htons(~VLAN_VID_MASK)) {
-				return EINVAL;
+            if (a->vlan_vid.vlan_vid & htons(~VLAN_VID_MASK)) {
+                return EINVAL;
             }
-			break;
+            break;
 
-		case ODPAT_SET_VLAN_PCP:
+        case ODPAT_SET_VLAN_PCP:
             *mutates = true;
-			if (a->vlan_pcp.vlan_pcp & ~(VLAN_PCP_MASK >> VLAN_PCP_SHIFT)) {
-				return EINVAL;
+            if (a->vlan_pcp.vlan_pcp & ~(VLAN_PCP_MASK >> VLAN_PCP_SHIFT)) {
+                return EINVAL;
             }
-			break;
+            break;
+
+        case ODPAT_SET_NW_TOS:
+            *mutates = true;
+            if (a->nw_tos.nw_tos & IP_ECN_MASK) {
+                return EINVAL;
+            }
+            break;
 
         case ODPAT_STRIP_VLAN:
         case ODPAT_SET_DL_SRC:
         case ODPAT_SET_DL_DST:
         case ODPAT_SET_NW_SRC:
         case ODPAT_SET_NW_DST:
-        case ODPAT_SET_NW_TOS:
         case ODPAT_SET_TP_SRC:
         case ODPAT_SET_TP_DST:
             *mutates = true;
             break;
 
-		default:
+        default:
             return EOPNOTSUPP;
-		}
-	}
-	return 0;
+        }
+    }
+    return 0;
 }
 
 static int
@@ -1189,7 +1195,7 @@ dp_netdev_set_nw_tos(struct ofpbuf *packet, flow_t *key,
         uint8_t *field = &nh->ip_tos;
 
         /* Set the DSCP bits and preserve the ECN bits. */
-        uint8_t new = (a->nw_tos & IP_DSCP_MASK) | (nh->ip_tos & IP_ECN_MASK);
+        uint8_t new = a->nw_tos | (nh->ip_tos & IP_ECN_MASK);
 
         nh->ip_csum = recalc_csum16(nh->ip_csum, htons((uint16_t)*field),
                 htons((uint16_t)a->nw_tos));
-- 
1.6.3.3





More information about the dev mailing list