ubgpsuite/lonetix/include/df/bgp/asn.h

88 lines
2.4 KiB
C
Executable File

// SPDX-License-Identifier: LGPL-3.0-or-later
/**
* \file bgp/asn.h
*
* Types, constant and utilities to work with ASN of various width.
*
* \copyright The DoubleFourteen Code Forge (C) All Rights Reserved
* \author Lorenzo Cogotti
*/
#ifndef DF_BGP_ASN_H_
#define DF_BGP_ASN_H_
#include "xpt.h"
/// 2 octet `AS_TRANS` constant, in network order (big-endian).
#define AS_TRANS BE16(23456)
/// 4 octet `AS_TRANS` constant, in network order (big-endian).
#define AS4_TRANS BE32(23456)
/// 2 bytes wide AS number (ASN16), in network order (big-endian).
typedef Uint16 Asn16;
/// 4 bytes wide AS number (ASN32), in network order (big-endian).
typedef Uint32 Asn32;
/**
* \brief Fat AS type capable of holding either a 4 octet (ASN32) or a 2 octet
* (ASN16) AS number, with additional flags indicating ASN properties.
*
* \note This type doesn't reflect any actual BGP ASN encoding, it is merely
* a convenience abstraction, useful when ASN properties should be bundled
* with the actual ASN.
*/
typedef Sint64 Asn; // NOTE: signed so negative values may be used for
// special purposes if necessary
/// `Asn` flag indicating that the currently stored ASN is 4 octet wide (ASN32).
#define ASN32BITFLAG BIT(62)
/**
* \brief Return an `Asn` holding an `Asn16` value.
*
* \note `asn` must be in network order (big endian).
*/
#define ASN16BIT(asn) ((Asn) ((Asn16) (asn)))
/**
* \brief Return an `Asn` holding a `Asn32`.
*
* \note `asn` should be in network order (big endian).
*/
#define ASN32BIT(asn) ((Asn) (ASN32BITFLAG | ((Asn) ((Asn32) asn))))
/// Test whether an `Asn` is holding a 4 octet wide ASN.
FORCE_INLINE Boolean ISASN32BIT(Asn asn)
{
return (asn & ASN32BITFLAG) != 0;
}
/**
* \brief Extract AS number stored inside an `Asn`.
*
* Returned ASN is extended to `Asn32` even if it was originally an `Asn16`,
* this allows code involving `Asn` to treat any ASN uniformly.
*
* \note Resulting ASN is in network byte order (big endian).
*/
FORCE_INLINE Asn32 ASN(Asn asn)
{
Asn32 res = asn & 0xffffffffuLL;
#if EDN_NATIVE != EDN_BE
// Shift _asn of 16 bits if this was originally ASN16,
// on LE machines this mimics a BE16 word to BE32 dword extension
res <<= (((asn & ASN32BITFLAG) == 0) << 4);
#endif
return res;
}
/// Test whether `asn` represents either `AS_TRANS` or `AS4_TRANS`.
FORCE_INLINE Boolean ISASTRANS(Asn asn)
{
return ASN(asn) == AS4_TRANS;
}
#endif