On Sun, 12 Jun 2016 15:00:14 +0200
Vincent Gross <[email protected]> wrote:
Damn you autowrap ! get off my diff !
(thanks jca@ for spotting)
> This diff moves the cmsg handling code on top of udp_output(). I split
> the whole IP_SENDSRCADDR thung in two chunks so that it's easier to
> audit.
>
> ok ?
>
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index 2db5998..1feea11 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -906,6 +906,47 @@ udp_output(struct inpcb *inp, struct mbuf *m, struct mbuf
*addr,
goto release;
}
+ if (control) {
+ u_int clen;
+ struct cmsghdr *cm;
+ caddr_t cmsgs;
+
+ /*
+ * XXX: Currently, we assume all the optional information is
stored
+ * in a single mbuf.
+ */
+ if (control->m_next) {
+ error = EINVAL;
+ goto release;
+ }
+
+ clen = control->m_len;
+ cmsgs = mtod(control, caddr_t);
+ do {
+ if (clen < CMSG_LEN(0)) {
+ error = EINVAL;
+ goto release;
+ }
+ cm = (struct cmsghdr *)cmsgs;
+ if (cm->cmsg_len < CMSG_LEN(0) ||
+ CMSG_ALIGN(cm->cmsg_len) > clen) {
+ error = EINVAL;
+ goto release;
+ }
+#ifdef IPSEC
+ if (ISSET(inp->inp_flags,INP_IPSECFLOWINFO) &&
+ cm->cmsg_len == CMSG_LEN(sizeof(ipsecflowinfo)) &&
+ cm->cmsg_level == IPPROTO_IP &&
+ cm->cmsg_type == IP_IPSECFLOWINFO) {
+ ipsecflowinfo = *(u_int32_t *)CMSG_DATA(cm);
+ break;
+ }
+#endif
+ clen -= CMSG_ALIGN(cm->cmsg_len);
+ cmsgs += CMSG_ALIGN(cm->cmsg_len);
+ } while (clen);
+ }
+
if (addr) {
sin = mtod(addr, struct sockaddr_in *);
@@ -947,45 +988,6 @@ udp_output(struct inpcb *inp, struct mbuf *m, struct mbuf
*addr,
laddr = &inp->inp_laddr;
}
-#ifdef IPSEC
- if (control && (inp->inp_flags & INP_IPSECFLOWINFO) != 0) {
- u_int clen;
- struct cmsghdr *cm;
- caddr_t cmsgs;
-
- /*
- * XXX: Currently, we assume all the optional information is
stored
- * in a single mbuf.
- */
- if (control->m_next) {
- error = EINVAL;
- goto release;
- }
-
- clen = control->m_len;
- cmsgs = mtod(control, caddr_t);
- do {
- if (clen < CMSG_LEN(0)) {
- error = EINVAL;
- goto release;
- }
- cm = (struct cmsghdr *)cmsgs;
- if (cm->cmsg_len < CMSG_LEN(0) ||
- CMSG_ALIGN(cm->cmsg_len) > clen) {
- error = EINVAL;
- goto release;
- }
- if (cm->cmsg_len == CMSG_LEN(sizeof(ipsecflowinfo)) &&
- cm->cmsg_level == IPPROTO_IP &&
- cm->cmsg_type == IP_IPSECFLOWINFO) {
- ipsecflowinfo = *(u_int32_t *)CMSG_DATA(cm);
- break;
- }
- clen -= CMSG_ALIGN(cm->cmsg_len);
- cmsgs += CMSG_ALIGN(cm->cmsg_len);
- } while (clen);
- }
-#endif
/*
* Calculate data length and get a mbuf
* for UDP and IP headers.