On architectures with strict alignment requirements compensate
the misalignment of the IP header that prepending the EtherIP header might have caused. PR: 131921 MFC after: 1 week
This commit is contained in:
parent
5f1286689c
commit
c89c8a1029
@ -100,6 +100,8 @@ struct etherip_header {
|
||||
#define ETHERIP_VER_VERS_MASK 0x0f
|
||||
#define ETHERIP_VER_RSVD_MASK 0xf0
|
||||
#define ETHERIP_VERSION 0x03
|
||||
/* mbuf adjust factor to force 32-bit alignment of IP header */
|
||||
#define ETHERIP_ALIGN 2
|
||||
|
||||
/* Prototypes */
|
||||
void gif_input(struct mbuf *, int, struct ifnet *);
|
||||
|
@ -102,7 +102,7 @@ in_gif_output(struct ifnet *ifp, int family, struct mbuf *m)
|
||||
struct sockaddr_in *sin_dst = (struct sockaddr_in *)sc->gif_pdst;
|
||||
struct ip iphdr; /* capsule IP header, host byte ordered */
|
||||
struct etherip_header eiphdr;
|
||||
int proto, error;
|
||||
int error, len, proto;
|
||||
u_int8_t tos;
|
||||
|
||||
GIF_LOCK_ASSERT(sc);
|
||||
@ -186,13 +186,27 @@ in_gif_output(struct ifnet *ifp, int family, struct mbuf *m)
|
||||
&iphdr.ip_tos, &tos);
|
||||
|
||||
/* prepend new IP header */
|
||||
M_PREPEND(m, sizeof(struct ip), M_DONTWAIT);
|
||||
if (m && m->m_len < sizeof(struct ip))
|
||||
m = m_pullup(m, sizeof(struct ip));
|
||||
len = sizeof(struct ip);
|
||||
#ifndef __NO_STRICT_ALIGNMENT
|
||||
if (family == AF_LINK)
|
||||
len += ETHERIP_ALIGN;
|
||||
#endif
|
||||
M_PREPEND(m, len, M_DONTWAIT);
|
||||
if (m != NULL && m->m_len < len)
|
||||
m = m_pullup(m, len);
|
||||
if (m == NULL) {
|
||||
printf("ENOBUFS in in_gif_output %d\n", __LINE__);
|
||||
return ENOBUFS;
|
||||
}
|
||||
#ifndef __NO_STRICT_ALIGNMENT
|
||||
if (family == AF_LINK) {
|
||||
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
|
||||
bcopy(&iphdr, mtod(m, struct ip *), sizeof(struct ip));
|
||||
|
||||
M_SETFIB(m, sc->gif_fibnum);
|
||||
|
@ -98,7 +98,7 @@ in6_gif_output(struct ifnet *ifp,
|
||||
struct sockaddr_in6 *sin6_dst = (struct sockaddr_in6 *)sc->gif_pdst;
|
||||
struct ip6_hdr *ip6;
|
||||
struct etherip_header eiphdr;
|
||||
int proto, error;
|
||||
int error, len, proto;
|
||||
u_int8_t itos, otos;
|
||||
|
||||
GIF_LOCK_ASSERT(sc);
|
||||
@ -166,13 +166,27 @@ in6_gif_output(struct ifnet *ifp,
|
||||
}
|
||||
|
||||
/* prepend new IP header */
|
||||
M_PREPEND(m, sizeof(struct ip6_hdr), M_DONTWAIT);
|
||||
if (m && m->m_len < sizeof(struct ip6_hdr))
|
||||
m = m_pullup(m, sizeof(struct ip6_hdr));
|
||||
len = sizeof(struct ip6_hdr);
|
||||
#ifndef __NO_STRICT_ALIGNMENT
|
||||
if (family == AF_LINK)
|
||||
len += ETHERIP_ALIGN;
|
||||
#endif
|
||||
M_PREPEND(m, len, M_DONTWAIT);
|
||||
if (m != NULL && m->m_len < len)
|
||||
m = m_pullup(m, len);
|
||||
if (m == NULL) {
|
||||
printf("ENOBUFS in in6_gif_output %d\n", __LINE__);
|
||||
return ENOBUFS;
|
||||
}
|
||||
#ifndef __NO_STRICT_ALIGNMENT
|
||||
if (family == AF_LINK) {
|
||||
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 *);
|
||||
ip6->ip6_flow = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user