]> git.proxmox.com Git - mirror_frr.git/blame - isisd/isis_tx_queue.c
Merge pull request #9438 from ranjanyash54/debug_comm
[mirror_frr.git] / isisd / isis_tx_queue.c
CommitLineData
9b39405f
CF
1/*
2 * IS-IS Rout(e)ing protocol - LSP TX Queuing logic
3 *
4 * Copyright (C) 2018 Christian Franke
5 *
8678d638 6 * This file is part of FRRouting (FRR)
9b39405f
CF
7 *
8 * FRR is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2, or (at your option) any
11 * later version.
12 *
13 * FRR is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; see the file COPYING; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22#include <zebra.h>
23
24#include "hash.h"
25#include "jhash.h"
26
27#include "isisd/isisd.h"
9b39405f 28#include "isisd/isis_flags.h"
9b39405f
CF
29#include "isisd/isis_circuit.h"
30#include "isisd/isis_lsp.h"
161fa356 31#include "isisd/isis_misc.h"
9b39405f
CF
32#include "isisd/isis_tx_queue.h"
33
bf8d3d6a
DL
34DEFINE_MTYPE_STATIC(ISISD, TX_QUEUE, "ISIS TX Queue");
35DEFINE_MTYPE_STATIC(ISISD, TX_QUEUE_ENTRY, "ISIS TX Queue Entry");
9b39405f
CF
36
37struct isis_tx_queue {
161fa356
CF
38 struct isis_circuit *circuit;
39 void (*send_event)(struct isis_circuit *circuit,
40 struct isis_lsp *, enum isis_tx_type);
9b39405f
CF
41 struct hash *hash;
42};
43
44struct isis_tx_queue_entry {
45 struct isis_lsp *lsp;
46 enum isis_tx_type type;
86d6f80d 47 bool is_retry;
9b39405f
CF
48 struct thread *retry;
49 struct isis_tx_queue *queue;
50};
51
d8b87afe 52static unsigned tx_queue_hash_key(const void *p)
9b39405f 53{
d8b87afe 54 const struct isis_tx_queue_entry *e = p;
9b39405f
CF
55
56 uint32_t id_key = jhash(e->lsp->hdr.lsp_id,
57 ISIS_SYS_ID_LEN + 2, 0x55aa5a5a);
58
59 return jhash_1word(e->lsp->level, id_key);
60}
61
74df8d6d 62static bool tx_queue_hash_cmp(const void *a, const void *b)
9b39405f
CF
63{
64 const struct isis_tx_queue_entry *ea = a, *eb = b;
65
66 if (ea->lsp->level != eb->lsp->level)
74df8d6d 67 return false;
9b39405f
CF
68
69 if (memcmp(ea->lsp->hdr.lsp_id, eb->lsp->hdr.lsp_id,
70 ISIS_SYS_ID_LEN + 2))
74df8d6d 71 return false;
9b39405f 72
74df8d6d 73 return true;
9b39405f
CF
74}
75
161fa356
CF
76struct isis_tx_queue *isis_tx_queue_new(
77 struct isis_circuit *circuit,
78 void(*send_event)(struct isis_circuit *circuit,
79 struct isis_lsp *,
80 enum isis_tx_type))
9b39405f
CF
81{
82 struct isis_tx_queue *rv = XCALLOC(MTYPE_TX_QUEUE, sizeof(*rv));
83
161fa356 84 rv->circuit = circuit;
9b39405f
CF
85 rv->send_event = send_event;
86
87 rv->hash = hash_create(tx_queue_hash_key, tx_queue_hash_cmp, NULL);
88 return rv;
89}
90
91static void tx_queue_element_free(void *element)
92{
93 struct isis_tx_queue_entry *e = element;
94
b3d6bc6e 95 thread_cancel(&(e->retry));
9b39405f
CF
96
97 XFREE(MTYPE_TX_QUEUE_ENTRY, e);
98}
99
100void isis_tx_queue_free(struct isis_tx_queue *queue)
101{
102 hash_clean(queue->hash, tx_queue_element_free);
103 hash_free(queue->hash);
104 XFREE(MTYPE_TX_QUEUE, queue);
105}
106
107static struct isis_tx_queue_entry *tx_queue_find(struct isis_tx_queue *queue,
108 struct isis_lsp *lsp)
109{
110 struct isis_tx_queue_entry e = {
111 .lsp = lsp
112 };
113
114 return hash_lookup(queue->hash, &e);
115}
116
117static int tx_queue_send_event(struct thread *thread)
118{
119 struct isis_tx_queue_entry *e = THREAD_ARG(thread);
120 struct isis_tx_queue *queue = e->queue;
121
122 e->retry = NULL;
123 thread_add_timer(master, tx_queue_send_event, e, 5, &e->retry);
124
89cdc4df 125 if (e->is_retry)
86d6f80d 126 queue->circuit->area->lsp_rxmt_count++;
89cdc4df 127 else
86d6f80d 128 e->is_retry = true;
89cdc4df 129
161fa356 130 queue->send_event(queue->circuit, e->lsp, e->type);
9b39405f
CF
131 /* Don't access e here anymore, send_event might have destroyed it */
132
133 return 0;
134}
135
161fa356
CF
136void _isis_tx_queue_add(struct isis_tx_queue *queue,
137 struct isis_lsp *lsp,
138 enum isis_tx_type type,
139 const char *func, const char *file,
140 int line)
9b39405f
CF
141{
142 if (!queue)
143 return;
144
e740f9c1 145 if (IS_DEBUG_TX_QUEUE) {
161fa356
CF
146 zlog_debug("Add LSP %s to %s queue as %s LSP. (From %s %s:%d)",
147 rawlspid_print(lsp->hdr.lsp_id),
148 queue->circuit->interface->name,
149 (type == TX_LSP_CIRCUIT_SCOPED) ?
150 "circuit scoped" : "regular",
151 func, file, line);
152 }
153
9b39405f
CF
154 struct isis_tx_queue_entry *e = tx_queue_find(queue, lsp);
155 if (!e) {
156 e = XCALLOC(MTYPE_TX_QUEUE_ENTRY, sizeof(*e));
157 e->lsp = lsp;
158 e->queue = queue;
159
160 struct isis_tx_queue_entry *inserted;
161 inserted = hash_get(queue->hash, e, hash_alloc_intern);
162 assert(inserted == e);
163 }
164
165 e->type = type;
166
b3d6bc6e 167 thread_cancel(&(e->retry));
9b39405f 168 thread_add_event(master, tx_queue_send_event, e, 0, &e->retry);
86d6f80d
CF
169
170 e->is_retry = false;
9b39405f
CF
171}
172
161fa356
CF
173void _isis_tx_queue_del(struct isis_tx_queue *queue, struct isis_lsp *lsp,
174 const char *func, const char *file, int line)
9b39405f
CF
175{
176 if (!queue)
177 return;
178
179 struct isis_tx_queue_entry *e = tx_queue_find(queue, lsp);
180 if (!e)
181 return;
182
e740f9c1 183 if (IS_DEBUG_TX_QUEUE) {
161fa356
CF
184 zlog_debug("Remove LSP %s from %s queue. (From %s %s:%d)",
185 rawlspid_print(lsp->hdr.lsp_id),
186 queue->circuit->interface->name,
187 func, file, line);
188 }
189
b3d6bc6e 190 thread_cancel(&(e->retry));
9b39405f
CF
191
192 hash_release(queue->hash, e);
193 XFREE(MTYPE_TX_QUEUE_ENTRY, e);
194}
195
196unsigned long isis_tx_queue_len(struct isis_tx_queue *queue)
197{
198 if (!queue)
199 return 0;
200
201 return hashcount(queue->hash);
202}
203
204void isis_tx_queue_clean(struct isis_tx_queue *queue)
205{
206 hash_clean(queue->hash, tx_queue_element_free);
207}