Module Name: src Committed By: ozaki-r Date: Mon Nov 7 01:55:17 UTC 2016
Modified Files: src/sys/netinet6: ip6_output.c Log Message: Pull routing header handling out of ip6_output No functional change. To generate a diff of this commit: cvs rdiff -u -r1.176 -r1.177 src/sys/netinet6/ip6_output.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/netinet6/ip6_output.c diff -u src/sys/netinet6/ip6_output.c:1.176 src/sys/netinet6/ip6_output.c:1.177 --- src/sys/netinet6/ip6_output.c:1.176 Mon Nov 7 01:05:39 2016 +++ src/sys/netinet6/ip6_output.c Mon Nov 7 01:55:17 2016 @@ -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 *, s 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 */