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

[dhcp6relay] Support relaying Relay-Forward message #9887

Merged
merged 3 commits into from
Feb 1, 2022
Merged
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
53 changes: 52 additions & 1 deletion src/dhcp6relay/src/relay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,46 @@ void relay_client(int sock, const uint8_t *msg, int32_t len, const ip6_hdr *ip_h
}
}

/**
* @code relay_relay_forw(int sock, const uint8_t *msg, int32_t len, const ip6_hdr *ip_hdr, relay_config *config)
*
* @brief construct a relay-forward message encapsulated relay-forward message
*
* @param sock L3 socket for sending data to servers
* @param msg pointer to dhcpv6 message header position
* @param len size of data received
* @param ip_hdr pointer to IPv6 header
* @param config pointer to the relay interface config
*
* @return none
*/
void relay_relay_forw(int sock, const uint8_t *msg, int32_t len, const ip6_hdr *ip_hdr, relay_config *config) {
static uint8_t buffer[4096];
dhcpv6_relay_msg new_message;
auto current_buffer_position = buffer;
auto dhcp_relay_header = parse_dhcpv6_relay(msg);

if (dhcp_relay_header->hop_count >= HOP_LIMIT)
return;

new_message.msg_type = DHCPv6_MESSAGE_TYPE_RELAY_FORW;
memcpy(&new_message.peer_address, &ip_hdr->ip6_src, sizeof(in6_addr));
new_message.hop_count = dhcp_relay_header->hop_count + 1;

memset(&new_message.link_address, 0, sizeof(in6_addr));

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);

for(auto server: config->servers_sock) {
send_udp(sock, buffer, server, current_buffer_position - buffer, config, new_message.msg_type);
}
}

/**
* @code relay_relay_reply(int sock, const uint8_t *msg, int32_t len, relay_config *configs);
*
Expand Down Expand Up @@ -573,7 +613,18 @@ void callback(evutil_socket_t fd, short event, void *arg) {
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);
switch (msg->msg_type) {
case DHCPv6_MESSAGE_TYPE_RELAY_FORW:
{
relay_relay_forw(config->local_sock, current_position, ntohs(udp_header->len) - sizeof(udphdr), ip_header, config);
break;
}
default:
{
relay_client(config->local_sock, current_position, ntohs(udp_header->len) - sizeof(udphdr), ip_header, ether_header, config);
break;
}
}
}

/**
Expand Down
17 changes: 16 additions & 1 deletion src/dhcp6relay/src/relay.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

#define RELAY_PORT 547
#define CLIENT_PORT 546
#define HOP_LIMIT 32
#define HOP_LIMIT 8 //HOP_LIMIT reduced from 32 to 8 as stated in RFC8415

#define lengthof(A) (sizeof (A) / sizeof (A)[0])

Expand Down Expand Up @@ -146,6 +146,21 @@ void relay_forward(uint8_t *buffer, const struct dhcpv6_msg *msg, uint16_t msg_l
*/
void relay_client(int sock, const uint8_t *msg, int32_t len, const ip6_hdr *ip_hdr, const ether_header *ether_hdr, relay_config *config);

/**
* @code relay_relay_forw(int sock, const uint8_t *msg, int32_t len, const ip6_hdr *ip_hdr, relay_config *config)
*
* @brief construct a relay-forward message encapsulated relay-forward message
*
* @param sock L3 socket for sending data to servers
* @param msg pointer to dhcpv6 message header position
* @param len size of data received
* @param ip_hdr pointer to IPv6 header
* @param config pointer to the relay interface config
*
* @return none
*/
void relay_relay_forw(int sock, const uint8_t *msg, int32_t len, const ip6_hdr *ip_hdr, relay_config *config);

/**
* @code relay_relay_reply(int sock, const uint8_t *msg, int32_t len, relay_config *configs);
*
Expand Down