back to topotato report
topotato coverage report
Current view: top level - pimd - pim_ssm.c (source / functions) Hit Total Coverage
Test: test_pim_crp.py::PIMCandidateBSRTest Lines: 19 48 39.6 %
Date: 2023-02-16 02:09:37 Functions: 3 5 60.0 %

          Line data    Source code
       1             : /*
       2             :  * IP SSM ranges for FRR
       3             :  * Copyright (C) 2017 Cumulus Networks, Inc.
       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 <lib/linklist.h>
      23             : #include <lib/prefix.h>
      24             : #include <lib/vty.h>
      25             : #include <lib/vrf.h>
      26             : #include <lib/plist.h>
      27             : #include <lib/lib_errors.h>
      28             : 
      29             : #include "pimd.h"
      30             : #include "pim_instance.h"
      31             : #include "pim_ssm.h"
      32             : #include "pim_igmp.h"
      33             : 
      34           0 : static void pim_ssm_range_reevaluate(struct pim_instance *pim)
      35             : {
      36             : #if PIM_IPV == 4
      37             :         /* 1. Setup register state for (S,G) entries if G has changed from SSM
      38             :          * to
      39             :          *    ASM.
      40             :          * 2. check existing (*,G) IGMP registrations to see if they are
      41             :          * still ASM. if they are now SSM delete them.
      42             :          * 3. Allow channel setup for IGMP (*,G) members if G is now ASM
      43             :          * 4. I could tear down all (*,G), (S,G,rpt) states. But that is an
      44             :          * unnecessary sladge hammer and may not be particularly useful as it is
      45             :          * likely the SPT switchover has already happened for flows along such
      46             :          * RPTs.
      47             :          * As for the RPT states it seems that the best thing to do is let them
      48             :          * age
      49             :          * out gracefully. As long as the FHR and LHR do the right thing RPTs
      50             :          * will
      51             :          * disappear in time for SSM groups.
      52             :          */
      53           0 :         pim_upstream_register_reevaluate(pim);
      54           0 :         igmp_source_forward_reevaluate_all(pim);
      55             : #endif
      56           0 : }
      57             : 
      58           0 : void pim_ssm_prefix_list_update(struct pim_instance *pim,
      59             :                                 struct prefix_list *plist)
      60             : {
      61           0 :         struct pim_ssm *ssm = pim->ssm_info;
      62             : 
      63           0 :         if (!ssm->plist_name
      64           0 :             || strcmp(ssm->plist_name, prefix_list_name(plist))) {
      65             :                 /* not ours */
      66           0 :                 return;
      67             :         }
      68             : 
      69           0 :         pim_ssm_range_reevaluate(pim);
      70             : }
      71             : 
      72          72 : static int pim_is_grp_standard_ssm(struct prefix *group)
      73             : {
      74          72 :         pim_addr addr = pim_addr_from_prefix(group);
      75             : 
      76          72 :         return pim_addr_ssm(addr);
      77             : }
      78             : 
      79          72 : int pim_is_grp_ssm(struct pim_instance *pim, pim_addr group_addr)
      80             : {
      81          72 :         struct pim_ssm *ssm;
      82          72 :         struct prefix group;
      83          72 :         struct prefix_list *plist;
      84             : 
      85          72 :         pim_addr_to_prefix(&group, group_addr);
      86             : 
      87          72 :         ssm = pim->ssm_info;
      88          72 :         if (!ssm->plist_name) {
      89          72 :                 return pim_is_grp_standard_ssm(&group);
      90             :         }
      91             : 
      92           0 :         plist = prefix_list_lookup(PIM_AFI, ssm->plist_name);
      93           0 :         if (!plist)
      94             :                 return 0;
      95             : 
      96           0 :         return (prefix_list_apply_ext(plist, NULL, &group, true) ==
      97             :                 PREFIX_PERMIT);
      98             : }
      99             : 
     100           0 : int pim_ssm_range_set(struct pim_instance *pim, vrf_id_t vrf_id,
     101             :                       const char *plist_name)
     102             : {
     103           0 :         struct pim_ssm *ssm;
     104           0 :         int change = 0;
     105             : 
     106           0 :         if (vrf_id != pim->vrf->vrf_id)
     107             :                 return PIM_SSM_ERR_NO_VRF;
     108             : 
     109           0 :         ssm = pim->ssm_info;
     110           0 :         if (plist_name) {
     111           0 :                 if (ssm->plist_name) {
     112           0 :                         if (!strcmp(ssm->plist_name, plist_name))
     113             :                                 return PIM_SSM_ERR_DUP;
     114           0 :                         XFREE(MTYPE_PIM_FILTER_NAME, ssm->plist_name);
     115             :                 }
     116           0 :                 ssm->plist_name = XSTRDUP(MTYPE_PIM_FILTER_NAME, plist_name);
     117           0 :                 change = 1;
     118             :         } else {
     119           0 :                 if (ssm->plist_name) {
     120           0 :                         change = 1;
     121           0 :                         XFREE(MTYPE_PIM_FILTER_NAME, ssm->plist_name);
     122             :                 }
     123             :         }
     124             : 
     125           0 :         if (change)
     126           0 :                 pim_ssm_range_reevaluate(pim);
     127             : 
     128             :         return PIM_SSM_ERR_NONE;
     129             : }
     130             : 
     131           3 : void *pim_ssm_init(void)
     132             : {
     133           3 :         struct pim_ssm *ssm;
     134             : 
     135           3 :         ssm = XCALLOC(MTYPE_PIM_SSM_INFO, sizeof(*ssm));
     136             : 
     137           3 :         return ssm;
     138             : }
     139             : 
     140           3 : void pim_ssm_terminate(struct pim_ssm *ssm)
     141             : {
     142           3 :         if (!ssm)
     143             :                 return;
     144             : 
     145           3 :         XFREE(MTYPE_PIM_FILTER_NAME, ssm->plist_name);
     146             : 
     147           3 :         XFREE(MTYPE_PIM_SSM_INFO, ssm);
     148             : }

Generated by: LCOV version v1.16-topotato