FD.io VPP  v21.06-3-gbb25fbf28
Vector Packet Processing
ip_neighbor_watch.c
Go to the documentation of this file.
1 /*
2  * ip_neighboor_watch.c; IP neighbor watching
3  *
4  * Copyright (c) 2019 Cisco and/or its affiliates.
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
20 #include <vnet/ip/ip_types_api.h>
22 
23 #include <vnet/ip-neighbor/ip_neighbor.api_enum.h>
24 #include <vnet/ip-neighbor/ip_neighbor.api_types.h>
25 
26 #include <vlibmemory/api.h>
27 
28 /**
29  * Database of registered watchers
30  * The key for a watcher is {type, sw_if_index, addreess}
31  * interface=~0 / address=all-zeros imples any.
32  */
34 {
37 
39 
40 static uword
43 {
44  ip_neighbor_event_t *ipne, *ipnes = NULL;
45  uword event_type = ~0;
46 
47  while (1)
48  {
50 
51  ipnes = vlib_process_get_event_data (vm, &event_type);
52 
53  switch (event_type)
54  {
55  default:
56  vec_foreach (ipne, ipnes) ip_neighbor_handle_event (ipne);
57  break;
58 
59  case ~0:
60  /* timeout - */
61  break;
62  }
63 
64  vec_reset_length (ipnes);
65  }
66  return 0;
67 }
68 
69 /* *INDENT-OFF* */
71  .function = ip_neighbor_event_process,
72  .type = VLIB_NODE_TYPE_PROCESS,
73  .name = "ip-neighbor-event",
74 };
75 /* *INDENT-ON* */
76 
77 
78 static clib_error_t *
80 {
81  ip_neighbor_key_t *key, *empty_keys = NULL;
82  ip_neighbor_watcher_t *watchers;
83  uword *v;
84  i32 pos;
85 
86  /* walk the entire IP neighbour DB and removes the client's registrations */
87  /* *INDENT-OFF* */
89  ({
90  watchers = (ip_neighbor_watcher_t*) *v;
91 
92  vec_foreach_index_backwards (pos, watchers) {
93  if (watchers[pos].ipw_client == client_index)
94  vec_del1(watchers, pos);
95  }
96 
97  if (vec_len(watchers) == 0)
98  vec_add1 (empty_keys, *key);
99  }));
100  /* *INDENT-OFF* */
101 
102  vec_foreach (key, empty_keys)
104  vec_free (empty_keys);
105  return (NULL);
106 }
107 
109 
110 static int
112  const ip_neighbor_watcher_t * w2)
113 {
114  return (0 == clib_memcmp (w1, w2, sizeof(*w1)));
115 }
116 
117 void
120  const ip_neighbor_watcher_t * watch)
121 {
123  .ipnk_ip = *ip,
124  .ipnk_sw_if_index = (sw_if_index == 0 ? ~0 : sw_if_index),
125  };
126  ip_neighbor_watcher_t *ipws = NULL;
127  uword *p;
128 
129  p = mhash_get (&ipnw_db.ipnwdb_hash, &key);
130 
131  if (p)
132  {
133  ipws = (ip_neighbor_watcher_t*) p[0];
134 
135  if (~0 != vec_search_with_function (ipws, watch,
137  /* duplicate */
138  return;
139  }
140 
141  vec_add1 (ipws, *watch);
142 
143  mhash_set (&ipnw_db.ipnwdb_hash, &key, (uword) ipws, NULL);
144 }
145 
146 void
149  const ip_neighbor_watcher_t * watch)
150 {
152  .ipnk_ip = *ip,
153  .ipnk_sw_if_index = (sw_if_index == 0 ? ~0 : sw_if_index),
154  };
155  ip_neighbor_watcher_t *ipws = NULL;
156  uword *p;
157  u32 pos;
158 
159  p = mhash_get (&ipnw_db.ipnwdb_hash, &key);
160 
161  if (!p)
162  return;
163 
164  ipws = (ip_neighbor_watcher_t*) p[0];
165 
166  pos = vec_search_with_function (ipws, watch, ip_neighbor_watch_cmp);
167 
168  if (~0 == pos)
169  return;
170 
171  vec_del1 (ipws, pos);
172 
173  if (vec_len(ipws) == 0)
174  mhash_unset (&ipnw_db.ipnwdb_hash, &key, NULL);
175 }
176 
177 static void
179  index_t ipni,
181 {
182  ip_neighbor_watcher_t *watcher;
183 
184  vec_foreach (watcher, watchers) {
185  ip_neighbor_event_t *ipne;
186 
189  0, 1, sizeof(*ipne));
190  ipne->ipne_watch = *watcher;
191  ipne->ipne_flags = flags;
193  }
194 }
195 
196 void
199 {
200  const ip_neighbor_t *ipn;
202  uword *p;
203 
204  ipn = ip_neighbor_get (ipni);
205 
206  clib_memcpy (&key, ipn->ipn_key, sizeof (key));
207 
208  /* Search the DB from longest to shortest key */
209  p = mhash_get (&ipnw_db.ipnwdb_hash, &key);
210 
211  if (p) {
213  }
214 
215  ip_address_reset (&key.ipnk_ip);
216  p = mhash_get (&ipnw_db.ipnwdb_hash, &key);
217 
218  if (p) {
220  }
221 
222  key.ipnk_sw_if_index = ~0;
223  p = mhash_get (&ipnw_db.ipnwdb_hash, &key);
224 
225  if (p) {
227  }
228 }
229 
230 static clib_error_t *
232  unformat_input_t * input,
233  vlib_cli_command_t * cmd)
234 {
235  ip_neighbor_watcher_t *watchers, *watcher;
237  uword *v;
238 
239  /* *INDENT-OFF* */
241  ({
242  watchers = (ip_neighbor_watcher_t*) *v;
243 
244  ASSERT(vec_len(watchers));
245  vlib_cli_output (vm, "Key: %U", format_ip_neighbor_key, key);
246 
247  vec_foreach (watcher, watchers)
248  vlib_cli_output (vm, " %U", format_ip_neighbor_watcher, watcher);
249  }));
250  /* *INDENT-ON* */
251  return (NULL);
252 }
253 
254 /* *INDENT-OFF* */
256  .path = "show ip neighbor-watcher",
257  .function = ip_neighbor_watchers_show,
258  .short_help = "show ip neighbors-watcher",
259 };
260 /* *INDENT-ON* */
261 
262 static clib_error_t *
264 {
266  sizeof (ip_neighbor_watcher_t *), sizeof (ip_neighbor_key_t));
267  return (NULL);
268 }
269 
270 /* *INDENT-OFF* */
272 {
273  .runs_after = VLIB_INITS("ip_neighbor_init"),
274 };
275 /* *INDENT-ON* */
276 
277 
278 /*
279  * fd.io coding-style-patch-verification: ON
280  *
281  * Local Variables:
282  * eval: (c-set-style "gnu")
283  * End:
284  */
ip_neighbor_t_
A representation of an IP neighbour/peer.
Definition: ip_neighbor_types.h:59
vec_reset_length
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
Definition: vec_bootstrap.h:194
ip_address
Definition: ip_types.h:79
ip_neighbor_watch_cmp
static int ip_neighbor_watch_cmp(const ip_neighbor_watcher_t *w1, const ip_neighbor_watcher_t *w2)
Definition: ip_neighbor_watch.c:111
api.h
want_ip_neighbor_events_reaper
static clib_error_t * want_ip_neighbor_events_reaper(u32 client_index)
Definition: ip_neighbor_watch.c:79
clib_memcpy
#define clib_memcpy(d, s, n)
Definition: string.h:197
ip_neighbor_watch_init
static clib_error_t * ip_neighbor_watch_init(vlib_main_t *vm)
Definition: ip_neighbor_watch.c:263
vlib_process_wait_for_event
static uword * vlib_process_wait_for_event(vlib_main_t *vm)
Definition: node_funcs.h:660
f
vlib_frame_t * f
Definition: interface_output.c:1080
clib_memcmp
#define clib_memcmp(s1, s2, m1)
Definition: string.h:734
ip_neighbor_get
ip_neighbor_t * ip_neighbor_get(index_t ipni)
Definition: ip_neighbor.c:89
ip_neighbor_event_t_
Definition: ip_neighbor_types.h:111
ip_neighbor_watcher_t_
Definition: ip_neighbor_types.h:40
vlib_cli_command_t::path
char * path
Definition: cli.h:96
mhash_t
Definition: mhash.h:46
ip_neighbor_event_process
static uword ip_neighbor_event_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
Definition: ip_neighbor_watch.c:41
ip_neighbor_event_process_node
vlib_node_registration_t ip_neighbor_event_process_node
(constructor) VLIB_REGISTER_NODE (ip_neighbor_event_process_node)
Definition: ip_neighbor_watch.c:70
mhash_get
static uword * mhash_get(mhash_t *h, const void *key)
Definition: mhash.h:110
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
ip_neighbor_clone
void ip_neighbor_clone(const ip_neighbor_t *ipn, ip_neighbor_t *clone)
Definition: ip_neighbor_types.c:21
unformat_input_t
struct _unformat_input_t unformat_input_t
mhash_init
__clib_export void mhash_init(mhash_t *h, uword n_value_bytes, uword n_key_bytes)
Definition: mhash.c:168
vlib_frame_t
Definition: node.h:372
vec_search_with_function
#define vec_search_with_function(v, E, fn)
Search a vector for the index of the entry that matches.
Definition: vec.h:1075
ip_neighbor_unwatch
void ip_neighbor_unwatch(const ip_address_t *ip, u32 sw_if_index, const ip_neighbor_watcher_t *watch)
Definition: ip_neighbor_watch.c:147
key
typedef key
Definition: ipsec_types.api:88
i32
signed int i32
Definition: types.h:77
ip_neighbor_signal
static void ip_neighbor_signal(ip_neighbor_watcher_t *watchers, index_t ipni, ip_neighbor_event_flags_t flags)
Definition: ip_neighbor_watch.c:178
vec_len
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Definition: vec_bootstrap.h:142
vec_add1
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:606
ip_neighbor_key_t_
Definition: ip_neighbor_types.h:49
vlib_process_get_event_data
static void * vlib_process_get_event_data(vlib_main_t *vm, uword *return_event_type_opaque)
Definition: node_funcs.h:530
ip_neighbor_t_::ipn_key
ip_neighbor_key_t * ipn_key
The idempotent key.
Definition: ip_neighbor_types.h:64
index_t
u32 index_t
A Data-Path Object is an object that represents actions that are applied to packets are they are swit...
Definition: dpo.h:43
uword
u64 uword
Definition: types.h:112
if
if(node->flags &VLIB_NODE_FLAG_TRACE) vnet_interface_output_trace(vm
vlib_process_signal_event_data
static void * vlib_process_signal_event_data(vlib_main_t *vm, uword node_index, uword type_opaque, uword n_data_elts, uword n_data_elt_bytes)
Definition: node_funcs.h:913
ip_neighbor_publish
void ip_neighbor_publish(index_t ipni, ip_neighbor_event_flags_t flags)
Definition: ip_neighbor_watch.c:197
ip_neighbor_watch.h
VLIB_CLI_COMMAND
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:163
ip_neighbor_watch_db_t_
Database of registered watchers The key for a watcher is {type, sw_if_index, addreess} interface=~0 /...
Definition: ip_neighbor_watch.c:33
show_ip_neighbor_watchers_cmd_node
static vlib_cli_command_t show_ip_neighbor_watchers_cmd_node
(constructor) VLIB_CLI_COMMAND (show_ip_neighbor_watchers_cmd_node)
Definition: ip_neighbor_watch.c:255
ipnw_db
static ip_neighbor_watch_db_t ipnw_db
Definition: ip_neighbor_watch.c:38
VL_MSG_API_REAPER_FUNCTION
VL_MSG_API_REAPER_FUNCTION(want_ip_neighbor_events_reaper)
ip_neighbor_handle_event
void ip_neighbor_handle_event(ip_neighbor_event_t *ipne)
From the watcher to the API to publish a new neighbor.
Definition: ip_neighbor_api.c:64
vlib_node_registration_t
struct _vlib_node_registration vlib_node_registration_t
vec_free
#define vec_free(V)
Free vector's memory (no header).
Definition: vec.h:395
ip_neighbor.h
ip_neighbor_watch
void ip_neighbor_watch(const ip_address_t *ip, u32 sw_if_index, const ip_neighbor_watcher_t *watch)
Definition: ip_neighbor_watch.c:118
u32
unsigned int u32
Definition: types.h:88
VLIB_INIT_FUNCTION
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:172
ethernet_types_api.h
ip_neighbor_watch_db_t
struct ip_neighbor_watch_db_t_ ip_neighbor_watch_db_t
Database of registered watchers The key for a watcher is {type, sw_if_index, addreess} interface=~0 /...
vec_foreach
#define vec_foreach(var, vec)
Vector iterator.
Definition: vec_bootstrap.h:213
VLIB_NODE_TYPE_PROCESS
@ VLIB_NODE_TYPE_PROCESS
Definition: node.h:84
ip_neighbor_watch_db_t_::ipnwdb_hash
mhash_t ipnwdb_hash
Definition: ip_neighbor_watch.c:35
vlib_main_t
Definition: main.h:102
VLIB_INITS
#define VLIB_INITS(...)
Definition: init.h:352
vlib_get_main
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:38
clib_error_t
Definition: clib_error.h:21
rt
vnet_interface_output_runtime_t * rt
Definition: interface_output.c:399
ip
vl_api_address_t ip
Definition: l2.api:558
vlib_init_function_t
clib_error_t *() vlib_init_function_t(struct vlib_main_t *vm)
Definition: init.h:51
ip_neighbor_event_t_::ipne_flags
ip_neighbor_event_flags_t ipne_flags
Definition: ip_neighbor_types.h:114
mhash_foreach
#define mhash_foreach(k, v, mh, body)
Definition: mhash.h:159
ip_neighbor_watchers_show
static clib_error_t * ip_neighbor_watchers_show(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ip_neighbor_watch.c:231
vlib_node_runtime_t
Definition: node.h:454
vlib_cli_command_t
Definition: cli.h:92
ip_neighbor_event_t_::ipne_watch
ip_neighbor_watcher_t ipne_watch
Definition: ip_neighbor_types.h:113
sw_if_index
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:34
ip_address_reset
void ip_address_reset(ip_address_t *ip)
Definition: ip_types.c:298
ip_types_api.h
mhash_unset
__clib_export uword mhash_unset(mhash_t *h, void *key, uword *old_value)
Definition: mhash.c:346
vec_del1
#define vec_del1(v, i)
Delete the element at index I.
Definition: vec.h:896
mhash_set
static uword mhash_set(mhash_t *h, void *key, uword new_value, uword *old_value)
Definition: mhash.h:117
ip_neighbor_event_flags_t
enum ip_neighbor_event_flags_t_ ip_neighbor_event_flags_t
VLIB_REGISTER_NODE
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
flags
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105
ip_neighbor_event_t_::ipne_nbr
ip_neighbor_t ipne_nbr
Definition: ip_neighbor_types.h:115