diff --git a/dockers/docker-dhcp-relay/cli-plugin-tests/test_show_dhcp6relay_counters.py b/dockers/docker-dhcp-relay/cli-plugin-tests/test_show_dhcp6relay_counters.py index f640ef1de6..501309ddd4 100644 --- a/dockers/docker-dhcp-relay/cli-plugin-tests/test_show_dhcp6relay_counters.py +++ b/dockers/docker-dhcp-relay/cli-plugin-tests/test_show_dhcp6relay_counters.py @@ -20,6 +20,7 @@ except KeyError: expected_counts = """\ Message Type Vlan1000 -------------- ----------- + Unknown Solicit Advertise Request diff --git a/dockers/docker-dhcp-relay/cli/show/plugins/show_dhcp_relay.py b/dockers/docker-dhcp-relay/cli/show/plugins/show_dhcp_relay.py index bad1de7d52..ffcecaf601 100644 --- a/dockers/docker-dhcp-relay/cli/show/plugins/show_dhcp_relay.py +++ b/dockers/docker-dhcp-relay/cli/show/plugins/show_dhcp_relay.py @@ -12,7 +12,7 @@ from swsscommon.swsscommon import SonicV2Connector DHCPv6_COUNTER_TABLE = 'DHCPv6_COUNTER_TABLE' # DHCPv6 Counter Messages -messages = ["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"] # DHCP_RELAY Config Table DHCP_RELAY = 'DHCP_RELAY' diff --git a/src/dhcp6relay/src/relay.cpp b/src/dhcp6relay/src/relay.cpp index 11bb4ace42..d8fa2747a5 100644 --- a/src/dhcp6relay/src/relay.cpp +++ b/src/dhcp6relay/src/relay.cpp @@ -49,7 +49,8 @@ const struct sock_fprog ether_relay_fprog = { /* DHCPv6 Counter */ uint64_t counters[DHCPv6_MESSAGE_TYPE_COUNT]; -std::map counterMap = {{1, "Solicit"}, +std::map counterMap = {{0, "Unknown"}, + {1, "Solicit"}, {2, "Advertise"}, {3, "Request"}, {4, "Confirm"}, @@ -72,6 +73,7 @@ std::map counterMap = {{1, "Solicit"}, * @return none */ void initialize_counter(swss::DBConnector *db, std::string counterVlan) { + db->hset(counterVlan, "Unknown", toString(counters[DHCPv6_MESSAGE_TYPE_UNKNOWN])); db->hset(counterVlan, "Solicit", toString(counters[DHCPv6_MESSAGE_TYPE_SOLICIT])); db->hset(counterVlan, "Advertise", toString(counters[DHCPv6_MESSAGE_TYPE_ADVERTISE])); db->hset(counterVlan, "Request", toString(counters[DHCPv6_MESSAGE_TYPE_REQUEST])); @@ -208,19 +210,26 @@ const struct dhcpv6_option *parse_dhcpv6_opt(const uint8_t *buffer, const uint8_ } /** - * @code void send_udp(int sock, uint8_t *buffer, struct sockaddr_in6 target, uint32_t n); + * @code void send_udp(int sock, uint8_t *buffer, struct sockaddr_in6 target, uint32_t n, relay_config *config, uint8_t msg_type); * * @brief send udp packet * * @param *buffer message buffer * @param sockaddr_in6 target target socket * @param n length of message + * @param relay_config *config pointer to relay_config + * @param uint8_t msg_type message type of dhcpv6 option of relayed message * * @return dhcpv6_option end of dhcpv6 message option */ -void send_udp(int sock, uint8_t *buffer, struct sockaddr_in6 target, uint32_t n) { +void send_udp(int sock, uint8_t *buffer, struct sockaddr_in6 target, uint32_t n, relay_config *config, uint8_t msg_type) { + std::string counterVlan = counter_table; if(sendto(sock, buffer, n, 0, (const struct sockaddr *)&target, sizeof(target)) == -1) syslog(LOG_ERR, "sendto: Failed to send to target address\n"); + else { + counters[msg_type]++; + update_counter(config->db, counterVlan.append(config->interface), msg_type); + } } /** @@ -453,7 +462,7 @@ void relay_client(int sock, const uint8_t *msg, int32_t len, const ip6_hdr *ip_h current_buffer_position += dhcp_message_length + sizeof(dhcpv6_option); for(auto server: config->servers_sock) { - send_udp(sock, buffer, server, current_buffer_position - buffer); + send_udp(sock, buffer, server, current_buffer_position - buffer, config, new_message.msg_type); } } @@ -471,6 +480,7 @@ void relay_client(int sock, const uint8_t *msg, int32_t len, const ip6_hdr *ip_h */ void relay_relay_reply(int sock, const uint8_t *msg, int32_t len, relay_config *configs) { static uint8_t buffer[4096]; + uint8_t type = 0; char ifname[configs->interface.size()]; struct sockaddr_in6 target_addr; auto current_buffer_position = buffer; @@ -479,6 +489,9 @@ void relay_client(int sock, const uint8_t *msg, int32_t len, const ip6_hdr *ip_h auto dhcp_relay_header = parse_dhcpv6_relay(msg); current_position += sizeof(struct dhcpv6_relay_msg); + auto position = current_position + sizeof(struct dhcpv6_option); + auto dhcpv6msg = parse_dhcpv6_hdr(position); + while ((current_position - msg) != len) { auto option = parse_dhcpv6_opt(current_position, &tmp); current_position = tmp; @@ -486,6 +499,7 @@ void relay_client(int sock, const uint8_t *msg, int32_t len, const ip6_hdr *ip_h case OPTION_RELAY_MSG: memcpy(current_buffer_position, ((uint8_t *)option) + sizeof(struct dhcpv6_option), ntohs(option->option_length)); current_buffer_position += ntohs(option->option_length); + type = dhcpv6msg->msg_type;; break; default: break; @@ -499,7 +513,7 @@ void relay_client(int sock, const uint8_t *msg, int32_t len, const ip6_hdr *ip_h target_addr.sin6_port = htons(CLIENT_PORT); target_addr.sin6_scope_id = if_nametoindex(ifname); - send_udp(sock, buffer, target_addr, current_buffer_position - buffer); + send_udp(sock, buffer, target_addr, current_buffer_position - buffer, configs, type); } diff --git a/src/dhcp6relay/src/relay.h b/src/dhcp6relay/src/relay.h index 6be60697da..e50d39786b 100644 --- a/src/dhcp6relay/src/relay.h +++ b/src/dhcp6relay/src/relay.h @@ -25,6 +25,7 @@ /* DHCPv6 message types */ typedef enum { + DHCPv6_MESSAGE_TYPE_UNKNOWN = 0, DHCPv6_MESSAGE_TYPE_SOLICIT = 1, DHCPv6_MESSAGE_TYPE_ADVERTISE = 2, DHCPv6_MESSAGE_TYPE_REQUEST = 3, @@ -321,15 +322,17 @@ const struct dhcpv6_relay_msg *parse_dhcpv6_relay(const uint8_t *buffer); const struct dhcpv6_option *parse_dhcpv6_opt(const uint8_t *buffer, const uint8_t **out_end); /** - * @code void send_udp(int sock, uint8_t *buffer, struct sockaddr_in6 target, uint32_t n); + * @code void send_udp(int sock, uint8_t *buffer, struct sockaddr_in6 target, uint32_t n, relay_config *config, uint8_t msg_type); * * @brief send udp packet * * @param *buffer message buffer * @param sockaddr_in6 target target socket * @param n length of message + * @param relay_config *config pointer to relay_config + * @param uint8_t msg_type message type of dhcpv6 option of relayed message * * @return dhcpv6_option end of dhcpv6 message option */ -void send_udp(int sock, struct sockaddr_in6 target, uint8_t *buffer, uint32_t n); +void send_udp(int sock, uint8_t *buffer, struct sockaddr_in6 target, uint32_t n, relay_config *config, uint8_t msg_type);