back to topotato report
topotato coverage report
Current view: top level - pimd - pim_hello.c (source / functions) Hit Total Coverage
Test: aggregated run ( view descriptions ) Lines: 95 185 51.4 %
Date: 2023-02-24 14:41:08 Functions: 3 5 60.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             : 
      22             : #include "log.h"
      23             : #include "if.h"
      24             : 
      25             : #include "pimd.h"
      26             : #include "pim_instance.h"
      27             : #include "pim_pim.h"
      28             : #include "pim_str.h"
      29             : #include "pim_tlv.h"
      30             : #include "pim_util.h"
      31             : #include "pim_hello.h"
      32             : #include "pim_iface.h"
      33             : #include "pim_neighbor.h"
      34             : #include "pim_upstream.h"
      35             : #include "pim_bsm.h"
      36             : 
      37           0 : static void on_trace(const char *label, struct interface *ifp, pim_addr src)
      38             : {
      39           0 :         if (PIM_DEBUG_PIM_TRACE)
      40           0 :                 zlog_debug("%s: from %pPAs on %s", label, &src, ifp->name);
      41           0 : }
      42             : 
      43           0 : static void tlv_trace_bool(const char *label, const char *tlv_name,
      44             :                            const char *ifname, pim_addr src_addr, int isset,
      45             :                            int value)
      46             : {
      47           0 :         if (isset)
      48           0 :                 zlog_debug(
      49             :                         "%s: PIM hello option from %pPAs on interface %s: %s=%d",
      50             :                         label, &src_addr, ifname, tlv_name, value);
      51             : }
      52             : 
      53           0 : static void tlv_trace_uint16(const char *label, const char *tlv_name,
      54             :                              const char *ifname, pim_addr src_addr, int isset,
      55             :                              uint16_t value)
      56             : {
      57           0 :         if (isset)
      58           0 :                 zlog_debug(
      59             :                         "%s: PIM hello option from %pPAs on interface %s: %s=%u",
      60             :                         label, &src_addr, ifname, tlv_name, value);
      61             : }
      62             : 
      63           0 : static void tlv_trace_uint32(const char *label, const char *tlv_name,
      64             :                              const char *ifname, pim_addr src_addr, int isset,
      65             :                              uint32_t value)
      66             : {
      67           0 :         if (isset)
      68           0 :                 zlog_debug(
      69             :                         "%s: PIM hello option from %pPAs on interface %s: %s=%u",
      70             :                         label, &src_addr, ifname, tlv_name, value);
      71             : }
      72             : 
      73           0 : static void tlv_trace_uint32_hex(const char *label, const char *tlv_name,
      74             :                                  const char *ifname, pim_addr src_addr,
      75             :                                  int isset, uint32_t value)
      76             : {
      77           0 :         if (isset)
      78           0 :                 zlog_debug(
      79             :                         "%s: PIM hello option from %pPAs on interface %s: %s=%08x",
      80             :                         label, &src_addr, ifname, tlv_name, value);
      81             : }
      82             : 
      83           0 : static void tlv_trace_list(const char *label, const char *tlv_name,
      84             :                            const char *ifname, pim_addr src_addr, int isset,
      85             :                            struct list *addr_list)
      86             : {
      87           0 :         if (isset)
      88           0 :                 zlog_debug(
      89             :                         "%s: PIM hello option from %pPAs on interface %s: %s size=%d list=%p",
      90             :                         label, &src_addr, ifname, tlv_name,
      91             :                         addr_list ? ((int)listcount(addr_list)) : -1,
      92             :                         (void *)addr_list);
      93           0 : }
      94             : 
      95             : #define FREE_ADDR_LIST                                                         \
      96             :         if (hello_option_addr_list) {                                          \
      97             :                 list_delete(&hello_option_addr_list);                          \
      98             :         }
      99             : 
     100             : #define FREE_ADDR_LIST_THEN_RETURN(code)                                       \
     101             :         {                                                                      \
     102             :                 FREE_ADDR_LIST                                                 \
     103             :                 return (code);                                                 \
     104             :         }
     105             : 
     106         590 : int pim_hello_recv(struct interface *ifp, pim_addr src_addr, uint8_t *tlv_buf,
     107             :                    int tlv_buf_size)
     108             : {
     109         590 :         struct pim_interface *pim_ifp;
     110         590 :         struct pim_neighbor *neigh;
     111         590 :         uint8_t *tlv_curr;
     112         590 :         uint8_t *tlv_pastend;
     113         590 :         pim_hello_options hello_options =
     114             :                 0; /* bit array recording options found */
     115         590 :         uint16_t hello_option_holdtime = 0;
     116         590 :         uint16_t hello_option_propagation_delay = 0;
     117         590 :         uint16_t hello_option_override_interval = 0;
     118         590 :         uint32_t hello_option_dr_priority = 0;
     119         590 :         uint32_t hello_option_generation_id = 0;
     120         590 :         struct list *hello_option_addr_list = 0;
     121             : 
     122         590 :         if (PIM_DEBUG_PIM_HELLO)
     123           0 :                 on_trace(__func__, ifp, src_addr);
     124             : 
     125         590 :         pim_ifp = ifp->info;
     126         590 :         assert(pim_ifp);
     127             : 
     128         590 :         if (pim_ifp->pim_passive_enable) {
     129           0 :                 if (PIM_DEBUG_PIM_PACKETS)
     130           0 :                         zlog_debug(
     131             :                                 "skip receiving PIM message on passive interface %s",
     132             :                                 ifp->name);
     133           0 :                 return 0;
     134             :         }
     135             : 
     136         590 :         ++pim_ifp->pim_ifstat_hello_recv;
     137             : 
     138             :         /*
     139             :           Parse PIM hello TLVs
     140             :          */
     141         590 :         assert(tlv_buf_size >= 0);
     142         590 :         tlv_curr = tlv_buf;
     143         590 :         tlv_pastend = tlv_buf + tlv_buf_size;
     144             : 
     145        3206 :         while (tlv_curr < tlv_pastend) {
     146        2616 :                 uint16_t option_type;
     147        2616 :                 uint16_t option_len;
     148        2616 :                 int remain = tlv_pastend - tlv_curr;
     149             : 
     150        2616 :                 if (remain < PIM_TLV_MIN_SIZE) {
     151           0 :                         if (PIM_DEBUG_PIM_HELLO)
     152           0 :                                 zlog_debug(
     153             :                                         "%s: short PIM hello TLV size=%d < min=%d from %pPAs on interface %s",
     154             :                                         __func__, remain, PIM_TLV_MIN_SIZE,
     155             :                                         &src_addr, ifp->name);
     156           0 :                         FREE_ADDR_LIST_THEN_RETURN(-1);
     157             :                 }
     158             : 
     159        2616 :                 option_type = PIM_TLV_GET_TYPE(tlv_curr);
     160        2616 :                 tlv_curr += PIM_TLV_TYPE_SIZE;
     161        2616 :                 option_len = PIM_TLV_GET_LENGTH(tlv_curr);
     162        2616 :                 tlv_curr += PIM_TLV_LENGTH_SIZE;
     163             : 
     164        2616 :                 if ((tlv_curr + option_len) > tlv_pastend) {
     165           0 :                         if (PIM_DEBUG_PIM_HELLO)
     166           0 :                                 zlog_debug(
     167             :                                         "%s: long PIM hello TLV type=%d length=%d > left=%td from %pPAs on interface %s",
     168             :                                         __func__, option_type, option_len,
     169             :                                         tlv_pastend - tlv_curr, &src_addr,
     170             :                                         ifp->name);
     171           0 :                         FREE_ADDR_LIST_THEN_RETURN(-2);
     172             :                 }
     173             : 
     174        2616 :                 if (PIM_DEBUG_PIM_HELLO)
     175           0 :                         zlog_debug(
     176             :                                 "%s: parse left_size=%d: PIM hello TLV type=%d length=%d from %pPAs on %s",
     177             :                                 __func__, remain, option_type, option_len,
     178             :                                 &src_addr, ifp->name);
     179             : 
     180        2616 :                 switch (option_type) {
     181         590 :                 case PIM_MSG_OPTION_TYPE_HOLDTIME:
     182         590 :                         if (pim_tlv_parse_holdtime(ifp->name, src_addr,
     183             :                                                    &hello_options,
     184             :                                                    &hello_option_holdtime,
     185             :                                                    option_len, tlv_curr)) {
     186           0 :                                 FREE_ADDR_LIST_THEN_RETURN(-3);
     187             :                         }
     188             :                         break;
     189         590 :                 case PIM_MSG_OPTION_TYPE_LAN_PRUNE_DELAY:
     190         590 :                         if (pim_tlv_parse_lan_prune_delay(
     191         590 :                                     ifp->name, src_addr, &hello_options,
     192             :                                     &hello_option_propagation_delay,
     193             :                                     &hello_option_override_interval, option_len,
     194             :                                     tlv_curr)) {
     195           0 :                                 FREE_ADDR_LIST_THEN_RETURN(-4);
     196             :                         }
     197             :                         break;
     198         590 :                 case PIM_MSG_OPTION_TYPE_DR_PRIORITY:
     199         590 :                         if (pim_tlv_parse_dr_priority(ifp->name, src_addr,
     200             :                                                       &hello_options,
     201             :                                                       &hello_option_dr_priority,
     202             :                                                       option_len, tlv_curr)) {
     203           0 :                                 FREE_ADDR_LIST_THEN_RETURN(-5);
     204             :                         }
     205             :                         break;
     206         590 :                 case PIM_MSG_OPTION_TYPE_GENERATION_ID:
     207         590 :                         if (pim_tlv_parse_generation_id(
     208         590 :                                     ifp->name, src_addr, &hello_options,
     209             :                                     &hello_option_generation_id, option_len,
     210             :                                     tlv_curr)) {
     211           0 :                                 FREE_ADDR_LIST_THEN_RETURN(-6);
     212             :                         }
     213             :                         break;
     214         256 :                 case PIM_MSG_OPTION_TYPE_ADDRESS_LIST:
     215         256 :                         if (pim_tlv_parse_addr_list(ifp->name, src_addr,
     216             :                                                     &hello_options,
     217             :                                                     &hello_option_addr_list,
     218             :                                                     option_len, tlv_curr)) {
     219             :                                 return -7;
     220             :                         }
     221             :                         break;
     222           0 :                 case PIM_MSG_OPTION_TYPE_DM_STATE_REFRESH:
     223           0 :                         if (PIM_DEBUG_PIM_HELLO)
     224           0 :                                 zlog_debug(
     225             :                                         "%s: ignoring PIM hello dense-mode state refresh TLV option type=%d length=%d from %pPAs on interface %s",
     226             :                                         __func__, option_type, option_len,
     227             :                                         &src_addr, ifp->name);
     228             :                         break;
     229           0 :                 default:
     230           0 :                         if (PIM_DEBUG_PIM_HELLO)
     231           0 :                                 zlog_debug(
     232             :                                         "%s: ignoring unknown PIM hello TLV type=%d length=%d from %pPAs on interface %s",
     233             :                                         __func__, option_type, option_len,
     234             :                                         &src_addr, ifp->name);
     235             :                 }
     236             : 
     237             :                 tlv_curr += option_len;
     238             :         }
     239             : 
     240             :         /*
     241             :           Check received PIM hello options
     242             :         */
     243             : 
     244         590 :         if (PIM_DEBUG_PIM_HELLO) {
     245           0 :                 tlv_trace_uint16(__func__, "holdtime", ifp->name, src_addr,
     246           0 :                                  PIM_OPTION_IS_SET(hello_options,
     247             :                                                    PIM_OPTION_MASK_HOLDTIME),
     248             :                                  hello_option_holdtime);
     249           0 :                 tlv_trace_uint16(
     250           0 :                         __func__, "propagation_delay", ifp->name, src_addr,
     251           0 :                         PIM_OPTION_IS_SET(hello_options,
     252             :                                           PIM_OPTION_MASK_LAN_PRUNE_DELAY),
     253             :                         hello_option_propagation_delay);
     254           0 :                 tlv_trace_uint16(
     255           0 :                         __func__, "override_interval", ifp->name, src_addr,
     256           0 :                         PIM_OPTION_IS_SET(hello_options,
     257             :                                           PIM_OPTION_MASK_LAN_PRUNE_DELAY),
     258             :                         hello_option_override_interval);
     259           0 :                 tlv_trace_bool(
     260           0 :                         __func__, "can_disable_join_suppression", ifp->name,
     261             :                         src_addr,
     262             :                         PIM_OPTION_IS_SET(hello_options,
     263             :                                           PIM_OPTION_MASK_LAN_PRUNE_DELAY),
     264           0 :                         PIM_OPTION_IS_SET(
     265             :                                 hello_options,
     266             :                                 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION));
     267           0 :                 tlv_trace_uint32(__func__, "dr_priority", ifp->name, src_addr,
     268           0 :                                  PIM_OPTION_IS_SET(hello_options,
     269             :                                                    PIM_OPTION_MASK_DR_PRIORITY),
     270             :                                  hello_option_dr_priority);
     271           0 :                 tlv_trace_uint32_hex(
     272           0 :                         __func__, "generation_id", ifp->name, src_addr,
     273           0 :                         PIM_OPTION_IS_SET(hello_options,
     274             :                                           PIM_OPTION_MASK_GENERATION_ID),
     275             :                         hello_option_generation_id);
     276           0 :                 tlv_trace_list(__func__, "address_list", ifp->name, src_addr,
     277           0 :                                PIM_OPTION_IS_SET(hello_options,
     278             :                                                  PIM_OPTION_MASK_ADDRESS_LIST),
     279             :                                hello_option_addr_list);
     280             :         }
     281             : 
     282         590 :         if (!PIM_OPTION_IS_SET(hello_options, PIM_OPTION_MASK_HOLDTIME)) {
     283           0 :                 if (PIM_DEBUG_PIM_HELLO)
     284           0 :                         zlog_debug(
     285             :                                 "%s: PIM hello missing holdtime from %pPAs on interface %s",
     286             :                                 __func__, &src_addr, ifp->name);
     287             :         }
     288             : 
     289             :         /*
     290             :           New neighbor?
     291             :         */
     292             : 
     293         590 :         neigh = pim_neighbor_find(ifp, src_addr);
     294         590 :         if (!neigh) {
     295             :                 /* Add as new neighbor */
     296             : 
     297          37 :                 neigh = pim_neighbor_add(
     298             :                         ifp, src_addr, hello_options, hello_option_holdtime,
     299             :                         hello_option_propagation_delay,
     300             :                         hello_option_override_interval,
     301             :                         hello_option_dr_priority, hello_option_generation_id,
     302             :                         hello_option_addr_list, PIM_NEIGHBOR_SEND_DELAY);
     303          37 :                 if (!neigh) {
     304           0 :                         if (PIM_DEBUG_PIM_HELLO)
     305           0 :                                 zlog_warn(
     306             :                                         "%s: failure creating PIM neighbor %pPAs on interface %s",
     307             :                                         __func__, &src_addr, ifp->name);
     308           0 :                         FREE_ADDR_LIST_THEN_RETURN(-8);
     309             :                 }
     310             :                 /* Forward BSM if required */
     311          37 :                 if (!pim_bsm_new_nbr_fwd(neigh, ifp)) {
     312          37 :                         if (PIM_DEBUG_PIM_HELLO)
     313           0 :                                 zlog_debug(
     314             :                                         "%s: forwarding bsm to new nbr failed",
     315             :                                         __func__);
     316             :                 }
     317             : 
     318             :                 /* actual addr list has been saved under neighbor */
     319          37 :                 return 0;
     320             :         }
     321             : 
     322             :         /*
     323             :           Received generation ID ?
     324             :         */
     325             : 
     326         553 :         if (PIM_OPTION_IS_SET(hello_options, PIM_OPTION_MASK_GENERATION_ID)) {
     327             :                 /* GenID mismatch ? */
     328         553 :                 if (!PIM_OPTION_IS_SET(neigh->hello_options,
     329             :                                        PIM_OPTION_MASK_GENERATION_ID)
     330         553 :                     || (hello_option_generation_id != neigh->generation_id)) {
     331             :                         /* GenID mismatch, then replace neighbor */
     332             : 
     333           1 :                         if (PIM_DEBUG_PIM_HELLO)
     334           0 :                                 zlog_debug(
     335             :                                         "%s: GenId mismatch new=%08x old=%08x: replacing neighbor %pPAs on %s",
     336             :                                         __func__, hello_option_generation_id,
     337             :                                         neigh->generation_id, &src_addr,
     338             :                                         ifp->name);
     339             : 
     340           1 :                         pim_upstream_rpf_genid_changed(pim_ifp->pim,
     341             :                                                        neigh->source_addr);
     342             : 
     343           1 :                         pim_neighbor_delete(ifp, neigh, "GenID mismatch");
     344           1 :                         neigh = pim_neighbor_add(ifp, src_addr, hello_options,
     345             :                                                  hello_option_holdtime,
     346             :                                                  hello_option_propagation_delay,
     347             :                                                  hello_option_override_interval,
     348             :                                                  hello_option_dr_priority,
     349             :                                                  hello_option_generation_id,
     350             :                                                  hello_option_addr_list,
     351             :                                                  PIM_NEIGHBOR_SEND_NOW);
     352           1 :                         if (!neigh) {
     353           0 :                                 if (PIM_DEBUG_PIM_HELLO)
     354           0 :                                         zlog_debug(
     355             :                                                 "%s: failure re-creating PIM neighbor %pPAs on interface %s",
     356             :                                                 __func__, &src_addr, ifp->name);
     357           0 :                                 FREE_ADDR_LIST_THEN_RETURN(-9);
     358             :                         }
     359             :                         /* Forward BSM if required */
     360           1 :                         if (!pim_bsm_new_nbr_fwd(neigh, ifp)) {
     361           1 :                                 if (PIM_DEBUG_PIM_HELLO)
     362           0 :                                         zlog_debug(
     363             :                                                 "%s: forwarding bsm to new nbr failed",
     364             :                                                 __func__);
     365             :                         }
     366             :                         /* actual addr list is saved under neighbor */
     367           1 :                         return 0;
     368             : 
     369             :                 } /* GenId mismatch: replace neighbor */
     370             : 
     371             :         } /* GenId received */
     372             : 
     373             :         /*
     374             :           Update existing neighbor
     375             :         */
     376             : 
     377         552 :         pim_neighbor_update(neigh, hello_options, hello_option_holdtime,
     378             :                             hello_option_dr_priority, hello_option_addr_list);
     379             :         /* actual addr list is saved under neighbor */
     380         552 :         return 0;
     381             : }
     382             : 
     383         823 : int pim_hello_build_tlv(struct interface *ifp, uint8_t *tlv_buf,
     384             :                         int tlv_buf_size, uint16_t holdtime,
     385             :                         uint32_t dr_priority, uint32_t generation_id,
     386             :                         uint16_t propagation_delay, uint16_t override_interval,
     387             :                         int can_disable_join_suppression)
     388             : {
     389         823 :         uint8_t *curr = tlv_buf;
     390         823 :         uint8_t *pastend = tlv_buf + tlv_buf_size;
     391         823 :         uint8_t *tmp;
     392             : #if PIM_IPV == 4
     393         321 :         struct pim_interface *pim_ifp = ifp->info;
     394         321 :         struct pim_instance *pim = pim_ifp->pim;
     395             : #endif
     396             : 
     397             :         /*
     398             :          * Append options
     399             :          */
     400             : 
     401             :         /* Holdtime */
     402         823 :         curr = pim_tlv_append_uint16(curr, pastend,
     403             :                                      PIM_MSG_OPTION_TYPE_HOLDTIME, holdtime);
     404         823 :         if (!curr) {
     405           0 :                 if (PIM_DEBUG_PIM_HELLO) {
     406           0 :                         zlog_debug(
     407             :                                 "%s: could not set PIM hello Holdtime option for interface %s",
     408             :                                 __func__, ifp->name);
     409             :                 }
     410           0 :                 return -1;
     411             :         }
     412             : 
     413             :         /* LAN Prune Delay */
     414         823 :         tmp = pim_tlv_append_2uint16(curr, pastend,
     415             :                                      PIM_MSG_OPTION_TYPE_LAN_PRUNE_DELAY,
     416             :                                      propagation_delay, override_interval);
     417         823 :         if (!tmp) {
     418           0 :                 if (PIM_DEBUG_PIM_HELLO) {
     419           0 :                         zlog_debug(
     420             :                                 "%s: could not set PIM LAN Prune Delay option for interface %s",
     421             :                                 __func__, ifp->name);
     422             :                 }
     423           0 :                 return -1;
     424             :         }
     425         823 :         if (can_disable_join_suppression) {
     426           0 :                 *(curr + 4) |= 0x80; /* enable T bit */
     427             :         }
     428         823 :         curr = tmp;
     429             : 
     430             :         /* DR Priority */
     431         823 :         curr = pim_tlv_append_uint32(
     432             :                 curr, pastend, PIM_MSG_OPTION_TYPE_DR_PRIORITY, dr_priority);
     433         823 :         if (!curr) {
     434           0 :                 if (PIM_DEBUG_PIM_HELLO) {
     435           0 :                         zlog_debug(
     436             :                                 "%s: could not set PIM hello DR Priority option for interface %s",
     437             :                                 __func__, ifp->name);
     438             :                 }
     439           0 :                 return -2;
     440             :         }
     441             : 
     442             :         /* Generation ID */
     443         823 :         curr = pim_tlv_append_uint32(curr, pastend,
     444             :                                      PIM_MSG_OPTION_TYPE_GENERATION_ID,
     445             :                                      generation_id);
     446         823 :         if (!curr) {
     447           0 :                 if (PIM_DEBUG_PIM_HELLO) {
     448           0 :                         zlog_debug(
     449             :                                 "%s: could not set PIM hello Generation ID option for interface %s",
     450             :                                 __func__, ifp->name);
     451             :                 }
     452           0 :                 return -3;
     453             :         }
     454             : 
     455             :         /* Secondary Address List */
     456         823 :         if (ifp->connected->count) {
     457         823 :                 curr = pim_tlv_append_addrlist_ucast(curr, pastend, ifp,
     458             :                                                      PIM_AF);
     459         823 :                 if (!curr) {
     460           0 :                         if (PIM_DEBUG_PIM_HELLO) {
     461           0 :                                 zlog_debug(
     462             :                                         "%s: could not set PIM hello %s Secondary Address List option for interface %s",
     463             :                                         __func__, PIM_AF_NAME, ifp->name);
     464             :                         }
     465           0 :                         return -4;
     466             :                 }
     467             : #if PIM_IPV == 4
     468         321 :                 if (pim->send_v6_secondary) {
     469         321 :                         curr = pim_tlv_append_addrlist_ucast(curr, pastend, ifp,
     470             :                                                              AF_INET6);
     471         321 :                         if (!curr) {
     472           0 :                                 if (PIM_DEBUG_PIM_HELLO) {
     473           0 :                                         zlog_debug(
     474             :                                                 "%s: could not sent PIM hello v6 secondary Address List option for interface %s",
     475             :                                                 __func__, ifp->name);
     476             :                                 }
     477           0 :                                 return -4;
     478             :                         }
     479             :                 }
     480             : #endif
     481             :         }
     482             : 
     483         823 :         return curr - tlv_buf;
     484             : }
     485             : 
     486             : /*
     487             :   RFC 4601: 4.3.1.  Sending Hello Messages
     488             : 
     489             :   Thus, if a router needs to send a Join/Prune or Assert message on an
     490             :   interface on which it has not yet sent a Hello message with the
     491             :   currently configured IP address, then it MUST immediately send the
     492             :   relevant Hello message without waiting for the Hello Timer to
     493             :   expire, followed by the Join/Prune or Assert message.
     494             : */
     495          19 : void pim_hello_require(struct interface *ifp)
     496             : {
     497          19 :         struct pim_interface *pim_ifp;
     498             : 
     499          19 :         assert(ifp);
     500             : 
     501          19 :         pim_ifp = ifp->info;
     502             : 
     503          19 :         assert(pim_ifp);
     504             : 
     505          19 :         if (PIM_IF_FLAG_TEST_HELLO_SENT(pim_ifp->flags))
     506             :                 return;
     507             : 
     508           0 :         pim_hello_restart_now(ifp); /* Send hello and restart timer */
     509             : }

Generated by: LCOV version v1.16-topotato