Signed-off-by: Pravin B Shelar <pshe...@nicira.com> --- datapath/Modules.mk | 2 - datapath/actions.c | 15 +- datapath/checksum.c | 271 --------------------- datapath/checksum.h | 173 ------------- datapath/datapath.c | 3 - datapath/datapath.h | 10 - datapath/linux/Modules.mk | 3 +- datapath/linux/compat/include/linux/netdevice.h | 7 - datapath/linux/compat/include/net/checksum.h | 12 +- datapath/linux/compat/include/net/sctp/checksum.h | 5 - datapath/linux/compat/ip_tunnels_core.c | 4 - datapath/linux/compat/skbuff-openvswitch.c | 22 -- datapath/linux/compat/utils.c | 39 +++ datapath/linux/compat/vxlan.c | 1 - datapath/vlan.h | 5 - datapath/vport-gre.c | 2 - datapath/vport-internal_dev.c | 7 - datapath/vport-lisp.c | 12 +- datapath/vport-netdev.c | 5 - datapath/vport-vxlan.c | 2 - 20 files changed, 55 insertions(+), 545 deletions(-) delete mode 100644 datapath/checksum.c delete mode 100644 datapath/checksum.h create mode 100644 datapath/linux/compat/utils.c
diff --git a/datapath/Modules.mk b/datapath/Modules.mk index ccf4dfa..e2a4dad 100644 --- a/datapath/Modules.mk +++ b/datapath/Modules.mk @@ -8,7 +8,6 @@ dist_modules = $(both_modules) # Modules to distribute openvswitch_sources = \ actions.c \ - checksum.c \ datapath.c \ dp_notify.c \ flow.c \ @@ -21,7 +20,6 @@ openvswitch_sources = \ vport-vxlan.c openvswitch_headers = \ - checksum.h \ compat.h \ datapath.h \ flow.h \ diff --git a/datapath/actions.c b/datapath/actions.c index 33633df..2a9d6e5 100644 --- a/datapath/actions.c +++ b/datapath/actions.c @@ -34,7 +34,6 @@ #include <net/dsfield.h> #include <net/sctp/checksum.h> -#include "checksum.h" #include "datapath.h" #include "vlan.h" #include "vport.h" @@ -60,7 +59,7 @@ static int __pop_vlan_tci(struct sk_buff *skb, __be16 *current_tci) if (unlikely(err)) return err; - if (get_ip_summed(skb) == OVS_CSUM_COMPLETE) + if (skb->ip_summed == CHECKSUM_COMPLETE) skb->csum = csum_sub(skb->csum, csum_partial(skb->data + (2 * ETH_ALEN), VLAN_HLEN, 0)); @@ -117,7 +116,7 @@ static int push_vlan(struct sk_buff *skb, const struct ovs_action_push_vlan *vla if (!__vlan_put_tag(skb, skb->vlan_proto, current_tag)) return -ENOMEM; - if (get_ip_summed(skb) == OVS_CSUM_COMPLETE) + if (skb->ip_summed == CHECKSUM_COMPLETE) skb->csum = csum_add(skb->csum, csum_partial(skb->data + (2 * ETH_ALEN), VLAN_HLEN, 0)); @@ -134,14 +133,14 @@ static int set_eth_addr(struct sk_buff *skb, if (unlikely(err)) return err; - if (get_ip_summed(skb) == OVS_CSUM_COMPLETE) + if (skb->ip_summed == CHECKSUM_COMPLETE) skb->csum = csum_sub(skb->csum, csum_partial(eth_hdr(skb), ETH_ALEN * 2, 0)); memcpy(eth_hdr(skb)->h_source, eth_key->eth_src, ETH_ALEN); memcpy(eth_hdr(skb)->h_dest, eth_key->eth_dst, ETH_ALEN); - if (get_ip_summed(skb) == OVS_CSUM_COMPLETE) + if (skb->ip_summed == CHECKSUM_COMPLETE) skb->csum = csum_add(skb->csum, csum_partial(eth_hdr(skb), ETH_ALEN * 2, 0)); @@ -162,7 +161,7 @@ static void set_ip_addr(struct sk_buff *skb, struct iphdr *nh, struct udphdr *uh = udp_hdr(skb); if (uh->check || - get_ip_summed(skb) == OVS_CSUM_PARTIAL) { + skb->ip_summed == CHECKSUM_PARTIAL) { inet_proto_csum_replace4(&uh->check, skb, *addr, new_addr, 1); if (!uh->check) @@ -190,7 +189,7 @@ static void update_ipv6_checksum(struct sk_buff *skb, u8 l4_proto, struct udphdr *uh = udp_hdr(skb); if (uh->check || - get_ip_summed(skb) == OVS_CSUM_PARTIAL) { + skb->ip_summed == CHECKSUM_PARTIAL) { inet_proto_csum_replace16(&uh->check, skb, addr, new_addr, 1); if (!uh->check) @@ -311,7 +310,7 @@ static void set_udp_port(struct sk_buff *skb, __be16 *port, __be16 new_port) { struct udphdr *uh = udp_hdr(skb); - if (uh->check && get_ip_summed(skb) != OVS_CSUM_PARTIAL) { + if (uh->check && skb->ip_summed != CHECKSUM_PARTIAL) { set_tp_port(skb, port, new_port, &uh->check); if (!uh->check) diff --git a/datapath/checksum.c b/datapath/checksum.c deleted file mode 100644 index 5146c65..0000000 --- a/datapath/checksum.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright (c) 2007-2011 Nicira, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/in.h> -#include <linux/ip.h> -#include <linux/tcp.h> -#include <linux/udp.h> - -#include "checksum.h" -#include "datapath.h" - -#ifdef NEED_CSUM_NORMALIZE - -#if defined(CONFIG_XEN) && defined(HAVE_PROTO_DATA_VALID) -/* This code is based on skb_checksum_setup() from Xen's net/dev/core.c. We - * can't call this function directly because it isn't exported in all - * versions. */ -static int vswitch_skb_checksum_setup(struct sk_buff *skb) -{ - struct iphdr *iph; - unsigned char *th; - int err = -EPROTO; - __u16 csum_start, csum_offset; - - if (!skb->proto_csum_blank) - return 0; - - if (skb->protocol != htons(ETH_P_IP)) - goto out; - - if (!pskb_may_pull(skb, skb_network_header(skb) + sizeof(struct iphdr) - skb->data)) - goto out; - - iph = ip_hdr(skb); - th = skb_network_header(skb) + 4 * iph->ihl; - - csum_start = th - skb->head; - switch (iph->protocol) { - case IPPROTO_TCP: - csum_offset = offsetof(struct tcphdr, check); - break; - case IPPROTO_UDP: - csum_offset = offsetof(struct udphdr, check); - break; - default: - if (net_ratelimit()) - pr_err("Attempting to checksum a non-TCP/UDP packet, " - "dropping a protocol %d packet", - iph->protocol); - goto out; - } - - if (!pskb_may_pull(skb, th + csum_offset + 2 - skb->data)) - goto out; - - skb->proto_csum_blank = 0; - set_ip_summed(skb, OVS_CSUM_PARTIAL); - set_skb_csum_pointers(skb, csum_start, csum_offset); - - err = 0; - -out: - return err; -} -#else -static int vswitch_skb_checksum_setup(struct sk_buff *skb) -{ - return 0; -} -#endif /* not Xen old style checksums */ - -/* - * compute_ip_summed - map external checksum state onto OVS representation - * - * @skb: Packet to manipulate. - * @xmit: Whether we were on transmit path of network stack. For example, - * this is true for the internal dev vport because it receives skbs - * that passed through dev_queue_xmit() but false for the netdev vport - * because its packets come from netif_receive_skb(). - * - * Older kernels (and various versions of Xen) were not explicit enough about - * checksum offload parameters and rely on a combination of context and - * non standard fields. This deals with all those variations so that we - * can internally manipulate checksum offloads without worrying about kernel - * version. - * - * Types of checksums that we can receive (these all refer to L4 checksums): - * 1. CHECKSUM_NONE: Device that did not compute checksum, contains full - * (though not verified) checksum in packet but not in skb->csum. Packets - * from the bridge local port will also have this type. - * 2. CHECKSUM_COMPLETE (CHECKSUM_HW): Good device that computes checksums, - * also the GRE module. This is the same as CHECKSUM_NONE, except it has - * a valid skb->csum. Importantly, both contain a full checksum (not - * verified) in the packet itself. The only difference is that if the - * packet gets to L4 processing on this machine (not in DomU) we won't - * have to recompute the checksum to verify. Most hardware devices do not - * produce packets with this type, even if they support receive checksum - * offloading (they produce type #5). - * 3. CHECKSUM_PARTIAL (CHECKSUM_HW): Packet without full checksum and needs to - * be computed if it is sent off box. Unfortunately on earlier kernels, - * this case is impossible to distinguish from #2, despite having opposite - * meanings. Xen adds an extra field on earlier kernels (see #4) in order - * to distinguish the different states. - * 4. CHECKSUM_UNNECESSARY (with proto_csum_blank true): This packet was - * generated locally by a Xen DomU and has a partial checksum. If it is - * handled on this machine (Dom0 or DomU), then the checksum will not be - * computed. If it goes off box, the checksum in the packet needs to be - * completed. Calling skb_checksum_setup converts this to CHECKSUM_HW - * (CHECKSUM_PARTIAL) so that the checksum can be completed. In later - * kernels, this combination is replaced with CHECKSUM_PARTIAL. - * 5. CHECKSUM_UNNECESSARY (with proto_csum_blank false): Packet with a correct - * full checksum or using a protocol without a checksum. skb->csum is - * undefined. This is common from devices with receive checksum - * offloading. This is somewhat similar to CHECKSUM_NONE, except that - * nobody will try to verify the checksum with CHECKSUM_UNNECESSARY. - * - * Note that on earlier kernels, CHECKSUM_COMPLETE and CHECKSUM_PARTIAL are - * both defined as CHECKSUM_HW. Normally the meaning of CHECKSUM_HW is clear - * based on whether it is on the transmit or receive path. After the datapath - * it will be intepreted as CHECKSUM_PARTIAL. If the packet already has a - * checksum, we will panic. Since we can receive packets with checksums, we - * assume that all CHECKSUM_HW packets have checksums and map them to - * CHECKSUM_NONE, which has a similar meaning (the it is only different if the - * packet is processed by the local IP stack, in which case it will need to - * be reverified). If we receive a packet with CHECKSUM_HW that really means - * CHECKSUM_PARTIAL, it will be sent with the wrong checksum. However, there - * shouldn't be any devices that do this with bridging. - */ -int compute_ip_summed(struct sk_buff *skb, bool xmit) -{ - /* For our convenience these defines change repeatedly between kernel - * versions, so we can't just copy them over... - */ - switch (skb->ip_summed) { - case CHECKSUM_NONE: - set_ip_summed(skb, OVS_CSUM_NONE); - break; - case CHECKSUM_UNNECESSARY: - set_ip_summed(skb, OVS_CSUM_UNNECESSARY); - break; -#ifdef CHECKSUM_HW - /* In theory this could be either CHECKSUM_PARTIAL or CHECKSUM_COMPLETE. - * However, on the receive side we should only get CHECKSUM_PARTIAL - * packets from Xen, which uses some special fields to represent this - * (see vswitch_skb_checksum_setup()). Since we can only make one type - * work, pick the one that actually happens in practice. - * - * On the transmit side (basically after skb_checksum_setup() - * has been run or on internal dev transmit), packets with - * CHECKSUM_COMPLETE aren't generated, so assume CHECKSUM_PARTIAL. - */ - case CHECKSUM_HW: - if (!xmit) - set_ip_summed(skb, OVS_CSUM_COMPLETE); - else - set_ip_summed(skb, OVS_CSUM_PARTIAL); - break; -#else - case CHECKSUM_COMPLETE: - set_ip_summed(skb, OVS_CSUM_COMPLETE); - break; - case CHECKSUM_PARTIAL: - set_ip_summed(skb, OVS_CSUM_PARTIAL); - break; -#endif - } - - OVS_CB(skb)->csum_start = skb_headroom(skb) + skb_transport_offset(skb); - - return vswitch_skb_checksum_setup(skb); -} - -/* - * forward_ip_summed - map internal checksum state back onto native - * kernel fields. - * - * @skb: Packet to manipulate. - * @xmit: Whether we are about send on the transmit path the network stack. - * This follows the same logic as the @xmit field in compute_ip_summed(). - * Generally, a given vport will have opposite values for @xmit passed to - * these two functions. - * - * When a packet is about to egress from OVS take our internal fields (including - * any modifications we have made) and recreate the correct representation for - * this kernel. This may do things like change the transport header offset. - */ -void forward_ip_summed(struct sk_buff *skb, bool xmit) -{ - switch (get_ip_summed(skb)) { - case OVS_CSUM_NONE: - skb->ip_summed = CHECKSUM_NONE; - break; - case OVS_CSUM_UNNECESSARY: - skb->ip_summed = CHECKSUM_UNNECESSARY; -#if defined(CONFIG_XEN) && defined(HAVE_PROTO_DATA_VALID) - skb->proto_data_valid = 1; -#endif - break; -#ifdef CHECKSUM_HW - case OVS_CSUM_COMPLETE: - if (!xmit) - skb->ip_summed = CHECKSUM_HW; - else - skb->ip_summed = CHECKSUM_NONE; - break; - case OVS_CSUM_PARTIAL: - if (!xmit) { - skb->ip_summed = CHECKSUM_UNNECESSARY; -#if defined(CONFIG_XEN) && defined(HAVE_PROTO_DATA_VALID) - skb->proto_csum_blank = 1; -#endif - } else { - skb->ip_summed = CHECKSUM_HW; - } - break; -#else - case OVS_CSUM_COMPLETE: - skb->ip_summed = CHECKSUM_COMPLETE; - break; - case OVS_CSUM_PARTIAL: - skb->ip_summed = CHECKSUM_PARTIAL; - break; -#endif - } - - if (get_ip_summed(skb) == OVS_CSUM_PARTIAL) - skb_set_transport_header(skb, OVS_CB(skb)->csum_start - - skb_headroom(skb)); -} - -u8 get_ip_summed(struct sk_buff *skb) -{ - return OVS_CB(skb)->ip_summed; -} - -void set_ip_summed(struct sk_buff *skb, u8 ip_summed) -{ - OVS_CB(skb)->ip_summed = ip_summed; -} - -void get_skb_csum_pointers(const struct sk_buff *skb, u16 *csum_start, - u16 *csum_offset) -{ - *csum_start = OVS_CB(skb)->csum_start; - *csum_offset = skb->csum; -} - -void set_skb_csum_pointers(struct sk_buff *skb, u16 csum_start, - u16 csum_offset) -{ - OVS_CB(skb)->csum_start = csum_start; - skb->csum = csum_offset; -} -#endif /* NEED_CSUM_NORMALIZE */ diff --git a/datapath/checksum.h b/datapath/checksum.h deleted file mode 100644 index a440c59..0000000 --- a/datapath/checksum.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (c) 2007-2011 Nicira, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - */ - -#ifndef CHECKSUM_H -#define CHECKSUM_H 1 - -#include <linux/skbuff.h> -#include <linux/version.h> - -#include <net/checksum.h> - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) || \ - (defined(CONFIG_XEN) && defined(HAVE_PROTO_DATA_VALID)) -#define NEED_CSUM_NORMALIZE -#endif - -/* These are the same values as the checksum constants in 2.6.22+. */ -enum csum_type { - OVS_CSUM_NONE = 0, - OVS_CSUM_UNNECESSARY = 1, - OVS_CSUM_COMPLETE = 2, - OVS_CSUM_PARTIAL = 3, -}; - -#ifdef NEED_CSUM_NORMALIZE -int compute_ip_summed(struct sk_buff *skb, bool xmit); -void forward_ip_summed(struct sk_buff *skb, bool xmit); -u8 get_ip_summed(struct sk_buff *skb); -void set_ip_summed(struct sk_buff *skb, u8 ip_summed); -void get_skb_csum_pointers(const struct sk_buff *skb, u16 *csum_start, - u16 *csum_offset); -void set_skb_csum_pointers(struct sk_buff *skb, u16 csum_start, - u16 csum_offset); -#else -static inline int compute_ip_summed(struct sk_buff *skb, bool xmit) -{ - return 0; -} - -static inline void forward_ip_summed(struct sk_buff *skb, bool xmit) { } - -static inline u8 get_ip_summed(struct sk_buff *skb) -{ - return skb->ip_summed; -} - -static inline void set_ip_summed(struct sk_buff *skb, u8 ip_summed) -{ - skb->ip_summed = ip_summed; -} - -static inline void get_skb_csum_pointers(const struct sk_buff *skb, - u16 *csum_start, u16 *csum_offset) -{ - *csum_start = skb->csum_start; - *csum_offset = skb->csum_offset; -} - -static inline void set_skb_csum_pointers(struct sk_buff *skb, u16 csum_start, - u16 csum_offset) -{ - skb->csum_start = csum_start; - skb->csum_offset = csum_offset; -} -#endif - -/* This is really compatibility code that belongs in the compat directory. - * However, it needs access to our normalized checksum values, so put it here. - */ -#if defined(NEED_CSUM_NORMALIZE) || LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) -#define inet_proto_csum_replace4 rpl_inet_proto_csum_replace4 -static inline void inet_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb, - __be32 from, __be32 to, - int pseudohdr) -{ - __be32 diff[] = { ~from, to }; - - if (get_ip_summed(skb) != OVS_CSUM_PARTIAL) { - *sum = csum_fold(csum_partial((char *)diff, sizeof(diff), - ~csum_unfold(*sum))); - if (get_ip_summed(skb) == OVS_CSUM_COMPLETE && pseudohdr) - skb->csum = ~csum_partial((char *)diff, sizeof(diff), - ~skb->csum); - } else if (pseudohdr) - *sum = ~csum_fold(csum_partial((char *)diff, sizeof(diff), - csum_unfold(*sum))); -} -#endif - -#if defined(NEED_CSUM_NORMALIZE) || LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0) -#define inet_proto_csum_replace16 rpl_inet_proto_csum_replace16 -static inline void inet_proto_csum_replace16(__sum16 *sum, - struct sk_buff *skb, - const __be32 *from, - const __be32 *to, - int pseudohdr) -{ - __be32 diff[] = { - ~from[0], ~from[1], ~from[2], ~from[3], - to[0], to[1], to[2], to[3], - }; - if (get_ip_summed(skb) != OVS_CSUM_PARTIAL) { - *sum = csum_fold(csum_partial(diff, sizeof(diff), - ~csum_unfold(*sum))); - if (get_ip_summed(skb) == OVS_CSUM_COMPLETE && pseudohdr) - skb->csum = ~csum_partial(diff, sizeof(diff), - ~skb->csum); - } else if (pseudohdr) - *sum = ~csum_fold(csum_partial(diff, sizeof(diff), - csum_unfold(*sum))); -} -#endif - -#ifdef NEED_CSUM_NORMALIZE -static inline void update_csum_start(struct sk_buff *skb, int delta) -{ - if (get_ip_summed(skb) == OVS_CSUM_PARTIAL) { - u16 csum_start, csum_offset; - - get_skb_csum_pointers(skb, &csum_start, &csum_offset); - set_skb_csum_pointers(skb, csum_start + delta, csum_offset); - } -} - -static inline int rpl_pskb_expand_head(struct sk_buff *skb, int nhead, - int ntail, gfp_t gfp_mask) -{ - int err; - int old_headroom = skb_headroom(skb); - - err = pskb_expand_head(skb, nhead, ntail, gfp_mask); - if (unlikely(err)) - return err; - - update_csum_start(skb, skb_headroom(skb) - old_headroom); - - return 0; -} -#define pskb_expand_head rpl_pskb_expand_head - -static inline unsigned char *rpl__pskb_pull_tail(struct sk_buff *skb, - int delta) -{ - unsigned char *ret; - int old_headroom = skb_headroom(skb); - - ret = __pskb_pull_tail(skb, delta); - if (unlikely(!ret)) - return ret; - - update_csum_start(skb, skb_headroom(skb) - old_headroom); - - return ret; -} -#define __pskb_pull_tail rpl__pskb_pull_tail -#endif - -#endif /* checksum.h */ diff --git a/datapath/datapath.c b/datapath/datapath.c index 1f7560a..9ed213e 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -54,7 +54,6 @@ #include <net/net_namespace.h> #include <net/netns/generic.h> -#include "checksum.h" #include "datapath.h" #include "flow.h" #include "vlan.h" @@ -295,8 +294,6 @@ int ovs_dp_upcall(struct datapath *dp, struct sk_buff *skb, goto err; } - forward_ip_summed(skb, true); - if (!skb_is_gso(skb)) err = queue_userspace_packet(ovs_dp_get_net(dp), dp_ifindex, skb, upcall_info); else diff --git a/datapath/datapath.h b/datapath/datapath.h index 064211d..e3cd2f7 100644 --- a/datapath/datapath.h +++ b/datapath/datapath.h @@ -26,7 +26,6 @@ #include <linux/skbuff.h> #include <linux/u64_stats_sync.h> -#include "checksum.h" #include "compat.h" #include "flow.h" #include "vlan.h" @@ -94,11 +93,6 @@ struct datapath { * @pkt_key: The flow information extracted from the packet. Must be nonnull. * @tun_key: Key for the tunnel that encapsulated this packet. NULL if the * packet is not being tunneled. - * @ip_summed: Consistently stores L4 checksumming status across different - * kernel versions. - * @csum_start: Stores the offset from which to start checksumming independent - * of the transport header on all kernel versions. - * packet was not received on a tunnel. * @vlan_tci: Provides a substitute for the skb->vlan_tci field on kernels * before 2.6.27. */ @@ -106,10 +100,6 @@ struct ovs_skb_cb { struct sw_flow *flow; struct sw_flow_key *pkt_key; struct ovs_key_ipv4_tunnel *tun_key; -#ifdef NEED_CSUM_NORMALIZE - enum csum_type ip_summed; - u16 csum_start; -#endif #ifdef NEED_VLAN_FIELD u16 vlan_tci; #endif diff --git a/datapath/linux/Modules.mk b/datapath/linux/Modules.mk index 15c518a..085e8fd 100644 --- a/datapath/linux/Modules.mk +++ b/datapath/linux/Modules.mk @@ -16,7 +16,8 @@ openvswitch_sources += \ linux/compat/skbuff-openvswitch.c \ linux/compat/time.c \ linux/compat/vxlan.c \ - linux/compat/workqueue.c + linux/compat/workqueue.c \ + linux/compat/utils.c openvswitch_headers += \ linux/compat/gso.h \ linux/compat/include/asm/percpu.h \ diff --git a/datapath/linux/compat/include/linux/netdevice.h b/datapath/linux/compat/include/linux/netdevice.h index 2ceff22..bd7a4b0 100644 --- a/datapath/linux/compat/include/linux/netdevice.h +++ b/datapath/linux/compat/include/linux/netdevice.h @@ -82,13 +82,6 @@ extern void unregister_netdevice_many(struct list_head *head); extern void dev_disable_lro(struct net_device *dev); #endif -#define skb_checksum_help rpl_skb_checksum_help -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) -extern int skb_checksum_help(struct sk_buff *skb, int); -#else -extern int skb_checksum_help(struct sk_buff *skb); -#endif - #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) || \ defined HAVE_RHEL_OVS_HOOK static inline int netdev_rx_handler_register(struct net_device *dev, diff --git a/datapath/linux/compat/include/net/checksum.h b/datapath/linux/compat/include/net/checksum.h index 502d02d..2bead4b 100644 --- a/datapath/linux/compat/include/net/checksum.h +++ b/datapath/linux/compat/include/net/checksum.h @@ -32,14 +32,14 @@ static inline void csum_replace2(__sum16 *sum, __be16 from, __be16 to) } #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) -#define inet_proto_csum_replace2(sum, skb, from, to, pseudohdr) \ - inet_proto_csum_replace4(sum, skb, (__force __be32)(from), \ - (__force __be32)(to), pseudohdr) -#endif - #ifndef CSUM_MANGLED_0 #define CSUM_MANGLED_0 ((__force __sum16)0xffff) #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0) +#define inet_proto_csum_replace16 rpl_inet_proto_csum_replace16 +void inet_proto_csum_replace16(__sum16 *sum, struct sk_buff *skb, + const __be32 *from, const __be32 *to, + int pseudohdr); +#endif #endif /* checksum.h */ diff --git a/datapath/linux/compat/include/net/sctp/checksum.h b/datapath/linux/compat/include/net/sctp/checksum.h index 11fb0b6..59d209b 100644 --- a/datapath/linux/compat/include/net/sctp/checksum.h +++ b/datapath/linux/compat/include/net/sctp/checksum.h @@ -2,12 +2,7 @@ #define __SCTP_CHECKSUM_WRAPPER_H 1 #include <linux/version.h> - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) -#include <net/sctp/sctp.h> -#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25) */ #include_next <net/sctp/checksum.h> -#endif #if LINUX_VERSION_CODE < KERNEL_VERSION(3,12,0) static inline __le32 sctp_compute_cksum(const struct sk_buff *skb, diff --git a/datapath/linux/compat/ip_tunnels_core.c b/datapath/linux/compat/ip_tunnels_core.c index 01cc2fb..f9f6cae 100644 --- a/datapath/linux/compat/ip_tunnels_core.c +++ b/datapath/linux/compat/ip_tunnels_core.c @@ -31,7 +31,6 @@ #include <net/route.h> #include <net/xfrm.h> -#include "checksum.h" #include "compat.h" #include "gso.h" @@ -100,9 +99,6 @@ int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto) skb->protocol = inner_proto; } - if (unlikely(compute_ip_summed(skb, false))) - return -EPROTO; - nf_reset(skb); secpath_reset(skb); skb_clear_rxhash(skb); diff --git a/datapath/linux/compat/skbuff-openvswitch.c b/datapath/linux/compat/skbuff-openvswitch.c index 2707ef0..3baa09e 100644 --- a/datapath/linux/compat/skbuff-openvswitch.c +++ b/datapath/linux/compat/skbuff-openvswitch.c @@ -14,25 +14,3 @@ void __skb_warn_lro_forwarding(const struct sk_buff *skb) } #endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) -int skb_checksum_help(struct sk_buff *skb, int inward) -#else -int skb_checksum_help(struct sk_buff *skb) -#endif -{ - if (unlikely(skb_is_nonlinear(skb))) { - int err; - - err = __skb_linearize(skb); - if (unlikely(err)) - return err; - } - -#undef skb_checksum_help -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) - return skb_checksum_help(skb, 0); -#else - return skb_checksum_help(skb); -#endif -} diff --git a/datapath/linux/compat/utils.c b/datapath/linux/compat/utils.c new file mode 100644 index 0000000..844d372 --- /dev/null +++ b/datapath/linux/compat/utils.c @@ -0,0 +1,39 @@ +#include <linux/module.h> +#include <linux/jiffies.h> +#include <linux/kernel.h> +#include <linux/ctype.h> +#include <linux/inet.h> +#include <linux/mm.h> +#include <linux/net.h> +#include <net/checksum.h> +#include <linux/string.h> +#include <linux/types.h> +#include <linux/percpu.h> +#include <linux/init.h> +#include <linux/ratelimit.h> + +#include <net/sock.h> + +#include <asm/byteorder.h> +#include <asm/uaccess.h> + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0) +void inet_proto_csum_replace16(__sum16 *sum, struct sk_buff *skb, + const __be32 *from, const __be32 *to, + int pseudohdr) +{ + __be32 diff[] = { + ~from[0], ~from[1], ~from[2], ~from[3], + to[0], to[1], to[2], to[3], + }; + if (skb->ip_summed != CHECKSUM_PARTIAL) { + *sum = csum_fold(csum_partial(diff, sizeof(diff), + ~csum_unfold(*sum))); + if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr) + skb->csum = ~csum_partial(diff, sizeof(diff), + ~skb->csum); + } else if (pseudohdr) + *sum = ~csum_fold(csum_partial(diff, sizeof(diff), + csum_unfold(*sum))); +} +#endif diff --git a/datapath/linux/compat/vxlan.c b/datapath/linux/compat/vxlan.c index 9d8991d..780344e 100644 --- a/datapath/linux/compat/vxlan.c +++ b/datapath/linux/compat/vxlan.c @@ -51,7 +51,6 @@ #include <net/netns/generic.h> #include <net/vxlan.h> -#include "checksum.h" #include "compat.h" #include "gso.h" #include "vlan.h" diff --git a/datapath/vlan.h b/datapath/vlan.h index aee5551..1356aed 100644 --- a/datapath/vlan.h +++ b/datapath/vlan.h @@ -93,11 +93,6 @@ static inline int vlan_deaccel_tag(struct sk_buff *skb) if (unlikely(!skb)) return -ENOMEM; - if (get_ip_summed(skb) == OVS_CSUM_COMPLETE) - skb->csum = csum_add(skb->csum, - csum_partial(skb->data + (2 * ETH_ALEN), - VLAN_HLEN, 0)); - vlan_set_tci(skb, 0); return 0; } diff --git a/datapath/vport-gre.c b/datapath/vport-gre.c index b9fff8a..7c65109 100644 --- a/datapath/vport-gre.c +++ b/datapath/vport-gre.c @@ -129,8 +129,6 @@ static int __send(struct vport *vport, struct sk_buff *skb, __be32 saddr; int err; - forward_ip_summed(skb, true); - /* Route lookup */ saddr = OVS_CB(skb)->tun_key->ipv4_src; rt = find_route(ovs_dp_get_net(vport->dp), diff --git a/datapath/vport-internal_dev.c b/datapath/vport-internal_dev.c index 904c0b3..f05f723 100644 --- a/datapath/vport-internal_dev.c +++ b/datapath/vport-internal_dev.c @@ -29,7 +29,6 @@ #include <net/dst.h> #include <net/xfrm.h> -#include "checksum.h" #include "datapath.h" #include "vlan.h" #include "vport-internal_dev.h" @@ -80,11 +79,6 @@ static struct net_device_stats *internal_dev_sys_stats(struct net_device *netdev /* Called with rcu_read_lock_bh. */ static int internal_dev_xmit(struct sk_buff *skb, struct net_device *netdev) { - if (unlikely(compute_ip_summed(skb, true))) { - kfree_skb(skb); - return 0; - } - vlan_copy_skb_tci(skb); rcu_read_lock(); @@ -274,7 +268,6 @@ static int internal_dev_recv(struct vport *vport, struct sk_buff *skb) skb->pkt_type = PACKET_HOST; skb->protocol = eth_type_trans(skb, netdev); skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN); - forward_ip_summed(skb, false); netif_rx(skb); diff --git a/datapath/vport-lisp.c b/datapath/vport-lisp.c index 818a471..6eb101a 100644 --- a/datapath/vport-lisp.c +++ b/datapath/vport-lisp.c @@ -238,11 +238,6 @@ static void ovs_tnl_rcv(struct vport *vport, struct sk_buff *skb, secpath_reset(skb); vlan_set_tci(skb, 0); - if (unlikely(compute_ip_summed(skb, false))) { - kfree_skb(skb); - return; - } - ovs_vport_receive(vport, skb, tun_key); } @@ -441,9 +436,6 @@ static struct sk_buff *handle_offloads(struct sk_buff *skb) { int err; - forward_ip_summed(skb, true); - - if (skb_is_gso(skb)) { struct sk_buff *nskb; char cb[sizeof(skb->cb)]; @@ -462,7 +454,7 @@ static struct sk_buff *handle_offloads(struct sk_buff *skb) memcpy(nskb->cb, cb, sizeof(cb)); nskb = nskb->next; } - } else if (get_ip_summed(skb) == OVS_CSUM_PARTIAL) { + } else if (skb->ip_summed == CHECKSUM_PARTIAL) { /* Pages aren't locked and could change at any time. * If this happens after we compute the checksum, the * checksum will be wrong. We linearize now to avoid @@ -479,8 +471,6 @@ static struct sk_buff *handle_offloads(struct sk_buff *skb) goto error; } - set_ip_summed(skb, OVS_CSUM_NONE); - return skb; error: diff --git a/datapath/vport-netdev.c b/datapath/vport-netdev.c index 1c2d7c5..c033816 100644 --- a/datapath/vport-netdev.c +++ b/datapath/vport-netdev.c @@ -29,7 +29,6 @@ #include <net/llc.h> -#include "checksum.h" #include "datapath.h" #include "vlan.h" #include "vport-internal_dev.h" @@ -240,9 +239,6 @@ static void netdev_port_receive(struct vport *vport, struct sk_buff *skb) if (unlikely(!skb)) return; - if (unlikely(compute_ip_summed(skb, false))) - goto error; - skb_push(skb, ETH_HLEN); ovs_skb_postpush_rcsum(skb, skb->data, ETH_HLEN); @@ -292,7 +288,6 @@ static int netdev_send(struct vport *vport, struct sk_buff *skb) } skb->dev = netdev_vport->dev; - forward_ip_summed(skb, true); if (vlan_tx_tag_present(skb) && !dev_supports_vlan_tx(skb->dev)) { int features; diff --git a/datapath/vport-vxlan.c b/datapath/vport-vxlan.c index 007e4ac..de49ab1 100644 --- a/datapath/vport-vxlan.c +++ b/datapath/vport-vxlan.c @@ -156,8 +156,6 @@ static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb) goto error; } - forward_ip_summed(skb, true); - /* Route lookup */ saddr = OVS_CB(skb)->tun_key->ipv4_src; rt = find_route(ovs_dp_get_net(vport->dp), -- 1.7.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev