Line data Source code
1 : /*
2 : * pim_bsm.h: PIM BSM handling related
3 : *
4 : * Copyright (C) 2018-19 Vmware, Inc.
5 : * Saravanan K
6 : *
7 : * This program is free software; you can redistribute it and/or modify
8 : * it under the terms of the GNU General Public License as published by
9 : * the Free Software Foundation; either version 2 of the License, or
10 : * (at your option) any later version.
11 : *
12 : * This program is distributed in the hope that it will be useful, but
13 : * WITHOUT ANY WARRANTY; without even the implied warranty of
14 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : * General Public License for more details.
16 : *
17 : * You should have received a copy of the GNU General Public License
18 : * along with this program; see the file COPYING; if not, write to the
19 : * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
20 : * MA 02110-1301 USA
21 : */
22 :
23 : #ifndef __PIM_BSM_H__
24 : #define __PIM_BSM_H__
25 :
26 : #include "if.h"
27 : #include "vty.h"
28 : #include "typesafe.h"
29 : #include "table.h"
30 : #include "pim_rp.h"
31 : #include "pim_msg.h"
32 :
33 : /* Defines */
34 : #define PIM_GBL_SZ_ID 0 /* global scope zone id set to 0 */
35 : #define PIM_BS_TIME 60 /* RFC 5059 - Sec 5 */
36 : #define PIM_BSR_DEFAULT_TIMEOUT 130 /* RFC 5059 - Sec 5 */
37 :
38 : /* These structures are only encoded IPv4 specific */
39 : #define PIM_BSM_HDR_LEN sizeof(struct bsm_hdr)
40 : #define PIM_BSM_GRP_LEN sizeof(struct bsmmsg_grpinfo)
41 : #define PIM_BSM_RP_LEN sizeof(struct bsmmsg_rpinfo)
42 :
43 : #define PIM_MIN_BSM_LEN \
44 : (PIM_HDR_LEN + PIM_BSM_HDR_LEN + PIM_BSM_GRP_LEN + PIM_BSM_RP_LEN)
45 :
46 : /* Datastructures
47 : * ==============
48 : */
49 :
50 : /* Non candidate BSR states */
51 : enum ncbsr_state {
52 : NO_INFO = 0,
53 : ACCEPT_ANY,
54 : ACCEPT_PREFERRED
55 : };
56 :
57 : PREDECL_DLIST(bsm_frags);
58 :
59 : /* BSM scope - bsm processing is per scope */
60 : struct bsm_scope {
61 : int sz_id; /* scope zone id */
62 : enum ncbsr_state state; /* non candidate BSR state */
63 : bool accept_nofwd_bsm; /* no fwd bsm accepted for scope */
64 : pim_addr current_bsr; /* current elected BSR for the sz */
65 : uint32_t current_bsr_prio; /* current BSR priority */
66 : int64_t current_bsr_first_ts; /* current BSR elected time */
67 : int64_t current_bsr_last_ts; /* Last BSM received from E-BSR */
68 : uint16_t bsm_frag_tag; /* Last received frag tag from E-BSR */
69 : uint8_t hashMasklen; /* Mask in hash calc RFC 7761 4.7.2 */
70 : struct pim_instance *pim; /* Back pointer to pim instance */
71 :
72 : /* current set of fragments for forwarding */
73 : struct bsm_frags_head bsm_frags[1];
74 :
75 : struct route_table *bsrp_table; /* group2rp mapping rcvd from BSR */
76 : struct thread *bs_timer; /* Boot strap timer */
77 : };
78 :
79 : /* BSM packet (= fragment) - this is stored as list in bsm_frags inside scope
80 : * This is used for forwarding to new neighbors or restarting mcast routers
81 : */
82 : struct bsm_frag {
83 : struct bsm_frags_item item;
84 :
85 : uint32_t size; /* size of the packet */
86 : uint8_t data[0]; /* Actual packet (dyn size) */
87 : };
88 :
89 24 : DECLARE_DLIST(bsm_frags, struct bsm_frag, item);
90 :
91 : PREDECL_SORTLIST_UNIQ(bsm_rpinfos);
92 :
93 : /* This is the group node of the bsrp table in scope.
94 : * this node maintains the list of rp for the group.
95 : */
96 : struct bsgrp_node {
97 : struct prefix group; /* Group range */
98 : struct bsm_scope *scope; /* Back ptr to scope */
99 :
100 : /* RPs advertised by BSR, and temporary list while receiving new set */
101 : struct bsm_rpinfos_head bsrp_list[1];
102 : struct bsm_rpinfos_head partial_bsrp_list[1];
103 :
104 : int pend_rp_cnt; /* Total RP - Received RP */
105 : uint16_t frag_tag; /* frag tag to identify the fragment */
106 : };
107 :
108 : /* Items on [partial_]bsrp_list above.
109 : * Holds info of each candidate RP received for the bsgrp_node's prefix.
110 : */
111 : struct bsm_rpinfo {
112 : struct bsm_rpinfos_item item;
113 :
114 : uint32_t hash; /* Hash Value as per RFC 7761 4.7.2 */
115 : uint32_t elapse_time; /* upd at expiry of elected RP node */
116 : uint16_t rp_prio; /* RP priority */
117 : uint16_t rp_holdtime; /* RP holdtime - g2rp timer value */
118 : pim_addr rp_address; /* RP Address */
119 : struct bsgrp_node *bsgrp_node; /* Back ptr to bsgrp_node */
120 : struct thread *g2rp_timer; /* Run only for elected RP node */
121 : };
122 :
123 : extern int pim_bsm_rpinfo_cmp(const struct bsm_rpinfo *a,
124 : const struct bsm_rpinfo *b);
125 0 : DECLARE_SORTLIST_UNIQ(bsm_rpinfos, struct bsm_rpinfo, item, pim_bsm_rpinfo_cmp);
126 :
127 : /* Structures to extract Bootstrap Message header and Grp to RP Mappings
128 : * =====================================================================
129 : * BSM Format:
130 : *
131 : * 0 1 2 3
132 : * 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
133 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
134 : * |PIM Ver| Type |N| Reserved | Checksum | PIM HDR
135 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
136 : * | Fragment Tag | Hash Mask Len | BSR Priority | BS HDR(1)
137 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
138 : * | BSR Address (Encoded-Unicast format) | BS HDR(2)
139 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
140 : * | Group Address 1 (Encoded-Group format) |
141 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
142 : * | RP Count 1 | Frag RP Cnt 1 | Reserved |
143 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
144 : * | RP Address 1 (Encoded-Unicast format) |
145 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
146 : * | RP1 Holdtime | RP1 Priority | Reserved |
147 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
148 : * | RP Address 2 (Encoded-Unicast format) |
149 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
150 : * | RP2 Holdtime | RP2 Priority | Reserved |
151 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
152 : * | . |
153 : * | . |
154 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
155 : * | RP Address m (Encoded-Unicast format) |
156 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
157 : * | RPm Holdtime | RPm Priority | Reserved |
158 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
159 : * | Group Address 2 (Encoded-Group format) |
160 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
161 : * | . |
162 : * | . |
163 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
164 : * | Group Address n (Encoded-Group format) |
165 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
166 : * | RP Count n | Frag RP Cnt n | Reserved |
167 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
168 : * | RP Address 1 (Encoded-Unicast format) |
169 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
170 : * | RP1 Holdtime | RP1 Priority | Reserved |
171 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
172 : * | RP Address 2 (Encoded-Unicast format) |
173 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
174 : * | RP2 Holdtime | RP2 Priority | Reserved |
175 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
176 : * | . |
177 : * | . |
178 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
179 : * | RP Address m (Encoded-Unicast format) |
180 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
181 : * | RPm Holdtime | RPm Priority | Reserved |
182 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
183 : */
184 : struct bsm_hdr {
185 : uint16_t frag_tag;
186 : uint8_t hm_len;
187 : uint8_t bsr_prio;
188 : #if PIM_IPV == 4
189 : struct pim_encoded_ipv4_unicast bsr_addr;
190 : #else
191 : struct pim_encoded_ipv6_unicast bsr_addr;
192 : #endif
193 : } __attribute__((packed));
194 :
195 : struct bsmmsg_grpinfo {
196 : #if PIM_IPV == 4
197 : struct pim_encoded_group_ipv4 group;
198 : #else
199 : struct pim_encoded_group_ipv6 group;
200 : #endif
201 : uint8_t rp_count;
202 : uint8_t frag_rp_count;
203 : uint16_t reserved;
204 : } __attribute__((packed));
205 :
206 : struct bsmmsg_rpinfo {
207 : #if PIM_IPV == 4
208 : struct pim_encoded_ipv4_unicast rpaddr;
209 : #else
210 : struct pim_encoded_ipv6_unicast rpaddr;
211 : #endif
212 : uint16_t rp_holdtime;
213 : uint8_t rp_pri;
214 : uint8_t reserved;
215 : } __attribute__((packed));
216 :
217 : /* API */
218 : void pim_bsm_proc_init(struct pim_instance *pim);
219 : void pim_bsm_proc_free(struct pim_instance *pim);
220 : void pim_bsm_clear(struct pim_instance *pim);
221 : void pim_bsm_write_config(struct vty *vty, struct interface *ifp);
222 : int pim_bsm_process(struct interface *ifp, pim_sgaddr *sg, uint8_t *buf,
223 : uint32_t buf_size, bool no_fwd);
224 : bool pim_bsm_new_nbr_fwd(struct pim_neighbor *neigh, struct interface *ifp);
225 : struct bsgrp_node *pim_bsm_get_bsgrp_node(struct bsm_scope *scope,
226 : struct prefix *grp);
227 : #endif
|