Merge branch 'sonic-net:master' into align-5600-buffer-templates
This commit is contained in:
commit
6dd3cfcc36
@ -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
|
||||
|
800
platform/mellanox/mlnx-platform-api/tests/test_modules_mgmt.py
Normal file
800
platform/mellanox/mlnx-platform-api/tests/test_modules_mgmt.py
Normal 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
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 */
|
@ -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" : [
|
||||
|
@ -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
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user