WIP
---
 datapath/actions.c      |  8 ++++++++
 datapath/flow.h         |  1 +
 datapath/flow_netlink.c | 22 ++++++++++++++++++++++
 3 files changed, 31 insertions(+)

diff --git a/datapath/actions.c b/datapath/actions.c
index beed5d8..05b465c 100644
--- a/datapath/actions.c
+++ b/datapath/actions.c
@@ -750,6 +750,7 @@ static int conntrack(struct datapath *dp, struct sk_buff 
*skb,
 {
        int nh_ofs = skb_network_offset(skb);
        struct net *net = ovs_dp_get_net(dp);
+       struct nf_conn *ct = info->ct;
 
        if (skb->nfct) {
                pr_warn_once("Attempt to run through conntrack again\n");
@@ -759,6 +760,13 @@ static int conntrack(struct datapath *dp, struct sk_buff 
*skb,
        /* The conntrack module expects to be working at L3. */
        skb_pull(skb, nh_ofs);
 
+       /* Associate skb with specified zone */
+       if (ct) {
+               atomic_inc(&ct->ct_general.use);
+               skb->nfct = &ct->ct_general;
+               skb->nfctinfo = IP_CT_NEW;
+       }
+
        /* xxx What's the best return val? */
        if (nf_conntrack_in(net, PF_INET, NF_INET_PRE_ROUTING, skb) != 
NF_ACCEPT)
                return EINVAL;
diff --git a/datapath/flow.h b/datapath/flow.h
index 2b26232..ce74958 100644
--- a/datapath/flow.h
+++ b/datapath/flow.h
@@ -121,6 +121,7 @@ static inline void ovs_flow_tun_info_init(struct 
ovs_tunnel_info *tun_info,
 
 struct ovs_conntrack_info {
        u16 zone;
+       struct nf_conn *ct;
 };
 
 #define OVS_SW_FLOW_KEY_METADATA_SIZE                  \
diff --git a/datapath/flow_netlink.c b/datapath/flow_netlink.c
index 3c57ead..75dc87f 100644
--- a/datapath/flow_netlink.c
+++ b/datapath/flow_netlink.c
@@ -1352,6 +1352,23 @@ static struct sw_flow_actions 
*nla_alloc_flow_actions(int size)
 
 void ovs_nla_free_flow_actions(struct sw_flow_actions *sf_acts)
 {
+       if (sf_acts) {
+               struct ovs_conntrack_info *ct_info;
+               struct nlattr *a;
+               int rem, len = sf_acts->actions_len;
+
+               for (a = sf_acts->actions, rem = len; rem > 0;
+                       a = nla_next(a, &rem)) {
+                       switch (nla_type(a)) {
+                       case OVS_ACTION_ATTR_CONNTRACK:
+                               ct_info = nla_data(a);
+                               if (ct_info->ct)
+                                       nf_ct_put(ct_info->ct);
+                               break;
+                       }
+               }
+       }
+
        kfree(sf_acts);
 }
 
@@ -1500,6 +1517,11 @@ static int validate_and_copy_conntrack(struct net *net,
                case OVS_CT_ATTR_ZONE:
                        memset(&t, 0, sizeof(t));
                        ct_info.zone = nla_get_u16(a);
+                       ct_info.ct = nf_conntrack_alloc(net, ct_info.zone, &t, 
&t, GFP_KERNEL);
+                       if (!ct_info.ct)
+                               return -ENOMEM;
+
+                       nf_conntrack_tmpl_insert(net, ct_info.ct);
                        break;
                default:
                        OVS_NLERR("Unknown conntrack attribute (%d).\n", type);
-- 
1.9.3

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to