]> git.proxmox.com Git - mirror_frr.git/blame - ripd/rip_peer.c
zebra: Fix build error when `--disable-bfdd`
[mirror_frr.git] / ripd / rip_peer.c
CommitLineData
acddc0ed 1// SPDX-License-Identifier: GPL-2.0-or-later
718e3744 2/* RIP peer support
3 * Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
718e3744 4 */
5
6#include <zebra.h>
7
8#include "if.h"
9#include "prefix.h"
10#include "command.h"
11#include "linklist.h"
24a58196 12#include "frrevent.h"
718e3744 13#include "memory.h"
c262df82 14#include "table.h"
718e3744 15
16#include "ripd/ripd.h"
c262df82 17#include "ripd/rip_bfd.h"
718e3744 18
bf8d3d6a 19DEFINE_MTYPE_STATIC(RIPD, RIP_PEER, "RIP peer");
814a2585 20
d62a17ae 21static struct rip_peer *rip_peer_new(void)
718e3744 22{
d62a17ae 23 return XCALLOC(MTYPE_RIP_PEER, sizeof(struct rip_peer));
718e3744 24}
25
c262df82 26void rip_peer_free(struct rip_peer *peer)
718e3744 27{
c262df82 28 bfd_sess_free(&peer->bfd_session);
e16d030c 29 EVENT_OFF(peer->t_timeout);
d62a17ae 30 XFREE(MTYPE_RIP_PEER, peer);
718e3744 31}
32
045c5389 33struct rip_peer *rip_peer_lookup(struct rip *rip, struct in_addr *addr)
718e3744 34{
d62a17ae 35 struct rip_peer *peer;
36 struct listnode *node, *nnode;
37
29e897ad 38 for (ALL_LIST_ELEMENTS(rip->peer_list, node, nnode, peer)) {
d62a17ae 39 if (IPV4_ADDR_SAME(&peer->addr, addr))
40 return peer;
41 }
42 return NULL;
718e3744 43}
44
045c5389 45struct rip_peer *rip_peer_lookup_next(struct rip *rip, struct in_addr *addr)
718e3744 46{
d62a17ae 47 struct rip_peer *peer;
48 struct listnode *node, *nnode;
49
29e897ad 50 for (ALL_LIST_ELEMENTS(rip->peer_list, node, nnode, peer)) {
d62a17ae 51 if (htonl(peer->addr.s_addr) > htonl(addr->s_addr))
52 return peer;
53 }
54 return NULL;
718e3744 55}
56
57/* RIP peer is timeout. */
e6685141 58static void rip_peer_timeout(struct event *t)
718e3744 59{
d62a17ae 60 struct rip_peer *peer;
718e3744 61
e16d030c 62 peer = EVENT_ARG(t);
045c5389 63 listnode_delete(peer->rip->peer_list, peer);
d62a17ae 64 rip_peer_free(peer);
718e3744 65}
66
67/* Get RIP peer. At the same time update timeout thread. */
c262df82
RW
68static struct rip_peer *rip_peer_get(struct rip *rip, struct rip_interface *ri,
69 struct in_addr *addr)
718e3744 70{
d62a17ae 71 struct rip_peer *peer;
72
045c5389 73 peer = rip_peer_lookup(rip, addr);
d62a17ae 74
75 if (peer) {
e16d030c 76 EVENT_OFF(peer->t_timeout);
d62a17ae 77 } else {
78 peer = rip_peer_new();
045c5389 79 peer->rip = rip;
c262df82 80 peer->ri = ri;
d62a17ae 81 peer->addr = *addr;
c262df82 82 rip_bfd_session_update(peer);
29e897ad 83 listnode_add_sort(rip->peer_list, peer);
d62a17ae 84 }
85
86 /* Update timeout thread. */
907a2395
DS
87 event_add_timer(master, rip_peer_timeout, peer, RIP_PEER_TIMER_DEFAULT,
88 &peer->t_timeout);
d62a17ae 89
90 /* Last update time set. */
91 time(&peer->uptime);
92
93 return peer;
718e3744 94}
95
c262df82
RW
96void rip_peer_update(struct rip *rip, struct rip_interface *ri,
97 struct sockaddr_in *from, uint8_t version)
718e3744 98{
d62a17ae 99 struct rip_peer *peer;
c262df82 100 peer = rip_peer_get(rip, ri, &from->sin_addr);
d62a17ae 101 peer->version = version;
718e3744 102}
103
c262df82
RW
104void rip_peer_bad_route(struct rip *rip, struct rip_interface *ri,
105 struct sockaddr_in *from)
718e3744 106{
d62a17ae 107 struct rip_peer *peer;
c262df82 108 peer = rip_peer_get(rip, ri, &from->sin_addr);
d62a17ae 109 peer->recv_badroutes++;
718e3744 110}
111
c262df82
RW
112void rip_peer_bad_packet(struct rip *rip, struct rip_interface *ri,
113 struct sockaddr_in *from)
718e3744 114{
d62a17ae 115 struct rip_peer *peer;
c262df82 116 peer = rip_peer_get(rip, ri, &from->sin_addr);
d62a17ae 117 peer->recv_badpackets++;
718e3744 118}
119
120/* Display peer uptime. */
d62a17ae 121static char *rip_peer_uptime(struct rip_peer *peer, char *buf, size_t len)
718e3744 122{
d62a17ae 123 time_t uptime;
d62a17ae 124
125 /* If there is no connection has been done before print `never'. */
126 if (peer->uptime == 0) {
127 snprintf(buf, len, "never ");
128 return buf;
129 }
130
131 /* Get current time. */
132 uptime = time(NULL);
133 uptime -= peer->uptime;
d0636ead
MS
134
135 frrtime_to_interval(uptime, buf, len);
136
d62a17ae 137 return buf;
718e3744 138}
139
045c5389 140void rip_peer_display(struct vty *vty, struct rip *rip)
718e3744 141{
d62a17ae 142 struct rip_peer *peer;
143 struct listnode *node, *nnode;
718e3744 144#define RIP_UPTIME_LEN 25
d62a17ae 145 char timebuf[RIP_UPTIME_LEN];
146
29e897ad 147 for (ALL_LIST_ELEMENTS(rip->peer_list, node, nnode, peer)) {
36608f60 148 vty_out(vty, " %-17pI4 %9d %9d %9d %11s\n",
53bb7f9b 149 &peer->addr, peer->recv_badpackets,
d62a17ae 150 peer->recv_badroutes, ZEBRA_RIP_DISTANCE_DEFAULT,
151 rip_peer_uptime(peer, timebuf, RIP_UPTIME_LEN));
152 }
718e3744 153}
154
29e897ad 155int rip_peer_list_cmp(struct rip_peer *p1, struct rip_peer *p2)
718e3744 156{
27fa3398
DS
157 if (p2->addr.s_addr == p1->addr.s_addr)
158 return 0;
159
d17743d3 160 return (htonl(p1->addr.s_addr) < htonl(p2->addr.s_addr)) ? -1 : 1;
718e3744 161}
711915d2
RW
162
163void rip_peer_list_del(void *arg)
164{
165 rip_peer_free(arg);
166}
c262df82
RW
167
168void rip_peer_delete_routes(const struct rip_peer *peer)
169{
170 struct route_node *route_node;
171
172 for (route_node = route_top(peer->rip->table); route_node;
173 route_node = route_next(route_node)) {
174 struct rip_info *route_entry;
175 struct listnode *listnode;
176 struct listnode *listnode_next;
177 struct list *list;
178
179 list = route_node->info;
180 if (list == NULL)
181 continue;
182
183 for (ALL_LIST_ELEMENTS(list, listnode, listnode_next,
184 route_entry)) {
185 if (!rip_route_rte(route_entry))
186 continue;
187 if (route_entry->from.s_addr != peer->addr.s_addr)
188 continue;
189
190 if (listcount(list) == 1) {
191 EVENT_OFF(route_entry->t_timeout);
192 EVENT_OFF(route_entry->t_garbage_collect);
193 listnode_delete(list, route_entry);
194 if (list_isempty(list)) {
195 list_delete((struct list **)&route_node
196 ->info);
197 route_unlock_node(route_node);
198 }
199 rip_info_free(route_entry);
200
201 /* Signal the output process to trigger an
202 * update (see section 2.5). */
203 rip_event(peer->rip, RIP_TRIGGERED_UPDATE, 0);
204 } else
205 rip_ecmp_delete(peer->rip, route_entry);
206 break;
207 }
208 }
209}