/*
 * Copyright (c) 2015 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef __MPLS_LOOKUP_H__
#define __MPLS_LOOKUP_H__

#include <vnet/mpls/mpls.h>
#include <vnet/ip/ip.h>
#include <vnet/bier/bier_fwd.h>

/**
 * The arc/edge from the MPLS lookup node to the MPLS replicate node
 */
u32 mpls_lookup_to_replicate_edge;

/**
 * Enum of statically configred MPLS lookup next nodes
 */
typedef enum mpls_lookup_next_t_
{
    MPLS_LOOKUP_NEXT_DROP = 0,
} mpls_lookup_next_t;

/*
 * Compute flow hash. 
 * We'll use it to select which adjacency to use for this flow.  And other things.
 */
always_inline u32
mpls_compute_flow_hash (const mpls_unicast_header_t * hdr,
                        flow_hash_config_t flow_hash_config)
{
    /*
     * We need to byte swap so we use the numerical value. i.e. an odd label
     * leads to an odd bucket. as opposed to a label above and below value X.
     */
    u8 next_label_is_entropy;
    mpls_label_t ho_label;
    u32 hash, value;

    ho_label = clib_net_to_host_u32(hdr->label_exp_s_ttl);
    hash = vnet_mpls_uc_get_label(ho_label);
    next_label_is_entropy = 0;

    while (MPLS_EOS != vnet_mpls_uc_get_s(ho_label))
    {
        hdr++;
        ho_label = clib_net_to_host_u32(hdr->label_exp_s_ttl);
        value = vnet_mpls_uc_get_label(ho_label);

        if (1 == next_label_is_entropy)
        {
            /*
             * The label is an entropy value, use it alone as the hash
             */
            return (ho_label);
        }
        if (MPLS_IETF_ENTROPY_LABEL == value)
        {
            /*
             * we've met a label in the stack indicating that tha next
             * label is an entropy value
             */
            next_label_is_entropy = 1;
        }
        else
        {
            /*
             * XOR the label values in the stack together to
             * build up the hash value
             */
            hash ^= value;
        }
    }

    /*
     * check the top nibble for v4 and v6
     */
    hdr++;

    switch (((u8*)hdr)[0] >> 4)
    {
    case 4:
        /* incorporate the v4 flow-hash */
        hash ^= ip4_compute_flow_hash ((const ip4_header_t *)hdr,
                                       IP_FLOW_HASH_DEFAULT);
        break;
    case 6:
        /* incorporate the v6 flow-hash */
        hash ^= ip6_compute_flow_hash ((const ip6_header_t *)hdr,
                                       IP_FLOW_HASH_DEFAULT);
        break;
    case 5:
        /* incorporate the bier flow-hash */
        hash ^= bier_compute_flow_hash ((const bier_hdr_t *)hdr);
        break;
    default:
        break;
    }

    return (hash);
}

#endif /* __MPLS_LOOKUP_H__ */
