aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/fib/fib_path.h
blob: b6bf1e4fa832b1d94870c629bc0e1de33c887e21 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
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
/*
 * 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.
 */

/**
 * Given a route of the form;
 *   q.r.s.t/Y
 *     via <interface> <next-hop>
 *
 * The prefix is: q.r.s.t./Y
 * the path is: 'via <interface> <next-hop>
 *
 * The path is the description of where to send the traffic, and the
 * the prefix is a description of which traffic to send.
 * It is the aim of the FIB to resolve the path, i.e. to find the corresponding
 * adjacency to match the path's description.
 */

#ifndef __FIB_PATH_H__
#define __FIB_PATH_H__

#include <vnet/ip/ip.h>
#include <vnet/dpo/load_balance.h>

#include <vnet/fib/fib_types.h>
#include <vnet/adj/adj_types.h>

/**
 * Enurmeration of path configuration attributes
 */
typedef enum fib_path_cfg_attribute_t_ {
    /**
     * Marker. Add new types after this one.
     */
    FIB_PATH_CFG_ATTRIBUTE_FIRST = 0,
    /**
     * The path is forced to a drop, whatever the next-hop info says.
     * something somewhere knows better...
     */
    FIB_PATH_CFG_ATTRIBUTE_DROP = FIB_PATH_CFG_ATTRIBUTE_FIRST,
    /**
     * The path uses an adj that is exclusive. I.e. it is known only by
     * the source of the route.
     */
    FIB_PATH_CFG_ATTRIBUTE_EXCLUSIVE,
    /**
     * Recursion constraint via host
     */
    FIB_PATH_CFG_ATTRIBUTE_RESOLVE_HOST,
    /**
     * Recursion constraint via attached
     */
    FIB_PATH_CFG_ATTRIBUTE_RESOLVE_ATTACHED,
    /**
     * The path is attached
     */
    FIB_PATH_CFG_ATTRIBUTE_ATTACHED,
    /**
     * The path is a for-us path
     */
    FIB_PATH_CFG_ATTRIBUTE_INTF_RX,
    /**
     * The path is a deag with rpf-id
     */
    FIB_PATH_CFG_ATTRIBUTE_RPF_ID,
    /**
     * The path is an interface recieve
     */
    FIB_PATH_CFG_ATTRIBUTE_LOCAL,
    /**
     * Marker. Add new types before this one, then update it.
     */
    FIB_PATH_CFG_ATTRIBUTE_LAST = FIB_PATH_CFG_ATTRIBUTE_LOCAL,
} __attribute__ ((packed)) fib_path_cfg_attribute_t;

/**
 * The maximum number of path attributes
 */
#define FIB_PATH_CFG_ATTRIBUTE_MAX (FIB_PATH_CFG_ATTRIBUTE_LAST + 1)

#define FIB_PATH_CFG_ATTRIBUTES {			\
    [FIB_PATH_CFG_ATTRIBUTE_DROP]  = "drop",	        \
    [FIB_PATH_CFG_ATTRIBUTE_EXCLUSIVE] = "exclusive",	\
    [FIB_PATH_CFG_ATTRIBUTE_RESOLVE_HOST] = "resolve-host", \
    [FIB_PATH_CFG_ATTRIBUTE_RESOLVE_ATTACHED] = "resolve-attached", \
    [FIB_PATH_CFG_ATTRIBUTE_LOCAL] = "local",	        \
    [FIB_PATH_CFG_ATTRIBUTE_ATTACHED] = "attached",	\
    [FIB_PATH_CFG_ATTRIBUTE_INTF_RX] = "interface-rx",	\
    [FIB_PATH_CFG_ATTRIBUTE_RPF_ID] = "rpf-id",         \
}

#define FOR_EACH_FIB_PATH_CFG_ATTRIBUTE(_item) \
    for (_item = FIB_PATH_CFG_ATTRIBUTE_FIRST; \
	 _item <= FIB_PATH_CFG_ATTRIBUTE_LAST; \
	 _item++)

/**
 * Path config flags from the attributes
 */
typedef enum fib_path_cfg_flags_t_ {
    FIB_PATH_CFG_FLAG_NONE  = 0,
    FIB_PATH_CFG_FLAG_DROP  = (1 << FIB_PATH_CFG_ATTRIBUTE_DROP),
    FIB_PATH_CFG_FLAG_EXCLUSIVE = (1 << FIB_PATH_CFG_ATTRIBUTE_EXCLUSIVE),
    FIB_PATH_CFG_FLAG_RESOLVE_HOST = (1 << FIB_PATH_CFG_ATTRIBUTE_RESOLVE_HOST),
    FIB_PATH_CFG_FLAG_RESOLVE_ATTACHED = (1 << FIB_PATH_CFG_ATTRIBUTE_RESOLVE_ATTACHED),
    FIB_PATH_CFG_FLAG_LOCAL = (1 << FIB_PATH_CFG_ATTRIBUTE_LOCAL),
    FIB_PATH_CFG_FLAG_ATTACHED = (1 << FIB_PATH_CFG_ATTRIBUTE_ATTACHED),
    FIB_PATH_CFG_FLAG_INTF_RX = (1 << FIB_PATH_CFG_ATTRIBUTE_INTF_RX),
    FIB_PATH_CFG_FLAG_RPF_ID = (1 << FIB_PATH_CFG_ATTRIBUTE_RPF_ID),
} __attribute__ ((packed)) fib_path_cfg_flags_t;


extern u8 *fib_path_format(fib_node_index_t pi, u8 *s);
extern u8 *fib_path_adj_format(fib_node_index_t pi,
			       u32 indent,
			       u8 *s);

extern u8 * format_fib_path(u8 * s, va_list * args);

extern fib_node_index_t fib_path_create(fib_node_index_t pl_index,
					const fib_route_path_t *path);
extern fib_node_index_t fib_path_create_special(fib_node_index_t pl_index,
						fib_protocol_t nh_proto,
						fib_path_cfg_flags_t flags,
						const dpo_id_t *dpo);

extern int fib_path_cmp(fib_node_index_t path_index1,
			fib_node_index_t path_index2);
extern int fib_path_cmp_for_sort(void * a1, void * a2);
extern int fib_path_cmp_w_route_path(fib_node_index_t path_index,
				     const fib_route_path_t *rpath);
extern fib_node_index_t fib_path_copy(fib_node_index_t path_index,
				      fib_node_index_t path_list_index);
extern int fib_path_resolve(fib_node_index_t path_index);
extern int fib_path_is_resolved(fib_node_index_t path_index);
extern int fib_path_is_recursive_constrained(fib_node_index_t path_index);
extern int fib_path_is_exclusive(fib_node_index_t path_index);
extern int fib_path_is_deag(fib_node_index_t path_index);
extern int fib_path_is_looped(fib_node_index_t path_index);
extern fib_protocol_t fib_path_get_proto(fib_node_index_t path_index);
extern void fib_path_destroy(fib_node_index_t path_index);
extern uword fib_path_hash(fib_node_index_t path_index);
extern load_balance_path_t * fib_path_append_nh_for_multipath_hash(
    fib_node_index_t path_index,
    fib_forward_chain_type_t fct,
    load_balance_path_t *hash_key);
extern void fib_path_stack_mpls_disp(fib_node_index_t path_index,
                                     dpo_proto_t payload_proto,
                                     dpo_id_t *dpo);
extern void fib_path_contribute_forwarding(fib_node_index_t path_index,
					   fib_forward_chain_type_t type,
					   dpo_id_t *dpo);
extern void fib_path_contribute_urpf(fib_node_index_t path_index,
				     index_t urpf);
extern adj_index_t fib_path_get_adj(fib_node_index_t path_index);
extern int fib_path_recursive_loop_detect(fib_node_index_t path_index,
					  fib_node_index_t **entry_indicies);
extern u32 fib_path_get_resolving_interface(fib_node_index_t fib_entry_index);
extern int fib_path_get_weight(fib_node_index_t path_index);

extern void fib_path_module_init(void);
extern int fib_path_encode(fib_node_index_t path_list_index,
                           fib_node_index_t path_index,
			   void *ctx);

#endif