]>
Commit | Line | Data |
---|---|---|
7ef5fefc CF |
1 | /* |
2 | * IS-IS TLV Serializer/Deserializer | |
3 | * | |
4 | * Copyright (C) 2015,2017 Christian Franke | |
5 | * | |
6 | * This file is part of FRR. | |
7 | * | |
8 | * FRR is free software; you can redistribute it and/or modify it | |
9 | * under the terms of the GNU General Public License as published by the | |
10 | * Free Software Foundation; either version 2, or (at your option) any | |
11 | * later version. | |
12 | * | |
13 | * FRR is distributed in the hope that it will be useful, but | |
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 | * General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with FRR; see the file COPYING. If not, write to the Free | |
20 | * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | |
21 | * 02111-1307, USA. | |
22 | */ | |
841791b6 CF |
23 | #ifndef ISIS_TLVS_H |
24 | #define ISIS_TLVS_H | |
7ef5fefc CF |
25 | |
26 | #include "openbsd-tree.h" | |
27 | #include "prefix.h" | |
7ef5fefc | 28 | |
4bef0ec4 | 29 | struct lspdb_head; |
7ef5fefc CF |
30 | struct isis_subtlvs; |
31 | ||
32 | struct isis_area_address; | |
33 | struct isis_area_address { | |
34 | struct isis_area_address *next; | |
35 | ||
36 | uint8_t addr[20]; | |
37 | uint8_t len; | |
38 | }; | |
39 | ||
40 | struct isis_oldstyle_reach; | |
41 | struct isis_oldstyle_reach { | |
42 | struct isis_oldstyle_reach *next; | |
43 | ||
44 | uint8_t id[7]; | |
45 | uint8_t metric; | |
46 | }; | |
47 | ||
48 | struct isis_oldstyle_ip_reach; | |
49 | struct isis_oldstyle_ip_reach { | |
50 | struct isis_oldstyle_ip_reach *next; | |
51 | ||
52 | uint8_t metric; | |
53 | struct prefix_ipv4 prefix; | |
54 | }; | |
55 | ||
56 | struct isis_lsp_entry; | |
57 | struct isis_lsp_entry { | |
58 | struct isis_lsp_entry *next; | |
59 | ||
60 | uint16_t rem_lifetime; | |
61 | uint8_t id[8]; | |
62 | uint16_t checksum; | |
63 | uint32_t seqno; | |
64 | ||
65 | struct isis_lsp *lsp; | |
66 | }; | |
67 | ||
68 | struct isis_extended_reach; | |
69 | struct isis_extended_reach { | |
70 | struct isis_extended_reach *next; | |
71 | ||
72 | uint8_t id[7]; | |
73 | uint32_t metric; | |
74 | ||
75 | uint8_t *subtlvs; | |
76 | uint8_t subtlv_len; | |
77 | }; | |
78 | ||
79 | struct isis_extended_ip_reach; | |
80 | struct isis_extended_ip_reach { | |
81 | struct isis_extended_ip_reach *next; | |
82 | ||
83 | uint32_t metric; | |
84 | bool down; | |
85 | struct prefix_ipv4 prefix; | |
bd507085 CF |
86 | |
87 | struct isis_subtlvs *subtlvs; | |
7ef5fefc CF |
88 | }; |
89 | ||
90 | struct isis_ipv6_reach; | |
91 | struct isis_ipv6_reach { | |
92 | struct isis_ipv6_reach *next; | |
93 | ||
94 | uint32_t metric; | |
95 | bool down; | |
96 | bool external; | |
97 | ||
98 | struct prefix_ipv6 prefix; | |
99 | ||
100 | struct isis_subtlvs *subtlvs; | |
101 | }; | |
102 | ||
103 | struct isis_protocols_supported { | |
104 | uint8_t count; | |
105 | uint8_t *protocols; | |
106 | }; | |
107 | ||
41a145f1 CF |
108 | #define ISIS_TIER_UNDEFINED 15 |
109 | ||
110 | struct isis_spine_leaf { | |
111 | uint8_t tier; | |
112 | ||
113 | bool has_tier; | |
114 | bool is_leaf; | |
115 | bool is_spine; | |
116 | bool is_backup; | |
117 | }; | |
118 | ||
9fe21208 CF |
119 | enum isis_threeway_state { |
120 | ISIS_THREEWAY_DOWN = 2, | |
121 | ISIS_THREEWAY_INITIALIZING = 1, | |
122 | ISIS_THREEWAY_UP = 0 | |
123 | }; | |
124 | ||
125 | struct isis_threeway_adj { | |
126 | enum isis_threeway_state state; | |
127 | uint32_t local_circuit_id; | |
128 | bool neighbor_set; | |
129 | uint8_t neighbor_id[6]; | |
130 | uint32_t neighbor_circuit_id; | |
131 | }; | |
132 | ||
7ef5fefc CF |
133 | struct isis_item; |
134 | struct isis_item { | |
135 | struct isis_item *next; | |
136 | }; | |
137 | ||
138 | struct isis_lan_neighbor; | |
139 | struct isis_lan_neighbor { | |
140 | struct isis_lan_neighbor *next; | |
141 | ||
142 | uint8_t mac[6]; | |
143 | }; | |
144 | ||
145 | struct isis_ipv4_address; | |
146 | struct isis_ipv4_address { | |
147 | struct isis_ipv4_address *next; | |
148 | ||
149 | struct in_addr addr; | |
150 | }; | |
151 | ||
152 | struct isis_ipv6_address; | |
153 | struct isis_ipv6_address { | |
154 | struct isis_ipv6_address *next; | |
155 | ||
156 | struct in6_addr addr; | |
157 | }; | |
158 | ||
159 | struct isis_mt_router_info; | |
160 | struct isis_mt_router_info { | |
161 | struct isis_mt_router_info *next; | |
162 | ||
163 | bool overload; | |
164 | bool attached; | |
165 | uint16_t mtid; | |
166 | }; | |
167 | ||
168 | struct isis_auth; | |
169 | struct isis_auth { | |
170 | struct isis_auth *next; | |
171 | ||
172 | uint8_t type; | |
173 | uint8_t length; | |
174 | uint8_t value[256]; | |
175 | ||
176 | uint8_t plength; | |
177 | uint8_t passwd[256]; | |
178 | ||
179 | size_t offset; /* Only valid after packing */ | |
180 | }; | |
181 | ||
182 | struct isis_item_list; | |
183 | struct isis_item_list { | |
184 | struct isis_item *head; | |
185 | struct isis_item **tail; | |
186 | ||
187 | RB_ENTRY(isis_item_list) mt_tree; | |
188 | uint16_t mtid; | |
189 | unsigned int count; | |
190 | }; | |
191 | ||
5f77d901 CF |
192 | struct isis_purge_originator { |
193 | bool sender_set; | |
194 | ||
195 | uint8_t generator[6]; | |
196 | uint8_t sender[6]; | |
197 | }; | |
198 | ||
3380c990 EDP |
199 | enum isis_auth_result { |
200 | ISIS_AUTH_OK = 0, | |
201 | ISIS_AUTH_TYPE_FAILURE, | |
202 | ISIS_AUTH_FAILURE, | |
203 | ISIS_AUTH_NO_VALIDATOR, | |
204 | }; | |
205 | ||
7ef5fefc CF |
206 | RB_HEAD(isis_mt_item_list, isis_item_list); |
207 | ||
208 | struct isis_item_list *isis_get_mt_items(struct isis_mt_item_list *m, | |
209 | uint16_t mtid); | |
210 | struct isis_item_list *isis_lookup_mt_items(struct isis_mt_item_list *m, | |
211 | uint16_t mtid); | |
212 | ||
213 | struct isis_tlvs { | |
214 | struct isis_item_list isis_auth; | |
5f77d901 | 215 | struct isis_purge_originator *purge_originator; |
7ef5fefc CF |
216 | struct isis_item_list area_addresses; |
217 | struct isis_item_list oldstyle_reach; | |
218 | struct isis_item_list lan_neighbor; | |
219 | struct isis_item_list lsp_entries; | |
220 | struct isis_item_list extended_reach; | |
221 | struct isis_mt_item_list mt_reach; | |
222 | struct isis_item_list oldstyle_ip_reach; | |
223 | struct isis_protocols_supported protocols_supported; | |
224 | struct isis_item_list oldstyle_ip_reach_ext; | |
225 | struct isis_item_list ipv4_address; | |
226 | struct isis_item_list ipv6_address; | |
227 | struct isis_item_list mt_router_info; | |
228 | bool mt_router_info_empty; | |
229 | struct in_addr *te_router_id; | |
230 | struct isis_item_list extended_ip_reach; | |
231 | struct isis_mt_item_list mt_ip_reach; | |
232 | char *hostname; | |
233 | struct isis_item_list ipv6_reach; | |
234 | struct isis_mt_item_list mt_ipv6_reach; | |
9fe21208 | 235 | struct isis_threeway_adj *threeway_adj; |
41a145f1 | 236 | struct isis_spine_leaf *spine_leaf; |
7ef5fefc CF |
237 | }; |
238 | ||
bd507085 CF |
239 | #define ISIS_PREFIX_SID_READVERTISED 0x80 |
240 | #define ISIS_PREFIX_SID_NODE 0x40 | |
241 | #define ISIS_PREFIX_SID_NO_PHP 0x20 | |
242 | #define ISIS_PREFIX_SID_EXPLICIT_NULL 0x10 | |
243 | #define ISIS_PREFIX_SID_VALUE 0x08 | |
244 | #define ISIS_PREFIX_SID_LOCAL 0x04 | |
245 | ||
246 | struct isis_prefix_sid; | |
247 | struct isis_prefix_sid { | |
248 | struct isis_prefix_sid *next; | |
249 | ||
250 | uint8_t flags; | |
251 | uint8_t algorithm; | |
252 | ||
253 | uint32_t value; | |
7ef5fefc CF |
254 | }; |
255 | ||
256 | enum isis_tlv_context { | |
257 | ISIS_CONTEXT_LSP, | |
258 | ISIS_CONTEXT_SUBTLV_NE_REACH, | |
259 | ISIS_CONTEXT_SUBTLV_IP_REACH, | |
260 | ISIS_CONTEXT_SUBTLV_IPV6_REACH, | |
261 | ISIS_CONTEXT_MAX | |
262 | }; | |
263 | ||
bd507085 CF |
264 | struct isis_subtlvs { |
265 | enum isis_tlv_context context; | |
266 | ||
267 | /* draft-baker-ipv6-isis-dst-src-routing-06 */ | |
268 | struct prefix_ipv6 *source_prefix; | |
269 | /* draft-ietf-isis-segment-routing-extensions-16 */ | |
270 | struct isis_item_list prefix_sids; | |
271 | }; | |
272 | ||
7ef5fefc CF |
273 | enum isis_tlv_type { |
274 | ISIS_TLV_AREA_ADDRESSES = 1, | |
275 | ISIS_TLV_OLDSTYLE_REACH = 2, | |
276 | ISIS_TLV_LAN_NEIGHBORS = 6, | |
277 | ISIS_TLV_PADDING = 8, | |
278 | ISIS_TLV_LSP_ENTRY = 9, | |
279 | ISIS_TLV_AUTH = 10, | |
5f77d901 | 280 | ISIS_TLV_PURGE_ORIGINATOR = 13, |
7ef5fefc CF |
281 | ISIS_TLV_EXTENDED_REACH = 22, |
282 | ||
283 | ISIS_TLV_OLDSTYLE_IP_REACH = 128, | |
284 | ISIS_TLV_PROTOCOLS_SUPPORTED = 129, | |
285 | ISIS_TLV_OLDSTYLE_IP_REACH_EXT = 130, | |
286 | ISIS_TLV_IPV4_ADDRESS = 132, | |
287 | ISIS_TLV_TE_ROUTER_ID = 134, | |
288 | ISIS_TLV_EXTENDED_IP_REACH = 135, | |
289 | ISIS_TLV_DYNAMIC_HOSTNAME = 137, | |
41a145f1 | 290 | ISIS_TLV_SPINE_LEAF_EXT = 150, |
7ef5fefc CF |
291 | ISIS_TLV_MT_REACH = 222, |
292 | ISIS_TLV_MT_ROUTER_INFO = 229, | |
293 | ISIS_TLV_IPV6_ADDRESS = 232, | |
294 | ISIS_TLV_MT_IP_REACH = 235, | |
295 | ISIS_TLV_IPV6_REACH = 236, | |
296 | ISIS_TLV_MT_IPV6_REACH = 237, | |
9fe21208 | 297 | ISIS_TLV_THREE_WAY_ADJ = 240, |
7ef5fefc CF |
298 | ISIS_TLV_MAX = 256, |
299 | ||
bd507085 | 300 | ISIS_SUBTLV_PREFIX_SID = 3, |
7ef5fefc CF |
301 | ISIS_SUBTLV_IPV6_SOURCE_PREFIX = 22 |
302 | }; | |
303 | ||
304 | #define IS_COMPAT_MT_TLV(tlv_type) \ | |
305 | ((tlv_type == ISIS_TLV_MT_REACH) || (tlv_type == ISIS_TLV_MT_IP_REACH) \ | |
306 | || (tlv_type == ISIS_TLV_MT_IPV6_REACH)) | |
307 | ||
308 | struct stream; | |
309 | int isis_pack_tlvs(struct isis_tlvs *tlvs, struct stream *stream, | |
310 | size_t len_pointer, bool pad, bool is_lsp); | |
311 | void isis_free_tlvs(struct isis_tlvs *tlvs); | |
312 | struct isis_tlvs *isis_alloc_tlvs(void); | |
313 | int isis_unpack_tlvs(size_t avail_len, struct stream *stream, | |
314 | struct isis_tlvs **dest, const char **error_log); | |
315 | const char *isis_format_tlvs(struct isis_tlvs *tlvs); | |
316 | struct isis_tlvs *isis_copy_tlvs(struct isis_tlvs *tlvs); | |
317 | struct list *isis_fragment_tlvs(struct isis_tlvs *tlvs, size_t size); | |
318 | ||
319 | #define ISIS_EXTENDED_IP_REACH_DOWN 0x80 | |
320 | #define ISIS_EXTENDED_IP_REACH_SUBTLV 0x40 | |
321 | ||
322 | #define ISIS_IPV6_REACH_DOWN 0x80 | |
323 | #define ISIS_IPV6_REACH_EXTERNAL 0x40 | |
324 | #define ISIS_IPV6_REACH_SUBTLV 0x20 | |
325 | ||
326 | #ifndef ISIS_MT_MASK | |
327 | #define ISIS_MT_MASK 0x0fff | |
328 | #define ISIS_MT_OL_MASK 0x8000 | |
329 | #define ISIS_MT_AT_MASK 0x4000 | |
330 | #endif | |
331 | ||
332 | ||
333 | void isis_tlvs_add_auth(struct isis_tlvs *tlvs, struct isis_passwd *passwd); | |
334 | void isis_tlvs_add_area_addresses(struct isis_tlvs *tlvs, | |
335 | struct list *addresses); | |
336 | void isis_tlvs_add_lan_neighbors(struct isis_tlvs *tlvs, | |
337 | struct list *neighbors); | |
338 | void isis_tlvs_set_protocols_supported(struct isis_tlvs *tlvs, | |
339 | struct nlpids *nlpids); | |
340 | void isis_tlvs_add_mt_router_info(struct isis_tlvs *tlvs, uint16_t mtid, | |
341 | bool overload, bool attached); | |
342 | void isis_tlvs_add_ipv4_address(struct isis_tlvs *tlvs, struct in_addr *addr); | |
343 | void isis_tlvs_add_ipv4_addresses(struct isis_tlvs *tlvs, | |
344 | struct list *addresses); | |
345 | void isis_tlvs_add_ipv6_addresses(struct isis_tlvs *tlvs, | |
346 | struct list *addresses); | |
3380c990 EDP |
347 | int isis_tlvs_auth_is_valid(struct isis_tlvs *tlvs, struct isis_passwd *passwd, |
348 | struct stream *stream, bool is_lsp); | |
7ef5fefc CF |
349 | bool isis_tlvs_area_addresses_match(struct isis_tlvs *tlvs, |
350 | struct list *addresses); | |
351 | struct isis_adjacency; | |
352 | void isis_tlvs_to_adj(struct isis_tlvs *tlvs, struct isis_adjacency *adj, | |
353 | bool *changed); | |
354 | bool isis_tlvs_own_snpa_found(struct isis_tlvs *tlvs, uint8_t *snpa); | |
355 | void isis_tlvs_add_lsp_entry(struct isis_tlvs *tlvs, struct isis_lsp *lsp); | |
356 | void isis_tlvs_add_csnp_entries(struct isis_tlvs *tlvs, uint8_t *start_id, | |
357 | uint8_t *stop_id, uint16_t num_lsps, | |
4bef0ec4 DL |
358 | struct lspdb_head *lspdb, |
359 | struct isis_lsp **last_lsp); | |
7ef5fefc CF |
360 | void isis_tlvs_set_dynamic_hostname(struct isis_tlvs *tlvs, |
361 | const char *hostname); | |
362 | void isis_tlvs_set_te_router_id(struct isis_tlvs *tlvs, | |
363 | const struct in_addr *id); | |
364 | void isis_tlvs_add_oldstyle_ip_reach(struct isis_tlvs *tlvs, | |
365 | struct prefix_ipv4 *dest, uint8_t metric); | |
366 | void isis_tlvs_add_extended_ip_reach(struct isis_tlvs *tlvs, | |
367 | struct prefix_ipv4 *dest, uint32_t metric); | |
368 | void isis_tlvs_add_ipv6_reach(struct isis_tlvs *tlvs, uint16_t mtid, | |
369 | struct prefix_ipv6 *dest, uint32_t metric); | |
d43d2df5 CF |
370 | void isis_tlvs_add_ipv6_dstsrc_reach(struct isis_tlvs *tlvs, uint16_t mtid, |
371 | struct prefix_ipv6 *dest, | |
372 | struct prefix_ipv6 *src, | |
373 | uint32_t metric); | |
7ef5fefc CF |
374 | void isis_tlvs_add_oldstyle_reach(struct isis_tlvs *tlvs, uint8_t *id, |
375 | uint8_t metric); | |
376 | void isis_tlvs_add_extended_reach(struct isis_tlvs *tlvs, uint16_t mtid, | |
377 | uint8_t *id, uint32_t metric, | |
378 | uint8_t *subtlvs, uint8_t subtlv_len); | |
379 | ||
9fe21208 CF |
380 | const char *isis_threeway_state_name(enum isis_threeway_state state); |
381 | ||
382 | void isis_tlvs_add_threeway_adj(struct isis_tlvs *tlvs, | |
383 | enum isis_threeway_state state, | |
384 | uint32_t local_circuit_id, | |
385 | const uint8_t *neighbor_id, | |
386 | uint32_t neighbor_circuit_id); | |
387 | ||
41a145f1 CF |
388 | void isis_tlvs_add_spine_leaf(struct isis_tlvs *tlvs, uint8_t tier, |
389 | bool has_tier, bool is_leaf, bool is_spine, | |
390 | bool is_backup); | |
391 | ||
7ef5fefc CF |
392 | struct isis_mt_router_info * |
393 | isis_tlvs_lookup_mt_router_info(struct isis_tlvs *tlvs, uint16_t mtid); | |
2c92bee4 CF |
394 | |
395 | void isis_tlvs_set_purge_originator(struct isis_tlvs *tlvs, | |
396 | const uint8_t *generator, | |
397 | const uint8_t *sender); | |
7ef5fefc | 398 | #endif |