summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2020-05-13 13:57:35 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2020-06-04 13:48:48 +0200
commit4d0b3d977578092230d0a4f87d8f5d4195ba5956 (patch)
tree73d43636ffcd192b9d06d1a3a8bd27cea3a43f6c
parent78acfc82e43fc4af28a3315dd3c71d163cb53da1 (diff)
downloadNetworkManager-4d0b3d977578092230d0a4f87d8f5d4195ba5956.tar.gz
move tc parsing out of nm-device.c
The logic to create platform qdiscs from a setting does not belong to NMDevice. Move it to NetworkManagerUtils.h.
-rw-r--r--src/NetworkManagerUtils.c127
-rw-r--r--src/NetworkManagerUtils.h7
-rw-r--r--src/devices/nm-device.c121
3 files changed, 140 insertions, 115 deletions
diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c
index 3f2f44d3cd..f90ea2cc54 100644
--- a/src/NetworkManagerUtils.c
+++ b/src/NetworkManagerUtils.c
@@ -9,6 +9,7 @@
#include "NetworkManagerUtils.h"
#include <linux/fib_rules.h>
+#include <linux/pkt_sched.h>
#include "nm-glib-aux/nm-c-list.h"
@@ -18,6 +19,7 @@
#include "nm-setting-ip4-config.h"
#include "nm-setting-ip6-config.h"
#include "nm-core-internal.h"
+#include "platform/nmp-object.h"
#include "platform/nm-platform.h"
#include "nm-auth-utils.h"
@@ -1125,3 +1127,128 @@ nm_utils_file_is_in_path (const char *abs_filename,
? path
: NULL;
}
+
+/* The returned qdisc array is valid as long as s_tc is not modified */
+GPtrArray *
+nm_utils_qdiscs_from_tc_setting (NMPlatform *platform,
+ NMSettingTCConfig *s_tc,
+ int ip_ifindex)
+{
+ GPtrArray *qdiscs;
+ guint nqdiscs;
+ guint i;
+
+ nqdiscs = nm_setting_tc_config_get_num_qdiscs (s_tc);
+ qdiscs = g_ptr_array_new_full (nqdiscs, (GDestroyNotify) nmp_object_unref);
+
+ for (i = 0; i < nqdiscs; i++) {
+ NMTCQdisc *s_qdisc = nm_setting_tc_config_get_qdisc (s_tc, i);
+ NMPObject *q = nmp_object_new (NMP_OBJECT_TYPE_QDISC, NULL);
+ NMPlatformQdisc *qdisc = NMP_OBJECT_CAST_QDISC (q);
+
+ qdisc->ifindex = ip_ifindex;
+ qdisc->kind = nm_tc_qdisc_get_kind (s_qdisc);
+
+ qdisc->addr_family = AF_UNSPEC;
+ qdisc->handle = nm_tc_qdisc_get_handle (s_qdisc);
+ qdisc->parent = nm_tc_qdisc_get_parent (s_qdisc);
+ qdisc->info = 0;
+
+#define GET_ATTR(name, dst, variant_type, type, dflt) G_STMT_START { \
+ GVariant *_variant = nm_tc_qdisc_get_attribute (s_qdisc, ""name""); \
+ \
+ if ( _variant \
+ && g_variant_is_of_type (_variant, G_VARIANT_TYPE_ ## variant_type)) \
+ (dst) = g_variant_get_ ## type (_variant); \
+ else \
+ (dst) = (dflt); \
+} G_STMT_END
+
+ if (strcmp (qdisc->kind, "fq_codel") == 0) {
+ GET_ATTR ("limit", qdisc->fq_codel.limit, UINT32, uint32, 0);
+ GET_ATTR ("flows", qdisc->fq_codel.flows, UINT32, uint32, 0);
+ GET_ATTR ("target", qdisc->fq_codel.target, UINT32, uint32, 0);
+ GET_ATTR ("interval", qdisc->fq_codel.interval, UINT32, uint32, 0);
+ GET_ATTR ("quantum", qdisc->fq_codel.quantum, UINT32, uint32, 0);
+ GET_ATTR ("ce_threshold", qdisc->fq_codel.ce_threshold, UINT32, uint32, NM_PLATFORM_FQ_CODEL_CE_THRESHOLD_DISABLED);
+ GET_ATTR ("memory_limit", qdisc->fq_codel.memory_limit, UINT32, uint32, NM_PLATFORM_FQ_CODEL_MEMORY_LIMIT_UNSET);
+ GET_ATTR ("ecn", qdisc->fq_codel.ecn, BOOLEAN, boolean, FALSE);
+ }
+
+#undef GET_ADDR
+
+ g_ptr_array_add (qdiscs, q);
+ }
+
+ return qdiscs;
+}
+
+/* The returned tfilter array is valid as long as s_tc is not modified */
+GPtrArray *
+nm_utils_tfilters_from_tc_setting (NMPlatform *platform,
+ NMSettingTCConfig *s_tc,
+ int ip_ifindex)
+{
+ GPtrArray *tfilters;
+ guint ntfilters;
+ guint i;
+
+ ntfilters = nm_setting_tc_config_get_num_tfilters (s_tc);
+ tfilters = g_ptr_array_new_full (ntfilters, (GDestroyNotify) nmp_object_unref);
+
+ for (i = 0; i < ntfilters; i++) {
+ NMTCTfilter *s_tfilter = nm_setting_tc_config_get_tfilter (s_tc, i);
+ NMTCAction *action;
+ NMPObject *t = nmp_object_new (NMP_OBJECT_TYPE_TFILTER, NULL);
+ NMPlatformTfilter *tfilter = NMP_OBJECT_CAST_TFILTER (t);
+
+ tfilter->ifindex = ip_ifindex;
+ tfilter->kind = nm_tc_tfilter_get_kind (s_tfilter);
+ tfilter->addr_family = AF_UNSPEC;
+ tfilter->handle = nm_tc_tfilter_get_handle (s_tfilter);
+ tfilter->parent = nm_tc_tfilter_get_parent (s_tfilter);
+ tfilter->info = TC_H_MAKE (0, htons (ETH_P_ALL));
+
+ action = nm_tc_tfilter_get_action (s_tfilter);
+ if (action) {
+ GVariant *var;
+
+ tfilter->action.kind = nm_tc_action_get_kind (action);
+
+ if (strcmp (tfilter->action.kind, "simple") == 0) {
+ var = nm_tc_action_get_attribute (action, "sdata");
+ if (var && g_variant_is_of_type (var, G_VARIANT_TYPE_BYTESTRING)) {
+ g_strlcpy (tfilter->action.simple.sdata,
+ g_variant_get_bytestring (var),
+ sizeof (tfilter->action.simple.sdata));
+ }
+ } else if (strcmp (tfilter->action.kind, "mirred") == 0) {
+ if (nm_tc_action_get_attribute (action, "egress"))
+ tfilter->action.mirred.egress = TRUE;
+
+ if (nm_tc_action_get_attribute (action, "ingress"))
+ tfilter->action.mirred.ingress = TRUE;
+
+ if (nm_tc_action_get_attribute (action, "mirror"))
+ tfilter->action.mirred.mirror = TRUE;
+
+ if (nm_tc_action_get_attribute (action, "redirect"))
+ tfilter->action.mirred.redirect = TRUE;
+
+ var = nm_tc_action_get_attribute (action, "dev");
+ if (var && g_variant_is_of_type (var, G_VARIANT_TYPE_STRING)) {
+ int ifindex;
+
+ ifindex = nm_platform_link_get_ifindex (platform,
+ g_variant_get_string (var, NULL));
+ if (ifindex > 0)
+ tfilter->action.mirred.ifindex = ifindex;
+ }
+ }
+ }
+
+ g_ptr_array_add (tfilters, t);
+ }
+
+ return tfilters;
+}
diff --git a/src/NetworkManagerUtils.h b/src/NetworkManagerUtils.h
index 558a262b98..38386c3dab 100644
--- a/src/NetworkManagerUtils.h
+++ b/src/NetworkManagerUtils.h
@@ -134,4 +134,11 @@ nm_utils_file_is_in_path (const char *abs_filename,
/*****************************************************************************/
+GPtrArray *nm_utils_qdiscs_from_tc_setting (NMPlatform *platform,
+ NMSettingTCConfig *s_tc,
+ int ip_ifindex);
+GPtrArray *nm_utils_tfilters_from_tc_setting (NMPlatform *platform,
+ NMSettingTCConfig *s_tc,
+ int ip_ifindex);
+
#endif /* __NETWORKMANAGER_UTILS_H__ */
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 327df52c6c..30b16f449b 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -19,7 +19,6 @@
#include <linux/if_addr.h>
#include <linux/if_arp.h>
#include <linux/rtnetlink.h>
-#include <linux/pkt_sched.h>
#include "nm-std-aux/unaligned.h"
#include "nm-glib-aux/nm-dedup-multi.h"
@@ -7295,10 +7294,10 @@ tc_commit (NMDevice *self)
gs_unref_ptrarray GPtrArray *qdiscs = NULL;
gs_unref_ptrarray GPtrArray *tfilters = NULL;
NMSettingTCConfig *s_tc = NULL;
+ NMPlatform *platform;
int ip_ifindex;
- guint nqdiscs, ntfilters;
- guint i;
+ platform = nm_device_get_platform (self);
connection = nm_device_get_applied_connection (self);
if (connection)
s_tc = nm_connection_get_setting_tc_config (connection);
@@ -7308,122 +7307,14 @@ tc_commit (NMDevice *self)
return s_tc == NULL;
if (s_tc) {
- nqdiscs = nm_setting_tc_config_get_num_qdiscs (s_tc);
- qdiscs = g_ptr_array_new_full (nqdiscs, (GDestroyNotify) nmp_object_unref);
-
- for (i = 0; i < nqdiscs; i++) {
- NMTCQdisc *s_qdisc = nm_setting_tc_config_get_qdisc (s_tc, i);
- NMPObject *q = nmp_object_new (NMP_OBJECT_TYPE_QDISC, NULL);
- NMPlatformQdisc *qdisc = NMP_OBJECT_CAST_QDISC (q);
-
- qdisc->ifindex = ip_ifindex;
-
- /* Note: kind string is still owned by NMTCTfilter.
- * This qdisc instance must not be kept alive beyond this function.
- * nm_platform_qdisc_sync() promises to do that. */
- qdisc->kind = nm_tc_qdisc_get_kind (s_qdisc);
-
- qdisc->addr_family = AF_UNSPEC;
- qdisc->handle = nm_tc_qdisc_get_handle (s_qdisc);
- qdisc->parent = nm_tc_qdisc_get_parent (s_qdisc);
- qdisc->info = 0;
-
-#define GET_ATTR(name, dst, variant_type, type, dflt) G_STMT_START { \
- GVariant *_variant = nm_tc_qdisc_get_attribute (s_qdisc, ""name""); \
- \
- if ( _variant \
- && g_variant_is_of_type (_variant, G_VARIANT_TYPE_ ## variant_type)) \
- (dst) = g_variant_get_ ## type (_variant); \
- else \
- (dst) = (dflt); \
-} G_STMT_END
-
- if (strcmp (qdisc->kind, "fq_codel") == 0) {
- GET_ATTR ("limit", qdisc->fq_codel.limit, UINT32, uint32, 0);
- GET_ATTR ("flows", qdisc->fq_codel.flows, UINT32, uint32, 0);
- GET_ATTR ("target", qdisc->fq_codel.target, UINT32, uint32, 0);
- GET_ATTR ("interval", qdisc->fq_codel.interval, UINT32, uint32, 0);
- GET_ATTR ("quantum", qdisc->fq_codel.quantum, UINT32, uint32, 0);
- GET_ATTR ("ce_threshold", qdisc->fq_codel.ce_threshold, UINT32, uint32, NM_PLATFORM_FQ_CODEL_CE_THRESHOLD_DISABLED);
- GET_ATTR ("memory_limit", qdisc->fq_codel.memory_limit, UINT32, uint32, NM_PLATFORM_FQ_CODEL_MEMORY_LIMIT_UNSET);
- GET_ATTR ("ecn", qdisc->fq_codel.ecn, BOOLEAN, boolean, FALSE);
- }
-
-#undef GET_ADDR
-
- g_ptr_array_add (qdiscs, q);
- }
-
- ntfilters = nm_setting_tc_config_get_num_tfilters (s_tc);
- tfilters = g_ptr_array_new_full (ntfilters, (GDestroyNotify) nmp_object_unref);
-
- for (i = 0; i < ntfilters; i++) {
- NMTCTfilter *s_tfilter = nm_setting_tc_config_get_tfilter (s_tc, i);
- NMTCAction *action;
- NMPObject *q = nmp_object_new (NMP_OBJECT_TYPE_TFILTER, NULL);
- NMPlatformTfilter *tfilter = NMP_OBJECT_CAST_TFILTER (q);
-
- tfilter->ifindex = ip_ifindex;
-
- /* Note: kind string is still owned by NMTCTfilter.
- * This tfilter instance must not be kept alive beyond this function.
- * nm_platform_tfilter_sync() promises to do that. */
- tfilter->kind = nm_tc_tfilter_get_kind (s_tfilter);
-
- tfilter->addr_family = AF_UNSPEC;
- tfilter->handle = nm_tc_tfilter_get_handle (s_tfilter);
- tfilter->parent = nm_tc_tfilter_get_parent (s_tfilter);
- tfilter->info = TC_H_MAKE (0, htons (ETH_P_ALL));
-
- action = nm_tc_tfilter_get_action (s_tfilter);
- if (action) {
- GVariant *var;
-
- /* Note: kind string is still owned by NMTCAction.
- * This tfilter instance must not be kept alive beyond this function.
- * nm_platform_tfilter_sync() promises to do that. */
- tfilter->action.kind = nm_tc_action_get_kind (action);
-
- if (strcmp (tfilter->action.kind, "simple") == 0) {
- var = nm_tc_action_get_attribute (action, "sdata");
- if (var && g_variant_is_of_type (var, G_VARIANT_TYPE_BYTESTRING)) {
- g_strlcpy (tfilter->action.simple.sdata,
- g_variant_get_bytestring (var),
- sizeof (tfilter->action.simple.sdata));
- }
- } else if (strcmp (tfilter->action.kind, "mirred") == 0) {
- if (nm_tc_action_get_attribute (action, "egress"))
- tfilter->action.mirred.egress = TRUE;
-
- if (nm_tc_action_get_attribute (action, "ingress"))
- tfilter->action.mirred.ingress = TRUE;
-
- if (nm_tc_action_get_attribute (action, "mirror"))
- tfilter->action.mirred.mirror = TRUE;
-
- if (nm_tc_action_get_attribute (action, "redirect"))
- tfilter->action.mirred.redirect = TRUE;
-
- var = nm_tc_action_get_attribute (action, "dev");
- if (var && g_variant_is_of_type (var, G_VARIANT_TYPE_STRING)) {
- int ifindex;
-
- ifindex = nm_platform_link_get_ifindex (nm_device_get_platform (self),
- g_variant_get_string (var, NULL));
- if (ifindex > 0)
- tfilter->action.mirred.ifindex = ifindex;
- }
- }
- }
-
- g_ptr_array_add (tfilters, q);
- }
+ qdiscs = nm_utils_qdiscs_from_tc_setting (platform, s_tc, ip_ifindex);
+ tfilters = nm_utils_tfilters_from_tc_setting (platform, s_tc, ip_ifindex);
}
- if (!nm_platform_qdisc_sync (nm_device_get_platform (self), ip_ifindex, qdiscs))
+ if (!nm_platform_qdisc_sync (platform, ip_ifindex, qdiscs))
return FALSE;
- if (!nm_platform_tfilter_sync (nm_device_get_platform (self), ip_ifindex, tfilters))
+ if (!nm_platform_tfilter_sync (platform, ip_ifindex, tfilters))
return FALSE;
return TRUE;