if (!hash) {
struct sw_flow_key *pkt_key = OVS_CB(skb)->pkt_key;
- hash = jhash2((const u32 *)pkt_key,
- sizeof(*pkt_key) / sizeof(u32), 0);
+ if (skb->protocol == htons(ETH_P_IP))
+ hash = jhash2((const u32 *)&pkt_key->ipv4.addr,
+ sizeof(pkt_key->ipv4.addr) / sizeof(u32), 0);
+ else if (skb->protocol == htons(ETH_P_IPV6))
+ hash = jhash2((const u32 *)&pkt_key->ipv6.addr,
+ sizeof(pkt_key->ipv6.addr) / sizeof(u32), 0);
+ else
+ pr_warn_once("LISP inner protocol is not IP when "
+ "calculating hash.\n");
}
inet_get_local_port_range(net, &low, &high);
struct lisp_port *lisp_port = lisp_vport(vport);
struct udphdr *udph = udp_hdr(skb);
struct lisphdr *lisph = (struct lisphdr *)(udph + 1);
- const struct ovs_key_ipv4_tunnel *tun_key = OVS_CB(skb)->tun_key;
+ const struct ovs_key_ipv4_tunnel *tun_key = &OVS_CB(skb)->tun_info->tunnel;
udph->dest = lisp_port->dst_port;
udph->source = htons(get_src_port(net, skb));
struct lisp_port *lisp_port;
struct lisphdr *lisph;
struct iphdr *iph, *inner_iph;
- struct ovs_key_ipv4_tunnel tun_key;
+ struct ovs_tunnel_info tun_info;
__be64 key;
struct ethhdr *ethh;
__be16 protocol;
/* Save outer tunnel values */
iph = ip_hdr(skb);
- ovs_flow_tun_key_init(&tun_key, iph, key, TUNNEL_KEY);
+ ovs_flow_tun_info_init(&tun_info, iph, key, TUNNEL_KEY, NULL, 0);
/* Drop non-IP inner packets */
inner_iph = (struct iphdr *)(lisph + 1);
ovs_skb_postpush_rcsum(skb, skb->data, ETH_HLEN);
- ovs_vport_receive(vport_from_priv(lisp_port), skb, &tun_key);
+ ovs_vport_receive(vport_from_priv(lisp_port), skb, &tun_info);
goto out;
error:
#else
static int handle_offloads(struct sk_buff *skb)
{
+ if (skb->encapsulation && skb_is_gso(skb)) {
+ kfree_skb(skb);
+ return -ENOSYS;
+ }
+
if (skb_is_gso(skb)) {
int err = skb_unclone(skb, GFP_ATOMIC);
if (unlikely(err))
static int lisp_send(struct vport *vport, struct sk_buff *skb)
{
+ struct ovs_key_ipv4_tunnel *tun_key;
int network_offset = skb_network_offset(skb);
struct rtable *rt;
int min_headroom;
int sent_len;
int err;
- if (unlikely(!OVS_CB(skb)->tun_key))
+ if (unlikely(!OVS_CB(skb)->tun_info))
return -EINVAL;
+ tun_key = &OVS_CB(skb)->tun_info->tunnel;
+
if (skb->protocol != htons(ETH_P_IP) &&
skb->protocol != htons(ETH_P_IPV6)) {
kfree_skb(skb);
}
/* Route lookup */
- saddr = OVS_CB(skb)->tun_key->ipv4_src;
+ saddr = tun_key->ipv4_src;
rt = find_route(ovs_dp_get_net(vport->dp),
- &saddr,
- OVS_CB(skb)->tun_key->ipv4_dst,
- IPPROTO_UDP,
- OVS_CB(skb)->tun_key->ipv4_tos,
+ &saddr, tun_key->ipv4_dst,
+ IPPROTO_UDP, tun_key->ipv4_tos,
skb->mark);
if (IS_ERR(rt)) {
err = PTR_ERR(rt);
skb->local_df = 1;
- df = OVS_CB(skb)->tun_key->tun_flags &
- TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
+ df = tun_key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
sent_len = iptunnel_xmit(rt, skb,
- saddr, OVS_CB(skb)->tun_key->ipv4_dst,
- IPPROTO_UDP, OVS_CB(skb)->tun_key->ipv4_tos,
- OVS_CB(skb)->tun_key->ipv4_ttl, df, false);
+ saddr, tun_key->ipv4_dst,
+ IPPROTO_UDP, tun_key->ipv4_tos,
+ tun_key->ipv4_ttl, df, false);
return sent_len > 0 ? sent_len + network_offset : sent_len;