summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/user/zebra.rst27
-rw-r--r--lib/zclient.c18
-rw-r--r--lib/zclient.h3
-rw-r--r--zebra/router-id.c439
-rw-r--r--zebra/router-id.h2
-rw-r--r--zebra/zapi_msg.c47
-rw-r--r--zebra/zapi_msg.h4
-rw-r--r--zebra/zebra_vrf.h5
-rw-r--r--zebra/zserv.c4
-rw-r--r--zebra/zserv.h2
10 files changed, 435 insertions, 116 deletions
diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst
index 7b028fd67..a9ab162b4 100644
--- a/doc/user/zebra.rst
+++ b/doc/user/zebra.rst
@@ -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
to configure and display the router-id:
-.. index:: [no] router-id A.B.C.D
-.. clicmd:: [no] router-id A.B.C.D
+.. index:: [no] [ip] 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
- 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
-.. clicmd:: [no] router-id A.B.C.D vrf NAME
+.. index:: [no] [ip] 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.
A show run of this command will display the router-id command
under the vrf sub node. This command is deprecated and will
be removed at some point in time in the future.
-
-.. index:: show router-id [vrf NAME]
-.. clicmd:: show router-id [vrf NAME]
+
+.. index:: show [ip] router-id [vrf NAME]
+.. clicmd:: show [ip] router-id [vrf NAME]
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.
diff --git a/lib/zclient.c b/lib/zclient.c
index eb62350f4..250d697bb 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -436,7 +436,8 @@ void zclient_send_reg_requests(struct zclient *zclient, vrf_id_t vrf_id)
vrf_id);
/* 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. */
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);
/* 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);
@@ -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. */
void zclient_send_interface_radv_req(struct zclient *zclient, vrf_id_t vrf_id,
struct interface *ifp, int enable,
diff --git a/lib/zclient.h b/lib/zclient.h
index da06239d0..f1730f15b 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -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_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,
vrf_id_t vrf_id,
diff --git a/zebra/router-id.c b/zebra/router-id.c
index ba9e72161..7e81f2982 100644
--- a/zebra/router-id.c
+++ b/zebra/router-id.c
@@ -59,9 +59,6 @@ static struct connected *router_id_find_node(struct list *l,
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 */
if (!zebra_check_addr(ifc->address))
return 1;
@@ -69,40 +66,82 @@ static int router_id_bad_address(struct connected *ifc)
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 connected *c;
-
- p->u.prefix4.s_addr = INADDR_ANY;
- p->family = AF_INET;
- p->prefixlen = 32;
-
- 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;
+ struct in6_addr *addr = NULL;
+
+ switch (afi) {
+ case AFI_IP:
+ p->u.prefix4.s_addr = INADDR_ANY;
+ p->family = AF_INET;
+ p->prefixlen = 32;
+ 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;
+ 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 listnode *node;
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))
- 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)
@@ -113,27 +152,42 @@ void router_id_add_address(struct connected *ifc)
struct prefix after;
struct zserv *client;
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))
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))
- l = zvrf->rid_lo_sorted_list;
- else
- l = zvrf->rid_all_sorted_list;
+ router_id_get(afi, &before, zvrf);
+
+ l = if_is_loopback(ifc->ifp) ? rid_lo : rid_all;
if (!router_id_find_node(l, ifc))
listnode_add_sort(l, ifc);
- router_id_get(&after, zvrf);
+ router_id_get(afi, &after, zvrf);
if (prefix_same(&before, &after))
return;
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)
@@ -145,27 +199,45 @@ void router_id_del_address(struct connected *ifc)
struct listnode *node;
struct zserv *client;
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))
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))
- l = zvrf->rid_lo_sorted_list;
+ l = rid_lo;
else
- l = zvrf->rid_all_sorted_list;
+ l = rid_all;
if ((c = router_id_find_node(l, ifc)))
listnode_delete(l, c);
- router_id_get(&after, zvrf);
+ router_id_get(afi, &after, zvrf);
if (prefix_same(&before, &after))
return;
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)
@@ -178,70 +250,147 @@ void router_id_write(struct vty *vty, struct zebra_vrf *zvrf)
snprintf(space, sizeof(space), "%s", " ");
if (zvrf->rid_user_assigned.u.prefix4.s_addr != INADDR_ANY) {
- vty_out(vty, "%srouter-id %s\n", space,
- inet_ntoa(zvrf->rid_user_assigned.u.prefix4));
+ 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);
}
}
-DEFUN (router_id,
- router_id_cmd,
- "router-id A.B.C.D vrf NAME",
+DEFUN (ip_router_id,
+ ip_router_id_cmd,
+ "ip router-id A.B.C.D vrf NAME",
+ IP_STR
"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_name = 3;
+ int idx = 0;
+ struct prefix rid;
+ vrf_id_t vrf_id;
struct zebra_vrf *zvrf;
- struct prefix rid;
- vrf_id_t vrf_id = VRF_DEFAULT;
+ argv_find(argv, argc, "A.B.C.D", &idx);
- rid.u.prefix4.s_addr = inet_addr(argv[idx_ipv4]->arg);
- if (!rid.u.prefix4.s_addr)
+ if (!inet_pton(AF_INET, argv[idx]->arg, &rid.u.prefix4))
return CMD_WARNING_CONFIG_FAILED;
rid.prefixlen = 32;
rid.family = AF_INET;
- if (argc > 2)
- VRF_GET_ID(vrf_id, argv[idx_name]->arg, false);
+ argv_find(argv, argc, "NAME", &idx);
+ VRF_GET_ID(vrf_id, argv[idx]->arg, false);
zvrf = vrf_info_lookup(vrf_id);
- router_id_set(&rid, zvrf);
+ router_id_set(AFI_IP, &rid, zvrf);
return CMD_SUCCESS;
}
-DEFUN (router_id_in_vrf,
- router_id_in_vrf_cmd,
- "router-id A.B.C.D",
+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;
+
+ 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"
"IP address to use for router-id\n")
{
ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
- int idx_ipv4 = 1;
+ int idx = 0;
struct prefix rid;
- rid.u.prefix4.s_addr = inet_addr(argv[idx_ipv4]->arg);
- if (!rid.u.prefix4.s_addr)
+ argv_find(argv, argc, "A.B.C.D", &idx);
+
+ if (!inet_pton(AF_INET, argv[idx]->arg, &rid.u.prefix4))
return CMD_WARNING_CONFIG_FAILED;
rid.prefixlen = 32;
rid.family = AF_INET;
- router_id_set(&rid, zvrf);
+ router_id_set(AFI_IP, &rid, zvrf);
return CMD_SUCCESS;
}
-DEFUN (no_router_id,
- no_router_id_cmd,
- "no router-id [A.B.C.D vrf NAME]",
+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
+ "Manuall set the IPv6 router-id\n"
+ "IPV6 address to use for router-id\n")
+{
+ 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)
+ "IP address to use for router-id\n"
+ VRF_CMD_HELP_STR)
{
- int idx_name = 4;
+ int idx = 0;
struct prefix rid;
vrf_id_t vrf_id = VRF_DEFAULT;
struct zebra_vrf *zvrf;
@@ -250,19 +399,54 @@ DEFUN (no_router_id,
rid.prefixlen = 0;
rid.family = AF_INET;
- if (argc > 3)
- VRF_GET_ID(vrf_id, argv[idx_name]->arg, false);
+ if (argv_find(argv, argc, "NAME", &idx))
+ VRF_GET_ID(vrf_id, argv[idx]->arg, false);
- zvrf = vrf_info_get(vrf_id);
- router_id_set(&rid, zvrf);
+ zvrf = vrf_info_lookup(vrf_id);
+ router_id_set(AFI_IP, &rid, zvrf);
return CMD_SUCCESS;
}
-DEFUN (no_router_id_in_vrf,
- no_router_id_in_vrf_cmd,
- "no router-id [A.B.C.D]",
+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]",
NO_STR
+ IP_STR
"Remove the manually configured router-id\n"
"IP address to use for router-id\n")
{
@@ -274,40 +458,81 @@ DEFUN (no_router_id_in_vrf,
rid.prefixlen = 0;
rid.family = AF_INET;
- router_id_set(&rid, zvrf);
+ router_id_set(AFI_IP, &rid, zvrf);
return CMD_SUCCESS;
}
-DEFUN (show_router_id,
- show_router_id_cmd,
- "show router-id [vrf NAME]",
+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")
+{
+ 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
+ IP_STR
+ IPV6_STR
"Show the configured router-id\n"
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;
- struct zebra_vrf *zvrf;
+ is_ipv6 = argv_find(argv, argc, "ipv6", &idx);
- if (argc > 2)
- VRF_GET_ID(vrf_id, argv[idx_name]->arg, false);
+ if (argv_find(argv, argc, "NAME", &idx)) {
+ 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)) {
- vty_out(vty, "zebra:\n");
- if (vrf_id == VRF_DEFAULT)
- vty_out(vty, " router-id %s vrf default\n",
- inet_ntoa(zvrf->rid_user_assigned.u.prefix4));
- else
- vty_out(vty, " router-id %s vrf %s\n",
- inet_ntoa(zvrf->rid_user_assigned.u.prefix4),
- argv[idx_name]->arg);
- }
+ 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 {
+ if (zvrf->rid_user_assigned.u.prefix4.s_addr == 0)
+ 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);
+ }
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
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);
}
+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)
{
+ install_element(CONFIG_NODE, &ip_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, &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(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(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)
{
zvrf->rid_all_sorted_list = &zvrf->_rid_all_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,
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));
+ 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_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.prefixlen = 32;
+ zvrf->rid6_user_assigned.family = AF_INET6;
+ zvrf->rid6_user_assigned.prefixlen = 128;
}
diff --git a/zebra/router-id.h b/zebra/router-id.h
index c69c321fd..4a35f6605 100644
--- a/zebra/router-id.h
+++ b/zebra/router-id.h
@@ -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_cmd_init(void);
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
}
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index 0a459b4d0..48aa56613 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -907,17 +907,18 @@ void zsend_iptable_notify_owner(struct zebra_pbr_iptable *iptable,
zserv_send_message(client, s);
}
-/* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
-int zsend_router_id_update(struct zserv *client, struct prefix *p,
+/* Router-id is updated. Send ZEBRA_ROUTER_ID_UPDATE to client. */
+int zsend_router_id_update(struct zserv *client, afi_t afi, struct prefix *p,
vrf_id_t vrf_id)
{
int blen;
+ struct stream *s;
/* 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;
- struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
+ s = stream_new(ZEBRA_MAX_PACKET_SIZ);
/* Message type. */
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 */
static void zread_router_id_add(ZAPI_HANDLER_ARGS)
{
+ afi_t afi;
+
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. */
- 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. */
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)
@@ -1999,8 +2028,8 @@ static void zread_vrf_unregister(ZAPI_HANDLER_ARGS)
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
vrf_bitmap_unset(client->redist[afi][i], 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));
}
/*
diff --git a/zebra/zapi_msg.h b/zebra/zapi_msg.h
index eb50e3c41..13beb6a27 100644
--- a/zebra/zapi_msg.h
+++ b/zebra/zapi_msg.h
@@ -68,8 +68,8 @@ extern int zsend_redistribute_route(int cmd, struct zserv *zclient,
const struct prefix *src_p,
const struct route_entry *re);
-extern int zsend_router_id_update(struct zserv *zclient, struct prefix *p,
- vrf_id_t vrf_id);
+extern int zsend_router_id_update(struct zserv *zclient, afi_t afi,
+ struct prefix *p, vrf_id_t vrf_id);
extern int zsend_interface_vrf_update(struct zserv *zclient,
struct interface *ifp, vrf_id_t vrf_id);
extern int zsend_interface_link_params(struct zserv *zclient,
diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h
index d262faa07..d200f5a4c 100644
--- a/zebra/zebra_vrf.h
+++ b/zebra/zebra_vrf.h
@@ -92,6 +92,11 @@ struct zebra_vrf {
struct list *rid_all_sorted_list;
struct list *rid_lo_sorted_list;
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.
diff --git a/zebra/zserv.c b/zebra/zserv.c
index f1b7dcc84..cded6ea12 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -628,8 +628,8 @@ static void zserv_client_free(struct zserv *client)
}
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,
@@ -750,8 +750,8 @@ static struct zserv *zserv_client_create(int sock)
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
client->redist[afi][i] = 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. */
frr_with_mutex(&client_mutex) {
diff --git a/zebra/zserv.h b/zebra/zserv.h
index e90446078..54e840cd5 100644
--- a/zebra/zserv.h
+++ b/zebra/zserv.h
@@ -135,7 +135,7 @@ struct zserv {
vrf_bitmap_t redist_default[AFI_MAX];
/* Router-id information. */
- vrf_bitmap_t ridinfo;
+ vrf_bitmap_t ridinfo[AFI_MAX];
bool notify_owner;