mirror of
https://github.com/openvswitch/ovs
synced 2025-09-02 15:25:22 +00:00
meta-flow: Add OF1.2-like MFF_VLAN_VID and MFF_VLAN_PCP.
OpenFlow 1.0 and 1.2 have notions of VLAN that are different enough to warrant separate "meta-flow" fields, which this commit adds. Signed-off-by: Ben Pfaff <blp@nicira.com> Acked-by: Simon Horman <horms@verge.net.au>
This commit is contained in:
@@ -274,6 +274,31 @@ cls_rule_set_dl_vlan(struct cls_rule *rule, ovs_be16 dl_vlan)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Sets the VLAN VID that 'flow' matches to 'vid', which is interpreted as an
|
||||||
|
* OpenFlow 1.2 "vlan_vid" value, that is, the low 13 bits of 'vlan_tci' (VID
|
||||||
|
* plus CFI). */
|
||||||
|
void
|
||||||
|
cls_rule_set_vlan_vid(struct cls_rule *rule, ovs_be16 vid)
|
||||||
|
{
|
||||||
|
cls_rule_set_vlan_vid_masked(rule, vid, htons(VLAN_VID_MASK | VLAN_CFI));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Sets the VLAN VID that 'flow' matches to 'vid', which is interpreted as an
|
||||||
|
* OpenFlow 1.2 "vlan_vid" value, that is, the low 13 bits of 'vlan_tci' (VID
|
||||||
|
* plus CFI), with the corresponding 'mask'. */
|
||||||
|
void
|
||||||
|
cls_rule_set_vlan_vid_masked(struct cls_rule *rule,
|
||||||
|
ovs_be16 vid, ovs_be16 mask)
|
||||||
|
{
|
||||||
|
ovs_be16 pcp_mask = htons(VLAN_PCP_MASK);
|
||||||
|
ovs_be16 vid_mask = htons(VLAN_VID_MASK | VLAN_CFI);
|
||||||
|
|
||||||
|
mask &= vid_mask;
|
||||||
|
flow_set_vlan_vid(&rule->flow, vid & mask);
|
||||||
|
rule->wc.vlan_tci_mask = mask | (rule->wc.vlan_tci_mask & pcp_mask);
|
||||||
|
}
|
||||||
|
|
||||||
/* Modifies 'rule' so that the VLAN PCP is wildcarded. If the VID is already
|
/* Modifies 'rule' so that the VLAN PCP is wildcarded. If the VID is already
|
||||||
* wildcarded, then 'rule' will match a packet regardless of whether it has an
|
* wildcarded, then 'rule' will match a packet regardless of whether it has an
|
||||||
* 802.1Q header or not. */
|
* 802.1Q header or not. */
|
||||||
|
@@ -112,6 +112,9 @@ void cls_rule_set_dl_tci_masked(struct cls_rule *,
|
|||||||
ovs_be16 tci, ovs_be16 mask);
|
ovs_be16 tci, ovs_be16 mask);
|
||||||
void cls_rule_set_any_vid(struct cls_rule *);
|
void cls_rule_set_any_vid(struct cls_rule *);
|
||||||
void cls_rule_set_dl_vlan(struct cls_rule *, ovs_be16);
|
void cls_rule_set_dl_vlan(struct cls_rule *, ovs_be16);
|
||||||
|
void cls_rule_set_vlan_vid(struct cls_rule *, ovs_be16);
|
||||||
|
void cls_rule_set_vlan_vid_masked(struct cls_rule *,
|
||||||
|
ovs_be16 vid, ovs_be16 mask);
|
||||||
void cls_rule_set_any_pcp(struct cls_rule *);
|
void cls_rule_set_any_pcp(struct cls_rule *);
|
||||||
void cls_rule_set_dl_vlan_pcp(struct cls_rule *, uint8_t);
|
void cls_rule_set_dl_vlan_pcp(struct cls_rule *, uint8_t);
|
||||||
void cls_rule_set_tp_src(struct cls_rule *, ovs_be16);
|
void cls_rule_set_tp_src(struct cls_rule *, ovs_be16);
|
||||||
|
11
lib/flow.c
11
lib/flow.c
@@ -979,6 +979,17 @@ flow_set_dl_vlan(struct flow *flow, ovs_be16 vid)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Sets the VLAN VID that 'flow' matches to 'vid', which is interpreted as an
|
||||||
|
* OpenFlow 1.2 "vlan_vid" value, that is, the low 13 bits of 'vlan_tci' (VID
|
||||||
|
* plus CFI). */
|
||||||
|
void
|
||||||
|
flow_set_vlan_vid(struct flow *flow, ovs_be16 vid)
|
||||||
|
{
|
||||||
|
ovs_be16 mask = htons(VLAN_VID_MASK | VLAN_CFI);
|
||||||
|
flow->vlan_tci &= ~mask;
|
||||||
|
flow->vlan_tci |= vid & mask;
|
||||||
|
}
|
||||||
|
|
||||||
/* Sets the VLAN PCP that 'flow' matches to 'pcp', which should be in the
|
/* Sets the VLAN PCP that 'flow' matches to 'pcp', which should be in the
|
||||||
* range 0...7.
|
* range 0...7.
|
||||||
*
|
*
|
||||||
|
@@ -118,6 +118,7 @@ static inline bool flow_equal(const struct flow *, const struct flow *);
|
|||||||
static inline size_t flow_hash(const struct flow *, uint32_t basis);
|
static inline size_t flow_hash(const struct flow *, uint32_t basis);
|
||||||
|
|
||||||
void flow_set_dl_vlan(struct flow *, ovs_be16 vid);
|
void flow_set_dl_vlan(struct flow *, ovs_be16 vid);
|
||||||
|
void flow_set_vlan_vid(struct flow *, ovs_be16 vid);
|
||||||
void flow_set_vlan_pcp(struct flow *, uint8_t pcp);
|
void flow_set_vlan_pcp(struct flow *, uint8_t pcp);
|
||||||
|
|
||||||
void flow_compose(struct ofpbuf *, const struct flow *);
|
void flow_compose(struct ofpbuf *, const struct flow *);
|
||||||
|
@@ -163,6 +163,15 @@ static const struct mf_field mf_fields[MFF_N_IDS] = {
|
|||||||
MFS_DECIMAL,
|
MFS_DECIMAL,
|
||||||
MFP_NONE,
|
MFP_NONE,
|
||||||
true,
|
true,
|
||||||
|
0, NULL,
|
||||||
|
0, NULL,
|
||||||
|
}, {
|
||||||
|
MFF_VLAN_VID, "vlan_vid", NULL,
|
||||||
|
sizeof(ovs_be16), 12,
|
||||||
|
MFM_FULLY, 0,
|
||||||
|
MFS_DECIMAL,
|
||||||
|
MFP_NONE,
|
||||||
|
true,
|
||||||
OXM_OF_VLAN_VID, "OXM_OF_VLAN_VID",
|
OXM_OF_VLAN_VID, "OXM_OF_VLAN_VID",
|
||||||
OXM_OF_VLAN_VID, "OXM_OF_VLAN_VID",
|
OXM_OF_VLAN_VID, "OXM_OF_VLAN_VID",
|
||||||
}, {
|
}, {
|
||||||
@@ -172,6 +181,15 @@ static const struct mf_field mf_fields[MFF_N_IDS] = {
|
|||||||
MFS_DECIMAL,
|
MFS_DECIMAL,
|
||||||
MFP_NONE,
|
MFP_NONE,
|
||||||
true,
|
true,
|
||||||
|
0, NULL,
|
||||||
|
0, NULL,
|
||||||
|
}, {
|
||||||
|
MFF_VLAN_PCP, "vlan_pcp", NULL,
|
||||||
|
1, 3,
|
||||||
|
MFM_NONE, 0,
|
||||||
|
MFS_DECIMAL,
|
||||||
|
MFP_NONE,
|
||||||
|
true,
|
||||||
OXM_OF_VLAN_PCP, "OXM_OF_VLAN_PCP",
|
OXM_OF_VLAN_PCP, "OXM_OF_VLAN_PCP",
|
||||||
OXM_OF_VLAN_PCP, "OXM_OF_VLAN_PCP",
|
OXM_OF_VLAN_PCP, "OXM_OF_VLAN_PCP",
|
||||||
},
|
},
|
||||||
@@ -590,7 +608,10 @@ mf_is_all_wild(const struct mf_field *mf, const struct flow_wildcards *wc)
|
|||||||
return !wc->vlan_tci_mask;
|
return !wc->vlan_tci_mask;
|
||||||
case MFF_DL_VLAN:
|
case MFF_DL_VLAN:
|
||||||
return !(wc->vlan_tci_mask & htons(VLAN_VID_MASK));
|
return !(wc->vlan_tci_mask & htons(VLAN_VID_MASK));
|
||||||
|
case MFF_VLAN_VID:
|
||||||
|
return !(wc->vlan_tci_mask & htons(VLAN_VID_MASK | VLAN_CFI));
|
||||||
case MFF_DL_VLAN_PCP:
|
case MFF_DL_VLAN_PCP:
|
||||||
|
case MFF_VLAN_PCP:
|
||||||
return !(wc->vlan_tci_mask & htons(VLAN_PCP_MASK));
|
return !(wc->vlan_tci_mask & htons(VLAN_PCP_MASK));
|
||||||
|
|
||||||
case MFF_IPV4_SRC:
|
case MFF_IPV4_SRC:
|
||||||
@@ -681,7 +702,11 @@ mf_get_mask(const struct mf_field *mf, const struct flow_wildcards *wc,
|
|||||||
case MFF_DL_VLAN:
|
case MFF_DL_VLAN:
|
||||||
mask->be16 = wc->vlan_tci_mask & htons(VLAN_VID_MASK);
|
mask->be16 = wc->vlan_tci_mask & htons(VLAN_VID_MASK);
|
||||||
break;
|
break;
|
||||||
|
case MFF_VLAN_VID:
|
||||||
|
mask->be16 = wc->vlan_tci_mask & htons(VLAN_VID_MASK | VLAN_CFI);
|
||||||
|
break;
|
||||||
case MFF_DL_VLAN_PCP:
|
case MFF_DL_VLAN_PCP:
|
||||||
|
case MFF_VLAN_PCP:
|
||||||
mask->u8 = vlan_tci_to_pcp(wc->vlan_tci_mask);
|
mask->u8 = vlan_tci_to_pcp(wc->vlan_tci_mask);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -888,8 +913,11 @@ mf_is_value_valid(const struct mf_field *mf, const union mf_value *value)
|
|||||||
|
|
||||||
case MFF_DL_VLAN:
|
case MFF_DL_VLAN:
|
||||||
return !(value->be16 & htons(VLAN_CFI | VLAN_PCP_MASK));
|
return !(value->be16 & htons(VLAN_CFI | VLAN_PCP_MASK));
|
||||||
|
case MFF_VLAN_VID:
|
||||||
|
return !(value->be16 & htons(VLAN_PCP_MASK));
|
||||||
|
|
||||||
case MFF_DL_VLAN_PCP:
|
case MFF_DL_VLAN_PCP:
|
||||||
|
case MFF_VLAN_PCP:
|
||||||
return !(value->u8 & ~(VLAN_PCP_MASK >> VLAN_PCP_SHIFT));
|
return !(value->u8 & ~(VLAN_PCP_MASK >> VLAN_PCP_SHIFT));
|
||||||
|
|
||||||
case MFF_IPV6_LABEL:
|
case MFF_IPV6_LABEL:
|
||||||
@@ -942,8 +970,12 @@ mf_get_value(const struct mf_field *mf, const struct flow *flow,
|
|||||||
case MFF_DL_VLAN:
|
case MFF_DL_VLAN:
|
||||||
value->be16 = flow->vlan_tci & htons(VLAN_VID_MASK);
|
value->be16 = flow->vlan_tci & htons(VLAN_VID_MASK);
|
||||||
break;
|
break;
|
||||||
|
case MFF_VLAN_VID:
|
||||||
|
value->be16 = flow->vlan_tci & htons(VLAN_VID_MASK | VLAN_CFI);
|
||||||
|
break;
|
||||||
|
|
||||||
case MFF_DL_VLAN_PCP:
|
case MFF_DL_VLAN_PCP:
|
||||||
|
case MFF_VLAN_PCP:
|
||||||
value->u8 = vlan_tci_to_pcp(flow->vlan_tci);
|
value->u8 = vlan_tci_to_pcp(flow->vlan_tci);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1081,8 +1113,12 @@ mf_set_value(const struct mf_field *mf,
|
|||||||
case MFF_DL_VLAN:
|
case MFF_DL_VLAN:
|
||||||
cls_rule_set_dl_vlan(rule, value->be16);
|
cls_rule_set_dl_vlan(rule, value->be16);
|
||||||
break;
|
break;
|
||||||
|
case MFF_VLAN_VID:
|
||||||
|
cls_rule_set_vlan_vid(rule, value->be16);
|
||||||
|
break;
|
||||||
|
|
||||||
case MFF_DL_VLAN_PCP:
|
case MFF_DL_VLAN_PCP:
|
||||||
|
case MFF_VLAN_PCP:
|
||||||
cls_rule_set_dl_vlan_pcp(rule, value->u8);
|
cls_rule_set_dl_vlan_pcp(rule, value->u8);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1220,8 +1256,12 @@ mf_set_flow_value(const struct mf_field *mf,
|
|||||||
case MFF_DL_VLAN:
|
case MFF_DL_VLAN:
|
||||||
flow_set_dl_vlan(flow, value->be16);
|
flow_set_dl_vlan(flow, value->be16);
|
||||||
break;
|
break;
|
||||||
|
case MFF_VLAN_VID:
|
||||||
|
flow_set_vlan_vid(flow, value->be16);
|
||||||
|
break;
|
||||||
|
|
||||||
case MFF_DL_VLAN_PCP:
|
case MFF_DL_VLAN_PCP:
|
||||||
|
case MFF_VLAN_PCP:
|
||||||
flow_set_vlan_pcp(flow, value->u8);
|
flow_set_vlan_pcp(flow, value->u8);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1375,10 +1415,12 @@ mf_set_wild(const struct mf_field *mf, struct cls_rule *rule)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case MFF_DL_VLAN:
|
case MFF_DL_VLAN:
|
||||||
|
case MFF_VLAN_VID:
|
||||||
cls_rule_set_any_vid(rule);
|
cls_rule_set_any_vid(rule);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MFF_DL_VLAN_PCP:
|
case MFF_DL_VLAN_PCP:
|
||||||
|
case MFF_VLAN_PCP:
|
||||||
cls_rule_set_any_pcp(rule);
|
cls_rule_set_any_pcp(rule);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1505,6 +1547,7 @@ mf_set(const struct mf_field *mf,
|
|||||||
case MFF_ETH_TYPE:
|
case MFF_ETH_TYPE:
|
||||||
case MFF_DL_VLAN:
|
case MFF_DL_VLAN:
|
||||||
case MFF_DL_VLAN_PCP:
|
case MFF_DL_VLAN_PCP:
|
||||||
|
case MFF_VLAN_PCP:
|
||||||
case MFF_IP_PROTO:
|
case MFF_IP_PROTO:
|
||||||
case MFF_IP_TTL:
|
case MFF_IP_TTL:
|
||||||
case MFF_IP_DSCP:
|
case MFF_IP_DSCP:
|
||||||
@@ -1550,6 +1593,10 @@ mf_set(const struct mf_field *mf,
|
|||||||
cls_rule_set_dl_tci_masked(rule, value->be16, mask->be16);
|
cls_rule_set_dl_tci_masked(rule, value->be16, mask->be16);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MFF_VLAN_VID:
|
||||||
|
cls_rule_set_vlan_vid_masked(rule, value->be16, mask->be16);
|
||||||
|
break;
|
||||||
|
|
||||||
case MFF_IPV4_SRC:
|
case MFF_IPV4_SRC:
|
||||||
cls_rule_set_nw_src_masked(rule, value->be32, mask->be32);
|
cls_rule_set_nw_src_masked(rule, value->be32, mask->be32);
|
||||||
break;
|
break;
|
||||||
@@ -1726,8 +1773,12 @@ mf_random_value(const struct mf_field *mf, union mf_value *value)
|
|||||||
case MFF_DL_VLAN:
|
case MFF_DL_VLAN:
|
||||||
value->be16 &= htons(VLAN_VID_MASK);
|
value->be16 &= htons(VLAN_VID_MASK);
|
||||||
break;
|
break;
|
||||||
|
case MFF_VLAN_VID:
|
||||||
|
value->be16 &= htons(VLAN_VID_MASK | VLAN_CFI);
|
||||||
|
break;
|
||||||
|
|
||||||
case MFF_DL_VLAN_PCP:
|
case MFF_DL_VLAN_PCP:
|
||||||
|
case MFF_VLAN_PCP:
|
||||||
value->u8 &= 0x07;
|
value->u8 &= 0x07;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@@ -67,7 +67,9 @@ enum mf_field_id {
|
|||||||
|
|
||||||
MFF_VLAN_TCI, /* be16 */
|
MFF_VLAN_TCI, /* be16 */
|
||||||
MFF_DL_VLAN, /* be16 (OpenFlow 1.0 compatibility) */
|
MFF_DL_VLAN, /* be16 (OpenFlow 1.0 compatibility) */
|
||||||
|
MFF_VLAN_VID, /* be16 (OpenFlow 1.2 compatibility) */
|
||||||
MFF_DL_VLAN_PCP, /* u8 (OpenFlow 1.0 compatibility) */
|
MFF_DL_VLAN_PCP, /* u8 (OpenFlow 1.0 compatibility) */
|
||||||
|
MFF_VLAN_PCP, /* be16 (OpenFlow 1.2 compatibility) */
|
||||||
|
|
||||||
/* L3. */
|
/* L3. */
|
||||||
MFF_IPV4_SRC, /* be32 */
|
MFF_IPV4_SRC, /* be32 */
|
||||||
|
Reference in New Issue
Block a user