diff options
Diffstat (limited to 'passt.h')
| -rw-r--r-- | passt.h | 63 |
1 files changed, 57 insertions, 6 deletions
@@ -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 */ |
