The upstream has the fix for dev_forward_skb() to reset pkt_type to
PACKET_HOST. the change set of 06a23fe31ca3992863721f21bdb0307af93da807
So the pkt_type of PACKET_OTHERHOST doesn't come in.
This patch is a workaround for older kernel, reset skb->pkt_type when
receiving pkt_type of PACKET_OTHERHOST.

When two tunnel ports created on two OVS bridges on same host and
two ports are the end point of the tunnel, packets are dropped as below.

If a packet has pkt_type of PACKET_OTHERHOST when coming to ovs bridge,
the packet is dropped by ip_rcv() if rules are installed and skb are
forwarded by loopback device.
Packet isn't dropped if flow rule isn't installed in kernel datapath,
OVS_ACTION_ATTR_OUTPUT is used to send the packet.

netns A |                      root netns                     | netns B
   veth<->veth=ovs bridge=gre<-loop back->gre=ovs bridge=veth<->veth

arp packet ->
pkt_type
         BROADCAST------------>ip_rcv()------------------------>

                                                             <- arp reply
                                                                pkt_type

                                                         rule exists
                               ip_rcv()<-----------------OTHERHOST
                               drop

          <--------------------ip_rcv()<--- PACKET_HOST  rule doesn't exists
                               pass         ^              |
                                            |              |upcall
                                            |              V
                                            OVS_ACTION_ATTR_OUTPUT
                                            ovs-switchd

Cc: Murphy McCauley <murphy.mccau...@gmail.com>
Cc: Jesse Gross <je...@nicira.com>
Signed-off-by: Isaku Yamahata <yamah...@valinux.co.jp>
---
 datapath/vport.c |   29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/datapath/vport.c b/datapath/vport.c
index 03b775d..fadffe0 100644
--- a/datapath/vport.c
+++ b/datapath/vport.c
@@ -368,6 +368,35 @@ void ovs_vport_receive(struct vport *vport, struct sk_buff 
*skb,
        stats->rx_bytes += skb->len;
        u64_stats_update_end(&stats->syncp);
 
+       if (skb->pkt_type == PACKET_OTHERHOST) {
+               /*
+                * Workaround:
+                * Now dev_forward_skb() resets skb->packet_type to
+                * PACKET_HOST by the change set of
+                * 06a23fe31ca3992863721f21bdb0307af93da807
+                * For older kernel, skb can have packet_type of
+                * PACKET_OTHERHOST. In that case packet can be dropped
+                * unexpectedly as follows.
+                *
+                * root netns                     | netns X
+                * loop back<-gre=ovs bridge=veth<->veth  <--packet
+                *
+                *                           pkt_type
+                *                           dev_forward_skb():veth
+                *
+                *                           rule exists
+                * ip_rcv()<-----------------PACKET_OTHERHOST
+                * drop
+                *
+                * ip_rcv()<--- PACKET_HOST  rule doesn't exist
+                * pass         ^              |
+                *              |              |upcall
+                *              |              V
+                *              OVS_ACTION_ATTR_OUTPUT
+                *              ovs-switchd
+                */
+               skb->pkt_type = PACKET_HOST;
+       }
        OVS_CB(skb)->tun_key = tun_key;
        ovs_dp_process_received_packet(vport, skb);
 }
-- 
1.7.10.4

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to