Author: tuexen Date: Tue Jun 12 13:57:56 2012 New Revision: 236958 URL: http://svn.freebsd.org/changeset/base/236958
Log: Deliver IPV6_TCLASS, IPV6_HOPLIMIT and IPV6_PKTINFO cmsgs (if requested) on IPV6 sockets, which have been marked to be not IPV6_V6ONLY, for each received IPV4 packet. MFC after: 3 days Modified: head/sys/netinet6/ip6_input.c Modified: head/sys/netinet6/ip6_input.c ============================================================================== --- head/sys/netinet6/ip6_input.c Tue Jun 12 13:31:32 2012 (r236957) +++ head/sys/netinet6/ip6_input.c Tue Jun 12 13:57:56 2012 (r236958) @@ -1321,19 +1321,28 @@ ip6_savecontrol_v4(struct inpcb *inp, st } #endif - if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) { - if (v4only != NULL) - *v4only = 1; - return (mp); - } - #define IS2292(inp, x, y) (((inp)->inp_flags & IN6P_RFC2292) ? (x) : (y)) /* RFC 2292 sec. 5 */ if ((inp->inp_flags & IN6P_PKTINFO) != 0) { struct in6_pktinfo pi6; - bcopy(&ip6->ip6_dst, &pi6.ipi6_addr, sizeof(struct in6_addr)); - in6_clearscope(&pi6.ipi6_addr); /* XXX */ + if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) { +#ifdef INET + struct ip *ip; + + ip = mtod(m, struct ip *); + pi6.ipi6_addr.s6_addr32[0] = 0; + pi6.ipi6_addr.s6_addr32[1] = 0; + pi6.ipi6_addr.s6_addr32[2] = IPV6_ADDR_INT32_SMP; + pi6.ipi6_addr.s6_addr32[3] = ip->ip_dst.s_addr; +#else + /* We won't hit this code */ + bzero(&pi6.ipi6_addr, sizeof(struct in6_addr)); +#endif + } else { + bcopy(&ip6->ip6_dst, &pi6.ipi6_addr, sizeof(struct in6_addr)); + in6_clearscope(&pi6.ipi6_addr); /* XXX */ + } pi6.ipi6_ifindex = (m && m->m_pkthdr.rcvif) ? m->m_pkthdr.rcvif->if_index : 0; @@ -1345,8 +1354,21 @@ ip6_savecontrol_v4(struct inpcb *inp, st } if ((inp->inp_flags & IN6P_HOPLIMIT) != 0) { - int hlim = ip6->ip6_hlim & 0xff; + int hlim; + + if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) { +#ifdef INET + struct ip *ip; + ip = mtod(m, struct ip *); + hlim = ip->ip_ttl; +#else + /* We won't hit this code */ + hlim = 0; +#endif + } else { + hlim = ip6->ip6_hlim & 0xff; + } *mp = sbcreatecontrol((caddr_t) &hlim, sizeof(int), IS2292(inp, IPV6_2292HOPLIMIT, IPV6_HOPLIMIT), IPPROTO_IPV6); @@ -1354,8 +1376,40 @@ ip6_savecontrol_v4(struct inpcb *inp, st mp = &(*mp)->m_next; } - if (v4only != NULL) - *v4only = 0; + if ((inp->inp_flags & IN6P_TCLASS) != 0) { + int tclass; + + if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) { +#ifdef INET + struct ip *ip; + + ip = mtod(m, struct ip *); + tclass = ip->ip_tos; +#else + /* We won't hit this code */ + tclass = 0; +#endif + } else { + u_int32_t flowinfo; + + flowinfo = (u_int32_t)ntohl(ip6->ip6_flow & IPV6_FLOWINFO_MASK); + flowinfo >>= 20; + tclass = flowinfo & 0xff; + } + *mp = sbcreatecontrol((caddr_t) &tclass, sizeof(int), + IPV6_TCLASS, IPPROTO_IPV6); + if (*mp) + mp = &(*mp)->m_next; + } + + if (v4only != NULL) { + if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) { + *v4only = 1; + } else { + *v4only = 0; + } + } + return (mp); } @@ -1369,20 +1423,6 @@ ip6_savecontrol(struct inpcb *in6p, stru if (v4only) return; - if ((in6p->inp_flags & IN6P_TCLASS) != 0) { - u_int32_t flowinfo; - int tclass; - - flowinfo = (u_int32_t)ntohl(ip6->ip6_flow & IPV6_FLOWINFO_MASK); - flowinfo >>= 20; - - tclass = flowinfo & 0xff; - *mp = sbcreatecontrol((caddr_t) &tclass, sizeof(tclass), - IPV6_TCLASS, IPPROTO_IPV6); - if (*mp) - mp = &(*mp)->m_next; - } - /* * IPV6_HOPOPTS socket option. Recall that we required super-user * privilege for the option (see ip6_ctloutput), but it might be too _______________________________________________ svn-src-head@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"