Skip to content

Commit

Permalink
[dhcp6relay] Add dhcpv6 option check (sonic-net#10486)
Browse files Browse the repository at this point in the history
  • Loading branch information
kellyyeh authored and liushilongbuaa committed May 12, 2022
1 parent 07bbfa6 commit c6b1fd8
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
Decline
Relay-Forward
Relay-Reply
Malformed
"""

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
DHCPv6_COUNTER_TABLE = 'DHCPv6_COUNTER_TABLE'

# DHCPv6 Counter Messages
messages = ["Unknown", "Solicit", "Advertise", "Request", "Confirm", "Renew", "Rebind", "Reply", "Release", "Decline", "Relay-Forward", "Relay-Reply"]
messages = ["Unknown", "Solicit", "Advertise", "Request", "Confirm", "Renew", "Rebind", "Reply", "Release", "Decline", "Relay-Forward", "Relay-Reply", "Malformed"]

# DHCP_RELAY Config Table
DHCP_RELAY = 'DHCP_RELAY'
Expand Down
50 changes: 37 additions & 13 deletions src/dhcp6relay/src/relay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,19 @@ 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_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);
Expand All @@ -85,6 +86,7 @@ void initialize_counter(swss::DBConnector *db, std::string counterVlan) {
db->hset(counterVlan, "Decline", toString(counters[DHCPv6_MESSAGE_TYPE_DECLINE]));
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]));
}

/**
Expand Down Expand Up @@ -622,6 +624,8 @@ void callback(evutil_socket_t fd, short event, void *arg) {
current_position = tmp;

auto msg = parse_dhcpv6_hdr(current_position);
auto option_position = current_position + sizeof(struct dhcpv6_msg);

counters[msg->msg_type]++;
std::string counterVlan = counter_table;
update_counter(config->db, counterVlan.append(config->interface), msg->msg_type);
Expand All @@ -632,11 +636,31 @@ 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;
}
default:
case DHCPv6_MESSAGE_TYPE_SOLICIT:
case DHCPv6_MESSAGE_TYPE_REQUEST:
case DHCPv6_MESSAGE_TYPE_RENEW:
case DHCPv6_MESSAGE_TYPE_REBIND:
case DHCPv6_MESSAGE_TYPE_RELEASE:
case DHCPv6_MESSAGE_TYPE_DECLINE:
{
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;
}
}
relay_client(config->local_sock, current_position, ntohs(udp_header->len) - sizeof(udphdr), ip_header, ether_header, config);
break;
}
default:
{
syslog(LOG_WARNING, "DHCPv6 client message received was not relayed\n");
break;
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/dhcp6relay/src/relay.h
Original file line number Diff line number Diff line change
Expand Up @@ -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])

Expand All @@ -37,6 +38,7 @@ typedef enum
DHCPv6_MESSAGE_TYPE_DECLINE = 9,
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;
Expand Down

0 comments on commit c6b1fd8

Please sign in to comment.