source: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/addons/ipv6_static_routing/ip6_route_table.c@ 457

Last change on this file since 457 was 457, checked in by coas-nagasima, 4 years ago

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 7.6 KB
Line 
1/**
2 * @file
3 * IPv6 static route table.
4 */
5
6/*
7 * Copyright (c) 2015 Nest Labs, Inc.
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without modification,
11 * are permitted provided that the following conditions are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright notice,
14 * this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 * 3. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
22 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
24 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
26 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
29 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
30 * OF SUCH DAMAGE.
31 *
32 * Author: Pradip De <pradipd@google.com>
33 *
34 *
35 * Please coordinate changes and requests with Pradip De
36 * <pradipd@google.com>
37 */
38
39#include "lwip/opt.h"
40
41#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */
42
43#include "ip6_route_table.h"
44#include "lwip/def.h"
45#include "lwip/mem.h"
46#include "lwip/netif.h"
47#include "lwip/ip6.h"
48#include "lwip/ip6_addr.h"
49#include "lwip/nd6.h"
50#include "lwip/debug.h"
51#include "lwip/stats.h"
52
53#include "string.h"
54
55static struct ip6_route_entry static_route_table[LWIP_IPV6_NUM_ROUTE_ENTRIES];
56
57/**
58 * Add the ip6 prefix route and target netif into the static route table while
59 * keeping all entries sorted in decreasing order of prefix length.
60 * 1. Search from the last entry up to find the correct slot to insert while
61 * moving entries one position down to create room.
62 * 2. Insert into empty slot created.
63 *
64 * Subsequently, a linear search down the list can be performed to retrieve a
65 * matching route entry for a Longest Prefix Match.
66 *
67 * @param ip6_prefix the route prefix entry to add.
68 * @param netif pointer to target netif.
69 * @param gateway the gateway address to use to send through. Has to be link local.
70 * @param idx return value argument of index where route entry was added in table.
71 * @return ERR_OK if addition was successful.
72 * ERR_MEM if table is already full.
73 * ERR_ARG if passed argument is bad or route already exists in table.
74 */
75err_t
76ip6_add_route_entry(const struct ip6_prefix *ip6_prefix, struct netif *netif, const ip6_addr_t *gateway, s8_t *idx)
77{
78 s8_t i = -1;
79 err_t retval = ERR_OK;
80
81 if (!ip6_prefix_valid(ip6_prefix->prefix_len) || (netif == NULL)) {
82 retval = ERR_ARG;
83 goto exit;
84 }
85
86 /* Check if an entry already exists with matching prefix; If so, replace it. */
87 for (i = 0; i < LWIP_IPV6_NUM_ROUTE_ENTRIES; i++) {
88 if ((ip6_prefix->prefix_len == static_route_table[i].prefix.prefix_len) &&
89 memcmp(&ip6_prefix->addr, &static_route_table[i].prefix.addr,
90 ip6_prefix->prefix_len / 8) == 0) {
91 /* Prefix matches; replace the netif with the one being added. */
92 goto insert;
93 }
94 }
95
96 /* Check if the table is full */
97 if (static_route_table[LWIP_IPV6_NUM_ROUTE_ENTRIES - 1].netif != NULL) {
98 retval = ERR_MEM;
99 goto exit;
100 }
101
102 /* Shift all entries down the table until slot is found */
103 for (i = LWIP_IPV6_NUM_ROUTE_ENTRIES - 1;
104 i > 0 && (ip6_prefix->prefix_len > static_route_table[i - 1].prefix.prefix_len); i--) {
105 SMEMCPY(&static_route_table[i], &static_route_table[i - 1], sizeof(struct ip6_route_entry));
106 }
107
108insert:
109 /* Insert into the slot selected */
110 SMEMCPY(&static_route_table[i].prefix, ip6_prefix, sizeof(struct ip6_prefix));
111 static_route_table[i].netif = netif;
112
113 /* Add gateway to route table */
114 static_route_table[i].gateway = gateway;
115
116 if (idx != NULL) {
117 *idx = i;
118 }
119
120exit:
121 return retval;
122}
123
124/**
125 * Removes the route entry from the static route table.
126 *
127 * @param ip6_prefix the route prefix entry to delete.
128 */
129void
130ip6_remove_route_entry(const struct ip6_prefix *ip6_prefix)
131{
132 int i, pos = -1;
133
134 for (i = 0; i < LWIP_IPV6_NUM_ROUTE_ENTRIES; i++) {
135 /* compare prefix to find position to delete */
136 if (ip6_prefix->prefix_len == static_route_table[i].prefix.prefix_len &&
137 memcmp(&ip6_prefix->addr, &static_route_table[i].prefix.addr,
138 ip6_prefix->prefix_len / 8) == 0) {
139 pos = i;
140 break;
141 }
142 }
143
144 if (pos >= 0) {
145 /* Shift everything beyond pos one slot up */
146 for (i = pos; i < LWIP_IPV6_NUM_ROUTE_ENTRIES - 1; i++) {
147 SMEMCPY(&static_route_table[i], &static_route_table[i+1], sizeof(struct ip6_route_entry));
148 if (static_route_table[i].netif == NULL) {
149 break;
150 }
151 }
152 /* Zero the remaining entries */
153 for (; i < LWIP_IPV6_NUM_ROUTE_ENTRIES; i++) {
154 ip6_addr_set_zero((&static_route_table[i].prefix.addr));
155 static_route_table[i].netif = NULL;
156 }
157 }
158}
159
160/**
161 * Finds the appropriate route entry in the static route table corresponding to the given
162 * destination IPv6 address. Since the entries in the route table are kept sorted in decreasing
163 * order of prefix length, a linear search down the list is performed to retrieve a matching
164 * index.
165 *
166 * @param ip6_dest_addr the destination address to match
167 * @return the idx of the found route entry; -1 if not found.
168 */
169s8_t
170ip6_find_route_entry(const ip6_addr_t *ip6_dest_addr)
171{
172 s8_t i, idx = -1;
173
174 /* Search prefix in the sorted(decreasing order of prefix length) list */
175 for(i = 0; i < LWIP_IPV6_NUM_ROUTE_ENTRIES; i++) {
176 if (memcmp(ip6_dest_addr, &static_route_table[i].prefix.addr,
177 static_route_table[i].prefix.prefix_len / 8) == 0) {
178 idx = i;
179 break;
180 }
181 }
182
183 return idx;
184}
185
186/**
187 * Finds the appropriate network interface for a given IPv6 address from a routing table with
188 * static IPv6 routes.
189 *
190 * @param src the source IPv6 address, if known
191 * @param dest the destination IPv6 address for which to find the route
192 * @return the netif on which to send to reach dest
193 */
194struct netif *
195ip6_static_route(const ip6_addr_t *src, const ip6_addr_t *dest)
196{
197 int i;
198
199 LWIP_UNUSED_ARG(src);
200
201 /* Perform table lookup */
202 i = ip6_find_route_entry(dest);
203
204 if (i >= 0) {
205 return static_route_table[i].netif;
206 } else {
207 return NULL;
208 }
209}
210
211/**
212 * Finds the gateway IP6 address for a given destination IPv6 address and target netif
213 * from a routing table with static IPv6 routes.
214 *
215 * @param netif the netif used for sending
216 * @param dest the destination IPv6 address
217 * @return the ip6 address of the gateway to forward packet to
218 */
219const ip6_addr_t *
220ip6_get_gateway(struct netif *netif, const ip6_addr_t *dest)
221{
222 const ip6_addr_t *ret_gw = NULL;
223 const int i = ip6_find_route_entry(dest);
224
225 LWIP_UNUSED_ARG(netif);
226
227 if (i >= 0) {
228 if (static_route_table[i].gateway != NULL) {
229 ret_gw = static_route_table[i].gateway;
230 }
231 }
232
233 return ret_gw;
234}
235
236/**
237 * Returns the top of the route table.
238 * This should be used for debug printing only.
239 *
240 * @return the top of the route table.
241 */
242const struct ip6_route_entry *
243ip6_get_route_table(void)
244{
245 return static_route_table;
246}
247
248#endif /* LWIP_IPV6 */
Note: See TracBrowser for help on using the repository browser.