On Wed, 21 Feb 2018 21:26:50 -0500 Donald Sharp <sha...@cumulusnetworks.com> wrote:
> The vxlan driver when a neighbor add/delete event occurs sends > NDA_DST filled with a union: > > union vxlan_addr { > struct sockaddr_in sin; > struct sockaddr_in6 sin6; > struct sockaddr sa; > }; > > This eventually calls rt_addr_n2a_r which had no handler for the > AF_BRIDGE family and "???" was being printed. > > Add code to properly display this data when requested. > > Signed-off-by: Donald Sharp <sha...@cumulusnetworks.com> Minor style comment. > --- > lib/utils.c | 18 ++++++++++++++++++ > 1 file changed, 18 insertions(+) > > diff --git a/lib/utils.c b/lib/utils.c > index 24aeddd8..e01e18a7 100644 > --- a/lib/utils.c > +++ b/lib/utils.c > @@ -1004,6 +1004,24 @@ const char *rt_addr_n2a_r(int af, int len, > } > case AF_PACKET: > return ll_addr_n2a(addr, len, ARPHRD_VOID, buf, buflen); > + case AF_BRIDGE: > + { > + unsigned short family = ((struct sockaddr *)addr)->sa_family; > + struct sockaddr_in6 *sin6; > + struct sockaddr_in *sin; > + Since you are doing aliasing, would it be clearer to do? union { struct sockaddr sa; struct sockaddr_in6 sin6; struct sockaddr_in sin; } *sa = addr; > + switch(family) { > + case AF_INET: > + sin = (struct sockaddr_in *)addr; Casting a void pointer is unnecessary > + return inet_ntop(AF_INET, &sin->sin_addr, buf, buflen); > + case AF_INET6: > + sin6 = (struct sockaddr_in6 *)addr; > + return inet_ntop(AF_INET6, &sin6->sin6_addr, > + buf, buflen); > + } > + > + /* fallthrough */ > + } > default: > return "???"; > }