public inbox for passt-dev@passt.top
 help / color / mirror / code / Atom feed
4d5048f99aae9e5eb2b10aad81ef0e1ee2b7e630 blob 3474 bytes (raw)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
 
// 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
 */
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)));
	}
}

/**
 * fwd_rule_conflicts() - Test if two rules conflict with each other
 * @a, @b:	Rules to test
 */
static bool fwd_rule_conflicts(const struct fwd_rule *a, const struct fwd_rule *b)
{
	if (a->proto != b->proto)
		/* Non-conflicting protocols */
		return false;

	if (!inany_matches(fwd_rule_addr(a), fwd_rule_addr(b)))
		/* Non-conflicting addresses */
		return false;

	assert(a->first <= a->last && b->first <= b->last);
	if (a->last < b->first || b->last < a->first)
		/* Port ranges don't overlap */
		return false;

	return true;
}

/* fwd_rule_conflict_check() - Die with errir if rule conflicts with any in list
 * @new:	New rule
 * @rules:	Existing rules against which to test
 * @count:	Number of rules in @rules
 */
void fwd_rule_conflict_check(const struct fwd_rule *new,
			     const struct fwd_rule *rules, size_t count)
{
	unsigned i;

	for (i = 0; i < count; i++) {
		char newstr[FWD_RULE_STRLEN], rulestr[FWD_RULE_STRLEN];

		if (!fwd_rule_conflicts(new, &rules[i]))
			continue;

		die("Forwarding configuration conflict: %s versus %s",
		    fwd_rule_fmt(new, newstr, sizeof(newstr)),
		    fwd_rule_fmt(&rules[i], rulestr, sizeof(rulestr)));
	}
}
debug log:

solving 4d5048f9 ...
found 4d5048f9 in https://archives.passt.top/passt-dev/20260407031630.2457081-11-david@gibson.dropbear.id.au/
found abe9dfbf in https://archives.passt.top/passt-dev/20260407031630.2457081-8-david@gibson.dropbear.id.au/

applying [1/2] https://archives.passt.top/passt-dev/20260407031630.2457081-8-david@gibson.dropbear.id.au/
diff --git a/fwd_rule.c b/fwd_rule.c
new file mode 100644
index 00000000..abe9dfbf


applying [2/2] https://archives.passt.top/passt-dev/20260407031630.2457081-11-david@gibson.dropbear.id.au/
diff --git a/fwd_rule.c b/fwd_rule.c
index abe9dfbf..4d5048f9 100644

Checking patch fwd_rule.c...
Applied patch fwd_rule.c cleanly.
Checking patch fwd_rule.c...
Applied patch fwd_rule.c cleanly.

index at:
100644 4d5048f99aae9e5eb2b10aad81ef0e1ee2b7e630	fwd_rule.c

Code repositories for project(s) associated with this public inbox

	https://passt.top/passt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for IMAP folder(s).