forked from sonic-net/sonic-dhcp-relay
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfigInterface.cpp
More file actions
156 lines (143 loc) · 4.99 KB
/
Copy pathconfigInterface.cpp
File metadata and controls
156 lines (143 loc) · 4.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#include <sstream>
#include <syslog.h>
#include <algorithm>
#include "configInterface.h"
constexpr auto DEFAULT_TIMEOUT_MSEC = 1000;
bool pollSwssNotifcation = true;
std::shared_ptr<boost::thread> mSwssThreadPtr;
std::shared_ptr<swss::DBConnector> configDbPtr = std::make_shared<swss::DBConnector> ("CONFIG_DB", 0);
swss::SubscriberStateTable ipHelpersTable(configDbPtr.get(), "DHCP_RELAY");
swss::Select swssSelect;
/**
* @code void initialize_swss()
*
* @brief initialize DB tables and start SWSS listening thread
*
* @return none
*/
void initialize_swss(std::vector<relay_config> *vlans)
{
try {
swssSelect.addSelectable(&ipHelpersTable);
get_dhcp(vlans);
mSwssThreadPtr = std::make_shared<boost::thread> (&handleSwssNotification, vlans);
}
catch (const std::bad_alloc &e) {
syslog(LOG_ERR, "Failed allocate memory. Exception details: %s", e.what());
}
}
/**
* @code void deinitialize_swss()
*
* @brief deinitialize DB interface and join SWSS listening thread
*
* @return none
*/
void deinitialize_swss()
{
stopSwssNotificationPoll();
mSwssThreadPtr->interrupt();
}
/**
* @code void get_dhcp(std::vector<relay_config> *vlans)
*
* @brief initialize and get vlan table information from DHCP_RELAY
*
* @return none
*/
void get_dhcp(std::vector<relay_config> *vlans) {
swss::Selectable *selectable;
int ret = swssSelect.select(&selectable, DEFAULT_TIMEOUT_MSEC);
if (ret == swss::Select::ERROR) {
syslog(LOG_WARNING, "Select: returned ERROR");
} else if (ret == swss::Select::TIMEOUT) {
}
if (selectable == static_cast<swss::Selectable *> (&ipHelpersTable)) {
handleRelayNotification(ipHelpersTable, vlans);
}
}
/**
* @code void handleSwssNotification(std::vector<relay_config> *vlans)
*
* @brief main thread for handling SWSS notification
*
* @param context list of vlans/argument config that contains strings of server and option
*
* @return none
*/
void handleSwssNotification(std::vector<relay_config> *vlans)
{
while (pollSwssNotifcation) {
get_dhcp(vlans);
}
}
/**
* @code void handleRelayNotification(swss::SubscriberStateTable &ipHelpersTable, std::vector<relay_config> *vlans)
*
* @brief handles DHCPv6 relay configuration change notification
*
* @param ipHelpersTable DHCP table
* @param vlans list of vlans/argument config that contains strings of server and option
*
* @return none
*/
void handleRelayNotification(swss::SubscriberStateTable &ipHelpersTable, std::vector<relay_config> *vlans)
{
std::deque<swss::KeyOpFieldsValuesTuple> entries;
ipHelpersTable.pops(entries);
processRelayNotification(entries, vlans);
}
/**
* @code void processRelayNotification(std::deque<swss::KeyOpFieldsValuesTuple> &entries, std::vector<relay_config> *vlans)
*
* @brief process DHCPv6 relay servers and options configuration change notification
*
* @param entries queue of std::tuple<std::string, std::string, std::vector<FieldValueTuple>> entries in DHCP table
* @param vlans list of vlans/argument config that contains strings of server and option
*
* @return none
*/
void processRelayNotification(std::deque<swss::KeyOpFieldsValuesTuple> &entries, std::vector<relay_config> *vlans)
{
std::vector<std::string> servers;
for (auto &entry: entries) {
std::string vlan = kfvKey(entry);
std::string operation = kfvOp(entry);
std::vector<swss::FieldValueTuple> fieldValues = kfvFieldsValues(entry);
relay_config intf;
intf.is_option_79 = true;
intf.is_interface_id = false;
intf.interface = vlan;
intf.db = nullptr;
for (auto &fieldValue: fieldValues) {
std::string f = fvField(fieldValue);
std::string v = fvValue(fieldValue);
if(f == "dhcpv6_servers") {
std::stringstream ss(v);
while (ss.good()) {
std::string substr;
getline(ss, substr, ',');
intf.servers.push_back(substr);
}
syslog(LOG_DEBUG, "key: %s, Operation: %s, f: %s, v: %s", vlan.c_str(), operation.c_str(), f.c_str(), v.c_str());
}
if(f == "dhcpv6_option|rfc6939_support" && v == "false") {
intf.is_option_79 = false;
}
if(f == "dhcpv6_option|interface_id" && v == "true") { // interface-id is off by default on non-Dual-ToR, unless specified in config db
intf.is_interface_id = true;
}
}
vlans->push_back(intf);
}
}
/**
*@code stopSwssNotificationPoll
*
*@brief stop SWSS listening thread
*
*@return none
*/
void stopSwssNotificationPoll() {
pollSwssNotifcation = false;
};