Committed by
Ray Milkey
Changes include:
bug fix for host IP and MAC flows not being generated sometimes in multi-controller scenarios bug fix for filtering objectives not being sent sometimes when ports become available later npe fixes in ofdpa driver for cases where selectors or treatments may not be available new cli command to manually trigger routing and rule population portstats option on cli to display only those ports with non-zero stats group cli command tab completion displays choices in lower case (similar to flows) segment routing cli commands now start with sr- Change-Id: Idcd641882d180acbd304e5560ed3483b5a943f96
Showing
20 changed files
with
181 additions
and
24 deletions
... | @@ -32,6 +32,9 @@ import java.util.ArrayList; | ... | @@ -32,6 +32,9 @@ import java.util.ArrayList; |
32 | import java.util.HashMap; | 32 | import java.util.HashMap; |
33 | import java.util.HashSet; | 33 | import java.util.HashSet; |
34 | import java.util.Set; | 34 | import java.util.Set; |
35 | +import java.util.concurrent.Executors; | ||
36 | +import java.util.concurrent.ScheduledExecutorService; | ||
37 | +import java.util.concurrent.TimeUnit; | ||
35 | import java.util.concurrent.locks.Lock; | 38 | import java.util.concurrent.locks.Lock; |
36 | import java.util.concurrent.locks.ReentrantLock; | 39 | import java.util.concurrent.locks.ReentrantLock; |
37 | 40 | ||
... | @@ -53,6 +56,8 @@ public class DefaultRoutingHandler { | ... | @@ -53,6 +56,8 @@ public class DefaultRoutingHandler { |
53 | private DeviceConfiguration config; | 56 | private DeviceConfiguration config; |
54 | private final Lock statusLock = new ReentrantLock(); | 57 | private final Lock statusLock = new ReentrantLock(); |
55 | private volatile Status populationStatus; | 58 | private volatile Status populationStatus; |
59 | + private static final int MAX_RETRY_ATTEMPTS = 5; | ||
60 | + private ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1); | ||
56 | 61 | ||
57 | /** | 62 | /** |
58 | * Represents the default routing population status. | 63 | * Represents the default routing population status. |
... | @@ -515,9 +520,17 @@ public class DefaultRoutingHandler { | ... | @@ -515,9 +520,17 @@ public class DefaultRoutingHandler { |
515 | * @param deviceId Switch ID to set the rules | 520 | * @param deviceId Switch ID to set the rules |
516 | */ | 521 | */ |
517 | public void populatePortAddressingRules(DeviceId deviceId) { | 522 | public void populatePortAddressingRules(DeviceId deviceId) { |
518 | - rulePopulator.populateRouterMacVlanFilters(deviceId); | ||
519 | rulePopulator.populateXConnectVlanFilters(deviceId); | 523 | rulePopulator.populateXConnectVlanFilters(deviceId); |
520 | rulePopulator.populateRouterIpPunts(deviceId); | 524 | rulePopulator.populateRouterIpPunts(deviceId); |
525 | + | ||
526 | + // Although device is added, sometimes device store does not have the | ||
527 | + // ports for this device yet. It results in missing filtering rules in the | ||
528 | + // switch. We will attempt it a few times. If it still does not work, | ||
529 | + // user can manually repopulate using CLI command sr-reroute-network | ||
530 | + boolean success = rulePopulator.populateRouterMacVlanFilters(deviceId); | ||
531 | + if (!success) { | ||
532 | + executorService.schedule(new RetryFilters(deviceId), 200, TimeUnit.MILLISECONDS); | ||
533 | + } | ||
521 | } | 534 | } |
522 | 535 | ||
523 | /** | 536 | /** |
... | @@ -568,4 +581,25 @@ public class DefaultRoutingHandler { | ... | @@ -568,4 +581,25 @@ public class DefaultRoutingHandler { |
568 | updatedEcmpSpgMap.remove(deviceId); | 581 | updatedEcmpSpgMap.remove(deviceId); |
569 | } | 582 | } |
570 | } | 583 | } |
584 | + | ||
585 | + private class RetryFilters implements Runnable { | ||
586 | + int attempts = MAX_RETRY_ATTEMPTS; | ||
587 | + DeviceId devId; | ||
588 | + | ||
589 | + public RetryFilters(DeviceId deviceId) { | ||
590 | + devId = deviceId; | ||
591 | + } | ||
592 | + | ||
593 | + @Override | ||
594 | + public void run() { | ||
595 | + boolean success = rulePopulator.populateRouterMacVlanFilters(devId); | ||
596 | + if (!success && --attempts > 0) { | ||
597 | + executorService.schedule(this, 200, TimeUnit.MILLISECONDS); | ||
598 | + } else if (attempts == 0) { | ||
599 | + log.error("Unable to populate MacVlan filters in dev:{}", devId); | ||
600 | + } | ||
601 | + } | ||
602 | + | ||
603 | + } | ||
604 | + | ||
571 | } | 605 | } | ... | ... |
... | @@ -62,18 +62,28 @@ public class HostHandler { | ... | @@ -62,18 +62,28 @@ public class HostHandler { |
62 | flowObjectiveService = srManager.flowObjectiveService; | 62 | flowObjectiveService = srManager.flowObjectiveService; |
63 | } | 63 | } |
64 | 64 | ||
65 | - protected void readInitialHosts() { | 65 | + protected void readInitialHosts(DeviceId devId) { |
66 | hostService.getHosts().forEach(host -> { | 66 | hostService.getHosts().forEach(host -> { |
67 | + DeviceId deviceId = host.location().deviceId(); | ||
68 | + if (!deviceId.equals(devId)) { | ||
69 | + // not an attached host to this device | ||
70 | + return; | ||
71 | + } | ||
67 | MacAddress mac = host.mac(); | 72 | MacAddress mac = host.mac(); |
68 | VlanId vlanId = host.vlan(); | 73 | VlanId vlanId = host.vlan(); |
69 | - DeviceId deviceId = host.location().deviceId(); | ||
70 | PortNumber port = host.location().port(); | 74 | PortNumber port = host.location().port(); |
71 | Set<IpAddress> ips = host.ipAddresses(); | 75 | Set<IpAddress> ips = host.ipAddresses(); |
72 | - log.debug("Host {}/{} is added at {}:{}", mac, vlanId, deviceId, port); | 76 | + log.debug("Attached Host {}/{} is added at {}:{}", mac, vlanId, |
77 | + deviceId, port); | ||
73 | 78 | ||
74 | // Populate bridging table entry | 79 | // Populate bridging table entry |
75 | ForwardingObjective.Builder fob = | 80 | ForwardingObjective.Builder fob = |
76 | getForwardingObjectiveBuilder(deviceId, mac, vlanId, port); | 81 | getForwardingObjectiveBuilder(deviceId, mac, vlanId, port); |
82 | + if (fob == null) { | ||
83 | + log.warn("Aborting host bridging & routing table entries due " | ||
84 | + + "to error for dev:{} host:{}", deviceId, host); | ||
85 | + return; | ||
86 | + } | ||
77 | ObjectiveContext context = new DefaultObjectiveContext( | 87 | ObjectiveContext context = new DefaultObjectiveContext( |
78 | (objective) -> log.debug("Host rule for {} populated", host), | 88 | (objective) -> log.debug("Host rule for {} populated", host), |
79 | (objective, error) -> | 89 | (objective, error) -> |
... | @@ -127,6 +137,10 @@ public class HostHandler { | ... | @@ -127,6 +137,10 @@ public class HostHandler { |
127 | int portNextObjId = srManager.getPortNextObjectiveId(deviceId, outport, | 137 | int portNextObjId = srManager.getPortNextObjectiveId(deviceId, outport, |
128 | tbuilder.build(), | 138 | tbuilder.build(), |
129 | meta); | 139 | meta); |
140 | + if (portNextObjId == -1) { | ||
141 | + // warning log will come from getPortNextObjective method | ||
142 | + return null; | ||
143 | + } | ||
130 | 144 | ||
131 | return DefaultForwardingObjective.builder() | 145 | return DefaultForwardingObjective.builder() |
132 | .withFlag(ForwardingObjective.Flag.SPECIFIC) | 146 | .withFlag(ForwardingObjective.Flag.SPECIFIC) | ... | ... |
... | @@ -114,6 +114,11 @@ public class RoutingRulePopulator { | ... | @@ -114,6 +114,11 @@ public class RoutingRulePopulator { |
114 | log.warn(e.getMessage() + " Aborting populateIpRuleForHost."); | 114 | log.warn(e.getMessage() + " Aborting populateIpRuleForHost."); |
115 | return; | 115 | return; |
116 | } | 116 | } |
117 | + if (fwdBuilder == null) { | ||
118 | + log.warn("Aborting host routing table entries due " | ||
119 | + + "to error for dev:{} host:{}", deviceId, hostIp); | ||
120 | + return; | ||
121 | + } | ||
117 | ObjectiveContext context = new DefaultObjectiveContext( | 122 | ObjectiveContext context = new DefaultObjectiveContext( |
118 | (objective) -> log.debug("IP rule for host {} populated", hostIp), | 123 | (objective) -> log.debug("IP rule for host {} populated", hostIp), |
119 | (objective, error) -> | 124 | (objective, error) -> |
... | @@ -191,7 +196,10 @@ public class RoutingRulePopulator { | ... | @@ -191,7 +196,10 @@ public class RoutingRulePopulator { |
191 | .matchVlanId(outvlan).build(); | 196 | .matchVlanId(outvlan).build(); |
192 | int portNextObjId = srManager.getPortNextObjectiveId(deviceId, outPort, | 197 | int portNextObjId = srManager.getPortNextObjectiveId(deviceId, outPort, |
193 | treatment, meta); | 198 | treatment, meta); |
194 | - | 199 | + if (portNextObjId == -1) { |
200 | + // warning log will come from getPortNextObjective method | ||
201 | + return null; | ||
202 | + } | ||
195 | return DefaultForwardingObjective.builder() | 203 | return DefaultForwardingObjective.builder() |
196 | .withSelector(selector) | 204 | .withSelector(selector) |
197 | .nextStep(portNextObjId) | 205 | .nextStep(portNextObjId) |
... | @@ -464,7 +472,7 @@ public class RoutingRulePopulator { | ... | @@ -464,7 +472,7 @@ public class RoutingRulePopulator { |
464 | * | 472 | * |
465 | * @param deviceId the switch dpid for the router | 473 | * @param deviceId the switch dpid for the router |
466 | */ | 474 | */ |
467 | - public void populateRouterMacVlanFilters(DeviceId deviceId) { | 475 | + public boolean populateRouterMacVlanFilters(DeviceId deviceId) { |
468 | log.debug("Installing per-port filtering objective for untagged " | 476 | log.debug("Installing per-port filtering objective for untagged " |
469 | + "packets in device {}", deviceId); | 477 | + "packets in device {}", deviceId); |
470 | 478 | ||
... | @@ -473,10 +481,17 @@ public class RoutingRulePopulator { | ... | @@ -473,10 +481,17 @@ public class RoutingRulePopulator { |
473 | deviceMac = config.getDeviceMac(deviceId); | 481 | deviceMac = config.getDeviceMac(deviceId); |
474 | } catch (DeviceConfigNotFoundException e) { | 482 | } catch (DeviceConfigNotFoundException e) { |
475 | log.warn(e.getMessage() + " Aborting populateRouterMacVlanFilters."); | 483 | log.warn(e.getMessage() + " Aborting populateRouterMacVlanFilters."); |
476 | - return; | 484 | + return false; |
477 | } | 485 | } |
478 | 486 | ||
479 | - for (Port port : srManager.deviceService.getPorts(deviceId)) { | 487 | + List<Port> devPorts = srManager.deviceService.getPorts(deviceId); |
488 | + if (devPorts != null && devPorts.size() == 0) { | ||
489 | + log.warn("Device {} ports not available. Unable to add MacVlan filters", | ||
490 | + deviceId); | ||
491 | + return false; | ||
492 | + } | ||
493 | + | ||
494 | + for (Port port : devPorts) { | ||
480 | ConnectPoint connectPoint = new ConnectPoint(deviceId, port.number()); | 495 | ConnectPoint connectPoint = new ConnectPoint(deviceId, port.number()); |
481 | // TODO: Handles dynamic port events when we are ready for dynamic config | 496 | // TODO: Handles dynamic port events when we are ready for dynamic config |
482 | if (!srManager.deviceConfiguration.suppressSubnet().contains(connectPoint) && | 497 | if (!srManager.deviceConfiguration.suppressSubnet().contains(connectPoint) && |
... | @@ -498,6 +513,7 @@ public class RoutingRulePopulator { | ... | @@ -498,6 +513,7 @@ public class RoutingRulePopulator { |
498 | fob.withMeta(tt); | 513 | fob.withMeta(tt); |
499 | } | 514 | } |
500 | fob.permit().fromApp(srManager.appId); | 515 | fob.permit().fromApp(srManager.appId); |
516 | + log.debug("Sending filtering objective for dev/port:{}/{}", deviceId, port); | ||
501 | ObjectiveContext context = new DefaultObjectiveContext( | 517 | ObjectiveContext context = new DefaultObjectiveContext( |
502 | (objective) -> log.debug("Filter for {} populated", connectPoint), | 518 | (objective) -> log.debug("Filter for {} populated", connectPoint), |
503 | (objective, error) -> | 519 | (objective, error) -> |
... | @@ -505,6 +521,7 @@ public class RoutingRulePopulator { | ... | @@ -505,6 +521,7 @@ public class RoutingRulePopulator { |
505 | srManager.flowObjectiveService.filter(deviceId, fob.add(context)); | 521 | srManager.flowObjectiveService.filter(deviceId, fob.add(context)); |
506 | } | 522 | } |
507 | } | 523 | } |
524 | + return true; | ||
508 | } | 525 | } |
509 | 526 | ||
510 | /** | 527 | /** | ... | ... |
... | @@ -434,6 +434,15 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -434,6 +434,15 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
434 | return policyHandler.getPolicies(); | 434 | return policyHandler.getPolicies(); |
435 | } | 435 | } |
436 | 436 | ||
437 | + @Override | ||
438 | + public void rerouteNetwork() { | ||
439 | + cfgListener.configureNetwork(); | ||
440 | + for (Device device : deviceService.getDevices()) { | ||
441 | + defaultRoutingHandler.populatePortAddressingRules(device.id()); | ||
442 | + } | ||
443 | + defaultRoutingHandler.startPopulationProcess(); | ||
444 | + } | ||
445 | + | ||
437 | /** | 446 | /** |
438 | * Returns the tunnel object with the tunnel ID. | 447 | * Returns the tunnel object with the tunnel ID. |
439 | * | 448 | * |
... | @@ -567,7 +576,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -567,7 +576,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
567 | * @param portNum port number on device for which NextObjective is queried | 576 | * @param portNum port number on device for which NextObjective is queried |
568 | * @param treatment the actions to apply on the packets (should include outport) | 577 | * @param treatment the actions to apply on the packets (should include outport) |
569 | * @param meta metadata passed into the creation of a Next Objective if necessary | 578 | * @param meta metadata passed into the creation of a Next Objective if necessary |
570 | - * @return next objective ID or -1 if it was not found | 579 | + * @return next objective ID or -1 if an error occurred during retrieval or creation |
571 | */ | 580 | */ |
572 | public int getPortNextObjectiveId(DeviceId deviceId, PortNumber portNum, | 581 | public int getPortNextObjectiveId(DeviceId deviceId, PortNumber portNum, |
573 | TrafficTreatment treatment, | 582 | TrafficTreatment treatment, |
... | @@ -801,9 +810,9 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -801,9 +810,9 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
801 | // port addressing rules to the driver as well irrespective of whether | 810 | // port addressing rules to the driver as well irrespective of whether |
802 | // this instance is the master or not. | 811 | // this instance is the master or not. |
803 | defaultRoutingHandler.populatePortAddressingRules(device.id()); | 812 | defaultRoutingHandler.populatePortAddressingRules(device.id()); |
804 | - hostHandler.readInitialHosts(); | ||
805 | } | 813 | } |
806 | if (mastershipService.isLocalMaster(device.id())) { | 814 | if (mastershipService.isLocalMaster(device.id())) { |
815 | + hostHandler.readInitialHosts(device.id()); | ||
807 | DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id()); | 816 | DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id()); |
808 | groupHandler.createGroupsFromSubnetConfig(); | 817 | groupHandler.createGroupsFromSubnetConfig(); |
809 | routingRulePopulator.populateSubnetBroadcastRule(device.id()); | 818 | routingRulePopulator.populateSubnetBroadcastRule(device.id()); |
... | @@ -897,6 +906,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -897,6 +906,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
897 | // for any switch (even if this instance is a SLAVE or not even connected | 906 | // for any switch (even if this instance is a SLAVE or not even connected |
898 | // to the switch). To handle this, a default-group-handler instance is necessary | 907 | // to the switch). To handle this, a default-group-handler instance is necessary |
899 | // per switch. | 908 | // per switch. |
909 | + log.debug("Current groupHandlerMap devs: {}", groupHandlerMap.keySet()); | ||
900 | if (groupHandlerMap.get(device.id()) == null) { | 910 | if (groupHandlerMap.get(device.id()) == null) { |
901 | DefaultGroupHandler groupHandler; | 911 | DefaultGroupHandler groupHandler; |
902 | try { | 912 | try { |
... | @@ -911,6 +921,8 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -911,6 +921,8 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
911 | log.warn(e.getMessage() + " Aborting configureNetwork."); | 921 | log.warn(e.getMessage() + " Aborting configureNetwork."); |
912 | return; | 922 | return; |
913 | } | 923 | } |
924 | + log.debug("updating groupHandlerMap with new config for " | ||
925 | + + "device: {}", device.id()); | ||
914 | groupHandlerMap.put(device.id(), groupHandler); | 926 | groupHandlerMap.put(device.id(), groupHandler); |
915 | 927 | ||
916 | // Also, in some cases, drivers may need extra | 928 | // Also, in some cases, drivers may need extra |
... | @@ -918,9 +930,9 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -918,9 +930,9 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
918 | // port addressing rules to the driver as well, irrespective of whether | 930 | // port addressing rules to the driver as well, irrespective of whether |
919 | // this instance is the master or not. | 931 | // this instance is the master or not. |
920 | defaultRoutingHandler.populatePortAddressingRules(device.id()); | 932 | defaultRoutingHandler.populatePortAddressingRules(device.id()); |
921 | - hostHandler.readInitialHosts(); | ||
922 | } | 933 | } |
923 | if (mastershipService.isLocalMaster(device.id())) { | 934 | if (mastershipService.isLocalMaster(device.id())) { |
935 | + hostHandler.readInitialHosts(device.id()); | ||
924 | DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id()); | 936 | DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id()); |
925 | groupHandler.createGroupsFromSubnetConfig(); | 937 | groupHandler.createGroupsFromSubnetConfig(); |
926 | routingRulePopulator.populateSubnetBroadcastRule(device.id()); | 938 | routingRulePopulator.populateSubnetBroadcastRule(device.id()); | ... | ... |
... | @@ -103,4 +103,10 @@ public interface SegmentRoutingService { | ... | @@ -103,4 +103,10 @@ public interface SegmentRoutingService { |
103 | * SUCCESS if it is removed successfully | 103 | * SUCCESS if it is removed successfully |
104 | */ | 104 | */ |
105 | PolicyHandler.Result removePolicy(Policy policy); | 105 | PolicyHandler.Result removePolicy(Policy policy); |
106 | + | ||
107 | + /** | ||
108 | + * Use current state of the network to repopulate forwarding rules. | ||
109 | + * | ||
110 | + */ | ||
111 | + void rerouteNetwork(); | ||
106 | } | 112 | } | ... | ... |
... | @@ -26,7 +26,7 @@ import org.onosproject.segmentrouting.TunnelPolicy; | ... | @@ -26,7 +26,7 @@ import org.onosproject.segmentrouting.TunnelPolicy; |
26 | /** | 26 | /** |
27 | * Command to add a new policy. | 27 | * Command to add a new policy. |
28 | */ | 28 | */ |
29 | -@Command(scope = "onos", name = "srpolicy-add", | 29 | +@Command(scope = "onos", name = "sr-policy-add", |
30 | description = "Create a new policy") | 30 | description = "Create a new policy") |
31 | public class PolicyAddCommand extends AbstractShellCommand { | 31 | public class PolicyAddCommand extends AbstractShellCommand { |
32 | 32 | ... | ... |
... | @@ -24,7 +24,7 @@ import org.onosproject.segmentrouting.TunnelPolicy; | ... | @@ -24,7 +24,7 @@ import org.onosproject.segmentrouting.TunnelPolicy; |
24 | /** | 24 | /** |
25 | * Command to show the list of policies. | 25 | * Command to show the list of policies. |
26 | */ | 26 | */ |
27 | -@Command(scope = "onos", name = "srpolicy-list", | 27 | +@Command(scope = "onos", name = "sr-policy-list", |
28 | description = "Lists all policies") | 28 | description = "Lists all policies") |
29 | public class PolicyListCommand extends AbstractShellCommand { | 29 | public class PolicyListCommand extends AbstractShellCommand { |
30 | 30 | ... | ... |
... | @@ -26,7 +26,7 @@ import org.onosproject.segmentrouting.TunnelPolicy; | ... | @@ -26,7 +26,7 @@ import org.onosproject.segmentrouting.TunnelPolicy; |
26 | /** | 26 | /** |
27 | * Command to remove a policy. | 27 | * Command to remove a policy. |
28 | */ | 28 | */ |
29 | -@Command(scope = "onos", name = "srpolicy-remove", | 29 | +@Command(scope = "onos", name = "sr-policy-remove", |
30 | description = "Remove a policy") | 30 | description = "Remove a policy") |
31 | public class PolicyRemoveCommand extends AbstractShellCommand { | 31 | public class PolicyRemoveCommand extends AbstractShellCommand { |
32 | 32 | ... | ... |
apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/cli/RerouteNetworkCommand.java
0 → 100644
1 | +package org.onosproject.segmentrouting.cli; | ||
2 | + | ||
3 | + | ||
4 | +import org.apache.karaf.shell.commands.Command; | ||
5 | +import org.onosproject.cli.AbstractShellCommand; | ||
6 | +import org.onosproject.segmentrouting.SegmentRoutingService; | ||
7 | + | ||
8 | +/** | ||
9 | + * Command to manually trigger routing and rule-population in the network. | ||
10 | + * | ||
11 | + */ | ||
12 | +@Command(scope = "onos", name = "sr-reroute-network", | ||
13 | + description = "Repopulate routing rules given current network state") | ||
14 | +public class RerouteNetworkCommand extends AbstractShellCommand { | ||
15 | + | ||
16 | + @Override | ||
17 | + protected void execute() { | ||
18 | + SegmentRoutingService srService = | ||
19 | + AbstractShellCommand.get(SegmentRoutingService.class); | ||
20 | + srService.rerouteNetwork(); | ||
21 | + } | ||
22 | + | ||
23 | +} |
... | @@ -31,7 +31,7 @@ import java.util.StringTokenizer; | ... | @@ -31,7 +31,7 @@ import java.util.StringTokenizer; |
31 | /** | 31 | /** |
32 | * Command to add a new tunnel. | 32 | * Command to add a new tunnel. |
33 | */ | 33 | */ |
34 | -@Command(scope = "onos", name = "srtunnel-add", | 34 | +@Command(scope = "onos", name = "sr-tunnel-add", |
35 | description = "Create a new tunnel") | 35 | description = "Create a new tunnel") |
36 | public class TunnelAddCommand extends AbstractShellCommand { | 36 | public class TunnelAddCommand extends AbstractShellCommand { |
37 | 37 | ... | ... |
... | @@ -23,7 +23,7 @@ import org.onosproject.segmentrouting.Tunnel; | ... | @@ -23,7 +23,7 @@ import org.onosproject.segmentrouting.Tunnel; |
23 | /** | 23 | /** |
24 | * Command to show the list of tunnels. | 24 | * Command to show the list of tunnels. |
25 | */ | 25 | */ |
26 | -@Command(scope = "onos", name = "srtunnel-list", | 26 | +@Command(scope = "onos", name = "sr-tunnel-list", |
27 | description = "Lists all tunnels") | 27 | description = "Lists all tunnels") |
28 | public class TunnelListCommand extends AbstractShellCommand { | 28 | public class TunnelListCommand extends AbstractShellCommand { |
29 | 29 | ... | ... |
... | @@ -28,7 +28,7 @@ import org.onosproject.segmentrouting.TunnelHandler; | ... | @@ -28,7 +28,7 @@ import org.onosproject.segmentrouting.TunnelHandler; |
28 | /** | 28 | /** |
29 | * Command to remove a tunnel. | 29 | * Command to remove a tunnel. |
30 | */ | 30 | */ |
31 | -@Command(scope = "onos", name = "srtunnel-remove", | 31 | +@Command(scope = "onos", name = "sr-tunnel-remove", |
32 | description = "Remove a tunnel") | 32 | description = "Remove a tunnel") |
33 | public class TunnelRemoveCommand extends AbstractShellCommand { | 33 | public class TunnelRemoveCommand extends AbstractShellCommand { |
34 | 34 | ... | ... |
... | @@ -101,8 +101,8 @@ public class DeviceConfiguration implements DeviceProperties { | ... | @@ -101,8 +101,8 @@ public class DeviceConfiguration implements DeviceProperties { |
101 | info.mac = config.routerMac(); | 101 | info.mac = config.routerMac(); |
102 | info.isEdge = config.isEdgeRouter(); | 102 | info.isEdge = config.isEdgeRouter(); |
103 | info.adjacencySids = config.adjacencySids(); | 103 | info.adjacencySids = config.adjacencySids(); |
104 | - | ||
105 | deviceConfigMap.put(info.deviceId, info); | 104 | deviceConfigMap.put(info.deviceId, info); |
105 | + log.info("Read device config for device: {}", info.deviceId); | ||
106 | allSegmentIds.add(info.nodeSid); | 106 | allSegmentIds.add(info.nodeSid); |
107 | }); | 107 | }); |
108 | 108 | ... | ... |
... | @@ -197,6 +197,10 @@ public class DefaultGroupHandler { | ... | @@ -197,6 +197,10 @@ public class DefaultGroupHandler { |
197 | 197 | ||
198 | log.info("* LinkUP: Device {} linkUp at local port {} to neighbor {}", deviceId, | 198 | log.info("* LinkUP: Device {} linkUp at local port {} to neighbor {}", deviceId, |
199 | newLink.src().port(), newLink.dst().deviceId()); | 199 | newLink.src().port(), newLink.dst().deviceId()); |
200 | + // ensure local state is updated even if linkup is aborted later on | ||
201 | + addNeighborAtPort(newLink.dst().deviceId(), | ||
202 | + newLink.src().port()); | ||
203 | + | ||
200 | MacAddress dstMac; | 204 | MacAddress dstMac; |
201 | try { | 205 | try { |
202 | dstMac = deviceConfig.getDeviceMac(newLink.dst().deviceId()); | 206 | dstMac = deviceConfig.getDeviceMac(newLink.dst().deviceId()); |
... | @@ -205,8 +209,6 @@ public class DefaultGroupHandler { | ... | @@ -205,8 +209,6 @@ public class DefaultGroupHandler { |
205 | return; | 209 | return; |
206 | } | 210 | } |
207 | 211 | ||
208 | - addNeighborAtPort(newLink.dst().deviceId(), | ||
209 | - newLink.src().port()); | ||
210 | /*if (devicePortMap.get(newLink.dst().deviceId()) == null) { | 212 | /*if (devicePortMap.get(newLink.dst().deviceId()) == null) { |
211 | // New Neighbor | 213 | // New Neighbor |
212 | newNeighbor(newLink); | 214 | newNeighbor(newLink); | ... | ... |
... | @@ -34,6 +34,9 @@ | ... | @@ -34,6 +34,9 @@ |
34 | <command> | 34 | <command> |
35 | <action class="org.onosproject.segmentrouting.cli.TunnelRemoveCommand"/> | 35 | <action class="org.onosproject.segmentrouting.cli.TunnelRemoveCommand"/> |
36 | </command> | 36 | </command> |
37 | + <command> | ||
38 | + <action class="org.onosproject.segmentrouting.cli.RerouteNetworkCommand"/> | ||
39 | + </command> | ||
37 | </command-bundle> | 40 | </command-bundle> |
38 | </blueprint> | 41 | </blueprint> |
39 | 42 | ... | ... |
... | @@ -36,6 +36,10 @@ import org.onosproject.net.device.PortStatistics; | ... | @@ -36,6 +36,10 @@ import org.onosproject.net.device.PortStatistics; |
36 | description = "Lists statistics of all ports in the system") | 36 | description = "Lists statistics of all ports in the system") |
37 | public class DevicePortStatsCommand extends DevicesListCommand { | 37 | public class DevicePortStatsCommand extends DevicesListCommand { |
38 | 38 | ||
39 | + @Option(name = "-nz", aliases = "--nonzero", description = "Show only non-zero portstats", | ||
40 | + required = false, multiValued = false) | ||
41 | + private boolean nonzero = false; | ||
42 | + | ||
39 | @Option(name = "-d", aliases = "--delta", description = "Show Delta Port Statistics," | 43 | @Option(name = "-d", aliases = "--delta", description = "Show Delta Port Statistics," |
40 | + "only for the last polling interval", | 44 | + "only for the last polling interval", |
41 | required = false, multiValued = false) | 45 | required = false, multiValued = false) |
... | @@ -100,6 +104,9 @@ public class DevicePortStatsCommand extends DevicesListCommand { | ... | @@ -100,6 +104,9 @@ public class DevicePortStatsCommand extends DevicesListCommand { |
100 | if (portNumber != null && stat.port() != portNumber) { | 104 | if (portNumber != null && stat.port() != portNumber) { |
101 | continue; | 105 | continue; |
102 | } | 106 | } |
107 | + if (nonzero && stat.isZero()) { | ||
108 | + continue; | ||
109 | + } | ||
103 | print(FORMAT, stat.port(), stat.packetsReceived(), stat.packetsSent(), stat.bytesReceived(), | 110 | print(FORMAT, stat.port(), stat.packetsReceived(), stat.packetsSent(), stat.bytesReceived(), |
104 | stat.bytesSent(), stat.packetsRxDropped(), stat.packetsTxDropped(), stat.durationSec()); | 111 | stat.bytesSent(), stat.packetsRxDropped(), stat.packetsTxDropped(), stat.durationSec()); |
105 | } | 112 | } |
... | @@ -118,6 +125,9 @@ public class DevicePortStatsCommand extends DevicesListCommand { | ... | @@ -118,6 +125,9 @@ public class DevicePortStatsCommand extends DevicesListCommand { |
118 | if (portNumber != null && stat.port() != portNumber) { | 125 | if (portNumber != null && stat.port() != portNumber) { |
119 | continue; | 126 | continue; |
120 | } | 127 | } |
128 | + if (nonzero && stat.isZero()) { | ||
129 | + continue; | ||
130 | + } | ||
121 | float duration = ((float) stat.durationSec()) + | 131 | float duration = ((float) stat.durationSec()) + |
122 | (((float) stat.durationNano()) / TimeUnit.SECONDS.toNanos(1)); | 132 | (((float) stat.durationNano()) / TimeUnit.SECONDS.toNanos(1)); |
123 | float rateRx = stat.bytesReceived() * 8 / duration; | 133 | float rateRx = stat.bytesReceived() * 8 / duration; |
... | @@ -154,6 +164,9 @@ public class DevicePortStatsCommand extends DevicesListCommand { | ... | @@ -154,6 +164,9 @@ public class DevicePortStatsCommand extends DevicesListCommand { |
154 | if (portNumber != null && stat.port() != portNumber) { | 164 | if (portNumber != null && stat.port() != portNumber) { |
155 | continue; | 165 | continue; |
156 | } | 166 | } |
167 | + if (nonzero && stat.isZero()) { | ||
168 | + continue; | ||
169 | + } | ||
157 | float duration = ((float) stat.durationSec()) + | 170 | float duration = ((float) stat.durationSec()) + |
158 | (((float) stat.durationNano()) / TimeUnit.SECONDS.toNanos(1)); | 171 | (((float) stat.durationNano()) / TimeUnit.SECONDS.toNanos(1)); |
159 | float rateRx = stat.bytesReceived() * 8 / duration; | 172 | float rateRx = stat.bytesReceived() * 8 / duration; | ... | ... |
... | @@ -29,7 +29,7 @@ public class GroupStatusCompleter extends AbstractChoicesCompleter { | ... | @@ -29,7 +29,7 @@ public class GroupStatusCompleter extends AbstractChoicesCompleter { |
29 | protected List<String> choices() { | 29 | protected List<String> choices() { |
30 | List<String> strings = Lists.newArrayList(); | 30 | List<String> strings = Lists.newArrayList(); |
31 | for (Group.GroupState groupState : Group.GroupState.values()) { | 31 | for (Group.GroupState groupState : Group.GroupState.values()) { |
32 | - strings.add(groupState.toString()); | 32 | + strings.add(groupState.toString().toLowerCase()); |
33 | } | 33 | } |
34 | strings.add(GroupsListCommand.ANY); | 34 | strings.add(GroupsListCommand.ANY); |
35 | return strings; | 35 | return strings; | ... | ... |
... | @@ -142,6 +142,16 @@ public final class DefaultPortStatistics implements PortStatistics { | ... | @@ -142,6 +142,16 @@ public final class DefaultPortStatistics implements PortStatistics { |
142 | } | 142 | } |
143 | 143 | ||
144 | @Override | 144 | @Override |
145 | + public boolean isZero() { | ||
146 | + return bytesReceived() == 0 && | ||
147 | + bytesSent() == 0 && | ||
148 | + packetsReceived() == 0 && | ||
149 | + packetsRxDropped() == 0 && | ||
150 | + packetsSent() == 0 && | ||
151 | + packetsTxDropped() == 0; | ||
152 | + } | ||
153 | + | ||
154 | + @Override | ||
145 | public String toString() { | 155 | public String toString() { |
146 | StringBuilder sb = new StringBuilder("device: " + deviceId + ", "); | 156 | StringBuilder sb = new StringBuilder("device: " + deviceId + ", "); |
147 | 157 | ||
... | @@ -343,4 +353,5 @@ public final class DefaultPortStatistics implements PortStatistics { | ... | @@ -343,4 +353,5 @@ public final class DefaultPortStatistics implements PortStatistics { |
343 | } | 353 | } |
344 | 354 | ||
345 | } | 355 | } |
356 | + | ||
346 | } | 357 | } | ... | ... |
... | @@ -97,4 +97,11 @@ public interface PortStatistics { | ... | @@ -97,4 +97,11 @@ public interface PortStatistics { |
97 | */ | 97 | */ |
98 | long durationNano(); | 98 | long durationNano(); |
99 | 99 | ||
100 | + /** | ||
101 | + * Returns true if all the port stats are zero, excluding TxErrors and RxErrors. | ||
102 | + * | ||
103 | + * @return boolean true if all port stats are zero | ||
104 | + */ | ||
105 | + boolean isZero(); | ||
106 | + | ||
100 | } | 107 | } | ... | ... |
... | @@ -292,9 +292,11 @@ public class Ofdpa2Pipeline extends AbstractHandlerBehaviour implements Pipeline | ... | @@ -292,9 +292,11 @@ public class Ofdpa2Pipeline extends AbstractHandlerBehaviour implements Pipeline |
292 | } else { | 292 | } else { |
293 | log.warn("No key defined in filtering objective from app: {}. Not" | 293 | log.warn("No key defined in filtering objective from app: {}. Not" |
294 | + "processing filtering objective", applicationId); | 294 | + "processing filtering objective", applicationId); |
295 | - fail(filt, ObjectiveError.UNKNOWN); | 295 | + fail(filt, ObjectiveError.BADPARAMS); |
296 | return; | 296 | return; |
297 | } | 297 | } |
298 | + log.debug("Received filtering objective for dev/port: {}/{}", deviceId, | ||
299 | + portCriterion.port()); | ||
298 | // convert filtering conditions for switch-intfs into flowrules | 300 | // convert filtering conditions for switch-intfs into flowrules |
299 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | 301 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); |
300 | for (Criterion criterion : filt.conditions()) { | 302 | for (Criterion criterion : filt.conditions()) { |
... | @@ -333,7 +335,9 @@ public class Ofdpa2Pipeline extends AbstractHandlerBehaviour implements Pipeline | ... | @@ -333,7 +335,9 @@ public class Ofdpa2Pipeline extends AbstractHandlerBehaviour implements Pipeline |
333 | } | 335 | } |
334 | 336 | ||
335 | if (ethCriterion == null || ethCriterion.mac().equals(MacAddress.NONE)) { | 337 | if (ethCriterion == null || ethCriterion.mac().equals(MacAddress.NONE)) { |
336 | - log.debug("filtering objective missing dstMac, cannot program TMAC table"); | 338 | + log.warn("filtering objective missing dstMac, cannot program TMAC table"); |
339 | + fail(filt, ObjectiveError.BADPARAMS); | ||
340 | + return; | ||
337 | } else { | 341 | } else { |
338 | for (FlowRule tmacRule : processEthDstFilter(portCriterion, ethCriterion, | 342 | for (FlowRule tmacRule : processEthDstFilter(portCriterion, ethCriterion, |
339 | vidCriterion, assignedVlan, | 343 | vidCriterion, assignedVlan, |
... | @@ -345,8 +349,10 @@ public class Ofdpa2Pipeline extends AbstractHandlerBehaviour implements Pipeline | ... | @@ -345,8 +349,10 @@ public class Ofdpa2Pipeline extends AbstractHandlerBehaviour implements Pipeline |
345 | } | 349 | } |
346 | 350 | ||
347 | if (ethCriterion == null || vidCriterion == null) { | 351 | if (ethCriterion == null || vidCriterion == null) { |
348 | - log.debug("filtering objective missing dstMac or VLAN, " | 352 | + log.warn("filtering objective missing dstMac or VLAN, " |
349 | + "cannot program VLAN Table"); | 353 | + "cannot program VLAN Table"); |
354 | + fail(filt, ObjectiveError.BADPARAMS); | ||
355 | + return; | ||
350 | } else { | 356 | } else { |
351 | /* | 357 | /* |
352 | * NOTE: Separate vlan filtering rules and assignment rules | 358 | * NOTE: Separate vlan filtering rules and assignment rules |
... | @@ -1079,17 +1085,26 @@ public class Ofdpa2Pipeline extends AbstractHandlerBehaviour implements Pipeline | ... | @@ -1079,17 +1085,26 @@ public class Ofdpa2Pipeline extends AbstractHandlerBehaviour implements Pipeline |
1079 | } | 1085 | } |
1080 | 1086 | ||
1081 | protected static VlanId readVlanFromSelector(TrafficSelector selector) { | 1087 | protected static VlanId readVlanFromSelector(TrafficSelector selector) { |
1088 | + if (selector == null) { | ||
1089 | + return null; | ||
1090 | + } | ||
1082 | Criterion criterion = selector.getCriterion(Criterion.Type.VLAN_VID); | 1091 | Criterion criterion = selector.getCriterion(Criterion.Type.VLAN_VID); |
1083 | return (criterion == null) | 1092 | return (criterion == null) |
1084 | ? null : ((VlanIdCriterion) criterion).vlanId(); | 1093 | ? null : ((VlanIdCriterion) criterion).vlanId(); |
1085 | } | 1094 | } |
1086 | 1095 | ||
1087 | protected static IpPrefix readIpDstFromSelector(TrafficSelector selector) { | 1096 | protected static IpPrefix readIpDstFromSelector(TrafficSelector selector) { |
1097 | + if (selector == null) { | ||
1098 | + return null; | ||
1099 | + } | ||
1088 | Criterion criterion = selector.getCriterion(Criterion.Type.IPV4_DST); | 1100 | Criterion criterion = selector.getCriterion(Criterion.Type.IPV4_DST); |
1089 | return (criterion == null) ? null : ((IPCriterion) criterion).ip(); | 1101 | return (criterion == null) ? null : ((IPCriterion) criterion).ip(); |
1090 | } | 1102 | } |
1091 | 1103 | ||
1092 | private static VlanId readVlanFromTreatment(TrafficTreatment treatment) { | 1104 | private static VlanId readVlanFromTreatment(TrafficTreatment treatment) { |
1105 | + if (treatment == null) { | ||
1106 | + return null; | ||
1107 | + } | ||
1093 | for (Instruction i : treatment.allInstructions()) { | 1108 | for (Instruction i : treatment.allInstructions()) { |
1094 | if (i instanceof ModVlanIdInstruction) { | 1109 | if (i instanceof ModVlanIdInstruction) { |
1095 | return ((ModVlanIdInstruction) i).vlanId(); | 1110 | return ((ModVlanIdInstruction) i).vlanId(); | ... | ... |
-
Please register or login to post a comment