Message ID | 1603205672-9185-1-git-send-email-dceara@redhat.com |
---|---|
State | Accepted |
Headers | show |
Series | [ovs-dev] ovn-northd: Handle IPv6 addresses with prefixes for port security. | expand |
On Tue, Oct 20, 2020 at 8:25 PM Dumitru Ceara <dceara@redhat.com> wrote: > > Reported-by: Rodolfo Alonso <ralonsoh@redhat.com> > Reported-at: https://bugzilla.redhat.com/1856898 > CC: Numan Siddique <numans@ovn.org> > Fixes: f631376bf75d ("ovn-northd: Handle IPv4 addresses with prefixes in lport port security") > Signed-off-by: Dumitru Ceara <dceara@redhat.com> Thanks Dumitru. I applied this patch to master and backported to 20.09 and 20.06 branches. Numan > --- > lib/ovn-l7.h | 11 +++++++++++ > northd/ovn-northd.c | 35 ++++++++++++++++++++++++++++------- > tests/ovn.at | 40 +++++++++++++++++++++++++++++++--------- > 3 files changed, 70 insertions(+), 16 deletions(-) > > diff --git a/lib/ovn-l7.h b/lib/ovn-l7.h > index 30a7955..9b729db 100644 > --- a/lib/ovn-l7.h > +++ b/lib/ovn-l7.h > @@ -428,6 +428,17 @@ ipv6_addr_is_routable_multicast(const struct in6_addr *ip) { > } > } > > +static inline bool > +ipv6_addr_is_host_zero(const struct in6_addr *prefix, > + const struct in6_addr *mask) > +{ > + /* host-bits-non-zero <=> (prefix ^ mask) & prefix. */ > + struct in6_addr tmp = ipv6_addr_bitxor(prefix, mask); > + > + tmp = ipv6_addr_bitand(&tmp, prefix); > + return ipv6_is_zero(&tmp); > +} > + > #define IPV6_EXT_HEADER_LEN 8 > struct ipv6_ext_header { > uint8_t ip6_nxt_proto; > diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c > index 5b76868..1ca037f 100644 > --- a/northd/ovn-northd.c > +++ b/northd/ovn-northd.c > @@ -4324,10 +4324,20 @@ build_port_security_ipv6_nd_flow( > ipv6_string_mapped(ip6_str, &lla); > ds_put_format(match, " && (nd.target == %s", ip6_str); > > - for(int i = 0; i < n_ipv6_addrs; i++) { > - memset(ip6_str, 0, sizeof(ip6_str)); > - ipv6_string_mapped(ip6_str, &ipv6_addrs[i].addr); > - ds_put_format(match, " || nd.target == %s", ip6_str); > + for (size_t i = 0; i < n_ipv6_addrs; i++) { > + /* When the netmask is applied, if the host portion is > + * non-zero, the host can only use the specified > + * address in the nd.target. If zero, the host is allowed > + * to use any address in the subnet. > + */ > + if (ipv6_addrs[i].plen == 128 > + || !ipv6_addr_is_host_zero(&ipv6_addrs[i].addr, > + &ipv6_addrs[i].mask)) { > + ds_put_format(match, " || nd.target == %s", ipv6_addrs[i].addr_s); > + } else { > + ds_put_format(match, " || nd.target == %s/%d", > + ipv6_addrs[i].network_s, ipv6_addrs[i].plen); > + } > } > > ds_put_format(match, ")))"); > @@ -4353,9 +4363,20 @@ build_port_security_ipv6_flow( > if (pipeline == P_OUT) { > ds_put_cstr(match, "ff00::/8, "); > } > - for(int i = 0; i < n_ipv6_addrs; i++) { > - ipv6_string_mapped(ip6_str, &ipv6_addrs[i].addr); > - ds_put_format(match, "%s, ", ip6_str); > + for (size_t i = 0; i < n_ipv6_addrs; i++) { > + /* When the netmask is applied, if the host portion is > + * non-zero, the host can only use the specified > + * address. If zero, the host is allowed to use any > + * address in the subnet. > + */ > + if (ipv6_addrs[i].plen == 128 > + || !ipv6_addr_is_host_zero(&ipv6_addrs[i].addr, > + &ipv6_addrs[i].mask)) { > + ds_put_format(match, "%s, ", ipv6_addrs[i].addr_s); > + } else { > + ds_put_format(match, "%s/%d, ", ipv6_addrs[i].network_s, > + ipv6_addrs[i].plen); > + } > } > /* Replace ", " by "}". */ > ds_chomp(match, ' '); > diff --git a/tests/ovn.at b/tests/ovn.at > index 27a94e6..81c8762 100644 > --- a/tests/ovn.at > +++ b/tests/ovn.at > @@ -4133,10 +4133,10 @@ for i in 1 2 3; do > if test $j = 1; then > ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown > elif test $j = 2; then > - ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" > + ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j 4343::00$i$j" > ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j > else > - extra_addr="f0:00:00:00:0$i:$i$j fe80::ea2a:eaff:fe28:$i$j" > + extra_addr="f0:00:00:00:0$i:$i$j fe80::ea2a:eaff:fe28:$i$j 4242::00$i$j" > ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr" > ovn-nbctl lsp-set-port-security lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr" > fi > @@ -4352,7 +4352,7 @@ for i in 1 2 3; do > done > > # lp13 has extra port security with mac f0000000113 and ipv6 addr > -# fe80::ea2a:eaff:fe28:0012 > +# fe80::ea2a:eaff:fe28:0012 and 4242::0013 > > # ipv4 packet should be dropped for lp13 with mac f0000000113 > sip=`ip_to_hex 192 168 0 13` > @@ -4366,20 +4366,24 @@ sip=ee800000000000000000000000000000 > for i in 1 2 3; do > tip=fe80000000000000ea2aeafffe2800${i}3 > test_ipv6 11 f00000000011 f00000000${i}${i}3 $sip $tip ${i}3 > + tip=424200000000000000000000000000${i}3 > + test_ipv6 11 f00000000011 f00000000${i}${i}3 $sip $tip ${i}3 > done > > > # ipv6 packet should not be received by lp33 with mac f0000000333 > -# and ip6.dst as fe80::ea2a:eaff:fe28:0023 as it is > -# configured with fe80::ea2a:eaff:fe28:0033 > +# and ip6.dst as fe80::ea2a:eaff:fe28:0023 or 4242::0023 as it is > +# configured with fe80::ea2a:eaff:fe28:0033 and 4242::0033 > # lp11 can send ipv6 traffic as there is no port security > > sip=ee800000000000000000000000000000 > tip=fe80000000000000ea2aeafffe280023 > test_ipv6 11 f00000000011 f00000000333 $sip $tip > +tip=42420000000000000000000000000023 > +test_ipv6 11 f00000000011 f00000000333 $sip $tip > > # ipv6 packet should be allowed for lp[123]3 with mac f0000000${i}${i}3 > -# and ip6.src fe80::ea2a:eaff:fe28:0${i}${i}3 and ip6.src ::. > +# and ip6.src fe80::ea2a:eaff:fe28:0${i}${i}3, 4242::00${i}3 and ip6.src ::. > # and should be dropped for any other ip6.src > # lp21 can receive ipv6 traffic as there is no port security > > @@ -4387,6 +4391,8 @@ tip=ee800000000000000000000000000000 > for i in 1 2 3; do > sip=fe80000000000000ea2aeafffe2800${i}3 > test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 21 > + sip=424200000000000000000000000000${i}3 > + test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 21 > > # Test ICMPv6 MLD reports (v1 and v2) and NS for DAD > sip=00000000000000000000000000000000 > @@ -4404,9 +4410,7 @@ for i in 1 2 3; do > done > > # configure lsp13 to send and received IPv4 packets with an address range > -ovn-nbctl lsp-set-port-security lp13 "f0:00:00:00:00:13 192.168.0.13 20.0.0.4/24 10.0.0.0/24" > - > -sleep 2 > +ovn-nbctl --wait=hv lsp-set-port-security lp13 "f0:00:00:00:00:13 192.168.0.13 20.0.0.4/24 10.0.0.0/24 4242::/64" > > sip=`ip_to_hex 10 0 0 13` > tip=`ip_to_hex 192 168 0 22` > @@ -4419,12 +4423,24 @@ tip=`ip_to_hex 192 168 0 23` > # with dst ip 192.168.0.23 should be allowed > test_ip 13 f00000000013 f00000000023 $sip $tip 23 > > +sip=42420000000000000000000000000014 > +tip=42420000000000000000000000000023 > +# IPv6 packet from lsp13 with src ip 4242::14 destined to lsp23 > +# with dst ip 4242::23 should be received by lsp23 > +test_ipv6 13 f00000000013 f00000000223 $sip $tip 23 > + > sip=`ip_to_hex 192 168 0 33` > tip=`ip_to_hex 10 0 0 15` > # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13 > # with dst ip 10.0.0.15 should be received by lsp13 > test_ip 33 f00000000033 f00000000013 $sip $tip 13 > > +sip=42420000000000000000000000000033 > +tip=42420000000000000000000000000013 > +# IPv6 packet from lsp33 with src ip 4242::33 destined to lsp13 > +# with dst ip 4242::13 should be received by lsp13 > +test_ipv6 33 f00000000333 f00000000013 $sip $tip 13 > + > sip=`ip_to_hex 192 168 0 33` > tip=`ip_to_hex 20 0 0 4` > # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13 > @@ -4437,6 +4453,12 @@ tip=`ip_to_hex 20 0 0 5` > # with dst ip 20.0.0.5 should not be received by lsp13 > test_ip 33 f00000000033 f00000000013 $sip $tip > > +sip=42420000000000000000000000000033 > +tip=42420000000000000000000000000005 > +# IPv6 packet from lsp33 with src ip 4242::33 destined to lsp13 > +# with dst ip 4242::5 should not be received by lsp13 > +test_ipv6 33 f00000000333 f00000000013 $sip $tip 13 > + > sip=`ip_to_hex 192 168 0 33` > tip=`ip_to_hex 20 0 0 255` > # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13 > -- > 1.8.3.1 > > _______________________________________________ > dev mailing list > dev@openvswitch.org > https://mail.openvswitch.org/mailman/listinfo/ovs-dev >
On 10/22/20 3:50 PM, Numan Siddique wrote: > On Tue, Oct 20, 2020 at 8:25 PM Dumitru Ceara <dceara@redhat.com> wrote: >> >> Reported-by: Rodolfo Alonso <ralonsoh@redhat.com> >> Reported-at: https://bugzilla.redhat.com/1856898 >> CC: Numan Siddique <numans@ovn.org> >> Fixes: f631376bf75d ("ovn-northd: Handle IPv4 addresses with prefixes in lport port security") >> Signed-off-by: Dumitru Ceara <dceara@redhat.com> > > Thanks Dumitru. I applied this patch to master and backported to 20.09 > and 20.06 branches. > > Numan > Thanks!
diff --git a/lib/ovn-l7.h b/lib/ovn-l7.h index 30a7955..9b729db 100644 --- a/lib/ovn-l7.h +++ b/lib/ovn-l7.h @@ -428,6 +428,17 @@ ipv6_addr_is_routable_multicast(const struct in6_addr *ip) { } } +static inline bool +ipv6_addr_is_host_zero(const struct in6_addr *prefix, + const struct in6_addr *mask) +{ + /* host-bits-non-zero <=> (prefix ^ mask) & prefix. */ + struct in6_addr tmp = ipv6_addr_bitxor(prefix, mask); + + tmp = ipv6_addr_bitand(&tmp, prefix); + return ipv6_is_zero(&tmp); +} + #define IPV6_EXT_HEADER_LEN 8 struct ipv6_ext_header { uint8_t ip6_nxt_proto; diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c index 5b76868..1ca037f 100644 --- a/northd/ovn-northd.c +++ b/northd/ovn-northd.c @@ -4324,10 +4324,20 @@ build_port_security_ipv6_nd_flow( ipv6_string_mapped(ip6_str, &lla); ds_put_format(match, " && (nd.target == %s", ip6_str); - for(int i = 0; i < n_ipv6_addrs; i++) { - memset(ip6_str, 0, sizeof(ip6_str)); - ipv6_string_mapped(ip6_str, &ipv6_addrs[i].addr); - ds_put_format(match, " || nd.target == %s", ip6_str); + for (size_t i = 0; i < n_ipv6_addrs; i++) { + /* When the netmask is applied, if the host portion is + * non-zero, the host can only use the specified + * address in the nd.target. If zero, the host is allowed + * to use any address in the subnet. + */ + if (ipv6_addrs[i].plen == 128 + || !ipv6_addr_is_host_zero(&ipv6_addrs[i].addr, + &ipv6_addrs[i].mask)) { + ds_put_format(match, " || nd.target == %s", ipv6_addrs[i].addr_s); + } else { + ds_put_format(match, " || nd.target == %s/%d", + ipv6_addrs[i].network_s, ipv6_addrs[i].plen); + } } ds_put_format(match, ")))"); @@ -4353,9 +4363,20 @@ build_port_security_ipv6_flow( if (pipeline == P_OUT) { ds_put_cstr(match, "ff00::/8, "); } - for(int i = 0; i < n_ipv6_addrs; i++) { - ipv6_string_mapped(ip6_str, &ipv6_addrs[i].addr); - ds_put_format(match, "%s, ", ip6_str); + for (size_t i = 0; i < n_ipv6_addrs; i++) { + /* When the netmask is applied, if the host portion is + * non-zero, the host can only use the specified + * address. If zero, the host is allowed to use any + * address in the subnet. + */ + if (ipv6_addrs[i].plen == 128 + || !ipv6_addr_is_host_zero(&ipv6_addrs[i].addr, + &ipv6_addrs[i].mask)) { + ds_put_format(match, "%s, ", ipv6_addrs[i].addr_s); + } else { + ds_put_format(match, "%s/%d, ", ipv6_addrs[i].network_s, + ipv6_addrs[i].plen); + } } /* Replace ", " by "}". */ ds_chomp(match, ' '); diff --git a/tests/ovn.at b/tests/ovn.at index 27a94e6..81c8762 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -4133,10 +4133,10 @@ for i in 1 2 3; do if test $j = 1; then ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown elif test $j = 2; then - ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" + ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j 4343::00$i$j" ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j else - extra_addr="f0:00:00:00:0$i:$i$j fe80::ea2a:eaff:fe28:$i$j" + extra_addr="f0:00:00:00:0$i:$i$j fe80::ea2a:eaff:fe28:$i$j 4242::00$i$j" ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr" ovn-nbctl lsp-set-port-security lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr" fi @@ -4352,7 +4352,7 @@ for i in 1 2 3; do done # lp13 has extra port security with mac f0000000113 and ipv6 addr -# fe80::ea2a:eaff:fe28:0012 +# fe80::ea2a:eaff:fe28:0012 and 4242::0013 # ipv4 packet should be dropped for lp13 with mac f0000000113 sip=`ip_to_hex 192 168 0 13` @@ -4366,20 +4366,24 @@ sip=ee800000000000000000000000000000 for i in 1 2 3; do tip=fe80000000000000ea2aeafffe2800${i}3 test_ipv6 11 f00000000011 f00000000${i}${i}3 $sip $tip ${i}3 + tip=424200000000000000000000000000${i}3 + test_ipv6 11 f00000000011 f00000000${i}${i}3 $sip $tip ${i}3 done # ipv6 packet should not be received by lp33 with mac f0000000333 -# and ip6.dst as fe80::ea2a:eaff:fe28:0023 as it is -# configured with fe80::ea2a:eaff:fe28:0033 +# and ip6.dst as fe80::ea2a:eaff:fe28:0023 or 4242::0023 as it is +# configured with fe80::ea2a:eaff:fe28:0033 and 4242::0033 # lp11 can send ipv6 traffic as there is no port security sip=ee800000000000000000000000000000 tip=fe80000000000000ea2aeafffe280023 test_ipv6 11 f00000000011 f00000000333 $sip $tip +tip=42420000000000000000000000000023 +test_ipv6 11 f00000000011 f00000000333 $sip $tip # ipv6 packet should be allowed for lp[123]3 with mac f0000000${i}${i}3 -# and ip6.src fe80::ea2a:eaff:fe28:0${i}${i}3 and ip6.src ::. +# and ip6.src fe80::ea2a:eaff:fe28:0${i}${i}3, 4242::00${i}3 and ip6.src ::. # and should be dropped for any other ip6.src # lp21 can receive ipv6 traffic as there is no port security @@ -4387,6 +4391,8 @@ tip=ee800000000000000000000000000000 for i in 1 2 3; do sip=fe80000000000000ea2aeafffe2800${i}3 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 21 + sip=424200000000000000000000000000${i}3 + test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 21 # Test ICMPv6 MLD reports (v1 and v2) and NS for DAD sip=00000000000000000000000000000000 @@ -4404,9 +4410,7 @@ for i in 1 2 3; do done # configure lsp13 to send and received IPv4 packets with an address range -ovn-nbctl lsp-set-port-security lp13 "f0:00:00:00:00:13 192.168.0.13 20.0.0.4/24 10.0.0.0/24" - -sleep 2 +ovn-nbctl --wait=hv lsp-set-port-security lp13 "f0:00:00:00:00:13 192.168.0.13 20.0.0.4/24 10.0.0.0/24 4242::/64" sip=`ip_to_hex 10 0 0 13` tip=`ip_to_hex 192 168 0 22` @@ -4419,12 +4423,24 @@ tip=`ip_to_hex 192 168 0 23` # with dst ip 192.168.0.23 should be allowed test_ip 13 f00000000013 f00000000023 $sip $tip 23 +sip=42420000000000000000000000000014 +tip=42420000000000000000000000000023 +# IPv6 packet from lsp13 with src ip 4242::14 destined to lsp23 +# with dst ip 4242::23 should be received by lsp23 +test_ipv6 13 f00000000013 f00000000223 $sip $tip 23 + sip=`ip_to_hex 192 168 0 33` tip=`ip_to_hex 10 0 0 15` # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13 # with dst ip 10.0.0.15 should be received by lsp13 test_ip 33 f00000000033 f00000000013 $sip $tip 13 +sip=42420000000000000000000000000033 +tip=42420000000000000000000000000013 +# IPv6 packet from lsp33 with src ip 4242::33 destined to lsp13 +# with dst ip 4242::13 should be received by lsp13 +test_ipv6 33 f00000000333 f00000000013 $sip $tip 13 + sip=`ip_to_hex 192 168 0 33` tip=`ip_to_hex 20 0 0 4` # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13 @@ -4437,6 +4453,12 @@ tip=`ip_to_hex 20 0 0 5` # with dst ip 20.0.0.5 should not be received by lsp13 test_ip 33 f00000000033 f00000000013 $sip $tip +sip=42420000000000000000000000000033 +tip=42420000000000000000000000000005 +# IPv6 packet from lsp33 with src ip 4242::33 destined to lsp13 +# with dst ip 4242::5 should not be received by lsp13 +test_ipv6 33 f00000000333 f00000000013 $sip $tip 13 + sip=`ip_to_hex 192 168 0 33` tip=`ip_to_hex 20 0 0 255` # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
Reported-by: Rodolfo Alonso <ralonsoh@redhat.com> Reported-at: https://bugzilla.redhat.com/1856898 CC: Numan Siddique <numans@ovn.org> Fixes: f631376bf75d ("ovn-northd: Handle IPv4 addresses with prefixes in lport port security") Signed-off-by: Dumitru Ceara <dceara@redhat.com> --- lib/ovn-l7.h | 11 +++++++++++ northd/ovn-northd.c | 35 ++++++++++++++++++++++++++++------- tests/ovn.at | 40 +++++++++++++++++++++++++++++++--------- 3 files changed, 70 insertions(+), 16 deletions(-)