mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-08 07:03:07 +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 = XCALLOC(MTYPE_OSPF6_IF, sizeof(struct ospf6_interface));
|
||||||
|
|
||||||
|
oi->obuf = ospf6_fifo_new();
|
||||||
|
|
||||||
oi->area = (struct ospf6_area *)NULL;
|
oi->area = (struct ospf6_area *)NULL;
|
||||||
oi->neighbor_list = list_new();
|
oi->neighbor_list = list_new();
|
||||||
oi->neighbor_list->cmp = ospf6_neighbor_cmp;
|
oi->neighbor_list->cmp = ospf6_neighbor_cmp;
|
||||||
@ -243,6 +245,8 @@ void ospf6_interface_delete(struct ospf6_interface *oi)
|
|||||||
|
|
||||||
QOBJ_UNREG(oi);
|
QOBJ_UNREG(oi);
|
||||||
|
|
||||||
|
ospf6_fifo_free(oi->obuf);
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
|
for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
|
||||||
ospf6_neighbor_delete(on);
|
ospf6_neighbor_delete(on);
|
||||||
|
|
||||||
@ -888,6 +892,15 @@ int interface_down(struct thread *thread)
|
|||||||
ospf6_sso(oi->interface->ifindex, &allspfrouters6,
|
ospf6_sso(oi->interface->ifindex, &allspfrouters6,
|
||||||
IPV6_LEAVE_GROUP, ospf6->fd);
|
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);
|
ospf6_interface_state_change(OSPF6_INTERFACE_DOWN, oi);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -56,6 +56,9 @@ struct ospf6_interface {
|
|||||||
/* I/F transmission delay */
|
/* I/F transmission delay */
|
||||||
uint32_t transdelay;
|
uint32_t transdelay;
|
||||||
|
|
||||||
|
/* Packet send buffer. */
|
||||||
|
struct ospf6_fifo *obuf; /* Output queue */
|
||||||
|
|
||||||
/* Network Type */
|
/* Network Type */
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
bool type_cfg;
|
bool type_cfg;
|
||||||
@ -130,6 +133,8 @@ struct ospf6_interface {
|
|||||||
char *profile;
|
char *profile;
|
||||||
} bfd_config;
|
} bfd_config;
|
||||||
|
|
||||||
|
int on_write_q;
|
||||||
|
|
||||||
/* Statistics Fields */
|
/* Statistics Fields */
|
||||||
uint32_t hello_in;
|
uint32_t hello_in;
|
||||||
uint32_t hello_out;
|
uint32_t hello_out;
|
||||||
|
@ -50,6 +50,8 @@
|
|||||||
#include <netinet/ip6.h>
|
#include <netinet/ip6.h>
|
||||||
|
|
||||||
DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_MESSAGE, "OSPF6 message");
|
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};
|
unsigned char conf_debug_ospf6_message[6] = {0x03, 0, 0, 0, 0, 0};
|
||||||
static const struct message ospf6_message_type_str[] = {
|
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,
|
static void ospf6_hello_recv(struct in6_addr *src, struct in6_addr *dst,
|
||||||
struct ospf6_interface *oi,
|
struct ospf6_interface *oi,
|
||||||
struct ospf6_header *oh)
|
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_LSACK 0x5 /* Flooding acknowledgment */
|
||||||
#define OSPF6_MESSAGE_TYPE_ALL 0x6 /* For debug option */
|
#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 */
|
/* OSPFv3 packet header */
|
||||||
#define OSPF6_HEADER_SIZE 16U
|
#define OSPF6_HEADER_SIZE 16U
|
||||||
struct ospf6_header {
|
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_lsupdate_print(struct ospf6_header *, int action);
|
||||||
extern void ospf6_lsack_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 int ospf6_iobuf_size(unsigned int size);
|
||||||
extern void ospf6_message_terminate(void);
|
extern void ospf6_message_terminate(void);
|
||||||
extern int ospf6_receive(struct thread *thread);
|
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->max_multipath = MULTIPATH_NUM;
|
||||||
|
|
||||||
|
o->oi_write_q = list_new();
|
||||||
|
|
||||||
QOBJ_REG(o, ospf6);
|
QOBJ_REG(o, ospf6);
|
||||||
|
|
||||||
/* Make ospf protocol socket. */
|
/* Make ospf protocol socket. */
|
||||||
@ -482,6 +484,7 @@ void ospf6_delete(struct ospf6 *o)
|
|||||||
|
|
||||||
ospf6_distance_reset(o);
|
ospf6_distance_reset(o);
|
||||||
route_table_finish(o->distance_table);
|
route_table_finish(o->distance_table);
|
||||||
|
list_delete(&o->oi_write_q);
|
||||||
|
|
||||||
if (o->vrf_id != VRF_UNKNOWN) {
|
if (o->vrf_id != VRF_UNKNOWN) {
|
||||||
vrf = vrf_lookup_by_id(o->vrf_id);
|
vrf = vrf_lookup_by_id(o->vrf_id);
|
||||||
|
@ -128,6 +128,7 @@ struct ospf6 {
|
|||||||
struct thread *maxage_remover;
|
struct thread *maxage_remover;
|
||||||
struct thread *t_distribute_update; /* Distirbute update timer. */
|
struct thread *t_distribute_update; /* Distirbute update timer. */
|
||||||
struct thread *t_ospf6_receive; /* OSPF6 receive timer */
|
struct thread *t_ospf6_receive; /* OSPF6 receive timer */
|
||||||
|
struct thread *t_write;
|
||||||
|
|
||||||
uint32_t ref_bandwidth;
|
uint32_t ref_bandwidth;
|
||||||
|
|
||||||
@ -150,6 +151,7 @@ struct ospf6 {
|
|||||||
/* Count of NSSA areas */
|
/* Count of NSSA areas */
|
||||||
uint8_t anyNSSA;
|
uint8_t anyNSSA;
|
||||||
struct thread *t_abr_task; /* ABR task timer. */
|
struct thread *t_abr_task; /* ABR task timer. */
|
||||||
|
struct list *oi_write_q;
|
||||||
|
|
||||||
uint32_t redist_count;
|
uint32_t redist_count;
|
||||||
QOBJ_FIELDS;
|
QOBJ_FIELDS;
|
||||||
|
Loading…
Reference in New Issue
Block a user