Pull routing header handling out of ip6_output
No functional change.
This commit is contained in:
parent
2ad0a3feca
commit
29a46075c0
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user