diff --git a/ic/ovn-ic.c b/ic/ovn-ic.c index 41ef3ec7ed..fea287e053 100644 --- a/ic/ovn-ic.c +++ b/ic/ovn-ic.c @@ -1058,12 +1058,15 @@ prefix_is_black_listed(const struct smap *nb_options, continue; } } else { - struct in6_addr mask = ipv6_create_mask(bl_plen); - for (int i = 0; i < 16 && mask.s6_addr[i] != 0; i++) { - if ((prefix->s6_addr[i] & mask.s6_addr[i]) - != (bl_prefix.s6_addr[i] & mask.s6_addr[i])) { - continue; - } + struct in6_addr mask = ipv6_create_mask(plen); + /* First calculate the difference between bl_prefix and prefix, so + * use the bl mask to ensure prefixes are correctly validated. + * e.g.: 2005:1734:5678::/50 is a subnet of 2005:1234::/21 */ + struct in6_addr m_prefixes = ipv6_addr_bitand(prefix, &bl_prefix); + struct in6_addr m_prefix = ipv6_addr_bitand(&m_prefixes, &mask); + struct in6_addr m_bl_prefix = ipv6_addr_bitand(&bl_prefix, &mask); + if (!ipv6_addr_equals(&m_prefix, &m_bl_prefix)) { + continue; } } matched = true; diff --git a/tests/ovn-ic.at b/tests/ovn-ic.at index c40621d1b0..f3d52a082e 100644 --- a/tests/ovn-ic.at +++ b/tests/ovn-ic.at @@ -1204,3 +1204,102 @@ OVS_WAIT_FOR_OUTPUT([ovn_as az2 ovn-nbctl lr-route-list lr12 | grep dst-ip | sor AT_CLEANUP ]) + +OVN_FOR_EACH_NORTHD([ +AT_SETUP([ovn-ic -- route sync -- IPv6 blacklist filter]) +AT_KEYWORDS([IPv6-route-sync-blacklist]) + +ovn_init_ic_db +check ovn-ic-nbctl ts-add ts1 + +for i in 1 2; do + ovn_start az$i + ovn_as az$i + + # Enable route learning at AZ level + check ovn-nbctl set nb_global . options:ic-route-learn=true + # Enable route advertising at AZ level + check ovn-nbctl set nb_global . options:ic-route-adv=true + # Enable blacklist single filter for IPv6 + check ovn-nbctl set nb_global . options:ic-route-blacklist=" \ + 2003:db8:1::/64,2004:aaaa::/32,2005:1234::/21" + + OVS_WAIT_UNTIL([ovn-nbctl show | grep ts1]) + + # Create LRP and connect to TS + check ovn-nbctl lr-add lr$i + check ovn-nbctl lrp-add lr$i lrp-lr$i-ts1 aa:aa:aa:aa:aa:0$i \ + 2001:db8:1::$i/64 + check ovn-nbctl lsp-add ts1 lsp-ts1-lr$i \ + -- lsp-set-addresses lsp-ts1-lr$i router \ + -- lsp-set-type lsp-ts1-lr$i router \ + -- lsp-set-options lsp-ts1-lr$i router-port=lrp-lr$i-ts1 + + check ovn-nbctl lrp-add lr$i lrp-lr$i-p$i 00:00:00:00:00:0$i \ + 2002:db8:1::$i/64 + + # Create blacklisted LRPs and connect to TS + check ovn-nbctl lrp-add lr$i lrp-lr$i-p-ext$i \ + 11:11:11:11:11:1$i 2003:db8:1::$i/64 + + check ovn-nbctl lrp-add lr$i lrp-lr$i-p-ext2$i \ + 22:22:22:22:22:2$i 2004:aaaa:bbb::$i/48 + + # filtered by 2005:1234::/21 - (2005:1000: - 2005:17ff:) + check ovn-nbctl lrp-add lr$i lrp-lr$i-p-ext3$i \ + 33:33:33:33:33:3$i 2005:1734:5678::$i/50 + + # additional not filtered prefix -> different subnet bits + check ovn-nbctl lrp-add lr$i lrp-lr$i-p-ext4$i \ + 44:44:44:44:44:4$i 2005:1834:5678::$i/50 +done + +for i in 1 2; do + OVS_WAIT_UNTIL([ovn_as az$i ovn-nbctl lr-route-list lr$i | grep learned]) +done + +AT_CHECK([ovn_as az1 ovn-nbctl lr-route-list lr1 | + awk '/learned/{print $1, $2}' ], [0], [dnl +2002:db8:1::/64 2001:db8:1::2 +2005:1834:5678::/50 2001:db8:1::2 +]) + +for i in 1 2; do + ovn_as az$i + + # Drop blacklist + check ovn-nbctl remove nb_global . options ic-route-blacklist +done + +OVS_WAIT_FOR_OUTPUT([ovn_as az1 ovn-nbctl lr-route-list lr1 | + awk '/learned/{print $1, $2}' | sort ], [0], [dnl +2002:db8:1::/64 2001:db8:1::2 +2003:db8:1::/64 2001:db8:1::2 +2004:aaaa:bbb::/48 2001:db8:1::2 +2005:1734:5678::/50 2001:db8:1::2 +2005:1834:5678::/50 2001:db8:1::2 +]) + +for i in 1 2; do + ovn_as az$i + + check ovn-nbctl set nb_global . \ + options:ic-route-blacklist="2003:db8:1::/64,2004:db8:1::/64" + + # Create an 'extra' blacklisted LRP and connect to TS + check ovn-nbctl lrp-add lr$i lrp-lr$i-p-ext5$i \ + 55:55:55:55:55:5$i 2004:db8:1::$i/64 +done + +OVS_WAIT_FOR_OUTPUT([ovn_as az1 ovn-nbctl lr-route-list lr1 | + awk '/learned/{print $1, $2}' | sort ], [0], [dnl +2002:db8:1::/64 2001:db8:1::2 +2004:aaaa:bbb::/48 2001:db8:1::2 +2005:1734:5678::/50 2001:db8:1::2 +2005:1834:5678::/50 2001:db8:1::2 +]) + +OVN_CLEANUP_IC([az1], [az2]) + +AT_CLEANUP +])