flow_hash_symmetric_l3l4(const struct flow *flow, uint32_t basis,
                         bool inc_udp_ports)
{
    uint32_t hash = basis;

    /* UDP source and destination port are also taken into account. */
    if (flow->dl_type == htons(ETH_TYPE_IP)) {
        hash = hash_add(hash,
                        (OVS_FORCE uint32_t) (flow->nw_src ^ flow->nw_dst));
    } else if (flow->dl_type == htons(ETH_TYPE_IPV6)) {
        /* IPv6 addresses are 64-bit aligned inside struct flow. */
        const uint64_t *a = ALIGNED_CAST(uint64_t *, flow->ipv6_src.s6_addr);
        const uint64_t *b = ALIGNED_CAST(uint64_t *, flow->ipv6_dst.s6_addr);

        for (int i = 0; i < sizeof flow->ipv6_src / sizeof *a; i++) {
            hash = hash_add64(hash, a[i] ^ b[i]);
        }
    } else {
        /* Revert to hashing L2 headers */
        return flow_hash_symmetric_l2(flow, basis);
    }
    hash = hash_add(hash, flow->nw_proto);
    if (!(flow->nw_frag & FLOW_NW_FRAG_MASK)
        && (flow->nw_proto == IPPROTO_TCP || flow->nw_proto == IPPROTO_SCTP ||
            (inc_udp_ports && flow->nw_proto == IPPROTO_UDP))) {
        hash = hash_add(hash,
                        (OVS_FORCE uint16_t) (flow->tp_src ^ flow->tp_dst));
    }

    return hash_finish(hash, basis);
}
flow_hash_symmetric_l3l4(const struct flow *flow, uint32_t basis,
                         bool inc_udp_ports)
{
    uint32_t hash = basis;

     
    if (flow->dl_type == htons(ETH_TYPE_IP)) {
        hash = hash_add(hash,
                        (OVS_FORCE uint32_t) (flow->nw_src ^ flow->nw_dst));
    } else if (flow->dl_type == htons(ETH_TYPE_IPV6)) {
         
        const uint64_t *a = ALIGNED_CAST(uint64_t *, flow->ipv6_src.s6_addr);
        const uint64_t *b = ALIGNED_CAST(uint64_t *, flow->ipv6_dst.s6_addr);

        for (int i = 0; i < sizeof flow->ipv6_src / sizeof *a; i++) {
            hash = hash_add64(hash, a[i] ^ b[i]);
        }
    } else {
         
        return flow_hash_symmetric_l2(flow, basis);
    }
    hash = hash_add(hash, flow->nw_proto);
    if (!(flow->nw_frag & FLOW_NW_FRAG_MASK)
        && (flow->nw_proto == IPPROTO_TCP || flow->nw_proto == IPPROTO_SCTP ||
            (inc_udp_ports && flow->nw_proto == IPPROTO_UDP))) {
        hash = hash_add(hash,
                        (OVS_FORCE uint16_t) (flow->tp_src ^ flow->tp_dst));
    }

    return hash_finish(hash, basis);
}