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 <[email protected]>
Cc: Jesse Gross <[email protected]>
Signed-off-by: Isaku Yamahata <[email protected]>
---
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
[email protected]
http://openvswitch.org/mailman/listinfo/dev