git://git.onelab.eu
/
sliver-openvswitch.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
added targets to test links
[sliver-openvswitch.git]
/
datapath
/
tunnel.c
diff --git
a/datapath/tunnel.c
b/datapath/tunnel.c
index
0cc0607
..
bd63da5
100644
(file)
--- a/
datapath/tunnel.c
+++ b/
datapath/tunnel.c
@@
-37,12
+37,6
@@
#include "vlan.h"
#include "vport.h"
#include "vlan.h"
#include "vport.h"
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
-#define rt_dst(rt) (rt->dst)
-#else
-#define rt_dst(rt) (rt->u.dst)
-#endif
-
/**
* ovs_tnl_rcv - ingress point for generic tunnel code
*
/**
* ovs_tnl_rcv - ingress point for generic tunnel code
*
@@
-58,7
+52,8
@@
* - skb->csum does not include the inner Ethernet header.
* - The layer pointers are undefined.
*/
* - skb->csum does not include the inner Ethernet header.
* - The layer pointers are undefined.
*/
-void ovs_tnl_rcv(struct vport *vport, struct sk_buff *skb)
+void ovs_tnl_rcv(struct vport *vport, struct sk_buff *skb,
+ struct ovs_key_ipv4_tunnel *tun_key)
{
struct ethhdr *eh;
{
struct ethhdr *eh;
@@
-81,12
+76,12
@@
void ovs_tnl_rcv(struct vport *vport, struct sk_buff *skb)
return;
}
return;
}
- ovs_vport_receive(vport, skb);
+ ovs_vport_receive(vport, skb
, tun_key
);
}
}
-st
atic st
ruct rtable *find_route(struct net *net,
- __be32 *saddr, __be32 daddr, u8 ipproto,
- u8 tos, u32 skb_mark)
+struct rtable *find_route(struct net *net,
+
__be32 *saddr, __be32 daddr, u8 ipproto,
+
u8 tos, u32 skb_mark)
{
struct rtable *rt;
/* Tunnel configuration keeps DSCP part of TOS bits, But Linux
{
struct rtable *rt;
/* Tunnel configuration keeps DSCP part of TOS bits, But Linux
@@
-149,16
+144,22
@@
static struct sk_buff *handle_offloads(struct sk_buff *skb)
if (skb_is_gso(skb)) {
struct sk_buff *nskb;
if (skb_is_gso(skb)) {
struct sk_buff *nskb;
+ char cb[sizeof(skb->cb)];
+
+ memcpy(cb, skb->cb, sizeof(cb));
nskb = __skb_gso_segment(skb, 0, false);
if (IS_ERR(nskb)) {
nskb = __skb_gso_segment(skb, 0, false);
if (IS_ERR(nskb)) {
- kfree_skb(skb);
err = PTR_ERR(nskb);
goto error;
}
consume_skb(skb);
skb = nskb;
err = PTR_ERR(nskb);
goto error;
}
consume_skb(skb);
skb = nskb;
+ while (nskb) {
+ memcpy(nskb->cb, cb, sizeof(cb));
+ nskb = nskb->next;
+ }
} else if (get_ip_summed(skb) == OVS_CSUM_PARTIAL) {
/* Pages aren't locked and could change at any time.
* If this happens after we compute the checksum, the
} else if (get_ip_summed(skb) == OVS_CSUM_PARTIAL) {
/* Pages aren't locked and could change at any time.
* If this happens after we compute the checksum, the
@@
-168,20
+169,18
@@
static struct sk_buff *handle_offloads(struct sk_buff *skb)
if (unlikely(need_linearize(skb))) {
err = __skb_linearize(skb);
if (unlikely(err))
if (unlikely(need_linearize(skb))) {
err = __skb_linearize(skb);
if (unlikely(err))
- goto error
_free
;
+ goto error;
}
err = skb_checksum_help(skb);
if (unlikely(err))
}
err = skb_checksum_help(skb);
if (unlikely(err))
- goto error
_free
;
+ goto error;
}
set_ip_summed(skb, OVS_CSUM_NONE);
return skb;
}
set_ip_summed(skb, OVS_CSUM_NONE);
return skb;
-error_free:
- kfree_skb(skb);
error:
return ERR_PTR(err);
}
error:
return ERR_PTR(err);
}
@@
-194,7
+193,9
@@
u16 ovs_tnl_get_src_port(struct sk_buff *skb)
int low;
int high;
unsigned int range;
int low;
int high;
unsigned int range;
- u32 hash = OVS_CB(skb)->flow->hash;
+ struct sw_flow_key *pkt_key = OVS_CB(skb)->pkt_key;
+ u32 hash = jhash2((const u32 *)pkt_key,
+ sizeof(*pkt_key) / sizeof(u32), 0);
inet_get_local_port_range(&low, &high);
range = (high - low) + 1;
inet_get_local_port_range(&low, &high);
range = (high - low) + 1;
@@
-211,6
+212,8
@@
int ovs_tnl_send(struct vport *vport, struct sk_buff *skb,
struct rtable *rt;
__be32 saddr;
int sent_len = 0;
struct rtable *rt;
__be32 saddr;
int sent_len = 0;
+ int err;
+ struct sk_buff *nskb;
/* Route lookup */
saddr = OVS_CB(skb)->tun_key->ipv4_src;
/* Route lookup */
saddr = OVS_CB(skb)->tun_key->ipv4_src;
@@
-220,8
+223,10
@@
int ovs_tnl_send(struct vport *vport, struct sk_buff *skb,
ipproto,
OVS_CB(skb)->tun_key->ipv4_tos,
skb_get_mark(skb));
ipproto,
OVS_CB(skb)->tun_key->ipv4_tos,
skb_get_mark(skb));
- if (IS_ERR(rt))
- goto error_free;
+ if (IS_ERR(rt)) {
+ err = PTR_ERR(rt);
+ goto error;
+ }
tunnel_hlen += sizeof(struct iphdr);
tunnel_hlen += sizeof(struct iphdr);
@@
-230,7
+235,6
@@
int ovs_tnl_send(struct vport *vport, struct sk_buff *skb,
+ (vlan_tx_tag_present(skb) ? VLAN_HLEN : 0);
if (skb_headroom(skb) < min_headroom || skb_header_cloned(skb)) {
+ (vlan_tx_tag_present(skb) ? VLAN_HLEN : 0);
if (skb_headroom(skb) < min_headroom || skb_header_cloned(skb)) {
- int err;
int head_delta = SKB_DATA_ALIGN(min_headroom -
skb_headroom(skb) +
16);
int head_delta = SKB_DATA_ALIGN(min_headroom -
skb_headroom(skb) +
16);
@@
-242,11
+246,12
@@
int ovs_tnl_send(struct vport *vport, struct sk_buff *skb,
}
/* Offloading */
}
/* Offloading */
- skb = handle_offloads(skb);
- if (IS_ERR(skb)) {
-
skb = NULL
;
+
n
skb = handle_offloads(skb);
+ if (IS_ERR(
n
skb)) {
+
err = PTR_ERR(nskb)
;
goto err_free_rt;
}
goto err_free_rt;
}
+ skb = nskb;
/* Reset SKB */
nf_reset(skb);
/* Reset SKB */
nf_reset(skb);
@@
-258,7
+263,6
@@
int ovs_tnl_send(struct vport *vport, struct sk_buff *skb,
struct sk_buff *next_skb = skb->next;
struct iphdr *iph;
int frag_len;
struct sk_buff *next_skb = skb->next;
struct iphdr *iph;
int frag_len;
- int err;
skb->next = NULL;
skb->next = NULL;
@@
-288,7
+292,7
@@
int ovs_tnl_send(struct vport *vport, struct sk_buff *skb,
iph->tos = OVS_CB(skb)->tun_key->ipv4_tos;
iph->ttl = OVS_CB(skb)->tun_key->ipv4_ttl;
iph->frag_off = OVS_CB(skb)->tun_key->tun_flags &
iph->tos = OVS_CB(skb)->tun_key->ipv4_tos;
iph->ttl = OVS_CB(skb)->tun_key->ipv4_ttl;
iph->frag_off = OVS_CB(skb)->tun_key->tun_flags &
-
OVS_TNL_F
_DONT_FRAGMENT ? htons(IP_DF) : 0;
+
TUNNEL
_DONT_FRAGMENT ? htons(IP_DF) : 0;
/*
* Allow our local IP stack to fragment the outer packet even
* if the DF bit is set as a last resort. We also need to
/*
* Allow our local IP stack to fragment the outer packet even
* if the DF bit is set as a last resort. We also need to
@@
-311,15
+315,10
@@
next:
skb = next_skb;
}
skb = next_skb;
}
- if (unlikely(sent_len == 0))
- ovs_vport_record_error(vport, VPORT_E_TX_DROPPED);
-
return sent_len;
err_free_rt:
ip_rt_put(rt);
return sent_len;
err_free_rt:
ip_rt_put(rt);
-error_free:
- kfree_skb(skb);
- ovs_vport_record_error(vport, VPORT_E_TX_ERROR);
- return sent_len;
+error:
+ return err;
}
}