Committed by
Gerrit Code Review
CORD-484 Support management network for a VM
Change-Id: I866ae3ae7d839cd29f1732605170f3dfbab402bb
Showing
3 changed files
with
168 additions
and
15 deletions
| ... | @@ -38,7 +38,8 @@ public final class CordService { | ... | @@ -38,7 +38,8 @@ public final class CordService { |
| 38 | PRIVATE_DIRECT, | 38 | PRIVATE_DIRECT, |
| 39 | PRIVATE_INDIRECT, | 39 | PRIVATE_INDIRECT, |
| 40 | PUBLIC_DIRECT, | 40 | PUBLIC_DIRECT, |
| 41 | - PUBLIC_INDIRECT | 41 | + PUBLIC_INDIRECT, |
| 42 | + MANAGEMENT | ||
| 42 | } | 43 | } |
| 43 | 44 | ||
| 44 | private final CordServiceId id; | 45 | private final CordServiceId id; |
| ... | @@ -165,7 +166,7 @@ public final class CordService { | ... | @@ -165,7 +166,7 @@ public final class CordService { |
| 165 | * It assumes that network name contains network type. | 166 | * It assumes that network name contains network type. |
| 166 | * | 167 | * |
| 167 | * @param netName network name | 168 | * @param netName network name |
| 168 | - * @return network type, or null if it doesn't match any type | 169 | + * @return network type, or PRIVATE if it doesn't match any type |
| 169 | */ | 170 | */ |
| 170 | private ServiceType getServiceType(String netName) { | 171 | private ServiceType getServiceType(String netName) { |
| 171 | checkNotNull(netName); | 172 | checkNotNull(netName); |
| ... | @@ -179,10 +180,10 @@ public final class CordService { | ... | @@ -179,10 +180,10 @@ public final class CordService { |
| 179 | return PUBLIC_DIRECT; | 180 | return PUBLIC_DIRECT; |
| 180 | } else if (name.contains(PUBLIC_INDIRECT.toString())) { | 181 | } else if (name.contains(PUBLIC_INDIRECT.toString())) { |
| 181 | return PUBLIC_INDIRECT; | 182 | return PUBLIC_INDIRECT; |
| 182 | - } else if (name.contains(PRIVATE.toString())) { | 183 | + } else if (name.contains(MANAGEMENT.toString())) { |
| 183 | - return PRIVATE; | 184 | + return MANAGEMENT; |
| 184 | } else { | 185 | } else { |
| 185 | - return null; | 186 | + return PRIVATE; |
| 186 | } | 187 | } |
| 187 | } | 188 | } |
| 188 | } | 189 | } | ... | ... |
| ... | @@ -403,7 +403,13 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -403,7 +403,13 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
| 403 | host.ipAddresses().stream().findFirst().get()); | 403 | host.ipAddresses().stream().findFirst().get()); |
| 404 | 404 | ||
| 405 | CordService service = getCordService(vNet); | 405 | CordService service = getCordService(vNet); |
| 406 | - if (service != null) { | 406 | + if (service == null) { |
| 407 | + return; | ||
| 408 | + } | ||
| 409 | + | ||
| 410 | + if (service.serviceType().equals(CordService.ServiceType.MANAGEMENT)) { | ||
| 411 | + ruleInstaller.populateManagementNetworkRules(host, service); | ||
| 412 | + } else { | ||
| 407 | // TODO check if the service needs an update on its group buckets after done CORD-433 | 413 | // TODO check if the service needs an update on its group buckets after done CORD-433 |
| 408 | ruleInstaller.updateServiceGroup(service); | 414 | ruleInstaller.updateServiceGroup(service); |
| 409 | arpProxy.addServiceIp(service.serviceIp()); | 415 | arpProxy.addServiceIp(service.serviceIp()); |
| ... | @@ -440,7 +446,13 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -440,7 +446,13 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
| 440 | ruleInstaller.removeBasicConnectionRules(host); | 446 | ruleInstaller.removeBasicConnectionRules(host); |
| 441 | 447 | ||
| 442 | CordService service = getCordService(vNet); | 448 | CordService service = getCordService(vNet); |
| 443 | - if (service != null) { | 449 | + if (service == null) { |
| 450 | + return; | ||
| 451 | + } | ||
| 452 | + | ||
| 453 | + if (service.serviceType().equals(CordService.ServiceType.MANAGEMENT)) { | ||
| 454 | + ruleInstaller.removeManagementNetworkRules(host, service); | ||
| 455 | + } else { | ||
| 444 | // TODO check if the service needs an update on its group buckets after done CORD-433 | 456 | // TODO check if the service needs an update on its group buckets after done CORD-433 |
| 445 | ruleInstaller.updateServiceGroup(service); | 457 | ruleInstaller.updateServiceGroup(service); |
| 446 | 458 | ... | ... |
| ... | @@ -103,10 +103,11 @@ public class CordVtnRuleInstaller { | ... | @@ -103,10 +103,11 @@ public class CordVtnRuleInstaller { |
| 103 | private static final int TABLE_DST_IP = 4; | 103 | private static final int TABLE_DST_IP = 4; |
| 104 | private static final int TABLE_TUNNEL_IN = 5; | 104 | private static final int TABLE_TUNNEL_IN = 5; |
| 105 | 105 | ||
| 106 | + private static final int MANAGEMENT_PRIORITY = 55000; | ||
| 107 | + private static final int HIGH_PRIORITY = 50000; | ||
| 106 | private static final int DEFAULT_PRIORITY = 5000; | 108 | private static final int DEFAULT_PRIORITY = 5000; |
| 107 | - private static final int LOWER_PRIORITY = 4000; | 109 | + private static final int LOW_PRIORITY = 4000; |
| 108 | private static final int LOWEST_PRIORITY = 0; | 110 | private static final int LOWEST_PRIORITY = 0; |
| 109 | - private static final int HIGHER_PRIORITY = 50000; | ||
| 110 | 111 | ||
| 111 | private static final int VXLAN_UDP_PORT = 4789; | 112 | private static final int VXLAN_UDP_PORT = 4789; |
| 112 | 113 | ||
| ... | @@ -387,6 +388,126 @@ public class CordVtnRuleInstaller { | ... | @@ -387,6 +388,126 @@ public class CordVtnRuleInstaller { |
| 387 | } | 388 | } |
| 388 | 389 | ||
| 389 | /** | 390 | /** |
| 391 | + * Populates flow rules for management network access. | ||
| 392 | + * | ||
| 393 | + * @param host host which has management network interface | ||
| 394 | + * @param mService management network service | ||
| 395 | + */ | ||
| 396 | + public void populateManagementNetworkRules(Host host, CordService mService) { | ||
| 397 | + checkNotNull(mService); | ||
| 398 | + | ||
| 399 | + DeviceId deviceId = host.location().deviceId(); | ||
| 400 | + IpAddress hostIp = host.ipAddresses().stream().findFirst().get(); | ||
| 401 | + | ||
| 402 | + TrafficSelector selector = DefaultTrafficSelector.builder() | ||
| 403 | + .matchEthType(Ethernet.TYPE_ARP) | ||
| 404 | + .matchArpTpa(mService.serviceIp().getIp4Address()) | ||
| 405 | + .build(); | ||
| 406 | + | ||
| 407 | + TrafficTreatment treatment = DefaultTrafficTreatment.builder() | ||
| 408 | + .setOutput(PortNumber.LOCAL) | ||
| 409 | + .build(); | ||
| 410 | + | ||
| 411 | + FlowRule flowRule = DefaultFlowRule.builder() | ||
| 412 | + .fromApp(appId) | ||
| 413 | + .withSelector(selector) | ||
| 414 | + .withTreatment(treatment) | ||
| 415 | + .withPriority(MANAGEMENT_PRIORITY) | ||
| 416 | + .forDevice(deviceId) | ||
| 417 | + .forTable(TABLE_FIRST) | ||
| 418 | + .makePermanent() | ||
| 419 | + .build(); | ||
| 420 | + | ||
| 421 | + processFlowRule(true, flowRule); | ||
| 422 | + | ||
| 423 | + selector = DefaultTrafficSelector.builder() | ||
| 424 | + .matchInPort(PortNumber.LOCAL) | ||
| 425 | + .matchEthType(Ethernet.TYPE_ARP) | ||
| 426 | + .matchArpTpa(hostIp.getIp4Address()) | ||
| 427 | + .build(); | ||
| 428 | + | ||
| 429 | + treatment = DefaultTrafficTreatment.builder() | ||
| 430 | + .setOutput(host.location().port()) | ||
| 431 | + .build(); | ||
| 432 | + | ||
| 433 | + flowRule = DefaultFlowRule.builder() | ||
| 434 | + .fromApp(appId) | ||
| 435 | + .withSelector(selector) | ||
| 436 | + .withTreatment(treatment) | ||
| 437 | + .withPriority(MANAGEMENT_PRIORITY) | ||
| 438 | + .forDevice(deviceId) | ||
| 439 | + .forTable(TABLE_FIRST) | ||
| 440 | + .makePermanent() | ||
| 441 | + .build(); | ||
| 442 | + | ||
| 443 | + processFlowRule(true, flowRule); | ||
| 444 | + | ||
| 445 | + selector = DefaultTrafficSelector.builder() | ||
| 446 | + .matchInPort(PortNumber.LOCAL) | ||
| 447 | + .matchEthType(Ethernet.TYPE_IPV4) | ||
| 448 | + .matchIPDst(mService.serviceIpRange()) | ||
| 449 | + .build(); | ||
| 450 | + | ||
| 451 | + treatment = DefaultTrafficTreatment.builder() | ||
| 452 | + .transition(TABLE_DST_IP) | ||
| 453 | + .build(); | ||
| 454 | + | ||
| 455 | + flowRule = DefaultFlowRule.builder() | ||
| 456 | + .fromApp(appId) | ||
| 457 | + .withSelector(selector) | ||
| 458 | + .withTreatment(treatment) | ||
| 459 | + .withPriority(MANAGEMENT_PRIORITY) | ||
| 460 | + .forDevice(deviceId) | ||
| 461 | + .forTable(TABLE_FIRST) | ||
| 462 | + .makePermanent() | ||
| 463 | + .build(); | ||
| 464 | + | ||
| 465 | + processFlowRule(true, flowRule); | ||
| 466 | + | ||
| 467 | + selector = DefaultTrafficSelector.builder() | ||
| 468 | + .matchEthType(Ethernet.TYPE_IPV4) | ||
| 469 | + .matchIPDst(mService.serviceIp().toIpPrefix()) | ||
| 470 | + .build(); | ||
| 471 | + | ||
| 472 | + treatment = DefaultTrafficTreatment.builder() | ||
| 473 | + .setOutput(PortNumber.LOCAL) | ||
| 474 | + .build(); | ||
| 475 | + | ||
| 476 | + flowRule = DefaultFlowRule.builder() | ||
| 477 | + .fromApp(appId) | ||
| 478 | + .withSelector(selector) | ||
| 479 | + .withTreatment(treatment) | ||
| 480 | + .withPriority(MANAGEMENT_PRIORITY) | ||
| 481 | + .forDevice(deviceId) | ||
| 482 | + .forTable(TABLE_ACCESS_TYPE) | ||
| 483 | + .makePermanent() | ||
| 484 | + .build(); | ||
| 485 | + | ||
| 486 | + processFlowRule(true, flowRule); | ||
| 487 | + } | ||
| 488 | + | ||
| 489 | + /** | ||
| 490 | + * Removes management network access rules. | ||
| 491 | + * | ||
| 492 | + * @param host host to be removed | ||
| 493 | + * @param mService service for management network | ||
| 494 | + */ | ||
| 495 | + public void removeManagementNetworkRules(Host host, CordService mService) { | ||
| 496 | + checkNotNull(mService); | ||
| 497 | + | ||
| 498 | + for (FlowRule flowRule : flowRuleService.getFlowRulesById(appId)) { | ||
| 499 | + if (flowRule.deviceId().equals(host.location().deviceId())) { | ||
| 500 | + PortNumber port = getOutputFromTreatment(flowRule); | ||
| 501 | + if (port != null && port.equals(host.location().port())) { | ||
| 502 | + processFlowRule(false, flowRule); | ||
| 503 | + } | ||
| 504 | + } | ||
| 505 | + | ||
| 506 | + // TODO remove the other rules if mgmt network is not in use | ||
| 507 | + } | ||
| 508 | + } | ||
| 509 | + | ||
| 510 | + /** | ||
| 390 | * Populates default rules on the first table. | 511 | * Populates default rules on the first table. |
| 391 | * The rules are for shuttling vxlan-encapped packets and supporting physical | 512 | * The rules are for shuttling vxlan-encapped packets and supporting physical |
| 392 | * network connectivity. | 513 | * network connectivity. |
| ... | @@ -409,7 +530,7 @@ public class CordVtnRuleInstaller { | ... | @@ -409,7 +530,7 @@ public class CordVtnRuleInstaller { |
| 409 | .fromApp(appId) | 530 | .fromApp(appId) |
| 410 | .withSelector(selector) | 531 | .withSelector(selector) |
| 411 | .withTreatment(treatment) | 532 | .withTreatment(treatment) |
| 412 | - .withPriority(HIGHER_PRIORITY) | 533 | + .withPriority(HIGH_PRIORITY) |
| 413 | .forDevice(deviceId) | 534 | .forDevice(deviceId) |
| 414 | .forTable(TABLE_FIRST) | 535 | .forTable(TABLE_FIRST) |
| 415 | .makePermanent() | 536 | .makePermanent() |
| ... | @@ -433,7 +554,7 @@ public class CordVtnRuleInstaller { | ... | @@ -433,7 +554,7 @@ public class CordVtnRuleInstaller { |
| 433 | .fromApp(appId) | 554 | .fromApp(appId) |
| 434 | .withSelector(selector) | 555 | .withSelector(selector) |
| 435 | .withTreatment(treatment) | 556 | .withTreatment(treatment) |
| 436 | - .withPriority(HIGHER_PRIORITY) | 557 | + .withPriority(HIGH_PRIORITY) |
| 437 | .forDevice(deviceId) | 558 | .forDevice(deviceId) |
| 438 | .forTable(TABLE_FIRST) | 559 | .forTable(TABLE_FIRST) |
| 439 | .makePermanent() | 560 | .makePermanent() |
| ... | @@ -456,7 +577,7 @@ public class CordVtnRuleInstaller { | ... | @@ -456,7 +577,7 @@ public class CordVtnRuleInstaller { |
| 456 | .fromApp(appId) | 577 | .fromApp(appId) |
| 457 | .withSelector(selector) | 578 | .withSelector(selector) |
| 458 | .withTreatment(treatment) | 579 | .withTreatment(treatment) |
| 459 | - .withPriority(HIGHER_PRIORITY) | 580 | + .withPriority(HIGH_PRIORITY) |
| 460 | .forDevice(deviceId) | 581 | .forDevice(deviceId) |
| 461 | .forTable(TABLE_FIRST) | 582 | .forTable(TABLE_FIRST) |
| 462 | .makePermanent() | 583 | .makePermanent() |
| ... | @@ -479,7 +600,7 @@ public class CordVtnRuleInstaller { | ... | @@ -479,7 +600,7 @@ public class CordVtnRuleInstaller { |
| 479 | .fromApp(appId) | 600 | .fromApp(appId) |
| 480 | .withSelector(selector) | 601 | .withSelector(selector) |
| 481 | .withTreatment(treatment) | 602 | .withTreatment(treatment) |
| 482 | - .withPriority(HIGHER_PRIORITY) | 603 | + .withPriority(HIGH_PRIORITY) |
| 483 | .forDevice(deviceId) | 604 | .forDevice(deviceId) |
| 484 | .forTable(TABLE_FIRST) | 605 | .forTable(TABLE_FIRST) |
| 485 | .makePermanent() | 606 | .makePermanent() |
| ... | @@ -633,7 +754,7 @@ public class CordVtnRuleInstaller { | ... | @@ -633,7 +754,7 @@ public class CordVtnRuleInstaller { |
| 633 | .fromApp(appId) | 754 | .fromApp(appId) |
| 634 | .withSelector(selector) | 755 | .withSelector(selector) |
| 635 | .withTreatment(treatment) | 756 | .withTreatment(treatment) |
| 636 | - .withPriority(LOWER_PRIORITY) | 757 | + .withPriority(LOW_PRIORITY) |
| 637 | .forDevice(deviceId) | 758 | .forDevice(deviceId) |
| 638 | .forTable(TABLE_IN_PORT) | 759 | .forTable(TABLE_IN_PORT) |
| 639 | .makePermanent() | 760 | .makePermanent() |
| ... | @@ -665,7 +786,7 @@ public class CordVtnRuleInstaller { | ... | @@ -665,7 +786,7 @@ public class CordVtnRuleInstaller { |
| 665 | .fromApp(appId) | 786 | .fromApp(appId) |
| 666 | .withSelector(selector) | 787 | .withSelector(selector) |
| 667 | .withTreatment(treatment) | 788 | .withTreatment(treatment) |
| 668 | - .withPriority(LOWER_PRIORITY) | 789 | + .withPriority(LOW_PRIORITY) |
| 669 | .forDevice(device.id()) | 790 | .forDevice(device.id()) |
| 670 | .forTable(TABLE_ACCESS_TYPE) | 791 | .forTable(TABLE_ACCESS_TYPE) |
| 671 | .makePermanent() | 792 | .makePermanent() |
| ... | @@ -1006,6 +1127,25 @@ public class CordVtnRuleInstaller { | ... | @@ -1006,6 +1127,25 @@ public class CordVtnRuleInstaller { |
| 1006 | } | 1127 | } |
| 1007 | 1128 | ||
| 1008 | /** | 1129 | /** |
| 1130 | + * Returns the output port number from a given flow rule. | ||
| 1131 | + * | ||
| 1132 | + * @param flowRule flow rule | ||
| 1133 | + * @return port number, or null if the rule does not have output instruction | ||
| 1134 | + */ | ||
| 1135 | + private PortNumber getOutputFromTreatment(FlowRule flowRule) { | ||
| 1136 | + Instruction instruction = flowRule.treatment().allInstructions().stream() | ||
| 1137 | + .filter(inst -> inst instanceof Instructions.OutputInstruction) | ||
| 1138 | + .findFirst() | ||
| 1139 | + .orElse(null); | ||
| 1140 | + | ||
| 1141 | + if (instruction == null) { | ||
| 1142 | + return null; | ||
| 1143 | + } | ||
| 1144 | + | ||
| 1145 | + return ((Instructions.OutputInstruction) instruction).port(); | ||
| 1146 | + } | ||
| 1147 | + | ||
| 1148 | + /** | ||
| 1009 | * Creates a new group for a given service. | 1149 | * Creates a new group for a given service. |
| 1010 | * | 1150 | * |
| 1011 | * @param deviceId device id to create a group | 1151 | * @param deviceId device id to create a group | ... | ... |
-
Please register or login to post a comment