svn commit: r231744 - in projects/multi-fibv6/8: contrib/netcat etc
etc/rc.d share/man/man4 sys/contrib/pf/net sys/fs/nfsclient
sys/kern sys/net sys/netinet sys/netinet/ipfw sys/netinet6
sys/netips...
Bjoern A. Zeeb
bz at FreeBSD.org
Wed Feb 15 06:49:51 UTC 2012
Author: bz
Date: Wed Feb 15 06:49:50 2012
New Revision: 231744
URL: http://svn.freebsd.org/changeset/base/231744
Log:
Initial backport of the multi-FIB IPv6 changes from HEAD.
Sponsored by: Cisco Systems, Inc.
Modified:
projects/multi-fibv6/8/contrib/netcat/netcat.c
projects/multi-fibv6/8/etc/network.subr
projects/multi-fibv6/8/etc/rc.d/network_ipv6
projects/multi-fibv6/8/share/man/man4/faith.4
projects/multi-fibv6/8/sys/contrib/pf/net/pf.c
projects/multi-fibv6/8/sys/contrib/pf/net/pf_ioctl.c
projects/multi-fibv6/8/sys/fs/nfsclient/nfs_clport.c
projects/multi-fibv6/8/sys/fs/nfsclient/nfs_clvfsops.c
projects/multi-fibv6/8/sys/kern/uipc_socket.c
projects/multi-fibv6/8/sys/net/flowtable.c
projects/multi-fibv6/8/sys/net/if_faith.c
projects/multi-fibv6/8/sys/net/route.c
projects/multi-fibv6/8/sys/net/route.h
projects/multi-fibv6/8/sys/netinet/in.c
projects/multi-fibv6/8/sys/netinet/ipfw/ip_fw2.c
projects/multi-fibv6/8/sys/netinet/sctp_os_bsd.h
projects/multi-fibv6/8/sys/netinet/tcp_subr.c
projects/multi-fibv6/8/sys/netinet6/icmp6.c
projects/multi-fibv6/8/sys/netinet6/in6.c
projects/multi-fibv6/8/sys/netinet6/in6_gif.c
projects/multi-fibv6/8/sys/netinet6/in6_ifattach.c
projects/multi-fibv6/8/sys/netinet6/in6_mcast.c
projects/multi-fibv6/8/sys/netinet6/in6_rmx.c
projects/multi-fibv6/8/sys/netinet6/in6_src.c
projects/multi-fibv6/8/sys/netinet6/in6_var.h
projects/multi-fibv6/8/sys/netinet6/ip6_forward.c
projects/multi-fibv6/8/sys/netinet6/ip6_input.c
projects/multi-fibv6/8/sys/netinet6/ip6_output.c
projects/multi-fibv6/8/sys/netinet6/ip6_var.h
projects/multi-fibv6/8/sys/netinet6/nd6.c
projects/multi-fibv6/8/sys/netinet6/nd6_nbr.c
projects/multi-fibv6/8/sys/netinet6/nd6_rtr.c
projects/multi-fibv6/8/sys/netinet6/raw_ip6.c
projects/multi-fibv6/8/sys/netipsec/ipsec_output.c
projects/multi-fibv6/8/sys/nfs/bootp_subr.c
projects/multi-fibv6/8/sys/nfsclient/nfs_vfsops.c
projects/multi-fibv6/8/usr.bin/netstat/route.c
Modified: projects/multi-fibv6/8/contrib/netcat/netcat.c
==============================================================================
--- projects/multi-fibv6/8/contrib/netcat/netcat.c Wed Feb 15 06:45:49 2012 (r231743)
+++ projects/multi-fibv6/8/contrib/netcat/netcat.c Wed Feb 15 06:49:50 2012 (r231744)
@@ -605,8 +605,10 @@ remote_connect(const char *host, const c
#endif
if (rtableid) {
- if (setfib(rtableid) == -1)
- err(1, "setfib");
+ if (setsockopt(s, SOL_SOCKET, SO_SETFIB, &rtableid,
+ sizeof(rtableid)) == -1)
+ err(1, "setsockopt(.., SO_SETFIB, %u, ..)",
+ rtableid);
}
/* Bind to a local port or source address if specified. */
@@ -678,8 +680,11 @@ local_listen(char *host, char *port, str
continue;
if (rtableid) {
- if (setfib(rtableid) == -1)
- err(1, "setfib");
+ ret = setsockopt(s, SOL_SOCKET, SO_SETFIB, &rtableid,
+ sizeof(rtableid));
+ if (ret == -1)
+ err(1, "setsockopt(.., SO_SETFIB, %u, ..)",
+ rtableid);
}
ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x));
Modified: projects/multi-fibv6/8/etc/network.subr
==============================================================================
--- projects/multi-fibv6/8/etc/network.subr Wed Feb 15 06:45:49 2012 (r231743)
+++ projects/multi-fibv6/8/etc/network.subr Wed Feb 15 06:49:50 2012 (r231744)
@@ -1125,16 +1125,33 @@ network6_default_interface_setup()
;;
esac
+ # Get the number of FIBs supported.
+ fibs=`sysctl -n net.fibs`
+ : ${fibs:=1}
+
# Disallow unicast packets without outgoing scope identifiers,
# or route such packets to a "default" interface, if it is specified.
route add -inet6 fe80:: -prefixlen 10 ::1 -reject
case ${ipv6_default_interface} in
[Nn][Oo] | '')
- route add -inet6 ff02:: -prefixlen 16 ::1 -reject
+ i=0
+ while test ${i} -lt ${fibs}; do
+ setfib -F ${i} \
+ route add -inet6 ff02:: -prefixlen 16 ::1 -reject
+ i=$((i + 1))
+ done
;;
*)
laddr=`network6_getladdr ${ipv6_default_interface}`
+ # Only add the laddr route to the default FIB and a reject
+ # route to all others.
route add -inet6 ff02:: ${laddr} -prefixlen 16 -interface
+ i=1
+ while test ${i} -lt ${fibs}; do
+ setfib -F ${i} \
+ route add -inet6 ff02:: -prefixlen 16 ::1 -reject
+ i=$((i + 1))
+ done
# Disable installing the default interface with the
# case net.inet6.ip6.forwarding=0 and
Modified: projects/multi-fibv6/8/etc/rc.d/network_ipv6
==============================================================================
--- projects/multi-fibv6/8/etc/rc.d/network_ipv6 Wed Feb 15 06:45:49 2012 (r231743)
+++ projects/multi-fibv6/8/etc/rc.d/network_ipv6 Wed Feb 15 06:49:50 2012 (r231744)
@@ -41,9 +41,21 @@ start_cmd="network_ipv6_start"
network_ipv6_start()
{
- # disallow "internal" addresses to appear on the wire
- route add -inet6 ::ffff:0.0.0.0 -prefixlen 96 ::1 -reject
- route add -inet6 ::0.0.0.0 -prefixlen 96 ::1 -reject
+ local fibs i
+
+ # Get the number of FIBs supported.
+ fibs=`sysctl -n net.fibs`
+ : ${fibs:=1}
+
+ # disallow "internal" addresses to appear on the wire
+ i=0
+ while test ${i} -lt ${fibs}; do
+ setfib -F ${i} route add -inet6 \
+ ::ffff:0.0.0.0 -prefixlen 96 ::1 -reject
+ setfib -F ${i} route add -inet6 \
+ ::0.0.0.0 -prefixlen 96 ::1 -reject
+ i=$((i + 1))
+ done
case ${ipv6_network_interfaces} in
[Aa][Uu][Tt][Oo])
Modified: projects/multi-fibv6/8/share/man/man4/faith.4
==============================================================================
--- projects/multi-fibv6/8/share/man/man4/faith.4 Wed Feb 15 06:45:49 2012 (r231743)
+++ projects/multi-fibv6/8/share/man/man4/faith.4 Wed Feb 15 06:49:50 2012 (r231744)
@@ -29,7 +29,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd April 10, 1999
+.Dd January 23, 2012
.Dt FAITH 4
.Os
.Sh NAME
@@ -58,7 +58,7 @@ variable in
.Xr rc.conf 5 .
.Pp
Special action will be taken when IPv6 TCP traffic is seen on a router,
-and the routing table suggests to route it to the
+and the default routing table suggests to route it to the
.Nm
interface.
In this case, the packet will be accepted by the router,
Modified: projects/multi-fibv6/8/sys/contrib/pf/net/pf.c
==============================================================================
--- projects/multi-fibv6/8/sys/contrib/pf/net/pf.c Wed Feb 15 06:45:49 2012 (r231743)
+++ projects/multi-fibv6/8/sys/contrib/pf/net/pf.c Wed Feb 15 06:49:50 2012 (r231744)
@@ -3197,11 +3197,7 @@ pf_calc_mss(struct pf_addr *addr, sa_fam
dst->sin_len = sizeof(*dst);
dst->sin_addr = addr->v4;
#ifdef __FreeBSD__
-#ifdef RTF_PRCLONING
- rtalloc_ign(&ro, (RTF_CLONING | RTF_PRCLONING));
-#else /* !RTF_PRCLONING */
- in_rtalloc_ign(&ro, 0, 0);
-#endif
+ in_rtalloc_ign(&ro, 0, RT_DEFAULT_FIB);
#else /* ! __FreeBSD__ */
rtalloc_noclone(&ro, NO_CLONING);
#endif
@@ -3217,12 +3213,7 @@ pf_calc_mss(struct pf_addr *addr, sa_fam
dst6->sin6_len = sizeof(*dst6);
dst6->sin6_addr = addr->v6;
#ifdef __FreeBSD__
-#ifdef RTF_PRCLONING
- rtalloc_ign((struct route *)&ro6,
- (RTF_CLONING | RTF_PRCLONING));
-#else /* !RTF_PRCLONING */
- rtalloc_ign((struct route *)&ro6, 0);
-#endif
+ in6_rtalloc_ign(&ro6, 0, RT_DEFAULT_FIB);
#else /* ! __FreeBSD__ */
rtalloc_noclone((struct route *)&ro6, NO_CLONING);
#endif
@@ -6134,9 +6125,11 @@ pf_routable(struct pf_addr *addr, sa_fam
#ifdef __FreeBSD__
/* XXX MRT not always INET */ /* stick with table 0 though */
if (af == AF_INET)
- in_rtalloc_ign((struct route *)&ro, 0, 0);
+ in_rtalloc_ign((struct route *)&ro, 0, RT_DEFAULT_FIB);
+#ifdef INET6
else
- rtalloc_ign((struct route *)&ro, 0);
+ in6_rtalloc_ign(&ro, 0, RT_DEFAULT_FIB);
+#endif
#else /* ! __FreeBSD__ */
rtalloc_noclone((struct route *)&ro, NO_CLONING);
#endif
@@ -6212,14 +6205,12 @@ pf_rtlabel_match(struct pf_addr *addr, s
}
#ifdef __FreeBSD__
-# ifdef RTF_PRCLONING
- rtalloc_ign((struct route *)&ro, (RTF_CLONING|RTF_PRCLONING));
-# else /* !RTF_PRCLONING */
if (af == AF_INET)
- in_rtalloc_ign((struct route *)&ro, 0, 0);
+ in_rtalloc_ign((struct route *)&ro, 0, RT_DEFAULT_FIB);
+#ifdef INET6
else
- rtalloc_ign((struct route *)&ro, 0);
-# endif
+ in6_rtalloc_ign(&ro, 0, RT_DEFAULT_FIB);
+#endif
#else /* ! __FreeBSD__ */
rtalloc_noclone((struct route *)&ro, NO_CLONING);
#endif
Modified: projects/multi-fibv6/8/sys/contrib/pf/net/pf_ioctl.c
==============================================================================
--- projects/multi-fibv6/8/sys/contrib/pf/net/pf_ioctl.c Wed Feb 15 06:45:49 2012 (r231743)
+++ projects/multi-fibv6/8/sys/contrib/pf/net/pf_ioctl.c Wed Feb 15 06:49:50 2012 (r231744)
@@ -1531,7 +1531,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
}
#ifdef __FreeBSD__ /* ROUTING */
- if (rule->rtableid > 0 && rule->rtableid > rt_numfibs)
+ if (rule->rtableid > 0 && rule->rtableid >= rt_numfibs)
#else
if (rule->rtableid > 0 && !rtable_exists(rule->rtableid))
#endif
@@ -1794,7 +1794,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
if (newrule->rtableid > 0 &&
#ifdef __FreeBSD__ /* ROUTING */
- newrule->rtableid > rt_numfibs)
+ newrule->rtableid >= rt_numfibs)
#else
!rtable_exists(newrule->rtableid))
#endif
Modified: projects/multi-fibv6/8/sys/fs/nfsclient/nfs_clport.c
==============================================================================
--- projects/multi-fibv6/8/sys/fs/nfsclient/nfs_clport.c Wed Feb 15 06:45:49 2012 (r231743)
+++ projects/multi-fibv6/8/sys/fs/nfsclient/nfs_clport.c Wed Feb 15 06:49:50 2012 (r231744)
@@ -946,7 +946,8 @@ nfscl_getmyip(struct nfsmount *nmp, int
sad.sin_len = sizeof (struct sockaddr_in);
sad.sin_addr.s_addr = sin->sin_addr.s_addr;
CURVNET_SET(CRED_TO_VNET(nmp->nm_sockreq.nr_cred));
- rt = rtalloc1((struct sockaddr *)&sad, 0, 0UL);
+ rt = rtalloc1_fib((struct sockaddr *)&sad, 0, 0UL,
+ curthread->td_proc->p_fibnum);
if (rt != NULL) {
if (rt->rt_ifp != NULL &&
rt->rt_ifa != NULL &&
@@ -971,7 +972,8 @@ nfscl_getmyip(struct nfsmount *nmp, int
sad6.sin6_len = sizeof (struct sockaddr_in6);
sad6.sin6_addr = sin6->sin6_addr;
CURVNET_SET(CRED_TO_VNET(nmp->nm_sockreq.nr_cred));
- rt = rtalloc1((struct sockaddr *)&sad6, 0, 0UL);
+ rt = rtalloc1_fib((struct sockaddr *)&sad6, 0, 0UL,
+ curthread->td_proc->p_fibnum);
if (rt != NULL) {
if (rt->rt_ifp != NULL &&
rt->rt_ifa != NULL &&
Modified: projects/multi-fibv6/8/sys/fs/nfsclient/nfs_clvfsops.c
==============================================================================
--- projects/multi-fibv6/8/sys/fs/nfsclient/nfs_clvfsops.c Wed Feb 15 06:45:49 2012 (r231743)
+++ projects/multi-fibv6/8/sys/fs/nfsclient/nfs_clvfsops.c Wed Feb 15 06:49:50 2012 (r231744)
@@ -455,10 +455,10 @@ nfs_mountroot(struct mount *mp)
sin.sin_len = sizeof(sin);
/* XXX MRT use table 0 for this sort of thing */
CURVNET_SET(TD_TO_VNET(td));
- error = rtrequest(RTM_ADD, (struct sockaddr *)&sin,
+ error = rtrequest_fib(RTM_ADD, (struct sockaddr *)&sin,
(struct sockaddr *)&nd->mygateway,
(struct sockaddr *)&mask,
- RTF_UP | RTF_GATEWAY, NULL);
+ RTF_UP | RTF_GATEWAY, NULL, RT_DEFAULT_FIB);
CURVNET_RESTORE();
if (error)
panic("nfs_mountroot: RTM_ADD: %d", error);
Modified: projects/multi-fibv6/8/sys/kern/uipc_socket.c
==============================================================================
--- projects/multi-fibv6/8/sys/kern/uipc_socket.c Wed Feb 15 06:45:49 2012 (r231743)
+++ projects/multi-fibv6/8/sys/kern/uipc_socket.c Wed Feb 15 06:49:50 2012 (r231744)
@@ -383,6 +383,7 @@ socreate(int dom, struct socket **aso, i
so->so_type = type;
so->so_cred = crhold(cred);
if ((prp->pr_domain->dom_family == PF_INET) ||
+ (prp->pr_domain->dom_family == PF_INET6) ||
(prp->pr_domain->dom_family == PF_ROUTE))
so->so_fibnum = td->td_proc->p_fibnum;
else
@@ -2492,12 +2493,13 @@ sosetopt(struct socket *so, struct socko
case SO_SETFIB:
error = sooptcopyin(sopt, &optval, sizeof optval,
sizeof optval);
- if (optval < 0 || optval > rt_numfibs) {
+ if (optval < 0 || optval >= rt_numfibs) {
error = EINVAL;
goto bad;
}
if (so->so_proto != NULL &&
((so->so_proto->pr_domain->dom_family == PF_INET) ||
+ (so->so_proto->pr_domain->dom_family == PF_INET6) ||
(so->so_proto->pr_domain->dom_family == PF_ROUTE))) {
so->so_fibnum = optval;
/* Note: ignore error */
Modified: projects/multi-fibv6/8/sys/net/flowtable.c
==============================================================================
--- projects/multi-fibv6/8/sys/net/flowtable.c Wed Feb 15 06:45:49 2012 (r231743)
+++ projects/multi-fibv6/8/sys/net/flowtable.c Wed Feb 15 06:49:50 2012 (r231744)
@@ -373,7 +373,7 @@ SYSCTL_VNET_PROC(_net_inet_flowtable, OI
#ifndef RADIX_MPATH
static void
-in_rtalloc_ign_wrapper(struct route *ro, uint32_t hash, u_int fibnum)
+rtalloc_ign_wrapper(struct route *ro, uint32_t hash, u_int fibnum)
{
rtalloc_ign_fib(ro, 0, fibnum);
@@ -1313,7 +1313,7 @@ flowtable_alloc(char *name, int nentry,
#ifdef RADIX_MPATH
ft->ft_rtalloc = rtalloc_mpath_fib;
#else
- ft->ft_rtalloc = in_rtalloc_ign_wrapper;
+ ft->ft_rtalloc = rtalloc_ign_wrapper;
#endif
if (flags & FL_PCPU) {
ft->ft_lock = flowtable_pcpu_lock;
Modified: projects/multi-fibv6/8/sys/net/if_faith.c
==============================================================================
--- projects/multi-fibv6/8/sys/net/if_faith.c Wed Feb 15 06:45:49 2012 (r231743)
+++ projects/multi-fibv6/8/sys/net/if_faith.c Wed Feb 15 06:49:50 2012 (r231744)
@@ -338,7 +338,7 @@ faithprefix(in6)
sin6.sin6_family = AF_INET6;
sin6.sin6_len = sizeof(struct sockaddr_in6);
sin6.sin6_addr = *in6;
- rt = rtalloc1((struct sockaddr *)&sin6, 0, 0UL);
+ rt = in6_rtalloc1((struct sockaddr *)&sin6, 0, 0UL, RT_DEFAULT_FIB);
if (rt && rt->rt_ifp && rt->rt_ifp->if_type == IFT_FAITH &&
(rt->rt_ifp->if_flags & IFF_UP) != 0)
ret = 1;
Modified: projects/multi-fibv6/8/sys/net/route.c
==============================================================================
--- projects/multi-fibv6/8/sys/net/route.c Wed Feb 15 06:45:49 2012 (r231743)
+++ projects/multi-fibv6/8/sys/net/route.c Wed Feb 15 06:49:50 2012 (r231744)
@@ -35,6 +35,7 @@
***********************************************************************/
#include "opt_inet.h"
+#include "opt_inet6.h"
#include "opt_route.h"
#include "opt_mrouting.h"
#include "opt_mpath.h"
@@ -72,7 +73,11 @@ SYSCTL_INT(_net, OID_AUTO, fibs, CTLFLAG
/*
* Allow the boot code to allow LESS than RT_MAXFIBS to be used.
* We can't do more because storage is statically allocated for now.
- * (for compatibility reasons.. this will change).
+ * (for compatibility reasons.. this will change. When this changes, code should
+ * be refactored to protocol independent parts and protocol dependent parts,
+ * probably hanging of domain(9) specific storage to not need the full
+ * fib * af RNH allocation etc. but allow tuning the number of tables per
+ * address family).
*/
TUNABLE_INT("net.fibs", &rt_numfibs);
@@ -82,6 +87,9 @@ TUNABLE_INT("net.fibs", &rt_numfibs);
* changes for the FIB of the caller when adding a new set of addresses
* to an interface. XXX this is a shotgun aproach to a problem that needs
* a more fine grained solution.. that will come.
+ * XXX also has the problems getting the FIB from curthread which will not
+ * always work given the fib can be overridden and prefixes can be added
+ * from the network stack context.
*/
u_int rt_add_addr_allfibs = 1;
SYSCTL_INT(_net, OID_AUTO, add_addr_allfibs, CTLFLAG_RW,
@@ -196,27 +204,23 @@ vnet_route_init(const void *unused __unu
V_rtzone = uma_zcreate("rtentry", sizeof(struct rtentry), NULL, NULL,
NULL, NULL, UMA_ALIGN_PTR, 0);
for (dom = domains; dom; dom = dom->dom_next) {
- if (dom->dom_rtattach) {
- for (table = 0; table < rt_numfibs; table++) {
- if ( (fam = dom->dom_family) == AF_INET ||
- table == 0) {
- /* for now only AF_INET has > 1 table */
- /* XXX MRT
- * rtattach will be also called
- * from vfs_export.c but the
- * offset will be 0
- * (only for AF_INET and AF_INET6
- * which don't need it anyhow)
- */
- rnh = rt_tables_get_rnh_ptr(table, fam);
- if (rnh == NULL)
- panic("%s: rnh NULL", __func__);
- dom->dom_rtattach((void **)rnh,
- dom->dom_rtoffset);
- } else {
- break;
- }
- }
+ if (dom->dom_rtattach == NULL)
+ continue;
+
+ for (table = 0; table < rt_numfibs; table++) {
+ fam = dom->dom_family;
+ if (table != 0 && fam != AF_INET6 && fam != AF_INET)
+ break;
+
+ /*
+ * XXX MRT rtattach will be also called from
+ * vfs_export.c but the offset will be 0 (only for
+ * AF_INET and AF_INET6 which don't need it anyhow).
+ */
+ rnh = rt_tables_get_rnh_ptr(table, fam);
+ if (rnh == NULL)
+ panic("%s: rnh NULL", __func__);
+ dom->dom_rtattach((void **)rnh, dom->dom_rtoffset);
}
}
}
@@ -233,20 +237,19 @@ vnet_route_uninit(const void *unused __u
struct radix_node_head **rnh;
for (dom = domains; dom; dom = dom->dom_next) {
- if (dom->dom_rtdetach) {
- for (table = 0; table < rt_numfibs; table++) {
- if ( (fam = dom->dom_family) == AF_INET ||
- table == 0) {
- /* For now only AF_INET has > 1 tbl. */
- rnh = rt_tables_get_rnh_ptr(table, fam);
- if (rnh == NULL)
- panic("%s: rnh NULL", __func__);
- dom->dom_rtdetach((void **)rnh,
- dom->dom_rtoffset);
- } else {
- break;
- }
- }
+ if (dom->dom_rtdetach == NULL)
+ continue;
+
+ for (table = 0; table < rt_numfibs; table++) {
+ fam = dom->dom_family;
+
+ if (table != 0 && fam != AF_INET6 && fam != AF_INET)
+ break;
+
+ rnh = rt_tables_get_rnh_ptr(table, fam);
+ if (rnh == NULL)
+ panic("%s: rnh NULL", __func__);
+ dom->dom_rtdetach((void **)rnh, dom->dom_rtoffset);
}
}
}
@@ -274,7 +277,8 @@ setfib(struct thread *td, struct setfib_
void
rtalloc(struct route *ro)
{
- rtalloc_ign_fib(ro, 0UL, 0);
+
+ rtalloc_ign_fib(ro, 0UL, RT_DEFAULT_FIB);
}
void
@@ -294,7 +298,7 @@ rtalloc_ign(struct route *ro, u_long ign
RTFREE(rt);
ro->ro_rt = NULL;
}
- ro->ro_rt = rtalloc1_fib(&ro->ro_dst, 1, ignore, 0);
+ ro->ro_rt = rtalloc1_fib(&ro->ro_dst, 1, ignore, RT_DEFAULT_FIB);
if (ro->ro_rt)
RT_UNLOCK(ro->ro_rt);
}
@@ -324,7 +328,8 @@ rtalloc_ign_fib(struct route *ro, u_long
struct rtentry *
rtalloc1(struct sockaddr *dst, int report, u_long ignflags)
{
- return (rtalloc1_fib(dst, report, ignflags, 0));
+
+ return (rtalloc1_fib(dst, report, ignflags, RT_DEFAULT_FIB));
}
struct rtentry *
@@ -339,8 +344,15 @@ rtalloc1_fib(struct sockaddr *dst, int r
int needlock;
KASSERT((fibnum < rt_numfibs), ("rtalloc1_fib: bad fibnum"));
- if (dst->sa_family != AF_INET) /* Only INET supports > 1 fib now */
- fibnum = 0;
+ switch (dst->sa_family) {
+ case AF_INET6:
+ case AF_INET:
+ /* We support multiple FIBs. */
+ break;
+ default:
+ fibnum = RT_DEFAULT_FIB;
+ break;
+ }
rnh = rt_tables_get_rnh(fibnum, dst->sa_family);
newrt = NULL;
if (rnh == NULL)
@@ -486,7 +498,8 @@ rtredirect(struct sockaddr *dst,
int flags,
struct sockaddr *src)
{
- rtredirect_fib(dst, gateway, netmask, flags, src, 0);
+
+ rtredirect_fib(dst, gateway, netmask, flags, src, RT_DEFAULT_FIB);
}
void
@@ -617,7 +630,8 @@ out:
int
rtioctl(u_long req, caddr_t data)
{
- return (rtioctl_fib(req, data, 0));
+
+ return (rtioctl_fib(req, data, RT_DEFAULT_FIB));
}
/*
@@ -647,7 +661,8 @@ rtioctl_fib(u_long req, caddr_t data, u_
struct ifaddr *
ifa_ifwithroute(int flags, struct sockaddr *dst, struct sockaddr *gateway)
{
- return (ifa_ifwithroute_fib(flags, dst, gateway, 0));
+
+ return (ifa_ifwithroute_fib(flags, dst, gateway, RT_DEFAULT_FIB));
}
struct ifaddr *
@@ -732,7 +747,9 @@ rtrequest(int req,
int flags,
struct rtentry **ret_nrt)
{
- return (rtrequest_fib(req, dst, gateway, netmask, flags, ret_nrt, 0));
+
+ return (rtrequest_fib(req, dst, gateway, netmask, flags, ret_nrt,
+ RT_DEFAULT_FIB));
}
int
@@ -771,7 +788,8 @@ rtrequest_fib(int req,
int
rt_getifa(struct rt_addrinfo *info)
{
- return (rt_getifa_fib(info, 0));
+
+ return (rt_getifa_fib(info, RT_DEFAULT_FIB));
}
/*
@@ -1029,8 +1047,16 @@ rtrequest1_fib(int req, struct rt_addrin
#define senderr(x) { error = x ; goto bad; }
KASSERT((fibnum < rt_numfibs), ("rtrequest1_fib: bad fibnum"));
- if (dst->sa_family != AF_INET) /* Only INET supports > 1 fib now */
- fibnum = 0;
+ switch (dst->sa_family) {
+ case AF_INET6:
+ case AF_INET:
+ /* We support multiple FIBs. */
+ break;
+ default:
+ fibnum = RT_DEFAULT_FIB;
+ break;
+ }
+
/*
* Find the correct routing tree to use for this Address Family
*/
@@ -1136,8 +1162,7 @@ rtrequest1_fib(int req, struct rt_addrin
rt->rt_flags = RTF_UP | flags;
rt->rt_fibnum = fibnum;
/*
- * Add the gateway. Possibly re-malloc-ing the storage for it
- *
+ * Add the gateway. Possibly re-malloc-ing the storage for it.
*/
RT_LOCK(rt);
if ((error = rt_setgate(rt, dst, gateway)) != 0) {
@@ -1186,12 +1211,17 @@ rtrequest1_fib(int req, struct rt_addrin
#ifdef FLOWTABLE
rt0 = NULL;
- /* XXX
- * "flow-table" only support IPv4 at the moment.
- * XXX-BZ as of r205066 it would support IPv6.
- */
+ /* "flow-table" only supports IPv6 and IPv4 at the moment. */
+ switch (dst->sa_family) {
+#ifdef notyet
+#ifdef INET6
+ case AF_INET6:
+#endif
+#endif
#ifdef INET
- if (dst->sa_family == AF_INET) {
+ case AF_INET:
+#endif
+#if defined(INET6) || defined(INET)
rn = rnh->rnh_matchaddr(dst, rnh);
if (rn && ((rn->rn_flags & RNF_ROOT) == 0)) {
struct sockaddr *mask;
@@ -1230,9 +1260,9 @@ rtrequest1_fib(int req, struct rt_addrin
}
}
}
+#endif/* INET6 || INET */
}
-#endif
-#endif
+#endif /* FLOWTABLE */
/* XXX mtu manipulation will be done in rnh_addaddr -- itojun */
rn = rnh->rnh_addaddr(ndst, netmask, rnh, rt->rt_nodes);
@@ -1254,9 +1284,20 @@ rtrequest1_fib(int req, struct rt_addrin
}
#ifdef FLOWTABLE
else if (rt0 != NULL) {
+ switch (dst->sa_family) {
+#ifdef notyet
+#ifdef INET6
+ case AF_INET6:
+ flowtable_route_flush(V_ip6_ft, rt0);
+ break;
+#endif
+#endif
#ifdef INET
- flowtable_route_flush(V_ip_ft, rt0);
+ case AF_INET:
+ flowtable_route_flush(V_ip_ft, rt0);
+ break;
#endif
+ }
RTFREE(rt0);
}
#endif
@@ -1388,8 +1429,17 @@ rtinit1(struct ifaddr *ifa, int cmd, int
dst = ifa->ifa_addr;
netmask = ifa->ifa_netmask;
}
- if ( dst->sa_family != AF_INET)
- fibnum = 0;
+ if (dst->sa_len == 0)
+ return(EINVAL);
+ switch (dst->sa_family) {
+ case AF_INET6:
+ case AF_INET:
+ /* We support multiple FIBs. */
+ break;
+ default:
+ fibnum = RT_DEFAULT_FIB;
+ break;
+ }
if (fibnum == -1) {
if (rt_add_addr_allfibs == 0 && cmd == (int)RTM_ADD) {
startfib = endfib = curthread->td_proc->p_fibnum;
@@ -1402,8 +1452,6 @@ rtinit1(struct ifaddr *ifa, int cmd, int
startfib = fibnum;
endfib = fibnum;
}
- if (dst->sa_len == 0)
- return(EINVAL);
/*
* If it's a delete, check that if it exists,
@@ -1427,9 +1475,7 @@ rtinit1(struct ifaddr *ifa, int cmd, int
* Now go through all the requested tables (fibs) and do the
* requested action. Realistically, this will either be fib 0
* for protocols that don't do multiple tables or all the
- * tables for those that do. XXX For this version only AF_INET.
- * When that changes code should be refactored to protocol
- * independent parts and protocol dependent parts.
+ * tables for those that do.
*/
for ( fibnum = startfib; fibnum <= endfib; fibnum++) {
if (cmd == RTM_DELETE) {
@@ -1569,12 +1615,14 @@ rtinit1(struct ifaddr *ifa, int cmd, int
return (error);
}
+#ifndef BURN_BRIDGES
/* special one for inet internal use. may not use. */
int
rtinit_fib(struct ifaddr *ifa, int cmd, int flags)
{
return (rtinit1(ifa, cmd, flags, -1));
}
+#endif
/*
* Set up a routing table entry, normally
@@ -1584,7 +1632,7 @@ int
rtinit(struct ifaddr *ifa, int cmd, int flags)
{
struct sockaddr *dst;
- int fib = 0;
+ int fib = RT_DEFAULT_FIB;
if (flags & RTF_HOST) {
dst = ifa->ifa_dstaddr;
@@ -1592,7 +1640,12 @@ rtinit(struct ifaddr *ifa, int cmd, int
dst = ifa->ifa_addr;
}
- if (dst->sa_family == AF_INET)
+ switch (dst->sa_family) {
+ case AF_INET6:
+ case AF_INET:
+ /* We do support multiple FIBs. */
fib = -1;
+ break;
+ }
return (rtinit1(ifa, cmd, flags, fib));
}
Modified: projects/multi-fibv6/8/sys/net/route.h
==============================================================================
--- projects/multi-fibv6/8/sys/net/route.h Wed Feb 15 06:45:49 2012 (r231743)
+++ projects/multi-fibv6/8/sys/net/route.h Wed Feb 15 06:49:50 2012 (r231744)
@@ -107,6 +107,7 @@ struct rt_metrics {
#endif
#endif
+#define RT_DEFAULT_FIB 0 /* Explicitly mark fib=0 restricted cases */
extern u_int rt_numfibs; /* number fo usable routing tables */
/*
* XXX kernel function pointer `rt_output' is visible to applications.
@@ -401,8 +402,10 @@ void rtredirect(struct sockaddr *, stru
int rtrequest(int, struct sockaddr *,
struct sockaddr *, struct sockaddr *, int, struct rtentry **);
+#ifndef BURN_BRIDGES
/* defaults to "all" FIBs */
int rtinit_fib(struct ifaddr *, int, int);
+#endif
/* XXX MRT NEW VERSIONS THAT USE FIBs
* For now the protocol indepedent versions are the same as the AF_INET ones
Modified: projects/multi-fibv6/8/sys/netinet/in.c
==============================================================================
--- projects/multi-fibv6/8/sys/netinet/in.c Wed Feb 15 06:45:49 2012 (r231743)
+++ projects/multi-fibv6/8/sys/netinet/in.c Wed Feb 15 06:49:50 2012 (r231744)
@@ -957,7 +957,7 @@ in_ifinit(struct ifnet *ifp, struct in_i
bzero(&ia_ro, sizeof(ia_ro));
*((struct sockaddr_in *)(&ia_ro.ro_dst)) = ia->ia_addr;
- rtalloc_ign_fib(&ia_ro, 0, 0);
+ rtalloc_ign_fib(&ia_ro, 0, RT_DEFAULT_FIB);
if ((ia_ro.ro_rt != NULL) && (ia_ro.ro_rt->rt_ifp != NULL) &&
(ia_ro.ro_rt->rt_ifp == V_loif)) {
RT_LOCK(ia_ro.ro_rt);
Modified: projects/multi-fibv6/8/sys/netinet/ipfw/ip_fw2.c
==============================================================================
--- projects/multi-fibv6/8/sys/netinet/ipfw/ip_fw2.c Wed Feb 15 06:45:49 2012 (r231743)
+++ projects/multi-fibv6/8/sys/netinet/ipfw/ip_fw2.c Wed Feb 15 06:49:50 2012 (r231744)
@@ -494,7 +494,7 @@ search_ip6_addr_net (struct in6_addr * i
}
static int
-verify_path6(struct in6_addr *src, struct ifnet *ifp)
+verify_path6(struct in6_addr *src, struct ifnet *ifp, u_int fib)
{
struct route_in6 ro;
struct sockaddr_in6 *dst;
@@ -505,9 +505,8 @@ verify_path6(struct in6_addr *src, struc
dst->sin6_family = AF_INET6;
dst->sin6_len = sizeof(*dst);
dst->sin6_addr = *src;
- /* XXX MRT 0 for ipv6 at this time */
- rtalloc_ign((struct route *)&ro, 0);
+ in6_rtalloc_ign(&ro, 0, fib);
if (ro.ro_rt == NULL)
return 0;
@@ -1682,7 +1681,7 @@ do { \
#ifdef INET6
is_ipv6 ?
verify_path6(&(args->f_id.src_ip6),
- m->m_pkthdr.rcvif) :
+ m->m_pkthdr.rcvif, args->f_id.fib) :
#endif
verify_path(src_ip, m->m_pkthdr.rcvif,
args->f_id.fib)));
@@ -1694,7 +1693,7 @@ do { \
#ifdef INET6
is_ipv6 ?
verify_path6(&(args->f_id.src_ip6),
- NULL) :
+ NULL, args->f_id.fib) :
#endif
verify_path(src_ip, NULL, args->f_id.fib)));
break;
@@ -1712,7 +1711,8 @@ do { \
#ifdef INET6
is_ipv6 ? verify_path6(
&(args->f_id.src_ip6),
- m->m_pkthdr.rcvif) :
+ m->m_pkthdr.rcvif,
+ args->f_id.fib) :
#endif
verify_path(src_ip,
m->m_pkthdr.rcvif,
Modified: projects/multi-fibv6/8/sys/netinet/sctp_os_bsd.h
==============================================================================
--- projects/multi-fibv6/8/sys/netinet/sctp_os_bsd.h Wed Feb 15 06:45:49 2012 (r231743)
+++ projects/multi-fibv6/8/sys/netinet/sctp_os_bsd.h Wed Feb 15 06:49:50 2012 (r231744)
@@ -424,6 +424,12 @@ typedef struct callout sctp_os_timer_t;
typedef struct route sctp_route_t;
typedef struct rtentry sctp_rtentry_t;
+/*
+ * XXX multi-FIB support was backed out in r179783 and it seems clear that the
+ * VRF support as currently in FreeBSD is not ready to support multi-FIB.
+ * It might be best to implement multi-FIB support for both v4 and v6 indepedent
+ * of VRFs and leave those to a real MPLS stack.
+ */
#define SCTP_RTALLOC(ro, vrf_id) rtalloc_ign((struct route *)ro, 0UL)
/* Future zero copy wakeup/send function */
Modified: projects/multi-fibv6/8/sys/netinet/tcp_subr.c
==============================================================================
--- projects/multi-fibv6/8/sys/netinet/tcp_subr.c Wed Feb 15 06:45:49 2012 (r231743)
+++ projects/multi-fibv6/8/sys/netinet/tcp_subr.c Wed Feb 15 06:49:50 2012 (r231744)
@@ -1801,7 +1801,7 @@ tcp_maxmtu6(struct in_conninfo *inc, int
sro6.ro_dst.sin6_family = AF_INET6;
sro6.ro_dst.sin6_len = sizeof(struct sockaddr_in6);
sro6.ro_dst.sin6_addr = inc->inc6_faddr;
- rtalloc_ign((struct route *)&sro6, 0);
+ in6_rtalloc_ign(&sro6, 0, inc->inc_fibnum);
}
if (sro6.ro_rt != NULL) {
ifp = sro6.ro_rt->rt_ifp;
Modified: projects/multi-fibv6/8/sys/netinet6/icmp6.c
==============================================================================
--- projects/multi-fibv6/8/sys/netinet6/icmp6.c Wed Feb 15 06:45:49 2012 (r231743)
+++ projects/multi-fibv6/8/sys/netinet6/icmp6.c Wed Feb 15 06:49:50 2012 (r231744)
@@ -359,7 +359,7 @@ icmp6_error(struct mbuf *m, int type, in
m_adj(m, ICMPV6_PLD_MAXLEN - m->m_pkthdr.len);
preplen = sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr);
- M_PREPEND(m, preplen, M_DONTWAIT);
+ M_PREPEND(m, preplen, M_DONTWAIT); /* FIB is also copied over. */
if (m && m->m_len < preplen)
m = m_pullup(m, preplen);
if (m == NULL) {
@@ -581,7 +581,7 @@ icmp6_input(struct mbuf **mp, int *offp,
MGETHDR(n, M_DONTWAIT, n0->m_type);
n0len = n0->m_pkthdr.len; /* save for use below */
if (n)
- M_MOVE_PKTHDR(n, n0);
+ M_MOVE_PKTHDR(n, n0); /* FIB copied. */
if (n && maxlen >= MHLEN) {
MCLGET(n, M_DONTWAIT);
if ((n->m_flags & M_EXT) == 0) {
@@ -1419,7 +1419,7 @@ ni6_input(struct mbuf *m, int off)
m_freem(m);
return (NULL);
}
- M_MOVE_PKTHDR(n, m); /* just for recvif */
+ M_MOVE_PKTHDR(n, m); /* just for recvif and FIB */
if (replylen > MHLEN) {
if (replylen > MCLBYTES) {
/*
@@ -2332,7 +2332,7 @@ icmp6_redirect_input(struct mbuf *m, int
sin6.sin6_family = AF_INET6;
sin6.sin6_len = sizeof(struct sockaddr_in6);
bcopy(&reddst6, &sin6.sin6_addr, sizeof(reddst6));
- rt = rtalloc1((struct sockaddr *)&sin6, 0, 0UL);
+ rt = in6_rtalloc1((struct sockaddr *)&sin6, 0, 0UL, RT_DEFAULT_FIB);
if (rt) {
if (rt->rt_gateway == NULL ||
rt->rt_gateway->sa_family != AF_INET6) {
@@ -2421,6 +2421,7 @@ icmp6_redirect_input(struct mbuf *m, int
struct sockaddr_in6 sdst;
struct sockaddr_in6 sgw;
struct sockaddr_in6 ssrc;
+ u_int fibnum;
bzero(&sdst, sizeof(sdst));
bzero(&sgw, sizeof(sgw));
@@ -2431,9 +2432,11 @@ icmp6_redirect_input(struct mbuf *m, int
bcopy(&redtgt6, &sgw.sin6_addr, sizeof(struct in6_addr));
bcopy(&reddst6, &sdst.sin6_addr, sizeof(struct in6_addr));
bcopy(&src6, &ssrc.sin6_addr, sizeof(struct in6_addr));
- rtredirect((struct sockaddr *)&sdst, (struct sockaddr *)&sgw,
- (struct sockaddr *)NULL, RTF_GATEWAY | RTF_HOST,
- (struct sockaddr *)&ssrc);
+ for (fibnum = 0; fibnum < rt_numfibs; fibnum++)
+ in6_rtredirect((struct sockaddr *)&sdst,
+ (struct sockaddr *)&sgw, (struct sockaddr *)NULL,
+ RTF_GATEWAY | RTF_HOST, (struct sockaddr *)&ssrc,
+ fibnum);
}
/* finally update cached route in each socket via pfctlinput */
{
@@ -2517,6 +2520,7 @@ icmp6_redirect_output(struct mbuf *m0, s
MCLGET(m, M_DONTWAIT);
if (!m)
goto fail;
+ M_SETFIB(m, rt->rt_fibnum);
m->m_pkthdr.rcvif = NULL;
m->m_len = 0;
maxlen = M_TRAILINGSPACE(m);
Modified: projects/multi-fibv6/8/sys/netinet6/in6.c
==============================================================================
--- projects/multi-fibv6/8/sys/netinet6/in6.c Wed Feb 15 06:45:49 2012 (r231743)
+++ projects/multi-fibv6/8/sys/netinet6/in6.c Wed Feb 15 06:49:50 2012 (r231744)
@@ -198,6 +198,11 @@ in6_control(struct socket *so, u_long cm
switch (cmd) {
case SIOCGETSGCNT_IN6:
case SIOCGETMIFCNT_IN6:
+ /*
+ * XXX mrt_ioctl has a 3rd, unused, FIB argument in route.c.
+ * We cannot see how that would be needed, so do not adjust the
+ * KPI blindly; more likely should clean up the IPv4 variant.
+ */
return (mrt6_ioctl ? mrt6_ioctl(cmd, data) : EOPNOTSUPP);
}
@@ -696,6 +701,169 @@ out:
}
/*
+ * Join necessary multicast groups. Factored out from in6_update_ifa().
+ * This entire work should only be done once, for the default FIB.
+ */
+static int
+in6_update_ifa_join_mc(struct ifnet *ifp, struct in6_aliasreq *ifra,
+ struct in6_ifaddr *ia, int flags, struct in6_multi **in6m_sol)
+{
+ char ip6buf[INET6_ADDRSTRLEN];
+ struct sockaddr_in6 mltaddr, mltmask;
+ struct in6_addr llsol;
+ struct in6_multi_mship *imm;
+ struct rtentry *rt;
+ int delay, error;
+
+ KASSERT(in6m_sol != NULL, ("%s: in6m_sol is NULL", __func__));
+
+ /* Join solicited multicast addr for new host id. */
+ bzero(&llsol, sizeof(struct in6_addr));
+ llsol.s6_addr32[0] = IPV6_ADDR_INT32_MLL;
+ llsol.s6_addr32[1] = 0;
+ llsol.s6_addr32[2] = htonl(1);
+ llsol.s6_addr32[3] = ifra->ifra_addr.sin6_addr.s6_addr32[3];
+ llsol.s6_addr8[12] = 0xff;
+ if ((error = in6_setscope(&llsol, ifp, NULL)) != 0) {
+ /* XXX: should not happen */
+ log(LOG_ERR, "%s: in6_setscope failed\n", __func__);
+ goto cleanup;
+ }
+ delay = 0;
+ if ((flags & IN6_IFAUPDATE_DADDELAY)) {
+ /*
+ * We need a random delay for DAD on the address being
+ * configured. It also means delaying transmission of the
+ * corresponding MLD report to avoid report collision.
+ * [RFC 4861, Section 6.3.7]
+ */
+ delay = arc4random() % (MAX_RTR_SOLICITATION_DELAY * hz);
+ }
+ imm = in6_joingroup(ifp, &llsol, &error, delay);
+ if (imm == NULL) {
+ nd6log((LOG_WARNING, "%s: addmulti failed for %s on %s "
+ "(errno=%d)\n", __func__, ip6_sprintf(ip6buf, &llsol),
+ if_name(ifp), error));
+ goto cleanup;
+ }
+ LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
+ *in6m_sol = imm->i6mm_maddr;
+
+ bzero(&mltmask, sizeof(mltmask));
+ mltmask.sin6_len = sizeof(struct sockaddr_in6);
+ mltmask.sin6_family = AF_INET6;
+ mltmask.sin6_addr = in6mask32;
+#define MLTMASK_LEN 4 /* mltmask's masklen (=32bit=4octet) */
+
+ /*
+ * Join link-local all-nodes address.
+ */
+ bzero(&mltaddr, sizeof(mltaddr));
+ mltaddr.sin6_len = sizeof(struct sockaddr_in6);
+ mltaddr.sin6_family = AF_INET6;
+ mltaddr.sin6_addr = in6addr_linklocal_allnodes;
+ if ((error = in6_setscope(&mltaddr.sin6_addr, ifp, NULL)) != 0)
+ goto cleanup; /* XXX: should not fail */
+
+ /*
+ * XXX: do we really need this automatic routes? We should probably
+ * reconsider this stuff. Most applications actually do not need the
+ * routes, since they usually specify the outgoing interface.
+ */
+ rt = in6_rtalloc1((struct sockaddr *)&mltaddr, 0, 0UL, RT_DEFAULT_FIB);
+ if (rt != NULL) {
+ /* XXX: only works in !SCOPEDROUTING case. */
+ if (memcmp(&mltaddr.sin6_addr,
+ &((struct sockaddr_in6 *)rt_key(rt))->sin6_addr,
+ MLTMASK_LEN)) {
+ RTFREE_LOCKED(rt);
+ rt = NULL;
+ }
+ }
+ if (rt == NULL) {
+ error = in6_rtrequest(RTM_ADD, (struct sockaddr *)&mltaddr,
+ (struct sockaddr *)&ia->ia_addr,
+ (struct sockaddr *)&mltmask, RTF_UP,
+ (struct rtentry **)0, RT_DEFAULT_FIB);
+ if (error)
+ goto cleanup;
+ } else
+ RTFREE_LOCKED(rt);
+
+ imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error, 0);
+ if (imm == NULL) {
+ nd6log((LOG_WARNING, "%s: addmulti failed for %s on %s "
+ "(errno=%d)\n", __func__, ip6_sprintf(ip6buf,
+ &mltaddr.sin6_addr), if_name(ifp), error));
+ goto cleanup;
+ }
+ LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
+
+ /*
+ * Join node information group address.
+ */
+ delay = 0;
+ if ((flags & IN6_IFAUPDATE_DADDELAY)) {
+ /*
+ * The spec does not say anything about delay for this group,
+ * but the same logic should apply.
+ */
+ delay = arc4random() % (MAX_RTR_SOLICITATION_DELAY * hz);
+ }
+ if (in6_nigroup(ifp, NULL, -1, &mltaddr.sin6_addr) == 0) {
+ /* XXX jinmei */
+ imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error, delay);
+ if (imm == NULL)
+ nd6log((LOG_WARNING, "%s: addmulti failed for %s on %s "
+ "(errno=%d)\n", __func__, ip6_sprintf(ip6buf,
+ &mltaddr.sin6_addr), if_name(ifp), error));
+ /* XXX not very fatal, go on... */
+ else
+ LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
+ }
+
+ /*
+ * Join interface-local all-nodes address.
+ * (ff01::1%ifN, and ff01::%ifN/32)
+ */
+ mltaddr.sin6_addr = in6addr_nodelocal_allnodes;
+ if ((error = in6_setscope(&mltaddr.sin6_addr, ifp, NULL)) != 0)
+ goto cleanup; /* XXX: should not fail */
+ /* XXX: again, do we really need the route? */
+ rt = in6_rtalloc1((struct sockaddr *)&mltaddr, 0, 0UL, RT_DEFAULT_FIB);
+ if (rt != NULL) {
+ if (memcmp(&mltaddr.sin6_addr,
+ &((struct sockaddr_in6 *)rt_key(rt))->sin6_addr,
+ MLTMASK_LEN)) {
+ RTFREE_LOCKED(rt);
+ rt = NULL;
+ }
+ }
+ if (rt == NULL) {
+ error = in6_rtrequest(RTM_ADD, (struct sockaddr *)&mltaddr,
+ (struct sockaddr *)&ia->ia_addr,
+ (struct sockaddr *)&mltmask, RTF_UP,
+ (struct rtentry **)0, RT_DEFAULT_FIB);
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-projects
mailing list