mirror of
https://github.com/FRRouting/frr.git
synced 2025-04-30 21:47:15 +02:00
Merge ca2a57a67d
into 3dd4d417be
This commit is contained in:
commit
0a13d89d38
|
@ -74,7 +74,7 @@ static inline int bgp_is_withdraw_label(mpls_label_t *label)
|
||||||
|
|
||||||
static inline int bgp_is_valid_label(const mpls_label_t *label)
|
static inline int bgp_is_valid_label(const mpls_label_t *label)
|
||||||
{
|
{
|
||||||
uint8_t *t = (uint8_t *)label;
|
const uint8_t *t = (const uint8_t *)label;
|
||||||
if (!t)
|
if (!t)
|
||||||
return 0;
|
return 0;
|
||||||
return (t[2] & 0x02);
|
return (t[2] & 0x02);
|
||||||
|
|
11
configure.ac
11
configure.ac
|
@ -448,6 +448,17 @@ AH_VERBATIM([OpenBSD], [
|
||||||
#endif
|
#endif
|
||||||
])
|
])
|
||||||
|
|
||||||
|
dnl Debian 8.3.0-6 has a broken -Wdiscarded-qualifiers
|
||||||
|
dnl Gentoo 7.5.0 and 8.4.0 are both fine, so either it's gcc 8.3 or Debian's
|
||||||
|
dnl meddling. I'm guessing the latter. (2025-01-27 equinox)
|
||||||
|
AC_MSG_CHECKING([whether $CC is a broken Debian GCC 8.3])
|
||||||
|
if $CC -v 2>&1 | grep -q -E '^gcc.*Debian 8\.3\.'; then
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
CFLAGS="$CFLAGS -Wno-discarded-qualifiers"
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
fi
|
||||||
|
|
||||||
dnl always want these CFLAGS
|
dnl always want these CFLAGS
|
||||||
AC_C_FLAG([-fms-extensions], [
|
AC_C_FLAG([-fms-extensions], [
|
||||||
AC_MSG_ERROR([$CC does not support unnamed struct fields (-fms-extensions)])
|
AC_MSG_ERROR([$CC does not support unnamed struct fields (-fms-extensions)])
|
||||||
|
|
|
@ -32,11 +32,15 @@ struct ipv6_ph {
|
||||||
|
|
||||||
extern uint16_t in_cksumv(const struct iovec *iov, size_t iov_len);
|
extern uint16_t in_cksumv(const struct iovec *iov, size_t iov_len);
|
||||||
|
|
||||||
|
/* note the (char *) in the casts below is needed to make this header work
|
||||||
|
* when compiled as C++ as it behaves differently with const qualification
|
||||||
|
*/
|
||||||
|
|
||||||
static inline uint16_t in_cksum(const void *data, size_t nbytes)
|
static inline uint16_t in_cksum(const void *data, size_t nbytes)
|
||||||
{
|
{
|
||||||
struct iovec iov[1];
|
struct iovec iov[1];
|
||||||
|
|
||||||
iov[0].iov_base = (void *)data;
|
iov[0].iov_base = unconst((char *)data);
|
||||||
iov[0].iov_len = nbytes;
|
iov[0].iov_len = nbytes;
|
||||||
return in_cksumv(iov, array_size(iov));
|
return in_cksumv(iov, array_size(iov));
|
||||||
}
|
}
|
||||||
|
@ -46,9 +50,9 @@ static inline uint16_t in_cksum_with_ph4(const struct ipv4_ph *ph,
|
||||||
{
|
{
|
||||||
struct iovec iov[2];
|
struct iovec iov[2];
|
||||||
|
|
||||||
iov[0].iov_base = (void *)ph;
|
iov[0].iov_base = unconst(ph);
|
||||||
iov[0].iov_len = sizeof(*ph);
|
iov[0].iov_len = sizeof(*ph);
|
||||||
iov[1].iov_base = (void *)data;
|
iov[1].iov_base = unconst((char *)data);
|
||||||
iov[1].iov_len = nbytes;
|
iov[1].iov_len = nbytes;
|
||||||
return in_cksumv(iov, array_size(iov));
|
return in_cksumv(iov, array_size(iov));
|
||||||
}
|
}
|
||||||
|
@ -58,9 +62,9 @@ static inline uint16_t in_cksum_with_ph6(const struct ipv6_ph *ph,
|
||||||
{
|
{
|
||||||
struct iovec iov[2];
|
struct iovec iov[2];
|
||||||
|
|
||||||
iov[0].iov_base = (void *)ph;
|
iov[0].iov_base = unconst(ph);
|
||||||
iov[0].iov_len = sizeof(*ph);
|
iov[0].iov_len = sizeof(*ph);
|
||||||
iov[1].iov_base = (void *)data;
|
iov[1].iov_base = unconst((char *)data);
|
||||||
iov[1].iov_len = nbytes;
|
iov[1].iov_len = nbytes;
|
||||||
return in_cksumv(iov, array_size(iov));
|
return in_cksumv(iov, array_size(iov));
|
||||||
}
|
}
|
||||||
|
|
127
lib/compiler.h
127
lib/compiler.h
|
@ -6,7 +6,16 @@
|
||||||
#ifndef _FRR_COMPILER_H
|
#ifndef _FRR_COMPILER_H
|
||||||
#define _FRR_COMPILER_H
|
#define _FRR_COMPILER_H
|
||||||
|
|
||||||
|
#if defined(__cplusplus) || defined(test__cplusplus)
|
||||||
|
/* -Wcast-qual is not supported in the FRR codebase with C++, since the macros
|
||||||
|
* don't work
|
||||||
|
*/
|
||||||
|
#pragma GCC diagnostic ignored "-Wcast-qual"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -266,7 +275,98 @@ extern "C" {
|
||||||
#undef container_of
|
#undef container_of
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define typeof(x) decltype(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* strip qualifiers of a type */
|
||||||
|
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L
|
||||||
|
/* nothing - typeof_unqual is in ISO C23. note that that is normally
|
||||||
|
* 202311L, but gcc 14 claims 202000L for -std=gnu23 and that works too
|
||||||
|
*/
|
||||||
|
|
||||||
|
#elif !defined(__cplusplus) && (__GNUC__ >= 14 || (defined(__clang__) && __clang_major__ >= 19))
|
||||||
|
/* __typeof_unqual__ is available as an alias for the C23 feature for use
|
||||||
|
* outside C23 mode in GCC >= 14 and clang >= 19
|
||||||
|
*/
|
||||||
|
#define typeof_unqual(_t) __typeof_unqual__(_t)
|
||||||
|
|
||||||
|
#else
|
||||||
|
/* this works because a function return value can't have qualifiers attached.
|
||||||
|
* unfortunately there is a warning about the very thing we're intentionally
|
||||||
|
* doing here (ignoring the qualifiers), so mute that
|
||||||
|
*
|
||||||
|
* declaring a variable with this type would also do it, except that'll barf
|
||||||
|
* if we try to declare a variable of type "void"; a function pointer is fine
|
||||||
|
*
|
||||||
|
* turn off clang-format because it wrecks the _Pragma formatting
|
||||||
|
*/
|
||||||
|
/* clang-format off */
|
||||||
|
#define typeof_unqual(_t) \
|
||||||
|
typeof(({ \
|
||||||
|
_Pragma("GCC diagnostic push") \
|
||||||
|
_Pragma("GCC diagnostic ignored \"-Wignored-qualifiers\"") \
|
||||||
|
typeof(_t) (*_v)(void); \
|
||||||
|
_Pragma("GCC diagnostic pop") \
|
||||||
|
_v(); \
|
||||||
|
}))
|
||||||
|
/* clang-format on */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(__cplusplus)
|
||||||
|
/* cast val (pointer type) into the same type but without const
|
||||||
|
* this is built to work with -Wcast-qual, hence the cast via uintptr_t
|
||||||
|
*
|
||||||
|
* the type is automatically determined to help against accidentally changing
|
||||||
|
* into some other type while intending to only remove the const
|
||||||
|
*/
|
||||||
|
#define unconst(_val) \
|
||||||
|
({ \
|
||||||
|
__auto_type _v = _val; \
|
||||||
|
typeof_unqual(*_v) * d; \
|
||||||
|
(typeof(d))(uintptr_t)_v; \
|
||||||
|
})
|
||||||
|
#else
|
||||||
|
#define unconst(_val) \
|
||||||
|
({ \
|
||||||
|
auto _v = _val; \
|
||||||
|
const_cast<decltype(({ \
|
||||||
|
auto _t = *_v; \
|
||||||
|
&_t; \
|
||||||
|
}))>(_v); \
|
||||||
|
})
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !(defined(__cplusplus) || defined(test__cplusplus))
|
#if !(defined(__cplusplus) || defined(test__cplusplus))
|
||||||
|
/* returns 1 if v is a pointer to const (e.g. "const char *x; is_const_ptr(x)")
|
||||||
|
* or bare type specification (e.g. "is_const_ptr(const char *)")
|
||||||
|
* (supporting the latter is the reason for some extra hoops to jump through)
|
||||||
|
* "w" exists only to avoid a "duplicate use of const" warning on clang
|
||||||
|
*/
|
||||||
|
#define is_const_ptr(_v) \
|
||||||
|
__builtin_types_compatible_p(typeof(_v), typeof(({ \
|
||||||
|
typeof(_v) _w; \
|
||||||
|
const typeof(*_w) *_x; \
|
||||||
|
_x; \
|
||||||
|
})))
|
||||||
|
|
||||||
|
/* shortcut */
|
||||||
|
#define is_const_ptr2(_v1, _v2) is_const_ptr(_v1) || is_const_ptr(_v2)
|
||||||
|
|
||||||
|
/* conditionally add const. It is intentional that the combination of "const"
|
||||||
|
* and "typ" happens on the preprocessor level here, which is not quite the
|
||||||
|
* same thing as doing "const typeof(x)".
|
||||||
|
*/
|
||||||
|
#define constlify(cond, typ) \
|
||||||
|
typeof(__builtin_choose_expr(cond, ({ \
|
||||||
|
const typ _x; \
|
||||||
|
_x; \
|
||||||
|
}), \
|
||||||
|
({ \
|
||||||
|
typ _x; \
|
||||||
|
_x; \
|
||||||
|
})))
|
||||||
|
|
||||||
/* this variant of container_of() retains 'const' on pointers without needing
|
/* this variant of container_of() retains 'const' on pointers without needing
|
||||||
* to be told to do so. The following will all work without warning:
|
* to be told to do so. The following will all work without warning:
|
||||||
*
|
*
|
||||||
|
@ -284,22 +384,19 @@ extern "C" {
|
||||||
* struct cont *x = container_of(cp, struct cont, member);
|
* struct cont *x = container_of(cp, struct cont, member);
|
||||||
* struct cont *x = container_of(cp, const struct cont, member);
|
* struct cont *x = container_of(cp, const struct cont, member);
|
||||||
* struct cont *x = container_of(p, const struct cont, member);
|
* struct cont *x = container_of(p, const struct cont, member);
|
||||||
|
*
|
||||||
|
* _mptype, _outtype and _chtype are here to make compiler warnings better.
|
||||||
*/
|
*/
|
||||||
#define container_of(ptr, type, member) \
|
#define container_of(ptr, type, member) \
|
||||||
(__builtin_choose_expr( \
|
({ \
|
||||||
__builtin_types_compatible_p(typeof(&((type *)0)->member), \
|
__auto_type _p = ptr; /* avoid multiple eval */ \
|
||||||
typeof(ptr)) \
|
constlify(is_const_ptr2(_p, type *), typeof(((type *)0)->member) *) _mptype; \
|
||||||
|| __builtin_types_compatible_p(void *, typeof(ptr)), \
|
constlify(is_const_ptr2(_p, type *), typeof_unqual(type) *) _outtype; \
|
||||||
({ \
|
constlify(is_const_ptr2(_p, type *), char *) _chtype; \
|
||||||
typeof(((type *)0)->member) *__mptr = (void *)(ptr); \
|
typeof(_mptype) _memberptr = _p; /* input type check */ \
|
||||||
(type *)((char *)__mptr - offsetof(type, member)); \
|
(typeof(_outtype))((typeof(_chtype))_memberptr - offsetof(type, member)); \
|
||||||
}), \
|
})
|
||||||
({ \
|
|
||||||
typeof(((const type *)0)->member) *__mptr = (ptr); \
|
|
||||||
(const type *)((const char *)__mptr - \
|
|
||||||
offsetof(type, member)); \
|
|
||||||
}) \
|
|
||||||
))
|
|
||||||
#else
|
#else
|
||||||
/* current C++ compilers don't have the builtins used above; so this version
|
/* current C++ compilers don't have the builtins used above; so this version
|
||||||
* of the macro doesn't do the const check. */
|
* of the macro doesn't do the const check. */
|
||||||
|
|
|
@ -171,8 +171,14 @@ extern void _hook_unregister(struct hook *hook, void *funcptr, void *arg,
|
||||||
#define hook_call(hookname, ...) hook_call_##hookname(__VA_ARGS__)
|
#define hook_call(hookname, ...) hook_call_##hookname(__VA_ARGS__)
|
||||||
|
|
||||||
/* helpers to add the void * arg */
|
/* helpers to add the void * arg */
|
||||||
|
#ifndef __cplusplus
|
||||||
#define HOOK_ADDDEF(...) (void *hookarg , ## __VA_ARGS__)
|
#define HOOK_ADDDEF(...) (void *hookarg , ## __VA_ARGS__)
|
||||||
#define HOOK_ADDARG(...) (hookarg , ## __VA_ARGS__)
|
#define HOOK_ADDARG(...) (hookarg , ## __VA_ARGS__)
|
||||||
|
#else
|
||||||
|
/* apparently the preprocessor behaves differently in C++ mode... */
|
||||||
|
#define HOOK_ADDDEF(...) (void *hookarg __VA_OPT__(, )##__VA_ARGS__)
|
||||||
|
#define HOOK_ADDARG(...) (hookarg __VA_OPT__(, )##__VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* and another helper to convert () into (void) to get a proper prototype */
|
/* and another helper to convert () into (void) to get a proper prototype */
|
||||||
#define _SKIP_10(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, ret, ...) ret
|
#define _SKIP_10(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, ret, ...) ret
|
||||||
|
|
|
@ -124,7 +124,7 @@ static inline void ipv4_mapped_ipv6_to_ipv4(const struct in6_addr *in6,
|
||||||
struct in_addr *in)
|
struct in_addr *in)
|
||||||
{
|
{
|
||||||
memset(in, 0, sizeof(struct in_addr));
|
memset(in, 0, sizeof(struct in_addr));
|
||||||
memcpy(in, (char *)in6 + 12, sizeof(struct in_addr));
|
memcpy(in, (const char *)in6 + 12, sizeof(struct in_addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -145,8 +145,7 @@ static inline int ipaddr_cmp(const struct ipaddr *a, const struct ipaddr *b)
|
||||||
return (va < vb) ? -1 : 1;
|
return (va < vb) ? -1 : 1;
|
||||||
return 0;
|
return 0;
|
||||||
case IPADDR_V6:
|
case IPADDR_V6:
|
||||||
return memcmp((void *)&a->ipaddr_v6, (void *)&b->ipaddr_v6,
|
return memcmp(&a->ipaddr_v6, &b->ipaddr_v6, sizeof(a->ipaddr_v6));
|
||||||
sizeof(a->ipaddr_v6));
|
|
||||||
case IPADDR_NONE:
|
case IPADDR_NONE:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,7 +133,7 @@ static inline void vni2label(vni_t vni, mpls_label_t *label)
|
||||||
|
|
||||||
static inline vni_t label2vni(const mpls_label_t *label)
|
static inline vni_t label2vni(const mpls_label_t *label)
|
||||||
{
|
{
|
||||||
uint8_t *tag = (uint8_t *)label;
|
const uint8_t *tag = (const uint8_t *)label;
|
||||||
vni_t vni;
|
vni_t vni;
|
||||||
|
|
||||||
assert(tag);
|
assert(tag);
|
||||||
|
|
|
@ -72,41 +72,36 @@ skiplist_new(/* encouraged: set list.del callback on new lists */
|
||||||
|
|
||||||
extern void skiplist_free(struct skiplist *);
|
extern void skiplist_free(struct skiplist *);
|
||||||
|
|
||||||
extern int skiplist_insert(register struct skiplist *l, register void *key,
|
extern int skiplist_insert(struct skiplist *l, void *key, void *value);
|
||||||
register void *value);
|
|
||||||
|
|
||||||
extern int skiplist_delete(register struct skiplist *l, register void *key,
|
extern int skiplist_delete(struct skiplist *l, void *key, void *value);
|
||||||
register void *value);
|
|
||||||
|
|
||||||
extern int skiplist_search(register struct skiplist *l, register void *key,
|
extern int skiplist_search(struct skiplist *l, void *key, void **valuePointer);
|
||||||
void **valuePointer);
|
|
||||||
|
|
||||||
extern int skiplist_first_value(register struct skiplist *l, /* in */
|
extern int skiplist_first_value(struct skiplist *l, /* in */
|
||||||
register const void *key, /* in */
|
const void *key, /* in */
|
||||||
void **valuePointer, /* in/out */
|
void **valuePointer, /* in/out */
|
||||||
void **cursor); /* out */
|
void **cursor); /* out */
|
||||||
|
|
||||||
extern int skiplist_next_value(register struct skiplist *l, /* in */
|
extern int skiplist_next_value(struct skiplist *l, /* in */
|
||||||
register const void *key, /* in */
|
const void *key, /* in */
|
||||||
void **valuePointer, /* in/out */
|
void **valuePointer, /* in/out */
|
||||||
void **cursor); /* in/out */
|
void **cursor); /* in/out */
|
||||||
|
|
||||||
extern int skiplist_first(register struct skiplist *l, void **keyPointer,
|
extern int skiplist_first(struct skiplist *l, void **keyPointer, void **valuePointer);
|
||||||
void **valuePointer);
|
|
||||||
|
|
||||||
extern int skiplist_last(register struct skiplist *l, void **keyPointer,
|
extern int skiplist_last(struct skiplist *l, void **keyPointer, void **valuePointer);
|
||||||
void **valuePointer);
|
|
||||||
|
|
||||||
extern int skiplist_delete_first(register struct skiplist *l);
|
extern int skiplist_delete_first(struct skiplist *l);
|
||||||
|
|
||||||
extern int skiplist_next(register struct skiplist *l, /* in */
|
extern int skiplist_next(struct skiplist *l, /* in */
|
||||||
void **keyPointer, /* out */
|
void **keyPointer, /* out */
|
||||||
void **valuePointer, /* out */
|
void **valuePointer, /* out */
|
||||||
void **cursor); /* in/out */
|
void **cursor); /* in/out */
|
||||||
|
|
||||||
extern int skiplist_empty(register struct skiplist *l); /* in */
|
extern int skiplist_empty(struct skiplist *l); /* in */
|
||||||
|
|
||||||
extern unsigned int skiplist_count(register struct skiplist *l); /* in */
|
extern unsigned int skiplist_count(struct skiplist *l); /* in */
|
||||||
|
|
||||||
struct vty;
|
struct vty;
|
||||||
extern void skiplist_debug(struct vty *vty, struct skiplist *l);
|
extern void skiplist_debug(struct vty *vty, struct skiplist *l);
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* clang-format off */
|
||||||
|
|
||||||
/* generic macros for all list-like types */
|
/* generic macros for all list-like types */
|
||||||
|
|
||||||
/* to iterate using the const variants of the functions, append "_const" to
|
/* to iterate using the const variants of the functions, append "_const" to
|
||||||
|
@ -62,40 +64,40 @@ extern "C" {
|
||||||
#define TYPESAFE_FIRST_NEXT(prefix, type) \
|
#define TYPESAFE_FIRST_NEXT(prefix, type) \
|
||||||
macro_pure type *prefix ## _first(struct prefix##_head *h) \
|
macro_pure type *prefix ## _first(struct prefix##_head *h) \
|
||||||
{ \
|
{ \
|
||||||
return (type *)prefix ## _const_first(h); \
|
return unconst(prefix ## _const_first(h)); \
|
||||||
} \
|
} \
|
||||||
macro_pure type *prefix ## _next(struct prefix##_head *h, type *item) \
|
macro_pure type *prefix ## _next(struct prefix##_head *h, type *item) \
|
||||||
{ \
|
{ \
|
||||||
return (type *)prefix ## _const_next(h, item); \
|
return unconst(prefix ## _const_next(h, item)); \
|
||||||
} \
|
} \
|
||||||
/* ... */
|
/* ... */
|
||||||
#define TYPESAFE_LAST_PREV(prefix, type) \
|
#define TYPESAFE_LAST_PREV(prefix, type) \
|
||||||
macro_pure type *prefix ## _last(struct prefix##_head *h) \
|
macro_pure type *prefix ## _last(struct prefix##_head *h) \
|
||||||
{ \
|
{ \
|
||||||
return (type *)prefix ## _const_last(h); \
|
return unconst(prefix ## _const_last(h)); \
|
||||||
} \
|
} \
|
||||||
macro_pure type *prefix ## _prev(struct prefix##_head *h, type *item) \
|
macro_pure type *prefix ## _prev(struct prefix##_head *h, type *item) \
|
||||||
{ \
|
{ \
|
||||||
return (type *)prefix ## _const_prev(h, item); \
|
return unconst(prefix ## _const_prev(h, item)); \
|
||||||
} \
|
} \
|
||||||
/* ... */
|
/* ... */
|
||||||
#define TYPESAFE_FIND(prefix, type) \
|
#define TYPESAFE_FIND(prefix, type) \
|
||||||
macro_inline type *prefix ## _find(struct prefix##_head *h, \
|
macro_inline type *prefix ## _find(struct prefix##_head *h, \
|
||||||
const type *item) \
|
const type *item) \
|
||||||
{ \
|
{ \
|
||||||
return (type *)prefix ## _const_find(h, item); \
|
return unconst(prefix ## _const_find(h, item)); \
|
||||||
} \
|
} \
|
||||||
/* ... */
|
/* ... */
|
||||||
#define TYPESAFE_FIND_CMP(prefix, type) \
|
#define TYPESAFE_FIND_CMP(prefix, type) \
|
||||||
macro_inline type *prefix ## _find_lt(struct prefix##_head *h, \
|
macro_inline type *prefix ## _find_lt(struct prefix##_head *h, \
|
||||||
const type *item) \
|
const type *item) \
|
||||||
{ \
|
{ \
|
||||||
return (type *)prefix ## _const_find_lt(h, item); \
|
return unconst(prefix ## _const_find_lt(h, item)); \
|
||||||
} \
|
} \
|
||||||
macro_inline type *prefix ## _find_gteq(struct prefix##_head *h, \
|
macro_inline type *prefix ## _find_gteq(struct prefix##_head *h, \
|
||||||
const type *item) \
|
const type *item) \
|
||||||
{ \
|
{ \
|
||||||
return (type *)prefix ## _const_find_gteq(h, item); \
|
return unconst(prefix ## _const_find_gteq(h, item)); \
|
||||||
} \
|
} \
|
||||||
/* ... */
|
/* ... */
|
||||||
|
|
||||||
|
|
|
@ -147,7 +147,7 @@ static inline int pim_sgaddr_cmp(const pim_sgaddr a, const pim_sgaddr b)
|
||||||
|
|
||||||
static inline uint32_t pim_sgaddr_hash(const pim_sgaddr a, uint32_t initval)
|
static inline uint32_t pim_sgaddr_hash(const pim_sgaddr a, uint32_t initval)
|
||||||
{
|
{
|
||||||
return jhash2((uint32_t *)&a, sizeof(a) / sizeof(uint32_t), initval);
|
return jhash2((const uint32_t *)&a, sizeof(a) / sizeof(uint32_t), initval);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _FRR_ATTRIBUTE_PRINTFRR
|
#ifdef _FRR_ATTRIBUTE_PRINTFRR
|
||||||
|
|
|
@ -62,6 +62,7 @@ vtysh_cmd_head = """/* autogenerated file, DO NOT EDIT! */
|
||||||
#include "vtysh/vtysh.h"
|
#include "vtysh/vtysh.h"
|
||||||
|
|
||||||
#pragma GCC visibility push(internal)
|
#pragma GCC visibility push(internal)
|
||||||
|
#pragma GCC diagnostic ignored "-Wcast-qual"
|
||||||
|
|
||||||
#define MAKE_VECTOR(name, len, ...) \\
|
#define MAKE_VECTOR(name, len, ...) \\
|
||||||
static void * name ## _vitems[] = { __VA_ARGS__ }; \\
|
static void * name ## _vitems[] = { __VA_ARGS__ }; \\
|
||||||
|
|
Loading…
Reference in a new issue