]>
git.proxmox.com Git - mirror_frr.git/blob - pimd/pim_zpthread.c
3 * Copyright (C) 2008 Everton da Silva Marques
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; see the file COPYING; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #include <lib/lib_errors.h>
25 #include "pim_instance.h"
27 #include "pim_zebra.h"
29 extern struct zclient
*zclient
;
31 #define PIM_MLAG_POST_LIMIT 100
33 int32_t mlag_bulk_cnt
;
35 static void pim_mlag_zebra_fill_header(enum mlag_msg_type msg_type
)
37 uint32_t fill_msg_type
= msg_type
;
41 if (msg_type
== MLAG_MSG_NONE
)
47 data_len
= sizeof(struct mlag_msg
);
50 data_len
= sizeof(struct mlag_mroute_add
);
51 fill_msg_type
= MLAG_MROUTE_ADD_BULK
;
54 data_len
= sizeof(struct mlag_mroute_del
);
55 fill_msg_type
= MLAG_MROUTE_DEL_BULK
;
62 stream_reset(router
->mlag_stream
);
64 stream_putl(router
->mlag_stream
, fill_msg_type
);
66 * In case of Bulk actual size & msg_cnt will be updated
67 * just before writing onto zebra
69 stream_putw(router
->mlag_stream
, data_len
);
70 stream_putw(router
->mlag_stream
, msg_cnt
);
73 zlog_debug(":%s: msg_type: %d/%d len %d",
74 __func__
, msg_type
, fill_msg_type
, data_len
);
77 static void pim_mlag_zebra_flush_buffer(void)
81 /* Stream had bulk messages update the Hedaer */
82 if (mlag_bulk_cnt
> 1) {
84 * No need to reset the pointer, below api reads from data[0]
86 STREAM_GETL(router
->mlag_stream
, msg_type
);
87 if (msg_type
== MLAG_MROUTE_ADD_BULK
) {
89 router
->mlag_stream
, 4,
90 (mlag_bulk_cnt
* sizeof(struct mlag_mroute_add
)));
91 stream_putw_at(router
->mlag_stream
, 6, mlag_bulk_cnt
);
92 } else if (msg_type
== MLAG_MROUTE_DEL_BULK
) {
94 router
->mlag_stream
, 4,
95 (mlag_bulk_cnt
* sizeof(struct mlag_mroute_del
)));
96 stream_putw_at(router
->mlag_stream
, 6, mlag_bulk_cnt
);
98 flog_err(EC_LIB_ZAPI_ENCODE
,
99 "unknown bulk message type %d bulk_count %d",
100 msg_type
, mlag_bulk_cnt
);
101 stream_reset(router
->mlag_stream
);
107 zclient_send_mlag_data(zclient
, router
->mlag_stream
);
109 stream_reset(router
->mlag_stream
);
114 * Only ROUTE add & Delete will be bulked.
115 * Buffer will be flushed, when
116 * 1) there were no messages in the queue
117 * 2) Curr_msg_type != prev_msg_type
120 static void pim_mlag_zebra_check_for_buffer_flush(uint32_t curr_msg_type
,
121 uint32_t prev_msg_type
)
123 /* First Message, keep bulking */
124 if (prev_msg_type
== MLAG_MSG_NONE
) {
129 /*msg type is route add & delete, keep bulking */
130 if (curr_msg_type
== prev_msg_type
131 && (curr_msg_type
== MLAG_MROUTE_ADD
132 || curr_msg_type
== MLAG_MROUTE_DEL
)) {
137 pim_mlag_zebra_flush_buffer();
141 * Thsi thread reads the clients data from the Gloabl queue and encodes with
142 * protobuf and pass on to the MLAG socket.
144 static void pim_mlag_zthread_handler(struct thread
*event
)
146 struct stream
*read_s
;
147 uint32_t wr_count
= 0;
148 uint32_t prev_msg_type
= MLAG_MSG_NONE
;
149 uint32_t curr_msg_type
= MLAG_MSG_NONE
;
151 router
->zpthread_mlag_write
= NULL
;
152 wr_count
= stream_fifo_count_safe(router
->mlag_fifo
);
155 zlog_debug(":%s: Processing MLAG write, %d messages in queue",
161 for (wr_count
= 0; wr_count
< PIM_MLAG_POST_LIMIT
; wr_count
++) {
162 /* FIFO is empty,wait for teh message to be add */
163 if (stream_fifo_count_safe(router
->mlag_fifo
) == 0)
166 read_s
= stream_fifo_pop_safe(router
->mlag_fifo
);
168 zlog_debug(":%s: Got a NULL Messages, some thing wrong",
172 STREAM_GETL(read_s
, curr_msg_type
);
174 * Check for Buffer Overflow,
175 * MLAG Can't process more than 'PIM_MLAG_BUF_LIMIT' bytes
177 if (router
->mlag_stream
->endp
+ read_s
->endp
+ ZEBRA_HEADER_SIZE
179 pim_mlag_zebra_flush_buffer();
181 pim_mlag_zebra_check_for_buffer_flush(curr_msg_type
,
185 * First message to Buffer, fill the Header
187 if (router
->mlag_stream
->endp
== 0)
188 pim_mlag_zebra_fill_header(curr_msg_type
);
193 stream_put(router
->mlag_stream
, read_s
->data
+ read_s
->getp
,
194 read_s
->endp
- read_s
->getp
);
197 prev_msg_type
= curr_msg_type
;
202 * we are here , because
203 * 1. Queue might be empty
204 * 2. we crossed the max Q Read limit
205 * In any acse flush the buffer towards zebra
207 pim_mlag_zebra_flush_buffer();
209 if (wr_count
>= PIM_MLAG_POST_LIMIT
)
210 pim_mlag_signal_zpthread();
214 int pim_mlag_signal_zpthread(void)
216 if (router
->master
) {
218 zlog_debug(":%s: Scheduling PIM MLAG write Thread",
220 thread_add_event(router
->master
, pim_mlag_zthread_handler
, NULL
,
221 0, &router
->zpthread_mlag_write
);