2 * Author: Steven Barth <steven at midlink.org>
4 * Copyright 2015 Deutsche Telekom AG
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
21 #include <libubox/list.h>
22 #include <libubox/uloop.h>
23 #include <libubox/avl.h>
24 #include <netinet/in.h>
32 struct querier_iface
{
33 struct list_head head
;
34 struct list_head users
;
35 struct uloop_timeout timeout
;
36 struct groups_config cfg
;
38 struct uloop_fd igmp_fd
;
39 omgp_time_t igmp_next_query
;
40 bool igmp_other_querier
;
41 int igmp_startup_tries
;
43 struct uloop_fd mld_fd
;
44 omgp_time_t mld_next_query
;
45 bool mld_other_querier
;
46 int mld_startup_tries
;
48 struct mrib_querier mrib
;
55 struct querier_user_iface
;
57 typedef void (querier_iface_cb
)(struct querier_user_iface
*user
, const struct in6_addr
*group
,
58 bool include
, const struct in6_addr
*sources
, size_t len
);
61 struct list_head head
;
62 struct groups
*groups
;
63 struct querier
*querier
;
66 struct querier_user_iface
{
67 struct list_head head
;
68 struct querier_user user
;
69 struct querier_iface
*iface
;
70 querier_iface_cb
*user_cb
;
75 int querier_init(struct querier
*querier
);
76 void querier_deinit(struct querier
*querier
);
78 int querier_attach(struct querier_user_iface
*user
, struct querier
*querier
,
79 int ifindex
, querier_iface_cb
*cb
);
80 void querier_detach(struct querier_user_iface
*user
);
86 struct list_head ifaces
;
89 #define QUERIER_MAX_SOURCE 75
90 #define QUERIER_MAX_GROUPS 256
91 #define QUERIER_SUPPRESS (1 << 3)
93 static inline in_addr_t
querier_unmap(const struct in6_addr
*addr6
)
95 return addr6
->s6_addr32
[3];
98 static inline void querier_map(struct in6_addr
*addr6
, in_addr_t addr4
)
100 addr6
->s6_addr32
[0] = 0;
101 addr6
->s6_addr32
[1] = 0;
102 addr6
->s6_addr32
[2] = cpu_to_be32(0xffff);
103 addr6
->s6_addr32
[3] = addr4
;
106 void querier_announce(struct querier_user
*user
, omgp_time_t now
, const struct group
*group
, bool enabled
);
107 void querier_synthesize_events(struct querier
*querier
);
109 int querier_qqi(uint8_t qqic
);
110 int querier_mrd(uint16_t mrc
);
111 uint8_t querier_qqic(int qi
);
112 uint16_t querier_mrc(int mrd
);
115 void igmp_handle(struct mrib_querier
*mrib
, const struct igmphdr
*igmp
, size_t len
,
116 const struct sockaddr_in
*from
);
117 int igmp_send_query(struct querier_iface
*q
,
118 const struct in6_addr
*group
,
119 const struct list_head
*sources
,
123 void mld_handle(struct mrib_querier
*mrib
, const struct mld_hdr
*hdr
, size_t len
,
124 const struct sockaddr_in6
*from
);
125 ssize_t
mld_send_query(struct querier_iface
*q
,
126 const struct in6_addr
*group
,
127 const struct list_head
*sources
,