| 1038 | } |
| 1039 | |
| 1040 | static int |
| 1041 | tunopen(struct cdev *dev, int flag, int mode, struct thread *td) |
| 1042 | { |
| 1043 | struct ifnet *ifp; |
| 1044 | struct tuntap_softc *tp; |
| 1045 | int error, tunflags; |
| 1046 | |
| 1047 | tunflags = 0; |
| 1048 | CURVNET_SET(TD_TO_VNET(td)); |
| 1049 | error = tuntap_name2info(dev->si_name, NULL, &tunflags); |
| 1050 | if (error != 0) { |
| 1051 | CURVNET_RESTORE(); |
| 1052 | return (error); /* Shouldn't happen */ |
| 1053 | } |
| 1054 | |
| 1055 | tp = dev->si_drv1; |
| 1056 | KASSERT(tp != NULL, |
| 1057 | ("si_drv1 should have been initialized at creation")); |
| 1058 | |
| 1059 | TUN_LOCK(tp); |
| 1060 | if ((tp->tun_flags & TUN_INITED) == 0) { |
| 1061 | TUN_UNLOCK(tp); |
| 1062 | CURVNET_RESTORE(); |
| 1063 | return (ENXIO); |
| 1064 | } |
| 1065 | if ((tp->tun_flags & (TUN_OPEN | TUN_DYING)) != 0) { |
| 1066 | TUN_UNLOCK(tp); |
| 1067 | CURVNET_RESTORE(); |
| 1068 | return (EBUSY); |
| 1069 | } |
| 1070 | |
| 1071 | error = tun_busy_locked(tp); |
| 1072 | KASSERT(error == 0, ("Must be able to busy an unopen tunnel")); |
| 1073 | ifp = TUN2IFP(tp); |
| 1074 | |
| 1075 | if ((tp->tun_flags & TUN_L2) != 0) { |
| 1076 | bcopy(IF_LLADDR(ifp), tp->tun_ether.octet, |
| 1077 | sizeof(tp->tun_ether.octet)); |
| 1078 | |
| 1079 | ifp->if_drv_flags |= IFF_DRV_RUNNING; |
| 1080 | ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; |
| 1081 | |
| 1082 | if (tapuponopen) |
| 1083 | ifp->if_flags |= IFF_UP; |
| 1084 | } |
| 1085 | |
| 1086 | tp->tun_pid = td->td_proc->p_pid; |
| 1087 | tp->tun_flags |= TUN_OPEN; |
| 1088 | |
| 1089 | if_link_state_change(ifp, LINK_STATE_UP); |
| 1090 | TUNDEBUG(ifp, "open\n"); |
| 1091 | TUN_UNLOCK(tp); |
| 1092 | |
| 1093 | /* |
| 1094 | * This can fail with either ENOENT or EBUSY. This is in the middle of |
| 1095 | * d_open, so ENOENT should not be possible. EBUSY is possible, but |
| 1096 | * the only cdevpriv dtor being set will be tundtor and the softc being |
| 1097 | * passed is constant for a given cdev. We ignore the possible error |
nothing calls this directly
no test coverage detected