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