On 13/01/17(Fri) 13:28, Mike Belopuhov wrote:
> [...]
> However, I've just found a subtle bug here: destroying a loopback
> interface corresponding to a newly created rdomain will fail, while
> destroying loopback interfaces created in the same rdomain afterwards
> will work.  Observe:
> 
> kemushi:~% sudo ifconfig lo9 create rdomain 9
> kemushi:~% sudo ifconfig lo9
> lo9: flags=8008<LOOPBACK,MULTICAST> rdomain 9 mtu 32768
>       index 13 priority 0 llprio 3
>       groups: lo
> kemushi:~% sudo ifconfig lo9 destroy
> ifconfig: SIOCIFDESTROY: Operation not permitted
> kemushi:~% sudo ifconfig lo9 rdomain 0
> kemushi:~% sudo ifconfig lo9 destroy
> 
> Now we create lo9 again in the same rdomain:
> 
> kemushi:~% sudo ifconfig lo9
> lo9: no such interface
> kemushi:~% sudo ifconfig lo9 create rdomain 9
> kemushi:~% sudo ifconfig lo9
> lo9: flags=8008<LOOPBACK,MULTICAST> rdomain 9 mtu 32768
>       index 14 priority 0 llprio 3
>       groups: lo
> kemushi:~% sudo ifconfig lo9 destroy

Thanks for the report.  For the moment I'd take a safe approach an
forbid to change the rdomain of a lo(4) interface attached to a routing
domain.

Index: net/if_loop.c
===================================================================
RCS file: /cvs/src/sys/net/if_loop.c,v
retrieving revision 1.77
diff -u -p -r1.77 if_loop.c
--- net/if_loop.c       14 Nov 2016 10:32:46 -0000      1.77
+++ net/if_loop.c       19 Jan 2017 04:59:27 -0000
@@ -234,7 +234,7 @@ lortrequest(struct ifnet *ifp, int cmd, 
 int
 loioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
 {
-       struct ifreq *ifr;
+       struct ifreq *ifr = (struct ifreq *)data;
        int error = 0;
 
        switch (cmd) {
@@ -252,8 +252,13 @@ loioctl(struct ifnet *ifp, u_long cmd, c
                break;
 
        case SIOCSIFMTU:
-               ifr = (struct ifreq *)data;
                ifp->if_mtu = ifr->ifr_mtu;
+               break;
+
+       case SIOCSIFRDOMAIN:
+               if ((rtable_loindex(ifp->if_rdomain) == ifp->if_index) &&
+                   (ifr->ifr_rdomainid != ifp->if_rdomain))
+                       return (EPERM);
                break;
 
        default:

Reply via email to