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