From 3c5f6de3856fa47aa184ca389dcb8d4fcc13d29a Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Fri, 12 Mar 2010 16:05:25 -0500 Subject: [PATCH] datapath: Validate ToS when flow is added. 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 b6d5488ce..476786283 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 f8a2aa3c7..6365f9474 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #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 3b95e3bbc..9a94d0ba8 100644 --- a/datapath/flow.c +++ b/datapath/flow.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include "compat.h" diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index e19cb34a2..365b78a54 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)); -- 2.43.0