]>
Commit | Line | Data |
---|---|---|
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 | 21 | static 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 |
45 | void 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 | 59 | static 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 | 66 | int 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 |
87 | int 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 | 118 | void *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 | 127 | void 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 | } |