parent
148ff285a6
commit
79555c894a
@ -49,18 +49,21 @@ const struct sock_fprog ether_relay_fprog = {
|
||||
|
||||
/* DHCPv6 Counter */
|
||||
uint64_t counters[DHCPv6_MESSAGE_TYPE_COUNT];
|
||||
std::map<int, std::string> counterMap = {{0, "Unknown"},
|
||||
{1, "Solicit"},
|
||||
{2, "Advertise"},
|
||||
{3, "Request"},
|
||||
{4, "Confirm"},
|
||||
{5, "Renew"},
|
||||
{6, "Rebind"},
|
||||
{7, "Reply"},
|
||||
{8, "Release"},
|
||||
{9, "Decline"},
|
||||
{12, "Relay-Forward"},
|
||||
{13, "Relay-Reply"}};
|
||||
std::map<int, std::string> counterMap = {{DHCPv6_MESSAGE_TYPE_UNKNOWN, "Unknown"},
|
||||
{DHCPv6_MESSAGE_TYPE_SOLICIT, "Solicit"},
|
||||
{DHCPv6_MESSAGE_TYPE_ADVERTISE, "Advertise"},
|
||||
{DHCPv6_MESSAGE_TYPE_REQUEST, "Request"},
|
||||
{DHCPv6_MESSAGE_TYPE_CONFIRM, "Confirm"},
|
||||
{DHCPv6_MESSAGE_TYPE_RENEW, "Renew"},
|
||||
{DHCPv6_MESSAGE_TYPE_REBIND, "Rebind"},
|
||||
{DHCPv6_MESSAGE_TYPE_REPLY, "Reply"},
|
||||
{DHCPv6_MESSAGE_TYPE_RELEASE, "Release"},
|
||||
{DHCPv6_MESSAGE_TYPE_DECLINE, "Decline"},
|
||||
{DHCPv6_MESSAGE_TYPE_RECONFIGURE, "Reconfigure"},
|
||||
{DHCPv6_MESSAGE_TYPE_INFORMATION_REQUEST, "Information-Request"},
|
||||
{DHCPv6_MESSAGE_TYPE_RELAY_FORW, "Relay-Forward"},
|
||||
{DHCPv6_MESSAGE_TYPE_RELAY_REPL, "Relay-Reply"},
|
||||
{DHCPv6_MESSAGE_TYPE_MALFORMED, "Malformed"}};
|
||||
|
||||
/**
|
||||
* @code void initialize_counter(swss::DBConnector *db, std::string counterVlan);
|
||||
@ -83,8 +86,11 @@ void initialize_counter(swss::DBConnector *db, std::string counterVlan) {
|
||||
db->hset(counterVlan, "Reply", toString(counters[DHCPv6_MESSAGE_TYPE_REPLY]));
|
||||
db->hset(counterVlan, "Release", toString(counters[DHCPv6_MESSAGE_TYPE_RELEASE]));
|
||||
db->hset(counterVlan, "Decline", toString(counters[DHCPv6_MESSAGE_TYPE_DECLINE]));
|
||||
db->hset(counterVlan, "Reconfigure", toString(counters[DHCPv6_MESSAGE_TYPE_RECONFIGURE]));
|
||||
db->hset(counterVlan, "Information-Request", toString(counters[DHCPv6_MESSAGE_TYPE_INFORMATION_REQUEST]));
|
||||
db->hset(counterVlan, "Relay-Forward", toString(counters[DHCPv6_MESSAGE_TYPE_RELAY_FORW]));
|
||||
db->hset(counterVlan, "Relay-Reply", toString(counters[DHCPv6_MESSAGE_TYPE_RELAY_REPL]));
|
||||
db->hset(counterVlan, "Malformed", toString(counters[DHCPv6_MESSAGE_TYPE_MALFORMED]));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -202,11 +208,12 @@ const struct dhcpv6_relay_msg *parse_dhcpv6_relay(const uint8_t *buffer) {
|
||||
* @return dhcpv6_option end of dhcpv6 message option
|
||||
*/
|
||||
const struct dhcpv6_option *parse_dhcpv6_opt(const uint8_t *buffer, const uint8_t **out_end) {
|
||||
uint32_t size = 4; // option-code + option-len
|
||||
size += ntohs(*(uint16_t *)(buffer + 2));
|
||||
(*out_end) = buffer + size;
|
||||
auto option = (const struct dhcpv6_option *)buffer;
|
||||
uint8_t size = 4; // option-code + option-len
|
||||
size += *(uint16_t *)(buffer);
|
||||
(*out_end) = buffer + size + ntohs(option->option_length);
|
||||
|
||||
return (const struct dhcpv6_option *)buffer;
|
||||
return option;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -587,6 +594,7 @@ void relay_relay_forw(int sock, const uint8_t *msg, int32_t len, const ip6_hdr *
|
||||
void callback(evutil_socket_t fd, short event, void *arg) {
|
||||
struct relay_config *config = (struct relay_config *)arg;
|
||||
static uint8_t message_buffer[4096];
|
||||
std::string counterVlan = counter_table;
|
||||
int32_t len = recv(config->filter, message_buffer, 4096, 0);
|
||||
if (len <= 0) {
|
||||
syslog(LOG_WARNING, "recv: Failed to receive data at filter socket: %s\n", strerror(errno));
|
||||
@ -622,9 +630,7 @@ void callback(evutil_socket_t fd, short event, void *arg) {
|
||||
current_position = tmp;
|
||||
|
||||
auto msg = parse_dhcpv6_hdr(current_position);
|
||||
counters[msg->msg_type]++;
|
||||
std::string counterVlan = counter_table;
|
||||
update_counter(config->db, counterVlan.append(config->interface), msg->msg_type);
|
||||
auto option_position = current_position + sizeof(struct dhcpv6_msg);
|
||||
|
||||
switch (msg->msg_type) {
|
||||
case DHCPv6_MESSAGE_TYPE_RELAY_FORW:
|
||||
@ -632,9 +638,33 @@ void callback(evutil_socket_t fd, short event, void *arg) {
|
||||
relay_relay_forw(config->local_sock, current_position, ntohs(udp_header->len) - sizeof(udphdr), ip_header, config);
|
||||
break;
|
||||
}
|
||||
case DHCPv6_MESSAGE_TYPE_SOLICIT:
|
||||
case DHCPv6_MESSAGE_TYPE_REQUEST:
|
||||
case DHCPv6_MESSAGE_TYPE_CONFIRM:
|
||||
case DHCPv6_MESSAGE_TYPE_RENEW:
|
||||
case DHCPv6_MESSAGE_TYPE_REBIND:
|
||||
case DHCPv6_MESSAGE_TYPE_RELEASE:
|
||||
case DHCPv6_MESSAGE_TYPE_DECLINE:
|
||||
case DHCPv6_MESSAGE_TYPE_INFORMATION_REQUEST:
|
||||
{
|
||||
while (option_position - message_buffer < len) {
|
||||
auto option = parse_dhcpv6_opt(option_position, &tmp);
|
||||
option_position = tmp;
|
||||
if (ntohs(option->option_code) > DHCPv6_OPTION_LIMIT) {
|
||||
counters[DHCPv6_MESSAGE_TYPE_MALFORMED]++;
|
||||
update_counter(config->db, counterVlan.append(config->interface), DHCPv6_MESSAGE_TYPE_MALFORMED);
|
||||
syslog(LOG_WARNING, "DHCPv6 option is invalid or contains malformed payload\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
counters[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);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
relay_client(config->local_sock, current_position, ntohs(udp_header->len) - sizeof(udphdr), ip_header, ether_header, config);
|
||||
syslog(LOG_WARNING, "DHCPv6 client message received was not relayed\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
#define RELAY_PORT 547
|
||||
#define CLIENT_PORT 546
|
||||
#define HOP_LIMIT 8 //HOP_LIMIT reduced from 32 to 8 as stated in RFC8415
|
||||
#define DHCPv6_OPTION_LIMIT 56 // DHCPv6 option code greater than 56 are currently unassigned
|
||||
|
||||
#define lengthof(A) (sizeof (A) / sizeof (A)[0])
|
||||
|
||||
@ -35,8 +36,11 @@ typedef enum
|
||||
DHCPv6_MESSAGE_TYPE_REPLY = 7,
|
||||
DHCPv6_MESSAGE_TYPE_RELEASE = 8,
|
||||
DHCPv6_MESSAGE_TYPE_DECLINE = 9,
|
||||
DHCPv6_MESSAGE_TYPE_RECONFIGURE = 10,
|
||||
DHCPv6_MESSAGE_TYPE_INFORMATION_REQUEST = 11,
|
||||
DHCPv6_MESSAGE_TYPE_RELAY_FORW = 12,
|
||||
DHCPv6_MESSAGE_TYPE_RELAY_REPL = 13,
|
||||
DHCPv6_MESSAGE_TYPE_MALFORMED = 14,
|
||||
|
||||
DHCPv6_MESSAGE_TYPE_COUNT
|
||||
} dhcp_message_type_t;
|
||||
@ -58,6 +62,7 @@ struct relay_config {
|
||||
|
||||
struct dhcpv6_msg {
|
||||
uint8_t msg_type;
|
||||
uint8_t xid[3];
|
||||
};
|
||||
|
||||
struct PACKED dhcpv6_relay_msg {
|
||||
|
Loading…
Reference in New Issue
Block a user