|
@@ -604,6 +604,7 @@ int ovs_flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key,
|
|
|
|
|
|
key->phy.priority = skb->priority;
|
|
|
key->phy.in_port = in_port;
|
|
|
+ key->phy.skb_mark = skb->mark;
|
|
|
|
|
|
skb_reset_mac_header(skb);
|
|
|
|
|
@@ -803,6 +804,7 @@ const int ovs_key_lens[OVS_KEY_ATTR_MAX + 1] = {
|
|
|
[OVS_KEY_ATTR_ENCAP] = -1,
|
|
|
[OVS_KEY_ATTR_PRIORITY] = sizeof(u32),
|
|
|
[OVS_KEY_ATTR_IN_PORT] = sizeof(u32),
|
|
|
+ [OVS_KEY_ATTR_SKB_MARK] = sizeof(u32),
|
|
|
[OVS_KEY_ATTR_ETHERNET] = sizeof(struct ovs_key_ethernet),
|
|
|
[OVS_KEY_ATTR_VLAN] = sizeof(__be16),
|
|
|
[OVS_KEY_ATTR_ETHERTYPE] = sizeof(__be16),
|
|
@@ -988,6 +990,10 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
|
|
|
} else {
|
|
|
swkey->phy.in_port = DP_MAX_PORTS;
|
|
|
}
|
|
|
+ if (attrs & (1 << OVS_KEY_ATTR_SKB_MARK)) {
|
|
|
+ swkey->phy.skb_mark = nla_get_u32(a[OVS_KEY_ATTR_SKB_MARK]);
|
|
|
+ attrs &= ~(1 << OVS_KEY_ATTR_SKB_MARK);
|
|
|
+ }
|
|
|
|
|
|
/* Data attributes. */
|
|
|
if (!(attrs & (1 << OVS_KEY_ATTR_ETHERNET)))
|
|
@@ -1115,6 +1121,8 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
|
|
|
|
|
|
/**
|
|
|
* ovs_flow_metadata_from_nlattrs - parses Netlink attributes into a flow key.
|
|
|
+ * @priority: receives the skb priority
|
|
|
+ * @mark: receives the skb mark
|
|
|
* @in_port: receives the extracted input port.
|
|
|
* @key: Netlink attribute holding nested %OVS_KEY_ATTR_* Netlink attribute
|
|
|
* sequence.
|
|
@@ -1124,7 +1132,7 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
|
|
|
* get the metadata, that is, the parts of the flow key that cannot be
|
|
|
* extracted from the packet itself.
|
|
|
*/
|
|
|
-int ovs_flow_metadata_from_nlattrs(u32 *priority, u16 *in_port,
|
|
|
+int ovs_flow_metadata_from_nlattrs(u32 *priority, u32 *mark, u16 *in_port,
|
|
|
const struct nlattr *attr)
|
|
|
{
|
|
|
const struct nlattr *nla;
|
|
@@ -1132,6 +1140,7 @@ int ovs_flow_metadata_from_nlattrs(u32 *priority, u16 *in_port,
|
|
|
|
|
|
*in_port = DP_MAX_PORTS;
|
|
|
*priority = 0;
|
|
|
+ *mark = 0;
|
|
|
|
|
|
nla_for_each_nested(nla, attr, rem) {
|
|
|
int type = nla_type(nla);
|
|
@@ -1150,6 +1159,10 @@ int ovs_flow_metadata_from_nlattrs(u32 *priority, u16 *in_port,
|
|
|
return -EINVAL;
|
|
|
*in_port = nla_get_u32(nla);
|
|
|
break;
|
|
|
+
|
|
|
+ case OVS_KEY_ATTR_SKB_MARK:
|
|
|
+ *mark = nla_get_u32(nla);
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -1171,6 +1184,10 @@ int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
|
|
|
nla_put_u32(skb, OVS_KEY_ATTR_IN_PORT, swkey->phy.in_port))
|
|
|
goto nla_put_failure;
|
|
|
|
|
|
+ if (swkey->phy.skb_mark &&
|
|
|
+ nla_put_u32(skb, OVS_KEY_ATTR_SKB_MARK, swkey->phy.skb_mark))
|
|
|
+ goto nla_put_failure;
|
|
|
+
|
|
|
nla = nla_reserve(skb, OVS_KEY_ATTR_ETHERNET, sizeof(*eth_key));
|
|
|
if (!nla)
|
|
|
goto nla_put_failure;
|