1/*
2 * Copyright (c) 2018 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include <vlibapi/api_types.h>
17#include <vnet/ip/ip_types_api.h>
18
19#define vl_typedefs		/* define message structures */
20#include <vnet/vnet_all_api_h.h>
21#undef vl_typedefs
22
23#define vl_endianfun		/* define message structures */
24#include <vnet/vnet_all_api_h.h>
25#undef vl_endianfun
26
27/* instantiate all the print functions we know about */
28#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
29#define vl_printfun
30#include <vnet/vnet_all_api_h.h>
31#undef vl_printfun
32
33int
34ip_address_family_decode (vl_api_address_family_t af,
35			  ip_address_family_t * out)
36{
37  switch (af)
38    {
39    case ADDRESS_IP4:
40      *out = AF_IP4;
41      return (0);
42    case ADDRESS_IP6:
43      *out = AF_IP6;
44      return (0);
45    }
46  return (VNET_API_ERROR_INVALID_ADDRESS_FAMILY);
47}
48
49vl_api_address_family_t
50ip_address_family_encode (ip_address_family_t af)
51{
52  switch (af)
53    {
54    case AF_IP4:
55      return (ADDRESS_IP4);
56    case AF_IP6:
57      return (ADDRESS_IP6);
58    }
59
60  ASSERT (0);
61  return (ADDRESS_IP4);
62}
63
64int
65ip_proto_decode (vl_api_ip_proto_t ipp, ip_protocol_t * out)
66{
67  /* Not all protocol are defined in vl_api_ip_proto_t
68   * so we must cast to a different type.
69   */
70  switch ((u8) ipp)
71    {
72#define ip_protocol(n,s)                       \
73      case IP_PROTOCOL_##s:                    \
74        *out = IP_PROTOCOL_##s;                \
75        return (0);
76#include "protocols.def"
77#undef ip_protocol
78    }
79  return (VNET_API_ERROR_INVALID_PROTOCOL);
80}
81
82vl_api_ip_proto_t
83ip_proto_encode (ip_protocol_t ipp)
84{
85  switch (ipp)
86    {
87#define ip_protocol(n,s)                                \
88      case IP_PROTOCOL_##s:                             \
89        return ((vl_api_ip_proto_t) IP_PROTOCOL_##s);
90#include "protocols.def"
91#undef ip_protocol
92    }
93
94  ASSERT (0);
95  return (IP_API_PROTO_TCP);
96}
97
98ip_dscp_t
99ip_dscp_decode (vl_api_ip_dscp_t in)
100{
101  return ((ip_dscp_t) in);
102}
103
104vl_api_ip_dscp_t
105ip_dscp_encode (ip_dscp_t dscp)
106{
107  return ((vl_api_ip_dscp_t) dscp);
108}
109
110void
111ip6_address_encode (const ip6_address_t * in, vl_api_ip6_address_t out)
112{
113  clib_memcpy (out, in, sizeof (*in));
114}
115
116void
117ip6_address_decode (const vl_api_ip6_address_t in, ip6_address_t * out)
118{
119  clib_memcpy (out, in, sizeof (*out));
120}
121
122void
123ip4_address_encode (const ip4_address_t * in, vl_api_ip4_address_t out)
124{
125  clib_memcpy (out, in, sizeof (*in));
126}
127
128void
129ip4_address_decode (const vl_api_ip4_address_t in, ip4_address_t * out)
130{
131  clib_memcpy (out, in, sizeof (*out));
132}
133
134static ip46_type_t
135ip_address_union_decode (const vl_api_address_union_t * in,
136			 vl_api_address_family_t af, ip46_address_t * out)
137{
138  ip46_type_t type;
139
140  switch (af)
141    {
142    case ADDRESS_IP4:
143      clib_memset (out, 0, sizeof (*out));
144      clib_memcpy (&out->ip4, &in->ip4, sizeof (out->ip4));
145      type = IP46_TYPE_IP4;
146      break;
147    case ADDRESS_IP6:
148      clib_memcpy (&out->ip6, &in->ip6, sizeof (out->ip6));
149      type = IP46_TYPE_IP6;
150      break;
151    default:
152      type = IP46_TYPE_ANY;
153      break;
154    }
155
156  return type;
157}
158
159ip46_type_t
160ip_address_decode (const vl_api_address_t * in, ip46_address_t * out)
161{
162  return (ip_address_union_decode (&in->un, in->af, out));
163}
164
165void
166ip_address_decode2 (const vl_api_address_t * in, ip_address_t * out)
167{
168  switch (ip_address_union_decode (&in->un, in->af, &out->ip))
169    {
170    case IP46_TYPE_IP4:
171      out->version = AF_IP4;
172      break;
173    case IP46_TYPE_IP6:
174      out->version = AF_IP6;
175      break;
176    default:
177      ;
178      break;
179    }
180}
181
182static void
183ip_address_union_encode (const ip46_address_t * in,
184			 vl_api_address_family_t af,
185			 vl_api_address_union_t * out)
186{
187  if (ADDRESS_IP6 == af)
188    ip6_address_encode (&in->ip6, out->ip6);
189  else
190    ip4_address_encode (&in->ip4, out->ip4);
191}
192
193void
194ip_address_encode (const ip46_address_t * in,
195		   ip46_type_t type, vl_api_address_t * out)
196{
197  switch (type)
198    {
199    case IP46_TYPE_IP4:
200      out->af = ADDRESS_IP4;
201      break;
202    case IP46_TYPE_IP6:
203      out->af = ADDRESS_IP6;
204      break;
205    case IP46_TYPE_ANY:
206      if (ip46_address_is_ip4 (in))
207	out->af = ADDRESS_IP4;
208      else
209	out->af = ADDRESS_IP6;
210      break;
211    }
212  ip_address_union_encode (in, out->af, &out->un);
213}
214
215void
216ip_address_encode2 (const ip_address_t * in, vl_api_address_t * out)
217{
218  switch (in->version)
219    {
220    case AF_IP4:
221      out->af = ADDRESS_IP4;
222      ip4_address_encode (&in->ip.ip4, out->un.ip4);
223      break;
224    case AF_IP6:
225      out->af = ADDRESS_IP6;
226      ip6_address_encode (&in->ip.ip6, out->un.ip6);
227      break;
228    }
229  ip_address_union_encode (&in->ip, out->af, &out->un);
230}
231
232void
233ip_prefix_decode (const vl_api_prefix_t * in, fib_prefix_t * out)
234{
235  switch (in->address.af)
236    {
237    case ADDRESS_IP4:
238      out->fp_proto = FIB_PROTOCOL_IP4;
239      break;
240    case ADDRESS_IP6:
241      out->fp_proto = FIB_PROTOCOL_IP6;
242      break;
243    }
244  out->fp_len = in->len;
245  out->___fp___pad = 0;
246  ip_address_decode (&in->address, &out->fp_addr);
247}
248
249int
250ip_prefix_decode2 (const vl_api_prefix_t * in, ip_prefix_t * out)
251{
252  out->len = in->len;
253  ip_address_decode2 (&in->address, &out->addr);
254
255  if (!ip_prefix_validate (out))
256    return (VNET_API_ERROR_IP_PREFIX_INVALID);
257  return (0);
258}
259
260void
261ip_prefix_encode (const fib_prefix_t * in, vl_api_prefix_t * out)
262{
263  out->len = in->fp_len;
264  ip46_type_t ip46_type;
265
266  switch (in->fp_proto)
267    {
268    case FIB_PROTOCOL_IP4:
269      ip46_type = (IP46_TYPE_IP4);
270      break;
271    case FIB_PROTOCOL_IP6:
272      ip46_type = (IP46_TYPE_IP6);
273      break;
274    case FIB_PROTOCOL_MPLS:
275      ip46_type = (IP46_TYPE_ANY);
276      break;
277    default:
278      ip46_type = (IP46_TYPE_ANY);
279    }
280
281  ip_address_encode (&in->fp_addr, ip46_type, &out->address);
282}
283
284void
285ip_prefix_encode2 (const ip_prefix_t * in, vl_api_prefix_t * out)
286{
287  out->len = in->len;
288  ip_address_encode2 (&in->addr, &out->address);
289}
290
291void
292ip_mprefix_encode (const mfib_prefix_t * in, vl_api_mprefix_t * out)
293{
294  out->af = (FIB_PROTOCOL_IP6 == in->fp_proto ? ADDRESS_IP6 : ADDRESS_IP4);
295  out->grp_address_length = clib_host_to_net_u16 (in->fp_len);
296
297  ip_address_union_encode (&in->fp_grp_addr, out->af, &out->grp_address);
298  ip_address_union_encode (&in->fp_src_addr, out->af, &out->src_address);
299}
300
301void
302ip_mprefix_decode (const vl_api_mprefix_t * in, mfib_prefix_t * out)
303{
304  out->fp_proto = (ADDRESS_IP6 == in->af ?
305		   FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4);
306  out->fp_len = clib_net_to_host_u16 (in->grp_address_length);
307  out->___fp___pad = 0;
308
309  ip_address_union_decode (&in->grp_address, in->af, &out->fp_grp_addr);
310  ip_address_union_decode (&in->src_address, in->af, &out->fp_src_addr);
311
312  if (!ip46_address_is_zero (&out->fp_src_addr))
313    out->fp_len = (out->fp_proto == FIB_PROTOCOL_IP6 ? 256 : 64);
314}
315
316/*
317 * fd.io coding-style-patch-verification: ON
318 *
319 * Local Variables:
320 * eval: (c-set-style "gnu")
321 * End:
322 */
323