- } else if (!strcmp(node->name, "in_key")) {
- if (!strcmp(node->data, "flow")) {
- config->flags |= TNL_F_IN_KEY_MATCH;
- } else {
- config->in_key = htonl(atoi(node->data));
- }
- } else if (!strcmp(node->name, "out_key")) {
- if (!strcmp(node->data, "flow")) {
- config->flags |= TNL_F_OUT_KEY_ACTION;
- } else {
- config->out_key = htonl(atoi(node->data));
- }
- } else if (!strcmp(node->name, "tos")) {
- if (!strcmp(node->data, "inherit")) {
- config->flags |= TNL_F_TOS_INHERIT;
+ } else if (!strcmp(node->name, "remote_port")) {
+ sin->sin_port = htons(atoi(node->data));
+ netdev->valid_remote_port = true;
+ } else {
+ VLOG_WARN("%s: unknown argument '%s'",
+ netdev_get_name(dev_), node->name);
+ }
+ }
+ error = netdev_tunnel_connect(netdev);
+ ovs_mutex_unlock(&netdev->mutex);
+ return error;
+}
+
+static struct netdev_rxq *
+netdev_tunnel_rxq_alloc(void)
+{
+ struct netdev_rxq_tunnel *rx = xzalloc(sizeof *rx);
+ return &rx->up;
+}
+
+static int
+netdev_tunnel_rxq_construct(struct netdev_rxq *rx_)
+{
+ struct netdev_rxq_tunnel *rx = netdev_rxq_tunnel_cast(rx_);
+ struct netdev *netdev_ = rx->up.netdev;
+ struct netdev_tunnel *netdev = netdev_tunnel_cast(netdev_);
+
+ ovs_mutex_lock(&netdev->mutex);
+ rx->fd = netdev->sockfd;
+ ovs_mutex_unlock(&netdev->mutex);
+ return 0;
+}
+
+static void
+netdev_tunnel_rxq_destruct(struct netdev_rxq *rx_ OVS_UNUSED)
+{
+}
+
+static void
+netdev_tunnel_rxq_dealloc(struct netdev_rxq *rx_)
+{
+ struct netdev_rxq_tunnel *rx = netdev_rxq_tunnel_cast(rx_);
+
+ free(rx);
+}
+
+static int
+netdev_tunnel_rxq_recv(struct netdev_rxq *rx_, struct ofpbuf **packet, int *c)
+{
+ struct netdev_rxq_tunnel *rx = netdev_rxq_tunnel_cast(rx_);
+ struct netdev_tunnel *netdev =
+ netdev_tunnel_cast(rx_->netdev);
+ struct ofpbuf *buffer = NULL;
+ void *data;
+ size_t size;
+ int error = 0;
+
+ if (!netdev->connected)
+ return EAGAIN;
+ buffer = ofpbuf_new_with_headroom(VLAN_ETH_HEADER_LEN + ETH_PAYLOAD_MAX,
+ DP_NETDEV_HEADROOM);
+ data = ofpbuf_data(buffer);
+ size = ofpbuf_tailroom(buffer);
+
+ for (;;) {
+ ssize_t retval;
+ retval = recv(rx->fd, data, size, MSG_TRUNC);
+ VLOG_DBG("%s: recv(%"PRIxPTR", %"PRIuSIZE", MSG_TRUNC) = %"PRIdSIZE,
+ netdev_rxq_get_name(rx_), (uintptr_t)data, size, retval);
+ if (retval >= 0) {
+ netdev->stats.rx_packets++;
+ netdev->stats.rx_bytes += retval;
+ if (retval <= size) {
+ ofpbuf_set_size(buffer, ofpbuf_size(buffer) + retval);
+ goto out;