Deleted Added
full compact
in6_var.h (191341) in6_var.h (191672)
1/*-
2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 44 unchanged lines hidden (view full) ---

53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE.
59 *
60 * @(#)in_var.h 8.1 (Berkeley) 6/10/93
1/*-
2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 44 unchanged lines hidden (view full) ---

53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE.
59 *
60 * @(#)in_var.h 8.1 (Berkeley) 6/10/93
61 * $FreeBSD: head/sys/netinet6/in6_var.h 191341 2009-04-20 22:56:34Z rwatson $
61 * $FreeBSD: head/sys/netinet6/in6_var.h 191672 2009-04-29 19:19:13Z bms $
62 */
63
64#ifndef _NETINET6_IN6_VAR_H_
65#define _NETINET6_IN6_VAR_H_
66
62 */
63
64#ifndef _NETINET6_IN6_VAR_H_
65#define _NETINET6_IN6_VAR_H_
66
67#include <sys/tree.h>
68
69#ifdef _KERNEL
70#include <sys/libkern.h>
71#endif
72
67/*
68 * Interface address, Internet version. One of these structures
69 * is allocated for each interface with an Internet address.
70 * The ifaddr structure contains the protocol-independent part
71 * of the structure and is assumed to be first.
72 */
73
74/*

--- 9 unchanged lines hidden (view full) ---

84 time_t ia6t_preferred; /* preferred lifetime expiration time */
85 u_int32_t ia6t_vltime; /* valid lifetime */
86 u_int32_t ia6t_pltime; /* prefix lifetime */
87};
88
89struct nd_ifinfo;
90struct scope6_id;
91struct lltable;
73/*
74 * Interface address, Internet version. One of these structures
75 * is allocated for each interface with an Internet address.
76 * The ifaddr structure contains the protocol-independent part
77 * of the structure and is assumed to be first.
78 */
79
80/*

--- 9 unchanged lines hidden (view full) ---

90 time_t ia6t_preferred; /* preferred lifetime expiration time */
91 u_int32_t ia6t_vltime; /* valid lifetime */
92 u_int32_t ia6t_pltime; /* prefix lifetime */
93};
94
95struct nd_ifinfo;
96struct scope6_id;
97struct lltable;
98struct mld_ifinfo;
99
92struct in6_ifextra {
93 struct in6_ifstat *in6_ifstat;
94 struct icmp6_ifstat *icmp6_ifstat;
95 struct nd_ifinfo *nd_ifinfo;
96 struct scope6_id *scope6_id;
97 struct lltable *lltable;
100struct in6_ifextra {
101 struct in6_ifstat *in6_ifstat;
102 struct icmp6_ifstat *icmp6_ifstat;
103 struct nd_ifinfo *nd_ifinfo;
104 struct scope6_id *scope6_id;
105 struct lltable *lltable;
106 struct mld_ifinfo *mld_ifinfo;
98};
99
100#define LLTABLE6(ifp) (((struct in6_ifextra *)(ifp)->if_afdata[AF_INET6])->lltable)
101
102struct in6_ifaddr {
103 struct ifaddr ia_ifa; /* protocol-independent info */
104#define ia_ifp ia_ifa.ifa_ifp
105#define ia_flags ia_ifa.ifa_flags

--- 378 unchanged lines hidden (view full) ---

484#define in6_ifstat_inc(ifp, tag) \
485do { \
486 if (ifp) \
487 ((struct in6_ifextra *)((ifp)->if_afdata[AF_INET6]))->in6_ifstat->tag++; \
488} while (/*CONSTCOND*/ 0)
489
490extern struct in6_addr zeroin6_addr;
491extern u_char inet6ctlerrmap[];
107};
108
109#define LLTABLE6(ifp) (((struct in6_ifextra *)(ifp)->if_afdata[AF_INET6])->lltable)
110
111struct in6_ifaddr {
112 struct ifaddr ia_ifa; /* protocol-independent info */
113#define ia_ifp ia_ifa.ifa_ifp
114#define ia_flags ia_ifa.ifa_flags

--- 378 unchanged lines hidden (view full) ---

493#define in6_ifstat_inc(ifp, tag) \
494do { \
495 if (ifp) \
496 ((struct in6_ifextra *)((ifp)->if_afdata[AF_INET6]))->in6_ifstat->tag++; \
497} while (/*CONSTCOND*/ 0)
498
499extern struct in6_addr zeroin6_addr;
500extern u_char inet6ctlerrmap[];
492#ifdef MALLOC_DECLARE
493MALLOC_DECLARE(M_IP6MADDR);
494#endif /* MALLOC_DECLARE */
495
496/*
497 * Macro for finding the internet address structure (in6_ifaddr) corresponding
498 * to a given interface (ifnet structure).
499 */
500
501#define IFP_TO_IA6(ifp, ia) \
502/* struct ifnet *ifp; */ \

--- 6 unchanged lines hidden (view full) ---

509 break; \
510 } \
511 (ia) = (struct in6_ifaddr *)ifa; \
512} while (/*CONSTCOND*/ 0)
513
514#endif /* _KERNEL */
515
516/*
501
502/*
503 * Macro for finding the internet address structure (in6_ifaddr) corresponding
504 * to a given interface (ifnet structure).
505 */
506
507#define IFP_TO_IA6(ifp, ia) \
508/* struct ifnet *ifp; */ \

--- 6 unchanged lines hidden (view full) ---

515 break; \
516 } \
517 (ia) = (struct in6_ifaddr *)ifa; \
518} while (/*CONSTCOND*/ 0)
519
520#endif /* _KERNEL */
521
522/*
517 * Multi-cast membership entry. One for each group/ifp that a PCB
518 * belongs to.
523 * IPv6 multicast MLD-layer source entry.
519 */
524 */
525struct ip6_msource {
526 RB_ENTRY(ip6_msource) im6s_link; /* RB tree links */
527 struct in6_addr im6s_addr;
528 struct im6s_st {
529 uint16_t ex; /* # of exclusive members */
530 uint16_t in; /* # of inclusive members */
531 } im6s_st[2]; /* state at t0, t1 */
532 uint8_t im6s_stp; /* pending query */
533};
534RB_HEAD(ip6_msource_tree, ip6_msource);
535
536/*
537 * IPv6 multicast PCB-layer source entry.
538 *
539 * NOTE: overlapping use of struct ip6_msource fields at start.
540 */
541struct in6_msource {
542 RB_ENTRY(ip6_msource) im6s_link; /* Common field */
543 struct in6_addr im6s_addr; /* Common field */
544 uint8_t im6sl_st[2]; /* state before/at commit */
545};
546
547#ifdef _KERNEL
548/*
549 * IPv6 source tree comparison function.
550 *
551 * An ordered predicate is necessary; bcmp() is not documented to return
552 * an indication of order, memcmp() is, and is an ISO C99 requirement.
553 */
554static __inline int
555ip6_msource_cmp(const struct ip6_msource *a, const struct ip6_msource *b)
556{
557
558 return (memcmp(&a->im6s_addr, &b->im6s_addr, sizeof(struct in6_addr)));
559}
560RB_PROTOTYPE(ip6_msource_tree, ip6_msource, im6s_link, ip6_msource_cmp);
561#endif /* _KERNEL */
562
563/*
564 * IPv6 multicast PCB-layer group filter descriptor.
565 */
566struct in6_mfilter {
567 struct ip6_msource_tree im6f_sources; /* source list for (S,G) */
568 u_long im6f_nsrc; /* # of source entries */
569 uint8_t im6f_st[2]; /* state before/at commit */
570};
571
572/*
573 * Legacy KAME IPv6 multicast membership descriptor.
574 */
520struct in6_multi_mship {
575struct in6_multi_mship {
521 struct in6_multi *i6mm_maddr; /* Multicast address pointer */
522 LIST_ENTRY(in6_multi_mship) i6mm_chain; /* multicast options chain */
576 struct in6_multi *i6mm_maddr;
577 LIST_ENTRY(in6_multi_mship) i6mm_chain;
523};
524
578};
579
525struct in6_multi {
580/*
581 * IPv6 group descriptor.
582 *
583 * For every entry on an ifnet's if_multiaddrs list which represents
584 * an IP multicast group, there is one of these structures.
585 *
586 * If any source filters are present, then a node will exist in the RB-tree
587 * to permit fast lookup by source whenever an operation takes place.
588 * This permits pre-order traversal when we issue reports.
589 * Source filter trees are kept separately from the socket layer to
590 * greatly simplify locking.
591 *
592 * When MLDv2 is active, in6m_timer is the response to group query timer.
593 * The state-change timer in6m_sctimer is separate; whenever state changes
594 * for the group the state change record is generated and transmitted,
595 * and kept if retransmissions are necessary.
596 *
597 * FUTURE: in6m_link is now only used when groups are being purged
598 * on a detaching ifnet. It could be demoted to a SLIST_ENTRY, but
599 * because it is at the very start of the struct, we can't do this
600 * w/o breaking the ABI for ifmcstat.
601 */
602struct in6_multi {
526 LIST_ENTRY(in6_multi) in6m_entry; /* list glue */
603 LIST_ENTRY(in6_multi) in6m_entry; /* list glue */
527 struct in6_addr in6m_addr; /* IP6 multicast address */
604 struct in6_addr in6m_addr; /* IPv6 multicast address */
528 struct ifnet *in6m_ifp; /* back pointer to ifnet */
529 struct ifmultiaddr *in6m_ifma; /* back pointer to ifmultiaddr */
605 struct ifnet *in6m_ifp; /* back pointer to ifnet */
606 struct ifmultiaddr *in6m_ifma; /* back pointer to ifmultiaddr */
530 u_int in6m_refcount; /* # membership claims by sockets */
607 u_int in6m_refcount; /* reference count */
531 u_int in6m_state; /* state of the membership */
532 u_int in6m_timer; /* MLD6 listener report timer */
608 u_int in6m_state; /* state of the membership */
609 u_int in6m_timer; /* MLD6 listener report timer */
533 struct timeval in6m_timer_expire; /* when the timer expires */
534 struct callout *in6m_timer_ch;
610
611 /* New fields for MLDv2 follow. */
612 struct mld_ifinfo *in6m_mli; /* MLD info */
613 SLIST_ENTRY(in6_multi) in6m_nrele; /* to-be-released by MLD */
614 struct ip6_msource_tree in6m_srcs; /* tree of sources */
615 u_long in6m_nsrc; /* # of tree entries */
616
617 struct ifqueue in6m_scq; /* queue of pending
618 * state-change packets */
619 struct timeval in6m_lastgsrtv; /* last G-S-R query */
620 uint16_t in6m_sctimer; /* state-change timer */
621 uint16_t in6m_scrv; /* state-change rexmit count */
622
623 /*
624 * SSM state counters which track state at T0 (the time the last
625 * state-change report's RV timer went to zero) and T1
626 * (time of pending report, i.e. now).
627 * Used for computing MLDv2 state-change reports. Several refcounts
628 * are maintained here to optimize for common use-cases.
629 */
630 struct in6m_st {
631 uint16_t iss_fmode; /* MLD filter mode */
632 uint16_t iss_asm; /* # of ASM listeners */
633 uint16_t iss_ex; /* # of exclusive members */
634 uint16_t iss_in; /* # of inclusive members */
635 uint16_t iss_rec; /* # of recorded sources */
636 } in6m_st[2]; /* state at t0, t1 */
535};
536
637};
638
537#define IN6M_TIMER_UNDEF -1
639/*
640 * Helper function to derive the filter mode on a source entry
641 * from its internal counters. Predicates are:
642 * A source is only excluded if all listeners exclude it.
643 * A source is only included if no listeners exclude it,
644 * and at least one listener includes it.
645 * May be used by ifmcstat(8).
646 */
647static __inline uint8_t
648im6s_get_mode(const struct in6_multi *inm, const struct ip6_msource *ims,
649 uint8_t t)
650{
538
651
652 t = !!t;
653 if (inm->in6m_st[t].iss_ex > 0 &&
654 inm->in6m_st[t].iss_ex == ims->im6s_st[t].ex)
655 return (MCAST_EXCLUDE);
656 else if (ims->im6s_st[t].in > 0 && ims->im6s_st[t].ex == 0)
657 return (MCAST_INCLUDE);
658 return (MCAST_UNDEFINED);
659}
660
539#ifdef _KERNEL
661#ifdef _KERNEL
540/* flags to in6_update_ifa */
541#define IN6_IFAUPDATE_DADDELAY 0x1 /* first time to configure an address */
542
662
543extern LIST_HEAD(in6_multihead, in6_multi) in6_multihead;
544
545/*
663/*
546 * Structure used by macros below to remember position when stepping through
547 * all of the in6_multi records.
664 * Lock macros for IPv6 layer multicast address lists. IPv6 lock goes
665 * before link layer multicast locks in the lock order. In most cases,
666 * consumers of IN_*_MULTI() macros should acquire the locks before
667 * calling them; users of the in_{add,del}multi() functions should not.
548 */
668 */
549struct in6_multistep {
550 struct in6_ifaddr *i_ia;
551 struct in6_multi *i_in6m;
552};
669extern struct mtx in6_multi_mtx;
670#define IN6_MULTI_LOCK() mtx_lock(&in6_multi_mtx)
671#define IN6_MULTI_UNLOCK() mtx_unlock(&in6_multi_mtx)
672#define IN6_MULTI_LOCK_ASSERT() mtx_assert(&in6_multi_mtx, MA_OWNED)
673#define IN6_MULTI_UNLOCK_ASSERT() mtx_assert(&in6_multi_mtx, MA_NOTOWNED)
553
554/*
674
675/*
555 * Macros for looking up the in6_multi record for a given IP6 multicast
556 * address on a given interface. If no matching record is found, "in6m"
557 * returns NULL.
676 * Look up an in6_multi record for an IPv6 multicast address
677 * on the interface ifp.
678 * If no record found, return NULL.
679 *
680 * SMPng: The IN6_MULTI_LOCK and IF_ADDR_LOCK on ifp must be held.
558 */
681 */
682static __inline struct in6_multi *
683in6m_lookup_locked(struct ifnet *ifp, const struct in6_addr *mcaddr)
684{
685 struct ifmultiaddr *ifma;
686 struct in6_multi *inm;
559
687
560#define IN6_LOOKUP_MULTI(addr, ifp, in6m) \
561/* struct in6_addr addr; */ \
562/* struct ifnet *ifp; */ \
563/* struct in6_multi *in6m; */ \
564do { \
565 struct ifmultiaddr *ifma; \
566 IF_ADDR_LOCK(ifp); \
567 TAILQ_FOREACH(ifma, &(ifp)->if_multiaddrs, ifma_link) { \
568 if (ifma->ifma_addr->sa_family == AF_INET6 \
569 && IN6_ARE_ADDR_EQUAL(&((struct sockaddr_in6 *)ifma->ifma_addr)->sin6_addr, \
570 &(addr))) \
571 break; \
572 } \
573 (in6m) = (struct in6_multi *)(ifma ? ifma->ifma_protospec : 0); \
574 IF_ADDR_UNLOCK(ifp); \
575} while(0)
688 IN6_MULTI_LOCK_ASSERT();
689 IF_ADDR_LOCK_ASSERT(ifp);
576
690
691 inm = NULL;
692 TAILQ_FOREACH(ifma, &((ifp)->if_multiaddrs), ifma_link) {
693 if (ifma->ifma_addr->sa_family == AF_INET6) {
694 inm = (struct in6_multi *)ifma->ifma_protospec;
695 if (IN6_ARE_ADDR_EQUAL(&inm->in6m_addr, mcaddr))
696 break;
697 inm = NULL;
698 }
699 }
700 return (inm);
701}
702
577/*
703/*
578 * Macro to step through all of the in6_multi records, one at a time.
579 * The current position is remembered in "step", which the caller must
580 * provide. IN6_FIRST_MULTI(), below, must be called to initialize "step"
581 * and get the first record. Both macros return a NULL "in6m" when there
582 * are no remaining records.
704 * Wrapper for in6m_lookup_locked().
705 *
706 * SMPng: Assumes that neithr the IN6_MULTI_LOCK() or IF_ADDR_LOCK() are held.
583 */
707 */
584#define IN6_NEXT_MULTI(step, in6m) \
585/* struct in6_multistep step; */ \
586/* struct in6_multi *in6m; */ \
587do { \
588 if (((in6m) = (step).i_in6m) != NULL) \
589 (step).i_in6m = LIST_NEXT((step).i_in6m, in6m_entry); \
590} while(0)
708static __inline struct in6_multi *
709in6m_lookup(struct ifnet *ifp, const struct in6_addr *mcaddr)
710{
711 struct in6_multi *inm;
591
712
592#define IN6_FIRST_MULTI(step, in6m) \
593/* struct in6_multistep step; */ \
594/* struct in6_multi *in6m */ \
595do { \
596 (step).i_in6m = LIST_FIRST(&in6_multihead); \
597 IN6_NEXT_MULTI((step), (in6m)); \
598} while(0)
713 IN6_MULTI_LOCK();
714 IF_ADDR_LOCK(ifp);
715 inm = in6m_lookup_locked(ifp, mcaddr);
716 IF_ADDR_UNLOCK(ifp);
717 IN6_MULTI_UNLOCK();
599
718
600struct in6_multi *in6_addmulti __P((struct in6_addr *, struct ifnet *,
601 int *, int));
602void in6_delmulti __P((struct in6_multi *));
603struct in6_multi_mship *in6_joingroup(struct ifnet *, struct in6_addr *, int *, int);
719 return (inm);
720}
721
722/* Acquire an in6_multi record. */
723static __inline void
724in6m_acquire_locked(struct in6_multi *inm)
725{
726
727 IN6_MULTI_LOCK_ASSERT();
728 ++inm->in6m_refcount;
729}
730
731struct ip6_moptions;
732struct sockopt;
733
734/* Multicast KPIs. */
735int im6o_mc_filter(const struct ip6_moptions *, const struct ifnet *,
736 const struct sockaddr *, const struct sockaddr *);
737int in6_mc_join(struct ifnet *, const struct in6_addr *,
738 struct in6_mfilter *, struct in6_multi **, int);
739int in6_mc_join_locked(struct ifnet *, const struct in6_addr *,
740 struct in6_mfilter *, struct in6_multi **, int);
741int in6_mc_leave(struct in6_multi *, struct in6_mfilter *);
742int in6_mc_leave_locked(struct in6_multi *, struct in6_mfilter *);
743void in6m_clear_recorded(struct in6_multi *);
744void in6m_commit(struct in6_multi *);
745void in6m_print(const struct in6_multi *);
746int in6m_record_source(struct in6_multi *, const struct in6_addr *);
747void in6m_release_locked(struct in6_multi *);
748void ip6_freemoptions(struct ip6_moptions *);
749int ip6_getmoptions(struct inpcb *, struct sockopt *);
750int ip6_setmoptions(struct inpcb *, struct sockopt *);
751
752/* Legacy KAME multicast KPIs. */
753struct in6_multi_mship *
754 in6_joingroup(struct ifnet *, struct in6_addr *, int *, int);
604int in6_leavegroup(struct in6_multi_mship *);
755int in6_leavegroup(struct in6_multi_mship *);
756
757/* flags to in6_update_ifa */
758#define IN6_IFAUPDATE_DADDELAY 0x1 /* first time to configure an address */
759
605int in6_mask2len __P((struct in6_addr *, u_char *));
606int in6_control __P((struct socket *, u_long, caddr_t, struct ifnet *,
607 struct thread *));
608int in6_update_ifa __P((struct ifnet *, struct in6_aliasreq *,
609 struct in6_ifaddr *, int));
610void in6_purgeaddr __P((struct ifaddr *));
611int in6if_do_dad __P((struct ifnet *));
612void in6_purgeif __P((struct ifnet *));
613void in6_savemkludge __P((struct in6_ifaddr *));
614void *in6_domifattach __P((struct ifnet *));
615void in6_domifdetach __P((struct ifnet *, void *));
616void in6_setmaxmtu __P((void));
617int in6_if2idlen __P((struct ifnet *));
760int in6_mask2len __P((struct in6_addr *, u_char *));
761int in6_control __P((struct socket *, u_long, caddr_t, struct ifnet *,
762 struct thread *));
763int in6_update_ifa __P((struct ifnet *, struct in6_aliasreq *,
764 struct in6_ifaddr *, int));
765void in6_purgeaddr __P((struct ifaddr *));
766int in6if_do_dad __P((struct ifnet *));
767void in6_purgeif __P((struct ifnet *));
768void in6_savemkludge __P((struct in6_ifaddr *));
769void *in6_domifattach __P((struct ifnet *));
770void in6_domifdetach __P((struct ifnet *, void *));
771void in6_setmaxmtu __P((void));
772int in6_if2idlen __P((struct ifnet *));
618void in6_restoremkludge __P((struct in6_ifaddr *, struct ifnet *));
619void in6_purgemkludge __P((struct ifnet *));
620struct in6_ifaddr *in6ifa_ifpforlinklocal __P((struct ifnet *, int));
621struct in6_ifaddr *in6ifa_ifpwithaddr __P((struct ifnet *, struct in6_addr *));
622char *ip6_sprintf __P((char *, const struct in6_addr *));
623int in6_addr2zoneid __P((struct ifnet *, struct in6_addr *, u_int32_t *));
624int in6_matchlen __P((struct in6_addr *, struct in6_addr *));
625int in6_are_prefix_equal __P((struct in6_addr *, struct in6_addr *, int));
626void in6_prefixlen2mask __P((struct in6_addr *, int));
627int in6_prefix_ioctl __P((struct socket *, u_long, caddr_t,

--- 13 unchanged lines hidden ---
773struct in6_ifaddr *in6ifa_ifpforlinklocal __P((struct ifnet *, int));
774struct in6_ifaddr *in6ifa_ifpwithaddr __P((struct ifnet *, struct in6_addr *));
775char *ip6_sprintf __P((char *, const struct in6_addr *));
776int in6_addr2zoneid __P((struct ifnet *, struct in6_addr *, u_int32_t *));
777int in6_matchlen __P((struct in6_addr *, struct in6_addr *));
778int in6_are_prefix_equal __P((struct in6_addr *, struct in6_addr *, int));
779void in6_prefixlen2mask __P((struct in6_addr *, int));
780int in6_prefix_ioctl __P((struct socket *, u_long, caddr_t,

--- 13 unchanged lines hidden ---