From 1cfaf93c5e7512bf235613f651ef21440fbde792 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Thu, 10 Nov 2016 12:53:21 -0200 Subject: [PATCH 01/44] ripd: reject authentication strings with zeros in the middle RFC 2453 says: "If the password is under 16 octets, it must be left-justified and padded to the right with nulls (0x00)". Fixes IxANVL RIP test 10.3. Signed-off-by: Renato Westphal --- ripd/ripd.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/ripd/ripd.c b/ripd/ripd.c index 6124471161..ce7a6d1e99 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -812,7 +812,15 @@ rip_auth_simple_password (struct rte *rte, struct sockaddr_in *from, struct interface *ifp) { struct rip_interface *ri; - char *auth_str; + char *auth_str = (char *) &rte->prefix; + int i; + + /* reject passwords with zeros in the middle of the string */ + for (i = strlen (auth_str); i < 16; i++) + { + if (auth_str[i] != '\0') + return 0; + } if (IS_RIP_DEBUG_EVENT) zlog_debug ("RIPv2 simple password authentication from %s", @@ -827,8 +835,6 @@ rip_auth_simple_password (struct rte *rte, struct sockaddr_in *from, /* Simple password authentication. */ if (ri->auth_str) { - auth_str = (char *) &rte->prefix; - if (strncmp (auth_str, ri->auth_str, 16) == 0) return 1; } @@ -841,7 +847,7 @@ rip_auth_simple_password (struct rte *rte, struct sockaddr_in *from, if (keychain == NULL) return 0; - key = key_match_for_accept (keychain, (char *) &rte->prefix); + key = key_match_for_accept (keychain, auth_str); if (key) return 1; } From 4e0548665d50db273cceddb0210d5be9d25688c1 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Thu, 10 Nov 2016 12:54:07 -0200 Subject: [PATCH 02/44] ripd: ignore request for RTEs from unknown address-families Fixes IxANVL RIP test 6.5. Signed-off-by: Renato Westphal --- ripd/ripd.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ripd/ripd.c b/ripd/ripd.c index ce7a6d1e99..d84f863de2 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -1687,6 +1687,9 @@ rip_request_process (struct rip_packet *packet, int size, } else { + if (ntohs (rte->family) != AF_INET) + return; + /* Examine the list of RTEs in the Request one by one. For each entry, look up the destination in the router's routing database and, if there is a route, put that route's metric in From f90310cfe8a5d17357a0e31cb7e55eb7d6024092 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Thu, 10 Nov 2016 12:55:09 -0200 Subject: [PATCH 03/44] ripd: implement the "ip rip v2-broadcast" CLI command This command allows ripd to send v2 updates as broadcast packets instead of multicast packets. Useful as a technique to help with RIPv1/v2 interop issues. Fixes IxANVL RIP test 16.2 Signed-off-by: Renato Westphal --- ripd/rip_interface.c | 46 +++++++++++++++++++++++++++++++++++++++++++- ripd/ripd.c | 10 ++++++---- ripd/ripd.h | 3 +++ 3 files changed, 54 insertions(+), 5 deletions(-) diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c index 359549ed80..0d412ee997 100644 --- a/ripd/rip_interface.c +++ b/ripd/rip_interface.c @@ -536,7 +536,9 @@ rip_interface_reset (struct rip_interface *ri) ri->ri_send = RI_RIP_UNSPEC; ri->ri_receive = RI_RIP_UNSPEC; - + + ri->v2_broadcast = 0; + if (ri->auth_str) { free (ri->auth_str); @@ -1518,6 +1520,41 @@ ALIAS (no_ip_rip_send_version, "Version 1\n" "Version 2\n") +DEFUN (ip_rip_v2_broadcast, + ip_rip_v2_broadcast_cmd, + "ip rip v2-broadcast", + IP_STR + "Routing Information Protocol\n" + "Send ip broadcast v2 update\n") +{ + struct interface *ifp; + struct rip_interface *ri; + + ifp = (struct interface *)vty->index; + ri = ifp->info; + + ri->v2_broadcast = 1; + return CMD_SUCCESS; +} + +DEFUN (no_ip_rip_v2_broadcast, + no_ip_rip_v2_broadcast_cmd, + "no ip rip v2-broadcast", + NO_STR + IP_STR + "Routing Information Protocol\n" + "Send ip broadcast v2 update\n") +{ + struct interface *ifp; + struct rip_interface *ri; + + ifp = (struct interface *)vty->index; + ri = ifp->info; + + ri->v2_broadcast = 0; + return CMD_SUCCESS; +} + DEFUN (ip_rip_authentication_mode, ip_rip_authentication_mode_cmd, "ip rip authentication mode (md5|text)", @@ -1918,6 +1955,7 @@ rip_interface_config_write (struct vty *vty) (ri->ri_send == RI_RIP_UNSPEC) && (ri->ri_receive == RI_RIP_UNSPEC) && (ri->auth_type != RIP_AUTH_MD5) && + (!ri->v2_broadcast) && (ri->md5_auth_len != RIP_AUTH_MD5_SIZE) && (!ri->auth_str) && (!ri->key_chain) ) @@ -1959,6 +1997,9 @@ rip_interface_config_write (struct vty *vty) lookup (ri_version_msg, ri->ri_receive), VTY_NEWLINE); + if (ri->v2_broadcast) + vty_out (vty, " ip rip v2-broadcast%s", VTY_NEWLINE); + /* RIP authentication. */ if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD) vty_out (vty, " ip rip authentication mode text%s", VTY_NEWLINE); @@ -2099,6 +2140,9 @@ rip_if_init (void) install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd); install_element (INTERFACE_NODE, &no_ip_rip_receive_version_num_cmd); + install_element (INTERFACE_NODE, &ip_rip_v2_broadcast_cmd); + install_element (INTERFACE_NODE, &no_ip_rip_v2_broadcast_cmd); + install_element (INTERFACE_NODE, &ip_rip_authentication_mode_cmd); install_element (INTERFACE_NODE, &ip_rip_authentication_mode_authlen_cmd); install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd); diff --git a/ripd/ripd.c b/ripd/ripd.c index d84f863de2..97e80ed43b 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -2443,20 +2443,22 @@ rip_output_process (struct connected *ifc, struct sockaddr_in *to, static void rip_update_interface (struct connected *ifc, u_char version, int route_type) { + struct interface *ifp = ifc->ifp; + struct rip_interface *ri = ifp->info; struct sockaddr_in to; /* When RIP version is 2 and multicast enable interface. */ - if (version == RIPv2 && if_is_multicast (ifc->ifp)) + if (version == RIPv2 && !ri->v2_broadcast && if_is_multicast (ifp)) { if (IS_RIP_DEBUG_EVENT) - zlog_debug ("multicast announce on %s ", ifc->ifp->name); + zlog_debug ("multicast announce on %s ", ifp->name); rip_output_process (ifc, NULL, route_type, version); return; } /* If we can't send multicast packet, send it with unicast. */ - if (if_is_broadcast (ifc->ifp) || if_is_pointopoint (ifc->ifp)) + if (if_is_broadcast (ifp) || if_is_pointopoint (ifp)) { if (ifc->address->family == AF_INET) { @@ -2478,7 +2480,7 @@ rip_update_interface (struct connected *ifc, u_char version, int route_type) if (IS_RIP_DEBUG_EVENT) zlog_debug("%s announce to %s on %s", CONNECTED_PEER(ifc) ? "unicast" : "broadcast", - inet_ntoa (to.sin_addr), ifc->ifp->name); + inet_ntoa (to.sin_addr), ifp->name); rip_output_process (ifc, &to, route_type, version); } diff --git a/ripd/ripd.h b/ripd/ripd.h index 3de23ec334..1c212a081b 100644 --- a/ripd/ripd.h +++ b/ripd/ripd.h @@ -258,6 +258,9 @@ struct rip_interface int ri_send; int ri_receive; + /* RIPv2 broadcast mode */ + int v2_broadcast; + /* RIPv2 authentication type. */ int auth_type; From 6aec4b41760e6ba54fc52b09f6d3ecfe173f6ee6 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Thu, 10 Nov 2016 13:15:43 -0200 Subject: [PATCH 04/44] ripd: add "none" option to the "ip rip receive version" command RFC 2453 says (section 5.1): "(...) For completeness, routers should also implement a receive control switch which would determine whether to accept, RIP-1 only, RIP-2 only, both, or none. It should also be configurable on a per-interface basis". For the "ip rip send version" command, we don't need to implement the "none" option because there's already the "passive-interface" command for that. Fixes IxANVL RIP test 16.8. Signed-off-by: Renato Westphal --- ripd/rip_interface.c | 20 +++++++++++++------- ripd/ripd.c | 12 +++--------- ripd/ripd.h | 1 + 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c index 0d412ee997..6d6cb0c686 100644 --- a/ripd/rip_interface.c +++ b/ripd/rip_interface.c @@ -55,6 +55,7 @@ const struct message ri_version_msg[] = {RI_RIP_VERSION_1, "1"}, {RI_RIP_VERSION_2, "2"}, {RI_RIP_VERSION_1_AND_2, "1 2"}, + {RI_RIP_VERSION_NONE, "none"}, }; extern struct zebra_privs_t ripd_privs; @@ -1318,13 +1319,14 @@ DEFUN (no_rip_neighbor, DEFUN (ip_rip_receive_version, ip_rip_receive_version_cmd, - "ip rip receive version (1|2)", + "ip rip receive version (1|2|none)", IP_STR "Routing Information Protocol\n" "Advertisement reception\n" "Version control\n" "RIP version 1\n" - "RIP version 2\n") + "RIP version 2\n" + "None\n") { struct interface *ifp; struct rip_interface *ri; @@ -1332,17 +1334,21 @@ DEFUN (ip_rip_receive_version, ifp = (struct interface *)vty->index; ri = ifp->info; - /* Version 1. */ - if (atoi (argv[0]) == 1) + switch (*argv[0]) { + case '1': ri->ri_receive = RI_RIP_VERSION_1; return CMD_SUCCESS; - } - if (atoi (argv[0]) == 2) - { + case '2': ri->ri_receive = RI_RIP_VERSION_2; return CMD_SUCCESS; + case 'n': + ri->ri_receive = RI_RIP_VERSION_NONE; + return CMD_SUCCESS; + default: + break; } + return CMD_WARNING; } diff --git a/ripd/ripd.c b/ripd/ripd.c index 97e80ed43b..f27a817aed 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -1937,15 +1937,9 @@ rip_read (struct thread *t) /* RIP Version check. RFC2453, 4.6 and 5.1 */ vrecv = ((ri->ri_receive == RI_RIP_UNSPEC) ? rip->version_recv : ri->ri_receive); - if ((packet->version == RIPv1) && !(vrecv & RIPv1)) - { - if (IS_RIP_DEBUG_PACKET) - zlog_debug (" packet's v%d doesn't fit to if version spec", - packet->version); - rip_peer_bad_packet (&from); - return -1; - } - if ((packet->version == RIPv2) && !(vrecv & RIPv2)) + if (vrecv == RI_RIP_VERSION_NONE || + ((packet->version == RIPv1) && !(vrecv & RIPv1)) || + ((packet->version == RIPv2) && !(vrecv & RIPv2))) { if (IS_RIP_DEBUG_PACKET) zlog_debug (" packet's v%d doesn't fit to if version spec", diff --git a/ripd/ripd.h b/ripd/ripd.h index 1c212a081b..b26a1d234c 100644 --- a/ripd/ripd.h +++ b/ripd/ripd.h @@ -350,6 +350,7 @@ struct rip_md5_data #define RI_RIP_VERSION_1 1 #define RI_RIP_VERSION_2 2 #define RI_RIP_VERSION_1_AND_2 3 +#define RI_RIP_VERSION_NONE 4 /* N.B. stuff will break if (RIPv1 != RI_RIP_VERSION_1) || (RIPv2 != RI_RIP_VERSION_2) */ From b10ce841035275844cfe494d471865c8a1d4dda6 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Thu, 10 Nov 2016 15:35:47 -0200 Subject: [PATCH 05/44] ripd: fix the "neighbor" command. We can't use if_lookup_prefix() in rip_update_process() because this function uses prefix_cmp() internally to try matching an interface address to a static neighbor's address. Since prefix_cmp() tries to match exact prefixes, if_lookup_prefix() was always returning NULL. What we really need here is to use prefix_match(), which checks if one prefix includes the other (e.g. one /24 interface including a /32 static neighbor's address). The fix then is to replace the call to if_lookup_prefix() and use if_lookup_address() instead, which uses prefix_match() internally. Fixes IxANVL RIP test 17.1 Signed-off-by: Renato Westphal --- lib/if.c | 8 ++++---- lib/if.h | 4 ++-- ospfd/ospf_packet.c | 18 +++++++++++------- ripd/ripd.c | 19 +++++++------------ 4 files changed, 24 insertions(+), 25 deletions(-) diff --git a/lib/if.c b/lib/if.c index 6ae8500291..b52358fa87 100644 --- a/lib/if.c +++ b/lib/if.c @@ -393,7 +393,7 @@ if_lookup_exact_address (void *src, int family) } /* Lookup interface by IPv4 address. */ -struct interface * +struct connected * if_lookup_address_vrf (void *matchaddr, int family, vrf_id_t vrf_id) { struct listnode *node; @@ -402,7 +402,7 @@ if_lookup_address_vrf (void *matchaddr, int family, vrf_id_t vrf_id) struct listnode *cnode; struct interface *ifp; struct connected *c; - struct interface *match; + struct connected *match; if (family == AF_INET) { @@ -428,14 +428,14 @@ if_lookup_address_vrf (void *matchaddr, int family, vrf_id_t vrf_id) (c->address->prefixlen > bestlen)) { bestlen = c->address->prefixlen; - match = ifp; + match = c; } } } return match; } -struct interface * +struct connected * if_lookup_address (void *matchaddr, int family) { return if_lookup_address_vrf (matchaddr, family, VRF_DEFAULT); diff --git a/lib/if.h b/lib/if.h index 57062cd3fc..9b47159103 100644 --- a/lib/if.h +++ b/lib/if.h @@ -387,7 +387,7 @@ extern int if_cmp_name_func (char *, char *); extern struct interface *if_create (const char *name, int namelen); extern struct interface *if_lookup_by_index (ifindex_t); extern struct interface *if_lookup_exact_address (void *matchaddr, int family); -extern struct interface *if_lookup_address (void *matchaddr, int family); +extern struct connected *if_lookup_address (void *matchaddr, int family); extern struct interface *if_lookup_prefix (struct prefix *prefix); extern void if_update_vrf (struct interface *, const char *name, int namelen, @@ -397,7 +397,7 @@ extern struct interface *if_create_vrf (const char *name, int namelen, extern struct interface *if_lookup_by_index_vrf (ifindex_t, vrf_id_t vrf_id); extern struct interface *if_lookup_exact_address_vrf (void *matchaddr, int family, vrf_id_t vrf_id); -extern struct interface *if_lookup_address_vrf (void *matchaddr, int family, +extern struct connected *if_lookup_address_vrf (void *matchaddr, int family, vrf_id_t vrf_id); extern struct interface *if_lookup_prefix_vrf (struct prefix *prefix, vrf_id_t vrf_id); diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index b7ef24409e..72ce5586f6 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -2772,6 +2772,7 @@ ospf_read (struct thread *thread) struct ospf_header *ospfh; u_int16_t length; struct interface *ifp; + struct connected *c; /* first of all get interface pointer. */ ospf = THREAD_ARG (thread); @@ -2790,13 +2791,16 @@ ospf_read (struct thread *thread) /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */ if (ifp == NULL) - /* Handle cases where the platform does not support retrieving the ifindex, - and also platforms (such as Solaris 8) that claim to support ifindex - retrieval but do not. */ - ifp = if_lookup_address ((void *)&iph->ip_src, AF_INET); - - if (ifp == NULL) - return 0; + { + /* Handle cases where the platform does not support retrieving the ifindex, + and also platforms (such as Solaris 8) that claim to support ifindex + retrieval but do not. */ + c = if_lookup_address ((void *)&iph->ip_src, AF_INET); + if (c) + ifp = c->ifp; + if (ifp == NULL) + return 0; + } /* IP Header dump. */ if (IS_DEBUG_OSPF_PACKET(0, RECV)) diff --git a/ripd/ripd.c b/ripd/ripd.c index f27a817aed..79de56b781 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -1812,7 +1812,7 @@ rip_read (struct thread *t) int len; int vrecv; socklen_t fromlen; - struct interface *ifp; + struct interface *ifp = NULL; struct connected *ifc; struct rip_interface *ri; struct prefix p; @@ -1845,8 +1845,10 @@ rip_read (struct thread *t) } /* Which interface is this packet comes from. */ - ifp = if_lookup_address ((void *)&from.sin_addr, AF_INET); - + ifc = if_lookup_address ((void *)&from.sin_addr, AF_INET); + if (ifc) + ifp = ifc->ifp; + /* RIP packet received */ if (IS_RIP_DEBUG_EVENT) zlog_debug ("RECV packet from %s port %d on %s", @@ -2544,21 +2546,14 @@ rip_update_process (int route_type) { p = &rp->p; - ifp = if_lookup_prefix (p); - if (! ifp) + connected = if_lookup_address (&p->u.prefix4, AF_INET); + if (! connected) { zlog_warn ("Neighbor %s doesnt have connected interface!", inet_ntoa (p->u.prefix4)); continue; } - if ( (connected = connected_lookup_prefix (ifp, p)) == NULL) - { - zlog_warn ("Neighbor %s doesnt have connected network", - inet_ntoa (p->u.prefix4)); - continue; - } - /* Set destination address and port */ memset (&to, 0, sizeof (struct sockaddr_in)); to.sin_addr = p->u.prefix4; From ae735d2d0e13a6babd796ca171519b9db4feaf81 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Fri, 11 Nov 2016 20:19:13 -0200 Subject: [PATCH 06/44] ripd: fix race condition on input processing In the early days of ripd, we supported running RIP on secondary IP addresses. To do that, everytime we needed to send a multicast packet, we would create a new temporary socket for each of the interface's addresses and call bind() to change the source IP of the outgoing packets. The problem with these temporary sockets is that they are more specific than the global RIP socket (bound to INADDR_ANY). Then, even though these sockets only exist for a short amount of time, they can receive some RIP packets that were supposed to be received on the global RIP socket. And since we never read from the temporary sockets, these packets are dropped. Since we don't support secondary addresses anymore, the simplest way to fix this problem is to stop using temporary sockets for sending multicast packets. We are already setting IP_MULTICAST_IF before sending each multicast packet, and in this case the primary address of the selected interface is used as the source IP of the outgoing packets, which is exactly what we want. If we decide to reintroduce support for secondary addresses in the future, we should try one of the following: * Use IP_SENDSRCADDR/IP_PKTINFO to set the source address of the outgoing multicast packets; * Create one permanent UDP socket for each possible interface address, and enable reading on all sockets. Fixes the following IxANVL RIP tests: 7.10 and 14.1. Signed-off-by: Renato Westphal --- ripd/ripd.c | 50 +++++++++----------------------------------------- 1 file changed, 9 insertions(+), 41 deletions(-) diff --git a/ripd/ripd.c b/ripd/ripd.c index 79de56b781..a83c50c7ce 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -1339,25 +1339,18 @@ rip_response_process (struct rip_packet *packet, int size, /* Make socket for RIP protocol. */ static int -rip_create_socket (struct sockaddr_in *from) +rip_create_socket (void) { int ret; int sock; struct sockaddr_in addr; memset (&addr, 0, sizeof (struct sockaddr_in)); - - if (!from) - { - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = INADDR_ANY; + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_ANY; #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - addr.sin_len = sizeof (struct sockaddr_in); + addr.sin_len = sizeof (struct sockaddr_in); #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ - } else { - memcpy(&addr, from, sizeof(addr)); - } - /* sending port must always be the RIP port */ addr.sin_port = htons (RIP_PORT_DEFAULT); @@ -1412,7 +1405,7 @@ static int rip_send_packet (u_char * buf, int size, struct sockaddr_in *to, struct connected *ifc) { - int ret, send_sock; + int ret; struct sockaddr_in sin; assert (ifc != NULL); @@ -1468,38 +1461,16 @@ rip_send_packet (u_char * buf, int size, struct sockaddr_in *to, { sin.sin_port = to->sin_port; sin.sin_addr = to->sin_addr; - send_sock = rip->sock; } else { - struct sockaddr_in from; - sin.sin_port = htons (RIP_PORT_DEFAULT); sin.sin_addr.s_addr = htonl (INADDR_RIP_GROUP); - - /* multicast send should bind to local interface address */ - memset (&from, 0, sizeof (from)); - from.sin_family = AF_INET; - from.sin_port = htons (RIP_PORT_DEFAULT); - from.sin_addr = ifc->address->u.prefix4; -#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - from.sin_len = sizeof (struct sockaddr_in); -#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ - - /* - * we have to open a new socket for each packet because this - * is the most portable way to bind to a different source - * ipv4 address for each packet. - */ - if ( (send_sock = rip_create_socket (&from)) < 0) - { - zlog_warn("rip_send_packet could not create socket."); - return -1; - } - rip_interface_multicast_set (send_sock, ifc); + + rip_interface_multicast_set (rip->sock, ifc); } - ret = sendto (send_sock, buf, size, 0, (struct sockaddr *)&sin, + ret = sendto (rip->sock, buf, size, 0, (struct sockaddr *)&sin, sizeof (struct sockaddr_in)); if (IS_RIP_DEBUG_EVENT) @@ -1509,9 +1480,6 @@ rip_send_packet (u_char * buf, int size, struct sockaddr_in *to, if (ret < 0) zlog_warn ("can't send packet : %s", safe_strerror (errno)); - if (!to) - close(send_sock); - return ret; } @@ -2729,7 +2697,7 @@ rip_create (void) rip->obuf = stream_new (1500); /* Make socket. */ - rip->sock = rip_create_socket (NULL); + rip->sock = rip_create_socket (); if (rip->sock < 0) return rip->sock; From 5736139d4a9192c9ba296d2bddc5bbbd025dfd7f Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sat, 12 Nov 2016 18:39:51 -0200 Subject: [PATCH 07/44] pimd/zebra: fix setting of IP_MULTICAST_LOOP on OpenBSD Linux, FreeBSD and NetBSD (and possibly others too) accept both uint8_t and int for the IP_MULTICAST_LOOP sockoption. OpenBSD, in the other hand, accepts only uint8_t. To make setting IP_MULTICAST_LOOP work on every supported platform, always pass a uint8_t variable as a parameter. Signed-off-by: Renato Westphal --- pimd/pim_sock.c | 2 +- pimd/pim_sock.h | 2 +- pimd/pim_ssmpingd.c | 2 +- zebra/irdp_packet.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pimd/pim_sock.c b/pimd/pim_sock.c index a024e3ae01..90b11dcfd6 100644 --- a/pimd/pim_sock.c +++ b/pimd/pim_sock.c @@ -68,7 +68,7 @@ int pim_socket_raw(int protocol) return fd; } -int pim_socket_mcast(int protocol, struct in_addr ifaddr, int ifindex, int loop) +int pim_socket_mcast(int protocol, struct in_addr ifaddr, int ifindex, u_char loop) { int fd; diff --git a/pimd/pim_sock.h b/pimd/pim_sock.h index f0a1600818..cd29543fa0 100644 --- a/pimd/pim_sock.h +++ b/pimd/pim_sock.h @@ -39,7 +39,7 @@ #define PIM_SOCK_ERR_BIND (-11) /* Can't bind to interface */ int pim_socket_raw(int protocol); -int pim_socket_mcast(int protocol, struct in_addr ifaddr, int ifindex, int loop); +int pim_socket_mcast(int protocol, struct in_addr ifaddr, int ifindex, u_char loop); int pim_socket_join(int fd, struct in_addr group, struct in_addr ifaddr, ifindex_t ifindex); int pim_socket_join_source(int fd, ifindex_t ifindex, diff --git a/pimd/pim_ssmpingd.c b/pimd/pim_ssmpingd.c index fe88eba271..daa3c65e36 100644 --- a/pimd/pim_ssmpingd.c +++ b/pimd/pim_ssmpingd.c @@ -151,7 +151,7 @@ static int ssmpingd_socket(struct in_addr addr, int port, int mttl) } { - int loop = 0; + u_char loop = 0; if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, (void *) &loop, sizeof(loop))) { zlog_warn("%s: could not %s Multicast Loopback Option on socket fd=%d: errno=%d: %s", diff --git a/zebra/irdp_packet.c b/zebra/irdp_packet.c index 25c7aff26b..290a6180e7 100644 --- a/zebra/irdp_packet.c +++ b/zebra/irdp_packet.c @@ -282,7 +282,7 @@ send_packet(struct interface *ifp, char buf[256]; struct in_pktinfo *pktinfo; u_long src; - int on; + u_char on; if (!(ifp->flags & IFF_UP)) return; From c5bdb09fd9d18ac0524a14c90f79cfad95afefd7 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sat, 12 Nov 2016 19:05:08 -0200 Subject: [PATCH 08/44] *: create a helper function to set the IP_MULTICAST_LOOP sockoption Signed-off-by: Renato Westphal --- ldpd/socket.c | 10 +--------- lib/sockopt.c | 15 ++++++++++++++- lib/sockopt.h | 2 ++ ospfd/ospf_network.c | 8 +++----- pimd/pim_sock.c | 4 ++-- pimd/pim_ssmpingd.c | 18 +++++++----------- zebra/irdp_packet.c | 8 ++------ 7 files changed, 31 insertions(+), 34 deletions(-) diff --git a/ldpd/socket.c b/ldpd/socket.c index cf352d7204..1bb0837401 100644 --- a/ldpd/socket.c +++ b/ldpd/socket.c @@ -421,15 +421,7 @@ sock_set_ipv4_mcast(struct iface *iface) int sock_set_ipv4_mcast_loop(int fd) { - uint8_t loop = 0; - - if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, - (char *)&loop, sizeof(loop)) < 0) { - log_warn("%s: error setting IP_MULTICAST_LOOP", __func__); - return (-1); - } - - return (0); + return (setsockopt_ipv4_multicast_loop(fd, 0)); } int diff --git a/lib/sockopt.c b/lib/sockopt.c index c480cee0d7..be3ac0e4bf 100644 --- a/lib/sockopt.c +++ b/lib/sockopt.c @@ -384,7 +384,20 @@ setsockopt_ipv4_multicast_if(int sock, struct in_addr if_addr, #error "Unsupported multicast API" #endif } - + +int +setsockopt_ipv4_multicast_loop (int sock, u_char val) +{ + int ret; + + ret = setsockopt (sock, IPPROTO_IP, IP_MULTICAST_LOOP, (void *) &val, + sizeof (val)); + if (ret < 0) + zlog_warn ("can't setsockopt IP_MULTICAST_LOOP"); + + return ret; +} + static int setsockopt_ipv4_ifindex (int sock, ifindex_t val) { diff --git a/lib/sockopt.h b/lib/sockopt.h index d67b510b66..02f0189345 100644 --- a/lib/sockopt.h +++ b/lib/sockopt.h @@ -89,6 +89,8 @@ extern int setsockopt_ipv4_multicast(int sock, int optname, struct in_addr if_addr, unsigned int mcast_addr, ifindex_t ifindex); +extern int setsockopt_ipv4_multicast_loop (int sock, u_char val); + extern int setsockopt_ipv4_tos(int sock, int tos); /* Ask for, and get, ifindex, by whatever method is supported. */ diff --git a/ospfd/ospf_network.c b/ospfd/ospf_network.c index 6caa38d68b..088123ea24 100644 --- a/ospfd/ospf_network.c +++ b/ospfd/ospf_network.c @@ -132,18 +132,16 @@ ospf_if_ipmulticast (struct ospf *top, struct prefix *p, ifindex_t ifindex) { u_char val; int ret, len; - - val = 0; - len = sizeof (val); - + /* Prevent receiving self-origined multicast packets. */ - ret = setsockopt (top->fd, IPPROTO_IP, IP_MULTICAST_LOOP, (void *)&val, len); + ret = setsockopt_ipv4_multicast_loop (top->fd, 0); if (ret < 0) zlog_warn ("can't setsockopt IP_MULTICAST_LOOP(0) for fd %d: %s", top->fd, safe_strerror(errno)); /* Explicitly set multicast ttl to 1 -- endo. */ val = 1; + len = sizeof (val); ret = setsockopt (top->fd, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&val, len); if (ret < 0) zlog_warn ("can't setsockopt IP_MULTICAST_TTL(1) for fd %d: %s", diff --git a/pimd/pim_sock.c b/pimd/pim_sock.c index 90b11dcfd6..231efd0f22 100644 --- a/pimd/pim_sock.c +++ b/pimd/pim_sock.c @@ -35,6 +35,7 @@ #include "privs.h" #include "if.h" #include "vrf.h" +#include "sockopt.h" #include "pimd.h" #include "pim_mroute.h" @@ -173,8 +174,7 @@ int pim_socket_mcast(int protocol, struct in_addr ifaddr, int ifindex, u_char lo } } - if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, - (void *) &loop, sizeof(loop))) { + if (setsockopt_ipv4_multicast_loop (fd, loop)) { zlog_warn("Could not %s Multicast Loopback Option on socket fd=%d: errno=%d: %s", loop ? "enable" : "disable", fd, errno, safe_strerror(errno)); diff --git a/pimd/pim_ssmpingd.c b/pimd/pim_ssmpingd.c index daa3c65e36..fba563a6f8 100644 --- a/pimd/pim_ssmpingd.c +++ b/pimd/pim_ssmpingd.c @@ -25,6 +25,7 @@ #include "if.h" #include "log.h" #include "memory.h" +#include "sockopt.h" #include "pim_ssmpingd.h" #include "pim_time.h" @@ -150,17 +151,12 @@ static int ssmpingd_socket(struct in_addr addr, int port, int mttl) return -1; } - { - u_char loop = 0; - if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, - (void *) &loop, sizeof(loop))) { - zlog_warn("%s: could not %s Multicast Loopback Option on socket fd=%d: errno=%d: %s", - __PRETTY_FUNCTION__, - loop ? "enable" : "disable", - fd, errno, safe_strerror(errno)); - close(fd); - return PIM_SOCK_ERR_LOOP; - } + if (setsockopt_ipv4_multicast_loop (fd, 0)) { + zlog_warn("%s: could not disable Multicast Loopback Option on socket fd=%d: errno=%d: %s", + __PRETTY_FUNCTION__, + fd, errno, safe_strerror(errno)); + close(fd); + return PIM_SOCK_ERR_LOOP; } if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, diff --git a/zebra/irdp_packet.c b/zebra/irdp_packet.c index 290a6180e7..c9c32ce311 100644 --- a/zebra/irdp_packet.c +++ b/zebra/irdp_packet.c @@ -323,12 +323,8 @@ send_packet(struct interface *ifp, zlog_warn("sendto %s", safe_strerror (errno)); } - if(dst != INADDR_BROADCAST) { - on = 0; - if( setsockopt(irdp_sock,IPPROTO_IP, IP_MULTICAST_LOOP, - (char *)&on,sizeof(on)) < 0) - zlog_warn("sendto %s", safe_strerror (errno)); - } + if(dst != INADDR_BROADCAST) + setsockopt_ipv4_multicast_loop (irdp_sock, 0); memset(&sockdst,0,sizeof(sockdst)); sockdst.sin_family=AF_INET; From 043144ea897ba6a9d1e5f1a8d9e0d623d78bc2a4 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sat, 12 Nov 2016 19:11:13 -0200 Subject: [PATCH 09/44] ripd: make use of the IP_MULTICAST_LOOP sockoption We still need to check for self-generated packets on rip_read() because ripd may also send broadcast packets. But using IP_MULTICAST_LOOP on the ripd socket will at least prevent us from receiving a lot unnecessary multicast packets when RIPv2 is being used, thus improving performance. Signed-off-by: Renato Westphal --- ripd/ripd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ripd/ripd.c b/ripd/ripd.c index a83c50c7ce..c2872d937a 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -1365,6 +1365,7 @@ rip_create_socket (void) sockopt_broadcast (sock); sockopt_reuseaddr (sock); sockopt_reuseport (sock); + setsockopt_ipv4_multicast_loop (sock, 0); #ifdef RIP_RECVMSG setsockopt_pktinfo (sock); #endif /* RIP_RECVMSG */ From 8578874d6922538fd7f13dce74db488569446993 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sat, 12 Nov 2016 19:34:37 -0200 Subject: [PATCH 10/44] ripd: minor code simplification * Simplify the RIP_TIMER_OFF macro and use it on more places; * Be more explicit when creating the RIP UDP socket - cosmetic change since socket(AF_INET,SOCK_DGRAM,0) defaults to UDP on every known UNIX/Linux platform. Signed-off-by: Renato Westphal --- ripd/ripd.c | 26 +++++--------------------- ripd/ripd.h | 9 +-------- 2 files changed, 6 insertions(+), 29 deletions(-) diff --git a/ripd/ripd.c b/ripd/ripd.c index c2872d937a..e9d610cea7 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -1355,7 +1355,7 @@ rip_create_socket (void) addr.sin_port = htons (RIP_PORT_DEFAULT); /* Make datagram socket. */ - sock = socket (AF_INET, SOCK_DGRAM, 0); + sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (sock < 0) { zlog_err("Cannot create UDP socket: %s", safe_strerror(errno)); @@ -2548,11 +2548,7 @@ rip_update (struct thread *t) /* Triggered updates may be suppressed if a regular update is due by the time the triggered update would be sent. */ - if (rip->t_triggered_interval) - { - thread_cancel (rip->t_triggered_interval); - rip->t_triggered_interval = NULL; - } + RIP_TIMER_OFF (rip->t_triggered_interval); rip->trigger = 0; /* Register myself. */ @@ -2606,11 +2602,7 @@ rip_triggered_update (struct thread *t) rip->t_triggered_update = NULL; /* Cancel interval timer. */ - if (rip->t_triggered_interval) - { - thread_cancel (rip->t_triggered_interval); - rip->t_triggered_interval = NULL; - } + RIP_TIMER_OFF (rip->t_triggered_interval); rip->trigger = 0; /* Logging triggered update. */ @@ -2788,11 +2780,7 @@ rip_event (enum rip_event event, int sock) rip->t_read = thread_add_read (master, rip_read, NULL, sock); break; case RIP_UPDATE_EVENT: - if (rip->t_update) - { - thread_cancel (rip->t_update); - rip->t_update = NULL; - } + RIP_TIMER_OFF (rip->t_update); jitter = rip_update_jitter (rip->update_time); rip->t_update = thread_add_timer (master, rip_update, NULL, @@ -3887,11 +3875,7 @@ rip_clean (void) RIP_TIMER_OFF (rip->t_triggered_interval); /* Cancel read thread. */ - if (rip->t_read) - { - thread_cancel (rip->t_read); - rip->t_read = NULL; - } + THREAD_READ_OFF (rip->t_read); /* Close RIP socket. */ if (rip->sock >= 0) diff --git a/ripd/ripd.h b/ripd/ripd.h index b26a1d234c..cb4764a7f1 100644 --- a/ripd/ripd.h +++ b/ripd/ripd.h @@ -373,14 +373,7 @@ enum rip_event } while (0) /* Macro for timer turn off. */ -#define RIP_TIMER_OFF(X) \ - do { \ - if (X) \ - { \ - thread_cancel (X); \ - (X) = NULL; \ - } \ - } while (0) +#define RIP_TIMER_OFF(X) THREAD_TIMER_OFF(X) /* Prototypes. */ extern void rip_init (void); From 705e86f06eaea9676099f5a32cbed5599ae474c6 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Wed, 16 Nov 2016 16:14:45 -0200 Subject: [PATCH 11/44] ripngd: implement optional heuristic suggested by RFC 2080 RFC 2080 - Section 2.4.2: "If the new metric is the same as the old one, examine the timeout for the existing route. If it is at least halfway to the expiration point, switch to the new route. This heuristic is optional, but highly recommended". Implement this optional heuristic only when ECMP is disabled globally ("no allow-ecmp"), otherwise all routes with the same metric should be used. Fixes IxANVL RIPng test 7.21. Signed-off-by: Renato Westphal --- ripngd/ripngd.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c index 2a32b934f2..96206e2b08 100644 --- a/ripngd/ripngd.c +++ b/ripngd/ripngd.c @@ -829,8 +829,10 @@ ripng_route_process (struct rte *rte, struct sockaddr_in6 *from, * with the new one in below. */ break; - /* Metrics are same. Keep "rinfo" null and the new route - * is added in the ECMP list in below. */ + /* Metrics are same. Unless ECMP is disabled, keep "rinfo" null and + * the new route is added in the ECMP list in below. */ + if (! ripng->ecmp) + break; } } @@ -874,11 +876,24 @@ ripng_route_process (struct rte *rte, struct sockaddr_in6 *from, same = (IN6_ARE_ADDR_EQUAL (&rinfo->from, &from->sin6_addr) && (rinfo->ifindex == ifp->ifindex)); + /* + * RFC 2080 - Section 2.4.2: + * "If the new metric is the same as the old one, examine the timeout + * for the existing route. If it is at least halfway to the expiration + * point, switch to the new route. This heuristic is optional, but + * highly recommended". + */ + if (!ripng->ecmp && !same && + rinfo->metric == rte->metric && rinfo->t_timeout && + (thread_timer_remain_second (rinfo->t_timeout) < (ripng->timeout_time / 2))) + { + ripng_ecmp_replace (&newinfo); + } /* Next, compare the metrics. If the datagram is from the same router as the existing route, and the new metric is different than the old one; or, if the new metric is lower than the old one; do the following actions: */ - if ((same && rinfo->metric != rte->metric) || + else if ((same && rinfo->metric != rte->metric) || rte->metric < rinfo->metric) { if (listcount (list) == 1) From d7f966abed5f822e6f90442de5ccbf848be01b64 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Thu, 17 Nov 2016 16:33:09 -0200 Subject: [PATCH 12/44] ripngd: implement the "clear ipv6 ripng" vty command This command deletes all received routes from the RIPng routing table. It should be used with caution as it can create black holes in the network (until it reconverges). Very useful to make automated testing (e.g. ANVL) more predictable. Signed-off-by: Renato Westphal --- ripngd/ripngd.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c index 96206e2b08..82c4877485 100644 --- a/ripngd/ripngd.c +++ b/ripngd/ripngd.c @@ -2170,6 +2170,54 @@ DEFUN (show_ipv6_ripng_status, return CMD_SUCCESS; } +DEFUN (clear_ipv6_rip, + clear_ipv6_rip_cmd, + "clear ipv6 ripng", + CLEAR_STR + IPV6_STR + "Clear IPv6 RIP database") +{ + struct route_node *rp; + struct ripng_info *rinfo; + struct list *list; + struct listnode *listnode; + + /* Clear received RIPng routes */ + for (rp = route_top (ripng->table); rp; rp = route_next (rp)) + { + list = rp->info; + if (list == NULL) + continue; + + for (ALL_LIST_ELEMENTS_RO (list, listnode, rinfo)) + { + if (! ripng_route_rte (rinfo)) + continue; + + if (CHECK_FLAG (rinfo->flags, RIPNG_RTF_FIB)) + ripng_zebra_ipv6_delete (rp); + break; + } + + if (rinfo) + { + RIPNG_TIMER_OFF (rinfo->t_timeout); + RIPNG_TIMER_OFF (rinfo->t_garbage_collect); + listnode_delete (list, rinfo); + ripng_info_free (rinfo); + } + + if (list_isempty (list)) + { + list_free (list); + rp->info = NULL; + route_unlock_node (rp); + } + } + + return CMD_SUCCESS; +} + DEFUN (router_ripng, router_ripng_cmd, "router ripng", @@ -3047,6 +3095,8 @@ ripng_init () install_element (VIEW_NODE, &show_ipv6_ripng_cmd); install_element (VIEW_NODE, &show_ipv6_ripng_status_cmd); + install_element (ENABLE_NODE, &clear_ipv6_rip_cmd); + install_element (CONFIG_NODE, &router_ripng_cmd); install_element (CONFIG_NODE, &no_router_ripng_cmd); From 9e544a9c4bd13aac6bbeaff235abaaeb07a186b3 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Fri, 18 Nov 2016 15:39:25 -0200 Subject: [PATCH 13/44] ripngd: fix drop of multicast membership when the interface is down When an interface is shut down, ripng_multicast_leave() is called after ifp->flags is updated in ripng_interface_down(). So we shouldn't check if the interface is up in order to proceed with the membership drop. For consistency's sake, don't check for if_is_up() in ripng_multicast_join() as well. In this case, this function is only called when the interface is up, so the check was unnecessary. Signed-off-by: Renato Westphal --- ripngd/ripng_interface.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ripngd/ripng_interface.c b/ripngd/ripng_interface.c index c4dec7e7b1..a8742ec9a4 100644 --- a/ripngd/ripng_interface.c +++ b/ripngd/ripng_interface.c @@ -65,7 +65,7 @@ ripng_multicast_join (struct interface *ifp) struct ipv6_mreq mreq; int save_errno; - if (if_is_up (ifp) && if_is_multicast (ifp)) { + if (if_is_multicast (ifp)) { memset (&mreq, 0, sizeof (mreq)); inet_pton(AF_INET6, RIPNG_GROUP, &mreq.ipv6mr_multiaddr); mreq.ipv6mr_interface = ifp->ifindex; @@ -116,7 +116,7 @@ ripng_multicast_leave (struct interface *ifp) int ret; struct ipv6_mreq mreq; - if (if_is_up (ifp) && if_is_multicast (ifp)) { + if (if_is_multicast (ifp)) { memset (&mreq, 0, sizeof (mreq)); inet_pton(AF_INET6, RIPNG_GROUP, &mreq.ipv6mr_multiaddr); mreq.ipv6mr_interface = ifp->ifindex; From 46e6bac7eb8500ffcb6bcef38dea04d6f5148818 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Mon, 24 Oct 2016 21:53:37 -0200 Subject: [PATCH 14/44] bgpd: use loops to reduce code duplication Signed-off-by: Renato Westphal --- bgpd/bgp_nexthop.c | 51 +++++++++++++++++----------------------------- 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c index 6c30fefae5..46ccd06c4b 100644 --- a/bgpd/bgp_nexthop.c +++ b/bgpd/bgp_nexthop.c @@ -554,17 +554,14 @@ DEFUN (show_ip_bgp_instance_nexthop_detail, void bgp_scan_init (struct bgp *bgp) { - bgp->nexthop_cache_table[AFI_IP] = bgp_table_init (AFI_IP, SAFI_UNICAST); - bgp->connected_table[AFI_IP] = bgp_table_init (AFI_IP, SAFI_UNICAST); - bgp->import_check_table[AFI_IP] = bgp_table_init (AFI_IP, SAFI_UNICAST); + afi_t afi; - bgp->nexthop_cache_table[AFI_IP6] = bgp_table_init (AFI_IP6, SAFI_UNICAST); - bgp->connected_table[AFI_IP6] = bgp_table_init (AFI_IP6, SAFI_UNICAST); - bgp->import_check_table[AFI_IP6] = bgp_table_init (AFI_IP6, SAFI_UNICAST); - - bgp->nexthop_cache_table[AFI_ETHER] = bgp_table_init (AFI_ETHER, SAFI_UNICAST); - bgp->connected_table[AFI_ETHER] = bgp_table_init (AFI_ETHER, SAFI_UNICAST); - bgp->import_check_table[AFI_ETHER] = bgp_table_init (AFI_ETHER, SAFI_UNICAST); + for (afi = AFI_IP; afi < AFI_MAX; afi++) + { + bgp->nexthop_cache_table[afi] = bgp_table_init (afi, SAFI_UNICAST); + bgp->connected_table[afi] = bgp_table_init (afi, SAFI_UNICAST); + bgp->import_check_table[afi] = bgp_table_init (afi, SAFI_UNICAST); + } } void @@ -580,29 +577,19 @@ bgp_scan_vty_init (void) void bgp_scan_finish (struct bgp *bgp) { - /* Only the current one needs to be reset. */ - bgp_nexthop_cache_reset (bgp->nexthop_cache_table[AFI_IP]); + afi_t afi; - bgp_table_unlock (bgp->nexthop_cache_table[AFI_IP]); - bgp->nexthop_cache_table[AFI_IP] = NULL; + for (afi = AFI_IP; afi < AFI_MAX; afi++) + { + /* Only the current one needs to be reset. */ + bgp_nexthop_cache_reset (bgp->nexthop_cache_table[afi]); + bgp_table_unlock (bgp->nexthop_cache_table[afi]); + bgp->nexthop_cache_table[afi] = NULL; - bgp_table_unlock (bgp->connected_table[AFI_IP]); - bgp->connected_table[AFI_IP] = NULL; + bgp_table_unlock (bgp->connected_table[afi]); + bgp->connected_table[afi] = NULL; - bgp_table_unlock (bgp->import_check_table[AFI_IP]); - bgp->import_check_table[AFI_IP] = NULL; - -#ifdef HAVE_IPV6 - /* Only the current one needs to be reset. */ - bgp_nexthop_cache_reset (bgp->nexthop_cache_table[AFI_IP6]); - - bgp_table_unlock (bgp->nexthop_cache_table[AFI_IP6]); - bgp->nexthop_cache_table[AFI_IP6] = NULL; - - bgp_table_unlock (bgp->connected_table[AFI_IP6]); - bgp->connected_table[AFI_IP6] = NULL; - - bgp_table_unlock (bgp->import_check_table[AFI_IP6]); - bgp->import_check_table[AFI_IP6] = NULL; -#endif /* HAVE_IPV6 */ + bgp_table_unlock (bgp->import_check_table[afi]); + bgp->import_check_table[afi] = NULL; + } } From 658bbf6d704a776495dd7914c45efc399f03da52 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Tue, 1 Nov 2016 07:37:50 -0200 Subject: [PATCH 15/44] bgpd: optimize copy of strings on peer_xfer_conn() Signed-off-by: Renato Westphal --- bgpd/bgp_fsm.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index ab4ea71d61..e669b4f9b7 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -171,8 +171,7 @@ peer_xfer_conn(struct peer *from_peer) peer->hostname = NULL; } - peer->hostname = XSTRDUP(MTYPE_BGP_PEER_HOST, from_peer->hostname); - XFREE(MTYPE_BGP_PEER_HOST, from_peer->hostname); + peer->hostname = from_peer->hostname; from_peer->hostname = NULL; } @@ -184,8 +183,7 @@ peer_xfer_conn(struct peer *from_peer) peer->domainname= NULL; } - peer->domainname = XSTRDUP(MTYPE_BGP_PEER_HOST, from_peer->domainname); - XFREE(MTYPE_BGP_PEER_HOST, from_peer->domainname); + peer->domainname = from_peer->domainname; from_peer->domainname = NULL; } From 235022cbaaf6873f0b745c0e4c5844e5343b824f Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Wed, 2 Nov 2016 00:29:46 -0200 Subject: [PATCH 16/44] bgpd: reuse sockunion2hostprefix() on bgp_nht.c Signed-off-by: Renato Westphal --- bgpd/bgp_nht.c | 54 +++++++++----------------------------------------- 1 file changed, 9 insertions(+), 45 deletions(-) diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index 9aae3e7b33..1ca0483678 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -115,19 +115,7 @@ bgp_unlink_nexthop_by_peer (struct peer *peer) struct bgp_nexthop_cache *bnc; afi_t afi = family2afi(peer->su.sa.sa_family); - if (afi == AFI_IP) - { - p.family = AF_INET; - p.prefixlen = IPV4_MAX_BITLEN; - p.u.prefix4 = peer->su.sin.sin_addr; - } - else if (afi == AFI_IP6) - { - p.family = AF_INET6; - p.prefixlen = IPV6_MAX_BITLEN; - p.u.prefix6 = peer->su.sin6.sin6_addr; - } - else + if (! sockunion2hostprefix (&peer->su, &p)) return; rn = bgp_node_get (peer->bgp->nexthop_cache_table[afi], &p); @@ -168,23 +156,11 @@ bgp_find_or_add_nexthop (struct bgp *bgp, afi_t afi, struct bgp_info *ri, } else if (peer) { - if (afi == AFI_IP) - { - p.family = AF_INET; - p.prefixlen = IPV4_MAX_BITLEN; - p.u.prefix4 = peer->su.sin.sin_addr; - } - else if (afi == AFI_IP6) - { - p.family = AF_INET6; - p.prefixlen = IPV6_MAX_BITLEN; - p.u.prefix6 = peer->su.sin6.sin6_addr; + /* Don't register link local NH */ + if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL (&peer->su.sin6.sin6_addr)) + return 1; - /* Don't register link local NH */ - if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) - return 1; - } - else + if (! sockunion2hostprefix (&peer->su, &p)) { if (BGP_DEBUG(nht, NHT)) { @@ -297,23 +273,11 @@ bgp_delete_connected_nexthop (afi_t afi, struct peer *peer) if (!peer) return; - if (afi == AFI_IP) - { - p.family = AF_INET; - p.prefixlen = IPV4_MAX_BITLEN; - p.u.prefix4 = peer->su.sin.sin_addr; - } - else if (afi == AFI_IP6) - { - p.family = AF_INET6; - p.prefixlen = IPV6_MAX_BITLEN; - p.u.prefix6 = peer->su.sin6.sin6_addr; + /* We don't register link local address for NHT */ + if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL (&peer->su.sin6.sin6_addr)) + return; - /* We don't register link local address for NHT */ - if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) - return; - } - else + if (! sockunion2hostprefix (&peer->su, &p)) return; rn = bgp_node_lookup(peer->bgp->nexthop_cache_table[family2afi(p.family)], &p); From 37d361e7fd6b35dc4badd7e0124e2f49c4ac9e5e Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Fri, 21 Oct 2016 20:13:51 -0200 Subject: [PATCH 17/44] bgpd: plug several memleaks Signed-off-by: Renato Westphal --- bgpd/bgp_nexthop.c | 8 +++++++- bgpd/bgp_zebra.c | 1 + bgpd/bgpd.c | 20 ++++++++++++-------- tests/bgp_mpath_test.c | 2 ++ 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c index 46ccd06c4b..2d3d8e6a65 100644 --- a/bgpd/bgp_nexthop.c +++ b/bgpd/bgp_nexthop.c @@ -113,6 +113,12 @@ bgp_address_hash_alloc (void *p) return addr; } +static void +bgp_address_hash_free (void *addr) +{ + XFREE (MTYPE_BGP_ADDR, addr); +} + static unsigned int bgp_address_hash_key_make (void *p) { @@ -142,7 +148,7 @@ bgp_address_destroy (struct bgp *bgp) { if (bgp->address_hash == NULL) return; - hash_clean(bgp->address_hash, NULL); + hash_clean(bgp->address_hash, bgp_address_hash_free); hash_free(bgp->address_hash); bgp->address_hash = NULL; } diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 8ecd025397..3d3bd90f5b 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1792,6 +1792,7 @@ bgp_redist_del (struct bgp *bgp, afi_t afi, u_char type, u_short instance) if (red) { listnode_delete(bgp->redist[afi][type], red); + XFREE (MTYPE_BGP_REDIST, red); if (!bgp->redist[afi][type]->count) { list_free(bgp->redist[afi][type]); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 3ddb465a75..a786271541 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -1047,6 +1047,12 @@ peer_free (struct peer *peer) peer->host = NULL; } + if (peer->domainname) + { + XFREE (MTYPE_BGP_PEER_HOST, peer->domainname); + peer->domainname = NULL; + } + if (peer->ifname) { XFREE(MTYPE_BGP_PEER_IFNAME, peer->ifname); @@ -3123,6 +3129,7 @@ bgp_delete (struct bgp *bgp) struct peer *peer; struct peer_group *group; struct listnode *node, *next; + struct vrf *vrf; afi_t afi; int i; @@ -3186,8 +3193,6 @@ bgp_delete (struct bgp *bgp) * routes to be processed still referencing the struct bgp. */ listnode_delete (bm->bgp, bgp); - if (list_isempty(bm->bgp)) - bgp_close (); /* Deregister from Zebra, if needed */ if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) @@ -3196,6 +3201,10 @@ bgp_delete (struct bgp *bgp) /* Free interfaces in this instance. */ bgp_if_finish (bgp); + vrf = bgp_vrf_lookup_by_instance_type (bgp); + if (vrf) + bgp_vrf_unlink (bgp, vrf); + thread_master_free_unused(bm->master); bgp_unlock(bgp); /* initial reference */ @@ -3223,7 +3232,6 @@ bgp_free (struct bgp *bgp) { afi_t afi; safi_t safi; - struct vrf *vrf; list_delete (bgp->group); list_delete (bgp->peer); @@ -3245,13 +3253,9 @@ bgp_free (struct bgp *bgp) bgp_table_finish (&bgp->rib[afi][safi]); } + bgp_scan_finish (bgp); bgp_address_destroy (bgp); - /* If Default instance or VRF, unlink from the VRF structure. */ - vrf = bgp_vrf_lookup_by_instance_type (bgp); - if (vrf) - bgp_vrf_unlink (bgp, vrf); - if (bgp->name) XFREE(MTYPE_BGP, bgp->name); diff --git a/tests/bgp_mpath_test.c b/tests/bgp_mpath_test.c index dbcb00a2ef..723f2977d5 100644 --- a/tests/bgp_mpath_test.c +++ b/tests/bgp_mpath_test.c @@ -37,6 +37,7 @@ #include "bgpd/bgp_table.h" #include "bgpd/bgp_route.h" #include "bgpd/bgp_attr.h" +#include "bgpd/bgp_nexthop.h" #include "bgpd/bgp_mpath.h" #define VT100_RESET "\x1b[0m" @@ -116,6 +117,7 @@ bgp_create_fake (as_t *as, const char *name) bgp->maxpaths[afi][safi].maxpaths_ibgp = MULTIPATH_NUM; } + bgp_scan_init (bgp); bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF; bgp->default_holdtime = BGP_DEFAULT_HOLDTIME; bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE; From 0c6262ed6a2941c063aa2cf40107ef6b45d8628a Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Tue, 25 Oct 2016 00:04:24 -0200 Subject: [PATCH 18/44] bgpd: release all memory explicitly on exit --- bgpd/bgp_route.c | 94 +++++++++++++++++++++++++----------------------- bgpd/bgp_route.h | 2 +- bgpd/bgpd.c | 4 +-- 3 files changed, 51 insertions(+), 49 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 57e38ce10c..b23a52e1df 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -3123,7 +3123,7 @@ bgp_clear_route_table (struct peer *peer, afi_t afi, safi_t safi, struct bgp_table *table) { struct bgp_node *rn; - + int force = bm->process_main_queue ? 0 : 1; if (! table) table = peer->bgp->rib[afi][safi]; @@ -3134,7 +3134,7 @@ bgp_clear_route_table (struct peer *peer, afi_t afi, safi_t safi, for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn)) { - struct bgp_info *ri; + struct bgp_info *ri, *next; struct bgp_adj_in *ain; struct bgp_adj_in *ain_next; @@ -3186,20 +3186,28 @@ bgp_clear_route_table (struct peer *peer, afi_t afi, safi_t safi, ain = ain_next; } - for (ri = rn->info; ri; ri = ri->next) - if (ri->peer == peer) - { - struct bgp_clear_node_queue *cnq; + for (ri = rn->info; ri; ri = next) + { + next = ri->next; + if (ri->peer != peer) + continue; - /* both unlocked in bgp_clear_node_queue_del */ - bgp_table_lock (bgp_node_table (rn)); - bgp_lock_node (rn); - cnq = XCALLOC (MTYPE_BGP_CLEAR_NODE_QUEUE, - sizeof (struct bgp_clear_node_queue)); - cnq->rn = rn; - work_queue_add (peer->clear_node_queue, cnq); - break; - } + if (force) + bgp_info_reap (rn, ri); + else + { + struct bgp_clear_node_queue *cnq; + + /* both unlocked in bgp_clear_node_queue_del */ + bgp_table_lock (bgp_node_table (rn)); + bgp_lock_node (rn); + cnq = XCALLOC (MTYPE_BGP_CLEAR_NODE_QUEUE, + sizeof (struct bgp_clear_node_queue)); + cnq->rn = rn; + work_queue_add (peer->clear_node_queue, cnq); + break; + } + } } return; } @@ -3336,51 +3344,47 @@ bgp_cleanup_table(struct bgp_table *table, safi_t safi) vnc_import_bgp_del_route(table->owner->bgp, &rn->p, ri); #endif bgp_zebra_withdraw (&rn->p, ri, safi); + bgp_info_reap (rn, ri); } } } /* Delete all kernel routes. */ void -bgp_cleanup_routes (void) +bgp_cleanup_routes (struct bgp *bgp) { - struct bgp *bgp; - struct listnode *node, *nnode; afi_t afi; - for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp)) + for (afi = AFI_IP; afi < AFI_MAX; ++afi) { - for (afi = AFI_IP; afi < AFI_MAX; ++afi) + struct bgp_node *rn; + + bgp_cleanup_table(bgp->rib[afi][SAFI_UNICAST], SAFI_UNICAST); + + /* + * VPN and ENCAP tables are two-level (RD is top level) + */ + for (rn = bgp_table_top(bgp->rib[afi][SAFI_MPLS_VPN]); rn; + rn = bgp_route_next (rn)) { - struct bgp_node *rn; - - bgp_cleanup_table(bgp->rib[afi][SAFI_UNICAST], SAFI_UNICAST); - - /* - * VPN and ENCAP tables are two-level (RD is top level) - */ - for (rn = bgp_table_top(bgp->rib[afi][SAFI_MPLS_VPN]); rn; - rn = bgp_route_next (rn)) + if (rn->info) { - if (rn->info) - { - bgp_cleanup_table((struct bgp_table *)(rn->info), SAFI_MPLS_VPN); - bgp_table_finish ((struct bgp_table **)&(rn->info)); - rn->info = NULL; - bgp_unlock_node(rn); - } + bgp_cleanup_table((struct bgp_table *)(rn->info), SAFI_MPLS_VPN); + bgp_table_finish ((struct bgp_table **)&(rn->info)); + rn->info = NULL; + bgp_unlock_node(rn); } + } - for (rn = bgp_table_top(bgp->rib[afi][SAFI_ENCAP]); rn; - rn = bgp_route_next (rn)) + for (rn = bgp_table_top(bgp->rib[afi][SAFI_ENCAP]); rn; + rn = bgp_route_next (rn)) + { + if (rn->info) { - if (rn->info) - { - bgp_cleanup_table((struct bgp_table *)(rn->info), SAFI_ENCAP); - bgp_table_finish ((struct bgp_table **)&(rn->info)); - rn->info = NULL; - bgp_unlock_node(rn); - } + bgp_cleanup_table((struct bgp_table *)(rn->info), SAFI_ENCAP); + bgp_table_finish ((struct bgp_table **)&(rn->info)); + rn->info = NULL; + bgp_unlock_node(rn); } } } diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 6bd54aba13..63b18aa2d8 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -241,7 +241,7 @@ bgp_bump_version (struct bgp_node *node) extern void bgp_process_queue_init (void); extern void bgp_route_init (void); extern void bgp_route_finish (void); -extern void bgp_cleanup_routes (void); +extern void bgp_cleanup_routes (struct bgp *); extern void bgp_announce_route (struct peer *, afi_t, safi_t); extern void bgp_stop_announce_route_timer(struct peer_af *paf); extern void bgp_announce_route_all (struct peer *); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index a786271541..53258880ab 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -3186,8 +3186,8 @@ bgp_delete (struct bgp *bgp) #if ENABLE_BGP_VNC rfapi_delete(bgp); - bgp_cleanup_routes(); /* rfapi cleanup can create route entries! */ #endif + bgp_cleanup_routes(bgp); /* Remove visibility via the master list - there may however still be * routes to be processed still referencing the struct bgp. @@ -7601,8 +7601,6 @@ bgp_terminate (void) bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_PEER_UNCONFIG); - bgp_cleanup_routes (); - if (bm->process_main_queue) { work_queue_free (bm->process_main_queue); From 58ac32e2d598b5dc45fa05b7a8a85b107571d697 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Tue, 1 Nov 2016 18:57:53 -0200 Subject: [PATCH 19/44] zebra/lib: plug several memleaks Signed-off-by: Renato Westphal --- lib/command.c | 2 ++ lib/qobj.c | 1 + lib/table.c | 4 ++-- lib/table.h | 5 +++++ zebra/interface.c | 16 +++++++++++++++- zebra/main.c | 12 ++++++++++++ zebra/zebra_memory.h | 1 - zebra/zebra_mpls.c | 10 ++++++---- zebra/zebra_ns.c | 13 +++++-------- zebra/zebra_ns.h | 2 +- zebra/zebra_ptm.c | 2 ++ 11 files changed, 51 insertions(+), 17 deletions(-) diff --git a/lib/command.c b/lib/command.c index e8ba637623..acfcf68576 100644 --- a/lib/command.c +++ b/lib/command.c @@ -4436,4 +4436,6 @@ cmd_terminate () XFREE (MTYPE_HOST, host.motdfile); if (host.config) XFREE (MTYPE_HOST, host.config); + + qobj_finish (); } diff --git a/lib/qobj.c b/lib/qobj.c index 65b537f961..f64972e32a 100644 --- a/lib/qobj.c +++ b/lib/qobj.c @@ -78,6 +78,7 @@ void qobj_init (void) void qobj_finish (void) { + hash_clean (nodes, NULL); hash_free (nodes); nodes = NULL; } diff --git a/lib/table.c b/lib/table.c index d0e084ead2..5133ef6974 100644 --- a/lib/table.c +++ b/lib/table.c @@ -494,7 +494,7 @@ route_table_count (const struct route_table *table) * * Default function for creating a route node. */ -static struct route_node * +struct route_node * route_node_create (route_table_delegate_t *delegate, struct route_table *table) { @@ -508,7 +508,7 @@ route_node_create (route_table_delegate_t *delegate, * * Default function for destroying a route node. */ -static void +void route_node_destroy (route_table_delegate_t *delegate, struct route_table *table, struct route_node *node) { diff --git a/lib/table.h b/lib/table.h index e6cdcfef1e..78bf5da748 100644 --- a/lib/table.h +++ b/lib/table.h @@ -169,6 +169,11 @@ extern struct route_node *route_node_match_ipv6 (const struct route_table *, extern unsigned long route_table_count (const struct route_table *); +extern struct route_node *route_node_create (route_table_delegate_t *, + struct route_table *); +extern void route_node_destroy (route_table_delegate_t *, + struct route_table *, struct route_node *); + extern struct route_node * route_table_get_next (const struct route_table *table, struct prefix *p); extern int diff --git a/zebra/interface.c b/zebra/interface.c index b87f61f920..422368852d 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -59,6 +59,20 @@ const char *rtadv_pref_strs[] = { "medium", "high", "INVALID", "low", 0 }; static void if_down_del_nbr_connected (struct interface *ifp); +static void +zebra_if_node_destroy (route_table_delegate_t *delegate, + struct route_table *table, struct route_node *node) +{ + if (node->info) + list_delete (node->info); + route_node_destroy (delegate, table, node); +} + +route_table_delegate_t zebra_if_table_delegate = { + .create_node = route_node_create, + .destroy_node = zebra_if_node_destroy +}; + /* Called when new interface is added. */ static int if_zebra_new_hook (struct interface *ifp) @@ -101,7 +115,7 @@ if_zebra_new_hook (struct interface *ifp) #endif /* HAVE_RTADV */ /* Initialize installed address chains tree. */ - zebra_if->ipv4_subnets = route_table_init (); + zebra_if->ipv4_subnets = route_table_init_with_delegate (&zebra_if_table_delegate); ifp->info = zebra_if; diff --git a/zebra/main.c b/zebra/main.c index 9247d43507..1b41f8deff 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -196,6 +196,18 @@ sigint (void) zns = zebra_ns_lookup (NS_DEFAULT); zebra_ns_disable (0, (void **)&zns); + + access_list_reset (); + prefix_list_reset (); + route_map_finish (); + cmd_terminate (); + vty_terminate (); + zprivs_terminate (&zserv_privs); + list_delete (zebrad.client_list); + thread_master_free (zebrad.master); + if (zlog_default) + closezlog (zlog_default); + exit (0); } diff --git a/zebra/zebra_memory.h b/zebra/zebra_memory.h index fbd8f3261d..c1ac4fe955 100644 --- a/zebra/zebra_memory.h +++ b/zebra/zebra_memory.h @@ -35,6 +35,5 @@ DECLARE_MTYPE(STATIC_ROUTE) DECLARE_MTYPE(RIB_DEST) DECLARE_MTYPE(RIB_TABLE_INFO) DECLARE_MTYPE(RNH) -DECLARE_MTYPE(NETLINK_NAME) #endif /* _QUAGGA_ZEBRA_MEMORY_H */ diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index 15e5c330e4..b64cab625d 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -1829,7 +1829,7 @@ zebra_mpls_print_lsp_table (struct vty *vty, struct zebra_vrf *zvrf, vty_out (vty, "%s", VTY_NEWLINE); } - list_delete_all_node(lsp_list); + list_delete (lsp_list); } /* @@ -1869,7 +1869,7 @@ zebra_mpls_write_lsp_config (struct vty *vty, struct zebra_vrf *zvrf) } } - list_delete_all_node(slsp_list); + list_delete (slsp_list); return (zvrf->slsp_table->count ? 1 : 0); } @@ -1881,9 +1881,11 @@ zebra_mpls_write_lsp_config (struct vty *vty, struct zebra_vrf *zvrf) void zebra_mpls_close_tables (struct zebra_vrf *zvrf) { - if (!zvrf) - return; hash_iterate(zvrf->lsp_table, lsp_uninstall_from_kernel, NULL); + hash_clean(zvrf->lsp_table, NULL); + hash_free(zvrf->lsp_table); + hash_clean(zvrf->slsp_table, NULL); + hash_free(zvrf->slsp_table); } /* diff --git a/zebra/zebra_ns.c b/zebra/zebra_ns.c index 41034e1980..4499901021 100644 --- a/zebra/zebra_ns.c +++ b/zebra/zebra_ns.c @@ -32,7 +32,6 @@ #include "zebra_memory.h" DEFINE_MTYPE(ZEBRA, ZEBRA_NS, "Zebra Name Space") -DEFINE_MTYPE(ZEBRA, NETLINK_NAME, "Netlink name") struct zebra_ns *dzns; @@ -46,9 +45,6 @@ int zebra_ns_enable (ns_id_t ns_id, void **info) { struct zebra_ns *zns = (struct zebra_ns *) (*info); -#ifdef HAVE_NETLINK - char nl_name[64]; -#endif #if defined (HAVE_RTADV) rtadv_init (zns); @@ -56,13 +52,13 @@ zebra_ns_enable (ns_id_t ns_id, void **info) #ifdef HAVE_NETLINK /* Initialize netlink sockets */ - snprintf (nl_name, 64, "netlink-listen (NS %u)", ns_id); + snprintf (zns->netlink.name, sizeof (zns->netlink.name), + "netlink-listen (NS %u)", ns_id); zns->netlink.sock = -1; - zns->netlink.name = XSTRDUP (MTYPE_NETLINK_NAME, nl_name); - snprintf (nl_name, 64, "netlink-cmd (NS %u)", ns_id); + snprintf (zns->netlink_cmd.name, sizeof (zns->netlink_cmd.name), + "netlink-cmd (NS %u)", ns_id); zns->netlink_cmd.sock = -1; - zns->netlink_cmd.name = XSTRDUP (MTYPE_NETLINK_NAME, nl_name); #endif zns->if_table = route_table_init (); kernel_init (zns); @@ -77,6 +73,7 @@ zebra_ns_disable (ns_id_t ns_id, void **info) { struct zebra_ns *zns = (struct zebra_ns *) (*info); + route_table_finish (zns->if_table); #if defined (HAVE_RTADV) rtadv_terminate (zns); #endif diff --git a/zebra/zebra_ns.h b/zebra/zebra_ns.h index 8a821c465a..c50f9249d2 100644 --- a/zebra/zebra_ns.h +++ b/zebra/zebra_ns.h @@ -32,7 +32,7 @@ struct nlsock int sock; int seq; struct sockaddr_nl snl; - const char *name; + char name[64]; }; #endif diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c index ebae1bd4b9..28e6c42ec6 100644 --- a/zebra/zebra_ptm.c +++ b/zebra/zebra_ptm.c @@ -140,6 +140,8 @@ zebra_ptm_finish(void) buffer_flush_all(ptm_cb.wb, ptm_cb.ptm_sock); + free (ptm_hdl); + if (ptm_cb.out_data) free(ptm_cb.out_data); From 1fbe3e585ddb0a1c16a870b8112b145732549f45 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Wed, 26 Oct 2016 12:58:32 -0200 Subject: [PATCH 20/44] lib: remove unused ns code Signed-off-by: Renato Westphal --- lib/ns.c | 211 ------------------------------------------------------- lib/ns.h | 74 +------------------ 2 files changed, 1 insertion(+), 284 deletions(-) diff --git a/lib/ns.c b/lib/ns.c index 556350ed17..07e6ec5b9a 100644 --- a/lib/ns.c +++ b/lib/ns.c @@ -310,217 +310,6 @@ ns_add_hook (int type, int (*func)(ns_id_t, void **)) } } -/* Return the iterator of the first NS. */ -ns_iter_t -ns_first (void) -{ - struct route_node *rn; - - for (rn = route_top (ns_table); rn; rn = route_next (rn)) - if (rn->info) - { - route_unlock_node (rn); /* top/next */ - return (ns_iter_t)rn; - } - return NS_ITER_INVALID; -} - -/* Return the next NS iterator to the given iterator. */ -ns_iter_t -ns_next (ns_iter_t iter) -{ - struct route_node *rn = NULL; - - /* Lock it first because route_next() will unlock it. */ - if (iter != NS_ITER_INVALID) - rn = route_next (route_lock_node ((struct route_node *)iter)); - - for (; rn; rn = route_next (rn)) - if (rn->info) - { - route_unlock_node (rn); /* next */ - return (ns_iter_t)rn; - } - return NS_ITER_INVALID; -} - -/* Return the NS iterator of the given NS ID. If it does not exist, - * the iterator of the next existing NS is returned. */ -ns_iter_t -ns_iterator (ns_id_t ns_id) -{ - struct prefix p; - struct route_node *rn; - - ns_build_key (ns_id, &p); - rn = route_node_get (ns_table, &p); - if (rn->info) - { - /* OK, the NS exists. */ - route_unlock_node (rn); /* get */ - return (ns_iter_t)rn; - } - - /* Find the next NS. */ - for (rn = route_next (rn); rn; rn = route_next (rn)) - if (rn->info) - { - route_unlock_node (rn); /* next */ - return (ns_iter_t)rn; - } - - return NS_ITER_INVALID; -} - -/* Obtain the NS ID from the given NS iterator. */ -ns_id_t -ns_iter2id (ns_iter_t iter) -{ - struct route_node *rn = (struct route_node *) iter; - return (rn && rn->info) ? ((struct ns *)rn->info)->ns_id : NS_DEFAULT; -} - -/* Obtain the data pointer from the given NS iterator. */ -void * -ns_iter2info (ns_iter_t iter) -{ - struct route_node *rn = (struct route_node *) iter; - return (rn && rn->info) ? ((struct ns *)rn->info)->info : NULL; -} - -/* Obtain the interface list from the given NS iterator. */ -struct list * -ns_iter2iflist (ns_iter_t iter) -{ - struct route_node *rn = (struct route_node *) iter; - return (rn && rn->info) ? ((struct ns *)rn->info)->iflist : NULL; -} - -/* Get the data pointer of the specified NS. If not found, create one. */ -void * -ns_info_get (ns_id_t ns_id) -{ - struct ns *ns = ns_get (ns_id); - return ns->info; -} - -/* Look up the data pointer of the specified NS. */ -void * -ns_info_lookup (ns_id_t ns_id) -{ - struct ns *ns = ns_lookup (ns_id); - return ns ? ns->info : NULL; -} - -/* Look up the interface list in a NS. */ -struct list * -ns_iflist (ns_id_t ns_id) -{ - struct ns * ns = ns_lookup (ns_id); - return ns ? ns->iflist : NULL; -} - -/* Get the interface list of the specified NS. Create one if not find. */ -struct list * -ns_iflist_get (ns_id_t ns_id) -{ - struct ns * ns = ns_get (ns_id); - return ns->iflist; -} - -/* - * NS bit-map - */ - -#define NS_BITMAP_NUM_OF_GROUPS 8 -#define NS_BITMAP_NUM_OF_BITS_IN_GROUP \ - (UINT16_MAX / NS_BITMAP_NUM_OF_GROUPS) -#define NS_BITMAP_NUM_OF_BYTES_IN_GROUP \ - (NS_BITMAP_NUM_OF_BITS_IN_GROUP / CHAR_BIT + 1) /* +1 for ensure */ - -#define NS_BITMAP_GROUP(_id) \ - ((_id) / NS_BITMAP_NUM_OF_BITS_IN_GROUP) -#define NS_BITMAP_BIT_OFFSET(_id) \ - ((_id) % NS_BITMAP_NUM_OF_BITS_IN_GROUP) - -#define NS_BITMAP_INDEX_IN_GROUP(_bit_offset) \ - ((_bit_offset) / CHAR_BIT) -#define NS_BITMAP_FLAG(_bit_offset) \ - (((u_char)1) << ((_bit_offset) % CHAR_BIT)) - -struct ns_bitmap -{ - u_char *groups[NS_BITMAP_NUM_OF_GROUPS]; -}; - -ns_bitmap_t -ns_bitmap_init (void) -{ - return (ns_bitmap_t) XCALLOC (MTYPE_NS_BITMAP, sizeof (struct ns_bitmap)); -} - -void -ns_bitmap_free (ns_bitmap_t bmap) -{ - struct ns_bitmap *bm = (struct ns_bitmap *) bmap; - int i; - - if (bmap == NS_BITMAP_NULL) - return; - - for (i = 0; i < NS_BITMAP_NUM_OF_GROUPS; i++) - if (bm->groups[i]) - XFREE (MTYPE_NS_BITMAP, bm->groups[i]); - - XFREE (MTYPE_NS_BITMAP, bm); -} - -void -ns_bitmap_set (ns_bitmap_t bmap, ns_id_t ns_id) -{ - struct ns_bitmap *bm = (struct ns_bitmap *) bmap; - u_char group = NS_BITMAP_GROUP (ns_id); - u_char offset = NS_BITMAP_BIT_OFFSET (ns_id); - - if (bmap == NS_BITMAP_NULL) - return; - - if (bm->groups[group] == NULL) - bm->groups[group] = XCALLOC (MTYPE_NS_BITMAP, - NS_BITMAP_NUM_OF_BYTES_IN_GROUP); - - SET_FLAG (bm->groups[group][NS_BITMAP_INDEX_IN_GROUP (offset)], - NS_BITMAP_FLAG (offset)); -} - -void -ns_bitmap_unset (ns_bitmap_t bmap, ns_id_t ns_id) -{ - struct ns_bitmap *bm = (struct ns_bitmap *) bmap; - u_char group = NS_BITMAP_GROUP (ns_id); - u_char offset = NS_BITMAP_BIT_OFFSET (ns_id); - - if (bmap == NS_BITMAP_NULL || bm->groups[group] == NULL) - return; - - UNSET_FLAG (bm->groups[group][NS_BITMAP_INDEX_IN_GROUP (offset)], - NS_BITMAP_FLAG (offset)); -} - -int -ns_bitmap_check (ns_bitmap_t bmap, ns_id_t ns_id) -{ - struct ns_bitmap *bm = (struct ns_bitmap *) bmap; - u_char group = NS_BITMAP_GROUP (ns_id); - u_char offset = NS_BITMAP_BIT_OFFSET (ns_id); - - if (bmap == NS_BITMAP_NULL || bm->groups[group] == NULL) - return 0; - - return CHECK_FLAG (bm->groups[group][NS_BITMAP_INDEX_IN_GROUP (offset)], - NS_BITMAP_FLAG (offset)) ? 1 : 0; -} - /* * NS realization with NETNS */ diff --git a/lib/ns.h b/lib/ns.h index 3fac739861..c96f1b2743 100644 --- a/lib/ns.h +++ b/lib/ns.h @@ -30,15 +30,8 @@ typedef u_int16_t ns_id_t; /* The default NS ID */ #define NS_DEFAULT 0 -/* - * The command strings - */ +/* Default netns directory (Linux) */ #define NS_RUN_DIR "/var/run/netns" -#define NS_CMD_STR "logical-router <0-65535>" -#define NS_CMD_HELP_STR "Specify the Logical-Router\nThe Logical-Router ID\n" - -#define NS_ALL_CMD_STR "logical-router all" -#define NS_ALL_CMD_HELP_STR "Specify the logical-router\nAll logical-router's\n" /* * NS hooks @@ -59,71 +52,6 @@ typedef u_int16_t ns_id_t; */ extern void ns_add_hook (int, int (*)(ns_id_t, void **)); -/* - * NS iteration - */ - -typedef void * ns_iter_t; -#define NS_ITER_INVALID NULL /* invalid value of the iterator */ - -/* - * NS iteration utilities. Example for the usage: - * - * ns_iter_t iter = ns_first(); - * for (; iter != NS_ITER_INVALID; iter = ns_next (iter)) - * - * or - * - * ns_iter_t iter = ns_iterator (); - * for (; iter != NS_ITER_INVALID; iter = ns_next (iter)) - */ - -/* Return the iterator of the first NS. */ -extern ns_iter_t ns_first (void); -/* Return the next NS iterator to the given iterator. */ -extern ns_iter_t ns_next (ns_iter_t); -/* Return the NS iterator of the given NS ID. If it does not exist, - * the iterator of the next existing NS is returned. */ -extern ns_iter_t ns_iterator (ns_id_t); - -/* - * NS iterator to properties - */ -extern ns_id_t ns_iter2id (ns_iter_t); -extern void *ns_iter2info (ns_iter_t); -extern struct list *ns_iter2iflist (ns_iter_t); - -/* - * Utilities to obtain the user data - */ - -/* Get the data pointer of the specified NS. If not found, create one. */ -extern void *ns_info_get (ns_id_t); -/* Look up the data pointer of the specified NS. */ -extern void *ns_info_lookup (ns_id_t); - -/* - * Utilities to obtain the interface list - */ - -/* Look up the interface list of the specified NS. */ -extern struct list *ns_iflist (ns_id_t); -/* Get the interface list of the specified NS. Create one if not find. */ -extern struct list *ns_iflist_get (ns_id_t); - -/* - * NS bit-map: maintaining flags, one bit per NS ID - */ - -typedef void * ns_bitmap_t; -#define NS_BITMAP_NULL NULL - -extern ns_bitmap_t ns_bitmap_init (void); -extern void ns_bitmap_free (ns_bitmap_t); -extern void ns_bitmap_set (ns_bitmap_t, ns_id_t); -extern void ns_bitmap_unset (ns_bitmap_t, ns_id_t); -extern int ns_bitmap_check (ns_bitmap_t, ns_id_t); - /* * NS initializer/destructor */ From f30c50b99223be343b7fe1ae9e374602ec0d93d5 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Fri, 28 Oct 2016 22:32:07 -0200 Subject: [PATCH 21/44] zebra/lib: move some code around * move netlink code from zebra_nc.c to kernel_netlink.c; * move vrf CLI commands from if.c/interface.c to vrf.c/zebra_vrf.c; * move declaration of the 'ns' structure to a header file. Signed-off-by: Renato Westphal --- lib/if.c | 54 ------------------------------------------ lib/ns.c | 16 ------------- lib/ns.h | 16 +++++++++++++ lib/vrf.c | 54 ++++++++++++++++++++++++++++++++++++++++++ zebra/interface.c | 49 -------------------------------------- zebra/kernel_netlink.c | 15 ++++++++---- zebra/zebra_ns.c | 10 -------- zebra/zebra_vrf.c | 50 ++++++++++++++++++++++++++++++++++++++ 8 files changed, 131 insertions(+), 133 deletions(-) diff --git a/lib/if.c b/lib/if.c index 6ae8500291..70304e584c 100644 --- a/lib/if.c +++ b/lib/if.c @@ -840,60 +840,6 @@ ALIAS (no_interface, "Interface's name\n" VRF_CMD_HELP_STR) -DEFUN (vrf, - vrf_cmd, - "vrf NAME", - "Select a VRF to configure\n" - "VRF's name\n") -{ - struct vrf *vrfp; - size_t sl; - - if ((sl = strlen(argv[0])) > VRF_NAMSIZ) - { - vty_out (vty, "%% VRF name %s is invalid: length exceeds " - "%d characters%s", - argv[0], VRF_NAMSIZ, VTY_NEWLINE); - return CMD_WARNING; - } - - vrfp = vrf_get (VRF_UNKNOWN, argv[0]); - - VTY_PUSH_CONTEXT_COMPAT (VRF_NODE, vrfp); - - return CMD_SUCCESS; -} - -DEFUN_NOSH (no_vrf, - no_vrf_cmd, - "no vrf NAME", - NO_STR - "Delete a pseudo VRF's configuration\n" - "VRF's name\n") -{ - struct vrf *vrfp; - - vrfp = vrf_list_lookup_by_name (argv[0]); - - if (vrfp == NULL) - { - vty_out (vty, "%% VRF %s does not exist%s", argv[0], VTY_NEWLINE); - return CMD_WARNING; - } - - if (CHECK_FLAG (vrfp->status, VRF_ACTIVE)) - { - vty_out (vty, "%% Only inactive VRFs can be deleted%s", - VTY_NEWLINE); - return CMD_WARNING; - } - - vrf_delete(vrfp); - - return CMD_SUCCESS; -} - - /* For debug purpose. */ DEFUN (show_address, show_address_cmd, diff --git a/lib/ns.c b/lib/ns.c index 07e6ec5b9a..904fc6999c 100644 --- a/lib/ns.c +++ b/lib/ns.c @@ -91,22 +91,6 @@ static int have_netns(void) #endif } -struct ns -{ - /* Identifier, same as the vector index */ - ns_id_t ns_id; - /* Name */ - char *name; - /* File descriptor */ - int fd; - - /* Master list of interfaces belonging to this NS */ - struct list *iflist; - - /* User data */ - void *info; -}; - /* Holding NS hooks */ struct ns_master { diff --git a/lib/ns.h b/lib/ns.h index c96f1b2743..74616cd62f 100644 --- a/lib/ns.h +++ b/lib/ns.h @@ -33,6 +33,22 @@ typedef u_int16_t ns_id_t; /* Default netns directory (Linux) */ #define NS_RUN_DIR "/var/run/netns" +struct ns +{ + /* Identifier, same as the vector index */ + ns_id_t ns_id; + /* Name */ + char *name; + /* File descriptor */ + int fd; + + /* Master list of interfaces belonging to this NS */ + struct list *iflist; + + /* User data */ + void *info; +}; + /* * NS hooks */ diff --git a/lib/vrf.c b/lib/vrf.c index 63adea4aec..d87e38ebe8 100644 --- a/lib/vrf.c +++ b/lib/vrf.c @@ -740,6 +740,60 @@ vrf_socket (int domain, int type, int protocol, vrf_id_t vrf_id) return ret; } +/* vrf CLI commands */ +DEFUN (vrf, + vrf_cmd, + "vrf NAME", + "Select a VRF to configure\n" + "VRF's name\n") +{ + struct vrf *vrfp; + size_t sl; + + if ((sl = strlen(argv[0])) > VRF_NAMSIZ) + { + vty_out (vty, "%% VRF name %s is invalid: length exceeds " + "%d characters%s", + argv[0], VRF_NAMSIZ, VTY_NEWLINE); + return CMD_WARNING; + } + + vrfp = vrf_get (VRF_UNKNOWN, argv[0]); + + VTY_PUSH_CONTEXT_COMPAT (VRF_NODE, vrfp); + + return CMD_SUCCESS; +} + +DEFUN_NOSH (no_vrf, + no_vrf_cmd, + "no vrf NAME", + NO_STR + "Delete a pseudo VRF's configuration\n" + "VRF's name\n") +{ + struct vrf *vrfp; + + vrfp = vrf_list_lookup_by_name (argv[0]); + + if (vrfp == NULL) + { + vty_out (vty, "%% VRF %s does not exist%s", argv[0], VTY_NEWLINE); + return CMD_WARNING; + } + + if (CHECK_FLAG (vrfp->status, VRF_ACTIVE)) + { + vty_out (vty, "%% Only inactive VRFs can be deleted%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + vrf_delete(vrfp); + + return CMD_SUCCESS; +} + /* * Debug CLI for vrf's */ diff --git a/zebra/interface.c b/zebra/interface.c index 422368852d..dd1f8a146b 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -1289,33 +1289,6 @@ struct cmd_node interface_node = 1 }; -/* Wrapper hook point for zebra daemon so that ifindex can be set - * DEFUN macro not used as extract.pl HAS to ignore this - * See also interface_cmd in lib/if.c - */ -DEFUN_NOSH (zebra_vrf, - zebra_vrf_cmd, - "vrf NAME", - "Select a VRF to configure\n" - "VRF's name\n") -{ - // VTY_DECLVAR_CONTEXT (vrf, vrfp); - int ret; - - /* Call lib vrf() */ - if ((ret = vrf_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS) - return ret; - - return ret; -} - -struct cmd_node vrf_node = -{ - VRF_NODE, - "%s(config-vrf)# ", - 1 -}; - /* Show all interfaces to vty. */ DEFUN (show_interface, show_interface_cmd, "show interface", @@ -2929,23 +2902,6 @@ if_config_write (struct vty *vty) return 0; } -static int -vrf_config_write (struct vty *vty) -{ - struct listnode *node; - struct zebra_vrf *zvrf; - - for (ALL_LIST_ELEMENTS_RO (zvrf_list, node, zvrf)) - { - if (strcmp(zvrf->name, VRF_DEFAULT_NAME)) - { - vty_out (vty, "vrf %s%s", zvrf->name, VTY_NEWLINE); - vty_out (vty, "!%s", VTY_NEWLINE); - } - } - return 0; -} - /* Allocate and initialize interface vector. */ void zebra_if_init (void) @@ -2957,7 +2913,6 @@ zebra_if_init (void) /* Install configuration write function. */ install_node (&interface_node, if_config_write); install_node (&link_params_node, NULL); - install_node (&vrf_node, vrf_config_write); install_element (VIEW_NODE, &show_interface_cmd); install_element (VIEW_NODE, &show_interface_vrf_cmd); @@ -3020,8 +2975,4 @@ zebra_if_init (void) install_element(LINK_PARAMS_NODE, &link_params_use_bw_cmd); install_element(LINK_PARAMS_NODE, &no_link_params_use_bw_cmd); install_element(LINK_PARAMS_NODE, &exit_link_params_cmd); - - install_element (CONFIG_NODE, &zebra_vrf_cmd); - install_element (CONFIG_NODE, &no_vrf_cmd); - install_default (VRF_NODE); } diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c index 378327ab46..9f9a62f384 100644 --- a/zebra/kernel_netlink.c +++ b/zebra/kernel_netlink.c @@ -716,11 +716,18 @@ kernel_init (struct zebra_ns *zns) { unsigned long groups; - groups = RTMGRP_LINK | RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_IFADDR; -#ifdef HAVE_IPV6 - groups |= RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFADDR; -#endif /* HAVE_IPV6 */ + /* Initialize netlink sockets */ + groups = RTMGRP_LINK | RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_IFADDR | + RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFADDR; + + snprintf (zns->netlink.name, sizeof (zns->netlink.name), + "netlink-listen (NS %u)", zns->ns_id); + zns->netlink.sock = -1; netlink_socket (&zns->netlink, groups, zns->ns_id); + + snprintf (zns->netlink_cmd.name, sizeof (zns->netlink_cmd.name), + "netlink-cmd (NS %u)", zns->ns_id); + zns->netlink_cmd.sock = -1; netlink_socket (&zns->netlink_cmd, 0, zns->ns_id); /* Register kernel socket. */ diff --git a/zebra/zebra_ns.c b/zebra/zebra_ns.c index 4499901021..642d2700a4 100644 --- a/zebra/zebra_ns.c +++ b/zebra/zebra_ns.c @@ -50,16 +50,6 @@ zebra_ns_enable (ns_id_t ns_id, void **info) rtadv_init (zns); #endif -#ifdef HAVE_NETLINK - /* Initialize netlink sockets */ - snprintf (zns->netlink.name, sizeof (zns->netlink.name), - "netlink-listen (NS %u)", ns_id); - zns->netlink.sock = -1; - - snprintf (zns->netlink_cmd.name, sizeof (zns->netlink_cmd.name), - "netlink-cmd (NS %u)", ns_id); - zns->netlink_cmd.sock = -1; -#endif zns->if_table = route_table_init (); kernel_init (zns); interface_list (zns); diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index ab825281e4..a4e5eabbc8 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -23,6 +23,7 @@ #include "log.h" #include "linklist.h" +#include "command.h" #include "memory.h" #include "zebra/debug.h" @@ -427,6 +428,50 @@ zebra_vrf_other_route_table (afi_t afi, u_int32_t table_id, vrf_id_t vrf_id) return zvrf->table[afi][SAFI_UNICAST]; } +/* Wrapper hook point for zebra daemon so that ifindex can be set + * DEFUN macro not used as extract.pl HAS to ignore this + * See also interface_cmd in lib/if.c + */ +DEFUN_NOSH (zebra_vrf, + zebra_vrf_cmd, + "vrf NAME", + "Select a VRF to configure\n" + "VRF's name\n") +{ + // VTY_DECLVAR_CONTEXT (vrf, vrfp); + int ret; + + /* Call lib vrf() */ + if ((ret = vrf_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS) + return ret; + + return ret; +} + +static int +vrf_config_write (struct vty *vty) +{ + struct listnode *node; + struct zebra_vrf *zvrf; + + for (ALL_LIST_ELEMENTS_RO (zvrf_list, node, zvrf)) + { + if (strcmp(zvrf->name, VRF_DEFAULT_NAME)) + { + vty_out (vty, "vrf %s%s", zvrf->name, VTY_NEWLINE); + vty_out (vty, "!%s", VTY_NEWLINE); + } + } + return 0; +} + +struct cmd_node vrf_node = +{ + VRF_NODE, + "%s(config-vrf)# ", + 1 +}; + /* Zebra VRF initialization. */ void zebra_vrf_init (void) @@ -439,4 +484,9 @@ zebra_vrf_init (void) zvrf_list = list_new (); vrf_init (); + + install_node (&vrf_node, vrf_config_write); + install_default (VRF_NODE); + install_element (CONFIG_NODE, &zebra_vrf_cmd); + install_element (CONFIG_NODE, &no_vrf_cmd); } From 60f1637a8b35b2968e64dd1619e499033c8068bb Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Fri, 28 Oct 2016 16:53:38 -0200 Subject: [PATCH 22/44] lib: fix creation of pre-provisioned VRFs If we configure a VRF that doesn't match any device in the kernel, we'll fall in the first case of the vrf_get() function. In this function, a vrf structure is callocated and it's vrf_id is never set explicitly, which means it's set to zero (the vrf-id of the default VRF). When this happens, commands like "router-id A.B.C.D vrf ..." will act on the default VRF and not on the pre-provisioned VRF. To fix this, always set the vrf_id of pre-provisioned VRFs to VRF_UNKNOWN. Signed-off-by: Renato Westphal --- lib/vrf.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/vrf.c b/lib/vrf.c index d87e38ebe8..13884aba62 100644 --- a/lib/vrf.c +++ b/lib/vrf.c @@ -124,6 +124,7 @@ vrf_get (vrf_id_t vrf_id, const char *name) zlog_debug ("VRF(%u) %s is created.", vrf_id, (name) ? name : "(NULL)"); strcpy (vrf->name, name); + vrf->vrf_id = VRF_UNKNOWN; listnode_add_sort (vrf_list, vrf); if_init (&vrf->iflist); QOBJ_REG (vrf, vrf); From 51bdc5f85ceb5d597924fc5f9b550257972a38fd Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Fri, 28 Oct 2016 22:26:04 -0200 Subject: [PATCH 23/44] zebra: nuke zvrf_list and always use vrf_list instead zvrf_list doesn't need to exist, it's basically a duplicate version of vrf_list. Also, zebra_vrf_delete() wasn't removing zvrf from zvrf_list, which was a bug. Signed-off-by: Renato Westphal --- zebra/zebra_vrf.c | 24 ++++++++++-------------- zebra/zebra_vrf.h | 2 -- zebra/zebra_vty.c | 22 +++++++++++++++++----- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index a4e5eabbc8..915849c057 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -36,7 +36,6 @@ #include "zebra/zebra_mpls.h" extern struct zebra_t zebrad; -struct list *zvrf_list; /* VRF information update. */ static void @@ -96,7 +95,6 @@ zebra_vrf_new (vrf_id_t vrf_id, const char *name, void **info) zvrf->zns = zebra_ns_lookup (NS_DEFAULT); /* Point to the global (single) NS */ *info = (void *)zvrf; router_id_init (zvrf); - listnode_add_sort (zvrf_list, zvrf); } else { @@ -346,21 +344,19 @@ zebra_vrf_lookup (vrf_id_t vrf_id) return vrf_info_lookup (vrf_id); } -/* Lookup the zvrf in the zvrf_list. */ +/* Lookup VRF by name. */ struct zebra_vrf * zebra_vrf_list_lookup_by_name (const char *name) { - struct listnode *node; - struct zebra_vrf *zvrf; + struct vrf *vrf; if (!name) name = VRF_DEFAULT_NAME; - for (ALL_LIST_ELEMENTS_RO (zvrf_list, node, zvrf)) - { - if (strcmp(name, zvrf->name) == 0) - return zvrf; - } + vrf = vrf_list_lookup_by_name (name); + if (vrf) + return ((struct zebra_vrf *) vrf->info); + return NULL; } @@ -452,11 +448,13 @@ static int vrf_config_write (struct vty *vty) { struct listnode *node; + struct vrf *vrf; struct zebra_vrf *zvrf; - for (ALL_LIST_ELEMENTS_RO (zvrf_list, node, zvrf)) + for (ALL_LIST_ELEMENTS_RO (vrf_list, node, vrf)) { - if (strcmp(zvrf->name, VRF_DEFAULT_NAME)) + zvrf = vrf->info; + if (! zvrf || strcmp (zvrf->name, VRF_DEFAULT_NAME)) { vty_out (vty, "vrf %s%s", zvrf->name, VTY_NEWLINE); vty_out (vty, "!%s", VTY_NEWLINE); @@ -481,8 +479,6 @@ zebra_vrf_init (void) vrf_add_hook (VRF_DISABLE_HOOK, zebra_vrf_disable); vrf_add_hook (VRF_DELETE_HOOK, zebra_vrf_delete); - zvrf_list = list_new (); - vrf_init (); install_node (&vrf_node, vrf_config_write); diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h index 0baddc1b6a..8dffe27dcf 100644 --- a/zebra/zebra_vrf.h +++ b/zebra/zebra_vrf.h @@ -86,8 +86,6 @@ struct zebra_vrf #define MPLS_FLAG_SCHEDULE_LSPS (1 << 0) }; -extern struct list *zvrf_list; - struct route_table * zebra_vrf_table_with_table_id (afi_t afi, safi_t safi, vrf_id_t vrf_id, u_int32_t table_id); diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 9b0fad93e0..74f64dd057 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -3673,13 +3673,18 @@ static_config_ipv4 (struct vty *vty, safi_t safi, const char *cmd) struct route_node *rn; struct static_route *si; struct route_table *stable; + struct vrf *vrf; struct zebra_vrf *zvrf; char buf[BUFSIZ]; int write =0; struct listnode *node; - for (ALL_LIST_ELEMENTS_RO (zvrf_list, node, zvrf)) + for (ALL_LIST_ELEMENTS_RO (vrf_list, node, vrf)) { + zvrf = vrf->info; + if (! zvrf) + continue; + if ((stable = zvrf->stable[AFI_IP][safi]) == NULL) continue; @@ -5782,11 +5787,16 @@ static_config_ipv6 (struct vty *vty) int write = 0; char buf[PREFIX_STRLEN]; struct route_table *stable; + struct vrf *vrf; struct zebra_vrf *zvrf; struct listnode *node; - for (ALL_LIST_ELEMENTS_RO (zvrf_list, node, zvrf)) + for (ALL_LIST_ELEMENTS_RO (vrf_list, node, vrf)) { + zvrf = vrf->info; + if (! zvrf) + continue; + if ((stable = zvrf->stable[AFI_IP6][SAFI_UNICAST]) == NULL) continue; @@ -5874,13 +5884,15 @@ DEFUN (show_vrf, SHOW_STR "VRF\n") { + struct vrf *vrf; struct zebra_vrf *zvrf; struct listnode *node; - for (ALL_LIST_ELEMENTS_RO (zvrf_list, node, zvrf)) + for (ALL_LIST_ELEMENTS_RO (vrf_list, node, vrf)) { - if (!zvrf->vrf_id) - continue; + zvrf = vrf->info; + if (! zvrf || ! zvrf->vrf_id) + continue; vty_out (vty, "vrf %s ", zvrf->name); if (zvrf->vrf_id == VRF_UNKNOWN) From c7fdd84f36a262d062a10c1439121df361ab78d3 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Fri, 28 Oct 2016 23:03:35 -0200 Subject: [PATCH 24/44] lib: convert namespace code to use red-black trees We definitely need to stop abusing the route table data structure when it's not necessary. Convert the namespace code to use red-black trees instead. This greatly improves code readability. Signed-off-by: Renato Westphal --- lib/ns.c | 81 ++++++++++++++++++++------------------------------------ lib/ns.h | 9 +++++++ 2 files changed, 37 insertions(+), 53 deletions(-) diff --git a/lib/ns.c b/lib/ns.c index 904fc6999c..08432764db 100644 --- a/lib/ns.c +++ b/lib/ns.c @@ -31,8 +31,6 @@ #include "if.h" #include "ns.h" -#include "prefix.h" -#include "table.h" #include "log.h" #include "memory.h" @@ -43,6 +41,13 @@ DEFINE_MTYPE_STATIC(LIB, NS, "Logical-Router") DEFINE_MTYPE_STATIC(LIB, NS_NAME, "Logical-Router Name") DEFINE_MTYPE_STATIC(LIB, NS_BITMAP, "Logical-Router bit-map") +static __inline int ns_compare (struct ns *, struct ns *); +static struct ns *ns_lookup (ns_id_t); + +RB_GENERATE (ns_head, ns, entry, ns_compare) + +struct ns_head ns_tree = RB_INITIALIZER (&ns_tree); + #ifndef CLONE_NEWNET #define CLONE_NEWNET 0x40000000 /* New network namespace (lo, device, names sockets, etc) */ #endif @@ -100,44 +105,30 @@ struct ns_master int (*ns_disable_hook) (ns_id_t, void **); } ns_master = {0,}; -/* NS table */ -struct route_table *ns_table = NULL; - static int ns_is_enabled (struct ns *ns); static int ns_enable (struct ns *ns); static void ns_disable (struct ns *ns); - -/* Build the table key */ -static void -ns_build_key (ns_id_t ns_id, struct prefix *p) +static __inline int +ns_compare(struct ns *a, struct ns *b) { - p->family = AF_INET; - p->prefixlen = IPV4_MAX_BITLEN; - p->u.prefix4.s_addr = ns_id; + return (a->ns_id - b->ns_id); } /* Get a NS. If not found, create one. */ static struct ns * ns_get (ns_id_t ns_id) { - struct prefix p; - struct route_node *rn; struct ns *ns; - ns_build_key (ns_id, &p); - rn = route_node_get (ns_table, &p); - if (rn->info) - { - ns = (struct ns *)rn->info; - route_unlock_node (rn); /* get */ - return ns; - } + ns = ns_lookup (ns_id); + if (ns) + return (ns); ns = XCALLOC (MTYPE_NS, sizeof (struct ns)); ns->ns_id = ns_id; ns->fd = -1; - rn->info = ns; + RB_INSERT (ns_head, &ns_tree, ns); /* * Initialize interfaces. @@ -172,6 +163,7 @@ ns_delete (struct ns *ns) */ //if_terminate (&ns->iflist); + RB_REMOVE (ns_head, &ns_tree, ns); if (ns->name) XFREE (MTYPE_NS_NAME, ns->name); @@ -182,18 +174,9 @@ ns_delete (struct ns *ns) static struct ns * ns_lookup (ns_id_t ns_id) { - struct prefix p; - struct route_node *rn; - struct ns *ns = NULL; - - ns_build_key (ns_id, &p); - rn = route_node_lookup (ns_table, &p); - if (rn) - { - ns = (struct ns *)rn->info; - route_unlock_node (rn); /* lookup */ - } - return ns; + struct ns ns; + ns.ns_id = ns_id; + return (RB_FIND (ns_head, &ns_tree, &ns)); } /* @@ -414,17 +397,17 @@ static struct cmd_node ns_node = static int ns_config_write (struct vty *vty) { - struct route_node *rn; struct ns *ns; int write = 0; - for (rn = route_top (ns_table); rn; rn = route_next (rn)) - if ((ns = rn->info) != NULL && - ns->ns_id != NS_DEFAULT && ns->name) - { - vty_out (vty, "logical-router %u netns %s%s", ns->ns_id, ns->name, VTY_NEWLINE); - write++; - } + RB_FOREACH (ns, ns_head, &ns_tree) { + if (ns->ns_id == NS_DEFAULT || ns->name == NULL) + continue; + + vty_out (vty, "logical-router %u netns %s%s", ns->ns_id, ns->name, + VTY_NEWLINE); + write = 1; + } return write; } @@ -435,9 +418,6 @@ ns_init (void) { struct ns *default_ns; - /* Allocate NS table. */ - ns_table = route_table_init (); - /* The default NS always exists. */ default_ns = ns_get (NS_DEFAULT); if (!default_ns) @@ -469,15 +449,10 @@ ns_init (void) void ns_terminate (void) { - struct route_node *rn; struct ns *ns; - for (rn = route_top (ns_table); rn; rn = route_next (rn)) - if ((ns = rn->info) != NULL) - ns_delete (ns); - - route_table_finish (ns_table); - ns_table = NULL; + while ((ns = RB_ROOT (&ns_tree)) != NULL) + ns_delete (ns); } /* Create a socket for the NS. */ diff --git a/lib/ns.h b/lib/ns.h index 74616cd62f..2a7be1ef8a 100644 --- a/lib/ns.h +++ b/lib/ns.h @@ -23,6 +23,7 @@ #ifndef _ZEBRA_NS_H #define _ZEBRA_NS_H +#include "openbsd-tree.h" #include "linklist.h" typedef u_int16_t ns_id_t; @@ -35,10 +36,14 @@ typedef u_int16_t ns_id_t; struct ns { + RB_ENTRY(ns) entry; + /* Identifier, same as the vector index */ ns_id_t ns_id; + /* Name */ char *name; + /* File descriptor */ int fd; @@ -48,6 +53,10 @@ struct ns /* User data */ void *info; }; +RB_HEAD (ns_head, ns); +RB_PROTOTYPE (ns_head, ns, entry, ns_compare) + +extern struct ns_head ns_tree; /* * NS hooks From 1a1a70655c869a1b66e363894e5aba19f4aa08f3 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sat, 29 Oct 2016 14:37:11 -0200 Subject: [PATCH 25/44] lib: convert vrf code to use red-black trees as well Signed-off-by: Renato Westphal --- lib/if.c | 35 +++----- lib/vrf.c | 199 +++++++---------------------------------- lib/vrf.h | 45 ++-------- zebra/interface.c | 31 ++++--- zebra/irdp_main.c | 7 +- zebra/router-id.c | 6 +- zebra/rt_netlink.c | 6 +- zebra/rtadv.c | 6 +- zebra/zebra_ptm.c | 12 +-- zebra/zebra_rib.c | 65 +++++++------- zebra/zebra_routemap.c | 8 +- zebra/zebra_vrf.c | 5 +- zebra/zebra_vty.c | 120 ++++++++++++------------- zebra/zserv.c | 14 ++- 14 files changed, 188 insertions(+), 371 deletions(-) diff --git a/lib/if.c b/lib/if.c index 70304e584c..6df4942296 100644 --- a/lib/if.c +++ b/lib/if.c @@ -308,13 +308,11 @@ if_lookup_by_name_vrf (const char *name, vrf_id_t vrf_id) struct interface * if_lookup_by_name_all_vrf (const char *name) { + struct vrf *vrf; struct interface *ifp; - struct vrf *vrf = NULL; - vrf_iter_t iter; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - vrf = vrf_iter2vrf (iter); ifp = if_lookup_by_name_vrf (name, vrf->vrf_id); if (ifp) return ifp; @@ -490,18 +488,16 @@ struct interface * if_get_by_name_len_vrf (const char *name, size_t namelen, vrf_id_t vrf_id, int vty) { struct interface *ifp; + struct vrf *vrf; struct listnode *node; - struct vrf *vrf = NULL; - vrf_iter_t iter; ifp = if_lookup_by_name_len_vrf (name, namelen, vrf_id); if (ifp) return ifp; /* Didn't find the interface on that vrf. Defined on a different one? */ - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - vrf = vrf_iter2vrf(iter); for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf->vrf_id), node, ifp)) { if (!memcmp(name, ifp->name, namelen) && (ifp->name[namelen] == '\0')) @@ -666,14 +662,13 @@ if_dump (const struct interface *ifp) void if_dump_all (void) { - struct list *intf_list; + struct vrf *vrf; struct listnode *node; void *p; - vrf_iter_t iter; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - if ((intf_list = vrf_iter2iflist (iter)) != NULL) - for (ALL_LIST_ELEMENTS_RO (intf_list, node, p)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + if (vrf->iflist != NULL) + for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, p)) if_dump (p); } @@ -885,24 +880,22 @@ DEFUN (show_address_vrf_all, "address\n" VRF_ALL_CMD_HELP_STR) { - struct list *intf_list; + struct vrf *vrf; struct listnode *node; struct listnode *node2; struct interface *ifp; struct connected *ifc; struct prefix *p; - vrf_iter_t iter; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - intf_list = vrf_iter2iflist (iter); - if (!intf_list || !listcount (intf_list)) + if (!vrf->iflist || !listcount (vrf->iflist)) continue; - vty_out (vty, "%sVRF %u%s%s", VTY_NEWLINE, vrf_iter2id (iter), - VTY_NEWLINE, VTY_NEWLINE); + vty_out (vty, "%sVRF %u%s%s", VTY_NEWLINE, vrf->vrf_id, VTY_NEWLINE, + VTY_NEWLINE); - for (ALL_LIST_ELEMENTS_RO (intf_list, node, ifp)) + for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp)) { for (ALL_LIST_ELEMENTS_RO (ifp->connected, node2, ifc)) { diff --git a/lib/vrf.c b/lib/vrf.c index 13884aba62..79885ff3e3 100644 --- a/lib/vrf.c +++ b/lib/vrf.c @@ -35,6 +35,12 @@ DEFINE_MTYPE_STATIC(LIB, VRF_BITMAP, "VRF bit-map") DEFINE_QOBJ_TYPE(vrf) +static __inline int vrf_id_compare (struct vrf *, struct vrf *); + +RB_GENERATE (vrf_id_head, vrf, id_entry, vrf_id_compare) + +struct vrf_id_head vrfs_by_id = RB_INITIALIZER (&vrfs_by_id); + /* * Turn on/off debug code * for vrf. @@ -50,9 +56,6 @@ struct vrf_master int (*vrf_disable_hook) (vrf_id_t, const char *, void **); } vrf_master = {0,}; -/* VRF table */ -struct route_table *vrf_table = NULL; - /* VRF is part of a list too to store it before its actually active */ struct list *vrf_list; @@ -75,13 +78,10 @@ vrf_list_lookup_by_name (const char *name) return NULL; } -/* Build the table key */ -static void -vrf_build_key (vrf_id_t vrf_id, struct prefix *p) +static __inline int +vrf_id_compare (struct vrf *a, struct vrf *b) { - p->family = AF_INET; - p->prefixlen = IPV4_MAX_BITLEN; - p->u.prefix4.s_addr = vrf_id; + return (a->vrf_id - b->vrf_id); } /* Get a VRF. If not found, create one. @@ -94,9 +94,7 @@ vrf_build_key (vrf_id_t vrf_id, struct prefix *p) struct vrf * vrf_get (vrf_id_t vrf_id, const char *name) { - struct prefix p; - struct route_node *rn = NULL; - struct vrf *vrf = NULL; + struct vrf *vrf; if (debug_vrf) zlog_debug ("VRF_GET: %s(%d)", name, vrf_id); @@ -156,17 +154,8 @@ vrf_get (vrf_id_t vrf_id, const char *name) if (vrf->vrf_id == vrf_id) return vrf; - /* - * Now we have a situation where we've had a - * vrf created, but not yet created the vrf_id route - * node, let's do so and match the code up. - */ - vrf_build_key (vrf_id, &p); - rn = route_node_get (vrf_table, &p); - - rn->info = vrf; - vrf->node = rn; vrf->vrf_id = vrf_id; + RB_INSERT (vrf_id_head, &vrfs_by_id, vrf); if (vrf_master.vrf_new_hook) (*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info); @@ -182,12 +171,9 @@ vrf_get (vrf_id_t vrf_id, const char *name) * We've already been told about the vrf_id * or we haven't. */ - vrf_build_key (vrf_id, &p); - rn = route_node_get (vrf_table, &p); - if (rn->info) + vrf = vrf_lookup (vrf_id); + if (vrf) { - vrf = rn->info; - route_unlock_node (rn); /* * We know at this point that the vrf->name is not * right because we would have caught it above. @@ -209,12 +195,10 @@ vrf_get (vrf_id_t vrf_id, const char *name) else { vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf)); - - rn->info = vrf; - vrf->node = rn; vrf->vrf_id = vrf_id; strcpy (vrf->name, name); listnode_add_sort (vrf_list, vrf); + RB_INSERT (vrf_id_head, &vrfs_by_id, vrf); if_init (&vrf->iflist); QOBJ_REG (vrf, vrf); if (vrf_master.vrf_new_hook) @@ -237,23 +221,18 @@ vrf_get (vrf_id_t vrf_id, const char *name) */ else if (!name) { - vrf_build_key (vrf_id, &p); - rn = route_node_get (vrf_table, &p); + vrf = vrf_lookup (vrf_id); if (debug_vrf) - zlog_debug("Vrf found: %p", rn->info); + zlog_debug("Vrf found: %p", vrf); - if (rn->info) - { - route_unlock_node (rn); - return (rn->info); - } + if (vrf) + return vrf; else { vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf)); - rn->info = vrf; - vrf->node = rn; vrf->vrf_id = vrf_id; if_init (&vrf->iflist); + RB_INSERT (vrf_id_head, &vrfs_by_id, vrf); QOBJ_REG (vrf, vrf); if (debug_vrf) zlog_debug("Vrf Created: %p", vrf); @@ -284,12 +263,8 @@ vrf_delete (struct vrf *vrf) QOBJ_UNREG (vrf); if_terminate (&vrf->iflist); - if (vrf->node) - { - vrf->node->info = NULL; - route_unlock_node(vrf->node); - } - + if (vrf->vrf_id != VRF_UNKNOWN) + RB_REMOVE (vrf_id_head, &vrfs_by_id, vrf); listnode_delete (vrf_list, vrf); XFREE (MTYPE_VRF, vrf); @@ -299,18 +274,9 @@ vrf_delete (struct vrf *vrf) struct vrf * vrf_lookup (vrf_id_t vrf_id) { - struct prefix p; - struct route_node *rn; - struct vrf *vrf = NULL; - - vrf_build_key (vrf_id, &p); - rn = route_node_lookup (vrf_table, &p); - if (rn) - { - vrf = (struct vrf *)rn->info; - route_unlock_node (rn); /* lookup */ - } - return vrf; + struct vrf vrf; + vrf.vrf_id = vrf_id; + return (RB_FIND (vrf_id_head, &vrfs_by_id, &vrf)); } /* @@ -401,112 +367,15 @@ vrf_add_hook (int type, int (*func)(vrf_id_t, const char *, void **)) } } -/* Return the iterator of the first VRF. */ -vrf_iter_t -vrf_first (void) -{ - struct route_node *rn; - - for (rn = route_top (vrf_table); rn; rn = route_next (rn)) - if (rn->info) - { - route_unlock_node (rn); /* top/next */ - return (vrf_iter_t)rn; - } - return VRF_ITER_INVALID; -} - -/* Return the next VRF iterator to the given iterator. */ -vrf_iter_t -vrf_next (vrf_iter_t iter) -{ - struct route_node *rn = NULL; - - /* Lock it first because route_next() will unlock it. */ - if (iter != VRF_ITER_INVALID) - rn = route_next (route_lock_node ((struct route_node *)iter)); - - for (; rn; rn = route_next (rn)) - if (rn->info) - { - route_unlock_node (rn); /* next */ - return (vrf_iter_t)rn; - } - return VRF_ITER_INVALID; -} - -/* Return the VRF iterator of the given VRF ID. If it does not exist, - * the iterator of the next existing VRF is returned. */ -vrf_iter_t -vrf_iterator (vrf_id_t vrf_id) -{ - struct prefix p; - struct route_node *rn; - - vrf_build_key (vrf_id, &p); - rn = route_node_get (vrf_table, &p); - if (rn->info) - { - /* OK, the VRF exists. */ - route_unlock_node (rn); /* get */ - return (vrf_iter_t)rn; - } - - /* Find the next VRF. */ - for (rn = route_next (rn); rn; rn = route_next (rn)) - if (rn->info) - { - route_unlock_node (rn); /* next */ - return (vrf_iter_t)rn; - } - - return VRF_ITER_INVALID; -} - -/* Obtain the VRF ID from the given VRF iterator. */ -vrf_id_t -vrf_iter2id (vrf_iter_t iter) -{ - struct route_node *rn = (struct route_node *) iter; - return (rn && rn->info) ? ((struct vrf *)rn->info)->vrf_id : VRF_DEFAULT; -} - -struct vrf * -vrf_iter2vrf (vrf_iter_t iter) -{ - struct route_node *rn = (struct route_node *) iter; - return (rn && rn->info) ? (struct vrf *)rn->info : NULL; -} - -/* Obtain the data pointer from the given VRF iterator. */ -void * -vrf_iter2info (vrf_iter_t iter) -{ - struct route_node *rn = (struct route_node *) iter; - return (rn && rn->info) ? ((struct vrf *)rn->info)->info : NULL; -} - -/* Obtain the interface list from the given VRF iterator. */ -struct list * -vrf_iter2iflist (vrf_iter_t iter) -{ - struct route_node *rn = (struct route_node *) iter; - return (rn && rn->info) ? ((struct vrf *)rn->info)->iflist : NULL; -} - /* Look up a VRF by name. */ struct vrf * vrf_lookup_by_name (const char *name) { - struct vrf *vrf = NULL; - vrf_iter_t iter; + struct vrf *vrf; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - { - vrf = vrf_iter2vrf (iter); - if (vrf && !strcmp(vrf->name, name)) - return vrf; - } + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + if (!strcmp(vrf->name, name)) + return vrf; return NULL; } @@ -693,9 +562,6 @@ vrf_init (void) vrf_list = list_new (); vrf_list->cmp = (int (*)(void *, void *))vrf_cmp_func; - /* Allocate VRF table. */ - vrf_table = route_table_init (); - /* The default VRF always exists. */ default_vrf = vrf_get (VRF_DEFAULT, VRF_DEFAULT_NAME); if (!default_vrf) @@ -716,18 +582,13 @@ vrf_init (void) void vrf_terminate (void) { - struct route_node *rn; struct vrf *vrf; if (debug_vrf) zlog_debug ("%s: Shutting down vrf subsystem", __PRETTY_FUNCTION__); - for (rn = route_top (vrf_table); rn; rn = route_next (rn)) - if ((vrf = rn->info) != NULL) - vrf_delete (vrf); - - route_table_finish (vrf_table); - vrf_table = NULL; + while ((vrf = RB_ROOT (&vrfs_by_id)) != NULL) + vrf_delete (vrf); } /* Create a socket for the VRF. */ diff --git a/lib/vrf.h b/lib/vrf.h index 127b7082e9..f093f4fbd8 100644 --- a/lib/vrf.h +++ b/lib/vrf.h @@ -23,6 +23,7 @@ #ifndef _ZEBRA_VRF_H #define _ZEBRA_VRF_H +#include "openbsd-tree.h" #include "linklist.h" #include "qobj.h" @@ -69,18 +70,18 @@ enum { struct vrf { + RB_ENTRY(vrf) id_entry; + /* Identifier, same as the vector index */ vrf_id_t vrf_id; - /* Name */ + /* Name */ char name[VRF_NAMSIZ + 1]; /* Zebra internal VRF status */ u_char status; #define VRF_ACTIVE (1 << 0) - struct route_node *node; - /* Master list of interfaces belonging to this VRF */ struct list *iflist; @@ -89,9 +90,12 @@ struct vrf QOBJ_FIELDS }; +RB_HEAD (vrf_id_head, vrf); +RB_PROTOTYPE (vrf_id_head, vrf, id_entry, vrf_id_compare) DECLARE_QOBJ_TYPE(vrf) +extern struct vrf_id_head vrfs_by_id; extern struct list *vrf_list; /* @@ -104,13 +108,6 @@ extern struct list *vrf_list; */ extern void vrf_add_hook (int, int (*)(vrf_id_t, const char *, void **)); -/* - * VRF iteration - */ - -typedef void * vrf_iter_t; -#define VRF_ITER_INVALID NULL /* invalid value of the iterator */ - extern struct vrf *vrf_lookup (vrf_id_t); extern struct vrf *vrf_lookup_by_name (const char *); extern struct vrf *vrf_list_lookup_by_name (const char *); @@ -135,34 +132,6 @@ extern vrf_id_t vrf_name_to_id (const char *); (V) = vrf->vrf_id; \ } while (0) -/* - * VRF iteration utilities. Example for the usage: - * - * vrf_iter_t iter = vrf_first(); - * for (; iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - * - * or - * - * vrf_iter_t iter = vrf_iterator (); - * for (; iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - */ - -/* Return the iterator of the first VRF. */ -extern vrf_iter_t vrf_first (void); -/* Return the next VRF iterator to the given iterator. */ -extern vrf_iter_t vrf_next (vrf_iter_t); -/* Return the VRF iterator of the given VRF ID. If it does not exist, - * the iterator of the next existing VRF is returned. */ -extern vrf_iter_t vrf_iterator (vrf_id_t); - -/* - * VRF iterator to properties - */ -extern vrf_id_t vrf_iter2id (vrf_iter_t); -extern struct vrf *vrf_iter2vrf (vrf_iter_t); -extern void *vrf_iter2info (vrf_iter_t); -extern struct list *vrf_iter2iflist (vrf_iter_t); - /* * Utilities to obtain the user data */ diff --git a/zebra/interface.c b/zebra/interface.c index dd1f8a146b..75040a87f0 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -1325,15 +1325,15 @@ DEFUN (show_interface_vrf_all, show_interface_vrf_all_cmd, "Interface status and configuration\n" VRF_ALL_CMD_HELP_STR) { + struct vrf *vrf; struct listnode *node; struct interface *ifp; - vrf_iter_t iter; interface_update_stats (); /* All interface print. */ - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp)) if_dump_vty (vty, ifp); return CMD_SUCCESS; @@ -1378,17 +1378,17 @@ DEFUN (show_interface_name_vrf_all, show_interface_name_vrf_all_cmd, "Interface name\n" VRF_ALL_CMD_HELP_STR) { + struct vrf *vrf; struct interface *ifp; - vrf_iter_t iter; int found = 0; interface_update_stats (); /* All interface print. */ - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { /* Specified interface print. */ - ifp = if_lookup_by_name_vrf (argv[0], vrf_iter2id (iter)); + ifp = if_lookup_by_name_vrf (argv[0], vrf->vrf_id); if (ifp) { if_dump_vty (vty, ifp); @@ -1484,15 +1484,14 @@ DEFUN (show_interface_desc_vrf_all, "Interface description\n" VRF_ALL_CMD_HELP_STR) { - vrf_iter_t iter; + struct vrf *vrf; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - if (!list_isempty (vrf_iter2iflist (iter))) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + if (!list_isempty (vrf->iflist)) { - vty_out (vty, "%s\tVRF %u%s%s", VTY_NEWLINE, - vrf_iter2id (iter), - VTY_NEWLINE, VTY_NEWLINE); - if_show_description (vty, vrf_iter2id (iter)); + vty_out (vty, "%s\tVRF %u%s%s", VTY_NEWLINE, vrf->vrf_id, + VTY_NEWLINE, VTY_NEWLINE); + if_show_description (vty, vrf->vrf_id); } return CMD_SUCCESS; @@ -2818,14 +2817,14 @@ link_params_config_write (struct vty *vty, struct interface *ifp) static int if_config_write (struct vty *vty) { + struct vrf *vrf; struct listnode *node; struct interface *ifp; - vrf_iter_t iter; zebra_ptm_write (vty); - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp)) { struct zebra_if *if_data; struct listnode *addrnode; diff --git a/zebra/irdp_main.c b/zebra/irdp_main.c index cc3a4abaf3..7fa4ad4cbe 100644 --- a/zebra/irdp_main.c +++ b/zebra/irdp_main.c @@ -304,17 +304,16 @@ void process_solicit (struct interface *ifp) void irdp_finish() { - + struct vrf *vrf; struct listnode *node, *nnode; struct interface *ifp; struct zebra_if *zi; struct irdp_interface *irdp; - vrf_iter_t iter; zlog_info("IRDP: Received shutdown notification."); - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - for (ALL_LIST_ELEMENTS (vrf_iter2iflist (iter), node, nnode, ifp)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + for (ALL_LIST_ELEMENTS (vrf->iflist, node, nnode, ifp)) { zi = ifp->info; diff --git a/zebra/router-id.c b/zebra/router-id.c index d5d9652c59..155a8e3939 100644 --- a/zebra/router-id.c +++ b/zebra/router-id.c @@ -195,11 +195,11 @@ router_id_del_address (struct connected *ifc) void router_id_write (struct vty *vty) { + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - if ((zvrf = vrf_iter2info (iter)) != NULL) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + if ((zvrf = vrf->info) != NULL) if (zvrf->rid_user_assigned.u.prefix4.s_addr) { if (zvrf->vrf_id == VRF_DEFAULT) diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index f16fd55c98..b18bf1ef7a 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -98,12 +98,12 @@ Pending: create an efficient table_id (in a tree/hash) based lookup) static vrf_id_t vrf_lookup_by_table (u_int32_t table_id) { + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((zvrf = vrf_iter2info (iter)) == NULL || + if ((zvrf = vrf->info) == NULL || (zvrf->table_id != table_id)) continue; diff --git a/zebra/rtadv.c b/zebra/rtadv.c index 3e0a198702..1ab7ac147c 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -373,7 +373,7 @@ static int rtadv_timer (struct thread *thread) { struct zebra_ns *zns = THREAD_ARG (thread); - vrf_iter_t iter; + struct vrf *vrf; struct listnode *node, *nnode; struct interface *ifp; struct zebra_if *zif; @@ -391,8 +391,8 @@ rtadv_timer (struct thread *thread) rtadv_event (zns, RTADV_TIMER_MSEC, 10 /* 10 ms */); } - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - for (ALL_LIST_ELEMENTS (vrf_iter2iflist (iter), node, nnode, ifp)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + for (ALL_LIST_ELEMENTS (vrf->iflist, node, nnode, ifp)) { if (if_is_loopback (ifp) || CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK) || diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c index 28e6c42ec6..4fc1173241 100644 --- a/zebra/zebra_ptm.c +++ b/zebra/zebra_ptm.c @@ -258,15 +258,15 @@ DEFUN (zebra_ptm_enable, "ptm-enable", "Enable neighbor check with specified topology\n") { + struct vrf *vrf; struct listnode *i; struct interface *ifp; struct zebra_if *if_data; - vrf_iter_t iter; ptm_cb.ptm_enable = ZEBRA_IF_PTM_ENABLE_ON; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), i, ifp)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + for (ALL_LIST_ELEMENTS_RO (vrf->iflist, i, ifp)) if (!ifp->ptm_enable) { if_data = (struct zebra_if *)ifp->info; @@ -1112,13 +1112,13 @@ zebra_ptm_send_status_req(void) void zebra_ptm_reset_status(int ptm_disable) { + struct vrf *vrf; struct listnode *i; struct interface *ifp; int send_linkup; - vrf_iter_t iter; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), i, ifp)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + for (ALL_LIST_ELEMENTS_RO (vrf->iflist, i, ifp)) { send_linkup = 0; if (ifp->ptm_enable) diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 394469950d..ec7d1e7fde 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -2052,24 +2052,24 @@ process_subq (struct list * subq, u_char qindex) static void meta_queue_process_complete (struct work_queue *dummy) { - vrf_iter_t iter; + struct vrf *vrf; struct zebra_vrf *zvrf; /* Evaluate nexthops for those VRFs which underwent route processing. This * should limit the evaluation to the necessary VRFs in most common * situations. */ - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if (((zvrf = vrf_iter2info (iter)) != NULL) && - (zvrf->flags & ZEBRA_VRF_RIB_SCHEDULED)) - { - zvrf->flags &= ~ZEBRA_VRF_RIB_SCHEDULED; - zebra_evaluate_rnh(zvrf->vrf_id, AF_INET, 0, RNH_NEXTHOP_TYPE, NULL); - zebra_evaluate_rnh(zvrf->vrf_id, AF_INET, 0, RNH_IMPORT_CHECK_TYPE, NULL); - zebra_evaluate_rnh(zvrf->vrf_id, AF_INET6, 0, RNH_NEXTHOP_TYPE, NULL); - zebra_evaluate_rnh(zvrf->vrf_id, AF_INET6, 0, RNH_IMPORT_CHECK_TYPE, NULL); - } + zvrf = vrf->info; + if (zvrf == NULL || !(zvrf->flags & ZEBRA_VRF_RIB_SCHEDULED)) + continue; + + zvrf->flags &= ~ZEBRA_VRF_RIB_SCHEDULED; + zebra_evaluate_rnh(zvrf->vrf_id, AF_INET, 0, RNH_NEXTHOP_TYPE, NULL); + zebra_evaluate_rnh(zvrf->vrf_id, AF_INET, 0, RNH_IMPORT_CHECK_TYPE, NULL); + zebra_evaluate_rnh(zvrf->vrf_id, AF_INET6, 0, RNH_NEXTHOP_TYPE, NULL); + zebra_evaluate_rnh(zvrf->vrf_id, AF_INET6, 0, RNH_IMPORT_CHECK_TYPE, NULL); } /* Schedule LSPs for processing, if needed. */ @@ -3037,11 +3037,11 @@ rib_weed_table (struct route_table *table) void rib_weed_tables (void) { - vrf_iter_t iter; + struct vrf *vrf; struct zebra_vrf *zvrf; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - if ((zvrf = vrf_iter2info (iter)) != NULL) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + if ((zvrf = vrf->info) != NULL) { rib_weed_table (zvrf->table[AFI_IP][SAFI_UNICAST]); rib_weed_table (zvrf->table[AFI_IP6][SAFI_UNICAST]); @@ -3078,11 +3078,11 @@ rib_sweep_table (struct route_table *table) void rib_sweep_route (void) { - vrf_iter_t iter; + struct vrf *vrf; struct zebra_vrf *zvrf; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - if ((zvrf = vrf_iter2info (iter)) != NULL) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + if ((zvrf = vrf->info) != NULL) { rib_sweep_table (zvrf->table[AFI_IP][SAFI_UNICAST]); rib_sweep_table (zvrf->table[AFI_IP6][SAFI_UNICAST]); @@ -3118,12 +3118,12 @@ rib_score_proto_table (u_char proto, u_short instance, struct route_table *table unsigned long rib_score_proto (u_char proto, u_short instance) { - vrf_iter_t iter; + struct vrf *vrf; struct zebra_vrf *zvrf; unsigned long cnt = 0; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - if ((zvrf = vrf_iter2info (iter)) != NULL) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + if ((zvrf = vrf->info) != NULL) cnt += rib_score_proto_table (proto, instance, zvrf->table[AFI_IP][SAFI_UNICAST]) +rib_score_proto_table (proto, instance, zvrf->table[AFI_IP6][SAFI_UNICAST]); @@ -3157,20 +3157,20 @@ rib_close_table (struct route_table *table) void rib_close (void) { - vrf_iter_t iter; + struct vrf *vrf; struct zebra_vrf *zvrf; struct listnode *node; struct interface *ifp; u_int32_t table_id; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((zvrf = vrf_iter2info (iter)) != NULL) + if ((zvrf = vrf->info) != NULL) { rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]); rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]); } - for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp)) + for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp)) if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp); } @@ -3207,17 +3207,16 @@ rib_init (void) static inline int vrf_id_get_next (vrf_id_t vrf_id, vrf_id_t *next_id_p) { - vrf_iter_t iter = vrf_iterator (vrf_id); - struct zebra_vrf *zvrf = vrf_iter2info (iter); + struct vrf *vrf; - /* The same one ? Then find out the next. */ - if (zvrf && (zvrf->vrf_id == vrf_id)) - zvrf = vrf_iter2info (vrf_next (iter)); - - if (zvrf) + vrf = vrf_lookup (vrf_id); + if (vrf) { - *next_id_p = zvrf->vrf_id; - return 1; + vrf = RB_NEXT (vrf_id_head, &vrfs_by_id, vrf); + if (vrf) { + *next_id_p = vrf->vrf_id; + return 1; + } } return 0; diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index 25091a3eab..3075a61c4a 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -633,7 +633,7 @@ DEFUN (set_src, struct interface *pif = NULL; int family; struct prefix p; - vrf_iter_t iter; + struct vrf *vrf; if (inet_pton(AF_INET, argv[0], &src.ipv4) != 1) { @@ -660,14 +660,14 @@ DEFUN (set_src, return CMD_WARNING; } - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { if (family == AF_INET) pif = if_lookup_exact_address_vrf ((void *)&src.ipv4, AF_INET, - vrf_iter2id (iter)); + vrf->vrf_id); else if (family == AF_INET6) pif = if_lookup_exact_address_vrf ((void *)&src.ipv6, AF_INET6, - vrf_iter2id (iter)); + vrf->vrf_id); if (pif != NULL) break; diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index 915849c057..4c1bbbb1a0 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -68,11 +68,10 @@ void zebra_vrf_update_all (struct zserv *client) { struct vrf *vrf; - vrf_iter_t iter; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((vrf = vrf_iter2vrf (iter)) && vrf->vrf_id) + if (vrf->vrf_id) zsend_vrf_add (client, vrf_info_lookup (vrf->vrf_id)); } } diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 74f64dd057..444d251357 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -2569,11 +2569,11 @@ DEFUN (show_ip_nht_vrf_all, "IP nexthop tracking table\n" VRF_ALL_CMD_HELP_STR) { + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - if ((zvrf = vrf_iter2info (iter)) != NULL) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + if ((zvrf = vrf->info) != NULL) { vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); zebra_print_rnh_table(zvrf->vrf_id, AF_INET, vty, RNH_NEXTHOP_TYPE); @@ -2614,11 +2614,11 @@ DEFUN (show_ipv6_nht_vrf_all, "IPv6 nexthop tracking table\n" VRF_ALL_CMD_HELP_STR) { + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - if ((zvrf = vrf_iter2info (iter)) != NULL) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + if ((zvrf = vrf->info) != NULL) { vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); zebra_print_rnh_table(zvrf->vrf_id, AF_INET6, vty, RNH_NEXTHOP_TYPE); @@ -3287,14 +3287,14 @@ DEFUN (show_ip_route_vrf_all, struct route_table *table; struct route_node *rn; struct rib *rib; + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; int first = 1; int vrf_header = 1; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((zvrf = vrf_iter2info (iter)) == NULL || + if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) continue; @@ -3334,8 +3334,8 @@ DEFUN (show_ip_route_vrf_all_tag, struct route_table *table; struct route_node *rn; struct rib *rib; + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; int first = 1; int vrf_header = 1; route_tag_t tag = 0; @@ -3343,9 +3343,9 @@ DEFUN (show_ip_route_vrf_all_tag, if (argv[0]) tag = atol(argv[0]); - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((zvrf = vrf_iter2info (iter)) == NULL || + if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) continue; @@ -3388,8 +3388,8 @@ DEFUN (show_ip_route_vrf_all_prefix_longer, struct route_node *rn; struct rib *rib; struct prefix p; + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; int ret; int first = 1; int vrf_header = 1; @@ -3401,9 +3401,9 @@ DEFUN (show_ip_route_vrf_all_prefix_longer, return CMD_WARNING; } - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((zvrf = vrf_iter2info (iter)) == NULL || + if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) continue; @@ -3443,15 +3443,15 @@ DEFUN (show_ip_route_vrf_all_supernets, struct route_table *table; struct route_node *rn; struct rib *rib; + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; u_int32_t addr; int first = 1; int vrf_header = 1; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((zvrf = vrf_iter2info (iter)) == NULL || + if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) continue; @@ -3498,8 +3498,8 @@ DEFUN (show_ip_route_vrf_all_protocol, struct route_table *table; struct route_node *rn; struct rib *rib; + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; int first = 1; int vrf_header = 1; @@ -3510,9 +3510,9 @@ DEFUN (show_ip_route_vrf_all_protocol, return CMD_WARNING; } - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((zvrf = vrf_iter2info (iter)) == NULL || + if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) continue; @@ -3553,8 +3553,8 @@ DEFUN (show_ip_route_vrf_all_addr, struct prefix_ipv4 p; struct route_table *table; struct route_node *rn; + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; ret = str2prefix_ipv4 (argv[0], &p); if (ret <= 0) @@ -3563,9 +3563,9 @@ DEFUN (show_ip_route_vrf_all_addr, return CMD_WARNING; } - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((zvrf = vrf_iter2info (iter)) == NULL || + if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) continue; @@ -3594,8 +3594,8 @@ DEFUN (show_ip_route_vrf_all_prefix, struct prefix_ipv4 p; struct route_table *table; struct route_node *rn; + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; ret = str2prefix_ipv4 (argv[0], &p); if (ret <= 0) @@ -3604,9 +3604,9 @@ DEFUN (show_ip_route_vrf_all_prefix, return CMD_WARNING; } - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((zvrf = vrf_iter2info (iter)) == NULL || + if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) continue; @@ -3636,11 +3636,11 @@ DEFUN (show_ip_route_vrf_all_summary, VRF_ALL_CMD_HELP_STR "Summary of all routes\n") { + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - if ((zvrf = vrf_iter2info (iter)) != NULL) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + if ((zvrf = vrf->info) != NULL) vty_show_ip_route_summary (vty, zvrf->table[AFI_IP][SAFI_UNICAST]); return CMD_SUCCESS; @@ -3656,11 +3656,11 @@ DEFUN (show_ip_route_vrf_all_summary_prefix, "Summary of all routes\n" "Prefix routes\n") { + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - if ((zvrf = vrf_iter2info (iter)) != NULL) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + if ((zvrf = vrf->info) != NULL) vty_show_ip_route_summary_prefix (vty, zvrf->table[AFI_IP][SAFI_UNICAST]); return CMD_SUCCESS; @@ -5416,14 +5416,14 @@ DEFUN (show_ipv6_route_vrf_all, struct route_table *table; struct route_node *rn; struct rib *rib; + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; int first = 1; int vrf_header = 1; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((zvrf = vrf_iter2info (iter)) == NULL || + if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) continue; @@ -5463,8 +5463,8 @@ DEFUN (show_ipv6_route_vrf_all_tag, struct route_table *table; struct route_node *rn; struct rib *rib; + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; int first = 1; int vrf_header = 1; route_tag_t tag = 0; @@ -5472,9 +5472,9 @@ DEFUN (show_ipv6_route_vrf_all_tag, if (argv[0]) tag = atol(argv[0]); - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((zvrf = vrf_iter2info (iter)) == NULL || + if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) continue; @@ -5518,8 +5518,8 @@ DEFUN (show_ipv6_route_vrf_all_prefix_longer, struct route_node *rn; struct rib *rib; struct prefix p; + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; int ret; int first = 1; int vrf_header = 1; @@ -5531,9 +5531,9 @@ DEFUN (show_ipv6_route_vrf_all_prefix_longer, return CMD_WARNING; } - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((zvrf = vrf_iter2info (iter)) == NULL || + if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) continue; @@ -5574,8 +5574,8 @@ DEFUN (show_ipv6_route_vrf_all_protocol, struct route_table *table; struct route_node *rn; struct rib *rib; + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; int first = 1; int vrf_header = 1; @@ -5586,9 +5586,9 @@ DEFUN (show_ipv6_route_vrf_all_protocol, return CMD_WARNING; } - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((zvrf = vrf_iter2info (iter)) == NULL || + if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) continue; @@ -5629,8 +5629,8 @@ DEFUN (show_ipv6_route_vrf_all_addr, struct prefix_ipv6 p; struct route_table *table; struct route_node *rn; + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; ret = str2prefix_ipv6 (argv[0], &p); if (ret <= 0) @@ -5639,9 +5639,9 @@ DEFUN (show_ipv6_route_vrf_all_addr, return CMD_WARNING; } - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((zvrf = vrf_iter2info (iter)) == NULL || + if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) continue; @@ -5670,8 +5670,8 @@ DEFUN (show_ipv6_route_vrf_all_prefix, struct prefix_ipv6 p; struct route_table *table; struct route_node *rn; + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; ret = str2prefix_ipv6 (argv[0], &p); if (ret <= 0) @@ -5680,9 +5680,9 @@ DEFUN (show_ipv6_route_vrf_all_prefix, return CMD_WARNING; } - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((zvrf = vrf_iter2info (iter)) == NULL || + if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) continue; @@ -5712,11 +5712,11 @@ DEFUN (show_ipv6_route_vrf_all_summary, VRF_ALL_CMD_HELP_STR "Summary of all IPv6 routes\n") { + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - if ((zvrf = vrf_iter2info (iter)) != NULL) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + if ((zvrf = vrf->info) != NULL) vty_show_ip_route_summary (vty, zvrf->table[AFI_IP6][SAFI_UNICAST]); return CMD_SUCCESS; @@ -5733,13 +5733,13 @@ DEFUN (show_ipv6_mroute_vrf_all, struct route_table *table; struct route_node *rn; struct rib *rib; + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; int first = 1; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((zvrf = vrf_iter2info (iter)) == NULL || + if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) continue; @@ -5768,11 +5768,11 @@ DEFUN (show_ipv6_route_vrf_all_summary_prefix, "Summary of all IPv6 routes\n" "Prefix routes\n") { + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - if ((zvrf = vrf_iter2info (iter)) != NULL) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + if ((zvrf = vrf->info) != NULL) vty_show_ip_route_summary_prefix (vty, zvrf->table[AFI_IP6][SAFI_UNICAST]); return CMD_SUCCESS; diff --git a/zebra/zserv.c b/zebra/zserv.c index 0b69af5124..76fdebb3a5 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -1005,18 +1005,16 @@ zsend_router_id_update (struct zserv *client, struct prefix *p, static int zread_interface_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf) { + struct vrf *vrf; struct listnode *ifnode, *ifnnode; - vrf_iter_t iter; struct interface *ifp; - struct zebra_vrf *zvrf_iter; /* Interface information is needed. */ vrf_bitmap_set (client->ifinfo, zvrf->vrf_id); - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - zvrf_iter = vrf_iter2info (iter); - for (ALL_LIST_ELEMENTS (vrf_iflist (zvrf_iter->vrf_id), ifnode, ifnnode, ifp)) + for (ALL_LIST_ELEMENTS (vrf->iflist, ifnode, ifnnode, ifp)) { /* Skip pseudo interface. */ if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)) @@ -1724,12 +1722,12 @@ zread_mpls_labels (int command, struct zserv *client, u_short length, static void zebra_client_close_cleanup_rnh (struct zserv *client) { - vrf_iter_t iter; + struct vrf *vrf; struct zebra_vrf *zvrf; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((zvrf = vrf_iter2info (iter)) != NULL) + if ((zvrf = vrf->info) != NULL) { zebra_cleanup_rnh_client(zvrf->vrf_id, AF_INET, client, RNH_NEXTHOP_TYPE); zebra_cleanup_rnh_client(zvrf->vrf_id, AF_INET6, client, RNH_NEXTHOP_TYPE); From 5f3d1bdf3ce8ac030831ee8c4dd6655ce5172431 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Wed, 2 Nov 2016 12:16:58 -0200 Subject: [PATCH 26/44] *: rename two vrf functions Since VRFs can be searched by vrf_id or name, make this explicit in the helper functions. s/vrf_lookup/vrf_lookup_by_id/ s/zebra_vrf_lookup/zebra_vrf_lookup_by_id/ Signed-off-by: Renato Westphal --- bgpd/bgp_main.c | 4 ++-- bgpd/bgpd.c | 2 +- bgpd/bgpd.h | 2 +- lib/vrf.c | 14 +++++++------- lib/vrf.h | 2 +- lib/zclient.c | 2 +- zebra/if_netlink.c | 4 ++-- zebra/interface.c | 4 ++-- zebra/zebra_rib.c | 4 ++-- zebra/zebra_rnh.c | 4 ++-- zebra/zebra_static.c | 2 +- zebra/zebra_vrf.c | 4 ++-- zebra/zebra_vrf.h | 2 +- zebra/zserv.c | 2 +- 14 files changed, 26 insertions(+), 26 deletions(-) diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index 50ca7eda4c..4e31eb344c 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -332,7 +332,7 @@ bgp_vrf_enable (vrf_id_t vrf_id, const char *name, void **info) struct bgp *bgp; vrf_id_t old_vrf_id; - vrf = vrf_lookup (vrf_id); + vrf = vrf_lookup_by_id (vrf_id); if (!vrf) // unexpected return -1; @@ -365,7 +365,7 @@ bgp_vrf_disable (vrf_id_t vrf_id, const char *name, void **info) if (vrf_id == VRF_DEFAULT) return 0; - vrf = vrf_lookup (vrf_id); + vrf = vrf_lookup_by_id (vrf_id); if (!vrf) // unexpected return -1; diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 53258880ab..22d4dd8917 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -2971,7 +2971,7 @@ bgp_lookup_by_vrf_id (vrf_id_t vrf_id) struct vrf *vrf; /* Lookup VRF (in tree) and follow link. */ - vrf = vrf_lookup (vrf_id); + vrf = vrf_lookup_by_id (vrf_id); if (!vrf) return NULL; return (vrf->info) ? (struct bgp *)vrf->info : NULL; diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index dd6a0fdccf..510082fdc2 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -1490,7 +1490,7 @@ bgp_vrf_lookup_by_instance_type (struct bgp *bgp) struct vrf *vrf; if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) - vrf = vrf_lookup (VRF_DEFAULT); + vrf = vrf_lookup_by_id (VRF_DEFAULT); else if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF) vrf = vrf_lookup_by_name (bgp->name); else diff --git a/lib/vrf.c b/lib/vrf.c index 79885ff3e3..2d2c55f7a6 100644 --- a/lib/vrf.c +++ b/lib/vrf.c @@ -171,7 +171,7 @@ vrf_get (vrf_id_t vrf_id, const char *name) * We've already been told about the vrf_id * or we haven't. */ - vrf = vrf_lookup (vrf_id); + vrf = vrf_lookup_by_id (vrf_id); if (vrf) { /* @@ -221,7 +221,7 @@ vrf_get (vrf_id_t vrf_id, const char *name) */ else if (!name) { - vrf = vrf_lookup (vrf_id); + vrf = vrf_lookup_by_id (vrf_id); if (debug_vrf) zlog_debug("Vrf found: %p", vrf); @@ -272,7 +272,7 @@ vrf_delete (struct vrf *vrf) /* Look up a VRF by identifier. */ struct vrf * -vrf_lookup (vrf_id_t vrf_id) +vrf_lookup_by_id (vrf_id_t vrf_id) { struct vrf vrf; vrf.vrf_id = vrf_id; @@ -405,7 +405,7 @@ vrf_info_get (vrf_id_t vrf_id) void * vrf_info_lookup (vrf_id_t vrf_id) { - struct vrf *vrf = vrf_lookup (vrf_id); + struct vrf *vrf = vrf_lookup_by_id (vrf_id); return vrf ? vrf->info : NULL; } @@ -413,7 +413,7 @@ vrf_info_lookup (vrf_id_t vrf_id) struct list * vrf_iflist (vrf_id_t vrf_id) { - struct vrf * vrf = vrf_lookup (vrf_id); + struct vrf * vrf = vrf_lookup_by_id (vrf_id); return vrf ? vrf->iflist : NULL; } @@ -429,7 +429,7 @@ vrf_iflist_get (vrf_id_t vrf_id) void vrf_iflist_create (vrf_id_t vrf_id) { - struct vrf * vrf = vrf_lookup (vrf_id); + struct vrf * vrf = vrf_lookup_by_id (vrf_id); if (vrf && !vrf->iflist) if_init (&vrf->iflist); } @@ -438,7 +438,7 @@ vrf_iflist_create (vrf_id_t vrf_id) void vrf_iflist_terminate (vrf_id_t vrf_id) { - struct vrf * vrf = vrf_lookup (vrf_id); + struct vrf * vrf = vrf_lookup_by_id (vrf_id); if (vrf && vrf->iflist) if_terminate (&vrf->iflist); } diff --git a/lib/vrf.h b/lib/vrf.h index f093f4fbd8..4ee871b332 100644 --- a/lib/vrf.h +++ b/lib/vrf.h @@ -108,7 +108,7 @@ extern struct list *vrf_list; */ extern void vrf_add_hook (int, int (*)(vrf_id_t, const char *, void **)); -extern struct vrf *vrf_lookup (vrf_id_t); +extern struct vrf *vrf_lookup_by_id (vrf_id_t); extern struct vrf *vrf_lookup_by_name (const char *); extern struct vrf *vrf_list_lookup_by_name (const char *); extern struct vrf *vrf_get (vrf_id_t, const char *); diff --git a/lib/zclient.c b/lib/zclient.c index 84f7314baa..894e0d19ef 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -1042,7 +1042,7 @@ zclient_vrf_delete (struct zclient *zclient, vrf_id_t vrf_id) struct vrf *vrf; /* Lookup vrf by vrf_id. */ - vrf = vrf_lookup (vrf_id); + vrf = vrf_lookup_by_id (vrf_id); /* * If a routing protocol doesn't know about a diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index c44219a495..abf1c781a3 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -211,7 +211,7 @@ netlink_vrf_change (struct nlmsghdr *h, struct rtattr *tb, const char *name) /* If VRF already exists, we just return; status changes are handled * against the VRF "interface". */ - vrf = vrf_lookup ((vrf_id_t)ifi->ifi_index); + vrf = vrf_lookup_by_id ((vrf_id_t)ifi->ifi_index); if (vrf && vrf->info) return; @@ -250,7 +250,7 @@ netlink_vrf_change (struct nlmsghdr *h, struct rtattr *tb, const char *name) if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug ("RTM_DELLINK for VRF %s(%u)", name, ifi->ifi_index); - vrf = vrf_lookup ((vrf_id_t)ifi->ifi_index); + vrf = vrf_lookup_by_id ((vrf_id_t)ifi->ifi_index); if (!vrf) { diff --git a/zebra/interface.c b/zebra/interface.c index 75040a87f0..d5d6ffd9f0 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -1038,7 +1038,7 @@ if_dump_vty (struct vty *vty, struct interface *ifp) zebra_ptm_show_status(vty, ifp); - vrf = vrf_lookup(ifp->vrf_id); + vrf = vrf_lookup_by_id (ifp->vrf_id); vty_out (vty, " vrf: %s%s", vrf->name, VTY_NEWLINE); if (ifp->desc) @@ -2833,7 +2833,7 @@ if_config_write (struct vty *vty) struct vrf *vrf; if_data = ifp->info; - vrf = vrf_lookup(ifp->vrf_id); + vrf = vrf_lookup_by_id (ifp->vrf_id); if (ifp->vrf_id == VRF_DEFAULT) vty_out (vty, "interface %s%s", ifp->name, VTY_NEWLINE); diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index ec7d1e7fde..9d9b10457d 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -2152,7 +2152,7 @@ rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn) rnode_debug (rn, rib->vrf_id, "queued rn %p into sub-queue %u", (void *)rn, qindex); - zvrf = zebra_vrf_lookup (rib->vrf_id); + zvrf = zebra_vrf_lookup_by_id (rib->vrf_id); if (zvrf) zvrf->flags |= ZEBRA_VRF_RIB_SCHEDULED; } @@ -3209,7 +3209,7 @@ vrf_id_get_next (vrf_id_t vrf_id, vrf_id_t *next_id_p) { struct vrf *vrf; - vrf = vrf_lookup (vrf_id); + vrf = vrf_lookup_by_id (vrf_id); if (vrf) { vrf = RB_NEXT (vrf_id_head, &vrfs_by_id, vrf); diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index 8df9277cb3..7df759030d 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -57,7 +57,7 @@ static void copy_state(struct rnh *rnh, struct rib *rib, ({ \ struct zebra_vrf *zvrf; \ struct route_table *t = NULL; \ - zvrf = zebra_vrf_lookup(v); \ + zvrf = zebra_vrf_lookup_by_id(v); \ if (zvrf) \ t = zvrf->rnh_table[family2afi(f)]; \ t; \ @@ -77,7 +77,7 @@ static inline struct route_table *get_rnh_table(vrf_id_t vrfid, int family, struct zebra_vrf *zvrf; struct route_table *t = NULL; - zvrf = zebra_vrf_lookup(vrfid); + zvrf = zebra_vrf_lookup_by_id(vrfid); if (zvrf) switch (type) { diff --git a/zebra/zebra_static.c b/zebra/zebra_static.c index 298fc4e09d..32ba90ef9a 100644 --- a/zebra/zebra_static.c +++ b/zebra/zebra_static.c @@ -129,7 +129,7 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ro rib->metric = 0; rib->mtu = 0; rib->vrf_id = si->vrf_id; - rib->table = si->vrf_id ? (zebra_vrf_lookup(si->vrf_id))->table_id : zebrad.rtm_table_default; + rib->table = si->vrf_id ? (zebra_vrf_lookup_by_id(si->vrf_id))->table_id : zebrad.rtm_table_default; rib->nexthop_num = 0; rib->tag = si->tag; diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index 4c1bbbb1a0..fbb41eb5a8 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -120,7 +120,7 @@ zebra_vrf_static_route_interface_fixup (struct interface *ifp) { afi_t afi; safi_t safi; - struct zebra_vrf *zvrf = zebra_vrf_lookup (ifp->vrf_id); + struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id (ifp->vrf_id); struct route_table *stable = NULL; struct route_node *rn = NULL; struct static_route *si = NULL; @@ -338,7 +338,7 @@ zebra_vrf_alloc (vrf_id_t vrf_id, const char *name) /* Lookup VRF by identifier. */ struct zebra_vrf * -zebra_vrf_lookup (vrf_id_t vrf_id) +zebra_vrf_lookup_by_id (vrf_id_t vrf_id) { return vrf_info_lookup (vrf_id); } diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h index 8dffe27dcf..c7814e6c99 100644 --- a/zebra/zebra_vrf.h +++ b/zebra/zebra_vrf.h @@ -92,7 +92,7 @@ zebra_vrf_table_with_table_id (afi_t afi, safi_t safi, extern void zebra_vrf_static_route_interface_fixup (struct interface *ifp); extern void zebra_vrf_update_all (struct zserv *client); -extern struct zebra_vrf *zebra_vrf_lookup (vrf_id_t vrf_id); +extern struct zebra_vrf *zebra_vrf_lookup_by_id (vrf_id_t vrf_id); extern struct zebra_vrf *zebra_vrf_list_lookup_by_name (const char *); extern struct zebra_vrf *zebra_vrf_alloc (vrf_id_t, const char *); extern struct route_table *zebra_vrf_table (afi_t, safi_t, vrf_id_t); diff --git a/zebra/zserv.c b/zebra/zserv.c index 76fdebb3a5..947e7324db 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -1935,7 +1935,7 @@ zebra_client_read (struct thread *thread) client->last_read_time = quagga_monotime(); client->last_read_cmd = command; - zvrf = zebra_vrf_lookup (vrf_id); + zvrf = zebra_vrf_lookup_by_id (vrf_id); if (!zvrf) { if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV) From 806f87607e6b41f67cd1550bc8a9b579522fb15c Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sat, 29 Oct 2016 20:30:57 -0200 Subject: [PATCH 27/44] lib/zebra: convert vrf_list to a red-black tree Since we're already using a red-black tree to store VRFs sorted by their vrf_id's, create a new tree to store VRFs sorted by their names. The biggest advantage of doing this is that we reduce the time complexity of vrf_list_lookup_by_name() from O(n) to O(log n). Signed-off-by: Renato Westphal --- lib/vrf.c | 50 +++++++++++++++-------------------------------- lib/vrf.h | 6 ++++-- zebra/zebra_vrf.c | 3 +-- zebra/zebra_vty.c | 9 +++------ 4 files changed, 24 insertions(+), 44 deletions(-) diff --git a/lib/vrf.c b/lib/vrf.c index 2d2c55f7a6..3def16151a 100644 --- a/lib/vrf.c +++ b/lib/vrf.c @@ -36,10 +36,13 @@ DEFINE_MTYPE_STATIC(LIB, VRF_BITMAP, "VRF bit-map") DEFINE_QOBJ_TYPE(vrf) static __inline int vrf_id_compare (struct vrf *, struct vrf *); +static __inline int vrf_name_compare (struct vrf *, struct vrf *); RB_GENERATE (vrf_id_head, vrf, id_entry, vrf_id_compare) +RB_GENERATE (vrf_name_head, vrf, name_entry, vrf_name_compare) struct vrf_id_head vrfs_by_id = RB_INITIALIZER (&vrfs_by_id); +struct vrf_name_head vrfs_by_name = RB_INITIALIZER (&vrfs_by_name); /* * Turn on/off debug code @@ -56,9 +59,6 @@ struct vrf_master int (*vrf_disable_hook) (vrf_id_t, const char *, void **); } vrf_master = {0,}; -/* VRF is part of a list too to store it before its actually active */ -struct list *vrf_list; - static int vrf_is_enabled (struct vrf *vrf); static void vrf_disable (struct vrf *vrf); @@ -66,16 +66,9 @@ static void vrf_disable (struct vrf *vrf); struct vrf * vrf_list_lookup_by_name (const char *name) { - struct listnode *node; - struct vrf *vrfp; - - if (name) - for (ALL_LIST_ELEMENTS_RO (vrf_list, node, vrfp)) - { - if (strcmp(name, vrfp->name) == 0) - return vrfp; - } - return NULL; + struct vrf vrf; + strlcpy (vrf.name, name, sizeof (vrf.name)); + return (RB_FIND (vrf_name_head, &vrfs_by_name, &vrf)); } static __inline int @@ -84,6 +77,12 @@ vrf_id_compare (struct vrf *a, struct vrf *b) return (a->vrf_id - b->vrf_id); } +static int +vrf_name_compare (struct vrf *a, struct vrf *b) +{ + return strcmp (a->name, b->name); +} + /* Get a VRF. If not found, create one. * Arg: * name - The name of the vrf. May be NULL if unknown. @@ -123,7 +122,7 @@ vrf_get (vrf_id_t vrf_id, const char *name) vrf_id, (name) ? name : "(NULL)"); strcpy (vrf->name, name); vrf->vrf_id = VRF_UNKNOWN; - listnode_add_sort (vrf_list, vrf); + RB_INSERT (vrf_name_head, &vrfs_by_name, vrf); if_init (&vrf->iflist); QOBJ_REG (vrf, vrf); if (vrf_master.vrf_new_hook) @@ -180,7 +179,7 @@ vrf_get (vrf_id_t vrf_id, const char *name) * so let's set it. */ strcpy (vrf->name, name); - listnode_add_sort (vrf_list, vrf); + RB_INSERT (vrf_name_head, &vrfs_by_name, vrf); if (vrf_master.vrf_new_hook) { (*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info); @@ -197,7 +196,7 @@ vrf_get (vrf_id_t vrf_id, const char *name) vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf)); vrf->vrf_id = vrf_id; strcpy (vrf->name, name); - listnode_add_sort (vrf_list, vrf); + RB_INSERT (vrf_name_head, &vrfs_by_name, vrf); RB_INSERT (vrf_id_head, &vrfs_by_id, vrf); if_init (&vrf->iflist); QOBJ_REG (vrf, vrf); @@ -265,7 +264,7 @@ vrf_delete (struct vrf *vrf) if (vrf->vrf_id != VRF_UNKNOWN) RB_REMOVE (vrf_id_head, &vrfs_by_id, vrf); - listnode_delete (vrf_list, vrf); + RB_REMOVE (vrf_name_head, &vrfs_by_name, vrf); XFREE (MTYPE_VRF, vrf); } @@ -536,20 +535,6 @@ vrf_bitmap_check (vrf_bitmap_t bmap, vrf_id_t vrf_id) VRF_BITMAP_FLAG (offset)) ? 1 : 0; } -/* Compare interface names, returning an integer greater than, equal to, or - * less than 0, (following the strcmp convention), according to the - * relationship between vrfp1 and vrfp2. Interface names consist of an - * alphabetic prefix and a numeric suffix. The primary sort key is - * lexicographic by name, and then numeric by number. No number sorts - * before all numbers. Examples: de0 < de1, de100 < fxp0 < xl0, devpty < - * devpty0, de0 < del0 - */ -static int -vrf_cmp_func (struct vrf *vrfp1, struct vrf *vrfp2) -{ - return if_cmp_name_func (vrfp1->name, vrfp2->name); -} - /* Initialize VRF module. */ void vrf_init (void) @@ -559,9 +544,6 @@ vrf_init (void) if (debug_vrf) zlog_debug ("%s: Initializing VRF subsystem", __PRETTY_FUNCTION__); - vrf_list = list_new (); - vrf_list->cmp = (int (*)(void *, void *))vrf_cmp_func; - /* The default VRF always exists. */ default_vrf = vrf_get (VRF_DEFAULT, VRF_DEFAULT_NAME); if (!default_vrf) diff --git a/lib/vrf.h b/lib/vrf.h index 4ee871b332..9dfaae21fc 100644 --- a/lib/vrf.h +++ b/lib/vrf.h @@ -70,7 +70,7 @@ enum { struct vrf { - RB_ENTRY(vrf) id_entry; + RB_ENTRY(vrf) id_entry, name_entry; /* Identifier, same as the vector index */ vrf_id_t vrf_id; @@ -92,11 +92,13 @@ struct vrf }; RB_HEAD (vrf_id_head, vrf); RB_PROTOTYPE (vrf_id_head, vrf, id_entry, vrf_id_compare) +RB_HEAD (vrf_name_head, vrf); +RB_PROTOTYPE (vrf_name_head, vrf, name_entry, vrf_name_compare) DECLARE_QOBJ_TYPE(vrf) extern struct vrf_id_head vrfs_by_id; -extern struct list *vrf_list; +extern struct vrf_name_head vrfs_by_name; /* * Add a specific hook to VRF module. diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index fbb41eb5a8..e28f97d763 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -446,11 +446,10 @@ DEFUN_NOSH (zebra_vrf, static int vrf_config_write (struct vty *vty) { - struct listnode *node; struct vrf *vrf; struct zebra_vrf *zvrf; - for (ALL_LIST_ELEMENTS_RO (vrf_list, node, vrf)) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { zvrf = vrf->info; if (! zvrf || strcmp (zvrf->name, VRF_DEFAULT_NAME)) diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 444d251357..3aa7ada917 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -3677,9 +3677,8 @@ static_config_ipv4 (struct vty *vty, safi_t safi, const char *cmd) struct zebra_vrf *zvrf; char buf[BUFSIZ]; int write =0; - struct listnode *node; - for (ALL_LIST_ELEMENTS_RO (vrf_list, node, vrf)) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { zvrf = vrf->info; if (! zvrf) @@ -5789,9 +5788,8 @@ static_config_ipv6 (struct vty *vty) struct route_table *stable; struct vrf *vrf; struct zebra_vrf *zvrf; - struct listnode *node; - for (ALL_LIST_ELEMENTS_RO (vrf_list, node, vrf)) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { zvrf = vrf->info; if (! zvrf) @@ -5886,9 +5884,8 @@ DEFUN (show_vrf, { struct vrf *vrf; struct zebra_vrf *zvrf; - struct listnode *node; - for (ALL_LIST_ELEMENTS_RO (vrf_list, node, vrf)) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { zvrf = vrf->info; if (! zvrf || ! zvrf->vrf_id) From a62c490110765542690860776f44628657a86169 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sat, 29 Oct 2016 20:44:04 -0200 Subject: [PATCH 28/44] zebra: order VRFs by name on user output Signed-off-by: Renato Westphal --- lib/if.c | 2 +- zebra/interface.c | 8 ++++---- zebra/router-id.c | 2 +- zebra/zebra_ptm.c | 2 +- zebra/zebra_vty.c | 40 ++++++++++++++++++++-------------------- 5 files changed, 27 insertions(+), 27 deletions(-) diff --git a/lib/if.c b/lib/if.c index 6df4942296..6f892e783e 100644 --- a/lib/if.c +++ b/lib/if.c @@ -887,7 +887,7 @@ DEFUN (show_address_vrf_all, struct connected *ifc; struct prefix *p; - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { if (!vrf->iflist || !listcount (vrf->iflist)) continue; diff --git a/zebra/interface.c b/zebra/interface.c index d5d6ffd9f0..7fd0259d2a 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -1332,7 +1332,7 @@ DEFUN (show_interface_vrf_all, show_interface_vrf_all_cmd, interface_update_stats (); /* All interface print. */ - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp)) if_dump_vty (vty, ifp); @@ -1385,7 +1385,7 @@ DEFUN (show_interface_name_vrf_all, show_interface_name_vrf_all_cmd, interface_update_stats (); /* All interface print. */ - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { /* Specified interface print. */ ifp = if_lookup_by_name_vrf (argv[0], vrf->vrf_id); @@ -1486,7 +1486,7 @@ DEFUN (show_interface_desc_vrf_all, { struct vrf *vrf; - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) if (!list_isempty (vrf->iflist)) { vty_out (vty, "%s\tVRF %u%s%s", VTY_NEWLINE, vrf->vrf_id, @@ -2823,7 +2823,7 @@ if_config_write (struct vty *vty) zebra_ptm_write (vty); - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp)) { struct zebra_if *if_data; diff --git a/zebra/router-id.c b/zebra/router-id.c index 155a8e3939..0799611399 100644 --- a/zebra/router-id.c +++ b/zebra/router-id.c @@ -198,7 +198,7 @@ router_id_write (struct vty *vty) struct vrf *vrf; struct zebra_vrf *zvrf; - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) if ((zvrf = vrf->info) != NULL) if (zvrf->rid_user_assigned.u.prefix4.s_addr) { diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c index 4fc1173241..fe1f6e0e6f 100644 --- a/zebra/zebra_ptm.c +++ b/zebra/zebra_ptm.c @@ -265,7 +265,7 @@ DEFUN (zebra_ptm_enable, ptm_cb.ptm_enable = ZEBRA_IF_PTM_ENABLE_ON; - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) for (ALL_LIST_ELEMENTS_RO (vrf->iflist, i, ifp)) if (!ifp->ptm_enable) { diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 3aa7ada917..d069c31893 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -2572,7 +2572,7 @@ DEFUN (show_ip_nht_vrf_all, struct vrf *vrf; struct zebra_vrf *zvrf; - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) if ((zvrf = vrf->info) != NULL) { vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); @@ -2617,7 +2617,7 @@ DEFUN (show_ipv6_nht_vrf_all, struct vrf *vrf; struct zebra_vrf *zvrf; - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) if ((zvrf = vrf->info) != NULL) { vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); @@ -3292,7 +3292,7 @@ DEFUN (show_ip_route_vrf_all, int first = 1; int vrf_header = 1; - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) @@ -3343,7 +3343,7 @@ DEFUN (show_ip_route_vrf_all_tag, if (argv[0]) tag = atol(argv[0]); - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) @@ -3401,7 +3401,7 @@ DEFUN (show_ip_route_vrf_all_prefix_longer, return CMD_WARNING; } - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) @@ -3449,7 +3449,7 @@ DEFUN (show_ip_route_vrf_all_supernets, int first = 1; int vrf_header = 1; - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) @@ -3510,7 +3510,7 @@ DEFUN (show_ip_route_vrf_all_protocol, return CMD_WARNING; } - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) @@ -3563,7 +3563,7 @@ DEFUN (show_ip_route_vrf_all_addr, return CMD_WARNING; } - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) @@ -3604,7 +3604,7 @@ DEFUN (show_ip_route_vrf_all_prefix, return CMD_WARNING; } - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) @@ -3639,7 +3639,7 @@ DEFUN (show_ip_route_vrf_all_summary, struct vrf *vrf; struct zebra_vrf *zvrf; - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) if ((zvrf = vrf->info) != NULL) vty_show_ip_route_summary (vty, zvrf->table[AFI_IP][SAFI_UNICAST]); @@ -3659,7 +3659,7 @@ DEFUN (show_ip_route_vrf_all_summary_prefix, struct vrf *vrf; struct zebra_vrf *zvrf; - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) if ((zvrf = vrf->info) != NULL) vty_show_ip_route_summary_prefix (vty, zvrf->table[AFI_IP][SAFI_UNICAST]); @@ -5420,7 +5420,7 @@ DEFUN (show_ipv6_route_vrf_all, int first = 1; int vrf_header = 1; - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) @@ -5471,7 +5471,7 @@ DEFUN (show_ipv6_route_vrf_all_tag, if (argv[0]) tag = atol(argv[0]); - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) @@ -5530,7 +5530,7 @@ DEFUN (show_ipv6_route_vrf_all_prefix_longer, return CMD_WARNING; } - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) @@ -5585,7 +5585,7 @@ DEFUN (show_ipv6_route_vrf_all_protocol, return CMD_WARNING; } - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) @@ -5638,7 +5638,7 @@ DEFUN (show_ipv6_route_vrf_all_addr, return CMD_WARNING; } - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) @@ -5679,7 +5679,7 @@ DEFUN (show_ipv6_route_vrf_all_prefix, return CMD_WARNING; } - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) @@ -5714,7 +5714,7 @@ DEFUN (show_ipv6_route_vrf_all_summary, struct vrf *vrf; struct zebra_vrf *zvrf; - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) if ((zvrf = vrf->info) != NULL) vty_show_ip_route_summary (vty, zvrf->table[AFI_IP6][SAFI_UNICAST]); @@ -5736,7 +5736,7 @@ DEFUN (show_ipv6_mroute_vrf_all, struct zebra_vrf *zvrf; int first = 1; - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) @@ -5770,7 +5770,7 @@ DEFUN (show_ipv6_route_vrf_all_summary_prefix, struct vrf *vrf; struct zebra_vrf *zvrf; - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) if ((zvrf = vrf->info) != NULL) vty_show_ip_route_summary_prefix (vty, zvrf->table[AFI_IP6][SAFI_UNICAST]); From 05e8e11e54a38cb9d6ed9c2522b557231197b1bc Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sat, 29 Oct 2016 22:44:06 -0200 Subject: [PATCH 29/44] lib/zebra: put vrf_get() on a diet Also, for some reason we had two functions to search a VRF by its name: zebra_vrf_lookup_by_name() and zebra_vrf_list_lookup_by_name(). The first one would loop through vrf_table and the other one through vrf_list. This is not necessary anymore, so remove zebra_vrf_lookup_by_name() and rename zebra_vrf_list_lookup_by_name() to zebra_vrf_lookup_by_name(). Signed-off-by: Renato Westphal --- lib/vrf.c | 219 +++++++++++---------------------------------- lib/vrf.h | 3 +- zebra/if_netlink.c | 7 -- zebra/zebra_vrf.c | 6 +- zebra/zebra_vrf.h | 2 +- zebra/zebra_vty.c | 8 +- 6 files changed, 62 insertions(+), 183 deletions(-) diff --git a/lib/vrf.c b/lib/vrf.c index 3def16151a..aa1bfeeabd 100644 --- a/lib/vrf.c +++ b/lib/vrf.c @@ -64,7 +64,7 @@ static void vrf_disable (struct vrf *vrf); /* VRF list existance check by name. */ struct vrf * -vrf_list_lookup_by_name (const char *name) +vrf_lookup_by_name (const char *name) { struct vrf vrf; strlcpy (vrf.name, name, sizeof (vrf.name)); @@ -93,157 +93,59 @@ vrf_name_compare (struct vrf *a, struct vrf *b) struct vrf * vrf_get (vrf_id_t vrf_id, const char *name) { - struct vrf *vrf; + struct vrf *vrf = NULL; + int new = 0; if (debug_vrf) zlog_debug ("VRF_GET: %s(%d)", name, vrf_id); - /* - * Nothing to see, move along here - */ + /* Nothing to see, move along here */ if (!name && vrf_id == VRF_UNKNOWN) return NULL; - /* - * Valid vrf name and unknown vrf_id case - * - * This is called when we are configured from - * the cli but we have no kernel information yet. - */ - if (name && vrf_id == VRF_UNKNOWN) - { - vrf = vrf_list_lookup_by_name (name); - if (vrf) - return vrf; + /* Try to find VRF both by ID and name */ + if (vrf_id != VRF_UNKNOWN) + vrf = vrf_lookup_by_id (vrf_id); + if (! vrf && name) + vrf = vrf_lookup_by_name (name); + if (vrf == NULL) + { vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf)); - if (debug_vrf) - zlog_debug ("VRF(%u) %s is created.", - vrf_id, (name) ? name : "(NULL)"); - strcpy (vrf->name, name); vrf->vrf_id = VRF_UNKNOWN; - RB_INSERT (vrf_name_head, &vrfs_by_name, vrf); if_init (&vrf->iflist); QOBJ_REG (vrf, vrf); - if (vrf_master.vrf_new_hook) - { - (*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info); + new = 1; - if (debug_vrf && vrf->info) - zlog_info ("zvrf is created."); - } if (debug_vrf) - zlog_debug("Vrf Created: %p", vrf); - return vrf; + zlog_debug ("VRF(%u) %s is created.", + vrf_id, (name) ? name : "(NULL)"); } - /* - * Valid vrf name and valid vrf_id case - * - * This can be passed from the kernel - */ - else if (name && vrf_id != VRF_UNKNOWN) + + /* Set identifier */ + if (vrf_id != VRF_UNKNOWN && vrf->vrf_id == VRF_UNKNOWN) { - vrf = vrf_list_lookup_by_name (name); - if (vrf) - { - /* - * If the passed in vrf_id and name match - * return, nothing to do here. - */ - if (vrf->vrf_id == vrf_id) - return vrf; - - vrf->vrf_id = vrf_id; - RB_INSERT (vrf_id_head, &vrfs_by_id, vrf); - if (vrf_master.vrf_new_hook) - (*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info); - - if (debug_vrf) - zlog_debug("Vrf found matched stuff up: %p", vrf); - - return vrf; - } - else - { - /* - * We can have 1 of two situations here - * We've already been told about the vrf_id - * or we haven't. - */ - vrf = vrf_lookup_by_id (vrf_id); - if (vrf) - { - /* - * We know at this point that the vrf->name is not - * right because we would have caught it above. - * so let's set it. - */ - strcpy (vrf->name, name); - RB_INSERT (vrf_name_head, &vrfs_by_name, vrf); - if (vrf_master.vrf_new_hook) - { - (*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info); - - if (debug_vrf && vrf->info) - zlog_info ("zvrf is created."); - } - if (debug_vrf) - zlog_debug("Vrf Created: %p", vrf); - return vrf; - } - else - { - vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf)); - vrf->vrf_id = vrf_id; - strcpy (vrf->name, name); - RB_INSERT (vrf_name_head, &vrfs_by_name, vrf); - RB_INSERT (vrf_id_head, &vrfs_by_id, vrf); - if_init (&vrf->iflist); - QOBJ_REG (vrf, vrf); - if (vrf_master.vrf_new_hook) - { - (*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info); - - if (debug_vrf && vrf->info) - zlog_info ("zvrf is created."); - } - if (debug_vrf) - zlog_debug("Vrf Created: %p", vrf); - return vrf; - } - } + vrf->vrf_id = vrf_id; + RB_INSERT (vrf_id_head, &vrfs_by_id, vrf); } - /* - * The final case, we've been passed a valid vrf_id - * but no name. So we create the route node - * if it hasn't already been created. - */ - else if (!name) + + /* Set name */ + if (name && vrf->name[0] != '\0' && strcmp (name, vrf->name)) { - vrf = vrf_lookup_by_id (vrf_id); - if (debug_vrf) - zlog_debug("Vrf found: %p", vrf); - - if (vrf) - return vrf; - else - { - vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf)); - vrf->vrf_id = vrf_id; - if_init (&vrf->iflist); - RB_INSERT (vrf_id_head, &vrfs_by_id, vrf); - QOBJ_REG (vrf, vrf); - if (debug_vrf) - zlog_debug("Vrf Created: %p", vrf); - return vrf; - } + RB_REMOVE (vrf_name_head, &vrfs_by_name, vrf); + strlcpy (vrf->name, name, sizeof (vrf->name)); + RB_INSERT (vrf_name_head, &vrfs_by_name, vrf); + } + else if (name && vrf->name[0] == '\0') + { + strlcpy (vrf->name, name, sizeof (vrf->name)); + RB_INSERT (vrf_name_head, &vrfs_by_name, vrf); } - /* - * We shouldn't get here and if we do - * something has gone wrong. - */ - return NULL; + if (new && vrf_master.vrf_new_hook) + (*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info); + + return vrf; } /* Delete a VRF. This is called in vrf_terminate(). */ @@ -264,7 +166,8 @@ vrf_delete (struct vrf *vrf) if (vrf->vrf_id != VRF_UNKNOWN) RB_REMOVE (vrf_id_head, &vrfs_by_id, vrf); - RB_REMOVE (vrf_name_head, &vrfs_by_name, vrf); + if (vrf->name[0] != '\0') + RB_REMOVE (vrf_name_head, &vrfs_by_name, vrf); XFREE (MTYPE_VRF, vrf); } @@ -279,18 +182,12 @@ vrf_lookup_by_id (vrf_id_t vrf_id) } /* - * Check whether the VRF is enabled - that is, whether the VRF - * is ready to allocate resources. Currently there's only one - * type of resource: socket. + * Check whether the VRF is enabled. */ static int vrf_is_enabled (struct vrf *vrf) { return vrf && CHECK_FLAG (vrf->status, VRF_ACTIVE); - - /*Pending: figure out the real use of this routine.. it used to be.. - return vrf && vrf->vrf_id == VRF_DEFAULT; - */ } /* @@ -303,11 +200,13 @@ vrf_is_enabled (struct vrf *vrf) int vrf_enable (struct vrf *vrf) { + if (vrf_is_enabled (vrf)) + return 1; + if (debug_vrf) zlog_debug ("VRF %u is enabled.", vrf->vrf_id); - if (!CHECK_FLAG (vrf->status, VRF_ACTIVE)) - SET_FLAG (vrf->status, VRF_ACTIVE); + SET_FLAG (vrf->status, VRF_ACTIVE); if (vrf_master.vrf_enable_hook) (*vrf_master.vrf_enable_hook) (vrf->vrf_id, vrf->name, &vrf->info); @@ -323,20 +222,19 @@ vrf_enable (struct vrf *vrf) static void vrf_disable (struct vrf *vrf) { - if (vrf_is_enabled (vrf)) - { - UNSET_FLAG (vrf->status, VRF_ACTIVE); + if (! vrf_is_enabled (vrf)) + return; - if (debug_vrf) - zlog_debug ("VRF %u is to be disabled.", vrf->vrf_id); + UNSET_FLAG (vrf->status, VRF_ACTIVE); - /* Till now, nothing to be done for the default VRF. */ - //Pending: see why this statement. + if (debug_vrf) + zlog_debug ("VRF %u is to be disabled.", vrf->vrf_id); - if (vrf_master.vrf_disable_hook) - (*vrf_master.vrf_disable_hook) (vrf->vrf_id, vrf->name, &vrf->info); - } + /* Till now, nothing to be done for the default VRF. */ + //Pending: see why this statement. + if (vrf_master.vrf_disable_hook) + (*vrf_master.vrf_disable_hook) (vrf->vrf_id, vrf->name, &vrf->info); } @@ -366,19 +264,6 @@ vrf_add_hook (int type, int (*func)(vrf_id_t, const char *, void **)) } } -/* Look up a VRF by name. */ -struct vrf * -vrf_lookup_by_name (const char *name) -{ - struct vrf *vrf; - - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) - if (!strcmp(vrf->name, name)) - return vrf; - - return NULL; -} - vrf_id_t vrf_name_to_id (const char *name) { @@ -571,6 +456,8 @@ vrf_terminate (void) while ((vrf = RB_ROOT (&vrfs_by_id)) != NULL) vrf_delete (vrf); + while ((vrf = RB_ROOT (&vrfs_by_name)) != NULL) + vrf_delete (vrf); } /* Create a socket for the VRF. */ @@ -618,7 +505,7 @@ DEFUN_NOSH (no_vrf, { struct vrf *vrfp; - vrfp = vrf_list_lookup_by_name (argv[0]); + vrfp = vrf_lookup_by_name (argv[0]); if (vrfp == NULL) { diff --git a/lib/vrf.h b/lib/vrf.h index 9dfaae21fc..feaf768969 100644 --- a/lib/vrf.h +++ b/lib/vrf.h @@ -112,7 +112,6 @@ extern void vrf_add_hook (int, int (*)(vrf_id_t, const char *, void **)); extern struct vrf *vrf_lookup_by_id (vrf_id_t); extern struct vrf *vrf_lookup_by_name (const char *); -extern struct vrf *vrf_list_lookup_by_name (const char *); extern struct vrf *vrf_get (vrf_id_t, const char *); extern void vrf_delete (struct vrf *); extern int vrf_enable (struct vrf *); @@ -121,7 +120,7 @@ extern vrf_id_t vrf_name_to_id (const char *); #define VRF_GET_ID(V,NAME) \ do { \ struct vrf *vrf; \ - if (!(vrf = vrf_list_lookup_by_name(NAME))) \ + if (!(vrf = vrf_lookup_by_name(NAME))) \ { \ vty_out (vty, "%% VRF %s not found%s", NAME, VTY_NEWLINE);\ return CMD_WARNING; \ diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index abf1c781a3..be7a5ac78d 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -208,13 +208,6 @@ netlink_vrf_change (struct nlmsghdr *h, struct rtattr *tb, const char *name) if (h->nlmsg_type == RTM_NEWLINK) { - /* If VRF already exists, we just return; status changes are handled - * against the VRF "interface". - */ - vrf = vrf_lookup_by_id ((vrf_id_t)ifi->ifi_index); - if (vrf && vrf->info) - return; - if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug ("RTM_NEWLINK for VRF %s(%u) table %u", name, ifi->ifi_index, nl_table_id); diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index e28f97d763..94e5d49c2c 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -87,7 +87,7 @@ zebra_vrf_new (vrf_id_t vrf_id, const char *name, void **info) if (! zvrf) { - zvrf = zebra_vrf_list_lookup_by_name (name); + zvrf = zebra_vrf_lookup_by_name (name); if (!zvrf) { zvrf = zebra_vrf_alloc (vrf_id, name); @@ -345,14 +345,14 @@ zebra_vrf_lookup_by_id (vrf_id_t vrf_id) /* Lookup VRF by name. */ struct zebra_vrf * -zebra_vrf_list_lookup_by_name (const char *name) +zebra_vrf_lookup_by_name (const char *name) { struct vrf *vrf; if (!name) name = VRF_DEFAULT_NAME; - vrf = vrf_list_lookup_by_name (name); + vrf = vrf_lookup_by_name (name); if (vrf) return ((struct zebra_vrf *) vrf->info); diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h index c7814e6c99..8247365644 100644 --- a/zebra/zebra_vrf.h +++ b/zebra/zebra_vrf.h @@ -93,7 +93,7 @@ zebra_vrf_table_with_table_id (afi_t afi, safi_t safi, extern void zebra_vrf_static_route_interface_fixup (struct interface *ifp); extern void zebra_vrf_update_all (struct zserv *client); extern struct zebra_vrf *zebra_vrf_lookup_by_id (vrf_id_t vrf_id); -extern struct zebra_vrf *zebra_vrf_list_lookup_by_name (const char *); +extern struct zebra_vrf *zebra_vrf_lookup_by_name (const char *); extern struct zebra_vrf *zebra_vrf_alloc (vrf_id_t, const char *); extern struct route_table *zebra_vrf_table (afi_t, safi_t, vrf_id_t); extern struct route_table *zebra_vrf_static_table (afi_t, safi_t, struct zebra_vrf *zvrf); diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index d069c31893..4ae12559ad 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -107,7 +107,7 @@ zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd, tag = atol(tag_str); /* VRF id */ - zvrf = zebra_vrf_list_lookup_by_name (vrf_id_str); + zvrf = zebra_vrf_lookup_by_name (vrf_id_str); if (!zvrf) { @@ -2450,7 +2450,7 @@ do_show_ip_route (struct vty *vty, const char *vrf_name, safi_t safi, json_object *json = NULL; json_object *json_prefix = NULL; - if (!(zvrf = zebra_vrf_list_lookup_by_name (vrf_name))) + if (!(zvrf = zebra_vrf_lookup_by_name (vrf_name))) { if (use_json) vty_out (vty, "{}%s", VTY_NEWLINE); @@ -3784,7 +3784,7 @@ static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str, ret = inet_pton (AF_INET6, gate_str, &gate_addr); /* VRF id */ - zvrf = zebra_vrf_list_lookup_by_name (vrf_id_str); + zvrf = zebra_vrf_lookup_by_name (vrf_id_str); if (!zvrf) { @@ -4925,7 +4925,7 @@ DEFUN (show_ipv6_route, if (argc > 0 && argv[0] && strcmp(argv[0], "json") != 0) { - if (!(zvrf = zebra_vrf_list_lookup_by_name (argv[0]))) + if (!(zvrf = zebra_vrf_lookup_by_name (argv[0]))) { if (uj) vty_out (vty, "{}%s", VTY_NEWLINE); From 661512bf053ecc3d441bb8938dcd4541ae7ffc33 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sun, 30 Oct 2016 19:50:26 -0200 Subject: [PATCH 30/44] zebra/lib: remove redundant fields from zebra_vrf There's no need to duplicate the 'vrf_id' and 'name' fields from the 'vrf' structure into the 'zebra_vrf' structure. Instead of that, add a back pointer in 'zebra_vrf' that should point to the associated 'vrf' structure. Additionally, modify the vrf callbacks to pass the whole vrf structure as a parameter. This allow us to make further simplifications in the code. Signed-off-by: Renato Westphal --- bgpd/bgp_main.c | 32 +++++++----------- lib/vrf.c | 18 +++++----- lib/vrf.h | 2 +- zebra/redistribute.c | 16 ++++----- zebra/router-id.c | 16 ++++----- zebra/rt_netlink.c | 4 +-- zebra/rtadv.c | 8 ++--- zebra/zebra_fpm.c | 2 +- zebra/zebra_fpm_netlink.c | 2 +- zebra/zebra_mpls.c | 4 +-- zebra/zebra_ptm.c | 8 ++--- zebra/zebra_rib.c | 32 +++++++++--------- zebra/zebra_static.c | 2 +- zebra/zebra_vrf.c | 69 +++++++++++++-------------------------- zebra/zebra_vrf.h | 21 ++++++++---- zebra/zebra_vty.c | 58 ++++++++++++++++---------------- zebra/zserv.c | 58 ++++++++++++++++---------------- 17 files changed, 164 insertions(+), 188 deletions(-) diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index 4e31eb344c..91eacc9320 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -308,38 +308,33 @@ bgp_exit (int status) } static int -bgp_vrf_new (vrf_id_t vrf_id, const char *name, void **info) +bgp_vrf_new (struct vrf *vrf) { if (BGP_DEBUG (zebra, ZEBRA)) - zlog_debug ("VRF Created: %s(%d)", name, vrf_id); + zlog_debug ("VRF Created: %s(%d)", vrf->name, vrf->vrf_id); return 0; } static int -bgp_vrf_delete (vrf_id_t vrf_id, const char *name, void **info) +bgp_vrf_delete (struct vrf *vrf) { if (BGP_DEBUG (zebra, ZEBRA)) - zlog_debug ("VRF Deletion: %s(%d)", name, vrf_id); + zlog_debug ("VRF Deletion: %s(%d)", vrf->name, vrf->vrf_id); return 0; } static int -bgp_vrf_enable (vrf_id_t vrf_id, const char *name, void **info) +bgp_vrf_enable (struct vrf *vrf) { - struct vrf *vrf; struct bgp *bgp; vrf_id_t old_vrf_id; - vrf = vrf_lookup_by_id (vrf_id); - if (!vrf) // unexpected - return -1; - if (BGP_DEBUG (zebra, ZEBRA)) - zlog_debug("VRF enable add %s id %d", name, vrf_id); + zlog_debug("VRF enable add %s id %d", vrf->name, vrf->vrf_id); - bgp = bgp_lookup_by_name(name); + bgp = bgp_lookup_by_name (vrf->name); if (bgp) { old_vrf_id = bgp->vrf_id; @@ -356,23 +351,18 @@ bgp_vrf_enable (vrf_id_t vrf_id, const char *name, void **info) } static int -bgp_vrf_disable (vrf_id_t vrf_id, const char *name, void **info) +bgp_vrf_disable (struct vrf *vrf) { - struct vrf *vrf; struct bgp *bgp; vrf_id_t old_vrf_id; - if (vrf_id == VRF_DEFAULT) + if (vrf->vrf_id == VRF_DEFAULT) return 0; - vrf = vrf_lookup_by_id (vrf_id); - if (!vrf) // unexpected - return -1; - if (BGP_DEBUG (zebra, ZEBRA)) - zlog_debug("VRF disable %s id %d", name, vrf_id); + zlog_debug("VRF disable %s id %d", vrf->name, vrf->vrf_id); - bgp = bgp_lookup_by_name(name); + bgp = bgp_lookup_by_name (vrf->name); if (bgp) { old_vrf_id = bgp->vrf_id; diff --git a/lib/vrf.c b/lib/vrf.c index aa1bfeeabd..39d8a89a7c 100644 --- a/lib/vrf.c +++ b/lib/vrf.c @@ -53,10 +53,10 @@ int debug_vrf = 0; /* Holding VRF hooks */ struct vrf_master { - int (*vrf_new_hook) (vrf_id_t, const char *, void **); - int (*vrf_delete_hook) (vrf_id_t, const char *, void **); - int (*vrf_enable_hook) (vrf_id_t, const char *, void **); - int (*vrf_disable_hook) (vrf_id_t, const char *, void **); + int (*vrf_new_hook) (struct vrf *); + int (*vrf_delete_hook) (struct vrf *); + int (*vrf_enable_hook) (struct vrf *); + int (*vrf_disable_hook) (struct vrf *); } vrf_master = {0,}; static int vrf_is_enabled (struct vrf *vrf); @@ -143,7 +143,7 @@ vrf_get (vrf_id_t vrf_id, const char *name) } if (new && vrf_master.vrf_new_hook) - (*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info); + (*vrf_master.vrf_new_hook) (vrf); return vrf; } @@ -159,7 +159,7 @@ vrf_delete (struct vrf *vrf) vrf_disable (vrf); if (vrf_master.vrf_delete_hook) - (*vrf_master.vrf_delete_hook) (vrf->vrf_id, vrf->name, &vrf->info); + (*vrf_master.vrf_delete_hook) (vrf); QOBJ_UNREG (vrf); if_terminate (&vrf->iflist); @@ -209,7 +209,7 @@ vrf_enable (struct vrf *vrf) SET_FLAG (vrf->status, VRF_ACTIVE); if (vrf_master.vrf_enable_hook) - (*vrf_master.vrf_enable_hook) (vrf->vrf_id, vrf->name, &vrf->info); + (*vrf_master.vrf_enable_hook) (vrf); return 1; } @@ -234,13 +234,13 @@ vrf_disable (struct vrf *vrf) //Pending: see why this statement. if (vrf_master.vrf_disable_hook) - (*vrf_master.vrf_disable_hook) (vrf->vrf_id, vrf->name, &vrf->info); + (*vrf_master.vrf_disable_hook) (vrf); } /* Add a VRF hook. Please add hooks before calling vrf_init(). */ void -vrf_add_hook (int type, int (*func)(vrf_id_t, const char *, void **)) +vrf_add_hook (int type, int (*func)(struct vrf *)) { if (debug_vrf) zlog_debug ("%s: Add Hook %d to function %p", __PRETTY_FUNCTION__, diff --git a/lib/vrf.h b/lib/vrf.h index feaf768969..c9e81bf669 100644 --- a/lib/vrf.h +++ b/lib/vrf.h @@ -108,7 +108,7 @@ extern struct vrf_name_head vrfs_by_name; * - param 2: the address of the user data pointer (the user data * can be stored in or freed from there) */ -extern void vrf_add_hook (int, int (*)(vrf_id_t, const char *, void **)); +extern void vrf_add_hook (int, int (*)(struct vrf *)); extern struct vrf *vrf_lookup_by_id (vrf_id_t); extern struct vrf *vrf_lookup_by_name (const char *); diff --git a/zebra/redistribute.c b/zebra/redistribute.c index c74485bb35..9c7ef5f12c 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -262,13 +262,13 @@ zebra_redistribute_add (int command, struct zserv *client, int length, if (! redist_check_instance (&client->mi_redist[afi][type], instance)) { redist_add_instance (&client->mi_redist[afi][type], instance); - zebra_redistribute (client, type, instance, zvrf->vrf_id); + zebra_redistribute (client, type, instance, zvrf_id (zvrf)); } } else { - if (! vrf_bitmap_check (client->redist[afi][type], zvrf->vrf_id)) + if (! vrf_bitmap_check (client->redist[afi][type], zvrf_id (zvrf))) { - vrf_bitmap_set (client->redist[afi][type], zvrf->vrf_id); - zebra_redistribute (client, type, 0, zvrf->vrf_id); + vrf_bitmap_set (client->redist[afi][type], zvrf_id (zvrf)); + zebra_redistribute (client, type, 0, zvrf_id (zvrf)); } } } @@ -296,22 +296,22 @@ zebra_redistribute_delete (int command, struct zserv *client, int length, if (instance) redist_del_instance (&client->mi_redist[afi][type], instance); else - vrf_bitmap_unset (client->redist[afi][type], zvrf->vrf_id); + vrf_bitmap_unset (client->redist[afi][type], zvrf_id (zvrf)); } void zebra_redistribute_default_add (int command, struct zserv *client, int length, struct zebra_vrf *zvrf) { - vrf_bitmap_set (client->redist_default, zvrf->vrf_id); - zebra_redistribute_default (client, zvrf->vrf_id); + vrf_bitmap_set (client->redist_default, zvrf_id (zvrf)); + zebra_redistribute_default (client, zvrf_id (zvrf)); } void zebra_redistribute_default_delete (int command, struct zserv *client, int length, struct zebra_vrf *zvrf) { - vrf_bitmap_unset (client->redist_default, zvrf->vrf_id); + vrf_bitmap_unset (client->redist_default, zvrf_id (zvrf)); } /* Interface up information. */ diff --git a/zebra/router-id.c b/zebra/router-id.c index 0799611399..0aa1bdc770 100644 --- a/zebra/router-id.c +++ b/zebra/router-id.c @@ -138,7 +138,7 @@ router_id_add_address (struct connected *ifc) if (router_id_bad_address (ifc)) return; - router_id_get (&before, zvrf->vrf_id); + router_id_get (&before, zvrf_id (zvrf)); if (!strncmp (ifc->ifp->name, "lo", 2) || !strncmp (ifc->ifp->name, "dummy", 5)) @@ -149,13 +149,13 @@ router_id_add_address (struct connected *ifc) if (!router_id_find_node (l, ifc)) listnode_add_sort (l, ifc); - router_id_get (&after, zvrf->vrf_id); + router_id_get (&after, zvrf_id (zvrf)); if (prefix_same (&before, &after)) return; for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client)) - zsend_router_id_update (client, &after, zvrf->vrf_id); + zsend_router_id_update (client, &after, zvrf_id (zvrf)); } void @@ -172,7 +172,7 @@ router_id_del_address (struct connected *ifc) if (router_id_bad_address (ifc)) return; - router_id_get (&before, zvrf->vrf_id); + router_id_get (&before, zvrf_id (zvrf)); if (!strncmp (ifc->ifp->name, "lo", 2) || !strncmp (ifc->ifp->name, "dummy", 5)) @@ -183,13 +183,13 @@ router_id_del_address (struct connected *ifc) if ((c = router_id_find_node (l, ifc))) listnode_delete (l, c); - router_id_get (&after, zvrf->vrf_id); + router_id_get (&after, zvrf_id (zvrf)); if (prefix_same (&before, &after)) return; for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client)) - zsend_router_id_update (client, &after, zvrf->vrf_id); + zsend_router_id_update (client, &after, zvrf_id (zvrf)); } void @@ -202,14 +202,14 @@ router_id_write (struct vty *vty) if ((zvrf = vrf->info) != NULL) if (zvrf->rid_user_assigned.u.prefix4.s_addr) { - if (zvrf->vrf_id == VRF_DEFAULT) + if (zvrf_id (zvrf) == VRF_DEFAULT) vty_out (vty, "router-id %s%s", inet_ntoa (zvrf->rid_user_assigned.u.prefix4), VTY_NEWLINE); else vty_out (vty, "router-id %s vrf %s%s", inet_ntoa (zvrf->rid_user_assigned.u.prefix4), - zvrf->name, + zvrf_name (zvrf), VTY_NEWLINE); } } diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index b18bf1ef7a..c04f9188fa 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -107,7 +107,7 @@ vrf_lookup_by_table (u_int32_t table_id) (zvrf->table_id != table_id)) continue; - return zvrf->vrf_id; + return zvrf_id (zvrf); } return VRF_DEFAULT; @@ -1069,7 +1069,7 @@ _netlink_route_debug( zlog_debug ("netlink_route_multipath() (%s): %s %s vrf %u type %s", routedesc, nl_msg_type_to_str (cmd), - prefix2str (p, buf, sizeof(buf)), zvrf->vrf_id, + prefix2str (p, buf, sizeof(buf)), zvrf_id (zvrf), (nexthop) ? nexthop_type_to_str (nexthop->type) : "UNK"); } } diff --git a/zebra/rtadv.c b/zebra/rtadv.c index 1ab7ac147c..26c83bc6ac 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -826,7 +826,7 @@ zebra_interface_radv_set (struct zserv *client, int sock, u_short length, if (IS_ZEBRA_DEBUG_EVENT) zlog_debug("%u: IF %u RA %s from client %s, interval %ds", - zvrf->vrf_id, ifindex, enable ? "enable" : "disable", + zvrf_id (zvrf), ifindex, enable ? "enable" : "disable", zebra_route_string(client->proto), ra_interval); /* Locate interface and check VRF match. */ @@ -834,14 +834,14 @@ zebra_interface_radv_set (struct zserv *client, int sock, u_short length, if (!ifp) { zlog_warn("%u: IF %u RA %s client %s - interface unknown", - zvrf->vrf_id, ifindex, enable ? "enable" : "disable", + zvrf_id (zvrf), ifindex, enable ? "enable" : "disable", zebra_route_string(client->proto)); return; } - if (ifp->vrf_id != zvrf->vrf_id) + if (ifp->vrf_id != zvrf_id (zvrf)) { zlog_warn("%u: IF %u RA %s client %s - VRF mismatch, IF VRF %u", - zvrf->vrf_id, ifindex, enable ? "enable" : "disable", + zvrf_id (zvrf), ifindex, enable ? "enable" : "disable", zebra_route_string(client->proto), ifp->vrf_id); return; } diff --git a/zebra/zebra_fpm.c b/zebra/zebra_fpm.c index 343ce1776c..5920cde29e 100644 --- a/zebra/zebra_fpm.c +++ b/zebra/zebra_fpm.c @@ -348,7 +348,7 @@ zfpm_is_table_for_fpm (struct route_table *table) * We only send the unicast tables in the main instance to the FPM * at this point. */ - if (info->zvrf->vrf_id != 0) + if (zvrf_id (info->zvrf) != 0) return 0; if (info->safi != SAFI_UNICAST) diff --git a/zebra/zebra_fpm_netlink.c b/zebra/zebra_fpm_netlink.c index 6543298605..be77e91a53 100644 --- a/zebra/zebra_fpm_netlink.c +++ b/zebra/zebra_fpm_netlink.c @@ -245,7 +245,7 @@ netlink_route_info_fill (netlink_route_info_t *ri, int cmd, ri->af = rib_dest_af (dest); ri->nlmsg_type = cmd; - ri->rtm_table = rib_dest_vrf (dest)->vrf_id; + ri->rtm_table = zvrf_id (rib_dest_vrf (dest)); ri->rtm_protocol = RTPROT_UNSPEC; /* diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index b64cab625d..2ed0ce7673 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -1268,7 +1268,7 @@ mpls_ftn_update (int add, struct zebra_vrf *zvrf, enum lsp_types_t type, struct nexthop *nexthop; /* Lookup table. */ - table = zebra_vrf_table (family2afi(prefix->family), SAFI_UNICAST, zvrf->vrf_id); + table = zebra_vrf_table (family2afi(prefix->family), SAFI_UNICAST, zvrf_id (zvrf)); if (! table) return -1; @@ -1502,7 +1502,7 @@ mpls_ldp_ftn_uninstall_all (struct zebra_vrf *zvrf, int afi) int update; /* Process routes of interested address-families. */ - table = zebra_vrf_table (afi, SAFI_UNICAST, zvrf->vrf_id); + table = zebra_vrf_table (afi, SAFI_UNICAST, zvrf_id (zvrf)); if (!table) return; diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c index fe1f6e0e6f..e6d13b5070 100644 --- a/zebra/zebra_ptm.c +++ b/zebra/zebra_ptm.c @@ -768,9 +768,9 @@ zebra_ptm_bfd_dst_register (struct zserv *client, int sock, u_short length, ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_MAX_HOP_CNT_FIELD, tmp_buf); - if (zvrf->vrf_id != VRF_DEFAULT) + if (zvrf_id (zvrf) != VRF_DEFAULT) ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_VRF_NAME_FIELD, - zvrf->name); + zvrf_name (zvrf)); } else { @@ -915,9 +915,9 @@ zebra_ptm_bfd_dst_deregister (struct zserv *client, int sock, u_short length, ZEBRA_PTM_BFD_SRC_IP_FIELD, buf); } #endif /* HAVE_IPV6 */ - if (zvrf->vrf_id != VRF_DEFAULT) + if (zvrf_id (zvrf) != VRF_DEFAULT) ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_VRF_NAME_FIELD, - zvrf->name); + zvrf_name (zvrf)); } else { diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 9d9b10457d..54caeba892 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -1353,7 +1353,7 @@ rib_gc_dest (struct route_node *rn) zvrf = rib_dest_vrf (dest); if (IS_ZEBRA_DEBUG_RIB) - rnode_debug (rn, zvrf->vrf_id, "removing dest from table"); + rnode_debug (rn, zvrf_id (zvrf), "removing dest from table"); dest->rnode = NULL; XFREE (MTYPE_RIB_DEST, dest); @@ -1386,7 +1386,7 @@ rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn, { inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN); zlog_debug ("%u:%s/%d: Adding route rn %p, rib %p (type %d)", - zvrf->vrf_id, buf, rn->p.prefixlen, rn, new, new->type); + zvrf_id (zvrf), buf, rn->p.prefixlen, rn, new, new->type); } if (!RIB_SYSTEM_ROUTE (new)) @@ -1395,7 +1395,7 @@ rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn, { inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN); zlog_warn ("%u:%s/%d: Route install failed", - zvrf->vrf_id, buf, rn->p.prefixlen); + zvrf_id (zvrf), buf, rn->p.prefixlen); } } @@ -1415,7 +1415,7 @@ rib_process_del_fib(struct zebra_vrf *zvrf, struct route_node *rn, { inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN); zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d)", - zvrf->vrf_id, buf, rn->p.prefixlen, rn, old, old->type); + zvrf_id (zvrf), buf, rn->p.prefixlen, rn, old, old->type); } if (!RIB_SYSTEM_ROUTE (old)) @@ -1464,11 +1464,11 @@ rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn, { if (new != old) zlog_debug ("%u:%s/%d: Updating route rn %p, rib %p (type %d) " - "old %p (type %d)", zvrf->vrf_id, buf, rn->p.prefixlen, + "old %p (type %d)", zvrf_id (zvrf), buf, rn->p.prefixlen, rn, new, new->type, old, old->type); else zlog_debug ("%u:%s/%d: Updating route rn %p, rib %p (type %d)", - zvrf->vrf_id, buf, rn->p.prefixlen, rn, new, new->type); + zvrf_id (zvrf), buf, rn->p.prefixlen, rn, new, new->type); } /* Non-system route should be installed. */ if (!RIB_SYSTEM_ROUTE (new)) @@ -1478,7 +1478,7 @@ rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn, installed = 0; inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN); zlog_warn ("%u:%s/%d: Route install failed", - zvrf->vrf_id, buf, rn->p.prefixlen); + zvrf_id (zvrf), buf, rn->p.prefixlen); } } @@ -1512,12 +1512,12 @@ rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn, { if (new != old) zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d) " - "old %p (type %d) - %s", zvrf->vrf_id, buf, rn->p.prefixlen, + "old %p (type %d) - %s", zvrf_id (zvrf), buf, rn->p.prefixlen, rn, new, new->type, old, old->type, nh_active ? "install failed" : "nexthop inactive"); else zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d) - %s", - zvrf->vrf_id, buf, rn->p.prefixlen, rn, new, new->type, + zvrf_id (zvrf), buf, rn->p.prefixlen, rn, new, new->type, nh_active ? "install failed" : "nexthop inactive"); } @@ -1627,7 +1627,7 @@ rib_process (struct route_node *rn) if (dest) { zvrf = rib_dest_vrf (dest); - vrf_id = zvrf->vrf_id; + vrf_id = zvrf_id (zvrf); } if (IS_ZEBRA_DEBUG_RIB) @@ -2027,7 +2027,7 @@ process_subq (struct list * subq, u_char qindex) { inet_ntop (rnode->p.family, &rnode->p.u.prefix, buf, INET6_ADDRSTRLEN); zlog_debug ("%u:%s/%d: rn %p dequeued from sub-queue %u", - zvrf ? zvrf->vrf_id : 0, buf, rnode->p.prefixlen, rnode, qindex); + zvrf ? zvrf_id (zvrf) : 0, buf, rnode->p.prefixlen, rnode, qindex); } if (rnode->info) @@ -2066,10 +2066,10 @@ meta_queue_process_complete (struct work_queue *dummy) continue; zvrf->flags &= ~ZEBRA_VRF_RIB_SCHEDULED; - zebra_evaluate_rnh(zvrf->vrf_id, AF_INET, 0, RNH_NEXTHOP_TYPE, NULL); - zebra_evaluate_rnh(zvrf->vrf_id, AF_INET, 0, RNH_IMPORT_CHECK_TYPE, NULL); - zebra_evaluate_rnh(zvrf->vrf_id, AF_INET6, 0, RNH_NEXTHOP_TYPE, NULL); - zebra_evaluate_rnh(zvrf->vrf_id, AF_INET6, 0, RNH_IMPORT_CHECK_TYPE, NULL); + zebra_evaluate_rnh(zvrf_id (zvrf), AF_INET, 0, RNH_NEXTHOP_TYPE, NULL); + zebra_evaluate_rnh(zvrf_id (zvrf), AF_INET, 0, RNH_IMPORT_CHECK_TYPE, NULL); + zebra_evaluate_rnh(zvrf_id (zvrf), AF_INET6, 0, RNH_NEXTHOP_TYPE, NULL); + zebra_evaluate_rnh(zvrf_id (zvrf), AF_INET6, 0, RNH_IMPORT_CHECK_TYPE, NULL); } /* Schedule LSPs for processing, if needed. */ @@ -2077,7 +2077,7 @@ meta_queue_process_complete (struct work_queue *dummy) if (mpls_should_lsps_be_processed(zvrf)) { if (IS_ZEBRA_DEBUG_MPLS) - zlog_debug ("%u: Scheduling all LSPs upon RIB completion", zvrf->vrf_id); + zlog_debug ("%u: Scheduling all LSPs upon RIB completion", zvrf_id (zvrf)); zebra_mpls_lsp_schedule (zvrf); mpls_unmark_lsps_for_processing(zvrf); } diff --git a/zebra/zebra_static.c b/zebra/zebra_static.c index 32ba90ef9a..a7a68bd0de 100644 --- a/zebra/zebra_static.c +++ b/zebra/zebra_static.c @@ -422,7 +422,7 @@ static_add_route (afi_t afi, safi_t safi, u_char type, struct prefix *p, si->distance = distance; si->flags = flags; si->tag = tag; - si->vrf_id = zvrf->vrf_id; + si->vrf_id = zvrf_id (zvrf); si->ifindex = ifindex; if (si->ifindex) strcpy(si->ifname, ifname); diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index 94e5d49c2c..fbfa70d63f 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -45,7 +45,7 @@ zebra_vrf_add_update (struct zebra_vrf *zvrf) struct zserv *client; if (IS_ZEBRA_DEBUG_EVENT) - zlog_debug ("MESSAGE: ZEBRA_VRF_ADD %s", zvrf->name); + zlog_debug ("MESSAGE: ZEBRA_VRF_ADD %s", zvrf_name (zvrf)); for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client)) zsend_vrf_add (client, zvrf); @@ -58,7 +58,7 @@ zebra_vrf_delete_update (struct zebra_vrf *zvrf) struct zserv *client; if (IS_ZEBRA_DEBUG_EVENT) - zlog_debug ("MESSAGE: ZEBRA_VRF_DELETE %s", zvrf->name); + zlog_debug ("MESSAGE: ZEBRA_VRF_DELETE %s", zvrf_name (zvrf)); for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client)) zsend_vrf_delete (client, zvrf); @@ -78,32 +78,18 @@ zebra_vrf_update_all (struct zserv *client) /* Callback upon creating a new VRF. */ static int -zebra_vrf_new (vrf_id_t vrf_id, const char *name, void **info) +zebra_vrf_new (struct vrf *vrf) { - struct zebra_vrf *zvrf = *info; + struct zebra_vrf *zvrf; if (IS_ZEBRA_DEBUG_EVENT) - zlog_info ("ZVRF %s with id %u", name, vrf_id); + zlog_info ("ZVRF %s with id %u", vrf->name, vrf->vrf_id); - if (! zvrf) - { - zvrf = zebra_vrf_lookup_by_name (name); - if (!zvrf) - { - zvrf = zebra_vrf_alloc (vrf_id, name); - zvrf->zns = zebra_ns_lookup (NS_DEFAULT); /* Point to the global (single) NS */ - *info = (void *)zvrf; - router_id_init (zvrf); - } - else - { - *info = (void *)zvrf; - router_id_init (zvrf); - } - } - - if (zvrf->vrf_id == VRF_UNKNOWN) - zvrf->vrf_id = vrf_id; + zvrf = zebra_vrf_alloc (); + zvrf->zns = zebra_ns_lookup (NS_DEFAULT); /* Point to the global (single) NS */ + router_id_init (zvrf); + vrf->info = zvrf; + zvrf->vrf = vrf; return 0; } @@ -154,9 +140,9 @@ zebra_vrf_static_route_interface_fixup (struct interface *ifp) /* Callback upon enabling a VRF. */ static int -zebra_vrf_enable (vrf_id_t vrf_id, const char *name, void **info) +zebra_vrf_enable (struct vrf *vrf) { - struct zebra_vrf *zvrf = (struct zebra_vrf *) (*info); + struct zebra_vrf *zvrf = vrf->info; struct route_table *stable = NULL; struct route_node *rn = NULL; struct static_route *si = NULL; @@ -180,7 +166,7 @@ zebra_vrf_enable (vrf_id_t vrf_id, const char *name, void **info) if (rn->info) { si = rn->info; - si->vrf_id = vrf_id; + si->vrf_id = vrf->vrf_id; if (si->ifindex) { ifp = if_lookup_by_name_vrf (si->ifname, si->vrf_id); @@ -200,9 +186,9 @@ zebra_vrf_enable (vrf_id_t vrf_id, const char *name, void **info) /* Callback upon disabling a VRF. */ static int -zebra_vrf_disable (vrf_id_t vrf_id, const char *name, void **info) +zebra_vrf_disable (struct vrf *vrf) { - struct zebra_vrf *zvrf = (struct zebra_vrf *)(*info); + struct zebra_vrf *zvrf = vrf->info; struct route_table *stable = NULL; struct route_node *rn = NULL; afi_t afi; @@ -210,7 +196,7 @@ zebra_vrf_disable (vrf_id_t vrf_id, const char *name, void **info) if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug ("VRF %s id %u is now disabled.", - zvrf->name, zvrf->vrf_id); + zvrf_name (zvrf), zvrf_id (zvrf)); for (afi = AFI_IP; afi < AFI_MAX; afi++) { @@ -231,9 +217,9 @@ zebra_vrf_disable (vrf_id_t vrf_id, const char *name, void **info) } static int -zebra_vrf_delete (vrf_id_t vrf_id, const char *name, void **info) +zebra_vrf_delete (struct vrf *vrf) { - struct zebra_vrf *zvrf = (struct zebra_vrf *) (*info); + struct zebra_vrf *zvrf = vrf->info; assert (zvrf); @@ -245,9 +231,9 @@ zebra_vrf_delete (vrf_id_t vrf_id, const char *name, void **info) list_delete_all_node (zvrf->rid_all_sorted_list); list_delete_all_node (zvrf->rid_lo_sorted_list); - zvrf->vrf_id = VRF_UNKNOWN; + vrf->vrf_id = VRF_UNKNOWN; + vrf->info = NULL; - *info = NULL; return 0; } @@ -300,7 +286,7 @@ zebra_vrf_table_create (struct zebra_vrf *zvrf, afi_t afi, safi_t safi) /* Allocate new zebra VRF. */ struct zebra_vrf * -zebra_vrf_alloc (vrf_id_t vrf_id, const char *name) +zebra_vrf_alloc (void) { struct zebra_vrf *zvrf; @@ -322,15 +308,6 @@ zebra_vrf_alloc (vrf_id_t vrf_id, const char *name) zvrf->import_check_table[AFI_IP] = route_table_init(); zvrf->import_check_table[AFI_IP6] = route_table_init(); - /* Set VRF ID */ - zvrf->vrf_id = vrf_id; - - if (name) - { - strncpy (zvrf->name, name, strlen(name)); - zvrf->name[strlen(name)] = '\0'; - } - zebra_mpls_init_tables (zvrf); return zvrf; @@ -452,9 +429,9 @@ vrf_config_write (struct vty *vty) RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { zvrf = vrf->info; - if (! zvrf || strcmp (zvrf->name, VRF_DEFAULT_NAME)) + if (! zvrf || strcmp (zvrf_name (zvrf), VRF_DEFAULT_NAME)) { - vty_out (vty, "vrf %s%s", zvrf->name, VTY_NEWLINE); + vty_out (vty, "vrf %s%s", zvrf_name (zvrf), VTY_NEWLINE); vty_out (vty, "!%s", VTY_NEWLINE); } } diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h index 8247365644..8c4f0b4a28 100644 --- a/zebra/zebra_vrf.h +++ b/zebra/zebra_vrf.h @@ -28,11 +28,8 @@ /* Routing table instance. */ struct zebra_vrf { - /* Identifier. */ - vrf_id_t vrf_id; - - /* Routing table name. */ - char name[VRF_NAMSIZ]; + /* Back pointer */ + struct vrf *vrf; /* Description. */ char *desc; @@ -86,6 +83,18 @@ struct zebra_vrf #define MPLS_FLAG_SCHEDULE_LSPS (1 << 0) }; +static inline vrf_id_t +zvrf_id (struct zebra_vrf *zvrf) +{ + return zvrf->vrf->vrf_id; +} + +static inline const char * +zvrf_name (struct zebra_vrf *zvrf) +{ + return zvrf->vrf->name; +} + struct route_table * zebra_vrf_table_with_table_id (afi_t afi, safi_t safi, vrf_id_t vrf_id, u_int32_t table_id); @@ -94,7 +103,7 @@ extern void zebra_vrf_static_route_interface_fixup (struct interface *ifp); extern void zebra_vrf_update_all (struct zserv *client); extern struct zebra_vrf *zebra_vrf_lookup_by_id (vrf_id_t vrf_id); extern struct zebra_vrf *zebra_vrf_lookup_by_name (const char *); -extern struct zebra_vrf *zebra_vrf_alloc (vrf_id_t, const char *); +extern struct zebra_vrf *zebra_vrf_alloc (void); extern struct route_table *zebra_vrf_table (afi_t, safi_t, vrf_id_t); extern struct route_table *zebra_vrf_static_table (afi_t, safi_t, struct zebra_vrf *zvrf); extern struct route_table *zebra_vrf_other_route_table (afi_t afi, u_int32_t table_id, diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 4ae12559ad..84106e7ff9 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -183,7 +183,7 @@ zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd, ret = inet_aton (gate_str, &gate); if (!ret) { - struct interface *ifp = if_lookup_by_name_vrf (gate_str, zvrf->vrf_id); + struct interface *ifp = if_lookup_by_name_vrf (gate_str, zvrf_id (zvrf)); if (!ifp) { vty_out (vty, "%% Unknown interface: %s%s", gate_str, VTY_NEWLINE); @@ -2025,7 +2025,7 @@ vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast) if (rib->vrf_id != VRF_DEFAULT) { zvrf = vrf_info_lookup(rib->vrf_id); - vty_out (vty, ", vrf %s", zvrf->name); + vty_out (vty, ", vrf %s", zvrf_name (zvrf)); } if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)) vty_out (vty, ", best"); @@ -2459,7 +2459,7 @@ do_show_ip_route (struct vty *vty, const char *vrf_name, safi_t safi, return CMD_SUCCESS; } - if (zvrf->vrf_id == VRF_UNKNOWN) + if (zvrf_id (zvrf) == VRF_UNKNOWN) { if (use_json) vty_out (vty, "{}%s", VTY_NEWLINE); @@ -2468,7 +2468,7 @@ do_show_ip_route (struct vty *vty, const char *vrf_name, safi_t safi, return CMD_SUCCESS; } - table = zebra_vrf_table (AFI_IP, safi, zvrf->vrf_id); + table = zebra_vrf_table (AFI_IP, safi, zvrf_id (zvrf)); if (! table) { if (use_json) @@ -2575,8 +2575,8 @@ DEFUN (show_ip_nht_vrf_all, RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) if ((zvrf = vrf->info) != NULL) { - vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); - zebra_print_rnh_table(zvrf->vrf_id, AF_INET, vty, RNH_NEXTHOP_TYPE); + vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE); + zebra_print_rnh_table(zvrf_id (zvrf), AF_INET, vty, RNH_NEXTHOP_TYPE); } return CMD_SUCCESS; @@ -2620,8 +2620,8 @@ DEFUN (show_ipv6_nht_vrf_all, RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) if ((zvrf = vrf->info) != NULL) { - vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); - zebra_print_rnh_table(zvrf->vrf_id, AF_INET6, vty, RNH_NEXTHOP_TYPE); + vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE); + zebra_print_rnh_table(zvrf_id (zvrf), AF_INET6, vty, RNH_NEXTHOP_TYPE); } return CMD_SUCCESS; @@ -3098,7 +3098,7 @@ vty_show_ip_route_summary (struct vty *vty, struct route_table *table) vty_out (vty, "%-20s %-20s %s (vrf %s)%s", "Route Source", "Routes", "FIB", - ((rib_table_info_t *)table->info)->zvrf->name, + zvrf_name (((rib_table_info_t *)table->info)->zvrf), VTY_NEWLINE); for (i = 0; i < ZEBRA_ROUTE_MAX; i++) @@ -3179,7 +3179,7 @@ vty_show_ip_route_summary_prefix (struct vty *vty, struct route_table *table) vty_out (vty, "%-20s %-20s %s (vrf %s)%s", "Route Source", "Prefix Routes", "FIB", - ((rib_table_info_t *)table->info)->zvrf->name, + zvrf_name (((rib_table_info_t *)table->info)->zvrf), VTY_NEWLINE); for (i = 0; i < ZEBRA_ROUTE_MAX; i++) @@ -3310,7 +3310,7 @@ DEFUN (show_ip_route_vrf_all, if (vrf_header) { - vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); + vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE); vrf_header = 0; } vty_show_ip_route (vty, rn, rib, NULL); @@ -3364,7 +3364,7 @@ DEFUN (show_ip_route_vrf_all_tag, if (vrf_header) { - vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); + vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE); vrf_header = 0; } vty_show_ip_route (vty, rn, rib, NULL); @@ -3420,7 +3420,7 @@ DEFUN (show_ip_route_vrf_all_prefix_longer, if (vrf_header) { - vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); + vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE); vrf_header = 0; } vty_show_ip_route (vty, rn, rib, NULL); @@ -3473,7 +3473,7 @@ DEFUN (show_ip_route_vrf_all_supernets, if (vrf_header) { - vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); + vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE); vrf_header = 0; } vty_show_ip_route (vty, rn, rib, NULL); @@ -3529,7 +3529,7 @@ DEFUN (show_ip_route_vrf_all_protocol, if (vrf_header) { - vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); + vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE); vrf_header = 0; } vty_show_ip_route (vty, rn, rib, NULL); @@ -3722,7 +3722,7 @@ static_config_ipv4 (struct vty *vty, safi_t safi, const char *cmd) vty_out (vty, " %d", si->distance); if (si->vrf_id != VRF_DEFAULT) - vty_out (vty, " vrf %s", zvrf ? zvrf->name : ""); + vty_out (vty, " vrf %s", zvrf ? zvrf_name (zvrf) : ""); /* Label information */ if (si->snh_label.num_labels) @@ -3855,7 +3855,7 @@ static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str, } type = STATIC_IPV6_GATEWAY_IFINDEX; gate = &gate_addr; - ifp = if_lookup_by_name_vrf (ifname, zvrf->vrf_id); + ifp = if_lookup_by_name_vrf (ifname, zvrf_id (zvrf)); if (!ifp) { vty_out (vty, "%% Malformed Interface name %s%s", ifname, VTY_NEWLINE); @@ -3873,7 +3873,7 @@ static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str, else { type = STATIC_IFINDEX; - ifp = if_lookup_by_name_vrf (gate_str, zvrf->vrf_id); + ifp = if_lookup_by_name_vrf (gate_str, zvrf_id (zvrf)); if (!ifp) { vty_out (vty, "%% Malformed Interface name %s%s", gate_str, VTY_NEWLINE); @@ -4934,7 +4934,7 @@ DEFUN (show_ipv6_route, return CMD_SUCCESS; } - if (zvrf->vrf_id == VRF_UNKNOWN) + if (zvrf_id (zvrf) == VRF_UNKNOWN) { if (uj) vty_out (vty, "{}%s", VTY_NEWLINE); @@ -4943,7 +4943,7 @@ DEFUN (show_ipv6_route, return CMD_SUCCESS; } else - vrf_id = zvrf->vrf_id; + vrf_id = zvrf_id (zvrf); } table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id); @@ -5438,7 +5438,7 @@ DEFUN (show_ipv6_route_vrf_all, if (vrf_header) { - vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); + vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE); vrf_header = 0; } vty_show_ip_route (vty, rn, rib, NULL); @@ -5492,7 +5492,7 @@ DEFUN (show_ipv6_route_vrf_all_tag, if (vrf_header) { - vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); + vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE); vrf_header = 0; } vty_show_ip_route (vty, rn, rib, NULL); @@ -5549,7 +5549,7 @@ DEFUN (show_ipv6_route_vrf_all_prefix_longer, if (vrf_header) { - vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); + vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE); vrf_header = 0; } vty_show_ip_route (vty, rn, rib, NULL); @@ -5604,7 +5604,7 @@ DEFUN (show_ipv6_route_vrf_all_protocol, if (vrf_header) { - vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); + vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE); vrf_header = 0; } vty_show_ip_route (vty, rn, rib, NULL); @@ -5838,7 +5838,7 @@ static_config_ipv6 (struct vty *vty) if (si->vrf_id != VRF_DEFAULT) { - vty_out (vty, " vrf %s", zvrf->name); + vty_out (vty, " vrf %s", zvrf_name (zvrf)); } /* Label information */ @@ -5888,14 +5888,14 @@ DEFUN (show_vrf, RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { zvrf = vrf->info; - if (! zvrf || ! zvrf->vrf_id) + if (! zvrf || ! zvrf_id (zvrf)) continue; - vty_out (vty, "vrf %s ", zvrf->name); - if (zvrf->vrf_id == VRF_UNKNOWN) + vty_out (vty, "vrf %s ", zvrf_name (zvrf)); + if (zvrf_id (zvrf) == VRF_UNKNOWN) vty_out (vty, "inactive"); else - vty_out (vty, "id %u table %u", zvrf->vrf_id, zvrf->table_id); + vty_out (vty, "id %u table %u", zvrf_id (zvrf), zvrf->table_id); vty_out (vty, "%s", VTY_NEWLINE); } diff --git a/zebra/zserv.c b/zebra/zserv.c index 947e7324db..83d7d0f811 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -185,7 +185,7 @@ static void zserv_encode_vrf (struct stream *s, struct zebra_vrf *zvrf) { /* Interface information. */ - stream_put (s, zvrf->name, VRF_NAMSIZ); + stream_put (s, zvrf_name (zvrf), VRF_NAMSIZ); /* Write packet size. */ stream_putw_at (s, 0, stream_get_endp (s)); @@ -241,7 +241,7 @@ zsend_vrf_add (struct zserv *client, struct zebra_vrf *zvrf) s = client->obuf; stream_reset (s); - zserv_create_header (s, ZEBRA_VRF_ADD, zvrf->vrf_id); + zserv_create_header (s, ZEBRA_VRF_ADD, zvrf_id (zvrf)); zserv_encode_vrf (s, zvrf); client->vrfadd_cnt++; @@ -257,7 +257,7 @@ zsend_vrf_delete (struct zserv *client, struct zebra_vrf *zvrf) s = client->obuf; stream_reset (s); - zserv_create_header (s, ZEBRA_VRF_DELETE, zvrf->vrf_id); + zserv_create_header (s, ZEBRA_VRF_DELETE, zvrf_id (zvrf)); zserv_encode_vrf (s, zvrf); client->vrfdel_cnt++; @@ -850,7 +850,7 @@ zserv_rnh_register (struct zserv *client, int sock, u_short length, p.family); return -1; } - rnh = zebra_add_rnh(&p, zvrf->vrf_id, type); + rnh = zebra_add_rnh(&p, zvrf_id (zvrf), type); if (type == RNH_NEXTHOP_TYPE) { if (flags && !CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED)) @@ -866,9 +866,9 @@ zserv_rnh_register (struct zserv *client, int sock, u_short length, UNSET_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH); } - zebra_add_rnh_client(rnh, client, type, zvrf->vrf_id); + zebra_add_rnh_client(rnh, client, type, zvrf_id (zvrf)); /* Anything not AF_INET/INET6 has been filtered out above */ - zebra_evaluate_rnh(zvrf->vrf_id, p.family, 1, type, &p); + zebra_evaluate_rnh(zvrf_id (zvrf), p.family, 1, type, &p); } return 0; } @@ -911,7 +911,7 @@ zserv_rnh_unregister (struct zserv *client, int sock, u_short length, p.family); return -1; } - rnh = zebra_lookup_rnh(&p, zvrf->vrf_id, type); + rnh = zebra_lookup_rnh(&p, zvrf_id (zvrf), type); if (rnh) { client->nh_dereg_time = quagga_monotime(); @@ -939,7 +939,7 @@ zsend_ipv4_nexthop_lookup_mrib (struct zserv *client, struct in_addr addr, struc stream_reset (s); /* Fill in result. */ - zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, zvrf->vrf_id); + zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, zvrf_id (zvrf)); stream_put_in_addr (s, &addr); if (rib) @@ -1010,7 +1010,7 @@ zread_interface_add (struct zserv *client, u_short length, struct zebra_vrf *zvr struct interface *ifp; /* Interface information is needed. */ - vrf_bitmap_set (client->ifinfo, zvrf->vrf_id); + vrf_bitmap_set (client->ifinfo, zvrf_id (zvrf)); RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { @@ -1034,7 +1034,7 @@ zread_interface_add (struct zserv *client, u_short length, struct zebra_vrf *zvr static int zread_interface_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf) { - vrf_bitmap_unset (client->ifinfo, zvrf->vrf_id); + vrf_bitmap_unset (client->ifinfo, zvrf_id (zvrf)); return 0; } @@ -1091,7 +1091,7 @@ zread_ipv4_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf) stream_get (&p.u.prefix4, s, PSIZE (p.prefixlen)); /* VRF ID */ - rib->vrf_id = zvrf->vrf_id; + rib->vrf_id = zvrf_id (zvrf); /* Nexthop parse. */ if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP)) @@ -1243,7 +1243,7 @@ zread_ipv4_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf) table_id = zvrf->table_id; - rib_delete (AFI_IP, api.safi, zvrf->vrf_id, api.type, api.instance, + rib_delete (AFI_IP, api.safi, zvrf_id (zvrf), api.type, api.instance, api.flags, &p, nexthop_p, ifindex, table_id); client->v4_route_del_cnt++; return 0; @@ -1257,7 +1257,7 @@ zread_ipv4_nexthop_lookup_mrib (struct zserv *client, u_short length, struct zeb struct rib *rib; addr.s_addr = stream_get_ipv4 (client->ibuf); - rib = rib_match_ipv4_multicast (zvrf->vrf_id, addr, NULL); + rib = rib_match_ipv4_multicast (zvrf_id (zvrf), addr, NULL); return zsend_ipv4_nexthop_lookup_mrib (client, addr, rib, zvrf); } @@ -1301,7 +1301,7 @@ zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length, struct stream_get (&p.u.prefix4, s, PSIZE (p.prefixlen)); /* VRF ID */ - rib->vrf_id = zvrf->vrf_id; + rib->vrf_id = zvrf_id (zvrf); /* We need to give nh-addr, nh-ifindex with the same next-hop object * to the rib to ensure that IPv6 multipathing works; need to coalesce @@ -1498,7 +1498,7 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf) rib->mtu = 0; /* VRF ID */ - rib->vrf_id = zvrf->vrf_id; + rib->vrf_id = zvrf_id (zvrf); rib->table = zvrf->table_id; ret = rib_add_multipath (AFI_IP6, safi, &p, rib); @@ -1582,10 +1582,10 @@ zread_ipv6_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf) api.tag = 0; if (IN6_IS_ADDR_UNSPECIFIED (&nexthop)) - rib_delete (AFI_IP6, api.safi, zvrf->vrf_id, api.type, api.instance, + rib_delete (AFI_IP6, api.safi, zvrf_id (zvrf), api.type, api.instance, api.flags, &p, NULL, ifindex, client->rtm_table); else - rib_delete (AFI_IP6, api.safi, zvrf->vrf_id, api.type, api.instance, + rib_delete (AFI_IP6, api.safi, zvrf_id (zvrf), api.type, api.instance, api.flags, &p, pnexthop, ifindex, client->rtm_table); client->v6_route_del_cnt++; @@ -1599,18 +1599,18 @@ zread_router_id_add (struct zserv *client, u_short length, struct zebra_vrf *zvr struct prefix p; /* Router-id information is needed. */ - vrf_bitmap_set (client->ridinfo, zvrf->vrf_id); + vrf_bitmap_set (client->ridinfo, zvrf_id (zvrf)); - router_id_get (&p, zvrf->vrf_id); + router_id_get (&p, zvrf_id (zvrf)); - return zsend_router_id_update (client, &p, zvrf->vrf_id); + return zsend_router_id_update (client, &p, zvrf_id (zvrf)); } /* Unregister zebra server router-id information. */ static int zread_router_id_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf) { - vrf_bitmap_unset (client->ridinfo, zvrf->vrf_id); + vrf_bitmap_unset (client->ridinfo, zvrf_id (zvrf)); return 0; } @@ -1648,10 +1648,10 @@ zread_vrf_unregister (struct zserv *client, u_short length, struct zebra_vrf *zv for (afi = AFI_IP; afi < AFI_MAX; afi++) for (i = 0; i < ZEBRA_ROUTE_MAX; i++) - vrf_bitmap_unset (client->redist[afi][i], zvrf->vrf_id); - vrf_bitmap_unset (client->redist_default, zvrf->vrf_id); - vrf_bitmap_unset (client->ifinfo, zvrf->vrf_id); - vrf_bitmap_unset (client->ridinfo, zvrf->vrf_id); + vrf_bitmap_unset (client->redist[afi][i], zvrf_id (zvrf)); + vrf_bitmap_unset (client->redist_default, zvrf_id (zvrf)); + vrf_bitmap_unset (client->ifinfo, zvrf_id (zvrf)); + vrf_bitmap_unset (client->ridinfo, zvrf_id (zvrf)); return 0; } @@ -1729,10 +1729,10 @@ zebra_client_close_cleanup_rnh (struct zserv *client) { if ((zvrf = vrf->info) != NULL) { - zebra_cleanup_rnh_client(zvrf->vrf_id, AF_INET, client, RNH_NEXTHOP_TYPE); - zebra_cleanup_rnh_client(zvrf->vrf_id, AF_INET6, client, RNH_NEXTHOP_TYPE); - zebra_cleanup_rnh_client(zvrf->vrf_id, AF_INET, client, RNH_IMPORT_CHECK_TYPE); - zebra_cleanup_rnh_client(zvrf->vrf_id, AF_INET6, client, RNH_IMPORT_CHECK_TYPE); + zebra_cleanup_rnh_client(zvrf_id (zvrf), AF_INET, client, RNH_NEXTHOP_TYPE); + zebra_cleanup_rnh_client(zvrf_id (zvrf), AF_INET6, client, RNH_NEXTHOP_TYPE); + zebra_cleanup_rnh_client(zvrf_id (zvrf), AF_INET, client, RNH_IMPORT_CHECK_TYPE); + zebra_cleanup_rnh_client(zvrf_id (zvrf), AF_INET6, client, RNH_IMPORT_CHECK_TYPE); if (client->proto == ZEBRA_ROUTE_LDP) { hash_iterate(zvrf->lsp_table, mpls_ldp_lsp_uninstall_all, From 2414ffe50c5c66dc08f241d918917fd765970d35 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Tue, 1 Nov 2016 07:57:39 -0200 Subject: [PATCH 31/44] zebra: loop through all static routes on vrf enable/disable Signed-off-by: Renato Westphal --- zebra/zebra_vrf.c | 78 ++++++++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 42 deletions(-) diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index fbfa70d63f..13010bfdcd 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -143,10 +143,10 @@ static int zebra_vrf_enable (struct vrf *vrf) { struct zebra_vrf *zvrf = vrf->info; - struct route_table *stable = NULL; - struct route_node *rn = NULL; - struct static_route *si = NULL; - struct interface *ifp = NULL; + struct route_table *stable; + struct route_node *rn; + struct static_route *si; + struct interface *ifp; afi_t afi; safi_t safi; @@ -155,32 +155,28 @@ zebra_vrf_enable (struct vrf *vrf) zebra_vrf_add_update (zvrf); for (afi = AFI_IP; afi < AFI_MAX; afi++) - { - for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) - { - stable = zvrf->stable[afi][safi]; - if (stable) + for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) + { + stable = zvrf->stable[afi][safi]; + if (! stable) + continue; + + for (rn = route_top (stable); rn; rn = route_next (rn)) + for (si = rn->info; si; si = si->next) { - for (rn = route_top (stable); rn; rn = route_next (rn)) + si->vrf_id = vrf->vrf_id; + if (si->ifindex) { - if (rn->info) - { - si = rn->info; - si->vrf_id = vrf->vrf_id; - if (si->ifindex) - { - ifp = if_lookup_by_name_vrf (si->ifname, si->vrf_id); - if (ifp) - si->ifindex = ifp->ifindex; - else - continue; - } - static_install_route (afi, safi, &rn->p, si); - } + ifp = if_lookup_by_name_vrf (si->ifname, si->vrf_id); + if (ifp) + si->ifindex = ifp->ifindex; + else + continue; } + static_install_route (afi, safi, &rn->p, si); } - } - } + } + return 0; } @@ -189,8 +185,9 @@ static int zebra_vrf_disable (struct vrf *vrf) { struct zebra_vrf *zvrf = vrf->info; - struct route_table *stable = NULL; - struct route_node *rn = NULL; + struct route_table *stable; + struct route_node *rn; + struct static_route *si; afi_t afi; safi_t safi; @@ -199,20 +196,17 @@ zebra_vrf_disable (struct vrf *vrf) zvrf_name (zvrf), zvrf_id (zvrf)); for (afi = AFI_IP; afi < AFI_MAX; afi++) - { - for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) - { - stable = zvrf->stable[afi][safi]; - if (stable) - { - for (rn = route_top (stable); rn; rn = route_next (rn)) - { - if (rn->info) - static_uninstall_route(afi, safi, &rn->p, rn->info); - } - } - } - } + for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) + { + stable = zvrf->stable[afi][safi]; + if (! stable) + continue; + + for (rn = route_top (stable); rn; rn = route_next (rn)) + for (si = rn->info; si; si = si->next) + static_uninstall_route(afi, safi, &rn->p, si); + } + return 0; } From 5a8dfcd891fd12bb9db8f504bf3a083cea4f3cbd Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Mon, 31 Oct 2016 15:15:16 -0200 Subject: [PATCH 32/44] zebra: plug more memory leaks Try to free all memory explicitly on exit. This should help to detect new memory leaks in the future with tools like valgrind. Signed-off-by: Renato Westphal --- zebra/main.c | 18 ++++- zebra/rib.h | 3 +- zebra/zebra_rib.c | 52 +++---------- zebra/zebra_rnh.c | 17 +++-- zebra/zebra_rnh.h | 1 + zebra/zebra_rnh_null.c | 4 + zebra/zebra_vrf.c | 163 ++++++++++++++++++++++++++++++++++++----- zebra/zebra_vrf.h | 1 + 8 files changed, 191 insertions(+), 68 deletions(-) diff --git a/zebra/main.c b/zebra/main.c index 1b41f8deff..4fea0104f5 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -182,17 +182,27 @@ sighup (void) static void sigint (void) { + struct vrf *vrf; + struct zebra_vrf *zvrf; struct zebra_ns *zns; zlog_notice ("Terminating on signal"); - if (!retain_mode) - rib_close (); #ifdef HAVE_IRDP irdp_finish(); #endif zebra_ptm_finish(); + list_delete_all_node (zebrad.client_list); + + if (retain_mode) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) + { + zvrf = vrf->info; + if (zvrf) + SET_FLAG (zvrf->flags, ZEBRA_VRF_RETAIN); + } + vrf_terminate (); zns = zebra_ns_lookup (NS_DEFAULT); zebra_ns_disable (0, (void **)&zns); @@ -204,6 +214,10 @@ sigint (void) vty_terminate (); zprivs_terminate (&zserv_privs); list_delete (zebrad.client_list); + work_queue_free (zebrad.ribq); + if (zebrad.lsp_process_q) + work_queue_free (zebrad.lsp_process_q); + meta_queue_free (zebrad.mq); thread_master_free (zebrad.master); if (zlog_default) closezlog (zlog_default); diff --git a/zebra/rib.h b/zebra/rib.h index c95a9ba0c3..30929f1beb 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -366,13 +366,14 @@ extern void rib_update (vrf_id_t, rib_update_event_t); extern void rib_weed_tables (void); extern void rib_sweep_route (void); extern void rib_close_table (struct route_table *); -extern void rib_close (void); extern void rib_init (void); extern unsigned long rib_score_proto (u_char proto, u_short instance); extern void rib_queue_add (struct route_node *rn); +extern void meta_queue_free (struct meta_queue *mq); extern struct route_table *rib_table_ipv6; +extern void rib_unlink (struct route_node *, struct rib *); extern int rib_gc_dest (struct route_node *rn); extern struct route_table *rib_tables_iter_next (rib_tables_iter_t *iter); diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 54caeba892..e29307be27 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -1304,8 +1304,6 @@ rib_uninstall (struct route_node *rn, struct rib *rib) } } -static void rib_unlink (struct route_node *, struct rib *); - /* * rib_can_delete_dest * @@ -2216,6 +2214,17 @@ meta_queue_new (void) return new; } +void +meta_queue_free (struct meta_queue *mq) +{ + unsigned i; + + for (i = 0; i < MQ_SIZE; i++) + list_delete (mq->subq[i]); + + XFREE (MTYPE_WORK_QUEUE, mq); +} + /* initialise zebra rib work queue */ static void rib_queue_init (struct zebra_t *zebra) @@ -2351,7 +2360,7 @@ rib_addnode (struct route_node *rn, struct rib *rib, int process) * rib_gc_dest() at some point. This allows a rib_dest_t that is no * longer required to be deleted. */ -static void +void rib_unlink (struct route_node *rn, struct rib *rib) { rib_dest_t *dest; @@ -3153,43 +3162,6 @@ rib_close_table (struct route_table *table) } } -/* Close all RIB tables. */ -void -rib_close (void) -{ - struct vrf *vrf; - struct zebra_vrf *zvrf; - struct listnode *node; - struct interface *ifp; - u_int32_t table_id; - - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) - { - if ((zvrf = vrf->info) != NULL) - { - rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]); - rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]); - } - for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp)) - if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp); - } - - /* If we do multiple tables per vrf, need to move this to loop above */ - zvrf = vrf_info_lookup (VRF_DEFAULT); - - for (table_id = 0; table_id < ZEBRA_KERNEL_TABLE_MAX; table_id++) - { - if (zvrf->other_table[AFI_IP][table_id]) - rib_close_table (zvrf->other_table[AFI_IP][table_id]); - - if (zvrf->other_table[AFI_IP6][table_id]) - rib_close_table (zvrf->other_table[AFI_IP6][table_id]); - } - - zebra_mpls_close_tables(zvrf); - -} - /* Routing information base initialize. */ void rib_init (void) diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index 7df759030d..c6fc404bed 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -163,6 +163,16 @@ zebra_lookup_rnh (struct prefix *p, vrf_id_t vrfid, rnh_type_t type) return (rn->info); } +void +zebra_free_rnh (struct rnh *rnh) +{ + rnh->flags |= ZEBRA_NHT_DELETED; + list_free (rnh->client_list); + list_free (rnh->zebra_static_route_list); + free_state (rnh->vrf_id, rnh->state, rnh->node); + XFREE (MTYPE_RNH, rnh); +} + void zebra_delete_rnh (struct rnh *rnh, rnh_type_t type) { @@ -178,14 +188,9 @@ zebra_delete_rnh (struct rnh *rnh, rnh_type_t type) rnh->vrf_id, rnh_str(rnh, buf, sizeof (buf)), type); } - rnh->flags |= ZEBRA_NHT_DELETED; - list_free(rnh->client_list); - list_free(rnh->zebra_static_route_list); - free_state(rnh->vrf_id, rnh->state, rn); - XFREE(MTYPE_RNH, rn->info); + zebra_free_rnh (rnh); rn->info = NULL; route_unlock_node (rn); - return; } void diff --git a/zebra/zebra_rnh.h b/zebra/zebra_rnh.h index 3a57ef1bc6..4394fde4f3 100644 --- a/zebra/zebra_rnh.h +++ b/zebra/zebra_rnh.h @@ -59,6 +59,7 @@ extern struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, rnh_type_t type); extern struct rnh *zebra_lookup_rnh(struct prefix *p, vrf_id_t vrfid, rnh_type_t type); +extern void zebra_free_rnh (struct rnh *rnh); extern void zebra_delete_rnh(struct rnh *rnh, rnh_type_t type); extern void zebra_add_rnh_client(struct rnh *rnh, struct zserv *client, rnh_type_t type, vrf_id_t vrfid); diff --git a/zebra/zebra_rnh_null.c b/zebra/zebra_rnh_null.c index eecb8519d5..a97ae1a612 100644 --- a/zebra/zebra_rnh_null.c +++ b/zebra/zebra_rnh_null.c @@ -26,6 +26,10 @@ int zebra_rnh_ip_default_route = 0; int zebra_rnh_ipv6_default_route = 0; +void +zebra_free_rnh (struct rnh *rnh) +{} + void zebra_evaluate_rnh (vrf_id_t vrfid, int family, int force, rnh_type_t type, struct prefix *p) {} diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index 13010bfdcd..b1c5e4dd35 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -30,9 +30,11 @@ #include "zebra/zserv.h" #include "zebra/rib.h" #include "zebra/zebra_vrf.h" +#include "zebra/zebra_rnh.h" #include "zebra/router-id.h" #include "zebra/zebra_memory.h" #include "zebra/zebra_static.h" +#include "zebra/interface.h" #include "zebra/zebra_mpls.h" extern struct zebra_t zebrad; @@ -214,18 +216,84 @@ static int zebra_vrf_delete (struct vrf *vrf) { struct zebra_vrf *zvrf = vrf->info; + struct route_table *table; + u_int32_t table_id; + afi_t afi; + safi_t safi; + unsigned i; assert (zvrf); zebra_vrf_delete_update (zvrf); - rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]); - rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]); + /* uninstall everything */ + if (! CHECK_FLAG (zvrf->flags, ZEBRA_VRF_RETAIN)) + { + struct listnode *node; + struct interface *ifp; + for (afi = AFI_IP; afi <= AFI_IP6; afi++) + { + for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) + rib_close_table (zvrf->table[afi][safi]); + + if (vrf->vrf_id == VRF_DEFAULT) + for (table_id = 0; table_id < ZEBRA_KERNEL_TABLE_MAX; table_id++) + if (zvrf->other_table[afi][table_id]) + rib_close_table (zvrf->other_table[afi][table_id]); + } + + zebra_mpls_close_tables (zvrf); + + for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp)) + if_nbr_ipv6ll_to_ipv4ll_neigh_del_all (ifp); + } + + /* clean-up work queues */ + for (i = 0; i < MQ_SIZE; i++) + { + struct listnode *lnode, *nnode; + struct route_node *rnode; + rib_dest_t *dest; + + for (ALL_LIST_ELEMENTS (zebrad.mq->subq[i], lnode, nnode, rnode)) + { + dest = rib_dest_from_rnode (rnode); + if (dest && rib_dest_vrf (dest) == zvrf) + { + route_unlock_node (rnode); + list_delete_node (zebrad.mq->subq[i], lnode); + } + } + } + + /* release allocated memory */ + for (afi = AFI_IP; afi <= AFI_IP6; afi++) + { + for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) + { + table = zvrf->table[afi][safi]; + XFREE (MTYPE_RIB_TABLE_INFO, table->info); + route_table_finish (table); + + table = zvrf->stable[afi][safi]; + route_table_finish (table); + } + + for (table_id = 0; table_id < ZEBRA_KERNEL_TABLE_MAX; table_id++) + if (zvrf->other_table[afi][table_id]) + { + table = zvrf->other_table[afi][table_id]; + XFREE (MTYPE_RIB_TABLE_INFO, table->info); + route_table_finish (table); + } + + route_table_finish (zvrf->rnh_table[afi]); + route_table_finish (zvrf->import_check_table[afi]); + } list_delete_all_node (zvrf->rid_all_sorted_list); list_delete_all_node (zvrf->rid_lo_sorted_list); - - vrf->vrf_id = VRF_UNKNOWN; + XFREE (MTYPE_ZEBRA_VRF, zvrf); vrf->info = NULL; return 0; @@ -257,6 +325,62 @@ zebra_vrf_table_with_table_id (afi_t afi, safi_t safi, return table; } +static void +zebra_rtable_node_destroy (route_table_delegate_t *delegate, + struct route_table *table, struct route_node *node) +{ + struct rib *rib, *next; + + RNODE_FOREACH_RIB_SAFE (node, rib, next) + rib_unlink (node, rib); + + if (node->info) + XFREE (MTYPE_RIB_DEST, node->info); + + route_node_destroy (delegate, table, node); +} + +static void +zebra_stable_node_destroy (route_table_delegate_t *delegate, + struct route_table *table, struct route_node *node) +{ + struct static_route *si, *next; + + if (node->info) + for (si = node->info; si; si = next) + { + next = si->next; + XFREE (MTYPE_STATIC_ROUTE, si); + } + + route_node_destroy (delegate, table, node); +} + +static void +zebra_rnhtable_node_destroy (route_table_delegate_t *delegate, + struct route_table *table, struct route_node *node) +{ + if (node->info) + zebra_free_rnh (node->info); + + route_node_destroy (delegate, table, node); +} + +route_table_delegate_t zebra_rtable_delegate = { + .create_node = route_node_create, + .destroy_node = zebra_rtable_node_destroy +}; + +route_table_delegate_t zebra_stable_delegate = { + .create_node = route_node_create, + .destroy_node = zebra_stable_node_destroy +}; + +route_table_delegate_t zebra_rnhtable_delegate = { + .create_node = route_node_create, + .destroy_node = zebra_rnhtable_node_destroy +}; + /* * Create a routing table for the specific AFI/SAFI in the given VRF. */ @@ -268,7 +392,7 @@ zebra_vrf_table_create (struct zebra_vrf *zvrf, afi_t afi, safi_t safi) assert (!zvrf->table[afi][safi]); - table = route_table_init (); + table = route_table_init_with_delegate (&zebra_rtable_delegate); zvrf->table[afi][safi] = table; info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info)); @@ -283,24 +407,25 @@ struct zebra_vrf * zebra_vrf_alloc (void) { struct zebra_vrf *zvrf; + afi_t afi; + safi_t safi; zvrf = XCALLOC (MTYPE_ZEBRA_VRF, sizeof (struct zebra_vrf)); - /* Allocate routing table and static table. */ - zebra_vrf_table_create (zvrf, AFI_IP, SAFI_UNICAST); - zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_UNICAST); - zvrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init (); - zvrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init (); - zebra_vrf_table_create (zvrf, AFI_IP, SAFI_MULTICAST); - zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_MULTICAST); - zvrf->stable[AFI_IP][SAFI_MULTICAST] = route_table_init (); - zvrf->stable[AFI_IP6][SAFI_MULTICAST] = route_table_init (); + for (afi = AFI_IP; afi <= AFI_IP6; afi++) + { + for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) + { + zebra_vrf_table_create (zvrf, afi, safi); + zvrf->stable[afi][safi] = + route_table_init_with_delegate (&zebra_stable_delegate); + } - zvrf->rnh_table[AFI_IP] = route_table_init(); - zvrf->rnh_table[AFI_IP6] = route_table_init(); - - zvrf->import_check_table[AFI_IP] = route_table_init(); - zvrf->import_check_table[AFI_IP6] = route_table_init(); + zvrf->rnh_table[afi] = + route_table_init_with_delegate (&zebra_rnhtable_delegate); + zvrf->import_check_table[afi] = + route_table_init_with_delegate (&zebra_rnhtable_delegate); + } zebra_mpls_init_tables (zvrf); diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h index 8c4f0b4a28..96d631d646 100644 --- a/zebra/zebra_vrf.h +++ b/zebra/zebra_vrf.h @@ -40,6 +40,7 @@ struct zebra_vrf /* Flags. */ u_int16_t flags; #define ZEBRA_VRF_RIB_SCHEDULED (1 << 0) +#define ZEBRA_VRF_RETAIN (2 << 0) u_int32_t table_id; From f4f59de462018e48c639978cfe57cf4301a0d209 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Mon, 28 Nov 2016 15:00:05 -0200 Subject: [PATCH 33/44] bgpd: fix invalid memory access in peer_free() We shoult not call bgp_unlock() before calling bgp_delete_connected_nexthop() in the peer_free() function. Otherwise, if bgp->lock reaches zero, bgp_free() is called and peer->bgp becomes an invalid pointer in the bgp_delete_connected_nexthop() function. To fix this, move the call to bgp_unlock() to the end of peer_free(). Bug exposed by commit 37d361e ("bgpd: plug several memleaks"). Signed-off-by: Renato Westphal --- bgpd/bgpd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 22d4dd8917..d5aff84dae 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -1019,8 +1019,6 @@ peer_free (struct peer *peer) { assert (peer->status == Deleted); - bgp_unlock(peer->bgp); - /* this /ought/ to have been done already through bgp_stop earlier, * but just to be sure.. */ @@ -1092,6 +1090,8 @@ peer_free (struct peer *peer) bfd_info_free(&(peer->bfd_info)); + bgp_unlock(peer->bgp); + memset (peer, 0, sizeof (struct peer)); XFREE (MTYPE_BGP_PEER, peer); From 45d430e81de0c3ca127b378b1d0e020d116f01cb Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 2 Dec 2016 08:19:26 -0500 Subject: [PATCH 34/44] ospfd: Fix json Crash with inactive timer When nbr->t_inactivity is not active, and you do a show json over the neighbor it will crash ospfd. Fix the code so it prints out -1 when the timer is inactive. Ticket:CM-13835 Signed-off-by: Donald Sharp Reviewed-by: Don Slice Reviewed-by: Daniel Walton (cherry picked from commit 78d8fcb9623ab4d9cebf6187a451448e056a84bf) Signed-off-by: David Lamparter --- ospfd/ospf_vty.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 43a443421f..4eeb5c15d9 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -4590,10 +4590,15 @@ show_ip_ospf_neighbor_detail_sub (struct vty *vty, struct ospf_interface *oi, /* Show Router Dead interval timer. */ if (use_json) { - struct timeval res = tv_sub (nbr->t_inactivity->u.sands, recent_relative_time ()); - unsigned long time_store = 0; - time_store = (1000 * res.tv_sec) + (res.tv_usec / 1000); - json_object_int_add(json_sub, "routerDeadIntervalTimerDueMsec", time_store); + if (nbr->t_inactivity) + { + struct timeval res = tv_sub (nbr->t_inactivity->u.sands, recent_relative_time ()); + unsigned long time_store = 0; + time_store = (1000 * res.tv_sec) + (res.tv_usec / 1000); + json_object_int_add(json_sub, "routerDeadIntervalTimerDueMsec", time_store); + } + else + json_object_int_add(json_sub, "routerDeadIntervalTimerDueMsec", -1); } else vty_out (vty, " Dead timer due in %s%s", From 9166c8ebd1e8f38f421b95f1be432daa7be158c6 Mon Sep 17 00:00:00 2001 From: vivek Date: Fri, 2 Dec 2016 08:22:21 -0500 Subject: [PATCH 35/44] bgpd: Fix route node unlock when clearing adj-out When clearing the adj-out for a subgroup (e.g., upon peer going down), ensure that the adj-out is removed before unlocking the route node that it points to, otherwise, there is a possibility that the route node may be prematurely freed. Signed-off-by: Vivek Venkatraman Ticket: CM-13690 Reviewed By: None Testing Done: bgp-smoke, resilient-hash tests (cherry picked from commit c3d7d35f3b7152c9e50e52c3cfd60b0dc52df703) Signed-off-by: David Lamparter --- bgpd/bgp_updgrp_adv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bgpd/bgp_updgrp_adv.c b/bgpd/bgp_updgrp_adv.c index c485e61e5c..a95a11b620 100644 --- a/bgpd/bgp_updgrp_adv.c +++ b/bgpd/bgp_updgrp_adv.c @@ -573,8 +573,8 @@ subgroup_clear_table (struct update_subgroup *subgrp) SUBGRP_FOREACH_ADJ_SAFE (subgrp, aout, taout) { - bgp_unlock_node (aout->rn); bgp_adj_out_remove_subgroup (aout->rn, aout, subgrp); + bgp_unlock_node (aout->rn); } } From 612630321db78dc08b438b7df99958b939c92f0b Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 2 Dec 2016 13:57:04 -0500 Subject: [PATCH 36/44] bgpd: Fix 'show ip bgp' to not change it's output For unicast routes do not change the output of the 'show ip bgp' command. This will allow people with existing scripts to continue to work. Signed-off-by: Donald Sharp Signed-off-by: David Lamparter --- bgpd/bgp_route.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 23ecefa6e2..c2c63049a8 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -6329,7 +6329,7 @@ route_vty_out (struct vty *vty, struct prefix *p, vty_out (vty, "%s", VTY_NEWLINE); #if ENABLE_BGP_VNC /* prints an additional line, indented, with VNC info, if present */ - if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP) || (safi == SAFI_UNICAST)) + if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) rfapi_vty_out_vncinfo(vty, p, binfo, safi); #endif } From 2b71bbdda1a0974a613d5f32fe47223315d47513 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sat, 3 Dec 2016 21:35:23 -0200 Subject: [PATCH 37/44] doc: update README to mention PIM-SSM and LDP support Signed-off-by: David Lamparter --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index f1b25d8a92..91a1d8d0fb 100644 --- a/README +++ b/README @@ -2,7 +2,7 @@ Quagga is free software that manages various IPv4 and IPv6 routing protocols. Currently Quagga supports BGP4, BGP4+, OSPFv2, OSPFv3, RIPv1, -RIPv2, and RIPng as well as very early support for IS-IS. +RIPv2, RIPng, PIM-SSM and LDP as well as very early support for IS-IS. See the file INSTALL.quagga.txt for building and installation instructions. From 7cd6a66a6f6ea6ec9987146020f3910601699c77 Mon Sep 17 00:00:00 2001 From: vivek Date: Sat, 3 Dec 2016 21:51:49 -0500 Subject: [PATCH 38/44] bgpd: Remove nexthop for peer only for "real" peer During connection establishment, there is a separate peer structure created for the doppelganger (for incoming connection). When this is deleted after the connection has established, take care to ensure that the nexthop entry for the peer is not deleted. Fixes: f9164b1d74f6a20d69d7ef10d2e39b4ae7996cbf Signed-off-by: Vivek Venkatraman Ticket: CM-13875 Reviewed By: None Testing Done: Manual (cherry picked from commit 4f2bc892cbddbf36bd5e1b2f36c33260af614b33) Signed-off-by: David Lamparter --- bgpd/bgpd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 7675df226b..7f92310d91 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -1972,7 +1972,8 @@ peer_delete (struct peer *peer) bgp_fsm_change_status (peer, Deleted); /* Remove from NHT */ - bgp_unlink_nexthop_by_peer (peer); + if (CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE)) + bgp_unlink_nexthop_by_peer (peer); /* Password configuration */ if (peer->password) From b6a9e7b4878f76306ca2b25960cb52805794c8a5 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 1 Dec 2016 10:49:22 -0500 Subject: [PATCH 39/44] lib, zebra: Minimize display of link-params sub data When link-params is configured it auto starts displaying 6000-02# conf t dell-s6000-02(config)# int swp1 dell-s6000-02(config-if)# link-params dell-s6000-02(config-link-params)# admin-grp 0x12345678 dell-s6000-02(config-link-params)# end dell-s6000-02# show run interface swp1 link-params enable metric 0 <----Remove the bw lines max-bw 1.25e+06 max-rsv-bw 1.25e+06 unrsv-bw 0 1.25e+06 unrsv-bw 1 1.25e+06 unrsv-bw 2 1.25e+06 unrsv-bw 3 1.25e+06 unrsv-bw 4 1.25e+06 unrsv-bw 5 1.25e+06 unrsv-bw 6 1.25e+06 unrsv-bw 7 1.25e+06 admin-grp 305419896 exit-link-params ! I'd like to reduce this to: interface enp0s3 ip igmp ip pim sm link-params enable admin-grp 0x12345678 <----- Fix this to be what we entered exit-link-params ! Signed-off-by: Donald Sharp Signed-off-by: David Lamparter --- lib/if.c | 10 +++++----- lib/if.h | 2 ++ zebra/interface.c | 17 +++++++++-------- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/lib/if.c b/lib/if.c index df53f8d4e8..e745dc9027 100644 --- a/lib/if.c +++ b/lib/if.c @@ -1366,14 +1366,14 @@ if_link_params_get (struct interface *ifp) iflp->te_metric = ifp->metric; /* Compute default bandwidth based on interface */ - int bw = (float)((ifp->bandwidth ? ifp->bandwidth : DEFAULT_BANDWIDTH) - * TE_KILO_BIT / TE_BYTE); + iflp->default_bw = ((ifp->bandwidth ? ifp->bandwidth : DEFAULT_BANDWIDTH) + * TE_KILO_BIT / TE_BYTE); /* Set Max, Reservable and Unreserved Bandwidth */ - iflp->max_bw = bw; - iflp->max_rsv_bw = bw; + iflp->max_bw = iflp->default_bw; + iflp->max_rsv_bw = iflp->default_bw; for (i = 0; i < MAX_CLASS_TYPE; i++) - iflp->unrsv_bw[i] = bw; + iflp->unrsv_bw[i] = iflp->default_bw; /* Update Link parameters status */ iflp->lp_status = LP_TE | LP_MAX_BW | LP_MAX_RSV_BW | LP_UNRSV_BW; diff --git a/lib/if.h b/lib/if.h index 7fdd46d3f2..59141e7871 100644 --- a/lib/if.h +++ b/lib/if.h @@ -161,6 +161,7 @@ struct if_stats #define LP_RES_BW 0x0400 #define LP_AVA_BW 0x0800 #define LP_USE_BW 0x1000 +#define LP_TE_METRIC 0x2000 #define IS_PARAM_UNSET(lp, st) !(lp->lp_status & st) #define IS_PARAM_SET(lp, st) (lp->lp_status & st) @@ -174,6 +175,7 @@ struct if_stats struct if_link_params { u_int32_t lp_status; /* Status of Link Parameters: */ u_int32_t te_metric; /* Traffic Engineering metric */ + float default_bw; float max_bw; /* Maximum Bandwidth */ float max_rsv_bw; /* Maximum Reservable Bandwidth */ float unrsv_bw[MAX_CLASS_TYPE]; /* Unreserved Bandwidth per Class Type (8) */ diff --git a/zebra/interface.c b/zebra/interface.c index 68edd30de3..3fec663f12 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -1846,7 +1846,7 @@ DEFUN (link_params_metric, VTY_GET_ULONG("metric", metric, argv[0]); /* Update TE metric if needed */ - link_param_cmd_set_uint32 (ifp, &iflp->te_metric, LP_TE, metric); + link_param_cmd_set_uint32 (ifp, &iflp->te_metric, LP_TE | LP_TE_METRIC, metric); return CMD_SUCCESS; } @@ -1860,7 +1860,7 @@ DEFUN (no_link_params_metric, VTY_DECLVAR_CONTEXT (interface, ifp); /* Unset TE Metric */ - link_param_cmd_unset(ifp, LP_TE); + link_param_cmd_unset(ifp, LP_TE | LP_TE_METRIC); return CMD_SUCCESS; } @@ -2788,20 +2788,21 @@ link_params_config_write (struct vty *vty, struct interface *ifp) vty_out (vty, " link-params%s", VTY_NEWLINE); vty_out(vty, " enable%s", VTY_NEWLINE); - if (IS_PARAM_SET(iflp, LP_TE)) + if (IS_PARAM_SET(iflp, LP_TE) && IS_PARAM_SET(iflp, LP_TE_METRIC)) vty_out(vty, " metric %u%s",iflp->te_metric, VTY_NEWLINE); - if (IS_PARAM_SET(iflp, LP_MAX_BW)) + if (IS_PARAM_SET(iflp, LP_MAX_BW) && iflp->max_bw != iflp->default_bw) vty_out(vty, " max-bw %g%s", iflp->max_bw, VTY_NEWLINE); - if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW)) + if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW) && iflp->max_rsv_bw != iflp->default_bw) vty_out(vty, " max-rsv-bw %g%s", iflp->max_rsv_bw, VTY_NEWLINE); if (IS_PARAM_SET(iflp, LP_UNRSV_BW)) { for (i = 0; i < 8; i++) - vty_out(vty, " unrsv-bw %d %g%s", - i, iflp->unrsv_bw[i], VTY_NEWLINE); + if (iflp->unrsv_bw[i] != iflp->default_bw) + vty_out(vty, " unrsv-bw %d %g%s", + i, iflp->unrsv_bw[i], VTY_NEWLINE); } if (IS_PARAM_SET(iflp, LP_ADM_GRP)) - vty_out(vty, " admin-grp %u%s", iflp->admin_grp, VTY_NEWLINE); + vty_out(vty, " admin-grp 0x%x%s", iflp->admin_grp, VTY_NEWLINE); if (IS_PARAM_SET(iflp, LP_DELAY)) { vty_out(vty, " delay %u", iflp->av_delay); From 242ab042559570cdacc9a577445c8497142fd624 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Mon, 5 Dec 2016 16:34:15 +0100 Subject: [PATCH 40/44] lib: remove unused NS_BITMAP MTYPE Signed-off-by: David Lamparter --- lib/ns.c | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/ns.c b/lib/ns.c index 08432764db..e6d6a9f9a8 100644 --- a/lib/ns.c +++ b/lib/ns.c @@ -39,7 +39,6 @@ DEFINE_MTYPE_STATIC(LIB, NS, "Logical-Router") DEFINE_MTYPE_STATIC(LIB, NS_NAME, "Logical-Router Name") -DEFINE_MTYPE_STATIC(LIB, NS_BITMAP, "Logical-Router bit-map") static __inline int ns_compare (struct ns *, struct ns *); static struct ns *ns_lookup (ns_id_t); From 8793176b5a180bff8e637ce7cba6005f880e8915 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Mon, 5 Dec 2016 19:08:00 +0100 Subject: [PATCH 41/44] build: number sections in COMMUNITY.md HTML adds some CSS to get section numbers. Signed-off-by: David Lamparter --- render_md.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/render_md.py b/render_md.py index d2d1fb4805..16c4bbe8a3 100644 --- a/render_md.py +++ b/render_md.py @@ -4,11 +4,14 @@ import sys, markdown template = '''