api: autogenerate api trace print/endian
[vpp.git] / src / plugins / map / map_api.c
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/ip/ip_types_api.h>
21 #include <map/map.h>
22 #include <map/map_msg_enum.h>
23 #include <vnet/ip/ip.h>
24 #include <vnet/fib/fib_table.h>
25 #include <vlibmemory/api.h>
26
27 #define vl_typedefs             /* define message structures */
28 #include <map/map_all_api_h.h>
29 #undef vl_typedefs
30
31 #define vl_endianfun            /* define message structures */
32 #include <map/map_all_api_h.h>
33 #undef vl_endianfun
34
35 /* instantiate all the print functions we know about */
36 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
37 #define vl_printfun
38 #include <map/map_all_api_h.h>
39 #undef vl_printfun
40
41 /* Get the API version number */
42 #define vl_api_version(n,v) static u32 api_version=(v);
43 #include <map/map_all_api_h.h>
44 #undef vl_api_version
45
46 #define REPLY_MSG_ID_BASE mm->msg_id_base
47 #include <vlibapi/api_helper_macros.h>
48
49 static void
50 vl_api_map_add_domain_t_handler (vl_api_map_add_domain_t * mp)
51 {
52   map_main_t *mm = &map_main;
53   vl_api_map_add_domain_reply_t *rmp;
54   int rv = 0;
55   u32 index;
56   u8 flags = 0;
57
58   u8 *tag = format (0, "%s", mp->tag);
59   rv =
60     map_create_domain ((ip4_address_t *) & mp->ip4_prefix.address,
61                        mp->ip4_prefix.len,
62                        (ip6_address_t *) & mp->ip6_prefix.address,
63                        mp->ip6_prefix.len,
64                        (ip6_address_t *) & mp->ip6_src.address,
65                        mp->ip6_src.len, mp->ea_bits_len, mp->psid_offset,
66                        mp->psid_length, &index, ntohs (mp->mtu), flags, tag);
67   vec_free (tag);
68   /* *INDENT-OFF* */
69   REPLY_MACRO2(VL_API_MAP_ADD_DOMAIN_REPLY,
70   ({
71     rmp->index = ntohl(index);
72   }));
73   /* *INDENT-ON* */
74 }
75
76 static void
77 vl_api_map_del_domain_t_handler (vl_api_map_del_domain_t * mp)
78 {
79   map_main_t *mm = &map_main;
80   vl_api_map_del_domain_reply_t *rmp;
81   int rv = 0;
82
83   rv = map_delete_domain (ntohl (mp->index));
84
85   REPLY_MACRO (VL_API_MAP_DEL_DOMAIN_REPLY);
86 }
87
88 static void
89 vl_api_map_add_del_rule_t_handler (vl_api_map_add_del_rule_t * mp)
90 {
91   map_main_t *mm = &map_main;
92   vl_api_map_del_domain_reply_t *rmp;
93   int rv = 0;
94
95   rv =
96     map_add_del_psid (ntohl (mp->index), ntohs (mp->psid),
97                       (ip6_address_t *) & mp->ip6_dst, mp->is_add);
98
99   REPLY_MACRO (VL_API_MAP_ADD_DEL_RULE_REPLY);
100 }
101
102 static void
103 vl_api_map_domain_dump_t_handler (vl_api_map_domain_dump_t * mp)
104 {
105   vl_api_map_domain_details_t *rmp;
106   map_main_t *mm = &map_main;
107   map_domain_t *d;
108   map_domain_extra_t *de;
109   vl_api_registration_t *reg;
110   u32 map_domain_index;
111
112   if (pool_elts (mm->domains) == 0)
113     return;
114
115   reg = vl_api_client_index_to_registration (mp->client_index);
116   if (!reg)
117     return;
118
119   /* *INDENT-OFF* */
120   pool_foreach(d, mm->domains,
121   ({
122     map_domain_index = d - mm->domains;
123     de = vec_elt_at_index(mm->domain_extras, map_domain_index);
124     int tag_len = clib_min(ARRAY_LEN(rmp->tag), vec_len(de->tag) + 1);
125
126     /* Make sure every field is initiated (or don't skip the clib_memset()) */
127     rmp = vl_msg_api_alloc (sizeof (*rmp) + tag_len);
128
129     rmp->_vl_msg_id = htons(VL_API_MAP_DOMAIN_DETAILS + mm->msg_id_base);
130     rmp->context = mp->context;
131     rmp->domain_index = htonl(map_domain_index);
132     clib_memcpy(&rmp->ip6_prefix.address, &d->ip6_prefix, sizeof(rmp->ip6_prefix.address));
133     clib_memcpy(&rmp->ip4_prefix.address, &d->ip4_prefix, sizeof(rmp->ip4_prefix.address));
134     clib_memcpy(&rmp->ip6_src.address, &d->ip6_src, sizeof(rmp->ip6_src.address));
135     rmp->ip6_prefix.len = d->ip6_prefix_len;
136     rmp->ip4_prefix.len = d->ip4_prefix_len;
137     rmp->ip6_src.len = d->ip6_src_len;
138     rmp->ea_bits_len = d->ea_bits_len;
139     rmp->psid_offset = d->psid_offset;
140     rmp->psid_length = d->psid_length;
141     rmp->flags = d->flags;
142     rmp->mtu = htons(d->mtu);
143     memcpy(rmp->tag, de->tag, tag_len-1);
144     rmp->tag[tag_len-1] = '\0';
145
146     vl_api_send_msg (reg, (u8 *) rmp);
147   }));
148   /* *INDENT-ON* */
149 }
150
151 static void
152 vl_api_map_rule_dump_t_handler (vl_api_map_rule_dump_t * mp)
153 {
154   vl_api_registration_t *reg;
155   u16 i;
156   ip6_address_t dst;
157   vl_api_map_rule_details_t *rmp;
158   map_main_t *mm = &map_main;
159   u32 domain_index = ntohl (mp->domain_index);
160   map_domain_t *d;
161
162   if (pool_elts (mm->domains) == 0)
163     return;
164
165   d = pool_elt_at_index (mm->domains, domain_index);
166   if (!d || !d->rules)
167     {
168       return;
169     }
170
171   reg = vl_api_client_index_to_registration (mp->client_index);
172   if (!reg)
173     return;
174
175   for (i = 0; i < (0x1 << d->psid_length); i++)
176     {
177       dst = d->rules[i];
178       if (dst.as_u64[0] == 0 && dst.as_u64[1] == 0)
179         {
180           continue;
181         }
182       rmp = vl_msg_api_alloc (sizeof (*rmp));
183       clib_memset (rmp, 0, sizeof (*rmp));
184       rmp->_vl_msg_id = ntohs (VL_API_MAP_RULE_DETAILS + mm->msg_id_base);
185       rmp->psid = htons (i);
186       clib_memcpy (&rmp->ip6_dst, &dst, sizeof (rmp->ip6_dst));
187       rmp->context = mp->context;
188       vl_api_send_msg (reg, (u8 *) rmp);
189     }
190 }
191
192 static void
193 vl_api_map_summary_stats_t_handler (vl_api_map_summary_stats_t * mp)
194 {
195   vl_api_map_summary_stats_reply_t *rmp;
196   vlib_combined_counter_main_t *cm;
197   vlib_counter_t v;
198   int i, which;
199   u64 total_pkts[VLIB_N_RX_TX];
200   u64 total_bytes[VLIB_N_RX_TX];
201   map_main_t *mm = &map_main;
202   vl_api_registration_t *reg;
203
204   reg = vl_api_client_index_to_registration (mp->client_index);
205   if (!reg)
206     return;
207
208   rmp = vl_msg_api_alloc (sizeof (*rmp));
209   rmp->_vl_msg_id = htons (VL_API_MAP_SUMMARY_STATS_REPLY + mm->msg_id_base);
210   rmp->context = mp->context;
211   rmp->retval = 0;
212
213   if (pool_elts (mm->domains) == 0)
214     {
215       rmp->retval = -1;
216       goto out;
217     }
218
219   clib_memset (total_pkts, 0, sizeof (total_pkts));
220   clib_memset (total_bytes, 0, sizeof (total_bytes));
221
222   map_domain_counter_lock (mm);
223   vec_foreach (cm, mm->domain_counters)
224   {
225     which = cm - mm->domain_counters;
226
227     for (i = 0; i < vlib_combined_counter_n_counters (cm); i++)
228       {
229         vlib_get_combined_counter (cm, i, &v);
230         total_pkts[which] += v.packets;
231         total_bytes[which] += v.bytes;
232       }
233   }
234
235   map_domain_counter_unlock (mm);
236
237   /* Note: in network byte order! */
238   rmp->total_pkts[MAP_DOMAIN_COUNTER_RX] =
239     clib_host_to_net_u64 (total_pkts[MAP_DOMAIN_COUNTER_RX]);
240   rmp->total_bytes[MAP_DOMAIN_COUNTER_RX] =
241     clib_host_to_net_u64 (total_bytes[MAP_DOMAIN_COUNTER_RX]);
242   rmp->total_pkts[MAP_DOMAIN_COUNTER_TX] =
243     clib_host_to_net_u64 (total_pkts[MAP_DOMAIN_COUNTER_TX]);
244   rmp->total_bytes[MAP_DOMAIN_COUNTER_TX] =
245     clib_host_to_net_u64 (total_bytes[MAP_DOMAIN_COUNTER_TX]);
246   rmp->total_bindings = clib_host_to_net_u64 (pool_elts (mm->domains));
247   rmp->total_ip4_fragments = 0; // Not yet implemented. Should be a simple counter.
248   rmp->total_security_check[MAP_DOMAIN_COUNTER_TX] =
249     clib_host_to_net_u64 (map_error_counter_get
250                           (ip4_map_node.index, MAP_ERROR_ENCAP_SEC_CHECK));
251   rmp->total_security_check[MAP_DOMAIN_COUNTER_RX] =
252     clib_host_to_net_u64 (map_error_counter_get
253                           (ip4_map_node.index, MAP_ERROR_DECAP_SEC_CHECK));
254
255 out:
256   vl_api_send_msg (reg, (u8 *) rmp);
257 }
258
259
260 int
261 map_param_set_fragmentation (bool inner, bool ignore_df)
262 {
263   map_main_t *mm = &map_main;
264
265   mm->frag_inner = ! !inner;
266   mm->frag_ignore_df = ! !ignore_df;
267
268   return 0;
269 }
270
271 static void
272   vl_api_map_param_set_fragmentation_t_handler
273   (vl_api_map_param_set_fragmentation_t * mp)
274 {
275   map_main_t *mm = &map_main;
276   vl_api_map_param_set_fragmentation_reply_t *rmp;
277   int rv = 0;
278
279   rv = map_param_set_fragmentation (mp->inner, mp->ignore_df);
280
281   REPLY_MACRO (VL_API_MAP_PARAM_SET_FRAGMENTATION_REPLY);
282 }
283
284
285 int
286 map_param_set_icmp (ip4_address_t * icmp_src_address)
287 {
288   map_main_t *mm = &map_main;
289
290   if (icmp_src_address == 0)
291     return -1;
292
293   mm->icmp4_src_address = *icmp_src_address;
294
295   return 0;
296 }
297
298
299 static void
300 vl_api_map_param_set_icmp_t_handler (vl_api_map_param_set_icmp_t * mp)
301 {
302   map_main_t *mm = &map_main;
303   vl_api_map_param_set_icmp_reply_t *rmp;
304   int rv;
305
306   rv = map_param_set_icmp ((ip4_address_t *) & mp->ip4_err_relay_src);
307
308   REPLY_MACRO (VL_API_MAP_PARAM_SET_ICMP_REPLY);
309 }
310
311
312 int
313 map_param_set_icmp6 (u8 enable_unreachable)
314 {
315   map_main_t *mm = &map_main;
316
317   mm->icmp6_enabled = ! !enable_unreachable;
318
319   return 0;
320 }
321
322 static void
323 vl_api_map_param_set_icmp6_t_handler (vl_api_map_param_set_icmp6_t * mp)
324 {
325   map_main_t *mm = &map_main;
326   vl_api_map_param_set_icmp6_reply_t *rmp;
327   int rv;
328
329   rv = map_param_set_icmp6 (mp->enable_unreachable);
330
331   REPLY_MACRO (VL_API_MAP_PARAM_SET_ICMP6_REPLY);
332 }
333
334
335 static void
336   vl_api_map_param_add_del_pre_resolve_t_handler
337   (vl_api_map_param_add_del_pre_resolve_t * mp)
338 {
339   map_main_t *mm = &map_main;
340   vl_api_map_param_add_del_pre_resolve_reply_t *rmp;
341   int rv = 0;
342
343   map_pre_resolve ((ip4_address_t *) & mp->ip4_nh_address,
344                    (ip6_address_t *) & mp->ip6_nh_address, !mp->is_add);
345
346   REPLY_MACRO (VL_API_MAP_PARAM_ADD_DEL_PRE_RESOLVE_REPLY);
347 }
348
349
350 int
351 map_param_set_reassembly (bool is_ipv6,
352                           u16 lifetime_ms,
353                           u16 pool_size,
354                           u32 buffers,
355                           f64 ht_ratio, u32 * reass, u32 * packets)
356 {
357   u32 ps_reass = 0, ps_packets = 0;
358   u32 ht_reass = 0, ht_packets = 0;
359
360   if (is_ipv6)
361     {
362       if (pool_size != (u16) ~ 0)
363         {
364           if (pool_size > MAP_IP6_REASS_CONF_POOL_SIZE_MAX)
365             return MAP_ERR_BAD_POOL_SIZE;
366           if (map_ip6_reass_conf_pool_size
367               (pool_size, &ps_reass, &ps_packets))
368             return MAP_ERR_BAD_POOL_SIZE;
369         }
370
371       if (ht_ratio != (MAP_IP6_REASS_CONF_HT_RATIO_MAX + 1))
372         {
373           if (ht_ratio > MAP_IP6_REASS_CONF_HT_RATIO_MAX)
374             return MAP_ERR_BAD_HT_RATIO;
375           if (map_ip6_reass_conf_ht_ratio (ht_ratio, &ht_reass, &ht_packets))
376             return MAP_ERR_BAD_HT_RATIO;
377         }
378
379       if (lifetime_ms != (u16) ~ 0)
380         {
381           if (lifetime_ms > MAP_IP6_REASS_CONF_LIFETIME_MAX)
382             return MAP_ERR_BAD_LIFETIME;
383           if (map_ip6_reass_conf_lifetime (lifetime_ms))
384             return MAP_ERR_BAD_LIFETIME;
385         }
386
387       if (buffers != ~0)
388         {
389           if (buffers > MAP_IP6_REASS_CONF_BUFFERS_MAX)
390             return MAP_ERR_BAD_BUFFERS;
391           if (map_ip6_reass_conf_buffers (buffers))
392             return MAP_ERR_BAD_BUFFERS;
393         }
394
395       if (map_main.ip6_reass_conf_buffers >
396           map_main.ip6_reass_conf_pool_size *
397           MAP_IP6_REASS_MAX_FRAGMENTS_PER_REASSEMBLY)
398         {
399           return MAP_ERR_BAD_BUFFERS_TOO_LARGE;
400         }
401     }
402   else
403     {
404       if (pool_size != (u16) ~ 0)
405         {
406           if (pool_size > MAP_IP4_REASS_CONF_POOL_SIZE_MAX)
407             return MAP_ERR_BAD_POOL_SIZE;
408           if (map_ip4_reass_conf_pool_size
409               (pool_size, &ps_reass, &ps_packets))
410             return MAP_ERR_BAD_POOL_SIZE;
411         }
412
413       if (ht_ratio != (MAP_IP4_REASS_CONF_HT_RATIO_MAX + 1))
414         {
415           if (ht_ratio > MAP_IP4_REASS_CONF_HT_RATIO_MAX)
416             return MAP_ERR_BAD_HT_RATIO;
417           if (map_ip4_reass_conf_ht_ratio (ht_ratio, &ht_reass, &ht_packets))
418             return MAP_ERR_BAD_HT_RATIO;
419         }
420
421       if (lifetime_ms != (u16) ~ 0)
422         {
423           if (lifetime_ms > MAP_IP4_REASS_CONF_LIFETIME_MAX)
424             return MAP_ERR_BAD_LIFETIME;
425           if (map_ip4_reass_conf_lifetime (lifetime_ms))
426             return MAP_ERR_BAD_LIFETIME;
427         }
428
429       if (buffers != ~0)
430         {
431           if (buffers > MAP_IP4_REASS_CONF_BUFFERS_MAX)
432             return MAP_ERR_BAD_BUFFERS;
433           if (map_ip4_reass_conf_buffers (buffers))
434             return MAP_ERR_BAD_BUFFERS;
435         }
436
437       if (map_main.ip4_reass_conf_buffers >
438           map_main.ip4_reass_conf_pool_size *
439           MAP_IP4_REASS_MAX_FRAGMENTS_PER_REASSEMBLY)
440         {
441           return MAP_ERR_BAD_BUFFERS_TOO_LARGE;
442         }
443     }
444
445   if (reass)
446     *reass = ps_reass + ht_reass;
447
448   if (packets)
449     *packets = ps_packets + ht_packets;
450
451   return 0;
452 }
453
454
455 static void
456   vl_api_map_param_set_reassembly_t_handler
457   (vl_api_map_param_set_reassembly_t * mp)
458 {
459   map_main_t *mm = &map_main;
460   vl_api_map_param_set_reassembly_reply_t *rmp;
461   u32 reass = 0, packets = 0;
462   int rv;
463   f64 ht_ratio;
464
465   ht_ratio = (f64) clib_net_to_host_f64 (mp->ht_ratio);
466   if (ht_ratio == ~0)
467     ht_ratio = MAP_IP6_REASS_CONF_HT_RATIO_MAX + 1;
468
469   rv = map_param_set_reassembly (mp->is_ip6,
470                                  clib_net_to_host_u16 (mp->lifetime_ms),
471                                  clib_net_to_host_u16 (mp->pool_size),
472                                  clib_net_to_host_u32 (mp->buffers),
473                                  ht_ratio, &reass, &packets);
474
475   /*
476    * FIXME: Should the lost reass and packet counts be returned in the API?
477    */
478
479   REPLY_MACRO (VL_API_MAP_PARAM_SET_REASSEMBLY_REPLY);
480 }
481
482
483 int
484 map_param_set_security_check (bool enable, bool fragments)
485 {
486   map_main_t *mm = &map_main;
487
488   mm->sec_check = ! !enable;
489   mm->sec_check_frag = ! !fragments;
490
491   return 0;
492 }
493
494 static void
495   vl_api_map_param_set_security_check_t_handler
496   (vl_api_map_param_set_security_check_t * mp)
497 {
498   map_main_t *mm = &map_main;
499   vl_api_map_param_set_security_check_reply_t *rmp;
500   int rv;
501
502   rv = map_param_set_security_check (mp->enable, mp->fragments);
503
504   REPLY_MACRO (VL_API_MAP_PARAM_SET_SECURITY_CHECK_REPLY);
505 }
506
507
508 int
509 map_param_set_traffic_class (bool copy, u8 tc)
510 {
511   map_main_t *mm = &map_main;
512
513   mm->tc_copy = ! !copy;
514   mm->tc = tc;
515
516   return 0;
517 }
518
519 static void
520   vl_api_map_param_set_traffic_class_t_handler
521   (vl_api_map_param_set_traffic_class_t * mp)
522 {
523   map_main_t *mm = &map_main;
524   vl_api_map_param_set_traffic_class_reply_t *rmp;
525   int rv;
526
527   rv = map_param_set_traffic_class (mp->copy, mp->tc_class);
528
529   REPLY_MACRO (VL_API_MAP_PARAM_SET_TRAFFIC_CLASS_REPLY);
530 }
531
532
533 int
534 map_param_set_tcp (u16 tcp_mss)
535 {
536   map_main_t *mm = &map_main;
537
538   mm->tcp_mss = tcp_mss;
539
540   return 0;
541 }
542
543
544 static void
545 vl_api_map_param_set_tcp_t_handler (vl_api_map_param_set_tcp_t * mp)
546 {
547   map_main_t *mm = &map_main;
548   vl_api_map_param_set_tcp_reply_t *rmp;
549   int rv = 0;
550
551   map_param_set_tcp (ntohs (mp->tcp_mss));
552   REPLY_MACRO (VL_API_MAP_PARAM_SET_TCP_REPLY);
553 }
554
555
556 static void
557 vl_api_map_param_get_t_handler (vl_api_map_param_get_t * mp)
558 {
559   map_main_t *mm = &map_main;
560   vl_api_map_param_get_reply_t *rmp;
561   vl_api_registration_t *reg;
562
563   reg = vl_api_client_index_to_registration (mp->client_index);
564   if (!reg)
565     return;
566
567   rmp = vl_msg_api_alloc (sizeof (*rmp));
568   rmp->_vl_msg_id = htons (VL_API_MAP_PARAM_GET_REPLY + mm->msg_id_base);
569   rmp->context = mp->context;
570   rmp->retval = 0;
571
572   rmp->frag_inner = mm->frag_inner;
573   rmp->frag_ignore_df = mm->frag_ignore_df;
574
575   clib_memcpy (&rmp->icmp_ip4_err_relay_src,
576                &mm->icmp4_src_address, sizeof (rmp->icmp_ip4_err_relay_src));
577
578   rmp->icmp6_enable_unreachable = mm->icmp6_enabled;
579
580   /*
581    * FIXME: How are these addresses re-extracted from the FIB?
582    * Or should a local map_main copy be kept?
583    */
584   clib_memset (&rmp->ip4_nh_address, 0, sizeof (rmp->ip4_nh_address));
585   clib_memset (&rmp->ip6_nh_address, 0, sizeof (rmp->ip6_nh_address));
586
587   rmp->ip4_lifetime_ms =
588     clib_net_to_host_u16 (mm->ip4_reass_conf_lifetime_ms);
589   rmp->ip4_pool_size = clib_net_to_host_u16 (mm->ip4_reass_conf_pool_size);
590   rmp->ip4_buffers = clib_net_to_host_u32 (mm->ip4_reass_conf_buffers);
591   rmp->ip4_ht_ratio = clib_net_to_host_f64 (mm->ip4_reass_conf_ht_ratio);
592
593   rmp->ip6_lifetime_ms =
594     clib_net_to_host_u16 (mm->ip6_reass_conf_lifetime_ms);
595   rmp->ip6_pool_size = clib_net_to_host_u16 (mm->ip6_reass_conf_pool_size);
596   rmp->ip6_buffers = clib_net_to_host_u32 (mm->ip6_reass_conf_buffers);
597   rmp->ip6_ht_ratio = clib_net_to_host_f64 (mm->ip6_reass_conf_ht_ratio);
598
599   rmp->sec_check_enable = mm->sec_check;
600   rmp->sec_check_fragments = mm->sec_check_frag;
601
602   rmp->tc_copy = mm->tc_copy;
603   rmp->tc_class = mm->tc;
604
605   vl_api_send_msg (reg, (u8 *) rmp);
606 }
607
608
609 int
610 map_if_enable_disable (bool is_enable, u32 sw_if_index, bool is_translation)
611 {
612   map_main_t *mm = &map_main;
613
614   if (pool_is_free_index (mm->vnet_main->interface_main.sw_interfaces,
615                           sw_if_index))
616     return VNET_API_ERROR_INVALID_SW_IF_INDEX;
617
618   is_enable = ! !is_enable;
619
620   if (is_translation)
621     {
622       if (clib_bitmap_get (mm->bm_trans_enabled_by_sw_if, sw_if_index)
623           == is_enable)
624         return 0;
625     }
626   else
627     {
628       if (clib_bitmap_get (mm->bm_encap_enabled_by_sw_if, sw_if_index)
629           == is_enable)
630         return 0;
631     }
632
633   if (is_translation == false)
634     {
635       vnet_feature_enable_disable ("ip4-unicast", "ip4-map", sw_if_index,
636                                    is_enable ? 1 : 0, 0, 0);
637       vnet_feature_enable_disable ("ip6-unicast", "ip6-map", sw_if_index,
638                                    is_enable ? 1 : 0, 0, 0);
639       mm->bm_encap_enabled_by_sw_if =
640         clib_bitmap_set (mm->bm_encap_enabled_by_sw_if, sw_if_index,
641                          is_enable);
642     }
643   else
644     {
645       vnet_feature_enable_disable ("ip4-unicast", "ip4-map-t", sw_if_index,
646                                    is_enable ? 1 : 0, 0, 0);
647       vnet_feature_enable_disable ("ip6-unicast", "ip6-map-t", sw_if_index,
648                                    is_enable ? 1 : 0, 0, 0);
649       mm->bm_trans_enabled_by_sw_if =
650         clib_bitmap_set (mm->bm_trans_enabled_by_sw_if, sw_if_index,
651                          is_enable);
652     }
653
654   return 0;
655 }
656
657
658 static void
659 vl_api_map_if_enable_disable_t_handler (vl_api_map_if_enable_disable_t * mp)
660 {
661   map_main_t *mm = &map_main;
662   vl_api_map_if_enable_disable_reply_t *rmp;
663   int rv = 0;
664
665   VALIDATE_SW_IF_INDEX (mp);
666
667   rv =
668     map_if_enable_disable (mp->is_enable, htonl (mp->sw_if_index),
669                            mp->is_translation);
670
671   BAD_SW_IF_INDEX_LABEL;
672   REPLY_MACRO (VL_API_MAP_IF_ENABLE_DISABLE_REPLY);
673 }
674
675
676 #define foreach_map_plugin_api_msg              \
677 _(MAP_ADD_DOMAIN, map_add_domain)               \
678 _(MAP_DEL_DOMAIN, map_del_domain)               \
679 _(MAP_ADD_DEL_RULE, map_add_del_rule)           \
680 _(MAP_DOMAIN_DUMP, map_domain_dump)             \
681 _(MAP_RULE_DUMP, map_rule_dump)                 \
682 _(MAP_IF_ENABLE_DISABLE, map_if_enable_disable) \
683 _(MAP_SUMMARY_STATS, map_summary_stats)         \
684 _(MAP_PARAM_SET_FRAGMENTATION, map_param_set_fragmentation)     \
685 _(MAP_PARAM_SET_ICMP, map_param_set_icmp)       \
686 _(MAP_PARAM_SET_ICMP6, map_param_set_icmp6)     \
687 _(MAP_PARAM_ADD_DEL_PRE_RESOLVE, map_param_add_del_pre_resolve) \
688 _(MAP_PARAM_SET_REASSEMBLY, map_param_set_reassembly)           \
689 _(MAP_PARAM_SET_SECURITY_CHECK, map_param_set_security_check)   \
690 _(MAP_PARAM_SET_TRAFFIC_CLASS, map_param_set_traffic_class)     \
691 _(MAP_PARAM_SET_TCP, map_param_set_tcp) \
692 _(MAP_PARAM_GET, map_param_get)
693
694 #define vl_msg_name_crc_list
695 #include <map/map_all_api_h.h>
696 #undef vl_msg_name_crc_list
697
698 static void
699 setup_message_id_table (map_main_t * mm, api_main_t * am)
700 {
701 #define _(id,n,crc)                                                     \
702   vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id + mm->msg_id_base);
703   foreach_vl_msg_name_crc_map;
704 #undef _
705 }
706
707 /* Set up the API message handling tables */
708 clib_error_t *
709 map_plugin_api_hookup (vlib_main_t * vm)
710 {
711   map_main_t *mm = &map_main;
712   u8 *name = format (0, "map_%08x%c", api_version, 0);
713
714   /* Ask for a correctly-sized block of API message decode slots */
715   mm->msg_id_base =
716     vl_msg_api_get_msg_ids ((char *) name, VL_MSG_FIRST_AVAILABLE);
717 #define _(N,n)                                                  \
718     vl_msg_api_set_handlers((VL_API_##N + mm->msg_id_base),     \
719                            #n,                                  \
720                            vl_api_##n##_t_handler,              \
721                            vl_noop_handler,                     \
722                            vl_api_##n##_t_endian,               \
723                            vl_api_##n##_t_print,                \
724                            sizeof(vl_api_##n##_t), 1);
725   foreach_map_plugin_api_msg;
726 #undef _
727
728   /*
729    * Set up the (msg_name, crc, message-id) table
730    */
731   setup_message_id_table (mm, &api_main);
732
733   vec_free (name);
734   return 0;
735 }
736
737 /*
738  * fd.io coding-style-patch-verification: ON
739  *
740  * Local Variables:
741  * eval: (c-set-style "gnu")
742  * End:
743  */