From 5cce04b6f6527f4de2a71e22a4dc968a4c147d13 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Wed, 7 Jan 2015 12:55:49 +0100 Subject: [PATCH 1/1] datapath: move make_writable helper into common code note that skb_make_writable already exists in net/netfilter/core.c but does something slightly different. Upstream: e219512 ("net: move make_writable helper into common code") Signed-off-by: Thomas Graf Acked-by: Pravin B Shelar --- acinclude.m4 | 1 + datapath/actions.c | 39 +++++++------------- datapath/linux/compat/include/linux/skbuff.h | 5 +++ datapath/linux/compat/skbuff-openvswitch.c | 13 +++++++ 4 files changed, 33 insertions(+), 25 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 444141d7f..9766bed51 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -345,6 +345,7 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [ OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], [int.skb_zerocopy(], [OVS_DEFINE([HAVE_SKB_ZEROCOPY])]) OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], [l4_rxhash]) + OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], [skb_ensure_writable]) OVS_GREP_IFELSE([$KSRC/include/linux/types.h], [bool], [OVS_DEFINE([HAVE_BOOL_TYPE])]) diff --git a/datapath/actions.c b/datapath/actions.c index 9a49cd536..7f619153e 100644 --- a/datapath/actions.c +++ b/datapath/actions.c @@ -122,17 +122,6 @@ static bool is_flow_key_valid(const struct sw_flow_key *key) return !!key->eth.type; } -static int make_writable(struct sk_buff *skb, int write_len) -{ - if (!pskb_may_pull(skb, write_len)) - return -ENOMEM; - - if (!skb_cloned(skb) || skb_clone_writable(skb, write_len)) - return 0; - - return pskb_expand_head(skb, 0, 0, GFP_ATOMIC); -} - static int push_mpls(struct sk_buff *skb, struct sw_flow_key *key, const struct ovs_action_push_mpls *mpls) { @@ -174,7 +163,7 @@ static int pop_mpls(struct sk_buff *skb, struct sw_flow_key *key, struct ethhdr *hdr; int err; - err = make_writable(skb, skb->mac_len + MPLS_HLEN); + err = skb_ensure_writable(skb, skb->mac_len + MPLS_HLEN); if (unlikely(err)) return err; @@ -207,7 +196,7 @@ static int set_mpls(struct sk_buff *skb, struct sw_flow_key *key, __be32 *stack; int err; - err = make_writable(skb, skb->mac_len + MPLS_HLEN); + err = skb_ensure_writable(skb, skb->mac_len + MPLS_HLEN); if (unlikely(err)) return err; @@ -229,7 +218,7 @@ static int __pop_vlan_tci(struct sk_buff *skb, __be16 *current_tci) struct vlan_hdr *vhdr; int err; - err = make_writable(skb, VLAN_ETH_HLEN); + err = skb_ensure_writable(skb, VLAN_ETH_HLEN); if (unlikely(err)) return err; @@ -313,7 +302,7 @@ static int set_eth_addr(struct sk_buff *skb, struct sw_flow_key *key, const struct ovs_key_ethernet *eth_key) { int err; - err = make_writable(skb, ETH_HLEN); + err = skb_ensure_writable(skb, ETH_HLEN); if (unlikely(err)) return err; @@ -419,8 +408,8 @@ static int set_ipv4(struct sk_buff *skb, struct sw_flow_key *key, struct iphdr *nh; int err; - err = make_writable(skb, skb_network_offset(skb) + - sizeof(struct iphdr)); + err = skb_ensure_writable(skb, skb_network_offset(skb) + + sizeof(struct iphdr)); if (unlikely(err)) return err; @@ -457,8 +446,8 @@ static int set_ipv6(struct sk_buff *skb, struct sw_flow_key *key, __be32 *saddr; __be32 *daddr; - err = make_writable(skb, skb_network_offset(skb) + - sizeof(struct ipv6hdr)); + err = skb_ensure_writable(skb, skb_network_offset(skb) + + sizeof(struct ipv6hdr)); if (unlikely(err)) return err; @@ -500,7 +489,7 @@ static int set_ipv6(struct sk_buff *skb, struct sw_flow_key *key, return 0; } -/* Must follow make_writable() since that can move the skb data. */ +/* Must follow skb_ensure_writable() since that can move the skb data. */ static void set_tp_port(struct sk_buff *skb, __be16 *port, __be16 new_port, __sum16 *check) { @@ -530,8 +519,8 @@ static int set_udp(struct sk_buff *skb, struct sw_flow_key *key, struct udphdr *uh; int err; - err = make_writable(skb, skb_transport_offset(skb) + - sizeof(struct udphdr)); + err = skb_ensure_writable(skb, skb_transport_offset(skb) + + sizeof(struct udphdr)); if (unlikely(err)) return err; @@ -555,8 +544,8 @@ static int set_tcp(struct sk_buff *skb, struct sw_flow_key *key, struct tcphdr *th; int err; - err = make_writable(skb, skb_transport_offset(skb) + - sizeof(struct tcphdr)); + err = skb_ensure_writable(skb, skb_transport_offset(skb) + + sizeof(struct tcphdr)); if (unlikely(err)) return err; @@ -581,7 +570,7 @@ static int set_sctp(struct sk_buff *skb, struct sw_flow_key *key, int err; unsigned int sctphoff = skb_transport_offset(skb); - err = make_writable(skb, sctphoff + sizeof(struct sctphdr)); + err = skb_ensure_writable(skb, sctphoff + sizeof(struct sctphdr)); if (unlikely(err)) return err; diff --git a/datapath/linux/compat/include/linux/skbuff.h b/datapath/linux/compat/include/linux/skbuff.h index 67a14b762..fae39a5c7 100644 --- a/datapath/linux/compat/include/linux/skbuff.h +++ b/datapath/linux/compat/include/linux/skbuff.h @@ -324,4 +324,9 @@ static inline void __skb_fill_page_desc(struct sk_buff *skb, int i, } #endif +#ifndef HAVE_SKB_ENSURE_WRITABLE +#define skb_ensure_writable rpl_skb_ensure_writable +int skb_ensure_writable(struct sk_buff *skb, int write_len); +#endif + #endif diff --git a/datapath/linux/compat/skbuff-openvswitch.c b/datapath/linux/compat/skbuff-openvswitch.c index 65ea74726..66cc6143a 100644 --- a/datapath/linux/compat/skbuff-openvswitch.c +++ b/datapath/linux/compat/skbuff-openvswitch.c @@ -124,3 +124,16 @@ skb_zerocopy(struct sk_buff *to, struct sk_buff *from, int len, int hlen) } #endif #endif + +#ifndef HAVE_SKB_ENSURE_WRITABLE +int skb_ensure_writable(struct sk_buff *skb, int write_len) +{ + if (!pskb_may_pull(skb, write_len)) + return -ENOMEM; + + if (!skb_cloned(skb) || skb_clone_writable(skb, write_len)) + return 0; + + return pskb_expand_head(skb, 0, 0, GFP_ATOMIC); +} +#endif -- 2.20.1