On Sat, 24 Sep 2016 16:45:09 -0400 (EDT)
Martin Brandenburg <[email protected]> wrote:
> On Sun, 25 Sep 2016, YASUOKA Masahiko wrote:
> 
>> On Sat, 24 Sep 2016 13:08:18 -0400 (EDT)
>> Martin Brandenburg <[email protected]> wrote:
>> > On Sat, 24 Sep 2016, YASUOKA Masahiko wrote:
>> >> The problem doesn't repeat on my Octeon.
>> >>
>> >> Can you try the diff below?
>> >>
>> >>   - I assume the diff fixes the problem
>> >>   - A kernel message is added.  please let me know if it appears.
>> >
>> > I got the message, but had another panic.
>> >
>> > ip_etherip_output: leading space is small 2
>>
>> Thanks.  The diff was wrong.  I'm sorry.
>>
>> Let me update the diff.
> 
> Still panicking.

Sorry again.  Can try the diff below?

Finally I understand that any precondition about m->m_data alignment
cannot be assumed.

diff --git a/sys/net/if_etherip.c b/sys/net/if_etherip.c
index ad58c52..74dba63 100644
--- a/sys/net/if_etherip.c
+++ b/sys/net/if_etherip.c
@@ -354,6 +354,8 @@ ip_etherip_output(struct ifnet *ifp, struct mbuf *m)
        struct sockaddr_in *src, *dst;
        struct etherip_header *eip;
        struct ip *ip;
+       struct mbuf *m1;
+       int len;
 
        src = (struct sockaddr_in *)&sc->sc_src;
        dst = (struct sockaddr_in *)&sc->sc_dst;
@@ -370,24 +372,27 @@ ip_etherip_output(struct ifnet *ifp, struct mbuf *m)
 
        m->m_flags &= ~(M_BCAST|M_MCAST);
 
-       M_PREPEND(m, sizeof(struct etherip_header), M_DONTWAIT);
-       if (m == NULL) {
-               etheripstat.etherip_adrops++;
+       len = sizeof(struct ip) + sizeof(struct etherip_header);
+       MGET(m1, M_DONTWAIT, m->m_type);
+       if (m1 == NULL) {
+               m_freem(m);
                return ENOBUFS;
        }
-       eip = mtod(m, struct etherip_header *);
-       eip->eip_ver = ETHERIP_VERSION;
-       eip->eip_res = 0;
-       eip->eip_pad = 0;
+       M_MOVE_PKTHDR(m1, m);
+       m1->m_next = m;
+       m = m1;
+       m->m_len = len;
+       m->m_pkthdr.len += len;
 
-       M_PREPEND(m, sizeof(struct ip), M_DONTWAIT);
-       if (m == NULL) {
-               etheripstat.etherip_adrops++;
-               return ENOBUFS;
-       }
        ip = mtod(m, struct ip *);
        memset(ip, 0, sizeof(struct ip));
 
+       eip = (struct etherip_header *)(ip + 1);
+
+       eip->eip_ver = ETHERIP_VERSION;
+       eip->eip_res = 0;
+       eip->eip_pad = 0;
+
        ip->ip_v = IPVERSION;
        ip->ip_hl = sizeof(struct ip) >> 2;
        ip->ip_id = htons(ip_randomid());
@@ -514,6 +519,8 @@ ip6_etherip_output(struct ifnet *ifp, struct mbuf *m)
        struct sockaddr_in6 *src, *dst;
        struct etherip_header *eip;
        struct ip6_hdr *ip6;
+       struct mbuf *m1;
+       int len;
 
        src = (struct sockaddr_in6 *)&sc->sc_src;
        dst = (struct sockaddr_in6 *)&sc->sc_dst;
@@ -530,22 +537,24 @@ ip6_etherip_output(struct ifnet *ifp, struct mbuf *m)
 
        m->m_flags &= ~(M_BCAST|M_MCAST);
 
-       M_PREPEND(m, sizeof(struct etherip_header), M_DONTWAIT);
-       if (m == NULL) {
-               etheripstat.etherip_adrops++;
+       MGET(m1, M_DONTWAIT, m->m_type);
+       if (m1 == NULL) {
+               m_freem(m);
                return ENOBUFS;
        }
-       eip = mtod(m, struct etherip_header *);
+       M_MOVE_PKTHDR(m1, m);
+       m1->m_next = m;
+       m = m1;
+       m->m_len = len;
+       m->m_pkthdr.len += len;
+
+       ip6 = mtod(m, struct ip6_hdr *);
+       eip = (struct etherip_header *)(ip6 + 1);
+
        eip->eip_ver = ETHERIP_VERSION;
        eip->eip_res = 0;
        eip->eip_pad = 0;
 
-       M_PREPEND(m, sizeof(struct ip6_hdr), M_DONTWAIT);
-       if (m == NULL) {
-               etheripstat.etherip_adrops++;
-               return ENOBUFS;
-       }
-       ip6 = mtod(m, struct ip6_hdr *);
        ip6->ip6_flow = 0;
        ip6->ip6_vfc &= ~IPV6_VERSION_MASK;
        ip6->ip6_vfc |= IPV6_VERSION;

Reply via email to