Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0-or-later
2 : /*
3 : * Router ID for zebra daemon.
4 : *
5 : * Copyright (C) 2004 James R. Leu
6 : *
7 : * This file is part of Quagga routing suite.
8 : */
9 :
10 : #include <zebra.h>
11 :
12 : #include "if.h"
13 : #include "vty.h"
14 : #include "sockunion.h"
15 : #include "prefix.h"
16 : #include "stream.h"
17 : #include "command.h"
18 : #include "memory.h"
19 : #include "ioctl.h"
20 : #include "connected.h"
21 : #include "network.h"
22 : #include "log.h"
23 : #include "table.h"
24 : #include "rib.h"
25 : #include "vrf.h"
26 :
27 : #include "zebra/zebra_router.h"
28 : #include "zebra/zapi_msg.h"
29 : #include "zebra/zebra_vrf.h"
30 : #include "zebra/router-id.h"
31 : #include "zebra/redistribute.h"
32 :
33 21 : static struct connected *router_id_find_node(struct list *l,
34 : struct connected *ifc)
35 : {
36 21 : struct listnode *node;
37 21 : struct connected *c;
38 :
39 53 : for (ALL_LIST_ELEMENTS_RO(l, node, c))
40 16 : if (prefix_same(ifc->address, c->address))
41 5 : return c;
42 :
43 : return NULL;
44 : }
45 :
46 27 : static int router_id_bad_address(struct connected *ifc)
47 : {
48 : /* non-redistributable addresses shouldn't be used for RIDs either */
49 27 : if (!zebra_check_addr(ifc->address))
50 : return 1;
51 :
52 : return 0;
53 : }
54 :
55 30 : static bool router_id_v6_is_any(struct prefix *p)
56 : {
57 30 : return memcmp(&p->u.prefix6, &in6addr_any, sizeof(struct in6_addr))
58 : == 0;
59 : }
60 :
61 44 : int router_id_get(afi_t afi, struct prefix *p, struct zebra_vrf *zvrf)
62 : {
63 44 : struct listnode *node;
64 44 : struct connected *c;
65 44 : struct in6_addr *addr = NULL;
66 :
67 44 : switch (afi) {
68 14 : case AFI_IP:
69 14 : p->u.prefix4.s_addr = INADDR_ANY;
70 14 : p->family = AF_INET;
71 14 : p->prefixlen = IPV4_MAX_BITLEN;
72 14 : if (zvrf->rid_user_assigned.u.prefix4.s_addr != INADDR_ANY)
73 0 : p->u.prefix4.s_addr =
74 : zvrf->rid_user_assigned.u.prefix4.s_addr;
75 14 : else if (!list_isempty(zvrf->rid_lo_sorted_list)) {
76 12 : node = listtail(zvrf->rid_lo_sorted_list);
77 12 : c = listgetdata(node);
78 12 : p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
79 2 : } else if (!list_isempty(zvrf->rid_all_sorted_list)) {
80 0 : node = listtail(zvrf->rid_all_sorted_list);
81 0 : c = listgetdata(node);
82 0 : p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
83 : }
84 : return 0;
85 30 : case AFI_IP6:
86 30 : p->u.prefix6 = in6addr_any;
87 30 : p->family = AF_INET6;
88 30 : p->prefixlen = IPV6_MAX_BITLEN;
89 30 : if (!router_id_v6_is_any(&zvrf->rid6_user_assigned))
90 : addr = &zvrf->rid6_user_assigned.u.prefix6;
91 30 : else if (!list_isempty(zvrf->rid6_lo_sorted_list)) {
92 28 : node = listtail(zvrf->rid6_lo_sorted_list);
93 28 : c = listgetdata(node);
94 28 : addr = &c->address->u.prefix6;
95 2 : } else if (!list_isempty(zvrf->rid6_all_sorted_list)) {
96 0 : node = listtail(zvrf->rid6_all_sorted_list);
97 0 : c = listgetdata(node);
98 0 : addr = &c->address->u.prefix6;
99 : }
100 28 : if (addr)
101 28 : memcpy(&p->u.prefix6, addr, sizeof(struct in6_addr));
102 : return 0;
103 : case AFI_UNSPEC:
104 : case AFI_L2VPN:
105 : case AFI_MAX:
106 : return -1;
107 : }
108 :
109 0 : assert(!"Reached end of function we should never hit");
110 : }
111 :
112 0 : static int router_id_set(afi_t afi, struct prefix *p, struct zebra_vrf *zvrf)
113 : {
114 0 : struct prefix after, before;
115 0 : struct listnode *node;
116 0 : struct zserv *client;
117 :
118 0 : router_id_get(afi, &before, zvrf);
119 :
120 0 : switch (afi) {
121 0 : case AFI_IP:
122 0 : zvrf->rid_user_assigned.u.prefix4.s_addr = p->u.prefix4.s_addr;
123 0 : break;
124 0 : case AFI_IP6:
125 0 : zvrf->rid6_user_assigned.u.prefix6 = p->u.prefix6;
126 0 : break;
127 : case AFI_UNSPEC:
128 : case AFI_L2VPN:
129 : case AFI_MAX:
130 : return -1;
131 : }
132 :
133 0 : router_id_get(afi, &after, zvrf);
134 :
135 : /*
136 : * If we've been told that the router-id is exactly the same
137 : * do we need to really do anything here?
138 : */
139 0 : if (prefix_same(&before, &after))
140 : return 0;
141 :
142 0 : for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client))
143 0 : zsend_router_id_update(client, afi, &after, zvrf->vrf->vrf_id);
144 :
145 : return 0;
146 : }
147 :
148 23 : void router_id_add_address(struct connected *ifc)
149 : {
150 23 : struct list *l = NULL;
151 23 : struct listnode *node;
152 23 : struct prefix before;
153 23 : struct prefix after;
154 23 : struct zserv *client;
155 23 : struct zebra_vrf *zvrf = ifc->ifp->vrf->info;
156 23 : afi_t afi;
157 23 : struct list *rid_lo;
158 23 : struct list *rid_all;
159 :
160 23 : if (router_id_bad_address(ifc))
161 19 : return;
162 :
163 17 : switch (ifc->address->family) {
164 5 : case AF_INET:
165 5 : afi = AFI_IP;
166 5 : rid_lo = zvrf->rid_lo_sorted_list;
167 5 : rid_all = zvrf->rid_all_sorted_list;
168 5 : break;
169 12 : case AF_INET6:
170 12 : afi = AFI_IP6;
171 12 : rid_lo = zvrf->rid6_lo_sorted_list;
172 12 : rid_all = zvrf->rid6_all_sorted_list;
173 12 : break;
174 : default:
175 : return;
176 : }
177 :
178 17 : router_id_get(afi, &before, zvrf);
179 :
180 17 : l = if_is_loopback(ifc->ifp) ? rid_lo : rid_all;
181 :
182 17 : if (!router_id_find_node(l, ifc))
183 16 : listnode_add_sort(l, ifc);
184 :
185 17 : router_id_get(afi, &after, zvrf);
186 :
187 17 : if (prefix_same(&before, &after))
188 : return;
189 :
190 8 : for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client))
191 0 : zsend_router_id_update(client, afi, &after, zvrf_id(zvrf));
192 : }
193 :
194 4 : void router_id_del_address(struct connected *ifc)
195 : {
196 4 : struct connected *c;
197 4 : struct list *l;
198 4 : struct prefix after;
199 4 : struct prefix before;
200 4 : struct listnode *node;
201 4 : struct zserv *client;
202 4 : struct zebra_vrf *zvrf = ifc->ifp->vrf->info;
203 4 : afi_t afi;
204 4 : struct list *rid_lo;
205 4 : struct list *rid_all;
206 :
207 4 : if (router_id_bad_address(ifc))
208 4 : return;
209 :
210 4 : switch (ifc->address->family) {
211 1 : case AF_INET:
212 1 : afi = AFI_IP;
213 1 : rid_lo = zvrf->rid_lo_sorted_list;
214 1 : rid_all = zvrf->rid_all_sorted_list;
215 1 : break;
216 3 : case AF_INET6:
217 3 : afi = AFI_IP6;
218 3 : rid_lo = zvrf->rid6_lo_sorted_list;
219 3 : rid_all = zvrf->rid6_all_sorted_list;
220 3 : break;
221 : default:
222 : return;
223 : }
224 :
225 4 : router_id_get(afi, &before, zvrf);
226 :
227 4 : if (if_is_loopback(ifc->ifp))
228 : l = rid_lo;
229 : else
230 4 : l = rid_all;
231 :
232 4 : if ((c = router_id_find_node(l, ifc)))
233 4 : listnode_delete(l, c);
234 :
235 4 : router_id_get(afi, &after, zvrf);
236 :
237 4 : if (prefix_same(&before, &after))
238 : return;
239 :
240 0 : for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client))
241 0 : zsend_router_id_update(client, afi, &after, zvrf_id(zvrf));
242 : }
243 :
244 0 : void router_id_write(struct vty *vty, struct zebra_vrf *zvrf)
245 : {
246 0 : char space[2];
247 :
248 0 : memset(space, 0, sizeof(space));
249 :
250 0 : if (zvrf_id(zvrf) != VRF_DEFAULT)
251 0 : snprintf(space, sizeof(space), "%s", " ");
252 :
253 0 : if (zvrf->rid_user_assigned.u.prefix4.s_addr != INADDR_ANY) {
254 0 : vty_out(vty, "%sip router-id %pI4\n", space,
255 : &zvrf->rid_user_assigned.u.prefix4);
256 : }
257 0 : if (!router_id_v6_is_any(&zvrf->rid6_user_assigned)) {
258 0 : vty_out(vty, "%sipv6 router-id %pI6\n", space,
259 : &zvrf->rid_user_assigned.u.prefix6);
260 : }
261 0 : }
262 :
263 0 : DEFUN (ip_router_id,
264 : ip_router_id_cmd,
265 : "ip router-id A.B.C.D vrf NAME",
266 : IP_STR
267 : "Manually set the router-id\n"
268 : "IP address to use for router-id\n"
269 : VRF_CMD_HELP_STR)
270 : {
271 0 : int idx = 0;
272 0 : struct prefix rid;
273 0 : vrf_id_t vrf_id;
274 0 : struct zebra_vrf *zvrf;
275 :
276 0 : argv_find(argv, argc, "A.B.C.D", &idx);
277 :
278 0 : if (!inet_pton(AF_INET, argv[idx]->arg, &rid.u.prefix4))
279 : return CMD_WARNING_CONFIG_FAILED;
280 :
281 0 : rid.prefixlen = IPV4_MAX_BITLEN;
282 0 : rid.family = AF_INET;
283 :
284 0 : argv_find(argv, argc, "NAME", &idx);
285 0 : VRF_GET_ID(vrf_id, argv[idx]->arg, false);
286 :
287 0 : zvrf = zebra_vrf_lookup_by_id(vrf_id);
288 0 : router_id_set(AFI_IP, &rid, zvrf);
289 :
290 0 : return CMD_SUCCESS;
291 : }
292 :
293 : ALIAS (ip_router_id,
294 : router_id_cmd,
295 : "router-id A.B.C.D vrf NAME",
296 : "Manually set the router-id\n"
297 : "IP address to use for router-id\n"
298 : VRF_CMD_HELP_STR);
299 :
300 0 : DEFUN (ipv6_router_id,
301 : ipv6_router_id_cmd,
302 : "ipv6 router-id X:X::X:X vrf NAME",
303 : IPV6_STR
304 : "Manually set the router-id\n"
305 : "IPv6 address to use for router-id\n"
306 : VRF_CMD_HELP_STR)
307 : {
308 0 : int idx = 0;
309 0 : struct prefix rid;
310 0 : vrf_id_t vrf_id;
311 0 : struct zebra_vrf *zvrf;
312 :
313 0 : argv_find(argv, argc, "X:X::X:X", &idx);
314 :
315 0 : if (!inet_pton(AF_INET6, argv[idx]->arg, &rid.u.prefix6))
316 : return CMD_WARNING_CONFIG_FAILED;
317 :
318 0 : rid.prefixlen = IPV6_MAX_BITLEN;
319 0 : rid.family = AF_INET6;
320 :
321 0 : argv_find(argv, argc, "NAME", &idx);
322 0 : VRF_GET_ID(vrf_id, argv[idx]->arg, false);
323 :
324 0 : zvrf = zebra_vrf_lookup_by_id(vrf_id);
325 0 : router_id_set(AFI_IP6, &rid, zvrf);
326 :
327 0 : return CMD_SUCCESS;
328 : }
329 :
330 :
331 0 : DEFUN (ip_router_id_in_vrf,
332 : ip_router_id_in_vrf_cmd,
333 : "ip router-id A.B.C.D",
334 : IP_STR
335 : "Manually set the router-id\n"
336 : "IP address to use for router-id\n")
337 : {
338 0 : ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf);
339 0 : int idx = 0;
340 0 : struct prefix rid;
341 :
342 0 : argv_find(argv, argc, "A.B.C.D", &idx);
343 :
344 0 : if (!inet_pton(AF_INET, argv[idx]->arg, &rid.u.prefix4))
345 : return CMD_WARNING_CONFIG_FAILED;
346 :
347 0 : rid.prefixlen = IPV4_MAX_BITLEN;
348 0 : rid.family = AF_INET;
349 :
350 0 : router_id_set(AFI_IP, &rid, zvrf);
351 :
352 0 : return CMD_SUCCESS;
353 : }
354 :
355 : ALIAS (ip_router_id_in_vrf,
356 : router_id_in_vrf_cmd,
357 : "router-id A.B.C.D",
358 : "Manually set the router-id\n"
359 : "IP address to use for router-id\n");
360 :
361 0 : DEFUN (ipv6_router_id_in_vrf,
362 : ipv6_router_id_in_vrf_cmd,
363 : "ipv6 router-id X:X::X:X",
364 : IP6_STR
365 : "Manually set the IPv6 router-id\n"
366 : "IPV6 address to use for router-id\n")
367 : {
368 0 : ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf);
369 0 : int idx = 0;
370 0 : struct prefix rid;
371 :
372 0 : argv_find(argv, argc, "X:X::X:X", &idx);
373 :
374 0 : if (!inet_pton(AF_INET6, argv[idx]->arg, &rid.u.prefix6))
375 : return CMD_WARNING_CONFIG_FAILED;
376 :
377 0 : rid.prefixlen = IPV6_MAX_BITLEN;
378 0 : rid.family = AF_INET6;
379 :
380 0 : router_id_set(AFI_IP6, &rid, zvrf);
381 :
382 0 : return CMD_SUCCESS;
383 : }
384 :
385 0 : DEFUN (no_ip_router_id,
386 : no_ip_router_id_cmd,
387 : "no ip router-id [A.B.C.D vrf NAME]",
388 : NO_STR
389 : IP_STR
390 : "Remove the manually configured router-id\n"
391 : "IP address to use for router-id\n"
392 : VRF_CMD_HELP_STR)
393 : {
394 0 : int idx = 0;
395 0 : struct prefix rid;
396 0 : vrf_id_t vrf_id = VRF_DEFAULT;
397 0 : struct zebra_vrf *zvrf;
398 :
399 0 : rid.u.prefix4.s_addr = 0;
400 0 : rid.prefixlen = 0;
401 0 : rid.family = AF_INET;
402 :
403 0 : if (argv_find(argv, argc, "NAME", &idx))
404 0 : VRF_GET_ID(vrf_id, argv[idx]->arg, false);
405 :
406 0 : zvrf = zebra_vrf_lookup_by_id(vrf_id);
407 0 : router_id_set(AFI_IP, &rid, zvrf);
408 :
409 0 : return CMD_SUCCESS;
410 : }
411 :
412 : ALIAS (no_ip_router_id,
413 : no_router_id_cmd,
414 : "no router-id [A.B.C.D vrf NAME]",
415 : NO_STR
416 : "Remove the manually configured router-id\n"
417 : "IP address to use for router-id\n"
418 : VRF_CMD_HELP_STR);
419 :
420 0 : DEFUN (no_ipv6_router_id,
421 : no_ipv6_router_id_cmd,
422 : "no ipv6 router-id [X:X::X:X vrf NAME]",
423 : NO_STR
424 : IPV6_STR
425 : "Remove the manually configured IPv6 router-id\n"
426 : "IPv6 address to use for router-id\n"
427 : VRF_CMD_HELP_STR)
428 : {
429 0 : int idx = 0;
430 0 : struct prefix rid;
431 0 : vrf_id_t vrf_id = VRF_DEFAULT;
432 0 : struct zebra_vrf *zvrf;
433 :
434 0 : memset(&rid, 0, sizeof(rid));
435 0 : rid.family = AF_INET;
436 :
437 0 : if (argv_find(argv, argc, "NAME", &idx))
438 0 : VRF_GET_ID(vrf_id, argv[idx]->arg, false);
439 :
440 0 : zvrf = zebra_vrf_lookup_by_id(vrf_id);
441 0 : router_id_set(AFI_IP6, &rid, zvrf);
442 :
443 0 : return CMD_SUCCESS;
444 : }
445 :
446 0 : DEFUN (no_ip_router_id_in_vrf,
447 : no_ip_router_id_in_vrf_cmd,
448 : "no ip router-id [A.B.C.D]",
449 : NO_STR
450 : IP_STR
451 : "Remove the manually configured router-id\n"
452 : "IP address to use for router-id\n")
453 : {
454 0 : ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf);
455 :
456 0 : struct prefix rid;
457 :
458 0 : rid.u.prefix4.s_addr = 0;
459 0 : rid.prefixlen = 0;
460 0 : rid.family = AF_INET;
461 :
462 0 : router_id_set(AFI_IP, &rid, zvrf);
463 :
464 0 : return CMD_SUCCESS;
465 : }
466 :
467 : ALIAS (no_ip_router_id_in_vrf,
468 : no_router_id_in_vrf_cmd,
469 : "no router-id [A.B.C.D]",
470 : NO_STR
471 : "Remove the manually configured router-id\n"
472 : "IP address to use for router-id\n");
473 :
474 0 : DEFUN (no_ipv6_router_id_in_vrf,
475 : no_ipv6_router_id_in_vrf_cmd,
476 : "no ipv6 router-id [X:X::X:X]",
477 : NO_STR
478 : IP6_STR
479 : "Remove the manually configured IPv6 router-id\n"
480 : "IPv6 address to use for router-id\n")
481 : {
482 0 : ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf);
483 :
484 0 : struct prefix rid;
485 :
486 0 : memset(&rid, 0, sizeof(rid));
487 0 : rid.family = AF_INET;
488 :
489 0 : router_id_set(AFI_IP6, &rid, zvrf);
490 :
491 0 : return CMD_SUCCESS;
492 : }
493 :
494 0 : DEFUN (show_ip_router_id,
495 : show_ip_router_id_cmd,
496 : "show [ip|ipv6] router-id [vrf NAME]",
497 : SHOW_STR
498 : IP_STR
499 : IPV6_STR
500 : "Show the configured router-id\n"
501 : VRF_CMD_HELP_STR)
502 : {
503 0 : int idx = 0;
504 0 : vrf_id_t vrf_id = VRF_DEFAULT;
505 0 : struct zebra_vrf *zvrf;
506 0 : const char *vrf_name = "default";
507 0 : char addr_name[INET6_ADDRSTRLEN];
508 0 : int is_ipv6 = 0;
509 :
510 0 : is_ipv6 = argv_find(argv, argc, "ipv6", &idx);
511 :
512 0 : if (argv_find(argv, argc, "NAME", &idx)) {
513 0 : VRF_GET_ID(vrf_id, argv[idx]->arg, false);
514 0 : vrf_name = argv[idx]->arg;
515 : }
516 :
517 0 : zvrf = zebra_vrf_lookup_by_id(vrf_id);
518 :
519 0 : if (zvrf != NULL) {
520 0 : if (is_ipv6) {
521 0 : if (router_id_v6_is_any(&zvrf->rid6_user_assigned))
522 : return CMD_SUCCESS;
523 0 : inet_ntop(AF_INET6, &zvrf->rid6_user_assigned.u.prefix6,
524 : addr_name, sizeof(addr_name));
525 : } else {
526 0 : if (zvrf->rid_user_assigned.u.prefix4.s_addr
527 : == INADDR_ANY)
528 : return CMD_SUCCESS;
529 0 : inet_ntop(AF_INET, &zvrf->rid_user_assigned.u.prefix4,
530 : addr_name, sizeof(addr_name));
531 : }
532 :
533 0 : vty_out(vty, "zebra:\n");
534 0 : vty_out(vty, " router-id %s vrf %s\n", addr_name, vrf_name);
535 : }
536 :
537 : return CMD_SUCCESS;
538 : }
539 :
540 0 : static int router_id_cmp(void *a, void *b)
541 : {
542 0 : const struct connected *ifa = (const struct connected *)a;
543 0 : const struct connected *ifb = (const struct connected *)b;
544 :
545 0 : return IPV4_ADDR_CMP(&ifa->address->u.prefix4.s_addr,
546 : &ifb->address->u.prefix4.s_addr);
547 : }
548 :
549 9 : static int router_id_v6_cmp(void *a, void *b)
550 : {
551 9 : const struct connected *ifa = (const struct connected *)a;
552 9 : const struct connected *ifb = (const struct connected *)b;
553 :
554 9 : return IPV6_ADDR_CMP(&ifa->address->u.prefix6,
555 : &ifb->address->u.prefix6);
556 : }
557 :
558 2 : void router_id_cmd_init(void)
559 : {
560 2 : install_element(CONFIG_NODE, &ip_router_id_cmd);
561 2 : install_element(CONFIG_NODE, &router_id_cmd);
562 2 : install_element(CONFIG_NODE, &ipv6_router_id_cmd);
563 2 : install_element(CONFIG_NODE, &no_ip_router_id_cmd);
564 2 : install_element(CONFIG_NODE, &no_router_id_cmd);
565 2 : install_element(CONFIG_NODE, &ip_router_id_in_vrf_cmd);
566 2 : install_element(VRF_NODE, &ip_router_id_in_vrf_cmd);
567 2 : install_element(CONFIG_NODE, &router_id_in_vrf_cmd);
568 2 : install_element(VRF_NODE, &router_id_in_vrf_cmd);
569 2 : install_element(CONFIG_NODE, &ipv6_router_id_in_vrf_cmd);
570 2 : install_element(VRF_NODE, &ipv6_router_id_in_vrf_cmd);
571 2 : install_element(CONFIG_NODE, &no_ipv6_router_id_cmd);
572 2 : install_element(CONFIG_NODE, &no_ip_router_id_in_vrf_cmd);
573 2 : install_element(VRF_NODE, &no_ip_router_id_in_vrf_cmd);
574 2 : install_element(CONFIG_NODE, &no_router_id_in_vrf_cmd);
575 2 : install_element(VRF_NODE, &no_router_id_in_vrf_cmd);
576 2 : install_element(CONFIG_NODE, &no_ipv6_router_id_in_vrf_cmd);
577 2 : install_element(VRF_NODE, &no_ipv6_router_id_in_vrf_cmd);
578 2 : install_element(VIEW_NODE, &show_ip_router_id_cmd);
579 2 : }
580 :
581 2 : void router_id_init(struct zebra_vrf *zvrf)
582 : {
583 2 : zvrf->rid_all_sorted_list = &zvrf->_rid_all_sorted_list;
584 2 : zvrf->rid_lo_sorted_list = &zvrf->_rid_lo_sorted_list;
585 2 : zvrf->rid6_all_sorted_list = &zvrf->_rid6_all_sorted_list;
586 2 : zvrf->rid6_lo_sorted_list = &zvrf->_rid6_lo_sorted_list;
587 :
588 2 : memset(zvrf->rid_all_sorted_list, 0,
589 : sizeof(zvrf->_rid_all_sorted_list));
590 2 : memset(zvrf->rid_lo_sorted_list, 0, sizeof(zvrf->_rid_lo_sorted_list));
591 2 : memset(&zvrf->rid_user_assigned, 0, sizeof(zvrf->rid_user_assigned));
592 2 : memset(zvrf->rid6_all_sorted_list, 0,
593 : sizeof(zvrf->_rid6_all_sorted_list));
594 2 : memset(zvrf->rid6_lo_sorted_list, 0,
595 : sizeof(zvrf->_rid6_lo_sorted_list));
596 2 : memset(&zvrf->rid6_user_assigned, 0, sizeof(zvrf->rid6_user_assigned));
597 :
598 2 : zvrf->rid_all_sorted_list->cmp = router_id_cmp;
599 2 : zvrf->rid_lo_sorted_list->cmp = router_id_cmp;
600 2 : zvrf->rid6_all_sorted_list->cmp = router_id_v6_cmp;
601 2 : zvrf->rid6_lo_sorted_list->cmp = router_id_v6_cmp;
602 :
603 2 : zvrf->rid_user_assigned.family = AF_INET;
604 2 : zvrf->rid_user_assigned.prefixlen = IPV4_MAX_BITLEN;
605 2 : zvrf->rid6_user_assigned.family = AF_INET6;
606 2 : zvrf->rid6_user_assigned.prefixlen = IPV6_MAX_BITLEN;
607 2 : }
|