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
[email protected]
http://openvswitch.org/mailman/listinfo/dev