* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with GNU Zebra; see the file COPYING. If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* RIPng support added by Vincent Jardin <vincent.jardin@6wind.com>
#include "ripngd/ripngd.h"
#include "ripngd/ripng_nexthop.h"
-
-/* Linked list of RIPng peer. */
-struct list *peer_list;
+DEFINE_MTYPE_STATIC(RIPNGD, RIPNG_PEER, "RIPng peer")
static struct ripng_peer *ripng_peer_new(void)
{
static void ripng_peer_free(struct ripng_peer *peer)
{
+ RIPNG_TIMER_OFF(peer->t_timeout);
XFREE(MTYPE_RIPNG_PEER, peer);
}
-struct ripng_peer *ripng_peer_lookup(struct in6_addr *addr)
+struct ripng_peer *ripng_peer_lookup(struct ripng *ripng, struct in6_addr *addr)
{
struct ripng_peer *peer;
struct listnode *node, *nnode;
- for (ALL_LIST_ELEMENTS(peer_list, node, nnode, peer)) {
+ for (ALL_LIST_ELEMENTS(ripng->peer_list, node, nnode, peer)) {
if (IPV6_ADDR_SAME(&peer->addr, addr))
return peer;
}
return NULL;
}
-struct ripng_peer *ripng_peer_lookup_next(struct in6_addr *addr)
+struct ripng_peer *ripng_peer_lookup_next(struct ripng *ripng,
+ struct in6_addr *addr)
{
struct ripng_peer *peer;
struct listnode *node, *nnode;
- for (ALL_LIST_ELEMENTS(peer_list, node, nnode, peer)) {
+ for (ALL_LIST_ELEMENTS(ripng->peer_list, node, nnode, peer)) {
if (addr6_cmp(&peer->addr, addr) > 0)
return peer;
}
struct ripng_peer *peer;
peer = THREAD_ARG(t);
- listnode_delete(peer_list, peer);
+ listnode_delete(peer->ripng->peer_list, peer);
ripng_peer_free(peer);
return 0;
}
/* Get RIPng peer. At the same time update timeout thread. */
-static struct ripng_peer *ripng_peer_get(struct in6_addr *addr)
+static struct ripng_peer *ripng_peer_get(struct ripng *ripng,
+ struct in6_addr *addr)
{
struct ripng_peer *peer;
- peer = ripng_peer_lookup(addr);
+ peer = ripng_peer_lookup(ripng, addr);
if (peer) {
if (peer->t_timeout)
thread_cancel(peer->t_timeout);
} else {
peer = ripng_peer_new();
- peer->addr = *addr; /* XXX */
- listnode_add_sort(peer_list, peer);
+ peer->ripng = ripng;
+ peer->addr = *addr;
+ listnode_add_sort(ripng->peer_list, peer);
}
/* Update timeout thread. */
- peer->t_timeout = thread_add_timer(master, ripng_peer_timeout, peer,
- RIPNG_PEER_TIMER_DEFAULT);
+ peer->t_timeout = NULL;
+ thread_add_timer(master, ripng_peer_timeout, peer,
+ RIPNG_PEER_TIMER_DEFAULT, &peer->t_timeout);
/* Last update time set. */
time(&peer->uptime);
return peer;
}
-void ripng_peer_update(struct sockaddr_in6 *from, u_char version)
+void ripng_peer_update(struct ripng *ripng, struct sockaddr_in6 *from,
+ uint8_t version)
{
struct ripng_peer *peer;
- peer = ripng_peer_get(&from->sin6_addr);
+ peer = ripng_peer_get(ripng, &from->sin6_addr);
peer->version = version;
}
-void ripng_peer_bad_route(struct sockaddr_in6 *from)
+void ripng_peer_bad_route(struct ripng *ripng, struct sockaddr_in6 *from)
{
struct ripng_peer *peer;
- peer = ripng_peer_get(&from->sin6_addr);
+ peer = ripng_peer_get(ripng, &from->sin6_addr);
peer->recv_badroutes++;
}
-void ripng_peer_bad_packet(struct sockaddr_in6 *from)
+void ripng_peer_bad_packet(struct ripng *ripng, struct sockaddr_in6 *from)
{
struct ripng_peer *peer;
- peer = ripng_peer_get(&from->sin6_addr);
+ peer = ripng_peer_get(ripng, &from->sin6_addr);
peer->recv_badpackets++;
}
uptime -= peer->uptime;
tm = gmtime(&uptime);
-/* Making formatted timer strings. */
-#define ONE_DAY_SECOND 60*60*24
-#define ONE_WEEK_SECOND 60*60*24*7
-
if (uptime < ONE_DAY_SECOND)
snprintf(buf, len, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min,
tm->tm_sec);
return buf;
}
-void ripng_peer_display(struct vty *vty)
+void ripng_peer_display(struct vty *vty, struct ripng *ripng)
{
struct ripng_peer *peer;
struct listnode *node, *nnode;
#define RIPNG_UPTIME_LEN 25
char timebuf[RIPNG_UPTIME_LEN];
- for (ALL_LIST_ELEMENTS(peer_list, node, nnode, peer)) {
- vty_out(vty, " %s %s%14s %10d %10d %10d %s%s",
- inet6_ntoa(peer->addr), VTY_NEWLINE, " ",
- peer->recv_badpackets, peer->recv_badroutes,
- ZEBRA_RIPNG_DISTANCE_DEFAULT,
- ripng_peer_uptime(peer, timebuf, RIPNG_UPTIME_LEN),
- VTY_NEWLINE);
+ for (ALL_LIST_ELEMENTS(ripng->peer_list, node, nnode, peer)) {
+ vty_out(vty, " %s \n%14s %10d %10d %10d %s\n",
+ inet6_ntoa(peer->addr), " ", peer->recv_badpackets,
+ peer->recv_badroutes, ZEBRA_RIPNG_DISTANCE_DEFAULT,
+ ripng_peer_uptime(peer, timebuf, RIPNG_UPTIME_LEN));
}
}
-static int ripng_peer_list_cmp(struct ripng_peer *p1, struct ripng_peer *p2)
+int ripng_peer_list_cmp(struct ripng_peer *p1, struct ripng_peer *p2)
{
- return addr6_cmp(&p1->addr, &p2->addr) > 0;
+ return memcmp(&p1->addr, &p2->addr, sizeof(struct in6_addr));
}
-void ripng_peer_init()
+void ripng_peer_list_del(void *arg)
{
- peer_list = list_new();
- peer_list->cmp = (int (*)(void *, void *))ripng_peer_list_cmp;
+ ripng_peer_free(arg);
}