From 4daa6442fe6ff3558b2dfb9abc82494a61553bc0 Mon Sep 17 00:00:00 2001 From: bluhm Date: Fri, 12 Aug 2022 17:04:16 +0000 Subject: [PATCH] Remove differences between ip_fragment() and ip6_fragment(). They do nearly the same thing, so they should look similar. OK sashan@ --- sys/netinet/ip_output.c | 56 ++++++++++++++++++++++----------------- sys/netinet6/ip6_output.c | 43 +++++++++++++++++------------- 2 files changed, 55 insertions(+), 44 deletions(-) diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index fa4d5bafa4c..b0c6ed720f6 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_output.c,v 1.381 2022/05/25 19:48:46 mvs Exp $ */ +/* $OpenBSD: ip_output.c,v 1.382 2022/08/12 17:04:16 bluhm Exp $ */ /* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */ /* @@ -677,73 +677,78 @@ ip_output_ipsec_send(struct tdb *tdb, struct mbuf *m, struct route *ro, int fwd) #endif /* IPSEC */ int -ip_fragment(struct mbuf *m, struct mbuf_list *fml, struct ifnet *ifp, +ip_fragment(struct mbuf *m0, struct mbuf_list *fml, struct ifnet *ifp, u_long mtu) { - struct ip *ip, *mhip; - struct mbuf *m0; - int len, hlen, off; - int mhlen, firstlen; + struct mbuf *m; + struct ip *ip; + int firstlen, hlen, tlen, len, off; int error; ml_init(fml); - ml_enqueue(fml, m); + ml_enqueue(fml, m0); - ip = mtod(m, struct ip *); + ip = mtod(m0, struct ip *); hlen = ip->ip_hl << 2; + tlen = m0->m_pkthdr.len; len = (mtu - hlen) &~ 7; if (len < 8) { error = EMSGSIZE; goto bad; } + firstlen = len; /* * If we are doing fragmentation, we can't defer TCP/UDP * checksumming; compute the checksum and clear the flag. */ - in_proto_cksum_out(m, NULL); - firstlen = len; + in_proto_cksum_out(m0, NULL); /* * Loop through length of segment after first fragment, * make new header and copy data of each part and link onto chain. */ - m0 = m; - mhlen = sizeof (struct ip); - for (off = hlen + len; off < ntohs(ip->ip_len); off += len) { + for (off = hlen + firstlen; off < tlen; off += len) { + struct ip *mhip; + int mhlen; + MGETHDR(m, M_DONTWAIT, MT_HEADER); if (m == NULL) { error = ENOBUFS; goto bad; } ml_enqueue(fml, m); + if ((error = m_dup_pkthdr(m, m0, M_DONTWAIT)) != 0) goto bad; m->m_data += max_linkhdr; mhip = mtod(m, struct ip *); *mhip = *ip; - if (hlen > sizeof (struct ip)) { - mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip); + if (hlen > sizeof(struct ip)) { + mhlen = ip_optcopy(ip, mhip) + sizeof(struct ip); mhip->ip_hl = mhlen >> 2; - } + } else + mhlen = sizeof(struct ip); m->m_len = mhlen; + mhip->ip_off = ((off - hlen) >> 3) + (ntohs(ip->ip_off) & ~IP_MF); if (ip->ip_off & htons(IP_MF)) mhip->ip_off |= IP_MF; - if (off + len >= ntohs(ip->ip_len)) - len = ntohs(ip->ip_len) - off; + if (off + len >= tlen) + len = tlen - off; else mhip->ip_off |= IP_MF; - mhip->ip_len = htons((u_int16_t)(len + mhlen)); + mhip->ip_off = htons(mhip->ip_off); + + m->m_pkthdr.len = mhlen + len; + mhip->ip_len = htons(m->m_pkthdr.len); m->m_next = m_copym(m0, off, len, M_NOWAIT); if (m->m_next == NULL) { error = ENOBUFS; goto bad; } - m->m_pkthdr.len = mhlen + len; - m->m_pkthdr.ph_ifidx = 0; - mhip->ip_off = htons((u_int16_t)mhip->ip_off); + mhip->ip_sum = 0; if (in_ifcap_cksum(m, ifp, IFCAP_CSUM_IPv4)) m->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT; @@ -752,15 +757,16 @@ ip_fragment(struct mbuf *m, struct mbuf_list *fml, struct ifnet *ifp, mhip->ip_sum = in_cksum(m, mhlen); } } + /* * Update first fragment by trimming what's been copied out * and updating header, then send each fragment (in order). */ m = m0; - m_adj(m, hlen + firstlen - ntohs(ip->ip_len)); - m->m_pkthdr.len = hlen + firstlen; - ip->ip_len = htons((u_int16_t)m->m_pkthdr.len); + m_adj(m, hlen + firstlen - tlen); ip->ip_off |= htons(IP_MF); + ip->ip_len = htons(m->m_pkthdr.len); + ip->ip_sum = 0; if (in_ifcap_cksum(m, ifp, IFCAP_CSUM_IPv4)) m->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT; diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index 355aa3edc4a..81d8f592ab3 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_output.c,v 1.270 2022/08/08 23:00:51 bluhm Exp $ */ +/* $OpenBSD: ip6_output.c,v 1.271 2022/08/12 17:04:17 bluhm Exp $ */ /* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */ /* @@ -793,30 +793,31 @@ int ip6_fragment(struct mbuf *m0, struct mbuf_list *fml, int hlen, u_char nextproto, u_long mtu) { - struct mbuf *m, *m_frgpart; - struct ip6_hdr *mhip6; - struct ip6_frag *ip6f; - u_int32_t id; - int tlen, len, off; - int error; + struct mbuf *m; + struct ip6_hdr *ip6; + u_int32_t id; + int tlen, len, off; + int error; ml_init(fml); + ip6 = mtod(m0, struct ip6_hdr *); tlen = m0->m_pkthdr.len; len = (mtu - hlen - sizeof(struct ip6_frag)) & ~7; if (len < 8) { error = EMSGSIZE; goto bad; } - id = htonl(ip6_randomid()); /* - * Loop through length of segment after first fragment, + * Loop through length of segment, * make new header and copy data of each part and link onto chain. */ for (off = hlen; off < tlen; off += len) { struct mbuf *mlast; + struct ip6_hdr *mhip6; + struct ip6_frag *ip6f; MGETHDR(m, M_DONTWAIT, MT_HEADER); if (m == NULL) { @@ -824,29 +825,33 @@ ip6_fragment(struct mbuf *m0, struct mbuf_list *fml, int hlen, goto bad; } ml_enqueue(fml, m); + if ((error = m_dup_pkthdr(m, m0, M_DONTWAIT)) != 0) goto bad; m->m_data += max_linkhdr; mhip6 = mtod(m, struct ip6_hdr *); - *mhip6 = *mtod(m0, struct ip6_hdr *); - m->m_len = sizeof(*mhip6); + *mhip6 = *ip6; + m->m_len = sizeof(struct ip6_hdr); + if ((error = ip6_insertfraghdr(m0, m, hlen, &ip6f)) != 0) goto bad; - ip6f->ip6f_offlg = htons((u_int16_t)((off - hlen) & ~7)); + ip6f->ip6f_offlg = htons((off - hlen) & ~7); if (off + len >= tlen) len = tlen - off; else ip6f->ip6f_offlg |= IP6F_MORE_FRAG; - mhip6->ip6_plen = htons((u_int16_t)(len + hlen + - sizeof(*ip6f) - sizeof(struct ip6_hdr))); - if ((m_frgpart = m_copym(m0, off, len, M_DONTWAIT)) == NULL) { + + m->m_pkthdr.len = hlen + sizeof(struct ip6_frag) + len; + mhip6->ip6_plen = htons(m->m_pkthdr.len - + sizeof(struct ip6_hdr)); + for (mlast = m; mlast->m_next; mlast = mlast->m_next) + ; + mlast->m_next = m_copym(m0, off, len, M_DONTWAIT); + if (mlast->m_next == NULL) { error = ENOBUFS; goto bad; } - for (mlast = m; mlast->m_next; mlast = mlast->m_next) - ; - mlast->m_next = m_frgpart; - m->m_pkthdr.len = len + hlen + sizeof(*ip6f); + ip6f->ip6f_reserved = 0; ip6f->ip6f_ident = id; ip6f->ip6f_nxt = nextproto; -- 2.20.1