Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F105714391
D24135.id69786.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D24135.id69786.diff
View Options
Index: sys/netinet/udp_usrreq.c
===================================================================
--- sys/netinet/udp_usrreq.c
+++ sys/netinet/udp_usrreq.c
@@ -162,7 +162,7 @@
#ifdef INET
static void udp_detach(struct socket *so);
static int udp_output(struct inpcb *, struct mbuf *, struct sockaddr *,
- struct mbuf *, struct thread *);
+ struct mbuf *, struct thread *, int);
#endif
static void
@@ -1082,9 +1082,65 @@
}
#ifdef INET
+#ifdef INET6
+/* The logic here is derived from ip6_setpktopt(). See comments there. */
static int
+udp_v4mapped_pktinfo(struct cmsghdr *cm, struct sockaddr_in * src,
+ struct inpcb *inp, int flags)
+{
+ struct ifnet *ifp;
+ struct in6_pktinfo *pktinfo;
+ struct in_addr ia;
+
+ if ((flags & PRUS_IPV6) == 0)
+ return (0);
+
+ if (cm->cmsg_level != IPPROTO_IPV6)
+ return (0);
+
+ if (cm->cmsg_type != IPV6_2292PKTINFO &&
+ cm->cmsg_type != IPV6_PKTINFO)
+ return (0);
+
+ if (cm->cmsg_len !=
+ CMSG_LEN(sizeof(struct in6_pktinfo)))
+ return (EINVAL);
+
+ pktinfo = (struct in6_pktinfo *)CMSG_DATA(cm);
+ if (!IN6_IS_ADDR_V4MAPPED(&pktinfo->ipi6_addr) &&
+ !IN6_IS_ADDR_UNSPECIFIED(&pktinfo->ipi6_addr))
+ return (EINVAL);
+
+ /* Validate the interface index if specified. */
+ if (pktinfo->ipi6_ifindex > V_if_index)
+ return (ENXIO);
+
+ ifp = NULL;
+ if (pktinfo->ipi6_ifindex) {
+ ifp = ifnet_byindex(pktinfo->ipi6_ifindex);
+ if (ifp == NULL)
+ return (ENXIO);
+ }
+ if (ifp != NULL && !IN6_IS_ADDR_UNSPECIFIED(&pktinfo->ipi6_addr)) {
+
+ ia.s_addr = pktinfo->ipi6_addr.s6_addr32[3];
+ if (in_ifhasaddr(ifp, ia) == 0)
+ return (EADDRNOTAVAIL);
+ }
+
+ bzero(src, sizeof(*src));
+ src->sin_family = AF_INET;
+ src->sin_len = sizeof(*src);
+ src->sin_port = inp->inp_lport;
+ src->sin_addr.s_addr = pktinfo->ipi6_addr.s6_addr32[3];
+
+ return (0);
+}
+#endif
+
+static int
udp_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr,
- struct mbuf *control, struct thread *td)
+ struct mbuf *control, struct thread *td, int flags)
{
struct udpiphdr *ui;
int len = m->m_pkthdr.len;
@@ -1148,6 +1204,11 @@
error = EINVAL;
break;
}
+#ifdef INET6
+ error = udp_v4mapped_pktinfo(cm, &src, inp, flags);
+ if (error != 0)
+ break;
+#endif
if (cm->cmsg_level != IPPROTO_IP)
continue;
@@ -1695,7 +1756,7 @@
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("udp_send: inp == NULL"));
- return (udp_output(inp, m, addr, control, td));
+ return (udp_output(inp, m, addr, control, td, flags));
}
#endif /* INET */
Index: sys/netinet6/udp6_usrreq.c
===================================================================
--- sys/netinet6/udp6_usrreq.c
+++ sys/netinet6/udp6_usrreq.c
@@ -784,7 +784,7 @@
in6_sin6_2_sin_in_sock((struct sockaddr *)sin6);
pru = inetsw[ip_protox[nxt]].pr_usrreqs;
/* addr will just be freed in sendit(). */
- return ((*pru->pru_send)(so, flags_arg, m,
+ return ((*pru->pru_send)(so, flags_arg | PRUS_IPV6, m,
(struct sockaddr *)sin6, control, td));
}
} else
Index: sys/sys/protosw.h
===================================================================
--- sys/sys/protosw.h
+++ sys/sys/protosw.h
@@ -210,6 +210,7 @@
#define PRUS_EOF 0x2
#define PRUS_MORETOCOME 0x4
#define PRUS_NOTREADY 0x8
+#define PRUS_IPV6 0x10
int (*pru_ready)(struct socket *so, struct mbuf *m, int count);
int (*pru_sense)(struct socket *so, struct stat *sb);
int (*pru_shutdown)(struct socket *so);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Dec 20, 2:41 PM (20 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15530983
Default Alt Text
D24135.id69786.diff (3 KB)
Attached To
Mode
D24135: IPV6_PKTINFO support for v4-mapped IPv6 sockets
Attached
Detach File
Event Timeline
Log In to Comment