Skip to content

Commit

Permalink
Merge pull request #14736 from opensourcerouting/transparent-sockunion
Browse files Browse the repository at this point in the history
lib: create a transparent union `sockunion`
  • Loading branch information
donaldsharp authored Nov 6, 2023
2 parents 23ebea3 + bf098b4 commit b66dc09
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 22 deletions.
4 changes: 2 additions & 2 deletions lib/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -424,10 +424,10 @@ _Static_assert(sizeof(_uint64_t) == 8 && sizeof(_int64_t) == 8,
* type.)
*/
#ifndef __cplusplus
#define prefixtype(uname, typename, fieldname) typename *fieldname;
#define uniontype(uname, typename, fieldname) typename *fieldname;
#define TRANSPARENT_UNION __attribute__((transparent_union))
#else
#define prefixtype(uname, typename, fieldname) \
#define uniontype(uname, typename, fieldname) \
typename *fieldname; \
uname(typename *x) \
{ \
Expand Down
26 changes: 14 additions & 12 deletions lib/prefix.h
Original file line number Diff line number Diff line change
Expand Up @@ -286,23 +286,25 @@ struct prefix_sg {
struct in_addr grp;
};

/* clang-format off */
union prefixptr {
prefixtype(prefixptr, struct prefix, p)
prefixtype(prefixptr, struct prefix_ipv4, p4)
prefixtype(prefixptr, struct prefix_ipv6, p6)
prefixtype(prefixptr, struct prefix_evpn, evp)
prefixtype(prefixptr, struct prefix_fs, fs)
prefixtype(prefixptr, struct prefix_rd, rd)
uniontype(prefixptr, struct prefix, p)
uniontype(prefixptr, struct prefix_ipv4, p4)
uniontype(prefixptr, struct prefix_ipv6, p6)
uniontype(prefixptr, struct prefix_evpn, evp)
uniontype(prefixptr, struct prefix_fs, fs)
uniontype(prefixptr, struct prefix_rd, rd)
} TRANSPARENT_UNION;

union prefixconstptr {
prefixtype(prefixconstptr, const struct prefix, p)
prefixtype(prefixconstptr, const struct prefix_ipv4, p4)
prefixtype(prefixconstptr, const struct prefix_ipv6, p6)
prefixtype(prefixconstptr, const struct prefix_evpn, evp)
prefixtype(prefixconstptr, const struct prefix_fs, fs)
prefixtype(prefixconstptr, const struct prefix_rd, rd)
uniontype(prefixconstptr, const struct prefix, p)
uniontype(prefixconstptr, const struct prefix_ipv4, p4)
uniontype(prefixconstptr, const struct prefix_ipv6, p6)
uniontype(prefixconstptr, const struct prefix_evpn, evp)
uniontype(prefixconstptr, const struct prefix_fs, fs)
uniontype(prefixconstptr, const struct prefix_rd, rd)
} TRANSPARENT_UNION;
/* clang-format on */

#ifndef INET_ADDRSTRLEN
#define INET_ADDRSTRLEN 16
Expand Down
34 changes: 34 additions & 0 deletions lib/sockunion.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#ifndef _ZEBRA_SOCKUNION_H
#define _ZEBRA_SOCKUNION_H

#include "compiler.h"

#include "privs.h"
#include "if.h"
#include <sys/un.h>
Expand All @@ -27,8 +29,40 @@ union sockunion {
struct sockaddr_mpls smpls;
struct sockaddr_rtlabel rtlabel;
#endif

/* sockaddr_storage is guaranteed to be larger than the others */
struct sockaddr_storage sa_storage;
};

/* clang-format off */
/* for functions that want to accept any sockaddr pointer without casts */
union sockaddrptr {
uniontype(sockaddrptr, union sockunion, su)
uniontype(sockaddrptr, struct sockaddr, sa)
uniontype(sockaddrptr, struct sockaddr_in, sin)
uniontype(sockaddrptr, struct sockaddr_in6, sin6)
uniontype(sockaddrptr, struct sockaddr_un, sun)
#ifdef __OpenBSD__
uniontype(sockaddrptr, struct sockaddr_mpls, smpls)
uniontype(sockaddrptr, struct sockaddr_rtlabel, rtlabel)
#endif
uniontype(sockaddrptr, struct sockaddr_storage, sa_storage)
} TRANSPARENT_UNION;

union sockaddrconstptr {
uniontype(sockaddrconstptr, const union sockunion, su)
uniontype(sockaddrconstptr, const struct sockaddr, sa)
uniontype(sockaddrconstptr, const struct sockaddr_in, sin)
uniontype(sockaddrconstptr, const struct sockaddr_in6, sin6)
uniontype(sockaddrconstptr, const struct sockaddr_un, sun)
#ifdef __OpenBSD__
uniontype(sockaddrconstptr, const struct sockaddr_mpls, smpls)
uniontype(sockaddrconstptr, const struct sockaddr_rtlabel, rtlabel)
#endif
uniontype(sockaddrconstptr, const struct sockaddr_storage, sa_storage)
} TRANSPARENT_UNION;
/* clang-format on */

enum connect_result { connect_error, connect_success, connect_in_progress };

/* Default address family. */
Expand Down
16 changes: 8 additions & 8 deletions pimd/pim_addr.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ typedef struct in_addr pim_addr;
#define PIM_ADDR_FUNCNAME(name) ipv4_##name

union pimprefixptr {
prefixtype(pimprefixptr, struct prefix, p)
prefixtype(pimprefixptr, struct prefix_ipv4, p4)
uniontype(pimprefixptr, struct prefix, p)
uniontype(pimprefixptr, struct prefix_ipv4, p4)
} TRANSPARENT_UNION;

union pimprefixconstptr {
prefixtype(pimprefixconstptr, const struct prefix, p)
prefixtype(pimprefixconstptr, const struct prefix_ipv4, p4)
uniontype(pimprefixconstptr, const struct prefix, p)
uniontype(pimprefixconstptr, const struct prefix_ipv4, p4)
} TRANSPARENT_UNION;

#else
Expand All @@ -63,13 +63,13 @@ typedef struct in6_addr pim_addr;
#define PIM_ADDR_FUNCNAME(name) ipv6_##name

union pimprefixptr {
prefixtype(pimprefixptr, struct prefix, p)
prefixtype(pimprefixptr, struct prefix_ipv6, p6)
uniontype(pimprefixptr, struct prefix, p)
uniontype(pimprefixptr, struct prefix_ipv6, p6)
} TRANSPARENT_UNION;

union pimprefixconstptr {
prefixtype(pimprefixconstptr, const struct prefix, p)
prefixtype(pimprefixconstptr, const struct prefix_ipv6, p6)
uniontype(pimprefixconstptr, const struct prefix, p)
uniontype(pimprefixconstptr, const struct prefix_ipv6, p6)
} TRANSPARENT_UNION;
#endif

Expand Down

0 comments on commit b66dc09

Please sign in to comment.