Merge branch 'sonic-net:master' into align-5600-buffer-templates

This commit is contained in:
Stephen Sun 2024-03-22 15:05:26 +08:00 committed by GitHub
commit 6dd3cfcc36
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
27 changed files with 1189 additions and 222 deletions

View File

@ -1,5 +1,5 @@
{% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %}
FROM docker-config-engine-bullseye-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}}
FROM docker-config-engine-bookworm-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}}
ARG docker_container_name
ARG image_version

View File

@ -0,0 +1,800 @@
#
# Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES.
# Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import os
import queue
import sys
import threading
import time
import types
import unittest
from mock import MagicMock, patch, mock_open, Mock
if sys.version_info.major == 3:
from unittest import mock
else:
import mock
test_path = os.path.dirname(os.path.abspath(__file__))
modules_path = os.path.dirname(test_path)
sys.path.insert(0, modules_path)
from sonic_platform.device_data import DeviceDataManager
from sonic_py_common import device_info
from sonic_platform import modules_mgmt
from sonic_platform.modules_mgmt import ModulesMgmtTask
from sonic_platform_base.sonic_xcvr.api.public.cmis import CmisApi
from sonic_platform_base.sonic_xcvr.xcvr_eeprom import XcvrEeprom
from sonic_platform_base.sonic_xcvr.codes.public.cmis import CmisCodes
from sonic_platform_base.sonic_xcvr.mem_maps.public.cmis import CmisMemMap
from sonic_platform_base.sonic_xcvr.fields import consts
DEFAULT_NUM_OF_PORTS_1 = 1
DEFAULT_NUM_OF_PORTS_3 = 3
DEFAULT_NUM_OF_PORTS_32 = 32
POLLER_EXECUTED = False
def _mock_sysfs_default_file_content():
return {
modules_mgmt.SYSFS_INDEPENDENT_FD_PRESENCE.format("0"): "1",
modules_mgmt.SYSFS_INDEPENDENT_FD_PRESENCE.format("1"): "1",
modules_mgmt.SYSFS_INDEPENDENT_FD_PRESENCE.format("2"): "1",
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_GOOD.format("0"): "1",
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_GOOD.format("1"): "1",
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_GOOD.format("2"): "1",
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_ON.format("0"): "1",
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_ON.format("1"): "1",
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_ON.format("2"): "1",
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_LIMIT.format("0"): "48",
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_LIMIT.format("1"): "48",
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_LIMIT.format("2"): "48",
modules_mgmt.SYSFS_INDEPENDENT_FD_FREQ_SUPPORT.format("0"): "0",
modules_mgmt.SYSFS_INDEPENDENT_FD_FREQ_SUPPORT.format("1"): "0",
modules_mgmt.SYSFS_INDEPENDENT_FD_FREQ_SUPPORT.format("2"): "0",
modules_mgmt.SYSFS_INDEPENDENT_FD_HW_RESET: "",
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_LIMIT: "48",
modules_mgmt.SYSFS_LEGACY_FD_PRESENCE.format("0"): "1",
modules_mgmt.SYSFS_INDEPENDENT_FD_FW_CONTROL.format("0"): "1",
modules_mgmt.SYSFS_INDEPENDENT_FD_FW_CONTROL.format("1"): "1",
modules_mgmt.SYSFS_INDEPENDENT_FD_FW_CONTROL.format("2"): "1",
modules_mgmt.SYSFS_LEGACY_FD_PRESENCE: "1",
modules_mgmt.PROC_CMDLINE: ""
}
mock_file_content = _mock_sysfs_default_file_content()
class MockPoller:
def __init__(self, modules_mgmt_task_stopping_event, modules_mgmt_thrd=None, num_of_ports=3, port_plug_out=False
, feature_enabled=True, warm_reboot=False, port_plug_in=False, sleep_timeout=False):
self.fds_dict = {}
self.poller_iteration_count = 0
self.modules_mgmt_task_stopping_event = modules_mgmt_task_stopping_event
self.modules_mgmt_thrd = modules_mgmt_thrd
self.num_of_ports = num_of_ports
self.port_plug_out = port_plug_out
self.port_plug_in = port_plug_in
self.feature_enabled = feature_enabled
self.warm_reboot = warm_reboot
self.port_plug_out_changed = False
self.port_plug_in_changed = False
self.sleep_timeout = sleep_timeout
def register(self, fd, attrs):
self.fds_dict[fd.fileno()] = { fd : attrs }
assert fd.fileno() in self.fds_dict
def unregister(self, fd):
if fd.fileno() in self.fds_dict.keys():
del self.fds_dict[fd.fileno()]
assert fd.fileno() not in self.fds_dict.keys()
def poll(self, timeout=1000):
global POLLER_EXECUTED
assert len(self.modules_mgmt_thrd.sfp_port_dict_initial) == self.num_of_ports
assert self.modules_mgmt_thrd.is_supported_indep_mods_system == self.feature_enabled
# counting the number of poller iterations to know when to do the checks after plug out (and plug in)
# have to check at least on iteration 7 to let ports reach final state
self.poller_iteration_count += 1
if self.num_of_ports > 0:
if not self.port_plug_out_changed:
if self.port_plug_out:
# return first fd registered with some made up event number 870
fd_no_to_return = list(self.fds_dict.keys())[0]
fd = list(self.fds_dict[fd_no_to_return].keys())[0]
fd.set_file_int_content(0)
event_to_return = 870
self.port_plug_out_changed = True
return [(fd_no_to_return, event_to_return)]
if not self.port_plug_in_changed:
if self.port_plug_in:
# return first fd registered with some made up event number 871
fd_no_to_return = list(self.fds_dict.keys())[0]
fd = list(self.fds_dict[fd_no_to_return].keys())[0]
fd.set_file_int_content(1)
event_to_return = 871
self.port_plug_in_changed = True
return [(fd_no_to_return, event_to_return)]
if 7 == self.poller_iteration_count:
# when feature is enabled, need to check for each port both power_good and hw_present sysfs for
# cmis non-flat memory cables
num_of_sysfs_to_check = self.num_of_ports if (not self.port_plug_out or not self.feature_enabled
or self.warm_reboot) else self.num_of_ports * 2
for i in range(num_of_sysfs_to_check):
# when feature is enabled, power_good sysfs is also registered for cmis non-flat memory cables
# so each SW controlled port has 2 fds registered
port_to_test = i if not self.feature_enabled else int(i / 2)
assert self.modules_mgmt_thrd.sfp_port_dict_initial[port_to_test].port_num == port_to_test
assert self.modules_mgmt_thrd.sfp_port_dict_initial[
port_to_test].initial_state == modules_mgmt.STATE_HW_NOT_PRESENT
if self.feature_enabled:
module_obj = self.modules_mgmt_thrd.fds_mapping_to_obj[list(self.fds_dict.keys())[i]][
'module_obj']
assert module_obj.port_num == port_to_test
if not self.warm_reboot:
# in tests other than warm reboot it creates only SW control ports
if not self.port_plug_out:
assert module_obj.final_state == modules_mgmt.STATE_SW_CONTROL
else:
assert module_obj.final_state == modules_mgmt.STATE_HW_NOT_PRESENT
else:
if not self.port_plug_out:
assert module_obj.final_state == modules_mgmt.STATE_HW_PRESENT
# in warm reboot test with plug out plug in test creates only FW control ports
elif self.port_plug_out and self.port_plug_in:
assert module_obj.final_state == modules_mgmt.STATE_FW_CONTROL
else:
assert module_obj.final_state == modules_mgmt.STATE_HW_NOT_PRESENT
POLLER_EXECUTED = True
self.modules_mgmt_task_stopping_event.set()
if self.sleep_timeout:
time.sleep(timeout/1000)
return []
class MockOpen:
def __init__(self, name='', file_no=None, indep_mode_supported=True):
self.name = name
self.file_no = file_no
self.indep_mode_supported = indep_mode_supported
self.retint = None
self.curr = 0
def read(self):
if self.fileno() in [SAI_PROFILE_FD_FILENO]:
pass
else:
# if return value was changed, i.e. sysfs content changed from 1 to 0 to simulate plug out
if self.retint is not None:
return str(self.retint)
# return default values (can be changed per test)
else:
return mock_file_content[self.name]
def readline(self):
# if trying to read sai profile file, according to fd fileno
if self.fileno() in [SAI_PROFILE_FD_FILENO]:
if self.indep_mode_supported:
return "SAI_INDEPENDENT_MODULE_MODE=1"
else:
return ""
else:
return mock_file_content[self.name]
def fileno(self):
return self.file_no
def seek(self, seek_val):
self.curr = seek_val
def close(self):
pass
def write(self, write_val):
self.set_file_int_content(write_val)
def set_file_int_content(self, retint):
self.retint = str(retint)
mock_file_content[self.name] = str(retint)
def __enter__(self):
return self
def __exit__(self, filename, *args, **kwargs):
pass
class MockPollerStopEvent:
def __init__(self, modules_mgmt_task_stopping_event, modules_mgmt_thrd=None, num_of_ports=DEFAULT_NUM_OF_PORTS_3
, feature_enabled=True, ports_connected=True, fw_controlled_ports=False, sleep_timeout=False):
self.fds_dict = {}
self.modules_mgmt_task_stopping_event = modules_mgmt_task_stopping_event
self.modules_mgmt_thrd = modules_mgmt_thrd
self.num_of_ports = num_of_ports
self.feature_enabled = feature_enabled
self.ports_connected = ports_connected
self.sleep_timeout = sleep_timeout
self.fw_controlled_ports = fw_controlled_ports
def register(self, fd, attrs):
self.fds_dict[fd.fileno()] = 1 & attrs
assert fd.fileno() in self.fds_dict
def poll(self, timeout=0):
assert len(self.modules_mgmt_thrd.sfp_port_dict_initial) == self.num_of_ports
assert self.modules_mgmt_thrd.is_supported_indep_mods_system == self.feature_enabled
global POLLER_EXECUTED
if self.num_of_ports > 0:
# when feature is enabled, need to check for each port both power_good and hw_present sysfs for
# cmis non-flat memory cables
ports_to_test = self.num_of_ports if (not self.feature_enabled or not self.ports_connected
or self.fw_controlled_ports) else self.num_of_ports * 2
for i in range(ports_to_test):
# when feature is enabled, power_good sysfs is also registered for cmis non-flat memory cables
port_to_test = i if (not self.feature_enabled or not self.ports_connected
or self.fw_controlled_ports) else int(i / 2)
assert self.modules_mgmt_thrd.sfp_port_dict_initial[port_to_test].port_num == port_to_test
assert self.modules_mgmt_thrd.sfp_port_dict_initial[port_to_test].initial_state == modules_mgmt.STATE_HW_NOT_PRESENT
module_obj = self.modules_mgmt_thrd.fds_mapping_to_obj[list(self.fds_dict.keys())[i]]['module_obj']
assert module_obj.port_num == port_to_test
if self.ports_connected:
if self.feature_enabled:
if self.fw_controlled_ports:
assert module_obj.final_state == modules_mgmt.STATE_FW_CONTROL
else:
assert module_obj.final_state == modules_mgmt.STATE_SW_CONTROL
else:
assert module_obj.final_state == modules_mgmt.STATE_HW_PRESENT
else:
assert module_obj.final_state == modules_mgmt.STATE_HW_NOT_PRESENT
POLLER_EXECUTED = True
else:
POLLER_EXECUTED = True
self.modules_mgmt_task_stopping_event.set()
if self.sleep_timeout:
time.sleep(timeout/1000)
return []
def _mock_is_file_indep_mode_disabled_content():
return {
modules_mgmt.SYSFS_INDEPENDENT_FD_PRESENCE: True,
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_GOOD: True,
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_ON: True,
modules_mgmt.SYSFS_INDEPENDENT_FD_HW_RESET: True,
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_LIMIT: True,
modules_mgmt.SYSFS_INDEPENDENT_FD_FW_CONTROL: True,
modules_mgmt.SYSFS_LEGACY_FD_PRESENCE.format("0"): True,
modules_mgmt.SYSFS_LEGACY_FD_PRESENCE.format("1"): True,
modules_mgmt.SYSFS_LEGACY_FD_PRESENCE.format("2"): True,
'//usr/share/sonic/platform/ACS-MSN4700/sai.profile' : True
}
mock_is_file_indep_mode_disabled_content = _mock_is_file_indep_mode_disabled_content()
def mock_is_file_indep_mode_disabled(file_path, **kwargs):
return mock_is_file_indep_mode_disabled_content[file_path]
def _mock_is_file_indep_mode_enabled_content():
return {
modules_mgmt.SYSFS_INDEPENDENT_FD_PRESENCE: True,
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_GOOD: True,
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_ON: True,
modules_mgmt.SYSFS_INDEPENDENT_FD_HW_RESET: True,
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_LIMIT: True,
modules_mgmt.SYSFS_INDEPENDENT_FD_FW_CONTROL: True,
modules_mgmt.SYSFS_LEGACY_FD_PRESENCE.format("0"): True,
modules_mgmt.SYSFS_INDEPENDENT_FD_PRESENCE.format("0"): True,
modules_mgmt.SYSFS_INDEPENDENT_FD_PRESENCE.format("1"): True,
modules_mgmt.SYSFS_INDEPENDENT_FD_PRESENCE.format("2"): True,
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_GOOD.format("0"): True,
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_GOOD.format("1"): True,
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_GOOD.format("2"): True,
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_ON.format("0"): True,
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_ON.format("1"): True,
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_ON.format("2"): True,
'//usr/share/sonic/platform/ACS-MSN4700/sai.profile' : True
}
mock_is_file_indep_mode_enabled_content = _mock_is_file_indep_mode_enabled_content()
def mock_is_file_indep_mode_enabled(file_path, **kwargs):
return mock_is_file_indep_mode_enabled_content[file_path]
def mock_read_int_from_file(filename, *args):
return_dict = {
modules_mgmt.SYSFS_LEGACY_FD_PRESENCE.format("0") : 1,
modules_mgmt.SYSFS_LEGACY_FD_PRESENCE.format("1") : 1,
modules_mgmt.SYSFS_LEGACY_FD_PRESENCE.format("2") : 1
}
return return_dict[filename]
class MockXcvrEeprom():
def __init__(self, is_flat_memory, mem_map):
self.is_flat_memory = is_flat_memory
self.mem_map = mem_map
def is_cmis_api(self):
return self.is_cmis_api
def is_flat_memory(self):
return self.is_flat_memory
def read(self, field):
if consts.FLAT_MEM_FIELD == field:
return 0 if self.is_flat_memory else 1
else:
return 0
class MockXcvrapi:
def __init__(self, is_cmis_api=True, is_flat_memory_bool=False):
self.is_cmis_api = is_cmis_api
self.is_flat_memory_bool = is_flat_memory_bool
self.xcvr_eeprom = MagicMock(autospec=XcvrEeprom, return_value=MockXcvrEeprom(is_flat_memory_bool, CmisMemMap(CmisCodes)))
def is_flat_memory(self):
return self.is_flat_memory_bool
def xcvr_eeprom(self):
return self.xcvr_eeprom
class MockSFPxcvrapi:
def __init__(self, xcvr_api_is_cmis_api=True, xcvr_eeprom_is_flat_memory=False):
self.xcvr_api = Mock(spec=CmisApi(MockXcvrEeprom(False, CmisMemMap(CmisCodes))), return_value=MockXcvrapi(xcvr_api_is_cmis_api, xcvr_eeprom_is_flat_memory))
self.xcvr_api_is_cmis_api = xcvr_api_is_cmis_api
self.xcvr_eeprom_is_flat_memory = xcvr_eeprom_is_flat_memory
self.xcvr_api.is_flat_memory = types.MethodType(self.is_flat_memory, self)
def get_xcvr_api(self):
return self.xcvr_api
def is_flat_memory(self, ref):
return self.xcvr_eeprom_is_flat_memory
def check_power_cap(port, module_sm_obj):
pass
SAI_PROFILE_FD_FILENO = 99
class TestModulesMgmt(unittest.TestCase):
"""Test class to test modules_mgmt.py. The test cases covers:
1. cables detection for 1 to 3 ports - feature disabled / enabled / poller
2. cable disconnection - plug out
3. cable reconnection - plug in
4. warm reboot normal flow with FW ports
5. warm reboot flow with FW ports plugged out
6. warm reboot flow with FW ports plugged out and then plugged in (stays FW controlled, no SFP mock change)
7. test 32 FW controlled (non cmis flat mem) cables powered off
8. test 32 SW controlled (cmis active non flat mem) cables powered off
"""
def _mock_sysfs_file_content(self):
return {
modules_mgmt.SYSFS_INDEPENDENT_FD_PRESENCE : "1",
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_GOOD : "1",
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_ON : "0",
modules_mgmt.SYSFS_INDEPENDENT_FD_HW_RESET : "",
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_LIMIT : "48",
modules_mgmt.SYSFS_INDEPENDENT_FD_FW_CONTROL : "1",
modules_mgmt.SYSFS_LEGACY_FD_PRESENCE.format("0") : "1",
modules_mgmt.SYSFS_LEGACY_FD_PRESENCE.format("1") : "1",
modules_mgmt.SYSFS_LEGACY_FD_PRESENCE.format("2") : "1",
modules_mgmt.SYSFS_INDEPENDENT_FD_FREQ_SUPPORT.format("0"): "0"
}
def mock_open_builtin(self, file_name, feature_enabled=True):
return_dict = {
(modules_mgmt.SYSFS_LEGACY_FD_PRESENCE.format("0"), 'r') : MockOpen(modules_mgmt.SYSFS_LEGACY_FD_PRESENCE.format("0"), 100),
(modules_mgmt.SYSFS_LEGACY_FD_PRESENCE.format("1"), 'r') : MockOpen(modules_mgmt.SYSFS_LEGACY_FD_PRESENCE.format("1"), 101),
(modules_mgmt.SYSFS_LEGACY_FD_PRESENCE.format("2"), 'r') : MockOpen(modules_mgmt.SYSFS_LEGACY_FD_PRESENCE.format("2"), 102),
'//usr/share/sonic/platform/ACS-MSN4700/sai.profile' : MockOpen('//usr/share/sonic/platform/ACS-MSN4700/sai.profile'
, SAI_PROFILE_FD_FILENO, feature_enabled),
modules_mgmt.SYSFS_LEGACY_FD_PRESENCE.format("0") : MockOpen(modules_mgmt.SYSFS_LEGACY_FD_PRESENCE.format("0"), 100),
modules_mgmt.SYSFS_LEGACY_FD_PRESENCE.format("1") : MockOpen(modules_mgmt.SYSFS_LEGACY_FD_PRESENCE.format("1"), 101),
modules_mgmt.SYSFS_LEGACY_FD_PRESENCE.format("2") : MockOpen(modules_mgmt.SYSFS_LEGACY_FD_PRESENCE.format("2"), 102),
modules_mgmt.SYSFS_INDEPENDENT_FD_PRESENCE.format("0"): MockOpen(modules_mgmt.SYSFS_INDEPENDENT_FD_PRESENCE.format("0"), 0),
modules_mgmt.SYSFS_INDEPENDENT_FD_PRESENCE.format("1"): MockOpen(modules_mgmt.SYSFS_INDEPENDENT_FD_PRESENCE.format("1"), 1),
modules_mgmt.SYSFS_INDEPENDENT_FD_PRESENCE.format("2"): MockOpen(modules_mgmt.SYSFS_INDEPENDENT_FD_PRESENCE.format("2"), 2),
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_GOOD.format("0"): MockOpen(modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_GOOD.format("0"), 200),
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_GOOD.format("1"): MockOpen(modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_GOOD.format("1"), 201),
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_GOOD.format("2"): MockOpen(modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_GOOD.format("2"), 202),
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_ON.format("0"): MockOpen(modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_ON.format("0"), 300),
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_ON.format("1"): MockOpen(modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_ON.format("1"), 301),
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_ON.format("2"): MockOpen(modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_ON.format("2"), 302),
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_LIMIT.format("0"): MockOpen(modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_LIMIT.format("0"), 500),
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_LIMIT.format("1"): MockOpen(modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_LIMIT.format("1"), 501),
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_LIMIT.format("2"): MockOpen(modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_LIMIT.format("2"), 502),
modules_mgmt.SYSFS_INDEPENDENT_FD_FREQ_SUPPORT.format("0"): MockOpen(modules_mgmt.SYSFS_INDEPENDENT_FD_FREQ_SUPPORT.format("0"), 602),
modules_mgmt.SYSFS_INDEPENDENT_FD_FREQ_SUPPORT.format("1"): MockOpen(modules_mgmt.SYSFS_INDEPENDENT_FD_FREQ_SUPPORT.format("1"), 602),
modules_mgmt.SYSFS_INDEPENDENT_FD_FREQ_SUPPORT.format("2"): MockOpen(modules_mgmt.SYSFS_INDEPENDENT_FD_FREQ_SUPPORT.format("2"), 602),
modules_mgmt.PROC_CMDLINE: MockOpen(modules_mgmt.PROC_CMDLINE, self.fd_number_by_fd_name_dict[modules_mgmt.PROC_CMDLINE])
}
return return_dict[file_name]
# side effects are used in mock when want to create different mocks per variable, i.e. here it's filename
# see below mock_open_new_side_effect_poller_test where returning a new MockOpen passing it the filename
def mock_open_new_side_effect_feature_disabled(self, filename, *args, **kwargs):
mock_context = MagicMock()
mock_context.__enter__.return_value = self.mock_open_builtin(filename, False)
mock_context.__exit__.return_value = False
return mock_context
def mock_open_new_side_effect_feature_enabled(self, filename, *args, **kwargs):
mock_context = MagicMock()
mock_context.__enter__.return_value = self.mock_open_builtin(filename)
mock_context.__exit__.return_value = False
return mock_context
def mock_open_new_side_effect_poller_test(self, filename, *args, **kwargs):
if filename in ['//usr/share/sonic/platform/ACS-MSN4700/sai.profile']:
mock_context = MagicMock()
mock_context.__enter__.return_value = MockOpen(filename, SAI_PROFILE_FD_FILENO)
mock_context.__exit__.return_value = False
return mock_context
else:
mock_context = MagicMock()
mock_open_new = MockOpen(filename, self.fd_number_by_fd_name_dict[filename])
mock_context.return_value = mock_open_new
mock_context.__enter__.return_value = mock_open_new
mock_context.__exit__.return_value = False
if 'hw_present' in filename or 'power_on' in filename or 'freq' in filename or 'control' in filename:
return mock_context
else:
return mock_context.return_value
def mock_open_new_side_effect_warm_reboot(self, filename, *args, **kwargs):
if filename in ['//usr/share/sonic/platform/ACS-MSN4700/sai.profile']:
mock_context = MagicMock()
mock_context.__enter__.return_value = MockOpen(filename, SAI_PROFILE_FD_FILENO)
mock_context.__exit__.return_value = False
return mock_context
else:
mock_open_new = MockOpen(filename, self.fd_number_by_fd_name_dict[filename])
return mock_open_new
def setUp(cls):
cls.modules_mgmt_task_stopping_event = threading.Event()
cls.modules_changes_queue = queue.Queue()
global POLLER_EXECUTED
POLLER_EXECUTED = False
# start modules_mgmt thread and the test in poller part
cls.modules_mgmt_thrd = ModulesMgmtTask(main_thread_stop_event=cls.modules_mgmt_task_stopping_event,
q=cls.modules_changes_queue)
cls.modules_mgmt_thrd.check_power_cap = check_power_cap
assert cls.modules_mgmt_thrd.sfp_port_dict_initial == {}
@classmethod
def setup_class(cls):
os.environ["MLNX_PLATFORM_API_UNIT_TESTING"] = "1"
cls.fd_number_by_fd_name_dict = {
modules_mgmt.SYSFS_LEGACY_FD_PRESENCE.format("0") : 100,
modules_mgmt.SYSFS_LEGACY_FD_PRESENCE.format("1") : 101,
modules_mgmt.SYSFS_LEGACY_FD_PRESENCE.format("2") : 102,
'//usr/share/sonic/platform/ACS-MSN4700/sai.profile' : SAI_PROFILE_FD_FILENO,
modules_mgmt.SYSFS_INDEPENDENT_FD_PRESENCE.format("0") : 0,
modules_mgmt.SYSFS_INDEPENDENT_FD_PRESENCE.format("1") : 1,
modules_mgmt.SYSFS_INDEPENDENT_FD_PRESENCE.format("2") : 2,
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_GOOD.format("0") : 200,
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_GOOD.format("1") : 201,
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_GOOD.format("2") : 202,
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_ON.format("0") : 300,
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_ON.format("1") : 301,
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_ON.format("2") : 302,
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_LIMIT.format("0") : 500,
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_LIMIT.format("1") : 501,
modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_LIMIT.format("2") : 502,
modules_mgmt.SYSFS_INDEPENDENT_FD_FREQ_SUPPORT.format("0") : 600,
modules_mgmt.SYSFS_INDEPENDENT_FD_FREQ_SUPPORT.format("1") : 601,
modules_mgmt.SYSFS_INDEPENDENT_FD_FREQ_SUPPORT.format("2") : 602,
modules_mgmt.SYSFS_INDEPENDENT_FD_FW_CONTROL.format("0") : 700,
modules_mgmt.SYSFS_INDEPENDENT_FD_FW_CONTROL.format("1") : 701,
modules_mgmt.SYSFS_INDEPENDENT_FD_FW_CONTROL.format("2") : 702,
modules_mgmt.PROC_CMDLINE : 800
}
# mock the directory holding relevant sai.profile
device_info.get_paths_to_platform_and_hwsku_dirs = mock.MagicMock(return_value=('', '/usr/share/sonic/platform/ACS-MSN4700'))
@patch('sonic_platform.device_data.DeviceDataManager.get_sfp_count', MagicMock(return_value=DEFAULT_NUM_OF_PORTS_3))
@patch('os.path.isfile', MagicMock(side_effect=mock_is_file_indep_mode_disabled))
@patch('sonic_platform.utils.read_int_from_file', MagicMock(side_effect=mock_read_int_from_file))
@patch('builtins.open', spec=open)
def test_mdf_all_ports_feature_disabled(self, mock_open):
mock_open.side_effect = self.mock_open_new_side_effect_feature_disabled
num_of_tested_ports = DeviceDataManager.get_sfp_count()
assert num_of_tested_ports == DEFAULT_NUM_OF_PORTS_3
# start modules_mgmt thread and the test in poller part
with patch('select.poll', MagicMock(return_value=MockPollerStopEvent(self.modules_mgmt_task_stopping_event
, self.modules_mgmt_thrd, feature_enabled=False))):
self.modules_mgmt_thrd.run()
@patch('sonic_platform.device_data.DeviceDataManager.get_sfp_count', MagicMock(return_value=DEFAULT_NUM_OF_PORTS_3))
@patch('os.path.isfile', MagicMock(side_effect=mock_is_file_indep_mode_enabled))
@patch('builtins.open', spec=open)
@patch('sonic_platform.sfp.SFP', MagicMock(return_value=MockSFPxcvrapi()))
def test_mdf_all_ports_feature_enabled(self, mock_open):
mock_open.side_effect = self.mock_open_new_side_effect_feature_enabled
num_of_tested_ports = DeviceDataManager.get_sfp_count()
assert num_of_tested_ports == DEFAULT_NUM_OF_PORTS_3
# start modules_mgmt thread and the test in poller part
with patch('select.poll', MagicMock(return_value=MockPollerStopEvent(self.modules_mgmt_task_stopping_event
, self.modules_mgmt_thrd))):
self.modules_mgmt_thrd.run()
@patch('os.path.isfile', MagicMock(side_effect=mock_is_file_indep_mode_enabled))
@patch('builtins.open', spec=open)
@patch('sonic_platform.sfp.SFP', MagicMock(return_value=MockSFPxcvrapi()))
def test_modules_mgmt_poller_events_3_ports(self, mock_open):
mock_open.side_effect = self.mock_open_new_side_effect_poller_test
DeviceDataManager.get_sfp_count = mock.MagicMock(return_value=DEFAULT_NUM_OF_PORTS_3)
num_of_tested_ports = DeviceDataManager.get_sfp_count()
assert num_of_tested_ports == DEFAULT_NUM_OF_PORTS_3
# start modules_mgmt thread and the test in poller part
with patch('select.poll', MagicMock(return_value=MockPollerStopEvent(self.modules_mgmt_task_stopping_event
, self.modules_mgmt_thrd))):
self.modules_mgmt_thrd.run()
@patch('os.path.isfile', MagicMock(side_effect=mock_is_file_indep_mode_enabled))
@patch('builtins.open', spec=open)
@patch('sonic_platform.sfp.SFP', MagicMock(return_value=MockSFPxcvrapi()))
def test_modules_mgmt_poller_events_single_port(self, mock_open):
mock_open.side_effect = self.mock_open_new_side_effect_poller_test
DeviceDataManager.get_sfp_count = mock.MagicMock(return_value=DEFAULT_NUM_OF_PORTS_1)
num_of_tested_ports = DeviceDataManager.get_sfp_count()
assert num_of_tested_ports == DEFAULT_NUM_OF_PORTS_1
# start modules_mgmt thread and the test in poller part
with patch('select.poll', MagicMock(return_value=MockPollerStopEvent(self.modules_mgmt_task_stopping_event
, self.modules_mgmt_thrd, num_of_tested_ports))):
#with patch('builtins.open', MagicMock(side_effect=self.mock_open_new_side_effect_poller_test)):
self.modules_mgmt_thrd.run()
@patch('os.path.isfile', MagicMock(side_effect=mock_is_file_indep_mode_enabled))
@patch('builtins.open', spec=open)
@patch('sonic_platform.sfp.SFP', MagicMock(return_value=MockSFPxcvrapi(False, True)))
def test_modules_mgmt_normal_warm_reboot(self, mock_open):
mock_open.side_effect = self.mock_open_new_side_effect_warm_reboot
# mock /proc/cmdline with warm reboot boot type key value
mock_file_content[modules_mgmt.PROC_CMDLINE] = f'{modules_mgmt.CMDLINE_STR_TO_LOOK_FOR}{modules_mgmt.CMDLINE_VAL_TO_LOOK_FOR}'
DeviceDataManager.get_sfp_count = mock.MagicMock(return_value=DEFAULT_NUM_OF_PORTS_1)
num_of_tested_ports = DeviceDataManager.get_sfp_count()
assert num_of_tested_ports == DEFAULT_NUM_OF_PORTS_1
# set the port to start with FW controlled before warm reboot takes place
mock_file_content[modules_mgmt.SYSFS_INDEPENDENT_FD_FW_CONTROL.format("0")] = "0"
# start modules_mgmt thread and the test in poller part
with patch('select.poll', MagicMock(return_value=MockPoller(self.modules_mgmt_task_stopping_event
, self.modules_mgmt_thrd, num_of_tested_ports, warm_reboot=True))):
self.modules_mgmt_thrd.run()
@patch('os.path.isfile', MagicMock(side_effect=mock_is_file_indep_mode_enabled))
@patch('builtins.open', spec=open)
@patch('sonic_platform.sfp.SFP', MagicMock(return_value=MockSFPxcvrapi(False, True)))
def test_modules_mgmt_plug_out_fw_cable_after_warm_reboot(self, mock_open):
mock_open.side_effect = self.mock_open_new_side_effect_warm_reboot
# mock /proc/cmdline with warm reboot boot type key value
mock_file_content[modules_mgmt.PROC_CMDLINE] = f'{modules_mgmt.CMDLINE_STR_TO_LOOK_FOR}{modules_mgmt.CMDLINE_VAL_TO_LOOK_FOR}'
DeviceDataManager.get_sfp_count = mock.MagicMock(return_value=DEFAULT_NUM_OF_PORTS_1)
num_of_tested_ports = DeviceDataManager.get_sfp_count()
assert num_of_tested_ports == DEFAULT_NUM_OF_PORTS_1
# set the port to start with FW controlled before warm reboot takes place
mock_file_content[modules_mgmt.SYSFS_INDEPENDENT_FD_FW_CONTROL.format("0")] = "0"
# start modules_mgmt thread and the test in poller part
with patch('select.poll', MagicMock(return_value=MockPoller(self.modules_mgmt_task_stopping_event
, self.modules_mgmt_thrd, num_of_tested_ports, port_plug_out=True, warm_reboot=True))):
self.modules_mgmt_thrd.run()
@patch('os.path.isfile', MagicMock(side_effect=mock_is_file_indep_mode_enabled))
@patch('builtins.open', spec=open)
@patch('sonic_platform.sfp.SFP', MagicMock(return_value=MockSFPxcvrapi(False, True)))
def test_modules_mgmt_plug_out_plug_in_fw_cable_after_warm_reboot(self, mock_open):
mock_open.side_effect = self.mock_open_new_side_effect_warm_reboot
# mock /proc/cmdline with warm reboot boot type key value
mock_file_content[modules_mgmt.PROC_CMDLINE] = f'{modules_mgmt.CMDLINE_STR_TO_LOOK_FOR}{modules_mgmt.CMDLINE_VAL_TO_LOOK_FOR}'
DeviceDataManager.get_sfp_count = mock.MagicMock(return_value=DEFAULT_NUM_OF_PORTS_1)
num_of_tested_ports = DeviceDataManager.get_sfp_count()
assert num_of_tested_ports == DEFAULT_NUM_OF_PORTS_1
mock_file_content[modules_mgmt.SYSFS_INDEPENDENT_FD_FW_CONTROL.format("0")] = "0"
# start modules_mgmt thread and the test in poller part
with patch('select.poll', MagicMock(return_value=MockPoller(self.modules_mgmt_task_stopping_event
, self.modules_mgmt_thrd, num_of_tested_ports, port_plug_out=True, warm_reboot=True, port_plug_in=True))):
self.modules_mgmt_thrd.run()
@patch('os.path.isfile', MagicMock(side_effect=mock_is_file_indep_mode_enabled))
@patch('builtins.open', spec=open)
@patch('sonic_platform.sfp.SFP', MagicMock(return_value=MockSFPxcvrapi(False, True)))
def test_modules_mgmt_no_ports(self, mock_open):
mock_open.side_effect = self.mock_open_new_side_effect_poller_test
DeviceDataManager.get_sfp_count = mock.MagicMock(return_value=0)
num_of_tested_ports = DeviceDataManager.get_sfp_count()
assert num_of_tested_ports == 0
# start modules_mgmt thread and the test in poller part
with patch('select.poll', MagicMock(return_value=MockPollerStopEvent(self.modules_mgmt_task_stopping_event
, self.modules_mgmt_thrd, num_of_tested_ports))):
self.modules_mgmt_thrd.run()
@patch('os.path.isfile', MagicMock(side_effect=mock_is_file_indep_mode_enabled))
@patch('builtins.open', spec=open)
@patch('sonic_platform.sfp.SFP', MagicMock(return_value=MockSFPxcvrapi(False, True)))
def test_modules_mgmt_ports_disconnected(self, mock_open):
mock_open.side_effect = self.mock_open_new_side_effect_poller_test
DeviceDataManager.get_sfp_count = mock.MagicMock(return_value=DEFAULT_NUM_OF_PORTS_3)
num_of_tested_ports = DeviceDataManager.get_sfp_count()
assert num_of_tested_ports == DEFAULT_NUM_OF_PORTS_3
# update hw_present sysfs with value of 0 for each port
for i in range(num_of_tested_ports):
modules_sysfs = modules_mgmt.SYSFS_INDEPENDENT_FD_PRESENCE.format(f"{i}")
mock_file_content[modules_sysfs] = "0"
# start modules_mgmt thread and the test in poller part
with patch('select.poll', MagicMock(return_value=MockPollerStopEvent(self.modules_mgmt_task_stopping_event
, self.modules_mgmt_thrd, num_of_tested_ports, ports_connected=False))):
self.modules_mgmt_thrd.run()
@patch('os.path.isfile', MagicMock(side_effect=mock_is_file_indep_mode_enabled))
@patch('builtins.open', spec=open)
@patch('sonic_platform.sfp.SFP', MagicMock(return_value=MockSFPxcvrapi(False, True)))
def test_modules_mgmt_bad_flows_port_disconnected(self, mock_open):
mock_open.side_effect = self.mock_open_new_side_effect_poller_test
DeviceDataManager.get_sfp_count = mock.MagicMock(return_value=DEFAULT_NUM_OF_PORTS_1)
num_of_tested_ports = DeviceDataManager.get_sfp_count()
assert num_of_tested_ports == DEFAULT_NUM_OF_PORTS_1
# update hw_present sysfs with value of 0 for each port
for i in range(num_of_tested_ports):
modules_sysfs = modules_mgmt.SYSFS_INDEPENDENT_FD_PRESENCE.format(f"{i}")
mock_file_content[modules_sysfs] = "0"
# start modules_mgmt thread and the test in poller part
with patch('select.poll', MagicMock(return_value=MockPollerStopEvent(self.modules_mgmt_task_stopping_event
, self.modules_mgmt_thrd, num_of_tested_ports, ports_connected=False))):
self.modules_mgmt_thrd.run()
@patch('os.path.isfile', MagicMock(side_effect=mock_is_file_indep_mode_enabled))
@patch('builtins.open', spec=open)
@patch('sonic_platform.sfp.SFP', MagicMock(return_value=MockSFPxcvrapi(False, True)))
def test_modules_mgmt_bad_flows_power_good(self, mock_open):
mock_open.side_effect = self.mock_open_new_side_effect_poller_test
DeviceDataManager.get_sfp_count = mock.MagicMock(return_value=DEFAULT_NUM_OF_PORTS_1)
num_of_tested_ports = DeviceDataManager.get_sfp_count()
assert num_of_tested_ports == DEFAULT_NUM_OF_PORTS_1
# update power_good sysfs with value of 0 for each port
for i in range(num_of_tested_ports):
modules_sysfs = modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_GOOD.format(f"{i}")
mock_file_content[modules_sysfs] = "0"
# start modules_mgmt thread and the test in poller part
with patch('select.poll', MagicMock(return_value=MockPollerStopEvent(self.modules_mgmt_task_stopping_event
, self.modules_mgmt_thrd, num_of_tested_ports, ports_connected=False))):
self.modules_mgmt_thrd.run()
for i in range(num_of_tested_ports):
modules_sysfs = modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_GOOD.format(f"{i}")
mock_file_content[modules_sysfs] = "1"
@patch('os.path.isfile', MagicMock(side_effect=mock_is_file_indep_mode_enabled))
@patch('builtins.open', spec=open)
@patch('sonic_platform.sfp.SFP', MagicMock(return_value=MockSFPxcvrapi(False, True)))
def test_modules_mgmt_bad_flows_ports_powered_off_fw_controlled(self, mock_open):
mock_open.side_effect = self.mock_open_new_side_effect_poller_test
DeviceDataManager.get_sfp_count = mock.MagicMock(return_value=DEFAULT_NUM_OF_PORTS_32)
num_of_tested_ports = DeviceDataManager.get_sfp_count()
assert num_of_tested_ports == DEFAULT_NUM_OF_PORTS_32
# create or update different sysfs and is_file mocking with relevant value for each port
for i in range(num_of_tested_ports):
# mock power_on sysfs for all ports
modules_sysfs = modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_ON.format(f"{i}")
mock_file_content[modules_sysfs] = "0"
mock_is_file_indep_mode_enabled_content[modules_sysfs] = True
self.fd_number_by_fd_name_dict[modules_sysfs] = 300 + i
# mock hw_presence sysfs for all ports
modules_sysfs = modules_mgmt.SYSFS_INDEPENDENT_FD_PRESENCE.format(f'{i}')
mock_file_content[modules_sysfs] = "1"
mock_is_file_indep_mode_enabled_content[modules_sysfs] = True
self.fd_number_by_fd_name_dict[modules_sysfs] = i
# mock power_good sysfs for all ports
modules_sysfs = modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_GOOD.format(f'{i}')
mock_file_content[modules_sysfs] = "1"
mock_is_file_indep_mode_enabled_content[modules_sysfs] = True
self.fd_number_by_fd_name_dict[modules_sysfs] = 200 + i
# mock hw_reset sysfs for all ports
modules_sysfs = modules_mgmt.SYSFS_INDEPENDENT_FD_HW_RESET.format(f'{i}')
mock_is_file_indep_mode_enabled_content[modules_sysfs] = True
self.fd_number_by_fd_name_dict[modules_sysfs] = 400 + i
# start modules_mgmt thread and the test in poller part
with patch('select.poll', MagicMock(return_value=MockPollerStopEvent(self.modules_mgmt_task_stopping_event
, self.modules_mgmt_thrd, num_of_tested_ports, fw_controlled_ports=True))):
self.modules_mgmt_thrd.run()
# change power_on sysfs values back to the default ones
for i in range(num_of_tested_ports):
modules_sysfs = modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_ON.format(f"{i}")
mock_file_content[modules_sysfs] = "1"
@patch('os.path.isfile', MagicMock(side_effect=mock_is_file_indep_mode_enabled))
@patch('builtins.open', spec=open)
@patch('sonic_platform.sfp.SFP', MagicMock(return_value=MockSFPxcvrapi()))
def test_modules_mgmt_bad_flows_ports_powered_off_sw_controlled(self, mock_open):
mock_open.side_effect = self.mock_open_new_side_effect_poller_test
DeviceDataManager.get_sfp_count = mock.MagicMock(return_value=DEFAULT_NUM_OF_PORTS_32)
num_of_tested_ports = DeviceDataManager.get_sfp_count()
assert num_of_tested_ports == DEFAULT_NUM_OF_PORTS_32
# create or update different sysfs and is_file mocking with relevant value for each port
for i in range(num_of_tested_ports):
# mock power_on sysfs for all ports
modules_sysfs = modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_ON.format(f"{i}")
mock_file_content[modules_sysfs] = "0"
mock_is_file_indep_mode_enabled_content[modules_sysfs] = True
self.fd_number_by_fd_name_dict[modules_sysfs] = 300 + i
# mock hw_presence sysfs for all ports
modules_sysfs = modules_mgmt.SYSFS_INDEPENDENT_FD_PRESENCE.format(f'{i}')
mock_file_content[modules_sysfs] = "1"
mock_is_file_indep_mode_enabled_content[modules_sysfs] = True
self.fd_number_by_fd_name_dict[modules_sysfs] = i
# mock power_good sysfs for all ports
modules_sysfs = modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_GOOD.format(f'{i}')
mock_file_content[modules_sysfs] = "1"
mock_is_file_indep_mode_enabled_content[modules_sysfs] = True
self.fd_number_by_fd_name_dict[modules_sysfs] = 200 + i
# mock hw_reset sysfs for all ports
modules_sysfs = modules_mgmt.SYSFS_INDEPENDENT_FD_HW_RESET.format(f'{i}')
mock_is_file_indep_mode_enabled_content[modules_sysfs] = True
self.fd_number_by_fd_name_dict[modules_sysfs] = 400 + i
# mock frequency_support sysfs for all ports
modules_sysfs = modules_mgmt.SYSFS_INDEPENDENT_FD_FREQ_SUPPORT.format(f'{i}')
mock_file_content[modules_sysfs] = "0"
mock_is_file_indep_mode_enabled_content[modules_sysfs] = True
self.fd_number_by_fd_name_dict[modules_sysfs] = 600 + i
# start modules_mgmt thread and the test in poller part
with patch('select.poll', MagicMock(return_value=MockPollerStopEvent(self.modules_mgmt_task_stopping_event
, self.modules_mgmt_thrd, num_of_tested_ports))):
self.modules_mgmt_thrd.run()
# change power_on sysfs values back to the default ones
for i in range(num_of_tested_ports):
modules_sysfs = modules_mgmt.SYSFS_INDEPENDENT_FD_POWER_ON.format(f"{i}")
mock_file_content[modules_sysfs] = "1"
def tearDown(cls):
mock_file_content[modules_mgmt.PROC_CMDLINE] = ''
cls.modules_mgmt_thrd = None
# a check that modules mgmt thread ran and got into the poller part where the tests here has all checks
assert POLLER_EXECUTED

View File

@ -8,12 +8,12 @@ $(DOCKER_DHCP_RELAY)_PATH = $(DOCKERS_PATH)/$(DOCKER_DHCP_RELAY_STEM)
$(DOCKER_DHCP_RELAY)_DEPENDS += $(ISC_DHCP_RELAY) $(SONIC_DHCPMON) $(SONIC_DHCPRELAY) $(LIBSWSSCOMMON) $(SONIC_RSYSLOG_PLUGIN)
$(DOCKER_DHCP_RELAY)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BULLSEYE)_DBG_DEPENDS)
$(DOCKER_DHCP_RELAY)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BOOKWORM)_DBG_DEPENDS)
$(DOCKER_DHCP_RELAY)_DBG_DEPENDS += $(ISC_DHCP_RELAY_DBG) $(SONIC_DHCPRELAY_DBG) $(SONIC_DHCPMON_DBG) $(SONIC_RSYSLOG_PLUGIN)
$(DOCKER_DHCP_RELAY)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BULLSEYE)_DBG_IMAGE_PACKAGES)
$(DOCKER_DHCP_RELAY)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BOOKWORM)_DBG_IMAGE_PACKAGES)
$(DOCKER_DHCP_RELAY)_LOAD_DOCKERS = $(DOCKER_CONFIG_ENGINE_BULLSEYE)
$(DOCKER_DHCP_RELAY)_LOAD_DOCKERS = $(DOCKER_CONFIG_ENGINE_BOOKWORM)
$(DOCKER_DHCP_RELAY)_INSTALL_PYTHON_WHEELS = $(SONIC_UTILITIES_PY3)
$(DOCKER_DHCP_RELAY)_INSTALL_DEBS = $(PYTHON3_SWSSCOMMON)
@ -29,9 +29,7 @@ $(DOCKER_DHCP_RELAY)_SERVICE_BEFORE = ntp-config
$(DOCKER_DHCP_RELAY)_SERVICE_DEPENDENT_OF = swss
SONIC_DOCKER_IMAGES += $(DOCKER_DHCP_RELAY)
SONIC_BULLSEYE_DOCKERS += $(DOCKER_DHCP_RELAY)
SONIC_DOCKER_DBG_IMAGES += $(DOCKER_DHCP_RELAY_DBG)
SONIC_BULLSEYE_DBG_DOCKERS += $(DOCKER_DHCP_RELAY_DBG)
ifeq ($(INCLUDE_KUBERNETES),y)
$(DOCKER_DHCP_RELAY)_DEFAULT_FEATURE_OWNER = kube

View File

@ -1,7 +1,7 @@
# isc-dhcp packages
ISC_DHCP_VERSION = 4.4.1
ISC_DHCP_VERSION_FULL = ${ISC_DHCP_VERSION}-2.3+deb11u2
ISC_DHCP_VERSION = 4.4.3-P1
ISC_DHCP_VERSION_FULL = ${ISC_DHCP_VERSION}-2
export ISC_DHCP_VERSION ISC_DHCP_VERSION_FULL

View File

@ -418,7 +418,9 @@ RUN apt-get update && apt-get install -y \
auditd \
# For protobuf
protobuf-compiler \
libprotobuf-dev
libprotobuf-dev \
# For sonic-dhcp6relay build
libjsoncpp-dev
{%- if CROSS_BUILD_ENVIRON == "y" %}
# Arm vs. amd64 versions conflict - remove amd64 packages

View File

@ -4,11 +4,11 @@ Date: Thu, 25 Apr 2019 22:07:20 +0000
Subject: [PATCH] Customizable Option 82 circuit ID and remote ID fields
---
relay/dhcrelay.c | 171 ++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 147 insertions(+), 24 deletions(-)
relay/dhcrelay.c | 178 +++++++++++++++++++++++++++++++++++++++--------
1 file changed, 150 insertions(+), 28 deletions(-)
diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c
index 0cb2ef6..418b943 100644
index 3b9c71b..19843f7 100644
--- a/relay/dhcrelay.c
+++ b/relay/dhcrelay.c
@@ -75,6 +75,8 @@ int bad_circuit_id = 0; /* Circuit ID option in matching RAI option
@ -20,7 +20,7 @@ index 0cb2ef6..418b943 100644
int max_hop_count = 10; /* Maximum hop count */
int no_daemon = 0;
@@ -151,10 +153,20 @@ static const char url[] =
@@ -160,10 +162,20 @@ static const char url[] =
char *progname;
@ -42,7 +42,7 @@ index 0cb2ef6..418b943 100644
" [-A <length>] [-c <hops>]\n" \
" [-p <port> | -rp <relay-port>]\n" \
" [-pf <pid-file>] [--no-pid]\n"\
@@ -171,11 +183,11 @@ char *progname;
@@ -180,11 +192,11 @@ char *progname;
" -l lower0 [ ... -l lowerN]\n" \
" -u upper0 [ ... -u upperN]\n" \
" lower (client link): [address%%]interface[#index]\n" \
@ -56,7 +56,7 @@ index 0cb2ef6..418b943 100644
" [-A <length>] [-c <hops>] [-p <port>]\n" \
" [-pf <pid-file>] [--no-pid]\n"\
" [-m append|replace|forward|discard]\n" \
@@ -190,13 +202,13 @@ char *progname;
@@ -199,13 +211,13 @@ char *progname;
" -l lower0 [ ... -l lowerN]\n" \
" -u upper0 [ ... -u upperN]\n" \
" lower (client link): [address%%]interface[#index]\n" \
@ -72,10 +72,10 @@ index 0cb2ef6..418b943 100644
" [-p <port> | -rp <relay-port>]\n" \
" [-pf <pid-file>] [--no-pid]\n" \
" [-m append|replace|forward|discard]\n" \
@@ -204,18 +216,18 @@ char *progname;
@@ -213,18 +225,18 @@ char *progname;
" [-iu interface0 [ ... -iu interfaceN]\n" \
" [-id interface0 [ ... -id interfaceN]\n" \
" [-U interface]\n" \
" [-U interface] [-g <ip-address>]\n" \
-" server0 [ ... serverN]\n\n" \
+" server0 [ ... serverN]\n\n" DHCRELAY_OPTION82_USAGE \
" %s {--version|--help|-h}"
@ -88,13 +88,13 @@ index 0cb2ef6..418b943 100644
" [-i interface0 [ ... -i interfaceN]\n" \
" [-iu interface0 [ ... -iu interfaceN]\n" \
" [-id interface0 [ ... -id interfaceN]\n" \
" [-U interface]\n" \
" [-U interface] [-g <ip-address>]\n" \
-" server0 [ ... serverN]\n\n" \
+" server0 [ ... serverN]\n\n" DHCRELAY_OPTION82_USAGE \
" %s {--version|--help|-h}"
#endif
#endif
@@ -471,6 +483,15 @@ main(int argc, char **argv) {
@@ -480,6 +492,15 @@ main(int argc, char **argv) {
local_family_set = 1;
local_family = AF_INET;
#endif
@ -110,7 +110,7 @@ index 0cb2ef6..418b943 100644
add_agent_options = 1;
} else if (!strcmp(argv[i], "-A")) {
#ifdef DHCPv6
@@ -1171,6 +1192,81 @@ find_interface_by_agent_option(struct dhcp_packet *packet,
@@ -1207,6 +1228,81 @@ find_interface_by_agent_option(struct dhcp_packet *packet,
return (-1);
}
@ -192,7 +192,7 @@ index 0cb2ef6..418b943 100644
/*
* Examine a packet to see if it's a candidate to have a Relay
* Agent Information option tacked onto its tail. If it is, tack
@@ -1180,9 +1276,12 @@ static int
@@ -1216,9 +1312,12 @@ int
add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet,
unsigned length, struct in_addr giaddr) {
int is_dhcp = 0, mms;
@ -206,7 +206,7 @@ index 0cb2ef6..418b943 100644
/* If we're not adding agent options to packets, we can skip
this. */
@@ -1316,17 +1415,40 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet,
@@ -1357,17 +1456,40 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet,
op = sp;
#endif
@ -258,7 +258,7 @@ index 0cb2ef6..418b943 100644
}
if (adding_link_select) {
@@ -1351,7 +1473,7 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet,
@@ -1392,7 +1514,7 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet,
* If not, forward without adding the option.
*/
if (max - sp >= optlen + 3) {
@ -267,7 +267,7 @@ index 0cb2ef6..418b943 100644
/* Okay, cons up *our* Relay Agent Information option. */
*sp++ = DHO_DHCP_AGENT_OPTIONS;
@@ -1359,16 +1481,16 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet,
@@ -1400,16 +1522,16 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet,
/* Copy in the circuit id... */
*sp++ = RAI_CIRCUIT_ID;
@ -292,5 +292,5 @@ index 0cb2ef6..418b943 100644
/* RFC3527: Use the inbound packet's interface address in
--
2.17.1
2.25.1

View File

@ -9,10 +9,10 @@ Subject: [PATCH] Support for loading port alias map file to replace port name
1 file changed, 104 insertions(+), 1 deletion(-)
diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c
index 00c81d3..54f132a 100644
index 0d9b2e7..b72b1bc 100644
--- a/relay/dhcrelay.c
+++ b/relay/dhcrelay.c
@@ -129,6 +129,14 @@ static void setup_streams(void);
@@ -133,6 +133,14 @@ static void setup_streams(void);
char *dhcrelay_sub_id = NULL;
#endif
@ -24,11 +24,11 @@ index 00c81d3..54f132a 100644
+static struct interface_name_alias_tuple *g_interface_name_alias_map = NULL;
+static size_t g_interface_name_alias_map_size = 0;
+
#ifndef UNIT_TEST
static void do_relay4(struct interface_info *, struct dhcp_packet *,
unsigned int, unsigned int, struct iaddr,
struct hardware *);
@@ -143,6 +151,10 @@ static int strip_relay_agent_options(struct interface_info *,
@@ -152,6 +160,10 @@ extern int strip_relay_agent_options(struct interface_info *,
#ifndef UNIT_TEST
static void request_v4_interface(const char* name, int flags);
+static int load_interface_alias_map(const char *port_alias_map_file_path);
@ -36,9 +36,9 @@ index 00c81d3..54f132a 100644
+static void free_interface_alias_map(void);
+
static const char copyright[] =
"Copyright 2004-2018 Internet Systems Consortium.";
"Copyright 2004-2022 Internet Systems Consortium.";
static const char arr[] = "All rights reserved.";
@@ -158,7 +170,7 @@ char *progname;
@@ -167,7 +179,7 @@ char *progname;
"\n" \
" %%%% A single %%\n" \
" %%h Hostname of device\n" \
@ -47,7 +47,7 @@ index 00c81d3..54f132a 100644
" %%P Hardware address of interface that generated the request\n" \
" %%C Client hardware address\n" \
" %%I DHCP relay agent IP Address\n" \
@@ -171,6 +183,7 @@ char *progname;
@@ -180,6 +192,7 @@ char *progname;
" [-p <port> | -rp <relay-port>]\n" \
" [-pf <pid-file>] [--no-pid]\n"\
" [-m append|replace|forward|discard]\n" \
@ -55,7 +55,7 @@ index 00c81d3..54f132a 100644
" [-i interface0 [ ... -i interfaceN]\n" \
" [-iu interface0 [ ... -iu interfaceN]\n" \
" [-id interface0 [ ... -id interfaceN]\n" \
@@ -179,6 +192,7 @@ char *progname;
@@ -188,6 +201,7 @@ char *progname;
" %s -6 [-d] [-q] [-I] [-c <hops>]\n" \
" [-p <port> | -rp <relay-port>]\n" \
" [-pf <pid-file>] [--no-pid]\n" \
@ -63,7 +63,7 @@ index 00c81d3..54f132a 100644
" [-s <subscriber-id>]\n" \
" -l lower0 [ ... -l lowerN]\n" \
" -u upper0 [ ... -u upperN]\n" \
@@ -619,6 +633,11 @@ main(int argc, char **argv) {
@@ -643,6 +657,11 @@ main(int argc, char **argv) {
no_dhcrelay_pid = ISC_TRUE;
} else if (!strcmp(argv[i], "--no-pid")) {
no_pid_file = ISC_TRUE;
@ -75,7 +75,7 @@ index 00c81d3..54f132a 100644
} else if (argv[i][0] == '-') {
usage("Unknown command: %s", argv[i]);
} else {
@@ -841,6 +860,7 @@ main(int argc, char **argv) {
@@ -865,6 +884,7 @@ main(int argc, char **argv) {
dispatch();
/* In fact dispatch() never returns. */
@ -83,7 +83,7 @@ index 00c81d3..54f132a 100644
return (0);
}
@@ -1271,6 +1291,7 @@ format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_pack
@@ -1307,6 +1327,7 @@ format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_pack
*/
if (packet->htype && !packet->giaddr.s_addr) {
int ret = 0, vlanid = 0;
@ -91,10 +91,11 @@ index 00c81d3..54f132a 100644
ret = _bridgefdbquery(print_hw_addr(packet->htype, packet->hlen, packet->chaddr),
ifname,
@@ -1287,6 +1308,18 @@ format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_pack
@@ -1322,6 +1343,18 @@ format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_pack
strncpy(ifname, ip->name, IFNAMSIZ);
}
+
+ // Attempt to translate SONiC interface name to vendor alias
+ ret = get_interface_alias_by_name(ifname, ifalias);
+ if (ret < 0) {
@ -106,11 +107,10 @@ index 00c81d3..54f132a 100644
+
+ strncpy(ifname, ifalias, IFNAMSIZ);
+ }
+
str = ifname;
}
break;
@@ -2313,3 +2346,73 @@ void request_v4_interface(const char* name, int flags) {
@@ -2361,3 +2394,73 @@ void request_v4_interface(const char* name, int flags) {
interface_snorf(tmp, (INTERFACE_REQUESTED | flags));
interface_dereference(&tmp, MDL);
}
@ -185,5 +185,5 @@ index 00c81d3..54f132a 100644
+ g_interface_name_alias_map_size = 0;
+}
--
2.17.1
2.25.1

View File

@ -9,18 +9,18 @@ Subject: [PATCH 1/3] Add --enable-use-sockets to configure flags in
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/debian/rules b/debian/rules
index d3fcc1d..2a7219d 100755
index dc2a9b1..3d12fb5 100755
--- a/debian/rules
+++ b/debian/rules
@@ -24,7 +24,7 @@ CFLAGS+=-D_PATH_DHCLIENT_CONF='\"/etc/dhcp/dhclient.conf\"'
@@ -23,7 +23,7 @@ CFLAGS+=-D_PATH_DHCLIENT_CONF='\"/etc/dhcp/dhclient.conf\"'
CFLAGS+=-D_PATH_DHCLIENT_DB='\"$(LEASE_PATH)/dhclient.leases\"'
CFLAGS+=-D_PATH_DHCLIENT6_DB='\"$(LEASE_PATH)/dhclient6.leases\"'
-CONFFLAGS=--prefix=/usr --with-libbind=/usr --enable-log-pid --enable-paranoia
+CONFFLAGS=--prefix=/usr --with-libbind=/usr --enable-log-pid --enable-paranoia --enable-use-sockets
-CONFFLAGS+=--prefix=/usr --enable-log-pid --enable-paranoia
+CONFFLAGS+=--prefix=/usr --enable-log-pid --enable-paranoia --enable-use-sockets
include /usr/share/dpkg/buildtools.mk
# cross-architecture building
ifneq ($(DEB_HOST_GNU_TYPE),$(DEB_BUILD_GNU_TYPE))
--
2.17.1
2.25.1

View File

@ -9,10 +9,10 @@ Subject: [PATCH 2/3] Bugfix: Ensure HAVE_SO_BINDTODEVICE has a chance to be
1 file changed, 120 insertions(+), 119 deletions(-)
diff --git a/includes/osdep.h b/includes/osdep.h
index cfae90b..f07c43c 100644
index 0742858..dfccb8c 100644
--- a/includes/osdep.h
+++ b/includes/osdep.h
@@ -48,37 +48,6 @@
@@ -47,37 +47,6 @@
#define BYTE_ORDER DHCP_BYTE_ORDER
#endif /* BYTE_ORDER */
@ -50,7 +50,7 @@ index cfae90b..f07c43c 100644
#if !defined (TIME_MAX)
# define TIME_MAX 2147483647
#endif
@@ -91,94 +60,6 @@
@@ -90,98 +59,10 @@
# define vsnprintf isc_print_vsnprintf
#endif
@ -102,6 +102,10 @@ index cfae90b..f07c43c 100644
-# define USE_UPF_RECEIVE
-#endif
-
#if defined (SO_BINDTODEVICE) && !defined (HAVE_SO_BINDTODEVICE)
# define HAVE_SO_BINDTODEVICE
#endif
-/* Porting::
-
- If you add support for sending packets directly out an interface,
@ -145,7 +149,7 @@ index cfae90b..f07c43c 100644
/* If we don't have a DLPI packet filter, we have to filter in userland.
Probably not worth doing, actually. */
#if defined (USE_DLPI_RECEIVE) && !defined (USE_DLPI_PFMOD)
@@ -288,4 +169,124 @@
@@ -287,4 +168,124 @@
# define STDERR_FILENO 2
#endif
@ -271,5 +275,5 @@ index cfae90b..f07c43c 100644
+
#endif /* __ISC_DHCP_OSDEP_H__ */
--
2.17.1
2.25.1

View File

@ -6,16 +6,16 @@ Subject: [PATCH 3/3] If destination of BOOTREQUEST is directed broadcast,
interfaces
---
common/discover.c | 46 +++++++++++++++++++---
common/discover.c | 40 +++++++++++++++++++--
includes/dhcpd.h | 3 ++
relay/dhcrelay.c | 98 +++++++++++++++++++++++++++++++++++++++++------
3 files changed, 131 insertions(+), 16 deletions(-)
relay/dhcrelay.c | 90 +++++++++++++++++++++++++++++++++++++++++++----
3 files changed, 123 insertions(+), 10 deletions(-)
diff --git a/common/discover.c b/common/discover.c
index 98ac46a..53afecc 100644
index 0c5ad39..32f2516 100644
--- a/common/discover.c
+++ b/common/discover.c
@@ -236,6 +236,7 @@ struct iface_conf_list {
@@ -239,6 +239,7 @@ struct iface_conf_list {
struct iface_info {
char name[IF_NAMESIZE+1]; /* name of the interface, e.g. "bge0" */
struct sockaddr_storage addr; /* address information */
@ -23,7 +23,7 @@ index 98ac46a..53afecc 100644
isc_uint64_t flags; /* interface flags, e.g. IFF_LOOPBACK */
};
@@ -367,6 +368,17 @@ next_iface(struct iface_info *info, int *err, struct iface_conf_list *ifaces) {
@@ -370,6 +371,17 @@ next_iface(struct iface_info *info, int *err, struct iface_conf_list *ifaces) {
}
info->flags = tmp.lifr_flags;
@ -41,7 +41,7 @@ index 98ac46a..53afecc 100644
ifaces->next++;
*err = 0;
return 1;
@@ -410,6 +422,7 @@ struct iface_conf_list {
@@ -413,6 +425,7 @@ struct iface_conf_list {
struct iface_info {
char name[IFNAMSIZ]; /* name of the interface, e.g. "bge0" */
struct sockaddr_storage addr; /* address information */
@ -49,17 +49,17 @@ index 98ac46a..53afecc 100644
isc_uint64_t flags; /* interface flags, e.g. IFF_LOOPBACK */
};
@@ -487,7 +500,8 @@ end_iface_scan(struct iface_conf_list *ifaces) {
@@ -490,7 +503,8 @@ end_iface_scan(struct iface_conf_list *ifaces) {
/* XXX: perhaps create drealloc() rather than do it manually */
void
add_ipv4_addr_to_interface(struct interface_info *iface,
add_ipv4_addr_to_interface(struct interface_info *iface,
- const struct in_addr *addr) {
+ const struct in_addr *addr,
+ const struct in_addr *netmask) {
/*
* We don't expect a lot of addresses per IPv4 interface, so
* we use 4, as our "chunk size" for collecting addresses.
@@ -498,6 +512,11 @@ add_ipv4_addr_to_interface(struct interface_info *iface,
@@ -501,6 +515,11 @@ add_ipv4_addr_to_interface(struct interface_info *iface,
log_fatal("Out of memory saving IPv4 address "
"on interface.");
}
@ -71,7 +71,7 @@ index 98ac46a..53afecc 100644
iface->address_count = 0;
iface->address_max = 4;
} else if (iface->address_count >= iface->address_max) {
@@ -515,9 +534,23 @@ add_ipv4_addr_to_interface(struct interface_info *iface,
@@ -518,9 +537,23 @@ add_ipv4_addr_to_interface(struct interface_info *iface,
iface->address_max * sizeof(struct in_addr));
dfree(iface->addresses, MDL);
iface->addresses = tmp;
@ -96,15 +96,15 @@ index 98ac46a..53afecc 100644
}
#ifdef DHCPv6
@@ -656,6 +689,7 @@ discover_interfaces(int state) {
if ((info.addr.ss_family == AF_INET) &&
@@ -661,6 +694,7 @@ discover_interfaces(int state) {
if ((info.addr.ss_family == AF_INET) &&
(local_family == AF_INET)) {
struct sockaddr_in *a = (struct sockaddr_in*)&info.addr;
+ struct sockaddr_in *n = (struct sockaddr_in*)&info.netmask;
struct iaddr addr;
/* We don't want the loopback interface. */
@@ -670,7 +704,7 @@ discover_interfaces(int state) {
@@ -675,7 +709,7 @@ discover_interfaces(int state) {
if (a->sin_addr.s_addr != htonl(INADDR_ANY))
tmp->configured = 1;
@ -114,10 +114,10 @@ index 98ac46a..53afecc 100644
/* invoke the setup hook */
addr.len = 4;
diff --git a/includes/dhcpd.h b/includes/dhcpd.h
index df3da59..2c7f059 100644
index 20f9bfb..b54a36e 100644
--- a/includes/dhcpd.h
+++ b/includes/dhcpd.h
@@ -1369,6 +1369,9 @@ struct interface_info {
@@ -1380,6 +1380,9 @@ struct interface_info {
struct in_addr *addresses; /* Addresses associated with this
* interface.
*/
@ -128,7 +128,7 @@ index df3da59..2c7f059 100644
int address_max; /* Size of addresses buffer. */
struct in6_addr *v6addresses; /* IPv6 addresses associated with
diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c
index 54f132a..beae977 100644
index b72b1bc..9143e85 100644
--- a/relay/dhcrelay.c
+++ b/relay/dhcrelay.c
@@ -30,6 +30,7 @@
@ -139,7 +139,7 @@ index 54f132a..beae977 100644
#include <isc/file.h>
TIME default_lease_time = 43200; /* 12 hours... */
@@ -1001,20 +1002,95 @@ do_relay4(struct interface_info *ip, struct dhcp_packet *packet,
@@ -1030,20 +1031,95 @@ do_relay4(struct interface_info *ip, struct dhcp_packet *packet,
/* Otherwise, it's a BOOTREQUEST, so forward it to all the
servers. */
for (sp = servers; sp; sp = sp->next) {
@ -147,7 +147,6 @@ index 54f132a..beae977 100644
- ? fallback_interface : interfaces),
- NULL, packet, length, ip->addresses[0],
- &sp->to, NULL) < 0) {
- ++client_packet_errors;
+ int packet_relay_attempted = 0;
+
+ log_debug("Server IP: %s", inet_ntoa(sp->to.sin_addr));
@ -180,14 +179,16 @@ index 54f132a..beae977 100644
+ log_debug("Packet destined for broadcast IP of %s", out->name);
+ if (send_packet(out, NULL, packet,
+ length, ip->addresses[0],&sp->to, NULL) < 0) {
+ ++client_packet_errors;
+ } else {
+ log_debug("Forwarded BOOTREQUEST for %s to %s on interface %s",
+ print_hw_addr(packet->htype, packet->hlen,
+ packet->chaddr),
+ inet_ntoa(sp->to.sin_addr), out->name);
++client_packet_errors;
} else {
- log_debug("Forwarded BOOTREQUEST for %s to %s",
+ log_debug("Forwarded BOOTREQUEST for %s to %s on interface %s",
print_hw_addr(packet->htype, packet->hlen,
packet->chaddr),
- inet_ntoa(sp->to.sin_addr));
+ inet_ntoa(sp->to.sin_addr), out->name);
+
+ ++client_packets_relayed;
++client_packets_relayed;
+ }
+
+ packet_relay_attempted = 1;
@ -198,8 +199,9 @@ index 54f132a..beae977 100644
+
+ if (packet_relay_attempted)
+ break;
+ }
+
}
- }
+ if (packet_relay_attempted)
+ continue;
+
@ -217,12 +219,7 @@ index 54f132a..beae977 100644
+
+ ++client_packets_relayed;
+ }
} else {
- log_debug("Forwarded BOOTREQUEST for %s to %s",
- print_hw_addr(packet->htype, packet->hlen,
- packet->chaddr),
- inet_ntoa(sp->to.sin_addr));
- ++client_packets_relayed;
+ } else {
+ for (out = interfaces; out; out = out->next) {
+ // Only relay BOOTREQUEST on upstream interfaces
+ if (!(out->flags & INTERFACE_UPSTREAM))
@ -240,12 +237,11 @@ index 54f132a..beae977 100644
+ ++client_packets_relayed;
+ }
+ }
}
}
-
+ }
+ }
}
/* Strip any Relay Agent Information options from the DHCP packet
#endif /* UNIT_TEST */
--
2.17.1
2.25.1

View File

@ -14,10 +14,10 @@ didn't discover the interface(s) when it started up.
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/common/discover.c b/common/discover.c
index 8d5b958..5efff49 100644
index 32f2516..31dae3c 100644
--- a/common/discover.c
+++ b/common/discover.c
@@ -1016,7 +1016,8 @@ discover_interfaces(int state) {
@@ -668,7 +668,8 @@ discover_interfaces(int state) {
info.flags & IFF_LOOPBACK ||
info.flags & IFF_POINTOPOINT) && !tmp) ||
(!(info.flags & IFF_UP) &&
@ -25,8 +25,8 @@ index 8d5b958..5efff49 100644
+ state != DISCOVER_UNCONFIGURED &&
+ state != DISCOVER_RELAY))
continue;
/* If there isn't already an interface by this name,
--
2.17.1
2.25.1

View File

@ -4,11 +4,11 @@ Date: Tue, 1 Dec 2020 16:33:34 -0800
Subject: [PATCH] support for dual tor scenario
---
relay/dhcrelay.c | 117 +++++++++++++++++++++++++++++++++++++++--------
1 file changed, 98 insertions(+), 19 deletions(-)
relay/dhcrelay.c | 115 +++++++++++++++++++++++++++++++++++++++--------
1 file changed, 97 insertions(+), 18 deletions(-)
diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c
index e158efe..055d97f 100644
index 9143e85..4134a58 100644
--- a/relay/dhcrelay.c
+++ b/relay/dhcrelay.c
@@ -56,6 +56,8 @@ int bogus_agent_drops = 0; /* Packets dropped because agent option
@ -34,52 +34,51 @@ index e158efe..055d97f 100644
#ifdef DHCPv6
/* Force use of DHCPv6 interface-id option. */
isc_boolean_t use_if_id = ISC_FALSE;
@@ -156,6 +165,8 @@ static int load_interface_alias_map(const char *port_alias_map_file_path);
@@ -165,6 +174,8 @@ static int load_interface_alias_map(const char *port_alias_map_file_path);
static int get_interface_alias_by_name(const char *if_name, char *if_alias_out);
static void free_interface_alias_map(void);
+static void free_downstream_intfs(void);
+
static const char copyright[] =
"Copyright 2004-2018 Internet Systems Consortium.";
"Copyright 2004-2022 Internet Systems Consortium.";
static const char arr[] = "All rights reserved.";
@@ -189,6 +200,7 @@ char *progname;
@@ -198,6 +209,7 @@ char *progname;
" [-iu interface0 [ ... -iu interfaceN]\n" \
" [-id interface0 [ ... -id interfaceN]\n" \
" [-U interface]\n" \
" [-U interface] [-g <ip-address>]\n" \
+" [-dt]\n"\
" server0 [ ... serverN]\n\n" \
" %s -6 [-d] [-q] [-I] [-c <hops>]\n" \
" [-p <port> | -rp <relay-port>]\n" \
@@ -210,6 +222,7 @@ char *progname;
@@ -219,6 +231,7 @@ char *progname;
" [-iu interface0 [ ... -iu interfaceN]\n" \
" [-id interface0 [ ... -id interfaceN]\n" \
" [-U interface]\n" \
" [-U interface] [-g <ip-address>]\n" \
+" [-dt]\n"\
" server0 [ ... serverN]\n\n" \
" %s -6 [-d] [-q] [-I] [-c <hops>] [-p <port>]\n" \
" [-pf <pid-file>] [--no-pid]\n" \
@@ -231,6 +244,7 @@ char *progname;
@@ -240,6 +253,7 @@ char *progname;
" [-iu interface0 [ ... -iu interfaceN]\n" \
" [-id interface0 [ ... -id interfaceN]\n" \
" [-U interface]\n" \
" [-U interface] [-g <ip-address>]\n" \
+" [-dt]\n"\
" server0 [ ... serverN]\n\n" DHCRELAY_OPTION82_USAGE \
" %s {--version|--help|-h}"
#else
@@ -242,6 +256,7 @@ char *progname;
@@ -251,6 +265,7 @@ char *progname;
" [-iu interface0 [ ... -iu interfaceN]\n" \
" [-id interface0 [ ... -id interfaceN]\n" \
" [-U interface]\n" \
" [-U interface] [-g <ip-address>]\n" \
+" [-dt]\n"\
" server0 [ ... serverN]\n\n" DHCRELAY_OPTION82_USAGE \
" %s {--version|--help|-h}"
#endif
@@ -639,7 +654,16 @@ main(int argc, char **argv) {
@@ -663,6 +678,15 @@ main(int argc, char **argv) {
usage(use_noarg, argv[i-1]);
if (load_interface_alias_map(argv[i]) != 0)
log_fatal("Failed to load interface name-alias map.");
- } else if (argv[i][0] == '-') {
+ } else if (!strcmp(argv[i], "-dt")) {
+#ifdef DHCPv6
+ if (local_family_set && (local_family == AF_INET6)) {
@ -89,11 +88,10 @@ index e158efe..055d97f 100644
+ local_family = AF_INET;
+#endif
+ enable_support_for_dual_tor = 1;
+ } else if (argv[i][0] == '-') {
} else if (argv[i][0] == '-') {
usage("Unknown command: %s", argv[i]);
} else {
struct hostent *he;
@@ -747,7 +771,6 @@ main(int argc, char **argv) {
@@ -771,7 +795,6 @@ main(int argc, char **argv) {
log_fatal("No servers specified.");
}
@ -101,7 +99,7 @@ index e158efe..055d97f 100644
/* Set up the server sockaddrs. */
for (sp = servers; sp; sp = sp->next) {
sp->to.sin_port = local_port;
@@ -862,6 +885,8 @@ main(int argc, char **argv) {
@@ -886,6 +909,8 @@ main(int argc, char **argv) {
/* In fact dispatch() never returns. */
free_interface_alias_map();
@ -110,7 +108,7 @@ index e158efe..055d97f 100644
return (0);
}
@@ -885,25 +910,50 @@ do_relay4(struct interface_info *ip, struct dhcp_packet *packet,
@@ -909,25 +934,50 @@ do_relay4(struct interface_info *ip, struct dhcp_packet *packet,
return;
}
@ -174,7 +172,7 @@ index e158efe..055d97f 100644
}
/* If it's a bootreply, forward it to the client. */
@@ -913,6 +963,10 @@ do_relay4(struct interface_info *ip, struct dhcp_packet *packet,
@@ -937,6 +987,10 @@ do_relay4(struct interface_info *ip, struct dhcp_packet *packet,
return;
}
@ -182,10 +180,10 @@ index e158efe..055d97f 100644
+ if (enable_support_for_dual_tor && !out)
+ return;
+
log_debug("BOOTREPLY giaddr: %s\n", inet_ntoa(packet->giaddr));
if (!(packet->flags & htons(BOOTP_BROADCAST)) &&
can_unicast_without_arp(out)) {
to.sin_addr = packet->yiaddr;
@@ -945,9 +999,13 @@ do_relay4(struct interface_info *ip, struct dhcp_packet *packet,
@@ -970,9 +1024,13 @@ do_relay4(struct interface_info *ip, struct dhcp_packet *packet,
return;
if (!out) {
@ -202,7 +200,7 @@ index e158efe..055d97f 100644
return;
}
@@ -989,6 +1047,7 @@ do_relay4(struct interface_info *ip, struct dhcp_packet *packet,
@@ -1023,6 +1081,7 @@ do_relay4(struct interface_info *ip, struct dhcp_packet *packet,
that set giaddr, so we won't see it. */
if (!packet->giaddr.s_addr)
packet->giaddr = ip->addresses[0];
@ -210,7 +208,7 @@ index e158efe..055d97f 100644
if (packet->hops < max_hop_count)
packet->hops = packet->hops + 1;
else
@@ -1264,7 +1323,6 @@ find_interface_by_agent_option(struct dhcp_packet *packet,
@@ -1305,7 +1364,6 @@ find_interface_by_agent_option(struct dhcp_packet *packet,
/* Scan the interface list looking for an interface whose
name matches the one specified in circuit_id. */
@ -218,7 +216,7 @@ index e158efe..055d97f 100644
for (ip = interfaces; ip; ip = ip->next) {
if (ip->circuit_id &&
ip->circuit_id_len == circuit_id_len &&
@@ -1668,6 +1726,7 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet,
@@ -1714,6 +1772,7 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet,
*sp++ = 4u;
memcpy(sp, &giaddr.s_addr, 4);
sp += 4;
@ -226,7 +224,7 @@ index e158efe..055d97f 100644
packet->giaddr = uplink->addresses[0];
log_debug ("Adding link selection suboption"
" with addr: %s", inet_ntoa(giaddr));
@@ -2398,6 +2457,7 @@ void request_v4_interface(const char* name, int flags) {
@@ -2451,6 +2510,7 @@ void request_v4_interface(const char* name, int flags) {
struct interface_info *tmp = NULL;
int len = strlen(name);
isc_result_t status;
@ -234,7 +232,7 @@ index e158efe..055d97f 100644
if (len >= sizeof(tmp->name)) {
log_fatal("%s: interface name too long (is %d)", name, len);
@@ -2413,6 +2473,15 @@ void request_v4_interface(const char* name, int flags) {
@@ -2466,6 +2526,15 @@ void request_v4_interface(const char* name, int flags) {
(flags & INTERFACE_UPSTREAM ? 'Y' : 'N'),
(flags & INTERFACE_DOWNSTREAM ? 'Y' : 'N'));
@ -247,10 +245,10 @@ index e158efe..055d97f 100644
+ ci->interface = tmp;
+ }
+
strncpy(tmp->name, name, len);
memcpy(tmp->name, name, len);
interface_snorf(tmp, (INTERFACE_REQUESTED | flags));
interface_dereference(&tmp, MDL);
@@ -2487,3 +2556,13 @@ free_interface_alias_map(void) {
@@ -2540,3 +2609,13 @@ free_interface_alias_map(void) {
free(g_interface_name_alias_map);
g_interface_name_alias_map_size = 0;
}
@ -265,5 +263,5 @@ index e158efe..055d97f 100644
+ }
+}
--
2.17.1
2.25.1

View File

@ -4,13 +4,13 @@ Date: Fri, 12 Mar 2021 23:30:56 -0800
Subject: [PATCH] add option -si to support using src intf ip in relay
---
common/socket.c | 119 ++++++++++++++++++++++++++++++++++++-----------
common/socket.c | 120 +++++++++++++++++++++++++++++++++++------------
includes/dhcpd.h | 1 +
relay/dhcrelay.c | 8 ++++
3 files changed, 100 insertions(+), 28 deletions(-)
relay/dhcrelay.c | 2 +
3 files changed, 94 insertions(+), 29 deletions(-)
diff --git a/common/socket.c b/common/socket.c
index 483eb9c..da9f501 100644
index 3953eac..eae86e8 100644
--- a/common/socket.c
+++ b/common/socket.c
@@ -83,6 +83,29 @@ static unsigned int global_v4_socket_references = 0;
@ -43,7 +43,7 @@ index 483eb9c..da9f501 100644
/*
* If we can't bind() to a specific interface, then we can only have
* a single socket. This variable insures that we don't try to listen
@@ -712,37 +735,77 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
@@ -722,38 +745,77 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
struct hardware *hto;
{
int result;
@ -59,8 +59,9 @@ index 483eb9c..da9f501 100644
- pktinfo.ipi_ifindex = interface->ifp->ifr_index;
- if (setsockopt(interface->wfdesc, IPPROTO_IP,
- IP_PKTINFO, (char *)&pktinfo,
- sizeof(pktinfo)) < 0)
- log_fatal("setsockopt: IP_PKTINFO: %m");
- sizeof(pktinfo)) < 0)
- log_fatal("setsockopt: IP_PKTINFO for %s: %m",
- (char*)(interface->ifp));
+ struct msghdr m;
+ struct iovec v;
+ struct sockaddr_in dst;
@ -150,10 +151,10 @@ index 483eb9c..da9f501 100644
}
diff --git a/includes/dhcpd.h b/includes/dhcpd.h
index 36cd518..0c25582 100644
index b54a36e..68d44cf 100644
--- a/includes/dhcpd.h
+++ b/includes/dhcpd.h
@@ -2660,6 +2660,7 @@ ssize_t send_fallback6(struct interface_info *, struct packet *,
@@ -2676,6 +2676,7 @@ ssize_t send_fallback6(struct interface_info *, struct packet *,
#endif
#ifdef USE_SOCKET_SEND
@ -162,10 +163,10 @@ index 36cd518..0c25582 100644
void if_register_send (struct interface_info *);
void if_deregister_send (struct interface_info *);
diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c
index 221106a..c44a79d 100644
index ccf7417..6aa1179 100644
--- a/relay/dhcrelay.c
+++ b/relay/dhcrelay.c
@@ -431,6 +431,8 @@ main(int argc, char **argv) {
@@ -440,6 +440,8 @@ main(int argc, char **argv) {
#endif
} else if (!strcmp(argv[i], "-d")) {
/* no_daemon = 1; */
@ -175,5 +176,5 @@ index 221106a..c44a79d 100644
quiet = 1;
quiet_interface_discovery = 1;
--
2.17.1
2.25.1

View File

@ -1,53 +0,0 @@
From 0a2f9a62bceb90b0d30461add2e25c4ce7a24547 Mon Sep 17 00:00:00 2001
From: Thomas Markwalder <tmark@isc.org>
Date: Fri, 20 Dec 2019 10:11:54 -0500
Subject: [PATCH] [#71] Fix dhcrelay agent option buffer pointer logic
relay/dhcrelay.c
strip_relay_agent_options()
strip_relay_agent_options()
- corrected buffer pointer logic
---
relay/dhcrelay.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c
index 896e1e2e..980dacae 100644
--- a/relay/dhcrelay.c
+++ b/relay/dhcrelay.c
@@ -1238,8 +1238,13 @@ strip_relay_agent_options(struct interface_info *in,
return (0);
if (sp != op) {
- memmove(sp, op, op[1] + 2);
- sp += op[1] + 2;
+ size_t mlen = op[1] + 2;
+ memmove(sp, op, mlen);
+ sp += mlen;
+ if (sp > max) {
+ return (0);
+ }
+
op = nextop;
} else
op = sp = nextop;
@@ -1620,8 +1620,13 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet,
end_pad = NULL;
if (sp != op) {
- memmove(sp, op, op[1] + 2);
- sp += op[1] + 2;
+ size_t mlen = op[1] + 2;
+ memmove(sp, op, mlen);
+ sp += mlen;
+ if (sp > max) {
+ return (0);
+ }
+
op = nextop;
} else
op = sp = nextop;
--
2.17.1

View File

@ -1,8 +1,8 @@
diff --git a/debian/rules b/debian/rules
index 3c8318f..28f4657 100755
index 0906e53..6e96ffe 100755
--- a/debian/rules
+++ b/debian/rules
@@ -37,6 +37,13 @@ export DO_LPF=1
@@ -38,6 +38,13 @@ export DO_LPF=1
CONFFLAGS+=--enable-use-sockets
endif
@ -16,27 +16,27 @@ index 3c8318f..28f4657 100755
%:
dh $@ --parallel --with autoreconf
@@ -46,17 +53,17 @@ override_dh_auto_build:
@@ -59,17 +66,17 @@ override_dh_auto_build:
# ldap-enabled build
test -f Makefile && $(MAKE) distclean || true
./configure --with-ldap --with-ldapcrypto CFLAGS="$(CFLAGS) -DNSUPDATE" LIBS="-lirs-export $(LIBS)" $(CONFFLAGS)
./configure --with-ldap --with-ldapcrypto CFLAGS="$(CFLAGS) -DNSUPDATE" $(CONFFLAGS) LIBS="$(LIBS) -latomic"
- $(MAKE)
+ $(MAKE) $(PARALLEL)
mv server/dhcpd dhcpd
# ddns-disabled build
test -f Makefile && $(MAKE) distclean || true
./configure CFLAGS="$(CFLAGS)" $(CONFFLAGS)
./configure CFLAGS="$(CFLAGS)" $(CONFFLAGS) LIBS="$(LIBS) -latomic"
- $(MAKE)
+ $(MAKE) $(PARALLEL)
mv client/dhclient dhclient
# ldap-disabled build
test -f Makefile && $(MAKE) distclean || true
./configure CFLAGS="$(CFLAGS) -DNSUPDATE" LIBS="-lirs-export $(LIBS)" $(CONFFLAGS)
./configure CFLAGS="$(CFLAGS) -DNSUPDATE" $(CONFFLAGS) LIBS="$(LIBS) -latomic"
- $(MAKE)
+ $(MAKE) $(PARALLEL)
override_dh_install:
# rename some upstream files
--
2.34.1
2.25.1

View File

@ -1,8 +1,8 @@
diff --git a/common/discover.c b/common/discover.c
index ab50234..40e13f5 100644
index 20d7c54..9ee8bc2 100644
--- a/common/discover.c
+++ b/common/discover.c
@@ -1614,3 +1614,16 @@ void interface_snorf (struct interface_info *tmp, int ir)
@@ -1619,3 +1619,16 @@ void interface_snorf (struct interface_info *tmp, int ir)
}
interface_reference (&interfaces, tmp, MDL);
}
@ -21,10 +21,10 @@ index ab50234..40e13f5 100644
+}
\ No newline at end of file
diff --git a/includes/dhcpd.h b/includes/dhcpd.h
index 257b31e..e7f9f06 100644
index 68d44cf..8c307b6 100644
--- a/includes/dhcpd.h
+++ b/includes/dhcpd.h
@@ -2873,6 +2873,7 @@ extern int interface_count;
@@ -2885,6 +2885,7 @@ extern int interface_count;
extern int interface_max;
isc_result_t interface_initialize(omapi_object_t *, const char *, int);
void discover_interfaces(int);
@ -33,7 +33,7 @@ index 257b31e..e7f9f06 100644
int if_readsocket (omapi_object_t *);
void reinitialize_interfaces (void);
diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c
index ff0ad17..31fe61b 100644
index 6aa1179..a1aa234 100644
--- a/relay/dhcrelay.c
+++ b/relay/dhcrelay.c
@@ -92,6 +92,11 @@ struct downstream_intf_list {
@ -48,23 +48,23 @@ index ff0ad17..31fe61b 100644
#ifdef DHCPv6
/* Force use of DHCPv6 interface-id option. */
isc_boolean_t use_if_id = ISC_FALSE;
@@ -199,6 +204,7 @@ char *progname;
@@ -208,6 +213,7 @@ char *progname;
" [-i interface0 [ ... -i interfaceN]\n" \
" [-iu interface0 [ ... -iu interfaceN]\n" \
" [-id interface0 [ ... -id interfaceN]\n" \
+" [-pg ip-address0 [ ... -pg ip-addressN]]\n" \
" [-U interface]\n" \
" [-U interface] [-g <ip-address>]\n" \
" [-dt]\n"\
" server0 [ ... serverN]\n\n" \
@@ -221,6 +227,7 @@ char *progname;
@@ -230,6 +236,7 @@ char *progname;
" [-i interface0 [ ... -i interfaceN]\n" \
" [-iu interface0 [ ... -iu interfaceN]\n" \
" [-id interface0 [ ... -id interfaceN]\n" \
+" [-pg ip-address0 [ ... -pg ip-addressN]]\n" \
" [-U interface]\n" \
" [-U interface] [-g <ip-address>]\n" \
" [-dt]\n"\
" server0 [ ... serverN]\n\n" \
@@ -649,6 +656,34 @@ main(int argc, char **argv) {
@@ -673,6 +680,34 @@ main(int argc, char **argv) {
usage(use_noarg, argv[i-1]);
path_dhcrelay_pid = argv[i];
no_dhcrelay_pid = ISC_TRUE;
@ -99,7 +99,7 @@ index ff0ad17..31fe61b 100644
} else if (!strcmp(argv[i], "--no-pid")) {
no_pid_file = ISC_TRUE;
} else if (!strcmp(argv[i], "--name-alias-map-file")) {
@@ -818,6 +853,12 @@ main(int argc, char **argv) {
@@ -842,6 +877,12 @@ main(int argc, char **argv) {
/* Discover all the network interfaces. */
discover_interfaces(DISCOVER_RELAY);
@ -112,3 +112,6 @@ index ff0ad17..31fe61b 100644
#ifdef DHCPv6
if (local_family == AF_INET6)
setup_streams();
--
2.25.1

View File

@ -11,7 +11,6 @@
0010-Bugfix-correctly-set-interface-netmask.patch
0011-dhcp-relay-Prevent-Buffer-Overrun.patch
0012-add-option-si-to-support-using-src-intf-ip-in-relay.patch
0013-Fix-dhcrelay-agent-option-buffer-pointer-logic.patch
0014-enable-parallel-build.patch
0015-option-to-set-primary-address-in-interface.patch
0016-Don-t-look-up-the-ifindex-for-fallback.patch

@ -1 +1 @@
Subproject commit fbb5fcdb9c8fc142b2840f99c6aa25894c369185
Subproject commit 4f329233be35d223f01f85b02f8124ad096926ed

@ -1 +1 @@
Subproject commit 56921d80e42971f2579115f26c5194b9e0ecbc05
Subproject commit 2606cd5fb0a58fc956577602235a9f8f84a887c6

@ -1 +1 @@
Subproject commit 04b0f88d06537f934ca1ebb853ba00609650274b
Subproject commit 2770fd2c7909ae031d72066530559f4b2e3ea23c

View File

@ -378,10 +378,17 @@ class SonicYangExtMixin:
#choices, this is tricky, since leafs are under cases in tree.
choices = model.get('choice')
if choices:
for choice in choices:
cases = choice['case']
# If single choice exists in container/list
if isinstance(choices, dict):
cases = choices['case']
for case in cases:
self._fillLeafDict(case.get('leaf'), leafDict)
# If multiple choices exist in container/list
else:
for choice in choices:
cases = choice['case']
for case in cases:
self._fillLeafDict(case.get('leaf'), leafDict)
# leaf-lists
self._fillLeafDict(model.get('leaf-list'), leafDict, True)
@ -535,6 +542,29 @@ class SonicYangExtMixin:
continue
return
"""
Process container inside a List.
This function will call xlateContainer based on Container(s) present
in outer List.
"""
def _xlateContainerInList(self, model, yang, configC, table):
ccontainer = model
ccName = ccontainer.get('@name')
if ccName not in configC:
# Inner container doesn't exist in config
return
if bool(configC[ccName]):
# Empty container - return
return
self.sysLog(msg="xlateProcessListOfContainer: {}".format(ccName))
self.elementPath.append(ccName)
self._xlateContainer(ccontainer, yang, configC[ccName], table)
self.elementPath.pop()
return
"""
Xlate a list
This function will xlate from a dict in config DB to a Yang JSON list
@ -553,6 +583,9 @@ class SonicYangExtMixin:
self._xlateType1MapList(model, yang, config, table, exceptionList)
return
# For handling of container(s) in list
ccontainer = model.get('container')
#create a dict to map each key under primary key with a dict yang model.
#This is done to improve performance of mapping from values of TABLEs in
#config DB to leaf in YANG LIST.
@ -572,6 +605,19 @@ class SonicYangExtMixin:
keyDict = self._extractKey(pkey, listKeys)
# fill rest of the values in keyDict
for vKey in config[pkey]:
if ccontainer and vKey == ccontainer.get('@name'):
self.sysLog(syslog.LOG_DEBUG, "xlateList Handle container {} in list {}".\
format(vKey, table))
yangContainer = dict()
if isinstance(ccontainer, dict) and bool(config):
self._xlateContainerInList(ccontainer, yangContainer, config[pkey], table)
# If multi-list exists in container,
elif ccontainer and isinstance(ccontainer, list) and bool(config):
for modelContainer in ccontainer:
self._xlateContainerInList(modelContainer, yangContainer, config[pkey], table)
if len(yangContainer):
keyDict[vKey] = yangContainer
continue
self.elementPath.append(vKey)
self.sysLog(syslog.LOG_DEBUG, "xlateList vkey {}".format(vKey))
try:
@ -617,7 +663,7 @@ class SonicYangExtMixin:
"""
def _xlateContainerInContainer(self, model, yang, configC, table):
ccontainer = model
ccName = ccontainer['@name']
ccName = ccontainer.get('@name')
yang[ccName] = dict()
if ccName not in configC:
# Inner container doesn't exist in config
@ -876,6 +922,9 @@ class SonicYangExtMixin:
self._revXlateType1MapList(model, yang, config, table)
return
# For handling of container(s) in list
ccontainer = model.get('container')
# get keys from YANG model list itself
listKeys = model['key']['@value']
# create a dict to map each key under primary key with a dict yang model.
@ -894,6 +943,17 @@ class SonicYangExtMixin:
# fill rest of the entries
for key in entry:
if key not in pkeydict:
if ccontainer and key == ccontainer['@name']:
self.sysLog(syslog.LOG_DEBUG, "revXlateList handle container {} in list {}".format(pkey, table))
# IF container has only one inner container
if isinstance(ccontainer, dict):
self._revXlateContainerInContainer(ccontainer, entry, config[pkey], table)
# IF container has many inner container
elif isinstance(ccontainer, list):
for modelContainer in ccontainer:
self._revXlateContainerInContainer(modelContainer, entry, config[pkey], table)
continue
self.elementPath.append(key)
config[pkey][key] = self._revFindYangTypedValue(key, \
entry[key], leafDict)

View File

@ -256,5 +256,39 @@
}
]
}
},
"test-yang-structure:test-yang-container": {
"test-yang-structure:YANG_STRUCT_TEST": {
"YANG_LIST_TEST_LIST": [{
"name" : "Vlan1001",
"leaf-list-test": [
"fc02:2000::1",
"fc02:2000::2"
],
"container-in-list-test": {
"leaf-1": true,
"leaf-2": "test1",
"mc-case-leaf-1": 55,
"mc-case-leaf-3": 1234
},
"case-leaf-1": 101
},
{
"name" : "Test123",
"leaf-list-test": [
"3003:2000::1",
"2002:2001::2"
],
"container-in-list-test": {
"leaf-1": false,
"leaf-2": "test2",
"mc-case-leaf-2": 77,
"mc-case-leaf-3": 4321
},
"case-leaf-2": 1001
}
]
}
}
}

View File

@ -0,0 +1,105 @@
module test-yang-structure {
namespace "http://github.com/sonic-net/test";
prefix yangstructtest;
yang-version 1.1;
import ietf-yang-types {
prefix yang;
}
import ietf-inet-types {
prefix inet;
}
import test-head {
prefix head;
revision-date 2019-07-01;
}
revision 2021-10-30 {
description "First Revision";
}
container test-yang-container {
container YANG_STRUCT_TEST {
description "sample test container";
list YANG_LIST_TEST_LIST {
key "name";
leaf name {
type string;
}
leaf-list leaf-list-test {
description "Test leaf-list statement";
type inet:ipv6-address;
}
container container-in-list-test {
leaf leaf-1 {
description "test leaf in container";
type string {
pattern "false|true";
}
}
leaf leaf-2 {
description "test leaf in container";
type string;
}
choice multi-choice-in-container-test-1 {
case mc-case-test-1 {
leaf mc-case-leaf-1 {
description "test leaf in multi choice";
type uint32;
}
}
case mc-case-test-2 {
leaf mc-case-leaf-2 {
description "test leaf in multi choice";
type uint8;
}
}
}
choice multi-choice-in-container-test-2 {
case mc-case-test-3 {
leaf mc-case-leaf-3 {
description "test leaf in multi choice";
type uint16;
}
}
}
}
choice single-choice-in-list-test {
case case-test-1 {
leaf case-leaf-1 {
description "test leaf in single choice";
type uint32;
}
}
case case-test-2 {
leaf case-leaf-2 {
description "test leaf in single choice";
type uint16;
}
}
}
}
/* end of YANG_LIST_TEST_LIST */
}
/* end of container YANG_STRUCT_TEST */
}
/* end of container test-yang-container */
}
/* end of module test-yang-structure */

View File

@ -168,6 +168,10 @@
{
"file" : "test-vlan.yang",
"module" : "test-vlan"
},
{
"file" : "test-yang-structure.yang",
"module" : "test-yang-structure"
}
],
"new_nodes" : [
@ -244,6 +248,10 @@
{
"module_name" : "test-vlan",
"module_prefix" : "vlan"
},
{
"module_name" : "test-yang-structure",
"module_prefix" : "yangstructtest"
}
],
"schema_dependencies" : [

View File

@ -30,6 +30,18 @@
"replay_window": 64,
"send_sci": "true",
"rekey_period": 3600
},
{
"name": "test_nofallback",
"priority": 64,
"cipher_suite": "GCM-AES-XPN-256",
"primary_cak": "5207554155500e5d5157786d6c2a3d2031425a5e577e7e727f6b6c03312432262706080a00005b554f4e007975707670725b0a54540c0252445e5d7a29252b046a",
"primary_ckn": "6162636465666768696A6B6C6D6E6F706162636465666768696A6B6C6D6E6F70",
"policy": "security",
"enable_replay_protect": "true",
"replay_window": 64,
"send_sci": "true",
"rekey_period": 3600
}
]
}

View File

@ -70,9 +70,9 @@ module sonic-macsec {
}
}
must "string-length(fallback_cak) = string-length(primary_cak)";
must "string-length(fallback_cak) = 0 or string-length(fallback_cak) = string-length(primary_cak)";
must "primary_ckn != fallback_ckn";
must "string-length(fallback_ckn) = 0 or primary_ckn != fallback_ckn";
leaf policy {
type string {

View File

@ -70,12 +70,12 @@ index 0000000..e23acec
+#include "trace.h"
+
+/* Accounting log format. */
+#define ACCOUNTING_LOG_FORMAT "Accounting: user: %s, tty: %s, host: %s, command: %s, type: %d, task ID: %d"
+#define ACCOUNTING_LOG_FORMAT "Audisp-tacplus: Accounting: user: %s, tty: %s, host: %s, command: %s, type: %d, task ID: %d"
+
+/* Write the accounting information to syslog. */
+void accounting_to_syslog(char *user, char *tty, char *host, char *cmdmsg, int type, uint16_t task_id)
+{
+ trace(ACCOUNTING_LOG_FORMAT, user, tty, host, cmdmsg, type, task_id);
+ syslog(LOG_INFO, ACCOUNTING_LOG_FORMAT, user, tty, host, cmdmsg, type, task_id);
+}
\ No newline at end of file
diff --git a/local_accounting.h b/local_accounting.h