Describe dummy test model. Work on OpenFlow intro.
[openvswitch] / datapath / flow.c
index 2acdd0599acda08795d0e91ce1928feefb9cbed4..0c3d75fd2f8d158f15746220bc5a71819b7f956e 100644 (file)
@@ -622,8 +622,9 @@ int ovs_flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key,
 
        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);
 
@@ -784,10 +785,10 @@ static u32 ovs_flow_hash(const struct sw_flow_key *key, int key_start, int key_l
 
 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,
@@ -835,6 +836,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),
@@ -1024,6 +1026,15 @@ 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)) {
+               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)) {
@@ -1034,21 +1045,17 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
 
                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]);
@@ -1056,7 +1063,8 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
                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);
        }
 
@@ -1199,14 +1207,15 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
 
 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);
@@ -1224,23 +1233,23 @@ int ovs_flow_metadata_from_nlattrs(struct sw_flow *flow, int key_len, const stru
                                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)
@@ -1257,6 +1266,14 @@ int ovs_flow_metadata_from_nlattrs(struct sw_flow *flow, int key_len, const stru
                                        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;
                        }
                }
        }
@@ -1278,22 +1295,26 @@ int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
            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;