aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2021-03-08 11:05:54 +0100
committerAleksander Morgado <aleksander@aleksander.es>2021-03-09 11:03:07 +0000
commitcece9c4266604b98e21c7060b4503138b3b39a1b (patch)
treef06a8035f83699be82d71eacd9f247459d7c30fa
parent0a1971899ebfe44ad5b3e690608b2842d5df362a (diff)
libqmi-glib,device: new add_link_with_flags() method
The rmnet backend allows some configuration when creating link interfaces. This configuration specifies how the link being created works, and is strictly dependent on the setup. E.g. when using rmnet over IPA we may need to always specify that checksum offload is supported, while when using rmnet over qmi_wwan, no checksum offload is currently supported. None of the flags are applicable to the qmi_wwan-only backend, and so this new method will return an UNSUPPORTED error if any flag is given to this backend. The generic add_link() method is now equivalent to running add_link_with_flags() with QMI_DEVICE_ADD_LINK_FLAG_NONE.
-rw-r--r--docs/reference/libqmi-glib/libqmi-glib-common.sections7
-rw-r--r--src/libqmi-glib/qmi-device.c47
-rw-r--r--src/libqmi-glib/qmi-device.h76
-rw-r--r--src/libqmi-glib/qmi-net-port-manager-qmiwwan.c32
-rw-r--r--src/libqmi-glib/qmi-net-port-manager-rmnet.c39
-rw-r--r--src/libqmi-glib/qmi-net-port-manager.c18
-rw-r--r--src/libqmi-glib/qmi-net-port-manager.h52
7 files changed, 206 insertions, 65 deletions
diff --git a/docs/reference/libqmi-glib/libqmi-glib-common.sections b/docs/reference/libqmi-glib/libqmi-glib-common.sections
index b572201..247e2bf 100644
--- a/docs/reference/libqmi-glib/libqmi-glib-common.sections
+++ b/docs/reference/libqmi-glib/libqmi-glib-common.sections
@@ -92,6 +92,10 @@ QMI_DEVICE_MUX_ID_MAX
qmi_device_list_links
qmi_device_add_link
qmi_device_add_link_finish
+QmiDeviceAddLinkFlags
+qmi_device_add_link_flags_build_string_from_mask
+qmi_device_add_link_with_flags
+qmi_device_add_link_with_flags_finish
qmi_device_delete_link
qmi_device_delete_link_finish
qmi_device_delete_all_links
@@ -121,15 +125,18 @@ QMI_TYPE_DEVICE
QMI_TYPE_DEVICE_OPEN_FLAGS
QMI_TYPE_DEVICE_RELEASE_CLIENT_FLAGS
QMI_TYPE_DEVICE_EXPECTED_DATA_FORMAT
+QMI_TYPE_DEVICE_ADD_LINK_FLAGS
QmiDevicePrivate
qmi_device_get_type
qmi_device_open_flags_get_type
qmi_device_release_client_flags_get_type
qmi_device_expected_data_format_get_type
+qmi_device_add_link_flags_get_type
<SUBSECTION Private>
qmi_device_open_flags_get_string
qmi_device_release_client_flags_get_string
qmi_device_expected_data_format_build_string_from_mask
+qmi_device_add_link_flags_get_string
</SECTION>
<SECTION>
diff --git a/src/libqmi-glib/qmi-device.c b/src/libqmi-glib/qmi-device.c
index 2e8faf0..d8e82de 100644
--- a/src/libqmi-glib/qmi-device.c
+++ b/src/libqmi-glib/qmi-device.c
@@ -1819,10 +1819,10 @@ add_link_result_free (AddLinkResult *ctx)
}
gchar *
-qmi_device_add_link_finish (QmiDevice *self,
- GAsyncResult *res,
- guint *mux_id,
- GError **error)
+qmi_device_add_link_with_flags_finish (QmiDevice *self,
+ GAsyncResult *res,
+ guint *mux_id,
+ GError **error)
{
AddLinkResult *ctx;
@@ -1836,6 +1836,15 @@ qmi_device_add_link_finish (QmiDevice *self,
return g_steal_pointer (&ctx->ifname);
}
+gchar *
+qmi_device_add_link_finish (QmiDevice *self,
+ GAsyncResult *res,
+ guint *mux_id,
+ GError **error)
+{
+ return qmi_device_add_link_with_flags_finish (self, res, mux_id, error);
+}
+
static void
device_add_link_ready (QmiNetPortManager *net_port_manager,
GAsyncResult *res,
@@ -1858,13 +1867,14 @@ device_add_link_ready (QmiNetPortManager *net_port_manager,
}
void
-qmi_device_add_link (QmiDevice *self,
- guint mux_id,
- const gchar *base_ifname,
- const gchar *ifname_prefix,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+qmi_device_add_link_with_flags (QmiDevice *self,
+ guint mux_id,
+ const gchar *base_ifname,
+ const gchar *ifname_prefix,
+ QmiDeviceAddLinkFlags flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
GTask *task;
GError *error = NULL;
@@ -1887,12 +1897,27 @@ qmi_device_add_link (QmiDevice *self,
mux_id,
base_ifname,
ifname_prefix,
+ flags,
5,
cancellable,
(GAsyncReadyCallback) device_add_link_ready,
task);
}
+void
+qmi_device_add_link (QmiDevice *self,
+ guint mux_id,
+ const gchar *base_ifname,
+ const gchar *ifname_prefix,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ qmi_device_add_link_with_flags (self, mux_id, base_ifname, ifname_prefix,
+ QMI_DEVICE_ADD_LINK_FLAGS_NONE,
+ cancellable, callback, user_data);
+}
+
gboolean
qmi_device_delete_link_finish (QmiDevice *self,
GAsyncResult *res,
diff --git a/src/libqmi-glib/qmi-device.h b/src/libqmi-glib/qmi-device.h
index 93567ce..4fb71b5 100644
--- a/src/libqmi-glib/qmi-device.h
+++ b/src/libqmi-glib/qmi-device.h
@@ -949,6 +949,82 @@ gchar *qmi_device_add_link_finish (QmiDevice *self,
GError **error);
/**
+ * QmiDeviceAddLinkFlags:
+ * @QMI_DEVICE_ADD_LINK_FLAGS_NONE: none.
+ * @QMI_DEVICE_ADD_LINK_FLAGS_INGRESS_MAP_CKSUMV4: checksum offload (v4) is enabled in ingress path.
+ * @QMI_DEVICE_ADD_LINK_FLAGS_EGRESS_MAP_CKSUMV4: checksum offload (v4) is enabled in egress path.
+ *
+ * Flags specifying the behavior of the new link.
+ *
+ * Since: 1.30
+ */
+typedef enum { /*< since=1.30 >*/
+ QMI_DEVICE_ADD_LINK_FLAGS_NONE = 0,
+ QMI_DEVICE_ADD_LINK_FLAGS_INGRESS_MAP_CKSUMV4 = 1 << 1,
+ QMI_DEVICE_ADD_LINK_FLAGS_EGRESS_MAP_CKSUMV4 = 1 << 2,
+} QmiDeviceAddLinkFlags;
+
+/**
+ * qmi_device_add_link_with_flags:
+ * @self: a #QmiDevice.
+ * @mux_id: the mux id for the link, in the
+ * [%QMI_DEVICE_MUX_ID_MIN,%QMI_DEVICE_MUX_ID_MAX] range, or
+ * %QMI_DEVICE_MUX_ID_AUTOMATIC to find the first available mux id.
+ * @base_ifname: the interface which the new link will be created on.
+ * @ifname_prefix: the prefix suggested to be used for the name of the new link
+ * created.
+ * @flags: bitmask of %QmiDeviceAddLinkFlags values to pass to the kernel when
+ * creating the new link.
+ * @cancellable: a #GCancellable, or %NULL.
+ * @callback: a #GAsyncReadyCallback to call when the operation is finished.
+ * @user_data: the data to pass to callback function.
+ *
+ * Asynchronously creates a new virtual network device in the same way as
+ * qmi_device_add_link() does, but passing the additional @flags to the kernel
+ * during the operation.
+ *
+ * Using %QMI_DEVICE_ADD_LINK_FLAGS_NONE as @flags is equivalent to calling
+ * qmi_device_add_link() directly.
+ *
+ * If the link creation with the given set of @flags is unsupported by the
+ * backend, the operation may fail.
+ *
+ * <note><para>
+ * None of the @flags supported are applicable when using the multiplexing
+ * support provided by the qmi_wwan kernel driver, they are only used if using
+ * the rmnet backend for link management support.
+ * </para></note>
+ *
+ * Since: 1.30
+ */
+void qmi_device_add_link_with_flags (QmiDevice *self,
+ guint mux_id,
+ const gchar *base_ifname,
+ const gchar *ifname_prefix,
+ QmiDeviceAddLinkFlags flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+/**
+ * qmi_device_add_link_with_flags_finish:
+ * @self: a #QmiDevice.
+ * @res: a #GAsyncResult.
+ * @mux_id: the mux ID for the link created.
+ * @error: Return location for error or %NULL.
+ *
+ * Finishes an operation started with qmi_device_add_link_finish().
+ *
+ * Returns: The name of the net interface created, %NULL if @error is set.
+ *
+ * Since: 1.30
+ */
+gchar *qmi_device_add_link_with_flags_finish (QmiDevice *self,
+ GAsyncResult *res,
+ guint *mux_id,
+ GError **error);
+
+/**
* qmi_device_delete_link:
* @self: a #QmiDevice.
* @ifname: the name of the link to remove.
diff --git a/src/libqmi-glib/qmi-net-port-manager-qmiwwan.c b/src/libqmi-glib/qmi-net-port-manager-qmiwwan.c
index f6d1466..b620ac5 100644
--- a/src/libqmi-glib/qmi-net-port-manager-qmiwwan.c
+++ b/src/libqmi-glib/qmi-net-port-manager-qmiwwan.c
@@ -23,11 +23,12 @@
#include <limits.h>
#include <stdlib.h>
-#include "qmi-device.h"
+#include "qmi-net-port-manager-qmiwwan.h"
+#include "qmi-enum-types.h"
#include "qmi-error-types.h"
#include "qmi-errors.h"
#include "qmi-helpers.h"
-#include "qmi-net-port-manager-qmiwwan.h"
+
G_DEFINE_TYPE (QmiNetPortManagerQmiwwan, qmi_net_port_manager_qmiwwan, QMI_TYPE_NET_PORT_MANAGER)
@@ -255,14 +256,15 @@ net_port_manager_add_link_finish (QmiNetPortManager *self,
}
static void
-net_port_manager_add_link (QmiNetPortManager *_self,
- guint mux_id,
- const gchar *base_ifname,
- const gchar *ifname_prefix,
- guint timeout,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+net_port_manager_add_link (QmiNetPortManager *_self,
+ guint mux_id,
+ const gchar *base_ifname,
+ const gchar *ifname_prefix,
+ QmiDeviceAddLinkFlags flags,
+ guint timeout,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
QmiNetPortManagerQmiwwan *self = QMI_NET_PORT_MANAGER_QMIWWAN (_self);
GTask *task;
@@ -277,6 +279,16 @@ net_port_manager_add_link (QmiNetPortManager *_self,
task = g_task_new (self, cancellable, callback, user_data);
+ if (flags != QMI_DEVICE_ADD_LINK_FLAGS_NONE) {
+ g_autofree gchar *flags_str = NULL;
+
+ flags_str = qmi_device_add_link_flags_build_string_from_mask (flags);
+ g_task_return_new_error (task, QMI_CORE_ERROR, QMI_CORE_ERROR_UNSUPPORTED,
+ "Adding link with flags '%s' is not supported", flags_str);
+ g_object_unref (task);
+ return;
+ }
+
if (!qmi_helpers_list_links (self->priv->sysfs_file,
cancellable,
NULL,
diff --git a/src/libqmi-glib/qmi-net-port-manager-rmnet.c b/src/libqmi-glib/qmi-net-port-manager-rmnet.c
index bd6727e..eb26129 100644
--- a/src/libqmi-glib/qmi-net-port-manager-rmnet.c
+++ b/src/libqmi-glib/qmi-net-port-manager-rmnet.c
@@ -301,7 +301,9 @@ transaction_new (QmiNetPortManagerRmnet *manager,
static NetlinkMessage *
netlink_message_new_link (guint mux_id,
gchar *ifname,
- guint base_if_index)
+ guint base_if_index,
+ guint rmnet_flags,
+ guint rmnet_mask)
{
NetlinkMessage *msg;
guint linkinfo_pos, datainfo_pos;
@@ -324,8 +326,8 @@ netlink_message_new_link (guint mux_id,
append_netlink_attribute_nested (msg, IFLA_INFO_DATA);
append_netlink_attribute_uint16 (msg, IFLA_RMNET_MUX_ID, mux_id);
- flags.flags = RMNET_FLAGS_EGRESS_MAP_CKSUMV4 | RMNET_FLAGS_INGRESS_MAP_CKSUMV4 | RMNET_FLAGS_INGRESS_DEAGGREGATION;
- flags.mask = flags.flags;
+ flags.flags = rmnet_flags;
+ flags.mask = rmnet_mask;
append_netlink_attribute (msg, IFLA_RMNET_FLAGS, &flags, sizeof (struct ifla_rmnet_flags));
/* Use memcpy to preserve byte alignment */
@@ -460,14 +462,15 @@ net_port_manager_add_link_finish (QmiNetPortManager *self,
}
static void
-net_port_manager_add_link (QmiNetPortManager *_self,
- guint mux_id,
- const gchar *base_ifname,
- const gchar *ifname_prefix,
- guint timeout,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+net_port_manager_add_link (QmiNetPortManager *_self,
+ guint mux_id,
+ const gchar *base_ifname,
+ const gchar *ifname_prefix,
+ QmiDeviceAddLinkFlags flags,
+ guint timeout,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
QmiNetPortManagerRmnet *self = QMI_NET_PORT_MANAGER_RMNET (_self);
NetlinkMessage *msg;
@@ -477,6 +480,8 @@ net_port_manager_add_link (QmiNetPortManager *_self,
gssize bytes_sent;
guint base_if_index;
AddLinkContext *ctx;
+ guint rmnet_flags;
+ guint rmnet_mask;
task = g_task_new (self, cancellable, callback, user_data);
@@ -521,7 +526,17 @@ net_port_manager_add_link (QmiNetPortManager *_self,
ctx->ifname = mux_id_to_ifname (ifname_prefix, ctx->mux_id);
- msg = netlink_message_new_link (ctx->mux_id, ctx->ifname, base_if_index);
+ /* Convert flags from libqmi API to rmnet API */
+ rmnet_flags = RMNET_FLAGS_INGRESS_DEAGGREGATION;
+ if (flags & QMI_DEVICE_ADD_LINK_FLAGS_INGRESS_MAP_CKSUMV4)
+ rmnet_flags |= RMNET_FLAGS_INGRESS_MAP_CKSUMV4;
+ if (flags & QMI_DEVICE_ADD_LINK_FLAGS_EGRESS_MAP_CKSUMV4)
+ rmnet_flags |= RMNET_FLAGS_EGRESS_MAP_CKSUMV4;
+ rmnet_mask = (RMNET_FLAGS_EGRESS_MAP_CKSUMV4 |
+ RMNET_FLAGS_INGRESS_MAP_CKSUMV4 |
+ RMNET_FLAGS_INGRESS_DEAGGREGATION);
+
+ msg = netlink_message_new_link (ctx->mux_id, ctx->ifname, base_if_index, rmnet_flags, rmnet_mask);
/* The task ownership is transferred to the transaction. */
tr = transaction_new (self, msg, timeout, task);
diff --git a/src/libqmi-glib/qmi-net-port-manager.c b/src/libqmi-glib/qmi-net-port-manager.c
index 461fc36..8649ff6 100644
--- a/src/libqmi-glib/qmi-net-port-manager.c
+++ b/src/libqmi-glib/qmi-net-port-manager.c
@@ -29,19 +29,21 @@ G_DEFINE_ABSTRACT_TYPE (QmiNetPortManager, qmi_net_port_manager, G_TYPE_OBJECT)
/*****************************************************************************/
void
-qmi_net_port_manager_add_link (QmiNetPortManager *self,
- guint mux_id,
- const gchar *base_ifname,
- const gchar *ifname_prefix,
- guint timeout,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+qmi_net_port_manager_add_link (QmiNetPortManager *self,
+ guint mux_id,
+ const gchar *base_ifname,
+ const gchar *ifname_prefix,
+ QmiDeviceAddLinkFlags flags,
+ guint timeout,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
QMI_NET_PORT_MANAGER_GET_CLASS (self)->add_link (self,
mux_id,
base_ifname,
ifname_prefix,
+ flags,
timeout,
cancellable,
callback,
diff --git a/src/libqmi-glib/qmi-net-port-manager.h b/src/libqmi-glib/qmi-net-port-manager.h
index c73ebb2..363885e 100644
--- a/src/libqmi-glib/qmi-net-port-manager.h
+++ b/src/libqmi-glib/qmi-net-port-manager.h
@@ -28,6 +28,8 @@
#include <gio/gio.h>
#include <glib-object.h>
+#include "qmi-device.h"
+
#define QMI_TYPE_NET_PORT_MANAGER (qmi_net_port_manager_get_type ())
#define QMI_NET_PORT_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), QMI_TYPE_NET_PORT_MANAGER, QmiNetPortManager))
#define QMI_NET_PORT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), QMI_TYPE_NET_PORT_MANAGER, QmiNetPortManagerClass))
@@ -50,18 +52,19 @@ struct _QmiNetPortManagerClass {
GPtrArray **out_links,
GError **error);
- void (* add_link) (QmiNetPortManager *self,
- guint mux_id,
- const gchar *base_ifname,
- const gchar *ifname_prefix,
- guint timeout,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
- gchar * (* add_link_finish) (QmiNetPortManager *self,
- guint *mux_id,
- GAsyncResult *res,
- GError **error);
+ void (* add_link) (QmiNetPortManager *self,
+ guint mux_id,
+ const gchar *base_ifname,
+ const gchar *ifname_prefix,
+ QmiDeviceAddLinkFlags flags,
+ guint timeout,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gchar * (* add_link_finish) (QmiNetPortManager *self,
+ guint *mux_id,
+ GAsyncResult *res,
+ GError **error);
void (* del_link) (QmiNetPortManager *self,
const gchar *ifname,
@@ -92,18 +95,19 @@ gboolean qmi_net_port_manager_list_links (QmiNetPortManager *self,
GPtrArray **out_links,
GError **error);
-void qmi_net_port_manager_add_link (QmiNetPortManager *self,
- guint mux_id,
- const gchar *base_ifname,
- const gchar *ifname_prefix,
- guint timeout,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-gchar *qmi_net_port_manager_add_link_finish (QmiNetPortManager *self,
- guint *mux_id,
- GAsyncResult *res,
- GError **error);
+void qmi_net_port_manager_add_link (QmiNetPortManager *self,
+ guint mux_id,
+ const gchar *base_ifname,
+ const gchar *ifname_prefix,
+ QmiDeviceAddLinkFlags flags,
+ guint timeout,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gchar *qmi_net_port_manager_add_link_finish (QmiNetPortManager *self,
+ guint *mux_id,
+ GAsyncResult *res,
+ GError **error);
void qmi_net_port_manager_del_link (QmiNetPortManager *self,
const gchar *ifname,