aboutgitcodebugslistschat
path: root/passt.h
diff options
context:
space:
mode:
Diffstat (limited to 'passt.h')
-rw-r--r--passt.h63
1 files changed, 57 insertions, 6 deletions
diff --git a/passt.h b/passt.h
index 947e859..d4661d8 100644
--- a/passt.h
+++ b/passt.h
@@ -64,11 +64,30 @@ enum passt_modes {
MODE_VU,
};
+/* Maximum number of addresses in context address array */
+#define MAX_GUEST_ADDRS 32
+
+/**
+ * struct guest_addr - Unified IPv4/IPv6 address entry
+ * @addr: IPv4 (as mapped) or IPv6 address
+ * @prefix_len: Prefix length in IPv6/IPv4-mapped [0,128]/[96,128] format
+ * @flags: CONF_ADDR_* flags
+ */
+struct guest_addr {
+ union inany_addr addr;
+ uint8_t prefix_len;
+ uint8_t flags;
+#define CONF_ADDR_USER BIT(0) /* User set via -a */
+#define CONF_ADDR_HOST BIT(1) /* From host */
+#define CONF_ADDR_GEN BIT(2) /* Generated by code */
+#define CONF_ADDR_ANY (CONF_ADDR_USER | \
+ CONF_ADDR_HOST | \
+ CONF_ADDR_GEN) /* Any provenance */
+};
+
/**
* struct ip4_ctx - IPv4 execution context
- * @addr: IPv4 address assigned to guest
* @addr_seen: Latest IPv4 address seen as source from tap
- * @prefixlen: IPv4 prefix length (netmask)
* @guest_gw: IPv4 gateway as seen by the guest
* @map_host_loopback: Outbound connections to this address are NATted to the
* host's 127.0.0.1
@@ -87,9 +106,7 @@ enum passt_modes {
*/
struct ip4_ctx {
/* PIF_TAP addresses */
- struct in_addr addr;
struct in_addr addr_seen;
- int prefix_len;
struct in_addr guest_gw;
struct in_addr map_host_loopback;
struct in_addr map_guest_addr;
@@ -110,7 +127,6 @@ struct ip4_ctx {
/**
* struct ip6_ctx - IPv6 execution context
- * @addr: IPv6 address assigned to guest
* @addr_seen: Latest IPv6 global/site address seen as source from tap
* @addr_ll_seen: Latest IPv6 link-local address seen as source from tap
* @guest_gw: IPv6 gateway as seen by the guest
@@ -132,7 +148,6 @@ struct ip4_ctx {
*/
struct ip6_ctx {
/* PIF_TAP addresses */
- struct in6_addr addr;
struct in6_addr addr_seen;
struct in6_addr addr_ll_seen;
struct in6_addr guest_gw;
@@ -192,6 +207,8 @@ struct ip6_ctx {
* @fqdn: Guest FQDN
* @ifi6: Template interface for IPv6, -1: none, 0: IPv6 disabled
* @ip6: IPv6 configuration
+ * @addrs: Unified address array for both IPv4 (mapped) and IPv6
+ * @addr_count: Number of active entries in @addrs array
* @pasta_ifn: Name of namespace interface for pasta
* @pasta_ifi: Index of namespace interface for pasta
* @pasta_conf_ns: Configure namespace after creating it
@@ -277,6 +294,9 @@ struct ctx {
int ifi6;
struct ip6_ctx ip6;
+ struct guest_addr addrs[MAX_GUEST_ADDRS];
+ int addr_count;
+
char pasta_ifn[IF_NAMESIZE];
unsigned int pasta_ifi;
int pasta_conf_ns;
@@ -323,6 +343,37 @@ struct ctx {
extern struct ctx passt_ctx;
+/**
+ * next_addr_idx_() - Find next address index matching family filter
+ * @addrs: Array of guest addresses
+ * @count: Number of addresses in array
+ * @i: Starting index
+ * @af: Address family filter: AF_INET, AF_INET6, or AF_UNSPEC for all
+ *
+ * Return: next matching index, or count if none found
+ */
+static inline int next_addr_idx_(const struct guest_addr *addrs, int count,
+ int i, sa_family_t af)
+{
+ for (; i < count; i++) {
+ if (af == AF_UNSPEC || af == inany_af(&addrs[i].addr))
+ return i;
+ }
+ return i;
+}
+
+/**
+ * for_each_addr() - Iterate over addresses in array
+ * @a: Pointer variable for current entry (struct guest_addr *)
+ * @addrs: Array of guest addresses (e.g., c->addrs)
+ * @count: Number of addresses (e.g., c->addr_count)
+ * @af: Address family filter: AF_INET, AF_INET6, or 0 for all
+ */
+#define for_each_addr(a, addrs, count, af) \
+ for (int i_ = next_addr_idx_((addrs), (count), 0, (af)); \
+ i_ < (count) && ((a) = &(addrs)[i_], true); \
+ i_ = next_addr_idx_((addrs), (count), i_ + 1, (af)))
+
void proto_update_l2_buf(const unsigned char *eth_d);
#endif /* PASST_H */