140 EV_DEBUG <<
"Parsing config on process " << this->
processID << endl;
142 cXMLElementList intList = interfaceConfig->getElementsByTagName(
"Interface");
143 for (
auto interfaceIt = intList.begin(); interfaceIt != intList.end(); interfaceIt++) {
144 const char *interfaceName = (*interfaceIt)->getAttribute(
"name");
145 NetworkInterface *myInterface =
CHK(
ift->findInterfaceByName(interfaceName));
147 if (
rt4 !=
nullptr && myInterface->isLoopback()) {
148 static const Ipv4Address tmpipv4(
"127.0.0.0");
152 rt4->deleteRoute(
rt4->getRoute(i));
156 cXMLElementList ipAddrList = (*interfaceIt)->getElementsByTagName(
"Ipv6Address");
157 for (
auto& ipv6Rec : ipAddrList) {
158 const char *addr6c = ipv6Rec->getNodeValue();
160 std::string add6 = addr6c;
161 std::string prefix6 = add6.substr(0, add6.find(
"/"));
162 auto intfData6 = myInterface->getProtocolDataForUpdate<Ipv6InterfaceData>();
164 Ipv6Address address6;
165 if (!(address6.tryParseAddrWithPrefix(addr6c, prefLength)))
166 throw cRuntimeError(
"Cannot parse Ipv6 address: '%s", addr6c);
168 address6 = Ipv6Address(prefix6.c_str());
170 Ipv6InterfaceData::AdvPrefix p;
172 p.prefixLength = prefLength;
175 intfData6->assignAddress(address6,
false, SIMTIME_ZERO, SIMTIME_ZERO);
178 Ipv6Route *route =
new Ipv6Route(p.prefix.getPrefix(prefLength), p.prefixLength,
IRoute::IFACENETMASK);
179 route->setInterface(myInterface);
180 route->setExpiryTime(SIMTIME_ZERO);
184 rt6->addRoutingProtocolRoute(route);
189 bool alreadySet =
false;
191 cXMLElementList ipv4AddrList = (*interfaceIt)->getElementsByTagName(
"IPAddress");
192 if (ipv4AddrList.size() == 1) {
194 throw cRuntimeError(
"ipv4 routing table required for current config");
197 auto intfData = myInterface->getProtocolDataForUpdate<Ipv4InterfaceData>();
198 for (
auto& ipv4Rec : ipv4AddrList) {
199 const char *addr4c = ipv4Rec->getNodeValue();
200 addr = (Ipv4Address(addr4c));
205 intfData->setIPAddress(addr);
208 cXMLElementList ipv4MaskList = (*interfaceIt)->getElementsByTagName(
"Mask");
209 if (ipv4MaskList.size() != 1)
210 throw cRuntimeError(
"Interface %s has more or less than one mask", interfaceName);
212 for (
auto& ipv4Rec : ipv4MaskList) {
213 const char *mask4c = ipv4Rec->getNodeValue();
214 mask = (Ipv4Address(mask4c));
215 intfData->setNetmask(mask);
218 Ipv4Address networkAdd = (Ipv4Address((intfData->getIPAddress()).getInt() & (intfData->getNetmask()).getInt()));
219 Ipv4Route *entry =
new Ipv4Route;
221 entry->setDestination(networkAdd);
222 entry->setNetmask(intfData->getNetmask());
223 entry->setInterface(myInterface);
227 rt4->addRoute(entry);
231 else if (ipv4AddrList.size() > 1)
232 throw cRuntimeError(
"Interface %s has more than one IPv4 address ", interfaceName);
234 const char *routerPriority =
nullptr;
235 const char *helloInterval =
nullptr;
236 const char *deadInterval =
nullptr;
237 const char *interfaceCost =
nullptr;
238 const char *interfaceType =
nullptr;
240 bool passiveInterface =
false;
242 cXMLElementList process = (*interfaceIt)->getElementsByTagName(
"Process");
243 if (process.size() > 2)
244 throw cRuntimeError(
"More than two processes configured for interface %s", (*interfaceIt)->getAttribute(
"name"));
247 int processCount = process.size();
248 for (
int i = 0; i < processCount; i++) {
249 int procId = atoi(process.at(i)->getAttribute(
"id"));
253 EV_DEBUG <<
"Creating new interface " << interfaceName <<
" in process " << procId << endl;
256 cXMLElementList instList = process.at(i)->getElementsByTagName(
"Instance");
257 for (
auto instIt = instList.begin(); instIt != instList.end(); instIt++) {
258 const char *instId = (*instIt)->getAttribute(
"instanceID");
259 const char *addressFamily = (*instIt)->getAttribute(
"AF");
262 cXMLElementList interfaceOptions = (*instIt)->getElementsByTagName(
"RouterPriority");
263 if (interfaceOptions.size() > 1)
264 throw cRuntimeError(
"Multiple router priority is configured for interface %s", interfaceName);
266 if (interfaceOptions.size() != 0)
267 routerPriority = interfaceOptions.at(0)->getNodeValue();
270 interfaceOptions = (*instIt)->getElementsByTagName(
"HelloInterval");
271 if (interfaceOptions.size() > 1)
272 throw cRuntimeError(
"Multiple HelloInterval value is configured for interface %s", interfaceName);
274 if (interfaceOptions.size() != 0)
275 helloInterval = interfaceOptions.at(0)->getNodeValue();
278 interfaceOptions = (*instIt)->getElementsByTagName(
"DeadInterval");
279 if (interfaceOptions.size() > 1)
280 throw cRuntimeError(
"Multiple DeadInterval value is configured for interface %s", interfaceName);
282 if (interfaceOptions.size() != 0)
283 deadInterval = interfaceOptions.at(0)->getNodeValue();
286 interfaceOptions = (*instIt)->getElementsByTagName(
"InterfaceCost");
287 if (interfaceOptions.size() > 1)
288 throw cRuntimeError(
"Multiple InterfaceCost value is configured for interface %s", interfaceName);
290 if (interfaceOptions.size() != 0)
291 interfaceCost = interfaceOptions.at(0)->getNodeValue();
294 interfaceOptions = (*instIt)->getElementsByTagName(
"InterfaceType");
295 if (interfaceOptions.size() > 1)
296 throw cRuntimeError(
"Multiple InterfaceType value is configured for interface %s", interfaceName);
298 if (interfaceOptions.size() != 0) {
299 interfaceType = interfaceOptions.at(0)->getNodeValue();
300 if (strcmp(interfaceType,
"Broadcast") == 0)
302 else if (strcmp(interfaceType,
"PointToPoint") == 0)
304 else if (strcmp(interfaceType,
"NBMA") == 0)
306 else if (strcmp(interfaceType,
"PointToMultipoint") == 0)
308 else if (strcmp(interfaceType,
"Virtual") == 0)
314 throw cRuntimeError(
"Interface type needs to be specified for interface %s", interfaceName);
317 interfaceOptions = (*instIt)->getElementsByTagName(
"PassiveInterface");
318 if (interfaceOptions.size() > 1)
319 throw cRuntimeError(
"Multiple PassiveInterface value is configured for interface %s", interfaceName);
321 if (interfaceOptions.size() != 0) {
322 if (strcmp(interfaceOptions.at(0)->getNodeValue(),
"True") == 0)
323 passiveInterface =
true;
328 if (instId ==
nullptr) {
329 EV_DEBUG <<
"Address Family " << addressFamily << endl;
330 if (strcmp(addressFamily,
"IPv4") == 0) {
331 EV_DEBUG <<
"IPv4 instance\n";
334 else if (strcmp(addressFamily,
"IPv6") == 0) {
335 EV_DEBUG <<
"IPv6 instance\n";
339 throw cRuntimeError(
"Unknown address family in process %d", this->
getProcessID());
342 instIdNum = atoi(instId);
350 if (instance ==
nullptr) {
351 if (strcmp(addressFamily,
"IPv4") == 0)
352 instance =
new Ospfv3Instance(instIdNum,
this,
IPV4INSTANCE);
354 instance =
new Ospfv3Instance(instIdNum,
this,
IPV6INSTANCE);
356 EV_DEBUG <<
"Adding instance " << instIdNum <<
" to process " << this->
processID << endl;
361 cXMLElementList areasList = (*instIt)->getElementsByTagName(
"Area");
362 for (
auto areasIt = areasList.begin(); areasIt != areasList.end(); areasIt++) {
363 const char *areaId = (*areasIt)->getNodeValue();
364 Ipv4Address areaIP = Ipv4Address(areaId);
365 const char *areaType = (*areasIt)->getAttribute(
"type");
368 if (areaType !=
nullptr) {
369 if (strcmp(areaType,
"stub") == 0)
371 else if (strcmp(areaType,
"nssa") == 0)
375 const char *summary = (*areasIt)->getAttribute(
"summary");
377 if (summary !=
nullptr) {
378 if (strcmp(summary,
"no") == 0) {
388 if (!(instance->hasArea(areaIP))) {
389 area =
new Ospfv3Area(areaIP, instance,
type);
390 instance->addArea(area);
393 area = instance->getAreaById(areaIP);
395 if (!area->hasInterface(std::string(interfaceName))) {
396 Ospfv3Interface *newInterface =
new Ospfv3Interface(interfaceName, this->
containingModule,
this, interfaceTypeNum, passiveInterface);
397 if (helloInterval !=
nullptr)
398 newInterface->setHelloInterval(atoi(helloInterval));
400 if (deadInterval !=
nullptr)
401 newInterface->setDeadInterval(atoi(deadInterval));
403 if (interfaceCost !=
nullptr)
404 newInterface->setInterfaceCost(atoi(interfaceCost));
406 if (routerPriority !=
nullptr) {
407 int rtrPrio = atoi(routerPriority);
408 if (rtrPrio < 0 || rtrPrio > 255)
409 throw cRuntimeError(
"Router priority out of range on interface %s", interfaceName);
411 newInterface->setRouterPriority(rtrPrio);
414 newInterface->setArea(area);
416 cXMLElementList ipAddrList = (*interfaceIt)->getElementsByTagName(
"Ipv6Address");
417 for (
auto& ipv6Rec : ipAddrList) {
418 const char *addr6c = ipv6Rec->getNodeValue();
419 std::string add6 = addr6c;
420 std::string prefix6 = add6.substr(0, add6.find(
"/"));
422 Ipv6Address address6;
423 if (!(address6.tryParseAddrWithPrefix(addr6c, prefLength)))
424 throw cRuntimeError(
"Cannot parse Ipv6 address: '%s", addr6c);
426 address6 = Ipv6Address(prefix6.c_str());
428 Ipv6AddressRange ipv6addRange;
429 ipv6addRange.prefix = address6;
430 ipv6addRange.prefixLength = prefLength;
431 area->addAddressRange(ipv6addRange,
true);
434 cXMLElementList ipv4AddrList = (*interfaceIt)->getElementsByTagName(
"IPAddress");
435 if (ipv4AddrList.size() == 1) {
436 Ipv4AddressRange ipv4addRange;
437 for (
auto& ipv4Rec : ipv4AddrList) {
438 const char *addr4c = ipv4Rec->getNodeValue();
439 ipv4addRange.address = Ipv4Address(addr4c);
442 cXMLElementList ipv4MaskList = (*interfaceIt)->getElementsByTagName(
"Mask");
443 if (ipv4MaskList.size() != 1)
444 throw cRuntimeError(
"Interface %s has more or less than one mask", interfaceName);
446 for (
auto& ipv4Rec : ipv4MaskList) {
447 const char *mask4c = ipv4Rec->getNodeValue();
448 ipv4addRange.mask = Ipv4Address(mask4c);
450 area->addAddressRange(ipv4addRange,
true);
452 EV_DEBUG <<
"I am " << this->getOwner()->getOwner()->getName() <<
" on int " << newInterface->getInterfaceLLIP() <<
" with area " << area->getAreaID() <<
"\n";
453 area->addInterface(newInterface);