Merge branch 'mainstream'
[sliver-openvswitch.git] / lib / netdev-provider.h
index 6769014..1442367 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010, 2011 Nicira Networks.
+ * Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 /* Generic interface to network devices. */
 
-#include <assert.h>
-
 #include "netdev.h"
 #include "list.h"
 #include "shash.h"
+#include "smap.h"
 
 #ifdef  __cplusplus
 extern "C" {
@@ -39,11 +38,9 @@ struct netdev_dev {
                                                 this device. */
     int ref_cnt;                        /* Times this devices was opened. */
     struct shash_node *node;            /* Pointer to element in global map. */
-    struct shash args;                  /* Argument list from last config. */
 };
 
 void netdev_dev_init(struct netdev_dev *, const char *name,
-                     const struct shash *args,
                      const struct netdev_class *);
 void netdev_dev_uninit(struct netdev_dev *, bool destroy);
 const char *netdev_dev_get_type(const struct netdev_dev *);
@@ -56,7 +53,7 @@ void netdev_dev_get_devices(const struct netdev_class *,
 static inline void netdev_dev_assert_class(const struct netdev_dev *netdev_dev,
                                            const struct netdev_class *class_)
 {
-    assert(netdev_dev->netdev_class == class_);
+    ovs_assert(netdev_dev->netdev_class == class_);
 }
 
 /* A instance of an open network device.
@@ -114,11 +111,10 @@ struct netdev_class {
      * needed here. */
     void (*wait)(void);
 
-    /* Attempts to create a network device named 'name' with initial 'args' in
-     * 'netdev_class'.  On success sets 'netdev_devp' to the newly created
-     * device. */
+    /* Attempts to create a network device named 'name' in 'netdev_class'.  On
+     * success sets 'netdev_devp' to the newly created device. */
     int (*create)(const struct netdev_class *netdev_class, const char *name,
-                  const struct shash *args, struct netdev_dev **netdev_devp);
+                  struct netdev_dev **netdev_devp);
 
     /* Destroys 'netdev_dev'.
      *
@@ -128,46 +124,68 @@ struct netdev_class {
      * called. */
     void (*destroy)(struct netdev_dev *netdev_dev);
 
+    /* Fetches the device 'netdev_dev''s configuration, storing it in 'args'.
+     * The caller owns 'args' and pre-initializes it to an empty smap.
+     *
+     * If this netdev class does not have any configuration options, this may
+     * be a null pointer. */
+    int (*get_config)(struct netdev_dev *netdev_dev, struct smap *args);
+
     /* Changes the device 'netdev_dev''s configuration to 'args'.
      *
-     * If this netdev class does not support reconfiguring a netdev
-     * device, this may be a null pointer.
-     */
-    int (*set_config)(struct netdev_dev *netdev_dev, const struct shash *args);
+     * If this netdev class does not support configuration, this may be a null
+     * pointer. */
+    int (*set_config)(struct netdev_dev *netdev_dev, const struct smap *args);
 
-    /* Attempts to open a network device.  On success, sets 'netdevp'
-     * to the new network device.
+    /* Returns the tunnel configuration of 'netdev_dev'.  If 'netdev_dev' is
+     * not a tunnel, returns null.
      *
-     * 'ethertype' may be a 16-bit Ethernet protocol value in host byte order
-     * to capture frames of that type received on the device.  It may also be
-     * one of the 'enum netdev_pseudo_ethertype' values to receive frames in
-     * one of those categories. */
-    int (*open)(struct netdev_dev *netdev_dev, int ethertype,
-                struct netdev **netdevp);
+     * If this function would always return null, it may be null instead. */
+    const struct netdev_tunnel_config *
+        (*get_tunnel_config)(const struct netdev_dev *netdev_dev);
+
+    /* Attempts to open a network device.  On success, sets 'netdevp'
+     * to the new network device. */
+    int (*open)(struct netdev_dev *netdev_dev, struct netdev **netdevp);
 
     /* Closes 'netdev'. */
     void (*close)(struct netdev *netdev);
+\f
+/* ## ----------------- ## */
+/* ## Receiving Packets ## */
+/* ## ----------------- ## */
+
+/* The network provider interface is mostly used for inspecting and configuring
+ * device "metadata", not for sending and receiving packets directly.  It may
+ * be impractical to implement these functions on some operating systems and
+ * hardware.  These functions may all be NULL in such cases.
+ *
+ * (However, the "dpif-netdev" implementation, which is the easiest way to
+ * integrate Open vSwitch with a new operating system or hardware, does require
+ * the ability to receive packets.) */
 
-    /* Enumerates the names of all network devices of this class.
-     *
-     * The caller has already initialized 'all_names' and might already have
-     * added some names to it.  This function should not disturb any existing
-     * names in 'all_names'.
-     *
-     * If this netdev class does not support enumeration, this may be a null
-     * pointer. */
-    int (*enumerate)(struct sset *all_names);
+    /* Attempts to set up 'netdev' for receiving packets with ->recv().
+     * Returns 0 if successful, otherwise a positive errno value.  Return
+     * EOPNOTSUPP to indicate that the network device does not implement packet
+     * reception through this interface.  This function may be set to null if
+     * it would always return EOPNOTSUPP anyhow.  (This will prevent the
+     * network device from being usefully used by the netdev-based "userspace
+     * datapath".)*/
+    int (*listen)(struct netdev *netdev);
 
     /* Attempts to receive a packet from 'netdev' into the 'size' bytes in
      * 'buffer'.  If successful, returns the number of bytes in the received
      * packet, otherwise a negative errno value.  Returns -EAGAIN immediately
      * if no packet is ready to be received.
      *
-     * May return -EOPNOTSUPP if a network device does not implement packet
-     * reception through this interface.  This function may be set to null if
-     * it would always return -EOPNOTSUPP anyhow.  (This will prevent the
-     * network device from being usefully used by the netdev-based "userspace
-     * datapath".) */
+     * Returns -EMSGSIZE, and discards the packet, if the received packet is
+     * longer than 'size' bytes.
+     *
+     * This function can only be expected to return a packet if ->listen() has
+     * been called successfully.
+     *
+     * May be null if not needed, such as for a network device that does not
+     * implement packet reception through the 'recv' member function. */
     int (*recv)(struct netdev *netdev, void *buffer, size_t size);
 
     /* Registers with the poll loop to wake up from the next call to
@@ -183,7 +201,7 @@ struct netdev_class {
      * May be null if not needed, such as for a network device that does not
      * implement packet reception through the 'recv' member function. */
     int (*drain)(struct netdev *netdev);
-
+\f
     /* Sends the 'size'-byte packet in 'buffer' on 'netdev'.  Returns 0 if
      * successful, otherwise a positive errno value.  Returns EAGAIN without
      * blocking if the packet cannot be queued immediately.  Returns EMSGSIZE
@@ -219,7 +237,10 @@ struct netdev_class {
     /* Sets 'netdev''s Ethernet address to 'mac' */
     int (*set_etheraddr)(struct netdev *netdev, const uint8_t mac[6]);
 
-    /* Retrieves 'netdev''s Ethernet address into 'mac'. */
+    /* Retrieves 'netdev''s Ethernet address into 'mac'.
+     *
+     * This address will be advertised as 'netdev''s MAC address through the
+     * OpenFlow protocol, among other uses. */
     int (*get_etheraddr)(const struct netdev *netdev, uint8_t mac[6]);
 
     /* Retrieves 'netdev''s MTU into '*mtup'.
@@ -229,9 +250,17 @@ struct netdev_class {
      * bytes for Ethernet devices.
      *
      * If 'netdev' does not have an MTU (e.g. as some tunnels do not), then
-     * this function should set '*mtup' to INT_MAX. */
+     * this function should return EOPNOTSUPP.  This function may be set to
+     * null if it would always return EOPNOTSUPP. */
     int (*get_mtu)(const struct netdev *netdev, int *mtup);
 
+    /* Sets 'netdev''s MTU to 'mtu'.
+     *
+     * If 'netdev' does not have an MTU (e.g. as some tunnels do not), then
+     * this function should return EOPNOTSUPP.  This function may be set to
+     * null if it would always return EOPNOTSUPP. */
+    int (*set_mtu)(const struct netdev *netdev, int mtu);
+
     /* Returns the ifindex of 'netdev', if successful, as a positive number.
      * On failure, returns a negative errno value.
      *
@@ -253,6 +282,12 @@ struct netdev_class {
      */
     int (*get_carrier)(const struct netdev *netdev, bool *carrier);
 
+    /* Returns the number of times 'netdev''s carrier has changed since being
+     * initialized.
+     *
+     * If null, callers will assume the number of carrier resets is zero. */
+    long long int (*get_carrier_resets)(const struct netdev *netdev);
+
     /* Forces ->get_carrier() to poll 'netdev''s MII registers for link status
      * instead of checking 'netdev''s carrier.  'netdev''s MII registers will
      * be polled once ever 'interval' milliseconds.  If 'netdev' does not
@@ -282,31 +317,23 @@ struct netdev_class {
 
     /* Stores the features supported by 'netdev' into each of '*current',
      * '*advertised', '*supported', and '*peer'.  Each value is a bitmap of
-     * "enum ofp_port_features" bits, in host byte order.
+     * NETDEV_F_* bits.
      *
      * This function may be set to null if it would always return EOPNOTSUPP.
      */
     int (*get_features)(const struct netdev *netdev,
-                        uint32_t *current, uint32_t *advertised,
-                        uint32_t *supported, uint32_t *peer);
+                        enum netdev_features *current,
+                        enum netdev_features *advertised,
+                        enum netdev_features *supported,
+                        enum netdev_features *peer);
 
     /* Set the features advertised by 'netdev' to 'advertise', which is a
-     * bitmap of "enum ofp_port_features" bits, in host byte order.
+     * set of NETDEV_F_* bits.
      *
      * This function may be set to null for a network device that does not
      * support configuring advertisements. */
-    int (*set_advertisements)(struct netdev *netdev, uint32_t advertise);
-
-    /* If 'netdev' is a VLAN network device (e.g. one created with vconfig(8)),
-     * sets '*vlan_vid' to the VLAN VID associated with that device and returns
-     * 0.
-     *
-     * Returns ENOENT if 'netdev' is a network device that is not a
-     * VLAN device.
-     *
-     * This function should be set to null if it doesn't make any sense for
-     * your network device (it probably doesn't). */
-    int (*get_vlan_vid)(const struct netdev *netdev, int *vlan_vid);
+    int (*set_advertisements)(struct netdev *netdev,
+                              enum netdev_features advertise);
 
     /* Attempts to set input rate limiting (policing) policy, such that up to
      * 'kbits_rate' kbps of traffic is accepted, with a maximum accumulative
@@ -360,7 +387,7 @@ struct netdev_class {
      *
      * May be NULL if 'netdev' does not support QoS at all. */
     int (*get_qos)(const struct netdev *netdev,
-                   const char **typep, struct shash *details);
+                   const char **typep, struct smap *details);
 
     /* Attempts to reconfigure QoS on 'netdev', changing the form of QoS to
      * 'type' with details of configuration from 'details'.
@@ -380,7 +407,7 @@ struct netdev_class {
      *
      * May be NULL if 'netdev' does not support QoS at all. */
     int (*set_qos)(struct netdev *netdev,
-                   const char *type, const struct shash *details);
+                   const char *type, const struct smap *details);
 
     /* Queries 'netdev' for information about the queue numbered 'queue_id'.
      * If successful, adds that information as string key-value pairs to
@@ -399,7 +426,7 @@ struct netdev_class {
      * vswitchd/vswitch.xml (which is built as ovs-vswitchd.conf.db(8)).
      */
     int (*get_queue)(const struct netdev *netdev,
-                     unsigned int queue_id, struct shash *details);
+                     unsigned int queue_id, struct smap *details);
 
     /* Configures the queue numbered 'queue_id' on 'netdev' with the key-value
      * string pairs in 'details'.  The contents of 'details' should be
@@ -419,7 +446,7 @@ struct netdev_class {
      *
      * May be NULL if 'netdev' does not support QoS at all. */
     int (*set_queue)(struct netdev *netdev,
-                     unsigned int queue_id, const struct shash *details);
+                     unsigned int queue_id, const struct smap *details);
 
     /* Attempts to delete the queue numbered 'queue_id' from 'netdev'.
      *
@@ -446,10 +473,15 @@ struct netdev_class {
      * of iteration is unspecified, but (when successful) each queue is visited
      * exactly once.
      *
-     * 'cb' will not modify or free the 'details' argument passed in. */
+     * 'cb' will not modify or free the 'details' argument passed in.  It may
+     * delete or modify the queue passed in as its 'queue_id' argument.  It may
+     * modify but will not delete any other queue within 'netdev'.  If 'cb'
+     * adds new queues, then ->dump_queues is allowed to visit some queues
+     * twice or not at all.
+     */
     int (*dump_queues)(const struct netdev *netdev,
                        void (*cb)(unsigned int queue_id,
-                                  const struct shash *details,
+                                  const struct smap *details,
                                   void *aux),
                        void *aux);
 
@@ -517,19 +549,18 @@ struct netdev_class {
     int (*get_next_hop)(const struct in_addr *host, struct in_addr *next_hop,
                         char **netdev_name);
 
-    /* Retrieves the status of the device.
+    /* Retrieves driver information of the device.
      *
-     * Populates 'sh' with key-value pairs representing the status of the
-     * device.  A device's status is a set of key-value string pairs
-     * representing netdev type specific information.  For more information see
+     * Populates 'smap' with key-value pairs representing the status of the
+     * device.  'smap' is a set of key-value string pairs representing netdev
+     * type specific information.  For more information see
      * ovs-vswitchd.conf.db(5).
      *
-     * The data of 'sh' are heap allocated strings which the caller is
-     * responsible for deallocating.
+     * The caller is responsible for destroying 'smap' and its data.
      *
      * This function may be set to null if it would always return EOPNOTSUPP
      * anyhow. */
-    int (*get_status)(const struct netdev *netdev, struct shash *sh);
+    int (*get_status)(const struct netdev *netdev, struct smap *smap);
 
     /* Looks up the ARP table entry for 'ip' on 'netdev' and stores the
      * corresponding MAC address in 'mac'.  A return value of ENXIO, in
@@ -570,6 +601,12 @@ const struct netdev_class *netdev_lookup_provider(const char *type);
 extern const struct netdev_class netdev_linux_class;
 extern const struct netdev_class netdev_internal_class;
 extern const struct netdev_class netdev_tap_class;
+#ifdef __FreeBSD__
+extern const struct netdev_class netdev_bsd_class;
+#endif
+
+extern const struct netdev_class netdev_tunnel_class;
+extern const struct netdev_class netdev_pltap_class;
 
 #ifdef  __cplusplus
 }