]> git.proxmox.com Git - mirror_frr.git/blame - pimd/pim_ssm.c
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / pimd / pim_ssm.c
CommitLineData
acddc0ed 1// SPDX-License-Identifier: GPL-2.0-or-later
15a5dafe 2/*
3 * IP SSM ranges for FRR
4 * Copyright (C) 2017 Cumulus Networks, Inc.
15a5dafe 5 */
6
9e6fca3a 7#include <zebra.h>
8
15a5dafe 9#include <lib/linklist.h>
10#include <lib/prefix.h>
11#include <lib/vty.h>
12#include <lib/vrf.h>
13#include <lib/plist.h>
d9ff4302 14#include <lib/lib_errors.h>
15a5dafe 15
16#include "pimd.h"
993e3d8e 17#include "pim_instance.h"
15a5dafe 18#include "pim_ssm.h"
cd6d2858 19#include "pim_igmp.h"
15a5dafe 20
6f439a70 21static void pim_ssm_range_reevaluate(struct pim_instance *pim)
15a5dafe 22{
94120cb2 23#if PIM_IPV == 4
d62a17ae 24 /* 1. Setup register state for (S,G) entries if G has changed from SSM
25 * to
26 * ASM.
27 * 2. check existing (*,G) IGMP registrations to see if they are
28 * still ASM. if they are now SSM delete them.
29 * 3. Allow channel setup for IGMP (*,G) members if G is now ASM
30 * 4. I could tear down all (*,G), (S,G,rpt) states. But that is an
31 * unnecessary sladge hammer and may not be particularly useful as it is
32 * likely the SPT switchover has already happened for flows along such
33 * RPTs.
34 * As for the RPT states it seems that the best thing to do is let them
35 * age
36 * out gracefully. As long as the FHR and LHR do the right thing RPTs
37 * will
38 * disappear in time for SSM groups.
39 */
6f439a70 40 pim_upstream_register_reevaluate(pim);
5d59e408 41 igmp_source_forward_reevaluate_all(pim);
94120cb2 42#endif
15a5dafe 43}
44
6f439a70
DS
45void pim_ssm_prefix_list_update(struct pim_instance *pim,
46 struct prefix_list *plist)
15a5dafe 47{
6f439a70 48 struct pim_ssm *ssm = pim->ssm_info;
15a5dafe 49
d62a17ae 50 if (!ssm->plist_name
51 || strcmp(ssm->plist_name, prefix_list_name(plist))) {
52 /* not ours */
53 return;
54 }
15a5dafe 55
6f439a70 56 pim_ssm_range_reevaluate(pim);
15a5dafe 57}
58
d62a17ae 59static int pim_is_grp_standard_ssm(struct prefix *group)
15a5dafe 60{
95793341 61 pim_addr addr = pim_addr_from_prefix(group);
15a5dafe 62
95793341 63 return pim_addr_ssm(addr);
15a5dafe 64}
65
80d9fa1e 66int pim_is_grp_ssm(struct pim_instance *pim, pim_addr group_addr)
15a5dafe 67{
d62a17ae 68 struct pim_ssm *ssm;
69 struct prefix group;
70 struct prefix_list *plist;
71
80d9fa1e 72 pim_addr_to_prefix(&group, group_addr);
d62a17ae 73
6f439a70 74 ssm = pim->ssm_info;
d62a17ae 75 if (!ssm->plist_name) {
76 return pim_is_grp_standard_ssm(&group);
77 }
78
80d9fa1e 79 plist = prefix_list_lookup(PIM_AFI, ssm->plist_name);
d62a17ae 80 if (!plist)
81 return 0;
82
ab2f9e89
DL
83 return (prefix_list_apply_ext(plist, NULL, &group, true) ==
84 PREFIX_PERMIT);
15a5dafe 85}
86
6f439a70
DS
87int pim_ssm_range_set(struct pim_instance *pim, vrf_id_t vrf_id,
88 const char *plist_name)
15a5dafe 89{
d62a17ae 90 struct pim_ssm *ssm;
91 int change = 0;
92
d3cc1e45 93 if (vrf_id != pim->vrf->vrf_id)
d62a17ae 94 return PIM_SSM_ERR_NO_VRF;
95
6f439a70 96 ssm = pim->ssm_info;
d62a17ae 97 if (plist_name) {
98 if (ssm->plist_name) {
99 if (!strcmp(ssm->plist_name, plist_name))
100 return PIM_SSM_ERR_DUP;
101 XFREE(MTYPE_PIM_FILTER_NAME, ssm->plist_name);
102 }
103 ssm->plist_name = XSTRDUP(MTYPE_PIM_FILTER_NAME, plist_name);
104 change = 1;
105 } else {
106 if (ssm->plist_name) {
107 change = 1;
108 XFREE(MTYPE_PIM_FILTER_NAME, ssm->plist_name);
109 }
110 }
111
112 if (change)
6f439a70 113 pim_ssm_range_reevaluate(pim);
d62a17ae 114
115 return PIM_SSM_ERR_NONE;
15a5dafe 116}
117
e07fe9e6 118void *pim_ssm_init(void)
15a5dafe 119{
d62a17ae 120 struct pim_ssm *ssm;
15a5dafe 121
d62a17ae 122 ssm = XCALLOC(MTYPE_PIM_SSM_INFO, sizeof(*ssm));
15a5dafe 123
d62a17ae 124 return ssm;
15a5dafe 125}
126
d62a17ae 127void pim_ssm_terminate(struct pim_ssm *ssm)
15a5dafe 128{
27cfe222
DS
129 if (!ssm)
130 return;
131
0a22ddfb 132 XFREE(MTYPE_PIM_FILTER_NAME, ssm->plist_name);
27cfe222
DS
133
134 XFREE(MTYPE_PIM_SSM_INFO, ssm);
15a5dafe 135}