]> git.proxmox.com Git - mirror_frr.git/blame - pimd/pim_msg.h
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / pimd / pim_msg.h
CommitLineData
acddc0ed 1// SPDX-License-Identifier: GPL-2.0-or-later
12e41d03 2/*
896014f4
DL
3 * PIM for Quagga
4 * Copyright (C) 2008 Everton da Silva Marques
896014f4 5 */
12e41d03
DL
6
7#ifndef PIM_MSG_H
8#define PIM_MSG_H
9
10#include <netinet/in.h>
d1fd950a
MR
11#if PIM_IPV == 6
12#include <netinet/ip6.h>
13#endif
12e41d03 14
982bff89 15#include "pim_jp_agg.h"
d57a8bbf 16
17#define PIM_HDR_LEN sizeof(struct pim_msg_header)
12e41d03 18/*
d62a17ae 19 Number Description
12e41d03
DL
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*/
34687162 28enum pim_msg_address_family {
d62a17ae 29 PIM_MSG_ADDRESS_FAMILY_RESERVED,
30 PIM_MSG_ADDRESS_FAMILY_IPV4,
31 PIM_MSG_ADDRESS_FAMILY_IPV6,
34687162 32};
12e41d03 33
70ce34ae 34/*
be6a3245 35 * pim_msg_hdr
d57a8bbf 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 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
70ce34ae
DS
44 */
45struct pim_msg_header {
be6a3245 46#if (BYTE_ORDER == LITTLE_ENDIAN)
d62a17ae 47 uint8_t type : 4;
48 uint8_t ver : 4;
be6a3245
BA
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;
d57a8bbf 54 uint8_t Nbit : 1; /* No Fwd Bit */
55 uint8_t reserved : 7;
be6a3245
BA
56#else
57#error"Please set byte order"
58#endif
d62a17ae 59 uint16_t checksum;
60} __attribute__((packed));
70ce34ae 61
74ac496f 62struct pim_encoded_ipv4_unicast {
d62a17ae 63 uint8_t family;
64 uint8_t reserved;
65 struct in_addr addr;
66} __attribute__((packed));
74ac496f 67
16763d77
DL
68struct pim_encoded_ipv6_unicast {
69 uint8_t family;
70 uint8_t reserved;
71 struct in6_addr addr;
72} __attribute__((packed));
73
71361a2c 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 */
74ac496f 84struct pim_encoded_group_ipv4 {
d62a17ae 85 uint8_t family;
71361a2c 86 uint8_t ne;
be6a3245
BA
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)
d57a8bbf 92 uint8_t bidir : 1; /* Bidir bit */
93 uint8_t reserved : 6; /* Reserved */
94 uint8_t sz : 1; /* scope zone bit */
be6a3245
BA
95#else
96#error"Please set byte order"
97#endif
d62a17ae 98 uint8_t mask;
99 struct in_addr addr;
100} __attribute__((packed));
74ac496f 101
16763d77
DL
102struct 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));
71361a2c 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 */
74ac496f 130struct pim_encoded_source_ipv4 {
d62a17ae 131 uint8_t family;
71361a2c 132 uint8_t ne;
d62a17ae 133 uint8_t bits;
134 uint8_t mask;
135 struct in_addr addr;
136} __attribute__((packed));
74ac496f 137
16763d77
DL
138struct 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
148typedef struct pim_encoded_ipv4_unicast pim_encoded_unicast;
149typedef struct pim_encoded_group_ipv4 pim_encoded_group;
150typedef struct pim_encoded_source_ipv4 pim_encoded_source;
a5fa9822 151typedef 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
16763d77
DL
155#else
156typedef struct pim_encoded_ipv6_unicast pim_encoded_unicast;
157typedef struct pim_encoded_group_ipv6 pim_encoded_group;
158typedef struct pim_encoded_source_ipv6 pim_encoded_source;
a5fa9822 159typedef 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
16763d77
DL
163#endif
164/* clang-format on */
165
74ac496f 166struct pim_jp_groups {
16763d77 167 pim_encoded_group g;
d62a17ae 168 uint16_t joins;
169 uint16_t prunes;
16763d77 170 pim_encoded_source s[1];
d62a17ae 171} __attribute__((packed));
74ac496f
DS
172
173struct pim_jp {
d62a17ae 174 struct pim_msg_header header;
16763d77 175 pim_encoded_unicast addr;
d62a17ae 176 uint8_t reserved;
177 uint8_t num_groups;
178 uint16_t holdtime;
179 struct pim_jp_groups groups[1];
180} __attribute__((packed));
74ac496f 181
d1fd950a
MR
182#if PIM_IPV == 4
183static 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
194static 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
145e4c38
DL
206void 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);
f8e7d799
DS
209uint8_t *pim_msg_addr_encode_ipv4_ucast(uint8_t *buf, struct in_addr addr);
210uint8_t *pim_msg_addr_encode_ipv4_group(uint8_t *buf, struct in_addr addr);
984c84f4
DS
211
212#define PIM_ENCODE_SPARSE_BIT 0x04
213#define PIM_ENCODE_WC_BIT 0x02
214#define PIM_ENCODE_RPT_BIT 0x01
d62a17ae 215uint8_t *pim_msg_addr_encode_ipv4_source(uint8_t *buf, struct in_addr addr,
216 uint8_t bits);
12e41d03 217
16763d77
DL
218uint8_t *pim_msg_addr_encode_ipv6_ucast(uint8_t *buf, struct in6_addr addr);
219uint8_t *pim_msg_addr_encode_ipv6_group(uint8_t *buf, struct in6_addr addr);
220uint8_t *pim_msg_addr_encode_ipv6_source(uint8_t *buf, struct in6_addr addr,
221 uint8_t bits);
222
223uint8_t *pim_msg_addr_encode_ucast(uint8_t *buf, pim_addr addr);
224uint8_t *pim_msg_addr_encode_group(uint8_t *buf, pim_addr addr);
225uint8_t *pim_msg_addr_encode_source(uint8_t *buf, pim_addr addr, uint8_t bits);
346cffe3 226
d62a17ae 227size_t pim_msg_get_jp_group_size(struct list *sources);
228size_t pim_msg_build_jp_groups(struct pim_jp_groups *grp,
229 struct pim_jp_agg_group *sgs, size_t size);
12e41d03 230#endif /* PIM_MSG_H */