back to topotato report
topotato coverage report
Current view: top level - pimd - pim_zpthread.c (source / functions) Hit Total Coverage
Test: aggregated run ( view descriptions ) Lines: 0 89 0.0 %
Date: 2023-02-24 14:41:08 Functions: 0 5 0.0 %

          Line data    Source code
       1             : /*
       2             :  * PIM for Quagga
       3             :  * Copyright (C) 2008  Everton da Silva Marques
       4             :  *
       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.
       9             :  *
      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.
      14             :  *
      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
      18             :  */
      19             : 
      20             : #include <zebra.h>
      21             : #include <lib/log.h>
      22             : #include <lib/lib_errors.h>
      23             : 
      24             : #include "pimd.h"
      25             : #include "pim_instance.h"
      26             : #include "pim_mlag.h"
      27             : #include "pim_zebra.h"
      28             : 
      29             : extern struct zclient *zclient;
      30             : 
      31             : #define PIM_MLAG_POST_LIMIT 100
      32             : 
      33             : int32_t mlag_bulk_cnt;
      34             : 
      35           0 : static void pim_mlag_zebra_fill_header(enum mlag_msg_type msg_type)
      36             : {
      37           0 :         uint32_t fill_msg_type = msg_type;
      38           0 :         uint16_t data_len = 0;
      39           0 :         uint16_t msg_cnt = 1;
      40             : 
      41           0 :         if (msg_type == MLAG_MSG_NONE)
      42             :                 return;
      43             : 
      44           0 :         switch (msg_type) {
      45           0 :         case MLAG_REGISTER:
      46             :         case MLAG_DEREGISTER:
      47           0 :                 data_len = sizeof(struct mlag_msg);
      48           0 :                 break;
      49           0 :         case MLAG_MROUTE_ADD:
      50           0 :                 data_len = sizeof(struct mlag_mroute_add);
      51           0 :                 fill_msg_type = MLAG_MROUTE_ADD_BULK;
      52           0 :                 break;
      53           0 :         case MLAG_MROUTE_DEL:
      54           0 :                 data_len = sizeof(struct mlag_mroute_del);
      55           0 :                 fill_msg_type = MLAG_MROUTE_DEL_BULK;
      56           0 :                 break;
      57             :         case MLAG_MSG_NONE:
      58             :         case MLAG_STATUS_UPDATE:
      59             :         case MLAG_DUMP:
      60             :         case MLAG_MROUTE_ADD_BULK:
      61             :         case MLAG_MROUTE_DEL_BULK:
      62             :         case MLAG_PIM_CFG_DUMP:
      63             :         case MLAG_VXLAN_UPDATE:
      64             :         case MLAG_PEER_FRR_STATUS:
      65             :                 data_len = 0;
      66             :                 break;
      67             :         }
      68             : 
      69           0 :         stream_reset(router->mlag_stream);
      70             :         /* ADD Hedaer */
      71           0 :         stream_putl(router->mlag_stream, fill_msg_type);
      72             :         /*
      73             :          * In case of Bulk actual size & msg_cnt will be updated
      74             :          * just before writing onto zebra
      75             :          */
      76           0 :         stream_putw(router->mlag_stream, data_len);
      77           0 :         stream_putw(router->mlag_stream, msg_cnt);
      78             : 
      79           0 :         if (PIM_DEBUG_MLAG)
      80           0 :                 zlog_debug(":%s: msg_type: %d/%d len %d",
      81             :                            __func__, msg_type, fill_msg_type, data_len);
      82             : }
      83             : 
      84           0 : static void pim_mlag_zebra_flush_buffer(void)
      85             : {
      86           0 :         uint32_t msg_type;
      87             : 
      88             :         /* Stream had bulk messages update the Hedaer */
      89           0 :         if (mlag_bulk_cnt > 1) {
      90             :                 /*
      91             :                  * No need to reset the pointer, below api reads from data[0]
      92             :                  */
      93           0 :                 STREAM_GETL(router->mlag_stream, msg_type);
      94           0 :                 if (msg_type == MLAG_MROUTE_ADD_BULK) {
      95           0 :                         stream_putw_at(
      96           0 :                                 router->mlag_stream, 4,
      97             :                                 (mlag_bulk_cnt * sizeof(struct mlag_mroute_add)));
      98           0 :                         stream_putw_at(router->mlag_stream, 6, mlag_bulk_cnt);
      99           0 :                 } else if (msg_type == MLAG_MROUTE_DEL_BULK) {
     100           0 :                         stream_putw_at(
     101           0 :                                 router->mlag_stream, 4,
     102             :                                 (mlag_bulk_cnt * sizeof(struct mlag_mroute_del)));
     103           0 :                         stream_putw_at(router->mlag_stream, 6, mlag_bulk_cnt);
     104             :                 } else {
     105           0 :                         flog_err(EC_LIB_ZAPI_ENCODE,
     106             :                                 "unknown bulk message type %d bulk_count %d",
     107             :                                 msg_type, mlag_bulk_cnt);
     108           0 :                         stream_reset(router->mlag_stream);
     109           0 :                         mlag_bulk_cnt = 0;
     110           0 :                         return;
     111             :                 }
     112             :         }
     113             : 
     114           0 :         zclient_send_mlag_data(zclient, router->mlag_stream);
     115           0 : stream_failure:
     116           0 :         stream_reset(router->mlag_stream);
     117           0 :         mlag_bulk_cnt = 0;
     118             : }
     119             : 
     120             : /*
     121             :  * Only ROUTE add & Delete will be bulked.
     122             :  * Buffer will be flushed, when
     123             :  * 1) there were no messages in the queue
     124             :  * 2) Curr_msg_type != prev_msg_type
     125             :  */
     126             : 
     127           0 : static void pim_mlag_zebra_check_for_buffer_flush(uint32_t curr_msg_type,
     128             :                                                   uint32_t prev_msg_type)
     129             : {
     130             :         /* First Message, keep bulking */
     131           0 :         if (prev_msg_type == MLAG_MSG_NONE) {
     132           0 :                 mlag_bulk_cnt = 1;
     133           0 :                 return;
     134             :         }
     135             : 
     136             :         /*msg type is route add & delete, keep bulking */
     137           0 :         if (curr_msg_type == prev_msg_type
     138           0 :             && (curr_msg_type == MLAG_MROUTE_ADD
     139           0 :                 || curr_msg_type == MLAG_MROUTE_DEL)) {
     140           0 :                 mlag_bulk_cnt++;
     141           0 :                 return;
     142             :         }
     143             : 
     144           0 :         pim_mlag_zebra_flush_buffer();
     145             : }
     146             : 
     147             : /*
     148             :  * Thsi thread reads the clients data from the Gloabl queue and encodes with
     149             :  * protobuf and pass on to the MLAG socket.
     150             :  */
     151           0 : static void pim_mlag_zthread_handler(struct thread *event)
     152             : {
     153           0 :         struct stream *read_s;
     154           0 :         uint32_t wr_count = 0;
     155           0 :         uint32_t prev_msg_type = MLAG_MSG_NONE;
     156           0 :         uint32_t curr_msg_type = MLAG_MSG_NONE;
     157             : 
     158           0 :         router->zpthread_mlag_write = NULL;
     159           0 :         wr_count = stream_fifo_count_safe(router->mlag_fifo);
     160             : 
     161           0 :         if (PIM_DEBUG_MLAG)
     162           0 :                 zlog_debug(":%s: Processing MLAG write, %d messages in queue",
     163             :                            __func__, wr_count);
     164             : 
     165           0 :         if (wr_count == 0)
     166             :                 return;
     167             : 
     168           0 :         for (wr_count = 0; wr_count < PIM_MLAG_POST_LIMIT; wr_count++) {
     169             :                 /* FIFO is empty,wait for teh message to be add */
     170           0 :                 if (stream_fifo_count_safe(router->mlag_fifo) == 0)
     171             :                         break;
     172             : 
     173           0 :                 read_s = stream_fifo_pop_safe(router->mlag_fifo);
     174           0 :                 if (!read_s) {
     175           0 :                         zlog_debug(":%s: Got a NULL Messages, some thing wrong",
     176             :                                    __func__);
     177           0 :                         break;
     178             :                 }
     179           0 :                 STREAM_GETL(read_s, curr_msg_type);
     180             :                 /*
     181             :                  * Check for Buffer Overflow,
     182             :                  * MLAG Can't process more than 'PIM_MLAG_BUF_LIMIT' bytes
     183             :                  */
     184           0 :                 if (router->mlag_stream->endp + read_s->endp + ZEBRA_HEADER_SIZE
     185             :                     > MLAG_BUF_LIMIT)
     186           0 :                         pim_mlag_zebra_flush_buffer();
     187             : 
     188           0 :                 pim_mlag_zebra_check_for_buffer_flush(curr_msg_type,
     189             :                                                       prev_msg_type);
     190             : 
     191             :                 /*
     192             :                  * First message to Buffer, fill the Header
     193             :                  */
     194           0 :                 if (router->mlag_stream->endp == 0)
     195           0 :                         pim_mlag_zebra_fill_header(curr_msg_type);
     196             : 
     197             :                 /*
     198             :                  * add the data now
     199             :                  */
     200           0 :                 stream_put(router->mlag_stream, read_s->data + read_s->getp,
     201           0 :                            read_s->endp - read_s->getp);
     202             : 
     203           0 :                 stream_free(read_s);
     204           0 :                 prev_msg_type = curr_msg_type;
     205             :         }
     206             : 
     207           0 : stream_failure:
     208             :         /*
     209             :          * we are here , because
     210             :          * 1. Queue might be empty
     211             :          * 2. we crossed the max Q Read limit
     212             :          * In any acse flush the buffer towards zebra
     213             :          */
     214           0 :         pim_mlag_zebra_flush_buffer();
     215             : 
     216           0 :         if (wr_count >= PIM_MLAG_POST_LIMIT)
     217           0 :                 pim_mlag_signal_zpthread();
     218             : }
     219             : 
     220             : 
     221           0 : int pim_mlag_signal_zpthread(void)
     222             : {
     223           0 :         if (router->master) {
     224           0 :                 if (PIM_DEBUG_MLAG)
     225           0 :                         zlog_debug(":%s: Scheduling PIM MLAG write Thread",
     226             :                                    __func__);
     227           0 :                 thread_add_event(router->master, pim_mlag_zthread_handler, NULL,
     228             :                                  0, &router->zpthread_mlag_write);
     229             :         }
     230           0 :         return (0);
     231             : }

Generated by: LCOV version v1.16-topotato