On Fri, Mar 26, 2021 at 11:00:22AM +0000, Schreilechner, Dominik wrote: > --- a/sys/netinet/ip_output.c > +++ b/sys/netinet/ip_output.c > @@ -765,6 +765,11 @@ ip_insertoptions(struct mbuf *m, struct mbuf *opt, int > *phlen) > optlen = opt->m_len - sizeof(p->ipopt_dst); > if (optlen + ntohs(ip->ip_len) > IP_MAXPACKET) > return (m); /* XXX should fail */ > + > + /* check if options will fit to IP header */ > + if ((optlen + (ip->ip_hl << 2)) > (0x0f << 2)) > + return (m); > + > if (p->ipopt_dst.s_addr) > ip->ip_dst = p->ipopt_dst; > if (m->m_flags & M_EXT || m->m_data - optlen < m->m_pktdat) { > @@ -790,6 +795,7 @@ ip_insertoptions(struct mbuf *m, struct mbuf *opt, int > *phlen) > memcpy(ip + 1, p->ipopt_list, optlen); > *phlen = sizeof(struct ip) + optlen; > ip->ip_len = htons(ntohs(ip->ip_len) + optlen); > + ip->ip_hl += (optlen >> 2); > return (m); > }
I think ip_insertoptions() is not intended to insert additional options, but to set them. The *phlen is set to htons(ntohs(ip->ip_len) + optlen), so the option length is optlen. The ip->ip_hl += makes no sense. I am not sure if ip->ip_hl is always initialized. ip_insertoptions() returns the option length in &hlen. I think it is the callers job to write it into the header. Instead of touching ip_insertoptions() I would set ip->ip_hl = hlen >> 2 in this block, like it is done in ip_output(). > + if (opts != NULL) { > m = ip_insertoptions(m, opts, &hlen); > + ip->ip_v = IPVERSION; > + ip->ip_off &= htons(IP_DF); > + ip->ip_id = htons(ip_randomid()); > + ipstat_inc(ips_localout); > + ip_send_raw(m); > + } else Appart from that, adding a special task seems the way to go. bluhm