key->phy.priority = skb->priority;
if (OVS_CB(skb)->tun_key)
- memcpy(&key->phy.tun.tun_key, OVS_CB(skb)->tun_key, sizeof(key->phy.tun.tun_key));
+ memcpy(&key->tun_key, OVS_CB(skb)->tun_key, sizeof(key->tun_key));
key->phy.in_port = in_port;
+ key->phy.skb_mark = skb_get_mark(skb);
skb_reset_mac_header(skb);
static int flow_key_start(struct sw_flow_key *key)
{
- if (key->phy.tun.tun_key.ipv4_dst)
+ if (key->tun_key.ipv4_dst)
return 0;
else
- return offsetof(struct sw_flow_key, phy.priority);
+ return offsetof(struct sw_flow_key, phy);
}
struct sw_flow *ovs_flow_tbl_lookup(struct flow_table *table,
[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),
} else {
swkey->phy.in_port = DP_MAX_PORTS;
}
+ if (attrs & (1 << OVS_KEY_ATTR_SKB_MARK)) {
+ uint32_t mark = nla_get_u32(a[OVS_KEY_ATTR_SKB_MARK]);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) && !defined(CONFIG_NETFILTER)
+ if (mark != 0)
+ return -EINVAL;
+#endif
+ swkey->phy.skb_mark = mark;
+ attrs &= ~(1 << OVS_KEY_ATTR_SKB_MARK);
+ }
if (attrs & (1ULL << OVS_KEY_ATTR_TUN_ID) &&
attrs & (1ULL << OVS_KEY_ATTR_IPV4_TUNNEL)) {
if (!tun_key->ipv4_dst)
return -EINVAL;
- if (!(tun_key->tun_flags & OVS_FLOW_TNL_F_KEY))
+ if (!(tun_key->tun_flags & OVS_TNL_F_KEY))
return -EINVAL;
tun_id = nla_get_be64(a[OVS_KEY_ATTR_TUN_ID]);
if (tun_id != tun_key->tun_id)
return -EINVAL;
- memcpy(&swkey->phy.tun.tun_key, tun_key, sizeof(swkey->phy.tun.tun_key));
- attrs &= ~(1ULL << OVS_KEY_ATTR_TUN_ID);
- attrs &= ~(1ULL << OVS_KEY_ATTR_IPV4_TUNNEL);
- } else if (attrs & (1ULL << OVS_KEY_ATTR_TUN_ID)) {
- swkey->phy.tun.tun_key.tun_id = nla_get_be64(a[OVS_KEY_ATTR_TUN_ID]);
- swkey->phy.tun.tun_key.tun_flags |= OVS_FLOW_TNL_F_KEY;
+ memcpy(&swkey->tun_key, tun_key, sizeof(swkey->tun_key));
attrs &= ~(1ULL << OVS_KEY_ATTR_TUN_ID);
+ attrs &= ~(1ULL << OVS_KEY_ATTR_IPV4_TUNNEL);
} else if (attrs & (1ULL << OVS_KEY_ATTR_IPV4_TUNNEL)) {
struct ovs_key_ipv4_tunnel *tun_key;
tun_key = nla_data(a[OVS_KEY_ATTR_IPV4_TUNNEL]);
if (!tun_key->ipv4_dst)
return -EINVAL;
- memcpy(&swkey->phy.tun.tun_key, tun_key, sizeof(swkey->phy.tun.tun_key));
+ memcpy(&swkey->tun_key, tun_key, sizeof(swkey->tun_key));
+
attrs &= ~(1ULL << OVS_KEY_ATTR_IPV4_TUNNEL);
}
int ovs_flow_metadata_from_nlattrs(struct sw_flow *flow, int key_len, const struct nlattr *attr)
{
- struct ovs_key_ipv4_tunnel *tun_key = &flow->key.phy.tun.tun_key;
+ struct ovs_key_ipv4_tunnel *tun_key = &flow->key.tun_key;
const struct nlattr *nla;
int rem;
__be64 tun_id = 0;
flow->key.phy.in_port = DP_MAX_PORTS;
flow->key.phy.priority = 0;
- memset(tun_key, 0, sizeof(flow->key.phy.tun.tun_key));
+ flow->key.phy.skb_mark = 0;
+ memset(tun_key, 0, sizeof(flow->key.tun_key));
nla_for_each_nested(nla, attr, rem) {
int type = nla_type(nla);
tun_id = nla_get_be64(nla);
if (tun_key->ipv4_dst) {
- if (!(tun_key->tun_flags & OVS_FLOW_TNL_F_KEY))
+ if (!(tun_key->tun_flags & OVS_TNL_F_KEY))
return -EINVAL;
if (tun_key->tun_id != tun_id)
return -EINVAL;
break;
}
tun_key->tun_id = tun_id;
- tun_key->tun_flags |= OVS_FLOW_TNL_F_KEY;
+ tun_key->tun_flags |= OVS_TNL_F_KEY;
break;
case OVS_KEY_ATTR_IPV4_TUNNEL:
- if (tun_key->tun_flags & OVS_FLOW_TNL_F_KEY) {
+ if (tun_key->tun_flags & OVS_TNL_F_KEY) {
tun_id = tun_key->tun_id;
memcpy(tun_key, nla_data(nla), sizeof(*tun_key));
- if (!(tun_key->tun_flags & OVS_FLOW_TNL_F_KEY))
+ if (!(tun_key->tun_flags & OVS_TNL_F_KEY))
return -EINVAL;
if (tun_key->tun_id != tun_id)
return -EINVAL;
flow->key.phy.in_port = nla_get_u32(nla);
break;
+
+ case OVS_KEY_ATTR_SKB_MARK:
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) && !defined(CONFIG_NETFILTER)
+ if (nla_get_u32(nla) != 0)
+ return -EINVAL;
+#endif
+ flow->key.phy.skb_mark = nla_get_u32(nla);
+ break;
}
}
}
nla_put_u32(skb, OVS_KEY_ATTR_PRIORITY, swkey->phy.priority))
goto nla_put_failure;
- if (swkey->phy.tun.tun_key.ipv4_dst) {
+ if (swkey->tun_key.ipv4_dst) {
struct ovs_key_ipv4_tunnel *tun_key;
nla = nla_reserve(skb, OVS_KEY_ATTR_IPV4_TUNNEL, sizeof(*tun_key));
if (!nla)
goto nla_put_failure;
tun_key = nla_data(nla);
- memcpy(tun_key, &swkey->phy.tun.tun_key, sizeof(*tun_key));
+ memcpy(tun_key, &swkey->tun_key, sizeof(*tun_key));
}
- if ((swkey->phy.tun.tun_key.tun_flags & OVS_FLOW_TNL_F_KEY) &&
- nla_put_be64(skb, OVS_KEY_ATTR_TUN_ID, swkey->phy.tun.tun_key.tun_id))
+ if ((swkey->tun_key.tun_flags & OVS_TNL_F_KEY) &&
+ nla_put_be64(skb, OVS_KEY_ATTR_TUN_ID, swkey->tun_key.tun_id))
goto nla_put_failure;
if (swkey->phy.in_port != DP_MAX_PORTS &&
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;