From 655eac52913c98b6a5401640d34aac5d487d73be Mon Sep 17 00:00:00 2001 From: bluhm Date: Thu, 15 Apr 2021 13:42:33 +0000 Subject: [PATCH] On powerpc64 regress/usr.sbin/bgpd/config failed. It parses a config file, writes bgpd's config to stdout and compares it with an expected output. On big endian machines the order of the set of communities is different. The parser used memcmp(3) to sort a struct of integers. This depends of the endianess. The correct way is to compare the integer fields in native byte order. With this change, the resulting order is the same on i386 and powerpc64. OK claudio@ --- regress/usr.sbin/bgpd/config/bgpd.conf.10.ok | 2 +- regress/usr.sbin/bgpd/config/bgpd.conf.11.ok | 4 +- usr.sbin/bgpd/parse.y | 39 ++++++++++++++++---- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/regress/usr.sbin/bgpd/config/bgpd.conf.10.ok b/regress/usr.sbin/bgpd/config/bgpd.conf.10.ok index 6420aba3e0f..b0da8a576f0 100644 --- a/regress/usr.sbin/bgpd/config/bgpd.conf.10.ok +++ b/regress/usr.sbin/bgpd/config/bgpd.conf.10.ok @@ -40,4 +40,4 @@ match from any large-community 1234:5678:1 large-community 1234:5678:2 match from any large-community 1234:5678:1 large-community 1234:5678:2 large-community 1234:5678:3 match from any community 1234:1 large-community 1234:5678:1 match from any large-community 1234:5678:1 community 1234:1 -match from any set { community delete 1234:5678 community delete 1234:* community delete *:5678 community delete local-as:5678 community delete local-as:neighbor-as large-community delete 1234:15:5678 large-community delete *:15:5678 large-community delete local-as:15:5678 large-community delete local-as:15:* large-community delete local-as:15:neighbor-as large-community delete local-as:*:* community 1234:5678 community local-as:5678 community local-as:neighbor-as large-community 1234:15:5678 large-community local-as:15:5678 large-community local-as:15:neighbor-as } +match from any set { community delete 1234:5678 large-community delete 1234:15:5678 community delete *:5678 large-community delete *:15:5678 community delete local-as:5678 large-community delete local-as:15:5678 community delete 1234:* community delete local-as:neighbor-as large-community delete local-as:15:* large-community delete local-as:*:* large-community delete local-as:15:neighbor-as community 1234:5678 large-community 1234:15:5678 community local-as:5678 large-community local-as:15:5678 community local-as:neighbor-as large-community local-as:15:neighbor-as } diff --git a/regress/usr.sbin/bgpd/config/bgpd.conf.11.ok b/regress/usr.sbin/bgpd/config/bgpd.conf.11.ok index 18ab41f24e5..d0997429874 100644 --- a/regress/usr.sbin/bgpd/config/bgpd.conf.11.ok +++ b/regress/usr.sbin/bgpd/config/bgpd.conf.11.ok @@ -33,7 +33,7 @@ match from any ext-community ovs invalid match from any ext-community ovs not-found match from any ext-community rt 64496:201 ext-community soo 64496:202 match from any ext-community rt 64496:301 ext-community soo 4200000001:302 ext-community odi 127.0.0.1:303 -match from any set { ext-community delete ovs valid ext-community delete odi 127.0.0.1:6003 ext-community delete soo 4200000001:6002 ext-community delete ort 0x123456789abf ext-community delete rt 64496:6001 ext-community ovs valid ext-community odi 127.0.0.1:5003 ext-community soo 4200000001:5002 ext-community ort 0x123456789abc ext-community rt 64496:5001 } +match from any set { ext-community delete ovs valid ext-community delete ort 0x123456789abf ext-community delete rt 64496:6001 ext-community delete odi 127.0.0.1:6003 ext-community delete soo 4200000001:6002 ext-community ovs valid ext-community ort 0x123456789abc ext-community rt 64496:5001 ext-community odi 127.0.0.1:5003 ext-community soo 4200000001:5002 } match from any ext-community * * match from any ext-community rt * match from any ext-community soo * @@ -47,7 +47,7 @@ match from any ext-community rt 127.0.0.1:* match from any ext-community soo 64496:* match from any ext-community soo 4200000001:* match from any ext-community soo 127.0.0.1:* -match from any set { ext-community delete odi 127.0.0.1:* ext-community delete soo 4200000001:* ext-community delete rt 64496:* ext-community delete mac-mob * ext-community delete ovs * ext-community delete rt * ext-community delete soo * ext-community delete odi * ext-community delete ort * } +match from any set { ext-community delete ort * ext-community delete mac-mob * ext-community delete ovs * ext-community delete rt * ext-community delete soo * ext-community delete odi * ext-community delete rt 64496:* ext-community delete odi 127.0.0.1:* ext-community delete soo 4200000001:* } match from any ext-community rt 64496:local-as match from any ext-community soo 4200000001:local-as match from any ext-community odi 127.0.0.1:local-as diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y index 79f6c97cb71..c5d987a5ec1 100644 --- a/usr.sbin/bgpd/parse.y +++ b/usr.sbin/bgpd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.414 2021/03/02 09:45:07 claudio Exp $ */ +/* $OpenBSD: parse.y,v 1.415 2021/04/15 13:42:33 bluhm Exp $ */ /* * Copyright (c) 2002, 2003, 2004 Henning Brauer @@ -3557,6 +3557,28 @@ symget(const char *nam) return (NULL); } +static int +cmpcommunity(struct community *a, struct community *b) +{ + if (a->flags > b->flags) + return 1; + if (a->flags < b->flags) + return -1; + if (a->data1 > b->data1) + return 1; + if (a->data1 < b->data1) + return -1; + if (a->data2 > b->data2) + return 1; + if (a->data2 < b->data2) + return -1; + if (a->data3 > b->data3) + return 1; + if (a->data3 < b->data3) + return -1; + return 0; +} + static int getcommunity(char *s, int large, u_int32_t *val, u_int32_t *flag) { @@ -4396,16 +4418,17 @@ filterset_add(struct filter_set_head *sh, struct filter_set *s) switch (s->type) { case ACTION_SET_COMMUNITY: case ACTION_DEL_COMMUNITY: - if (memcmp(&s->action.community, - &t->action.community, - sizeof(s->action.community)) < 0) { + switch (cmpcommunity(&s->action.community, + &t->action.community)) { + case -1: TAILQ_INSERT_BEFORE(t, s, entry); return; - } else if (memcmp(&s->action.community, - &t->action.community, - sizeof(s->action.community)) == 0) + case 0: break; - continue; + case 1: + continue; + } + break; case ACTION_SET_NEXTHOP: /* only last nexthop per AF matters */ if (s->action.nexthop.aid < -- 2.20.1