[ovs-dev] [IP DEFRAG ACTION RFC 2/2] datapath: add ip_defag action
Andy Zhou
azhou at nicira.com
Mon Nov 10 22:52:54 UTC 2014
Implements ip_defrag action in Linux kenrel using ip_defrag kernel APIs.
Signed-off-by: Andy Zhou <azhou at nicira.com>
---
datapath/actions.c | 39 ++++++++++++++++++++++++++++++++++++++-
datapath/flow_netlink.c | 6 +++++-
2 files changed, 43 insertions(+), 2 deletions(-)
diff --git a/datapath/actions.c b/datapath/actions.c
index 5a1dbe2..668d44f 100644
--- a/datapath/actions.c
+++ b/datapath/actions.c
@@ -826,6 +826,38 @@ static int execute_recirc(struct datapath *dp, struct sk_buff *skb,
return 0;
}
+static int ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
+{
+ int err;
+
+ local_bh_disable();
+ err = ip_defrag(skb, user);
+ local_bh_enable();
+
+ if (!err) {
+ ip_send_check(ip_hdr(skb));
+ skb->ignore_df = 1;
+ }
+
+ return err;
+}
+
+static int execute_ip_defrag(struct sk_buff *skb, struct sw_flow_key *key,
+ const struct ovs_action_ip_defrag *act_ip_defrag)
+{
+ if (key->eth.type == htons(ETH_P_IP)) {
+ if (ip_is_fragment(ip_hdr(skb))) {
+ enum ip_defrag_users user;
+
+ user = IP_DEFRAG_CONNTRACK_IN + act_ip_defrag->zone;
+ if (ipv4_gather_frags(skb, user))
+ return -EINPROGRESS;
+ }
+ }
+
+ return 0;
+}
+
/* Execute a list of actions against 'skb'. */
static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
struct sw_flow_key *key,
@@ -902,10 +934,15 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
case OVS_ACTION_ATTR_SAMPLE:
err = sample(dp, skb, key, a);
break;
+
+ case OVS_ACTION_ATTR_IP_DEFRAG:
+ err = execute_ip_defrag(skb, key, nla_data(a));
+ break;
}
if (unlikely(err)) {
- kfree_skb(skb);
+ if (err != -EINPROGRESS)
+ kfree_skb(skb);
return err;
}
}
diff --git a/datapath/flow_netlink.c b/datapath/flow_netlink.c
index 503cf63..d96ad65 100644
--- a/datapath/flow_netlink.c
+++ b/datapath/flow_netlink.c
@@ -1782,7 +1782,8 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr,
[OVS_ACTION_ATTR_POP_VLAN] = 0,
[OVS_ACTION_ATTR_SET] = (u32)-1,
[OVS_ACTION_ATTR_SAMPLE] = (u32)-1,
- [OVS_ACTION_ATTR_HASH] = sizeof(struct ovs_action_hash)
+ [OVS_ACTION_ATTR_HASH] = sizeof(struct ovs_action_hash),
+ [OVS_ACTION_ATTR_IP_DEFRAG] = sizeof(struct ovs_action_ip_defrag)
};
const struct ovs_action_push_vlan *vlan;
int type = nla_type(a);
@@ -1899,6 +1900,9 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr,
skip_copy = true;
break;
+ case OVS_ACTION_ATTR_IP_DEFRAG:
+ break;
+
default:
OVS_NLERR(log, "Unknown Action type %d", type);
return -EINVAL;
--
1.9.1
More information about the dev
mailing list