Merge "master" into "wdp".
authorBen Pfaff <blp@nicira.com>
Mon, 24 May 2010 17:01:14 +0000 (10:01 -0700)
committerBen Pfaff <blp@nicira.com>
Mon, 24 May 2010 17:01:14 +0000 (10:01 -0700)
12 files changed:
1  2 
datapath/Modules.mk
datapath/linux-2.6/Modules.mk
datapath/vport.c
datapath/vport.h
lib/automake.mk
lib/netdev-gre.c
lib/netdev-patch.c
lib/netdev-provider.h
lib/netdev-vport.c
lib/netdev.c
lib/vlog-modules.def
lib/xfif-linux.c

@@@ -28,11 -30,12 +30,12 @@@ openvswitch_headers = 
        datapath.h \
        dp_sysfs.h \
        flow.h \
 -      odp-compat.h \
        table.h \
        vport.h \
+       vport-generic.h \
        vport-internal_dev.h \
 -      vport-netdev.h
 +      vport-netdev.h \
 +      xflow-compat.h
  
  dist_sources = $(foreach module,$(dist_modules),$($(module)_sources))
  dist_headers = $(foreach module,$(dist_modules),$($(module)_headers))
Simple merge
Simple merge
Simple merge
diff --cc lib/automake.mk
@@@ -60,9 -65,14 +60,12 @@@ lib_libopenvswitch_a_SOURCES = 
        lib/mac-learning.h \
        lib/netdev-gre.c \
        lib/netdev-linux.c \
+       lib/netdev-patch.c \
        lib/netdev-provider.h \
+       lib/netdev-vport.c \
+       lib/netdev-vport.h \
        lib/netdev.c \
        lib/netdev.h \
 -      lib/odp-util.c \
 -      lib/odp-util.h \
        lib/ofp-print.c \
        lib/ofp-print.h \
        lib/ofpbuf.c \
  #include <net/if.h>
  #include <sys/ioctl.h>
  
- #include "list.h"
  #include "netdev-provider.h"
+ #include "netdev-vport.h"
  #include "openflow/openflow.h"
 -#include "openvswitch/datapath-protocol.h"
  #include "openvswitch/gre.h"
 +#include "openvswitch/xflow.h"
  #include "packets.h"
- #include "shash.h"
  #include "socket-util.h"
  
  #define THIS_MODULE VLM_netdev_gre
@@@ -183,16 -151,16 +151,16 @@@ netdev_gre_create(const char *name, con
          return err;
      }
  
-     err = do_ioctl(XFLOW_VPORT_ADD, &ova);
 -    err = netdev_vport_do_ioctl(ODP_VPORT_ADD, &ova);
++    err = netdev_vport_do_ioctl(XFLOW_VPORT_ADD, &ova);
      if (err == EEXIST) {
          VLOG_WARN("%s: destroying existing device", name);
  
-         err = do_ioctl(XFLOW_VPORT_DEL, ova.devname);
 -        err = netdev_vport_do_ioctl(ODP_VPORT_DEL, ova.devname);
++        err = netdev_vport_do_ioctl(XFLOW_VPORT_DEL, ova.devname);
          if (err) {
              return err;
          }
  
-         err = do_ioctl(XFLOW_VPORT_ADD, &ova);
 -        err = netdev_vport_do_ioctl(ODP_VPORT_ADD, &ova);
++        err = netdev_vport_do_ioctl(XFLOW_VPORT_ADD, &ova);
      }
  
      if (err) {
@@@ -222,7 -190,7 +190,7 @@@ netdev_gre_reconfigure(struct netdev_de
          return err;
      }
  
-     return do_ioctl(XFLOW_VPORT_MOD, &ovm);
 -    return netdev_vport_do_ioctl(ODP_VPORT_MOD, &ovm);
++    return netdev_vport_do_ioctl(XFLOW_VPORT_MOD, &ovm);
  }
  
  static void
@@@ -230,7 -198,7 +198,7 @@@ netdev_gre_destroy(struct netdev_dev *n
  {
      struct netdev_dev_gre *netdev_dev = netdev_dev_gre_cast(netdev_dev_);
  
-     do_ioctl(XFLOW_VPORT_DEL, (char *)netdev_dev_get_name(netdev_dev_));
 -    netdev_vport_do_ioctl(ODP_VPORT_DEL, (char *)netdev_dev_get_name(netdev_dev_));
++    netdev_vport_do_ioctl(XFLOW_VPORT_DEL, (char *)netdev_dev_get_name(netdev_dev_));
      free(netdev_dev);
  }
  
index 0000000,22353a1..0f18346
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,223 +1,223 @@@
 -#include "openvswitch/datapath-protocol.h"
+ /*
+  * Copyright (c) 2010 Nicira Networks.
+  *
+  * Licensed under the Apache License, Version 2.0 (the "License");
+  * you may not use this file except in compliance with the License.
+  * You may obtain a copy of the License at:
+  *
+  *     http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or apatched to in writing, software
+  * distributed under the License is distributed on an "AS IS" BASIS,
+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  * See the License for the specific language governing permissions and
+  * limitations under the License.
+  */
+ #include <config.h>
+ #include <errno.h>
+ #include <fcntl.h>
+ #include <net/if.h>
+ #include <sys/ioctl.h>
+ #include "netdev-provider.h"
+ #include "netdev-vport.h"
+ #include "openflow/openflow.h"
 -    struct odp_vport_add ova;
++#include "openvswitch/xflow.h"
+ #include "packets.h"
+ #include "socket-util.h"
+ #define THIS_MODULE VLM_netdev_patch
+ #include "vlog.h"
+ struct netdev_dev_patch {
+     struct netdev_dev netdev_dev;
+ };
+ struct netdev_patch {
+     struct netdev netdev;
+ };
+ static struct netdev_dev_patch *
+ netdev_dev_patch_cast(const struct netdev_dev *netdev_dev)
+ {
+     netdev_dev_assert_class(netdev_dev, &netdev_patch_class);
+     return CONTAINER_OF(netdev_dev, struct netdev_dev_patch, netdev_dev);
+ }
+ static struct netdev_patch *
+ netdev_patch_cast(const struct netdev *netdev)
+ {
+     netdev_assert_class(netdev, &netdev_patch_class);
+     return CONTAINER_OF(netdev, struct netdev_patch, netdev);
+ }
+ static int
+ parse_config(const char *name, const struct shash *args,
+              const char **peerp)
+ {
+     const char *peer;
+     peer = shash_find_data(args, "peer");
+     if (!peer) {
+         VLOG_WARN("%s: patch type requires valid 'peer' argument", name);
+         return EINVAL;
+     }
+     if (shash_count(args) > 1) {
+         VLOG_WARN("%s: patch type takes only a 'peer' argument", name);
+         return EINVAL;
+     }
+     if (strlen(peer) >= IFNAMSIZ) {
+         VLOG_WARN("%s: patch 'peer' arg too long", name);
+         return EINVAL;
+     }
+     if (!strcmp(name, peer)) {
+         VLOG_WARN("%s: patch peer must not be self", name);
+         return EINVAL;
+     }
+     *peerp = peer;
+     return 0;
+ }
+ static int
+ netdev_patch_create(const char *name, const char *type OVS_UNUSED,
+                   const struct shash *args, struct netdev_dev **netdev_devp)
+ {
+     int err;
 -    err = netdev_vport_do_ioctl(ODP_VPORT_ADD, &ova);
++    struct xflow_vport_add ova;
+     const char *peer;
+     struct netdev_dev_patch *netdev_dev;
+     err = parse_config(name, args, &peer);
+     if (err) {
+         return err;
+     }
+     ovs_strlcpy(ova.port_type, "patch", sizeof ova.port_type);
+     ovs_strlcpy(ova.devname, name, sizeof ova.devname);
+     ova.config = (char *)peer;
 -        err = netdev_vport_do_ioctl(ODP_VPORT_DEL, ova.devname);
++    err = netdev_vport_do_ioctl(XFLOW_VPORT_ADD, &ova);
+     if (err == EEXIST) {
+         VLOG_WARN("%s: destroying existing device", name);
 -        err = netdev_vport_do_ioctl(ODP_VPORT_ADD, &ova);
++        err = netdev_vport_do_ioctl(XFLOW_VPORT_DEL, ova.devname);
+         if (err) {
+             return err;
+         }
 -    struct odp_vport_mod ovm;
++        err = netdev_vport_do_ioctl(XFLOW_VPORT_ADD, &ova);
+     }
+     if (err) {
+         return err;
+     }
+     netdev_dev = xmalloc(sizeof *netdev_dev);
+     netdev_dev_init(&netdev_dev->netdev_dev, name, &netdev_patch_class);
+     *netdev_devp = &netdev_dev->netdev_dev;
+     return 0;
+ }
+ static int
+ netdev_patch_reconfigure(struct netdev_dev *netdev_dev_, const struct shash *args)
+ {
+     const char *name = netdev_dev_get_name(netdev_dev_);
 -    return netdev_vport_do_ioctl(ODP_VPORT_MOD, &ovm);
++    struct xflow_vport_mod ovm;
+     const char *peer;
+     int err;
+     err = parse_config(name, args, &peer);
+     if (err) {
+         return err;
+     }
+     ovs_strlcpy(ovm.devname, name, sizeof ovm.devname);
+     ovm.config = (char *)peer;
 -    netdev_vport_do_ioctl(ODP_VPORT_DEL, (char *)netdev_dev_get_name(netdev_dev_));
++    return netdev_vport_do_ioctl(XFLOW_VPORT_MOD, &ovm);
+ }
+ static void
+ netdev_patch_destroy(struct netdev_dev *netdev_dev_)
+ {
+     struct netdev_dev_patch *netdev_dev = netdev_dev_patch_cast(netdev_dev_);
++    netdev_vport_do_ioctl(XFLOW_VPORT_DEL, (char *)netdev_dev_get_name(netdev_dev_));
+     free(netdev_dev);
+ }
+ static int
+ netdev_patch_open(struct netdev_dev *netdev_dev_, int ethertype OVS_UNUSED,
+                 struct netdev **netdevp)
+ {
+     struct netdev_patch *netdev;
+     netdev = xmalloc(sizeof *netdev);
+     netdev_init(&netdev->netdev, netdev_dev_);
+     *netdevp = &netdev->netdev;
+     return 0;
+ }
+ static void
+ netdev_patch_close(struct netdev *netdev_)
+ {
+     struct netdev_patch *netdev = netdev_patch_cast(netdev_);
+     free(netdev);
+ }
+ const struct netdev_class netdev_patch_class = {
+     "patch",
+     NULL,                       /* init */
+     NULL,                       /* run */
+     NULL,                       /* wait */
+     netdev_patch_create,
+     netdev_patch_destroy,
+     netdev_patch_reconfigure,
+     netdev_patch_open,
+     netdev_patch_close,
+     NULL,                       /* enumerate */
+     NULL,                       /* recv */
+     NULL,                       /* recv_wait */
+     NULL,                       /* drain */
+     NULL,                       /* send */
+     NULL,                       /* send_wait */
+     netdev_vport_set_etheraddr,
+     netdev_vport_get_etheraddr,
+     netdev_vport_get_mtu,
+     NULL,                       /* get_ifindex */
+     netdev_vport_get_carrier,
+     netdev_vport_get_stats,
+     NULL,                       /* set_stats */
+     NULL,                       /* get_features */
+     NULL,                       /* set_advertisements */
+     NULL,                       /* get_vlan_vid */
+     NULL,                       /* set_policing */
+     NULL,                       /* get_in4 */
+     NULL,                       /* set_in4 */
+     NULL,                       /* get_in6 */
+     NULL,                       /* add_router */
+     NULL,                       /* get_next_hop */
+     NULL,                       /* arp_lookup */
+     netdev_vport_update_flags,
+     netdev_vport_poll_add,
+     netdev_vport_poll_remove,
+ };
Simple merge
index 0000000,a81262a..911e560
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,246 +1,246 @@@
 -#include "openvswitch/datapath-protocol.h"
+ /*
+  * Copyright (c) 2010 Nicira Networks.
+  *
+  * Licensed under the Apache License, Version 2.0 (the "License");
+  * you may not use this file except in compliance with the License.
+  * You may obtain a copy of the License at:
+  *
+  *     http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or apatched to in writing, software
+  * distributed under the License is distributed on an "AS IS" BASIS,
+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  * See the License for the specific language governing permissions and
+  * limitations under the License.
+  */
+ #include <config.h>
+ #include <errno.h>
+ #include <fcntl.h>
+ #include <sys/ioctl.h>
+ #include "list.h"
+ #include "netdev-vport.h"
 -    struct odp_vport_ether vport_ether;
++#include "openvswitch/xflow.h"
+ #include "shash.h"
+ #include "socket-util.h"
+ #define THIS_MODULE VLM_netdev_vport
+ #include "vlog.h"
+ struct netdev_vport_notifier {
+     struct netdev_notifier notifier;
+     struct list list_node;
+     struct shash_node *shash_node; 
+ };
+ static struct shash netdev_vport_notifiers =
+                                     SHASH_INITIALIZER(&netdev_vport_notifiers);
+ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20);
+ int
+ netdev_vport_do_ioctl(int cmd, void *arg)
+ {
+     static int ioctl_fd = -1;
+     if (ioctl_fd < 0) {
+         ioctl_fd = open("/dev/net/dp0", O_RDONLY | O_NONBLOCK);
+         if (ioctl_fd < 0) {
+             VLOG_ERR_RL(&rl, "failed to open ioctl fd: %s", strerror(errno));
+             return errno;
+         }
+     }
+     return ioctl(ioctl_fd, cmd, arg) ? errno : 0;
+ }
+ int
+ netdev_vport_set_etheraddr(struct netdev *netdev,
+                            const uint8_t mac[ETH_ADDR_LEN])
+ {
 -    err = netdev_vport_do_ioctl(ODP_VPORT_ETHER_SET, &vport_ether);
++    struct xflow_vport_ether vport_ether;
+     int err;
+     ovs_strlcpy(vport_ether.devname, netdev_get_name(netdev),
+                 sizeof vport_ether.devname);
+     memcpy(vport_ether.ether_addr, mac, ETH_ADDR_LEN);
 -    struct odp_vport_ether vport_ether;
++    err = netdev_vport_do_ioctl(XFLOW_VPORT_ETHER_SET, &vport_ether);
+     if (err) {
+         return err;
+     }
+     netdev_vport_poll_notify(netdev);
+     return 0;
+ }
+ int
+ netdev_vport_get_etheraddr(const struct netdev *netdev,
+                            uint8_t mac[ETH_ADDR_LEN])
+ {
 -    err = netdev_vport_do_ioctl(ODP_VPORT_ETHER_GET, &vport_ether);
++    struct xflow_vport_ether vport_ether;
+     int err;
+     ovs_strlcpy(vport_ether.devname, netdev_get_name(netdev),
+                 sizeof vport_ether.devname);
 -    struct odp_vport_mtu vport_mtu;
++    err = netdev_vport_do_ioctl(XFLOW_VPORT_ETHER_GET, &vport_ether);
+     if (err) {
+         return err;
+     }
+     memcpy(mac, vport_ether.ether_addr, ETH_ADDR_LEN);
+     return 0;
+ }
+ int
+ netdev_vport_get_mtu(const struct netdev *netdev, int *mtup)
+ {
 -    err = netdev_vport_do_ioctl(ODP_VPORT_MTU_GET, &vport_mtu);
++    struct xflow_vport_mtu vport_mtu;
+     int err;
+     ovs_strlcpy(vport_mtu.devname, netdev_get_name(netdev),
+                 sizeof vport_mtu.devname);
 -    struct odp_vport_stats_req ovsr;
++    err = netdev_vport_do_ioctl(XFLOW_VPORT_MTU_GET, &vport_mtu);
+     if (err) {
+         return err;
+     }
+     *mtup = vport_mtu.mtu;
+     return 0;
+ }
+ int
+ netdev_vport_get_carrier(const struct netdev *netdev OVS_UNUSED, bool *carrier)
+ {
+     *carrier = true;
+     return 0;
+ }
+ int
+ netdev_vport_get_stats(const struct netdev *netdev, struct netdev_stats *stats)
+ {
+     const char *name = netdev_get_name(netdev);
 -    err = netdev_vport_do_ioctl(ODP_VPORT_STATS_GET, &ovsr);
++    struct xflow_vport_stats_req ovsr;
+     int err;
+     ovs_strlcpy(ovsr.devname, name, sizeof ovsr.devname);
++    err = netdev_vport_do_ioctl(XFLOW_VPORT_STATS_GET, &ovsr);
+     if (err) {
+         return err;
+     }
+     stats->rx_packets = ovsr.stats.rx_packets;
+     stats->tx_packets = ovsr.stats.tx_packets;
+     stats->rx_bytes = ovsr.stats.rx_bytes;
+     stats->tx_bytes = ovsr.stats.tx_bytes;
+     stats->rx_errors = ovsr.stats.rx_errors;
+     stats->tx_errors = ovsr.stats.tx_errors;
+     stats->rx_dropped = ovsr.stats.rx_dropped;
+     stats->tx_dropped = ovsr.stats.tx_dropped;
+     stats->multicast = UINT64_MAX;
+     stats->collisions = ovsr.stats.collisions;
+     stats->rx_length_errors = UINT64_MAX;
+     stats->rx_over_errors = ovsr.stats.rx_over_err;
+     stats->rx_crc_errors = ovsr.stats.rx_crc_err;
+     stats->rx_frame_errors = ovsr.stats.rx_frame_err;
+     stats->rx_fifo_errors = UINT64_MAX;
+     stats->rx_missed_errors = UINT64_MAX;
+     stats->tx_aborted_errors = UINT64_MAX;
+     stats->tx_carrier_errors = UINT64_MAX;
+     stats->tx_fifo_errors = UINT64_MAX;
+     stats->tx_heartbeat_errors = UINT64_MAX;
+     stats->tx_window_errors = UINT64_MAX;
+     return 0;
+ }
+ int
+ netdev_vport_update_flags(struct netdev *netdev OVS_UNUSED,
+                         enum netdev_flags off, enum netdev_flags on OVS_UNUSED,
+                         enum netdev_flags *old_flagsp)
+ {
+     if (off & (NETDEV_UP | NETDEV_PROMISC)) {
+         return EOPNOTSUPP;
+     }
+     *old_flagsp = NETDEV_UP | NETDEV_PROMISC;
+     return 0;
+ }
+ static char *
+ make_poll_name(const struct netdev *netdev)
+ {
+     return xasprintf("%s:%s", netdev_get_type(netdev), netdev_get_name(netdev));
+ }
+ int
+ netdev_vport_poll_add(struct netdev *netdev,
+                       void (*cb)(struct netdev_notifier *), void *aux,
+                       struct netdev_notifier **notifierp)
+ {
+     char *poll_name = make_poll_name(netdev);
+     struct netdev_vport_notifier *notifier;
+     struct list *list;
+     struct shash_node *shash_node;
+     shash_node = shash_find_data(&netdev_vport_notifiers, poll_name);
+     if (!shash_node) {
+         list = xmalloc(sizeof *list);
+         list_init(list);
+         shash_node = shash_add(&netdev_vport_notifiers,
+                              netdev_get_name(netdev), list);
+     } else {
+         list = shash_node->data;
+     }
+     notifier = xmalloc(sizeof *notifier);
+     netdev_notifier_init(&notifier->notifier, netdev, cb, aux);
+     list_push_back(list, &notifier->list_node);
+     notifier->shash_node = shash_node;
+     *notifierp = &notifier->notifier;
+     free(poll_name);
+     return 0;
+ }
+ void
+ netdev_vport_poll_remove(struct netdev_notifier *notifier_)
+ {
+     struct netdev_vport_notifier *notifier =
+                 CONTAINER_OF(notifier_, struct netdev_vport_notifier, notifier);
+     struct list *list;
+     list = list_remove(&notifier->list_node);
+     if (list_is_empty(list)) {
+         shash_delete(&netdev_vport_notifiers, notifier->shash_node);
+         free(list);
+     }
+     free(notifier);
+ }
+ void
+ netdev_vport_poll_notify(const struct netdev *netdev)
+ {
+     char *poll_name = make_poll_name(netdev);
+     struct list *list = shash_find_data(&netdev_vport_notifiers,
+                                         poll_name);
+     if (list) {
+         struct netdev_vport_notifier *notifier;
+         LIST_FOR_EACH (notifier, struct netdev_vport_notifier,
+                        list_node, list) {
+             struct netdev_notifier *n = &notifier->notifier;
+             n->cb(n);
+         }
+     }
+     free(poll_name);
+ }
diff --cc lib/netdev.c
Simple merge
Simple merge
  #include <linux/sockios.h>
  #include <stdlib.h>
  #include <sys/ioctl.h>
+ #include <sys/stat.h>
  #include <unistd.h>
  
 -#include "dpif-provider.h"
  #include "netdev.h"
  #include "ofpbuf.h"
  #include "poll-loop.h"