root/usr/src/cmd/cmd-inet/usr.lib/in.ndpd/tables.h
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef _NDPD_TABLES_H
#define _NDPD_TABLES_H

#ifdef  __cplusplus
extern "C" {
#endif

#include <ndpd.h>
#include <libipadm.h>

enum adv_states { NO_ADV = 0, REG_ADV, INIT_ADV, SOLICIT_ADV, FINAL_ADV };
enum adv_events { ADV_OFF, START_INIT_ADV, START_FINAL_ADV, RECEIVED_SOLICIT,
                        ADV_TIMER };

enum solicit_states { NO_SOLICIT = 0, INIT_SOLICIT, DONE_SOLICIT };
enum solicit_events { SOLICIT_OFF, START_INIT_SOLICIT, SOL_TIMER,
                        SOLICIT_DONE, RESTART_INIT_SOLICIT };

/*
 * A doubly linked list of all physical interfaces that each contain a
 * doubly linked list of prefixes (i.e. logical interfaces) and default
 * routers.
 */
struct phyint {
        struct phyint   *pi_next;
        struct phyint   *pi_prev;
        struct prefix   *pi_prefix_list;        /* Doubly linked prefixes */
        struct router   *pi_router_list;        /* Doubly linked routers */
        struct adv_prefix *pi_adv_prefix_list;  /* Doubly linked adv.prefixes */

        uint_t          pi_index;               /* Identifier > 0 */
        char            pi_name[LIFNAMSIZ];     /* Used to identify it */
        int             pi_sock;                /* For sending and receiving */
        struct in6_addr pi_ifaddr;              /* Local address */
        uint64_t                pi_flags;               /* IFF_* flags */
        uint_t          pi_mtu;                 /* From SIOCGLIFMTU */
        struct in6_addr pi_token;
        uint_t          pi_token_length;
        boolean_t       pi_stateless;
        boolean_t       pi_stateful;
        struct in6_addr pi_tmp_token;           /* For RFC3041 addrs */
        struct in6_addr pi_dst_token;           /* For POINTOPOINT */

        uint_t          pi_state;               /* PI_* below */
        uint_t          pi_kernel_state;        /* PI_* below */
        uint_t          pi_num_k_routers;       /* # routers in kernel */
        uint_t          pi_reach_time_since_random;     /* In milliseconds */

        /* Applies if pi_AdvSendAdvertisements */
        uint_t          pi_adv_time_left;       /* In milliseconds */
        uint_t          pi_adv_time_since_sent; /* In milliseconds */
        enum adv_states pi_adv_state;
        uint_t          pi_adv_count;

        /* Applies if not pi_AdvSendAdvertisements */
        uint_t          pi_sol_time_left;       /* In milliseconds */
        enum solicit_states pi_sol_state;
        uint_t          pi_sol_count;

        /* Interface specific configurable variables */
        struct confvar  pi_config[I_IFSIZE];
#define pi_DupAddrDetectTransmits pi_config[I_DupAddrDetectTransmits].cf_value
#define pi_AdvSendAdvertisements pi_config[I_AdvSendAdvertisements].cf_value
#define pi_MaxRtrAdvInterval    pi_config[I_MaxRtrAdvInterval].cf_value
#define pi_MinRtrAdvInterval    pi_config[I_MinRtrAdvInterval].cf_value
#define pi_AdvManagedFlag       pi_config[I_AdvManagedFlag].cf_value
#define pi_AdvOtherConfigFlag   pi_config[I_AdvOtherConfigFlag].cf_value
#define pi_AdvLinkMTU           pi_config[I_AdvLinkMTU].cf_value
#define pi_AdvReachableTime     pi_config[I_AdvReachableTime].cf_value
#define pi_AdvRetransTimer      pi_config[I_AdvRetransTimer].cf_value
#define pi_AdvCurHopLimit       pi_config[I_AdvCurHopLimit].cf_value
#define pi_AdvDefaultLifetime   pi_config[I_AdvDefaultLifetime].cf_value
#define pi_StatelessAddrConf    pi_config[I_StatelessAddrConf].cf_value
#define pi_TmpAddrsEnabled      pi_config[I_TmpAddrsEnabled].cf_value
#define pi_TmpValidLifetime     pi_config[I_TmpValidLifetime].cf_value
#define pi_TmpPreferredLifetime pi_config[I_TmpPreferredLifetime].cf_value
#define pi_TmpRegenAdvance      pi_config[I_TmpRegenAdvance].cf_value
#define pi_TmpMaxDesyncFactor   pi_config[I_TmpMaxDesyncFactor].cf_value
#define pi_StatefulAddrConf     pi_config[I_StatefulAddrConf].cf_value

        /* Recorded variables for RFC3041 addresses */
        uint_t          pi_TmpDesyncFactor;             /* In milliseconds */
        uint_t          pi_TmpRegenCountdown;           /* In milliseconds */

        /* Recorded variables on node/host */
        uint_t          pi_LinkMTU;
        uint_t          pi_CurHopLimit;
        uint_t          pi_BaseReachableTime;           /* In milliseconds */
        uint_t          pi_ReachableTime;               /* In milliseconds */
        /*
         * The above value should be a uniformly-distributed random
         * value between ND_MIN_RANDOM_FACTOR and
         * ND_MAX_RANDOM_FACTOR times BaseReachableTime
         * milliseconds.  A new random value should be
         * calculated when BaseReachableTime changes (due to
         * Router Advertisements) or at least every few hours
         * even if no Router Advertisements are received.
         * Tracked using pi_each_time_since_random.
         */
        uint_t          pi_RetransTimer;        /* In milliseconds */

        uint_t          pi_ra_flags;    /* Detect when to start DHCP */
        boolean_t       pi_autoconf;    /* Enable/Disable autoconfiguration */
        boolean_t       pi_default_token;       /* Use default token */
        char            pi_ipadm_aobjname[IPADM_AOBJSIZ];
};

/*
 * pi_state/pr_kernel_state values
 */
#define PI_PRESENT              0x01
#define PI_JOINED_ALLNODES      0x02    /* allnodes multicast joined */
#define PI_JOINED_ALLROUTERS    0x04    /* allrouters multicast joined */

/*
 * Prefix configuration variable indices
 */
#define I_AdvValidLifetime      0       /* In seconds */
#define I_AdvOnLinkFlag         1
#define I_AdvPreferredLifetime  2       /* In seconds */
#define I_AdvAutonomousFlag     3
#define I_AdvValidExpiration    4       /* Seconds left */
#define I_AdvPreferredExpiration 5      /* Seconds left */
#define I_PREFIXSIZE            6       /* # of variables */

/*
 * A doubly-linked list of prefixes for onlink and addrconf.
 * ("Prefixes" in this context are identical to logical interfaces.)
 */
struct prefix {
        struct prefix   *pr_next;       /* Next prefix for this physical */
        struct prefix   *pr_prev;       /* Prev prefix for this physical */
        struct phyint   *pr_physical;   /* Back pointer */

        struct in6_addr pr_prefix;      /* Used to indentify prefix */
        uint_t          pr_prefix_len;  /* Num bits valid */

        char            pr_name[LIFNAMSIZ];
        struct in6_addr pr_address;
        uint64_t        pr_flags;       /* IFF_* flags */

        uint_t          pr_state;       /* PR_ONLINK | PR_AUTO etc */
        uint_t          pr_kernel_state; /* PR_ONLINK | PR_AUTO etc */
        boolean_t       pr_in_use;      /* To detect removed prefixes */

        /* Recorded variables on node/host */
        uint_t          pr_ValidLifetime;       /* In ms w/ 2 hour rule */
        uint_t          pr_PreferredLifetime;   /* In millseconds */
        uint_t          pr_OnLinkLifetime;      /* ms valid w/o 2 hour rule */
        boolean_t       pr_OnLinkFlag;
        boolean_t       pr_AutonomousFlag;

        uint_t          pr_CreateTime;          /* tmpaddr creation time */
                                                /* in SECONDS */
        uint_t          pr_attempts;    /* attempts to configure */
};

/*
 * Flags used for pr_kernel_state and pr_state where the latter is
 * user-level state.
 */
#define PR_ONLINK       0x01            /* On-link */
#define PR_AUTO         0x02            /* Stateless addrconf */
#define PR_DEPRECATED   0x04            /* Address is deprecated */
#define PR_STATIC       0x08            /* Not created by ndpd */

/*
 * The sum of all possible state string lengths, plus terminating
 * null character; if new states are added, this needs to be updated.
 * Useful for passing an appropriately sized buffer to prefix_print_state().
 *
 * Current strings: "ONLINK ", "AUTO ", "DEPRECATED ", "STATIC ", "\n"
 *                      7     +   5    +     11       +    7     +  1
 */
#define PREFIX_STATESTRLEN      31

/* Prefix used for storing advertisement specific stuff */
struct adv_prefix {
        struct adv_prefix       *adv_pr_next;   /* Next prefix */
        struct adv_prefix       *adv_pr_prev;   /* Prev prefix */
        struct phyint           *adv_pr_physical;       /* Back pointer */

        struct in6_addr         adv_pr_prefix;  /* Used to indentify prefix */
        uint_t                  adv_pr_prefix_len;      /* Num bits valid */

        /* Used when sending advertisements */
        struct confvar          adv_pr_config[I_PREFIXSIZE];
#define adv_pr_AdvValidLifetime adv_pr_config[I_AdvValidLifetime].cf_value
#define adv_pr_AdvOnLinkFlag    adv_pr_config[I_AdvOnLinkFlag].cf_value
#define adv_pr_AdvPreferredLifetime     \
                        adv_pr_config[I_AdvPreferredLifetime].cf_value
#define adv_pr_AdvAutonomousFlag        \
                        adv_pr_config[I_AdvAutonomousFlag].cf_value
#define adv_pr_AdvValidExpiration       \
                        adv_pr_config[I_AdvValidExpiration].cf_value
#define adv_pr_AdvPreferredExpiration   \
                        adv_pr_config[I_AdvPreferredExpiration].cf_value
        /* The two below are set if the timers decrement in real time */
#define adv_pr_AdvValidRealTime         \
                        adv_pr_config[I_AdvValidExpiration].cf_notdefault
#define adv_pr_AdvPreferredRealTime     \
                        adv_pr_config[I_AdvPreferredExpiration].cf_notdefault
};

/*
 * Doubly-linked list of default routers on a phyint.
 */
struct router {
        struct router   *dr_next;       /* Next router for this physical */
        struct router   *dr_prev;       /* Prev router for this physical */
        struct phyint   *dr_physical;   /* Back pointer */

        struct in6_addr dr_address;     /* Used to identify the router */
        uint_t          dr_lifetime;    /* In milliseconds */
        boolean_t       dr_inkernel;    /* Route added to kernel */
};

/*
 * Globals
 */
extern struct phyint *phyints;
extern int num_of_phyints;

/*
 * Functions
 */
extern uint_t           getcurrenttime(void);

extern struct phyint    *phyint_lookup(char *name);
extern struct phyint    *phyint_lookup_on_index(uint_t ifindex);
extern struct phyint    *phyint_create(char *name);
extern int              phyint_init_from_k(struct phyint *pi);
extern void             phyint_delete(struct phyint *pi);
extern uint_t           phyint_timer(struct phyint *pi, uint_t elapsed);
extern void             phyint_print_all(void);
extern int              phyint_get_lla(struct phyint *pi, struct lifreq *lifrp);
extern void             phyint_reach_random(struct phyint *pi,
                            boolean_t set_needed);
extern void             phyint_cleanup(struct phyint *pi);

extern boolean_t        tmptoken_create(struct phyint *pi);
extern void             tmptoken_delete(struct phyint *pi);
extern uint_t           tmptoken_timer(struct phyint *pi, uint_t elapsed);
extern boolean_t        token_equal(struct in6_addr t1, struct in6_addr t2,
                            int bits);

extern struct prefix    *prefix_create(struct phyint *pi, struct in6_addr addr,
                            int addrlen, uint64_t flags);
extern struct prefix    *prefix_lookup_name(struct phyint *pi, char *name);
extern struct prefix    *prefix_lookup_addr_match(struct prefix *pr);
extern struct prefix    *prefix_create_name(struct phyint *pi, char *name);
extern int              prefix_init_from_k(struct prefix *pr);
extern void             prefix_delete(struct prefix *pr);
extern boolean_t        prefix_equal(struct in6_addr p1, struct in6_addr p2,
                            int bits);
extern void             prefix_update_dhcp(struct prefix *pr);
extern void             prefix_update_k(struct prefix *pr);
extern uint_t           prefix_timer(struct prefix *pr, uint_t elapsed);
extern uint_t           adv_prefix_timer(struct adv_prefix *adv_pr,
                            uint_t elapsed);
extern struct prefix    *prefix_lookup_addr(struct phyint *pi,
                            struct in6_addr prefix);

extern struct adv_prefix *adv_prefix_lookup(struct phyint *pi,
                            struct in6_addr addr, int addrlen);
extern struct adv_prefix *adv_prefix_create(struct phyint *pi,
                            struct in6_addr addr, int addrlen);

extern struct router    *router_lookup(struct phyint *pi, struct in6_addr addr);
extern struct router    *router_create(struct phyint *pi, struct in6_addr addr,
                            uint_t lifetime);
extern void             router_update_k(struct router *dr);
extern uint_t           router_timer(struct router *dr, uint_t elapsed);

extern void     check_to_advertise(struct phyint *pi, enum adv_events event);
extern void     check_to_solicit(struct phyint *pi,
                    enum solicit_events event);
extern uint_t   advertise_event(struct phyint *pi, enum adv_events event,
                    uint_t elapsed);
extern uint_t   solicit_event(struct phyint *pi, enum solicit_events event,
                    uint_t elapsed);

extern void     print_route_sol(char *str, struct phyint *pi,
                    struct nd_router_solicit *rs, int len,
                    struct sockaddr_in6 *addr);
extern void     print_route_adv(char *str, struct phyint *pi,
                    struct nd_router_advert *ra, int len,
                    struct sockaddr_in6 *addr);
extern void     print_iflist(struct confvar *confvar);
extern void     print_prefixlist(struct confvar *confvar);

extern void     in_data(struct phyint *pi);

extern void     start_dhcp(struct phyint *pi);
extern void     release_dhcp(struct phyint *pi);

extern void     incoming_ra(struct phyint *pi, struct nd_router_advert *ra,
                    int len, struct sockaddr_in6 *from, boolean_t loopback);

extern boolean_t incoming_prefix_addrconf_process(struct phyint *pi,
                    struct prefix *pr, uchar_t *opt,
                    struct sockaddr_in6 *from, boolean_t loopback,
                    boolean_t new_prefix);

extern void     incoming_prefix_onlink_process(struct prefix *pr,
                    uchar_t *opt);

extern void     check_autoconf_var_consistency(struct phyint *, boolean_t,
    boolean_t);
extern void     prefix_update_ipadm_addrobj(struct prefix *pr, boolean_t add);
#ifdef  __cplusplus
}
#endif

#endif  /* _NDPD_TABLES_H */