]> git.proxmox.com Git - mirror_ovs.git/commitdiff
tunneling: Don't send ICMP messages if no tunnel port is found.
authorJesse Gross <jesse@nicira.com>
Fri, 1 Feb 2013 23:34:10 +0000 (15:34 -0800)
committerJesse Gross <jesse@nicira.com>
Sat, 2 Feb 2013 01:07:10 +0000 (17:07 -0800)
Some tunnel code in OVS (for example, CAPWAP) uses the skb->cb to
store information while processing packets.  However, if we don't
find an appropriate tunnel port on receive, then we send an ICMP
port unreachable message, which calls back into the IP stack.  The
stack assumes that skb->cb will still contain valid information
about from the IP layer, including any IP options.  As a result,
icmp_echo_options() can read the garbage values from OVS and
overwrite data on the stack, panicing the machine.

This simply stops sending ICMP messages when ports are not found.
Many people find them confusing and flow based tunneling will
never send them (since it always finds a port) so it solves both
problems at once.

Bug #14880

Reported-by: Deepesh Govindan <dgovindan@nicira.com>
Signed-off-by: Jesse Gross <jesse@nicira.com>
Acked-by: Kyle Mestery <kmestery@cisco.com>
datapath/vport-capwap.c
datapath/vport-gre.c
datapath/vport-vxlan.c

index 56e6394a0f0d50ea70e6bd8cbff31ef4c95ce895..1230682319e8badd9059b67f2e6338922a901959 100644 (file)
@@ -331,10 +331,8 @@ static int capwap_rcv(struct sock *sk, struct sk_buff *skb)
        iph = ip_hdr(skb);
        vport = ovs_tnl_find_port(sock_net(sk), iph->daddr, iph->saddr, key,
                                  TNL_T_PROTO_CAPWAP, &mutable);
-       if (unlikely(!vport)) {
-               icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
+       if (unlikely(!vport))
                goto error;
-       }
 
        if (key_present && mutable->key.daddr &&
                         !(mutable->flags & TNL_F_IN_KEY_MATCH)) {
index 14c5ba340e927881a5bc0a47ee6f68b6fe6e2abe..680e7b34ae0f48ee31b8ad34d1f5da31956ed398 100644 (file)
@@ -274,10 +274,8 @@ static int gre_rcv(struct sk_buff *skb)
        iph = ip_hdr(skb);
        vport = ovs_tnl_find_port(dev_net(skb->dev), iph->daddr, iph->saddr, key,
                                  tunnel_type, &mutable);
-       if (unlikely(!vport)) {
-               icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
+       if (unlikely(!vport))
                goto error;
-       }
 
        tnl_flags = gre_flags_to_tunnel_flags(mutable, gre_flags, &key);
        tnl_tun_key_init(&tun_key, iph, key, tnl_flags);
index 4f9f33941cbaeaba1b4e0fa2a0b3f176e11fd27c..413452ed196294c99a651d8f16ae6cef41c01a01 100644 (file)
@@ -166,10 +166,8 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb)
        iph = ip_hdr(skb);
        vport = ovs_tnl_find_port(dev_net(skb->dev), iph->daddr, iph->saddr,
                key, TNL_T_PROTO_VXLAN, &mutable);
-       if (unlikely(!vport)) {
-               icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
+       if (unlikely(!vport))
                goto error;
-       }
 
        if (mutable->flags & TNL_F_IN_KEY_MATCH || !mutable->key.daddr)
                tunnel_flags = OVS_TNL_F_KEY;