]> git.proxmox.com Git - mirror_frr.git/blame - ripngd/ripng_peer.c
Merge pull request #13649 from donaldsharp/unlock_the_node_or_else
[mirror_frr.git] / ripngd / ripng_peer.c
CommitLineData
acddc0ed 1// SPDX-License-Identifier: GPL-2.0-or-later
a94434b6 2/* RIPng peer support
3 * Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
a94434b6 4 */
5
6/* RIPng support added by Vincent Jardin <vincent.jardin@6wind.com>
7 * Copyright (C) 2002 6WIND
8 */
9
10#include <zebra.h>
11
12#include "if.h"
13#include "prefix.h"
14#include "command.h"
15#include "linklist.h"
24a58196 16#include "frrevent.h"
a94434b6 17#include "memory.h"
18
19#include "ripngd/ripngd.h"
20#include "ripngd/ripng_nexthop.h"
21
bf8d3d6a 22DEFINE_MTYPE_STATIC(RIPNGD, RIPNG_PEER, "RIPng peer");
b3a7e30d 23
d62a17ae 24static struct ripng_peer *ripng_peer_new(void)
a94434b6 25{
d62a17ae 26 return XCALLOC(MTYPE_RIPNG_PEER, sizeof(struct ripng_peer));
a94434b6 27}
28
d62a17ae 29static void ripng_peer_free(struct ripng_peer *peer)
a94434b6 30{
e16d030c 31 EVENT_OFF(peer->t_timeout);
d62a17ae 32 XFREE(MTYPE_RIPNG_PEER, peer);
a94434b6 33}
34
5c84b9a5 35struct ripng_peer *ripng_peer_lookup(struct ripng *ripng, struct in6_addr *addr)
a94434b6 36{
d62a17ae 37 struct ripng_peer *peer;
38 struct listnode *node, *nnode;
39
ecece94c 40 for (ALL_LIST_ELEMENTS(ripng->peer_list, node, nnode, peer)) {
d62a17ae 41 if (IPV6_ADDR_SAME(&peer->addr, addr))
42 return peer;
43 }
44 return NULL;
a94434b6 45}
46
5c84b9a5
RW
47struct ripng_peer *ripng_peer_lookup_next(struct ripng *ripng,
48 struct in6_addr *addr)
a94434b6 49{
d62a17ae 50 struct ripng_peer *peer;
51 struct listnode *node, *nnode;
52
ecece94c 53 for (ALL_LIST_ELEMENTS(ripng->peer_list, node, nnode, peer)) {
d62a17ae 54 if (addr6_cmp(&peer->addr, addr) > 0)
55 return peer;
56 }
57 return NULL;
a94434b6 58}
59
60/* RIPng peer is timeout.
61 * Garbage collector.
62 **/
e6685141 63static void ripng_peer_timeout(struct event *t)
a94434b6 64{
d62a17ae 65 struct ripng_peer *peer;
a94434b6 66
e16d030c 67 peer = EVENT_ARG(t);
5c84b9a5 68 listnode_delete(peer->ripng->peer_list, peer);
d62a17ae 69 ripng_peer_free(peer);
a94434b6 70}
71
72/* Get RIPng peer. At the same time update timeout thread. */
5c84b9a5
RW
73static struct ripng_peer *ripng_peer_get(struct ripng *ripng,
74 struct in6_addr *addr)
a94434b6 75{
d62a17ae 76 struct ripng_peer *peer;
77
5c84b9a5 78 peer = ripng_peer_lookup(ripng, addr);
d62a17ae 79
80 if (peer) {
e16d030c 81 EVENT_OFF(peer->t_timeout);
d62a17ae 82 } else {
83 peer = ripng_peer_new();
5c84b9a5
RW
84 peer->ripng = ripng;
85 peer->addr = *addr;
ecece94c 86 listnode_add_sort(ripng->peer_list, peer);
d62a17ae 87 }
88
89 /* Update timeout thread. */
907a2395
DS
90 event_add_timer(master, ripng_peer_timeout, peer,
91 RIPNG_PEER_TIMER_DEFAULT, &peer->t_timeout);
d62a17ae 92
93 /* Last update time set. */
94 time(&peer->uptime);
95
96 return peer;
a94434b6 97}
98
5c84b9a5
RW
99void ripng_peer_update(struct ripng *ripng, struct sockaddr_in6 *from,
100 uint8_t version)
a94434b6 101{
d62a17ae 102 struct ripng_peer *peer;
5c84b9a5 103 peer = ripng_peer_get(ripng, &from->sin6_addr);
d62a17ae 104 peer->version = version;
a94434b6 105}
106
5c84b9a5 107void ripng_peer_bad_route(struct ripng *ripng, struct sockaddr_in6 *from)
a94434b6 108{
d62a17ae 109 struct ripng_peer *peer;
5c84b9a5 110 peer = ripng_peer_get(ripng, &from->sin6_addr);
d62a17ae 111 peer->recv_badroutes++;
a94434b6 112}
113
5c84b9a5 114void ripng_peer_bad_packet(struct ripng *ripng, struct sockaddr_in6 *from)
a94434b6 115{
d62a17ae 116 struct ripng_peer *peer;
5c84b9a5 117 peer = ripng_peer_get(ripng, &from->sin6_addr);
d62a17ae 118 peer->recv_badpackets++;
a94434b6 119}
120
121/* Display peer uptime. */
d62a17ae 122static char *ripng_peer_uptime(struct ripng_peer *peer, char *buf, size_t len)
a94434b6 123{
d62a17ae 124 time_t uptime;
d62a17ae 125
126 /* If there is no connection has been done before print `never'. */
127 if (peer->uptime == 0) {
128 snprintf(buf, len, "never ");
129 return buf;
130 }
131
132 /* Get current time. */
133 uptime = time(NULL);
134 uptime -= peer->uptime;
d0636ead
MS
135
136 frrtime_to_interval(uptime, buf, len);
137
d62a17ae 138 return buf;
a94434b6 139}
140
5c84b9a5 141void ripng_peer_display(struct vty *vty, struct ripng *ripng)
a94434b6 142{
d62a17ae 143 struct ripng_peer *peer;
144 struct listnode *node, *nnode;
a94434b6 145#define RIPNG_UPTIME_LEN 25
d62a17ae 146 char timebuf[RIPNG_UPTIME_LEN];
147
ecece94c 148 for (ALL_LIST_ELEMENTS(ripng->peer_list, node, nnode, peer)) {
2e5b3f37
MS
149 vty_out(vty, " %pI6 \n%14s %10d %10d %10d %s\n",
150 &peer->addr, " ", peer->recv_badpackets,
d62a17ae 151 peer->recv_badroutes, ZEBRA_RIPNG_DISTANCE_DEFAULT,
152 ripng_peer_uptime(peer, timebuf, RIPNG_UPTIME_LEN));
153 }
a94434b6 154}
155
ecece94c 156int ripng_peer_list_cmp(struct ripng_peer *p1, struct ripng_peer *p2)
a94434b6 157{
27fa3398 158 return memcmp(&p1->addr, &p2->addr, sizeof(struct in6_addr));
a94434b6 159}
56bf1cb2
RW
160
161void ripng_peer_list_del(void *arg)
162{
163 ripng_peer_free(arg);
164}