• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
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  * Description: implementation for nat64 API
15  * Author: NA
16  * Create: 2020
17  */
18 
19 #include <stdint.h>
20 #include "lwip/opt.h"
21 #if LWIP_NAT64
22 #include "lwip/nat64_api.h"
23 #include "lwip/nat64.h"
24 #include "lwip/nat64_addr.h"
25 #include "lwip/netifapi.h"
26 #include "lwip/nat64_v4_dhcpc.h"
27 #include "rpl_common.h"
28 
29 static err_t
lwip_nat64_translate(lwip_nat64_entry_t * nate,nat64_entry_t * dst)30 lwip_nat64_translate(lwip_nat64_entry_t *nate, nat64_entry_t *dst)
31 {
32   int ret;
33 
34   ret = memcpy_s(dst->mac.addr, NETIF_MAX_HWADDR_LEN, nate->mac, NETIF_MAX_HWADDR_LEN);
35   if (ret != EOK) {
36     return ERR_MEM;
37   }
38   dst->mac.addrlen = NETIF_MAX_HWADDR_LEN;
39 
40 #if !LWIP_NAT64_MIN_SUBSTITUTE
41   dst->ip.addr = nate->ip;
42 #endif
43 
44   dst->lifetime = nate->lifetime;
45   dst->conn_time = nate->conn_time;
46   dst->state = nate->state;
47   dst->dao_sn = nate->dao_sn;
48   dst->mnid = nate->mnid;
49   dst->orig_mnid = nate->orig_mnid;
50   return ERR_OK;
51 }
52 
53 static err_t
lwip_nat64_copy(nat64_entry_t * nate,void * data)54 lwip_nat64_copy(nat64_entry_t *nate, void *data)
55 {
56   lwip_nate_arg_t *arg = (lwip_nate_arg_t *)data;
57   lwip_nat64_entry_t *dst = NULL;
58   int ret;
59 
60   if (arg->index >= arg->cnt) {
61     return ERR_VAL;
62   }
63   if ((arg->is_all == lwIP_FALSE) && (nate->nat64_sync == lwIP_TRUE)) {
64     return ERR_OK;
65   }
66   if (nate->state != NAT64_STATE_ESTABLISH) {
67     return ERR_OK;
68   }
69   dst = &arg->nate[arg->index];
70 
71   ret = memcpy_s(dst->mac, NETIF_MAX_HWADDR_LEN, nate->mac.addr, nate->mac.addrlen);
72   if (ret != EOK) {
73     return ERR_MEM;
74   }
75 
76   dst->ip = nate->ip.addr;
77   dst->lifetime = nate->lifetime;
78   dst->conn_time = nate->conn_time;
79   dst->state = nate->state;
80   dst->dao_sn = nate->dao_sn;
81   dst->mnid = rpl_get_mbr_mnid();
82   dst->orig_mnid = nate->orig_mnid;
83   dst->nat64_sync = lwIP_TRUE;
84 
85   arg->index++;
86   return ERR_OK;
87 }
88 
89 static err_t
lwip_nat64_get(struct netif * nif,void * arg)90 lwip_nat64_get(struct netif *nif, void *arg)
91 {
92   lwip_nate_arg_t *nate_arg = (lwip_nate_arg_t *)arg;
93   nate_arg->index = 0;
94   (void)nat64_entry_traverse(lwip_nat64_copy, arg);
95 
96   LWIP_UNUSED_ARG(nif);
97   return ERR_OK;
98 }
99 
100 static err_t
lwip_nat64_get_cnt(struct netif * nif,void * arg)101 lwip_nat64_get_cnt(struct netif *nif, void *arg)
102 {
103   LWIP_UNUSED_ARG(nif);
104   lwip_nate_arg_t *nate_arg = (lwip_nate_arg_t *)arg;
105   nate_arg->index = 0;
106   int state = 0;
107   nat64_entry_t *nate = NULL;
108   while ((nate = nat64_get_next_inuse_entry(&state)) != NULL) {
109     if (nate_arg->type == NAT64_ENTRY_GET_ALL) {
110       if (nate->state == NAT64_STATE_ESTABLISH) {
111         nate_arg->index++;
112       }
113     } else if ((nate_arg->type == NAT64_ENERY_GET_SYNC) && (nate->nat64_sync != lwIP_TRUE)) {
114       if (nate->state == NAT64_STATE_ESTABLISH) {
115         nate_arg->index++;
116       }
117     }
118   }
119 
120   return ERR_OK;
121 }
122 
123 static void
lwip_nat64_handle_add(nat64_entry_t * dst_nate,nat64_entry_t * nate_exist,u8_t mbr_mnid)124 lwip_nat64_handle_add(nat64_entry_t *dst_nate, nat64_entry_t *nate_exist, u8_t mbr_mnid)
125 {
126   err_t ret;
127   if (dst_nate->mnid == mbr_mnid) {
128     return;
129   }
130   if ((nate_exist != NULL) && (nate_exist->mnid != dst_nate->mnid)) {
131     if (nate_exist->nat64_sync == lwIP_FALSE) {
132       if (nate_exist->conn_time < dst_nate->conn_time) {
133         return;
134       }
135       ret = nat64_dhcp_stop(nat64_netif_get(), &(nate_exist->mac), lwIP_FALSE);
136       if (ret != ERR_OK) {
137         LWIP_DEBUGF(NAT64_DEBUG, ("stop nat64 dhcp proxy fail\n"));
138       }
139     }
140     (void)nat64_entry_update(dst_nate, lwIP_TRUE);
141     return;
142   }
143   (void)nat64_entry_add_new(dst_nate);
144 }
145 
146 static err_t
lwip_nat64_handle(struct netif * nif,void * arg)147 lwip_nat64_handle(struct netif *nif, void *arg)
148 {
149   nat64_entry_t dst_nate;
150   u8_t mbr_mnid;
151   (void)memset_s(&dst_nate, sizeof(nat64_entry_t), 0, sizeof(nat64_entry_t));
152 
153   mbr_mnid = rpl_get_mbr_mnid();
154 
155   lwip_nate_arg_t *lwip_nate = (lwip_nate_arg_t *)arg;
156 
157   (void)lwip_nat64_translate(lwip_nate->nate, &dst_nate);
158 
159   nat64_entry_t *nate_exist = NULL;
160   nate_exist = nat64_entry_lookup_by_mac(&dst_nate.mac);
161 
162   switch (lwip_nate->type) {
163     case NAT64_ENTRY_ADD:
164       lwip_nat64_handle_add(&dst_nate, nate_exist, mbr_mnid);
165       break;
166     case NAT64_ENTRY_DEL:
167       if (nate_exist != NULL) {
168         if ((nate_exist->mnid == dst_nate.mnid) && (nate_exist->nat64_sync == lwIP_TRUE)) {
169           (void)nat64_entry_remove(nate_exist, lwIP_FALSE);
170         }
171       }
172       break;
173     case NAT64_ENTRY_UPDATE:
174       if (dst_nate.mnid == mbr_mnid) {
175         break;
176       }
177       if ((nate_exist != NULL) && (nate_exist->mnid == dst_nate.mnid) &&
178           (nate_exist->nat64_sync == lwIP_TRUE)) {
179         (void)nat64_entry_update(&dst_nate, lwIP_TRUE);
180       }
181       break;
182     default:
183       break;
184   }
185   LWIP_UNUSED_ARG(nif);
186   return ERR_OK;
187 }
188 
189 int
lwip_nat64_entry_delete(lwip_nat64_entry_t * nate)190 lwip_nat64_entry_delete(lwip_nat64_entry_t *nate)
191 {
192   lwip_nate_arg_t arg;
193   err_t ret;
194   if (nate == NULL) {
195     return ERR_VAL;
196   }
197 
198   arg.nate = nate;
199   arg.type = NAT64_ENTRY_DEL;
200 
201   ret = netifapi_call_argcb(lwip_nat64_handle, (void *)&arg);
202   if (ret != ERR_OK) {
203     return ERR_VAL;
204   }
205   return ERR_OK;
206 }
207 
208 int
lwip_nat64_entry_add(lwip_nat64_entry_t * nate)209 lwip_nat64_entry_add(lwip_nat64_entry_t *nate)
210 {
211   lwip_nate_arg_t arg;
212   err_t ret;
213   if (nate == NULL) {
214     return ERR_VAL;
215   }
216 
217   arg.nate = nate;
218   arg.type = NAT64_ENTRY_ADD;
219 
220   ret = netifapi_call_argcb(lwip_nat64_handle, (void *)&arg);
221   if (ret != ERR_OK) {
222     return ERR_VAL;
223   }
224   return ERR_OK;
225 }
226 
227 int
lwip_nat64_entry_update(lwip_nat64_entry_t * nate)228 lwip_nat64_entry_update(lwip_nat64_entry_t *nate)
229 {
230   lwip_nate_arg_t arg;
231   err_t ret;
232   if (nate == NULL) {
233     return ERR_VAL;
234   }
235 
236   arg.nate = nate;
237   arg.type = NAT64_ENTRY_UPDATE;
238 
239   ret = netifapi_call_argcb(lwip_nat64_handle, (void *)&arg);
240   if (ret != ERR_OK) {
241     return ERR_VAL;
242   }
243   return ERR_OK;
244 }
245 
246 int
lwip_nat64_entry_get(lwip_nat64_entry_t * nate,uint16_t cnt,uint8_t is_all)247 lwip_nat64_entry_get(lwip_nat64_entry_t *nate, uint16_t cnt, uint8_t is_all)
248 {
249   lwip_nate_arg_t arg;
250   err_t ret;
251 
252   if ((nate == NULL) || (cnt == 0)) {
253     return -1;
254   }
255 
256   arg.nate = nate;
257   arg.cnt = cnt;
258   arg.is_all = is_all;
259 
260   ret = netifapi_call_argcb(lwip_nat64_get, &arg);
261   if (ret != ERR_OK) {
262     return -1;
263   }
264 
265   return arg.index;
266 }
267 
268 uint16_t
lwip_nat64_entry_cnt(uint8_t type)269 lwip_nat64_entry_cnt(uint8_t type)
270 {
271   err_t ret;
272   lwip_nate_arg_t arg;
273   (void)memset_s(&arg, sizeof(lwip_nate_arg_t), 0, sizeof(lwip_nate_arg_t));
274   arg.type = type;
275   ret = netifapi_call_argcb(lwip_nat64_get_cnt, &arg);
276   if (ret != ERR_OK) {
277     return 0;
278   }
279   return arg.index;
280 }
281 
282 int
lwip_nat64_sync_entry_remove(uint8_t mnid)283 lwip_nat64_sync_entry_remove(uint8_t mnid)
284 {
285   uint8_t arg = mnid;
286   err_t ret;
287   ret = netifapi_call_argcb(nat64_entry_remove_by_mnid, &arg);
288   if (ret != ERR_OK) {
289     return -1;
290   }
291 
292   return ERR_OK;
293 }
294 
295 static err_t
nat64_clients_mac_get(struct netif * netif,void * arg)296 nat64_clients_mac_get(struct netif *netif, void *arg)
297 {
298   struct mesh_clients_mac_info *clis_info = (struct mesh_clients_mac_info *)arg;
299   int state = 0;
300   nat64_entry_t *nate = NULL;
301   struct mesh_client_mac_info *cli_mac = NULL;
302   u16_t cnt = 0;
303 
304   (void)netif;
305 
306   if ((clis_info == NULL) || (clis_info->num == 0)) {
307     LWIP_DEBUGF(NAT64_DEBUG, ("nat64_clients_mac_get: invalid arg\n"));
308     return ERR_ARG;
309   }
310 
311   while (((nate = nat64_get_next_inuse_entry(&state)) != NULL) && (cnt < clis_info->num)) {
312     cli_mac = &((clis_info->clis)[cnt]);
313     (void)memcpy_s(cli_mac->mac, NETIF_MAX_HWADDR_LEN, nate->mac.addr, NETIF_MAX_HWADDR_LEN);
314     cli_mac->mac_len = nate->mac.addrlen;
315     cnt++;
316   }
317   clis_info->num = cnt;
318   return ERR_OK;
319 }
320 
321 static err_t
nat64_client_address_find(struct netif * netif,void * cli_address)322 nat64_client_address_find(struct netif *netif, void *cli_address)
323 {
324   struct mesh_client_address *cli_info = (struct mesh_client_address *)cli_address;
325   nat64_entry_t *nate = NULL;
326   linklayer_addr_t lladdr = {0};
327 
328   (void)netif;
329 
330   if (cli_info == NULL) {
331     LWIP_DEBUGF(NAT64_DEBUG, ("nat64_client_address_find: invalid arg\n"));
332     return ERR_ARG;
333   }
334 
335   (void)memcpy_s(lladdr.addr, NETIF_MAX_HWADDR_LEN, cli_info->mac, NETIF_MAX_HWADDR_LEN);
336   lladdr.addrlen = cli_info->mac_len;
337   nate = nat64_entry_lookup_by_mac((const linklayer_addr_t *)&lladdr);
338   if (nate == NULL) {
339     LWIP_DEBUGF(NAT64_DEBUG, ("nat64_client_address_find: no entry\n"));
340     return ERR_VAL;
341   }
342   cli_info->ip4addr.addr = 0;
343   (void)nat64_entry_to4(nate, &(cli_info->ip4addr));
344   (void)memset_s(&(cli_info->ip6addr), sizeof(ip6_addr_t), 0, sizeof(ip6_addr_t));
345   (void)nat64_entry_to6(nate, &(cli_info->ip6addr));
346   cli_info->is_sync = nate->nat64_sync;
347 
348   return ERR_OK;
349 }
350 
351 err_t
lwip_nat64_clients_mac_get(struct mesh_clients_mac_info * clis_info)352 lwip_nat64_clients_mac_get(struct mesh_clients_mac_info *clis_info)
353 {
354   return netifapi_call_argcb(nat64_clients_mac_get, (void *)clis_info);
355 }
356 
357 err_t
lwip_nat64_client_address_find(struct mesh_client_address * cli_address)358 lwip_nat64_client_address_find(struct mesh_client_address *cli_address)
359 {
360   return netifapi_call_argcb(nat64_client_address_find, (void *)cli_address);
361 }
362 #endif
363 
364