On Mon, 2023-01-23 at 10:01 +0100, Lorenzo Bianconi wrote: > Avoid learning Link-Local reserved multicast addresses if advertised in > a MLD reports since this interferes with Slaac IPv6 address resolution > implemented in OVN. > > Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2154930 > Tested-by: Eduardo Olivares <eoliv...@redhat.com> > Signed-off-by: Lorenzo Bianconi <lorenzo.bianc...@redhat.com> > --- > lib/mcast-snooping.c | 69 ++++++++++++++++++++++++++++++++------------ > lib/packets.c | 11 +++++++ > lib/packets.h | 13 +++++++++ > 3 files changed, 74 insertions(+), 19 deletions(-) > > diff --git a/lib/mcast-snooping.c b/lib/mcast-snooping.c > index 029ca2855..a9d2e7900 100644 > --- a/lib/mcast-snooping.c > +++ b/lib/mcast-snooping.c > @@ -38,6 +38,8 @@ > COVERAGE_DEFINE(mcast_snooping_learned); > COVERAGE_DEFINE(mcast_snooping_expired); > > +VLOG_DEFINE_THIS_MODULE(mcast_snooping); > + > static struct mcast_port_bundle * > mcast_snooping_port_lookup(struct ovs_list *list, void *port); > static struct mcast_mrouter_bundle * > @@ -489,6 +491,28 @@ mcast_snooping_add_report(struct mcast_snooping *ms, > return count; > } > > +static bool > +mcast_snooping_should_learn_mld_group(struct in6_addr *addr) > +{ > + /* we should learn multicast group from the following IPv6 multicast
Is this supposed to be "should *not* learn multicast group"? Dan > + * groups: > + * - All Nodes Address (ff02::1) > + * - All Router Address (ff02::2) > + * - All Site Router Address (ff05::2) > + * - Solicited-Node Address (ff02::1:ff00:0000/104) > + */ > + if (in6_addr_is_solicited_node(addr) || ipv6_is_all_hosts(addr) || > + ipv6_is_all_router(addr) || ipv6_is_all_site_router(addr)) { > + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); > + char ip_str[INET6_ADDRSTRLEN + 1]; > + > + ipv6_string_mapped(ip_str, addr); > + VLOG_DBG_RL(&rl, "Invalid Multicast group %s", ip_str); > + return false; > + } > + return true; > +} > + > int > mcast_snooping_add_mld(struct mcast_snooping *ms, > const struct dp_packet *p, > @@ -531,26 +555,33 @@ mcast_snooping_add_mld(struct mcast_snooping *ms, > break; > } > /* Only consider known record types. */ > - if (record->type >= IGMPV3_MODE_IS_INCLUDE > - && record->type <= IGMPV3_BLOCK_OLD_SOURCES) { > - struct in6_addr maddr; > - memcpy(maddr.s6_addr, record->maddr.be16, 16); > - addr = &maddr; > - /* > - * If record is INCLUDE MODE and there are no sources, it's > - * equivalent to a LEAVE. > - */ > - if (record->nsrcs == htons(0) > - && (record->type == IGMPV3_MODE_IS_INCLUDE > - || record->type == IGMPV3_CHANGE_TO_INCLUDE_MODE)) { > - ret = mcast_snooping_leave_group(ms, addr, vlan, port); > - } else { > - ret = mcast_snooping_add_group(ms, addr, vlan, port); > - } > - if (ret) { > - count++; > - } > + if (record->type < IGMPV3_MODE_IS_INCLUDE || > + record->type > IGMPV3_BLOCK_OLD_SOURCES) { > + goto next; > + } > + > + struct in6_addr maddr; > + memcpy(maddr.s6_addr, record->maddr.be16, 16); > + if (!mcast_snooping_should_learn_mld_group(&maddr)) { > + goto next; > + } > + > + /* > + * If record is INCLUDE MODE and there are no sources, it's > + * equivalent to a LEAVE. > + */ > + addr = &maddr; > + if (record->nsrcs == htons(0) > + && (record->type == IGMPV3_MODE_IS_INCLUDE > + || record->type == IGMPV3_CHANGE_TO_INCLUDE_MODE)) { > + ret = mcast_snooping_leave_group(ms, addr, vlan, port); > + } else { > + ret = mcast_snooping_add_group(ms, addr, vlan, port); > + } > + if (ret) { > + count++; > } > +next: > offset += sizeof(*record) > + ntohs(record->nsrcs) * sizeof(struct in6_addr) > + record->aux_len; > diff --git a/lib/packets.c b/lib/packets.c > index 06f516cb1..b43f78bc1 100644 > --- a/lib/packets.c > +++ b/lib/packets.c > @@ -38,6 +38,7 @@ > const struct in6_addr in6addr_exact = IN6ADDR_EXACT_INIT; > const struct in6_addr in6addr_all_hosts = IN6ADDR_ALL_HOSTS_INIT; > const struct in6_addr in6addr_all_routers = IN6ADDR_ALL_ROUTERS_INIT; > +const struct in6_addr in6addr_all_site_routers = > IN6ADDR_ALL_SITE_ROUTERS_INIT; > > struct in6_addr > flow_tnl_dst(const struct flow_tnl *tnl) > @@ -605,6 +606,16 @@ in6_addr_solicited_node(struct in6_addr *addr, const > struct in6_addr *ip6) > memcpy(&addr->s6_addr[13], &ip6->s6_addr[13], 3); > } > > +bool > +in6_addr_is_solicited_node(struct in6_addr *addr) > +{ > + union ovs_16aligned_in6_addr *taddr = > + (union ovs_16aligned_in6_addr *) addr; > + return taddr->be16[0] == htons(0xff02) && > + taddr->be16[5] == htons(0x1) && > + taddr->be16[6] == htons(0xff00); > +} > + > /* > * Generates ipv6 EUI64 address from the given eth addr > * and prefix and stores it in 'lla' > diff --git a/lib/packets.h b/lib/packets.h > index 8626aac8d..e88753456 100644 > --- a/lib/packets.h > +++ b/lib/packets.h > @@ -1146,6 +1146,10 @@ extern const struct in6_addr in6addr_all_routers; > #define IN6ADDR_ALL_ROUTERS_INIT { { { > 0xff,0x02,0x00,0x00,0x00,0x00,0x00,0x00, \ > > 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02 } } } > > +extern const struct in6_addr in6addr_all_site_routers; > +#define IN6ADDR_ALL_SITE_ROUTERS_INIT { { { > 0xff,0x05,0x00,0x00,0x00,0x00,0x00,0x00, \ > + > 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02 } } } > + > static inline bool ipv6_addr_equals(const struct in6_addr *a, > const struct in6_addr *b) > { > @@ -1169,6 +1173,14 @@ static inline bool ipv6_is_all_hosts(const struct > in6_addr *addr) { > return ipv6_addr_equals(addr, &in6addr_all_hosts); > } > > +static inline bool ipv6_is_all_router(const struct in6_addr *addr) { > + return ipv6_addr_equals(addr, &in6addr_all_routers); > +} > + > +static inline bool ipv6_is_all_site_router(const struct in6_addr *addr) { > + return ipv6_addr_equals(addr, &in6addr_all_site_routers); > +} > + > static inline bool ipv6_addr_is_set(const struct in6_addr *addr) { > return !ipv6_addr_equals(addr, &in6addr_any); > } > @@ -1207,6 +1219,7 @@ in6_addr_get_mapped_ipv4(const struct in6_addr *addr) > > void in6_addr_solicited_node(struct in6_addr *addr, > const struct in6_addr *ip6); > +bool in6_addr_is_solicited_node(struct in6_addr *addr); > > void in6_generate_eui64(struct eth_addr ea, const struct in6_addr *prefix, > struct in6_addr *lla); _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev