Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/conf_mode/policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import re
from sys import exit

from vyos.config import Config
Expand All @@ -24,9 +25,20 @@
from vyos.utils.dict import dict_search
from vyos.utils.process import is_systemd_service_running
from vyos import ConfigError
from vyos.base import Warning
from vyos import airbag
airbag.enable()

# Sanity checks for large-community-list regex:
# * Require complete 3-tuples, no blank members. Catch missed & doubled colons.
# * Permit appropriate community separators (whitespace, underscore)
# * Permit common regex between tuples while requiring at least one separator
# (eg, "1:1:1_.*_4:4:4", matching "1:1:1 4:4:4" and "1:1:1 2:2:2 4:4:4",
# but not "1:1:13 24:4:4")
# Best practice: stick with basic patterns, mind your wildcards and whitespace.
# Regex that doesn't match this pattern will be allowed with a warning.
large_community_regex_pattern = r'([^: _]+):([^: _]+):([^: _]+)([ _]([^:]+):([^: _]+):([^: _]+))*'

def community_action_compatibility(actions: dict) -> bool:
"""
Check compatibility of values in community and large community sections
Expand Down Expand Up @@ -147,6 +159,10 @@ def verify(config_dict):
if 'regex' not in rule_config:
raise ConfigError(f'A regex {mandatory_error}')

if policy_type == 'large_community_list':
if not re.fullmatch(large_community_regex_pattern, rule_config['regex']):
Warning(f'"policy large-community-list {instance} rule {rule} regex" does not follow expected form and may not match as expected.')

if policy_type in ['prefix_list', 'prefix_list6']:
if 'prefix' not in rule_config:
raise ConfigError(f'A prefix {mandatory_error}')
Expand Down
21 changes: 15 additions & 6 deletions src/validators/bgp-large-community-list
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
# Copyright (C) 2021-2023 VyOS maintainers and contributors
# Copyright (C) 2021-2025 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
Expand All @@ -17,18 +17,27 @@
import re
import sys

pattern = '(.*):(.*):(.*)'
allowedChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '+', '*', '?', '^', '$', '(', ')', '[', ']', '{', '}', '|', '\\', ':', '-' }
allowedChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '+', '*', '?', '^', '$', '(', ')', '[', ']', '{', '}', '|', '\\', ':', '-', '_', ' ' }

if __name__ == '__main__':
if len(sys.argv) != 2:
sys.exit(1)

value = sys.argv[1].split(':')
if not len(value) == 3:
value = sys.argv[1]

# Require at least one well-formed large-community tuple in the pattern.
tmp = value.split(':')
if len(tmp) < 3:
sys.exit(1)

# Simple guard against invalid community & 1003.2 pattern chars
if not set(value).issubset(allowedChars):
sys.exit(1)

if not (re.match(pattern, sys.argv[1]) and set(sys.argv[1]).issubset(allowedChars)):
# Don't feed FRR badly formed regex
try:
re.compile(value)
except re.error:
sys.exit(1)

sys.exit(0)
Loading