blob: ff10fc929a644dee89a39e71746e03bd814964aa [file] [log] [blame]
Ole Troand575e692016-08-25 12:26:47 +02001/*
2 * test.c : MAP unit tests
3 *
4 * Copyright (c) 2016 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 <assert.h>
19#include "map.h"
20
21static map_domain_t *
22get_domain(ip4_address_t * ip4_prefix, u8 ip4_prefix_len,
23 ip6_address_t * ip6_prefix, u8 ip6_prefix_len,
24 ip6_address_t * ip6_src, u8 ip6_src_len,
25 u8 ea_bits_len, u8 psid_offset,
26 u8 psid_length, u16 mtu, u8 flags)
27{
28 map_domain_t * d = malloc(sizeof(*d));
29 u8 suffix_len;
30
31 /* EA bits must be within the first 64 bits */
32 if (ea_bits_len > 0 && (ip6_prefix_len + ea_bits_len) > 64)
33 return NULL;
34
35 /* Init domain struct */
36 d->ip4_prefix.as_u32 = ip4_prefix->as_u32;
37 d->ip4_prefix_len = ip4_prefix_len;
38 d->ip6_prefix = *ip6_prefix;
39 d->ip6_prefix_len = ip6_prefix_len;
40 d->ip6_src = *ip6_src;
41 d->ip6_src_len = ip6_src_len;
42 d->ea_bits_len = ea_bits_len;
43 d->psid_offset = psid_offset;
44 d->psid_length = psid_length;
45 d->mtu = mtu;
46 d->flags = flags;
47
48 /* How many, and which bits to grab from the IPv4 DA */
49 if (ip4_prefix_len + ea_bits_len < 32)
50 {
Juraj Sloboda0ae15ed2017-12-19 20:57:48 +010051 if (!(flags & MAP_DOMAIN_TRANSLATION))
52 d->flags |= MAP_DOMAIN_PREFIX;
Ole Troand575e692016-08-25 12:26:47 +020053 d->suffix_shift = 32 - ip4_prefix_len - ea_bits_len;
54 suffix_len = ea_bits_len;
55 }
56 else
57 {
58 d->suffix_shift = 0;
59 suffix_len = 32 - ip4_prefix_len;
60 }
61 d->suffix_mask = (1 << suffix_len) - 1;
62
63 d->psid_shift = 16 - psid_length - psid_offset;
64 d->psid_mask = (1 << d->psid_length) - 1;
65
66 if (ip6_prefix_len + suffix_len + d->psid_length > 64)
67 return NULL;
68
69 d->ea_shift = 64 - ip6_prefix_len - suffix_len - d->psid_length;
70
71 return d;
72}
73
74
75/*
76 * VPP-340:
77 * map_add_domain ip4-pfx 20.0.0.0/8 ip6-pfx 2001:db8::/40 ip6-src 2001:db8:ffff::/96 ea-bits-len 24 psid-offset 0 psid-len 0 map-t
78 * IPv4 src = 100.0.0.1
79 * IPv4 dst = 20.169.201.219
80 * UDP dest port = 1232
81 * IPv6 src = 2001:db8:ffff::6400:1
82 * IPv6 dst = a9c9:dfb8::14a9:c9db:0
83 * a9c9:dfb8::14a9:c9db:0 != 2001:db8:a9:c9db:0:14a9:c9db:0
84 */
85static void
86test_map_t_destaddr (void)
87{
88 ip4_address_t ip4_prefix;
89 ip6_address_t ip6_prefix;
90 ip6_address_t ip6_src;
91
92 ip4_prefix.as_u32 = clib_host_to_net_u32(0x14000000);
93 ip6_prefix.as_u64[0] = clib_host_to_net_u64(0x20010db800000000);
94 ip6_prefix.as_u64[1] = 0;
95 ip6_src.as_u64[0] = clib_host_to_net_u64(0x20010db8ffff0000);
96 map_domain_t * d = get_domain (&ip4_prefix, 8, &ip6_prefix, 40, &ip6_src, 96, 24, 0, 0, 0, MAP_DOMAIN_TRANSLATION);
97
98 ip6_address_t dst6;
99
100 dst6.as_u64[0] = map_get_pfx(d, 0x14a9c9db, 1232);
101 dst6.as_u64[1] = map_get_sfx(d, 0x14a9c9db, 1232);
102 assert(dst6.as_u64[0] == 0x20010db800a9c9db);
103 assert(dst6.as_u64[1] == 0x000014a9c9db0000);
104}
105
106/*
107 * VPP-228
108 * ip4-pfx 20.0.0.0/8
109 * ip6-pfx 2001:db8::/<n>
110 * ip6-src 2001:db8:ffff::1
111 * ea-bits-len 16 psid-offset 6 psid-len 8
112 * 20.169.201.219 port 1232
113 */
114static void
115test_map_eabits (void)
116{
117 ip4_address_t ip4_prefix;
118 ip6_address_t ip6_prefix;
119 ip6_address_t ip6_src;
120 ip6_address_t dst6;
121
122 ip4_prefix.as_u32 = clib_host_to_net_u32(0x14000000);
123 ip6_prefix.as_u64[0] = clib_host_to_net_u64(0x20010db800000000);
124 ip6_prefix.as_u64[1] = 0;
125 ip6_src.as_u64[0] = clib_host_to_net_u64(0x20010db8ffff0000);
126 ip6_src.as_u64[1] = clib_host_to_net_u64(0x0000000000000001);
127 map_domain_t * d = get_domain (&ip4_prefix, 16, &ip6_prefix, 48, &ip6_src,
128 128, 16, 6, 8, 0, 0);
129 assert(!d);
130
131 //20.0.0.0/8 2001:db8::/32 4 2001:db8:a000::14a0:0:0
132 d = get_domain (&ip4_prefix, 8, &ip6_prefix, 32, &ip6_src,
133 128, 4, 0, 0, 0, 0);
134 dst6.as_u64[0] = map_get_pfx(d, 0x14a9c9db, 1232);
135 dst6.as_u64[1] = map_get_sfx(d, 0x14a9c9db, 1232);
136 assert(dst6.as_u64[0] == 0x20010db8a0000000);
137 assert(dst6.as_u64[1] == 0x000014a000000000);
138
139 //20.0.0.0/8 2001:db8::/32 8 2001:db8:a900::14a9:0:0
140 d = get_domain (&ip4_prefix, 8, &ip6_prefix, 32, &ip6_src,
141 128, 8, 0, 0, 0, 0);
142 dst6.as_u64[0] = map_get_pfx(d, 0x14a9c9db, 1232);
143 dst6.as_u64[1] = map_get_sfx(d, 0x14a9c9db, 1232);
144 assert(dst6.as_u64[0] == 0x20010db8a9000000);
145 assert(dst6.as_u64[1] == 0x000014a900000000);
146
147 //20.0.0.0/8 2001:db8::/32 10 2001:db8:a9c0::14a9:c000:0
148 d = get_domain (&ip4_prefix, 8, &ip6_prefix, 32, &ip6_src,
149 128, 10, 0, 0, 0, 0);
150 dst6.as_u64[0] = map_get_pfx(d, 0x14a9c9db, 1232);
151 dst6.as_u64[1] = map_get_sfx(d, 0x14a9c9db, 1232);
152 assert(dst6.as_u64[0] == 0x20010db8a9c00000);
153 assert(dst6.as_u64[1] == 0x000014a9c0000000);
154
155 //20.0.0.0/8 2001:db8::/32 16 2001:db8:a9c9::14a9:c900:0
156 d = get_domain (&ip4_prefix, 8, &ip6_prefix, 32, &ip6_src,
157 128, 16, 0, 0, 0, 0);
158 dst6.as_u64[0] = map_get_pfx(d, 0x14a9c9db, 1232);
159 dst6.as_u64[1] = map_get_sfx(d, 0x14a9c9db, 1232);
160 assert(dst6.as_u64[0] == 0x20010db8a9c90000);
161 assert(dst6.as_u64[1] == 0x000014a9c9000000);
162
163 //20.0.0.0/8 2001:db8::/32 20 2001:db8:a9c9:d000:0:14a9:c9d0:0
164 d = get_domain (&ip4_prefix, 8, &ip6_prefix, 32, &ip6_src,
165 128, 20, 0, 0, 0, 0);
166 dst6.as_u64[0] = map_get_pfx(d, 0x14a9c9db, 1232);
167 dst6.as_u64[1] = map_get_sfx(d, 0x14a9c9db, 1232);
168 assert(dst6.as_u64[0] == 0x20010db8a9c9d000);
169 assert(dst6.as_u64[1] == 0x000014a9c9d00000);
170
171 //20.0.0.0/8 2001:db8::/32 23 2001:db8:a9c9:da00:0:14a9:c9da:0
172 d = get_domain (&ip4_prefix, 8, &ip6_prefix, 32, &ip6_src,
173 128, 23, 0, 0, 0, 0);
174 dst6.as_u64[0] = map_get_pfx(d, 0x14a9c9db, 1232);
175 dst6.as_u64[1] = map_get_sfx(d, 0x14a9c9db, 1232);
176 assert(dst6.as_u64[0] == 0x20010db8a9c9da00);
177 assert(dst6.as_u64[1] == 0x000014a9c9da0000);
178
179 //20.169.201.0/24 2001:db8::/32 7 2001:db8:da00::14a9:c9da:0
180 d = get_domain (&ip4_prefix, 8, &ip6_prefix, 32, &ip6_src,
181 128, 7, 0, 0, 0, 0);
182 dst6.as_u64[0] = map_get_pfx(d, 0x14a9c9db, 1232);
183 dst6.as_u64[1] = map_get_sfx(d, 0x14a9c9db, 1232);
184 assert(dst6.as_u64[0] == 0x20010db8a8000000);
185 assert(dst6.as_u64[1] == 0x000014a800000000);
186}
187
188#define foreach_test_case \
189 _(map_t_destaddr) \
190 _(map_eabits)
191
192static void
193run_tests (void)
194{
195#define _(_test_name) \
196 test_ ## _test_name ();
197
198 foreach_test_case
199#undef _
200}
201
202int main()
203{
204 run_tests ();
205 return 0;
206}