#include <net/xfrm.h>
#include "checksum.h"
+#include "compat.h"
#include "datapath.h"
#include "tunnel.h"
#include "vlan.h"
static struct rtable *find_route(struct net *net,
__be32 *saddr, __be32 daddr, u8 ipproto,
- u8 tos)
+ u8 tos, u32 skb_mark)
{
struct rtable *rt;
/* Tunnel configuration keeps DSCP part of TOS bits, But Linux
struct flowi fl = { .nl_u = { .ip4_u = {
.daddr = daddr,
.saddr = *saddr,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+ .fwmark = skb_mark,
+#endif
.tos = RT_TOS(tos) } },
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ .mark = skb_mark,
+#endif
.proto = ipproto };
if (unlikely(ip_route_output_key(net, &rt, &fl)))
struct flowi4 fl = { .daddr = daddr,
.saddr = *saddr,
.flowi4_tos = RT_TOS(tos),
+ .flowi4_mark = skb_mark,
.flowi4_proto = ipproto };
rt = ip_route_output_key(net, &fl);
return sent_len;
}
+/* Compute source UDP port for outgoing packet.
+ * Currently we use the flow hash.
+ */
+u16 ovs_tnl_get_src_port(struct sk_buff *skb)
+{
+ int low;
+ int high;
+ unsigned int range;
+ u32 hash = OVS_CB(skb)->flow->hash;
+
+ inet_get_local_port_range(&low, &high);
+ range = (high - low) + 1;
+ return (((u64) hash * range) >> 32) + low;
+}
+
int ovs_tnl_send(struct vport *vport, struct sk_buff *skb)
{
struct tnl_vport *tnl_vport = tnl_vport_priv(vport);
__be16 frag_off;
__be32 daddr;
__be32 saddr;
+ u32 skb_mark;
u8 ttl;
u8 tos;
}
/* Route lookup */
+ skb_mark = skb_get_mark(skb);
rt = find_route(port_key_get_net(&mutable->key), &saddr, daddr,
- tnl_vport->tnl_ops->ipproto, tos);
+ tnl_vport->tnl_ops->ipproto, tos, skb_mark);
if (IS_ERR(rt))
goto error_free;
rt = find_route(port_key_get_net(&mutable->key),
&saddr, mutable->key.daddr,
- tnl_ops->ipproto, mutable->tos);
+ tnl_ops->ipproto, mutable->tos, 0);
if (IS_ERR(rt))
return -EADDRNOTAVAIL;
dev = rt_dst(rt).dev;
struct vport *vport;
struct tnl_vport *tnl_vport;
struct tnl_mutable_config *mutable;
- int initial_frag_id;
int err;
vport = ovs_vport_alloc(sizeof(struct tnl_vport), vport_ops, parms);
goto error_free_vport;
}
- get_random_bytes(&initial_frag_id, sizeof(int));
- atomic_set(&tnl_vport->frag_id, initial_frag_id);
-
err = tnl_set_config(ovs_dp_get_net(parms->dp), parms->options, tnl_ops,
NULL, mutable);
if (err)