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
|
/*
* 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.
*/
/**
* An adjacency is a representation of an attached L3 peer.
*
* Adjacency Sub-types:
* - neighbour: a representation of an attached L3 peer.
* Key:{addr,interface,link/ether-type}
* SHARED
* - glean: used to drive ARP/ND for packets destined to a local sub-net.
* 'glean' mean use the packet's destination address as the target
* address in the ARP packet.
* UNSHARED. Only one per-interface.
* - midchain: a nighbour adj on a virtual/tunnel interface.
* - rewrite: an adj with no key, but with a rewrite string.
*
* The API to create and update the adjacency is very sub-type specific. This
* is intentional as it encourages the user to carefully consider which adjacency
* sub-type they are really using, and hence assign it data in the appropriate
* sub-type space in the union of sub-types. This prevents the adj becoming a
* disorganised dumping group for 'my features needs a u16 somewhere' data. It
* is important to enforce this approach as space in the adjacency is a premium,
* as we need it to fit in 1 cache line.
*
* the API is also based around an index to an ajdacency not a raw pointer. This
* is so the user doesn't suffer the same limp inducing firearm injuries that
* the author suffered as the adjacenices can realloc.
*/
#ifndef __ADJ_H__
#define __ADJ_H__
#include <vnet/ip/lookup.h>
#include <vnet/adj/adj_types.h>
#include <vnet/adj/adj_nbr.h>
#include <vnet/adj/adj_glean.h>
/**
* @brief
* Take a reference counting lock on the adjacency
*/
extern void adj_lock(adj_index_t adj_index);
/**
* @brief
* Release a reference counting lock on the adjacency
*/
extern void adj_unlock(adj_index_t adj_index);
/**
* @brief
* Add a child dependent to an adjacency. The child will
* thus be informed via its registerd back-walk function
* when the adjacency state changes.
*/
extern u32 adj_child_add(adj_index_t adj_index,
fib_node_type_t type,
fib_node_index_t child_index);
/**
* @brief
* Remove a child dependent
*/
extern void adj_child_remove(adj_index_t adj_index,
u32 sibling_index);
/**
* @brief Walk the Adjacencies on a given interface
*/
extern void adj_walk (u32 sw_if_index,
adj_walk_cb_t cb,
void *ctx);
/**
* @brief Return the link type of the adjacency
*/
extern vnet_link_t adj_get_link_type (adj_index_t ai);
/**
* @brief Return the sw interface index of the adjacency.
*/
extern u32 adj_get_sw_if_index (adj_index_t ai);
/**
* @brief Return the link type of the adjacency
*/
extern const u8* adj_get_rewrite (adj_index_t ai);
/**
* @brief Notify the adjacency subsystem that the features settings for
* an interface have changed
*/
extern void adj_feature_update (u32 sw_if_index, u8 arc_index, u8 is_enable);
/**
* @brief
* The global adjacnecy pool. Exposed for fast/inline data-plane access
*/
extern ip_adjacency_t *adj_pool;
/**
* @brief
* Adjacency packet counters
*/
extern vlib_combined_counter_main_t adjacency_counters;
/**
* @brief Global Config for enabling per-adjacency counters
* This is configurable because it comes with a non-negligible
* performance cost. */
extern int adj_per_adj_counters;
/**
* @brief
* Get a pointer to an adjacency object from its index
*/
static inline ip_adjacency_t *
adj_get (adj_index_t adj_index)
{
return (vec_elt_at_index(adj_pool, adj_index));
}
/**
* @brief Get the global configuration option for enabling per-adj counters
*/
static inline int
adj_are_counters_enabled (void)
{
return (adj_per_adj_counters);
}
#endif
|