On Fri, Mar 24, 2017 at 06:14:50PM +0100, Rafael Zalamena wrote:
> I found a problem in the routing socket interface address install message.
> This issue only happens when installing IPv4 addresses on interfaces
> without specifying a prefix.
> 
> e.g. ifconfig vether0 1.1.1.1
> 
> The command above causes the installation of this address in the
> 'vether0' interface and sending a routing message 'RTM_NEWADDR' to all
> routing daemons listening to the routing socket. The message generated
> by the command above does not contain the prefix information, so the
> daemons listening will receive a new address with prefixlen value set to
> '0'.
> 
> The problem is that the prefix is not really '0', it was just not filled
> in this case, so when you remove the above address from the interface the
> next message that the routing daemons will receive will be a RTM_DELADDR
> with a prefixlen of whatever class is the address that you installed
> (in the case of the previous example, it would be '8'). Since some of
> the routing daemons will consider the prefixlen to match the routes, this
> route would never be deleted from these daemons.
> 
> This problem doesn't happen with IPv6 and you can check this by looking
> at the route monitor output or by debugging routing daemon installed
> addresses.
> 
> I've made a diff that fixes this problem for me. I just moved the mask
> calculation to somewhere before rt_ifa_addlocal(), which is the function
> responsible for calling the RTM_NEWADDR message.

IMO we should kill classless routes and just deny the request. We're well
beyond the 80is. The diff is still OK clauio@
 
> Index: sys/netinet/in.c
> ===================================================================
> RCS file: /home/obsdcvs/src/sys/netinet/in.c,v
> retrieving revision 1.135
> diff -u -p -r1.135 in.c
> --- sys/netinet/in.c  16 Feb 2017 10:15:12 -0000      1.135
> +++ sys/netinet/in.c  24 Mar 2017 16:46:27 -0000
> @@ -614,6 +614,16 @@ in_ifinit(struct ifnet *ifp, struct in_i
>       oldaddr = ia->ia_addr;
>       ia->ia_addr = *sin;
>  
> +     if (ia->ia_netmask == 0) {
> +             if (IN_CLASSA(i))
> +                     ia->ia_netmask = IN_CLASSA_NET;
> +             else if (IN_CLASSB(i))
> +                     ia->ia_netmask = IN_CLASSB_NET;
> +             else
> +                     ia->ia_netmask = IN_CLASSC_NET;
> +             ia->ia_sockmask.sin_addr.s_addr = ia->ia_netmask;
> +     }
> +
>       /*
>        * Give the interface a chance to initialize
>        * if this is its first address,
> @@ -641,15 +651,6 @@ in_ifinit(struct ifnet *ifp, struct in_i
>       if (error)
>               goto out;
>  
> -     if (ia->ia_netmask == 0) {
> -             if (IN_CLASSA(i))
> -                     ia->ia_netmask = IN_CLASSA_NET;
> -             else if (IN_CLASSB(i))
> -                     ia->ia_netmask = IN_CLASSB_NET;
> -             else
> -                     ia->ia_netmask = IN_CLASSC_NET;
> -             ia->ia_sockmask.sin_addr.s_addr = ia->ia_netmask;
> -     }
>  
>       ia->ia_net = i & ia->ia_netmask;
>       in_socktrim(&ia->ia_sockmask);
> 

-- 
:wq Claudio

Reply via email to