[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