5619b24c9aadf71c503eaa162f231f316872aab5
[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 <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 #include <vlibapi/api_types_inlines.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   u8 *vtag = 0;
58   vtag = vl_api_from_api_to_vec (&mp->tag);
59   rv =
60     map_create_domain ((ip4_address_t *) & mp->ip4_prefix.prefix,
61                        mp->ip4_prefix.len,
62                        (ip6_address_t *) & mp->ip6_prefix.prefix,
63                        mp->ip6_prefix.len,
64                        (ip6_address_t *) & mp->ip6_src.prefix,
65                        mp->ip6_src.len, mp->ea_bits_len, mp->psid_offset,
66                        mp->psid_length, &index, ntohs (mp->mtu), flags, vtag);
67   vec_free (vtag);
68
69   /* *INDENT-OFF* */
70   REPLY_MACRO2(VL_API_MAP_ADD_DOMAIN_REPLY,
71   ({
72     rmp->index = ntohl(index);
73   }));
74   /* *INDENT-ON* */
75 }
76
77 static void
78 vl_api_map_del_domain_t_handler (vl_api_map_del_domain_t * mp)
79 {
80   map_main_t *mm = &map_main;
81   vl_api_map_del_domain_reply_t *rmp;
82   int rv = 0;
83
84   rv = map_delete_domain (ntohl (mp->index));
85
86   REPLY_MACRO (VL_API_MAP_DEL_DOMAIN_REPLY);
87 }
88
89 static void
90 vl_api_map_add_del_rule_t_handler (vl_api_map_add_del_rule_t * mp)
91 {
92   map_main_t *mm = &map_main;
93   vl_api_map_del_domain_reply_t *rmp;
94   int rv = 0;
95
96   rv =
97     map_add_del_psid (ntohl (mp->index), ntohs (mp->psid),
98                       (ip6_address_t *) & mp->ip6_dst, mp->is_add);
99
100   REPLY_MACRO (VL_API_MAP_ADD_DEL_RULE_REPLY);
101 }
102
103 static void
104 vl_api_map_domain_dump_t_handler (vl_api_map_domain_dump_t * mp)
105 {
106   vl_api_map_domain_details_t *rmp;
107   map_main_t *mm = &map_main;
108   map_domain_t *d;
109   map_domain_extra_t *de;
110   vl_api_registration_t *reg;
111   u32 map_domain_index;
112
113   if (pool_elts (mm->domains) == 0)
114     return;
115
116   reg = vl_api_client_index_to_registration (mp->client_index);
117   if (!reg)
118     return;
119
120   /* *INDENT-OFF* */
121   pool_foreach(d, mm->domains,
122   ({
123     map_domain_index = d - mm->domains;
124     de = vec_elt_at_index(mm->domain_extras, map_domain_index);
125
126     /* Make sure every field is initiated (or don't skip the clib_memset()) */
127     rmp = vl_msg_api_alloc (sizeof (*rmp) + vec_len(de->tag));
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.prefix, &d->ip6_prefix, sizeof(rmp->ip6_prefix.prefix));
133     clib_memcpy(&rmp->ip4_prefix.prefix, &d->ip4_prefix, sizeof(rmp->ip4_prefix.prefix));
134     clib_memcpy(&rmp->ip6_src.prefix, &d->ip6_src, sizeof(rmp->ip6_src.prefix));
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
144     vl_api_vec_to_api_string (de->tag, &rmp->tag );
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_u64 (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->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 =
592     clib_net_to_host_u64 ((u64) mm->ip4_reass_conf_ht_ratio);
593
594   rmp->ip6_lifetime_ms =
595     clib_net_to_host_u16 (mm->ip6_reass_conf_lifetime_ms);
596   rmp->ip6_pool_size = clib_net_to_host_u16 (mm->ip6_reass_conf_pool_size);
597   rmp->ip6_buffers = clib_net_to_host_u32 (mm->ip6_reass_conf_buffers);
598   rmp->ip6_ht_ratio =
599     clib_net_to_host_u64 ((u64) mm->ip6_reass_conf_ht_ratio);
600
601   rmp->sec_check_enable = mm->sec_check;
602   rmp->sec_check_fragments = mm->sec_check_frag;
603
604   rmp->tc_copy = mm->tc_copy;
605   rmp->tc_class = mm->tc;
606
607   vl_api_send_msg (reg, (u8 *) rmp);
608 }
609
610
611 int
612 map_if_enable_disable (bool is_enable, u32 sw_if_index, bool is_translation)
613 {
614   map_main_t *mm = &map_main;
615
616   if (pool_is_free_index (mm->vnet_main->interface_main.sw_interfaces,
617                           sw_if_index))
618     return VNET_API_ERROR_INVALID_SW_IF_INDEX;
619
620   is_enable = ! !is_enable;
621
622   if (is_translation)
623     {
624       if (clib_bitmap_get (mm->bm_trans_enabled_by_sw_if, sw_if_index)
625           == is_enable)
626         return 0;
627     }
628   else
629     {
630       if (clib_bitmap_get (mm->bm_encap_enabled_by_sw_if, sw_if_index)
631           == is_enable)
632         return 0;
633     }
634
635   if (is_translation == false)
636     {
637       vnet_feature_enable_disable ("ip4-unicast", "ip4-map", sw_if_index,
638                                    is_enable ? 1 : 0, 0, 0);
639       vnet_feature_enable_disable ("ip6-unicast", "ip6-map", sw_if_index,
640                                    is_enable ? 1 : 0, 0, 0);
641       mm->bm_encap_enabled_by_sw_if =
642         clib_bitmap_set (mm->bm_encap_enabled_by_sw_if, sw_if_index,
643                          is_enable);
644     }
645   else
646     {
647       vnet_feature_enable_disable ("ip4-unicast", "ip4-map-t", sw_if_index,
648                                    is_enable ? 1 : 0, 0, 0);
649       vnet_feature_enable_disable ("ip6-unicast", "ip6-map-t", sw_if_index,
650                                    is_enable ? 1 : 0, 0, 0);
651       mm->bm_trans_enabled_by_sw_if =
652         clib_bitmap_set (mm->bm_trans_enabled_by_sw_if, sw_if_index,
653                          is_enable);
654     }
655
656   return 0;
657 }
658
659
660 static void
661 vl_api_map_if_enable_disable_t_handler (vl_api_map_if_enable_disable_t * mp)
662 {
663   map_main_t *mm = &map_main;
664   vl_api_map_if_enable_disable_reply_t *rmp;
665   int rv = 0;
666
667   VALIDATE_SW_IF_INDEX (mp);
668
669   rv =
670     map_if_enable_disable (mp->is_enable, htonl (mp->sw_if_index),
671                            mp->is_translation);
672
673   BAD_SW_IF_INDEX_LABEL;
674   REPLY_MACRO (VL_API_MAP_IF_ENABLE_DISABLE_REPLY);
675 }
676
677
678 #define foreach_map_plugin_api_msg              \
679 _(MAP_ADD_DOMAIN, map_add_domain)               \
680 _(MAP_DEL_DOMAIN, map_del_domain)               \
681 _(MAP_ADD_DEL_RULE, map_add_del_rule)           \
682 _(MAP_DOMAIN_DUMP, map_domain_dump)             \
683 _(MAP_RULE_DUMP, map_rule_dump)                 \
684 _(MAP_IF_ENABLE_DISABLE, map_if_enable_disable) \
685 _(MAP_SUMMARY_STATS, map_summary_stats)         \
686 _(MAP_PARAM_SET_FRAGMENTATION, map_param_set_fragmentation)     \
687 _(MAP_PARAM_SET_ICMP, map_param_set_icmp)       \
688 _(MAP_PARAM_SET_ICMP6, map_param_set_icmp6)     \
689 _(MAP_PARAM_ADD_DEL_PRE_RESOLVE, map_param_add_del_pre_resolve) \
690 _(MAP_PARAM_SET_REASSEMBLY, map_param_set_reassembly)           \
691 _(MAP_PARAM_SET_SECURITY_CHECK, map_param_set_security_check)   \
692 _(MAP_PARAM_SET_TRAFFIC_CLASS, map_param_set_traffic_class)     \
693 _(MAP_PARAM_SET_TCP, map_param_set_tcp) \
694 _(MAP_PARAM_GET, map_param_get)
695
696 #define vl_msg_name_crc_list
697 #include <map/map_all_api_h.h>
698 #undef vl_msg_name_crc_list
699
700 static void
701 setup_message_id_table (map_main_t * mm, api_main_t * am)
702 {
703 #define _(id,n,crc)                                                     \
704   vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id + mm->msg_id_base);
705   foreach_vl_msg_name_crc_map;
706 #undef _
707 }
708
709 /* Set up the API message handling tables */
710 clib_error_t *
711 map_plugin_api_hookup (vlib_main_t * vm)
712 {
713   map_main_t *mm = &map_main;
714   u8 *name = format (0, "map_%08x%c", api_version, 0);
715
716   /* Ask for a correctly-sized block of API message decode slots */
717   mm->msg_id_base =
718     vl_msg_api_get_msg_ids ((char *) name, VL_MSG_FIRST_AVAILABLE);
719 #define _(N,n)                                                  \
720     vl_msg_api_set_handlers((VL_API_##N + mm->msg_id_base),     \
721                            #n,                                  \
722                            vl_api_##n##_t_handler,              \
723                            vl_noop_handler,                     \
724                            vl_api_##n##_t_endian,               \
725                            vl_api_##n##_t_print,                \
726                            sizeof(vl_api_##n##_t), 1);
727   foreach_map_plugin_api_msg;
728 #undef _
729
730   /*
731    * Set up the (msg_name, crc, message-id) table
732    */
733   setup_message_id_table (mm, &api_main);
734
735   vec_free (name);
736   return 0;
737 }
738
739 /*
740  * fd.io coding-style-patch-verification: ON
741  *
742  * Local Variables:
743  * eval: (c-set-style "gnu")
744  * End:
745  */