diff options
| -rw-r--r-- | Makefile | 10 | ||||
| -rw-r--r-- | conf.c | 2 | ||||
| -rw-r--r-- | fwd.c | 48 | ||||
| -rw-r--r-- | fwd.h | 1 | ||||
| -rw-r--r-- | fwd_rule.c | 95 | ||||
| -rw-r--r-- | fwd_rule.h | 12 |
6 files changed, 113 insertions, 55 deletions
@@ -38,11 +38,11 @@ FLAGS += -DVERSION=\"$(VERSION)\" FLAGS += -DDUAL_STACK_SOCKETS=$(DUAL_STACK_SOCKETS) PASST_SRCS = arch.c arp.c bitmap.c checksum.c conf.c dhcp.c dhcpv6.c \ - epoll_ctl.c flow.c fwd.c icmp.c igmp.c inany.c iov.c ip.c isolation.c \ - lineread.c log.c mld.c ndp.c netlink.c migrate.c packet.c passt.c \ - pasta.c pcap.c pif.c repair.c serialise.c tap.c tcp.c tcp_buf.c \ - tcp_splice.c tcp_vu.c udp.c udp_flow.c udp_vu.c util.c vhost_user.c \ - virtio.c vu_common.c + epoll_ctl.c flow.c fwd.c fwd_rule.c icmp.c igmp.c inany.c iov.c ip.c \ + isolation.c lineread.c log.c mld.c ndp.c netlink.c migrate.c packet.c \ + passt.c pasta.c pcap.c pif.c repair.c serialise.c tap.c tcp.c \ + tcp_buf.c tcp_splice.c tcp_vu.c udp.c udp_flow.c udp_vu.c util.c \ + vhost_user.c virtio.c vu_common.c QRAP_SRCS = qrap.c PASST_REPAIR_SRCS = passt-repair.c SRCS = $(PASST_SRCS) $(QRAP_SRCS) $(PASST_REPAIR_SRCS) @@ -1269,7 +1269,7 @@ dns6: dir = "Inbound"; info("%s forwarding rules (%s):", dir, pif_name(i)); - fwd_rules_print(c->fwd[i]); + fwd_rules_info(c->fwd[i]->rules, c->fwd[i]->count); } } @@ -305,20 +305,6 @@ parse_err: } /** - * fwd_rule_addr() - Return match address for a rule - * @rule: Forwarding rule - * - * Return: matching address for rule, NULL if it matches all addresses - */ -static const union inany_addr *fwd_rule_addr(const struct fwd_rule *rule) -{ - if (rule->flags & FWD_DUAL_STACK_ANY) - return NULL; - - return &rule->addr; -} - -/** * fwd_port_map_ephemeral() - Mark ephemeral ports in a bitmap * @map: Bitmap to update */ @@ -487,40 +473,6 @@ const struct fwd_rule *fwd_rule_search(const struct fwd_table *fwd, return NULL; } -/** - * fwd_rules_print() - Print forwarding rules for debugging - * @fwd: Table to print - */ -void fwd_rules_print(const struct fwd_table *fwd) -{ - unsigned i; - - for (i = 0; i < fwd->count; i++) { - const struct fwd_rule *rule = &fwd->rules[i]; - const char *percent = *rule->ifname ? "%" : ""; - const char *weak = "", *scan = ""; - char addr[INANY_ADDRSTRLEN]; - - inany_ntop(fwd_rule_addr(rule), addr, sizeof(addr)); - if (rule->flags & FWD_WEAK) - weak = " (best effort)"; - if (rule->flags & FWD_SCAN) - scan = " (auto-scan)"; - - if (rule->first == rule->last) { - info(" %s [%s]%s%s:%hu => %hu %s%s", - ipproto_name(rule->proto), addr, percent, - rule->ifname, rule->first, rule->to, weak, scan); - } else { - info(" %s [%s]%s%s:%hu-%hu => %hu-%hu %s%s", - ipproto_name(rule->proto), addr, percent, - rule->ifname, rule->first, rule->last, - rule->to, rule->last - rule->first + rule->to, - weak, scan); - } - } -} - /** fwd_sync_one() - Create or remove listening sockets for a forward entry * @c: Execution context * @pif: Interface to create listening sockets for @@ -91,7 +91,6 @@ void fwd_rule_add(struct fwd_table *fwd, uint8_t proto, uint8_t flags, const struct fwd_rule *fwd_rule_search(const struct fwd_table *fwd, const struct flowside *ini, uint8_t proto, int hint); -void fwd_rules_print(const struct fwd_table *fwd); void fwd_scan_ports_init(struct ctx *c); void fwd_scan_ports_timer(struct ctx * c, const struct timespec *now); diff --git a/fwd_rule.c b/fwd_rule.c new file mode 100644 index 0000000..a034d5d --- /dev/null +++ b/fwd_rule.c @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +/* PASST - Plug A Simple Socket Transport + * for qemu/UNIX domain socket mode + * + * PASTA - Pack A Subtle Tap Abstraction + * for network namespace/tap device mode + * + * PESTO - Programmable Extensible Socket Translation Orchestrator + * front-end for passt(1) and pasta(1) forwarding configuration + * + * fwd_rule.c - Helpers for working with forwarding rule specifications + * + * Copyright Red Hat + * Author: David Gibson <david@gibson.dropbear.id.au> + */ + +#include <stdio.h> + +#include "fwd_rule.h" + +/** + * fwd_rule_addr() - Return match address for a rule + * @rule: Forwarding rule + * + * Return: matching address for rule, NULL if it matches all addresses + */ +const union inany_addr *fwd_rule_addr(const struct fwd_rule *rule) +{ + if (rule->flags & FWD_DUAL_STACK_ANY) + return NULL; + + return &rule->addr; +} + +/** + * fwd_rule_fmt() - Prettily format forwarding rule as a string + * @rule: Rule to format + * @dst: Buffer to store output (should have FWD_RULE_STRLEN bytes) + * @size: Size of @dst + */ +#if defined(__GNUC__) && __GNUC__ < 15 +/* Workaround bug in gcc 12, 13 & 14 (at least) which gives a false positive + * -Wformat-overflow message if this function is inlined. + */ +__attribute__((noinline)) +#endif +static const char *fwd_rule_fmt(const struct fwd_rule *rule, + char *dst, size_t size) +{ + const char *percent = *rule->ifname ? "%" : ""; + const char *weak = "", *scan = ""; + char addr[INANY_ADDRSTRLEN]; + int len; + + inany_ntop(fwd_rule_addr(rule), addr, sizeof(addr)); + if (rule->flags & FWD_WEAK) + weak = " (best effort)"; + if (rule->flags & FWD_SCAN) + scan = " (auto-scan)"; + + if (rule->first == rule->last) { + len = snprintf(dst, size, + "%s [%s]%s%s:%hu => %hu %s%s", + ipproto_name(rule->proto), addr, percent, + rule->ifname, rule->first, rule->to, weak, scan); + } else { + in_port_t tolast = rule->last - rule->first + rule->to; + len = snprintf(dst, size, + "%s [%s]%s%s:%hu-%hu => %hu-%hu %s%s", + ipproto_name(rule->proto), addr, percent, + rule->ifname, rule->first, rule->last, + rule->to, tolast, weak, scan); + } + + if (len < 0 || (size_t)len >= size) + return NULL; + + return dst; +} + +/** + * fwd_rules_info() - Print forwarding rules for debugging + * @fwd: Table to print + */ +void fwd_rules_info(const struct fwd_rule *rules, size_t count) +{ + unsigned i; + + for (i = 0; i < count; i++) { + char buf[FWD_RULE_STRLEN]; + + info(" %s", fwd_rule_fmt(&rules[i], buf, sizeof(buf))); + } +} @@ -13,7 +13,9 @@ #include <net/if.h> #include <netinet/in.h> +#include "ip.h" #include "inany.h" +#include "bitmap.h" /** * struct fwd_rule - Forwarding rule governing a range of ports @@ -41,4 +43,14 @@ struct fwd_rule { uint8_t flags; }; +#define FWD_RULE_STRLEN \ + (IPPROTO_STRLEN - 1 \ + + INANY_ADDRSTRLEN - 1 \ + + IFNAMSIZ - 1 \ + + 4 * (UINT16_STRLEN - 1) \ + + sizeof(" []%:- => - (best effort) (auto-scan)")) + +const union inany_addr *fwd_rule_addr(const struct fwd_rule *rule); +void fwd_rules_info(const struct fwd_rule *rules, size_t count); + #endif /* FWD_RULE_H */ |
