diff options
| author | Justin Pettit <jpettit@nicira.com> | 2009-11-11 14:59:49 -0800 |
|---|---|---|
| committer | Justin Pettit <jpettit@nicira.com> | 2010-02-20 02:22:26 -0800 |
| commit | 959a2ecdc8a5ffe53e74456ff6eb1ec25092db75 (patch) | |
| tree | d7f7759d577a14c00c0e255e2403a4ecd1f4534d /lib/dpif-netdev.c | |
| parent | 2f6d344525463ebe52f6bbd0e9a4cc22e33dacbe (diff) | |
| download | openvswitch-959a2ecdc8a5ffe53e74456ff6eb1ec25092db75.tar.gz | |
ofproto: Match VLAN PCP and rewrite ToS bits (OpenFlow 0.9)
Starting in OpenFlow 0.9, it is possible to match on the VLAN PCP
(priority) field and rewrite the IP ToS/DSCP bits. This check-in
provides that support and bumps the wire protocol number to 0x98.
NOTE: The wire changes come together over the set of OpenFlow 0.9 commits,
so OVS will not be OpenFlow-compatible with any official release between
this commit and the one that completes the set.
Diffstat (limited to 'lib/dpif-netdev.c')
| -rw-r--r-- | lib/dpif-netdev.c | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 1dee14b47..8a749b184 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -663,7 +663,6 @@ dp_netdev_lookup_flow(const struct dp_netdev *dp, const flow_t *key) { struct dp_netdev_flow *flow; - assert(key->reserved == 0); HMAP_FOR_EACH_WITH_HASH (flow, struct dp_netdev_flow, node, flow_hash(key, 0), &dp->flow_table) { if (flow_equal(&flow->key, key)) { @@ -761,6 +760,7 @@ dpif_netdev_validate_actions(const union odp_action *actions, int n_actions, 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; @@ -805,7 +805,6 @@ add_flow(struct dpif *dpif, struct odp_flow *odp_flow) flow = xzalloc(sizeof *flow); flow->key = odp_flow->key; - flow->key.reserved = 0; error = set_flow_actions(flow, odp_flow); if (error) { @@ -1171,6 +1170,23 @@ dp_netdev_set_nw_addr(struct ofpbuf *packet, flow_t *key, } static void +dp_netdev_set_nw_tos(struct ofpbuf *packet, flow_t *key, + const struct odp_action_nw_tos *a) +{ + if (key->dl_type == htons(ETH_TYPE_IP)) { + struct ip_header *nh = packet->l3; + uint8_t *field = &nh->ip_tos; + + /* We only set the lower 6 bits. */ + uint8_t new = (a->nw_tos & 0x3f) | (nh->ip_tos & 0xc0); + + nh->ip_csum = recalc_csum16(nh->ip_csum, htons((uint16_t)*field), + htons((uint16_t)a->nw_tos)); + *field = new; + } +} + +static void dp_netdev_set_tp_port(struct ofpbuf *packet, flow_t *key, const struct odp_action_tp_port *a) { @@ -1293,6 +1309,10 @@ dp_netdev_execute_actions(struct dp_netdev *dp, dp_netdev_set_nw_addr(packet, key, &a->nw_addr); break; + case ODPAT_SET_NW_TOS: + dp_netdev_set_nw_tos(packet, key, &a->nw_tos); + break; + case ODPAT_SET_TP_SRC: case ODPAT_SET_TP_DST: dp_netdev_set_tp_port(packet, key, &a->tp_port); |
