]>
git.proxmox.com Git - mirror_frr.git/blob - isisd/isis_tx_queue.c
2 * IS-IS Rout(e)ing protocol - LSP TX Queuing logic
4 * Copyright (C) 2018 Christian Franke
6 * This file is part of FreeRangeRouting (FRR)
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
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.
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
27 #include "isisd/isisd.h"
28 #include "isisd/isis_memory.h"
29 #include "isisd/isis_flags.h"
31 #include "isisd/isis_circuit.h"
32 #include "isisd/isis_lsp.h"
33 #include "isisd/isis_tx_queue.h"
35 DEFINE_MTYPE_STATIC(ISISD
, TX_QUEUE
, "ISIS TX Queue")
36 DEFINE_MTYPE_STATIC(ISISD
, TX_QUEUE_ENTRY
, "ISIS TX Queue Entry")
38 struct isis_tx_queue
{
40 void (*send_event
)(void *arg
, struct isis_lsp
*, enum isis_tx_type
);
44 struct isis_tx_queue_entry
{
46 enum isis_tx_type type
;
48 struct isis_tx_queue
*queue
;
51 static unsigned tx_queue_hash_key(void *p
)
53 struct isis_tx_queue_entry
*e
= p
;
55 uint32_t id_key
= jhash(e
->lsp
->hdr
.lsp_id
,
56 ISIS_SYS_ID_LEN
+ 2, 0x55aa5a5a);
58 return jhash_1word(e
->lsp
->level
, id_key
);
61 static bool tx_queue_hash_cmp(const void *a
, const void *b
)
63 const struct isis_tx_queue_entry
*ea
= a
, *eb
= b
;
65 if (ea
->lsp
->level
!= eb
->lsp
->level
)
68 if (memcmp(ea
->lsp
->hdr
.lsp_id
, eb
->lsp
->hdr
.lsp_id
,
75 struct isis_tx_queue
*isis_tx_queue_new(void *arg
,
76 void(*send_event
)(void *arg
,
80 struct isis_tx_queue
*rv
= XCALLOC(MTYPE_TX_QUEUE
, sizeof(*rv
));
83 rv
->send_event
= send_event
;
85 rv
->hash
= hash_create(tx_queue_hash_key
, tx_queue_hash_cmp
, NULL
);
89 static void tx_queue_element_free(void *element
)
91 struct isis_tx_queue_entry
*e
= element
;
94 thread_cancel(e
->retry
);
96 XFREE(MTYPE_TX_QUEUE_ENTRY
, e
);
99 void isis_tx_queue_free(struct isis_tx_queue
*queue
)
101 hash_clean(queue
->hash
, tx_queue_element_free
);
102 hash_free(queue
->hash
);
103 XFREE(MTYPE_TX_QUEUE
, queue
);
106 static struct isis_tx_queue_entry
*tx_queue_find(struct isis_tx_queue
*queue
,
107 struct isis_lsp
*lsp
)
109 struct isis_tx_queue_entry e
= {
113 return hash_lookup(queue
->hash
, &e
);
116 static int tx_queue_send_event(struct thread
*thread
)
118 struct isis_tx_queue_entry
*e
= THREAD_ARG(thread
);
119 struct isis_tx_queue
*queue
= e
->queue
;
122 thread_add_timer(master
, tx_queue_send_event
, e
, 5, &e
->retry
);
124 queue
->send_event(queue
->arg
, e
->lsp
, e
->type
);
125 /* Don't access e here anymore, send_event might have destroyed it */
130 void isis_tx_queue_add(struct isis_tx_queue
*queue
,
131 struct isis_lsp
*lsp
,
132 enum isis_tx_type type
)
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 thread_cancel(e
->retry
);
152 thread_add_event(master
, tx_queue_send_event
, e
, 0, &e
->retry
);
155 void isis_tx_queue_del(struct isis_tx_queue
*queue
, struct isis_lsp
*lsp
)
160 struct isis_tx_queue_entry
*e
= tx_queue_find(queue
, lsp
);
165 thread_cancel(e
->retry
);
167 hash_release(queue
->hash
, e
);
168 XFREE(MTYPE_TX_QUEUE_ENTRY
, e
);
171 unsigned long isis_tx_queue_len(struct isis_tx_queue
*queue
)
176 return hashcount(queue
->hash
);
179 void isis_tx_queue_clean(struct isis_tx_queue
*queue
)
181 hash_clean(queue
->hash
, tx_queue_element_free
);