aboutgitcodebugslistschat
path: root/fwd_rule.c
diff options
context:
space:
mode:
Diffstat (limited to 'fwd_rule.c')
-rw-r--r--fwd_rule.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/fwd_rule.c b/fwd_rule.c
index a034d5d..5bc94ef 100644
--- a/fwd_rule.c
+++ b/fwd_rule.c
@@ -93,3 +93,48 @@ void fwd_rules_info(const struct fwd_rule *rules, size_t count)
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 if given 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)));
+ }
+}