Re: [ovs-discuss] Questions about qinq packet get a wrong hash from 'skb_get_hash'

2020-04-13 Thread Pravin Shelar
On Fri, Apr 3, 2020 at 8:20 AM Yutao (Simon, Cloud Infrastructure Service
Product Dept.)  wrote:

> 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:a0c25fb502f2(mac header),
> skb->network_header:a0c25fb50304(ip header), skb->protocol:0x8100,
> skb->protocol:0x8100,, is_vlan_tag_present:true
>
> ovs_vport_receive
>
> netdev_port_receive
>
> netdev_frame_hook skb->data:a0c25fb50300(inner vlan
> header), skb->network_header:a0c25fb50300, 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.
>
> [image: 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:
>
>
>
 So you are saying that the __skb_flow_dissect() fails when it is trying to
parse cvaln, right?




> 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?
>
We could write another  skb_get_hash() which takes noff as a parameter and
passed it on to __skb_flow_dissect(). OVS can call such function when
handling qinq packets.




> ___
> discuss mailing list
> disc...@openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-discuss
>
___
discuss mailing list
disc...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-discuss


[ovs-discuss] Questions about qinq packet get a wrong hash from 'skb_get_hash'

2020-04-03 Thread Yutao (Simon, Cloud Infrastructure Service Product Dept.)
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:a0c25fb502f2(mac header), 
skb->network_header:a0c25fb50304(ip header), skb->protocol:0x8100, 
skb->protocol:0x8100,, is_vlan_tag_present:true
ovs_vport_receive
netdev_port_receive
netdev_frame_hook skb->data:a0c25fb50300(inner vlan header), 
skb->network_header:a0c25fb50300, 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