* Tun/Tap allocation routine * * @param[in] pmd * Pointer to private structure. * * @param[in] is_keepalive * Keepalive flag * * @param[in] persistent * Mark device as persistent * * @return * -1 on failure, fd on success */
| 150 | * -1 on failure, fd on success |
| 151 | */ |
| 152 | static int |
| 153 | tun_alloc(struct pmd_internals *pmd, int is_keepalive, int persistent) |
| 154 | { |
| 155 | struct ifreq ifr; |
| 156 | #ifdef IFF_MULTI_QUEUE |
| 157 | unsigned int features; |
| 158 | #endif |
| 159 | int fd, signo, flags; |
| 160 | |
| 161 | memset(&ifr, 0, sizeof(struct ifreq)); |
| 162 | |
| 163 | /* |
| 164 | * Do not set IFF_NO_PI as packet information header will be needed |
| 165 | * to check if a received packet has been truncated. |
| 166 | */ |
| 167 | ifr.ifr_flags = (pmd->type == ETH_TUNTAP_TYPE_TAP) ? |
| 168 | IFF_TAP : IFF_TUN | IFF_POINTOPOINT; |
| 169 | strlcpy(ifr.ifr_name, pmd->name, IFNAMSIZ); |
| 170 | |
| 171 | fd = open(TUN_TAP_DEV_PATH, O_RDWR); |
| 172 | if (fd < 0) { |
| 173 | TAP_LOG(ERR, "Unable to open %s interface", TUN_TAP_DEV_PATH); |
| 174 | goto error; |
| 175 | } |
| 176 | |
| 177 | #ifdef IFF_MULTI_QUEUE |
| 178 | /* Grab the TUN features to verify we can work multi-queue */ |
| 179 | if (ioctl(fd, TUNGETFEATURES, &features) < 0) { |
| 180 | TAP_LOG(ERR, "unable to get TUN/TAP features"); |
| 181 | goto error; |
| 182 | } |
| 183 | TAP_LOG(DEBUG, "%s Features %08x", TUN_TAP_DEV_PATH, features); |
| 184 | |
| 185 | if (features & IFF_MULTI_QUEUE) { |
| 186 | TAP_LOG(DEBUG, " Multi-queue support for %d queues", |
| 187 | RTE_PMD_TAP_MAX_QUEUES); |
| 188 | ifr.ifr_flags |= IFF_MULTI_QUEUE; |
| 189 | } else |
| 190 | #endif |
| 191 | { |
| 192 | ifr.ifr_flags |= IFF_ONE_QUEUE; |
| 193 | TAP_LOG(DEBUG, " Single queue only support"); |
| 194 | } |
| 195 | |
| 196 | /* Set the TUN/TAP configuration and set the name if needed */ |
| 197 | if (ioctl(fd, TUNSETIFF, (void *)&ifr) < 0) { |
| 198 | TAP_LOG(WARNING, "Unable to set TUNSETIFF for %s: %s", |
| 199 | ifr.ifr_name, strerror(errno)); |
| 200 | goto error; |
| 201 | } |
| 202 | |
| 203 | /* Keep the device after application exit */ |
| 204 | if (persistent && ioctl(fd, TUNSETPERSIST, 1) < 0) { |
| 205 | TAP_LOG(WARNING, |
| 206 | "Unable to set persist %s: %s", |
| 207 | ifr.ifr_name, strerror(errno)); |
| 208 | goto error; |
| 209 | } |