mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-04 10:09:25 +00:00
ospf6d: add tx fifo infrastructure
Add per interface fifo and per instance write list as a precursor to implementing fairer sharing of the ospf6 oscket resources. Signed-off-by: Pat Ruddy <pat@voltanet.io>
This commit is contained in:
parent
aa6a96ba78
commit
4f7bf1ab05
@ -185,6 +185,8 @@ struct ospf6_interface *ospf6_interface_create(struct interface *ifp)
|
||||
|
||||
oi = XCALLOC(MTYPE_OSPF6_IF, sizeof(struct ospf6_interface));
|
||||
|
||||
oi->obuf = ospf6_fifo_new();
|
||||
|
||||
oi->area = (struct ospf6_area *)NULL;
|
||||
oi->neighbor_list = list_new();
|
||||
oi->neighbor_list->cmp = ospf6_neighbor_cmp;
|
||||
@ -243,6 +245,8 @@ void ospf6_interface_delete(struct ospf6_interface *oi)
|
||||
|
||||
QOBJ_UNREG(oi);
|
||||
|
||||
ospf6_fifo_free(oi->obuf);
|
||||
|
||||
for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
|
||||
ospf6_neighbor_delete(on);
|
||||
|
||||
@ -888,6 +892,15 @@ int interface_down(struct thread *thread)
|
||||
ospf6_sso(oi->interface->ifindex, &allspfrouters6,
|
||||
IPV6_LEAVE_GROUP, ospf6->fd);
|
||||
|
||||
/* deal with write fifo */
|
||||
ospf6_fifo_flush(oi->obuf);
|
||||
if (oi->on_write_q) {
|
||||
listnode_delete(ospf6->oi_write_q, oi);
|
||||
if (list_isempty(ospf6->oi_write_q))
|
||||
thread_cancel(&ospf6->t_write);
|
||||
oi->on_write_q = 0;
|
||||
}
|
||||
|
||||
ospf6_interface_state_change(OSPF6_INTERFACE_DOWN, oi);
|
||||
|
||||
return 0;
|
||||
|
@ -56,6 +56,9 @@ struct ospf6_interface {
|
||||
/* I/F transmission delay */
|
||||
uint32_t transdelay;
|
||||
|
||||
/* Packet send buffer. */
|
||||
struct ospf6_fifo *obuf; /* Output queue */
|
||||
|
||||
/* Network Type */
|
||||
uint8_t type;
|
||||
bool type_cfg;
|
||||
@ -130,6 +133,8 @@ struct ospf6_interface {
|
||||
char *profile;
|
||||
} bfd_config;
|
||||
|
||||
int on_write_q;
|
||||
|
||||
/* Statistics Fields */
|
||||
uint32_t hello_in;
|
||||
uint32_t hello_out;
|
||||
|
@ -50,6 +50,8 @@
|
||||
#include <netinet/ip6.h>
|
||||
|
||||
DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_MESSAGE, "OSPF6 message");
|
||||
DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_PACKET, "OSPF6 packet");
|
||||
DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_FIFO, "OSPF6 FIFO queue");
|
||||
|
||||
unsigned char conf_debug_ospf6_message[6] = {0x03, 0, 0, 0, 0, 0};
|
||||
static const struct message ospf6_message_type_str[] = {
|
||||
@ -252,6 +254,95 @@ void ospf6_lsack_print(struct ospf6_header *oh, int action)
|
||||
}
|
||||
}
|
||||
|
||||
void ospf6_packet_free(struct ospf6_packet *op)
|
||||
{
|
||||
if (op->s)
|
||||
stream_free(op->s);
|
||||
|
||||
XFREE(MTYPE_OSPF6_PACKET, op);
|
||||
}
|
||||
|
||||
struct ospf6_fifo *ospf6_fifo_new(void)
|
||||
{
|
||||
struct ospf6_fifo *new;
|
||||
|
||||
new = XCALLOC(MTYPE_OSPF6_FIFO, sizeof(struct ospf6_fifo));
|
||||
return new;
|
||||
}
|
||||
|
||||
/* Add new packet to fifo. */
|
||||
void ospf6_fifo_push(struct ospf6_fifo *fifo, struct ospf6_packet *op)
|
||||
{
|
||||
if (fifo->tail)
|
||||
fifo->tail->next = op;
|
||||
else
|
||||
fifo->head = op;
|
||||
|
||||
fifo->tail = op;
|
||||
|
||||
fifo->count++;
|
||||
}
|
||||
|
||||
/* Add new packet to head of fifo. */
|
||||
void ospf6_fifo_push_head(struct ospf6_fifo *fifo, struct ospf6_packet *op)
|
||||
{
|
||||
op->next = fifo->head;
|
||||
|
||||
if (fifo->tail == NULL)
|
||||
fifo->tail = op;
|
||||
|
||||
fifo->head = op;
|
||||
|
||||
fifo->count++;
|
||||
}
|
||||
|
||||
/* Delete first packet from fifo. */
|
||||
struct ospf6_packet *ospf6_fifo_pop(struct ospf6_fifo *fifo)
|
||||
{
|
||||
struct ospf6_packet *op;
|
||||
|
||||
op = fifo->head;
|
||||
|
||||
if (op) {
|
||||
fifo->head = op->next;
|
||||
|
||||
if (fifo->head == NULL)
|
||||
fifo->tail = NULL;
|
||||
|
||||
fifo->count--;
|
||||
}
|
||||
|
||||
return op;
|
||||
}
|
||||
|
||||
/* Return first fifo entry. */
|
||||
struct ospf6_packet *ospf6_fifo_head(struct ospf6_fifo *fifo)
|
||||
{
|
||||
return fifo->head;
|
||||
}
|
||||
|
||||
/* Flush ospf packet fifo. */
|
||||
void ospf6_fifo_flush(struct ospf6_fifo *fifo)
|
||||
{
|
||||
struct ospf6_packet *op;
|
||||
struct ospf6_packet *next;
|
||||
|
||||
for (op = fifo->head; op; op = next) {
|
||||
next = op->next;
|
||||
ospf6_packet_free(op);
|
||||
}
|
||||
fifo->head = fifo->tail = NULL;
|
||||
fifo->count = 0;
|
||||
}
|
||||
|
||||
/* Free ospf packet fifo. */
|
||||
void ospf6_fifo_free(struct ospf6_fifo *fifo)
|
||||
{
|
||||
ospf6_fifo_flush(fifo);
|
||||
|
||||
XFREE(MTYPE_OSPF6_FIFO, fifo);
|
||||
}
|
||||
|
||||
static void ospf6_hello_recv(struct in6_addr *src, struct in6_addr *dst,
|
||||
struct ospf6_interface *oi,
|
||||
struct ospf6_header *oh)
|
||||
|
@ -63,6 +63,27 @@ extern unsigned char conf_debug_ospf6_message[];
|
||||
#define OSPF6_MESSAGE_TYPE_LSACK 0x5 /* Flooding acknowledgment */
|
||||
#define OSPF6_MESSAGE_TYPE_ALL 0x6 /* For debug option */
|
||||
|
||||
struct ospf6_packet {
|
||||
struct ospf6_packet *next;
|
||||
|
||||
/* Pointer to data stream. */
|
||||
struct stream *s;
|
||||
|
||||
/* IP destination address. */
|
||||
struct in6_addr dst;
|
||||
|
||||
/* OSPF6 packet length. */
|
||||
uint16_t length;
|
||||
};
|
||||
|
||||
/* OSPF packet queue structure. */
|
||||
struct ospf6_fifo {
|
||||
unsigned long count;
|
||||
|
||||
struct ospf6_packet *head;
|
||||
struct ospf6_packet *tail;
|
||||
};
|
||||
|
||||
/* OSPFv3 packet header */
|
||||
#define OSPF6_HEADER_SIZE 16U
|
||||
struct ospf6_header {
|
||||
@ -136,6 +157,15 @@ extern void ospf6_lsreq_print(struct ospf6_header *, int action);
|
||||
extern void ospf6_lsupdate_print(struct ospf6_header *, int action);
|
||||
extern void ospf6_lsack_print(struct ospf6_header *, int action);
|
||||
|
||||
extern void ospf6_packet_free(struct ospf6_packet *op);
|
||||
extern struct ospf6_fifo *ospf6_fifo_new(void);
|
||||
extern void ospf6_fifo_push(struct ospf6_fifo *fifo, struct ospf6_packet *op);
|
||||
void ospf6_fifo_push_head(struct ospf6_fifo *fifo, struct ospf6_packet *op);
|
||||
extern struct ospf6_packet *ospf6_fifo_pop(struct ospf6_fifo *fifo);
|
||||
extern struct ospf6_packet *ospf6_fifo_head(struct ospf6_fifo *fifo);
|
||||
extern void ospf6_fifo_flush(struct ospf6_fifo *fifo);
|
||||
extern void ospf6_fifo_free(struct ospf6_fifo *fifo);
|
||||
|
||||
extern int ospf6_iobuf_size(unsigned int size);
|
||||
extern void ospf6_message_terminate(void);
|
||||
extern int ospf6_receive(struct thread *thread);
|
||||
|
@ -413,6 +413,8 @@ static struct ospf6 *ospf6_create(const char *name)
|
||||
|
||||
o->max_multipath = MULTIPATH_NUM;
|
||||
|
||||
o->oi_write_q = list_new();
|
||||
|
||||
QOBJ_REG(o, ospf6);
|
||||
|
||||
/* Make ospf protocol socket. */
|
||||
@ -482,6 +484,7 @@ void ospf6_delete(struct ospf6 *o)
|
||||
|
||||
ospf6_distance_reset(o);
|
||||
route_table_finish(o->distance_table);
|
||||
list_delete(&o->oi_write_q);
|
||||
|
||||
if (o->vrf_id != VRF_UNKNOWN) {
|
||||
vrf = vrf_lookup_by_id(o->vrf_id);
|
||||
|
@ -128,6 +128,7 @@ struct ospf6 {
|
||||
struct thread *maxage_remover;
|
||||
struct thread *t_distribute_update; /* Distirbute update timer. */
|
||||
struct thread *t_ospf6_receive; /* OSPF6 receive timer */
|
||||
struct thread *t_write;
|
||||
|
||||
uint32_t ref_bandwidth;
|
||||
|
||||
@ -150,6 +151,7 @@ struct ospf6 {
|
||||
/* Count of NSSA areas */
|
||||
uint8_t anyNSSA;
|
||||
struct thread *t_abr_task; /* ABR task timer. */
|
||||
struct list *oi_write_q;
|
||||
|
||||
uint32_t redist_count;
|
||||
QOBJ_FIELDS;
|
||||
|
Loading…
Reference in New Issue
Block a user