FD.io VPP  v18.07.1-19-g511ce25
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 <map/map.h>
21 #include <map/map_msg_enum.h>
22 #include <vnet/ip/ip.h>
23 #include <vnet/fib/fib_table.h>
24 #include <vlibmemory/api.h>
25 
26 #define vl_typedefs /* define message structures */
27 #include <map/map_all_api_h.h>
28 #undef vl_typedefs
29 
30 #define vl_endianfun /* define message structures */
31 #include <map/map_all_api_h.h>
32 #undef vl_endianfun
33 
34 /* instantiate all the print functions we know about */
35 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
36 #define vl_printfun
37 #include <map/map_all_api_h.h>
38 #undef vl_printfun
39 
40 /* Get the API version number */
41 #define vl_api_version(n,v) static u32 api_version=(v);
42 #include <map/map_all_api_h.h>
43 #undef vl_api_version
44 
45 #define REPLY_MSG_ID_BASE mm->msg_id_base
47 
48 static void
50 {
51  map_main_t *mm = &map_main;
53  int rv = 0;
54  u32 index;
55  u8 flags = 0;
56 
57  if (mp->is_translation)
58  flags |= MAP_DOMAIN_TRANSLATION;
59 
60  if (mp->is_rfc6052)
61  flags |= MAP_DOMAIN_RFC6052;
62 
63  rv =
66  (ip6_address_t *) & mp->ip6_src,
68  mp->psid_offset, mp->psid_length, &index,
69  ntohs (mp->mtu), flags);
70 
71  /* *INDENT-OFF* */
72  REPLY_MACRO2(VL_API_MAP_ADD_DOMAIN_REPLY,
73  ({
74  rmp->index = ntohl(index);
75  }));
76  /* *INDENT-ON* */
77 }
78 
79 static void
81 {
82  map_main_t *mm = &map_main;
83  vl_api_map_del_domain_reply_t *rmp;
84  int rv = 0;
85 
86  rv = map_delete_domain (ntohl (mp->index));
87 
88  REPLY_MACRO (VL_API_MAP_DEL_DOMAIN_REPLY);
89 }
90 
91 static void
93 {
94  map_main_t *mm = &map_main;
95  vl_api_map_del_domain_reply_t *rmp;
96  int rv = 0;
97 
98  rv =
99  map_add_del_psid (ntohl (mp->index), ntohs (mp->psid),
100  (ip6_address_t *) mp->ip6_dst, mp->is_add);
101 
102  REPLY_MACRO (VL_API_MAP_ADD_DEL_RULE_REPLY);
103 }
104 
105 static void
107 {
109  map_main_t *mm = &map_main;
110  map_domain_t *d;
112 
113  if (pool_elts (mm->domains) == 0)
114  return;
115 
117  if (!reg)
118  return;
119 
120  /* *INDENT-OFF* */
121  pool_foreach(d, mm->domains,
122  ({
123  /* Make sure every field is initiated (or don't skip the memset()) */
124  rmp = vl_msg_api_alloc (sizeof (*rmp));
125  rmp->_vl_msg_id = htons(VL_API_MAP_DOMAIN_DETAILS + mm->msg_id_base);
126  rmp->context = mp->context;
127  rmp->domain_index = htonl(d - mm->domains);
128  clib_memcpy(rmp->ip6_prefix, &d->ip6_prefix, sizeof(rmp->ip6_prefix));
129  clib_memcpy(rmp->ip4_prefix, &d->ip4_prefix, sizeof(rmp->ip4_prefix));
130  clib_memcpy(rmp->ip6_src, &d->ip6_src, sizeof(rmp->ip6_src));
131  rmp->ip6_prefix_len = d->ip6_prefix_len;
132  rmp->ip4_prefix_len = d->ip4_prefix_len;
133  rmp->ip6_src_len = d->ip6_src_len;
134  rmp->ea_bits_len = d->ea_bits_len;
135  rmp->psid_offset = d->psid_offset;
136  rmp->psid_length = d->psid_length;
137  rmp->flags = d->flags;
138  rmp->mtu = htons(d->mtu);
139  rmp->is_translation = (d->flags & MAP_DOMAIN_TRANSLATION); // Redundant
140 
141  vl_api_send_msg (reg, (u8 *) rmp);
142  }));
143  /* *INDENT-ON* */
144 }
145 
146 static void
148 {
150  u16 i;
151  ip6_address_t dst;
153  map_main_t *mm = &map_main;
154  u32 domain_index = ntohl (mp->domain_index);
155  map_domain_t *d;
156 
157  if (pool_elts (mm->domains) == 0)
158  return;
159 
160  d = pool_elt_at_index (mm->domains, domain_index);
161  if (!d || !d->rules)
162  {
163  return;
164  }
165 
167  if (!reg)
168  return;
169 
170  for (i = 0; i < (0x1 << d->psid_length); i++)
171  {
172  dst = d->rules[i];
173  if (dst.as_u64[0] == 0 && dst.as_u64[1] == 0)
174  {
175  continue;
176  }
177  rmp = vl_msg_api_alloc (sizeof (*rmp));
178  memset (rmp, 0, sizeof (*rmp));
179  rmp->_vl_msg_id = ntohs (VL_API_MAP_RULE_DETAILS + mm->msg_id_base);
180  rmp->psid = htons (i);
181  clib_memcpy (rmp->ip6_dst, &dst, sizeof (rmp->ip6_dst));
182  rmp->context = mp->context;
183  vl_api_send_msg (reg, (u8 *) rmp);
184  }
185 }
186 
187 static void
189 {
193  int i, which;
194  u64 total_pkts[VLIB_N_RX_TX];
195  u64 total_bytes[VLIB_N_RX_TX];
196  map_main_t *mm = &map_main;
198 
200  if (!reg)
201  return;
202 
203  rmp = vl_msg_api_alloc (sizeof (*rmp));
204  rmp->_vl_msg_id = htons (VL_API_MAP_SUMMARY_STATS_REPLY + mm->msg_id_base);
205  rmp->context = mp->context;
206  rmp->retval = 0;
207 
208  if (pool_elts (mm->domains) == 0)
209  {
210  rmp->retval = -1;
211  goto out;
212  }
213 
214  memset (total_pkts, 0, sizeof (total_pkts));
215  memset (total_bytes, 0, sizeof (total_bytes));
216 
218  vec_foreach (cm, mm->domain_counters)
219  {
220  which = cm - mm->domain_counters;
221 
222  for (i = 0; i < vlib_combined_counter_n_counters (cm); i++)
223  {
224  vlib_get_combined_counter (cm, i, &v);
225  total_pkts[which] += v.packets;
226  total_bytes[which] += v.bytes;
227  }
228  }
229 
231 
232  /* Note: in network byte order! */
234  clib_host_to_net_u64 (total_pkts[MAP_DOMAIN_COUNTER_RX]);
236  clib_host_to_net_u64 (total_bytes[MAP_DOMAIN_COUNTER_RX]);
238  clib_host_to_net_u64 (total_pkts[MAP_DOMAIN_COUNTER_TX]);
240  clib_host_to_net_u64 (total_bytes[MAP_DOMAIN_COUNTER_TX]);
241  rmp->total_bindings = clib_host_to_net_u64 (pool_elts (mm->domains));
242  rmp->total_ip4_fragments = 0; // Not yet implemented. Should be a simple counter.
244  clib_host_to_net_u64 (map_error_counter_get
245  (ip4_map_node.index, MAP_ERROR_ENCAP_SEC_CHECK));
247  clib_host_to_net_u64 (map_error_counter_get
248  (ip4_map_node.index, MAP_ERROR_DECAP_SEC_CHECK));
249 
250 out:
251  vl_api_send_msg (reg, (u8 *) rmp);
252 }
253 
254 #define foreach_map_plugin_api_msg \
255 _(MAP_ADD_DOMAIN, map_add_domain) \
256 _(MAP_DEL_DOMAIN, map_del_domain) \
257 _(MAP_ADD_DEL_RULE, map_add_del_rule) \
258 _(MAP_DOMAIN_DUMP, map_domain_dump) \
259 _(MAP_RULE_DUMP, map_rule_dump) \
260 _(MAP_SUMMARY_STATS, map_summary_stats)
261 
262 #define vl_msg_name_crc_list
263 #include <map/map_all_api_h.h>
264 #undef vl_msg_name_crc_list
265 
266 static void
268 {
269 #define _(id,n,crc) \
270  vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id + mm->msg_id_base);
271  foreach_vl_msg_name_crc_map;
272 #undef _
273 }
274 
275 /* Set up the API message handling tables */
276 clib_error_t *
278 {
279  map_main_t *mm = &map_main;
280  u8 *name = format (0, "map_%08x%c", api_version, 0);
281 
282  /* Ask for a correctly-sized block of API message decode slots */
283  mm->msg_id_base =
285 #define _(N,n) \
286  vl_msg_api_set_handlers((VL_API_##N + mm->msg_id_base), \
287  #n, \
288  vl_api_##n##_t_handler, \
289  vl_noop_handler, \
290  vl_api_##n##_t_endian, \
291  vl_api_##n##_t_print, \
292  sizeof(vl_api_##n##_t), 1);
294 #undef _
295 
296  /*
297  * Set up the (msg_name, crc, message-id) table
298  */
300 
301  vec_free (name);
302  return 0;
303 }
304 
305 /*
306  * fd.io coding-style-patch-verification: ON
307  *
308  * Local Variables:
309  * eval: (c-set-style "gnu")
310  * End:
311  */
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:258
map_main_t map_main
Definition: map.c:27
static void vl_api_map_domain_dump_t_handler(vl_api_map_domain_dump_t *mp)
Definition: map_api.c:106
u64 as_u64[2]
Definition: ip6_packet.h:51
unsigned long u64
Definition: types.h:89
u16 msg_id_base
Definition: map.h:240
#define REPLY_MACRO2(t, body)
u64 map_error_counter_get(u32 node_index, map_error_t map_error)
Definition: map.c:1138
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:558
Combined counter to hold both packets and byte differences.
Definition: counter.h:140
int i
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
vlib_node_registration_t ip4_map_node
(constructor) VLIB_REGISTER_NODE (ip4_map_node)
Definition: ip4_map.c:703
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:92
unsigned char u8
Definition: types.h:56
static void vl_api_map_summary_stats_t_handler(vl_api_map_summary_stats_t *mp)
Definition: map_api.c:188
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:49
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:443
vlib_combined_counter_main_t * domain_counters
Definition: map.h:236
ip6_address_t * rules
Definition: map.h:87
unsigned int u32
Definition: types.h:88
static void vl_api_map_del_domain_t_handler(vl_api_map_del_domain_t *mp)
Definition: map_api.c:80
int map_add_del_psid(u32 map_domain_index, u16 psid, ip6_address_t *tep, u8 is_add)
Definition: map.c:302
Delete MAP domain.
Definition: map.api:68
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:464
counter_t packets
packet counter
Definition: counter.h:142
clib_error_t * map_plugin_api_hookup(vlib_main_t *vm)
Definition: map_api.c:277
static void vl_api_map_rule_dump_t_handler(vl_api_map_rule_dump_t *mp)
Definition: map_api.c:147
#define v
Definition: acl.c:491
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:120
unsigned short u16
Definition: types.h:57
map_domain_t * domains
Definition: map.h:232
#define REPLY_MACRO(t)
static void setup_message_id_table(map_main_t *mm, api_main_t *am)
Definition: map_api.c:267
API main structure, used by both vpp and binary API clients.
Definition: api_common.h:201
u32 flags
Definition: vhost_user.h:110
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:252
vlib_main_t * vm
Definition: buffer.c:294
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:339
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:65
#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:551
Request for a single block of summary stats.
Definition: map.api:140
Reply for MAP domain add.
Definition: map.api:56
#define foreach_map_plugin_api_msg
Definition: map_api.c:254
counter_t bytes
byte counter
Definition: counter.h:143
A collection of combined counters.
Definition: counter.h:181
Add MAP domains.
Definition: map.api:33
#define vec_foreach(var, vec)
Vector iterator.
api_main_t api_main
Definition: api_shared.c:35
u16 vl_msg_api_get_msg_ids(const char *name, int n)
Definition: api_shared.c:872
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:128