X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fdpif-netdev.c;h=aa4fdf830bf8cc7c14a3cf52c793c5553d26a4f6;hb=cb49ee4fd15e1b24aaae4a2d25f3dd538734b4df;hp=daaa12280f5ac82e7047ed326d9015e9c880854b;hpb=ae412e7dd89489911a32c6723d4109c6d1de3a38;p=openvswitch diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index daaa1228..aa4fdf83 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -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: