mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-05 09:58:07 +02:00
platform: rework qdisc synchronization
Rework qdisc synchronization. The previous implementation added all known qdiscs and removed unneeded ones from platform; this had some problems: - kernel doesn't allow to add (with exclusive flag) a qdisc if one with the same parent already exists; - if we use the replace flag instead of add, then it becomes possible to add a new qdisc with the same parent of an existing one. However if the existing qdisc is of the same kind, kernel will try to to change() it, which fails for some qdiscs (e.g. sfq). - kernel doesn't allow to delete a qdisc with handle of zero because that is the default qdisc and can only be replaced; Fix that.
This commit is contained in:
parent
9a4578c8f9
commit
9064502834
2 changed files with 48 additions and 10 deletions
|
|
@ -5064,12 +5064,15 @@ nm_platform_qdisc_sync (NMPlatform *self,
|
|||
|
||||
known_qdiscs_idx = g_hash_table_new ((GHashFunc) nmp_object_id_hash,
|
||||
(GEqualFunc) nmp_object_id_equal);
|
||||
|
||||
if (known_qdiscs) {
|
||||
for (i = 0; i < known_qdiscs->len; i++) {
|
||||
const NMPObject *q = g_ptr_array_index (known_qdiscs, i);
|
||||
|
||||
g_hash_table_insert (known_qdiscs_idx, (gpointer) q, (gpointer) q);
|
||||
if (!g_hash_table_insert (known_qdiscs_idx, (gpointer) q, (gpointer) q)) {
|
||||
_LOGW ("duplicate qdisc %s", nm_platform_qdisc_to_string (&q->qdisc, NULL, 0));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5078,13 +5081,34 @@ nm_platform_qdisc_sync (NMPlatform *self,
|
|||
NMP_OBJECT_TYPE_QDISC,
|
||||
ifindex),
|
||||
NULL, NULL);
|
||||
|
||||
if (plat_qdiscs) {
|
||||
for (i = 0; i < plat_qdiscs->len; i++) {
|
||||
const NMPObject *q = g_ptr_array_index (plat_qdiscs, i);
|
||||
const NMPObject *p = g_ptr_array_index (plat_qdiscs, i);
|
||||
const NMPObject *k;
|
||||
|
||||
if (!g_hash_table_lookup (known_qdiscs_idx, q))
|
||||
success &= nm_platform_object_delete (self, q);
|
||||
/* look up known qdisc with same parent */
|
||||
k = g_hash_table_lookup (known_qdiscs_idx, p);
|
||||
|
||||
if (k) {
|
||||
const NMPlatformQdisc *qdisc_k = NMP_OBJECT_CAST_QDISC (k);
|
||||
const NMPlatformQdisc *qdisc_p = NMP_OBJECT_CAST_QDISC (p);
|
||||
|
||||
/* check other fields */
|
||||
if ( nm_platform_qdisc_cmp_full (qdisc_k, qdisc_p, FALSE) != 0
|
||||
|| ( qdisc_k->handle != qdisc_p->handle
|
||||
&& qdisc_k != 0)) {
|
||||
k = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (k) {
|
||||
g_hash_table_remove (known_qdiscs_idx, k);
|
||||
} else {
|
||||
/* can't delete qdisc with zero handle */
|
||||
if (TC_H_MAJ (p->qdisc.handle) != 0) {
|
||||
success &= nm_platform_object_delete (self, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5092,8 +5116,10 @@ nm_platform_qdisc_sync (NMPlatform *self,
|
|||
for (i = 0; i < known_qdiscs->len; i++) {
|
||||
const NMPObject *q = g_ptr_array_index (known_qdiscs, i);
|
||||
|
||||
success &= (nm_platform_qdisc_add (self, NMP_NLM_FLAG_ADD,
|
||||
NMP_OBJECT_CAST_QDISC (q)) >= 0);
|
||||
if (g_hash_table_contains (known_qdiscs_idx, q)) {
|
||||
success &= (nm_platform_qdisc_add (self, NMP_NLM_FLAG_ADD,
|
||||
NMP_OBJECT_CAST_QDISC (q)) >= 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6518,14 +6544,17 @@ nm_platform_qdisc_hash_update (const NMPlatformQdisc *obj, NMHashState *h)
|
|||
}
|
||||
|
||||
int
|
||||
nm_platform_qdisc_cmp (const NMPlatformQdisc *a, const NMPlatformQdisc *b)
|
||||
nm_platform_qdisc_cmp_full (const NMPlatformQdisc *a,
|
||||
const NMPlatformQdisc *b,
|
||||
gboolean compare_handle)
|
||||
{
|
||||
NM_CMP_SELF (a, b);
|
||||
NM_CMP_FIELD (a, b, ifindex);
|
||||
NM_CMP_FIELD (a, b, parent);
|
||||
NM_CMP_FIELD_STR_INTERNED (a, b, kind);
|
||||
NM_CMP_FIELD (a, b, addr_family);
|
||||
NM_CMP_FIELD (a, b, handle);
|
||||
if (compare_handle)
|
||||
NM_CMP_FIELD (a, b, handle);
|
||||
NM_CMP_FIELD (a, b, info);
|
||||
|
||||
if (nm_streq0 (a->kind, "fq_codel")) {
|
||||
|
|
@ -6542,6 +6571,12 @@ nm_platform_qdisc_cmp (const NMPlatformQdisc *a, const NMPlatformQdisc *b)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
nm_platform_qdisc_cmp (const NMPlatformQdisc *a, const NMPlatformQdisc *b)
|
||||
{
|
||||
return nm_platform_qdisc_cmp_full (a, b, TRUE);
|
||||
}
|
||||
|
||||
const char *
|
||||
nm_platform_tfilter_to_string (const NMPlatformTfilter *tfilter, char *buf, gsize len)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1909,6 +1909,9 @@ nm_platform_routing_rule_cmp_full (const NMPlatformRoutingRule *a, const NMPlatf
|
|||
}
|
||||
|
||||
int nm_platform_qdisc_cmp (const NMPlatformQdisc *a, const NMPlatformQdisc *b);
|
||||
int nm_platform_qdisc_cmp_full (const NMPlatformQdisc *a,
|
||||
const NMPlatformQdisc *b,
|
||||
gboolean compare_handle);
|
||||
int nm_platform_tfilter_cmp (const NMPlatformTfilter *a, const NMPlatformTfilter *b);
|
||||
|
||||
void nm_platform_link_hash_update (const NMPlatformLink *obj, NMHashState *h);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue