OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
gmpr_private.h
Go to the documentation of this file.
1 /* $Id: gmpr_private.h 514187 2012-05-06 12:25:25Z ib-builder $
2  *
3  * gmpr_private.h - Private definitions for GMP Router support
4  *
5  * Dave Katz, March 2008
6  *
7  * Copyright (c) 2008, Juniper Networks, Inc.
8  * All rights reserved.
9  */
10 
11 #ifndef __GMPR_PRIVATE_H__
12 #define __GMPR_PRIVATE_H__
13 
14 /*
15  * This module defines the private data structures for GMP router support.
16  * This file should only be used by the gmp_router code.
17  */
18 
19 
20 /*
21  * Data Structure Overview
22  *
23  * The primary data structure is the instance. There are one or more of
24  * these. An instance is a grouping of interfaces under a protocol (IGMP
25  * or MLD). Multiple instances are required if both IGMP and MLD are
26  * running. Multiple instances within a protocol can be used by clients
27  * if desired (this is likely to be useful only if there are different
28  * clients for some interfaces and they have significantly different needs.)
29  *
30  * An interface structure is created for each interface. The same structure
31  * is used for both the input (protocol) and output (data forwarding) roles.
32  * For generic IGMP, the same interface acts as input and output, but if
33  * OIF mapping is taking place, the protocol may run on one interface and
34  * the data delivered on another. The interface is bound to an instance.
35  *
36  * The group state is kept in several forms. The input state on an interface
37  * corresponds to the aggregation of all host state on an interface. This
38  * is built according to the protocol spec.
39  *
40  * Output state is kept on the output interface. This corresponds to
41  * the forwarding state being built for the interface. In generic
42  * IGMP this is semantically identical to the input state, but if OIF
43  * mapping is used it will differ, and it represents the aggregation
44  * of all input state that is mapped to that output interface.
45  *
46  * Finally, if host tracking is taking place, state is built on a
47  * per-host basis. This is used to allow for immediate leaves and
48  * query suppression (since there will be no ambiguity about when
49  * state is to be deleted.)
50  */
51 
52 /*
53  * Instance entry
54  *
55  * The instance block contains global storage for GMP router support. This
56  * is primarily to ensure that the code remains reentrant (no fixed storage.)
57  * It also allows multiple instances of this code to be running, though the
58  * semantics of that are beyond the scope of this code.
59  *
60  * Note that the tree of interfaces will not be in lexicographic order
61  * by interface ID on little-endian machines.
62  */
63 typedef struct gmpr_instance_ {
64  uint32_t rinst_magic; /* Magic number for robustness */
65  task_thread rinst_thread; /* Link on global instance thread */
66  task_thread rinst_client_thread; /* Head of client task_thread */
67  task_thread rinst_startup_intf_thread; /* Head of intfs starting up */
68 
69  gmpx_patroot *rinst_intfs; /* Tree of interfaces */
70  gmpx_patroot *rinst_global_state_root; /* Root of global state tree */
71  gmp_proto rinst_proto; /* Protocol (IGMP/MLD) */
72  uint32_t rinst_addrlen; /* Address length (v4 or v6) */
73  gmp_addr_catalog rinst_addr_cat; /* Address catalog */
74  uint32_t rinst_min_max_resp; /* Min value of max resp field */
75 
76  ordinal_handle rinst_ord_handle; /* Handle for client ordinals */
77  void *rinst_context; /* Client instance context */
78  gmpr_instance_context rinst_cb_context; /* Instance callbacks */
79 
80  uint32_t rinst_group_timeout; /* Group timeout count */
81 
82  uint32_t rinst_traceflags; /* Trace flags */
83 
84  gmpx_timer *rinst_smear_timer; /* Timer for query timer smearing */
85 
86  boolean rinst_host_tracking; /* TRUE if doing host tracking */
87  boolean rinst_smear_timer_accelerated; /* TRUE if we're smearing soon */
89 
90 THREAD_TO_STRUCT(gmpr_thread_to_instance, gmpr_instance, rinst_thread);
91 
92 /*
93  * Query timer smear values
94  *
95  * In order to deal with large numbers of interfaces, we periodically smear
96  * general query timers to smooth the transmission of queries. In addition,
97  * whenever a new interface is created, we accelerate the smearing so that
98  * it happens not long after the new interfaces arrive.
99  */
100 #define GMP_QUERY_SMEAR_IVL (30*60*MSECS_PER_SEC) /* Half hour seems OK */
101 #define GMP_QUERY_QUICK_SMEAR_IVL (10*MSECS_PER_SEC) /* Quick fix */
102 
103 #define GMPR_INSTANCE_MAGIC 0x52696E73 /* 'Rins' */
104 
105 typedef enum {
110 
111 /*
112  * Interface entry
113  *
114  * One of these entries is created for every interface mentioned by a client.
115  * It is stored on a patricia tree in the instance, keyed by interface index.
116  *
117  * Note that an interface may play one of two roles, or both. The
118  * first role is that of an input interface (one on which IGMP packets
119  * are sent and received.) The other is that of an output interface
120  * (one on which multicast traffic is forwarded.) Normally an
121  * interface plays both roles, but when OIF mapping is taking place,
122  * the two roles may be on different interfaces on a per-group or
123  * per-source basis.
124  */
125 typedef struct gmpr_intf_ {
126 
127  /* Fundamental parameters */
128 
129  gmp_version rintf_ver; /* GMP version running */
131  gmp_addr_string rintf_querier_addr; /* Querier address */
132 
133  /* Linkages */
134 
135  gmpr_instance *rintf_instance; /* Owning instance */
136  gmpx_patnode rintf_inst_patnode; /* Node on instance tree */
137  gmpx_patnode rintf_global_patnode; /* Node on global tree */
138  gmpx_patroot *rintf_group_root; /* Root of aggregated group records */
139  uint32_t rintf_group_count; /* Number of groups */
140  gmpx_patroot *rintf_oif_group_root; /* Root of output group records */
141  uint32_t rintf_oif_group_count; /* Number of output groups */
142  gmpx_intf_id rintf_id; /* Interface ID */
143  gmpx_patroot *rintf_host_root; /* Root of host entries */
144  task_thread rintf_startup_thread; /* Entry on instance startup thread */
145 
146  /* Query stuff */
147 
148  gmpx_timer *rintf_query_timer; /* General query timer */
149  uint32_t rintf_query_ivl; /* General query timer interval */
150  uint32_t rintf_local_query_ivl; /* Local general query interval */
151  uint32_t rintf_query_resp_ivl; /* Query response interval */
152  uint32_t rintf_local_query_resp_ivl; /* Local query response interval */
153  uint32_t rintf_robustness; /* Robustness variable */
154  uint32_t rintf_local_robustness; /* Local robustness variable */
155  uint32_t rintf_lmq_ivl; /* Last member query interval */
156  uint32_t rintf_lmq_count; /* Last member query count */
157  uint32_t rintf_group_membership_ivl; /* Group membership interval */
158  uint32_t rintf_lmqt; /* Last member query time */
159  uint32_t rintf_other_querier_ivl; /* Other querier present interval */
160  gmpx_timer *rintf_other_querier_present; /* Other querier present timer */
161  boolean rintf_suppress_gen_query; /* Suppress general queries */
162  boolean rintf_gen_query_requested; /* General query seq was requested */
163  boolean rintf_first_query_pending; /* First query in sequence ready */
164  boolean rintf_suppress_gs_query; /* Suppress GS/GSS queries */
165 
166  uint32_t rintf_startup_query_count; /* Count of initial queries */
167 
168  uint32_t rintf_channel_limit; /* Max number of channels */
169  uint32_t rintf_channel_threshold; /* Percentage of maximum at which to
170  start generating warnings */
171  uint32_t rintf_log_interval; /* Time between consecutive limit log msgs */
172  time_t last_log_time; /* Time last group limit related message
173  was logged */
174  uint32_t rintf_channel_count; /* Current channel count */
175  uint32_t rintf_chan_limit_drops; /* Count of drops due to chan limit */
176  gmpr_limit_state_t rintf_limit_state; /* if count is above/below chan limit/threshold */
177 
178  /* Transmission stuff */
179 
180  task_thread rintf_xmit_head; /* Head of xmit groups */
181  boolean rintf_xmit_pending; /* TRUE if we have a pending xmit */
182  boolean rintf_send_gen_query; /* TRUE if we should send gen query */
183 
184  boolean rintf_up; /* TRUE if interface is up */
185  boolean rintf_fast_leaves; /* TRUE if doing fast leaves */
186  boolean rintf_querier_enabled; /* TRUE if allowed to be V1 querier */
187  boolean rintf_querier; /* TRUE if we are querier */
188 
189  /* Receive stuff */
190 
191  boolean rintf_passive_receive; /* Passive receive */
192 } gmpr_intf;
193 
194 GMPX_PATNODE_TO_STRUCT(gmpr_inst_patnode_to_intf, gmpr_intf,
195  rintf_inst_patnode);
196 GMPX_PATNODE_TO_STRUCT(gmpr_global_patnode_to_intf, gmpr_intf,
197  rintf_global_patnode);
198 
199 #define GMPR_QUERY_IVL_DEFAULT 125000 /* Default query interval */
200 #define GMPR_QUERY_RESP_IVL_DEFAULT 10000 /* Default query response interval */
201 #define GMPR_INIT_FIRST_QUERY_IVL 100 /* Initial query delay */
202 #define GMPR_INIT_LATER_QUERY_IVL 2000 /* Later startup query delay */
203 #define GMPR_LMQI_DEFAULT 1000 /* Default LMQI value */
204 
205 
206 /*
207  * Notification block
208  *
209  * This block contains linkages for notifications to clients about
210  * changes to GMP state. It is embedded in groups (for notification
211  * of group-wide changes) and address entries (for notification of
212  * source changes.) The same mechanism is used for host-related
213  * notifications, and is embedded in host group and host source
214  * entries in the same way.
215  *
216  * The REFRESH_END type is used to mark the end of a client refresh
217  * sequence; this block is embeded in the client structure itself.
218  *
219  * The type field provides the ability to obtain the address of the
220  * enclosing data structure.
221  *
222  * In order to minimize the number of calls to the client callbacks,
223  * we keep per-client indications of whether a notification callback
224  * should be made. This is set when the first notification of the
225  * type (regular or host) is enqueued, cleared when the callback is made,
226  * and not set again until after the queue is drained.
227  */
228 typedef enum {
229  GMPR_NOTIFY_GROUP = 1, /* Group notification */
230  GMPR_NOTIFY_SOURCE, /* Source notification */
231  GMPR_NOTIFY_REFRESH_END, /* End of refresh sequence */
232  GMPR_NOTIFY_HOST_GROUP, /* Host group notification */
233  GMPR_NOTIFY_HOST_SOURCE, /* Host source notification */
235 
236 typedef struct gmpr_notify_block_ {
237  gmpr_notification_type gmpr_notify_type; /* Notification type */
238  task_thread gmpr_notify_thread; /* Entry on client notify thread */
240 
241 THREAD_TO_STRUCT(gmpr_thread_to_notify_block, gmpr_notify_block,
242  gmpr_notify_thread);
243 
244 
245 /*
246  * Input interface group entry
247  *
248  * This data structure defines the group record for an input interface.
249  * This represents a group requested by one or more hosts connected to
250  * the interface.
251  *
252  * Source addresses are kept in two lists, one for those with source
253  * timers running, and the other for those with source timers stopped.
254  * In Include mode, the running-timer list constitutes the included
255  * sources. In Exclude mode, the stopped-timer list constitutes the
256  * excluded sources.
257  *
258  * Two lists are maintained to help with sending queries. One list has
259  * all of the sources to be queried that have timers greater than LMQT,
260  * and the other has the sources to be queried that have timers less than
261  * LMQT.
262  *
263  * Input groups are linked to OIF groups if the input group is a (*,G)
264  * entry. Otherwise, the input group is not linked (but the individual
265  * sources are.)
266  */
267 typedef struct gmpr_group_ {
268 
269  /* Linkages */
270 
271  gmpr_intf *rgroup_intf; /* Pointer back to interface */
272  gmpx_patnode rgroup_intf_patnode; /* Node on interface tree of groups */
273  task_thread rgroup_host_group_head; /* Head of host group thread */
274  task_thread rgroup_oif_thread; /* Entry on OIF group thread */
275  struct gmpr_ogroup_ *rgroup_oif_group; /* OIF group pointer */
276 
277  /* Group state */
278 
279  gmp_addr_string rgroup_addr; /* Group address */
280  gmp_filter_mode rgroup_filter_mode; /* Include/Exclude */
281  gmp_addr_list rgroup_src_addr_running; /* Sources with running timers */
282  gmp_addr_list rgroup_src_addr_stopped; /* Sources with stopped timers */
283  gmpx_timer *rgroup_group_timer; /* Group timer */
284  gmp_addr_string rgroup_last_reporter; /* Address of last reporting host */
285 
286  /* Query stuff */
287 
288  gmpx_timer *rgroup_query_timer; /* For sending group queries */
289  gmpx_timer *rgroup_gss_query_timer; /* For sending GSS queries */
290  uint8_t rgroup_query_rexmit_count; /* Rexmit count for group queries */
291  gmp_addr_list rgroup_query_lo_timers; /* List of sources with lo timers */
292  gmp_addr_list rgroup_query_hi_timers; /* List of sources with hi timers */
293 
294  /* Version compatibility stuff */
295 
297  gmpx_timer *rgroup_basic_host_present; /* Basic version host present */
298  gmpx_timer *rgroup_leaves_host_present; /* Leaves version host present */
299 
300  /* Transmission stuff */
301 
302  task_thread rgroup_xmit_thread; /* Entry on intf transmit list */
303  boolean rgroup_send_gss_query; /* We need to send a GSS query */
304  boolean rgroup_send_group_query; /* We need to send a group query */
305 } gmpr_group;
306 
307 GMPX_PATNODE_TO_STRUCT(gmpr_intf_patnode_to_group, gmpr_group,
308  rgroup_intf_patnode);
309 THREAD_TO_STRUCT(gmpr_xmit_thread_to_group, gmpr_group, rgroup_xmit_thread);
310 THREAD_TO_STRUCT(gmpr_oif_thread_to_group, gmpr_group, rgroup_oif_thread);
311 
312 
313 /*
314  * Input interface group member address entry
315  *
316  * This structure represents a single source address in an input
317  * interface group. It consists of an address entry structure plus a
318  * timer, used to age the address entry, and a retransmission counter,
319  * used for counting GSS queries sent with this address. It also
320  * carries a group pointer, so we can get back to the group as
321  * necessary, and client notification linkages.
322  *
323  * The address entry is linked to the corresponding output entry, which
324  * may be bound to a different interface if OIF mapping is in use.
325  */
327 {
329  gmpr_group *rgroup_addr_group; /* Owning group */
331  uint8_t rgroup_addr_rexmit_count; /* Query retransmission count */
332  task_thread rgroup_addr_oif_thread; /* Entry on OIF thread */
334 
335  /* Host stuff */
336 
337  task_thread rgroup_host_addr_head; /* Head of host address thread */
338 
339  /* Wasted space */
340 
341  gmp_addr_string rgroup_addr_last_reporter; /* Last host to mention us */
342 
344 
345 THREAD_TO_STRUCT(gmpr_oif_thread_to_group_addr_entry, gmpr_group_addr_entry,
346  rgroup_addr_oif_thread);
347 EMBEDDED_STRUCT_TO_STRUCT(gmpr_addr_entry_to_group_entry,
349  rgroup_addr_entry);
350 
351 
352 /*
353  * Output interface group entry
354  *
355  * This structure represents a group on an output interface. For
356  * generic IGMP/MLD, this will map one-to-one with the input interface
357  * group entry and will be semantically the same. When OIF mapping is
358  * taking place, this entry may have contributors from multiple input
359  * interface groups.
360  *
361  * This structure contains two address lists, one for Include
362  * contributions and one for Exclude contributions. This is necessary
363  * because the contributing input interfaces may be in different
364  * states (Include or Exclude.) If the output group is in Include
365  * state, the set of sources is that on the Include list. If the
366  * output group is in Exclude state, the set of sources is that on the
367  * Exclude list, *minus* the ones on the Include list (since those are
368  * not to be excluded.) Note that the same source address may be present
369  * on both the include and exclude lists.
370  *
371  * If the output group is a (*,G), it has a thread of all contributing
372  * input groups. If there are sources, the contributing input sources
373  * are bound to the individual output sources.
374  *
375  * The output group is bound to the output interface.
376  *
377  * Client notifications are done with output groups and sources, since they
378  * represent the actual forwarding state.
379  */
380 typedef struct gmpr_ogroup_ {
381  gmpr_intf *rogroup_intf; /* Pointer back to interface */
382  gmpx_patnode rogroup_intf_patnode; /* Node on interface tree of groups */
384  /* Notification blocks */
386  /* TRUE if we should send full notif */
387  task_thread rogroup_global_thread; /* Entry on global state thread */
388  task_thread rogroup_oif_head; /* Head of input groups contributing */
389 
390  /* Group state */
391 
392  gmp_addr_string rogroup_addr; /* Group address */
393  gmp_filter_mode rogroup_filter_mode; /* Include/Exclude */
394  gmp_addr_list rogroup_incl_src_addr; /* Active include sources */
395  gmp_addr_list rogroup_excl_src_addr; /* Active exclude sources */
396  gmp_addr_list rogroup_src_addr_deleted; /* Deleted sources for notify */
397 } gmpr_ogroup;
398 
399 GMPX_PATNODE_TO_STRUCT(gmpr_oif_patnode_to_group, gmpr_ogroup,
400  rogroup_intf_patnode);
401 THREAD_TO_STRUCT(gmpr_global_thread_to_group, gmpr_ogroup,
402  rogroup_global_thread);
403 
404 
405 /*
406  * Output interface group member address entry
407  *
408  * This structure represents a single source address in an output
409  * interface group. It represents a single source being included
410  * or excluded on the output interface.
411  *
412  * Note that the same source address may be present on both the exclude
413  * and include lists on the output group.
414  *
415  * A thread of all contributing input group sources is included.
416  */
418 {
420  gmpr_ogroup *rogroup_addr_group; /* Owning group */
421  task_thread rogroup_addr_oif_head; /* Head of contributing sources */
422 
423  /* Notification stuff */
424 
426  /* Notification blocks */
427  boolean rogroup_notify; /* TRUE if notification required */
429 
430 
431 EMBEDDED_STRUCT_TO_STRUCT(gmpr_addr_entry_to_ogroup_entry,
433  rogroup_addr_entry);
434 
435 
436 /*
437  * Client entry
438  *
439  * Each client has an associated data structure that tracks its associated
440  * state.
441  */
442 typedef struct gmpr_client_ {
443  uint32_t rclient_magic; /* Magic number for robustness */
444  gmpr_instance *rclient_instance; /* Owning instance */
445  ordinal_t rclient_ordinal; /* Client ordinal */
446  task_thread rclient_thread; /* Link on instance client thread */
447  void *rclient_context; /* Client context */
448 
449  task_thread rclient_notif_head; /* Head of group notifications */
450  task_thread rclient_host_notif_head; /* Head of host notifications */
452  gmpr_notify_block rclient_refresh_end_notif; /* End-refresh notification */
453 
454  gmpx_timer *rclient_startup_timer; /* Startup timer */
455  boolean rclient_notify; /* TRUE if we need to notify */
456  boolean rclient_host_notify; /* Ditto for host notifications */
457 } gmpr_client;
458 
459 THREAD_TO_STRUCT(gmpr_thread_to_client, gmpr_client, rclient_thread);
460 
461 #define GMPR_CLIENT_MAGIC 0x52636C69 /* 'Rcli' */
462 
463 
464 /*
465  * Host entry
466  *
467  * If host tracking is active, this structure exists for each host seen
468  * in the protocol. Host entries are used for two purposes--accounting
469  * and fast leaves.
470  *
471  * Host entries are added to a tree rooted at the interface and keyed
472  * by the host address.
473  */
474 typedef struct gmpr_host_ {
475  gmpx_patnode rhost_node; /* Node on interface tree */
476  gmp_addr_string rhost_addr; /* Host address */
477  gmpr_intf *rhost_intf; /* Interface pointer */
478  gmpx_patroot *rhost_group_root; /* Root of group tree */
479 } gmpr_host;
480 
481 GMPX_PATNODE_TO_STRUCT(gmpr_patnode_to_host, gmpr_host, rhost_node);
482 
483 
484 /*
485  * Host group
486  *
487  * This structure represents a group from the perspective of a host. It
488  * lives on a tree rooted at the host entry, and on a thread rooted
489  * at the main group entry.
490  *
491  * We only keep track of active groups and sources; in particular, if the
492  * host requests a non-null Exclude list, we do not track those sources
493  * here (in that case it would look like a group join.)
494  *
495  * If the rhgroup_group pointer is NULL, the entry is inactive (has no
496  * active source or group state) and is not linked to the main group
497  * entry. If the pointer is set and there are no sources present, the
498  * group is active for all sources.
499  *
500  * Note that we don't keep a filter mode (include/exclude) here, because
501  * we know by implication--a group with no sources is a (*,G), and a
502  * group with sources is an Include-mode set of (S,G)s.
503  *
504  * We do limited refcounting to avoid double-freeing this structure
505  * as a side effect of deleting source addresses.
506  */
507 typedef struct gmpr_host_group_ {
508  gmpx_patnode rhgroup_node; /* Node on tree */
509  gmp_addr_string rhgroup_addr; /* Group address */
510  gmpr_host *rhgroup_host; /* Host pointer */
511  gmp_addr_list rhgroup_addrs; /* List of sources */
512  gmp_addr_list rhgroup_deleted; /* Deleted sources awaiting notify */
513  task_thread rhgroup_thread; /* Entry on main group thread */
514  gmpr_group *rhgroup_group; /* Pointer to main group entry */
515  gmpx_timer *rhgroup_timer; /* Host group timer */
517  /* Notification block */
518  boolean rhgroup_is_deleted; /* Deleted, but locked */
519  uint8_t rhgroup_lock_count; /* Lock count */
521 
522 THREAD_TO_STRUCT(gmpr_thread_to_host_group, gmpr_host_group, rhgroup_thread);
523 GMPX_PATNODE_TO_STRUCT(gmpr_patnode_to_host_group, gmpr_host_group,
524  rhgroup_node);
525 
526 /*
527  * gmpr_host_group_active
528  *
529  * Returns TRUE if the host group is active (is bound to a group) or
530  * FALSE otherwise.
531  */
532 static inline boolean
534 {
535  /* Tolerate NULL pointers. */
536 
537  if (!host_group)
538  return FALSE;
539 
540  /* The host group is active if it's bound to a group. */
541 
542  return (host_group->rhgroup_group != NULL);
543 }
544 
545 
546 /*
547  * Host group address entry
548  *
549  * This structure represents a single source address on a host group entry.
550  */
551 typedef struct gmpr_host_group_addr_ {
552  gmp_addr_list_entry rhga_addr_ent; /* Address entry */
553  task_thread rhga_thread; /* Entry on main addr entry thread */
554  gmpr_group_addr_entry *rhga_source; /* Pointer to main addr entry */
556  /* Notification block */
557  gmpr_host_group *rhga_host_group; /* Pointer to owning host group */
558  gmpx_timer *rhga_timer; /* Host source timer */
560 
561 EMBEDDED_STRUCT_TO_STRUCT(gmpr_addr_entry_to_host_group_entry,
563  rhga_addr_ent);
564 THREAD_TO_STRUCT(gmpr_thread_to_host_group_addr_entry, gmpr_host_group_addr,
565  rhga_thread);
566 
567 
568 /*
569  * Global table entries
570  *
571  * We keep a global linkage into the state across all interfaces and
572  * groups. Looking up in the global table based on group leads to a
573  * task_thread of all group entries within that instance that match the
574  * group address. This is done so that the
575  * gmp_router_which_interfaces() call can be implemented; it returns
576  * all of the interfaces on which the entry was heard.
577  *
578  * This is an abomination and should be ripped out (at considerable memory
579  * savings) once PIM becomes smart enough to not lose track of the interfaces
580  * provided in the notifications.
581  */
582 typedef struct gmpr_global_group_ {
583  patnode global_group_node; /* Entry on global tree */
584  gmp_addr_string global_group_addr; /* Group address */
585  task_thread global_group_head; /* Head of thread of groups */
587 
588 GMPX_PATNODE_TO_STRUCT(gmpr_patnode_to_global_group, gmpr_global_group,
589  global_group_node);
590 
591 /*
592  * Inlines...
593  */
594 
595 /*
596  * gmpr_client_notification_to_group
597  *
598  * Return the address of an output group, given a pointer to the
599  * client notification and the client ordinal.
600  *
601  * Returns NULL with a null pointer.
602  */
603 static inline gmpr_ogroup *
605  ordinal_t ordinal)
606 {
607  uint8_t *byte_ptr;
608  gmpr_ogroup *group;
609 
610  if (!notify_block)
611  return NULL;
612 
614 
615  /*
616  * Do the grody pointer math. First, adjust for the client
617  * ordinal offset.
618  */
619  notify_block -= ordinal;
620 
621  /* Now back up to the start of the group. */
622 
623  byte_ptr = (uint8_t *) notify_block;
624  byte_ptr -= offsetof(gmpr_ogroup, rogroup_client_thread);
625 
626  group = (gmpr_ogroup *) byte_ptr;
627 
628  return group;
629 }
630 
631 
632 /*
633  * gmpr_client_notification_to_addr_entry
634  *
635  * Return the address of a group member address entry, given a pointer
636  * to the client notification and the client ordinal.
637  *
638  * Returns NULL with a null pointer.
639  */
640 static inline gmpr_ogroup_addr_entry *
642  ordinal_t ordinal)
643 {
644  uint8_t *byte_ptr;
645  gmpr_ogroup_addr_entry *group_addr;
646 
648 
649  /* Bail if the ordinal is out of range. */
650 
651  if (ordinal >= GMPX_MAX_RTR_CLIENTS)
652  return NULL;
653 
654  /* Adjust for the client ordinal offset. */
655 
656  notify_block -= ordinal;
657 
658  /* Now back up to the start of the address entry. */
659 
660  byte_ptr = (uint8_t *) notify_block;
661  byte_ptr -= offsetof(gmpr_ogroup_addr_entry, rogroup_addr_client_thread);
662 
663  group_addr = (gmpr_ogroup_addr_entry *) byte_ptr;
664 
665  return group_addr;
666 }
667 
668 /*
669  * gmpr_client_notification_to_host_group
670  *
671  * Return the address of a host group, given a pointer to the client
672  * notification and the client ordinal.
673  *
674  * Returns NULL with a null pointer.
675  */
676 static inline gmpr_host_group *
678  ordinal_t ordinal)
679 {
680  uint8_t *byte_ptr;
681  gmpr_host_group *host_group;
682 
683  if (!notify_block)
684  return NULL;
685 
687 
688  /*
689  * Do the grody pointer math. First, adjust for the client
690  * ordinal offset.
691  */
692  notify_block -= ordinal;
693 
694  /* Now back up to the start of the group. */
695 
696  byte_ptr = (uint8_t *) notify_block;
697  byte_ptr -= offsetof(gmpr_host_group, rhgroup_notify);
698 
699  host_group = (gmpr_host_group *) byte_ptr;
700 
701  return host_group;
702 }
703 
704 
705 /*
706  * gmpr_client_notification_to_host_group_addr
707  *
708  * Return the address of a host group address entry, given a pointer
709  * to the client notification and the client ordinal.
710  *
711  * Returns NULL with a null pointer.
712  */
713 static inline gmpr_host_group_addr *
715  ordinal_t ordinal)
716 {
717  uint8_t *byte_ptr;
718  gmpr_host_group_addr *group_addr;
719 
721 
722  /* Bail if the ordinal is out of range. */
723 
724  if (ordinal >= GMPX_MAX_RTR_CLIENTS)
725  return NULL;
726 
727  /* Adjust for the client ordinal offset. */
728 
729  notify_block -= ordinal;
730 
731  /* Now back up to the start of the address entry. */
732 
733  byte_ptr = (uint8_t *) notify_block;
734  byte_ptr -= offsetof(gmpr_host_group_addr, rhga_notify);
735 
736  group_addr = (gmpr_host_group_addr *) byte_ptr;
737 
738  return group_addr;
739 }
740 
741 
742 /*
743  * gmpr_group_addr_deleted
744  *
745  * Returns TRUE if the address entry is on the group deleted list.
746  */
747 static inline boolean
749 {
750  gmp_addr_list_entry *addr_entry;
751  gmpr_ogroup *group;
752 
753  addr_entry = &group_addr->rogroup_addr_entry;
754  group = group_addr->rogroup_addr_group;
755  return (addr_entry->addr_ent_list == &group->rogroup_src_addr_deleted);
756 }
757 
758 
759 /*
760  * gmpr_group_addr_included
761  *
762  * Returns TRUE if the address entry is on the group include list.
763  */
764 static inline boolean
766 {
767  gmp_addr_list_entry *addr_entry;
768  gmpr_ogroup *group;
769 
770  addr_entry = &group_addr->rogroup_addr_entry;
771  group = group_addr->rogroup_addr_group;
772  return (addr_entry->addr_ent_list == &group->rogroup_incl_src_addr);
773 }
774 
775 
776 /*
777  * gmpr_group_addr_mode
778  *
779  * Returns the filter mode (include/exclude) associated with an output
780  * group source entry.
781  */
782 static inline gmp_filter_mode
784 {
785  gmp_filter_mode mode;
786 
787  gmpx_assert(!gmpr_group_addr_deleted(group_addr));
789  if (gmpr_group_addr_included(group_addr))
791 
792  return mode;
793 }
794 
795 
796 /*
797  * gmpr_group_addr_excluded
798  *
799  * Returns TRUE if the address entry is on the group exclude list.
800  */
801 static inline boolean
803 {
804  gmp_addr_list_entry *addr_entry;
805  gmpr_ogroup *group;
806 
807  addr_entry = &group_addr->rogroup_addr_entry;
808  group = group_addr->rogroup_addr_group;
809  return (addr_entry->addr_ent_list == &group->rogroup_excl_src_addr);
810 }
811 
812 
813 /*
814  * gmpr_host_group_addr_deleted
815  *
816  * Returns TRUE if the address entry is on the host group deleted list.
817  */
818 static inline boolean
820 {
821  gmp_addr_list_entry *addr_entry;
822  gmpr_host_group *host_group;
823 
824  addr_entry = &group_addr->rhga_addr_ent;
825  host_group = group_addr->rhga_host_group;
826  return (addr_entry->addr_ent_list == &host_group->rhgroup_deleted);
827 }
828 
829 
830 /*
831  * gmpr_group_is_active
832  *
833  * Returns TRUE if the input group is active (in Exclude mode, or a
834  * non-null source list) or FALSE if not.
835  */
836 static inline boolean
838 {
840  return TRUE;
842  return TRUE;
843  return FALSE;
844 }
845 
846 
847 /*
848  * gmpr_ogroup_is_active
849  *
850  * Returns TRUE if the output group is active (in Exclude mode, or a
851  * non-null source list) or FALSE if not.
852  */
853 static inline boolean
855 {
857  return TRUE;
859  return TRUE;
860  return FALSE;
861 }
862 
863 
864 /*
865  * gmpr_ogroup_source_list_by_mode
866  *
867  * Returns a pointer to the appropriate source list for an output group
868  * (the include list if in Include mode, or the exclude if not) based
869  * on the supplied filter mode.
870  */
871 static inline gmp_addr_list *
873 {
874  if (mode == GMP_FILTER_MODE_INCLUDE) {
875  return &group->rogroup_incl_src_addr;
876  } else {
877  return &group->rogroup_excl_src_addr;
878  }
879 }
880 
881 
882 /*
883  * gmpr_ogroup_source_list
884  *
885  * Returns a pointer to the appropriate source list for an output group
886  * (the include list if in Include mode, or the exclude if not.)
887  */
888 static inline gmp_addr_list *
890 {
892 }
893 
894 
895 /*
896  * gmpr_all_group_lists_empty
897  *
898  * Returns TRUE if there are no sources anywhere on a group, or FALSE if not.
899  */
900 static inline boolean
902 {
903  return (gmp_addr_list_empty(&group->rgroup_src_addr_running) &&
905 }
906 
907 
908 /*
909  * gmpr_group_source_list
910  *
911  * Returns a pointer to the appropriate source list for an input group
912  * (the running list if in Include mode, or the stopped list if not.)
913  */
914 static inline gmp_addr_list *
916 {
918  return &group->rgroup_src_addr_running;
919  } else {
920  return &group->rgroup_src_addr_stopped;
921  }
922 }
923 
924 
925 /*
926  * gmpr_source_ord_is_active
927  *
928  * Returns TRUE if the source corresponding to an address ordinal is
929  * active on an output group, or FALSE if not.
930  *
931  * The source is active if it is in the include list and the group is
932  * in Include mode, or if it is in the exclude list and *not* in the
933  * include list if the group is in Exclude mode.
934  */
935 static inline boolean
937 {
938  boolean in_include;
939 
940  /* See if it's in the include list. */
941 
942  in_include = gmp_addr_in_list(&group->rogroup_incl_src_addr, ord);
943 
944  /* If the group is in Include mode, it's active if in the include list. */
945 
947  return in_include;
948 
949  /*
950  * Exclude mode. The source is active if it's in the exclude list and
951  * not in the include list.
952  */
953  return (gmp_addr_in_list(&group->rogroup_excl_src_addr, ord) &&
954  !in_include);
955 }
956 
957 
958 /*
959  * gmpr_source_is_active
960  *
961  * Returns TRUE if a source is active on an output group, or FALSE if not.
962  *
963  * The source is assumed to be from the list matching the filter state
964  * (include or exclude.) The source is active if the group is in
965  * Include mode (since all sources are, by definition.) If the group
966  * is in Exclude mode, the source is active (excluded) only if the
967  * source is *not* in the Include list.
968  */
969 static inline boolean
971 {
972  /* Active if we're in include mode. */
973 
975  return TRUE;
976 
977  /*
978  * Active if the excluded source is *not* in the Include list, or
979  * inactive if it is.
980  */
981  return (!gmp_addr_in_list(&group->rogroup_incl_src_addr,
982  group_addr->rogroup_addr_entry.addr_ent_ord));
983 }
984 
985 
986 /*
987  * oif_update_type
988  *
989  * Enum for gmpr_update_group_oif and gmpr_update_source_oif
990  */
991 typedef enum {
992  OIF_DELETE, /* Deleting component */
993  OIF_UPDATE, /* Updating component */
995 
996 
997 /*
998  * Externals
999  */
1017 
1018 
1019 /* gmpr_instance.c */
1020 
1022  void *inst_context);
1023 extern gmpr_instance *gmpr_get_instance(gmp_instance_id instance_id);
1024 extern void gmpr_instance_destroy(gmpr_instance *instance);
1025 extern void gmpr_accelerate_query_smear(gmpr_instance *instance);
1026 
1027 /* gmpr_client.c */
1028 
1029 extern gmpr_client *gmpr_create_client(gmpr_instance *instance);
1030 extern gmpr_client *gmpr_get_client(gmp_client_id client_id);
1031 extern void gmpr_destroy_client(gmpr_client *client);
1032 extern void gmpr_destroy_instance_clients(gmpr_instance *instance);
1035 extern void gmpr_source_notify_clients(gmpr_ogroup_addr_entry *group_addr,
1037 extern void gmpr_client_enqueue_all_groups(gmpr_client *client, boolean flush);
1039  gmpr_intf *intf,
1040  boolean flush);
1041 extern gmpr_client_notification *
1043  gmpr_client_notification *last_notification);
1044 extern void gmpr_free_notification(gmpr_client_notification *notification);
1045 extern void gmpr_mode_change_notify_clients(gmpr_ogroup *group);
1046 extern void gmpr_group_notify_clients(gmpr_ogroup *group);
1047 extern void gmpr_alert_clients(gmpr_instance *instance);
1048 extern boolean gmpr_notifications_active(gmpr_notify_block *notify_block);
1049 extern void gmpr_set_notification_type(gmpr_notify_block *notify_block,
1050  gmpr_notification_type notify_type);
1051 extern void gmpr_flush_notifications(gmpr_notify_block *notify_block,
1052  boolean just_delink);
1053 extern void gmpr_enqueue_refresh_end(gmpr_client *client);
1054 
1055 /* gmpr_intf.c */
1056 
1057 extern int gmpr_intf_set_params(gmpr_instance *instance, gmpx_intf_id intf_id,
1058  gmpr_intf_params *params);
1059 extern gmpr_intf *gmpr_intf_lookup(gmpr_instance *instance,
1060  gmpx_intf_id intf_id);
1062  gmpx_intf_id intf_id);
1063 extern void gmpr_kick_xmit(gmpr_intf *intf);
1064 extern int gmpr_attach_intf_internal(gmpr_instance *instance,
1065  gmpx_intf_id intf_id);
1066 extern int gmpr_detach_intf_internal(gmpr_instance *instance,
1067  gmpx_intf_id intf_id);
1068 extern void gmpr_destroy_instance_intfs(gmpr_instance *instance);
1069 extern void gmpr_intf_update_robustness(gmpr_intf *intf, uint32_t robustness);
1070 extern void gmpr_intf_update_query_ivl(gmpr_intf *intf, uint32_t query_ivl);
1071 extern void gmpr_update_querier(gmpr_intf *intf, gmp_addr_string *addr,
1072  boolean querier);
1073 extern void gmpr_setup_initial_query_timer(gmpr_intf *intf);
1074 extern void gmpr_trigger_one_query(gmpr_intf *intf);
1076  gmpr_intf *prev_intf);
1077 
1078 /* gmpr_group.c */
1079 
1080 extern gmpr_group *gmpr_group_create(gmpr_intf *intf,
1081  const gmp_addr_string *group_addr);
1082 extern gmpr_group *gmpr_group_lookup(gmpr_intf *intf, const uint8_t *group);
1083 extern gmpr_ogroup *gmpr_ogroup_lookup(gmpr_intf *intf, const uint8_t *group);
1086 extern void gmpr_dequeue_group_xmit(gmpr_group *group);
1087 extern void gmpr_attempt_group_free(gmpr_group *group);
1088 extern boolean gmpr_attempt_ogroup_free(gmpr_ogroup *ogroup);
1089 extern void gmpr_destroy_intf_groups(gmpr_intf *intf);
1090 extern void gmpr_enqueue_group_xmit(gmpr_group *group);
1091 extern void gmpr_init_group_addr_entry(gmpr_group *group,
1092  gmp_addr_list_entry *addr_entry);
1094 extern void gmpr_delink_global_group(gmpr_ogroup *group);
1096  uint8_t *group_addr);
1097 extern void gmpr_evaluate_group_version(gmpr_group *group);
1098 extern gmp_version gmpr_group_version(gmpr_intf *intf, gmpr_group *group);
1099 extern boolean gmpr_group_forwards_all_sources(gmpr_ogroup *group);
1100 extern boolean gmpr_group_forwards_source(gmpr_ogroup *group,
1101  const uint8_t *source);
1102 extern void gmpr_timeout_group(gmpr_group *group);
1104 extern void gmpr_update_source_oif(gmpr_group_addr_entry *group_addr,
1106 extern void gmpr_update_oif_mode_change(gmpr_group *group);
1108 extern gmpr_group *gmpr_next_intf_group(gmpr_intf *intf, gmpr_group *group);
1110 extern void gmpr_update_intf_output_groups(gmpr_intf *intf);
1111 extern void gmpr_flush_intf_input_groups(gmpr_intf *intf);
1113  gmpr_client *client);
1114 extern void gmpr_flush_notifications_group(gmpr_ogroup *ogroup);
1115 extern boolean gmpr_check_grp_limit(gmpr_intf *intf, boolean incr);
1116 
1117 /* gmpr_engine.c */
1118 
1119 extern void gmpr_register_packet_handler(void);
1120 extern void gmpr_group_query_timer_expiry (gmpx_timer *timer, void *context);
1121 extern void gmpr_group_timer_expiry (gmpx_timer *timer, void *context);
1122 extern void gmpr_gss_query_timer_expiry (gmpx_timer *timer, void *context);
1123 extern void gmpr_source_timer_expiry (gmpx_timer *timer, void *context);
1124 extern void
1126 extern void gmpr_last_host_group_ref_gone(gmpr_group *group);
1127 
1128 /* gmpr_host.c */
1129 
1130 extern void
1131  gmpr_host_process_report(uint8_t *src_addr, gmp_report_rectype rec_type,
1132  gmpr_group *group, gmp_addr_vect *source_vect);
1135  gmpr_client_host_notification *last_notification);
1137  gmpr_client_host_notification *host_notif);
1138 extern void gmpr_alert_host_clients(gmpr_instance *instance);
1141 extern void gmpr_destroy_intf_hosts(gmpr_intf *intf);
1142 extern void gmpr_host_notify_oif_map_change(gmpr_group *group);
1143 extern gmpr_host *gmpr_lookup_host(gmpr_intf *intf, const uint8_t *host_addr);
1144 
1145 #endif /* __GMPR_PRIVATE_H__ */
task_thread rgroup_host_addr_head
Definition: gmpr_private.h:337
gmp_version rgroup_compatibility_mode
Definition: gmpr_private.h:296
uint32_t rintf_other_querier_ivl
Definition: gmpr_private.h:159
gmpr_client_notification * gmpr_client_get_notification(gmpr_client *client, gmpr_client_notification *last_notification)
void gmpr_trigger_one_query(gmpr_intf *intf)
task_thread rclient_host_notif_head
Definition: gmpr_private.h:450
gmpx_block_tag gmpr_host_notification_tag
Definition: gmpr_private.h:417
task_thread rhga_thread
Definition: gmpr_private.h:553
boolean rintf_suppress_gs_query
Definition: gmpr_private.h:164
boolean rinst_smear_timer_accelerated
Definition: gmpr_private.h:87
gmp_addr_string rintf_querier_addr
Definition: gmpr_private.h:131
task_thread rinst_startup_intf_thread
Definition: gmpr_private.h:67
gmpx_timer * rgroup_query_timer
Definition: gmpr_private.h:288
gmp_addr_string rgroup_last_reporter
Definition: gmpr_private.h:284
gmpx_timer * rhgroup_timer
Definition: gmpr_private.h:515
gmpx_patnode rintf_inst_patnode
Definition: gmpr_private.h:136
static gmp_addr_list * gmpr_group_source_list(gmpr_group *group)
Definition: gmpr_private.h:915
#define GMPX_MAX_RTR_CLIENTS
gmpr_intf * rhost_intf
Definition: gmpr_private.h:477
void gmpr_destroy_instance_clients(gmpr_instance *instance)
bv_bitnum_t ordinal_t
Definition: ordinal.h:80
ordinal_handle rinst_ord_handle
Definition: gmpr_private.h:76
gmpx_patroot * rinst_global_state_root
Definition: gmpr_private.h:70
void gmpr_evaluate_group_version(gmpr_group *group)
gmpx_patroot * rintf_group_root
Definition: gmpr_private.h:138
#define EMBEDDED_STRUCT_TO_STRUCT(procname, outerstruct, innerstruct, field)
Definition: gmp_private.h:28
boolean gmpr_notifications_active(gmpr_notify_block *notify_block)
gmpx_patnode rintf_global_patnode
Definition: gmpr_private.h:137
void gmpr_enqueue_group_xmit(gmpr_group *group)
#define TRUE
Definition: mcast_common.h:15
gmpx_timer * rintf_other_querier_present
Definition: gmpr_private.h:160
gmpx_intf_id rintf_id
Definition: gmpr_private.h:142
void gmpr_init_group_addr_entry(gmpr_group *group, gmp_addr_list_entry *addr_entry)
gmpx_timer * rintf_query_timer
Definition: gmpr_private.h:148
boolean gmpr_group_forwards_all_sources(gmpr_ogroup *group)
void gmpr_destroy_instance_intfs(gmpr_instance *instance)
struct gmpr_global_group_ gmpr_global_group
uint32_t rintf_robustness
Definition: gmpr_private.h:153
task_thread rintf_xmit_head
Definition: gmpr_private.h:180
static boolean gmp_addr_in_list(gmp_addr_list *addr_list, ordinal_t ordinal)
Definition: gmp_private.h:498
gmpx_block_tag gmpr_global_group_tag
uint32_t rinst_magic
Definition: gmpr_private.h:64
static gmp_filter_mode gmpr_group_addr_mode(gmpr_ogroup_addr_entry *group_addr)
Definition: gmpr_private.h:783
struct gmpr_intf_ gmpr_intf
void gmpr_flush_host_notifications_client(gmpr_client *client)
gmpr_notify_block rhgroup_notify[GMPX_MAX_RTR_CLIENTS]
Definition: gmpr_private.h:516
gmp_addr_string rgroup_addr
Definition: gmpr_private.h:279
void gmpr_destroy_intf_groups(gmpr_intf *intf)
void gmpr_group_timer_expiry(gmpx_timer *timer, void *context)
uint32_t rinst_min_max_resp
Definition: gmpr_private.h:74
void * gmp_instance_id
Definition: gmp.h:32
boolean rintf_querier
Definition: gmpr_private.h:187
struct gmpr_ogroup_ gmpr_ogroup
void gmpr_instance_destroy(gmpr_instance *instance)
void gmpr_group_query_timer_expiry(gmpx_timer *timer, void *context)
gmpx_patroot * rinst_intfs
Definition: gmpr_private.h:69
gmpr_intf * gmpr_intf_lookup_global(gmp_proto proto, gmpx_intf_id intf_id)
gmpx_block_tag gmpr_instance_tag
gmpx_block_tag gmpr_intf_group_tag
int gmpr_intf_set_params(gmpr_instance *instance, gmpx_intf_id intf_id, gmpr_intf_params *params)
gmp_addr_list rgroup_src_addr_stopped
Definition: gmpr_private.h:282
gmp_version
Definition: gmp_private.h:42
gmpr_intf * rogroup_intf
Definition: gmpr_private.h:381
gmpr_notification_type
Definition: gmpr_private.h:228
uint32_t rintf_query_ivl
Definition: gmpr_private.h:149
void gmpr_update_querier(gmpr_intf *intf, gmp_addr_string *addr, boolean querier)
task_thread gmpr_notify_thread
Definition: gmpr_private.h:238
gmpr_group * gmpr_first_group_xmit(gmpr_intf *intf)
void gmpr_client_enqueue_all_groups(gmpr_client *client, boolean flush)
gmp_addr_list rogroup_incl_src_addr
Definition: gmpr_private.h:394
gmp_addr_string rgroup_addr_last_reporter
Definition: gmpr_private.h:341
#define GMPX_PATNODE_TO_STRUCT
task_thread rgroup_xmit_thread
Definition: gmpr_private.h:302
#define THREAD_TO_STRUCT(function, structure, member)
void gmpr_last_host_group_ref_gone(gmpr_group *group)
ordinal_t rclient_ordinal
Definition: gmpr_private.h:445
struct gmpr_host_group_ gmpr_host_group
struct gmpr_notify_block_ gmpr_notify_block
gmp_addr_list_entry rogroup_addr_entry
Definition: gmpr_private.h:419
gmpx_patnode rogroup_intf_patnode
Definition: gmpr_private.h:382
task_thread rinst_client_thread
Definition: gmpr_private.h:66
void gmpr_timeout_group(gmpr_group *group)
gmp_addr_list rgroup_query_hi_timers
Definition: gmpr_private.h:292
void gmpr_free_notification(gmpr_client_notification *notification)
void gmpr_register_packet_handler(void)
#define FALSE
Definition: mcast_common.h:14
gmp_report_rectype
Definition: gmp_private.h:279
void gmpr_attempt_group_free(gmpr_group *group)
gmp_filter_mode rgroup_filter_mode
Definition: gmpr_private.h:280
void gmpr_dequeue_group_xmit(gmpr_group *group)
oif_update_type
Definition: gmpr_private.h:991
uint32_t rintf_local_query_ivl
Definition: gmpr_private.h:150
gmp_proto
Definition: gmp.h:45
gmpr_host_group * rhga_host_group
Definition: gmpr_private.h:557
gmp_version gmpr_group_version(gmpr_intf *intf, gmpr_group *group)
static gmpr_host_group_addr * gmpr_client_notification_to_host_group_addr(gmpr_notify_block *notify_block, ordinal_t ordinal)
Definition: gmpr_private.h:714
static gmp_addr_list * gmpr_ogroup_source_list(gmpr_ogroup *group)
Definition: gmpr_private.h:889
void gmpr_alert_clients(gmpr_instance *instance)
boolean rhgroup_is_deleted
Definition: gmpr_private.h:518
uint32_t rintf_group_count
Definition: gmpr_private.h:139
gmpx_block_tag gmpr_ogroup_tag
gmpr_intf * rgroup_intf
Definition: gmpr_private.h:271
gmpr_limit_state_t rintf_limit_state
Definition: gmpr_private.h:176
void gmpr_host_notify_oif_map_change(gmpr_group *group)
static gmpr_ogroup_addr_entry * gmpr_client_notification_to_addr_entry(gmpr_notify_block *notify_block, ordinal_t ordinal)
Definition: gmpr_private.h:641
gmpr_client_host_notification * gmpr_client_get_host_notification(gmpr_client *client, gmpr_client_host_notification *last_notification)
time_t last_log_time
Definition: gmpr_private.h:172
uint32_t rintf_lmq_ivl
Definition: gmpr_private.h:155
gmpx_patnode rhost_node
Definition: gmpr_private.h:475
void gmpr_accelerate_query_smear(gmpr_instance *instance)
boolean rgroup_send_gss_query
Definition: gmpr_private.h:303
uint32_t rintf_lmq_count
Definition: gmpr_private.h:156
gmpx_patroot * rintf_oif_group_root
Definition: gmpr_private.h:140
struct gmpr_client_ gmpr_client
uint32_t rintf_log_interval
Definition: gmpr_private.h:171
void gmpr_source_timer_expiry(gmpx_timer *timer, void *context)
static boolean gmpr_host_group_addr_deleted(gmpr_host_group_addr *group_addr)
Definition: gmpr_private.h:819
gmp_addr_list * addr_ent_list
Definition: gmp_private.h:207
struct gmpr_ogroup_addr_entry_ gmpr_ogroup_addr_entry
gmp_addr_list rgroup_src_addr_running
Definition: gmpr_private.h:281
gmp_addr_list rogroup_src_addr_deleted
Definition: gmpr_private.h:396
gmpx_patnode rgroup_intf_patnode
Definition: gmpr_private.h:272
void gmpr_client_free_host_notification(gmpr_client_host_notification *host_notif)
gmpr_group * rhgroup_group
Definition: gmpr_private.h:514
uint8_t rgroup_query_rexmit_count
Definition: gmpr_private.h:290
task_thread rclient_thread
Definition: gmpr_private.h:446
static boolean gmpr_group_addr_excluded(gmpr_ogroup_addr_entry *group_addr)
Definition: gmpr_private.h:802
struct gmpr_group_ gmpr_group
Definition: gmpr_private.h:326
gmpr_group * gmpr_next_intf_group(gmpr_intf *intf, gmpr_group *group)
gmpr_intf * gmpr_intf_lookup(gmpr_instance *instance, gmpx_intf_id intf_id)
static boolean gmpr_host_group_active(gmpr_host_group *host_group)
Definition: gmpr_private.h:533
uint8_t type
Definition: load_balance.h:109
void gmpr_gss_query_timer_expiry(gmpx_timer *timer, void *context)
gmp_addr_list rhgroup_deleted
Definition: gmpr_private.h:512
gmpr_instance * gmpr_instance_create(gmp_proto proto, void *inst_context)
boolean gmpr_check_grp_limit(gmpr_intf *intf, boolean incr)
void gmpr_notify_oif_map_change_internal(gmpr_intf *intf)
task_thread rhgroup_thread
Definition: gmpr_private.h:513
gmpx_block_tag gmpr_group_tag
#define gmpx_block_tag
gmpr_notification_type gmpr_notify_type
Definition: gmpr_private.h:237
gmpx_timer * rinst_smear_timer
Definition: gmpr_private.h:84
void gmpr_alert_host_clients(gmpr_instance *instance)
gmp_addr_string rhgroup_addr
Definition: gmpr_private.h:509
void gmpr_intf_update_robustness(gmpr_intf *intf, uint32_t robustness)
boolean rclient_notify
Definition: gmpr_private.h:455
void gmpr_setup_initial_query_timer(gmpr_intf *intf)
gmpr_group * gmpr_group_create(gmpr_intf *intf, const gmp_addr_string *group_addr)
uint32_t rintf_oif_group_count
Definition: gmpr_private.h:141
patnode global_group_node
Definition: gmpr_private.h:583
task_thread rclient_notif_head
Definition: gmpr_private.h:449
task_thread rintf_startup_thread
Definition: gmpr_private.h:144
gmpr_notify_block rogroup_addr_client_thread[GMPX_MAX_RTR_CLIENTS]
Definition: gmpr_private.h:425
void gmpr_destroy_intf_hosts(gmpr_intf *intf)
void gmpr_set_notification_type(gmpr_notify_block *notify_block, gmpr_notification_type notify_type)
void gmpr_update_group_oif(gmpr_group *group, oif_update_type type)
void gmpr_source_notify_clients(gmpr_ogroup_addr_entry *group_addr, gmpr_source_notify_flag flag)
int gmpr_attach_intf_internal(gmpr_instance *instance, gmpx_intf_id intf_id)
boolean rintf_xmit_pending
Definition: gmpr_private.h:181
gmpr_notify_block rogroup_client_thread[GMPX_MAX_RTR_CLIENTS]
Definition: gmpr_private.h:383
task_thread rogroup_global_thread
Definition: gmpr_private.h:387
void gmpr_enqueue_refresh_end(gmpr_client *client)
gmpr_limit_state_t
Definition: gmpr_private.h:105
static gmpr_host_group * gmpr_client_notification_to_host_group(gmpr_notify_block *notify_block, ordinal_t ordinal)
Definition: gmpr_private.h:677
boolean rintf_up
Definition: gmpr_private.h:184
gmpr_global_group * gmpr_link_global_group(gmpr_ogroup *group)
gmpx_patroot * rhost_group_root
Definition: gmpr_private.h:478
gmpx_timer * rgroup_basic_host_present
Definition: gmpr_private.h:297
struct gmpr_instance_ gmpr_instance
gmpr_ogroup * gmpr_ogroup_lookup(gmpr_intf *intf, const uint8_t *group)
boolean rintf_first_query_pending
Definition: gmpr_private.h:163
gmpx_patnode rhgroup_node
Definition: gmpr_private.h:508
static boolean gmpr_all_group_lists_empty(gmpr_group *group)
Definition: gmpr_private.h:901
gmpx_block_tag gmpr_host_group_tag
uint8_t rgroup_addr_rexmit_count
Definition: gmpr_private.h:331
boolean gmp_addr_list_empty(gmp_addr_list *list)
gmp_addr_list_entry rhga_addr_ent
Definition: gmpr_private.h:552
static boolean gmpr_group_addr_included(gmpr_ogroup_addr_entry *group_addr)
Definition: gmpr_private.h:765
void gmpr_flush_notifications(gmpr_notify_block *notify_block, boolean just_delink)
uint32_t rintf_group_membership_ivl
Definition: gmpr_private.h:157
boolean rintf_passive_receive
Definition: gmpr_private.h:191
gmpx_timer * gmpr_create_change_report_timer(gmpr_group *group)
task_thread rgroup_oif_thread
Definition: gmpr_private.h:274
gmpr_source_notify_flag
void gmpr_destroy_client(gmpr_client *client)
gmpr_instance_context rinst_cb_context
Definition: gmpr_private.h:78
boolean rintf_suppress_gen_query
Definition: gmpr_private.h:161
struct gmpr_ogroup_ * rgroup_oif_group
Definition: gmpr_private.h:275
void * ordinal_handle
Definition: ordinal.h:75
boolean rintf_querier_enabled
Definition: gmpr_private.h:186
gmpr_group_addr_entry * rhga_source
Definition: gmpr_private.h:554
gmpx_block_tag gmpr_ogroup_addr_entry_tag
#define gmpx_assert
uint32_t rintf_channel_count
Definition: gmpr_private.h:174
boolean rogroup_notify
Definition: gmpr_private.h:427
gmpx_block_tag gmpr_client_tag
gmpr_group * gmpr_group_lookup(gmpr_intf *intf, const uint8_t *group)
void gmpr_delink_global_group(gmpr_ogroup *group)
gmpr_client * gmpr_get_client(gmp_client_id client_id)
gmpx_timer * rgroup_group_timer
Definition: gmpr_private.h:283
boolean rclient_host_notify
Definition: gmpr_private.h:456
task_thread rogroup_oif_head
Definition: gmpr_private.h:388
#define gmpx_patroot
gmpr_instance * rclient_instance
Definition: gmpr_private.h:444
uint32_t rintf_local_robustness
Definition: gmpr_private.h:154
gmpx_timer * rhga_timer
Definition: gmpr_private.h:558
gmpx_block_tag gmpr_intf_tag
uint32_t rinst_group_timeout
Definition: gmpr_private.h:80
task_thread rinst_thread
Definition: gmpr_private.h:65
gmp_addr_list rogroup_excl_src_addr
Definition: gmpr_private.h:395
gmpr_host * rhgroup_host
Definition: gmpr_private.h:510
boolean rintf_gen_query_requested
Definition: gmpr_private.h:162
task_thread global_group_head
Definition: gmpr_private.h:585
static boolean gmpr_ogroup_is_active(gmpr_ogroup *ogroup)
Definition: gmpr_private.h:854
void gmpr_flush_notifications_group(gmpr_ogroup *ogroup)
gmpx_patroot * rintf_host_root
Definition: gmpr_private.h:143
gmpr_intf * gmpr_next_instance_intf(gmpr_instance *instance, gmpr_intf *prev_intf)
void gmpr_intf_update_query_ivl(gmpr_intf *intf, uint32_t query_ivl)
gmpr_ogroup * rogroup_addr_group
Definition: gmpr_private.h:420
static boolean gmpr_group_addr_deleted(gmpr_ogroup_addr_entry *group_addr)
Definition: gmpr_private.h:748
void gmpr_host_process_report(uint8_t *src_addr, gmp_report_rectype rec_type, gmpr_group *group, gmp_addr_vect *source_vect)
uint32_t rintf_query_resp_ivl
Definition: gmpr_private.h:151
gmpr_instance * gmpr_get_instance(gmp_instance_id instance_id)
boolean rintf_fast_leaves
Definition: gmpr_private.h:185
Definition: gmp_private.h:206
boolean rogroup_send_full_notif[GMPX_MAX_RTR_CLIENTS]
Definition: gmpr_private.h:385
void gmpr_enqueue_all_source_notifications(gmpr_ogroup *ogroup, gmpr_client *client)
void gmpr_client_enqueue_all_host_groups(gmpr_client *client)
gmp_addr_list_entry rgroup_addr_entry
Definition: gmpr_private.h:328
uint32_t rinst_traceflags
Definition: gmpr_private.h:82
struct gmpr_ogroup_addr_entry_ * rgroup_addr_oif_addr
Definition: gmpr_private.h:333
void gmpr_update_intf_output_groups(gmpr_intf *intf)
boolean rintf_send_gen_query
Definition: gmpr_private.h:182
void gmpr_update_source_oif(gmpr_group_addr_entry *group_addr, oif_update_type type)
struct gmpr_host_group_addr_ gmpr_host_group_addr
gmpx_block_tag gmpr_host_tag
gmpx_patroot * gmpr_global_intf_tree[]
task_thread gmpr_global_instance_thread
task_thread rgroup_host_group_head
Definition: gmpr_private.h:273
gmp_addr_string rhost_addr
Definition: gmpr_private.h:476
static gmpr_ogroup * gmpr_client_notification_to_group(gmpr_notify_block *notify_block, ordinal_t ordinal)
Definition: gmpr_private.h:604
gmpx_timer * rgroup_leaves_host_present
Definition: gmpr_private.h:298
gmpr_notify_block rhga_notify[GMPX_MAX_RTR_CLIENTS]
Definition: gmpr_private.h:555
void gmpr_group_notify_clients(gmpr_ogroup *group)
gmpx_block_tag gmpr_group_addr_entry_tag
gmp_filter_mode rogroup_filter_mode
Definition: gmpr_private.h:393
#define gmpx_patnode
ordinal_t addr_ent_ord
Definition: gmp_private.h:211
uint32_t rintf_startup_query_count
Definition: gmpr_private.h:166
gmpx_block_tag gmpr_intf_list_tag
gmp_addr_string rintf_local_addr
Definition: gmpr_private.h:130
uint32_t rintf_channel_limit
Definition: gmpr_private.h:168
gmpr_notify_block rclient_refresh_end_notif
Definition: gmpr_private.h:452
gmpx_timer * rclient_startup_timer
Definition: gmpr_private.h:454
gmp_version rintf_ver
Definition: gmpr_private.h:129
gmpr_client_context rclient_cb_context
Definition: gmpr_private.h:451
boolean rinst_host_tracking
Definition: gmpr_private.h:86
gmp_addr_string global_group_addr
Definition: gmpr_private.h:584
gmp_filter_mode
Definition: gmp.h:66
uint32_t rintf_chan_limit_drops
Definition: gmpr_private.h:175
static boolean gmpr_group_is_active(gmpr_group *group)
Definition: gmpr_private.h:837
gmp_addr_list rgroup_query_lo_timers
Definition: gmpr_private.h:291
void gmpr_client_enqueue_all_intf_groups(gmpr_client *client, gmpr_intf *intf, boolean flush)
gmp_proto rinst_proto
Definition: gmpr_private.h:71
gmpr_client * gmpr_create_client(gmpr_instance *instance)
task_thread rgroup_addr_oif_thread
Definition: gmpr_private.h:332
void * rinst_context
Definition: gmpr_private.h:77
gmpr_group * rgroup_addr_group
Definition: gmpr_private.h:329
gmpx_timer * rgroup_addr_timer
Definition: gmpr_private.h:330
void gmpr_flush_intf_input_groups(gmpr_intf *intf)
uint32_t rintf_lmqt
Definition: gmpr_private.h:158
gmpr_instance * rintf_instance
Definition: gmpr_private.h:135
uint32_t rinst_addrlen
Definition: gmpr_private.h:72
boolean rgroup_send_group_query
Definition: gmpr_private.h:304
int gmpr_detach_intf_internal(gmpr_instance *instance, gmpx_intf_id intf_id)
void gmpr_mode_change_notify_clients(gmpr_ogroup *group)
struct gmpr_group_addr_entry_ gmpr_group_addr_entry
void gmpr_last_host_addr_ref_gone(gmpr_group_addr_entry *group_addr_entry)
void * rclient_context
Definition: gmpr_private.h:447
gmp_addr_string rogroup_addr
Definition: gmpr_private.h:392
gmpx_block_tag gmpr_host_group_addr_tag
task_thread rogroup_addr_oif_head
Definition: gmpr_private.h:421
gmpx_block_tag gmpr_notification_tag
gmpr_ogroup * gmpr_next_oif_group(gmpr_intf *oif, gmpr_ogroup *group)
uint32_t rintf_channel_threshold
Definition: gmpr_private.h:169
boolean gmpr_group_forwards_source(gmpr_ogroup *group, const uint8_t *source)
void * gmp_client_id
Definition: gmp.h:39
static boolean gmpr_source_is_active(gmpr_ogroup *group, gmpr_ogroup_addr_entry *group_addr)
Definition: gmpr_private.h:970
void gmpr_kick_xmit(gmpr_intf *intf)
gmpx_timer * rgroup_gss_query_timer
Definition: gmpr_private.h:289
static boolean gmpr_source_ord_is_active(gmpr_ogroup *group, ordinal_t ord)
Definition: gmpr_private.h:936
gmp_addr_list rhgroup_addrs
Definition: gmpr_private.h:511
gmpr_host * gmpr_lookup_host(gmpr_intf *intf, const uint8_t *host_addr)
gmp_addr_catalog rinst_addr_cat
Definition: gmpr_private.h:73
void gmpr_update_oif_mode_change(gmpr_group *group)
struct gmpr_host_ gmpr_host
boolean gmpr_attempt_ogroup_free(gmpr_ogroup *ogroup)
gmpr_global_group * gmpr_lookup_global_group(gmpr_instance *instance, uint8_t *group_addr)
uint32_t rintf_local_query_resp_ivl
Definition: gmpr_private.h:152
static gmp_addr_list * gmpr_ogroup_source_list_by_mode(gmpr_ogroup *group, gmp_filter_mode mode)
Definition: gmpr_private.h:872
uint8_t rhgroup_lock_count
Definition: gmpr_private.h:519
uint32_t rclient_magic
Definition: gmpr_private.h:443