]> git.proxmox.com Git - mirror_frr.git/blob - pimd/pim6_mld_protocol.h
bgpd: fix the IGP metric for best path selection on VPN import
[mirror_frr.git] / pimd / pim6_mld_protocol.h
1 /*
2 * MLD protocol definitions
3 * Copyright (C) 2022 David Lamparter for NetDEF, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation; either version 2 of the License, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; see the file COPYING; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #ifndef _PIM6_MLD_PROTOCOL_H
21 #define _PIM6_MLD_PROTOCOL_H
22
23 #include <stdalign.h>
24 #include <stdint.h>
25
26 /* There is a struct icmp6_hdr provided by OS, but it includes 4 bytes of data.
27 * Not helpful for us if we want to put the MLD struct after it.
28 */
29
30 struct icmp6_plain_hdr {
31 uint8_t icmp6_type;
32 uint8_t icmp6_code;
33 uint16_t icmp6_cksum;
34 };
35 static_assert(sizeof(struct icmp6_plain_hdr) == 4, "struct mismatch");
36 static_assert(alignof(struct icmp6_plain_hdr) <= 4, "struct mismatch");
37
38 /* for MLDv1 query, report and leave all use the same packet format */
39 struct mld_v1_pkt {
40 uint16_t max_resp_code;
41 uint16_t rsvd0;
42 struct in6_addr grp;
43 };
44 static_assert(sizeof(struct mld_v1_pkt) == 20, "struct mismatch");
45 static_assert(alignof(struct mld_v1_pkt) <= 4, "struct mismatch");
46
47
48 struct mld_v2_query_hdr {
49 uint16_t max_resp_code;
50 uint16_t rsvd0;
51 struct in6_addr grp;
52 uint8_t flags;
53 uint8_t qqic;
54 uint16_t n_src;
55 struct in6_addr srcs[0];
56 };
57 static_assert(sizeof(struct mld_v2_query_hdr) == 24, "struct mismatch");
58 static_assert(alignof(struct mld_v2_query_hdr) <= 4, "struct mismatch");
59
60
61 struct mld_v2_report_hdr {
62 uint16_t rsvd;
63 uint16_t n_records;
64 };
65 static_assert(sizeof(struct mld_v2_report_hdr) == 4, "struct mismatch");
66 static_assert(alignof(struct mld_v2_report_hdr) <= 4, "struct mismatch");
67
68
69 struct mld_v2_rec_hdr {
70 uint8_t type;
71 uint8_t aux_len;
72 uint16_t n_src;
73 struct in6_addr grp;
74 struct in6_addr srcs[0];
75 };
76 static_assert(sizeof(struct mld_v2_rec_hdr) == 20, "struct mismatch");
77 static_assert(alignof(struct mld_v2_rec_hdr) <= 4, "struct mismatch");
78
79 /* clang-format off */
80 enum icmp6_mld_type {
81 ICMP6_MLD_QUERY = 130,
82 ICMP6_MLD_V1_REPORT = 131,
83 ICMP6_MLD_V1_DONE = 132,
84 ICMP6_MLD_V2_REPORT = 143,
85 };
86
87 enum mld_v2_rec_type {
88 MLD_RECTYPE_IS_INCLUDE = 1,
89 MLD_RECTYPE_IS_EXCLUDE = 2,
90 MLD_RECTYPE_CHANGE_TO_INCLUDE = 3,
91 MLD_RECTYPE_CHANGE_TO_EXCLUDE = 4,
92 MLD_RECTYPE_ALLOW_NEW_SOURCES = 5,
93 MLD_RECTYPE_BLOCK_OLD_SOURCES = 6,
94 };
95 /* clang-format on */
96
97 /* helper functions */
98
99 static inline unsigned int mld_max_resp_decode(uint16_t wire)
100 {
101 uint16_t code = ntohs(wire);
102 uint8_t exp;
103
104 if (code < 0x8000)
105 return code;
106 exp = (code >> 12) & 0x7;
107 return ((code & 0xfff) | 0x1000) << (exp + 3);
108 }
109
110 static inline uint16_t mld_max_resp_encode(uint32_t value)
111 {
112 uint16_t code;
113 uint8_t exp;
114
115 if (value < 0x8000)
116 code = value;
117 else {
118 exp = 16 - __builtin_clz(value);
119 code = (value >> (exp + 3)) & 0xfff;
120 code |= 0x8000 | (exp << 12);
121 }
122 return htons(code);
123 }
124
125 #endif /* _PIM6_MLD_PROTOCOL_H */