[dhcp6relay] Support relaying Relay-Forward message (#9887)

This commit is contained in:
kellyyeh 2022-02-01 11:36:48 -08:00 committed by GitHub
parent adb87162c4
commit bc88535b88
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 68 additions and 2 deletions

View File

@ -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); * @code relay_relay_reply(int sock, const uint8_t *msg, int32_t len, relay_config *configs);
* *
@ -573,7 +613,18 @@ void callback(evutil_socket_t fd, short event, void *arg) {
std::string counterVlan = counter_table; std::string counterVlan = counter_table;
update_counter(config->db, counterVlan.append(config->interface), msg->msg_type); 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;
}
}
} }
/** /**

View File

@ -15,7 +15,7 @@
#define RELAY_PORT 547 #define RELAY_PORT 547
#define CLIENT_PORT 546 #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]) #define lengthof(A) (sizeof (A) / sizeof (A)[0])
@ -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); 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); * @code relay_relay_reply(int sock, const uint8_t *msg, int32_t len, relay_config *configs);
* *