diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2020-05-13 13:57:35 +0200 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2020-06-04 13:48:48 +0200 |
commit | 4d0b3d977578092230d0a4f87d8f5d4195ba5956 (patch) | |
tree | 73d43636ffcd192b9d06d1a3a8bd27cea3a43f6c | |
parent | 78acfc82e43fc4af28a3315dd3c71d163cb53da1 (diff) | |
download | NetworkManager-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.c | 127 | ||||
-rw-r--r-- | src/NetworkManagerUtils.h | 7 | ||||
-rw-r--r-- | src/devices/nm-device.c | 121 |
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; |