Page MenuHomeFreeBSD

D27244.id79627.diff
No OneTemporary

D27244.id79627.diff

Index: UPDATING
===================================================================
--- UPDATING
+++ UPDATING
@@ -26,6 +26,10 @@
world, or to merely disable the most expensive debugging functionality
at runtime, run "ln -s 'abort:false,junk:false' /etc/malloc.conf".)
+20201116:
+ Multipath routing can be enabled by compiling kernel with
+ ROUTE_MPATH config option. It supersedes RADIX_MPATH option,
+ which has been removed.
20201108:
Default value of net.add_addr_allfibs has been changed to 0.
If you have multi-fib configuration and rely on existence of all
Index: sys/conf/options
===================================================================
--- sys/conf/options
+++ sys/conf/options
@@ -453,7 +453,6 @@
NFSLOCKD
PCBGROUP opt_pcbgroup.h
PF_DEFAULT_TO_DROP opt_pf.h
-RADIX_MPATH opt_mpath.h
ROUTE_MPATH opt_route.h
ROUTETABLES opt_route.h
RSS opt_rss.h
Index: sys/net/radix_mpath.h
===================================================================
--- sys/net/radix_mpath.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/* $KAME: radix_mpath.h,v 1.10 2004/11/06 15:44:28 itojun Exp $ */
-
-/*
- * SPDX-License-Identifier: BSD-3-Clause
- *
- * Copyright (C) 2001 WIDE Project.
- * 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.
- * 3. Neither the name of the project 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 PROJECT 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 PROJECT 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.
- * THE AUTHORS DO NOT GUARANTEE THAT THIS SOFTWARE DOES NOT INFRINGE
- * ANY OTHERS' INTELLECTUAL PROPERTIES. IN NO EVENT SHALL THE AUTHORS
- * BE LIABLE FOR ANY INFRINGEMENT OF ANY OTHERS' INTELLECTUAL
- * PROPERTIES.
- */
-/* $FreeBSD$ */
-
-#ifndef _NET_RADIX_MPATH_H_
-#define _NET_RADIX_MPATH_H_
-
-#ifdef _KERNEL
-/*
- * Radix tree API with multipath support
- */
-struct route;
-struct rtentry;
-struct sockaddr;
-struct rib_head;
-int rt_mpath_capable(struct rib_head *);
-int rn_mpath_capable(struct radix_head *);
-struct radix_node *rn_mpath_next(struct radix_node *);
-u_int32_t rn_mpath_count(struct radix_node *);
-struct rtentry *rt_mpath_matchgate(struct rtentry *, struct sockaddr *);
-int rt_mpath_conflict(struct rib_head *, struct rtentry *,
- struct sockaddr *);
-struct rtentry *rt_mpath_select(struct rtentry *, uint32_t);
-struct rtentry *rt_mpath_selectrte(struct rtentry *, uint32_t);
-int rt_mpath_deldup(struct rtentry *, struct rtentry *);
-int rn4_mpath_inithead(void **, int, u_int);
-int rn6_mpath_inithead(void **, int, u_int);
-
-static inline struct rtentry *
-rt_mpath_next(struct rtentry *rt)
-{
- struct radix_node *next, *rn;
-
- rn = (struct radix_node *)rt;
-
- if (!rn->rn_dupedkey)
- return (NULL);
- next = rn->rn_dupedkey;
- if (rn->rn_mask == next->rn_mask)
- return (struct rtentry *)next;
- else
- return (NULL);
-}
-
-#endif
-
-#endif /* _NET_RADIX_MPATH_H_ */
Index: sys/net/radix_mpath.c
===================================================================
--- sys/net/radix_mpath.c
+++ /dev/null
@@ -1,276 +0,0 @@
-/* $KAME: radix_mpath.c,v 1.17 2004/11/08 10:29:39 itojun Exp $ */
-
-/*
- * SPDX-License-Identifier: BSD-3-Clause
- *
- * Copyright (C) 2001 WIDE Project.
- * 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.
- * 3. Neither the name of the project 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 PROJECT 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 PROJECT 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.
- * THE AUTHORS DO NOT GUARANTEE THAT THIS SOFTWARE DOES NOT INFRINGE
- * ANY OTHERS' INTELLECTUAL PROPERTIES. IN NO EVENT SHALL THE AUTHORS
- * BE LIABLE FOR ANY INFRINGEMENT OF ANY OTHERS' INTELLECTUAL
- * PROPERTIES.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "opt_inet.h"
-#include "opt_inet6.h"
-#include "opt_mpath.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mutex.h>
-#include <sys/socket.h>
-#include <sys/domain.h>
-#include <sys/kernel.h>
-#include <sys/syslog.h>
-#include <net/radix.h>
-#include <net/radix_mpath.h>
-#include <sys/rmlock.h>
-#include <net/route.h>
-#include <net/route/nhop.h>
-#include <net/route/route_var.h>
-#include <net/route/nhop.h>
-#include <net/if.h>
-#include <net/if_var.h>
-
-/*
- * give some jitter to hash, to avoid synchronization between routers
- */
-static uint32_t hashjitter;
-
-int
-rt_mpath_capable(struct rib_head *rnh)
-{
-
- return rnh->rnh_multipath;
-}
-
-int
-rn_mpath_capable(struct radix_head *rh)
-{
-
- return (rt_mpath_capable((struct rib_head *)rh));
-}
-
-struct radix_node *
-rn_mpath_next(struct radix_node *rn)
-{
- struct radix_node *next;
-
- if (!rn->rn_dupedkey)
- return NULL;
- next = rn->rn_dupedkey;
- if (rn->rn_mask == next->rn_mask)
- return next;
- else
- return NULL;
-}
-
-uint32_t
-rn_mpath_count(struct radix_node *rn)
-{
- uint32_t i = 0;
- struct rtentry *rt;
-
- while (rn != NULL) {
- rt = (struct rtentry *)rn;
- i += rt->rt_weight;
- rn = rn_mpath_next(rn);
- }
- return (i);
-}
-
-struct rtentry *
-rt_mpath_matchgate(struct rtentry *rt, struct sockaddr *gate)
-{
- struct radix_node *rn;
- struct nhop_object *nh;
-
- if (gate == NULL)
- return (NULL);
-
- /* beyond here, we use rn as the master copy */
- rn = (struct radix_node *)rt;
- do {
- rt = (struct rtentry *)rn;
- nh = rt->rt_nhop;
- /*
- * we are removing an address alias that has
- * the same prefix as another address
- * we need to compare the interface address because
- * gateway is a special sockaddr_dl structure
- */
- if (nh->gw_sa.sa_family == AF_LINK) {
- if (!memcmp(nh->nh_ifa->ifa_addr, gate, gate->sa_len))
- break;
- }
-
- /*
- * Check for other options:
- * 1) Routes with 'real' IPv4/IPv6 gateway
- * 2) Loopback host routes (another AF_LINK/sockadd_dl check)
- * */
- if (nh->gw_sa.sa_len == gate->sa_len &&
- !memcmp(&nh->gw_sa, gate, gate->sa_len))
- break;
- } while ((rn = rn_mpath_next(rn)) != NULL);
-
- return (struct rtentry *)rn;
-}
-
-/*
- * go through the chain and unlink "rt" from the list
- * the caller will free "rt"
- */
-int
-rt_mpath_deldup(struct rtentry *headrt, struct rtentry *rt)
-{
- struct radix_node *t, *tt;
-
- if (!headrt || !rt)
- return (0);
- t = (struct radix_node *)headrt;
- tt = rn_mpath_next(t);
- while (tt) {
- if (tt == (struct radix_node *)rt) {
- t->rn_dupedkey = tt->rn_dupedkey;
- tt->rn_dupedkey = NULL;
- tt->rn_flags &= ~RNF_ACTIVE;
- tt[1].rn_flags &= ~RNF_ACTIVE;
- return (1);
- }
- t = tt;
- tt = rn_mpath_next((struct radix_node *)t);
- }
- return (0);
-}
-
-/*
- * check if we have the same key/mask/gateway on the table already.
- * Assume @rt rt_key host bits are cleared according to @netmask
- */
-int
-rt_mpath_conflict(struct rib_head *rnh, struct rtentry *rt,
- struct sockaddr *netmask)
-{
- struct radix_node *rn, *rn1;
- struct nhop_object *nh, *nh1;
- struct rtentry *rt1;
-
- rn = (struct radix_node *)rt;
- rn1 = rnh->rnh_lookup(rt_key(rt), netmask, &rnh->head);
- if (!rn1 || rn1->rn_flags & RNF_ROOT)
- return (0);
-
- /* key/mask are the same. compare gateway for all multipaths */
- do {
- rt1 = (struct rtentry *)rn1;
-
- /* sanity: no use in comparing the same thing */
- if (rn1 == rn)
- continue;
-
- nh = rt->rt_nhop;
- nh1 = rt1->rt_nhop;
-
- if (nh1->gw_sa.sa_family == AF_LINK) {
- if (nh1->nh_ifa->ifa_addr->sa_len != nh->nh_ifa->ifa_addr->sa_len ||
- bcmp(nh1->nh_ifa->ifa_addr, nh->nh_ifa->ifa_addr,
- nh1->nh_ifa->ifa_addr->sa_len))
- continue;
- } else {
- if (nh1->gw_sa.sa_len != nh->gw_sa.sa_len ||
- bcmp(&nh1->gw_sa, &nh->gw_sa, nh1->gw_sa.sa_len))
- continue;
- }
-
- /* all key/mask/gateway are the same. conflicting entry. */
- return (EEXIST);
- } while ((rn1 = rn_mpath_next(rn1)) != NULL);
-
- return (0);
-}
-
-struct rtentry *
-rt_mpath_selectrte(struct rtentry *rte, uint32_t hash)
-{
- struct radix_node *rn0, *rn;
- uint32_t total_weight;
- struct rtentry *rt;
- int64_t weight;
-
- /* beyond here, we use rn as the master copy */
- rn0 = rn = (struct radix_node *)rte;
- rt = rte;
-
- /* gw selection by Modulo-N Hash (RFC2991) XXX need improvement? */
- total_weight = rn_mpath_count(rn0);
- hash += hashjitter;
- hash %= total_weight;
- for (weight = abs((int32_t)hash);
- rt != NULL && weight >= rt->rt_weight;
- weight -= (rt == NULL) ? 0 : rt->rt_weight) {
-
- /* stay within the multipath routes */
- if (rn->rn_dupedkey && rn->rn_mask != rn->rn_dupedkey->rn_mask)
- break;
- rn = rn->rn_dupedkey;
- rt = (struct rtentry *)rn;
- }
-
- return (rt);
-}
-
-struct rtentry *
-rt_mpath_select(struct rtentry *rte, uint32_t hash)
-{
- if (rn_mpath_next((struct radix_node *)rte) == NULL)
- return (rte);
-
- return (rt_mpath_selectrte(rte, hash));
-}
-
-void
-rt_mpath_init_rnh(struct rib_head *rnh)
-{
-
- rnh->rnh_multipath = 1;
-}
-
-#ifdef RADIX_MPATH
-static void
-mpath_init(void)
-{
-
- hashjitter = arc4random();
-}
-SYSINIT(mpath_init, SI_SUB_LAST, SI_ORDER_ANY, mpath_init, NULL);
-#endif
Index: sys/net/route.c
===================================================================
--- sys/net/route.c
+++ sys/net/route.c
@@ -65,10 +65,6 @@
#include <net/route/nhop.h>
#include <net/vnet.h>
-#ifdef RADIX_MPATH
-#include <net/radix_mpath.h>
-#endif
-
#include <netinet/in.h>
#include <netinet/ip_mroute.h>
@@ -749,87 +745,6 @@
}
return (i);
-}
-#endif
-
-#ifdef RADIX_MPATH
-/*
- * Deletes key for single-path routes, unlinks rtentry with
- * gateway specified in @info from multi-path routes.
- *
- * Returnes unlinked entry. In case of failure, returns NULL
- * and sets @perror to ESRCH.
- */
-struct radix_node *
-rt_mpath_unlink(struct rib_head *rnh, struct rt_addrinfo *info,
- struct rtentry *rto, int *perror)
-{
- /*
- * if we got multipath routes, we require users to specify
- * a matching RTAX_GATEWAY.
- */
- struct rtentry *rt; // *rto = NULL;
- struct radix_node *rn;
- struct sockaddr *gw;
-
- gw = info->rti_info[RTAX_GATEWAY];
- rt = rt_mpath_matchgate(rto, gw);
- if (rt == NULL) {
- *perror = ESRCH;
- return (NULL);
- }
-
- /*
- * this is the first entry in the chain
- */
- if (rto == rt) {
- rn = rn_mpath_next((struct radix_node *)rt);
- /*
- * there is another entry, now it's active
- */
- if (rn) {
- rto = RNTORT(rn);
- rto->rte_flags |= RTF_UP;
- } else if (rt->rte_flags & RTF_GATEWAY) {
- /*
- * For gateway routes, we need to
- * make sure that we we are deleting
- * the correct gateway.
- * rt_mpath_matchgate() does not
- * check the case when there is only
- * one route in the chain.
- */
- if (gw &&
- (rt->rt_nhop->gw_sa.sa_len != gw->sa_len ||
- memcmp(&rt->rt_nhop->gw_sa, gw, gw->sa_len))) {
- *perror = ESRCH;
- return (NULL);
- }
- }
-
- /*
- * use the normal delete code to remove
- * the first entry
- */
- rn = rnh->rnh_deladdr(info->rti_info[RTAX_DST],
- info->rti_info[RTAX_NETMASK],
- &rnh->head);
- if (rn != NULL) {
- *perror = 0;
- } else {
- *perror = ESRCH;
- }
- return (rn);
- }
-
- /*
- * if the entry is 2nd and on up
- */
- if (rt_mpath_deldup(rto, rt) == 0)
- panic ("rtrequest1: rt_mpath_deldup");
- *perror = 0;
- rn = (struct radix_node *)rt;
- return (rn);
}
#endif
Index: sys/net/route/route_ctl.c
===================================================================
--- sys/net/route/route_ctl.c
+++ sys/net/route/route_ctl.c
@@ -54,10 +54,6 @@
#include <net/route/nhop_var.h>
#include <netinet/in.h>
-#ifdef RADIX_MPATH
-#include <net/radix_mpath.h>
-#endif
-
#include <vm/uma.h>
/*
Index: sys/net/route/route_ifaddrs.c
===================================================================
--- sys/net/route/route_ifaddrs.c
+++ sys/net/route/route_ifaddrs.c
@@ -32,7 +32,6 @@
* $FreeBSD$
*/
-#include "opt_mpath.h"
#include "opt_route.h"
#include <sys/param.h>
@@ -64,6 +63,66 @@
VNET_DEFINE(u_int, rt_add_addr_allfibs) = 0;
SYSCTL_UINT(_net, OID_AUTO, add_addr_allfibs, CTLFLAG_RWTUN | CTLFLAG_VNET,
&VNET_NAME(rt_add_addr_allfibs), 0, "");
+
+
+static int
+handle_change(struct rt_addrinfo *info, int fibnum)
+{
+ struct epoch_tracker et;
+ struct rib_cmd_info rc;
+
+ NET_EPOCH_ENTER(et);
+ error = rib_action(fibnum, cmd, &info, &rc);
+ if (error == 0) {
+ /*
+ * notify any listening routing agents of the change
+ */
+ KASSERT(rc.rc_rt != NULL, ("F"));
+
+ /* TODO: interface routes/aliases */
+ rt_newaddrmsg_fib(cmd, ifa, rc.rc_rt, fibnum);
+ }
+ NET_EPOCH_EXIT(et);
+
+ return (error);
+}
+
+static int
+rtinit2(struct ifaddr *ifa, int cmd, int flags, int fibnum)
+{
+ RIB_RLOCK_TRACKER;
+ struct epoch_tracker et;
+ struct sockaddr *dst;
+ struct sockaddr *netmask;
+ struct rt_addrinfo info;
+
+ struct sockaddr_dl_short sdl;
+ struct rib_head *rnh;
+
+ if (flags & RTF_HOST) {
+ dst = ifa->ifa_dstaddr;
+ netmask = NULL;
+ } else {
+ dst = (struct sockaddr *)&ss;
+ netmask = ifa->ifa_netmask;
+ rt_maskedcopy(ifa->ifa_addr, dst, netmask);
+ }
+
+ /* Gateway for the interface routes is always AF_LINK with interface index */
+ bzero(&sdl, sizeof(struct sockaddr_dl_short));
+ sdl.sdl_family = AF_LINK;
+ sdl.sdl_len = sizeof(struct sockaddr_dl_short);
+ sdl.sdl_type = ifa->ifa_ifp->if_type;
+ sdl.sdl_index = ifa->ifa_ifp->if_index;
+
+ /* Setup actual request */
+ bzero(&info, sizeof(info));
+ info.rti_ifa = ifa;
+ info.rti_flags = flags | (ifa->ifa_flags & ~IFA_RTSELF) | RTF_PINNED;
+ info.rti_info[RTAX_DST] = dst;
+ info.rti_info[RTAX_NETMASK] = netmask;
+ info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&sdl;
+}
/*
* Set up a routing table entry, normally
Index: sys/net/rtsock.c
===================================================================
--- sys/net/rtsock.c
+++ sys/net/rtsock.c
@@ -64,9 +64,6 @@
#include <net/route.h>
#include <net/route/route_ctl.h>
#include <net/route/route_var.h>
-#ifdef RADIX_MPATH
-#include <net/radix_mpath.h>
-#endif
#include <net/vnet.h>
#include <netinet/in.h>
Index: sys/netinet/ip_input.c
===================================================================
--- sys/netinet/ip_input.c
+++ sys/netinet/ip_input.c
@@ -981,11 +981,7 @@
sin->sin_family = AF_INET;
sin->sin_len = sizeof(*sin);
sin->sin_addr = ip->ip_dst;
-#ifdef RADIX_MPATH
- flowid = ntohl(ip->ip_src.s_addr ^ ip->ip_dst.s_addr);
-#else
flowid = m->m_pkthdr.flowid;
-#endif
ro.ro_nh = fib4_lookup(M_GETFIB(m), ip->ip_dst, 0, NHR_REF, flowid);
if (ro.ro_nh != NULL) {
ia = ifatoia(ro.ro_nh->nh_ifa);
Index: sys/netinet6/nd6.c
===================================================================
--- sys/netinet6/nd6.c
+++ sys/netinet6/nd6.c
@@ -1309,11 +1309,7 @@
* This is the case where multiple interfaces
* have the same prefix, but only one is installed
* into the routing table and that prefix entry
- * is not the one being examined here. In the case
- * where RADIX_MPATH is enabled, multiple route
- * entries (of the same rt_key value) will be
- * installed because the interface addresses all
- * differ.
+ * is not the one being examined here.
*/
if (!IN6_ARE_ADDR_EQUAL(&pr->ndpr_prefix.sin6_addr,
&rt_key.sin6_addr))

File Metadata

Mime Type
text/plain
Expires
Fri, Dec 20, 4:02 PM (20 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15531496
Default Alt Text
D27244.id79627.diff (17 KB)

Event Timeline