[dhcp6relay] Add dhcpv6 option check (#10486)
This commit is contained in:
parent
8ec8900d31
commit
cfdb8431df
@ -32,6 +32,7 @@ expected_counts = """\
|
|||||||
Decline
|
Decline
|
||||||
Relay-Forward
|
Relay-Forward
|
||||||
Relay-Reply
|
Relay-Reply
|
||||||
|
Malformed
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ from swsscommon.swsscommon import SonicV2Connector
|
|||||||
DHCPv6_COUNTER_TABLE = 'DHCPv6_COUNTER_TABLE'
|
DHCPv6_COUNTER_TABLE = 'DHCPv6_COUNTER_TABLE'
|
||||||
|
|
||||||
# DHCPv6 Counter Messages
|
# 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 Config Table
|
||||||
DHCP_RELAY = 'DHCP_RELAY'
|
DHCP_RELAY = 'DHCP_RELAY'
|
||||||
|
@ -49,18 +49,19 @@ const struct sock_fprog ether_relay_fprog = {
|
|||||||
|
|
||||||
/* DHCPv6 Counter */
|
/* DHCPv6 Counter */
|
||||||
uint64_t counters[DHCPv6_MESSAGE_TYPE_COUNT];
|
uint64_t counters[DHCPv6_MESSAGE_TYPE_COUNT];
|
||||||
std::map<int, std::string> counterMap = {{0, "Unknown"},
|
std::map<int, std::string> counterMap = {{DHCPv6_MESSAGE_TYPE_UNKNOWN, "Unknown"},
|
||||||
{1, "Solicit"},
|
{DHCPv6_MESSAGE_TYPE_SOLICIT, "Solicit"},
|
||||||
{2, "Advertise"},
|
{DHCPv6_MESSAGE_TYPE_ADVERTISE, "Advertise"},
|
||||||
{3, "Request"},
|
{DHCPv6_MESSAGE_TYPE_REQUEST, "Request"},
|
||||||
{4, "Confirm"},
|
{DHCPv6_MESSAGE_TYPE_CONFIRM, "Confirm"},
|
||||||
{5, "Renew"},
|
{DHCPv6_MESSAGE_TYPE_RENEW, "Renew"},
|
||||||
{6, "Rebind"},
|
{DHCPv6_MESSAGE_TYPE_REBIND, "Rebind"},
|
||||||
{7, "Reply"},
|
{DHCPv6_MESSAGE_TYPE_REPLY, "Reply"},
|
||||||
{8, "Release"},
|
{DHCPv6_MESSAGE_TYPE_RELEASE, "Release"},
|
||||||
{9, "Decline"},
|
{DHCPv6_MESSAGE_TYPE_DECLINE, "Decline"},
|
||||||
{12, "Relay-Forward"},
|
{DHCPv6_MESSAGE_TYPE_RELAY_FORW, "Relay-Forward"},
|
||||||
{13, "Relay-Reply"}};
|
{DHCPv6_MESSAGE_TYPE_RELAY_REPL, "Relay-Reply"},
|
||||||
|
{DHCPv6_MESSAGE_TYPE_MALFORMED, "Malformed"}};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @code void initialize_counter(swss::DBConnector *db, std::string counterVlan);
|
* @code void initialize_counter(swss::DBConnector *db, std::string counterVlan);
|
||||||
@ -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, "Decline", toString(counters[DHCPv6_MESSAGE_TYPE_DECLINE]));
|
||||||
db->hset(counterVlan, "Relay-Forward", toString(counters[DHCPv6_MESSAGE_TYPE_RELAY_FORW]));
|
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, "Relay-Reply", toString(counters[DHCPv6_MESSAGE_TYPE_RELAY_REPL]));
|
||||||
|
db->hset(counterVlan, "Malformed", toString(counters[DHCPv6_MESSAGE_TYPE_MALFORMED]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -622,6 +624,8 @@ void callback(evutil_socket_t fd, short event, void *arg) {
|
|||||||
current_position = tmp;
|
current_position = tmp;
|
||||||
|
|
||||||
auto msg = parse_dhcpv6_hdr(current_position);
|
auto msg = parse_dhcpv6_hdr(current_position);
|
||||||
|
auto option_position = current_position + sizeof(struct dhcpv6_msg);
|
||||||
|
|
||||||
counters[msg->msg_type]++;
|
counters[msg->msg_type]++;
|
||||||
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);
|
||||||
@ -632,9 +636,29 @@ 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);
|
relay_relay_forw(config->local_sock, current_position, ntohs(udp_header->len) - sizeof(udphdr), ip_header, config);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
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:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#define RELAY_PORT 547
|
#define RELAY_PORT 547
|
||||||
#define CLIENT_PORT 546
|
#define CLIENT_PORT 546
|
||||||
#define HOP_LIMIT 8 //HOP_LIMIT reduced from 32 to 8 as stated in RFC8415
|
#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])
|
#define lengthof(A) (sizeof (A) / sizeof (A)[0])
|
||||||
|
|
||||||
@ -37,6 +38,7 @@ typedef enum
|
|||||||
DHCPv6_MESSAGE_TYPE_DECLINE = 9,
|
DHCPv6_MESSAGE_TYPE_DECLINE = 9,
|
||||||
DHCPv6_MESSAGE_TYPE_RELAY_FORW = 12,
|
DHCPv6_MESSAGE_TYPE_RELAY_FORW = 12,
|
||||||
DHCPv6_MESSAGE_TYPE_RELAY_REPL = 13,
|
DHCPv6_MESSAGE_TYPE_RELAY_REPL = 13,
|
||||||
|
DHCPv6_MESSAGE_TYPE_MALFORMED = 14,
|
||||||
|
|
||||||
DHCPv6_MESSAGE_TYPE_COUNT
|
DHCPv6_MESSAGE_TYPE_COUNT
|
||||||
} dhcp_message_type_t;
|
} dhcp_message_type_t;
|
||||||
|
Loading…
Reference in New Issue
Block a user