tunnel: support copying TTL and flow label from inner to outer
[vpp.git] / src / vnet / tunnel / tunnel_types_api.c
1 /*
2  * tunnel_api.c - tunnel api
3  *
4  * Copyright (c) 2018 Cisco and/or its affiliates.
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include <vnet/api_errno.h>
19 #include <vnet/tunnel/tunnel_types_api.h>
20 #include <vnet/ip/ip_types_api.h>
21 #include <vnet/fib/fib_table.h>
22
23 #include <vnet/tunnel/tunnel_types.api_enum.h>
24 #include <vnet/tunnel/tunnel_types.api_types.h>
25
26
27 STATIC_ASSERT (sizeof (vl_api_tunnel_encap_decap_flags_t) ==
28                sizeof (tunnel_encap_decap_flags_t),
29                "tunnel API and internal flags enum size differ");
30 STATIC_ASSERT (sizeof (vl_api_tunnel_flags_t) == sizeof (tunnel_flags_t),
31                "tunnel API and internal flags enum size differ");
32
33 int
34 tunnel_encap_decap_flags_decode (vl_api_tunnel_encap_decap_flags_t f,
35                                  tunnel_encap_decap_flags_t * o)
36 {
37   if (f & ~TUNNEL_ENCAP_DECAP_FLAG_MASK)
38     /* unknown flags set */
39     return (VNET_API_ERROR_INVALID_VALUE_2);
40
41   *o = (tunnel_encap_decap_flags_t) f;
42   return (0);
43 }
44
45 vl_api_tunnel_encap_decap_flags_t
46 tunnel_encap_decap_flags_encode (tunnel_encap_decap_flags_t f)
47 {
48   return ((vl_api_tunnel_encap_decap_flags_t) f);
49 }
50
51 int
52 tunnel_flags_decode (vl_api_tunnel_flags_t f, tunnel_flags_t *o)
53 {
54   if (f & ~TUNNEL_FLAG_MASK)
55     /* unknown flags set */
56     return (VNET_API_ERROR_INVALID_VALUE_2);
57
58   *o = (tunnel_flags_t) f;
59   return (0);
60 }
61
62 vl_api_tunnel_flags_t
63 tunnel_flags_encode (tunnel_flags_t f)
64 {
65   return ((vl_api_tunnel_flags_t) f);
66 }
67
68 int
69 tunnel_mode_decode (vl_api_tunnel_mode_t in, tunnel_mode_t * out)
70 {
71   switch (in)
72     {
73 #define _(n, v)                                       \
74       case TUNNEL_API_MODE_##n:                       \
75         *out = TUNNEL_MODE_##n;                       \
76         return (0);
77       foreach_tunnel_mode
78 #undef _
79     }
80
81   return (VNET_API_ERROR_INVALID_VALUE_2);
82 }
83
84 vl_api_tunnel_mode_t
85 tunnel_mode_encode (tunnel_mode_t in)
86 {
87   vl_api_tunnel_mode_t out = TUNNEL_API_MODE_P2P;
88
89   switch (in)
90     {
91 #define _(n, v)                                       \
92       case TUNNEL_MODE_##n:                           \
93         out = TUNNEL_API_MODE_##n;                    \
94         break;
95       foreach_tunnel_mode
96 #undef _
97     }
98
99   return (out);
100 }
101
102 int
103 tunnel_decode (const vl_api_tunnel_t *in, tunnel_t *out)
104 {
105   int rv;
106
107   ip_address_decode2 (&in->src, &out->t_src);
108   ip_address_decode2 (&in->dst, &out->t_dst);
109
110   if (ip_addr_version (&out->t_src) != ip_addr_version (&out->t_dst))
111     return (VNET_API_ERROR_INVALID_PROTOCOL);
112
113   if (0 == ip_address_cmp (&out->t_src, &out->t_dst))
114     return (VNET_API_ERROR_SAME_SRC_DST);
115
116   rv = tunnel_encap_decap_flags_decode (in->encap_decap_flags,
117                                         &out->t_encap_decap_flags);
118
119   if (rv)
120     return (rv);
121
122   rv = tunnel_mode_decode (in->mode, &out->t_mode);
123
124   if (rv)
125     return (rv);
126
127   rv = tunnel_flags_decode (in->flags, &out->t_flags);
128
129   if (rv)
130     return (rv);
131
132   out->t_table_id = clib_net_to_host_u32 (in->table_id);
133   out->t_fib_index = fib_table_find (
134     ip_address_family_to_fib_proto (ip_addr_version (&out->t_dst)),
135     out->t_table_id);
136
137   if (~0 == out->t_fib_index)
138     return (VNET_API_ERROR_NO_SUCH_FIB);
139
140   out->t_dscp = ip_dscp_decode (in->dscp);
141   out->t_hop_limit = in->hop_limit;
142
143   return (0);
144 }
145
146 void
147 tunnel_encode (const tunnel_t *in, vl_api_tunnel_t *out)
148 {
149   ip_address_encode2 (&in->t_src, &out->src);
150   ip_address_encode2 (&in->t_dst, &out->dst);
151
152   out->encap_decap_flags =
153     tunnel_encap_decap_flags_encode (in->t_encap_decap_flags);
154   out->mode = tunnel_mode_encode (in->t_mode);
155   out->flags = tunnel_flags_encode (in->t_flags);
156   out->table_id = clib_host_to_net_u32 (in->t_table_id);
157   out->dscp = ip_dscp_encode (in->t_dscp);
158   out->hop_limit = in->t_hop_limit;
159 }
160
161 /*
162  * fd.io coding-style-patch-verification: ON
163  *
164  * Local Variables:
165  * eval: (c-set-style "gnu")
166  * End:
167  */