2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-30 22:05:19 +00:00

datapath: Combine dl_vlan and dl_vlan_pcp.

This allows eliminating padding from odp_flow_key, although actually doing
that is postponed until the next commit.

Signed-off-by: Ben Pfaff <blp@nicira.com>
Acked-by: Jesse Gross <jesse@nicira.com>
This commit is contained in:
Ben Pfaff
2010-10-08 16:26:21 -07:00
parent ae412e7dd8
commit 26233bb461
11 changed files with 147 additions and 108 deletions

View File

@@ -665,16 +665,14 @@ dpif_netdev_validate_actions(const union odp_action *actions, int n_actions,
case ODPAT_CONTROLLER:
break;
case ODPAT_SET_VLAN_VID:
case ODPAT_SET_DL_TCI:
*mutates = true;
if (a->vlan_vid.vlan_vid & htons(~VLAN_VID_MASK)) {
if (a->dl_tci.mask != htons(VLAN_VID_MASK)
&& a->dl_tci.mask != htons(VLAN_PCP_MASK)
&& a->dl_tci.mask != htons(VLAN_VID_MASK | VLAN_PCP_MASK)) {
return EINVAL;
}
break;
case ODPAT_SET_VLAN_PCP:
*mutates = true;
if (a->vlan_pcp.vlan_pcp & ~(VLAN_PCP_MASK >> VLAN_PCP_SHIFT)) {
if (a->dl_tci.tci & ~a->dl_tci.mask){
return EINVAL;
}
break;
@@ -1013,16 +1011,16 @@ dp_netdev_wait(void)
}
/* Modify the TCI field of 'packet'. If a VLAN tag is not present, one
* is added with the TCI field set to 'tci'. If a VLAN tag is present,
* then 'mask' bits are cleared before 'tci' is logically OR'd into the
* TCI field.
/* Modify the TCI field of 'packet'. If a VLAN tag is not present, one is
* added with the TCI field set to 'a->tci'. If a VLAN tag is present, then
* 'a->mask' bits are cleared before 'a->tci' is logically OR'd into the TCI
* field.
*
* Note that the function does not ensure that 'tci' does not affect
* bits outside of 'mask'.
* Note that the function does not ensure that 'a->tci' does not affect bits
* outside of 'a->mask'.
*/
static void
dp_netdev_modify_vlan_tci(struct ofpbuf *packet, uint16_t tci, uint16_t mask)
dp_netdev_set_dl_tci(struct ofpbuf *packet, const struct odp_action_dl_tci *a)
{
struct vlan_eth_header *veh;
struct eth_header *eh;
@@ -1032,15 +1030,14 @@ dp_netdev_modify_vlan_tci(struct ofpbuf *packet, uint16_t tci, uint16_t mask)
&& eh->eth_type == htons(ETH_TYPE_VLAN)) {
/* Clear 'mask' bits, but maintain other TCI bits. */
veh = packet->l2;
veh->veth_tci &= ~htons(mask);
veh->veth_tci |= htons(tci);
veh->veth_tci = (veh->veth_tci & ~a->mask) | a->tci;
} else {
/* Insert new 802.1Q header. */
struct vlan_eth_header tmp;
memcpy(tmp.veth_dst, eh->eth_dst, ETH_ADDR_LEN);
memcpy(tmp.veth_src, eh->eth_src, ETH_ADDR_LEN);
tmp.veth_type = htons(ETH_TYPE_VLAN);
tmp.veth_tci = htons(tci);
tmp.veth_tci = htons(a->tci);
tmp.veth_next_type = eh->eth_type;
veh = ofpbuf_push_uninit(packet, VLAN_HEADER_LEN);
@@ -1237,15 +1234,8 @@ dp_netdev_execute_actions(struct dp_netdev *dp,
key->in_port, a->controller.arg);
break;
case ODPAT_SET_VLAN_VID:
dp_netdev_modify_vlan_tci(packet, ntohs(a->vlan_vid.vlan_vid),
VLAN_VID_MASK);
break;
case ODPAT_SET_VLAN_PCP:
dp_netdev_modify_vlan_tci(packet,
a->vlan_pcp.vlan_pcp << VLAN_PCP_SHIFT,
VLAN_PCP_MASK);
case ODPAT_SET_DL_TCI:
dp_netdev_set_dl_tci(packet, &a->dl_tci);
break;
case ODPAT_STRIP_VLAN: