1 #include <boost/lexical_cast.hpp>
3 #include "snmp_pp/snmp_pp.h"
7 #include "subscriber.h"
10 #include "snmptable.h"
16 Switch::Switch(const Settings & settings,
18 const std::string & ip,
19 const std::string & readCommunity,
20 const std::string & writeCommunity,
22 : _settings(settings),
25 _readCommunity(readCommunity),
26 _writeCommunity(writeCommunity),
27 _uplinkPort(uplinkPort),
34 Switch::Switch(const Switch & rvalue)
35 : _settings(rvalue._settings),
38 _readCommunity(rvalue._readCommunity),
39 _writeCommunity(rvalue._writeCommunity),
40 _uplinkPort(rvalue._uplinkPort),
41 _nextUpACL(rvalue._nextUpACL),
42 _nextDownACL(rvalue._nextDownACL),
44 _aclsCreated(rvalue._aclsCreated)
51 IpAddress addr(_ip.c_str());
53 logger << "Switch::~Switch() - ivalid switch ip: '" << _ip << "'" << std::endl;
57 CTarget target(addr, _readCommunity.c_str(), _writeCommunity.c_str());
58 if (!target.valid()) {
59 logger << "Switch::~Switch() - failed to create target for the switch '" << _ip << "'" << std::endl;
63 target.set_version(version2c);
65 if (!checkProfiles(target)) {
66 logger << "Switch::~Switch() - no upload and download profiles defined for the switch '" << _ip << "'" << std::endl;
70 if (!dropACLs(target)) {
71 logger << "Switch::~Switch() - failed to drop ACLs for the switch '" << _ip << "'" << std::endl;
77 Switch & Switch::operator=(const Switch & rvalue)
80 _readCommunity = rvalue._readCommunity;
81 _writeCommunity = rvalue._writeCommunity;
82 _uplinkPort = rvalue._uplinkPort;
83 _nextUpACL = rvalue._nextUpACL;
84 _nextDownACL = rvalue._nextDownACL;
86 _aclsCreated = rvalue._aclsCreated;
91 void Switch::addSubscriber(const Subscriber & subscriber)
93 _acls.push_back(ACL(_nextUpACL++,
94 _settings.upProfileId(),
97 subscriber.getUpShape(),
98 subscriber.getUpBurst(),
100 _acls.push_back(ACL(_nextDownACL++,
101 _settings.downProfileId(),
104 subscriber.getDownShape(),
105 subscriber.getDownBurst(),
111 IpAddress addr(_ip.c_str());
113 logger << "Switch::sync() - ivalid switch ip: '" << _ip << "'" << std::endl;
117 CTarget target(addr, _readCommunity.c_str(), _writeCommunity.c_str());
118 if (!target.valid()) {
119 logger << "Switch::sync() - failed to create target for the switch '" << _ip << "'" << std::endl;
123 target.set_version(version2c);
125 if (!checkProfiles(target)) {
126 logger << "Switch::sync() - no upload and download profiles defined for the switch '" << _ip << "'" << std::endl;
130 if (!dropACLs(target)) {
131 logger << "Switch::sync() - failed to drop ACLs for the switch '" << _ip << "'" << std::endl;
135 if (!createACLs(target)) {
136 logger << "Switch::sync() - failed to create ACLs for the switch '" << _ip << "'" << std::endl;
140 if (_settings.isDebug()) {
141 logger << "Switch::sync() - switch '" << _ip << "' synchronized successfully, ACLs: " << _acls.size() << std::endl;
145 bool Switch::checkProfiles(const CTarget & target)
147 SNMPTable table(_snmp, target, Oid(swACLEtherRuleProfileID));
148 if (!table.valid()) {
149 logger << "Switch::checkProfiles() - profiles SNMPTable is invalid for the switch '" << _ip << "'" << std::endl;
153 // Ok, just an empty table
156 if (table.valueExists(
157 static_cast<int>(_settings.upProfileId())
160 static_cast<int>(_settings.downProfileId())
167 bool Switch::dropACLs(const CTarget & target)
169 std::string upOidValue(swACLEtherRuleAccessID);
171 upOidValue += boost::lexical_cast<std::string>(_settings.upProfileId());
172 std::string downOidValue(swACLEtherRuleAccessID);
174 downOidValue += boost::lexical_cast<std::string>(_settings.downProfileId());
175 SNMPTable aclsUpTable(_snmp, target, Oid(upOidValue.c_str()));
176 SNMPTable aclsDownTable(_snmp, target, Oid(downOidValue.c_str()));
177 if (!aclsUpTable.valid()) {
178 logger << "Switch::dropACLs() - upload profile acls SNMPTable is invalid for the switch '" << _ip << "'" << std::endl;
181 if (!aclsDownTable.valid()) {
182 logger << "Switch::dropACLs() - download profile acls SNMPTable is invalid for the switch '" << _ip << "'" << std::endl;
185 if (!aclsUpTable.empty()) {
186 if (!dropACLsByTable(target, _settings.upProfileId(), aclsUpTable)) {
187 logger << "Switch::dropACLs() - failed to drop acls from upload table for the switch '" << _ip << "'" << std::endl;
191 if (!aclsDownTable.empty()) {
192 if (!dropACLsByTable(target, _settings.downProfileId(), aclsDownTable)) {
193 logger << "Switch::dropACLs() - failed to drop acls from download table for the switch '" << _ip << "'" << std::endl;
200 bool Switch::dropACLsByTable(const CTarget & target, unsigned profileId, const SNMPTable & table)
202 std::string dropACLOidPrefix(swACLEtherRuleRowStatus);
203 dropACLOidPrefix += ".";
204 dropACLOidPrefix += boost::lexical_cast<std::string>(profileId);
205 SNMPList aclsList(table.getList());
206 SNMPList::const_iterator it(aclsList.begin());
207 size_t chunks = aclsList.size() / _settings.maxACLPerPDU() + 1;
208 for (size_t i = 0; i < chunks && it != aclsList.end(); ++i) {
210 for (size_t j = 0; j < _settings.maxACLPerPDU() && it != aclsList.end(); ++j, ++it) {
212 if (int c = it->get_value(id) != SNMP_CLASS_SUCCESS) {
213 logger << "Switch::dropACLsByTable() - failed to get ACL id for the switch '" << _ip << "'. Error message: '" << Snmp::error_msg(c) << "'" << std::endl;
216 std::string dropACLOid(dropACLOidPrefix);
218 dropACLOid += boost::lexical_cast<std::string>(id);
219 Vb vb(Oid(dropACLOid.c_str()));
220 vb.set_value(int(6));
223 if (int c = _snmp.set(pdu, target) != SNMP_CLASS_SUCCESS) {
224 if (c != SNMP_ERROR_TOO_BIG) {
225 logger << "Switch::dropACLsByTable() - failed to invoke Snmp::set for the switch '" << _ip << "'. Error message: '" << Snmp::error_msg(c) << "'" << std::endl;
233 bool Switch::createACLs(const CTarget & target)
235 std::vector<ACL>::const_iterator it;
237 for (it = _acls.begin(); it != _acls.end(); ++it) {
240 if (int c = _snmp.set(pdu, target) != SNMP_CLASS_SUCCESS) {
241 if (c != SNMP_ERROR_TOO_BIG) {
242 logger << "Switch::createACLs() - failed to invoke Snmp::set for the switch '" << _ip << "'. Error message: '" << Snmp::error_msg(c) << "'. Error occured at creation of " << (pos + 1) << " from " << _acls.size() << " ACL's" << std::endl;
243 logger << "Switch::createACLs() - ACL dump: " << *it << std::endl;