Pull routing header handling out of ip6_output

No functional change.
This commit is contained in:
ozaki-r 2016-11-07 01:55:17 +00:00
parent 2ad0a3feca
commit 29a46075c0

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip6_output.c,v 1.176 2016/11/07 01:05:39 ozaki-r Exp $ */
/* $NetBSD: ip6_output.c,v 1.177 2016/11/07 01:55:17 ozaki-r Exp $ */
/* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */
/*
@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ip6_output.c,v 1.176 2016/11/07 01:05:39 ozaki-r Exp $");
__KERNEL_RCSID(0, "$NetBSD: ip6_output.c,v 1.177 2016/11/07 01:55:17 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@ -136,11 +136,50 @@ static int ip6_splithdr(struct mbuf *, struct ip6_exthdrs *);
static int ip6_getpmtu(struct rtentry *, struct ifnet *, u_long *, int *);
static int copypktopts(struct ip6_pktopts *, struct ip6_pktopts *, int);
static int ip6_ifaddrvalid(const struct in6_addr *);
static int ip6_handle_rthdr(struct ip6_rthdr *, struct ip6_hdr *);
#ifdef RFC2292
static int ip6_pcbopts(struct ip6_pktopts **, struct socket *, struct sockopt *);
#endif
static int
ip6_handle_rthdr(struct ip6_rthdr *rh, struct ip6_hdr *ip6)
{
struct ip6_rthdr0 *rh0;
struct in6_addr *addr;
struct sockaddr_in6 sa;
int error = 0;
switch (rh->ip6r_type) {
case IPV6_RTHDR_TYPE_0:
rh0 = (struct ip6_rthdr0 *)rh;
addr = (struct in6_addr *)(rh0 + 1);
/*
* construct a sockaddr_in6 form of the first hop.
*
* XXX we may not have enough information about its scope zone;
* there is no standard API to pass the information from the
* application.
*/
sockaddr_in6_init(&sa, addr, 0, 0, 0);
error = sa6_embedscope(&sa, ip6_use_defzone);
if (error != 0)
break;
(void)memmove(&addr[0], &addr[1],
sizeof(struct in6_addr) * (rh0->ip6r0_segleft - 1));
addr[rh0->ip6r0_segleft - 1] = ip6->ip6_dst;
ip6->ip6_dst = sa.sin6_addr;
/* XXX */
in6_clearscope(addr + rh0->ip6r0_segleft - 1);
break;
default: /* is it possible? */
error = EINVAL;
}
return error;
}
/*
* IP6 output. The packet in mbuf chain m contains a skeletal IP6
* header (with pri, len, nxt, hlim, src, dst).
@ -375,45 +414,14 @@ ip6_output(
*/
if (exthdrs.ip6e_rthdr) {
struct ip6_rthdr *rh;
struct ip6_rthdr0 *rh0;
struct in6_addr *addr;
struct sockaddr_in6 sa;
rh = (struct ip6_rthdr *)(mtod(exthdrs.ip6e_rthdr,
struct ip6_rthdr *));
finaldst = ip6->ip6_dst;
switch (rh->ip6r_type) {
case IPV6_RTHDR_TYPE_0:
rh0 = (struct ip6_rthdr0 *)rh;
addr = (struct in6_addr *)(rh0 + 1);
finaldst = ip6->ip6_dst; /* need to save for pmtu */
/*
* construct a sockaddr_in6 form of
* the first hop.
*
* XXX: we may not have enough
* information about its scope zone;
* there is no standard API to pass
* the information from the
* application.
*/
sockaddr_in6_init(&sa, addr, 0, 0, 0);
if ((error = sa6_embedscope(&sa,
ip6_use_defzone)) != 0) {
goto bad;
}
ip6->ip6_dst = sa.sin6_addr;
(void)memmove(&addr[0], &addr[1],
sizeof(struct in6_addr) *
(rh0->ip6r0_segleft - 1));
addr[rh0->ip6r0_segleft - 1] = finaldst;
/* XXX */
in6_clearscope(addr + rh0->ip6r0_segleft - 1);
break;
default: /* is it possible? */
error = EINVAL;
goto bad;
}
error = ip6_handle_rthdr(rh, ip6);
if (error != 0)
goto bad;
}
/* Source address validation */