From f1db17ff093935d68179ba330d80d02b2124a81f Mon Sep 17 00:00:00 2001 From: kellyyeh Date: Thu, 22 Jul 2021 20:26:31 +0000 Subject: [PATCH 01/16] Added DHCPv6 Relay --- src/dhcp6relay/.gitignore | 5 + src/dhcp6relay/Makefile | 42 ++ src/dhcp6relay/debian/changelog | 5 + src/dhcp6relay/debian/compat | 1 + src/dhcp6relay/debian/control | 15 + src/dhcp6relay/debian/rules | 7 + src/dhcp6relay/src/configInterface.cpp | 137 +++++ src/dhcp6relay/src/configInterface.h | 16 + src/dhcp6relay/src/main.cpp | 18 + src/dhcp6relay/src/relay.cpp | 665 +++++++++++++++++++++++++ src/dhcp6relay/src/relay.h | 175 +++++++ src/dhcp6relay/src/subdir.mk | 23 + 12 files changed, 1109 insertions(+) create mode 100644 src/dhcp6relay/.gitignore create mode 100644 src/dhcp6relay/Makefile create mode 100644 src/dhcp6relay/debian/changelog create mode 100644 src/dhcp6relay/debian/compat create mode 100644 src/dhcp6relay/debian/control create mode 100755 src/dhcp6relay/debian/rules create mode 100644 src/dhcp6relay/src/configInterface.cpp create mode 100644 src/dhcp6relay/src/configInterface.h create mode 100644 src/dhcp6relay/src/main.cpp create mode 100644 src/dhcp6relay/src/relay.cpp create mode 100644 src/dhcp6relay/src/relay.h create mode 100644 src/dhcp6relay/src/subdir.mk diff --git a/src/dhcp6relay/.gitignore b/src/dhcp6relay/.gitignore new file mode 100644 index 000000000000..9d09ae6b3f1a --- /dev/null +++ b/src/dhcp6relay/.gitignore @@ -0,0 +1,5 @@ +debian/* +!debian/changelog +!debian/compat +!debian/control +!debian/rules diff --git a/src/dhcp6relay/Makefile b/src/dhcp6relay/Makefile new file mode 100644 index 000000000000..afb76932065c --- /dev/null +++ b/src/dhcp6relay/Makefile @@ -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 +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 + + diff --git a/src/dhcp6relay/debian/changelog b/src/dhcp6relay/debian/changelog new file mode 100644 index 000000000000..1a1c6482d640 --- /dev/null +++ b/src/dhcp6relay/debian/changelog @@ -0,0 +1,5 @@ +sonic-dhcp6relay (1.0.0-0) UNRELEASED; urgency=medium + + * Initial release. + + -- Kelly Yeh Mon, 09 Dec 2019 12:00:00 -0700 diff --git a/src/dhcp6relay/debian/compat b/src/dhcp6relay/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/src/dhcp6relay/debian/compat @@ -0,0 +1 @@ +9 diff --git a/src/dhcp6relay/debian/control b/src/dhcp6relay/debian/control new file mode 100644 index 000000000000..1e383a8515bf --- /dev/null +++ b/src/dhcp6relay/debian/control @@ -0,0 +1,15 @@ +Source: sonic-dhcp6relay +Section: devel +Priority: optional +Maintainer: Kelly Yeh +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 +Description: SONiC DHCPv6 Relay \ No newline at end of file diff --git a/src/dhcp6relay/debian/rules b/src/dhcp6relay/debian/rules new file mode 100755 index 000000000000..00c628b6625f --- /dev/null +++ b/src/dhcp6relay/debian/rules @@ -0,0 +1,7 @@ +#!/usr/bin/make -f + +DEB_CFLAGS_APPEND=-std=gnu11 +export DEB_CFLAGS_APPEND + +%: + dh $@ --parallel diff --git a/src/dhcp6relay/src/configInterface.cpp b/src/dhcp6relay/src/configInterface.cpp new file mode 100644 index 000000000000..315fedd925c9 --- /dev/null +++ b/src/dhcp6relay/src/configInterface.cpp @@ -0,0 +1,137 @@ +#include +#include +#include +#include "configInterface.h" + +constexpr auto DEFAULT_TIMEOUT_MSEC = 1000; + +bool mPollSwssNotifcation = true; +std::shared_ptr mSwssThreadPtr; + +// +// ---> initialize(); +// +// initialize DB tables and start SWSS listening thread +// +void initialize_swss(arg_config *context) +{ + try { + mSwssThreadPtr = std::make_shared (&handleSwssNotification, context); + } + catch (const std::bad_alloc &e) { + syslog(LOG_ERR, "Failed allocate memory. Exception details: %s", e.what()); + } +} + +// +// ---> deinitialize(); +// +// deinitialize DB interface and join SWSS listening thread +// +void deinitialize_swss() +{ + stopSwssNotificationPoll(); + mSwssThreadPtr->interrupt(); +} + +/** + * @code void handleSwssNotification(arg_config *context) + * + * @brief main thread for handling SWSS notification + * + * @param context argument config that contains strings of server and option + * + * @return none + */ +void handleSwssNotification(arg_config *context) +{ + std::shared_ptr configDbPtr = std::make_shared ("CONFIG_DB", 0); + swss::SubscriberStateTable ipHelpersTable(configDbPtr.get(), "DHCP"); + + swss::Select swssSelect; + swssSelect.addSelectable(&ipHelpersTable); + while (mPollSwssNotifcation) { + swss::Selectable *selectable; + int ret = swssSelect.select(&selectable, DEFAULT_TIMEOUT_MSEC); + if (ret == swss::Select::ERROR) { + syslog(LOG_WARNING, "Select: returned ERROR"); + continue; + } else if (ret == swss::Select::TIMEOUT) { + continue; + } + if (selectable == static_cast (&ipHelpersTable)) { + handleRelayNotification(ipHelpersTable, context); + } + } +} + +/** + * @code void handleRelayNotification(swss::SubscriberStateTable &ipHelpersTable, arg_config context) + * + * @brief handles DHCPv6 relay configuration change notification + * + * @param ipHelpersTable DHCP table + * @param context argument config that contains strings of server and option + * + * @return none + */ +void handleRelayNotification(swss::SubscriberStateTable &ipHelpersTable, arg_config *context) +{ + std::deque entries; + + ipHelpersTable.pops(entries); + processRelayNotification(entries, context); +} + +/** + * @code void processRelayNotification(std::deque &entries, arg_config context) + * + * @brief process DHCPv6 relay servers and options configuration change notification + * + * @param entries queue of std::tuple> entries in DHCP table + * @param context argument config that contains strings of server and option + * + * @return none + */ +void processRelayNotification(std::deque &entries, arg_config *context) +{ + std::vector servers; + + for (auto &entry: entries) { + std::string vlan = kfvKey(entry); + std::vector fieldValues = kfvFieldsValues(entry); + + 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, ','); + context->servers.push_back(substr); + } + } + if(f == "options") { + std::stringstream ss(v); + while (ss.good()) { + std::string substr; + getline(ss, substr, ','); + if(substr == "79") + context->is_option_79 = true; + } + } + } + } +} + +/** +*@code stopSwssNotificationPoll +* +*@brief stop SWSS listening thread +* +*@return none +*/ +void stopSwssNotificationPoll() { + mPollSwssNotifcation = false; +}; \ No newline at end of file diff --git a/src/dhcp6relay/src/configInterface.h b/src/dhcp6relay/src/configInterface.h new file mode 100644 index 000000000000..4008821e6061 --- /dev/null +++ b/src/dhcp6relay/src/configInterface.h @@ -0,0 +1,16 @@ +#include +#include "subscriberstatetable.h" +#include "select.h" +#include "relay.h" + +void initialize_swss(arg_config *context); + +void deinitialize_swss(); + +void handleSwssNotification(arg_config *context); + +void handleRelayNotification(swss::SubscriberStateTable &configMuxTable, arg_config *context); + +void processRelayNotification(std::deque &entries, arg_config *context); + +void stopSwssNotificationPoll(); \ No newline at end of file diff --git a/src/dhcp6relay/src/main.cpp b/src/dhcp6relay/src/main.cpp new file mode 100644 index 000000000000..77135e5507f8 --- /dev/null +++ b/src/dhcp6relay/src/main.cpp @@ -0,0 +1,18 @@ +#include +#include "configInterface.h" + +int main(int argc, char *argv[]) { + try { + auto parser = ArgumentParser(); + parser.parse_args(argc, argv); + auto context = parser.get_arg(); + initialize_swss(&context); + loop_relay(&context); + } + catch (std::exception &e) + { + printf("Usage: -i -o