[ovs-dev] [PATCH 2/3] mcast-snooping: Use IPv6 address for MDB

Flavio Leitner fbl at sysclose.org
Thu Jun 25 20:10:59 UTC 2015


On Tue, Jun 23, 2015 at 05:03:15PM -0300, Thadeu Lima de Souza Cascardo wrote:
> Use IPv6 internally for storing multicast addresses. IPv4 addresses are
> translated to their IPv4-mapped equivalent.
> 
> Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo at redhat.com>
> ---
>  lib/mcast-snooping.c         | 69 +++++++++++++++++++++++++++++++++++---------
>  lib/mcast-snooping.h         | 24 +++++++++++----
>  ofproto/ofproto-dpif-xlate.c |  6 ++--
>  ofproto/ofproto-dpif.c       |  5 ++--
>  4 files changed, 79 insertions(+), 25 deletions(-)
> 
> diff --git a/lib/mcast-snooping.c b/lib/mcast-snooping.c
> index 7b927aa..f2684f3 100644
> --- a/lib/mcast-snooping.c
> +++ b/lib/mcast-snooping.c
> @@ -87,10 +87,11 @@ mcast_bundle_age(const struct mcast_snooping *ms,
>  }
>  
>  static uint32_t
> -mcast_table_hash(const struct mcast_snooping *ms, ovs_be32 grp_ip4,
> -                 uint16_t vlan)
> +mcast_table_hash(const struct mcast_snooping *ms,
> +                 const struct in6_addr *grp_addr, uint16_t vlan)
>  {
> -    return hash_3words((OVS_FORCE uint32_t) grp_ip4, vlan, ms->secret);
> +    return hash_words((const uint32_t *) grp_addr->s6_addr, 4,
> +                      hash_2words(ms->secret, vlan));
>  }
>  
>  static struct mcast_group_bundle *
> @@ -108,8 +109,8 @@ mcast_group_from_lru_node(struct ovs_list *list)
>  /* Searches 'ms' for and returns an mcast group for destination address
>   * 'dip' in 'vlan'. */
>  struct mcast_group *
> -mcast_snooping_lookup(const struct mcast_snooping *ms, ovs_be32 dip,
> -                      uint16_t vlan)
> +mcast_snooping_lookup(const struct mcast_snooping *ms,
> +                      const struct in6_addr *dip, uint16_t vlan)
>      OVS_REQ_RDLOCK(ms->rwlock)
>  {
>      struct mcast_group *grp;
> @@ -117,13 +118,32 @@ mcast_snooping_lookup(const struct mcast_snooping *ms, ovs_be32 dip,
>  
>      hash = mcast_table_hash(ms, dip, vlan);
>      HMAP_FOR_EACH_WITH_HASH (grp, hmap_node, hash, &ms->table) {
> -        if (grp->vlan == vlan && grp->ip4 == dip) {
> +        if (grp->vlan == vlan && ipv6_addr_equals(&grp->addr, dip)) {
>             return grp;
>          }
>      }
>      return NULL;
>  }
>  
> +static inline void
> +in6_addr_set_mapped_ipv4(struct in6_addr *addr, ovs_be32 ip4)
> +{
> +    union ovs_16aligned_in6_addr *taddr = (void *) addr;
> +    memset(taddr->be16, 0, sizeof(taddr->be16));
> +    taddr->be16[5] = 0xffff;
> +    put_16aligned_be32(&taddr->be32[3], ip4);
> +}

I am fine with the ipv4 to ipv6 mapping because it is enforcing
starting with all bits zero, then 16 bits one plus the IPv4 which
is how IPv4 addresses are mapped to IPv6.
[...]

> diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
> index 04f6229..cb6d303 100644
> --- a/ofproto/ofproto-dpif.c
> +++ b/ofproto/ofproto-dpif.c
> @@ -4429,8 +4429,9 @@ ofproto_unixctl_mcast_snooping_show(struct unixctl_conn *conn,
>              bundle = b->port;
>              ofputil_port_to_string(ofbundle_get_a_port(bundle)->up.ofp_port,
>                                     name, sizeof name);
> -            ds_put_format(&ds, "%5s  %4d  "IP_FMT"         %3d\n",
> -                          name, grp->vlan, IP_ARGS(grp->ip4),
> +            ds_put_format(&ds, "%5s  %4d  ", name, grp->vlan);
> +            print_ipv6_addr(&ds, &grp->addr);
> +            ds_put_format(&ds, "         %3d\n",
>                            mcast_bundle_age(ofproto->ms, b));

But here it exposes the internal implementation showing only IPv6
addresses, so everyone looking at the output would have to known
that their IPv4 addresses are mapped into IPv6 space.

fbl




More information about the dev mailing list