]>
git.proxmox.com Git - mirror_frr.git/blob - pimd/pim_zpthread.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * Copyright (C) 2008 Everton da Silva Marques
9 #include <lib/lib_errors.h>
12 #include "pim_instance.h"
14 #include "pim_zebra.h"
16 extern struct zclient
*zclient
;
18 #define PIM_MLAG_POST_LIMIT 100
20 int32_t mlag_bulk_cnt
;
22 static void pim_mlag_zebra_fill_header(enum mlag_msg_type msg_type
)
24 uint32_t fill_msg_type
= msg_type
;
25 uint16_t data_len
= 0;
31 data_len
= sizeof(struct mlag_msg
);
34 data_len
= sizeof(struct mlag_mroute_add
);
35 fill_msg_type
= MLAG_MROUTE_ADD_BULK
;
38 data_len
= sizeof(struct mlag_mroute_del
);
39 fill_msg_type
= MLAG_MROUTE_DEL_BULK
;
43 case MLAG_STATUS_UPDATE
:
45 case MLAG_MROUTE_ADD_BULK
:
46 case MLAG_MROUTE_DEL_BULK
:
47 case MLAG_PIM_CFG_DUMP
:
48 case MLAG_VXLAN_UPDATE
:
49 case MLAG_PEER_FRR_STATUS
:
54 stream_reset(router
->mlag_stream
);
56 stream_putl(router
->mlag_stream
, fill_msg_type
);
58 * In case of Bulk actual size & msg_cnt will be updated
59 * just before writing onto zebra
61 stream_putw(router
->mlag_stream
, data_len
);
62 stream_putw(router
->mlag_stream
, msg_cnt
);
65 zlog_debug(":%s: msg_type: %d/%d len %d",
66 __func__
, msg_type
, fill_msg_type
, data_len
);
69 static void pim_mlag_zebra_flush_buffer(void)
73 /* Stream had bulk messages update the Hedaer */
74 if (mlag_bulk_cnt
> 1) {
76 * No need to reset the pointer, below api reads from data[0]
78 STREAM_GETL(router
->mlag_stream
, msg_type
);
79 if (msg_type
== MLAG_MROUTE_ADD_BULK
) {
81 router
->mlag_stream
, 4,
82 (mlag_bulk_cnt
* sizeof(struct mlag_mroute_add
)));
83 stream_putw_at(router
->mlag_stream
, 6, mlag_bulk_cnt
);
84 } else if (msg_type
== MLAG_MROUTE_DEL_BULK
) {
86 router
->mlag_stream
, 4,
87 (mlag_bulk_cnt
* sizeof(struct mlag_mroute_del
)));
88 stream_putw_at(router
->mlag_stream
, 6, mlag_bulk_cnt
);
90 flog_err(EC_LIB_ZAPI_ENCODE
,
91 "unknown bulk message type %d bulk_count %d",
92 msg_type
, mlag_bulk_cnt
);
93 stream_reset(router
->mlag_stream
);
99 zclient_send_mlag_data(zclient
, router
->mlag_stream
);
101 stream_reset(router
->mlag_stream
);
106 * Only ROUTE add & Delete will be bulked.
107 * Buffer will be flushed, when
108 * 1) there were no messages in the queue
109 * 2) Curr_msg_type != prev_msg_type
112 static void pim_mlag_zebra_check_for_buffer_flush(uint32_t curr_msg_type
,
113 uint32_t prev_msg_type
)
115 /* First Message, keep bulking */
116 if (prev_msg_type
== MLAG_MSG_NONE
) {
121 /*msg type is route add & delete, keep bulking */
122 if (curr_msg_type
== prev_msg_type
123 && (curr_msg_type
== MLAG_MROUTE_ADD
124 || curr_msg_type
== MLAG_MROUTE_DEL
)) {
129 pim_mlag_zebra_flush_buffer();
133 * Thsi thread reads the clients data from the Gloabl queue and encodes with
134 * protobuf and pass on to the MLAG socket.
136 static void pim_mlag_zthread_handler(struct event
*event
)
138 struct stream
*read_s
;
139 uint32_t wr_count
= 0;
140 uint32_t prev_msg_type
= MLAG_MSG_NONE
;
141 uint32_t curr_msg_type
= MLAG_MSG_NONE
;
143 router
->zpthread_mlag_write
= NULL
;
144 wr_count
= stream_fifo_count_safe(router
->mlag_fifo
);
147 zlog_debug(":%s: Processing MLAG write, %d messages in queue",
153 for (wr_count
= 0; wr_count
< PIM_MLAG_POST_LIMIT
; wr_count
++) {
154 /* FIFO is empty,wait for teh message to be add */
155 if (stream_fifo_count_safe(router
->mlag_fifo
) == 0)
158 read_s
= stream_fifo_pop_safe(router
->mlag_fifo
);
160 zlog_debug(":%s: Got a NULL Messages, some thing wrong",
164 STREAM_GETL(read_s
, curr_msg_type
);
166 * Check for Buffer Overflow,
167 * MLAG Can't process more than 'PIM_MLAG_BUF_LIMIT' bytes
169 if (router
->mlag_stream
->endp
+ read_s
->endp
+ ZEBRA_HEADER_SIZE
171 pim_mlag_zebra_flush_buffer();
173 pim_mlag_zebra_check_for_buffer_flush(curr_msg_type
,
177 * First message to Buffer, fill the Header
179 if (router
->mlag_stream
->endp
== 0)
180 pim_mlag_zebra_fill_header(curr_msg_type
);
185 stream_put(router
->mlag_stream
, read_s
->data
+ read_s
->getp
,
186 read_s
->endp
- read_s
->getp
);
189 prev_msg_type
= curr_msg_type
;
194 * we are here , because
195 * 1. Queue might be empty
196 * 2. we crossed the max Q Read limit
197 * In any acse flush the buffer towards zebra
199 pim_mlag_zebra_flush_buffer();
201 if (wr_count
>= PIM_MLAG_POST_LIMIT
)
202 pim_mlag_signal_zpthread();
206 int pim_mlag_signal_zpthread(void)
208 if (router
->master
) {
210 zlog_debug(":%s: Scheduling PIM MLAG write Thread",
212 thread_add_event(router
->master
, pim_mlag_zthread_handler
, NULL
,
213 0, &router
->zpthread_mlag_write
);