]> git.proxmox.com Git - mirror_frr.git/blob - pimd/pim_msg.h
Merge pull request #13522 from LabNConsulting/chopps/fix-bgp-test
[mirror_frr.git] / pimd / pim_msg.h
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * PIM for Quagga
4 * Copyright (C) 2008 Everton da Silva Marques
5 */
6
7 #ifndef PIM_MSG_H
8 #define PIM_MSG_H
9
10 #include <netinet/in.h>
11 #if PIM_IPV == 6
12 #include <netinet/ip6.h>
13 #endif
14
15 #include "pim_jp_agg.h"
16
17 #define PIM_HDR_LEN sizeof(struct pim_msg_header)
18 /*
19 Number Description
20 ---------- ------------------
21 0 Reserved
22 1 IP (IP version 4)
23 2 IP6 (IP version 6)
24
25 From:
26 http://www.iana.org/assignments/address-family-numbers
27 */
28 enum pim_msg_address_family {
29 PIM_MSG_ADDRESS_FAMILY_RESERVED,
30 PIM_MSG_ADDRESS_FAMILY_IPV4,
31 PIM_MSG_ADDRESS_FAMILY_IPV6,
32 };
33
34 /*
35 * pim_msg_hdr
36 * =========================
37 * PIM Header definition as per RFC 5059. N bit introduced to indicate
38 * do-not-forward option in PIM Boot strap Message.
39 * 0 1 2 3
40 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
41 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
42 * |PIM Ver| Type |N| Reserved | Checksum |
43 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44 */
45 struct pim_msg_header {
46 #if (BYTE_ORDER == LITTLE_ENDIAN)
47 uint8_t type : 4;
48 uint8_t ver : 4;
49 uint8_t reserved : 7;
50 uint8_t Nbit : 1; /* No Fwd Bit */
51 #elif (BYTE_ORDER == BIG_ENDIAN)
52 uint8_t ver : 4;
53 uint8_t type : 4;
54 uint8_t Nbit : 1; /* No Fwd Bit */
55 uint8_t reserved : 7;
56 #else
57 #error"Please set byte order"
58 #endif
59 uint16_t checksum;
60 } __attribute__((packed));
61
62 struct pim_encoded_ipv4_unicast {
63 uint8_t family;
64 uint8_t reserved;
65 struct in_addr addr;
66 } __attribute__((packed));
67
68 struct pim_encoded_ipv6_unicast {
69 uint8_t family;
70 uint8_t reserved;
71 struct in6_addr addr;
72 } __attribute__((packed));
73
74 /*
75 * Encoded Group format. RFC 4601 Sec 4.9.1
76 * 0 1 2 3
77 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
78 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
79 * | Addr Family | Encoding Type |B| Reserved |Z| Mask Len |
80 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
81 * | Group multicast Address
82 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+...
83 */
84 struct pim_encoded_group_ipv4 {
85 uint8_t family;
86 uint8_t ne;
87 #if (BYTE_ORDER == LITTLE_ENDIAN)
88 uint8_t sz : 1; /* scope zone bit */
89 uint8_t reserved : 6; /* Reserved */
90 uint8_t bidir : 1; /* Bidir bit */
91 #elif (BYTE_ORDER == BIG_ENDIAN)
92 uint8_t bidir : 1; /* Bidir bit */
93 uint8_t reserved : 6; /* Reserved */
94 uint8_t sz : 1; /* scope zone bit */
95 #else
96 #error"Please set byte order"
97 #endif
98 uint8_t mask;
99 struct in_addr addr;
100 } __attribute__((packed));
101
102 struct pim_encoded_group_ipv6 {
103 uint8_t family;
104 uint8_t ne;
105 #if (BYTE_ORDER == LITTLE_ENDIAN)
106 uint8_t sz : 1; /* scope zone bit */
107 uint8_t reserved : 6; /* Reserved */
108 uint8_t bidir : 1; /* Bidir bit */
109 #elif (BYTE_ORDER == BIG_ENDIAN)
110 uint8_t bidir : 1; /* Bidir bit */
111 uint8_t reserved : 6; /* Reserved */
112 uint8_t sz : 1; /* scope zone bit */
113 #else
114 #error "Please set byte order"
115 #endif
116 uint8_t mask;
117 struct in6_addr addr;
118 } __attribute__((packed));
119
120 /*
121 * Encoded Source format. RFC 4601 Sec 4.9.1
122 * 0 1 2 3
123 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
124 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
125 * | Addr Family | Encoding Type | Rsrvd |S|W|R| Mask Len |
126 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
127 * | Source Address
128 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-...
129 */
130 struct pim_encoded_source_ipv4 {
131 uint8_t family;
132 uint8_t ne;
133 uint8_t bits;
134 uint8_t mask;
135 struct in_addr addr;
136 } __attribute__((packed));
137
138 struct pim_encoded_source_ipv6 {
139 uint8_t family;
140 uint8_t ne;
141 uint8_t bits;
142 uint8_t mask;
143 struct in6_addr addr;
144 } __attribute__((packed));
145
146 /* clang-format off */
147 #if PIM_IPV == 4
148 typedef struct pim_encoded_ipv4_unicast pim_encoded_unicast;
149 typedef struct pim_encoded_group_ipv4 pim_encoded_group;
150 typedef struct pim_encoded_source_ipv4 pim_encoded_source;
151 typedef struct ip ipv_hdr;
152 #define IPV_SRC(ip_hdr) ((ip_hdr))->ip_src
153 #define IPV_DST(ip_hdr) ((ip_hdr))->ip_dst
154 #define IPV_LEN(ip_hdr) ((ip_hdr))->ip_len
155 #else
156 typedef struct pim_encoded_ipv6_unicast pim_encoded_unicast;
157 typedef struct pim_encoded_group_ipv6 pim_encoded_group;
158 typedef struct pim_encoded_source_ipv6 pim_encoded_source;
159 typedef struct ip6_hdr ipv_hdr;
160 #define IPV_SRC(ip_hdr) ((ip_hdr))->ip6_src
161 #define IPV_DST(ip_hdr) ((ip_hdr))->ip6_dst
162 #define IPV_LEN(ip_hdr) ((ip_hdr))->ip6_plen
163 #endif
164 /* clang-format on */
165
166 struct pim_jp_groups {
167 pim_encoded_group g;
168 uint16_t joins;
169 uint16_t prunes;
170 pim_encoded_source s[1];
171 } __attribute__((packed));
172
173 struct pim_jp {
174 struct pim_msg_header header;
175 pim_encoded_unicast addr;
176 uint8_t reserved;
177 uint8_t num_groups;
178 uint16_t holdtime;
179 struct pim_jp_groups groups[1];
180 } __attribute__((packed));
181
182 #if PIM_IPV == 4
183 static inline pim_sgaddr pim_sgaddr_from_iphdr(const void *iphdr)
184 {
185 const struct ip *ipv4_hdr = iphdr;
186 pim_sgaddr sg;
187
188 sg.src = ipv4_hdr->ip_src;
189 sg.grp = ipv4_hdr->ip_dst;
190
191 return sg;
192 }
193 #else
194 static inline pim_sgaddr pim_sgaddr_from_iphdr(const void *iphdr)
195 {
196 const struct ip6_hdr *ipv6_hdr = iphdr;
197 pim_sgaddr sg;
198
199 sg.src = ipv6_hdr->ip6_src;
200 sg.grp = ipv6_hdr->ip6_dst;
201
202 return sg;
203 }
204 #endif
205
206 void pim_msg_build_header(pim_addr src, pim_addr dst, uint8_t *pim_msg,
207 size_t pim_msg_size, uint8_t pim_msg_type,
208 bool no_fwd);
209 uint8_t *pim_msg_addr_encode_ipv4_ucast(uint8_t *buf, struct in_addr addr);
210 uint8_t *pim_msg_addr_encode_ipv4_group(uint8_t *buf, struct in_addr addr);
211
212 #define PIM_ENCODE_SPARSE_BIT 0x04
213 #define PIM_ENCODE_WC_BIT 0x02
214 #define PIM_ENCODE_RPT_BIT 0x01
215 uint8_t *pim_msg_addr_encode_ipv4_source(uint8_t *buf, struct in_addr addr,
216 uint8_t bits);
217
218 uint8_t *pim_msg_addr_encode_ipv6_ucast(uint8_t *buf, struct in6_addr addr);
219 uint8_t *pim_msg_addr_encode_ipv6_group(uint8_t *buf, struct in6_addr addr);
220 uint8_t *pim_msg_addr_encode_ipv6_source(uint8_t *buf, struct in6_addr addr,
221 uint8_t bits);
222
223 uint8_t *pim_msg_addr_encode_ucast(uint8_t *buf, pim_addr addr);
224 uint8_t *pim_msg_addr_encode_group(uint8_t *buf, pim_addr addr);
225 uint8_t *pim_msg_addr_encode_source(uint8_t *buf, pim_addr addr, uint8_t bits);
226
227 size_t pim_msg_get_jp_group_size(struct list *sources);
228 size_t pim_msg_build_jp_groups(struct pim_jp_groups *grp,
229 struct pim_jp_agg_group *sgs, size_t size);
230 #endif /* PIM_MSG_H */