bugtool: Uninstall plugins on "make uninstall".
[openvswitch] / lib / netdev.c
index ec8ae4fc41a303a6f6d50c4c47f9ab2a9dd5996e..1a668c8b11ed815ee270c1b965fca36020ee5fd7 100644 (file)
@@ -192,14 +192,15 @@ netdev_enumerate_types(struct sset *types)
     }
 }
 
-/* Opens the network device named 'name' (e.g. "eth0") and returns zero if
- * successful, otherwise a positive errno value.  On success, sets '*netdevp'
- * to the new network device, otherwise to null.
+/* Opens the network device named 'name' (e.g. "eth0") of the specified 'type'
+ * (e.g. "system") and returns zero if successful, otherwise a positive errno
+ * value.  On success, sets '*netdevp' to the new network device, otherwise to
+ * null.
  *
  * Some network devices may need to be configured (with netdev_set_config())
  * before they can be used. */
 int
-netdev_open(struct netdev_options *options, struct netdev **netdevp)
+netdev_open(const char *name, const char *type, struct netdev **netdevp)
 {
     struct netdev_dev *netdev_dev;
     int error;
@@ -207,18 +208,18 @@ netdev_open(struct netdev_options *options, struct netdev **netdevp)
     *netdevp = NULL;
     netdev_initialize();
 
-    netdev_dev = shash_find_data(&netdev_dev_shash, options->name);
+    netdev_dev = shash_find_data(&netdev_dev_shash, name);
 
     if (!netdev_dev) {
         const struct netdev_class *class;
 
-        class = netdev_lookup_provider(options->type);
+        class = netdev_lookup_provider(type);
         if (!class) {
             VLOG_WARN("could not create netdev %s of unknown type %s",
-                      options->name, options->type);
+                      name, type);
             return EAFNOSUPPORT;
         }
-        error = class->create(class, options->name, &netdev_dev);
+        error = class->create(class, name, &netdev_dev);
         if (error) {
             return error;
         }
@@ -239,17 +240,6 @@ netdev_open(struct netdev_options *options, struct netdev **netdevp)
     return error;
 }
 
-int
-netdev_open_default(const char *name, struct netdev **netdevp)
-{
-    struct netdev_options options;
-
-    memset(&options, 0, sizeof options);
-    options.name = name;
-
-    return netdev_open(&options, netdevp);
-}
-
 /* Reconfigures the device 'netdev' with 'args'.  'args' may be empty
  * or NULL if none are needed. */
 int
@@ -321,7 +311,7 @@ netdev_exists(const char *name)
     struct netdev *netdev;
     int error;
 
-    error = netdev_open_default(name, &netdev);
+    error = netdev_open(name, "system", &netdev);
     if (!error) {
         netdev_close(netdev);
         return true;
@@ -369,6 +359,25 @@ netdev_enumerate(struct sset *sset)
     return error;
 }
 
+/* Parses 'netdev_name_', which is of the form [type@]name into its component
+ * pieces.  'name' and 'type' must be freed by the caller. */
+void
+netdev_parse_name(const char *netdev_name_, char **name, char **type)
+{
+    char *netdev_name = xstrdup(netdev_name_);
+    char *separator;
+
+    separator = strchr(netdev_name, '@');
+    if (separator) {
+        *separator = '\0';
+        *type = netdev_name;
+        *name = xstrdup(separator + 1);
+    } else {
+        *name = netdev_name;
+        *type = xstrdup("system");
+    }
+}
+
 /* Attempts to set up 'netdev' for receiving packets with netdev_recv().
  * Returns 0 if successful, otherwise a positive errno value.  EOPNOTSUPP
  * indicates that the network device does not implement packet reception
@@ -520,19 +529,45 @@ netdev_get_name(const struct netdev *netdev)
  * (and received) packets, in bytes, not including the hardware header; thus,
  * this is typically 1500 bytes for Ethernet devices.
  *
- * If successful, returns 0 and stores the MTU size in '*mtup'.  Stores INT_MAX
- * in '*mtup' if 'netdev' does not have an MTU (as e.g. some tunnels do not).On
- * failure, returns a positive errno value and stores ETH_PAYLOAD_MAX (1500) in
- * '*mtup'. */
+ * If successful, returns 0 and stores the MTU size in '*mtup'.  Returns
+ * EOPNOTSUPP if 'netdev' does not have an MTU (as e.g. some tunnels do not).
+ * On other failure, returns a positive errno value.  On failure, sets '*mtup'
+ * to 0. */
 int
 netdev_get_mtu(const struct netdev *netdev, int *mtup)
 {
-    int error = netdev_get_dev(netdev)->netdev_class->get_mtu(netdev, mtup);
+    const struct netdev_class *class = netdev_get_dev(netdev)->netdev_class;
+    int error;
+
+    error = class->get_mtu ? class->get_mtu(netdev, mtup) : EOPNOTSUPP;
     if (error) {
+        *mtup = 0;
+        if (error != EOPNOTSUPP) {
+            VLOG_WARN_RL(&rl, "failed to retrieve MTU for network device %s: "
+                         "%s", netdev_get_name(netdev), strerror(error));
+        }
+    }
+    return error;
+}
+
+/* Sets the MTU of 'netdev'.  The MTU is the maximum size of transmitted
+ * (and received) packets, in bytes.
+ *
+ * If successful, returns 0.  Returns EOPNOTSUPP if 'netdev' does not have an
+ * MTU (as e.g. some tunnels do not).  On other failure, returns a positive
+ * errno value. */
+int
+netdev_set_mtu(const struct netdev *netdev, int mtu)
+{
+    const struct netdev_class *class = netdev_get_dev(netdev)->netdev_class;
+    int error;
+
+    error = class->set_mtu ? class->set_mtu(netdev, mtu) : EOPNOTSUPP;
+    if (error && error != EOPNOTSUPP) {
         VLOG_WARN_RL(&rl, "failed to retrieve MTU for network device %s: %s",
                      netdev_get_name(netdev), strerror(error));
-        *mtup = ETH_PAYLOAD_MAX;
     }
+
     return error;
 }
 
@@ -650,7 +685,7 @@ netdev_set_advertisements(struct netdev *netdev, uint32_t advertise)
  *
  *   - EOPNOTSUPP: No IPv4 network stack attached to 'netdev'.
  *
- * 'address' or 'netmask' or both may be null, in which case the address or 
+ * 'address' or 'netmask' or both may be null, in which case the address or
  * netmask is not reported. */
 int
 netdev_get_in4(const struct netdev *netdev,
@@ -1265,7 +1300,7 @@ netdev_find_dev_by_in4(const struct in_addr *in4)
     SSET_FOR_EACH (name, &dev_list) {
         struct in_addr dev_in4;
 
-        if (!netdev_open_default(name, &netdev)
+        if (!netdev_open(name, "system", &netdev)
             && !netdev_get_in4(netdev, &dev_in4, NULL)
             && dev_in4.s_addr == in4->s_addr) {
             goto exit;