From: Maria Matejka Date: Thu, 28 Nov 2024 08:09:00 +0000 (+0100) Subject: Merge commit '00b139bd' into thread-merge-2.16 X-Git-Tag: v3.0.0~66 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cbd986cd35888913b22bdb3ec71120941b08651e;p=thirdparty%2Fbird.git Merge commit '00b139bd' into thread-merge-2.16 --- cbd986cd35888913b22bdb3ec71120941b08651e diff --cc sysdep/linux/netlink.c index ea79a1aa7,533cc2686..9e275152d --- a/sysdep/linux/netlink.c +++ b/sysdep/linux/netlink.c @@@ -1593,8 -1465,24 +1593,24 @@@ done } static inline int - nl_allow_replace(struct krt_proto *p, rte *new) -nl_allow_replace(struct krt_proto *p, rte *new, rte *old) ++nl_allow_replace(struct krt_proto *p, const rte *new, const rte *old) { + /* + * In kernel routing tables, (net, metric) is the primary key. Therefore, we + * can use NL_OP_REPLACE only if the new and and the old route have the same + * kernel metric, otherwise the replace would just add the new route while + * keep the old one. + */ + + if ((p->af != AF_MPLS) && (KRT_CF->sys.metric == 0)) + { - uint new_metric = ea_get_int(new->attrs->eattrs, EA_KRT_METRIC, 0); - uint old_metric = ea_get_int(old->attrs->eattrs, EA_KRT_METRIC, 0); ++ uint new_metric = ea_get_int(new->attrs, &ea_krt_metric, 0); ++ uint old_metric = ea_get_int(old->attrs, &ea_krt_metric, 0); + + if (new_metric != old_metric) + return 0; + } + /* * We use NL_OP_REPLACE for IPv4, it has an issue with not checking for * matching rtm_protocol, but that is OK when dedicated priority is used.