}
}
-/* 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;
*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;
}
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
struct netdev *netdev;
int error;
- error = netdev_open_default(name, &netdev);
+ error = netdev_open(name, "system", &netdev);
if (!error) {
netdev_close(netdev);
return true;
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
* (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;
}
*
* - 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,
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;