2023-02-08 13:17:09 +01:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2004-10-03 20:18:34 +02:00
|
|
|
/*
|
|
|
|
* Router ID for zebra daemon.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2004 James R. Leu
|
|
|
|
*
|
|
|
|
* This file is part of Quagga routing suite.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <zebra.h>
|
|
|
|
|
|
|
|
#include "if.h"
|
|
|
|
#include "vty.h"
|
|
|
|
#include "sockunion.h"
|
|
|
|
#include "prefix.h"
|
|
|
|
#include "stream.h"
|
|
|
|
#include "command.h"
|
|
|
|
#include "memory.h"
|
|
|
|
#include "ioctl.h"
|
|
|
|
#include "connected.h"
|
|
|
|
#include "network.h"
|
|
|
|
#include "log.h"
|
|
|
|
#include "table.h"
|
|
|
|
#include "rib.h"
|
2015-05-22 11:40:07 +02:00
|
|
|
#include "vrf.h"
|
2004-10-03 20:18:34 +02:00
|
|
|
|
2019-01-11 19:38:19 +01:00
|
|
|
#include "zebra/zebra_router.h"
|
2018-04-22 22:01:20 +02:00
|
|
|
#include "zebra/zapi_msg.h"
|
2016-04-14 15:20:47 +02:00
|
|
|
#include "zebra/zebra_vrf.h"
|
2005-06-28 19:17:12 +02:00
|
|
|
#include "zebra/router-id.h"
|
2007-04-10 21:24:45 +02:00
|
|
|
#include "zebra/redistribute.h"
|
2004-10-03 20:18:34 +02:00
|
|
|
|
|
|
|
static struct connected *router_id_find_node(struct list *l,
|
|
|
|
struct connected *ifc)
|
|
|
|
{
|
|
|
|
struct listnode *node;
|
|
|
|
struct connected *c;
|
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(l, node, c))
|
|
|
|
if (prefix_same(ifc->address, c->address))
|
|
|
|
return c;
|
|
|
|
|
2004-10-03 20:18:34 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int router_id_bad_address(struct connected *ifc)
|
|
|
|
{
|
2007-04-10 21:24:45 +02:00
|
|
|
/* non-redistributable addresses shouldn't be used for RIDs either */
|
|
|
|
if (!zebra_check_addr(ifc->address))
|
2004-10-03 20:18:34 +02:00
|
|
|
return 1;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-10-03 20:18:34 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-05-26 14:01:03 +02:00
|
|
|
static bool router_id_v6_is_any(struct prefix *p)
|
|
|
|
{
|
|
|
|
return memcmp(&p->u.prefix6, &in6addr_any, sizeof(struct in6_addr))
|
|
|
|
== 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int router_id_get(afi_t afi, struct prefix *p, struct zebra_vrf *zvrf)
|
2004-10-03 20:18:34 +02:00
|
|
|
{
|
|
|
|
struct listnode *node;
|
|
|
|
struct connected *c;
|
2020-05-26 14:01:03 +02:00
|
|
|
struct in6_addr *addr = NULL;
|
|
|
|
|
|
|
|
switch (afi) {
|
|
|
|
case AFI_IP:
|
|
|
|
p->u.prefix4.s_addr = INADDR_ANY;
|
|
|
|
p->family = AF_INET;
|
2021-07-01 17:05:11 +02:00
|
|
|
p->prefixlen = IPV4_MAX_BITLEN;
|
2020-05-26 14:01:03 +02:00
|
|
|
if (zvrf->rid_user_assigned.u.prefix4.s_addr != INADDR_ANY)
|
|
|
|
p->u.prefix4.s_addr =
|
|
|
|
zvrf->rid_user_assigned.u.prefix4.s_addr;
|
|
|
|
else if (!list_isempty(zvrf->rid_lo_sorted_list)) {
|
|
|
|
node = listtail(zvrf->rid_lo_sorted_list);
|
|
|
|
c = listgetdata(node);
|
|
|
|
p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
|
|
|
|
} else if (!list_isempty(zvrf->rid_all_sorted_list)) {
|
|
|
|
node = listtail(zvrf->rid_all_sorted_list);
|
|
|
|
c = listgetdata(node);
|
|
|
|
p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
case AFI_IP6:
|
|
|
|
p->u.prefix6 = in6addr_any;
|
|
|
|
p->family = AF_INET6;
|
2021-07-01 16:53:21 +02:00
|
|
|
p->prefixlen = IPV6_MAX_BITLEN;
|
2020-05-26 14:01:03 +02:00
|
|
|
if (!router_id_v6_is_any(&zvrf->rid6_user_assigned))
|
|
|
|
addr = &zvrf->rid6_user_assigned.u.prefix6;
|
|
|
|
else if (!list_isempty(zvrf->rid6_lo_sorted_list)) {
|
|
|
|
node = listtail(zvrf->rid6_lo_sorted_list);
|
|
|
|
c = listgetdata(node);
|
|
|
|
addr = &c->address->u.prefix6;
|
|
|
|
} else if (!list_isempty(zvrf->rid6_all_sorted_list)) {
|
|
|
|
node = listtail(zvrf->rid6_all_sorted_list);
|
|
|
|
c = listgetdata(node);
|
|
|
|
addr = &c->address->u.prefix6;
|
|
|
|
}
|
|
|
|
if (addr)
|
|
|
|
memcpy(&p->u.prefix6, addr, sizeof(struct in6_addr));
|
|
|
|
return 0;
|
2023-01-30 16:05:58 +01:00
|
|
|
case AFI_UNSPEC:
|
|
|
|
case AFI_L2VPN:
|
|
|
|
case AFI_MAX:
|
2020-05-26 14:01:03 +02:00
|
|
|
return -1;
|
2004-10-03 20:18:34 +02:00
|
|
|
}
|
2023-01-30 16:05:58 +01:00
|
|
|
|
|
|
|
assert(!"Reached end of function we should never hit");
|
2004-10-03 20:18:34 +02:00
|
|
|
}
|
|
|
|
|
2020-05-26 14:01:03 +02:00
|
|
|
static int router_id_set(afi_t afi, struct prefix *p, struct zebra_vrf *zvrf)
|
2004-10-03 20:18:34 +02:00
|
|
|
{
|
2021-09-03 15:44:38 +02:00
|
|
|
struct prefix after, before;
|
2004-10-03 20:18:34 +02:00
|
|
|
struct listnode *node;
|
|
|
|
struct zserv *client;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-09-03 15:44:38 +02:00
|
|
|
router_id_get(afi, &before, zvrf);
|
|
|
|
|
2020-05-26 14:01:03 +02:00
|
|
|
switch (afi) {
|
|
|
|
case AFI_IP:
|
|
|
|
zvrf->rid_user_assigned.u.prefix4.s_addr = p->u.prefix4.s_addr;
|
|
|
|
break;
|
|
|
|
case AFI_IP6:
|
|
|
|
zvrf->rid6_user_assigned.u.prefix6 = p->u.prefix6;
|
|
|
|
break;
|
2023-01-30 16:05:58 +01:00
|
|
|
case AFI_UNSPEC:
|
|
|
|
case AFI_L2VPN:
|
|
|
|
case AFI_MAX:
|
2020-05-26 14:01:03 +02:00
|
|
|
return -1;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-09-03 15:44:38 +02:00
|
|
|
router_id_get(afi, &after, zvrf);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If we've been told that the router-id is exactly the same
|
|
|
|
* do we need to really do anything here?
|
|
|
|
*/
|
|
|
|
if (prefix_same(&before, &after))
|
|
|
|
return 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-01-11 19:38:19 +01:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client))
|
2021-09-03 15:44:38 +02:00
|
|
|
zsend_router_id_update(client, afi, &after, zvrf->vrf->vrf_id);
|
2020-05-26 14:01:03 +02:00
|
|
|
|
|
|
|
return 0;
|
2004-10-03 20:18:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void router_id_add_address(struct connected *ifc)
|
|
|
|
{
|
|
|
|
struct list *l = NULL;
|
|
|
|
struct listnode *node;
|
|
|
|
struct prefix before;
|
|
|
|
struct prefix after;
|
|
|
|
struct zserv *client;
|
2021-10-22 00:17:40 +02:00
|
|
|
struct zebra_vrf *zvrf = ifc->ifp->vrf->info;
|
2020-05-26 14:01:03 +02:00
|
|
|
afi_t afi;
|
|
|
|
struct list *rid_lo;
|
|
|
|
struct list *rid_all;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-10-03 20:18:34 +02:00
|
|
|
if (router_id_bad_address(ifc))
|
|
|
|
return;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-05-26 14:01:03 +02:00
|
|
|
switch (ifc->address->family) {
|
|
|
|
case AF_INET:
|
|
|
|
afi = AFI_IP;
|
|
|
|
rid_lo = zvrf->rid_lo_sorted_list;
|
|
|
|
rid_all = zvrf->rid_all_sorted_list;
|
|
|
|
break;
|
|
|
|
case AF_INET6:
|
|
|
|
afi = AFI_IP6;
|
|
|
|
rid_lo = zvrf->rid6_lo_sorted_list;
|
|
|
|
rid_all = zvrf->rid6_all_sorted_list;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-05-26 14:01:03 +02:00
|
|
|
router_id_get(afi, &before, zvrf);
|
|
|
|
|
|
|
|
l = if_is_loopback(ifc->ifp) ? rid_lo : rid_all;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-10-03 20:18:34 +02:00
|
|
|
if (!router_id_find_node(l, ifc))
|
2009-12-21 16:50:43 +01:00
|
|
|
listnode_add_sort(l, ifc);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-05-26 14:01:03 +02:00
|
|
|
router_id_get(afi, &after, zvrf);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-10-03 20:18:34 +02:00
|
|
|
if (prefix_same(&before, &after))
|
|
|
|
return;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-01-11 19:38:19 +01:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client))
|
2020-05-26 14:01:03 +02:00
|
|
|
zsend_router_id_update(client, afi, &after, zvrf_id(zvrf));
|
2004-10-03 20:18:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void router_id_del_address(struct connected *ifc)
|
|
|
|
{
|
|
|
|
struct connected *c;
|
|
|
|
struct list *l;
|
|
|
|
struct prefix after;
|
|
|
|
struct prefix before;
|
|
|
|
struct listnode *node;
|
|
|
|
struct zserv *client;
|
2021-10-22 00:17:40 +02:00
|
|
|
struct zebra_vrf *zvrf = ifc->ifp->vrf->info;
|
2020-05-26 14:01:03 +02:00
|
|
|
afi_t afi;
|
|
|
|
struct list *rid_lo;
|
|
|
|
struct list *rid_all;
|
2004-10-03 20:18:34 +02:00
|
|
|
|
|
|
|
if (router_id_bad_address(ifc))
|
|
|
|
return;
|
|
|
|
|
2020-05-26 14:01:03 +02:00
|
|
|
switch (ifc->address->family) {
|
|
|
|
case AF_INET:
|
|
|
|
afi = AFI_IP;
|
|
|
|
rid_lo = zvrf->rid_lo_sorted_list;
|
|
|
|
rid_all = zvrf->rid_all_sorted_list;
|
|
|
|
break;
|
|
|
|
case AF_INET6:
|
|
|
|
afi = AFI_IP6;
|
|
|
|
rid_lo = zvrf->rid6_lo_sorted_list;
|
|
|
|
rid_all = zvrf->rid6_all_sorted_list;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
router_id_get(afi, &before, zvrf);
|
2004-10-03 20:18:34 +02:00
|
|
|
|
2018-11-18 00:33:37 +01:00
|
|
|
if (if_is_loopback(ifc->ifp))
|
2020-05-26 14:01:03 +02:00
|
|
|
l = rid_lo;
|
2004-10-03 20:18:34 +02:00
|
|
|
else
|
2020-05-26 14:01:03 +02:00
|
|
|
l = rid_all;
|
2004-10-03 20:18:34 +02:00
|
|
|
|
|
|
|
if ((c = router_id_find_node(l, ifc)))
|
|
|
|
listnode_delete(l, c);
|
|
|
|
|
2020-05-26 14:01:03 +02:00
|
|
|
router_id_get(afi, &after, zvrf);
|
2004-10-03 20:18:34 +02:00
|
|
|
|
|
|
|
if (prefix_same(&before, &after))
|
|
|
|
return;
|
|
|
|
|
2019-01-11 19:38:19 +01:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client))
|
2020-05-26 14:01:03 +02:00
|
|
|
zsend_router_id_update(client, afi, &after, zvrf_id(zvrf));
|
2004-10-03 20:18:34 +02:00
|
|
|
}
|
|
|
|
|
2020-07-09 17:57:22 +02:00
|
|
|
void router_id_write(struct vty *vty, struct zebra_vrf *zvrf)
|
2004-10-03 20:18:34 +02:00
|
|
|
{
|
2020-07-09 17:57:22 +02:00
|
|
|
char space[2];
|
|
|
|
|
|
|
|
memset(space, 0, sizeof(space));
|
|
|
|
|
|
|
|
if (zvrf_id(zvrf) != VRF_DEFAULT)
|
|
|
|
snprintf(space, sizeof(space), "%s", " ");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-07-09 17:57:22 +02:00
|
|
|
if (zvrf->rid_user_assigned.u.prefix4.s_addr != INADDR_ANY) {
|
2020-05-26 14:01:03 +02:00
|
|
|
vty_out(vty, "%sip router-id %pI4\n", space,
|
|
|
|
&zvrf->rid_user_assigned.u.prefix4);
|
|
|
|
}
|
|
|
|
if (!router_id_v6_is_any(&zvrf->rid6_user_assigned)) {
|
|
|
|
vty_out(vty, "%sipv6 router-id %pI6\n", space,
|
|
|
|
&zvrf->rid_user_assigned.u.prefix6);
|
2020-07-09 17:57:22 +02:00
|
|
|
}
|
2004-10-03 20:18:34 +02:00
|
|
|
}
|
|
|
|
|
2020-05-26 14:01:03 +02:00
|
|
|
DEFUN (ip_router_id,
|
|
|
|
ip_router_id_cmd,
|
|
|
|
"ip router-id A.B.C.D vrf NAME",
|
|
|
|
IP_STR
|
2004-10-03 20:18:34 +02:00
|
|
|
"Manually set the router-id\n"
|
2020-05-26 14:01:03 +02:00
|
|
|
"IP address to use for router-id\n"
|
|
|
|
VRF_CMD_HELP_STR)
|
2004-10-03 20:18:34 +02:00
|
|
|
{
|
2020-05-26 14:01:03 +02:00
|
|
|
int idx = 0;
|
|
|
|
struct prefix rid;
|
|
|
|
vrf_id_t vrf_id;
|
2020-07-09 17:57:22 +02:00
|
|
|
struct zebra_vrf *zvrf;
|
2016-09-25 05:00:04 +02:00
|
|
|
|
2020-05-26 14:01:03 +02:00
|
|
|
argv_find(argv, argc, "A.B.C.D", &idx);
|
2004-10-03 20:18:34 +02:00
|
|
|
|
2020-05-26 14:01:03 +02:00
|
|
|
if (!inet_pton(AF_INET, argv[idx]->arg, &rid.u.prefix4))
|
2017-07-13 21:56:08 +02:00
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
2004-10-03 20:18:34 +02:00
|
|
|
|
2021-07-01 17:05:11 +02:00
|
|
|
rid.prefixlen = IPV4_MAX_BITLEN;
|
2004-10-03 20:18:34 +02:00
|
|
|
rid.family = AF_INET;
|
|
|
|
|
2020-05-26 14:01:03 +02:00
|
|
|
argv_find(argv, argc, "NAME", &idx);
|
|
|
|
VRF_GET_ID(vrf_id, argv[idx]->arg, false);
|
2015-05-22 11:40:07 +02:00
|
|
|
|
2020-07-09 17:57:22 +02:00
|
|
|
zvrf = vrf_info_lookup(vrf_id);
|
2020-05-26 14:01:03 +02:00
|
|
|
router_id_set(AFI_IP, &rid, zvrf);
|
2020-07-09 17:57:22 +02:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2020-05-26 14:01:03 +02:00
|
|
|
ALIAS (ip_router_id,
|
|
|
|
router_id_cmd,
|
|
|
|
"router-id A.B.C.D vrf NAME",
|
|
|
|
"Manually set the router-id\n"
|
|
|
|
"IP address to use for router-id\n"
|
|
|
|
VRF_CMD_HELP_STR);
|
|
|
|
|
|
|
|
DEFUN (ipv6_router_id,
|
|
|
|
ipv6_router_id_cmd,
|
|
|
|
"ipv6 router-id X:X::X:X vrf NAME",
|
|
|
|
IPV6_STR
|
|
|
|
"Manually set the router-id\n"
|
|
|
|
"IPv6 address to use for router-id\n"
|
|
|
|
VRF_CMD_HELP_STR)
|
|
|
|
{
|
|
|
|
int idx = 0;
|
|
|
|
struct prefix rid;
|
|
|
|
vrf_id_t vrf_id;
|
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
|
|
|
|
argv_find(argv, argc, "X:X::X:X", &idx);
|
|
|
|
|
|
|
|
if (!inet_pton(AF_INET6, argv[idx]->arg, &rid.u.prefix6))
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
|
2021-07-01 16:53:21 +02:00
|
|
|
rid.prefixlen = IPV6_MAX_BITLEN;
|
2020-05-26 14:01:03 +02:00
|
|
|
rid.family = AF_INET6;
|
|
|
|
|
|
|
|
argv_find(argv, argc, "NAME", &idx);
|
|
|
|
VRF_GET_ID(vrf_id, argv[idx]->arg, false);
|
|
|
|
|
|
|
|
zvrf = vrf_info_lookup(vrf_id);
|
|
|
|
router_id_set(AFI_IP6, &rid, zvrf);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DEFUN (ip_router_id_in_vrf,
|
|
|
|
ip_router_id_in_vrf_cmd,
|
|
|
|
"ip router-id A.B.C.D",
|
|
|
|
IP_STR
|
2020-10-29 21:06:13 +01:00
|
|
|
"Manually set the router-id\n"
|
2020-07-09 17:57:22 +02:00
|
|
|
"IP address to use for router-id\n")
|
|
|
|
{
|
2022-04-28 11:06:20 +02:00
|
|
|
ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf);
|
2020-05-26 14:01:03 +02:00
|
|
|
int idx = 0;
|
2020-07-09 17:57:22 +02:00
|
|
|
struct prefix rid;
|
|
|
|
|
2020-05-26 14:01:03 +02:00
|
|
|
argv_find(argv, argc, "A.B.C.D", &idx);
|
|
|
|
|
|
|
|
if (!inet_pton(AF_INET, argv[idx]->arg, &rid.u.prefix4))
|
2020-07-09 17:57:22 +02:00
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
|
2021-07-01 17:05:11 +02:00
|
|
|
rid.prefixlen = IPV4_MAX_BITLEN;
|
2020-07-09 17:57:22 +02:00
|
|
|
rid.family = AF_INET;
|
|
|
|
|
2020-05-26 14:01:03 +02:00
|
|
|
router_id_set(AFI_IP, &rid, zvrf);
|
2004-10-03 20:18:34 +02:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2020-05-26 14:01:03 +02:00
|
|
|
ALIAS (ip_router_id_in_vrf,
|
|
|
|
router_id_in_vrf_cmd,
|
|
|
|
"router-id A.B.C.D",
|
|
|
|
"Manually set the router-id\n"
|
|
|
|
"IP address to use for router-id\n");
|
|
|
|
|
|
|
|
DEFUN (ipv6_router_id_in_vrf,
|
|
|
|
ipv6_router_id_in_vrf_cmd,
|
|
|
|
"ipv6 router-id X:X::X:X",
|
|
|
|
IP6_STR
|
2020-10-29 21:06:13 +01:00
|
|
|
"Manually set the IPv6 router-id\n"
|
2020-05-26 14:01:03 +02:00
|
|
|
"IPV6 address to use for router-id\n")
|
|
|
|
{
|
2022-04-28 11:06:20 +02:00
|
|
|
ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf);
|
2020-05-26 14:01:03 +02:00
|
|
|
int idx = 0;
|
|
|
|
struct prefix rid;
|
|
|
|
|
|
|
|
argv_find(argv, argc, "X:X::X:X", &idx);
|
|
|
|
|
|
|
|
if (!inet_pton(AF_INET6, argv[idx]->arg, &rid.u.prefix6))
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
|
2021-07-01 16:53:21 +02:00
|
|
|
rid.prefixlen = IPV6_MAX_BITLEN;
|
2020-05-26 14:01:03 +02:00
|
|
|
rid.family = AF_INET6;
|
|
|
|
|
|
|
|
router_id_set(AFI_IP6, &rid, zvrf);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_ip_router_id,
|
|
|
|
no_ip_router_id_cmd,
|
|
|
|
"no ip router-id [A.B.C.D vrf NAME]",
|
2004-10-03 20:18:34 +02:00
|
|
|
NO_STR
|
2020-05-26 14:01:03 +02:00
|
|
|
IP_STR
|
2016-09-25 05:00:04 +02:00
|
|
|
"Remove the manually configured router-id\n"
|
2020-05-26 14:01:03 +02:00
|
|
|
"IP address to use for router-id\n"
|
|
|
|
VRF_CMD_HELP_STR)
|
2004-10-03 20:18:34 +02:00
|
|
|
{
|
2020-05-26 14:01:03 +02:00
|
|
|
int idx = 0;
|
2004-10-03 20:18:34 +02:00
|
|
|
struct prefix rid;
|
2015-05-22 11:40:07 +02:00
|
|
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
2020-07-09 17:57:22 +02:00
|
|
|
struct zebra_vrf *zvrf;
|
2004-10-03 20:18:34 +02:00
|
|
|
|
|
|
|
rid.u.prefix4.s_addr = 0;
|
|
|
|
rid.prefixlen = 0;
|
|
|
|
rid.family = AF_INET;
|
|
|
|
|
2020-05-26 14:01:03 +02:00
|
|
|
if (argv_find(argv, argc, "NAME", &idx))
|
|
|
|
VRF_GET_ID(vrf_id, argv[idx]->arg, false);
|
2015-05-22 11:40:07 +02:00
|
|
|
|
2020-05-26 14:01:03 +02:00
|
|
|
zvrf = vrf_info_lookup(vrf_id);
|
|
|
|
router_id_set(AFI_IP, &rid, zvrf);
|
2020-07-09 17:57:22 +02:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2020-05-26 14:01:03 +02:00
|
|
|
ALIAS (no_ip_router_id,
|
|
|
|
no_router_id_cmd,
|
|
|
|
"no router-id [A.B.C.D vrf NAME]",
|
|
|
|
NO_STR
|
|
|
|
"Remove the manually configured router-id\n"
|
|
|
|
"IP address to use for router-id\n"
|
|
|
|
VRF_CMD_HELP_STR);
|
|
|
|
|
|
|
|
DEFUN (no_ipv6_router_id,
|
|
|
|
no_ipv6_router_id_cmd,
|
|
|
|
"no ipv6 router-id [X:X::X:X vrf NAME]",
|
|
|
|
NO_STR
|
|
|
|
IPV6_STR
|
|
|
|
"Remove the manually configured IPv6 router-id\n"
|
|
|
|
"IPv6 address to use for router-id\n"
|
|
|
|
VRF_CMD_HELP_STR)
|
|
|
|
{
|
|
|
|
int idx = 0;
|
|
|
|
struct prefix rid;
|
|
|
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
|
|
|
|
memset(&rid, 0, sizeof(rid));
|
|
|
|
rid.family = AF_INET;
|
|
|
|
|
|
|
|
if (argv_find(argv, argc, "NAME", &idx))
|
|
|
|
VRF_GET_ID(vrf_id, argv[idx]->arg, false);
|
|
|
|
|
|
|
|
zvrf = vrf_info_lookup(vrf_id);
|
|
|
|
router_id_set(AFI_IP6, &rid, zvrf);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_ip_router_id_in_vrf,
|
|
|
|
no_ip_router_id_in_vrf_cmd,
|
|
|
|
"no ip router-id [A.B.C.D]",
|
2020-07-09 17:57:22 +02:00
|
|
|
NO_STR
|
2020-05-26 14:01:03 +02:00
|
|
|
IP_STR
|
2020-07-09 17:57:22 +02:00
|
|
|
"Remove the manually configured router-id\n"
|
|
|
|
"IP address to use for router-id\n")
|
|
|
|
{
|
2022-04-28 11:06:20 +02:00
|
|
|
ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf);
|
2020-07-09 17:57:22 +02:00
|
|
|
|
|
|
|
struct prefix rid;
|
|
|
|
|
|
|
|
rid.u.prefix4.s_addr = 0;
|
|
|
|
rid.prefixlen = 0;
|
|
|
|
rid.family = AF_INET;
|
|
|
|
|
2020-05-26 14:01:03 +02:00
|
|
|
router_id_set(AFI_IP, &rid, zvrf);
|
2004-10-03 20:18:34 +02:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2020-05-26 14:01:03 +02:00
|
|
|
ALIAS (no_ip_router_id_in_vrf,
|
|
|
|
no_router_id_in_vrf_cmd,
|
|
|
|
"no router-id [A.B.C.D]",
|
|
|
|
NO_STR
|
|
|
|
"Remove the manually configured router-id\n"
|
|
|
|
"IP address to use for router-id\n");
|
|
|
|
|
|
|
|
DEFUN (no_ipv6_router_id_in_vrf,
|
|
|
|
no_ipv6_router_id_in_vrf_cmd,
|
|
|
|
"no ipv6 router-id [X:X::X:X]",
|
|
|
|
NO_STR
|
|
|
|
IP6_STR
|
|
|
|
"Remove the manually configured IPv6 router-id\n"
|
|
|
|
"IPv6 address to use for router-id\n")
|
|
|
|
{
|
2022-04-28 11:06:20 +02:00
|
|
|
ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf);
|
2020-05-26 14:01:03 +02:00
|
|
|
|
|
|
|
struct prefix rid;
|
|
|
|
|
|
|
|
memset(&rid, 0, sizeof(rid));
|
|
|
|
rid.family = AF_INET;
|
|
|
|
|
|
|
|
router_id_set(AFI_IP6, &rid, zvrf);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_router_id,
|
|
|
|
show_ip_router_id_cmd,
|
|
|
|
"show [ip|ipv6] router-id [vrf NAME]",
|
2019-12-17 07:02:12 +01:00
|
|
|
SHOW_STR
|
2020-05-26 14:01:03 +02:00
|
|
|
IP_STR
|
|
|
|
IPV6_STR
|
2019-12-17 07:02:12 +01:00
|
|
|
"Show the configured router-id\n"
|
|
|
|
VRF_CMD_HELP_STR)
|
|
|
|
{
|
2020-05-26 14:01:03 +02:00
|
|
|
int idx = 0;
|
|
|
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
const char *vrf_name = "default";
|
|
|
|
char addr_name[INET6_ADDRSTRLEN];
|
|
|
|
int is_ipv6 = 0;
|
2019-12-17 07:02:12 +01:00
|
|
|
|
2020-05-26 14:01:03 +02:00
|
|
|
is_ipv6 = argv_find(argv, argc, "ipv6", &idx);
|
2019-12-17 07:02:12 +01:00
|
|
|
|
2020-05-26 14:01:03 +02:00
|
|
|
if (argv_find(argv, argc, "NAME", &idx)) {
|
|
|
|
VRF_GET_ID(vrf_id, argv[idx]->arg, false);
|
|
|
|
vrf_name = argv[idx]->arg;
|
|
|
|
}
|
2019-12-17 07:02:12 +01:00
|
|
|
|
2021-10-22 00:17:40 +02:00
|
|
|
zvrf = vrf_info_lookup(vrf_id);
|
2019-12-17 07:02:12 +01:00
|
|
|
|
2020-05-26 14:01:03 +02:00
|
|
|
if (zvrf != NULL) {
|
|
|
|
if (is_ipv6) {
|
|
|
|
if (router_id_v6_is_any(&zvrf->rid6_user_assigned))
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
inet_ntop(AF_INET6, &zvrf->rid6_user_assigned.u.prefix6,
|
|
|
|
addr_name, sizeof(addr_name));
|
|
|
|
} else {
|
2020-12-14 20:01:31 +01:00
|
|
|
if (zvrf->rid_user_assigned.u.prefix4.s_addr
|
|
|
|
== INADDR_ANY)
|
2020-05-26 14:01:03 +02:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
inet_ntop(AF_INET, &zvrf->rid_user_assigned.u.prefix4,
|
|
|
|
addr_name, sizeof(addr_name));
|
|
|
|
}
|
|
|
|
|
|
|
|
vty_out(vty, "zebra:\n");
|
|
|
|
vty_out(vty, " router-id %s vrf %s\n", addr_name, vrf_name);
|
|
|
|
}
|
2019-12-17 07:02:12 +01:00
|
|
|
|
2020-05-26 14:01:03 +02:00
|
|
|
return CMD_SUCCESS;
|
2019-12-17 07:02:12 +01:00
|
|
|
}
|
2015-11-23 19:05:03 +01:00
|
|
|
|
2004-10-03 20:18:34 +02:00
|
|
|
static int router_id_cmp(void *a, void *b)
|
|
|
|
{
|
2009-12-21 16:50:43 +01:00
|
|
|
const struct connected *ifa = (const struct connected *)a;
|
|
|
|
const struct connected *ifb = (const struct connected *)b;
|
2004-10-03 20:18:34 +02:00
|
|
|
|
2014-04-15 04:23:11 +02:00
|
|
|
return IPV4_ADDR_CMP(&ifa->address->u.prefix4.s_addr,
|
|
|
|
&ifb->address->u.prefix4.s_addr);
|
2004-10-03 20:18:34 +02:00
|
|
|
}
|
|
|
|
|
2020-05-26 14:01:03 +02:00
|
|
|
static int router_id_v6_cmp(void *a, void *b)
|
|
|
|
{
|
|
|
|
const struct connected *ifa = (const struct connected *)a;
|
|
|
|
const struct connected *ifb = (const struct connected *)b;
|
|
|
|
|
|
|
|
return IPV6_ADDR_CMP(&ifa->address->u.prefix6,
|
|
|
|
&ifb->address->u.prefix6);
|
|
|
|
}
|
|
|
|
|
2015-05-22 11:40:07 +02:00
|
|
|
void router_id_cmd_init(void)
|
2004-10-03 20:18:34 +02:00
|
|
|
{
|
2020-05-26 14:01:03 +02:00
|
|
|
install_element(CONFIG_NODE, &ip_router_id_cmd);
|
2004-10-03 20:18:34 +02:00
|
|
|
install_element(CONFIG_NODE, &router_id_cmd);
|
2020-05-26 14:01:03 +02:00
|
|
|
install_element(CONFIG_NODE, &ipv6_router_id_cmd);
|
|
|
|
install_element(CONFIG_NODE, &no_ip_router_id_cmd);
|
2004-10-03 20:18:34 +02:00
|
|
|
install_element(CONFIG_NODE, &no_router_id_cmd);
|
2020-05-26 14:01:03 +02:00
|
|
|
install_element(CONFIG_NODE, &ip_router_id_in_vrf_cmd);
|
|
|
|
install_element(VRF_NODE, &ip_router_id_in_vrf_cmd);
|
2020-07-09 17:57:22 +02:00
|
|
|
install_element(CONFIG_NODE, &router_id_in_vrf_cmd);
|
|
|
|
install_element(VRF_NODE, &router_id_in_vrf_cmd);
|
2020-05-26 14:01:03 +02:00
|
|
|
install_element(CONFIG_NODE, &ipv6_router_id_in_vrf_cmd);
|
|
|
|
install_element(VRF_NODE, &ipv6_router_id_in_vrf_cmd);
|
|
|
|
install_element(CONFIG_NODE, &no_ipv6_router_id_cmd);
|
|
|
|
install_element(CONFIG_NODE, &no_ip_router_id_in_vrf_cmd);
|
|
|
|
install_element(VRF_NODE, &no_ip_router_id_in_vrf_cmd);
|
2020-07-09 17:57:22 +02:00
|
|
|
install_element(CONFIG_NODE, &no_router_id_in_vrf_cmd);
|
|
|
|
install_element(VRF_NODE, &no_router_id_in_vrf_cmd);
|
2020-05-26 14:01:03 +02:00
|
|
|
install_element(CONFIG_NODE, &no_ipv6_router_id_in_vrf_cmd);
|
|
|
|
install_element(VRF_NODE, &no_ipv6_router_id_in_vrf_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_router_id_cmd);
|
2015-05-22 11:40:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void router_id_init(struct zebra_vrf *zvrf)
|
|
|
|
{
|
|
|
|
zvrf->rid_all_sorted_list = &zvrf->_rid_all_sorted_list;
|
|
|
|
zvrf->rid_lo_sorted_list = &zvrf->_rid_lo_sorted_list;
|
2020-05-26 14:01:03 +02:00
|
|
|
zvrf->rid6_all_sorted_list = &zvrf->_rid6_all_sorted_list;
|
|
|
|
zvrf->rid6_lo_sorted_list = &zvrf->_rid6_lo_sorted_list;
|
2004-10-03 20:18:34 +02:00
|
|
|
|
2015-05-22 11:40:07 +02:00
|
|
|
memset(zvrf->rid_all_sorted_list, 0,
|
|
|
|
sizeof(zvrf->_rid_all_sorted_list));
|
|
|
|
memset(zvrf->rid_lo_sorted_list, 0, sizeof(zvrf->_rid_lo_sorted_list));
|
|
|
|
memset(&zvrf->rid_user_assigned, 0, sizeof(zvrf->rid_user_assigned));
|
2020-05-26 14:01:03 +02:00
|
|
|
memset(zvrf->rid6_all_sorted_list, 0,
|
|
|
|
sizeof(zvrf->_rid6_all_sorted_list));
|
|
|
|
memset(zvrf->rid6_lo_sorted_list, 0,
|
|
|
|
sizeof(zvrf->_rid6_lo_sorted_list));
|
|
|
|
memset(&zvrf->rid6_user_assigned, 0, sizeof(zvrf->rid6_user_assigned));
|
2004-10-03 20:18:34 +02:00
|
|
|
|
2015-05-22 11:40:07 +02:00
|
|
|
zvrf->rid_all_sorted_list->cmp = router_id_cmp;
|
|
|
|
zvrf->rid_lo_sorted_list->cmp = router_id_cmp;
|
2020-05-26 14:01:03 +02:00
|
|
|
zvrf->rid6_all_sorted_list->cmp = router_id_v6_cmp;
|
|
|
|
zvrf->rid6_lo_sorted_list->cmp = router_id_v6_cmp;
|
2004-10-03 20:18:34 +02:00
|
|
|
|
2015-05-22 11:40:07 +02:00
|
|
|
zvrf->rid_user_assigned.family = AF_INET;
|
2021-07-01 17:05:11 +02:00
|
|
|
zvrf->rid_user_assigned.prefixlen = IPV4_MAX_BITLEN;
|
2020-05-26 14:01:03 +02:00
|
|
|
zvrf->rid6_user_assigned.family = AF_INET6;
|
2021-07-01 16:53:21 +02:00
|
|
|
zvrf->rid6_user_assigned.prefixlen = IPV6_MAX_BITLEN;
|
2004-10-03 20:18:34 +02:00
|
|
|
}
|