diff options
-rw-r--r-- | doc/user/zebra.rst | 27 | ||||
-rw-r--r-- | lib/zclient.c | 18 | ||||
-rw-r--r-- | lib/zclient.h | 3 | ||||
-rw-r--r-- | zebra/router-id.c | 439 | ||||
-rw-r--r-- | zebra/router-id.h | 2 | ||||
-rw-r--r-- | zebra/zapi_msg.c | 47 | ||||
-rw-r--r-- | zebra/zapi_msg.h | 4 | ||||
-rw-r--r-- | zebra/zebra_vrf.h | 5 | ||||
-rw-r--r-- | zebra/zserv.c | 4 | ||||
-rw-r--r-- | zebra/zserv.h | 2 |
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; |