1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2016-2017 Intel Corporation
5 #include <rte_atomic.h>
6 #include <rte_branch_prediction.h>
7 #include <rte_byteorder.h>
8 #include <rte_common.h>
10 #include <rte_ethdev_driver.h>
11 #include <rte_ethdev_vdev.h>
12 #include <rte_malloc.h>
13 #include <rte_bus_vdev.h>
14 #include <rte_kvargs.h>
16 #include <rte_debug.h>
18 #include <rte_string_fns.h>
21 #include <sys/types.h>
23 #include <sys/socket.h>
24 #include <sys/ioctl.h>
25 #include <sys/utsname.h>
33 #include <arpa/inet.h>
35 #include <linux/if_tun.h>
36 #include <linux/if_ether.h>
40 #include <rte_eth_tap.h>
42 #include <tap_netlink.h>
43 #include <tap_tcmsgs.h>
45 /* Linux based path to the TUN device */
46 #define TUN_TAP_DEV_PATH "/dev/net/tun"
47 #define DEFAULT_TAP_NAME "dtap"
48 #define DEFAULT_TUN_NAME "dtun"
50 #define ETH_TAP_IFACE_ARG "iface"
51 #define ETH_TAP_REMOTE_ARG "remote"
52 #define ETH_TAP_MAC_ARG "mac"
53 #define ETH_TAP_MAC_FIXED "fixed"
55 #define ETH_TAP_USR_MAC_FMT "xx:xx:xx:xx:xx:xx"
56 #define ETH_TAP_CMP_MAC_FMT "0123456789ABCDEFabcdef"
57 #define ETH_TAP_MAC_ARG_FMT ETH_TAP_MAC_FIXED "|" ETH_TAP_USR_MAC_FMT
59 #define TAP_GSO_MBUFS_PER_CORE 128
60 #define TAP_GSO_MBUF_SEG_SIZE 128
61 #define TAP_GSO_MBUF_CACHE_SIZE 4
62 #define TAP_GSO_MBUFS_NUM \
63 (TAP_GSO_MBUFS_PER_CORE * TAP_GSO_MBUF_CACHE_SIZE)
65 static struct rte_vdev_driver pmd_tap_drv
;
66 static struct rte_vdev_driver pmd_tun_drv
;
68 static const char *valid_arguments
[] = {
75 static unsigned int tap_unit
;
76 static unsigned int tun_unit
;
78 static char tuntap_name
[8];
80 static volatile uint32_t tap_trigger
; /* Rx trigger */
82 static struct rte_eth_link pmd_link
= {
83 .link_speed
= ETH_SPEED_NUM_10G
,
84 .link_duplex
= ETH_LINK_FULL_DUPLEX
,
85 .link_status
= ETH_LINK_DOWN
,
86 .link_autoneg
= ETH_LINK_FIXED
,
90 tap_trigger_cb(int sig __rte_unused
)
92 /* Valid trigger values are nonzero */
93 tap_trigger
= (tap_trigger
+ 1) | 0x80000000;
96 /* Specifies on what netdevices the ioctl should be applied */
103 static int tap_intr_handle_set(struct rte_eth_dev
*dev
, int set
);
106 * Tun/Tap allocation routine
109 * Pointer to private structure.
111 * @param[in] is_keepalive
115 * -1 on failure, fd on success
118 tun_alloc(struct pmd_internals
*pmd
, int is_keepalive
)
121 #ifdef IFF_MULTI_QUEUE
122 unsigned int features
;
126 memset(&ifr
, 0, sizeof(struct ifreq
));
129 * Do not set IFF_NO_PI as packet information header will be needed
130 * to check if a received packet has been truncated.
132 ifr
.ifr_flags
= (pmd
->type
== ETH_TUNTAP_TYPE_TAP
) ?
133 IFF_TAP
: IFF_TUN
| IFF_POINTOPOINT
;
134 snprintf(ifr
.ifr_name
, IFNAMSIZ
, "%s", pmd
->name
);
136 TAP_LOG(DEBUG
, "ifr_name '%s'", ifr
.ifr_name
);
138 fd
= open(TUN_TAP_DEV_PATH
, O_RDWR
);
140 TAP_LOG(ERR
, "Unable to create %s interface", tuntap_name
);
144 #ifdef IFF_MULTI_QUEUE
145 /* Grab the TUN features to verify we can work multi-queue */
146 if (ioctl(fd
, TUNGETFEATURES
, &features
) < 0) {
147 TAP_LOG(ERR
, "%s unable to get TUN/TAP features",
151 TAP_LOG(DEBUG
, "%s Features %08x", tuntap_name
, features
);
153 if (features
& IFF_MULTI_QUEUE
) {
154 TAP_LOG(DEBUG
, " Multi-queue support for %d queues",
155 RTE_PMD_TAP_MAX_QUEUES
);
156 ifr
.ifr_flags
|= IFF_MULTI_QUEUE
;
160 ifr
.ifr_flags
|= IFF_ONE_QUEUE
;
161 TAP_LOG(DEBUG
, " Single queue only support");
164 /* Set the TUN/TAP configuration and set the name if needed */
165 if (ioctl(fd
, TUNSETIFF
, (void *)&ifr
) < 0) {
166 TAP_LOG(WARNING
, "Unable to set TUNSETIFF for %s: %s",
167 ifr
.ifr_name
, strerror(errno
));
173 * Detach the TUN/TAP keep-alive queue
174 * to avoid traffic through it
176 ifr
.ifr_flags
= IFF_DETACH_QUEUE
;
177 if (ioctl(fd
, TUNSETQUEUE
, (void *)&ifr
) < 0) {
179 "Unable to detach keep-alive queue for %s: %s",
180 ifr
.ifr_name
, strerror(errno
));
185 /* Always set the file descriptor to non-blocking */
186 if (fcntl(fd
, F_SETFL
, O_NONBLOCK
) < 0) {
188 "Unable to set %s to nonblocking: %s",
189 ifr
.ifr_name
, strerror(errno
));
193 /* Set up trigger to optimize empty Rx bursts */
197 int flags
= fcntl(fd
, F_GETFL
);
199 if (flags
== -1 || sigaction(SIGIO
, NULL
, &sa
) == -1)
201 if (sa
.sa_handler
!= tap_trigger_cb
) {
203 * Make sure SIGIO is not already taken. This is done
204 * as late as possible to leave the application a
205 * chance to set up its own signal handler first.
207 if (sa
.sa_handler
!= SIG_IGN
&&
208 sa
.sa_handler
!= SIG_DFL
) {
212 sa
= (struct sigaction
){
213 .sa_flags
= SA_RESTART
,
214 .sa_handler
= tap_trigger_cb
,
216 if (sigaction(SIGIO
, &sa
, NULL
) == -1)
219 /* Enable SIGIO on file descriptor */
220 fcntl(fd
, F_SETFL
, flags
| O_ASYNC
);
221 fcntl(fd
, F_SETOWN
, getpid());
225 /* Disable trigger globally in case of error */
227 TAP_LOG(WARNING
, "Rx trigger disabled: %s",
240 tap_verify_csum(struct rte_mbuf
*mbuf
)
242 uint32_t l2
= mbuf
->packet_type
& RTE_PTYPE_L2_MASK
;
243 uint32_t l3
= mbuf
->packet_type
& RTE_PTYPE_L3_MASK
;
244 uint32_t l4
= mbuf
->packet_type
& RTE_PTYPE_L4_MASK
;
245 unsigned int l2_len
= sizeof(struct ether_hdr
);
251 if (l2
== RTE_PTYPE_L2_ETHER_VLAN
)
253 else if (l2
== RTE_PTYPE_L2_ETHER_QINQ
)
255 /* Don't verify checksum for packets with discontinuous L2 header */
256 if (unlikely(l2_len
+ sizeof(struct ipv4_hdr
) >
257 rte_pktmbuf_data_len(mbuf
)))
259 l3_hdr
= rte_pktmbuf_mtod_offset(mbuf
, void *, l2_len
);
260 if (l3
== RTE_PTYPE_L3_IPV4
|| l3
== RTE_PTYPE_L3_IPV4_EXT
) {
261 struct ipv4_hdr
*iph
= l3_hdr
;
263 /* ihl contains the number of 4-byte words in the header */
264 l3_len
= 4 * (iph
->version_ihl
& 0xf);
265 if (unlikely(l2_len
+ l3_len
> rte_pktmbuf_data_len(mbuf
)))
268 cksum
= ~rte_raw_cksum(iph
, l3_len
);
269 mbuf
->ol_flags
|= cksum
?
270 PKT_RX_IP_CKSUM_BAD
:
271 PKT_RX_IP_CKSUM_GOOD
;
272 } else if (l3
== RTE_PTYPE_L3_IPV6
) {
273 l3_len
= sizeof(struct ipv6_hdr
);
275 /* IPv6 extensions are not supported */
278 if (l4
== RTE_PTYPE_L4_UDP
|| l4
== RTE_PTYPE_L4_TCP
) {
279 l4_hdr
= rte_pktmbuf_mtod_offset(mbuf
, void *, l2_len
+ l3_len
);
280 /* Don't verify checksum for multi-segment packets. */
281 if (mbuf
->nb_segs
> 1)
283 if (l3
== RTE_PTYPE_L3_IPV4
)
284 cksum
= ~rte_ipv4_udptcp_cksum(l3_hdr
, l4_hdr
);
285 else if (l3
== RTE_PTYPE_L3_IPV6
)
286 cksum
= ~rte_ipv6_udptcp_cksum(l3_hdr
, l4_hdr
);
287 mbuf
->ol_flags
|= cksum
?
288 PKT_RX_L4_CKSUM_BAD
:
289 PKT_RX_L4_CKSUM_GOOD
;
294 tap_rx_offload_get_port_capa(void)
297 * No specific port Rx offload capabilities.
303 tap_rx_offload_get_queue_capa(void)
305 return DEV_RX_OFFLOAD_SCATTER
|
306 DEV_RX_OFFLOAD_IPV4_CKSUM
|
307 DEV_RX_OFFLOAD_UDP_CKSUM
|
308 DEV_RX_OFFLOAD_TCP_CKSUM
|
309 DEV_RX_OFFLOAD_CRC_STRIP
;
312 /* Callback to handle the rx burst of packets to the correct interface and
313 * file descriptor(s) in a multi-queue setup.
316 pmd_rx_burst(void *queue
, struct rte_mbuf
**bufs
, uint16_t nb_pkts
)
318 struct rx_queue
*rxq
= queue
;
320 unsigned long num_rx_bytes
= 0;
321 uint32_t trigger
= tap_trigger
;
323 if (trigger
== rxq
->trigger_seen
)
326 rxq
->trigger_seen
= trigger
;
327 rte_compiler_barrier();
328 for (num_rx
= 0; num_rx
< nb_pkts
; ) {
329 struct rte_mbuf
*mbuf
= rxq
->pool
;
330 struct rte_mbuf
*seg
= NULL
;
331 struct rte_mbuf
*new_tail
= NULL
;
332 uint16_t data_off
= rte_pktmbuf_headroom(mbuf
);
335 len
= readv(rxq
->fd
, *rxq
->iovecs
,
337 (rxq
->rxmode
->offloads
& DEV_RX_OFFLOAD_SCATTER
?
338 rxq
->nb_rx_desc
: 1));
339 if (len
< (int)sizeof(struct tun_pi
))
342 /* Packet couldn't fit in the provided mbuf */
343 if (unlikely(rxq
->pi
.flags
& TUN_PKT_STRIP
)) {
344 rxq
->stats
.ierrors
++;
348 len
-= sizeof(struct tun_pi
);
351 mbuf
->port
= rxq
->in_port
;
353 struct rte_mbuf
*buf
= rte_pktmbuf_alloc(rxq
->mp
);
355 if (unlikely(!buf
)) {
356 rxq
->stats
.rx_nombuf
++;
357 /* No new buf has been allocated: do nothing */
358 if (!new_tail
|| !seg
)
362 rte_pktmbuf_free(mbuf
);
366 seg
= seg
? seg
->next
: mbuf
;
367 if (rxq
->pool
== mbuf
)
370 new_tail
->next
= buf
;
372 new_tail
->next
= seg
->next
;
374 /* iovecs[0] is reserved for packet info (pi) */
375 (*rxq
->iovecs
)[mbuf
->nb_segs
].iov_len
=
376 buf
->buf_len
- data_off
;
377 (*rxq
->iovecs
)[mbuf
->nb_segs
].iov_base
=
378 (char *)buf
->buf_addr
+ data_off
;
380 seg
->data_len
= RTE_MIN(seg
->buf_len
- data_off
, len
);
381 seg
->data_off
= data_off
;
383 len
-= seg
->data_len
;
387 /* First segment has headroom, not the others */
391 mbuf
->packet_type
= rte_net_get_ptype(mbuf
, NULL
,
393 if (rxq
->rxmode
->offloads
& DEV_RX_OFFLOAD_CHECKSUM
)
394 tap_verify_csum(mbuf
);
396 /* account for the receive frame */
397 bufs
[num_rx
++] = mbuf
;
398 num_rx_bytes
+= mbuf
->pkt_len
;
401 rxq
->stats
.ipackets
+= num_rx
;
402 rxq
->stats
.ibytes
+= num_rx_bytes
;
408 tap_tx_offload_get_port_capa(void)
411 * No specific port Tx offload capabilities.
417 tap_tx_offload_get_queue_capa(void)
419 return DEV_TX_OFFLOAD_MULTI_SEGS
|
420 DEV_TX_OFFLOAD_IPV4_CKSUM
|
421 DEV_TX_OFFLOAD_UDP_CKSUM
|
422 DEV_TX_OFFLOAD_TCP_CKSUM
|
423 DEV_TX_OFFLOAD_TCP_TSO
;
426 /* Finalize l4 checksum calculation */
428 tap_tx_l4_cksum(uint16_t *l4_cksum
, uint16_t l4_phdr_cksum
,
429 uint32_t l4_raw_cksum
)
434 cksum
= __rte_raw_cksum_reduce(l4_raw_cksum
);
435 cksum
+= l4_phdr_cksum
;
437 cksum
= ((cksum
& 0xffff0000) >> 16) + (cksum
& 0xffff);
438 cksum
= (~cksum
) & 0xffff;
445 /* Accumaulate L4 raw checksums */
447 tap_tx_l4_add_rcksum(char *l4_data
, unsigned int l4_len
, uint16_t *l4_cksum
,
448 uint32_t *l4_raw_cksum
)
450 if (l4_cksum
== NULL
)
453 *l4_raw_cksum
= __rte_raw_cksum(l4_data
, l4_len
, *l4_raw_cksum
);
456 /* L3 and L4 pseudo headers checksum offloads */
458 tap_tx_l3_cksum(char *packet
, uint64_t ol_flags
, unsigned int l2_len
,
459 unsigned int l3_len
, unsigned int l4_len
, uint16_t **l4_cksum
,
460 uint16_t *l4_phdr_cksum
, uint32_t *l4_raw_cksum
)
462 void *l3_hdr
= packet
+ l2_len
;
464 if (ol_flags
& (PKT_TX_IP_CKSUM
| PKT_TX_IPV4
)) {
465 struct ipv4_hdr
*iph
= l3_hdr
;
468 iph
->hdr_checksum
= 0;
469 cksum
= rte_raw_cksum(iph
, l3_len
);
470 iph
->hdr_checksum
= (cksum
== 0xffff) ? cksum
: ~cksum
;
472 if (ol_flags
& PKT_TX_L4_MASK
) {
475 l4_hdr
= packet
+ l2_len
+ l3_len
;
476 if ((ol_flags
& PKT_TX_L4_MASK
) == PKT_TX_UDP_CKSUM
)
477 *l4_cksum
= &((struct udp_hdr
*)l4_hdr
)->dgram_cksum
;
478 else if ((ol_flags
& PKT_TX_L4_MASK
) == PKT_TX_TCP_CKSUM
)
479 *l4_cksum
= &((struct tcp_hdr
*)l4_hdr
)->cksum
;
483 if (ol_flags
& PKT_TX_IPV4
)
484 *l4_phdr_cksum
= rte_ipv4_phdr_cksum(l3_hdr
, 0);
486 *l4_phdr_cksum
= rte_ipv6_phdr_cksum(l3_hdr
, 0);
487 *l4_raw_cksum
= __rte_raw_cksum(l4_hdr
, l4_len
, 0);
492 tap_write_mbufs(struct tx_queue
*txq
, uint16_t num_mbufs
,
493 struct rte_mbuf
**pmbufs
,
494 uint16_t *num_packets
, unsigned long *num_tx_bytes
)
499 for (i
= 0; i
< num_mbufs
; i
++) {
500 struct rte_mbuf
*mbuf
= pmbufs
[i
];
501 struct iovec iovecs
[mbuf
->nb_segs
+ 2];
502 struct tun_pi pi
= { .flags
= 0, .proto
= 0x00 };
503 struct rte_mbuf
*seg
= mbuf
;
504 char m_copy
[mbuf
->data_len
];
508 int k
; /* current index in iovecs for copying segments */
509 uint16_t seg_len
; /* length of first segment */
511 uint16_t *l4_cksum
; /* l4 checksum (pseudo header + payload) */
512 uint32_t l4_raw_cksum
= 0; /* TCP/UDP payload raw checksum */
513 uint16_t l4_phdr_cksum
= 0; /* TCP/UDP pseudo header checksum */
514 uint16_t is_cksum
= 0; /* in case cksum should be offloaded */
517 if (txq
->type
== ETH_TUNTAP_TYPE_TUN
) {
519 * TUN and TAP are created with IFF_NO_PI disabled.
520 * For TUN PMD this mandatory as fields are used by
521 * Kernel tun.c to determine whether its IP or non IP
524 * The logic fetches the first byte of data from mbuf
525 * then compares whether its v4 or v6. If first byte
526 * is 4 or 6, then protocol field is updated.
528 char *buff_data
= rte_pktmbuf_mtod(seg
, void *);
529 proto
= (*buff_data
& 0xf0);
530 pi
.proto
= (proto
== 0x40) ?
531 rte_cpu_to_be_16(ETHER_TYPE_IPv4
) :
533 rte_cpu_to_be_16(ETHER_TYPE_IPv6
) :
538 iovecs
[k
].iov_base
= &pi
;
539 iovecs
[k
].iov_len
= sizeof(pi
);
542 nb_segs
= mbuf
->nb_segs
;
544 ((mbuf
->ol_flags
& (PKT_TX_IP_CKSUM
| PKT_TX_IPV4
) ||
545 (mbuf
->ol_flags
& PKT_TX_L4_MASK
) == PKT_TX_UDP_CKSUM
||
546 (mbuf
->ol_flags
& PKT_TX_L4_MASK
) == PKT_TX_TCP_CKSUM
))) {
549 /* Support only packets with at least layer 4
550 * header included in the first segment
552 seg_len
= rte_pktmbuf_data_len(mbuf
);
553 l234_hlen
= mbuf
->l2_len
+ mbuf
->l3_len
+ mbuf
->l4_len
;
554 if (seg_len
< l234_hlen
)
557 /* To change checksums, work on a * copy of l2, l3
558 * headers + l4 pseudo header
560 rte_memcpy(m_copy
, rte_pktmbuf_mtod(mbuf
, void *),
562 tap_tx_l3_cksum(m_copy
, mbuf
->ol_flags
,
563 mbuf
->l2_len
, mbuf
->l3_len
, mbuf
->l4_len
,
564 &l4_cksum
, &l4_phdr_cksum
,
566 iovecs
[k
].iov_base
= m_copy
;
567 iovecs
[k
].iov_len
= l234_hlen
;
570 /* Update next iovecs[] beyond l2, l3, l4 headers */
571 if (seg_len
> l234_hlen
) {
572 iovecs
[k
].iov_len
= seg_len
- l234_hlen
;
574 rte_pktmbuf_mtod(seg
, char *) +
576 tap_tx_l4_add_rcksum(iovecs
[k
].iov_base
,
577 iovecs
[k
].iov_len
, l4_cksum
,
585 for (j
= k
; j
<= nb_segs
; j
++) {
586 iovecs
[j
].iov_len
= rte_pktmbuf_data_len(seg
);
587 iovecs
[j
].iov_base
= rte_pktmbuf_mtod(seg
, void *);
589 tap_tx_l4_add_rcksum(iovecs
[j
].iov_base
,
590 iovecs
[j
].iov_len
, l4_cksum
,
596 tap_tx_l4_cksum(l4_cksum
, l4_phdr_cksum
, l4_raw_cksum
);
598 /* copy the tx frame data */
599 n
= writev(txq
->fd
, iovecs
, j
);
603 (*num_tx_bytes
) += rte_pktmbuf_pkt_len(mbuf
);
607 /* Callback to handle sending packets from the tap interface
610 pmd_tx_burst(void *queue
, struct rte_mbuf
**bufs
, uint16_t nb_pkts
)
612 struct tx_queue
*txq
= queue
;
614 uint16_t num_packets
= 0;
615 unsigned long num_tx_bytes
= 0;
619 if (unlikely(nb_pkts
== 0))
622 struct rte_mbuf
*gso_mbufs
[MAX_GSO_MBUFS
];
623 max_size
= *txq
->mtu
+ (ETHER_HDR_LEN
+ ETHER_CRC_LEN
+ 4);
624 for (i
= 0; i
< nb_pkts
; i
++) {
625 struct rte_mbuf
*mbuf_in
= bufs
[num_tx
];
626 struct rte_mbuf
**mbuf
;
627 uint16_t num_mbufs
= 0;
628 uint16_t tso_segsz
= 0;
634 tso
= mbuf_in
->ol_flags
& PKT_TX_TCP_SEG
;
636 struct rte_gso_ctx
*gso_ctx
= &txq
->gso_ctx
;
638 assert(gso_ctx
!= NULL
);
640 /* TCP segmentation implies TCP checksum offload */
641 mbuf_in
->ol_flags
|= PKT_TX_TCP_CKSUM
;
643 /* gso size is calculated without ETHER_CRC_LEN */
644 hdrs_len
= mbuf_in
->l2_len
+ mbuf_in
->l3_len
+
646 tso_segsz
= mbuf_in
->tso_segsz
+ hdrs_len
;
647 if (unlikely(tso_segsz
== hdrs_len
) ||
648 tso_segsz
> *txq
->mtu
) {
652 gso_ctx
->gso_size
= tso_segsz
;
653 ret
= rte_gso_segment(mbuf_in
, /* packet to segment */
654 gso_ctx
, /* gso control block */
655 (struct rte_mbuf
**)&gso_mbufs
, /* out mbufs */
656 RTE_DIM(gso_mbufs
)); /* max tso mbufs */
658 /* ret contains the number of new created mbufs */
665 /* stats.errs will be incremented */
666 if (rte_pktmbuf_pkt_len(mbuf_in
) > max_size
)
669 /* ret 0 indicates no new mbufs were created */
675 tap_write_mbufs(txq
, num_mbufs
, mbuf
,
676 &num_packets
, &num_tx_bytes
);
678 /* free original mbuf */
679 rte_pktmbuf_free(mbuf_in
);
681 for (j
= 0; j
< ret
; j
++)
682 rte_pktmbuf_free(mbuf
[j
]);
685 txq
->stats
.opackets
+= num_packets
;
686 txq
->stats
.errs
+= nb_pkts
- num_tx
;
687 txq
->stats
.obytes
+= num_tx_bytes
;
693 tap_ioctl_req2str(unsigned long request
)
697 return "SIOCSIFFLAGS";
699 return "SIOCGIFFLAGS";
701 return "SIOCGIFHWADDR";
703 return "SIOCSIFHWADDR";
711 tap_ioctl(struct pmd_internals
*pmd
, unsigned long request
,
712 struct ifreq
*ifr
, int set
, enum ioctl_mode mode
)
714 short req_flags
= ifr
->ifr_flags
;
715 int remote
= pmd
->remote_if_index
&&
716 (mode
== REMOTE_ONLY
|| mode
== LOCAL_AND_REMOTE
);
718 if (!pmd
->remote_if_index
&& mode
== REMOTE_ONLY
)
721 * If there is a remote netdevice, apply ioctl on it, then apply it on
726 snprintf(ifr
->ifr_name
, IFNAMSIZ
, "%s", pmd
->remote_iface
);
727 else if (mode
== LOCAL_ONLY
|| mode
== LOCAL_AND_REMOTE
)
728 snprintf(ifr
->ifr_name
, IFNAMSIZ
, "%s", pmd
->name
);
731 /* fetch current flags to leave other flags untouched */
732 if (ioctl(pmd
->ioctl_sock
, SIOCGIFFLAGS
, ifr
) < 0)
735 ifr
->ifr_flags
|= req_flags
;
737 ifr
->ifr_flags
&= ~req_flags
;
745 RTE_LOG(WARNING
, PMD
, "%s: ioctl() called with wrong arg\n",
749 if (ioctl(pmd
->ioctl_sock
, request
, ifr
) < 0)
751 if (remote
-- && mode
== LOCAL_AND_REMOTE
)
756 TAP_LOG(DEBUG
, "%s(%s) failed: %s(%d)", ifr
->ifr_name
,
757 tap_ioctl_req2str(request
), strerror(errno
), errno
);
762 tap_link_set_down(struct rte_eth_dev
*dev
)
764 struct pmd_internals
*pmd
= dev
->data
->dev_private
;
765 struct ifreq ifr
= { .ifr_flags
= IFF_UP
};
767 dev
->data
->dev_link
.link_status
= ETH_LINK_DOWN
;
768 return tap_ioctl(pmd
, SIOCSIFFLAGS
, &ifr
, 0, LOCAL_ONLY
);
772 tap_link_set_up(struct rte_eth_dev
*dev
)
774 struct pmd_internals
*pmd
= dev
->data
->dev_private
;
775 struct ifreq ifr
= { .ifr_flags
= IFF_UP
};
777 dev
->data
->dev_link
.link_status
= ETH_LINK_UP
;
778 return tap_ioctl(pmd
, SIOCSIFFLAGS
, &ifr
, 1, LOCAL_AND_REMOTE
);
782 tap_dev_start(struct rte_eth_dev
*dev
)
786 err
= tap_intr_handle_set(dev
, 1);
790 err
= tap_link_set_up(dev
);
794 for (i
= 0; i
< dev
->data
->nb_tx_queues
; i
++)
795 dev
->data
->tx_queue_state
[i
] = RTE_ETH_QUEUE_STATE_STARTED
;
796 for (i
= 0; i
< dev
->data
->nb_rx_queues
; i
++)
797 dev
->data
->rx_queue_state
[i
] = RTE_ETH_QUEUE_STATE_STARTED
;
802 /* This function gets called when the current port gets stopped.
805 tap_dev_stop(struct rte_eth_dev
*dev
)
809 for (i
= 0; i
< dev
->data
->nb_tx_queues
; i
++)
810 dev
->data
->tx_queue_state
[i
] = RTE_ETH_QUEUE_STATE_STOPPED
;
811 for (i
= 0; i
< dev
->data
->nb_rx_queues
; i
++)
812 dev
->data
->rx_queue_state
[i
] = RTE_ETH_QUEUE_STATE_STOPPED
;
814 tap_intr_handle_set(dev
, 0);
815 tap_link_set_down(dev
);
819 tap_dev_configure(struct rte_eth_dev
*dev
)
821 if (dev
->data
->nb_rx_queues
> RTE_PMD_TAP_MAX_QUEUES
) {
823 "%s: number of rx queues %d exceeds max num of queues %d",
825 dev
->data
->nb_rx_queues
,
826 RTE_PMD_TAP_MAX_QUEUES
);
829 if (dev
->data
->nb_tx_queues
> RTE_PMD_TAP_MAX_QUEUES
) {
831 "%s: number of tx queues %d exceeds max num of queues %d",
833 dev
->data
->nb_tx_queues
,
834 RTE_PMD_TAP_MAX_QUEUES
);
838 TAP_LOG(INFO
, "%s: %p: TX configured queues number: %u",
839 dev
->device
->name
, (void *)dev
, dev
->data
->nb_tx_queues
);
841 TAP_LOG(INFO
, "%s: %p: RX configured queues number: %u",
842 dev
->device
->name
, (void *)dev
, dev
->data
->nb_rx_queues
);
848 tap_dev_speed_capa(void)
850 uint32_t speed
= pmd_link
.link_speed
;
853 if (speed
>= ETH_SPEED_NUM_10M
)
854 capa
|= ETH_LINK_SPEED_10M
;
855 if (speed
>= ETH_SPEED_NUM_100M
)
856 capa
|= ETH_LINK_SPEED_100M
;
857 if (speed
>= ETH_SPEED_NUM_1G
)
858 capa
|= ETH_LINK_SPEED_1G
;
859 if (speed
>= ETH_SPEED_NUM_5G
)
860 capa
|= ETH_LINK_SPEED_2_5G
;
861 if (speed
>= ETH_SPEED_NUM_5G
)
862 capa
|= ETH_LINK_SPEED_5G
;
863 if (speed
>= ETH_SPEED_NUM_10G
)
864 capa
|= ETH_LINK_SPEED_10G
;
865 if (speed
>= ETH_SPEED_NUM_20G
)
866 capa
|= ETH_LINK_SPEED_20G
;
867 if (speed
>= ETH_SPEED_NUM_25G
)
868 capa
|= ETH_LINK_SPEED_25G
;
869 if (speed
>= ETH_SPEED_NUM_40G
)
870 capa
|= ETH_LINK_SPEED_40G
;
871 if (speed
>= ETH_SPEED_NUM_50G
)
872 capa
|= ETH_LINK_SPEED_50G
;
873 if (speed
>= ETH_SPEED_NUM_56G
)
874 capa
|= ETH_LINK_SPEED_56G
;
875 if (speed
>= ETH_SPEED_NUM_100G
)
876 capa
|= ETH_LINK_SPEED_100G
;
882 tap_dev_info(struct rte_eth_dev
*dev
, struct rte_eth_dev_info
*dev_info
)
884 struct pmd_internals
*internals
= dev
->data
->dev_private
;
886 dev_info
->if_index
= internals
->if_index
;
887 dev_info
->max_mac_addrs
= 1;
888 dev_info
->max_rx_pktlen
= (uint32_t)ETHER_MAX_VLAN_FRAME_LEN
;
889 dev_info
->max_rx_queues
= RTE_PMD_TAP_MAX_QUEUES
;
890 dev_info
->max_tx_queues
= RTE_PMD_TAP_MAX_QUEUES
;
891 dev_info
->min_rx_bufsize
= 0;
892 dev_info
->speed_capa
= tap_dev_speed_capa();
893 dev_info
->rx_queue_offload_capa
= tap_rx_offload_get_queue_capa();
894 dev_info
->rx_offload_capa
= tap_rx_offload_get_port_capa() |
895 dev_info
->rx_queue_offload_capa
;
896 dev_info
->tx_queue_offload_capa
= tap_tx_offload_get_queue_capa();
897 dev_info
->tx_offload_capa
= tap_tx_offload_get_port_capa() |
898 dev_info
->tx_queue_offload_capa
;
899 dev_info
->hash_key_size
= TAP_RSS_HASH_KEY_SIZE
;
901 * limitation: TAP supports all of IP, UDP and TCP hash
902 * functions together and not in partial combinations
904 dev_info
->flow_type_rss_offloads
= ~TAP_RSS_HF_MASK
;
908 tap_stats_get(struct rte_eth_dev
*dev
, struct rte_eth_stats
*tap_stats
)
910 unsigned int i
, imax
;
911 unsigned long rx_total
= 0, tx_total
= 0, tx_err_total
= 0;
912 unsigned long rx_bytes_total
= 0, tx_bytes_total
= 0;
913 unsigned long rx_nombuf
= 0, ierrors
= 0;
914 const struct pmd_internals
*pmd
= dev
->data
->dev_private
;
916 /* rx queue statistics */
917 imax
= (dev
->data
->nb_rx_queues
< RTE_ETHDEV_QUEUE_STAT_CNTRS
) ?
918 dev
->data
->nb_rx_queues
: RTE_ETHDEV_QUEUE_STAT_CNTRS
;
919 for (i
= 0; i
< imax
; i
++) {
920 tap_stats
->q_ipackets
[i
] = pmd
->rxq
[i
].stats
.ipackets
;
921 tap_stats
->q_ibytes
[i
] = pmd
->rxq
[i
].stats
.ibytes
;
922 rx_total
+= tap_stats
->q_ipackets
[i
];
923 rx_bytes_total
+= tap_stats
->q_ibytes
[i
];
924 rx_nombuf
+= pmd
->rxq
[i
].stats
.rx_nombuf
;
925 ierrors
+= pmd
->rxq
[i
].stats
.ierrors
;
928 /* tx queue statistics */
929 imax
= (dev
->data
->nb_tx_queues
< RTE_ETHDEV_QUEUE_STAT_CNTRS
) ?
930 dev
->data
->nb_tx_queues
: RTE_ETHDEV_QUEUE_STAT_CNTRS
;
932 for (i
= 0; i
< imax
; i
++) {
933 tap_stats
->q_opackets
[i
] = pmd
->txq
[i
].stats
.opackets
;
934 tap_stats
->q_errors
[i
] = pmd
->txq
[i
].stats
.errs
;
935 tap_stats
->q_obytes
[i
] = pmd
->txq
[i
].stats
.obytes
;
936 tx_total
+= tap_stats
->q_opackets
[i
];
937 tx_err_total
+= tap_stats
->q_errors
[i
];
938 tx_bytes_total
+= tap_stats
->q_obytes
[i
];
941 tap_stats
->ipackets
= rx_total
;
942 tap_stats
->ibytes
= rx_bytes_total
;
943 tap_stats
->ierrors
= ierrors
;
944 tap_stats
->rx_nombuf
= rx_nombuf
;
945 tap_stats
->opackets
= tx_total
;
946 tap_stats
->oerrors
= tx_err_total
;
947 tap_stats
->obytes
= tx_bytes_total
;
952 tap_stats_reset(struct rte_eth_dev
*dev
)
955 struct pmd_internals
*pmd
= dev
->data
->dev_private
;
957 for (i
= 0; i
< RTE_PMD_TAP_MAX_QUEUES
; i
++) {
958 pmd
->rxq
[i
].stats
.ipackets
= 0;
959 pmd
->rxq
[i
].stats
.ibytes
= 0;
960 pmd
->rxq
[i
].stats
.ierrors
= 0;
961 pmd
->rxq
[i
].stats
.rx_nombuf
= 0;
963 pmd
->txq
[i
].stats
.opackets
= 0;
964 pmd
->txq
[i
].stats
.errs
= 0;
965 pmd
->txq
[i
].stats
.obytes
= 0;
970 tap_dev_close(struct rte_eth_dev
*dev
)
973 struct pmd_internals
*internals
= dev
->data
->dev_private
;
975 tap_link_set_down(dev
);
976 tap_flow_flush(dev
, NULL
);
977 tap_flow_implicit_flush(internals
, NULL
);
979 for (i
= 0; i
< RTE_PMD_TAP_MAX_QUEUES
; i
++) {
980 if (internals
->rxq
[i
].fd
!= -1) {
981 close(internals
->rxq
[i
].fd
);
982 internals
->rxq
[i
].fd
= -1;
984 if (internals
->txq
[i
].fd
!= -1) {
985 close(internals
->txq
[i
].fd
);
986 internals
->txq
[i
].fd
= -1;
990 if (internals
->remote_if_index
) {
991 /* Restore initial remote state */
992 ioctl(internals
->ioctl_sock
, SIOCSIFFLAGS
,
993 &internals
->remote_initial_flags
);
996 if (internals
->ka_fd
!= -1) {
997 close(internals
->ka_fd
);
998 internals
->ka_fd
= -1;
1001 * Since TUN device has no more opened file descriptors
1002 * it will be removed from kernel
1007 tap_rx_queue_release(void *queue
)
1009 struct rx_queue
*rxq
= queue
;
1011 if (rxq
&& (rxq
->fd
> 0)) {
1014 rte_pktmbuf_free(rxq
->pool
);
1015 rte_free(rxq
->iovecs
);
1022 tap_tx_queue_release(void *queue
)
1024 struct tx_queue
*txq
= queue
;
1026 if (txq
&& (txq
->fd
> 0)) {
1033 tap_link_update(struct rte_eth_dev
*dev
, int wait_to_complete __rte_unused
)
1035 struct rte_eth_link
*dev_link
= &dev
->data
->dev_link
;
1036 struct pmd_internals
*pmd
= dev
->data
->dev_private
;
1037 struct ifreq ifr
= { .ifr_flags
= 0 };
1039 if (pmd
->remote_if_index
) {
1040 tap_ioctl(pmd
, SIOCGIFFLAGS
, &ifr
, 0, REMOTE_ONLY
);
1041 if (!(ifr
.ifr_flags
& IFF_UP
) ||
1042 !(ifr
.ifr_flags
& IFF_RUNNING
)) {
1043 dev_link
->link_status
= ETH_LINK_DOWN
;
1047 tap_ioctl(pmd
, SIOCGIFFLAGS
, &ifr
, 0, LOCAL_ONLY
);
1048 dev_link
->link_status
=
1049 ((ifr
.ifr_flags
& IFF_UP
) && (ifr
.ifr_flags
& IFF_RUNNING
) ?
1056 tap_promisc_enable(struct rte_eth_dev
*dev
)
1058 struct pmd_internals
*pmd
= dev
->data
->dev_private
;
1059 struct ifreq ifr
= { .ifr_flags
= IFF_PROMISC
};
1061 dev
->data
->promiscuous
= 1;
1062 tap_ioctl(pmd
, SIOCSIFFLAGS
, &ifr
, 1, LOCAL_AND_REMOTE
);
1063 if (pmd
->remote_if_index
&& !pmd
->flow_isolate
)
1064 tap_flow_implicit_create(pmd
, TAP_REMOTE_PROMISC
);
1068 tap_promisc_disable(struct rte_eth_dev
*dev
)
1070 struct pmd_internals
*pmd
= dev
->data
->dev_private
;
1071 struct ifreq ifr
= { .ifr_flags
= IFF_PROMISC
};
1073 dev
->data
->promiscuous
= 0;
1074 tap_ioctl(pmd
, SIOCSIFFLAGS
, &ifr
, 0, LOCAL_AND_REMOTE
);
1075 if (pmd
->remote_if_index
&& !pmd
->flow_isolate
)
1076 tap_flow_implicit_destroy(pmd
, TAP_REMOTE_PROMISC
);
1080 tap_allmulti_enable(struct rte_eth_dev
*dev
)
1082 struct pmd_internals
*pmd
= dev
->data
->dev_private
;
1083 struct ifreq ifr
= { .ifr_flags
= IFF_ALLMULTI
};
1085 dev
->data
->all_multicast
= 1;
1086 tap_ioctl(pmd
, SIOCSIFFLAGS
, &ifr
, 1, LOCAL_AND_REMOTE
);
1087 if (pmd
->remote_if_index
&& !pmd
->flow_isolate
)
1088 tap_flow_implicit_create(pmd
, TAP_REMOTE_ALLMULTI
);
1092 tap_allmulti_disable(struct rte_eth_dev
*dev
)
1094 struct pmd_internals
*pmd
= dev
->data
->dev_private
;
1095 struct ifreq ifr
= { .ifr_flags
= IFF_ALLMULTI
};
1097 dev
->data
->all_multicast
= 0;
1098 tap_ioctl(pmd
, SIOCSIFFLAGS
, &ifr
, 0, LOCAL_AND_REMOTE
);
1099 if (pmd
->remote_if_index
&& !pmd
->flow_isolate
)
1100 tap_flow_implicit_destroy(pmd
, TAP_REMOTE_ALLMULTI
);
1104 tap_mac_set(struct rte_eth_dev
*dev
, struct ether_addr
*mac_addr
)
1106 struct pmd_internals
*pmd
= dev
->data
->dev_private
;
1107 enum ioctl_mode mode
= LOCAL_ONLY
;
1111 if (pmd
->type
== ETH_TUNTAP_TYPE_TUN
) {
1112 TAP_LOG(ERR
, "%s: can't MAC address for TUN",
1117 if (is_zero_ether_addr(mac_addr
)) {
1118 TAP_LOG(ERR
, "%s: can't set an empty MAC address",
1122 /* Check the actual current MAC address on the tap netdevice */
1123 ret
= tap_ioctl(pmd
, SIOCGIFHWADDR
, &ifr
, 0, LOCAL_ONLY
);
1126 if (is_same_ether_addr((struct ether_addr
*)&ifr
.ifr_hwaddr
.sa_data
,
1129 /* Check the current MAC address on the remote */
1130 ret
= tap_ioctl(pmd
, SIOCGIFHWADDR
, &ifr
, 0, REMOTE_ONLY
);
1133 if (!is_same_ether_addr((struct ether_addr
*)&ifr
.ifr_hwaddr
.sa_data
,
1135 mode
= LOCAL_AND_REMOTE
;
1136 ifr
.ifr_hwaddr
.sa_family
= AF_LOCAL
;
1137 rte_memcpy(ifr
.ifr_hwaddr
.sa_data
, mac_addr
, ETHER_ADDR_LEN
);
1138 ret
= tap_ioctl(pmd
, SIOCSIFHWADDR
, &ifr
, 1, mode
);
1141 rte_memcpy(&pmd
->eth_addr
, mac_addr
, ETHER_ADDR_LEN
);
1142 if (pmd
->remote_if_index
&& !pmd
->flow_isolate
) {
1143 /* Replace MAC redirection rule after a MAC change */
1144 ret
= tap_flow_implicit_destroy(pmd
, TAP_REMOTE_LOCAL_MAC
);
1147 "%s: Couldn't delete MAC redirection rule",
1151 ret
= tap_flow_implicit_create(pmd
, TAP_REMOTE_LOCAL_MAC
);
1154 "%s: Couldn't add MAC redirection rule",
1164 tap_gso_ctx_setup(struct rte_gso_ctx
*gso_ctx
, struct rte_eth_dev
*dev
)
1170 * Create private mbuf pool with TAP_GSO_MBUF_SEG_SIZE bytes
1171 * size per mbuf use this pool for both direct and indirect mbufs
1174 struct rte_mempool
*mp
; /* Mempool for GSO packets */
1176 /* initialize GSO context */
1177 gso_types
= DEV_TX_OFFLOAD_TCP_TSO
;
1178 snprintf(pool_name
, sizeof(pool_name
), "mp_%s", dev
->device
->name
);
1179 mp
= rte_mempool_lookup((const char *)pool_name
);
1181 mp
= rte_pktmbuf_pool_create(pool_name
, TAP_GSO_MBUFS_NUM
,
1182 TAP_GSO_MBUF_CACHE_SIZE
, 0,
1183 RTE_PKTMBUF_HEADROOM
+ TAP_GSO_MBUF_SEG_SIZE
,
1186 struct pmd_internals
*pmd
= dev
->data
->dev_private
;
1187 RTE_LOG(DEBUG
, PMD
, "%s: failed to create mbuf pool for device %s\n",
1188 pmd
->name
, dev
->device
->name
);
1193 gso_ctx
->direct_pool
= mp
;
1194 gso_ctx
->indirect_pool
= mp
;
1195 gso_ctx
->gso_types
= gso_types
;
1196 gso_ctx
->gso_size
= 0; /* gso_size is set in tx_burst() per packet */
1203 tap_setup_queue(struct rte_eth_dev
*dev
,
1204 struct pmd_internals
*internals
,
1212 struct pmd_internals
*pmd
= dev
->data
->dev_private
;
1213 struct rx_queue
*rx
= &internals
->rxq
[qid
];
1214 struct tx_queue
*tx
= &internals
->txq
[qid
];
1215 struct rte_gso_ctx
*gso_ctx
;
1226 gso_ctx
= &tx
->gso_ctx
;
1229 /* fd for this queue already exists */
1230 TAP_LOG(DEBUG
, "%s: fd %d for %s queue qid %d exists",
1231 pmd
->name
, *fd
, dir
, qid
);
1233 } else if (*other_fd
!= -1) {
1234 /* Only other_fd exists. dup it */
1235 *fd
= dup(*other_fd
);
1238 TAP_LOG(ERR
, "%s: dup() failed.", pmd
->name
);
1241 TAP_LOG(DEBUG
, "%s: dup fd %d for %s queue qid %d (%d)",
1242 pmd
->name
, *other_fd
, dir
, qid
, *fd
);
1244 /* Both RX and TX fds do not exist (equal -1). Create fd */
1245 *fd
= tun_alloc(pmd
, 0);
1247 *fd
= -1; /* restore original value */
1248 TAP_LOG(ERR
, "%s: tun_alloc() failed.", pmd
->name
);
1251 TAP_LOG(DEBUG
, "%s: add %s queue for qid %d fd %d",
1252 pmd
->name
, dir
, qid
, *fd
);
1255 tx
->mtu
= &dev
->data
->mtu
;
1256 rx
->rxmode
= &dev
->data
->dev_conf
.rxmode
;
1258 ret
= tap_gso_ctx_setup(gso_ctx
, dev
);
1263 tx
->type
= pmd
->type
;
1269 tap_rx_queue_setup(struct rte_eth_dev
*dev
,
1270 uint16_t rx_queue_id
,
1271 uint16_t nb_rx_desc
,
1272 unsigned int socket_id
,
1273 const struct rte_eth_rxconf
*rx_conf __rte_unused
,
1274 struct rte_mempool
*mp
)
1276 struct pmd_internals
*internals
= dev
->data
->dev_private
;
1277 struct rx_queue
*rxq
= &internals
->rxq
[rx_queue_id
];
1278 struct rte_mbuf
**tmp
= &rxq
->pool
;
1279 long iov_max
= sysconf(_SC_IOV_MAX
);
1280 uint16_t nb_desc
= RTE_MIN(nb_rx_desc
, iov_max
- 1);
1281 struct iovec (*iovecs
)[nb_desc
+ 1];
1282 int data_off
= RTE_PKTMBUF_HEADROOM
;
1287 if (rx_queue_id
>= dev
->data
->nb_rx_queues
|| !mp
) {
1289 "nb_rx_queues %d too small or mempool NULL",
1290 dev
->data
->nb_rx_queues
);
1295 rxq
->trigger_seen
= 1; /* force initial burst */
1296 rxq
->in_port
= dev
->data
->port_id
;
1297 rxq
->nb_rx_desc
= nb_desc
;
1298 iovecs
= rte_zmalloc_socket(dev
->device
->name
, sizeof(*iovecs
), 0,
1302 "%s: Couldn't allocate %d RX descriptors",
1303 dev
->device
->name
, nb_desc
);
1306 rxq
->iovecs
= iovecs
;
1308 dev
->data
->rx_queues
[rx_queue_id
] = rxq
;
1309 fd
= tap_setup_queue(dev
, internals
, rx_queue_id
, 1);
1315 (*rxq
->iovecs
)[0].iov_len
= sizeof(struct tun_pi
);
1316 (*rxq
->iovecs
)[0].iov_base
= &rxq
->pi
;
1318 for (i
= 1; i
<= nb_desc
; i
++) {
1319 *tmp
= rte_pktmbuf_alloc(rxq
->mp
);
1322 "%s: couldn't allocate memory for queue %d",
1323 dev
->device
->name
, rx_queue_id
);
1327 (*rxq
->iovecs
)[i
].iov_len
= (*tmp
)->buf_len
- data_off
;
1328 (*rxq
->iovecs
)[i
].iov_base
=
1329 (char *)(*tmp
)->buf_addr
+ data_off
;
1331 tmp
= &(*tmp
)->next
;
1334 TAP_LOG(DEBUG
, " RX TUNTAP device name %s, qid %d on fd %d",
1335 internals
->name
, rx_queue_id
, internals
->rxq
[rx_queue_id
].fd
);
1340 rte_pktmbuf_free(rxq
->pool
);
1342 rte_free(rxq
->iovecs
);
1348 tap_tx_queue_setup(struct rte_eth_dev
*dev
,
1349 uint16_t tx_queue_id
,
1350 uint16_t nb_tx_desc __rte_unused
,
1351 unsigned int socket_id __rte_unused
,
1352 const struct rte_eth_txconf
*tx_conf
)
1354 struct pmd_internals
*internals
= dev
->data
->dev_private
;
1355 struct tx_queue
*txq
;
1359 if (tx_queue_id
>= dev
->data
->nb_tx_queues
)
1361 dev
->data
->tx_queues
[tx_queue_id
] = &internals
->txq
[tx_queue_id
];
1362 txq
= dev
->data
->tx_queues
[tx_queue_id
];
1364 offloads
= tx_conf
->offloads
| dev
->data
->dev_conf
.txmode
.offloads
;
1365 txq
->csum
= !!(offloads
&
1366 (DEV_TX_OFFLOAD_IPV4_CKSUM
|
1367 DEV_TX_OFFLOAD_UDP_CKSUM
|
1368 DEV_TX_OFFLOAD_TCP_CKSUM
));
1370 ret
= tap_setup_queue(dev
, internals
, tx_queue_id
, 0);
1374 " TX TUNTAP device name %s, qid %d on fd %d csum %s",
1375 internals
->name
, tx_queue_id
, internals
->txq
[tx_queue_id
].fd
,
1376 txq
->csum
? "on" : "off");
1382 tap_mtu_set(struct rte_eth_dev
*dev
, uint16_t mtu
)
1384 struct pmd_internals
*pmd
= dev
->data
->dev_private
;
1385 struct ifreq ifr
= { .ifr_mtu
= mtu
};
1388 err
= tap_ioctl(pmd
, SIOCSIFMTU
, &ifr
, 1, LOCAL_AND_REMOTE
);
1390 dev
->data
->mtu
= mtu
;
1396 tap_set_mc_addr_list(struct rte_eth_dev
*dev __rte_unused
,
1397 struct ether_addr
*mc_addr_set __rte_unused
,
1398 uint32_t nb_mc_addr __rte_unused
)
1401 * Nothing to do actually: the tap has no filtering whatsoever, every
1402 * packet is received.
1408 tap_nl_msg_handler(struct nlmsghdr
*nh
, void *arg
)
1410 struct rte_eth_dev
*dev
= arg
;
1411 struct pmd_internals
*pmd
= dev
->data
->dev_private
;
1412 struct ifinfomsg
*info
= NLMSG_DATA(nh
);
1414 if (nh
->nlmsg_type
!= RTM_NEWLINK
||
1415 (info
->ifi_index
!= pmd
->if_index
&&
1416 info
->ifi_index
!= pmd
->remote_if_index
))
1418 return tap_link_update(dev
, 0);
1422 tap_dev_intr_handler(void *cb_arg
)
1424 struct rte_eth_dev
*dev
= cb_arg
;
1425 struct pmd_internals
*pmd
= dev
->data
->dev_private
;
1427 tap_nl_recv(pmd
->intr_handle
.fd
, tap_nl_msg_handler
, dev
);
1431 tap_lsc_intr_handle_set(struct rte_eth_dev
*dev
, int set
)
1433 struct pmd_internals
*pmd
= dev
->data
->dev_private
;
1435 /* In any case, disable interrupt if the conf is no longer there. */
1436 if (!dev
->data
->dev_conf
.intr_conf
.lsc
) {
1437 if (pmd
->intr_handle
.fd
!= -1) {
1438 tap_nl_final(pmd
->intr_handle
.fd
);
1439 rte_intr_callback_unregister(&pmd
->intr_handle
,
1440 tap_dev_intr_handler
, dev
);
1445 pmd
->intr_handle
.fd
= tap_nl_init(RTMGRP_LINK
);
1446 if (unlikely(pmd
->intr_handle
.fd
== -1))
1448 return rte_intr_callback_register(
1449 &pmd
->intr_handle
, tap_dev_intr_handler
, dev
);
1451 tap_nl_final(pmd
->intr_handle
.fd
);
1452 return rte_intr_callback_unregister(&pmd
->intr_handle
,
1453 tap_dev_intr_handler
, dev
);
1457 tap_intr_handle_set(struct rte_eth_dev
*dev
, int set
)
1461 err
= tap_lsc_intr_handle_set(dev
, set
);
1464 err
= tap_rx_intr_vec_set(dev
, set
);
1466 tap_lsc_intr_handle_set(dev
, 0);
1470 static const uint32_t*
1471 tap_dev_supported_ptypes_get(struct rte_eth_dev
*dev __rte_unused
)
1473 static const uint32_t ptypes
[] = {
1474 RTE_PTYPE_INNER_L2_ETHER
,
1475 RTE_PTYPE_INNER_L2_ETHER_VLAN
,
1476 RTE_PTYPE_INNER_L2_ETHER_QINQ
,
1477 RTE_PTYPE_INNER_L3_IPV4
,
1478 RTE_PTYPE_INNER_L3_IPV4_EXT
,
1479 RTE_PTYPE_INNER_L3_IPV6
,
1480 RTE_PTYPE_INNER_L3_IPV6_EXT
,
1481 RTE_PTYPE_INNER_L4_FRAG
,
1482 RTE_PTYPE_INNER_L4_UDP
,
1483 RTE_PTYPE_INNER_L4_TCP
,
1484 RTE_PTYPE_INNER_L4_SCTP
,
1486 RTE_PTYPE_L2_ETHER_VLAN
,
1487 RTE_PTYPE_L2_ETHER_QINQ
,
1489 RTE_PTYPE_L3_IPV4_EXT
,
1490 RTE_PTYPE_L3_IPV6_EXT
,
1502 tap_flow_ctrl_get(struct rte_eth_dev
*dev __rte_unused
,
1503 struct rte_eth_fc_conf
*fc_conf
)
1505 fc_conf
->mode
= RTE_FC_NONE
;
1510 tap_flow_ctrl_set(struct rte_eth_dev
*dev __rte_unused
,
1511 struct rte_eth_fc_conf
*fc_conf
)
1513 if (fc_conf
->mode
!= RTE_FC_NONE
)
1519 * DPDK callback to update the RSS hash configuration.
1522 * Pointer to Ethernet device structure.
1523 * @param[in] rss_conf
1524 * RSS configuration data.
1527 * 0 on success, a negative errno value otherwise and rte_errno is set.
1530 tap_rss_hash_update(struct rte_eth_dev
*dev
,
1531 struct rte_eth_rss_conf
*rss_conf
)
1533 if (rss_conf
->rss_hf
& TAP_RSS_HF_MASK
) {
1537 if (rss_conf
->rss_key
&& rss_conf
->rss_key_len
) {
1539 * Currently TAP RSS key is hard coded
1540 * and cannot be updated
1543 "port %u RSS key cannot be updated",
1544 dev
->data
->port_id
);
1552 tap_rx_queue_start(struct rte_eth_dev
*dev
, uint16_t rx_queue_id
)
1554 dev
->data
->rx_queue_state
[rx_queue_id
] = RTE_ETH_QUEUE_STATE_STARTED
;
1560 tap_tx_queue_start(struct rte_eth_dev
*dev
, uint16_t tx_queue_id
)
1562 dev
->data
->tx_queue_state
[tx_queue_id
] = RTE_ETH_QUEUE_STATE_STARTED
;
1568 tap_rx_queue_stop(struct rte_eth_dev
*dev
, uint16_t rx_queue_id
)
1570 dev
->data
->rx_queue_state
[rx_queue_id
] = RTE_ETH_QUEUE_STATE_STOPPED
;
1576 tap_tx_queue_stop(struct rte_eth_dev
*dev
, uint16_t tx_queue_id
)
1578 dev
->data
->tx_queue_state
[tx_queue_id
] = RTE_ETH_QUEUE_STATE_STOPPED
;
1582 static const struct eth_dev_ops ops
= {
1583 .dev_start
= tap_dev_start
,
1584 .dev_stop
= tap_dev_stop
,
1585 .dev_close
= tap_dev_close
,
1586 .dev_configure
= tap_dev_configure
,
1587 .dev_infos_get
= tap_dev_info
,
1588 .rx_queue_setup
= tap_rx_queue_setup
,
1589 .tx_queue_setup
= tap_tx_queue_setup
,
1590 .rx_queue_start
= tap_rx_queue_start
,
1591 .tx_queue_start
= tap_tx_queue_start
,
1592 .rx_queue_stop
= tap_rx_queue_stop
,
1593 .tx_queue_stop
= tap_tx_queue_stop
,
1594 .rx_queue_release
= tap_rx_queue_release
,
1595 .tx_queue_release
= tap_tx_queue_release
,
1596 .flow_ctrl_get
= tap_flow_ctrl_get
,
1597 .flow_ctrl_set
= tap_flow_ctrl_set
,
1598 .link_update
= tap_link_update
,
1599 .dev_set_link_up
= tap_link_set_up
,
1600 .dev_set_link_down
= tap_link_set_down
,
1601 .promiscuous_enable
= tap_promisc_enable
,
1602 .promiscuous_disable
= tap_promisc_disable
,
1603 .allmulticast_enable
= tap_allmulti_enable
,
1604 .allmulticast_disable
= tap_allmulti_disable
,
1605 .mac_addr_set
= tap_mac_set
,
1606 .mtu_set
= tap_mtu_set
,
1607 .set_mc_addr_list
= tap_set_mc_addr_list
,
1608 .stats_get
= tap_stats_get
,
1609 .stats_reset
= tap_stats_reset
,
1610 .dev_supported_ptypes_get
= tap_dev_supported_ptypes_get
,
1611 .rss_hash_update
= tap_rss_hash_update
,
1612 .filter_ctrl
= tap_dev_filter_ctrl
,
1616 eth_dev_tap_create(struct rte_vdev_device
*vdev
, char *tap_name
,
1617 char *remote_iface
, struct ether_addr
*mac_addr
,
1618 enum rte_tuntap_type type
)
1620 int numa_node
= rte_socket_id();
1621 struct rte_eth_dev
*dev
;
1622 struct pmd_internals
*pmd
;
1623 struct rte_eth_dev_data
*data
;
1627 TAP_LOG(DEBUG
, "%s device on numa %u",
1628 tuntap_name
, rte_socket_id());
1630 dev
= rte_eth_vdev_allocate(vdev
, sizeof(*pmd
));
1632 TAP_LOG(ERR
, "%s Unable to allocate device struct",
1634 goto error_exit_nodev
;
1637 pmd
= dev
->data
->dev_private
;
1639 snprintf(pmd
->name
, sizeof(pmd
->name
), "%s", tap_name
);
1642 pmd
->ioctl_sock
= socket(AF_INET
, SOCK_DGRAM
, 0);
1643 if (pmd
->ioctl_sock
== -1) {
1645 "%s Unable to get a socket for management: %s",
1646 tuntap_name
, strerror(errno
));
1650 /* Setup some default values */
1652 data
->dev_private
= pmd
;
1653 data
->dev_flags
= RTE_ETH_DEV_INTR_LSC
;
1654 data
->numa_node
= numa_node
;
1656 data
->dev_link
= pmd_link
;
1657 data
->mac_addrs
= &pmd
->eth_addr
;
1658 /* Set the number of RX and TX queues */
1659 data
->nb_rx_queues
= 0;
1660 data
->nb_tx_queues
= 0;
1662 dev
->dev_ops
= &ops
;
1663 dev
->rx_pkt_burst
= pmd_rx_burst
;
1664 dev
->tx_pkt_burst
= pmd_tx_burst
;
1666 pmd
->intr_handle
.type
= RTE_INTR_HANDLE_EXT
;
1667 pmd
->intr_handle
.fd
= -1;
1668 dev
->intr_handle
= &pmd
->intr_handle
;
1670 /* Presetup the fds to -1 as being not valid */
1672 for (i
= 0; i
< RTE_PMD_TAP_MAX_QUEUES
; i
++) {
1673 pmd
->rxq
[i
].fd
= -1;
1674 pmd
->txq
[i
].fd
= -1;
1677 if (pmd
->type
== ETH_TUNTAP_TYPE_TAP
) {
1678 if (is_zero_ether_addr(mac_addr
))
1679 eth_random_addr((uint8_t *)&pmd
->eth_addr
);
1681 rte_memcpy(&pmd
->eth_addr
, mac_addr
, sizeof(*mac_addr
));
1685 * Allocate a TUN device keep-alive file descriptor that will only be
1686 * closed when the TUN device itself is closed or removed.
1687 * This keep-alive file descriptor will guarantee that the TUN device
1688 * exists even when all of its queues are closed
1690 pmd
->ka_fd
= tun_alloc(pmd
, 1);
1691 if (pmd
->ka_fd
== -1) {
1692 TAP_LOG(ERR
, "Unable to create %s interface", tuntap_name
);
1696 ifr
.ifr_mtu
= dev
->data
->mtu
;
1697 if (tap_ioctl(pmd
, SIOCSIFMTU
, &ifr
, 1, LOCAL_AND_REMOTE
) < 0)
1700 if (pmd
->type
== ETH_TUNTAP_TYPE_TAP
) {
1701 memset(&ifr
, 0, sizeof(struct ifreq
));
1702 ifr
.ifr_hwaddr
.sa_family
= AF_LOCAL
;
1703 rte_memcpy(ifr
.ifr_hwaddr
.sa_data
, &pmd
->eth_addr
,
1705 if (tap_ioctl(pmd
, SIOCSIFHWADDR
, &ifr
, 0, LOCAL_ONLY
) < 0)
1710 * Set up everything related to rte_flow:
1712 * - tap / remote if_index
1713 * - mandatory QDISCs
1714 * - rte_flow actual/implicit lists
1717 pmd
->nlsk_fd
= tap_nl_init(0);
1718 if (pmd
->nlsk_fd
== -1) {
1719 TAP_LOG(WARNING
, "%s: failed to create netlink socket.",
1721 goto disable_rte_flow
;
1723 pmd
->if_index
= if_nametoindex(pmd
->name
);
1724 if (!pmd
->if_index
) {
1725 TAP_LOG(ERR
, "%s: failed to get if_index.", pmd
->name
);
1726 goto disable_rte_flow
;
1728 if (qdisc_create_multiq(pmd
->nlsk_fd
, pmd
->if_index
) < 0) {
1729 TAP_LOG(ERR
, "%s: failed to create multiq qdisc.",
1731 goto disable_rte_flow
;
1733 if (qdisc_create_ingress(pmd
->nlsk_fd
, pmd
->if_index
) < 0) {
1734 TAP_LOG(ERR
, "%s: failed to create ingress qdisc.",
1736 goto disable_rte_flow
;
1738 LIST_INIT(&pmd
->flows
);
1740 if (strlen(remote_iface
)) {
1741 pmd
->remote_if_index
= if_nametoindex(remote_iface
);
1742 if (!pmd
->remote_if_index
) {
1743 TAP_LOG(ERR
, "%s: failed to get %s if_index.",
1744 pmd
->name
, remote_iface
);
1747 snprintf(pmd
->remote_iface
, RTE_ETH_NAME_MAX_LEN
,
1748 "%s", remote_iface
);
1750 /* Save state of remote device */
1751 tap_ioctl(pmd
, SIOCGIFFLAGS
, &pmd
->remote_initial_flags
, 0, REMOTE_ONLY
);
1753 /* Replicate remote MAC address */
1754 if (tap_ioctl(pmd
, SIOCGIFHWADDR
, &ifr
, 0, REMOTE_ONLY
) < 0) {
1755 TAP_LOG(ERR
, "%s: failed to get %s MAC address.",
1756 pmd
->name
, pmd
->remote_iface
);
1759 rte_memcpy(&pmd
->eth_addr
, ifr
.ifr_hwaddr
.sa_data
,
1761 /* The desired MAC is already in ifreq after SIOCGIFHWADDR. */
1762 if (tap_ioctl(pmd
, SIOCSIFHWADDR
, &ifr
, 0, LOCAL_ONLY
) < 0) {
1763 TAP_LOG(ERR
, "%s: failed to get %s MAC address.",
1764 pmd
->name
, remote_iface
);
1769 * Flush usually returns negative value because it tries to
1770 * delete every QDISC (and on a running device, one QDISC at
1771 * least is needed). Ignore negative return value.
1773 qdisc_flush(pmd
->nlsk_fd
, pmd
->remote_if_index
);
1774 if (qdisc_create_ingress(pmd
->nlsk_fd
,
1775 pmd
->remote_if_index
) < 0) {
1776 TAP_LOG(ERR
, "%s: failed to create ingress qdisc.",
1780 LIST_INIT(&pmd
->implicit_flows
);
1781 if (tap_flow_implicit_create(pmd
, TAP_REMOTE_TX
) < 0 ||
1782 tap_flow_implicit_create(pmd
, TAP_REMOTE_LOCAL_MAC
) < 0 ||
1783 tap_flow_implicit_create(pmd
, TAP_REMOTE_BROADCAST
) < 0 ||
1784 tap_flow_implicit_create(pmd
, TAP_REMOTE_BROADCASTV6
) < 0) {
1786 "%s: failed to create implicit rules.",
1792 rte_eth_dev_probing_finish(dev
);
1796 TAP_LOG(ERR
, " Disabling rte flow support: %s(%d)",
1797 strerror(errno
), errno
);
1798 if (strlen(remote_iface
)) {
1799 TAP_LOG(ERR
, "Remote feature requires flow support.");
1805 TAP_LOG(ERR
, " Can't set up remote feature: %s(%d)",
1806 strerror(errno
), errno
);
1807 tap_flow_implicit_flush(pmd
, NULL
);
1810 if (pmd
->ioctl_sock
> 0)
1811 close(pmd
->ioctl_sock
);
1812 rte_eth_dev_release_port(dev
);
1815 TAP_LOG(ERR
, "%s Unable to initialize %s",
1816 tuntap_name
, rte_vdev_device_name(vdev
));
1822 set_interface_name(const char *key __rte_unused
,
1826 char *name
= (char *)extra_args
;
1829 strlcpy(name
, value
, RTE_ETH_NAME_MAX_LEN
- 1);
1831 snprintf(name
, RTE_ETH_NAME_MAX_LEN
- 1, "%s%d",
1832 DEFAULT_TAP_NAME
, (tap_unit
- 1));
1838 set_remote_iface(const char *key __rte_unused
,
1842 char *name
= (char *)extra_args
;
1845 strlcpy(name
, value
, RTE_ETH_NAME_MAX_LEN
);
1850 static int parse_user_mac(struct ether_addr
*user_mac
,
1853 unsigned int index
= 0;
1854 char mac_temp
[strlen(ETH_TAP_USR_MAC_FMT
) + 1], *mac_byte
= NULL
;
1856 if (user_mac
== NULL
|| value
== NULL
)
1859 strlcpy(mac_temp
, value
, sizeof(mac_temp
));
1860 mac_byte
= strtok(mac_temp
, ":");
1862 while ((mac_byte
!= NULL
) &&
1863 (strlen(mac_byte
) <= 2) &&
1864 (strlen(mac_byte
) == strspn(mac_byte
,
1865 ETH_TAP_CMP_MAC_FMT
))) {
1866 user_mac
->addr_bytes
[index
++] = strtoul(mac_byte
, NULL
, 16);
1867 mac_byte
= strtok(NULL
, ":");
1874 set_mac_type(const char *key __rte_unused
,
1878 struct ether_addr
*user_mac
= extra_args
;
1883 if (!strncasecmp(ETH_TAP_MAC_FIXED
, value
, strlen(ETH_TAP_MAC_FIXED
))) {
1884 static int iface_idx
;
1886 /* fixed mac = 00:64:74:61:70:<iface_idx> */
1887 memcpy((char *)user_mac
->addr_bytes
, "\0dtap", ETHER_ADDR_LEN
);
1888 user_mac
->addr_bytes
[ETHER_ADDR_LEN
- 1] = iface_idx
++ + '0';
1892 if (parse_user_mac(user_mac
, value
) != 6)
1895 TAP_LOG(DEBUG
, "TAP user MAC param (%s)", value
);
1899 TAP_LOG(ERR
, "TAP user MAC (%s) is not in format (%s|%s)",
1900 value
, ETH_TAP_MAC_FIXED
, ETH_TAP_USR_MAC_FMT
);
1905 * Open a TUN interface device. TUN PMD
1906 * 1) sets tap_type as false
1907 * 2) intakes iface as argument.
1908 * 3) as interface is virtual set speed to 10G
1911 rte_pmd_tun_probe(struct rte_vdev_device
*dev
)
1913 const char *name
, *params
;
1915 struct rte_kvargs
*kvlist
= NULL
;
1916 char tun_name
[RTE_ETH_NAME_MAX_LEN
];
1917 char remote_iface
[RTE_ETH_NAME_MAX_LEN
];
1918 struct rte_eth_dev
*eth_dev
;
1920 strcpy(tuntap_name
, "TUN");
1922 name
= rte_vdev_device_name(dev
);
1923 params
= rte_vdev_device_args(dev
);
1924 memset(remote_iface
, 0, RTE_ETH_NAME_MAX_LEN
);
1926 if (rte_eal_process_type() == RTE_PROC_SECONDARY
&&
1927 strlen(params
) == 0) {
1928 eth_dev
= rte_eth_dev_attach_secondary(name
);
1930 TAP_LOG(ERR
, "Failed to probe %s", name
);
1933 eth_dev
->dev_ops
= &ops
;
1934 eth_dev
->device
= &dev
->device
;
1935 rte_eth_dev_probing_finish(eth_dev
);
1939 snprintf(tun_name
, sizeof(tun_name
), "%s%u",
1940 DEFAULT_TUN_NAME
, tun_unit
++);
1942 if (params
&& (params
[0] != '\0')) {
1943 TAP_LOG(DEBUG
, "parameters (%s)", params
);
1945 kvlist
= rte_kvargs_parse(params
, valid_arguments
);
1947 if (rte_kvargs_count(kvlist
, ETH_TAP_IFACE_ARG
) == 1) {
1948 ret
= rte_kvargs_process(kvlist
,
1950 &set_interface_name
,
1958 pmd_link
.link_speed
= ETH_SPEED_NUM_10G
;
1960 TAP_LOG(NOTICE
, "Initializing pmd_tun for %s as %s",
1963 ret
= eth_dev_tap_create(dev
, tun_name
, remote_iface
, 0,
1964 ETH_TUNTAP_TYPE_TUN
);
1968 TAP_LOG(ERR
, "Failed to create pmd for %s as %s",
1970 tun_unit
--; /* Restore the unit number */
1972 rte_kvargs_free(kvlist
);
1977 /* Open a TAP interface device.
1980 rte_pmd_tap_probe(struct rte_vdev_device
*dev
)
1982 const char *name
, *params
;
1984 struct rte_kvargs
*kvlist
= NULL
;
1986 char tap_name
[RTE_ETH_NAME_MAX_LEN
];
1987 char remote_iface
[RTE_ETH_NAME_MAX_LEN
];
1988 struct ether_addr user_mac
= { .addr_bytes
= {0} };
1989 struct rte_eth_dev
*eth_dev
;
1991 strcpy(tuntap_name
, "TAP");
1993 name
= rte_vdev_device_name(dev
);
1994 params
= rte_vdev_device_args(dev
);
1996 if (rte_eal_process_type() == RTE_PROC_SECONDARY
&&
1997 strlen(params
) == 0) {
1998 eth_dev
= rte_eth_dev_attach_secondary(name
);
2000 TAP_LOG(ERR
, "Failed to probe %s", name
);
2003 /* TODO: request info from primary to set up Rx and Tx */
2004 eth_dev
->dev_ops
= &ops
;
2005 eth_dev
->device
= &dev
->device
;
2006 rte_eth_dev_probing_finish(eth_dev
);
2010 speed
= ETH_SPEED_NUM_10G
;
2011 snprintf(tap_name
, sizeof(tap_name
), "%s%u",
2012 DEFAULT_TAP_NAME
, tap_unit
++);
2013 memset(remote_iface
, 0, RTE_ETH_NAME_MAX_LEN
);
2015 if (params
&& (params
[0] != '\0')) {
2016 TAP_LOG(DEBUG
, "parameters (%s)", params
);
2018 kvlist
= rte_kvargs_parse(params
, valid_arguments
);
2020 if (rte_kvargs_count(kvlist
, ETH_TAP_IFACE_ARG
) == 1) {
2021 ret
= rte_kvargs_process(kvlist
,
2023 &set_interface_name
,
2029 if (rte_kvargs_count(kvlist
, ETH_TAP_REMOTE_ARG
) == 1) {
2030 ret
= rte_kvargs_process(kvlist
,
2038 if (rte_kvargs_count(kvlist
, ETH_TAP_MAC_ARG
) == 1) {
2039 ret
= rte_kvargs_process(kvlist
,
2048 pmd_link
.link_speed
= speed
;
2050 TAP_LOG(NOTICE
, "Initializing pmd_tap for %s as %s",
2053 ret
= eth_dev_tap_create(dev
, tap_name
, remote_iface
, &user_mac
,
2054 ETH_TUNTAP_TYPE_TAP
);
2058 TAP_LOG(ERR
, "Failed to create pmd for %s as %s",
2060 tap_unit
--; /* Restore the unit number */
2062 rte_kvargs_free(kvlist
);
2067 /* detach a TUNTAP device.
2070 rte_pmd_tap_remove(struct rte_vdev_device
*dev
)
2072 struct rte_eth_dev
*eth_dev
= NULL
;
2073 struct pmd_internals
*internals
;
2076 /* find the ethdev entry */
2077 eth_dev
= rte_eth_dev_allocated(rte_vdev_device_name(dev
));
2081 internals
= eth_dev
->data
->dev_private
;
2083 TAP_LOG(DEBUG
, "Closing %s Ethernet device on numa %u",
2084 (internals
->type
== ETH_TUNTAP_TYPE_TAP
) ? "TAP" : "TUN",
2087 if (internals
->nlsk_fd
) {
2088 tap_flow_flush(eth_dev
, NULL
);
2089 tap_flow_implicit_flush(internals
, NULL
);
2090 tap_nl_final(internals
->nlsk_fd
);
2092 for (i
= 0; i
< RTE_PMD_TAP_MAX_QUEUES
; i
++) {
2093 if (internals
->rxq
[i
].fd
!= -1) {
2094 close(internals
->rxq
[i
].fd
);
2095 internals
->rxq
[i
].fd
= -1;
2097 if (internals
->txq
[i
].fd
!= -1) {
2098 close(internals
->txq
[i
].fd
);
2099 internals
->txq
[i
].fd
= -1;
2103 close(internals
->ioctl_sock
);
2104 rte_free(eth_dev
->data
->dev_private
);
2105 rte_eth_dev_release_port(eth_dev
);
2107 if (internals
->ka_fd
!= -1) {
2108 close(internals
->ka_fd
);
2109 internals
->ka_fd
= -1;
2114 static struct rte_vdev_driver pmd_tun_drv
= {
2115 .probe
= rte_pmd_tun_probe
,
2116 .remove
= rte_pmd_tap_remove
,
2119 static struct rte_vdev_driver pmd_tap_drv
= {
2120 .probe
= rte_pmd_tap_probe
,
2121 .remove
= rte_pmd_tap_remove
,
2124 RTE_PMD_REGISTER_VDEV(net_tap
, pmd_tap_drv
);
2125 RTE_PMD_REGISTER_VDEV(net_tun
, pmd_tun_drv
);
2126 RTE_PMD_REGISTER_ALIAS(net_tap
, eth_tap
);
2127 RTE_PMD_REGISTER_PARAM_STRING(net_tun
,
2128 ETH_TAP_IFACE_ARG
"=<string> ");
2129 RTE_PMD_REGISTER_PARAM_STRING(net_tap
,
2130 ETH_TAP_IFACE_ARG
"=<string> "
2131 ETH_TAP_MAC_ARG
"=" ETH_TAP_MAC_ARG_FMT
" "
2132 ETH_TAP_REMOTE_ARG
"=<string>");
2135 RTE_INIT(tap_init_log
)
2137 tap_logtype
= rte_log_register("pmd.net.tap");
2138 if (tap_logtype
>= 0)
2139 rte_log_set_level(tap_logtype
, RTE_LOG_NOTICE
);