aboutsummaryrefslogtreecommitdiffstats
path: root/lib/includes/hicn/base.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/includes/hicn/base.h')
-rw-r--r--lib/includes/hicn/base.h348
1 files changed, 268 insertions, 80 deletions
diff --git a/lib/includes/hicn/base.h b/lib/includes/hicn/base.h
index 1061724ce..dcbe47877 100644
--- a/lib/includes/hicn/base.h
+++ b/lib/includes/hicn/base.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2021-2022 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
@@ -21,6 +21,8 @@
#ifndef HICN_BASE_H
#define HICN_BASE_H
+#include <stdio.h>
+#include <stdbool.h>
#include "common.h"
#ifdef _WIN32
#include <Winsock2.h>
@@ -30,20 +32,29 @@
/* Default header fields */
#define HICN_DEFAULT_TTL 254
+#define SYMBOLIC_NAME_LEN 16
+
+/* hICN attribute types */
+
+/* Face id */
+
typedef u32 hicn_faceid_t;
-typedef u8 hicn_pathlabel_t;
+
+/* Lifetime */
+
typedef u32 hicn_lifetime_t;
-#define HICN_MAX_LIFETIME_SCALED 0xFFFF
-#define HICN_MAX_LIFETIME_MULTIPLIER 0x0F /* 4 bits */
-#define HICN_MAX_LIFETIME HICN_MAX_LIFETIME_SCALED << HICN_MAX_LIFETIME_MULTIPLIER
+#define HICN_MAX_LIFETIME_SCALED 0xFFFF
+#define HICN_MAX_LIFETIME_MULTIPLIER 0x0F /* 4 bits */
+#define HICN_MAX_LIFETIME \
+ HICN_MAX_LIFETIME_SCALED << HICN_MAX_LIFETIME_MULTIPLIER
/**
* @brief hICN packet format type
*
- * The hICN type represents the sequence of protocols that we can find in packet
- * headers. They are represented as a quartet of u8 values, correponding to
- * IANA protocol assignment, and read from right to left. This is done to
+ * The hICN type represents the sequence of protocols that we can find in
+ * packet headers. They are represented as a quartet of u8 values, correponding
+ * to IANA protocol assignment, and read from right to left. This is done to
* faciliate decapsulation of packet header by simple shift/mask operations.
*
* For instance, an IPv6/TCP packet will be identified as :
@@ -53,72 +64,168 @@ typedef u32 hicn_lifetime_t;
* currently used by an hypothetical signed MAP-Me update :
* [IPPROTO_ICMPRD, IPPROTO_AH, IPPROTO_ICMP, IPPROTO_IPV6]
*/
-typedef union
-{
- /** protocol layers representation */
- struct
- {
-#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
- u8 l1; /**< First layer */
- u8 l2; /**< Second layer */
- u8 l3; /**< Third layer */
- u8 l4; /**< Fourth layer */
-#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
- u8 l4; /**< Fourth layer */
- u8 l3; /**< Third layer */
- u8 l2; /**< Second layer */
- u8 l1; /**< First layer */
-#elif _WIN32 /* Windows is assumed little-endian */
- u8 l1;
- u8 l2;
- u8 l3;
- u8 l4;
-#else
-#error "Unsupported endianness"
-#endif
- };
- /** u32 representation */
- u32 as_u32;
-} hicn_type_t;
+
+typedef uint32_t hicn_packet_format_t;
/* Common protocol layers */
-/* Common protocol layers */
-#ifndef _WIN32
-#define HICN_TYPE(x,y,z,t) (hicn_type_t) {{ .l1 = x, .l2 = y, .l3 = z, .l4 = t }}
-#else
-inline hicn_type_t
-HICN_TYPE(int x, int y, int z, int t)
-{
- hicn_type_t type;
- type.l1 = x;
- type.l2 = y;
- type.l3 = z;
- type.l4 = t;
- return type;
-}
+#define HICN_PACKET_FORMAT(x, y, z, t) \
+ (uint32_t) (((x) << 24) + ((y) << 16) + ((z) << 8) + (t))
+
+#define HICN_PACKET_FORMAT_SIZE 4
+
+// i = 0..3
+#define HICN_PACKET_FORMAT_GET(format, i) \
+ (i < 0 || i > 3) ? IPPROTO_NONE : ((format >> ((3 - (i)) << 3)) & 0xFF)
+
+#define HICN_PACKET_FORMAT_SET(format, i, val) \
+ format = ((val << ((3 - i) << 3)) | \
+ (format & (0xFFFFFFFF ^ (0xFF << ((3 - i) << 3)))))
+
+#define HICN_PACKET_FORMAT_ENUMERATE(FORMAT, POS, PROTOCOL, BODY) \
+ for (unsigned POS = 0; POS <= HICN_PACKET_FORMAT_SIZE - 1; POS++) \
+ { \
+ uint8_t PROTOCOL = HICN_PACKET_FORMAT_GET (FORMAT, POS); \
+ BODY; \
+ }
+
+#define HICN_PACKET_FORMAT_L1(format) HICN_PACKET_FORMAT_L ((format), 0)
+#define HICN_PACKET_FORMAT_L2(format) HICN_PACKET_FORMAT_L ((format), 1)
+#define HICN_PACKET_FORMAT_L3(format) HICN_PACKET_FORMAT_L ((format), 2)
+#define HICN_PACKET_FORMAT_L4(format) HICN_PACKET_FORMAT_L ((format), 3)
+
+extern const char *const _protocol_str[];
+
+#define protocol_str(x) protocol_str[x]
+
+int hicn_packet_format_snprintf (char *s, size_t size,
+ hicn_packet_format_t format);
+
+#define MAXSZ_HICN_PACKET_FORMAT 4 * 4 + 3 // ICMP/ICMP/ICMP/ICMP
+
+#if !defined(__cplusplus)
+#define constexpr const
#endif
-#define HICN_TYPE_IPV4_TCP HICN_TYPE(IPPROTO_IP, IPPROTO_TCP, IPPROTO_NONE, IPPROTO_NONE)
-#define HICN_TYPE_IPV4_ICMP HICN_TYPE(IPPROTO_IP, IPPROTO_ICMP, IPPROTO_NONE, IPPROTO_NONE)
-#define HICN_TYPE_IPV6_TCP HICN_TYPE(IPPROTO_IPV6, IPPROTO_TCP, IPPROTO_NONE, IPPROTO_NONE)
-#define HICN_TYPE_IPV6_ICMP HICN_TYPE(IPPROTO_IPV6, IPPROTO_ICMPV6, IPPROTO_NONE, IPPROTO_NONE)
-#define HICN_TYPE_IPV4_TCP_AH HICN_TYPE(IPPROTO_IP, IPPROTO_TCP, IPPROTO_AH, IPPROTO_NONE)
-#define HICN_TYPE_IPV4_ICMP_AH HICN_TYPE(IPPROTO_IP, IPPROTO_ICMP, IPPROTO_AH, IPPROTO_NONE)
-#define HICN_TYPE_IPV6_TCP_AH HICN_TYPE(IPPROTO_IPV6, IPPROTO_TCP, IPPROTO_AH, IPPROTO_NONE)
-#define HICN_TYPE_IPV6_ICMP_AH HICN_TYPE(IPPROTO_IPV6, IPPROTO_ICMPV6, IPPROTO_AH, IPPROTO_NONE)
-#define HICN_TYPE_NONE HICN_TYPE(IPPROTO_NONE, IPPROTO_NONE, IPPROTO_NONE, IPPROTO_NONE)
+#define HICN_PACKET_FORMAT_IPV4_TCP \
+ HICN_PACKET_FORMAT (IPPROTO_IP, IPPROTO_TCP, IPPROTO_NONE, IPPROTO_NONE)
+#define HICN_PACKET_FORMAT_IPV4_ICMP \
+ HICN_PACKET_FORMAT (IPPROTO_IP, IPPROTO_ICMP, IPPROTO_NONE, IPPROTO_NONE)
+#define HICN_PACKET_FORMAT_IPV6_TCP \
+ HICN_PACKET_FORMAT (IPPROTO_IPV6, IPPROTO_TCP, IPPROTO_NONE, IPPROTO_NONE)
+#define HICN_PACKET_FORMAT_IPV6_ICMP \
+ HICN_PACKET_FORMAT (IPPROTO_IPV6, IPPROTO_ICMPV6, IPPROTO_NONE, IPPROTO_NONE)
+#define HICN_PACKET_FORMAT_NEW \
+ HICN_PACKET_FORMAT (IPPROTO_ENCAP, IPPROTO_NONE, IPPROTO_NONE, IPPROTO_NONE)
+#define HICN_PACKET_FORMAT_IPV4_UDP \
+ HICN_PACKET_FORMAT (IPPROTO_IP, IPPROTO_UDP, IPPROTO_ENCAP, IPPROTO_NONE)
+#define HICN_PACKET_FORMAT_IPV6_UDP \
+ HICN_PACKET_FORMAT (IPPROTO_IPV6, IPPROTO_UDP, IPPROTO_ENCAP, IPPROTO_NONE)
+#define HICN_PACKET_FORMAT_IPV4_TCP_AH \
+ HICN_PACKET_FORMAT (IPPROTO_IP, IPPROTO_TCP, IPPROTO_AH, IPPROTO_NONE)
+#define HICN_PACKET_FORMAT_IPV4_ICMP_AH \
+ HICN_PACKET_FORMAT (IPPROTO_IP, IPPROTO_ICMP, IPPROTO_AH, IPPROTO_NONE)
+#define HICN_PACKET_FORMAT_IPV6_TCP_AH \
+ HICN_PACKET_FORMAT (IPPROTO_IPV6, IPPROTO_TCP, IPPROTO_AH, IPPROTO_NONE)
+#define HICN_PACKET_FORMAT_IPV6_ICMP_AH \
+ HICN_PACKET_FORMAT (IPPROTO_IPV6, IPPROTO_ICMPV6, IPPROTO_AH, IPPROTO_NONE)
+#define HICN_PACKET_FORMAT_NEW_AH \
+ HICN_PACKET_FORMAT (IPPROTO_ENCAP, IPPROTO_AH, IPPROTO_NONE, IPPROTO_NONE)
+#define HICN_PACKET_FORMAT_IPV6_UDP_AH \
+ HICN_PACKET_FORMAT (IPPROTO_IPV6, IPPROTO_UDP, IPPROTO_ENCAP, IPPROTO_AH)
+#define HICN_PACKET_FORMAT_IPV4_UDP_AH \
+ HICN_PACKET_FORMAT (IPPROTO_IP, IPPROTO_UDP, IPPROTO_ENCAP, IPPROTO_AH)
+#define HICN_PACKET_FORMAT_NONE \
+ HICN_PACKET_FORMAT (IPPROTO_NONE, IPPROTO_NONE, IPPROTO_NONE, IPPROTO_NONE)
+
+/* Default packet format */
+
+#define HICN_PACKET_FORMAT_DEFAULT HICN_PACKET_FORMAT_IPV6_TCP
/**
- * @brief Check if type is none.
- * @return 1 if none, 0 otherwise
+ * @brief Return the hICN format with an additional AH header
+ * @param [in] format - hICN packet format
+ * @return Updated hICN packet format
*/
-always_inline int
-hicn_type_is_none(hicn_type_t type)
+static inline hicn_packet_format_t
+hicn_get_ah_format (hicn_packet_format_t format)
{
- return (type.l1 == IPPROTO_NONE) && (type.l2 == IPPROTO_NONE) &&
- (type.l3 == IPPROTO_NONE) && (type.l4 == IPPROTO_NONE);
+ HICN_PACKET_FORMAT_ENUMERATE (format, i, protocol, {
+ switch (protocol)
+ {
+ {
+ case IPPROTO_AH:
+ return format;
+ case IPPROTO_NONE:
+ HICN_PACKET_FORMAT_SET (format, i, IPPROTO_AH);
+ return format;
+ default:
+ break;
+ }
+ }
+ });
+ return format;
}
+/*
+ * MAX(IPV4_HDRLEN (20), IPV6_HDRLEN (40))
+ * + MAX (TCP_HDRLEN (20), UDP_HDRLEN (8), ICMP_HDRLEN (8), NEW_HDRLEN (32))
+ * + AH_HDRLEN
+ */
+#define HICN_HDRLEN_MAX 72
+
+#define HICN_PACKET_FORMAT_IS_NONE(format) \
+ ((HICN_PACKET_FORMAT_GET (format, 0) == IPPROTO_NONE) && \
+ (HICN_PACKET_FORMAT_GET (format, 1) == IPPROTO_NONE) && \
+ (HICN_PACKET_FORMAT_GET (format, 2) == IPPROTO_NONE) && \
+ (HICN_PACKET_FORMAT_GET (format, 3) == IPPROTO_NONE))
+
+#define HICN_PACKET_FORMAT_IS_AH(format) \
+ ((HICN_PACKET_FORMAT_GET (format, 0) == IPPROTO_AH) || \
+ (HICN_PACKET_FORMAT_GET (format, 1) == IPPROTO_AH) || \
+ (HICN_PACKET_FORMAT_GET (format, 2) == IPPROTO_AH) || \
+ (HICN_PACKET_FORMAT_GET (format, 3) == IPPROTO_AH))
+
+#define HICN_PACKET_FORMAT_IS_IPV4(format) \
+ (HICN_PACKET_FORMAT_GET (format, 0) == IPPROTO_IP)
+#define HICN_PACKET_FORMAT_IS_IPV6(format) \
+ (HICN_PACKET_FORMAT_GET (format, 0) == IPPROTO_IPV6)
+
+/*
+ * @brief hICN packet types
+ *
+ * probes are like normal interest & data but:
+ * - interests use BFD port as the destination
+ * - data use BFD port as the source + expiry time must be 0.
+ * if any of these conditions is not met, the packet is still matched as an
+ * interest or data packet.
+ *
+ */
+
+#define foreach_packet_type \
+ _ (UNDEFINED) \
+ _ (INTEREST) \
+ _ (DATA) \
+ _ (WLDR_NOTIFICATION) \
+ _ (MAPME) \
+ _ (PROBE) \
+ _ (COMMAND) \
+ _ (N)
+
+/**
+ * @brief hICN Packet type
+ */
+typedef enum
+{
+#define _(x) HICN_PACKET_TYPE_##x,
+ foreach_packet_type
+#undef _
+} hicn_packet_type_t;
+#undef foreach_type
+
+extern const char *_hicn_packet_type_str[];
+
+#define hicn_packet_type_str(x) _hicn_packet_type_str[x]
+
/**
* @brief hICN Payload type
*
@@ -132,39 +239,120 @@ typedef enum
HPT_UNSPEC = 999
} hicn_payload_type_t;
+/* Path label */
+
+typedef u8 hicn_path_label_t;
+
+#define INVALID_PATH_LABEL 0
+
/**
* @brief Path label computations
*
- * Path label is computed by accumulating the identifiers of successive output
- * faces as a Data packet is traveling from its producer back to the consumer
- * originating the Interest.
+ * Path label is computed by accumulating the identifiers of successive
+ * output faces as a Data packet is traveling from its producer back to the
+ * consumer originating the Interest.
*
* NOTE: this computation is not (yet) part of the hICN specification.
*/
-#define HICN_PATH_LABEL_MASK 0x000000ff
-#define HICN_PATH_LABEL_SIZE 8
+#define HICN_PATH_LABEL_MASK 0x000000ff
+#define HICN_PATH_LABEL_SIZE_BITS sizeof (hicn_path_label_t) * 8
/**
* @brief Path label update
- * @param [in] current_label Current pathlabel
+ * @param [in] current_label Current path_label
* @param [in] face_id The face identifier to combine into the path label
- * @param [out] new_label Computed pathlabel
+ * @param [out] new_label Computed path_label
*
- * This function updates the current_label based on the new face_id, and returns
+ * This function updates the current_label based on the new face_id, and
+ * returns
*/
-always_inline void
-update_pathlabel (hicn_pathlabel_t current_label, hicn_faceid_t face_id,
- hicn_pathlabel_t * new_label)
+static inline void
+update_path_label (hicn_path_label_t current_label, hicn_faceid_t face_id,
+ hicn_path_label_t *new_label)
{
- hicn_pathlabel_t pl_face_id =
- (hicn_pathlabel_t) (face_id & HICN_PATH_LABEL_MASK);
+ hicn_path_label_t pl_face_id =
+ (hicn_path_label_t) (face_id & HICN_PATH_LABEL_MASK);
- *new_label =
- ((current_label << 1) | (current_label >> (HICN_PATH_LABEL_SIZE - 1))) ^
- pl_face_id;
+ *new_label = ((current_label << 1) |
+ (current_label >> (HICN_PATH_LABEL_SIZE_BITS - 1))) ^
+ pl_face_id;
}
+/***************************************************************
+ * Statistics
+ ***************************************************************/
+
+typedef struct
+{
+ // Packets processed
+ uint32_t countReceived; // Interest and data only
+ uint32_t countInterestsReceived;
+ uint32_t countObjectsReceived;
+
+ // Packets Dropped
+ uint32_t countDropped;
+ uint32_t countInterestsDropped;
+ uint32_t countObjectsDropped;
+ uint32_t countOtherDropped;
+
+ // Forwarding
+ uint32_t countInterestForwarded;
+ uint32_t countObjectsForwarded;
+
+ // Errors while forwarding
+ uint32_t countDroppedConnectionNotFound;
+ uint32_t countSendFailures;
+ uint32_t countDroppedNoRoute;
+
+ // Interest processing
+ uint32_t countInterestsAggregated;
+ uint32_t countInterestsRetransmitted;
+ uint32_t countInterestsSatisfiedFromStore;
+ uint32_t countInterestsExpired;
+
+ // Data processing
+ uint32_t countDroppedNoReversePath;
+ uint32_t countDataExpired;
+
+ // TODO(eloparco): Currently not used
+ // uint32_t countDroppedNoHopLimit;
+ // uint32_t countDroppedZeroHopLimitFromRemote;
+ // uint32_t countDroppedZeroHopLimitToRemote;
+} forwarder_stats_t;
+
+typedef struct
+{
+ uint32_t n_pit_entries;
+ uint32_t n_cs_entries;
+ uint32_t n_lru_evictions;
+} pkt_cache_stats_t;
+
+typedef struct
+{
+ forwarder_stats_t forwarder;
+ pkt_cache_stats_t pkt_cache;
+} hicn_light_stats_t;
+
+typedef struct
+{
+ uint32_t conn_id;
+ struct
+ {
+ uint32_t rx_pkts;
+ uint32_t rx_bytes;
+ uint32_t tx_pkts;
+ uint32_t tx_bytes;
+ } interests;
+ struct
+ {
+ uint32_t rx_pkts;
+ uint32_t rx_bytes;
+ uint32_t tx_pkts;
+ uint32_t tx_bytes;
+ } data;
+} connection_stats_t;
+
#endif /* HICN_BASE_H */
/*