OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
gmp_host.h
Go to the documentation of this file.
1 /* $Id: gmp_host.h 362048 2010-02-09 00:25:11Z builder $
2  *
3  * gmp_host.h - External definitions for gmp_host
4  *
5  * Dave Katz, March 2008
6  *
7  * Copyright (c) 2008, Juniper Networks, Inc.
8  * All rights reserved.
9  *
10  * This file contains the external definitions for host-side GMP. It should
11  * be included by code calling the host side.
12  */
13 
14 #ifndef __GMP_HOST_H__
15 #define __GMP_HOST_H__
16 
17 
18 /*
19  * Overview
20  *
21  * The gmph_* files define the host side of IGMP/MLD. This part of the
22  * protocol initiates requests for listening to multicast groups and
23  * responds to incoming Query packets from the router side.
24  *
25  * This code supports multiple instances. An instance is simply a
26  * grouping of interfaces and clients accessing those interfaces; an
27  * interface can be bound to one and only one instance, as is a
28  * client. The use of multiple instances may or may not be desirable
29  * depending on the circumstances of the application; combining or
30  * separating instances has no semantic impact from the standpoint of
31  * this code.
32  *
33  * Within an instance, one or more interfaces are bound to the instance; as
34  * outlined above, a set of interfaces semantically defines an instance.
35  * Interfaces are completely independent of one another. An interface
36  * is described by a gmpx_intf_id, which is an opaque type defined in the
37  * application's gmpx_environment.h file. This code neither knows nor
38  * cares about the actual data type (common values are pointers to an
39  * application data structure or an IFL index); the only requirement is
40  * that the data type is scalar and that the value is unique per interface.
41  * I/O is performed by passing the interface ID to and from the application's
42  * supplied I/O routines.
43  *
44  * Also within an instance, one or more clients are bound. A client is a
45  * single requestor of multicast traffic; the most typical binding is to
46  * a single user process. This code combines the possibly-overlapping
47  * requests from multiple clients to create the GMP interface state in such
48  * a way as to guarantee that requested traffic will be delivered. Note that
49  * this means that filtering of received traffic to a client, based on the
50  * actual request from that client, must still take place in the data path
51  * (since one client may include an (S,G) and another may exclude it, for
52  * example.)
53  *
54  * Clients make Listen calls to request or cancel reception of multicast groups.
55  *
56  *
57  * Application call flow
58  *
59  * When an application wants to use GMPH services, it must first create an
60  * instance with gmph_create_instance(). This returns an opaque instance ID
61  * that is used in subsequent calls.
62  *
63  * At least one client is then created with gmph_register().
64  *
65  * Interfaces are then bound to the instance with gmph_attach_intf().
66  * Interfaces and clients may be created in any order.
67  *
68  * Clients then may request or cancel multicast groups by calling gmph_listen()
69  * for the appropriate interface and group. Of course, a client may not
70  * call gmph_listen() for an interface until that interface is bound to the
71  * instance.
72  *
73  *
74  * When tearing down services, clients and interfaces may be torn down
75  * in any order. gmph_detach() is used to get rid of a client. In
76  * this case, gmph_listen() calls to clean up previously requested
77  * groups are unnecessary, and appropriate Leave messages will be
78  * enqueued for transmission.
79  *
80  * gmph_detach_intf() will unceremoniously destroy an interface, along with
81  * any group state bound to it. Any pending Leave messages will be
82  * discarded.
83  *
84  * If a graceful shutdown of an interface is desired,
85  * gmph_detach_intf_soft() can be called instead. The caller supplies
86  * a pointer to a callback routine, and once all pending messages are
87  * sent on the interface, GMP will call back to notify the application
88  * that the interface is being destroyed, and then immediately unbinds
89  * the interface. A subsequent call to gmph_attach_intf(), prior to
90  * the callback, will reanimate the interface and not shut it down,
91  * and no callback will be made. Similarly, a call to
92  * gmph_detach_intf() will unceremoniously and immediately unbind the
93  * interface (and there will be no callback).
94  *
95  * It is up to the application to cause Leaves to be sent for any
96  * joined groups by calling gmph_listen() for each of them (or by
97  * calling gmph_leave_all_groups()) prior to calling
98  * gmph_detach_intf_soft(). Otherwise, any Joins previously sent will
99  * not be countermanded.
100  *
101  * gmph_destroy_instance() is used to get rid of the instance when it
102  * is no longer needed. It will unceremoniously destroy all interface
103  * and client state, and will discard any packets pending
104  * transmission, so it can be called to single-handedly clean up
105  * everything. On the other hand, if a graceful shutdown is required,
106  * gmph_detach_intf_soft() should be called for each interface, and
107  * the application should wait for all callbacks, before destroying
108  * the intstance.
109  *
110  *
111  * Detailed calls
112  *
113  * gmph_create_instance(proto, context)
114  *
115  * Creates an instance, returning an instance ID that is used in subsequent
116  * calls. The context value is an opaque value that is passed through
117  * in timer creation calls.
118  *
119  * gmph_register(instance_id)
120  *
121  * Creates a client, returning a client ID that is used in subsequent calls.
122  *
123  * gmph_attach_intf(instance_id, intf_id)
124  *
125  * Binds an interface to an instance. Once the client is created and the
126  * interface is bound to the instance, listen requests can be made.
127  *
128  * gmph_listen(client_id, intf_id, group, filter_mode, sources)
129  *
130  * Requests or cancels reception of a (*,G) or multiple (S,G)s. A Leave is
131  * signaled by a listen request with filter mode Include and no sources;
132  * all other combinations are joins. The request must be idempotent for
133  * the group; in other words, the group state for the client is set to the
134  * contents of the request. If an additional source is to be added for an
135  * existing group, for instance, all requested sources must be listed on
136  * the request.
137  *
138  * gmph_detach_intf(instance_id, intf_id)
139  *
140  * Unbinds an interface from the instance. All state on the interface
141  * is destroyed immediately, and no Leave messages will be sent.
142  *
143  * gmph_detach_intf_soft(instance_id, intf_id, callback, context)
144  *
145  * Gracefully unbinds an interface from the instance. Once all
146  * necessary packets have been sent, the callback is made (with the
147  * opaque context passed by the caller) and the interface is
148  * destroyed immediately thereafter. If gmph_attach_intf() is called
149  * after this routine, but prior to the callback, it will keep the
150  * interface in existence and no callback will be made. Any enqueued
151  * packets will still be sent.
152  *
153  * gmph_detach(client_id)
154  *
155  * Detaches a client from the instance. Any active Listen requests
156  * from the client will be dealt with appropriately (enqueueing Leave
157  * messages if the client being destroyed is the only one interested in
158  * those groups.)
159  *
160  * gmph_destroy_instance(instance_id)
161  *
162  * Destroys the instance and all state contained therein, immediately. This
163  * will clean up all clients, interfaces, and listen requests, but will not
164  * send appropriate Leave messages.
165  *
166  * gmph_set_intf_version(instance_id, intf_id, version)
167  *
168  * Sets the maximum version number supported by the host. This is generally
169  * not called, since the code will adapt to the version sent by the querier
170  * automatically. Setting the version caps it to the specified value.
171  *
172  * gmph_set_intf_passive(instance_id, intf_id, passive)
173  *
174  * Sets the passive state of the interface to the specified value. If an
175  * interface is passive, the code will not send Report messages under any
176  * circumstances. This is primarily for the benefit of IGMP snooping
177  * switches, which pass host-generated Reports transparently but must keep
178  * aggregated host state on the upstream interfaces.
179  *
180  * gmph_send_intf_groups(instance_id, intf_id)
181  *
182  * Enqueues all group state on the specified interface for transmission.
183  * This is typically used for refreshing upstream state in proxy switches.
184  *
185  * gmph_leave_all_groups(client_id, intf_id)
186  *
187  * Removes all groups listened to on the specified interface by the
188  * specified client. This is equivalent to calling gmph_listen(client_id,
189  * intf_id, group, INCLUDE, NULL) for each group originally listend
190  * go, and will resut in Leaves being sent for these groups if no other
191  * client is listening to them.
192  *
193  * gmph_intf_has_channel(instance_id, intf_id, source, group, exact)
194  *
195  * Returns TRUE if the specified (S,G) has been requested on the
196  * interface, or FALSE if not. If exact matching is requested, it will
197  * return TRUE for a (*,G) call only if a (*,G) request has been made;
198  * if inexact, it will return TRUE for a (*,G) call if one or more (S,G)s
199  * for the same group have been requested.
200  */
201 
202 
203 /*
204  * Soft interface detach callback
205  *
206  * This typedef defines the callback passed as a parameter to
207  * gmph_detach_intf_soft(). This routine will be called after any necessary
208  * packets are transmitted. The interface will cease to exist immediately
209  * after the callback is made.
210  */
211 typedef void (*gmph_soft_detach_callback)(gmp_proto proto,
212  gmpx_intf_id intf_id,
213  void *context);
214 
215 /*
216  * External references
217  */
218 extern gmp_client_id gmph_register(gmp_instance_id instance_id);
219 extern void gmph_detach(gmp_client_id client_id);
220 extern int gmph_listen(gmp_client_id client_id, gmpx_intf_id intf_id,
221  const u_int8_t *group, gmp_filter_mode filter_mode,
222  gmp_addr_thread *addr_thread);
223 extern gmp_instance_id gmph_create_instance(gmp_proto proto, void *context);
224 extern void gmph_destroy_instance(gmp_instance_id instance_id);
225 extern int gmph_set_intf_version(gmp_instance_id instance_id,
226  gmpx_intf_id intf_id, u_int version);
227 extern int gmph_attach_intf(gmp_instance_id instance_id, gmpx_intf_id intf_id);
228 extern int gmph_detach_intf(gmp_instance_id instance_id, gmpx_intf_id intf_id);
229 extern int gmph_detach_intf_soft(gmp_instance_id instance_id,
230  gmpx_intf_id intf_id,
231  gmph_soft_detach_callback callback,
232  void *context);
233 extern int gmph_leave_all_groups(gmp_client_id client_id, gmpx_intf_id intf_id);
234 extern void gmph_send_intf_groups(gmp_instance_id instance_id,
235  gmpx_intf_id intf_id);
236 extern void gmph_set_intf_passive(gmp_instance_id instance_id,
237  gmpx_intf_id intf_id, boolean passive);
238 extern boolean gmph_intf_has_channel(gmp_instance_id instance_id,
239  gmpx_intf_id intf_id,
240  const u_int8_t *source_addr,
241  const u_int8_t *group_addr,
242  boolean exact);
243 
244 #endif /* __GMP_HOST_H__ */
gmp_client_id gmph_register(gmp_instance_id instance_id)
void gmph_destroy_instance(gmp_instance_id instance_id)
void * gmp_instance_id
Definition: gmp.h:32
gmp_instance_id gmph_create_instance(gmp_proto proto, void *context)
gmp_proto
Definition: gmp.h:45
void gmph_detach(gmp_client_id client_id)
int gmph_attach_intf(gmp_instance_id instance_id, gmpx_intf_id intf_id)
void gmph_set_intf_passive(gmp_instance_id instance_id, gmpx_intf_id intf_id, boolean passive)
int gmph_detach_intf(gmp_instance_id instance_id, gmpx_intf_id intf_id)
void(* gmph_soft_detach_callback)(gmp_proto proto, gmpx_intf_id intf_id, void *context)
Definition: gmp_host.h:211
int gmph_listen(gmp_client_id client_id, gmpx_intf_id intf_id, const u_int8_t *group, gmp_filter_mode filter_mode, gmp_addr_thread *addr_thread)
int gmph_detach_intf_soft(gmp_instance_id instance_id, gmpx_intf_id intf_id, gmph_soft_detach_callback callback, void *context)
int gmph_leave_all_groups(gmp_client_id client_id, gmpx_intf_id intf_id)
int gmph_set_intf_version(gmp_instance_id instance_id, gmpx_intf_id intf_id, u_int version)
boolean gmph_intf_has_channel(gmp_instance_id instance_id, gmpx_intf_id intf_id, const u_int8_t *source_addr, const u_int8_t *group_addr, boolean exact)
gmp_filter_mode
Definition: gmp.h:66
void gmph_send_intf_groups(gmp_instance_id instance_id, gmpx_intf_id intf_id)
void * gmp_client_id
Definition: gmp.h:39