Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorporate DHCPv6 Relay Agent into dhcp-relay docker #8321

Merged
merged 12 commits into from
Sep 22, 2021
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
16 changes: 7 additions & 9 deletions src/dhcp6relay/src/configInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ swss::SubscriberStateTable ipHelpersTable(configDbPtr.get(), "DHCP_RELAY");
swss::Select swssSelect;

/**
* @code void deinitialize_swss()
* @code void initialize_swss()
*
* @brief initialize DB tables and start SWSS listening thread
*
* @return none
*/
void initialize_swss(std::vector<relay_config> *vlans, swss::DBConnector *db)
void initialize_swss(std::vector<relay_config> *vlans)
{
try {
swssSelect.addSelectable(&ipHelpersTable);
Expand Down Expand Up @@ -85,7 +85,7 @@ void handleSwssNotification(std::vector<relay_config> *vlans)
* @brief handles DHCPv6 relay configuration change notification
*
* @param ipHelpersTable DHCP table
* @param context list of vlans/argument config that contains strings of server and option
* @param vlans list of vlans/argument config that contains strings of server and option
*
* @return none
*/
Expand All @@ -103,7 +103,7 @@ void handleRelayNotification(swss::SubscriberStateTable &ipHelpersTable, std::ve
* @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
* @param vlans list of vlans/argument config that contains strings of server and option
*
* @return none
*/
Expand All @@ -117,6 +117,7 @@ void processRelayNotification(std::deque<swss::KeyOpFieldsValuesTuple> &entries,
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);
Expand All @@ -130,11 +131,8 @@ void processRelayNotification(std::deque<swss::KeyOpFieldsValuesTuple> &entries,
}
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") {
if(v == "true")
intf.is_option_79 = true;
else if(v == "false")
intf.is_option_79 = false;
if(f == "dhcpv6_option|rfc6939_support" && v == "false") {
intf.is_option_79 = false;
}
}
vlans->push_back(intf);
Expand Down
8 changes: 4 additions & 4 deletions src/dhcp6relay/src/configInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
#include "relay.h"

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

/**
* @code void deinitialize_swss()
Expand All @@ -35,7 +35,7 @@ void get_dhcp(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
* @param vlans list of vlans/argument config that contains strings of server and option
*
* @return none
*/
Expand All @@ -47,7 +47,7 @@ void handleSwssNotification(std::vector<relay_config> *vlans);
* @brief handles DHCPv6 relay configuration change notification
*
* @param ipHelpersTable DHCP table
* @param context list of vlans/argument config that contains strings of server and option
* @param vlans list of vlans/argument config that contains strings of server and option
*
* @return none
*/
Expand Down
2 changes: 1 addition & 1 deletion src/dhcp6relay/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ int main(int argc, char *argv[]) {
try {
std::vector<relay_config> vlans;
swss::DBConnector state_db("STATE_DB", 0);
initialize_swss(&vlans, &state_db);
initialize_swss(&vlans);
loop_relay(&vlans, &state_db);
}
catch (std::exception &e)
Expand Down
51 changes: 30 additions & 21 deletions src/dhcp6relay/src/relay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ struct event *server_listen_event;
struct event_base *base;
struct event *ev_sigint;
struct event *ev_sigterm;
static std::string counter_table = "DHCPv6_COUNTER_TABLE|";

/* DHCPv6 filter */
/* sudo tcpdump -dd "ip6 dst ff02::1:2 && udp dst port 547" */
Expand Down Expand Up @@ -325,12 +326,12 @@ int sock_open(int ifindex, const struct sock_fprog *fprog)
*
* @return none
*/
void prepare_relay_config(relay_config *interface_config, int local_sock, int filter) {
void prepare_relay_config(relay_config *interface_config, int *local_sock, int filter) {
struct ifaddrs *ifa, *ifa_tmp;
sockaddr_in6 non_link_local;
sockaddr_in6 link_local;

interface_config->local_sock = local_sock;
interface_config->local_sock = *local_sock;
interface_config->filter = filter;

for(auto server: interface_config->servers) {
Expand Down Expand Up @@ -376,22 +377,20 @@ void prepare_relay_config(relay_config *interface_config, int local_sock, int fi
}

/**
* @code prepare_socket(int *local_sock, relay_config *config);
* @code prepare_socket(int *local_sock);
*
* @brief prepare L3 socket for sending
*
* @param local_sock pointer to socket to be prepared
* @param config relay config that contains strings of server and interface addresses
*
* @return none
*/
void prepare_socket(int *local_sock, relay_config *config, int index) {
void prepare_socket(int *local_sock) {
int flag = 1;
sockaddr_in6 addr;
memset(&addr, 0, sizeof(addr));
addr.sin6_family = AF_INET6;
addr.sin6_addr = in6addr_any;
addr.sin6_scope_id = index;
addr.sin6_port = htons(RELAY_PORT);

if ((*local_sock = socket(AF_INET6, SOCK_DGRAM, 0)) == -1) {
Expand Down Expand Up @@ -434,11 +433,6 @@ void relay_client(int sock, const uint8_t *msg, int32_t len, const ip6_hdr *ip_h
memcpy(current_buffer_position, &new_message, sizeof(dhcpv6_relay_msg));
current_buffer_position += sizeof(dhcpv6_relay_msg);


auto dhcp_message_length = len;
relay_forward(current_buffer_position, parse_dhcpv6_hdr(msg), dhcp_message_length);
current_buffer_position += dhcp_message_length + sizeof(dhcpv6_option);

if(config->is_option_79) {
linklayer_addr_option option79;
option79.link_layer_type = htons(1);
Expand All @@ -447,10 +441,14 @@ void relay_client(int sock, const uint8_t *msg, int32_t len, const ip6_hdr *ip_h

memcpy(current_buffer_position, &option79, sizeof(linklayer_addr_option));
current_buffer_position += sizeof(linklayer_addr_option);

memcpy(current_buffer_position, &ether_hdr->ether_shost, sizeof(ether_hdr->ether_shost));
current_buffer_position += sizeof(ether_hdr->ether_shost);
}

memcpy(current_buffer_position, &ether_hdr->ether_shost, sizeof(ether_hdr->ether_shost));
current_buffer_position += sizeof(ether_hdr->ether_shost);
auto dhcp_message_length = len;
relay_forward(current_buffer_position, parse_dhcpv6_hdr(msg), dhcp_message_length);
current_buffer_position += dhcp_message_length + sizeof(dhcpv6_option);

for(auto server: config->servers_sock) {
send_udp(sock, buffer, server, current_buffer_position - buffer);
Expand Down Expand Up @@ -546,11 +544,23 @@ void callback(evutil_socket_t fd, short event, void *arg) {

auto msg = parse_dhcpv6_hdr(current_position);
counters[msg->msg_type]++;
update_counter(config->db, config->counterVlan, msg->msg_type);
std::string counterVlan = counter_table;
update_counter(config->db, counterVlan.append(config->interface), msg->msg_type);

relay_client(config->local_sock, current_position, ntohs(udp_header->len) - sizeof(udphdr), ip_header, ether_header, config);
}

/**
* @code void server_callback(evutil_socket_t fd, short event, void *arg);
*
* @brief callback for libevent that is called everytime data is received at the server socket
*
* @param fd filter socket
* @param event libevent triggered event
* @param arg callback argument provided by user
*
* @return none
*/
void server_callback(evutil_socket_t fd, short event, void *arg) {
struct relay_config *config = (struct relay_config *)arg;
sockaddr_in6 from;
Expand All @@ -563,9 +573,9 @@ void server_callback(evutil_socket_t fd, short event, void *arg) {
}

auto msg = parse_dhcpv6_hdr(message_buffer);

counters[msg->msg_type]++;
update_counter(config->db, config->counterVlan, msg->msg_type);
std::string counterVlan = counter_table;
update_counter(config->db, counterVlan.append(config->interface), msg->msg_type);
if (msg->msg_type == DHCPv6_MESSAGE_TYPE_RELAY_REPL) {
relay_relay_reply(config->local_sock, message_buffer, data, config);
}
Expand Down Expand Up @@ -673,17 +683,16 @@ void loop_relay(std::vector<relay_config> *vlans, swss::DBConnector *db) {
int index = if_nametoindex(ifname);
config.db = db;

config.counterVlan = "DHCPv6_COUNTER_TABLE|";
config.counterVlan.append(ifname);
initialize_counter(config.db, config.counterVlan);
std::string counterVlan = counter_table;
initialize_counter(config.db, counterVlan.append(config.interface));

filter = sock_open(index, &ether_relay_fprog);

prepare_socket(&local_sock, &config, index);
prepare_socket(&local_sock);
sockets.push_back(filter);
sockets.push_back(local_sock);

prepare_relay_config(&config, local_sock, filter);
prepare_relay_config(&config, &local_sock, filter);

evutil_make_listen_socket_reuseable(filter);
evutil_make_socket_nonblocking(filter);
Expand Down
9 changes: 3 additions & 6 deletions src/dhcp6relay/src/relay.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ struct relay_config {
std::vector<std::string> servers;
std::vector<sockaddr_in6> servers_sock;
bool is_option_79;
std::string counterVlan;
};


Expand Down Expand Up @@ -91,17 +90,15 @@ struct linklayer_addr_option {
int sock_open(int ifindex, const struct sock_fprog *fprog);

/**
* @code prepare_socket(int *local_sock, arg_config *config);
* @code prepare_socket(int *local_sock);
*
* @brief prepare L3 socket for sending
*
* @param local_sock pointer to socket to be prepared
* @param config argument config that contains strings of server and interface addresses
* @param index interface id
*
* @return none
*/
void prepare_socket(int *local_sock, relay_config *config, int index);
void prepare_socket(int *local_sock);

/**
* @code prepare_relay_config(relay_config *interface_config, int local_sock, int filter);
Expand All @@ -114,7 +111,7 @@ void prepare_socket(int *local_sock, relay_config *config, int index);
*
* @return none
*/
void prepare_relay_config(relay_config *interface_config, int local_sock, int filter);
void prepare_relay_config(relay_config *interface_config, int *local_sock, int filter);

/**
* @code relay_forward(uint8_t *buffer, const struct dhcpv6_msg *msg, uint16_t msg_length);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ stderr_logfile=syslog
dependent_startup=true
dependent_startup_wait_for=rsyslogd:running

[group:isc-dhcp-relay]
programs=isc-dhcpv4-relay-Vlan1000,isc-dhcpv6-relay-Vlan1000
[group:dhcp-relay]
programs=isc-dhcpv4-relay-Vlan1000,dhcp6relay

[program:isc-dhcpv4-relay-Vlan1000]
command=/usr/sbin/dhcrelay -d -m discard -a %%h:%%p %%P --name-alias-map-file /tmp/port-name-alias-map.txt -id Vlan1000 -iu Vlan2000 -iu PortChannel02 -iu PortChannel03 -iu PortChannel04 -iu PortChannel01 192.0.0.1 192.0.0.2
Expand All @@ -52,8 +52,9 @@ stderr_logfile=syslog
dependent_startup=true
dependent_startup_wait_for=start:exited

[program:isc-dhcpv6-relay-Vlan1000]
command=/usr/sbin/dhcrelay -d -6 --name-alias-map-file /tmp/port-name-alias-map.txt -l Vlan1000 -u fc02:2000::1%%PortChannel04 -u fc02:2000::1%%PortChannel03 -u fc02:2000::1%%PortChannel01 -u fc02:2000::1%%PortChannel02 -u fc02:2000::2%%PortChannel04 -u fc02:2000::2%%PortChannel03 -u fc02:2000::2%%PortChannel01 -u fc02:2000::2%%PortChannel02
[program:dhcp6relay]
command=/usr/sbin/dhcp6relay

priority=3
autostart=false
autorestart=false
Expand All @@ -74,6 +75,6 @@ autorestart=false
stdout_logfile=syslog
stderr_logfile=syslog
dependent_startup=true
dependent_startup_wait_for=isc-dhcpv4-relay-Vlan1000:running isc-dhcpv6-relay-Vlan1000:running
dependent_startup_wait_for=isc-dhcpv4-relay-Vlan1000:running dhcp6relay:running


Loading