FD.io VPP  v20.05.1-6-gf53edbc3b
Vector Packet Processing
ip6_nd_api.c
Go to the documentation of this file.
1 /*
2  *------------------------------------------------------------------
3  * ip_api.c - vnet ip api
4  *
5  * Copyright (c) 2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19 
20 #include <stddef.h>
21 
22 #include <vnet/ip6-nd/ip6_nd.h>
23 #include <vnet/ip6-nd/ip6_ra.h>
24 
25 #include <vnet/fib/fib_table.h>
26 #include <vnet/ip/ip_types_api.h>
27 
28 #include <vpp/app/version.h>
29 
30 #include <vlibapi/api.h>
31 #include <vlibmemory/api.h>
32 
33 /* define message IDs */
34 #include <vnet/format_fns.h>
35 #include <vnet/ip6-nd/ip6_nd.api_enum.h>
36 #include <vnet/ip6-nd/ip6_nd.api_types.h>
37 
38 /**
39  * Base message ID fot the plugin
40  */
42 #define REPLY_MSG_ID_BASE ip6_nd_base_msg_id
43 
45 
46 static void
48  u32 context,
49  const ip46_address_t * addr, u32 sw_if_index)
50 {
52 
53  mp = vl_msg_api_alloc (sizeof (*mp));
54  clib_memset (mp, 0, sizeof (*mp));
55  mp->_vl_msg_id = ntohs (VL_API_IP6ND_PROXY_DETAILS);
56  mp->context = context;
57  mp->sw_if_index = htonl (sw_if_index);
58 
59  ip6_address_encode (&addr->ip6, mp->ip);
60 
61  vl_api_send_msg (reg, (u8 *) mp);
62 }
63 
65 {
68 
71 {
73 
75  {
76  vec_add1 (ctx->indices, fei);
77  }
78 
79  return (FIB_TABLE_WALK_CONTINUE);
80 }
81 
82 static void
84 {
85  ip6_main_t *im6 = &ip6_main;
86  fib_table_t *fib_table;
88  .indices = NULL,
89  };
90  fib_node_index_t *feip;
91  const fib_prefix_t *pfx;
93 
95  if (!reg)
96  return;
97 
98  /* *INDENT-OFF* */
99  pool_foreach (fib_table, im6->fibs,
100  ({
101  fib_table_walk(fib_table->ft_index,
102  FIB_PROTOCOL_IP6,
103  api_ip6nd_proxy_fib_table_walk,
104  &ctx);
105  }));
106  /* *INDENT-ON* */
107 
109 
110  vec_foreach (feip, ctx.indices)
111  {
112  pfx = fib_entry_get_prefix (*feip);
113 
115  mp->context,
116  &pfx->fp_addr,
118  }
119 
120  vec_free (ctx.indices);
121 }
122 
123 static void
125 {
126  vl_api_ip6nd_proxy_add_del_reply_t *rmp;
127  ip6_address_t ip6;
128  int rv = 0;
129 
131 
132  ip6_address_decode (mp->ip, &ip6);
133  if (mp->is_add)
134  rv = ip6_nd_proxy_add (ntohl (mp->sw_if_index), &ip6);
135  else
136  rv = ip6_nd_proxy_del (ntohl (mp->sw_if_index), &ip6);
137 
139  REPLY_MACRO (VL_API_IP6ND_PROXY_ADD_DEL_REPLY);
140 }
141 
142 static void
145 {
146  vl_api_sw_interface_ip6nd_ra_config_reply_t *rmp;
148  int rv = 0;
149  u8 is_no, suppress, managed, other, ll_option, send_unicast, cease,
150  default_router;
151 
152  is_no = mp->is_no == 1;
153  suppress = mp->suppress == 1;
154  managed = mp->managed == 1;
155  other = mp->other == 1;
156  ll_option = mp->ll_option == 1;
157  send_unicast = mp->send_unicast == 1;
158  cease = mp->cease == 1;
159  default_router = mp->default_router == 1;
160 
162 
163  rv = ip6_ra_config (vm, ntohl (mp->sw_if_index),
164  suppress, managed, other,
165  ll_option, send_unicast, cease,
166  default_router, ntohl (mp->lifetime),
167  ntohl (mp->initial_count),
168  ntohl (mp->initial_interval),
169  ntohl (mp->max_interval),
170  ntohl (mp->min_interval), is_no);
171 
173 
174  REPLY_MACRO (VL_API_SW_INTERFACE_IP6ND_RA_CONFIG_REPLY);
175 }
176 
177 static void
180 {
182  vl_api_sw_interface_ip6nd_ra_prefix_reply_t *rmp;
183  fib_prefix_t pfx;
184  int rv = 0;
185  u8 is_no, use_default, no_advertise, off_link, no_autoconfig, no_onlink;
186 
188 
189  ip_prefix_decode (&mp->prefix, &pfx);
190  is_no = mp->is_no == 1;
191  use_default = mp->use_default == 1;
192  no_advertise = mp->no_advertise == 1;
193  off_link = mp->off_link == 1;
194  no_autoconfig = mp->no_autoconfig == 1;
195  no_onlink = mp->no_onlink == 1;
196 
197  rv = ip6_ra_prefix (vm, ntohl (mp->sw_if_index),
198  &pfx.fp_addr.ip6,
199  pfx.fp_len, use_default,
200  ntohl (mp->val_lifetime),
201  ntohl (mp->pref_lifetime), no_advertise,
202  off_link, no_autoconfig, no_onlink, is_no);
203 
205  REPLY_MACRO (VL_API_SW_INTERFACE_IP6ND_RA_PREFIX_REPLY);
206 }
207 
208 static void
211 {
212  vl_api_ip6nd_send_router_solicitation_reply_t *rmp;
215  int rv = 0;
216 
218 
220  REPLY_MACRO (VL_API_IP6ND_SEND_ROUTER_SOLICITATION_REPLY);
221 
222  if (rv != 0)
223  return;
224 
225  params.irt = ntohl (mp->irt);
226  params.mrt = ntohl (mp->mrt);
227  params.mrc = ntohl (mp->mrc);
228  params.mrd = ntohl (mp->mrd);
229 
230  icmp6_send_router_solicitation (vm, ntohl (mp->sw_if_index), mp->stop,
231  &params);
232 }
233 
234 static void
236 {
237  /* *INDENT-OFF* */
239 
240  pool_foreach(rp, vpe_api_main.ip6_ra_events_registrations,
241  ({
242  vl_api_registration_t *vl_reg;
243 
244  vl_reg = vl_api_client_index_to_registration (rp->client_index);
245 
246  if (vl_reg && vl_api_can_send_msg (vl_reg))
247  {
248  vl_api_ip6_ra_prefix_info_t *prefix;
249  vl_api_ip6_ra_event_t *event;
250 
251  u32 event_size = (sizeof (vl_api_ip6_ra_event_t) +
252  vec_len (rap->prefixes) *
253  sizeof (vl_api_ip6_ra_prefix_info_t));
254  event = vl_msg_api_alloc_zero (event_size);
255 
256  event->_vl_msg_id = htons (VL_API_IP6_RA_EVENT + REPLY_MSG_ID_BASE);
257  event->client_index = rp->client_index;
258  event->pid = rp->client_pid;
259  event->sw_if_index = clib_host_to_net_u32 (rap->sw_if_index);
260 
261  ip6_address_encode (&rap->router_address,
262  event->router_addr);
263 
264  event->current_hop_limit = rap->current_hop_limit;
265  event->flags = rap->flags;
266  event->router_lifetime_in_sec =
267  clib_host_to_net_u16 (rap->router_lifetime_in_sec);
268  event->neighbor_reachable_time_in_msec =
269  clib_host_to_net_u32 (rap->neighbor_reachable_time_in_msec);
270  event->time_in_msec_between_retransmitted_neighbor_solicitations =
271  clib_host_to_net_u32 (rap->time_in_msec_between_retransmitted_neighbor_solicitations);
272  event->n_prefixes = clib_host_to_net_u32 (vec_len (rap->prefixes));
273 
274  prefix = event->prefixes;
275  // (typeof (prefix)) event->prefixes;
276  u32 j;
277  for (j = 0; j < vec_len (rap->prefixes); j++)
278  {
279  ra_report_prefix_info_t *info = &rap->prefixes[j];
280  ip_prefix_encode(&info->prefix, &prefix->prefix);
281  prefix->flags = info->flags;
282  prefix->valid_time = clib_host_to_net_u32 (info->valid_time);
283  prefix->preferred_time =
284  clib_host_to_net_u32 (info->preferred_time);
285  prefix++;
286  }
287 
288  vl_api_send_msg (vl_reg, (u8 *) event);
289  }
290  }));
291  /* *INDENT-ON* */
292 }
293 
294 static void
296 {
298  vl_api_want_ip6_ra_events_reply_t *rmp;
299  int rv = 0, had_reg, have_reg;
300 
301  had_reg = hash_elts (am->ip6_ra_events_registration_hash);
302  uword *p = hash_get (am->ip6_ra_events_registration_hash, mp->client_index);
304  if (p)
305  {
306  if (mp->enable)
307  {
308  clib_warning ("pid %d: already enabled...", ntohl (mp->pid));
309  rv = VNET_API_ERROR_INVALID_REGISTRATION;
310  goto reply;
311  }
312  else
313  {
314  rp = pool_elt_at_index (am->ip6_ra_events_registrations, p[0]);
315  pool_put (am->ip6_ra_events_registrations, rp);
316  hash_unset (am->ip6_ra_events_registration_hash, mp->client_index);
317  goto reply;
318  }
319  }
320  if (mp->enable == 0)
321  {
322  clib_warning ("pid %d: already disabled...", ntohl (mp->pid));
323  rv = VNET_API_ERROR_INVALID_REGISTRATION;
324  goto reply;
325  }
326  pool_get (am->ip6_ra_events_registrations, rp);
327  rp->client_index = mp->client_index;
328  rp->client_pid = ntohl (mp->pid);
329  hash_set (am->ip6_ra_events_registration_hash, rp->client_index,
330  rp - am->ip6_ra_events_registrations);
331 
332 reply:
333  have_reg = hash_elts (am->ip6_ra_events_registration_hash);
334 
335  if (!had_reg && have_reg)
337  else if (had_reg && !have_reg)
339 
340  REPLY_MACRO (VL_API_WANT_IP6_RA_EVENTS_REPLY);
341 }
342 
343 static clib_error_t *
345 {
348  uword *p;
349 
350  p = hash_get (am->ip6_ra_events_registration_hash, client_index);
351 
352  if (p)
353  {
354  rp = pool_elt_at_index (am->ip6_ra_events_registrations, p[0]);
355  pool_put (am->ip6_ra_events_registrations, rp);
356  hash_unset (am->ip6_ra_events_registration_hash, client_index);
357  }
358  return (NULL);
359 }
360 
362 
363 #include <vnet/ip6-nd/ip6_nd.api.c>
364 
365 static clib_error_t *
367 {
368  /* Ask for a correctly-sized block of API message decode slots */
369  ip6_nd_base_msg_id = setup_message_id_table ();
370 
371  return 0;
372 }
373 
375 
376 /*
377  * fd.io coding-style-patch-verification: ON
378  *
379  * Local Variables:
380  * eval: (c-set-style "gnu")
381  * End:
382  */
void ip6_ra_report_register(ip6_ra_report_notify_t fn)
Definition: ip6_ra.c:167
static void send_ip6nd_proxy_details(vl_api_registration_t *reg, u32 context, const ip46_address_t *addr, u32 sw_if_index)
Definition: ip6_nd_api.c:47
Continue on to the next entry.
Definition: fib_table.h:916
#define hash_set(h, key, value)
Definition: hash.h:255
Register for ip6 router advertisement events.
Definition: ip6_nd.api:181
#define hash_unset(h, key)
Definition: hash.h:261
void ip_prefix_decode(const vl_api_prefix_t *in, fib_prefix_t *out)
Definition: ip_types_api.c:233
static void vl_api_sw_interface_ip6nd_ra_prefix_t_handler(vl_api_sw_interface_ip6nd_ra_prefix_t *mp)
Definition: ip6_nd_api.c:179
static void vl_api_ip6nd_send_router_solicitation_t_handler(vl_api_ip6nd_send_router_solicitation_t *mp)
Definition: ip6_nd_api.c:210
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
static clib_error_t * ip6_nd_api_init(vlib_main_t *vm)
Definition: ip6_nd_api.c:366
static void vl_api_send_msg(vl_api_registration_t *rp, u8 *elem)
Definition: api.h:35
void ip6_address_decode(const vl_api_ip6_address_t in, ip6_address_t *out)
Definition: ip_types_api.c:117
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:590
void icmp6_send_router_solicitation(vlib_main_t *vm, u32 sw_if_index, u8 stop, const icmp6_send_router_solicitation_params_t *params)
Definition: ip6_ra.c:1303
const fib_prefix_t * fib_entry_get_prefix(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1691
IPv6 router advertisement config request.
Definition: ip6_nd.api:45
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:252
void * vl_msg_api_alloc(int nbytes)
int ip6_ra_config(vlib_main_t *vm, u32 sw_if_index, u8 suppress, u8 managed, u8 other, u8 ll_option, u8 send_unicast, u8 cease, u8 use_lifetime, u32 lifetime, u32 initial_count, u32 initial_interval, u32 max_interval, u32 min_interval, u8 is_no)
Definition: ip6_ra.c:1671
vhost_vring_addr_t addr
Definition: vhost_user.h:254
unsigned char u8
Definition: types.h:56
static void vl_api_sw_interface_ip6nd_ra_config_t_handler(vl_api_sw_interface_ip6nd_ra_config_t *mp)
Definition: ip6_nd_api.c:144
int ip6_nd_proxy_add(u32 sw_if_index, const ip6_address_t *addr)
Definition: ip6_nd_proxy.c:72
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:513
vl_api_interface_index_t sw_if_index
Definition: gre.api:53
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
Start / stop sending router solicitation.
Definition: ip6_nd.api:158
vl_api_ip6_address_t ip6
Definition: one.api:424
Aggregate type for a prefix.
Definition: fib_types.h:203
unsigned int u32
Definition: types.h:88
u16 fp_len
The mask length.
Definition: fib_types.h:207
int fib_entry_cmp_for_sort(void *i1, void *i2)
Definition: fib_entry.c:1623
#define hash_get(h, key)
Definition: hash.h:249
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:534
static void vl_api_want_ip6_ra_events_t_handler(vl_api_want_ip6_ra_events_t *mp)
Definition: ip6_nd_api.c:295
void ip6_ra_report_unregister(ip6_ra_report_notify_t fn)
Definition: ip6_ra.c:180
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
Definition: fib_types.h:226
long ctx[MAX_CONNS]
Definition: main.c:144
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:302
static u32 ip6_nd_base_msg_id
Base message ID fot the plugin.
Definition: ip6_nd_api.c:41
#define REPLY_MACRO(t)
ip6_main_t ip6_main
Definition: ip6_forward.c:2784
vl_api_ip6_address_t ip
Definition: ip6_nd.api:134
vlib_main_t * vm
Definition: in2out_ed.c:1599
u32 fib_entry_get_resolving_interface(fib_node_index_t entry_index)
Definition: fib_entry.c:1458
An API client registration, only in vpp/vlib.
Definition: api_common.h:47
#define BAD_SW_IF_INDEX_LABEL
int fib_entry_is_sourced(fib_node_index_t fib_entry_index, fib_source_t source)
static void vl_api_ip6nd_proxy_add_del_t_handler(vl_api_ip6nd_proxy_add_del_t *mp)
Definition: ip6_nd_api.c:124
enum fib_table_walk_rc_t_ fib_table_walk_rc_t
return code controlling how a table walk proceeds
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
#define clib_warning(format, args...)
Definition: error.h:59
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:30
static vl_api_registration_t * vl_api_client_index_to_registration(u32 index)
Definition: api.h:57
static fib_table_walk_rc_t api_ip6nd_proxy_fib_table_walk(fib_node_index_t fei, void *arg)
Definition: ip6_nd_api.c:70
vl_api_interface_index_t sw_if_index
Definition: ip6_nd.api:133
static void vl_api_ip6nd_proxy_dump_t_handler(vl_api_ip6nd_proxy_dump_t *mp)
Definition: ip6_nd_api.c:83
static uword hash_elts(void *v)
Definition: hash.h:118
IPv6 router advertisement prefix config request.
Definition: ip6_nd.api:93
IPv6 ND proxy details returned after request.
Definition: ip6_nd.api:130
IPv6 ND proxy dump request.
Definition: ip6_nd.api:140
void ip6_address_encode(const ip6_address_t *in, vl_api_ip6_address_t out)
Definition: ip_types_api.c:111
vl_api_interface_index_t sw_if_index
Definition: ip6_nd.api:166
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
IPv6 Proxy ND.
Definition: fib_source.h:92
int ip6_nd_proxy_del(u32 sw_if_index, const ip6_address_t *addr)
Definition: ip6_nd_proxy.c:78
vl_api_interface_index_t sw_if_index
Definition: ip6_nd.api:97
u64 uword
Definition: types.h:112
IPv6 ND proxy config.
Definition: ip6_nd.api:116
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:1053
struct api_ip6nd_proxy_fib_table_walk_ctx_t_ api_ip6nd_proxy_fib_table_walk_ctx_t
VL_MSG_API_REAPER_FUNCTION(want_ip6_ra_events_reaper)
vl_api_ip6_address_t ip
Definition: ip6_nd.api:122
vl_api_interface_index_t sw_if_index
Definition: ip6_nd.api:49
vl_api_interface_index_t sw_if_index
Definition: ip6_nd.api:120
int ip6_ra_prefix(vlib_main_t *vm, u32 sw_if_index, ip6_address_t *prefix_addr, u8 prefix_len, u8 use_default, u32 val_lifetime, u32 pref_lifetime, u8 no_advertise, u8 off_link, u8 no_autoconfig, u8 no_onlink, u8 is_no)
Definition: ip6_ra.c:1765
#define vec_foreach(var, vec)
Vector iterator.
static void setup_message_id_table(snat_main_t *sm, api_main_t *am)
Definition: nat_api.c:3256
vpe_api_main_t vpe_api_main
Definition: interface_api.c:54
static void ip6_ra_handle_report(const ip6_ra_report_t *rap)
Definition: ip6_nd_api.c:235
struct fib_table_t_ * fibs
Definition: ip6.h:184
static clib_error_t * want_ip6_ra_events_reaper(u32 client_index)
Definition: ip6_nd_api.c:344
#define VALIDATE_SW_IF_INDEX(mp)
A protocol Independent FIB table.
Definition: fib_table.h:71