Skip to content

Commit

Permalink
Replace isc-dhcp with DHCPv6 Relay in dhcp_relay docker (#8884)
Browse files Browse the repository at this point in the history
  • Loading branch information
kellyyeh authored Oct 2, 2021
1 parent ea064e2 commit a4b6788
Show file tree
Hide file tree
Showing 21 changed files with 1,471 additions and 32 deletions.
2 changes: 1 addition & 1 deletion dockers/docker-dhcp-relay/critical_processes
Original file line number Diff line number Diff line change
@@ -1 +1 @@
group:isc-dhcp-relay
group:dhcp-relay
4 changes: 2 additions & 2 deletions dockers/docker-dhcp-relay/dhcp-relay.programs.j2
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[group:isc-dhcp-relay]
[group:dhcp-relay]
programs=
{%- set add_preceding_comma = { 'flag': False } %}
{% for vlan_name in VLAN_INTERFACE %}
Expand All @@ -12,6 +12,6 @@ isc-dhcpv4-relay-{{ vlan_name }}
{% if VLAN and vlan_name in VLAN and 'dhcpv6_servers' in VLAN[vlan_name] and VLAN[vlan_name]['dhcpv6_servers']|length > 0 %}
{% if add_preceding_comma.flag %},{% endif %}
{% set _dummy = add_preceding_comma.update({'flag': True}) %}
isc-dhcpv6-relay-{{ vlan_name }}
dhcp6relay
{%- endif %}
{% endfor %}
19 changes: 2 additions & 17 deletions dockers/docker-dhcp-relay/dhcpv6-relay.agents.j2
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,8 @@
{% endfor %}
{% if relay_for_ipv6.flag %}
{% set _dummy = relay_for_ipv6.update({'flag': False}) %}
[program:isc-dhcpv6-relay-{{ vlan_name }}]
{# We treat this VLAN as a downstream interface (-l), as we only want to listen for requests #}
command=/usr/sbin/dhcrelay -d -6 --name-alias-map-file /tmp/port-name-alias-map.txt -l {{ vlan_name }}
{#- We treat all other interfaces as upstream interfaces (-u), as we only want to listen for replies #}
{%- for dhcpv6_server in VLAN[vlan_name]['dhcpv6_servers'] %}
{%- if dhcpv6_server | ipv6 %}
{%- for (name, prefix) in VLAN_INTERFACE|pfx_filter %}
{%- if prefix | ipv6 and name != vlan_name %} -u {{ dhcpv6_server }}%%{{ name }} {% endif -%}
{% endfor %}
{% for (name, prefix) in INTERFACE|pfx_filter %}
{% if prefix | ipv6 %} -u {{ dhcpv6_server }}%%{{ name }} {% endif -%}
{% endfor %}
{% for (name, prefix) in PORTCHANNEL_INTERFACE|pfx_filter %}
{% if prefix | ipv6 %} -u {{ dhcpv6_server }}%%{{ name }} {% endif -%}
{% endfor %}
{% endif -%}
{% endfor %}
[program:dhcp6relay]
command=/usr/sbin/dhcp6relay

priority=3
autostart=false
Expand Down
2 changes: 1 addition & 1 deletion dockers/docker-dhcp-relay/dhcpv6-relay.monitors.j2
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ stderr_logfile=syslog
dependent_startup=true
dependent_startup_wait_for=
{%- if relay_for_ipv4.flag %}isc-dhcpv4-relay-{{ vlan_name }}:running {% endif %}
{% if relay_for_ipv6.flag %}isc-dhcpv6-relay-{{ vlan_name }}:running{% endif %}
{% if relay_for_ipv6.flag %}dhcp6relay:running{% endif %}


{% set _dummy = relay_for_ipv4.update({'flag': False}) %}
Expand Down
9 changes: 9 additions & 0 deletions rules/dhcp6relay.dep
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

SPATH := $($(SONIC_DHCP6RELAY)_SRC_PATH)
DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/dhcp6relay.mk rules/dhcp6relay.dep
DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST)
DEP_FILES += $(shell git ls-files $(SPATH))

$(SONIC_DHCP6RELAY)_CACHE_MODE := GIT_CONTENT_SHA
$(SONIC_DHCP6RELAY)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST)
$(SONIC_DHCP6RELAY)_DEP_FILES := $(DEP_FILES)
10 changes: 10 additions & 0 deletions rules/dhcp6relay.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# SONiC DHCPV6 RELAY Package

SONIC_DHCP6RELAY_VERSION = 1.0.0-0
SONIC_DHCP6RELAY_PKG_NAME = dhcp6relay

SONIC_DHCP6RELAY = sonic-$(SONIC_DHCP6RELAY_PKG_NAME)_$(SONIC_DHCP6RELAY_VERSION)_$(CONFIGURED_ARCH).deb
$(SONIC_DHCP6RELAY)_DEPENDS = $(LIBSWSSCOMMON) $(LIBHIREDIS) $(LIBSWSSCOMMON_DEV) $(LIBHIREDIS_DEV)
$(DOCKER_DHCP_RELAY)_INSTALL_DEBS = $(LIBSWSSCOMMON) $(LIBHIREDIS) $(LIBSWSSCOMMON_DEV) $(LIBHIREDIS_DEV)
$(SONIC_DHCP6RELAY)_SRC_PATH = $(SRC_PATH)/$(SONIC_DHCP6RELAY_PKG_NAME)
SONIC_DPKG_DEBS += $(SONIC_DHCP6RELAY)
2 changes: 1 addition & 1 deletion rules/docker-dhcp-relay.mk
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ DOCKER_DHCP_RELAY_DBG = $(DOCKER_DHCP_RELAY_STEM)-$(DBG_IMAGE_MARK).gz

$(DOCKER_DHCP_RELAY)_PATH = $(DOCKERS_PATH)/$(DOCKER_DHCP_RELAY_STEM)

$(DOCKER_DHCP_RELAY)_DEPENDS += $(ISC_DHCP_RELAY) $(SONIC_DHCPMON)
$(DOCKER_DHCP_RELAY)_DEPENDS += $(ISC_DHCP_RELAY) $(SONIC_DHCPMON) $(SONIC_DHCP6RELAY) $(LIBSWSSCOMMON)

$(DOCKER_DHCP_RELAY)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS)
$(DOCKER_DHCP_RELAY)_DBG_DEPENDS += $(ISC_DHCP_RELAY_DBG)
Expand Down
5 changes: 5 additions & 0 deletions src/dhcp6relay/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
debian/*
!debian/changelog
!debian/compat
!debian/control
!debian/rules
42 changes: 42 additions & 0 deletions src/dhcp6relay/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
RM := rm -rf
DHCP6RELAY_TARGET := dhcp6relay
CP := cp
MKDIR := mkdir
CC := g++
MV := mv
LIBS := -levent -lhiredis -lswsscommon -pthread -lboost_thread -lboost_system -I $(PWD)/../sonic-swss-common/common
CFLAGS = -g -Wall -std=gnu11
PWD := $(shell pwd)

ifneq ($(MAKECMDGOALS),clean)
ifneq ($(strip $(C_DEPS)),)
-include $(C_DEPS) $(OBJS)
endif
endif

-include src/subdir.mk

all: sonic-dhcp6relay

sonic-dhcp6relay: $(OBJS)
@echo 'Building target: $@'
@echo 'Invoking: G++ Linker'
$(CC) -o $(DHCP6RELAY_TARGET) $(OBJS) $(LIBS)
@echo 'Finished building target: $@'
@echo ' '

install:
$(MKDIR) -p $(DESTDIR)/usr/sbin
$(MV) $(DHCP6RELAY_TARGET) $(DESTDIR)/usr/sbin

deinstall:
$(RM) $(DESTDIR)/usr/sbin/$(DHCP6RELAY_TARGET)
$(RM) -rf $(DESTDIR)/usr/sbin

clean:
-$(RM) $(EXECUTABLES) $(C_DEPS) $(OBJS) $(DHCP6RELAY_TARGET)
-@echo ' '

.PHONY: all clean dependents


5 changes: 5 additions & 0 deletions src/dhcp6relay/debian/changelog
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
sonic-dhcp6relay (1.0.0-0) UNRELEASED; urgency=medium

* Initial release.

-- Kelly Yeh <[email protected]>
1 change: 1 addition & 0 deletions src/dhcp6relay/debian/compat
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
9
17 changes: 17 additions & 0 deletions src/dhcp6relay/debian/control
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Source: sonic-dhcp6relay
Section: devel
Priority: optional
Maintainer: Kelly Yeh <[email protected]>
Build-Depends: debhelper (>= 8.0.0),
dh-systemd
Standards-Version: 3.9.3
Homepage: https://github.com/Azure/sonic-buildimage
XS-Go-Import-Path: github.com/Azure/sonic-buildimage

Package: sonic-dhcp6relay
Architecture: any
Built-Using: ${misc:Built-Using}
Depends: libevent-2.1-6,
libboost-thread1.71.0,
libboost-system1.71.0
Description: SONiC DHCPv6 Relay
4 changes: 4 additions & 0 deletions src/dhcp6relay/debian/rules
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/make -f

%:
dh $@ --parallel
151 changes: 151 additions & 0 deletions src/dhcp6relay/src/configInterface.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
#include <sstream>
#include <syslog.h>
#include <algorithm>
#include "configInterface.h"

constexpr auto DEFAULT_TIMEOUT_MSEC = 1000;

bool pollSwssNotifcation = true;
std::shared_ptr<boost::thread> mSwssThreadPtr;

std::shared_ptr<swss::DBConnector> configDbPtr = std::make_shared<swss::DBConnector> ("CONFIG_DB", 0);
swss::SubscriberStateTable ipHelpersTable(configDbPtr.get(), "DHCP_RELAY");
swss::Select swssSelect;

/**
* @code void initialize_swss()
*
* @brief initialize DB tables and start SWSS listening thread
*
* @return none
*/
void initialize_swss(std::vector<relay_config> *vlans)
{
try {
swssSelect.addSelectable(&ipHelpersTable);
get_dhcp(vlans);
mSwssThreadPtr = std::make_shared<boost::thread> (&handleSwssNotification, vlans);
}
catch (const std::bad_alloc &e) {
syslog(LOG_ERR, "Failed allocate memory. Exception details: %s", e.what());
}
}

/**
* @code void deinitialize_swss()
*
* @brief deinitialize DB interface and join SWSS listening thread
*
* @return none
*/
void deinitialize_swss()
{
stopSwssNotificationPoll();
mSwssThreadPtr->interrupt();
}


/**
* @code void get_dhcp(std::vector<relay_config> *vlans)
*
* @brief initialize and get vlan table information from DHCP_RELAY
*
* @return none
*/
void get_dhcp(std::vector<relay_config> *vlans) {
swss::Selectable *selectable;
int ret = swssSelect.select(&selectable, DEFAULT_TIMEOUT_MSEC);
if (ret == swss::Select::ERROR) {
syslog(LOG_WARNING, "Select: returned ERROR");
} else if (ret == swss::Select::TIMEOUT) {
}
if (selectable == static_cast<swss::Selectable *> (&ipHelpersTable)) {
handleRelayNotification(ipHelpersTable, vlans);
}
}
/**
* @code void handleSwssNotification(std::vector<relay_config> *vlans)
*
* @brief main thread for handling SWSS notification
*
* @param context list of vlans/argument config that contains strings of server and option
*
* @return none
*/
void handleSwssNotification(std::vector<relay_config> *vlans)
{
while (pollSwssNotifcation) {
get_dhcp(vlans);
}
}

/**
* @code void handleRelayNotification(swss::SubscriberStateTable &ipHelpersTable, std::vector<relay_config> *vlans)
*
* @brief handles DHCPv6 relay configuration change notification
*
* @param ipHelpersTable DHCP table
* @param vlans list of vlans/argument config that contains strings of server and option
*
* @return none
*/
void handleRelayNotification(swss::SubscriberStateTable &ipHelpersTable, std::vector<relay_config> *vlans)
{
std::deque<swss::KeyOpFieldsValuesTuple> entries;

ipHelpersTable.pops(entries);
processRelayNotification(entries, vlans);
}

/**
* @code void processRelayNotification(std::deque<swss::KeyOpFieldsValuesTuple> &entries, std::vector<relay_config> *vlans)
*
* @brief process DHCPv6 relay servers and options configuration change notification
*
* @param entries queue of std::tuple<std::string, std::string, std::vector<FieldValueTuple>> entries in DHCP table
* @param vlans list of vlans/argument config that contains strings of server and option
*
* @return none
*/
void processRelayNotification(std::deque<swss::KeyOpFieldsValuesTuple> &entries, std::vector<relay_config> *vlans)
{
std::vector<std::string> servers;

for (auto &entry: entries) {
std::string vlan = kfvKey(entry);
std::string operation = kfvOp(entry);
std::vector<swss::FieldValueTuple> fieldValues = kfvFieldsValues(entry);

relay_config intf;
intf.is_option_79 = true;
intf.interface = vlan;
for (auto &fieldValue: fieldValues) {
std::string f = fvField(fieldValue);
std::string v = fvValue(fieldValue);
if(f == "dhcpv6_servers") {
std::stringstream ss(v);
while (ss.good()) {
std::string substr;
getline(ss, substr, ',');
intf.servers.push_back(substr);
}
syslog(LOG_DEBUG, "key: %s, Operation: %s, f: %s, v: %s", vlan.c_str(), operation.c_str(), f.c_str(), v.c_str());
}
if(f == "dhcpv6_option|rfc6939_support" && v == "false") {
intf.is_option_79 = false;
}
}
vlans->push_back(intf);
}
}

/**
*@code stopSwssNotificationPoll
*
*@brief stop SWSS listening thread
*
*@return none
*/
void stopSwssNotificationPoll() {
pollSwssNotifcation = false;
};
75 changes: 75 additions & 0 deletions src/dhcp6relay/src/configInterface.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#include <boost/thread.hpp>
#include "subscriberstatetable.h"
#include "select.h"
#include "relay.h"

/**
* @code void initialize_swss()
*
* @brief initialize DB tables and start SWSS listening thread
*
* @return none
*/
void initialize_swss(std::vector<relay_config> *vlans);

/**
* @code void deinitialize_swss()
*
* @brief deinitialize DB interface and join SWSS listening thread
*
* @return none
*/
void deinitialize_swss();

/**
* @code void get_dhcp(std::vector<relay_config> *vlans)
*
* @brief initialize and get vlan information from DHCP_RELAY
*
* @return none
*/
void get_dhcp(std::vector<relay_config> *vlans);

/**
* @code void handleSwssNotification(std::vector<relay_config> *vlans)
*
* @brief main thread for handling SWSS notification
*
* @param vlans list of vlans/argument config that contains strings of server and option
*
* @return none
*/
void handleSwssNotification(std::vector<relay_config> *vlans);

/**
* @code void handleRelayNotification(swss::SubscriberStateTable &ipHelpersTable, std::vector<relay_config> *vlans)
*
* @brief handles DHCPv6 relay configuration change notification
*
* @param ipHelpersTable DHCP table
* @param vlans list of vlans/argument config that contains strings of server and option
*
* @return none
*/
void handleRelayNotification(swss::SubscriberStateTable &configMuxTable, std::vector<relay_config> *vlans);

/**
* @code void processRelayNotification(std::deque<swss::KeyOpFieldsValuesTuple> &entries, std::vector<relay_config> *vlans)
*
* @brief process DHCPv6 relay servers and options configuration change notification
*
* @param entries queue of std::tuple<std::string, std::string, std::vector<FieldValueTuple>> entries in DHCP table
* @param context list of vlans/argument config that contains strings of server and option
*
* @return none
*/
void processRelayNotification(std::deque<swss::KeyOpFieldsValuesTuple> &entries, std::vector<relay_config> *vlans);

/**
*@code stopSwssNotificationPoll
*
*@brief stop SWSS listening thread
*
*@return none
*/
void stopSwssNotificationPoll();
Loading

0 comments on commit a4b6788

Please sign in to comment.