]> git.proxmox.com Git - mirror_frr.git/blame - babeld/source.c
Merge pull request #12760 from opensourcerouting/fix/switch_to_pr_for_commitlint
[mirror_frr.git] / babeld / source.c
CommitLineData
acddc0ed 1// SPDX-License-Identifier: MIT
ca10883e
DS
2/*
3Copyright (c) 2007, 2008 by Juliusz Chroboczek
ca10883e
DS
4*/
5
b45ac5f5
DL
6#ifdef HAVE_CONFIG_H
7#include "config.h"
8#endif
9
ca10883e
DS
10#include <stdlib.h>
11#include <stdio.h>
12#include <string.h>
13#include <sys/time.h>
14
15#include "babel_main.h"
16#include "babeld.h"
17#include "util.h"
18#include "source.h"
19#include "babel_interface.h"
20#include "route.h"
e33b116c 21#include "babel_errors.h"
ca10883e
DS
22
23struct source *srcs = NULL;
24
25struct source*
26find_source(const unsigned char *id, const unsigned char *p, unsigned char plen,
27 int create, unsigned short seqno)
28{
29 struct source *src;
30
31 for(src = srcs; src; src = src->next) {
32 /* This should really be a hash table. For now, check the
33 last byte first. */
34 if(src->id[7] != id[7])
35 continue;
36 if(memcmp(src->id, id, 8) != 0)
37 continue;
38 if(src->plen != plen)
39 continue;
40 if(memcmp(src->prefix, p, 16) == 0)
41 return src;
42 }
43
44 if(!create)
45 return NULL;
46
47 src = malloc(sizeof(struct source));
48 if(src == NULL) {
5b003f31 49 flog_err(EC_BABEL_MEMORY, "malloc(source): %s", safe_strerror(errno));
ca10883e
DS
50 return NULL;
51 }
52
53 memcpy(src->id, id, 8);
54 memcpy(src->prefix, p, 16);
55 src->plen = plen;
56 src->seqno = seqno;
57 src->metric = INFINITY;
58 src->time = babel_now.tv_sec;
59 src->route_count = 0;
60 src->next = srcs;
61 srcs = src;
62 return src;
63}
64
65struct source *
66retain_source(struct source *src)
67{
68 assert(src->route_count < 0xffff);
69 src->route_count++;
70 return src;
71}
72
73void
74release_source(struct source *src)
75{
76 assert(src->route_count > 0);
77 src->route_count--;
78}
79
80int
81flush_source(struct source *src)
82{
83 if(src->route_count > 0)
84 /* The source is in use by a route. */
85 return 0;
86
87 if(srcs == src) {
88 srcs = src->next;
89 } else {
90 struct source *previous = srcs;
91 while(previous->next != src)
92 previous = previous->next;
93 previous->next = src->next;
94 }
95
96 free(src);
97 return 1;
98}
99
100void
101update_source(struct source *src,
102 unsigned short seqno, unsigned short metric)
103{
104 if(metric >= INFINITY)
105 return;
106
107 /* If a source is expired, pretend that it doesn't exist and update
108 it unconditionally. This makes ensures that old data will
109 eventually be overridden, and prevents us from getting stuck if
110 a router loses its sequence number. */
111 if(src->time < babel_now.tv_sec - SOURCE_GC_TIME ||
112 seqno_compare(src->seqno, seqno) < 0 ||
113 (src->seqno == seqno && src->metric > metric)) {
114 src->seqno = seqno;
115 src->metric = metric;
116 }
117 src->time = babel_now.tv_sec;
118}
119
120void
4d762f26 121expire_sources(void)
ca10883e
DS
122{
123 struct source *src;
124
125 src = srcs;
126 while(src) {
127 if(src->time > babel_now.tv_sec)
128 /* clock stepped */
129 src->time = babel_now.tv_sec;
130 if(src->time < babel_now.tv_sec - SOURCE_GC_TIME) {
131 struct source *old = src;
132 src = src->next;
133 flush_source(old);
134 continue;
135 }
136 src = src->next;
137 }
138}
139
140void
141check_sources_released(void)
142{
143 struct source *src;
144
145 for(src = srcs; src; src = src->next) {
146 if(src->route_count != 0)
147 fprintf(stderr, "Warning: source %s %s has refcount %d.\n",
148 format_eui64(src->id),
149 format_prefix(src->prefix, src->plen),
150 (int)src->route_count);
151 }
152}