]> git.proxmox.com Git - mirror_frr.git/blame - isisd/isis_tlv.c
isisd: add support to import routes from other protocols
[mirror_frr.git] / isisd / isis_tlv.c
Content-type: text/html ]> git.proxmox.com Git - mirror_frr.git/blame - isisd/isis_tlv.c


500 - Internal Server Error

Malformed UTF-8 character (fatal) at (eval 6) line 1, <$fd> line 735.
CommitLineData
eb5d44eb 1/*
2 * IS-IS Rout(e)ing protocol - isis_tlv.c
3 * IS-IS TLV related routines
4 *
5 * Copyright (C) 2001,2002 Sampo Saaristo
6 * Tampere University of Technology
7 * Institute of Communications Engineering
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public Licenseas published by the Free
11 * Software Foundation; either version 2 of the License, or (at your option)
12 * any later version.
13 *
14 * This program is distributed in the hope that it will be useful,but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * more details.
18
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24#include <zebra.h>
eb5d44eb 25
26#include "log.h"
27#include "linklist.h"
28#include "stream.h"
29#include "memory.h"
30#include "prefix.h"
31#include "vty.h"
32#include "if.h"
33
34#include "isisd/dict.h"
35#include "isisd/isis_constants.h"
36#include "isisd/isis_common.h"
37#include "isisd/isis_flags.h"
38#include "isisd/isis_circuit.h"
39#include "isisd/isis_tlv.h"
40#include "isisd/isisd.h"
41#include "isisd/isis_dynhn.h"
42#include "isisd/isis_misc.h"
43#include "isisd/isis_pdu.h"
44#include "isisd/isis_lsp.h"
45
eb5d44eb 46void
47free_tlv (void *val)
48{
f390d2c7 49 XFREE (MTYPE_ISIS_TLV, val);
50
51 return;
eb5d44eb 52}
53
54/*
55 * Called after parsing of a PDU. There shouldn't be any tlv's left, so this
56 * is only a caution to avoid memory leaks
57 */
f390d2c7 58void
eb5d44eb 59free_tlvs (struct tlvs *tlvs)
60{
f390d2c7 61 if (tlvs->area_addrs)
aac372f4 62 list_delete (tlvs->area_addrs);
f390d2c7 63 if (tlvs->is_neighs)
aac372f4 64 list_delete (tlvs->is_neighs);
f390d2c7 65 if (tlvs->te_is_neighs)
aac372f4 66 list_delete (tlvs->te_is_neighs);
f390d2c7 67 if (tlvs->es_neighs)
aac372f4 68 list_delete (tlvs->es_neighs);
f390d2c7 69 if (tlvs->lsp_entries)
aac372f4 70 list_delete (tlvs->lsp_entries);
f390d2c7 71 if (tlvs->prefix_neighs)
aac372f4 72 list_delete (tlvs->prefix_neighs);
3f045a08
JB
73 if (tlvs->lan_neighs)
74 list_delete (tlvs->lan_neighs);
f390d2c7 75 if (tlvs->ipv4_addrs)
aac372f4 76 list_delete (tlvs->ipv4_addrs);
f390d2c7 77 if (tlvs->ipv4_int_reachs)
aac372f4 78 list_delete (tlvs->ipv4_int_reachs);
f390d2c7 79 if (tlvs->ipv4_ext_reachs)
aac372f4 80 list_delete (tlvs->ipv4_ext_reachs);
f390d2c7 81 if (tlvs->te_ipv4_reachs)
aac372f4 82 list_delete (tlvs->te_ipv4_reachs);
eb5d44eb 83#ifdef HAVE_IPV6
f390d2c7 84 if (tlvs->ipv6_addrs)
aac372f4 85 list_delete (tlvs->ipv6_addrs);
f390d2c7 86 if (tlvs->ipv6_reachs)
aac372f4 87 list_delete (tlvs->ipv6_reachs);
eb5d44eb 88#endif /* HAVE_IPV6 */
3f045a08
JB
89
90 memset (tlvs, 0, sizeof (struct tlvs));
91
eb5d44eb 92 return;
93}
94
95/*
96 * Parses the tlvs found in the variant length part of the PDU.
97 * Caller tells with flags in "expected" which TLV's it is interested in.
98 */
f390d2c7 99int
100parse_tlvs (char *areatag, u_char * stream, int size, u_int32_t * expected,
3f045a08 101 u_int32_t * found, struct tlvs *tlvs, u_int32_t *auth_tlv_offset)
eb5d44eb 102{
f390d2c7 103 u_char type, length;
104 struct lan_neigh *lan_nei;
105 struct area_addr *area_addr;
106 struct is_neigh *is_nei;
107 struct te_is_neigh *te_is_nei;
108 struct es_neigh *es_nei;
109 struct lsp_entry *lsp_entry;
110 struct in_addr *ipv4_addr;
111 struct ipv4_reachability *ipv4_reach;
112 struct te_ipv4_reachability *te_ipv4_reach;
eb5d44eb 113#ifdef HAVE_IPV6
f390d2c7 114 struct in6_addr *ipv6_addr;
115 struct ipv6_reachability *ipv6_reach;
116 int prefix_octets;
eb5d44eb 117#endif /* HAVE_IPV6 */
f390d2c7 118 int value_len, retval = ISIS_OK;
f02a0992 119 u_char *start = stream, *pnt = stream, *endpnt;
eb5d44eb 120
121 *found = 0;
122 memset (tlvs, 0, sizeof (struct tlvs));
f390d2c7 123
124 while (pnt < stream + size - 2)
125 {
126 type = *pnt;
127 length = *(pnt + 1);
128 pnt += 2;
129 value_len = 0;
130 if (pnt + length > stream + size)
131 {
132 zlog_warn ("ISIS-TLV (%s): TLV (type %d, length %d) exceeds packet "
133 "boundaries", areatag, type, length);
134 retval = ISIS_WARNING;
135 break;
136 }
137 switch (type)
138 {
139 case AREA_ADDRESSES:
140 /* +-------+-------+-------+-------+-------+-------+-------+-------+
141 * | Address Length |
142 * +-------+-------+-------+-------+-------+-------+-------+-------+
143 * | Area Address |
144 * +-------+-------+-------+-------+-------+-------+-------+-------+
145 * : :
146 */
147 *found |= TLVFLAG_AREA_ADDRS;
eb5d44eb 148#ifdef EXTREME_TLV_DEBUG
529d65b3 149 zlog_debug ("TLV Area Adresses len %d", length);
eb5d44eb 150#endif /* EXTREME_TLV_DEBUG */
f390d2c7 151 if (*expected & TLVFLAG_AREA_ADDRS)
152 {
153 while (length > value_len)
154 {
155 area_addr = (struct area_addr *) pnt;
156 value_len += area_addr->addr_len + 1;
157 pnt += area_addr->addr_len + 1;
158 if (!tlvs->area_addrs)
159 tlvs->area_addrs = list_new ();
160 listnode_add (tlvs->area_addrs, area_addr);
161 }
162 }
163 else
164 {
165 pnt += length;
166 }
167 break;
168
169 case IS_NEIGHBOURS:
170 *found |= TLVFLAG_IS_NEIGHS;
eb5d44eb 171#ifdef EXTREME_TLV_DEBUG
529d65b3 172 zlog_debug ("ISIS-TLV (%s): IS Neighbours length %d",
173 areatag, length);
eb5d44eb 174#endif /* EXTREME_TLV_DEBUG */
f390d2c7 175 if (TLVFLAG_IS_NEIGHS & *expected)
176 {
177 /* +-------+-------+-------+-------+-------+-------+-------+-------+
178 * | Virtual Flag |
179 * +-------+-------+-------+-------+-------+-------+-------+-------+
180 */
f390d2c7 181 pnt++;
182 value_len++;
183 /* +-------+-------+-------+-------+-------+-------+-------+-------+
184 * | 0 | I/E | Default Metric |
185 * +-------+-------+-------+-------+-------+-------+-------+-------+
186 * | S | I/E | Delay Metric |
187 * +-------+-------+-------+-------+-------+-------+-------+-------+
188 * | S | I/E | Expense Metric |
189 * +-------+-------+-------+-------+-------+-------+-------+-------+
190 * | S | I/E | Error Metric |
191 * +-------+-------+-------+-------+-------+-------+-------+-------+
192 * | Neighbour ID |
193 * +---------------------------------------------------------------+
194 * : :
195 */
196 while (length > value_len)
197 {
198 is_nei = (struct is_neigh *) pnt;
199 value_len += 4 + ISIS_SYS_ID_LEN + 1;
200 pnt += 4 + ISIS_SYS_ID_LEN + 1;
201 if (!tlvs->is_neighs)
202 tlvs->is_neighs = list_new ();
203 listnode_add (tlvs->is_neighs, is_nei);
204 }
205 }
206 else
207 {
208 pnt += length;
209 }
210 break;
211
212 case TE_IS_NEIGHBOURS:
213 /* +-------+-------+-------+-------+-------+-------+-------+-------+
214 * | Neighbour ID | 7
215 * +---------------------------------------------------------------+
216 * | TE Metric | 3
217 * +---------------------------------------------------------------+
218 * | SubTLVs Length | 1
219 * +---------------------------------------------------------------+
220 * : :
221 */
222 *found |= TLVFLAG_TE_IS_NEIGHS;
eb5d44eb 223#ifdef EXTREME_TLV_DEBUG
529d65b3 224 zlog_debug ("ISIS-TLV (%s): Extended IS Neighbours length %d",
f390d2c7 225 areatag, length);
eb5d44eb 226#endif /* EXTREME_TLV_DEBUG */
f390d2c7 227 if (TLVFLAG_TE_IS_NEIGHS & *expected)
228 {
229 while (length > value_len)
230 {
231 te_is_nei = (struct te_is_neigh *) pnt;
232 value_len += 11;
233 pnt += 11;
234 /* FIXME - subtlvs are handled here, for now we skip */
235 value_len += te_is_nei->sub_tlvs_length;
236 pnt += te_is_nei->sub_tlvs_length;
237
238 if (!tlvs->te_is_neighs)
239 tlvs->te_is_neighs = list_new ();
240 listnode_add (tlvs->te_is_neighs, te_is_nei);
241 }
242 }
243 else
244 {
245 pnt += length;
246 }
247 break;
248
249 case ES_NEIGHBOURS:
250 /* +-------+-------+-------+-------+-------+-------+-------+-------+
251 * | 0 | I/E | Default Metric |
252 * +-------+-------+-------+-------+-------+-------+-------+-------+
253 * | S | I/E | Delay Metric |
254 * +-------+-------+-------+-------+-------+-------+-------+-------+
255 * | S | I/E | Expense Metric |
256 * +-------+-------+-------+-------+-------+-------+-------+-------+
257 * | S | I/E | Error Metric |
258 * +-------+-------+-------+-------+-------+-------+-------+-------+
259 * | Neighbour ID |
260 * +---------------------------------------------------------------+
261 * | Neighbour ID |
262 * +---------------------------------------------------------------+
263 * : :
264 */
eb5d44eb 265#ifdef EXTREME_TLV_DEBUG
529d65b3 266 zlog_debug ("ISIS-TLV (%s): ES Neighbours length %d",
f390d2c7 267 areatag, length);
eb5d44eb 268#endif /* EXTREME_TLV_DEBUG */
f390d2c7 269 *found |= TLVFLAG_ES_NEIGHS;
270 if (*expected & TLVFLAG_ES_NEIGHS)
271 {
272 es_nei = (struct es_neigh *) pnt;
273 value_len += 4;
274 pnt += 4;
275 while (length > value_len)
276 {
277 /* FIXME FIXME FIXME - add to the list */
278 /* sys_id->id = pnt; */
279 value_len += ISIS_SYS_ID_LEN;
280 pnt += ISIS_SYS_ID_LEN;
281 /* if (!es_nei->neigh_ids) es_nei->neigh_ids = sysid; */
282 }
283 if (!tlvs->es_neighs)
284 tlvs->es_neighs = list_new ();
285 listnode_add (tlvs->es_neighs, es_nei);
286 }
287 else
288 {
289 pnt += length;
290 }
291 break;
292
293 case LAN_NEIGHBOURS:
294 /* +-------+-------+-------+-------+-------+-------+-------+-------+
295 * | LAN Address |
296 * +-------+-------+-------+-------+-------+-------+-------+-------+
297 * : :
298 */
299 *found |= TLVFLAG_LAN_NEIGHS;
eb5d44eb 300#ifdef EXTREME_TLV_DEBUG
529d65b3 301 zlog_debug ("ISIS-TLV (%s): LAN Neigbours length %d",
302 areatag, length);
eb5d44eb 303#endif /* EXTREME_TLV_DEBUG */
f390d2c7 304 if (TLVFLAG_LAN_NEIGHS & *expected)
305 {
306 while (length > value_len)
307 {
308 lan_nei = (struct lan_neigh *) pnt;
309 if (!tlvs->lan_neighs)
310 tlvs->lan_neighs = list_new ();
311 listnode_add (tlvs->lan_neighs, lan_nei);
312 value_len += ETH_ALEN;
313 pnt += ETH_ALEN;
314 }
315 }
316 else
317 {
318 pnt += length;
319 }
320 break;
321
322 case PADDING:
eb5d44eb 323#ifdef EXTREME_TLV_DEBUG
529d65b3 324 zlog_debug ("TLV padding %d", length);
eb5d44eb 325#endif /* EXTREME_TLV_DEBUG */
f390d2c7 326 pnt += length;
327 break;
328
329 case LSP_ENTRIES:
330 /* +-------+-------+-------+-------+-------+-------+-------+-------+
331 * | Remaining Lifetime | 2
332 * +-------+-------+-------+-------+-------+-------+-------+-------+
333 * | LSP ID | id+2
334 * +-------+-------+-------+-------+-------+-------+-------+-------+
335