Skip to content

Commit 142a7ae

Browse files
committed
Add interface-id option (#8)
* Add interface-id option * Add out of bound check
1 parent 9a1cc2a commit 142a7ae

File tree

3 files changed

+29
-1
lines changed

3 files changed

+29
-1
lines changed

src/configInterface.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ void processRelayNotification(std::deque<swss::KeyOpFieldsValuesTuple> &entries,
120120

121121
relay_config intf;
122122
intf.is_option_79 = true;
123+
intf.is_interface_id = false;
123124
intf.interface = vlan;
124125
for (auto &fieldValue: fieldValues) {
125126
std::string f = fvField(fieldValue);
@@ -136,6 +137,9 @@ void processRelayNotification(std::deque<swss::KeyOpFieldsValuesTuple> &entries,
136137
if(f == "dhcpv6_option|rfc6939_support" && v == "false") {
137138
intf.is_option_79 = false;
138139
}
140+
if(f == "dhcpv6_option|interface_id" && v == "true") { // interface-id is off by default on non-Dual-ToR, unless specified in config db
141+
intf.is_interface_id = true;
142+
}
139143
}
140144
vlans->push_back(intf);
141145
}

src/relay.cpp

+17-1
Original file line numberDiff line numberDiff line change
@@ -434,14 +434,30 @@ void relay_client(int sock, const uint8_t *msg, int32_t len, const ip6_hdr *ip_h
434434
option79.link_layer_type = htons(1);
435435
option79.option_code = htons(OPTION_CLIENT_LINKLAYER_ADDR);
436436
option79.option_length = htons(2 + 6); // link_layer_type field + address
437-
437+
438+
if ((unsigned)(current_buffer_position + sizeof(linklayer_addr_option) - buffer) > sizeof(buffer)) {
439+
return;
440+
}
438441
memcpy(current_buffer_position, &option79, sizeof(linklayer_addr_option));
439442
current_buffer_position += sizeof(linklayer_addr_option);
440443

441444
memcpy(current_buffer_position, &ether_hdr->ether_shost, sizeof(ether_hdr->ether_shost));
442445
current_buffer_position += sizeof(ether_hdr->ether_shost);
443446
}
444447

448+
if(config->is_interface_id) {
449+
interface_id_option intf_id;
450+
intf_id.option_code = htons(OPTION_INTERFACE_ID);
451+
intf_id.option_length = htons(sizeof(in6_addr));
452+
intf_id.interface_id = config->link_address.sin6_addr;
453+
454+
if ((unsigned)(current_buffer_position + sizeof(linklayer_addr_option) - buffer) > sizeof(buffer)) {
455+
return;
456+
}
457+
memcpy(current_buffer_position, &intf_id, sizeof(interface_id_option));
458+
current_buffer_position += sizeof(interface_id_option);
459+
}
460+
445461
auto dhcp_message_length = len;
446462
relay_forward(current_buffer_position, parse_dhcpv6_hdr(msg), dhcp_message_length);
447463
current_buffer_position += dhcp_message_length + sizeof(dhcpv6_option);

src/relay.h

+8
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#define lengthof(A) (sizeof (A) / sizeof (A)[0])
2424

2525
#define OPTION_RELAY_MSG 9
26+
#define OPTION_INTERFACE_ID 18
2627
#define OPTION_CLIENT_LINKLAYER_ADDR 79
2728

2829
/* DHCPv6 message types */
@@ -54,6 +55,7 @@ struct relay_config {
5455
std::vector<std::string> servers;
5556
std::vector<sockaddr_in6> servers_sock;
5657
bool is_option_79;
58+
bool is_interface_id;
5759
};
5860

5961

@@ -82,6 +84,12 @@ struct linklayer_addr_option {
8284
uint16_t link_layer_type;
8385
};
8486

87+
struct interface_id_option {
88+
uint16_t option_code;
89+
uint16_t option_length;
90+
in6_addr interface_id; // to accomodate dual-tor, this opaque value is set to carry relay interface's global ipv6 address
91+
};
92+
8593
/**
8694
* @code sock_open(int ifindex, const struct sock_fprog *fprog);
8795
*

0 commit comments

Comments
 (0)