Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lib: create a transparent union sockunion #14736

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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