From: Alexander Bluhm Subject: Re: diff: setting M_BCAST flag To: YASUOKA Masahiko Cc: tech@openbsd.org Date: Mon, 10 Mar 2025 19:28:25 +0100 On Sat, Mar 08, 2025 at 12:54:35PM +0900, YASUOKA Masahiko wrote: > Hello, > > Our ip_input() doesn't set M_BCAST flag for 0.0.0.0 or 255.255.255.255 > if it's not set by the lower layer. The flag must be set since it is > used by the upper layers. (eg. TCP use the flag to drop the packet.) > > The modification on in_ouraddr() is to set M_BCAST flag consistently > if the packet is for directed broadcast. Previous the flag isn't set > if the packet is diverted by pf(4). > > (eg. on the host that runs a transparent proxy for 80/tcp, when it > receives a packet for directed broadcast but its destination mac > address is not ff:ff:ff:ff:ff:ff (eg. wrong netmask), TCP wil not drop > it and the connection will be established.) > > ok? comments? M_BCAST looks like a layer 2 flag to me. I we want to prevent layer 3 broadcast addresses in TCP, tcp_input() should care about it. NetBSD has if (IN_MULTICAST(ip->ip_dst.s_addr) || in_broadcast(ip->ip_dst, m_get_rcvif_NOMPSAFE(m))) goto drop; FreeBSD does if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) || IN_MULTICAST(ntohl(ip->ip_src.s_addr)) || ip->ip_src.s_addr == htonl(INADDR_BROADCAST) || in_ifnet_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) { if ((s = tcp_log_addrs(&inc, th, NULL, NULL))) log(LOG_DEBUG, "%s; %s: Listen socket: " "Connection attempt from/to broad- " "or multicast address ignored\n", s, __func__); goto dropunlock; } When receiving a SYN packet, they take a closer look. Maybe we need something simmilar. Do not move pf_ouraddr() after route_mpath(). This is a performance optimization. If pf knows that the packet belongs to a local socket, the route lookup is skipped. bluhm > Index: sys/netinet/ip_input.c > =================================================================== > RCS file: /cvs/src/sys/netinet/ip_input.c,v > diff -u -p -r1.404 ip_input.c > --- sys/netinet/ip_input.c 2 Mar 2025 21:28:32 -0000 1.404 > +++ sys/netinet/ip_input.c 8 Mar 2025 03:51:45 -0000 > @@ -508,6 +508,7 @@ ip_input_if(struct mbuf **mp, int *offp, > > if (ip->ip_dst.s_addr == INADDR_BROADCAST || > ip->ip_dst.s_addr == INADDR_ANY) { > + m->m_flags |= M_BCAST; /* Make sure M_BCAST is set */ > nxt = ip_ours(mp, offp, nxt, af, ns); > goto out; > } > @@ -518,7 +519,7 @@ ip_input_if(struct mbuf **mp, int *offp, > } else { > ro = &ns->ns_route; > } > - switch(in_ouraddr(m, ifp, ro, flags)) { > + switch (in_ouraddr(m, ifp, ro, flags)) { > case 2: > goto bad; > case 1: > @@ -851,18 +852,6 @@ in_ouraddr(struct mbuf *m, struct ifnet > struct ip *ip; > int match = 0; > > -#if NPF > 0 > - switch (pf_ouraddr(m)) { > - case 0: > - return (0); > - case 1: > - return (1); > - default: > - /* pf does not know it */ > - break; > - } > -#endif > - > ip = mtod(m, struct ip *); > > rt = route_mpath(ro, &ip->ip_dst, &ip->ip_src, m->m_pkthdr.ph_rtableid); > @@ -883,6 +872,18 @@ in_ouraddr(struct mbuf *m, struct ifnet > m->m_flags |= M_BCAST; > } > } > + > +#if NPF > 0 > + switch (pf_ouraddr(m)) { > + case 0: > + return (0); > + case 1: > + return (1); > + default: > + /* pf does not know it */ > + break; > + } > +#endif > > if (!match) { > struct ifaddr *ifa;