XXX: should return an error code so it can fail. */
| 926 | |
| 927 | /* XXX: should return an error code so it can fail. */ |
| 928 | static void |
| 929 | tuncreate(struct cdev *dev) |
| 930 | { |
| 931 | struct tuntap_driver *drv; |
| 932 | struct tuntap_softc *tp; |
| 933 | struct ifnet *ifp; |
| 934 | struct ether_addr eaddr; |
| 935 | int iflags; |
| 936 | u_char type; |
| 937 | |
| 938 | tp = dev->si_drv1; |
| 939 | KASSERT(tp != NULL, |
| 940 | ("si_drv1 should have been initialized at creation")); |
| 941 | |
| 942 | drv = tp->tun_drv; |
| 943 | iflags = IFF_MULTICAST; |
| 944 | if ((tp->tun_flags & TUN_L2) != 0) { |
| 945 | type = IFT_ETHER; |
| 946 | iflags |= IFF_BROADCAST | IFF_SIMPLEX; |
| 947 | } else { |
| 948 | type = IFT_PPP; |
| 949 | iflags |= IFF_POINTOPOINT; |
| 950 | } |
| 951 | ifp = tp->tun_ifp = if_alloc(type); |
| 952 | if (ifp == NULL) |
| 953 | panic("%s%d: failed to if_alloc() interface.\n", |
| 954 | drv->cdevsw.d_name, dev2unit(dev)); |
| 955 | ifp->if_softc = tp; |
| 956 | if_initname(ifp, drv->cdevsw.d_name, dev2unit(dev)); |
| 957 | ifp->if_ioctl = tunifioctl; |
| 958 | ifp->if_flags = iflags; |
| 959 | IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); |
| 960 | ifp->if_capabilities |= IFCAP_LINKSTATE; |
| 961 | ifp->if_capenable |= IFCAP_LINKSTATE; |
| 962 | |
| 963 | if ((tp->tun_flags & TUN_L2) != 0) { |
| 964 | ifp->if_init = tunifinit; |
| 965 | ifp->if_start = tunstart_l2; |
| 966 | |
| 967 | ether_gen_addr(ifp, &eaddr); |
| 968 | ether_ifattach(ifp, eaddr.octet); |
| 969 | } else { |
| 970 | ifp->if_mtu = TUNMTU; |
| 971 | ifp->if_start = tunstart; |
| 972 | ifp->if_output = tunoutput; |
| 973 | |
| 974 | ifp->if_snd.ifq_drv_maxlen = 0; |
| 975 | IFQ_SET_READY(&ifp->if_snd); |
| 976 | |
| 977 | if_attach(ifp); |
| 978 | bpfattach(ifp, DLT_NULL, sizeof(u_int32_t)); |
| 979 | } |
| 980 | |
| 981 | TUN_LOCK(tp); |
| 982 | tp->tun_flags |= TUN_INITED; |
| 983 | TUN_UNLOCK(tp); |
| 984 | |
| 985 | TUNDEBUG(ifp, "interface %s is created, minor = %#x\n", |
no test coverage detected