X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=datapath%2Fvport-gre.c;h=5d5090c89a502376c30583e82a4bbdeb4254000c;hb=c5cf10598f8c9f4428291e9df3ecd72a05fb1ccf;hp=38245a7d8c4c7c3e81fbe14e243e2cba6885919c;hpb=3b00e887bbc24bd5e88de9b1a92243e31e1e0eed;p=sliver-openvswitch.git diff --git a/datapath/vport-gre.c b/datapath/vport-gre.c index 38245a7d8..5d5090c89 100644 --- a/datapath/vport-gre.c +++ b/datapath/vport-gre.c @@ -26,8 +26,6 @@ #include #include #include -#include -#include #include #include #include @@ -35,10 +33,11 @@ #include #include #include +#include +#include #include #include - #include #include #include @@ -46,7 +45,6 @@ #include #include "datapath.h" -#include "tunnel.h" #include "vport.h" /* Returns the least-significant 32 bits of a __be64. */ @@ -112,25 +110,41 @@ static int gre_rcv(struct sk_buff *skb, return PACKET_REJECT; key = key_to_tunnel_id(tpi->key, tpi->seq); - tnl_tun_key_init(&tun_key, ip_hdr(skb), key, filter_tnl_flags(tpi->flags)); + ovs_flow_tun_key_init(&tun_key, ip_hdr(skb), key, filter_tnl_flags(tpi->flags)); ovs_vport_receive(vport, skb, &tun_key); return PACKET_RCVD; } +/* Called with rcu_read_lock and BH disabled. */ +static int gre_err(struct sk_buff *skb, u32 info, + const struct tnl_ptk_info *tpi) +{ + struct ovs_net *ovs_net; + struct vport *vport; + + ovs_net = net_generic(dev_net(skb->dev), ovs_net_id); + if ((tpi->flags & TUNNEL_KEY) && (tpi->flags & TUNNEL_SEQ)) + vport = rcu_dereference(ovs_net->vport_net.gre64_vport); + else + vport = rcu_dereference(ovs_net->vport_net.gre_vport); + + if (unlikely(!vport)) + return PACKET_REJECT; + else + return PACKET_RCVD; +} + static int __send(struct vport *vport, struct sk_buff *skb, int tunnel_hlen, __be32 seq, __be16 gre64_flag) { - struct net *net = ovs_dp_get_net(vport->dp); struct rtable *rt; int min_headroom; __be16 df; __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), @@ -138,7 +152,7 @@ static int __send(struct vport *vport, struct sk_buff *skb, OVS_CB(skb)->tun_key->ipv4_dst, IPPROTO_GRE, OVS_CB(skb)->tun_key->ipv4_tos, - skb_get_mark(skb)); + skb->mark); if (IS_ERR(rt)) { err = PTR_ERR(rt); goto error; @@ -158,9 +172,14 @@ static int __send(struct vport *vport, struct sk_buff *skb, goto err_free_rt; } - if (unlikely(vlan_deaccel_tag(skb))) { - err = -ENOMEM; - goto err_free_rt; + if (vlan_tx_tag_present(skb)) { + if (unlikely(!__vlan_put_tag(skb, + skb->vlan_proto, + vlan_tx_tag_get(skb)))) { + err = -ENOMEM; + goto err_free_rt; + } + vlan_set_tci(skb, 0); } /* Push Tunnel header. */ @@ -175,10 +194,10 @@ static int __send(struct vport *vport, struct sk_buff *skb, skb->local_df = 1; - return iptunnel_xmit(net, rt, skb, saddr, + return iptunnel_xmit(rt, skb, saddr, OVS_CB(skb)->tun_key->ipv4_dst, IPPROTO_GRE, OVS_CB(skb)->tun_key->ipv4_tos, - OVS_CB(skb)->tun_key->ipv4_ttl, df); + OVS_CB(skb)->tun_key->ipv4_ttl, df, false); err_free_rt: ip_rt_put(rt); error: @@ -187,6 +206,7 @@ error: static struct gre_cisco_protocol gre_protocol = { .handler = gre_rcv, + .err_handler = gre_err, .priority = 1, }; @@ -257,7 +277,7 @@ static void gre_tnl_destroy(struct vport *vport) ovs_net = net_generic(net, ovs_net_id); - rcu_assign_pointer(ovs_net->vport_net.gre_vport, NULL); + RCU_INIT_POINTER(ovs_net->vport_net.gre_vport, NULL); ovs_vport_deferred_free(vport); gre_exit(); }