blob: 87845bb031b26004bfea21758893ff9a8cdb4fa4 [file] [log] [blame]
/*
* 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.
*/
/**
* @brief bier_fmask : The BIER fmask
*
* The BIER fmask contains the bitString that is applied to packets that
* egress towards the next-hop. As such the fmask is part of the rewrite
* (adj) for that next-hop. It it thus an extension of the next-hop and in
* no way associated with the bit-position(s) that are reachable through it.
* Fmasks are thus shared by bit-positions that egress through the same
* nh (BFR-NBR).
* Deag fmasks are also shared in the event that a router has local
* bit-positions. This is necessary to prevent the router receiving two copies
* of each packet. Consequently it also means that they share the same
* disposition data for the global data.
*/
#ifndef __BIER_FMASK_H__
#define __BIER_FMASK_H__
#include <vlib/vlib.h>
#include <vnet/fib/fib_node.h>
#include <vnet/mpls/packet.h>
#include <vnet/dpo/dpo.h>
#include <vnet/bier/bier_types.h>
#include <vnet/bier/bier_fmask_db.h>
/**
* A struct that represents the reference counting of the bits
*/
typedef struct bier_fmask_bits_t_ {
/**
* each bit in the mask needs to be reference counted
* and set/cleared on the 0->1 and 1->0 transitions.
*/
bier_bit_string_t bfmb_input_reset_string;
u32 *bfmb_refs;
/**
* The total number of references to bits set on this mask
* in effect a count of the number of children.
*/
u32 bfmb_count;
} bier_fmask_bits_t;
/**
* Flags on fmask
*/
typedef enum bier_fmask_attributes_t_
{
BIER_FMASK_ATTR_FIRST,
BIER_FMASK_ATTR_FORWARDING = BIER_FMASK_ATTR_FIRST,
BIER_FMASK_ATTR_DISP,
BIER_FMASK_ATTR_MPLS,
BIER_FMASK_ATTR_LAST = BIER_FMASK_ATTR_DISP,
} bier_fmask_attributes_t;
#define BIER_FMASK_ATTR_NAMES { \
[BIER_FMASK_ATTR_FORWARDING] = "forwarding", \
[BIER_FMASK_ATTR_DISP] = "disposition", \
[BIER_FMASK_ATTR_MPLS] = "mpls", \
}
#define FOR_EACH_BIER_FMASK_ATTR(_item) \
for (_item = BIER_FMASK_ATTR_FIRST; \
_item <= BIER_FMASK_ATTR_LAST; \
_item++)
typedef enum bier_fmask_flags_t_
{
BIER_FMASK_FLAG_FORWARDING = (1 << BIER_FMASK_ATTR_FORWARDING),
BIER_FMASK_FLAG_DISP = (1 << BIER_FMASK_ATTR_DISP),
BIER_FMASK_FLAG_MPLS = (1 << BIER_FMASK_ATTR_MPLS),
} bier_fmask_flags_t;
/**
* An outgoing BIER mask. aka forwarding bit mask (in the RFCs)
*
* This mask's function is two-fold
* 1 - it is logical-AND with the input packet header to produce the
* output packet header
* 2 - it is logical NAND with the input packet header to modify the bit-mask
* for the next lookup
*/
typedef struct bier_fmask_t_ {
/**
* Required for pool_get_aligned
*/
CLIB_CACHE_LINE_ALIGN_MARK(cacheline0);
/**
* The BIER fmask is a child of a FIB entry in the FIB graph.
*/
fib_node_t bfm_node;
/**
* operational/state flags on the fmask
*/
bier_fmask_flags_t bfm_flags;
/**
* The bits, and their ref counts, that are set on this mask
* This mask changes as BIER entries link to and from this fmask
*/
bier_fmask_bits_t bfm_bits;
/**
* The key to this fmask - used for store/lookup in the DB
*/
bier_fmask_id_t *bfm_id;
/**
* The MPLS label to paint on the header during forwarding
*/
mpls_label_t bfm_label;
/**
* The path-list
*/
fib_node_index_t bfm_pl;
/**
* the index of this fmask in the parent's child list.
*/
u32 bfm_sibling;
/**
* The index into the adj table for the adj that
* this fmask resolves via
*/
dpo_id_t bfm_dpo;
} bier_fmask_t;
extern void bier_fmask_link(index_t bfmi, bier_bp_t bp);
extern void bier_fmask_unlink(index_t bfmi, bier_bp_t bp);
extern void bier_fmask_unlock(index_t bfmi);
extern void bier_fmask_lock(index_t bfmi);
extern index_t bier_fmask_create_and_lock(const bier_fmask_id_t *fmid,
const fib_route_path_t *rpath);
extern u8* format_bier_fmask(u8 *s, va_list *ap);
extern void bier_fmask_contribute_forwarding(index_t bfmi,
dpo_id_t *dpo);
extern u32 bier_fmask_child_add (fib_node_index_t fib_entry_index,
fib_node_type_t child_type,
fib_node_index_t child_index);
extern void bier_fmask_child_remove (fib_node_index_t fib_entry_index,
u32 sibling_index);
extern void bier_fmask_get_stats (index_t bfmi, u64 * packets, u64 * bytes);
extern void bier_fmask_encode (index_t bfmi,
bier_table_id_t *btid,
fib_route_path_t *rpath);
/*
* provided for fast data-path access
*/
extern bier_fmask_t *bier_fmask_pool;
static inline bier_fmask_t *
bier_fmask_get (u32 index)
{
return (pool_elt_at_index(bier_fmask_pool, index));
}
#endif