/*
 * Copyright (c) 2020 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.
 */

/**
 * @brief FIB Source Address selection
 *
 * Use the FIB for source address selection on an interface
 */

#include <vnet/fib/fib_sas.h>
#include <vnet/adj/adj_glean.h>
#include <vnet/ip/ip6_link.h>


bool
fib_sas_get (u32 sw_if_index,
             ip_address_family_t af,
             const ip46_address_t *dst,
             ip46_address_t *src)
{
    switch (af)
    {
    case AF_IP4:
        if (dst)
            return (fib_sas4_get(sw_if_index, &dst->ip4, &src->ip4));
        else
            return (fib_sas4_get(sw_if_index, NULL, &src->ip4));
    case AF_IP6:
        if (dst)
            return (fib_sas6_get(sw_if_index, &dst->ip6, &src->ip6));
        else
            return (fib_sas6_get(sw_if_index, NULL, &src->ip6));
    }
    return (false);
}

bool
fib_sas4_get (u32 sw_if_index,
              const ip4_address_t *dst,
              ip4_address_t *src)
{
    ip46_address_t d_tmp, *d_tmpp = NULL;
    const ip46_address_t *s_tmp;
    vnet_sw_interface_t *swif;

    if (dst)
    {
        d_tmpp = &d_tmp;
        d_tmp.ip4 = *dst;
    }

    if (vnet_sw_interface_is_p2p(vnet_get_main(), sw_if_index))
    {
        ip4_address_t *ip4;
        ip4 = ip_interface_get_first_ip (sw_if_index, 1);
        if (ip4) {
            src->as_u32 = ip4->as_u32;
            return (true);
        } else {
            return (false);
        }
    }

    /*
     * If the interface is unnumbered then use the IP interface
     */
    swif = vnet_get_sw_interface (vnet_get_main(), sw_if_index);

    if (swif->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED)
        sw_if_index = swif->unnumbered_sw_if_index;

    /*
     * get the source address from the glean adjacency
     */
    s_tmp = adj_glean_get_src (FIB_PROTOCOL_IP4, sw_if_index, d_tmpp);

    if (NULL != s_tmp)
    {
        src->as_u32 = s_tmp->ip4.as_u32;
        return (true);
    }

    return (false);
}

bool
fib_sas6_get (u32 sw_if_index,
              const ip6_address_t *dst,
              ip6_address_t *src)
{
    ip46_address_t d_tmp, *d_tmpp = NULL;
    const ip46_address_t *s_tmp;

    if (dst)
    {
        d_tmpp = &d_tmp;
        d_tmp.ip6 = *dst;
    }

    /*
     * if the dst is v6 and link local, use the source link local
     */
    if (dst && ip6_address_is_link_local_unicast (dst))
    {
        const ip6_address_t *ll = ip6_get_link_local_address (sw_if_index);
        if (NULL == ll)
        {
            return (false);
        }
        ip6_address_copy (src, ll);
        return (true);
    }

    if (vnet_sw_interface_is_p2p(vnet_get_main(), sw_if_index))
    {
        ip6_address_t *ip6;
        ip6 = ip_interface_get_first_ip (sw_if_index, 0);
        if (ip6) {
            ip6_address_copy(src, ip6);
            return (true);
        } else {
            return (false);
        }
    }

    /*
     * get the source address from the glean adjacency
     */
    s_tmp = adj_glean_get_src (FIB_PROTOCOL_IP6, sw_if_index, d_tmpp);

    if (NULL != s_tmp)
    {
        ip6_address_copy(src, &s_tmp->ip6);
        return (true);
    }

    return (false);
}
