mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 20:13:53 +00:00
zebra: optimize zserv_process_messages
* Simplify zapi_msg <-> zserv interaction * Remove header validity checks, as they're already performed before the packet ever makes it here * Perform the same kind of batch processing done in zserv_write by copying multiple inbound packets under lock instead of doing serial locking * Perform self-scheduling under the same lock Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
This commit is contained in:
parent
370d8dad79
commit
904e0d8830
@ -3017,14 +3017,27 @@ void (*zserv_handlers[])(ZAPI_HANDLER_ARGS) = {
|
||||
[ZEBRA_IPTABLE_DELETE] = zread_iptable,
|
||||
};
|
||||
|
||||
void zserv_handle_commands(struct zserv *client, struct zmsghdr *hdr,
|
||||
struct stream *msg, struct zebra_vrf *zvrf)
|
||||
void zserv_handle_commands(struct zserv *client, struct stream *msg)
|
||||
{
|
||||
if (hdr->command > array_size(zserv_handlers)
|
||||
|| zserv_handlers[hdr->command] == NULL)
|
||||
zlog_info("Zebra received unknown command %d", hdr->command);
|
||||
else
|
||||
zserv_handlers[hdr->command](client, hdr, msg, zvrf);
|
||||
struct zmsghdr hdr;
|
||||
struct zebra_vrf *zvrf;
|
||||
|
||||
stream_free(msg);
|
||||
zapi_parse_header(msg, &hdr);
|
||||
|
||||
hdr.length -= ZEBRA_HEADER_SIZE;
|
||||
|
||||
/* lookup vrf */
|
||||
zvrf = zebra_vrf_lookup_by_id(hdr.vrf_id);
|
||||
if (!zvrf) {
|
||||
if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
|
||||
zlog_warn("ZAPI message specifies unknown VRF: %d",
|
||||
hdr.vrf_id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (hdr.command > array_size(zserv_handlers)
|
||||
|| zserv_handlers[hdr.command] == NULL)
|
||||
zlog_info("Zebra received unknown command %d", hdr.command);
|
||||
else
|
||||
zserv_handlers[hdr.command](client, &hdr, msg, zvrf);
|
||||
}
|
||||
|
@ -35,17 +35,10 @@
|
||||
* client
|
||||
* the client datastructure
|
||||
*
|
||||
* hdr
|
||||
* the message header
|
||||
*
|
||||
* msg
|
||||
* the message contents, without the header
|
||||
*
|
||||
* zvrf
|
||||
* the vrf
|
||||
* the message
|
||||
*/
|
||||
extern void zserv_handle_commands(struct zserv *client, struct zmsghdr *hdr,
|
||||
struct stream *msg, struct zebra_vrf *zvrf);
|
||||
extern void zserv_handle_commands(struct zserv *client, struct stream *msg);
|
||||
|
||||
extern int zsend_vrf_add(struct zserv *zclient, struct zebra_vrf *zvrf);
|
||||
extern int zsend_vrf_delete(struct zserv *zclient, struct zebra_vrf *zvrf);
|
||||
|
@ -493,62 +493,40 @@ static void zserv_client_event(struct zserv *client,
|
||||
*
|
||||
* Each message is popped off the client's input queue and the action associated
|
||||
* with the message is executed. This proceeds until there are no more messages,
|
||||
* an error occurs, or the processing limit is reached. In the last case, this
|
||||
* task reschedules itself.
|
||||
* an error occurs, or the processing limit is reached.
|
||||
*
|
||||
* This task reschedules itself if it cannot process everything on the input
|
||||
* queue in one run.
|
||||
*/
|
||||
static int zserv_process_messages(struct thread *thread)
|
||||
{
|
||||
struct zserv *client = THREAD_ARG(thread);
|
||||
struct zebra_vrf *zvrf;
|
||||
struct zmsghdr hdr;
|
||||
struct stream *msg;
|
||||
bool hdrvalid;
|
||||
struct stream_fifo *cache = stream_fifo_new();
|
||||
|
||||
int p2p = zebrad.packets_to_process;
|
||||
uint32_t p2p = zebrad.packets_to_process;
|
||||
|
||||
do {
|
||||
pthread_mutex_lock(&client->ibuf_mtx);
|
||||
{
|
||||
msg = stream_fifo_pop(client->ibuf_fifo);
|
||||
}
|
||||
pthread_mutex_unlock(&client->ibuf_mtx);
|
||||
for (uint32_t i = p2p - 1; i && client->ibuf_fifo->head; --i)
|
||||
stream_fifo_push(cache,
|
||||
stream_fifo_pop(client->ibuf_fifo));
|
||||
|
||||
/* break if out of messages */
|
||||
if (!msg)
|
||||
continue;
|
||||
|
||||
/* read & check header */
|
||||
hdrvalid = zapi_parse_header(msg, &hdr);
|
||||
if (!hdrvalid && IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV) {
|
||||
const char *emsg = "Message has corrupt header";
|
||||
zserv_log_message(emsg, msg, NULL);
|
||||
}
|
||||
if (!hdrvalid)
|
||||
continue;
|
||||
|
||||
hdr.length -= ZEBRA_HEADER_SIZE;
|
||||
/* lookup vrf */
|
||||
zvrf = zebra_vrf_lookup_by_id(hdr.vrf_id);
|
||||
if (!zvrf && IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV) {
|
||||
const char *emsg = "Message specifies unknown VRF";
|
||||
zserv_log_message(emsg, msg, &hdr);
|
||||
}
|
||||
if (!zvrf)
|
||||
continue;
|
||||
|
||||
/* process commands */
|
||||
zserv_handle_commands(client, &hdr, msg, zvrf);
|
||||
|
||||
} while (msg && --p2p);
|
||||
|
||||
/* reschedule self if necessary */
|
||||
pthread_mutex_lock(&client->ibuf_mtx);
|
||||
{
|
||||
if (client->ibuf_fifo->count)
|
||||
if (client->ibuf_fifo->head)
|
||||
zserv_event(client, ZSERV_PROCESS_MESSAGES);
|
||||
}
|
||||
pthread_mutex_unlock(&client->ibuf_mtx);
|
||||
|
||||
while (p2p--) {
|
||||
msg = stream_fifo_pop(cache);
|
||||
if (!msg)
|
||||
break;
|
||||
zserv_handle_commands(client, msg);
|
||||
stream_free(msg);
|
||||
}
|
||||
|
||||
stream_fifo_free(cache);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user