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

Add DHCPv6 Relay Agent #8251

Merged
merged 16 commits into from
Aug 20, 2021
Merged

Conversation

kellyyeh
Copy link
Contributor

DHCPv6 is a network protocol used to assign IPv6 addresses and provide configuration for devices to communicate on a network. DHCPv6 relay agent helps forwards DHCP packets between clients and servers that do not reside on a shared physical subnet, so that all subnets can share DHCPv6 server, and DHCPv6 server is not required on every LAN. This DHCPv6 relay agent supports option 79 which incorporates the client link-layer address in Relay-Forward messages that is sent to the server, which is needed by the server to allow IPv6 reservation to clients based on their physical MAC addresses.

This PR is part of: sonic-net/SONiC#787
Signed-off-by: Kelly Yeh kellyyeh@microsoft.com

Why I did it

To support option 79 in DHCPv6.

How I did it

Implemented DHCPv6 operations along with option 79.
Read from config_db to process dhcpv6 server addresses and options.

How to verify it

Build the binary with Makefile and run it on switch with IPv6 configured and DHCPv6 server support

Which release branch to backport (provide reason below if selected)

  • 201811
  • 201911
  • 202006
  • 202012
  • 202106

Description for the changelog

A picture of a cute animal (not mandatory but encouraged)

@kellyyeh kellyyeh requested a review from tahmed-dev July 22, 2021 20:59
@kellyyeh kellyyeh requested a review from lguohan as a code owner July 22, 2021 20:59
Copy link
Contributor

@tahmed-dev tahmed-dev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

std::string vlan = kfvKey(entry);
std::vector<swss::FieldValueTuple> fieldValues = kfvFieldsValues(entry);

for (auto &fieldValue: fieldValues) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to check the operation here if it is ADD/DEL

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dhcpv6 server address are type string value. e.g.: "fc02:2000::1,fc02:2000::2"
HDEL would delete the entire string of addresses. HSET updates the list of server addresses.
When config_db updates the list of server addresses, all addresses are properly fetched and processed regardless new addresses are added/deleted. Therefore, I don't think there is a need to check for add/del

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can get the operation using std::string operation = kfvOp(entry);. This way we can tell the type of the record updates. I think they are SET/DEL operation.

src/dhcp6relay/src/main.cpp Outdated Show resolved Hide resolved
src/dhcp6relay/src/relay.cpp Outdated Show resolved Hide resolved
src/dhcp6relay/src/relay.cpp Outdated Show resolved Hide resolved
addr[0] = 0;

if (getifaddrs(&ifa) == -1) {
syslog(LOG_WARNING, "getifaddrs: Unable to get network interfaces\n");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: use spaces only for indentation

src/dhcp6relay/src/relay.cpp Outdated Show resolved Hide resolved
src/dhcp6relay/src/relay.cpp Outdated Show resolved Hide resolved
src/dhcp6relay/src/relay.cpp Outdated Show resolved Hide resolved
auto dhcp_header = parse_dhcpv6_hdr(current_position);

if ((ntohs(udp_header->dest)) == 547 ) {
if(dhcp_header->msg_type == SOLICIT || REQUEST || CONFIRM || RENEW || REBIND || RELEASE || DECLINE) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is meant by this condition? this is true all the time

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for catching. Fixed.

* @return none
*/
void listen_server(relay_config *config) {
while (serverListener) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why the server listener is not part of the even loop?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added server listener to libevent

if(dhcp_header->msg_type == SOLICIT || REQUEST || CONFIRM || RENEW || REBIND || RELEASE || DECLINE) {
relay_client(config->local_sock, current_position, ntohs(udp_header->len) - sizeof(udphdr), ip_header, ether_header, config);
}
if (((ntohs(udp_header->dest)) == RELAY_PORT) && (dhcp_header->msg_type == SOLICIT || REQUEST || CONFIRM || RENEW || REBIND || RELEASE || DECLINE)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This condition will always be true:
(dhcp_header->msg_type == SOLICIT || REQUEST || CONFIRM || RENEW || REBIND || RELEASE || DECLINE)

@@ -0,0 +1,7 @@
#!/usr/bin/make -f

DEB_CFLAGS_APPEND=-std=gnu11
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can add this flag to CFLAGS in Makefile above.


constexpr auto DEFAULT_TIMEOUT_MSEC = 1000;

bool mPollSwssNotifcation = true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can drop the letter m as it is normally used to indicate class member.

void handleSwssNotification(arg_config *context)
{
std::shared_ptr<swss::DBConnector> configDbPtr = std::make_shared<swss::DBConnector> ("CONFIG_DB", 0);
swss::SubscriberStateTable ipHelpersTable(configDbPtr.get(), "DHCP");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to add DHCP as a table name in schema.h file.

while (ss.good()) {
std::string substr;
getline(ss, substr, ',');
if(substr == "79")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is the option 79 name up-to-date?

#include "select.h"
#include "relay.h"

void initialize_swss(arg_config *context);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add doxygen comments to functions in this file.


ifa_tmp = ifa;
while (ifa_tmp) {
if ((ifa_tmp->ifa_addr) && (ifa_tmp->ifa_addr->sa_family == AF_INET6)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indentation

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please remove tabs and use 4 spaces indentation.

}
catch (std::exception &e)
{
printf("Usage: -i <interface> -o <option>\n");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we are not using cli args anymore.

/* DHCPv6 filter */
/* sudo tcpdump -dd "ip6 dst ff02::1:2 && udp dst port 547" */

static struct sock_filter ether_relay_filter[] = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please move this static variable to .c file

src/dhcp6relay/src/relay.cpp Outdated Show resolved Hide resolved
src/dhcp6relay/src/main.cpp Outdated Show resolved Hide resolved
src/dhcp6relay/src/main.cpp Outdated Show resolved Hide resolved
src/dhcp6relay/src/relay.cpp Show resolved Hide resolved

ifa_tmp = ifa;
while (ifa_tmp) {
if ((ifa_tmp->ifa_addr) && (ifa_tmp->ifa_addr->sa_family == AF_INET6)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please remove tabs and use 4 spaces indentation.

* @return none
*/
void relay_relay_reply(int sock, const uint8_t *msg, int32_t len, relay_config *configs) {
uint8_t buffer[4096];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you please avoid having large local vars?

src/dhcp6relay/src/main.cpp Outdated Show resolved Hide resolved
src/dhcp6relay/src/relay.cpp Show resolved Hide resolved
tahmed-dev
tahmed-dev previously approved these changes Aug 17, 2021
tahmed-dev
tahmed-dev previously approved these changes Aug 18, 2021
@kellyyeh kellyyeh merged commit f0e640f into sonic-net:master Aug 20, 2021
@kellyyeh kellyyeh deleted the kellyyeh-dhcp6relay branch August 20, 2021 16:12
@kellyyeh kellyyeh restored the kellyyeh-dhcp6relay branch August 20, 2021 17:28
kellyyeh added a commit to kellyyeh/sonic-buildimage that referenced this pull request Sep 30, 2021
* Added DHCPv6 Relay

* Added DHCPv6 Counter

(cherry picked from commit f0e640f)
@kellyyeh kellyyeh deleted the kellyyeh-dhcp6relay branch October 13, 2021 23:46
yxieca pushed a commit to yxieca/sonic-buildimage that referenced this pull request Oct 25, 2021
* Added DHCPv6 Relay

* Added DHCPv6 Counter
kellyyeh added a commit to kellyyeh/sonic-buildimage that referenced this pull request Oct 25, 2021
* Added DHCPv6 Relay

* Added DHCPv6 Counter
yxieca pushed a commit that referenced this pull request Oct 26, 2021
* Added DHCPv6 Relay

* Added DHCPv6 Counter
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants