]>
git.proxmox.com Git - mirror_frr.git/blob - isisd/isis_tx_queue.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * IS-IS Rout(e)ing protocol - LSP TX Queuing logic
5 * Copyright (C) 2018 Christian Franke
7 * This file is part of FRRouting (FRR)
14 #include "isisd/isisd.h"
15 #include "isisd/isis_flags.h"
16 #include "isisd/isis_circuit.h"
17 #include "isisd/isis_lsp.h"
18 #include "isisd/isis_misc.h"
19 #include "isisd/isis_tx_queue.h"
21 DEFINE_MTYPE_STATIC(ISISD
, TX_QUEUE
, "ISIS TX Queue");
22 DEFINE_MTYPE_STATIC(ISISD
, TX_QUEUE_ENTRY
, "ISIS TX Queue Entry");
24 struct isis_tx_queue
{
25 struct isis_circuit
*circuit
;
26 void (*send_event
)(struct isis_circuit
*circuit
,
27 struct isis_lsp
*, enum isis_tx_type
);
31 struct isis_tx_queue_entry
{
33 enum isis_tx_type type
;
36 struct isis_tx_queue
*queue
;
39 static unsigned tx_queue_hash_key(const void *p
)
41 const struct isis_tx_queue_entry
*e
= p
;
43 uint32_t id_key
= jhash(e
->lsp
->hdr
.lsp_id
,
44 ISIS_SYS_ID_LEN
+ 2, 0x55aa5a5a);
46 return jhash_1word(e
->lsp
->level
, id_key
);
49 static bool tx_queue_hash_cmp(const void *a
, const void *b
)
51 const struct isis_tx_queue_entry
*ea
= a
, *eb
= b
;
53 if (ea
->lsp
->level
!= eb
->lsp
->level
)
56 if (memcmp(ea
->lsp
->hdr
.lsp_id
, eb
->lsp
->hdr
.lsp_id
,
63 struct isis_tx_queue
*isis_tx_queue_new(
64 struct isis_circuit
*circuit
,
65 void(*send_event
)(struct isis_circuit
*circuit
,
69 struct isis_tx_queue
*rv
= XCALLOC(MTYPE_TX_QUEUE
, sizeof(*rv
));
71 rv
->circuit
= circuit
;
72 rv
->send_event
= send_event
;
74 rv
->hash
= hash_create(tx_queue_hash_key
, tx_queue_hash_cmp
, NULL
);
78 static void tx_queue_element_free(void *element
)
80 struct isis_tx_queue_entry
*e
= element
;
84 XFREE(MTYPE_TX_QUEUE_ENTRY
, e
);
87 void isis_tx_queue_free(struct isis_tx_queue
*queue
)
89 hash_clean_and_free(&queue
->hash
, tx_queue_element_free
);
90 XFREE(MTYPE_TX_QUEUE
, queue
);
93 static struct isis_tx_queue_entry
*tx_queue_find(struct isis_tx_queue
*queue
,
96 struct isis_tx_queue_entry e
= {
100 return hash_lookup(queue
->hash
, &e
);
103 static void tx_queue_send_event(struct event
*thread
)
105 struct isis_tx_queue_entry
*e
= EVENT_ARG(thread
);
106 struct isis_tx_queue
*queue
= e
->queue
;
108 event_add_timer(master
, tx_queue_send_event
, e
, 5, &e
->retry
);
111 queue
->circuit
->area
->lsp_rxmt_count
++;
115 queue
->send_event(queue
->circuit
, e
->lsp
, e
->type
);
116 /* Don't access e here anymore, send_event might have destroyed it */
119 void _isis_tx_queue_add(struct isis_tx_queue
*queue
,
120 struct isis_lsp
*lsp
,
121 enum isis_tx_type type
,
122 const char *func
, const char *file
,
128 if (IS_DEBUG_TX_QUEUE
) {
130 "Add LSP %pLS to %s queue as %s LSP. (From %s %s:%d)",
131 lsp
->hdr
.lsp_id
, queue
->circuit
->interface
->name
,
132 (type
== TX_LSP_CIRCUIT_SCOPED
) ? "circuit scoped"
137 struct isis_tx_queue_entry
*e
= tx_queue_find(queue
, lsp
);
139 e
= XCALLOC(MTYPE_TX_QUEUE_ENTRY
, sizeof(*e
));
143 struct isis_tx_queue_entry
*inserted
;
144 inserted
= hash_get(queue
->hash
, e
, hash_alloc_intern
);
145 assert(inserted
== e
);
151 event_add_event(master
, tx_queue_send_event
, e
, 0, &e
->retry
);
156 void _isis_tx_queue_del(struct isis_tx_queue
*queue
, struct isis_lsp
*lsp
,
157 const char *func
, const char *file
, int line
)
162 struct isis_tx_queue_entry
*e
= tx_queue_find(queue
, lsp
);
166 if (IS_DEBUG_TX_QUEUE
) {
167 zlog_debug("Remove LSP %pLS from %s queue. (From %s %s:%d)",
168 lsp
->hdr
.lsp_id
, queue
->circuit
->interface
->name
,
174 hash_release(queue
->hash
, e
);
175 XFREE(MTYPE_TX_QUEUE_ENTRY
, e
);
178 unsigned long isis_tx_queue_len(struct isis_tx_queue
*queue
)
183 return hashcount(queue
->hash
);
186 void isis_tx_queue_clean(struct isis_tx_queue
*queue
)
188 hash_clean(queue
->hash
, tx_queue_element_free
);