michael@0: /*- michael@0: * Copyright (c) 1980, 1986, 1993 michael@0: * The Regents of the University of California. All rights reserved. michael@0: * michael@0: * Redistribution and use in source and binary forms, with or without michael@0: * modification, are permitted provided that the following conditions michael@0: * are met: michael@0: * 1. Redistributions of source code must retain the above copyright michael@0: * notice, this list of conditions and the following disclaimer. michael@0: * 2. Redistributions in binary form must reproduce the above copyright michael@0: * notice, this list of conditions and the following disclaimer in the michael@0: * documentation and/or other materials provided with the distribution. michael@0: * 4. Neither the name of the University nor the names of its contributors michael@0: * may be used to endorse or promote products derived from this software michael@0: * without specific prior written permission. michael@0: * michael@0: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND michael@0: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE michael@0: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE michael@0: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE michael@0: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL michael@0: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS michael@0: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) michael@0: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT michael@0: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY michael@0: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF michael@0: * SUCH DAMAGE. michael@0: * michael@0: */ michael@0: michael@0: #ifndef _USER_ROUTE_H_ michael@0: #define _USER_ROUTE_H_ michael@0: michael@0: /* michael@0: * Kernel resident routing tables. michael@0: * michael@0: * The routing tables are initialized when interface addresses michael@0: * are set by making entries for all directly connected interfaces. michael@0: */ michael@0: michael@0: /* michael@0: * A route consists of a destination address and a reference michael@0: * to a routing entry. These are often held by protocols michael@0: * in their control blocks, e.g. inpcb. michael@0: */ michael@0: michael@0: struct sctp_route { michael@0: struct sctp_rtentry *ro_rt; michael@0: struct sockaddr ro_dst; michael@0: }; michael@0: michael@0: /* michael@0: * These numbers are used by reliable protocols for determining michael@0: * retransmission behavior and are included in the routing structure. michael@0: */ michael@0: struct sctp_rt_metrics_lite { michael@0: u_long rmx_mtu; /* MTU for this path */ michael@0: #if 0 michael@0: u_long rmx_expire; /* lifetime for route, e.g. redirect */ michael@0: u_long rmx_pksent; /* packets sent using this route */ michael@0: #endif michael@0: }; michael@0: michael@0: /* michael@0: * We distinguish between routes to hosts and routes to networks, michael@0: * preferring the former if available. For each route we infer michael@0: * the interface to use from the gateway address supplied when michael@0: * the route was entered. Routes that forward packets through michael@0: * gateways are marked so that the output routines know to address the michael@0: * gateway rather than the ultimate destination. michael@0: */ michael@0: struct sctp_rtentry { michael@0: #if 0 michael@0: struct radix_node rt_nodes[2]; /* tree glue, and other values */ michael@0: /* michael@0: * XXX struct rtentry must begin with a struct radix_node (or two!) michael@0: * because the code does some casts of a 'struct radix_node *' michael@0: * to a 'struct rtentry *' michael@0: */ michael@0: #define rt_key(r) (*((struct sockaddr **)(&(r)->rt_nodes->rn_key))) michael@0: #define rt_mask(r) (*((struct sockaddr **)(&(r)->rt_nodes->rn_mask))) michael@0: struct sockaddr *rt_gateway; /* value */ michael@0: u_long rt_flags; /* up/down?, host/net */ michael@0: #endif michael@0: struct ifnet *rt_ifp; /* the answer: interface to use */ michael@0: struct ifaddr *rt_ifa; /* the answer: interface address to use */ michael@0: struct sctp_rt_metrics_lite rt_rmx; /* metrics used by rx'ing protocols */ michael@0: long rt_refcnt; /* # held references */ michael@0: #if 0 michael@0: struct sockaddr *rt_genmask; /* for generation of cloned routes */ michael@0: caddr_t rt_llinfo; /* pointer to link level info cache */ michael@0: struct rtentry *rt_gwroute; /* implied entry for gatewayed routes */ michael@0: struct rtentry *rt_parent; /* cloning parent of this route */ michael@0: #endif michael@0: struct mtx rt_mtx; /* mutex for routing entry */ michael@0: }; michael@0: michael@0: #define RT_LOCK_INIT(_rt) mtx_init(&(_rt)->rt_mtx, "rtentry", NULL, MTX_DEF | MTX_DUPOK) michael@0: #define RT_LOCK(_rt) mtx_lock(&(_rt)->rt_mtx) michael@0: #define RT_UNLOCK(_rt) mtx_unlock(&(_rt)->rt_mtx) michael@0: #define RT_LOCK_DESTROY(_rt) mtx_destroy(&(_rt)->rt_mtx) michael@0: #define RT_LOCK_ASSERT(_rt) mtx_assert(&(_rt)->rt_mtx, MA_OWNED) michael@0: michael@0: #define RT_ADDREF(_rt) do { \ michael@0: RT_LOCK_ASSERT(_rt); \ michael@0: KASSERT((_rt)->rt_refcnt >= 0, \ michael@0: ("negative refcnt %ld", (_rt)->rt_refcnt)); \ michael@0: (_rt)->rt_refcnt++; \ michael@0: } while (0) michael@0: #define RT_REMREF(_rt) do { \ michael@0: RT_LOCK_ASSERT(_rt); \ michael@0: KASSERT((_rt)->rt_refcnt > 0, \ michael@0: ("bogus refcnt %ld", (_rt)->rt_refcnt)); \ michael@0: (_rt)->rt_refcnt--; \ michael@0: } while (0) michael@0: #define RTFREE_LOCKED(_rt) do { \ michael@0: if ((_rt)->rt_refcnt <= 1) { \ michael@0: rtfree(_rt); \ michael@0: } else { \ michael@0: RT_REMREF(_rt); \ michael@0: RT_UNLOCK(_rt); \ michael@0: } \ michael@0: /* guard against invalid refs */ \ michael@0: _rt = NULL; \ michael@0: } while (0) michael@0: #define RTFREE(_rt) do { \ michael@0: RT_LOCK(_rt); \ michael@0: RTFREE_LOCKED(_rt); \ michael@0: } while (0) michael@0: #endif