Index: projects/routing/.arcconfig =================================================================== --- projects/routing/.arcconfig (revision 287042) +++ projects/routing/.arcconfig (revision 287043) @@ -1,5 +1,6 @@ { "project.name": "S", + "repository.callsign" : "S", "phabricator.uri" : "https://reviews.freebsd.org/", "history.immutable" : true } Index: projects/routing/.arclint =================================================================== --- projects/routing/.arclint (revision 287042) +++ projects/routing/.arclint (revision 287043) @@ -1,9 +1,25 @@ { + "exclude": "(contrib|crypto)", "linters": { "python": { "type": "pep8", - "exclude": "(contrib)", "include": "(\\.py$)" + }, + "spelling": { + "type": "spelling" + }, + "chmod": { + "type": "chmod" + }, + "merge-conflict": { + "type": "merge-conflict" + }, + "filename": { + "type": "filename" + }, + "json": { + "type": "json", + "include": "(\\.arclint|\\.json$)" } } } Index: projects/routing/share/man/man9/lltable.9 =================================================================== --- projects/routing/share/man/man9/lltable.9 (revision 287042) +++ projects/routing/share/man/man9/lltable.9 (nonexistent) @@ -1,261 +0,0 @@ -.\"- -.\" Copyright (c) 2015 Alexander V. Chernikov -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.Dd January 5, 2015 -.Dt LLTABLE 9 -.Os -.Sh NAME -.Nm lltable -.Nd "Link Level address Table" -.Sh SYNOPSIS -.In net/if_llatbl.h -.In net/if_llatbl_var.h -.\" -.Ft void -.Fn lltable_link "struct lltable *llt" -.Ft void -.Fn lltable_free "struct lltable *llt" -.Ft struct ifnet * -.Fn lltable_get_ifp "const struct lltable *llt" -.Ft int -.Fn lltable_get_af "const struct lltable *llt" -.Ft void -.Fo lltable_fill_sa_entry -.Fa "const struct llentry *lle" "struct sockaddr *sa" -.Fc -.Ft typedef struct llentry * -.Fn (llt_lookup_t) "struct lltable *" "u_int flags" "const void *paddr" -.Ft typedef struct llentry * -.Fn (llt_create_t) "struct lltable *" "u_int flags" "const void *paddr" -.Ft typedef int -.Fn (llt_dump_entry_t) "struct lltable *" "struct llentry *" "struct sysctl_req *" -.Ft typedef uint32_t -.Fn (llt_hash_t) "const struct llentry *" -.Ft typedef int -.Fo (llt_match_prefix_t) -.Fa "const struct sockaddr *" "const struct sockaddr *" "u_int" "struct llentry *" -.Fc -.Ft typedef void -.Fn (llt_clear_entry_t) "struct lltable *" "struct llentry *" -.Ft typedef void -.Fn (llt_free_tbl_t) "struct lltable *" -.Ft typedef void -.Fn (llt_link_entry_t) "struct lltable *" "struct llentry *" -.Ft typedef void -.Fn (llt_unlink_entry_t) "struct llentry *" -.Ft typedef int -.Fo (llt_prepare_sentry_t) -.Fa "struct lltable *" "struct llentry * struct rt_addrinfo *" -.Fc -.Ft typedef const void * -.Fn (llt_get_sa_addr_t) "const struct sockaddr *l3addr" -.Ft typedef void -.Fn (llt_fill_sa_entry_t) "const struct llentry *" "struct sockaddr *" -.Ft typedef int -.Fn (llt_foreach_cb_t) "struct lltable *" "struct llentry *" "void *" -.Ft typedef int -.Fn (llt_foreach_entry_t) "struct lltable *" "llt_foreach_cb_t *" "void *" -.\" -.Sh DESCRIPTION -Link level tables provides abstract interface to manage mappings between -addresses and their link level counterparts. -.Pp -Should not be used directly in places other than implementation for particular address -family. -.Pp -The following objects are used in -.Nm : -.Ss lle -(link level entry), described in -.Xr llentry 9 -holds generic and per address family mapping between L3 address (IPv4/IPv6) and -link-layer address (MAC), resolution/management protocol (arp/ndp) state, -timers, packet queue (for unresolved addresses) and other data. -.Ss llt -( -.Vt "struct lltable" -) holds pointers to lle storage and all address family dependent functions for -managing entries in given table. -.Sh STORAGE MODEL -Currently, both IPv4 and IPv6 storage are implemented as chained hash table. -Tables are non-resizable and default size is LLTBL_HASHTBL_SIZE (32). -.Sh LOCKING MODEL -.Nm -uses dual-locking model for each table. -All control-plane (e.g. message processing/timers/etc) operations are protected -with afdata configuration rwlock. Fast path operations are protected with -afdata runtime rmlock. -Additionally, lle is protected by per-lle rwlock. -.Pp -Table changes (entry insertion/removal) are protected with both (e.g. CFG and -RUN) locks. -LLE changes (first 64 bytes used by fast path code) are protected with -CFG, RUN and LLE locks. -Other LLE fields are protected by LLE lock, -.Pp -The following lock order must be maintained: -.Bd -literal -offset indent -TABLE CFG lock -LLE lock -TABLE RUN lock -.Ed -.Sh EVENT HANDLERS -.Nm -invokes -.Fa lle_event -.Xr EVENTHANDLER 9 -event each time when lle changed its state. -Pointer to -.Pq Vt "struct llentry *" -is passed as the first argument, new state follows. -There are 4 different abstract states and mapping to actual protocol states -varies. -Current states are: -.Bd -literal -offset indent -LLENTRY_RESOLVED -LLENTRY_TIMEDOUT -LLENTRY_DELETED -LLENTRY_EXPIRED -.Ed -.Pp -Note that handler is invoked with lle lock held. -.Sh HELPER LLTABLE FUNCTIONS -Use -.Fn lltable_get_ifp -and -.Fn lltable_get_af -functions to retrieve interface and address family of -.Nm -.Pp -.Fn lltable_fill_sa_entry -can be used to store address of lle inside provided -.Vt "struct sockaddr" -buffer. -It is caller responsibility to ensure that sockaddr buffer size is enough. -.Vt "struct sockaddr_storage" -should be used for cases when address family is unknown. -.Sh NEW LLTABLE -To create new type of link-level table you need to implement all callbacks -described in -.Sx MANDATORY CALLBACKS -section. If you use non-default storage model you also have to implement all -non-mandatory callbacks. If (unlikely) protocol address or link layer address -can't fit into embedded lle storage it is safe to use private version of -.Vt "struct llentry" -with additional data necessary for your implementation. -.Pp -To use new code you need to create new -.Nm -instance (typically happens in -.Xr domain 9 -ifattach handler). Caller has to allocate -.Vt "struct lltable" , -fill address family, interface and all necessary methods. To bring new table -online you need to call -.Fn lltable_link -.Pp -To free it (with draining of all data) call -.Fn lltable_free -.Sh MANDATORY CALLBACKS -The most important method is -.Fn llt_lookup . -Function needs to find pointer to -.Vt "struct llentry" -in supplied table based on address pointer. Additionally, function -has to handle lookup flags (typically responcible for lle locking). -Table locking is done by the caller. -.Pp -To allocate new -.Vt "struct llentry" -entry stack calls -.Fn llt_create . -Function is responsible for allocating memory and setting initial configuration -for the entry. Called by the stack, table lock is not held. Can return NULL. -.Pp -To dump -.Vt "struct llentry" -entry via binary sysctl interface stack calls -.Fn llt_dump_entry . -Function is responsible for preparing data in -.Xr route 4 -format and calling -.Fn SYSCTL_OUT -to push data. -.Pp -To make valid lle entry from routing socket-provided data (static arp/ndp) -.Fn llt_prepare_static_entry -callback has to be implemented. -.Pp -If default storage model is used, you need to provide -.Fn llt_hash -implementation for default -.Fn llt_link_entry -and -.Fn llt_unlink_entry -callbacks to work. Function is mandatory for default storage model. -.Pp -To filter entries based on "match prefix" criteria, stacks uses -.Fn llt_match_prefix -callback. -.Pp -To free an entry stack calls -.Fn llt_clear_entry . -This functions unlinks entry from table (if not already), stops timers, -sets deleted flag, drops packets queue and frees entry. -.Pp -To permit stack work with both addresses and sockaddrs, -.Fn llt_get_sa_addr -and -.Fn llt_fill_sa_entry -callbacks has to be implemented. The former retrieves address pointer -from -.Vt "struct sockaddr" -while the latter makes valid -.Vt "struct sockaddr" from provided address. -.Sh STORAGE SPECIFIC CALLBACKS -To permit stack adding and deleting items to custom storage -.Fn llt_link_entry -and -.Fn llt_unlink_entry -needs to be implemented. -.Pp -In order to be able to traverse all items in table, -.Fn llt_foreach_entry -callback needs to be implemented. -.Pp -Custom -.Fn llt_free_tbl -callback has to be provided to ease cleanng up case for the stack. -Callback has to flush/free all entries for given table, free all allocated -structures and storage itself. -.Sh SEE ALSO -.Xr rtentry 9 , -.Xr arp 4 -.Sh AUTHORS -.An -nosplit -This manpage was written by -.An Alexander V. Chernikov. Property changes on: projects/routing/share/man/man9/lltable.9 ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: projects/routing/sys/net/if_llatbl_var.h =================================================================== --- projects/routing/sys/net/if_llatbl_var.h (revision 287042) +++ projects/routing/sys/net/if_llatbl_var.h (nonexistent) @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2014 Alexander V. Chernikov. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -__FBSDID("$FreeBSD$"); - -#ifndef _NET_IF_LLATBL_VAR_H_ -#define _NET_IF_LLATBL_VAR_H_ - - -extern struct rwlock lltable_rwlock; -#define LLTABLE_RLOCK() rw_rlock(&lltable_rwlock) -#define LLTABLE_RUNLOCK() rw_runlock(&lltable_rwlock) -#define LLTABLE_WLOCK() rw_wlock(&lltable_rwlock) -#define LLTABLE_WUNLOCK() rw_wunlock(&lltable_rwlock) -#define LLTABLE_LOCK_ASSERT() rw_assert(&lltable_rwlock, RA_LOCKED) - -typedef struct llentry *(llt_lookup_t)(struct lltable *, u_int flags, - const void *paddr); -typedef struct llentry *(llt_create_t)(struct lltable *, u_int flags, - const void *paddr); -typedef int (llt_dump_entry_t)(struct lltable *, struct llentry *, - struct sysctl_req *); -typedef uint32_t (llt_hash_t)(const struct llentry *, uint32_t); -typedef int (llt_match_prefix_t)(const struct sockaddr *, - const struct sockaddr *, u_int, struct llentry *); -typedef void (llt_clear_entry_t)(struct lltable *, struct llentry *); -typedef void (llt_free_tbl_t)(struct lltable *); -typedef void (llt_link_entry_t)(struct lltable *, struct llentry *); -typedef void (llt_unlink_entry_t)(struct llentry *); -typedef int (llt_prepare_sentry_t)(struct lltable *, struct llentry *, - struct rt_addrinfo *); -typedef const void *(llt_get_sa_addr_t)(const struct sockaddr *l3addr); -typedef void (llt_fill_sa_entry_t)(const struct llentry *, struct sockaddr *); - -typedef int (llt_foreach_cb_t)(struct lltable *, struct llentry *, void *); -typedef int (llt_foreach_entry_t)(struct lltable *, llt_foreach_cb_t *, void *); - - -struct lltable { - SLIST_ENTRY(lltable) llt_link; - int llt_af; - int llt_hsize; - struct llentries *lle_head; - struct ifnet *llt_ifp; - - llt_lookup_t *llt_lookup; - llt_create_t *llt_create; - llt_dump_entry_t *llt_dump_entry; - llt_hash_t *llt_hash; - llt_match_prefix_t *llt_match_prefix; - llt_clear_entry_t *llt_clear_entry; - llt_foreach_entry_t *llt_foreach_entry; - llt_link_entry_t *llt_link_entry; - llt_unlink_entry_t *llt_unlink_entry; - llt_prepare_sentry_t *llt_prepare_static_entry; - llt_get_sa_addr_t *llt_get_sa_addr; - llt_fill_sa_entry_t *llt_fill_sa_entry; - llt_free_tbl_t *llt_free_tbl; -}; - -MALLOC_DECLARE(M_LLTABLE); - -void lltable_link(struct lltable *llt); -void lltable_free(struct lltable *llt); -struct lltable *lltable_allocate_htbl(uint32_t hsize); - -/* helper functions */ -size_t lltable_drop_entry_queue(struct llentry *); - -/* - * Generic link layer table methods. - */ - -static __inline struct llentry * -lltable_lookup_lle(struct lltable *llt, u_int flags, - const void *paddr) -{ - - return (llt->llt_lookup(llt, flags, paddr)); -} - -struct llentry *lltable_create_lle(struct lltable *llt, u_int flags, - const void *paddr); -void lltable_link_entry(struct lltable *llt, struct llentry *lle); -void lltable_unlink_entry(struct lltable *llt, struct llentry *lle); - - -#endif Property changes on: projects/routing/sys/net/if_llatbl_var.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: projects/routing/sys/net/rt_nhops.c =================================================================== --- projects/routing/sys/net/rt_nhops.c (revision 287042) +++ projects/routing/sys/net/rt_nhops.c (nonexistent) @@ -1,1322 +0,0 @@ -/*- - * Copyright (c) 2014 - * Alexander V. Chernikov - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Temporary file. In future it should be split between net/route.c - * and per-AF files like netinet/in_rmx.c | netinet6/in6_rmx.c - */ - -#include "opt_inet.h" -#include "opt_inet6.h" -#include "opt_route.h" -#include "opt_mpath.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#ifdef RADIX_MPATH -#include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include - -struct fwd_info { - fib_lookup_t *lookup; - void *state; -}; - -#define FWD_FSM_NONE 0 -#define FWD_FSM_INIT 1 -#define FWD_FSM_FWD 2 -struct fwd_control { - int fwd_state; /* FSM */ - struct fwd_module *fm; -}; - -#if 0 -static struct fwd_info *fwd_db[FWD_SIZE]; -static struct fwd_control *fwd_ctl[FWD_SIZE]; - -static TAILQ_HEAD(fwd_module_list, fwd_module) modulehead = TAILQ_HEAD_INITIALIZER(modulehead); -static struct fwd_module_list fwd_modules[FWD_SIZE]; - -static uint8_t fwd_map_af[] = { - AF_INET, - AF_INET6, -}; - -static struct rwlock fwd_lock; -#define FWD_LOCK_INIT() rw_init(&fwd_lock, "fwd_lock") -#define FWD_RLOCK() rw_rlock(&fwd_lock) -#define FWD_RUNLOCK() rw_runlock(&fwd_lock) -#define FWD_WLOCK() rw_wlock(&fwd_lock) -#define FWD_WUNLOCK() rw_wunlock(&fwd_lock) - -int fwd_attach_fib(struct fwd_module *fm, u_int fib); -int fwd_destroy_fib(struct fwd_module *fm, u_int fib); -#endif - -static inline uint16_t fib_rte_to_nh_flags(int rt_flags); -#ifdef INET -static void rib4_rte_to_nh_extended(struct rtentry *rte, struct in_addr dst, - struct rt4_extended *prt4); -static void fib4_rte_to_nh_extended(struct rtentry *rte, struct in_addr dst, - uint32_t flags, struct nhop4_extended *pnh4); -static void fib4_rte_to_nh(struct rtentry *rte, struct in_addr dst, - uint32_t flags, struct nhop4_basic *pnh4); -#endif -#ifdef INET6 -static void fib6_rte_to_nh_extended(struct rtentry *rte, struct in6_addr *dst, - uint32_t flags, struct nhop6_extended *pnh6); -static void fib6_rte_to_nh(struct rtentry *rte, struct in6_addr *dst, - uint32_t flags, struct nhop6_basic *pnh6); -static int fib6_storelladdr(struct ifnet *ifp, struct in6_addr *dst, - int mm_flags, u_char *desten); -static uint16_t fib6_get_ifa(struct rtentry *rte); -static int fib6_lla_to_nh_basic(struct in6_addr *dst, uint32_t scopeid, - uint32_t flags, struct nhop6_basic *pnh6); -static int fib6_lla_to_nh_extended(struct in6_addr *dst, uint32_t scopeid, - uint32_t flags, struct nhop6_extended *pnh6); -static int fib6_lla_to_nh(struct in6_addr *dst, uint32_t scopeid, - struct nhop_prepend *nh, struct ifnet **lifp); -#endif - -MALLOC_DEFINE(M_RTFIB, "rtfib", "routing fwd"); - - - -/* - * Per-AF fast routines returning minimal needed info. - * It is not safe to dereference any pointers since it - * may end up with use-after-free case. - * Typically it may be used to check if outgoing - * interface matches or to calculate proper MTU. - * - * Note that returned interface pointer is logical one, - * e.g. actual transmit ifp may be different. - * Difference may be triggered by - * 1) loopback routes installed for interface addresses. - * e.g. for address 10.0.0.1 with prefix /24 bound to - * interface ix0, "logical" interface will be "ix0", - * while "trasmit" interface will be "lo0" since this is - * loopback route. You should consider using other - * functions if you need "transmit" interface or both. - * - * - * Returns 0 on match, error code overwise. - */ - -//#define NHOP_DIRECT -#define RNTORT(p) ((struct rtentry *)(p)) - - -/* - * Copies proper nexthop data based on @nh_src nexthop. - * - * For non-ECMP nexthop function simply copies @nh_src. - * For ECMP nexthops flowid is used to select proper - * nexthop. - * - */ -static inline void -fib_choose_prepend(uint32_t fibnum, struct nhop_prepend *nh_src, - uint32_t flowid, struct nhop_prepend *nh, int af) -{ - struct nhop_multi *nh_multi; - int idx; - - if ((nh_src->nh_flags & NHF_RECURSE) != 0) { - - /* - * Recursive nexthop. Choose direct nexthop - * based on flowid. - */ - nh_multi = (struct nhop_multi *)nh_src; - idx = nh_multi->nh_nhops[flowid % nh_multi->nh_count]; -#if 0 - KASSERT((fibnum < rt_numfibs), ("fib4_lookup_prepend§: bad fibnum")); - rh = rt_tables_get_rnh(fibnum, AF_INET); - //nh_src = &rh->nhops[i]; -#endif - } - - *nh = *nh_src; - /* TODO: Do some light-weight refcounting on egress ifp's */ -} - -static inline void -fib_free_nh_prepend(uint32_t fibnum, struct nhop_prepend *nh, int af) -{ - - /* TODO: Do some light-weight refcounting on egress ifp's */ -} - -#ifdef INET -void -fib4_free_nh_prepend(uint32_t fibnum, struct nhop_prepend *nh) -{ - - fib_free_nh_prepend(fibnum, nh, AF_INET); -} - -void -fib4_choose_prepend(uint32_t fibnum, struct nhop_prepend *nh_src, - uint32_t flowid, struct nhop_prepend *nh, struct nhop4_extended *nh_ext) -{ - - fib_choose_prepend(fibnum, nh_src, flowid, nh, AF_INET); - if (nh_ext == NULL) - return; - - nh_ext->nh_ifp = NH_LIFP(nh); - nh_ext->nh_mtu = nh->nh_mtu; - nh_ext->nh_flags = nh->nh_flags; -#if 0 - /* TODO: copy source/gw address from extended nexthop data */ - nh_ext->nh_addr = ; - nh_ext->nh_src= ; -#endif -} - -/* - * Function performs lookup in IPv4 table fib @fibnum. - * - * In case of successful lookup @nh header is filled with - * appropriate interface info and full L2 header to prepend. - * - * If no valid ARP record is present, NHF_L2_INCOMPLETE flag - * is set and gateway address is stored into nh->d.gw4 - * - * If @nh_ext is not NULL, additional nexthop data is stored there. - * - * Returns 0 on success. - * - */ -int -fib4_lookup_prepend(uint32_t fibnum, struct in_addr dst, struct mbuf *m, - struct nhop_prepend *nh, struct nhop4_extended *nh_ext) -{ - struct rib_head *rh; - struct radix_node *rn; - struct sockaddr_in *gw_sa, sin; - struct ifnet *lifp; - struct in_addr gw; - struct ether_header *eh; - int error, flags; - struct rtentry *rte; - RIB_LOCK_READER; - - KASSERT((fibnum < rt_numfibs), ("fib4_lookup_prepend: bad fibnum")); - rh = rt_tables_get_rnh(fibnum, AF_INET); - if (rh == NULL) - return (EHOSTUNREACH); - - /* Prepare lookup key */ - memset(&sin, 0, sizeof(sin)); - sin.sin_len = sizeof(struct sockaddr_in); - sin.sin_addr = dst; - - RIB_RLOCK(rh); - rn = rh->rnh_matchaddr((void *)&sin, &rh->head); - rte = RNTORT(rn); - if (rn == NULL || ((rn->rn_flags & RNF_ROOT) != 0) || - RT_LINK_IS_UP(rte->rt_ifp) == 0) { - RIB_RUNLOCK(rh); - return (EHOSTUNREACH); - } - - /* - * Currently we fill in @nh ourselves. - * In near future rte will have nhop index to copy from. - */ - - /* Calculate L3 info */ - flags = 0; - nh->nh_mtu = min(rte->rt_mtu, rte->rt_ifp->if_mtu); - if (rte->rt_flags & RTF_GATEWAY) { - gw_sa = (struct sockaddr_in *)rte->rt_gateway; - gw = gw_sa->sin_addr; - } else - gw = dst; - /* Set flags */ - flags = fib_rte_to_nh_flags(rte->rt_flags); - gw_sa = (struct sockaddr_in *)rt_key(rte); - if (gw_sa->sin_addr.s_addr == 0) - flags |= NHF_DEFAULT; - - /* - * TODO: nh L2/L3 resolve. - * Currently all we have is rte ifp. - * Simply use it. - */ - /* Save interface address ifp */ - lifp = rte->rt_ifa->ifa_ifp; - nh->aifp_idx = lifp->if_index; - /* Save both logical and transmit interface indexes */ - lifp = rte->rt_ifp; - nh->lifp_idx = lifp->if_index; - nh->i.ifp_idx = nh->lifp_idx; - - if (nh_ext != NULL) { - /* Fill in extended info */ - fib4_rte_to_nh_extended(rte, dst, 0, nh_ext); - } - - RIB_RUNLOCK(rh); - - nh->nh_flags = flags; - /* - * Try to lookup L2 info. - * Do this using separate LLE locks. - * TODO: move this under radix lock. - */ - if (lifp->if_type == IFT_ETHER) { - eh = (struct ether_header *)nh->d.data; - - /* - * Fill in ethernet header. - * It should be already presented if we're - * sending data via known gateway. - */ - error = arpresolve_fast(lifp, gw, m ? m->m_flags : 0, - eh->ether_dhost); - if (error == 0) { - memcpy(&eh->ether_shost, IF_LLADDR(lifp), ETHER_ADDR_LEN); - eh->ether_type = htons(ETHERTYPE_IP); - nh->nh_count = ETHER_HDR_LEN; - return (0); - } - } - - /* Notify caller that no L2 info is linked */ - nh->nh_count = 0; - nh->nh_flags |= NHF_L2_INCOMPLETE; - /* ..And save gateway address */ - nh->d.gw4 = gw; - return (0); -} - -int -fib4_sendmbuf(struct ifnet *ifp, struct mbuf *m, struct nhop_prepend *nh, - struct in_addr dst) -{ - int error; - - if (nh != NULL && (nh->nh_flags & NHF_L2_INCOMPLETE) == 0) { - - /* - * Fast path case. Most packets should - * be sent from here. - * TODO: Make special ifnet - * 'if_output_frame' handler for that. - */ - struct nhop_info ni; - struct ether_header *eh; - bzero(&ni, sizeof(ni)); - ni.ni_flags = RT_NHOP; - ni.ni_family = AF_INET; - ni.ni_nh = nh; - - M_PREPEND(m, nh->nh_count, M_NOWAIT); - if (m == NULL) - return (ENOBUFS); - eh = mtod(m, struct ether_header *); - memcpy(eh, nh->d.data, nh->nh_count); - error = (*ifp->if_output)(ifp, m, NULL, &ni); - } else { - struct sockaddr_in gw_out; - memset(&gw_out, 0, sizeof(gw_out)); - gw_out.sin_len = sizeof(gw_out); - gw_out.sin_family = AF_INET; - gw_out.sin_addr = nh ? nh->d.gw4 : dst; - error = (*ifp->if_output)(ifp, m, - (const struct sockaddr *)&gw_out, NULL); - } - - return (error); -} - -static inline uint16_t -fib_rte_to_nh_flags(int rt_flags) -{ - uint16_t res; - - res = (rt_flags & RTF_REJECT) ? NHF_REJECT : 0; - res |= (rt_flags & RTF_BLACKHOLE) ? NHF_BLACKHOLE : 0; - res |= (rt_flags & (RTF_DYNAMIC|RTF_MODIFIED)) ? NHF_REDIRECT : 0; - res |= (rt_flags & RTF_BROADCAST) ? NHF_BROADCAST : 0; - res |= (rt_flags & RTF_GATEWAY) ? NHF_GATEWAY : 0; - - return (res); -} - -static void -fib4_rte_to_nh(struct rtentry *rte, struct in_addr dst, - uint32_t flags, struct nhop4_basic *pnh4) -{ - struct sockaddr_in *gw; - - if ((flags & NHOP_LOOKUP_AIFP) == 0) - pnh4->nh_ifp = rte->rt_ifp; - else - pnh4->nh_ifp = rte->rt_ifa->ifa_ifp; - pnh4->nh_mtu = min(rte->rt_mtu, rte->rt_ifp->if_mtu); - if (rte->rt_flags & RTF_GATEWAY) { - gw = (struct sockaddr_in *)rte->rt_gateway; - pnh4->nh_addr = gw->sin_addr; - } else - pnh4->nh_addr = dst; - /* Set flags */ - pnh4->nh_flags = fib_rte_to_nh_flags(rte->rt_flags); - gw = (struct sockaddr_in *)rt_key(rte); - if (gw->sin_addr.s_addr == 0) - pnh4->nh_flags |= NHF_DEFAULT; - /* XXX: Set RTF_BROADCAST if GW address is broadcast */ -} - -static void -fib4_rte_to_nh_extended(struct rtentry *rte, struct in_addr dst, - uint32_t flags, struct nhop4_extended *pnh4) -{ - struct sockaddr_in *gw; - struct in_ifaddr *ia; - - if ((flags & NHOP_LOOKUP_AIFP) == 0) - pnh4->nh_ifp = rte->rt_ifp; - else - pnh4->nh_ifp = rte->rt_ifa->ifa_ifp; - pnh4->nh_mtu = min(rte->rt_mtu, rte->rt_ifp->if_mtu); - if (rte->rt_flags & RTF_GATEWAY) { - gw = (struct sockaddr_in *)rte->rt_gateway; - pnh4->nh_addr = gw->sin_addr; - } else - pnh4->nh_addr = dst; - /* Set flags */ - pnh4->nh_flags = fib_rte_to_nh_flags(rte->rt_flags); - gw = (struct sockaddr_in *)rt_key(rte); - if (gw->sin_addr.s_addr == 0) - pnh4->nh_flags |= NHF_DEFAULT; - /* XXX: Set RTF_BROADCAST if GW address is broadcast */ - - ia = ifatoia(rte->rt_ifa); - pnh4->nh_src = IA_SIN(ia)->sin_addr; -} - -static void -rib4_rte_to_nh_extended(struct rtentry *rte, struct in_addr dst, - struct rt4_extended *prt4) -{ - struct sockaddr_in *gw; - struct in_ifaddr *ia; - - /* Do explicit nexthop zero unless we're copying it */ - memset(prt4, 0, sizeof(*prt4)); - - gw = ((struct sockaddr_in *)rt_key(rte)); - prt4->rt_addr = gw->sin_addr; - gw = ((struct sockaddr_in *)rt_mask(rte)); - prt4->rt_mask.s_addr = (gw != NULL) ? - gw->sin_addr.s_addr : INADDR_BROADCAST; - - if (rte->rt_flags & RTF_GATEWAY) { - gw = (struct sockaddr_in *)rte->rt_gateway; - prt4->rt_gateway = gw->sin_addr; - } else - prt4->rt_gateway = dst; - - prt4->rt_lifp = rte->rt_ifp; - prt4->rt_aifp = rte->rt_ifa->ifa_ifp; - prt4->rt_flags = rte->rt_flags; - prt4->rt_mtu = min(rte->rt_mtu, rte->rt_ifp->if_mtu); - - prt4->rt_nhop = 0; /* XXX: fill real nexthop */ - - ia = ifatoia(rte->rt_ifa); - prt4->rt_src = IA_SIN(ia)->sin_addr; -} - -/* - * Performs IPv4 route table lookup on @dst. Returns 0 on success. - * Stores nexthop info provided @pnh4 structure. - * Note that - * - nh_ifp cannot be safely dereferenced - * - nh_ifp represents ifaddr ifp (e.g. if looking up address on - * interface "ix0" pointer to "ix0" interface will be returned instead - * of "lo0") - * - howewer mtu from "transmit" interface will be returned. - */ -int -fib4_lookup_nh(uint32_t fibnum, struct in_addr dst, uint32_t flowid, - uint32_t flags, struct nhop4_basic *pnh4) -{ - struct rib_head *rh; - struct radix_node *rn; - struct sockaddr_in sin; - struct rtentry *rte; - RIB_LOCK_READER; - - KASSERT((fibnum < rt_numfibs), ("fib4_lookup_nh: bad fibnum")); - rh = rt_tables_get_rnh(fibnum, AF_INET); - if (rh == NULL) - return (ENOENT); - - /* Prepare lookup key */ - memset(&sin, 0, sizeof(sin)); - sin.sin_len = sizeof(struct sockaddr_in); - sin.sin_addr = dst; - - RIB_RLOCK(rh); - rn = rh->rnh_matchaddr((void *)&sin, &rh->head); - if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) { - rte = RNTORT(rn); - /* Ensure route & ifp is UP */ - if (RT_LINK_IS_UP(rte->rt_ifp)) { - fib4_rte_to_nh(rte, dst, flags, pnh4); - RIB_RUNLOCK(rh); - - return (0); - } - } - RIB_RUNLOCK(rh); - - return (ENOENT); -} - -/* - * Performs IPv4 route table lookup on @dst. Returns 0 on success. - * Stores extende nexthop info provided @pnh4 structure. - * Note that - * - nh_ifp cannot be safely dereferenced unless NHOP_LOOKUP_REF is specified. - * - in that case you need to call fib4_free_nh_ext() - * - nh_ifp represents logical transmit interface (rt_ifp) - * - mtu from logical transmit interface will be returned. - */ -int -fib4_lookup_nh_ext(uint32_t fibnum, struct in_addr dst, uint32_t flowid, - uint32_t flags, struct nhop4_extended *pnh4) -{ - struct rib_head *rh; - struct radix_node *rn; - struct sockaddr_in sin; - struct rtentry *rte; - RIB_LOCK_READER; - - KASSERT((fibnum < rt_numfibs), ("fib4_lookup_nh_ext: bad fibnum")); - rh = rt_tables_get_rnh(fibnum, AF_INET); - if (rh == NULL) - return (ENOENT); - - /* Prepare lookup key */ - memset(&sin, 0, sizeof(sin)); - sin.sin_len = sizeof(struct sockaddr_in); - sin.sin_addr = dst; - - RIB_RLOCK(rh); - rn = rh->rnh_matchaddr((void *)&sin, &rh->head); - if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) { - rte = RNTORT(rn); - /* Ensure route & ifp is UP */ - if (RT_LINK_IS_UP(rte->rt_ifp)) { - fib4_rte_to_nh_extended(rte, dst, flags, pnh4); - if ((flags & NHOP_LOOKUP_REF) != 0) { - /* TODO: Do lwref on egress ifp's */ - } - RIB_RUNLOCK(rh); - - return (0); - } - } - RIB_RUNLOCK(rh); - - return (ENOENT); -} - -void -fib4_free_nh_ext(uint32_t fibnum, struct nhop4_extended *pnh4) -{ - -} - -int -rib4_lookup_nh_ext(uint32_t fibnum, struct in_addr dst, uint32_t flowid, - uint32_t flags, struct rt4_extended *prt4) -{ - struct rib_head *rh; - struct radix_node *rn; - struct sockaddr_in sin; - struct rtentry *rte; - RIB_LOCK_READER; - - KASSERT((fibnum < rt_numfibs), ("rib4_lookup_nh_ext: bad fibnum")); - rh = rt_tables_get_rnh(fibnum, AF_INET); - if (rh == NULL) - return (ENOENT); - - /* Prepare lookup key */ - memset(&sin, 0, sizeof(sin)); - sin.sin_len = sizeof(struct sockaddr_in); - sin.sin_addr = dst; - - RIB_RLOCK(rh); - rn = rh->rnh_matchaddr((void *)&sin, &rh->head); - if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) { - rte = RNTORT(rn); - /* Ensure route & ifp is UP */ - if (RT_LINK_IS_UP(rte->rt_ifp)) { - rib4_rte_to_nh_extended(rte, dst, prt4); - if ((flags & NHOP_LOOKUP_REF) != 0) { - /* TODO: Do lwref on egress ifp's */ - } - RIB_RUNLOCK(rh); - return (0); - } - } - RIB_RUNLOCK(rh); - - return (ENOENT); -} - -void -rib4_free_nh_ext(uint32_t fibnum, struct rt4_extended *prt4) -{ - -} - -#endif - -#ifdef INET6 -void -fib6_free_nh_prepend(uint32_t fibnum, struct nhop_prepend *nh) -{ - - fib_free_nh_prepend(fibnum, nh, AF_INET6); -} - -void -fib6_choose_prepend(uint32_t fibnum, struct nhop_prepend *nh_src, - uint32_t flowid, struct nhop_prepend *nh, struct nhop6_extended *nh_ext) -{ - - fib_choose_prepend(fibnum, nh_src, flowid, nh, AF_INET6); - if (nh_ext == NULL) - return; - - nh_ext->nh_ifp = NH_LIFP(nh); - nh_ext->nh_mtu = nh->nh_mtu; - nh_ext->nh_flags = nh->nh_flags; -/* - nh_ext->nh_addr = ; - nh_ext->nh_src= ; -*/ -} - -/* - * Temporary function to copy ethernet address from valid lle - */ -static int -fib6_storelladdr(struct ifnet *ifp, struct in6_addr *dst, int mm_flags, - u_char *desten) -{ - struct llentry *ln; - IF_AFDATA_RUN_TRACKER; - - if (mm_flags & M_MCAST) { - ETHER_MAP_IPV6_MULTICAST(&dst, desten); - return (0); - } - - /* - * the entry should have been created in nd6_store_lladdr - */ - IF_AFDATA_RUN_RLOCK(ifp); - ln = lltable_lookup_lle6(ifp, LLE_UNLOCKED, dst); - - /* - * Perform fast path for the following cases: - * 1) lle state is REACHABLE - * 2) lle state is DELAY (NS message sentNS message sent) - * - * Every other case involves lle modification, so we handle - * them separately. - */ - if (ln == NULL || (ln->ln_state != ND6_LLINFO_REACHABLE && - ln->ln_state != ND6_LLINFO_DELAY)) { - IF_AFDATA_RUN_RUNLOCK(ifp); - return (1); - } - bcopy(&ln->ll_addr, desten, ifp->if_addrlen); - IF_AFDATA_RUN_RUNLOCK(ifp); - - return (0); -} - -int -fib6_lookup_prepend(uint32_t fibnum, struct in6_addr *dst, uint32_t scopeid, - struct mbuf *m, struct nhop_prepend *nh, struct nhop6_extended *nh_ext) -{ - struct rib_head *rh; - struct radix_node *rn; - struct sockaddr_in6 sin6, *gw_sa; - struct in6_addr gw6; - struct rtentry *rte; - struct ifnet *lifp; - struct ether_header *eh; - RIB_LOCK_READER; - uint32_t flags; - int error; - - if (IN6_IS_SCOPE_LINKLOCAL(dst)) { - /* Do not lookup link-local addresses in rtable */ - error = fib6_lla_to_nh(dst, scopeid, nh, &lifp); - if (error != 0) - return (error); - /* */ - gw6 = *dst; - goto do_l2; - } - - - KASSERT((fibnum < rt_numfibs), ("fib6_lookup_prepend: bad fibnum")); - rh = rt_tables_get_rnh(fibnum, AF_INET6); - if (rh == NULL) - return (ENOENT); - - /* Prepare lookup key */ - memset(&sin6, 0, sizeof(sin6)); - sin6.sin6_len = sizeof(struct sockaddr_in6); - sin6.sin6_addr = *dst; - sin6.sin6_scope_id = scopeid; - sa6_embedscope(&sin6, 0); - - - RIB_RLOCK(rh); - rn = rh->rnh_matchaddr((void *)&sin6, &rh->head); - rte = RNTORT(rn); - if (rn == NULL || ((rn->rn_flags & RNF_ROOT) != 0) || - RT_LINK_IS_UP(rte->rt_ifp) == 0) { - RIB_RUNLOCK(rh); - return (EHOSTUNREACH); - } - - /* Explicitly zero nexthop */ - memset(nh, 0, sizeof(*nh)); - flags = 0; - nh->nh_mtu = min(rte->rt_mtu, IN6_LINKMTU(rte->rt_ifp)); - if (rte->rt_flags & RTF_GATEWAY) { - gw_sa = (struct sockaddr_in6 *)rte->rt_gateway; - gw6 = gw_sa->sin6_addr; - in6_clearscope(&gw6); - } else - gw6 = *dst; - /* Set flags */ - flags = fib_rte_to_nh_flags(rte->rt_flags); - gw_sa = (struct sockaddr_in6 *)rt_key(rte); - if (IN6_IS_ADDR_UNSPECIFIED(&gw_sa->sin6_addr)) - flags |= NHF_DEFAULT; - - /* - * TODO: nh L2/L3 resolve. - * Currently all we have is rte ifp. - * Simply use it. - */ - /* Save interface address ifp */ - nh->aifp_idx = fib6_get_ifa(rte); - /* Save both logical and transmit interface indexes */ - lifp = rte->rt_ifp; - nh->lifp_idx = lifp->if_index; - nh->i.ifp_idx = nh->lifp_idx; - - RIB_RUNLOCK(rh); - - nh->nh_flags = flags; -do_l2: - /* - * Try to lookup L2 info. - * Do this using separate LLE locks. - * TODO: move this under radix lock. - */ - if (lifp->if_type == IFT_ETHER) { - eh = (struct ether_header *)nh->d.data; - - /* - * Fill in ethernet header. - * It should be already presented if we're - * sending data via known gateway. - */ - error = fib6_storelladdr(lifp, &gw6, m ? m->m_flags : 0, - eh->ether_dhost); - if (error == 0) { - memcpy(&eh->ether_shost, IF_LLADDR(lifp), ETHER_ADDR_LEN); - eh->ether_type = htons(ETHERTYPE_IPV6); - nh->nh_count = ETHER_HDR_LEN; - return (0); - } - } - - /* Notify caller that no L2 info is linked */ - nh->nh_count = 0; - nh->nh_flags |= NHF_L2_INCOMPLETE; - /* ..And save gateway address */ - nh->d.gw6 = gw6; - return (0); -} - -int -fib6_sendmbuf(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *m, - struct nhop_prepend *nh) -{ - int error; - - if (nh != NULL && (nh->nh_flags & NHF_L2_INCOMPLETE) == 0) { - - /* - * Fast path case. Most packets should - * be sent from here. - * TODO: Make special ifnet - * 'if_output_frame' handler for that. - */ - struct nhop_info ni; - struct ether_header *eh; - bzero(&ni, sizeof(ni)); - ni.ni_family = AF_INET6; - ni.ni_flags = RT_NHOP; - ni.ni_nh = nh; - - M_PREPEND(m, nh->nh_count, M_NOWAIT); - if (m == NULL) - return (ENOBUFS); - eh = mtod(m, struct ether_header *); - memcpy(eh, nh->d.data, nh->nh_count); - error = (*ifp->if_output)(ifp, m, NULL, &ni); - } else { - /* We need to perform ND lookup */ - struct sockaddr_in6 gw_out; - - memset(&gw_out, 0, sizeof(gw_out)); - gw_out.sin6_family = AF_INET6; - gw_out.sin6_len = sizeof(gw_out); - gw_out.sin6_addr = nh->d.gw6; - gw_out.sin6_scope_id = ifp->if_index; - sa6_embedscope(&gw_out, 0); - - error = nd6_output(ifp, origifp, m, &gw_out, NULL); - } - - return (error); -} - -static uint16_t -fib6_get_ifa(struct rtentry *rte) -{ - struct ifnet *ifp; - struct sockaddr_dl *sdl; - - ifp = rte->rt_ifp; - if ((ifp->if_flags & IFF_LOOPBACK) && - rte->rt_gateway->sa_family == AF_LINK) { - sdl = (struct sockaddr_dl *)rte->rt_gateway; - return (sdl->sdl_index); - } - - return (ifp->if_index); -#if 0 - /* IPv6 case */ - /* Alternative way to get interface address ifp */ - /* - * Adjust the "outgoing" interface. If we're going to loop - * the packet back to ourselves, the ifp would be the loopback - * interface. However, we'd rather know the interface associated - * to the destination address (which should probably be one of - * our own addresses.) - */ - if (rt) { - if ((rt->rt_ifp->if_flags & IFF_LOOPBACK) && - (rt->rt_gateway->sa_family == AF_LINK)) - *retifp = - ifnet_byindex(((struct sockaddr_dl *) - rt->rt_gateway)->sdl_index); - } - /* IPv4 case */ - //pnh6->nh_ifp = rte->rt_ifa->ifa_ifp; -#endif -} - -static int -fib6_lla_to_nh_basic(struct in6_addr *dst, uint32_t scopeid, - uint32_t flags, struct nhop6_basic *pnh6) -{ - struct ifnet *ifp; - - ifp = ifnet_byindex_locked(scopeid); - if (ifp == NULL) - return (ENOENT); - - /* Do explicit nexthop zero unless we're copying it */ - memset(pnh6, 0, sizeof(*pnh6)); - - pnh6->nh_mtu = IN6_LINKMTU(ifp); - pnh6->nh_ifp = ifp; - if ((flags & NHOP_LOOKUP_AIFP)!=0 && in6_ifawithifp_lla(ifp, dst) != 0){ - if ((ifp = V_loif) != NULL) - pnh6->nh_ifp = ifp; - } - - /* No flags set */ - pnh6->nh_addr = *dst; - - return (0); -} - -static int -fib6_lla_to_nh_extended(struct in6_addr *dst, uint32_t scopeid, - uint32_t flags, struct nhop6_extended *pnh6) -{ - struct ifnet *ifp; - - ifp = ifnet_byindex_locked(scopeid); - if (ifp == NULL) - return (ENOENT); - - /* Do explicit nexthop zero unless we're copying it */ - memset(pnh6, 0, sizeof(*pnh6)); - - pnh6->nh_mtu = IN6_LINKMTU(ifp); - pnh6->nh_ifp = ifp; - if ((flags & NHOP_LOOKUP_AIFP)!=0 && in6_ifawithifp_lla(ifp, dst) != 0){ - if ((ifp = V_loif) != NULL) - pnh6->nh_ifp = ifp; - } - /* No flags set */ - pnh6->nh_addr = *dst; - - return (0); -} - -static int -rib6_lla_to_nh_extended(struct in6_addr *dst, uint32_t scopeid, - uint32_t flags, struct rt6_extended *prt6) -{ - struct ifnet *ifp; - - ifp = ifnet_byindex_locked(scopeid); - if (ifp == NULL) - return (ENOENT); - - /* Do explicit nexthop zero unless we're copying it */ - memset(prt6, 0, sizeof(*prt6)); - - prt6->rt_addr.s6_addr16[0] = htons(0xFE80); - prt6->rt_mask = 64; /* XXX check RFC */ - - prt6->rt_aifp = ifp; - prt6->rt_lifp = ifp; - /* Check id this is for-us address */ - if (in6_ifawithifp_lla(ifp, dst)) { - if ((ifp = V_loif) != NULL) - prt6->rt_lifp = ifp; - } - - prt6->rt_mtu = IN6_LINKMTU(ifp); - /* No flags set */ - - return (0); -} - -static int -fib6_lla_to_nh(struct in6_addr *dst, uint32_t scopeid, - struct nhop_prepend *nh, struct ifnet **lifp) -{ - struct ifnet *ifp; - - ifp = ifnet_byindex_locked(scopeid); - if (ifp == NULL) - return (ENOENT); - - /* Do explicit nexthop zero unless we're copying it */ - memset(nh, 0, sizeof(*nh)); - /* No flags set */ - nh->nh_mtu = IN6_LINKMTU(ifp); - - /* Save lifp */ - *lifp = ifp; - - nh->aifp_idx = scopeid; - nh->lifp_idx = scopeid; - /* Check id this is for-us address */ - if (in6_ifawithifp_lla(ifp, dst)) { - if ((ifp = V_loif) != NULL) - nh->lifp_idx = ifp->if_index; - } - - return (0); -} - - -static void -fib6_rte_to_nh(struct rtentry *rte, struct in6_addr *dst, - uint32_t flags, struct nhop6_basic *pnh6) -{ - struct sockaddr_in6 *gw; - - /* Do explicit nexthop zero unless we're copying it */ - memset(pnh6, 0, sizeof(*pnh6)); - - if ((flags & NHOP_LOOKUP_AIFP) == 0) - pnh6->nh_ifp = rte->rt_ifp; - else - pnh6->nh_ifp = ifnet_byindex(fib6_get_ifa(rte)); - - pnh6->nh_mtu = min(rte->rt_mtu, IN6_LINKMTU(rte->rt_ifp)); - if (rte->rt_flags & RTF_GATEWAY) { - gw = (struct sockaddr_in6 *)rte->rt_gateway; - pnh6->nh_addr = gw->sin6_addr; - in6_clearscope(&pnh6->nh_addr); - } else - pnh6->nh_addr = *dst; - /* Set flags */ - pnh6->nh_flags = fib_rte_to_nh_flags(rte->rt_flags); - gw = (struct sockaddr_in6 *)rt_key(rte); - if (IN6_IS_ADDR_UNSPECIFIED(&gw->sin6_addr)) - pnh6->nh_flags |= NHF_DEFAULT; -} - -static void -fib6_rte_to_nh_extended(struct rtentry *rte, struct in6_addr *dst, - uint32_t flags, struct nhop6_extended *pnh6) -{ - struct sockaddr_in6 *gw; - struct in6_ifaddr *ia; - - /* Do explicit nexthop zero unless we're copying it */ - memset(pnh6, 0, sizeof(*pnh6)); - - if ((flags & NHOP_LOOKUP_AIFP) == 0) - pnh6->nh_ifp = rte->rt_ifp; - else - pnh6->nh_ifp = ifnet_byindex(fib6_get_ifa(rte)); - - pnh6->nh_mtu = min(rte->rt_mtu, IN6_LINKMTU(rte->rt_ifp)); - if (rte->rt_flags & RTF_GATEWAY) { - gw = (struct sockaddr_in6 *)rte->rt_gateway; - pnh6->nh_addr = gw->sin6_addr; - in6_clearscope(&pnh6->nh_addr); - } else - pnh6->nh_addr = *dst; - /* Set flags */ - pnh6->nh_flags = fib_rte_to_nh_flags(rte->rt_flags); - gw = (struct sockaddr_in6 *)rt_key(rte); - if (IN6_IS_ADDR_UNSPECIFIED(&gw->sin6_addr)) - pnh6->nh_flags |= NHF_DEFAULT; - - ia = ifatoia6(rte->rt_ifa); -} - -#define ipv6_masklen(x) bitcount32((x).__u6_addr.__u6_addr32[0]) + \ - bitcount32((x).__u6_addr.__u6_addr32[1]) + \ - bitcount32((x).__u6_addr.__u6_addr32[2]) + \ - bitcount32((x).__u6_addr.__u6_addr32[3]) -static void -rib6_rte_to_nh_extended(struct rtentry *rte, struct in6_addr *dst, - uint32_t flags, struct rt6_extended *prt6) -{ - struct sockaddr_in6 *gw; - - /* Do explicit nexthop zero unless we're copying it */ - memset(prt6, 0, sizeof(*prt6)); - - gw = ((struct sockaddr_in6 *)rt_key(rte)); - prt6->rt_addr = gw->sin6_addr; - gw = ((struct sockaddr_in6 *)rt_mask(rte)); - prt6->rt_mask = (gw != NULL) ? ipv6_masklen(gw->sin6_addr) : 128; - - if (rte->rt_flags & RTF_GATEWAY) { - gw = (struct sockaddr_in6 *)rte->rt_gateway; - prt6->rt_gateway = gw->sin6_addr; - in6_clearscope(&prt6->rt_gateway); - } else - prt6->rt_gateway = *dst; - - prt6->rt_lifp = rte->rt_ifp; - prt6->rt_aifp = ifnet_byindex(fib6_get_ifa(rte)); - prt6->rt_flags = fib_rte_to_nh_flags(rte->rt_flags); - prt6->rt_mtu = min(rte->rt_mtu, IN6_LINKMTU(rte->rt_ifp)); -} - -int -fib6_lookup_nh(uint32_t fibnum, struct in6_addr *dst, uint32_t scopeid, - uint32_t flowid, uint32_t flags, struct nhop6_basic *pnh6) -{ - struct rib_head *rh; - struct radix_node *rn; - struct sockaddr_in6 sin6; - struct rtentry *rte; - RIB_LOCK_READER; - - if (IN6_IS_SCOPE_LINKLOCAL(dst)) { - /* Do not lookup link-local addresses in rtable */ - return (fib6_lla_to_nh_basic(dst, scopeid, flags, pnh6)); - } - - KASSERT((fibnum < rt_numfibs), ("fib6_lookup_nh: bad fibnum")); - rh = rt_tables_get_rnh(fibnum, AF_INET6); - if (rh == NULL) - return (ENOENT); - - /* Prepare lookup key */ - memset(&sin6, 0, sizeof(sin6)); - sin6.sin6_addr = *dst; - sin6.sin6_scope_id = scopeid; - sa6_embedscope(&sin6, 0); - - RIB_RLOCK(rh); - rn = rh->rnh_matchaddr((void *)&sin6, &rh->head); - if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) { - rte = RNTORT(rn); - /* Ensure route & ifp is UP */ - if (RT_LINK_IS_UP(rte->rt_ifp)) { - fib6_rte_to_nh(rte, dst, flags, pnh6); - RIB_RUNLOCK(rh); - return (0); - } - } - RIB_RUNLOCK(rh); - - return (ENOENT); -} - -/* - * Performs IPv6 route table lookup on @dst. Returns 0 on success. - * Stores extende nexthop info provided @pnh4 structure. - * Note that - * - nh_ifp cannot be safely dereferenced unless NHOP_LOOKUP_REF is specified. - * - in that case you need to call fib6_free_nh_ext() - * - nh_ifp represents logical transmit interface (rt_ifp) - * - mtu from logical transmit interface will be returned. - */ -int -fib6_lookup_nh_ext(uint32_t fibnum, struct in6_addr *dst, uint32_t scopeid, - uint32_t flowid, uint32_t flags, struct nhop6_extended *pnh6) -{ - struct rib_head *rh; - struct radix_node *rn; - struct sockaddr_in6 sin6; - struct rtentry *rte; - RIB_LOCK_READER; - - if (IN6_IS_SCOPE_LINKLOCAL(dst)) { - /* Do not lookup link-local addresses in rtable */ - /* XXX: Do lwref on egress ifp */ - return (fib6_lla_to_nh_extended(dst, scopeid, flags, pnh6)); - } - - KASSERT((fibnum < rt_numfibs), ("fib4_lookup_nh_ext: bad fibnum")); - rh = rt_tables_get_rnh(fibnum, AF_INET6); - if (rh == NULL) - return (ENOENT); - - /* Prepare lookup key */ - memset(&sin6, 0, sizeof(sin6)); - sin6.sin6_len = sizeof(struct sockaddr_in6); - sin6.sin6_addr = *dst; - sin6.sin6_scope_id = scopeid; - sa6_embedscope(&sin6, 0); - - RIB_RLOCK(rh); - rn = rh->rnh_matchaddr((void *)&sin6, &rh->head); - if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) { - rte = RNTORT(rn); - /* Ensure route & ifp is UP */ - if (RT_LINK_IS_UP(rte->rt_ifp)) { - fib6_rte_to_nh_extended(rte, dst, flags, pnh6); - if ((flags & NHOP_LOOKUP_REF) != 0) { - /* TODO: Do lwref on egress ifp's */ - } - RIB_RUNLOCK(rh); - - return (0); - } - } - RIB_RUNLOCK(rh); - - return (ENOENT); -} - -void -fib6_free_nh_ext(uint32_t fibnum, struct nhop6_extended *pnh6) -{ - -} - -int -rib6_lookup_nh_ext(uint32_t fibnum, struct in6_addr *dst, uint32_t scopeid, - uint32_t flowid, uint32_t flags, struct rt6_extended *prt6) -{ - struct rib_head *rh; - struct radix_node *rn; - struct sockaddr_in6 sin6; - struct rtentry *rte; - RIB_LOCK_READER; - - if (IN6_IS_SCOPE_LINKLOCAL(dst)) { - /* Do not lookup link-local addresses in rtable */ - /* XXX: Do lwref on egress ifp */ - return (rib6_lla_to_nh_extended(dst, scopeid, flags, prt6)); - } - - KASSERT((fibnum < rt_numfibs), ("rib6_lookup_nh_ext: bad fibnum")); - rh = rt_tables_get_rnh(fibnum, AF_INET6); - if (rh == NULL) - return (ENOENT); - - /* Prepare lookup key */ - memset(&sin6, 0, sizeof(sin6)); - sin6.sin6_len = sizeof(struct sockaddr_in6); - sin6.sin6_addr = *dst; - sin6.sin6_scope_id = scopeid; - sa6_embedscope(&sin6, 0); - - RIB_RLOCK(rh); - rn = rh->rnh_matchaddr((void *)&sin6, &rh->head); - if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) { - rte = RNTORT(rn); - /* Ensure route & ifp is UP */ - if (RT_LINK_IS_UP(rte->rt_ifp)) { - rib6_rte_to_nh_extended(rte, dst, flags, prt6); - if ((flags & NHOP_LOOKUP_REF) != 0) { - /* TODO: Do lwref on egress ifp's */ - } - RIB_RUNLOCK(rh); - - return (0); - } - } - RIB_RUNLOCK(rh); - - return (ENOENT); -} - -void -rib6_free_nh_ext(uint32_t fibnum, struct nhop6_extended *prt6) -{ - -} - -#endif - -void -fib_free_nh_ext(uint32_t fibnum, struct nhopu_extended *pnhu) -{ - -} - - -#if 0 -typedef void nhop_change_cb_t(void *state); - - -struct nhop_tracker { - TAILQ_ENTRY(nhop_tracker) next; - nhop_change_cb_t *f; - void *state; - uint32_t fibnum; - struct sockaddr_storage ss; -}; - -struct nhop_tracker * -nhop_alloc_tracked(uint32_t fibnum, struct sockaddr *sa, nhop_change_cb_t *f, - void *state) -{ - struct nhop_tracker *nt; - - nt = malloc(sizeof(struct nhop_tracker), M_RTFIB, M_WAITOK | M_ZERO); - - nt->f = f; - nt-state = state; - nt->fibnum = fibnum; - memcpy(&nt->ss, sa, sa->sa_len); - - return (nt); -} - - -int -nhop_bind(struct nhop_tracker *nt) -{ - NHOP_LOCK(nnh); - - NHOP_UNLOCK(nnh); - - return (0); -} -#endif - - - - - - - - Property changes on: projects/routing/sys/net/rt_nhops.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: projects/routing/sys/net/rt_nhops.h =================================================================== --- projects/routing/sys/net/rt_nhops.h (revision 287042) +++ projects/routing/sys/net/rt_nhops.h (nonexistent) @@ -1,314 +0,0 @@ -/*- - * Copyright (c) 2014 - * Alexander V. Chernikov - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef _NET_RT_NHOPS_H_ -#define _NET_RT_NHOPS_H_ - - - -#define NH_TYPE_DIRECT 1 /* Directly reachable, no data */ -#define NH_TYPE_BLACKHOLE 2 /* Blackhole route */ -#define NH_TYPE_REJECT 3 /* Send reject */ -#define NH_TYPE_L2 4 /* Provides full prepend header */ -#define NH_TYPE_MUTATOR 5 /* NH+callback function */ -#define NH_TYPE_MULTIPATH 6 /* Multipath route */ - -struct nhop_ctl_info { - uint64_t refcnt; /* Use references */ - uint64_t flags; /* Options */ - -}; - -/* Multipath nhop info */ -struct nhop_mpath_info { - uint16_t nhop; /* Netxthop id */ -}; - -/* mutator info */ -struct nhop_mutator_info; -struct nhop_prepend; - -typedef int nhop_mutate_t(struct mbuf **, struct nhop_prepend *nd, void *storage); -struct nhop_mutator_info { - nhop_mutate_t *func; - char data[]; -}; - -/* Structures used for forwarding purposes */ -#define MAX_PREPEND_LEN 48 /* Max data that can be prepended */ - -/* Non-recursive nexthop */ -struct nhop_prepend { - uint16_t nh_flags; /* NH flags */ - uint8_t nh_count; /* Number of nexthops or data length */ - uint8_t spare0; - uint16_t nh_mtu; /* given nhop MTU */ - uint16_t lifp_idx; /* Logical interface index */ - union { - uint16_t ifp_idx; /* Transmit interface index */ - uint16_t nhop_idx; /* L2 multipath nhop index */ - } i; - uint16_t aifp_idx; /* Interface address index */ - uint16_t spare1[2]; - union { - char data[MAX_PREPEND_LEN]; /* data to prepend */ -#ifdef INET - struct in_addr gw4; /* IPv4 gw address */ -#endif -#ifdef INET6 - struct in6_addr gw6; /* IPv4 gw address */ -#endif - } d; -}; - -/* Internal flags */ -#define NHF_RECURSE 0x0001 /* Nexthop structure is recursive */ -#define NHF_L2_NHOP 0x0002 /* L2 interface has to be selected */ -#define NHF_L2_ME 0x0004 /* dst L2 address is our address */ -#define NHF_L2_INCOMPLETE 0x0008 /* L2 header not prepended */ - -/* External flags */ -#define NHF_REJECT 0x0010 /* RTF_REJECT */ -#define NHF_BLACKHOLE 0x0020 /* RTF_BLACKHOLE */ -#define NHF_REDIRECT 0x0040 /* RTF_DYNAMIC|RTF_MODIFIED */ -#define NHF_DEFAULT 0x0080 /* Default route */ -#define NHF_BROADCAST 0x0100 /* RTF_BROADCAST */ -#define NHF_GATEWAY 0x0200 /* RTF_GATEWAY */ - -#define NH_LIFP(nh) ifnet_byindex_locked((nh)->lifp_idx) -#define NH_TIFP(nh) ifnet_byindex_locked((nh)->i.ifp_idx) -#define NH_AIFP(nh) ifnet_byindex_locked((nh)->aifp_idx) - -/* L2/L3 recursive nexthop */ -struct nhop_multi { - uint8_t nh_flags; /* NH flags */ - uint8_t nh_count; /* Number of nexthops or data length */ - uint8_t spare[2]; - uint16_t nh_nhops[30]; /* Nexthop indexes */ -}; - -/* Per-AF per-fib nhop table */ -struct nhops_descr { - uint32_t nhop_size; /* Nehthop data size */ - uint32_t nhops_max; /* Max number of nhops */ - void *nhops_data; /* Pointer to nhop data table */ - void *nhops_info; /* Pointer to nhop info table */ -}; - - -#if 0 -typedef int nhop_resolve_t(struct sockaddr *dst, u_int fib, struct nhop_prepend *nd, struct nhop_info *nf); - - - -int -lla_create_notify(struct sockaddr *dst, u_int fib, lla_notify_t *func, void *state, int flags); -#endif - -/* Basic nexthop info used for uRPF/mtu checks */ -struct nhop4_basic { - struct ifnet *nh_ifp; /* Logical egress interface */ - uint16_t nh_mtu; /* nexthop mtu */ - uint16_t nh_flags; /* nhop flags */ - struct in_addr nh_addr; /* GW/DST IPv4 address */ -}; - -struct nhop6_basic { - struct ifnet *nh_ifp; /* Logical egress interface */ - uint16_t nh_mtu; /* nexthop mtu */ - uint16_t nh_flags; /* nhop flags */ - uint8_t spare[4]; - struct in6_addr nh_addr; /* GW/DST IPv4 address */ -}; - -struct nhopu_basic { - union { - struct nhop4_basic nh4; - struct nhop6_basic nh6; - } u; -}; - -/* Extended nexthop info used for control protocols */ -struct nhop4_extended { - struct ifnet *nh_ifp; /* Logical egress interface */ - uint16_t nh_mtu; /* nexthop mtu */ - uint16_t nh_flags; /* nhop flags */ - uint8_t spare[4]; - struct in_addr nh_addr; /* GW/DST IPv4 address */ - struct in_addr nh_src; /* default source IPv4 address */ - uint64_t spare2[2]; -}; - -/* Does not differ from nhop6_basic */ -struct nhop6_extended { - struct ifnet *nh_ifp; /* Logical egress interface */ - uint16_t nh_mtu; /* nexthop mtu */ - uint16_t nh_flags; /* nhop flags */ - uint8_t spare[4]; - struct in6_addr nh_addr; /* GW/DST IPv6 address */ - uint64_t spare2[2]; -}; - -/* route info used for control plane purposes */ -struct rt4_extended { - struct in_addr rt_addr; /* route prefix */ - struct in_addr rt_gateway; /* GW used */ - struct ifnet *rt_lifp; /* logical interface */ - struct ifnet *rt_aifp; /* address interface */ - int rt_flags; /* Copy of rte flags */ - uint16_t rt_mtu; - uint16_t rt_nhop; /* nexthop id (might bi mpath) */ - struct in_addr rt_mask; /* route mask */ - struct in_addr rt_src; - uint16_t spare[2]; -}; - -struct rt6_extended { - struct in6_addr rt_addr; - struct in6_addr rt_gateway; - struct ifnet *rt_lifp; /* logical interface */ - struct ifnet *rt_aifp; /* address interface */ - int rt_flags; - uint16_t rt_mtu; - uint16_t rt_nhop; - uint8_t rt_mask; /*Hopefully, no more non-config masks */ - uint8_t spare[7]; -}; - -struct nhopu_extended { - union { - struct nhop4_extended nh4; - struct nhop6_extended nh6; - } u; -}; - -struct route_info { - struct nhop_prepend *ri_nh; /* Desired nexthop to use */ - struct nhopu_basic *ri_nh_info; /* Get selected route info */ - uint16_t ri_mtu; /* Get selected route MTU */ - uint16_t spare; - uint32_t scopeid; /* Desired scope id to use */ -}; - -#define NHOP_LOOKUP_REF 0x01 /* reference objects in passed structure */ -#define NHOP_LOOKUP_AIFP 0x02 /* return route "address" interface */ - -int fib4_lookup_nh(uint32_t fibnum, struct in_addr dst, uint32_t flowid, - uint32_t flags, struct nhop4_basic *pnh4); -int fib4_lookup_nh_ext(uint32_t fibnum, struct in_addr dst, - uint32_t flowid, uint32_t flags, struct nhop4_extended *pnh4); -void fib4_free_nh_ext(uint32_t fibnum, struct nhop4_extended *pnh4); -int rib4_lookup_nh_ext(uint32_t fibnum, struct in_addr dst, uint32_t flowid, - uint32_t flags, struct rt4_extended *prt4); -void rib4_free_nh_ext(uint32_t fibnum, struct rt4_extended *prt4); - - -int fib6_lookup_nh(uint32_t fibnum, struct in6_addr *dst, uint32_t scopeid, - uint32_t flowid, uint32_t flags, struct nhop6_basic *pnh6); -int fib6_lookup_nh_ext(uint32_t fibnum, struct in6_addr *dst, - uint32_t scopeid, uint32_t flowid, uint32_t flags, - struct nhop6_extended *pnh6); -void fib6_free_nh_ext(uint32_t fibnum, struct nhop6_extended *pnh6); -int rib6_lookup_nh_ext(uint32_t fibnum, struct in6_addr *dst, uint32_t scopeid, - uint32_t flowid, uint32_t flags, struct rt6_extended *prt6); -void rib6_free_nh_ext(uint32_t fibnum, struct nhop6_extended *prt6); - -void fib_free_nh_ext(uint32_t fibnum, struct nhopu_extended *pnhu); - - -void fib4_free_nh_prepend(uint32_t fibnum, struct nhop_prepend *nh); -void fib4_choose_prepend(uint32_t fibnum, struct nhop_prepend *nh_src, - uint32_t flowid, struct nhop_prepend *nh, struct nhop4_extended *nh_ext); -int fib4_lookup_prepend(uint32_t fibnum, struct in_addr dst, struct mbuf *m, - struct nhop_prepend *nh, struct nhop4_extended *nh_ext); - -int fib4_sendmbuf(struct ifnet *ifp, struct mbuf *m, struct nhop_prepend *nh, - struct in_addr dst); - -void fib6_free_nh_prepend(uint32_t fibnum, struct nhop_prepend *nh); -void fib6_choose_prepend(uint32_t fibnum, struct nhop_prepend *nh_src, - uint32_t flowid, struct nhop_prepend *nh, struct nhop6_extended *nh_ext); -int fib6_lookup_prepend(uint32_t fibnum, struct in6_addr *dst, uint32_t scopeid, - struct mbuf *m, struct nhop_prepend *nh, struct nhop6_extended *nh_ext); - -int fib6_sendmbuf(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *m, - struct nhop_prepend *nh); - -#define FWD_INET 0 -#define FWD_INET6 1 - -#define FWD_SIZE 2 - -#define FWD_NAME_MAX 15 - -#define FWD_MULTIPATH 0x0001 /* has multipath support */ -#define FWD_OLDMASKS 0x0002 /* has support for non-contig masks */ -#define FWD_DEFAULT 0x0004 /* installs as default fib mechanism */ -#define FWD_MANAGELOCK 0x0004 /* manage its own locking */ - -typedef void *fib_init_t(u_int fibnum); -typedef void fib_destroy_t(void *state); -typedef int fib_dump_t(void *state, struct rib_head *rh); -typedef int fib_change_t(void *state, int req, struct rtentry *rte, - struct rt_addrinfo *info); -typedef int fib_lookup_t(void *state, void *key, uint64_t *attr, u_int flowid, - void *nhop); - -/* Structure used by external module */ -struct fwd_module_info { - uint8_t fwd_family; /* family we're registering to */ - char name[FWD_NAME_MAX]; /* fwd module name */ - uint32_t capabilities; - fib_init_t *fib_init; - fib_destroy_t *fib_destroy; - fib_dump_t *fib_dump; - fib_change_t *fib_change; - fib_lookup_t *fib_lookup; -}; - -/* Internal version of previous structure */ -struct fwd_module { - TAILQ_ENTRY(fwd_module) list; - uint8_t fwd_family; - char name[FWD_NAME_MAX]; - uint32_t capabilities; - fib_init_t *fib_init; - fib_destroy_t *fib_destroy; - fib_dump_t *fib_dump; - fib_change_t *fib_change; - fib_lookup_t *fib_lookup; -}; - -int fwd_attach_module(struct fwd_module_info *m, void **); -int fwd_destroy_module(void *state); -int fwd_change_fib(struct rib_head *rh, int req, struct rtentry *rte, - struct rt_addrinfo *info); - -#endif - Property changes on: projects/routing/sys/net/rt_nhops.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: projects/routing/sys/net/route_internal.h =================================================================== --- projects/routing/sys/net/route_internal.h (revision 287042) +++ projects/routing/sys/net/route_internal.h (nonexistent) @@ -1,141 +0,0 @@ -/*- - * Copyright (c) 2014 - * Alexander V. Chernikov - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef _NET_ROUTE_INTERNAL_H_ -#define _NET_ROUTE_INTERNAL_H_ - -struct rib_head { - struct radix_head head; - struct rmlock rib_lock; /* data path lock */ - rn_matchaddr_f_t *rnh_matchaddr; /* longest match for sockaddr */ - rn_addaddr_f_t *rnh_addaddr; /* add based on sockaddr*/ - rn_deladdr_f_t *rnh_deladdr; /* remove based on sockaddr */ - rn_lookup_f_t *rnh_lookup; /* exact match for sockaddr */ - rn_walktree_t *rnh_walktree; /* traverse tree */ - rn_walktree_from_t *rnh_walktree_from; /* traverse tree below a */ - rn_close_t *rnh_close; /*do something when the last ref drops*/ - struct radix_node rnh_nodes[3]; /* empty tree for common case */ - struct rwlock rib_cfglock; /* config lock */ - struct radix_mask_head rmhead; /* masks radix head */ -}; - -#define RIB_RLOCK(rh) rm_rlock(&(rh)->rib_lock, &tracker) -#define RIB_RUNLOCK(rh) rm_runlock(&(rh)->rib_lock, &tracker) -#define RIB_WLOCK(rh) rm_wlock(&(rh)->rib_lock) -#define RIB_WUNLOCK(rh) rm_wunlock(&(rh)->rib_lock) -#define RIB_WLOCK_ASSERT(rh) rm_assert(&(rh)->rib_lock, RA_WLOCKED) -#define RIB_LOCK_READER struct rm_priotracker tracker -#define RIB_LOCK_ASSERT(rh) rm_assert(&(rh)->rib_lock, RA_LOCKED) - -#define RIB_CFG_RLOCK(rh) rw_rlock(&(rh)->rib_cfglock) -#define RIB_CFG_RUNLOCK(rh) rw_runlock(&(rh)->rib_cfglock) -#define RIB_CFG_WLOCK(rh) rw_wlock(&(rh)->rib_cfglock) -#define RIB_CFG_WUNLOCK(rh) rw_wunlock(&(rh)->rib_cfglock) -#define RIB_CFG_LOCK_ASSERT(rh) rw_assert(&(rh)->rib_cfglock, RA_LOCKED) -#define RIB_CFG_WLOCK_ASSERT(rh) rw_assert(&(rh)->rib_cfglock, RA_WLOCKED) - -struct rib_head *rt_table_init(int offset); -void rt_table_destroy(struct rib_head *rh); - - -struct rtentry { - struct radix_node rt_nodes[2]; /* tree glue, and other values */ - /* - * XXX struct rtentry must begin with a struct radix_node (or two!) - * because the code does some casts of a 'struct radix_node *' - * to a 'struct rtentry *' - */ -#define rt_key(r) (*((struct sockaddr **)(&(r)->rt_nodes->rn_key))) -#define rt_mask(r) (*((struct sockaddr **)(&(r)->rt_nodes->rn_mask))) - struct sockaddr *rt_gateway; /* value */ - struct ifnet *rt_ifp; /* the answer: interface to use */ - struct ifaddr *rt_ifa; /* the answer: interface address to use */ - int rt_flags; /* up/down?, host/net */ - int rt_refcnt; /* # held references */ - u_int rt_fibnum; /* which FIB */ - u_long rt_mtu; /* MTU for this path */ - u_long rt_weight; /* absolute weight */ - u_long rt_expire; /* lifetime for route, e.g. redirect */ - struct mtx rt_mtx; /* mutex for routing entry */ -}; - -#define RT_LOCK_INIT(_rt) \ - mtx_init(&(_rt)->rt_mtx, "rtentry", NULL, MTX_DEF | MTX_DUPOK) -#define RT_LOCK(_rt) mtx_lock(&(_rt)->rt_mtx) -#define RT_UNLOCK(_rt) mtx_unlock(&(_rt)->rt_mtx) -#define RT_LOCK_DESTROY(_rt) mtx_destroy(&(_rt)->rt_mtx) -#define RT_LOCK_ASSERT(_rt) mtx_assert(&(_rt)->rt_mtx, MA_OWNED) - -#define RT_ADDREF(_rt) do { \ - RT_LOCK_ASSERT(_rt); \ - KASSERT((_rt)->rt_refcnt >= 0, \ - ("negative refcnt %d", (_rt)->rt_refcnt)); \ - (_rt)->rt_refcnt++; \ -} while (0) - -#define RT_REMREF(_rt) do { \ - RT_LOCK_ASSERT(_rt); \ - KASSERT((_rt)->rt_refcnt > 0, \ - ("bogus refcnt %d", (_rt)->rt_refcnt)); \ - (_rt)->rt_refcnt--; \ -} while (0) - -#define RTFREE_LOCKED(_rt) do { \ - if ((_rt)->rt_refcnt <= 1) \ - rtfree(_rt); \ - else { \ - RT_REMREF(_rt); \ - RT_UNLOCK(_rt); \ - } \ - /* guard against invalid refs */ \ - _rt = 0; \ -} while (0) - -#define RTFREE(_rt) do { \ - RT_LOCK(_rt); \ - RTFREE_LOCKED(_rt); \ -} while (0) - -#define RO_RTFREE(_ro) do { \ - if ((_ro)->ro_rt) { \ - if ((_ro)->ro_flags & RT_NORTREF) { \ - (_ro)->ro_flags &= ~RT_NORTREF; \ - (_ro)->ro_rt = NULL; \ - } else { \ - RT_LOCK((_ro)->ro_rt); \ - RTFREE_LOCKED((_ro)->ro_rt); \ - } \ - } \ -} while (0) - - - -#endif - - Property changes on: projects/routing/sys/net/route_internal.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: projects/routing =================================================================== --- projects/routing (revision 287042) +++ projects/routing (revision 287043) Property changes on: projects/routing ___________________________________________________________________ Modified: svn:ignore ## -1,6 +1,7 ## _.tinderbox.* _.amd64.* _.arm.* +_.arm64.* _.i386.* _.ia64.* _.mips.* ## -8,3 +9,9 ## _.powerpc.* _.sparc64.* _.sun4v.* +GPATH +GRTAGS +GTAGS +ID +cscope.out +?cscope.out Modified: svn:mergeinfo ## -0,1 +0,8 ## Reverse-merged /projects/clang350-import:r275127,275134 Merged /projects/pms:r285199-285661 Merged /user/ngie/more-tests:r281427-281428,281430,281432,281450,281460,281464-281465,281485,281489-281491,281515,281519,281589,281593-281597,281619 Merged /head:r276889-286157 Merged /projects/building-blocks:r275142-275143,275306-275307,277445,277670,277673 Merged /projects/release-arm-redux:r278203,278595-278597,278610,280643-280650,280652,280655,282539-282546,282548,282553-282557,282564,282566,282570,282573,282587-282593,282596-282607,282615-282616,282624-282629,282631,282633,282635-282640,282642,282647-282648,282653-282654,282656-282657,282659,282662-282667,282682,282691 Merged /projects/release-arm64:r281786,281788,281792 Merged /user/delphij/zfs-arc-rebase:r281754 Merged /projects/clang360-import:r277327-280030