1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2020 Alexander V. Chernikov
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
29__FBSDID("$FreeBSD$");
30#include "opt_inet.h"
31#include "opt_inet6.h"
32#include "opt_route.h"
33
34#include <sys/param.h>
35#include <sys/jail.h>
36#include <sys/systm.h>
37#include <sys/malloc.h>
38#include <sys/mbuf.h>
39#include <sys/socket.h>
40#include <sys/sysctl.h>
41#include <sys/syslog.h>
42#include <sys/sysproto.h>
43#include <sys/proc.h>
44#include <sys/domain.h>
45#include <sys/kernel.h>
46#include <sys/lock.h>
47#include <sys/rmlock.h>
48
49#include <net/if.h>
50#include <net/if_var.h>
51#include <net/if_dl.h>
52#include <net/route.h>
53#include <net/route/route_ctl.h>
54#include <net/route/route_var.h>
55#include <net/route/nhop_utils.h>
56#include <net/route/nhop.h>
57#include <net/route/nhop_var.h>
58#include <net/route/shared.h>
59#ifdef INET
60#include <netinet/in_fib.h>
61#endif
62#ifdef INET6
63#include <netinet6/in6_fib.h>
64#endif
65#include <net/vnet.h>
66
67/*
68 * RIB helper functions.
69 */
70
71/*
72 * Calls @wa_f with @arg for each entry in the table specified by
73 * @af and @fibnum.
74 *
75 * Table is traversed under read lock.
76 */
77void
78rib_walk(int af, u_int fibnum, rt_walktree_f_t *wa_f, void *arg)
79{
80	RIB_RLOCK_TRACKER;
81	struct rib_head *rnh;
82
83	if ((rnh = rt_tables_get_rnh(fibnum, af)) == NULL)
84		return;
85
86	RIB_RLOCK(rnh);
87	rnh->rnh_walktree(&rnh->head, (walktree_f_t *)wa_f, arg);
88	RIB_RUNLOCK(rnh);
89}
90
91/*
92 * Wrapper for the control plane functions for performing af-agnostic
93 *  lookups.
94 * @fibnum: fib to perform the lookup.
95 * @dst: sockaddr with family and addr filled in. IPv6 addresses needs to be in
96 *  deembedded from.
97 * @flags: fib(9) flags.
98 * @flowid: flow id for path selection in multipath use case.
99 *
100 * Returns nhop_object or NULL.
101 *
102 * Requires NET_EPOCH.
103 *
104 */
105struct nhop_object *
106rib_lookup(uint32_t fibnum, const struct sockaddr *dst, uint32_t flags,
107    uint32_t flowid)
108{
109	struct nhop_object *nh;
110
111	nh = NULL;
112
113	switch (dst->sa_family) {
114#ifdef INET
115	case AF_INET:
116	{
117		const struct sockaddr_in *a = (const struct sockaddr_in *)dst;
118		nh = fib4_lookup(fibnum, a->sin_addr, 0, flags, flowid);
119		break;
120	}
121#endif
122#ifdef INET6
123	case AF_INET6:
124	{
125		const struct sockaddr_in6 *a = (const struct sockaddr_in6*)dst;
126		nh = fib6_lookup(fibnum, &a->sin6_addr, a->sin6_scope_id,
127		    flags, flowid);
128		break;
129	}
130#endif
131	}
132
133	return (nh);
134}
135
136