freebsd-nq/usr.sbin/pim6sd/mrt.h

341 lines
15 KiB
C
Raw Normal View History

/*
* Copyright (c) 1998 by the University of Southern California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and
* its documentation in source and binary forms for lawful
* purposes and without fee is hereby granted, provided
* that the above copyright notice appear in all copies and that both
* the copyright notice and this permission notice appear in supporting
* documentation, and that any documentation, advertising materials,
* and other materials related to such distribution and use acknowledge
* that the software was developed by the University of Southern
* California and/or Information Sciences Institute.
* The name of the University of Southern California may not
* be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THE UNIVERSITY OF SOUTHERN CALIFORNIA DOES NOT MAKE ANY REPRESENTATIONS
* ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. THIS SOFTWARE IS
* PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
* NON-INFRINGEMENT.
*
* IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT,
* TORT, OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH,
* THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Other copyrights might apply to parts of this software and are so
* noted when applicable.
*/
/*
* Questions concerning this software should be directed to
* Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg.
*
*/
/*
* This program has been derived from pim6dd.
* The pim6dd program is covered by the license in the accompanying file
* named "LICENSE.pim6dd".
*/
/*
* This program has been derived from pimd.
* The pimd program is covered by the license in the accompanying file
* named "LICENSE.pimd".
*
* $FreeBSD$
*/
#ifndef MRT_H
#define MRT_H
#include <sys/param.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/ip_mroute.h>
#include <netinet6/ip6_mroute.h>
#include <string.h>
#include "defs.h"
/* flags for the mrt entries */
#define MRTF_SPT 0x0001 /* iif toward source */
#define MRTF_WC 0x0002 /* (*,G) entry */
#define MRTF_RP 0x0004 /* iif toward RP */
#define MRTF_NEW 0x0008 /* new created routing entry */
#define MRTF_IIF_REGISTER 0x0020 /* ??? */
#define MRTF_REGISTER 0x0080 /* ??? */
#define MRTF_KERNEL_CACHE 0x0200 /* a mirror for the kernel cache */
#define MRTF_NULL_OIF 0x0400 /* null oif cache.. ??? */
#define MRTF_REG_SUPP 0x0800 /* register suppress ??? */
#define MRTF_ASSERTED 0x1000 /* upstream is not that of src ??? */
#define MRTF_SG 0x2000 /* (S,G) pure, not hanging off of (*,G)*/
#define MRTF_PMBR 0x4000 /* (*,*,RP) entry (for interop) */
#define MRTF_MFC_CLONE_SG 0x8000 /* clone (S,G) MFC from (*,G) or (*,*,RP) */
#define CREATE TRUE
#define DONT_CREATE FALSE
#define MFC_MOVE_FORCE 0x1
#define MFC_UPDATE_FORCE 0x2
/* Macro to duplicate oif info (oif bits, timers) */
#define VOIF_COPY(from , to ) \
do { \
IF_COPY(&from->joined_oifs , &to->joined_oifs); \
IF_COPY(&from->oifs ,&to->oifs ); \
IF_COPY(&from->leaves , &to->leaves); \
IF_COPY(&from->pruned_oifs , &to->leaves ); \
IF_COPY(&from->asserted_oifs ,&to->asserted_oifs); \
bcopy(from->vif_timers , to->vif_timers , \
numvifs*sizeof(from->vif_timers[0])); \
bcopy(from->vif_deletion_delay , to->vif_deletion_delay , \
numvifs*sizeof(from->vif_deletion_delay[0])); \
} while (0)
#define FREE_MRTENTRY(mrtentry_ptr) \
do { \
kernel_cache_t *prev; \
kernel_cache_t *next; \
\
free( (char *)( (mrtentry_ptr)->vif_timers ) ); \
free( (char *)( (mrtentry_ptr)->vif_deletion_delay ) ); \
for( next=(mrtentry_ptr)->kernel_cache ; next!=(kernel_cache_t *)NULL ; ) \
{ \
prev=next; \
next=next->next; \
free(prev); \
} \
free( (char *)( (mrtentry_ptr)->kernel_cache ) ); \
free( (char *)(mrtentry_ptr) ); \
} while (0)
/*
* The complicated structure used by the more complicated Join/Prune
* message building
*/
typedef struct build_jp_message {
struct build_jp_message *next; /* Used to chain the free entries */
u_int8 *jp_message; /* The Join/Prune message */
u_int32 jp_message_size; /* Size of the Join/Prune message (in bytes) */
u_int16 holdtime; /* Join/Prune message holdtime field */
struct sockaddr_in6 curr_group; /* Current group address */
u_int8 curr_group_msklen; /* Current group masklen */
u_int8 *join_list; /* The working area for the join addresses */
u_int32 join_list_size; /* The size of the join_list (in bytes) */
u_int16 join_addr_number; /* Number of the join addresses in join_list */
u_int8 *prune_list; /* The working area for the prune addresses */
u_int32 prune_list_size; /* The size of the prune_list (in bytes) */
u_int16 prune_addr_number; /* Number of the prune addresses in prune_list*/
u_int8 *rp_list_join; /* The working area for RP join addresses */
u_int32 rp_list_join_size; /* The size of the rp_list_join (in bytes) */
u_int16 rp_list_join_number; /* Number of RP addresses in rp_list_join */
u_int8 *rp_list_prune; /* The working area for RP prune addresses */
u_int32 rp_list_prune_size; /* The size of the rp_list_prune (in bytes) */
u_int16 rp_list_prune_number; /* Number of RP addresses in rp_list_prune */
u_int8 *num_groups_ptr; /* Pointer to number_of_groups in jp_message */
} build_jp_message_t;
typedef struct pim_nbr_entry {
struct pim_nbr_entry *next; /* link to next neighbor */
struct pim_nbr_entry *prev; /* link to prev neighbor */
struct sockaddr_in6 address; /* neighbor address */
vifi_t vifi; /* which interface */
u_int16 timer; /* for timing out neighbor */
build_jp_message_t *build_jp_message; /* A structure for fairly
* complicated Join/Prune
* message construction.
*/
} pim_nbr_entry_t;
typedef struct srcentry {
struct srcentry *next; /* link to next entry */
struct srcentry *prev; /* link to prev entry */
struct sockaddr_in6 address; /* source or RP address */
struct mrtentry *mrtlink; /* link to routing entries */
vifi_t incoming; /* incoming vif */
struct pim_nbr_entry *upstream; /* upstream router */
u_int32 metric; /* Unicast Routing Metric to the source */
u_int32 preference; /* The metric preference (for assers)*/
u_int16 timer; /* Entry timer??? Delete? */
struct cand_rp *cand_rp; /* Used if this is rpentry_t */
} srcentry_t;
typedef srcentry_t rpentry_t;
/* (RP<->group) matching table related structures */
typedef struct cand_rp {
struct cand_rp *next; /* Next candidate RP */
struct cand_rp *prev; /* Previous candidate RP */
struct rp_grp_entry *rp_grp_next; /* The rp_grp_entry chain for that RP*/
rpentry_t *rpentry; /* Pointer to the RP entry */
} cand_rp_t;
typedef struct grp_mask {
struct grp_mask *next;
struct grp_mask *prev;
struct rp_grp_entry *grp_rp_next;
struct sockaddr_in6 group_addr;
struct in6_addr group_mask;
struct in6_addr hash_mask;
u_int16 fragment_tag; /* Used for garbage collection */
u_int8 group_rp_number; /* Used when assembling segments */
} grp_mask_t;
typedef struct rp_grp_entry {
struct rp_grp_entry *rp_grp_next; /* Next entry for same RP */
struct rp_grp_entry *rp_grp_prev; /* Prev entry for same RP */
struct rp_grp_entry *grp_rp_next; /* Next entry for same grp prefix */
struct rp_grp_entry *grp_rp_prev; /* Prev entry for same grp prefix */
struct grpentry *grplink; /* Link to all grps via this entry*/
u_int16 advholdtime; /* The advertised holdtime */
u_int16 holdtime; /* The RP holdtime (will be aged) */
u_int16 fragment_tag; /* The fragment tag from the
* received BSR message
*/
u_int8 priority; /* The RP priority */
grp_mask_t *group; /* Pointer to (group,mask) entry */
cand_rp_t *rp; /* Pointer to the RP */
} rp_grp_entry_t;
typedef struct grpentry {
struct grpentry *next; /* link to next entry */
struct grpentry *prev; /* link to prev entry */
struct grpentry *rpnext; /* next grp for the same RP */
struct grpentry *rpprev; /* prev grp for the same RP */
struct sockaddr_in6 group; /* subnet group of multicasts */
struct sockaddr_in6 rpaddr; /* The IPv6 address of the RP */
struct mrtentry *mrtlink; /* link to (S,G) routing entries */
rp_grp_entry_t *active_rp_grp; /* Pointer to the active rp_grp entry*/
struct mrtentry *grp_route; /* Pointer to the (*,G) routing entry*/
} grpentry_t;
typedef struct mrtentry {
struct mrtentry *grpnext; /* next entry of same group */
struct mrtentry *grpprev; /* prev entry of same group */
struct mrtentry *srcnext; /* next entry of same source */
struct mrtentry *srcprev; /* prev entry of same source */
struct grpentry *group; /* pointer to group entry */
struct srcentry *source; /* pointer to source entry (or RP) */
vifi_t incoming; /* the iif (either toward S or RP) */
if_set oifs; /* The current result oifs */
if_set joined_oifs; /* The joined oifs (Join received) */
if_set pruned_oifs; /* The pruned oifs (Prune received) */
if_set asserted_oifs; /* The asserted oifs (lost Assert) */
if_set leaves; /* Has directly connected members */
struct pim_nbr_entry *upstream; /* upstream router, needed because
* of the asserts it may be different
* than the source (or RP) upstream
* router.
*/
u_int32 metric; /* Routing Metric for this entry */
u_int32 preference; /* The metric preference value */
struct sockaddr_in6 pmbr_addr; /* The PMBR address (for interop) */
u_int16 *vif_timers; /* vifs timer list */
u_int16 *vif_deletion_delay; /* vifs deletion delay list */
u_int16 flags; /* The MRTF_* flags */
u_int16 timer; /* entry timer */
u_int16 jp_timer; /* The Join/Prune timer */
u_int16 rs_timer; /* Register-Suppression Timer */
u_int assert_timer;
u_int assert_rate_timer;
struct kernel_cache *kernel_cache; /* List of the kernel cache entries */
#ifdef RSRR
struct rsrr_cache *rsrr_cache; /* Used to save RSRR requests for
* routes change notification.
*/
#endif /* RSRR */
} mrtentry_t;
/*
* Used to get forwarded data related counts (number of packet, number of
* bits, etc)
*/
struct sg_count {
u_quad_t pktcnt; /* Number of packets for (s,g) */
u_quad_t bytecnt; /* Number of bytes for (s,g) */
u_quad_t wrong_if; /* Number of packets received on wrong iif for (s,g) */
};
/*
* Structure to keep track of existing (S,G) MFC entries in the kernel
* for particular (*,G) or (*,*,RP) entry. We must keep track for
* each active source which doesn't have (S,G) entry in the daemon's
* routing table. We need to keep track of such sources for two reasons:
*
* (1) If the kernel does not support (*,G) MFC entries (currently, the
* "official" mcast code doesn't), we must know all installed (s,G) entries
* in the kernel and modify them if the iif or oif for the (*,G) changes.
*
* (2) By checking periodically the traffic coming from the shared tree,
* we can either delete the idle sources or switch to the shortest path.
*
* Note that even if we have (*,G) implemented in the kernel, we still
* need to have this structure because of (2)
*/
typedef struct kernel_cache {
struct kernel_cache *next;
struct kernel_cache *prev;
struct sockaddr_in6 source;
struct sockaddr_in6 group;
struct sg_count sg_count; /* The (s,g) data retated counters (see above) */
} kernel_cache_t;
struct vif_count {
u_long icount; /* Input packet count on vif */
u_long ocount; /* Output packet count on vif */
u_long ibytes; /* Input byte count on vif */
u_long obytes; /* Output byte count on vif */
};
/* globals and functions exportations */
extern srcentry_t *srclist;
extern grpentry_t *grplist;
extern void init_pim6_mrt __P((void));
extern mrtentry_t *find_route __P((struct sockaddr_in6 *source,
struct sockaddr_in6 *group,
u_int16 flags, char create));
extern grpentry_t *find_group __P((struct sockaddr_in6 *group));
extern srcentry_t *find_source __P((struct sockaddr_in6 *source));
extern void delete_mrtentry __P((mrtentry_t *mrtentry_ptr));
extern void delete_srcentry __P((srcentry_t *srcentry_ptr));
extern void delete_grpentry __P((grpentry_t *grpentry_ptr));
extern void delete_mrtentry_all_kernel_cache __P((mrtentry_t *mrtentry_ptr));
extern void delete_single_kernel_cache __P((mrtentry_t *mrtentry_ptr,
kernel_cache_t *kernel_cache_ptr));
extern void delete_single_kernel_cache_addr __P((mrtentry_t *mrtentry_ptr,
struct sockaddr_in6 *source,
struct sockaddr_in6 *group));
extern void add_kernel_cache __P((mrtentry_t *mrtentry_ptr,
struct sockaddr_in6 *source, struct sockaddr_in6 *group,
u_int16 flags));
#endif