Skip to content

Commit 60c9c0b

Browse files
authored
[DHCPv6 Relay] [202106] Fix kernel memory allocation, log verbosity and dhcpmon bugs (#8975)
Signed-off-by: Shlomi Bitton <[email protected]>
1 parent 58f082c commit 60c9c0b

File tree

6 files changed

+74
-8
lines changed

6 files changed

+74
-8
lines changed

files/dhcp/90-dhcp6-systcl.conf.j2

+2
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@ net.ipv6.conf.eth0.accept_ra = 0
55
net.ipv6.conf.eth0.accept_ra_defrtr = 1
66
net.ipv6.conf.eth0.accept_ra = 1
77
{% endif %}
8+
{# socket memory allocation size = (default value)20480 * 2 #}
9+
net.core.optmem_max=40960

src/dhcpmon/src/dhcp_device.c

+37-8
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ static struct sock_fprog dhcp_sock_bfp = {
121121
*/
122122
static dhcp_device_context_t aggregate_dev = {0};
123123

124+
static dhcp_device_context_t *mgmt_intf = NULL;
125+
124126
/** Monitored DHCPv4 message type */
125127
static dhcpv4_message_type_t v4_monitored_msgs[] = {
126128
DHCPv4_MESSAGE_TYPE_DISCOVER,
@@ -176,6 +178,11 @@ static void handle_dhcp_option_53(dhcp_device_context_t *context,
176178
if ((context->giaddr_ip == giaddr && context->is_uplink && dir == DHCP_TX) ||
177179
(!context->is_uplink && dir == DHCP_RX && iphdr->ip_dst.s_addr == INADDR_BROADCAST)) {
178180
context->counters.v4counters[DHCP_COUNTERS_CURRENT][dir][dhcp_option[2]]++;
181+
// If the packet recieved on the mgmt interface, we don't want to increment the aggregate device
182+
if (context == mgmt_intf)
183+
{
184+
break;
185+
}
179186
aggregate_dev.counters.v4counters[DHCP_COUNTERS_CURRENT][dir][dhcp_option[2]]++;
180187
}
181188
break;
@@ -186,6 +193,11 @@ static void handle_dhcp_option_53(dhcp_device_context_t *context,
186193
if ((context->giaddr_ip == iphdr->ip_dst.s_addr && context->is_uplink && dir == DHCP_RX) ||
187194
(!context->is_uplink && dir == DHCP_TX)) {
188195
context->counters.v4counters[DHCP_COUNTERS_CURRENT][dir][dhcp_option[2]]++;
196+
// If the packet recieved on the mgmt interface, we don't want to increment the aggregate device
197+
if (context == mgmt_intf)
198+
{
199+
break;
200+
}
189201
aggregate_dev.counters.v4counters[DHCP_COUNTERS_CURRENT][dir][dhcp_option[2]]++;
190202
}
191203
break;
@@ -224,6 +236,11 @@ static void handle_dhcpv6_option(dhcp_device_context_t *context,
224236
case DHCPv6_MESSAGE_TYPE_RECONFIGURE:
225237
case DHCPv6_MESSAGE_TYPE_INFORMATION_REQUEST:
226238
context->counters.v6counters[DHCP_COUNTERS_CURRENT][dir][dhcp_option]++;
239+
// If the packet recieved on the mgmt interface, we don't want to increment the aggregate device
240+
if (context == mgmt_intf)
241+
{
242+
break;
243+
}
227244
aggregate_dev.counters.v6counters[DHCP_COUNTERS_CURRENT][dir][dhcp_option]++;
228245
break;
229246
default:
@@ -309,7 +326,7 @@ static void read_callback(int fd, short event, void *arg)
309326
}
310327
}
311328
else if (!is_ipv4 && dhcpv6_enabled && (buffer_sz > UDPv6_START_OFFSET + sizeof(struct udphdr) + DHCPv6_TYPE_LENGTH)) {
312-
const u_char* dhcp_option = context->buffer + dhcp_option_offset;
329+
const u_char* dhcp_header = context->buffer + dhcp_option_offset;
313330
dhcp_packet_direction_t dir = (ethhdr->ether_shost[0] == context->mac[0] &&
314331
ethhdr->ether_shost[1] == context->mac[1] &&
315332
ethhdr->ether_shost[2] == context->mac[2] &&
@@ -319,23 +336,25 @@ static void read_callback(int fd, short event, void *arg)
319336
DHCP_TX : DHCP_RX;
320337
int offset = 0;
321338
uint16_t option = 0;
339+
uint16_t current_option_len = 0;
322340
// Get to inner DHCP header from encapsulated RELAY_FORWARD or RELAY_REPLY header
323-
while (dhcp_option[offset] == DHCPv6_MESSAGE_TYPE_RELAY_FORWARD || dhcp_option[offset] == DHCPv6_MESSAGE_TYPE_RELAY_REPLY)
341+
while (dhcp_header[offset] == DHCPv6_MESSAGE_TYPE_RELAY_FORWARD || dhcp_header[offset] == DHCPv6_MESSAGE_TYPE_RELAY_REPLY)
324342
{
325343
// Get to DHCPv6_OPTION_RELAY_MSG from all options
326344
offset += DHCPv6_RELAY_MSG_OPTIONS_OFFSET;
327-
option = htons(*((uint16_t*)(&(dhcp_option[offset]))));
345+
option = htons(*((uint16_t*)(&(dhcp_header[offset]))));
328346

329347
while (option != DHCPv6_OPTION_RELAY_MSG)
330348
{
331-
offset += DHCPv6_OPTION_LENGTH;
332349
// Add to offset the option length and get the next option ID
333-
offset += htons(*((uint16_t*)(&(dhcp_option[offset]))));
334-
option = htons(*((uint16_t*)(&(dhcp_option[offset]))));
350+
current_option_len = htons(*((uint16_t*)(&(dhcp_header[offset + DHCPv6_OPTION_LENGTH]))));
351+
offset += DHCPv6_OPTION_LENGTH + DHCPv6_OPTION_LEN_LENGTH + current_option_len;
352+
option = htons(*((uint16_t*)(&(dhcp_header[offset]))));
335353
}
354+
// Set the offset to DHCP-relay-message data
336355
offset += DHCPv6_OPTION_LENGTH + DHCPv6_OPTION_LEN_LENGTH;
337356
}
338-
handle_dhcpv6_option(context, dhcp_option[offset], dir);
357+
handle_dhcpv6_option(context, dhcp_header[offset], dir);
339358
} else {
340359
syslog(LOG_WARNING, "read_callback(%s): read length (%ld) is too small to capture DHCP options",
341360
context->intf, buffer_sz);
@@ -554,7 +573,7 @@ static dhcp_mon_status_t dhcp_device_check_health(dhcp_mon_check_t check_type,
554573
{
555574
dhcp_mon_status_t rv = DHCP_MON_STATUS_HEALTHY;
556575

557-
if (dhcp_device_is_dhcp_inactive(aggregate_dev.counters.v4counters, aggregate_dev.counters.v6counters, type)) {
576+
if (dhcp_device_is_dhcp_inactive(v4counters, v6counters, type)) {
558577
rv = DHCP_MON_STATUS_INDETERMINATE;
559578
} else if (check_type == DHCP_MON_CHECK_POSITIVE) {
560579
rv = dhcp_device_check_positive_health(v4counters, v6counters, type);
@@ -948,3 +967,13 @@ void dhcp_device_active_types(bool dhcpv4, bool dhcpv6)
948967
dhcpv4_enabled = dhcpv4;
949968
dhcpv6_enabled = dhcpv6;
950969
}
970+
971+
/**
972+
* @code dhcp_device_init_mgmt_intf(mgmt_intf_context);
973+
*
974+
* @brief assign context address of mgmt interface
975+
*/
976+
void dhcp_device_init_mgmt_intf(dhcp_device_context_t *mgmt_intf_context)
977+
{
978+
mgmt_intf = mgmt_intf_context;
979+
}

src/dhcpmon/src/dhcp_device.h

+11
Original file line numberDiff line numberDiff line change
@@ -255,4 +255,15 @@ void dhcp_device_print_status(dhcp_device_context_t *context, dhcp_counters_type
255255
* @return none
256256
*/
257257
void dhcp_device_active_types(bool dhcpv4, bool dhcpv6);
258+
259+
/**
260+
* @code dhcp_device_init_mgmt_intf(mgmt_intf_context);
261+
*
262+
* @brief assign context address of mgmt interface
263+
*
264+
* @param mgmt_intf_context MGMT interface context struct address
265+
*
266+
* @return none
267+
*/
268+
void dhcp_device_init_mgmt_intf(dhcp_device_context_t *mgmt_intf_context);
258269
#endif /* DHCP_DEVICE_H_ */

src/dhcpmon/src/dhcp_devman.c

+3
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,9 @@ int dhcp_devman_add_intf(const char *name, char intf_type)
148148
strncpy(agg_dev->intf + sizeof(AGG_DEV_PREFIX) - 1, name, sizeof(agg_dev->intf) - sizeof(AGG_DEV_PREFIX));
149149
agg_dev->intf[sizeof(agg_dev->intf) - 1] = '\0';
150150
}
151+
else if (rv == 0 && intf_type == 'm') {
152+
dhcp_device_init_mgmt_intf(dev->dev_context);
153+
}
151154

152155
LIST_INSERT_HEAD(&intfs, dev, entry);
153156
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
diff --git a/common/socket.c b/common/socket.c
2+
index da9f501..fa2a49c 100644
3+
--- a/common/socket.c
4+
+++ b/common/socket.c
5+
@@ -975,7 +975,14 @@ ssize_t send_packet6(struct interface_info *interface,
6+
7+
result = sendmsg(interface->wfdesc, &m, 0);
8+
if (result < 0) {
9+
- log_error("send_packet6: %m");
10+
+ /* 'Network is unreachable' should log as INFO,
11+
+ since not all up link interfaces have routes to the DHCP servers. */
12+
+ if (errno == 101) {
13+
+ log_info("send_packet6: %m");
14+
+ }
15+
+ else {
16+
+ log_error("send_packet6: %m");
17+
+ }
18+
}
19+
return result;
20+
}

src/isc-dhcp/patch/series

+1
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@
1111
0010-Bugfix-correctly-set-interface-netmask.patch
1212
0011-dhcp-relay-Prevent-Buffer-Overrun.patch
1313
0012-add-option-si-to-support-using-src-intf-ip-in-relay.patch
14+
0013-Change-verbosity-level-for-unreachable-network-error.patch

0 commit comments

Comments
 (0)