gif(4): Revert in{,6}_gif_output() misalignment handling

The code added in c89c8a1029 in order
to compensate possible misalignment caused by prepending the IP4/6
header with an EtherIP one got broken at some point by a rewrite of
gif(4). For better or worse, 8018ac153f
relaxed the alignment of struct ip from 32 bit to 16 bit, though. As
a result, a 16 bit offset of the IPv4 header induced by the addition
of the 16 bit EtherIP one no longer is a problem in the first place.
The alignment of struct ip6_hdr currently is even only 8 bit, making
it even less problematic with regards to possible misalignment.
Thus, remove the code for handling misalignment in in{,6}_gif_output()
altogether again.
While at it, replace the 3 bcopy(9) calls in gif(4) with memcpy(9) as
there's no need to handle overlap here.
This commit is contained in:
Marius Strobl 2023-07-19 19:17:43 +02:00
parent bb255cee93
commit e82d7b2952
4 changed files with 5 additions and 37 deletions

View File

@ -408,7 +408,7 @@ gif_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
uint32_t af;
if (dst->sa_family == AF_UNSPEC)
bcopy(dst->sa_data, &af, sizeof(af));
memcpy(&af, dst->sa_data, sizeof(af));
else
af = RO_GET_FAMILY(ro, dst);
/*

View File

@ -94,8 +94,6 @@ struct etherip_header {
} __packed;
#define ETHERIP_VERSION 0x3
/* mbuf adjust factor to force 32-bit alignment of IP header */
#define ETHERIP_ALIGN 2
#define GIF_WAIT() epoch_wait_preempt(net_epoch_preempt)

View File

@ -276,31 +276,16 @@ in_gif_output(struct ifnet *ifp, struct mbuf *m, int proto, uint8_t ecn)
{
struct gif_softc *sc = ifp->if_softc;
struct ip *ip;
int len;
/* prepend new IP header */
NET_EPOCH_ASSERT();
len = sizeof(struct ip);
#ifndef __NO_STRICT_ALIGNMENT
if (proto == IPPROTO_ETHERIP)
len += ETHERIP_ALIGN;
#endif
M_PREPEND(m, len, M_NOWAIT);
M_PREPEND(m, sizeof(struct ip), M_NOWAIT);
if (m == NULL)
return (ENOBUFS);
#ifndef __NO_STRICT_ALIGNMENT
if (proto == IPPROTO_ETHERIP) {
len = mtod(m, vm_offset_t) & 3;
KASSERT(len == 0 || len == ETHERIP_ALIGN,
("in_gif_output: unexpected misalignment"));
m->m_data += len;
m->m_len -= ETHERIP_ALIGN;
}
#endif
ip = mtod(m, struct ip *);
MPASS(sc->gif_family == AF_INET);
bcopy(sc->gif_iphdr, ip, sizeof(struct ip));
memcpy(ip, sc->gif_iphdr, sizeof(struct ip));
ip->ip_p = proto;
/* version will be set in ip_output() */
ip->ip_ttl = V_ip_gif_ttl;

View File

@ -291,31 +291,16 @@ in6_gif_output(struct ifnet *ifp, struct mbuf *m, int proto, uint8_t ecn)
{
struct gif_softc *sc = ifp->if_softc;
struct ip6_hdr *ip6;
int len;
/* prepend new IP header */
NET_EPOCH_ASSERT();
len = sizeof(struct ip6_hdr);
#ifndef __NO_STRICT_ALIGNMENT
if (proto == IPPROTO_ETHERIP)
len += ETHERIP_ALIGN;
#endif
M_PREPEND(m, len, M_NOWAIT);
M_PREPEND(m, sizeof(struct ip6_hdr), M_NOWAIT);
if (m == NULL)
return (ENOBUFS);
#ifndef __NO_STRICT_ALIGNMENT
if (proto == IPPROTO_ETHERIP) {
len = mtod(m, vm_offset_t) & 3;
KASSERT(len == 0 || len == ETHERIP_ALIGN,
("in6_gif_output: unexpected misalignment"));
m->m_data += len;
m->m_len -= ETHERIP_ALIGN;
}
#endif
ip6 = mtod(m, struct ip6_hdr *);
MPASS(sc->gif_family == AF_INET6);
bcopy(sc->gif_ip6hdr, ip6, sizeof(struct ip6_hdr));
memcpy(ip6, sc->gif_ip6hdr, sizeof(struct ip6_hdr));
ip6->ip6_flow |= htonl((uint32_t)ecn << 20);
ip6->ip6_nxt = proto;