aboutsummaryrefslogtreecommitdiffstats
path: root/Makefile
diff options
context:
space:
mode:
authorRadu Nicolau <radu.nicolau@intel.com>2018-05-04 12:51:53 +0100
committerDamjan Marion <dmarion.lists@gmail.com>2018-05-04 21:53:29 +0000
commit89c27818b3bba409ed8e4ccacc9be37384b46705 (patch)
tree62c1c7814f5ccef0bc5a5ed5f403207d2bd603cb /Makefile
parent6168623290ff55e722bf77e448f3df385b6979d1 (diff)
ipsec: allow null/null for crypto/integ algorithms pair
Change-Id: Ic1e189c22e3d344d165e0eab05ccb667eef088a9 Signed-off-by: Radu Nicolau <radu.nicolau@intel.com>
Diffstat (limited to 'Makefile')
0 files changed, 0 insertions, 0 deletions
a id='n127' href='#n127'>127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321
/*
 * Copyright (c) 2016 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.
 */

#include <vlib/vlib.h>
#include <vnet/ip/format.h>
#include <vnet/ip/lookup.h>
#include <vnet/adj/adj.h>
#include <vnet/dpo/drop_dpo.h>

#include "fib_entry_src.h"
#include "fib_entry_src_rr.h"
#include "fib_entry_cover.h"
#include "fib_entry.h"
#include "fib_table.h"
#include "fib_path_ext.h"

/*
 * fib_entry_src_rr_resolve_via_connected
 *
 * Resolve via a connected cover.
 */
void
fib_entry_src_rr_resolve_via_connected (fib_entry_src_t *src,
					const fib_entry_t *fib_entry,
					const fib_entry_t *cover)
{
    const fib_route_path_t path = {
	.frp_proto = fib_proto_to_dpo(fib_entry->fe_prefix.fp_proto),
	.frp_addr = fib_entry->fe_prefix.fp_addr,
	.frp_sw_if_index = fib_entry_get_resolving_interface(
	                       fib_entry_get_index(cover)),
	.frp_fib_index = ~0,
	.frp_weight = 1,
    };
    fib_route_path_t *paths = NULL;
    vec_add1(paths, path);

    /*
     * since the cover is connected, the address this entry corresponds
     * to is a peer (ARP-able for) on the interface to which the cover is
     * connected. The fact we resolve via the cover, just means this RR
     * source is the first SRC to use said peer. The ARP source will be along
     * shortly to over-rule this RR source.
     */
    src->fes_pl = fib_path_list_create(FIB_PATH_LIST_FLAG_NONE, paths);
    src->fes_entry_flags |= (fib_entry_get_flags(fib_entry_get_index(cover)) &
                             FIB_ENTRY_FLAGS_RR_INHERITED);

    vec_free(paths);
}


/**
 * Source initialisation Function 
 */
static void
fib_entry_src_rr_init (fib_entry_src_t *src)
{
    src->u.rr.fesr_cover = FIB_NODE_INDEX_INVALID;
    src->u.rr.fesr_sibling = FIB_NODE_INDEX_INVALID;
}


/*
 * use the path-list of the cover, unless it would form a loop.
 * that is unless the cover is via this entry.
 * If a loop were to form it would be a 1 level loop (i.e. X via X),
 * and there would be 2 locks on the path-list; one since its used
 * by the cover, and 1 from here. The first lock will go when the
 * cover is removed, the second, and last, when the covered walk
 * occurs during the cover's removal - this is not a place where
 * we can handle last lock gone.
 * In short, don't let the loop form. The usual rules of 'we must
 * let it form so we know when it breaks' don't apply here, since
 * the loop will break when the cover changes, and this function
 * will be called again when that happens.
 */
void
fib_entry_src_rr_use_covers_pl (fib_entry_src_t *src,
                                const fib_entry_t *fib_entry,
                                const fib_entry_t *cover)
{
    fib_node_index_t *entries = NULL;
    dpo_proto_t proto;
    fib_entry_src_t *s;

    proto = fib_proto_to_dpo(fib_entry->fe_prefix.fp_proto);
    vec_add1(entries, fib_entry_get_index(fib_entry));

    if (fib_path_list_recursive_loop_detect(cover->fe_parent,
                                            &entries))
    {
        src->fes_pl = fib_path_list_create_special(proto,
                                                   FIB_PATH_LIST_FLAG_DROP,
                                                   drop_dpo_get(proto));
    }
    else
    {
        src->fes_pl = cover->fe_parent;
        vec_foreach (s,cover->fe_srcs)
          {
            if (s->fes_pl != cover->fe_parent)
              continue;

            src->fes_path_exts.fpel_exts = vec_dup (s->fes_path_exts.fpel_exts);
            break;
          }
    }
    vec_free(entries);
}

/*
 * Source activation. Called when the source is the new best source on the entry
 */
static int
fib_entry_src_rr_activate (fib_entry_src_t *src,
			   const fib_entry_t *fib_entry)
{
    fib_entry_t *cover;

    /*
     * find the covering prefix. become a dependent thereof.
     * for IP there should always be a cover, though it may be the default route.
     * For MPLS there is never a cover.
     */
    if (FIB_PROTOCOL_MPLS == fib_entry->fe_prefix.fp_proto)
    {
	src->fes_pl = fib_path_list_create_special(DPO_PROTO_MPLS,
						   FIB_PATH_LIST_FLAG_DROP,
						   NULL);
	fib_path_list_lock(src->fes_pl);
	return (!0);
    }

    src->u.rr.fesr_cover = fib_table_get_less_specific(fib_entry->fe_fib_index,
						     &fib_entry->fe_prefix);

    ASSERT(FIB_NODE_INDEX_INVALID != src->u.rr.fesr_cover);

    cover = fib_entry_get(src->u.rr.fesr_cover);

    src->u.rr.fesr_sibling =
	fib_entry_cover_track(cover, fib_entry_get_index(fib_entry));

    /*
     * if the cover is attached then install an attached-host path
     * (like an adj-fib). Otherwise inherit the forwarding from the cover
     */
    if (FIB_ENTRY_FLAG_ATTACHED & fib_entry_get_flags_i(cover))
    {
	fib_entry_src_rr_resolve_via_connected(src, fib_entry, cover);
    }
    else
    {
        fib_entry_src_rr_use_covers_pl(src, fib_entry, cover);
    }
    fib_path_list_lock(src->fes_pl);

    /*
     * return go for install
     */
    return (!0);
}

/**
 * Source Deactivate. 
 * Called when the source is no longer best source on the entry
 */
static void
fib_entry_src_rr_deactivate (fib_entry_src_t *src,
			     const fib_entry_t *fib_entry)
{
    fib_entry_t *cover;

    /*
     * remove the dependency on the covering entry
     */
    if (FIB_NODE_INDEX_INVALID != src->u.rr.fesr_cover)
    {
        fib_node_index_t *entries = NULL;

	cover = fib_entry_get(src->u.rr.fesr_cover);
	fib_entry_cover_untrack(cover, src->u.rr.fesr_sibling);
	src->u.rr.fesr_cover = FIB_NODE_INDEX_INVALID;

        if (FIB_NODE_INDEX_INVALID != cover->fe_parent)
        {
            fib_path_list_recursive_loop_detect(cover->fe_parent, &entries);

            vec_free(entries);
        }
    }

    fib_path_list_unlock(src->fes_pl);
    src->fes_pl = FIB_NODE_INDEX_INVALID;
    vec_free (src->fes_path_exts.fpel_exts);
    src->fes_entry_flags = FIB_ENTRY_FLAG_NONE;
}

fib_entry_src_cover_res_t
fib_entry_src_rr_cover_change (fib_entry_src_t *src,
			       const fib_entry_t *fib_entry)
{
    fib_entry_src_cover_res_t res = {
	.install = !0,
	.bw_reason = FIB_NODE_BW_REASON_FLAG_NONE,
    };

    if (FIB_NODE_INDEX_INVALID == src->u.rr.fesr_cover)
    {
	/*
	 * the source may be added, but it is not active
	 * if it is not tracking the cover.
	 */
	return (res);
    }

    /*
     * this function is called when this entry's cover has a more specific
     * entry inserted benaeth it. That does not necessarily mean that this
     * entry is covered by the new prefix. check that
     */
    if (src->u.rr.fesr_cover != fib_table_get_less_specific(fib_entry->fe_fib_index,
							  &fib_entry->fe_prefix))
    {
	fib_entry_src_rr_deactivate(src, fib_entry);
	fib_entry_src_rr_activate(src, fib_entry);

	/*
	 * dependent children need to re-resolve to the new forwarding info
	 */
	res.bw_reason = FIB_NODE_BW_REASON_FLAG_EVALUATE;
    }
    return (res);
}

/*
 * fib_entry_src_rr_cover_update
 *
 * This entry's cover has updated its forwarding info. This entry
 * will need to re-inheret.
 */
fib_entry_src_cover_res_t
fib_entry_src_rr_cover_update (fib_entry_src_t *src,
			       const fib_entry_t *fib_entry)
{
    fib_entry_src_cover_res_t res = {
	.install = !0,
	.bw_reason = FIB_NODE_BW_REASON_FLAG_NONE,
    };
    fib_node_index_t old_path_list;
    fib_entry_t *cover;

    if (FIB_NODE_INDEX_INVALID == src->u.rr.fesr_cover)
    {
	/*
	 * the source may be added, but it is not active
	 * if it is not tracking the cover.
	 */
	return (res);
    }

    cover = fib_entry_get(src->u.rr.fesr_cover);
    old_path_list = src->fes_pl;

    /*
     * if the ocver is attached then install an attached-host path
     * (like an adj-fib). Otherwise inherit the forwarding from the cover
     */
    if (FIB_ENTRY_FLAG_ATTACHED & fib_entry_get_flags_i(cover))
    {
	fib_entry_src_rr_resolve_via_connected(src, fib_entry, cover);
    }
    else
    {
        fib_entry_src_rr_use_covers_pl(src, fib_entry, cover);
    }
    fib_path_list_lock(src->fes_pl);
    fib_path_list_unlock(old_path_list);

    /*
     * dependent children need to re-resolve to the new forwarding info
     */
    res.bw_reason = FIB_NODE_BW_REASON_FLAG_EVALUATE;

    return (res);
}

static u8*
fib_entry_src_rr_format (fib_entry_src_t *src,
			 u8* s)
{
    return (format(s, " cover:%d", src->u.rr.fesr_cover));
}

const static fib_entry_src_vft_t rr_src_vft = {
    .fesv_init = fib_entry_src_rr_init,
    .fesv_activate = fib_entry_src_rr_activate,
    .fesv_deactivate = fib_entry_src_rr_deactivate,
    .fesv_cover_change = fib_entry_src_rr_cover_change,
    .fesv_cover_update = fib_entry_src_rr_cover_update,
    .fesv_format = fib_entry_src_rr_format,
};

void
fib_entry_src_rr_register (void)
{
    fib_entry_src_behaviour_register(FIB_SOURCE_BH_RR, &rr_src_vft);
}