FD.io VPP  v18.04-17-g3a0d853
Vector Packet Processing
map_api.c
Go to the documentation of this file.
1 /*
2  *------------------------------------------------------------------
3  * map_api.c - vnet map 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 <vnet/vnet.h>
21 #include <vlibmemory/api.h>
22 
23 #include "map.h"
24 #include <vnet/api_errno.h>
25 #include <vnet/ip/ip.h>
26 #include <vnet/fib/fib_table.h>
27 #include <vnet/vnet_msg_enum.h>
28 
29 #define vl_typedefs /* define message structures */
30 #include <vnet/vnet_all_api_h.h>
31 #undef vl_typedefs
32 
33 #define vl_endianfun /* define message structures */
34 #include <vnet/vnet_all_api_h.h>
35 #undef vl_endianfun
36 
37 /* instantiate all the print functions we know about */
38 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
39 #define vl_printfun
40 #include <vnet/vnet_all_api_h.h>
41 #undef vl_printfun
42 
44 
45 #define foreach_vpe_api_msg \
46 _(MAP_ADD_DOMAIN, map_add_domain) \
47 _(MAP_DEL_DOMAIN, map_del_domain) \
48 _(MAP_ADD_DEL_RULE, map_add_del_rule) \
49 _(MAP_DOMAIN_DUMP, map_domain_dump) \
50 _(MAP_RULE_DUMP, map_rule_dump) \
51 _(MAP_SUMMARY_STATS, map_summary_stats)
52 
53 static void
55 {
57  int rv = 0;
58  u32 index;
59  u8 flags = 0;
60 
61  if (mp->is_translation)
62  flags |= MAP_DOMAIN_TRANSLATION;
63 
64  if (mp->is_rfc6052)
65  flags |= MAP_DOMAIN_RFC6052;
66 
67  rv =
70  (ip6_address_t *) & mp->ip6_src,
72  mp->psid_offset, mp->psid_length, &index,
73  ntohs (mp->mtu), flags);
74 
75  /* *INDENT-OFF* */
76  REPLY_MACRO2(VL_API_MAP_ADD_DOMAIN_REPLY,
77  ({
78  rmp->index = ntohl(index);
79  }));
80  /* *INDENT-ON* */
81 }
82 
83 static void
85 {
86  vl_api_map_del_domain_reply_t *rmp;
87  int rv = 0;
88 
89  rv = map_delete_domain (ntohl (mp->index));
90 
91  REPLY_MACRO (VL_API_MAP_DEL_DOMAIN_REPLY);
92 }
93 
94 static void
96 {
97  vl_api_map_del_domain_reply_t *rmp;
98  int rv = 0;
99 
100  rv =
101  map_add_del_psid (ntohl (mp->index), ntohs (mp->psid),
102  (ip6_address_t *) mp->ip6_dst, mp->is_add);
103 
104  REPLY_MACRO (VL_API_MAP_ADD_DEL_RULE_REPLY);
105 }
106 
107 static void
109 {
111  map_main_t *mm = &map_main;
112  map_domain_t *d;
114 
115  if (pool_elts (mm->domains) == 0)
116  return;
117 
119  if (!reg)
120  return;
121 
122  /* *INDENT-OFF* */
123  pool_foreach(d, mm->domains,
124  ({
125  /* Make sure every field is initiated (or don't skip the memset()) */
126  rmp = vl_msg_api_alloc (sizeof (*rmp));
127  rmp->_vl_msg_id = ntohs(VL_API_MAP_DOMAIN_DETAILS);
128  rmp->domain_index = htonl(d - mm->domains);
129  rmp->ea_bits_len = d->ea_bits_len;
130  rmp->psid_offset = d->psid_offset;
131  rmp->psid_length = d->psid_length;
132  clib_memcpy(rmp->ip4_prefix, &d->ip4_prefix, sizeof(rmp->ip4_prefix));
133  rmp->ip4_prefix_len = d->ip4_prefix_len;
134  clib_memcpy(rmp->ip6_prefix, &d->ip6_prefix, sizeof(rmp->ip6_prefix));
135  rmp->ip6_prefix_len = d->ip6_prefix_len;
136  clib_memcpy(rmp->ip6_src, &d->ip6_src, sizeof(rmp->ip6_src));
137  rmp->ip6_src_len = d->ip6_src_len;
138  rmp->mtu = htons(d->mtu);
139  rmp->is_translation = (d->flags & MAP_DOMAIN_TRANSLATION);
140  rmp->context = mp->context;
141 
142  vl_api_send_msg (reg, (u8 *)&rmp);
143  }));
144  /* *INDENT-ON* */
145 }
146 
147 static void
149 {
151  u16 i;
152  ip6_address_t dst;
154  map_main_t *mm = &map_main;
155  u32 domain_index = ntohl (mp->domain_index);
156  map_domain_t *d;
157 
158  if (pool_elts (mm->domains) == 0)
159  return;
160 
161  d = pool_elt_at_index (mm->domains, domain_index);
162  if (!d || !d->rules)
163  {
164  return;
165  }
166 
168  if (!reg)
169  return;
170 
171  for (i = 0; i < (0x1 << d->psid_length); i++)
172  {
173  dst = d->rules[i];
174  if (dst.as_u64[0] == 0 && dst.as_u64[1] == 0)
175  {
176  continue;
177  }
178  rmp = vl_msg_api_alloc (sizeof (*rmp));
179  memset (rmp, 0, sizeof (*rmp));
180  rmp->_vl_msg_id = ntohs (VL_API_MAP_RULE_DETAILS);
181  rmp->psid = htons (i);
182  clib_memcpy (rmp->ip6_dst, &dst, sizeof (rmp->ip6_dst));
183  rmp->context = mp->context;
184  vl_api_send_msg (reg, (u8 *) rmp);
185  }
186 }
187 
188 static void
190 {
194  int i, which;
195  u64 total_pkts[VLIB_N_RX_TX];
196  u64 total_bytes[VLIB_N_RX_TX];
197  map_main_t *mm = &map_main;
199 
201  if (!reg)
202  return;
203 
204  rmp = vl_msg_api_alloc (sizeof (*rmp));
205  rmp->_vl_msg_id = ntohs (VL_API_MAP_SUMMARY_STATS_REPLY);
206  rmp->context = mp->context;
207  rmp->retval = 0;
208 
209  if (pool_elts (mm->domains) == 0)
210  {
211  rmp->retval = -1;
212  goto out;
213  }
214 
215  memset (total_pkts, 0, sizeof (total_pkts));
216  memset (total_bytes, 0, sizeof (total_bytes));
217 
219  vec_foreach (cm, mm->domain_counters)
220  {
221  which = cm - mm->domain_counters;
222 
223  for (i = 0; i < vlib_combined_counter_n_counters (cm); i++)
224  {
225  vlib_get_combined_counter (cm, i, &v);
226  total_pkts[which] += v.packets;
227  total_bytes[which] += v.bytes;
228  }
229  }
230 
232 
233  /* Note: in network byte order! */
235  clib_host_to_net_u64 (total_pkts[MAP_DOMAIN_COUNTER_RX]);
237  clib_host_to_net_u64 (total_bytes[MAP_DOMAIN_COUNTER_RX]);
239  clib_host_to_net_u64 (total_pkts[MAP_DOMAIN_COUNTER_TX]);
241  clib_host_to_net_u64 (total_bytes[MAP_DOMAIN_COUNTER_TX]);
242  rmp->total_bindings = clib_host_to_net_u64 (pool_elts (mm->domains));
243  rmp->total_ip4_fragments = 0; // Not yet implemented. Should be a simple counter.
245  clib_host_to_net_u64 (map_error_counter_get
246  (ip4_map_node.index, MAP_ERROR_ENCAP_SEC_CHECK));
248  clib_host_to_net_u64 (map_error_counter_get
249  (ip4_map_node.index, MAP_ERROR_DECAP_SEC_CHECK));
250 
251 out:
252  vl_api_send_msg (reg, (u8 *) rmp);
253 }
254 
255 /*
256  * vpe_api_hookup
257  * Add vpe's API message handlers to the table.
258  * vlib has alread mapped shared memory and
259  * added the client registration handlers.
260  * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
261  */
262 #define vl_msg_name_crc_list
263 #include <vnet/vnet_all_api_h.h>
264 #undef vl_msg_name_crc_list
265 
266 static void
268 {
269 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
270  foreach_vl_msg_name_crc_map;
271 #undef _
272 }
273 
274 static clib_error_t *
276 {
277  api_main_t *am = &api_main;
278 
279 #define _(N,n) \
280  vl_msg_api_set_handlers(VL_API_##N, #n, \
281  vl_api_##n##_t_handler, \
282  vl_noop_handler, \
283  vl_api_##n##_t_endian, \
284  vl_api_##n##_t_print, \
285  sizeof(vl_api_##n##_t), 1);
287 #undef _
288 
289  /*
290  * Set up the (msg_name, crc, message-id) table
291  */
293 
294  return 0;
295 }
296 
298 
299 /*
300  * fd.io coding-style-patch-verification: ON
301  *
302  * Local Variables:
303  * eval: (c-set-style "gnu")
304  * End:
305  */
u8 psid_length
Definition: map.h:97
Add or Delete MAP rule from a domain (Only used for shared IPv4 per subscriber)
Definition: map.api:84
int map_delete_domain(u32 map_domain_index)
Definition: map.c:257
map_main_t map_main
Definition: map.c:26
static void vl_api_map_domain_dump_t_handler(vl_api_map_domain_dump_t *mp)
Definition: map_api.c:108
#define foreach_vpe_api_msg
Definition: map_api.c:45
u64 as_u64[2]
Definition: ip6_packet.h:51
#define REPLY_MACRO2(t, body)
u64 map_error_counter_get(u32 node_index, map_error_t map_error)
Definition: map.c:1137
static void vl_api_send_msg(vl_api_registration_t *rp, u8 *elem)
Definition: api.h:34
static void map_domain_counter_unlock(map_main_t *mm)
Definition: map.h:553
Combined counter to hold both packets and byte differences.
Definition: counter.h:139
int i
vlib_node_registration_t ip4_map_node
(constructor) VLIB_REGISTER_NODE (ip4_map_node)
Definition: ip4_map.c:703
static void setup_message_id_table(api_main_t *am)
Definition: map_api.c:267
void * vl_msg_api_alloc(int nbytes)
static void vl_api_map_add_del_rule_t_handler(vl_api_map_add_del_rule_t *mp)
Definition: map_api.c:95
static void vl_api_map_summary_stats_t_handler(vl_api_map_summary_stats_t *mp)
Definition: map_api.c:189
Get list of map domains.
Definition: map.api:98
static void vl_api_map_add_domain_t_handler(vl_api_map_add_domain_t *mp)
Definition: map_api.c:54
VLIB_API_INIT_FUNCTION(map_api_hookup)
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:440
vlib_combined_counter_main_t * domain_counters
Definition: map.h:236
ip6_address_t * rules
Definition: map.h:87
unsigned long u64
Definition: types.h:89
static void vl_api_map_del_domain_t_handler(vl_api_map_del_domain_t *mp)
Definition: map_api.c:84
int map_add_del_psid(u32 map_domain_index, u16 psid, ip6_address_t *tep, u8 is_add)
Definition: map.c:301
Delete MAP domain.
Definition: map.api:68
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:461
counter_t packets
packet counter
Definition: counter.h:141
static void vl_api_map_rule_dump_t_handler(vl_api_map_rule_dump_t *mp)
Definition: map_api.c:148
#define v
Definition: acl.c:495
u32 vlib_combined_counter_n_counters(const vlib_combined_counter_main_t *cm)
The number of counters (not the number of per-thread counters)
Definition: counter.c:100
map_domain_t * domains
Definition: map.h:232
#define REPLY_MACRO(t)
static clib_error_t * map_api_hookup(vlib_main_t *vm)
Definition: map_api.c:275
API main structure, used by both vpp and binary API clients.
Definition: api_common.h:199
An API client registration, only in vpp/vlib.
Definition: api_common.h:44
static void vlib_get_combined_counter(const vlib_combined_counter_main_t *cm, u32 index, vlib_counter_t *result)
Get the value of a combined counter, never called in the speed path Scrapes the entire set of per-thr...
Definition: counter.h:250
vlib_main_t * vm
Definition: buffer.c:294
int map_create_domain(ip4_address_t *ip4_prefix, u8 ip4_prefix_len, ip6_address_t *ip6_prefix, u8 ip6_prefix_len, ip6_address_t *ip6_src, u8 ip6_src_len, u8 ea_bits_len, u8 psid_offset, u8 psid_length, u32 *map_domain_index, u16 mtu, u8 flags)
Definition: map.c:64
#define clib_memcpy(a, b, c)
Definition: string.h:75
Reply for map_summary_stats request.
Definition: map.api:154
static vl_api_registration_t * vl_api_client_index_to_registration(u32 index)
Definition: api.h:56
static void map_domain_counter_lock(map_main_t *mm)
Definition: map.h:546
unsigned int u32
Definition: types.h:88
Request for a single block of summary stats.
Definition: map.api:140
Reply for MAP domain add.
Definition: map.api:56
counter_t bytes
byte counter
Definition: counter.h:142
unsigned short u16
Definition: types.h:57
unsigned char u8
Definition: types.h:56
A collection of combined counters.
Definition: counter.h:180
Add MAP domains.
Definition: map.api:33
#define vec_foreach(var, vec)
Vector iterator.
u32 flags
Definition: vhost-user.h:77
api_main_t api_main
Definition: api_shared.c:35
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:128