/* SPDX-License-Identifier: GPL-2.0-or-later * Copyright Red Hat * Author: David Gibson * * Tracking for logical "flows" of packets. */ #ifndef FLOW_H #define FLOW_H enum flow_type { FLOW_NONE = 0, FLOW_TCP, FLOW_TCP_SPLICE, FLOW_MAX = FLOW_TCP_SPLICE, }; extern const char *flow_type_str[]; #define FLOW_TYPE(f) \ ((f)->type <= FLOW_MAX ? flow_type_str[(f)->type] : "?") /** * struct flowside - Describes a logical packet flow as seen from one "side" * @eaddr: Endpoint address (remote address from passt's PoV) * @faddr: Forwarding address (local address from passt's PoV) * @eport: Endpoint port * @fport: Forwarding port */ struct flowside { union inany_addr faddr; union inany_addr eaddr; in_port_t fport, eport; }; /** flowside_from_af - Initialize a flowside from addresses * @fs: flowside to initialize * @af: Address family (AF_INET or AF_INET6) * @faddr: Forwarding address (pointer to in_addr or in6_addr) * @fport: Forwarding port * @eaddr: Endpoint address (pointer to in_addr or in6_addr) * @eport: Endpoint port */ static inline void flowside_from_af(struct flowside *fs, int af, const void *faddr, in_port_t fport, const void *eaddr, in_port_t eport) { inany_from_af(&fs->faddr, af, faddr); inany_from_af(&fs->eaddr, af, eaddr); fs->fport = fport; fs->eport = eport; } /** flowside_complete - Check if flowside is fully initialized * @fs: flowside to check */ static inline bool flowside_complete(const struct flowside *fs) { return !IN6_IS_ADDR_UNSPECIFIED(&fs->faddr) && !IN6_IS_ADDR_UNSPECIFIED(&fs->eaddr) && fs->fport != 0 && fs->eport != 0; } #define FLOWSIDE_STRLEN (2*(INET6_ADDRSTRLEN+8) + 6) int flowside_getsockname(struct flowside *fs, int s); const char *flowside_fmt(const struct flowside *fs, char *buf, size_t size); /** * flowside_eq() - Check if two flowsides are equal * @left, @right: Flowsides to compare * * Return: true if equal, false otherwise */ static inline bool flowside_eq(const struct flowside *left, const struct flowside *right) { return memcmp(left, right, sizeof(struct flowside)) == 0; } /** * flowside_hash() - Calculate hash value for a flowside * @fs: Flowside * @k: Hash secret (128-bits as array of 2 64-bit words) * * Return: hash value */ static inline unsigned int flowside_hash(const struct flowside *fs, const uint64_t *k) { ASSERT(flowside_complete(fs)); return siphash_36b((uint8_t *)fs, k); } /** * struct flow_common - Common fields for packet flows * @side[]: Information on the flow for each side. Flow types can have * their own conventions about which side is which * @type: Type of packet flow */ struct flow_common { struct flowside side[2]; enum flow_type type; }; #define FLOW_INDEX_BITS 17 /* 128k - 1 */ #define FLOW_MAX MAX_FROM_BITS(FLOW_INDEX_BITS) #define FLOW_TABLE_PRESSURE 30 /* % of FLOW_MAX */ #define FLOW_FILE_PRESSURE 30 /* % of c->nofile */ union flow; void flow_table_compact(struct ctx *c, union flow *hole); #endif /* FLOW_H */