Hi all,

We find a problem in our our environment with ovs+linux-kernel------ The same 
flow's packets will get different hash from 'skb_get_hash', if we push a vxlan 
header to these packets, the outter udp's sprot will be different.

The call stack and corresponding skb info:
ovs_dp_process_packet ------skb->data:ffffa0c25fb502f2(mac header), 
skb->network_header:ffffa0c25fb50304(ip header), skb->protocol:0x8100, 
skb->protocol:0x8100,, is_vlan_tag_present:true
ovs_vport_receive
netdev_port_receive
netdev_frame_hook ------------skb->data:ffffa0c25fb50300(inner vlan header), 
skb->network_header:ffffa0c25fb50300, skb->protocol:0x8100, 
skb->protocol:0x8100, is_vlan_tag_present:true
__netif_receive_skb_core
__netif_receive_skb
netif_receive_skb_internal
napi_gro_receive
recv_one_pkt
hinic_rx_poll
hinic_poll
net_rx_action
__do_softirq
call_softirq

Problem Description:
When ovs received a qinq packet, the kernel has untagged the outer vlan and 
save vlan_id in skb-> vlan_tci, vlan_protocol in skb->vlan_proto. Now 
skb->protocol=0x8100,skb->vlan_protocol=0x8100 skb->.

In 'netdev_frame_hook': skb->data point to packet's inner vlan, 
skb->network_header point to inner vlan too.

In 'ovs_vport_receive': After 'ovs_flow_key_extract', the skb->data will point 
to mac header, skb->network_header will point to ip header. Then 
'ovs_dp_process_packet' will call 'skb_get_hash'. 'skb_get_hash' will call 
'__skb_flow_dissect' finally.
[cid:image001.jpg@01D60995.BC93D3B0]

In '__skb_flow_dissect'( "flow_dissector.c" line 1161 of newest kernel code) . 
Because the network header is pointing to ip, when skb enter the vlan case in 
the second time, it will extract vlan info in ip header, then 
'__skb_flow_dissect' will return a error hash:

case htons(ETH_P_8021Q): {
                   const struct vlan_hdr *vlan = NULL;
                   struct vlan_hdr _vlan;
                   __be16 saved_vlan_tpid = proto;

                   if (dissector_vlan == FLOW_DISSECTOR_KEY_MAX &&
                       skb && skb_vlan_tag_present(skb)) {
                            proto = skb->protocol;
                   } else {
                            vlan = __skb_header_pointer(skb, nhoff, 
sizeof(_vlan),
                                                            data, hlen, &_vlan);
                            if (!vlan) {
                                     fdret = FLOW_DISSECT_RET_OUT_BAD;
                                     break;
                            }

                            proto = vlan->h_vlan_encapsulated_proto;
                            nhoff += sizeof(*vlan);
                   }



Is there any useful patch to fix this bug? Or some suggestion?
_______________________________________________
discuss mailing list
disc...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-discuss
  • [ovs-discuss] Qu... Yutao (Simon, Cloud Infrastructure Service Product Dept.)

Reply via email to