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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile.work
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ SONIC_BUILD_INSTRUCTION := make \
HTTP_PROXY=$(http_proxy) \
HTTPS_PROXY=$(https_proxy) \
SONIC_INCLUDE_SYSTEM_TELEMETRY=$(INCLUDE_SYSTEM_TELEMETRY) \
INCLUDE_DHCP_RELAY=$(INCLUDE_DHCP_RELAY) \
SONIC_INCLUDE_RESTAPI=$(INCLUDE_RESTAPI) \
TELEMETRY_WRITABLE=$(TELEMETRY_WRITABLE) \
EXTRA_DOCKER_TARGETS=$(EXTRA_DOCKER_TARGETS) \
Expand Down
1 change: 1 addition & 0 deletions dockers/docker-dhcp-relay/Dockerfile.j2
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ COPY ["docker_init.sh", "start.sh", "/usr/bin/"]
COPY ["docker-dhcp-relay.supervisord.conf.j2", "port-name-alias-map.txt.j2", "wait_for_intf.sh.j2", "/usr/share/sonic/templates/"]
COPY ["files/supervisor-proc-exit-listener", "/usr/bin"]
COPY ["critical_processes", "/etc/supervisor"]
COPY ["cli", "/cli/"]

LABEL com.azure.sonic.manifest="$manifest"

Expand Down
84 changes: 84 additions & 0 deletions dockers/docker-dhcp-relay/cli/config/plugins/dhcp_relay.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import click
import utilities_common.cli as clicommon

@click.group(cls=clicommon.AbbreviationGroup, name='dhcp_relay')
def vlan_dhcp_relay():
pass

@vlan_dhcp_relay.command('add')
@click.argument('vid', metavar='<vid>', required=True, type=int)
@click.argument('dhcp_relay_destination_ip', metavar='<dhcp_relay_destination_ip>', required=True)
@clicommon.pass_db
def add_vlan_dhcp_relay_destination(db, vid, dhcp_relay_destination_ip):
""" Add a destination IP address to the VLAN's DHCP relay """

ctx = click.get_current_context()

if not clicommon.is_ipaddress(dhcp_relay_destination_ip):
ctx.fail('{} is invalid IP address'.format(dhcp_relay_destination_ip))

vlan_name = 'Vlan{}'.format(vid)
vlan = db.cfgdb.get_entry('VLAN', vlan_name)
if len(vlan) == 0:
ctx.fail("{} doesn't exist".format(vlan_name))

dhcp_relay_dests = vlan.get('dhcp_servers', [])
if dhcp_relay_destination_ip in dhcp_relay_dests:
click.echo("{} is already a DHCP relay destination for {}".format(dhcp_relay_destination_ip, vlan_name))
return

dhcp_relay_dests.append(dhcp_relay_destination_ip)
vlan['dhcp_servers'] = dhcp_relay_dests
db.cfgdb.set_entry('VLAN', vlan_name, vlan)
click.echo("Added DHCP relay destination address {} to {}".format(dhcp_relay_destination_ip, vlan_name))
try:
click.echo("Restarting DHCP relay service...")
clicommon.run_command("systemctl stop dhcp_relay", display_cmd=False)
clicommon.run_command("systemctl reset-failed dhcp_relay", display_cmd=False)
clicommon.run_command("systemctl start dhcp_relay", display_cmd=False)
except SystemExit as e:
ctx.fail("Restart service dhcp_relay failed with error {}".format(e))

@vlan_dhcp_relay.command('del')
@click.argument('vid', metavar='<vid>', required=True, type=int)
@click.argument('dhcp_relay_destination_ip', metavar='<dhcp_relay_destination_ip>', required=True)
@clicommon.pass_db
def del_vlan_dhcp_relay_destination(db, vid, dhcp_relay_destination_ip):
""" Remove a destination IP address from the VLAN's DHCP relay """

ctx = click.get_current_context()

if not clicommon.is_ipaddress(dhcp_relay_destination_ip):
ctx.fail('{} is invalid IP address'.format(dhcp_relay_destination_ip))

vlan_name = 'Vlan{}'.format(vid)
vlan = db.cfgdb.get_entry('VLAN', vlan_name)
if len(vlan) == 0:
ctx.fail("{} doesn't exist".format(vlan_name))

dhcp_relay_dests = vlan.get('dhcp_servers', [])
if not dhcp_relay_destination_ip in dhcp_relay_dests:
ctx.fail("{} is not a DHCP relay destination for {}".format(dhcp_relay_destination_ip, vlan_name))

dhcp_relay_dests.remove(dhcp_relay_destination_ip)
if len(dhcp_relay_dests) == 0:
del vlan['dhcp_servers']
else:
vlan['dhcp_servers'] = dhcp_relay_dests
db.cfgdb.set_entry('VLAN', vlan_name, vlan)
click.echo("Removed DHCP relay destination address {} from {}".format(dhcp_relay_destination_ip, vlan_name))
try:
click.echo("Restarting DHCP relay service...")
clicommon.run_command("systemctl stop dhcp_relay", display_cmd=False)
clicommon.run_command("systemctl reset-failed dhcp_relay", display_cmd=False)
clicommon.run_command("systemctl start dhcp_relay", display_cmd=False)
except SystemExit as e:
ctx.fail("Restart service dhcp_relay failed with error {}".format(e))


def register(cli):
cli.commands['vlan'].add_command(vlan_dhcp_relay)


if __name__ == '__main__':
vlan_dhcp_relay()
22 changes: 22 additions & 0 deletions dockers/docker-dhcp-relay/cli/show/plugins/dhcp_relay.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from natsort import natsorted
from .. import vlan


def get_dhcp_helper_address(ctx, vlan):
cfg, _ = ctx
vlan_dhcp_helper_data, _, _ = cfg
vlan_config = vlan_dhcp_helper_data.get(vlan)
if not vlan_config:
return ""

dhcp_helpers = vlan_config.get('dhcp_servers', [])

return '\n'.join(natsorted(dhcp_helpers))


vlan.VlanBrief.COLUMNS.append(('DHCP Helper Address', get_dhcp_helper_address))


def register(cli):
pass

27 changes: 27 additions & 0 deletions dockers/docker-dhcp-relay/manifest.json.j2
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,34 @@
},
"service": {
"name": "{{ name }}",
"requires": [
"updategraph"
],
"after": [
"swss",
"syncd",
"teamd"
],
"before": [
"ntp-config"
],
"dependent-of": ["swss"],
"asic-service": false,
"host-service": true
},
"container": {
"privileged": true,
"volumes": [
"/etc/sonic:/etc/sonic:ro",
"/usr/share/sonic/scripts:/usr/share/sonic/scripts:ro"
],
"tmpfs": [
"/tmp/",
"/var/tmp/"
]
},
"cli": {
"config": "/cli/config/plugins/dhcp_relay.py",
"show": "/cli/show/plugins/dhcp_relay.py"
}
}
3 changes: 1 addition & 2 deletions files/build_templates/init_cfg.json.j2
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
},
{%- set features = [("bgp", "enabled", false, "enabled"),
("database", "always_enabled", false, "always_enabled"),
("dhcp_relay", "enabled", false, "enabled"),
("lldp", "enabled", false, "enabled"),
("pmon", "enabled", false, "enabled"),
("radv", "enabled", false, "enabled"),
Expand All @@ -45,7 +44,7 @@
"has_per_asic_scope": {% if feature + '@.service' in installer_services.split(' ') %}true{% else %}false{% endif %},
"auto_restart": "{{autorestart}}",
{%- if include_kubernetes == "y" %}
{%- if feature in ["dhcp_relay", "lldp", "pmon", "radv", "snmp", "telemetry"] %}
{%- if feature in ["lldp", "pmon", "radv", "snmp", "telemetry"] %}
"set_owner": "kube", {% else %}
"set_owner": "local", {% endif %} {% endif %}
"high_mem_alert": "disabled"
Expand Down
26 changes: 24 additions & 2 deletions files/build_templates/sonic_debian_extension.j2
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install watchd

{% if include_kubernetes == "y" %}
# Install remote Container mgmt package
# Required even if include_kubernetes != y, as it contains the
# Required even if include_kubernetes != y, as it contains the
# the container wrapper for docker start/stop/wait commands.
#
SONIC_CTRMGMT_WHEEL_NAME=$(basename {{sonic_ctrmgmt_py3_wheel_path}})
Expand All @@ -417,7 +417,7 @@ sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable ctrmgrd.service
# kubelet service is controlled by ctrmgrd daemon.
sudo LANG=C chroot $FILESYSTEM_ROOT systemctl disable kubelet.service
{% else %}
# container script for docker commands, which is required as
# container script for docker commands, which is required as
# all docker commands are replaced with container commands.
# So just copy that file only.
#
Expand Down Expand Up @@ -605,6 +605,28 @@ sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT docker pull k8s.gcr
echo "docker images pull complete"
{% endif %}

{% macro get_install_options(default_owner, enabled) -%}
{% set args = ["-y", "-v", "DEBUG"] -%}
{% if default_owner -%}
{% set args = args + ["--default-owner", default_owner] -%}
{% endif -%}
{% if enabled == "y" -%}
{% set args = args + ["--enable"] -%}
{% endif -%}
{{ args | join(' ') }}
{% endmacro -%}

{% for package in sonic_packages.strip().split() -%}
{% set name, repo, version, default_owner, enabled = package.split('|') -%}
sudo LANG=C chroot $FILESYSTEM_ROOT sonic-package-manager repository add {{ name }} {{ repo }}
sudo LANG=C chroot $FILESYSTEM_ROOT sonic-package-manager install {{ name }}=={{ version }} {{ get_install_options(default_owner, enabled) }}
{% endfor -%}

{% for package in sonic_local_packages.strip().split() -%}
{% set name, path, default_owner, enabled = package.split('|') -%}
sudo LANG=C chroot $FILESYSTEM_ROOT sonic-package-manager install {{ path }} {{ get_install_options(default_owner, enabled) }}
{% endfor -%}

sudo umount $FILESYSTEM_ROOT/target
sudo rm -r $FILESYSTEM_ROOT/target
if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then
Expand Down
11 changes: 10 additions & 1 deletion files/scripts/swss.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
#!/bin/bash

DEPENDENT="radv dhcp_relay"
DEPENDENT="radv"
MULTI_INST_DEPENDENT="teamd"

# Update dependent list based on other packages requirements
if [[ -f /etc/sonic/${SERVICE}_dependent ]]; then
DEPENDENT="${DEPENDENT} $(cat /etc/sonic/${SERVICE}_dependent)"
fi

if [[ -f /etc/sonic/${SERVICE}_multi_inst_dependent ]]; then
MULTI_INST_DEPENDENT="${MULTI_INST_DEPENDENT} cat /etc/sonic/${SERVICE}_multi_inst_dependent"
fi

function debug()
{
/usr/bin/logger $1
Expand Down
3 changes: 3 additions & 0 deletions rules/config
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ INCLUDE_RESTAPI = n
# INCLUDE_NAT - build docker-nat for nat support
INCLUDE_NAT = y

# INCLUDE_DHCP_RELAY - build and install dhcp-relay package
INCLUDE_DHCP_RELAY = y

# TELEMETRY_WRITABLE - Enable write/config operations via the gNMI interface.
# Uncomment to enable:
# TELEMETRY_WRITABLE = y
Expand Down
18 changes: 12 additions & 6 deletions rules/docker-dhcp-relay.mk
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,19 @@ $(DOCKER_DHCP_RELAY)_VERSION = 1.0.0
$(DOCKER_DHCP_RELAY)_PACKAGE_NAME = dhcp-relay

SONIC_DOCKER_IMAGES += $(DOCKER_DHCP_RELAY)
SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_DHCP_RELAY)

SONIC_DOCKER_DBG_IMAGES += $(DOCKER_DHCP_RELAY_DBG)
SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_DHCP_RELAY_DBG)

ifeq ($(INCLUDE_KUBERNETES),y)
$(DOCKER_DHCP_RELAY)_DEFAULT_FEATURE_OWNER = kube
endif

$(DOCKER_DHCP_RELAY)_DEFAULT_FEATURE_STATE_ENABLED = y

ifeq ($(INSTALL_DEBUG_TOOLS),y)
SONIC_PACKAGES_LOCAL += $(DOCKER_DHCP_RELAY_DBG)
else
SONIC_PACKAGES_LOCAL += $(DOCKER_DHCP_RELAY)
endif

$(DOCKER_DHCP_RELAY)_CONTAINER_NAME = dhcp_relay
$(DOCKER_DHCP_RELAY)_RUN_OPT += --privileged -t
$(DOCKER_DHCP_RELAY)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro
$(DOCKER_DHCP_RELAY)_RUN_OPT += -v /usr/share/sonic/scripts:/usr/share/sonic/scripts:ro
$(DOCKER_DHCP_RELAY)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT)
9 changes: 9 additions & 0 deletions rules/sonic-packages.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# rules to define remote packages that need to be installed
# during SONiC image build

## Example:
## PACKAGE = my-package
## $(PACKAGE)_REPOSITORY = myrepo/mypackage
## $(PACKAGE)_VERSION = 1.0.0
## SONIC_PACKAGES += $(PACKAGE)

15 changes: 13 additions & 2 deletions slave.mk
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ $(info "INCLUDE_HOST_SERVICE" : "$(INCLUDE_HOST_SERVICE)")
$(info "INCLUDE_RESTAPI" : "$(INCLUDE_RESTAPI)")
$(info "INCLUDE_SFLOW" : "$(INCLUDE_SFLOW)")
$(info "INCLUDE_NAT" : "$(INCLUDE_NAT)")
$(info "INCLUDE_DHCP_RELAY" : "$(INCLUDE_DHCP_RELAY)")
$(info "INCLUDE_KUBERNETES" : "$(INCLUDE_KUBERNETES)")
$(info "TELEMETRY_WRITABLE" : "$(TELEMETRY_WRITABLE)")
$(info "PDDF_SUPPORT" : "$(PDDF_SUPPORT)")
Expand Down Expand Up @@ -862,6 +863,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \
$(SONIC_UTILITIES_DATA) \
$(SONIC_HOST_SERVICES_DATA)) \
$$(addprefix $(TARGET_PATH)/,$$($$*_DOCKERS)) \
$$(addprefix $(TARGET_PATH)/,$$(SONIC_PACKAGES_LOCAL)) \
$$(addprefix $(FILES_PATH)/,$$($$*_FILES)) \
$(if $(findstring y,$(ENABLE_ZTP)),$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(SONIC_ZTP))) \
$(if $(findstring y,$(INCLUDE_HOST_SERVICE)),$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(SONIC_HOST_SERVICE))) \
Expand Down Expand Up @@ -913,8 +915,17 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \
export lazy_installer_debs="$(foreach deb, $($*_LAZY_INSTALLS),$(foreach device, $($(deb)_PLATFORM),$(addprefix $(device)@, $(IMAGE_DISTRO_DEBS_PATH)/$(deb))))"
export installer_images="$(foreach docker, $($*_DOCKERS),\
$(addprefix $($(docker)_PACKAGE_NAME)|,\
$(addprefix $($(docker)_PATH)|,\
$(addprefix $(TARGET_PATH)/,$(addsuffix :$($(docker)_VERSION),$(docker))))))"
$(addprefix $($(docker)_PATH)|,\
$(addprefix $(TARGET_PATH)/,$(addsuffix :$($(docker)_VERSION),$(docker))))))"
export sonic_packages="$(foreach package, $(SONIC_PACKAGES),\
$(addsuffix |$($(package)_DEFAULT_FEATURE_STATE_ENABLED),\
$(addsuffix |$($(package)_DEFAULT_FEATURE_OWNER),\
$(addsuffix |$($(package)_VERSION),\
$(addsuffix |$($(package)_REPOSITORY), $(package))))))"
export sonic_local_packages="$(foreach package, $(SONIC_PACKAGES_LOCAL),\
$(addsuffix |$($(package)_DEFAULT_FEATURE_STATE_ENABLED),\
$(addsuffix |$($(package)_DEFAULT_FEATURE_OWNER),\
$(addsuffix |$(addprefix $(TARGET_PATH)/, $(package)), $(package)))))"
export sonic_py_common_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PY_COMMON_PY2))"
export sonic_py_common_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PY_COMMON_PY3))"
export config_engine_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CONFIG_ENGINE_PY2))"
Expand Down