On Mon, Oct 26, 2015 at 07:08:19PM +0100, Martin Pieuchot wrote:
> This rewrites the code to send an ARP reply to no use ``myaddr''.  The
> goal is to get rid of the per-ifp address list iterations.
> 
> Instead do two route lookups.
> 
> ok?

Should the "reply:" label stay before the "if (op != ARPOP_REQUEST)"?
Otherwise you could send a reply in response to a reply.

bluhm

> 
> Index: netinet/if_ether.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet/if_ether.c,v
> retrieving revision 1.177
> diff -u -p -r1.177 if_ether.c
> --- netinet/if_ether.c        25 Oct 2015 11:58:11 -0000      1.177
> +++ netinet/if_ether.c        26 Oct 2015 18:01:12 -0000
> @@ -519,8 +519,9 @@ in_arpinput(struct mbuf *m)
>  #endif
>       char addr[INET_ADDRSTRLEN];
>       int op, changed = 0;
> -     unsigned int len;
> +     unsigned int len, rdomain;
>  
> +     rdomain = rtable_l2(m->m_pkthdr.ph_rtableid);
>       ifp = if_get(m->m_pkthdr.ph_ifidx);
>       if (ifp == NULL) {
>               m_freem(m);
> @@ -606,7 +607,7 @@ in_arpinput(struct mbuf *m)
>               goto reply;
>       }
>       rt = arplookup(isaddr.s_addr, itaddr.s_addr == myaddr.s_addr, 0,
> -         rtable_l2(m->m_pkthdr.ph_rtableid));
> +         rdomain);
>       if (rt != NULL && (sdl = satosdl(rt->rt_gateway)) != NULL) {
>               la = (struct llinfo_arp *)rt->rt_llinfo;
>               if (sdl->sdl_alen) {
> @@ -693,32 +694,29 @@ in_arpinput(struct mbuf *m)
>                       }
>               }
>       }
> -reply:
> -     if (op != ARPOP_REQUEST) {
> -out:
> -             rtfree(rt);
> -             if_put(ifp);
> -             m_freem(m);
> -             return;
> -     }
>  
> +     if (op != ARPOP_REQUEST)
> +             goto out;
>       rtfree(rt);
> -     if (itaddr.s_addr == myaddr.s_addr) {
> -             /* I am the target */
> -             memcpy(ea->arp_tha, ea->arp_sha, sizeof(ea->arp_sha));
> -             memcpy(ea->arp_sha, enaddr, sizeof(ea->arp_sha));
> -     } else {
> -             rt = arplookup(itaddr.s_addr, 0, SIN_PROXY,
> -                 rtable_l2(m->m_pkthdr.ph_rtableid));
> -             if (rt == NULL)
> -                     goto out;
> -             if (rt->rt_ifp->if_type == IFT_CARP && ifp->if_type != IFT_CARP)
> +
> +
> +reply:
> +     /*
> +      * Reply if we have a local or proxy entry.
> +      */
> +     rt = arplookup(itaddr.s_addr, 0, SIN_PROXY, rdomain);
> +     if (!rtisvalid(rt)) {
> +             rt = arplookup(itaddr.s_addr, 0, 0, rdomain);
> +             if (!rtisvalid(rt) || !ISSET(rt->rt_flags, RTF_LOCAL))
>                       goto out;
> -             memcpy(ea->arp_tha, ea->arp_sha, sizeof(ea->arp_sha));
> -             sdl = satosdl(rt->rt_gateway);
> -             memcpy(ea->arp_sha, LLADDR(sdl), sizeof(ea->arp_sha));
> -             rtfree(rt);
>       }
> +     if (rt->rt_ifp->if_type == IFT_CARP && ifp->if_type != IFT_CARP)
> +             goto out;
> +     memcpy(ea->arp_tha, ea->arp_sha, sizeof(ea->arp_sha));
> +     sdl = satosdl(rt->rt_gateway);
> +     memcpy(ea->arp_sha, LLADDR(sdl), sizeof(ea->arp_sha));
> +     rtfree(rt);
> +
>  
>       memcpy(ea->arp_tpa, ea->arp_spa, sizeof(ea->arp_spa));
>       memcpy(ea->arp_spa, &itaddr, sizeof(ea->arp_spa));
> @@ -738,6 +736,11 @@ out:
>       ifp->if_output(ifp, m, &sa, NULL);
>       if_put(ifp);
>       return;
> +
> +out:
> +     rtfree(rt);
> +     if_put(ifp);
> +     m_freem(m);
>  }
>  
>  /*

Reply via email to