]> git.proxmox.com Git - mirror_frr.git/blame - pimd/pim6_mld_protocol.h
Merge pull request #11887 from SaiGomathiN/igmptogm
[mirror_frr.git] / pimd / pim6_mld_protocol.h
CommitLineData
5e5034b0
DL
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
30struct icmp6_plain_hdr {
31 uint8_t icmp6_type;
32 uint8_t icmp6_code;
33 uint16_t icmp6_cksum;
34};
35static_assert(sizeof(struct icmp6_plain_hdr) == 4, "struct mismatch");
36static_assert(alignof(struct icmp6_plain_hdr) <= 4, "struct mismatch");
37
38/* for MLDv1 query, report and leave all use the same packet format */
39struct mld_v1_pkt {
40 uint16_t max_resp_code;
41 uint16_t rsvd0;
42 struct in6_addr grp;
43};
44static_assert(sizeof(struct mld_v1_pkt) == 20, "struct mismatch");
45static_assert(alignof(struct mld_v1_pkt) <= 4, "struct mismatch");
46
47
48struct 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};
57static_assert(sizeof(struct mld_v2_query_hdr) == 24, "struct mismatch");
58static_assert(alignof(struct mld_v2_query_hdr) <= 4, "struct mismatch");
59
60
61struct mld_v2_report_hdr {
62 uint16_t rsvd;
63 uint16_t n_records;
64};
65static_assert(sizeof(struct mld_v2_report_hdr) == 4, "struct mismatch");
66static_assert(alignof(struct mld_v2_report_hdr) <= 4, "struct mismatch");
67
68
69struct 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};
76static_assert(sizeof(struct mld_v2_rec_hdr) == 20, "struct mismatch");
77static_assert(alignof(struct mld_v2_rec_hdr) <= 4, "struct mismatch");
78
79/* clang-format off */
80enum 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
87enum 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
99static 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
110static 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 */