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