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