Merge pull request #6483 from sylane/router-id-v6

zebra: add IPv6 router-id
This commit is contained in:
Donald Sharp 2020-08-10 08:39:51 -04:00 committed by GitHub
commit 8e3ac40d2c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 436 additions and 117 deletions

View File

@ -1050,23 +1050,34 @@ Many routing protocols require a router-id to be configured. To have a
consistent router-id across all daemons, the following commands are available consistent router-id across all daemons, the following commands are available
to configure and display the router-id: to configure and display the router-id:
.. index:: [no] router-id A.B.C.D .. index:: [no] [ip] router-id A.B.C.D
.. clicmd:: [no] router-id A.B.C.D .. clicmd:: [no] [ip] router-id A.B.C.D
Allow entering of the router-id. This command also works under the Allow entering of the router-id. This command also works under the
vrf subnode, to allow router-id's per vrf. vrf subnode, to allow router-id's per vrf.
.. index:: [no] router-id A.B.C.D vrf NAME .. index:: [no] [ip] router-id A.B.C.D vrf NAME
.. clicmd:: [no] router-id A.B.C.D vrf NAME .. clicmd:: [no] [ip] router-id A.B.C.D vrf NAME
Configure the router-id of this router from the configure NODE. Configure the router-id of this router from the configure NODE.
A show run of this command will display the router-id command A show run of this command will display the router-id command
under the vrf sub node. This command is deprecated and will under the vrf sub node. This command is deprecated and will
be removed at some point in time in the future. be removed at some point in time in the future.
.. index:: show router-id [vrf NAME] .. index:: show [ip] router-id [vrf NAME]
.. clicmd:: show router-id [vrf NAME] .. clicmd:: show [ip] router-id [vrf NAME]
Display the user configured router-id. Display the user configured router-id.
For protocols requiring an IPv6 router-id, the following commands are available:
.. index:: [no] ipv6 router-id X:X::X:X
.. clicmd:: [no] ipv6 router-id X:X::X:X
Configure the IPv6 router-id of this router. Like its IPv4 counterpart,
this command works under the vrf subnode, to allow router-id's per vrf.
.. index:: show ipv6 router-id [vrf NAME]
.. clicmd:: show ipv6 router-id [vrf NAME]
Display the user configured IPv6 router-id.

View File

@ -436,7 +436,8 @@ void zclient_send_reg_requests(struct zclient *zclient, vrf_id_t vrf_id)
vrf_id); vrf_id);
/* We need router-id information. */ /* We need router-id information. */
zebra_message_send(zclient, ZEBRA_ROUTER_ID_ADD, vrf_id); zclient_send_router_id_update(zclient, ZEBRA_ROUTER_ID_ADD, AFI_IP,
vrf_id);
/* We need interface information. */ /* We need interface information. */
zebra_message_send(zclient, ZEBRA_INTERFACE_ADD, vrf_id); zebra_message_send(zclient, ZEBRA_INTERFACE_ADD, vrf_id);
@ -503,7 +504,8 @@ void zclient_send_dereg_requests(struct zclient *zclient, vrf_id_t vrf_id)
vrf_id); vrf_id);
/* We need router-id information. */ /* We need router-id information. */
zebra_message_send(zclient, ZEBRA_ROUTER_ID_DELETE, vrf_id); zclient_send_router_id_update(zclient, ZEBRA_ROUTER_ID_DELETE, AFI_IP,
vrf_id);
zebra_message_send(zclient, ZEBRA_INTERFACE_DELETE, vrf_id); zebra_message_send(zclient, ZEBRA_INTERFACE_DELETE, vrf_id);
@ -554,6 +556,18 @@ void zclient_send_dereg_requests(struct zclient *zclient, vrf_id_t vrf_id)
} }
} }
int zclient_send_router_id_update(struct zclient *zclient,
zebra_message_types_t type, afi_t afi,
vrf_id_t vrf_id)
{
struct stream *s = zclient->obuf;
stream_reset(s);
zclient_create_header(s, type, vrf_id);
stream_putw(s, afi);
stream_putw_at(s, 0, stream_get_endp(s));
return zclient_send_message(zclient);
}
/* Send request to zebra daemon to start or stop RA. */ /* Send request to zebra daemon to start or stop RA. */
void zclient_send_interface_radv_req(struct zclient *zclient, vrf_id_t vrf_id, void zclient_send_interface_radv_req(struct zclient *zclient, vrf_id_t vrf_id,
struct interface *ifp, int enable, struct interface *ifp, int enable,

View File

@ -659,6 +659,9 @@ extern void zclient_send_vrf_label(struct zclient *zclient, vrf_id_t vrf_id,
extern void zclient_send_reg_requests(struct zclient *, vrf_id_t); extern void zclient_send_reg_requests(struct zclient *, vrf_id_t);
extern void zclient_send_dereg_requests(struct zclient *, vrf_id_t); extern void zclient_send_dereg_requests(struct zclient *, vrf_id_t);
extern int zclient_send_router_id_update(struct zclient *zclient,
zebra_message_types_t type, afi_t afi,
vrf_id_t vrf_id);
extern void zclient_send_interface_radv_req(struct zclient *zclient, extern void zclient_send_interface_radv_req(struct zclient *zclient,
vrf_id_t vrf_id, vrf_id_t vrf_id,

View File

@ -59,9 +59,6 @@ static struct connected *router_id_find_node(struct list *l,
static int router_id_bad_address(struct connected *ifc) static int router_id_bad_address(struct connected *ifc)
{ {
if (ifc->address->family != AF_INET)
return 1;
/* non-redistributable addresses shouldn't be used for RIDs either */ /* non-redistributable addresses shouldn't be used for RIDs either */
if (!zebra_check_addr(ifc->address)) if (!zebra_check_addr(ifc->address))
return 1; return 1;
@ -69,40 +66,82 @@ static int router_id_bad_address(struct connected *ifc)
return 0; return 0;
} }
void router_id_get(struct prefix *p, struct zebra_vrf *zvrf) 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)
{ {
struct listnode *node; struct listnode *node;
struct connected *c; struct connected *c;
struct in6_addr *addr = NULL;
p->u.prefix4.s_addr = INADDR_ANY; switch (afi) {
p->family = AF_INET; case AFI_IP:
p->prefixlen = 32; p->u.prefix4.s_addr = INADDR_ANY;
p->family = AF_INET;
if (zvrf->rid_user_assigned.u.prefix4.s_addr != INADDR_ANY) p->prefixlen = 32;
p->u.prefix4.s_addr = zvrf->rid_user_assigned.u.prefix4.s_addr; if (zvrf->rid_user_assigned.u.prefix4.s_addr != INADDR_ANY)
else if (!list_isempty(zvrf->rid_lo_sorted_list)) { p->u.prefix4.s_addr =
node = listtail(zvrf->rid_lo_sorted_list); zvrf->rid_user_assigned.u.prefix4.s_addr;
c = listgetdata(node); else if (!list_isempty(zvrf->rid_lo_sorted_list)) {
p->u.prefix4.s_addr = c->address->u.prefix4.s_addr; node = listtail(zvrf->rid_lo_sorted_list);
} else if (!list_isempty(zvrf->rid_all_sorted_list)) { c = listgetdata(node);
node = listtail(zvrf->rid_all_sorted_list); p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
c = listgetdata(node); } else if (!list_isempty(zvrf->rid_all_sorted_list)) {
p->u.prefix4.s_addr = c->address->u.prefix4.s_addr; 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;
p->prefixlen = 128;
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;
default:
return -1;
} }
} }
static void router_id_set(struct prefix *p, struct zebra_vrf *zvrf) static int router_id_set(afi_t afi, struct prefix *p, struct zebra_vrf *zvrf)
{ {
struct prefix p2; struct prefix p2;
struct listnode *node; struct listnode *node;
struct zserv *client; struct zserv *client;
zvrf->rid_user_assigned.u.prefix4.s_addr = p->u.prefix4.s_addr; 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;
default:
return -1;
}
router_id_get(&p2, zvrf); router_id_get(afi, &p2, zvrf);
for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client))
zsend_router_id_update(client, &p2, zvrf->vrf->vrf_id); zsend_router_id_update(client, afi, &p2, zvrf->vrf->vrf_id);
return 0;
} }
void router_id_add_address(struct connected *ifc) void router_id_add_address(struct connected *ifc)
@ -113,27 +152,42 @@ void router_id_add_address(struct connected *ifc)
struct prefix after; struct prefix after;
struct zserv *client; struct zserv *client;
struct zebra_vrf *zvrf = vrf_info_get(ifc->ifp->vrf_id); struct zebra_vrf *zvrf = vrf_info_get(ifc->ifp->vrf_id);
afi_t afi;
struct list *rid_lo;
struct list *rid_all;
if (router_id_bad_address(ifc)) if (router_id_bad_address(ifc))
return; return;
router_id_get(&before, zvrf); 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;
}
if (if_is_loopback(ifc->ifp)) router_id_get(afi, &before, zvrf);
l = zvrf->rid_lo_sorted_list;
else l = if_is_loopback(ifc->ifp) ? rid_lo : rid_all;
l = zvrf->rid_all_sorted_list;
if (!router_id_find_node(l, ifc)) if (!router_id_find_node(l, ifc))
listnode_add_sort(l, ifc); listnode_add_sort(l, ifc);
router_id_get(&after, zvrf); router_id_get(afi, &after, zvrf);
if (prefix_same(&before, &after)) if (prefix_same(&before, &after))
return; return;
for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client))
zsend_router_id_update(client, &after, zvrf_id(zvrf)); zsend_router_id_update(client, afi, &after, zvrf_id(zvrf));
} }
void router_id_del_address(struct connected *ifc) void router_id_del_address(struct connected *ifc)
@ -145,27 +199,45 @@ void router_id_del_address(struct connected *ifc)
struct listnode *node; struct listnode *node;
struct zserv *client; struct zserv *client;
struct zebra_vrf *zvrf = vrf_info_get(ifc->ifp->vrf_id); struct zebra_vrf *zvrf = vrf_info_get(ifc->ifp->vrf_id);
afi_t afi;
struct list *rid_lo;
struct list *rid_all;
if (router_id_bad_address(ifc)) if (router_id_bad_address(ifc))
return; return;
router_id_get(&before, zvrf); 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);
if (if_is_loopback(ifc->ifp)) if (if_is_loopback(ifc->ifp))
l = zvrf->rid_lo_sorted_list; l = rid_lo;
else else
l = zvrf->rid_all_sorted_list; l = rid_all;
if ((c = router_id_find_node(l, ifc))) if ((c = router_id_find_node(l, ifc)))
listnode_delete(l, c); listnode_delete(l, c);
router_id_get(&after, zvrf); router_id_get(afi, &after, zvrf);
if (prefix_same(&before, &after)) if (prefix_same(&before, &after))
return; return;
for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client))
zsend_router_id_update(client, &after, zvrf_id(zvrf)); zsend_router_id_update(client, afi, &after, zvrf_id(zvrf));
} }
void router_id_write(struct vty *vty, struct zebra_vrf *zvrf) void router_id_write(struct vty *vty, struct zebra_vrf *zvrf)
@ -178,70 +250,147 @@ void router_id_write(struct vty *vty, struct zebra_vrf *zvrf)
snprintf(space, sizeof(space), "%s", " "); snprintf(space, sizeof(space), "%s", " ");
if (zvrf->rid_user_assigned.u.prefix4.s_addr != INADDR_ANY) { if (zvrf->rid_user_assigned.u.prefix4.s_addr != INADDR_ANY) {
vty_out(vty, "%srouter-id %s\n", space, vty_out(vty, "%sip router-id %pI4\n", space,
inet_ntoa(zvrf->rid_user_assigned.u.prefix4)); &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);
} }
} }
DEFUN (router_id, DEFUN (ip_router_id,
router_id_cmd, ip_router_id_cmd,
"router-id A.B.C.D vrf NAME", "ip router-id A.B.C.D vrf NAME",
IP_STR
"Manually set the router-id\n" "Manually set the router-id\n"
"IP address to use for router-id\n" VRF_CMD_HELP_STR) "IP address to use for router-id\n"
VRF_CMD_HELP_STR)
{ {
int idx_ipv4 = 1; int idx = 0;
int idx_name = 3; struct prefix rid;
vrf_id_t vrf_id;
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
struct prefix rid; argv_find(argv, argc, "A.B.C.D", &idx);
vrf_id_t vrf_id = VRF_DEFAULT;
rid.u.prefix4.s_addr = inet_addr(argv[idx_ipv4]->arg); if (!inet_pton(AF_INET, argv[idx]->arg, &rid.u.prefix4))
if (!rid.u.prefix4.s_addr)
return CMD_WARNING_CONFIG_FAILED; return CMD_WARNING_CONFIG_FAILED;
rid.prefixlen = 32; rid.prefixlen = 32;
rid.family = AF_INET; rid.family = AF_INET;
if (argc > 2) argv_find(argv, argc, "NAME", &idx);
VRF_GET_ID(vrf_id, argv[idx_name]->arg, false); VRF_GET_ID(vrf_id, argv[idx]->arg, false);
zvrf = vrf_info_lookup(vrf_id); zvrf = vrf_info_lookup(vrf_id);
router_id_set(&rid, zvrf); router_id_set(AFI_IP, &rid, zvrf);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
DEFUN (router_id_in_vrf, ALIAS (ip_router_id,
router_id_in_vrf_cmd, router_id_cmd,
"router-id A.B.C.D", "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;
rid.prefixlen = 128;
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
"Manuall set the router-id\n" "Manuall set the router-id\n"
"IP address to use for router-id\n") "IP address to use for router-id\n")
{ {
ZEBRA_DECLVAR_CONTEXT(vrf, zvrf); ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
int idx_ipv4 = 1; int idx = 0;
struct prefix rid; struct prefix rid;
rid.u.prefix4.s_addr = inet_addr(argv[idx_ipv4]->arg); argv_find(argv, argc, "A.B.C.D", &idx);
if (!rid.u.prefix4.s_addr)
if (!inet_pton(AF_INET, argv[idx]->arg, &rid.u.prefix4))
return CMD_WARNING_CONFIG_FAILED; return CMD_WARNING_CONFIG_FAILED;
rid.prefixlen = 32; rid.prefixlen = 32;
rid.family = AF_INET; rid.family = AF_INET;
router_id_set(&rid, zvrf); router_id_set(AFI_IP, &rid, zvrf);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
DEFUN (no_router_id, ALIAS (ip_router_id_in_vrf,
no_router_id_cmd, router_id_in_vrf_cmd,
"no router-id [A.B.C.D vrf NAME]", "router-id A.B.C.D",
NO_STR "Manually set the router-id\n"
"Remove the manually configured router-id\n" "IP address to use for router-id\n");
"IP address to use for router-id\n" VRF_CMD_HELP_STR)
DEFUN (ipv6_router_id_in_vrf,
ipv6_router_id_in_vrf_cmd,
"ipv6 router-id X:X::X:X",
IP6_STR
"Manuall set the IPv6 router-id\n"
"IPV6 address to use for router-id\n")
{ {
int idx_name = 4; ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
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;
rid.prefixlen = 128;
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]",
NO_STR
IP_STR
"Remove the manually configured router-id\n"
"IP address to use for router-id\n"
VRF_CMD_HELP_STR)
{
int idx = 0;
struct prefix rid; struct prefix rid;
vrf_id_t vrf_id = VRF_DEFAULT; vrf_id_t vrf_id = VRF_DEFAULT;
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
@ -250,20 +399,55 @@ DEFUN (no_router_id,
rid.prefixlen = 0; rid.prefixlen = 0;
rid.family = AF_INET; rid.family = AF_INET;
if (argc > 3) if (argv_find(argv, argc, "NAME", &idx))
VRF_GET_ID(vrf_id, argv[idx_name]->arg, false); VRF_GET_ID(vrf_id, argv[idx]->arg, false);
zvrf = vrf_info_get(vrf_id); zvrf = vrf_info_lookup(vrf_id);
router_id_set(&rid, zvrf); router_id_set(AFI_IP, &rid, zvrf);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
DEFUN (no_router_id_in_vrf, ALIAS (no_ip_router_id,
no_router_id_in_vrf_cmd, no_router_id_cmd,
"no router-id [A.B.C.D]", "no router-id [A.B.C.D vrf NAME]",
NO_STR NO_STR
"Remove the manually configured router-id\n" "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]",
NO_STR
IP_STR
"Remove the manually configured router-id\n"
"IP address to use for router-id\n") "IP address to use for router-id\n")
{ {
ZEBRA_DECLVAR_CONTEXT(vrf, zvrf); ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
@ -274,40 +458,81 @@ DEFUN (no_router_id_in_vrf,
rid.prefixlen = 0; rid.prefixlen = 0;
rid.family = AF_INET; rid.family = AF_INET;
router_id_set(&rid, zvrf); router_id_set(AFI_IP, &rid, zvrf);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
DEFUN (show_router_id, ALIAS (no_ip_router_id_in_vrf,
show_router_id_cmd, no_router_id_in_vrf_cmd,
"show router-id [vrf NAME]", "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")
{
ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
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]",
SHOW_STR SHOW_STR
IP_STR
IPV6_STR
"Show the configured router-id\n" "Show the configured router-id\n"
VRF_CMD_HELP_STR) VRF_CMD_HELP_STR)
{ {
int idx_name = 3; 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;
vrf_id_t vrf_id = VRF_DEFAULT; is_ipv6 = argv_find(argv, argc, "ipv6", &idx);
struct zebra_vrf *zvrf;
if (argc > 2) if (argv_find(argv, argc, "NAME", &idx)) {
VRF_GET_ID(vrf_id, argv[idx_name]->arg, false); VRF_GET_ID(vrf_id, argv[idx]->arg, false);
vrf_name = argv[idx]->arg;
}
zvrf = vrf_info_get(vrf_id); zvrf = vrf_info_get(vrf_id);
if ((zvrf != NULL) && (zvrf->rid_user_assigned.u.prefix4.s_addr)) { if (zvrf != NULL) {
vty_out(vty, "zebra:\n"); if (is_ipv6) {
if (vrf_id == VRF_DEFAULT) if (router_id_v6_is_any(&zvrf->rid6_user_assigned))
vty_out(vty, " router-id %s vrf default\n", return CMD_SUCCESS;
inet_ntoa(zvrf->rid_user_assigned.u.prefix4)); inet_ntop(AF_INET6, &zvrf->rid6_user_assigned.u.prefix6,
else addr_name, sizeof(addr_name));
vty_out(vty, " router-id %s vrf %s\n", } else {
inet_ntoa(zvrf->rid_user_assigned.u.prefix4), if (zvrf->rid_user_assigned.u.prefix4.s_addr == 0)
argv[idx_name]->arg); return CMD_SUCCESS;
} inet_ntop(AF_INET, &zvrf->rid_user_assigned.u.prefix4,
addr_name, sizeof(addr_name));
}
return CMD_SUCCESS; vty_out(vty, "zebra:\n");
vty_out(vty, " router-id %s vrf %s\n", addr_name, vrf_name);
}
return CMD_SUCCESS;
} }
static int router_id_cmp(void *a, void *b) static int router_id_cmp(void *a, void *b)
@ -319,30 +544,62 @@ static int router_id_cmp(void *a, void *b)
&ifb->address->u.prefix4.s_addr); &ifb->address->u.prefix4.s_addr);
} }
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);
}
void router_id_cmd_init(void) void router_id_cmd_init(void)
{ {
install_element(CONFIG_NODE, &ip_router_id_cmd);
install_element(CONFIG_NODE, &router_id_cmd); install_element(CONFIG_NODE, &router_id_cmd);
install_element(CONFIG_NODE, &ipv6_router_id_cmd);
install_element(CONFIG_NODE, &no_ip_router_id_cmd);
install_element(CONFIG_NODE, &no_router_id_cmd); install_element(CONFIG_NODE, &no_router_id_cmd);
install_element(CONFIG_NODE, &ip_router_id_in_vrf_cmd);
install_element(VRF_NODE, &ip_router_id_in_vrf_cmd);
install_element(CONFIG_NODE, &router_id_in_vrf_cmd); install_element(CONFIG_NODE, &router_id_in_vrf_cmd);
install_element(VRF_NODE, &router_id_in_vrf_cmd); install_element(VRF_NODE, &router_id_in_vrf_cmd);
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);
install_element(CONFIG_NODE, &no_router_id_in_vrf_cmd); install_element(CONFIG_NODE, &no_router_id_in_vrf_cmd);
install_element(VRF_NODE, &no_router_id_in_vrf_cmd); install_element(VRF_NODE, &no_router_id_in_vrf_cmd);
install_element(VIEW_NODE, &show_router_id_cmd); 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);
} }
void router_id_init(struct zebra_vrf *zvrf) void router_id_init(struct zebra_vrf *zvrf)
{ {
zvrf->rid_all_sorted_list = &zvrf->_rid_all_sorted_list; zvrf->rid_all_sorted_list = &zvrf->_rid_all_sorted_list;
zvrf->rid_lo_sorted_list = &zvrf->_rid_lo_sorted_list; zvrf->rid_lo_sorted_list = &zvrf->_rid_lo_sorted_list;
zvrf->rid6_all_sorted_list = &zvrf->_rid6_all_sorted_list;
zvrf->rid6_lo_sorted_list = &zvrf->_rid6_lo_sorted_list;
memset(zvrf->rid_all_sorted_list, 0, memset(zvrf->rid_all_sorted_list, 0,
sizeof(zvrf->_rid_all_sorted_list)); sizeof(zvrf->_rid_all_sorted_list));
memset(zvrf->rid_lo_sorted_list, 0, sizeof(zvrf->_rid_lo_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)); memset(&zvrf->rid_user_assigned, 0, sizeof(zvrf->rid_user_assigned));
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));
zvrf->rid_all_sorted_list->cmp = router_id_cmp; zvrf->rid_all_sorted_list->cmp = router_id_cmp;
zvrf->rid_lo_sorted_list->cmp = router_id_cmp; zvrf->rid_lo_sorted_list->cmp = router_id_cmp;
zvrf->rid6_all_sorted_list->cmp = router_id_v6_cmp;
zvrf->rid6_lo_sorted_list->cmp = router_id_v6_cmp;
zvrf->rid_user_assigned.family = AF_INET; zvrf->rid_user_assigned.family = AF_INET;
zvrf->rid_user_assigned.prefixlen = 32; zvrf->rid_user_assigned.prefixlen = 32;
zvrf->rid6_user_assigned.family = AF_INET6;
zvrf->rid6_user_assigned.prefixlen = 128;
} }

View File

@ -39,7 +39,7 @@ extern void router_id_del_address(struct connected *c);
extern void router_id_init(struct zebra_vrf *zvrf); extern void router_id_init(struct zebra_vrf *zvrf);
extern void router_id_cmd_init(void); extern void router_id_cmd_init(void);
extern void router_id_write(struct vty *vty, struct zebra_vrf *zvrf); extern void router_id_write(struct vty *vty, struct zebra_vrf *zvrf);
extern void router_id_get(struct prefix *p, struct zebra_vrf *zvrf); extern int router_id_get(afi_t afi, struct prefix *p, struct zebra_vrf *zvrf);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -907,17 +907,18 @@ void zsend_iptable_notify_owner(struct zebra_pbr_iptable *iptable,
zserv_send_message(client, s); zserv_send_message(client, s);
} }
/* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */ /* Router-id is updated. Send ZEBRA_ROUTER_ID_UPDATE to client. */
int zsend_router_id_update(struct zserv *client, struct prefix *p, int zsend_router_id_update(struct zserv *client, afi_t afi, struct prefix *p,
vrf_id_t vrf_id) vrf_id_t vrf_id)
{ {
int blen; int blen;
struct stream *s;
/* Check this client need interface information. */ /* Check this client need interface information. */
if (!vrf_bitmap_check(client->ridinfo, vrf_id)) if (!vrf_bitmap_check(client->ridinfo[afi], vrf_id))
return 0; return 0;
struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ); s = stream_new(ZEBRA_MAX_PACKET_SIZ);
/* Message type. */ /* Message type. */
zclient_create_header(s, ZEBRA_ROUTER_ID_UPDATE, vrf_id); zclient_create_header(s, ZEBRA_ROUTER_ID_UPDATE, vrf_id);
@ -1897,20 +1898,48 @@ stream_failure:
/* Register zebra server router-id information. Send current router-id */ /* Register zebra server router-id information. Send current router-id */
static void zread_router_id_add(ZAPI_HANDLER_ARGS) static void zread_router_id_add(ZAPI_HANDLER_ARGS)
{ {
afi_t afi;
struct prefix p; struct prefix p;
STREAM_GETW(msg, afi);
if (afi <= AFI_UNSPEC || afi >= AFI_MAX) {
zlog_warn(
"Invalid AFI %u while registering for router ID notifications",
afi);
goto stream_failure;
}
/* Router-id information is needed. */ /* Router-id information is needed. */
vrf_bitmap_set(client->ridinfo, zvrf_id(zvrf)); vrf_bitmap_set(client->ridinfo[afi], zvrf_id(zvrf));
router_id_get(&p, zvrf); router_id_get(afi, &p, zvrf);
zsend_router_id_update(client, &p, zvrf_id(zvrf)); zsend_router_id_update(client, afi, &p, zvrf_id(zvrf));
stream_failure:
return;
} }
/* Unregister zebra server router-id information. */ /* Unregister zebra server router-id information. */
static void zread_router_id_delete(ZAPI_HANDLER_ARGS) static void zread_router_id_delete(ZAPI_HANDLER_ARGS)
{ {
vrf_bitmap_unset(client->ridinfo, zvrf_id(zvrf)); afi_t afi;
STREAM_GETW(msg, afi);
if (afi <= AFI_UNSPEC || afi >= AFI_MAX) {
zlog_warn(
"Invalid AFI %u while unregistering from router ID notifications",
afi);
goto stream_failure;
}
vrf_bitmap_unset(client->ridinfo[afi], zvrf_id(zvrf));
stream_failure:
return;
} }
static void zsend_capabilities(struct zserv *client, struct zebra_vrf *zvrf) static void zsend_capabilities(struct zserv *client, struct zebra_vrf *zvrf)
@ -1999,8 +2028,8 @@ static void zread_vrf_unregister(ZAPI_HANDLER_ARGS)
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
vrf_bitmap_unset(client->redist[afi][i], zvrf_id(zvrf)); vrf_bitmap_unset(client->redist[afi][i], zvrf_id(zvrf));
vrf_bitmap_unset(client->redist_default[afi], zvrf_id(zvrf)); vrf_bitmap_unset(client->redist_default[afi], zvrf_id(zvrf));
vrf_bitmap_unset(client->ridinfo[afi], zvrf_id(zvrf));
} }
vrf_bitmap_unset(client->ridinfo, zvrf_id(zvrf));
} }
/* /*

View File

@ -68,8 +68,8 @@ extern int zsend_redistribute_route(int cmd, struct zserv *zclient,
const struct prefix *src_p, const struct prefix *src_p,
const struct route_entry *re); const struct route_entry *re);
extern int zsend_router_id_update(struct zserv *zclient, struct prefix *p, extern int zsend_router_id_update(struct zserv *zclient, afi_t afi,
vrf_id_t vrf_id); struct prefix *p, vrf_id_t vrf_id);
extern int zsend_interface_vrf_update(struct zserv *zclient, extern int zsend_interface_vrf_update(struct zserv *zclient,
struct interface *ifp, vrf_id_t vrf_id); struct interface *ifp, vrf_id_t vrf_id);
extern int zsend_interface_link_params(struct zserv *zclient, extern int zsend_interface_link_params(struct zserv *zclient,

View File

@ -92,6 +92,11 @@ struct zebra_vrf {
struct list *rid_all_sorted_list; struct list *rid_all_sorted_list;
struct list *rid_lo_sorted_list; struct list *rid_lo_sorted_list;
struct prefix rid_user_assigned; struct prefix rid_user_assigned;
struct list _rid6_all_sorted_list;
struct list _rid6_lo_sorted_list;
struct list *rid6_all_sorted_list;
struct list *rid6_lo_sorted_list;
struct prefix rid6_user_assigned;
/* /*
* Back pointer to the owning namespace. * Back pointer to the owning namespace.

View File

@ -628,8 +628,8 @@ static void zserv_client_free(struct zserv *client)
} }
vrf_bitmap_free(client->redist_default[afi]); vrf_bitmap_free(client->redist_default[afi]);
vrf_bitmap_free(client->ridinfo[afi]);
} }
vrf_bitmap_free(client->ridinfo);
/* /*
* If any instance are graceful restart enabled, * If any instance are graceful restart enabled,
@ -750,8 +750,8 @@ static struct zserv *zserv_client_create(int sock)
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
client->redist[afi][i] = vrf_bitmap_init(); client->redist[afi][i] = vrf_bitmap_init();
client->redist_default[afi] = vrf_bitmap_init(); client->redist_default[afi] = vrf_bitmap_init();
client->ridinfo[afi] = vrf_bitmap_init();
} }
client->ridinfo = vrf_bitmap_init();
/* Add this client to linked list. */ /* Add this client to linked list. */
frr_with_mutex(&client_mutex) { frr_with_mutex(&client_mutex) {

View File

@ -135,7 +135,7 @@ struct zserv {
vrf_bitmap_t redist_default[AFI_MAX]; vrf_bitmap_t redist_default[AFI_MAX];
/* Router-id information. */ /* Router-id information. */
vrf_bitmap_t ridinfo; vrf_bitmap_t ridinfo[AFI_MAX];
bool notify_owner; bool notify_owner;