logger.trace("Ignoring non-OpenFlow node {} from flow programming", node);
return new Status(StatusCode.BADREQUEST);
}
- logger.debug("Performing {} rules for VIP {} and member {}", action, lbConfig.getVip(), member.getIP());
+ logger.debug("Performing {} rules for member {} with index {} on LB with VIP {} and total members {}",
+ action, member.getIP(), member.getIndex(), lbConfig.getVip(), lbConfig.getMembers().size());
NodeBuilder nodeBuilder = new NodeBuilder();
nodeBuilder.setId(new NodeId(Constants.OPENFLOW_NODE_PREFIX + String.valueOf(node.getID())));
ab = new ActionBuilder();
ab.setAction(ActionUtils.nxMultipathAction(OfjNxHashFields.NXHASHFIELDSSYMMETRICL4,
- (Integer)0, OfjNxMpAlgorithm.NXMPALGMODULON, (Integer)lbConfig.getMembers().size(),
+ (Integer)0, OfjNxMpAlgorithm.NXMPALGMODULON,
+ (Integer)lbConfig.getMembers().size()-1, //By Nicira-Ext spec, this field is max_link minus 1
(Long)0L, new DstNxRegCaseBuilder().setNxReg(REG_FIELD_B).build(),
(Integer)0, (Integer)31));
ab.setOrder(1);
enqueueEvent(new NorthboundEvent(neutronLBPoolMember, Action.DELETE));
}
+ private void doNeutronLoadBalancerPoolMemberDelete(NeutronLoadBalancerPoolMember neutronLBPoolMember) {
+ Preconditions.checkNotNull(loadBalancerProvider);
+
+ LoadBalancerConfiguration lbConfig = extractLBConfiguration(neutronLBPoolMember);
+ if (lbConfig == null) {
+ logger.trace("Neutron LB configuration invalid for member {} ", neutronLBPoolMember.getPoolMemberAddress());
+ } else if (lbConfig.getVip() == null) {
+ logger.trace("Neutron LB VIP not created yet for member {} ", neutronLBPoolMember.getPoolMemberID());
+ } else if (!lbConfig.isValid()) {
+ logger.trace("Neutron LB pool configuration invalid for {} ", lbConfig.getName());
+ } else if (this.switchManager.getNodes().size() == 0) {
+ logger.trace("Noop with LB pool member {} creation because no nodes available.", neutronLBPoolMember.getPoolMemberID());
+ } else {
+ /* As of now, deleting a member involves recomputing member indices.
+ * This is best done through a complete update of the load balancer instance.
+ */
+ for (Node node: this.switchManager.getNodes())
+ loadBalancerProvider.programLoadBalancerRules(node, lbConfig, Action.DELETE);
+
+ for (NeutronLoadBalancer neutronLB: neutronLBCache.getAllNeutronLoadBalancers()) {
+ String loadBalancerSubnetID = neutronLB.getLoadBalancerVipSubnetID();
+ if (neutronLBPoolMember.getPoolMemberSubnetID().equals(loadBalancerSubnetID)) {
+ enqueueEvent(new NorthboundEvent(neutronLB, Action.ADD));
+ break;
+ }
+ }
+ }
+ }
+
/**
* Process the event.
*
*/
@Override
public void processEvent(AbstractEvent abstractEvent) {
+ logger.debug("Processing Loadbalancer member event " + abstractEvent);
if (!(abstractEvent instanceof NorthboundEvent)) {
logger.error("Unable to process abstract event " + abstractEvent);
return;
doNeutronLoadBalancerPoolMemberCreate(ev.getLoadBalancerPoolMember());
break;
case DELETE:
- /* As of now, deleting a member involves recomputing member indices.
- * This is best done through a complete update of the load balancer instance.
- */
- for (NeutronLoadBalancer neutronLB: neutronLBCache.getAllNeutronLoadBalancers()) {
- String loadBalancerSubnetID = neutronLB.getLoadBalancerVipSubnetID();
- if (ev.getLoadBalancerPoolMember()
- .getPoolMemberSubnetID().equals(loadBalancerSubnetID)) {
- enqueueEvent(new NorthboundEvent(neutronLB, Action.UPDATE));
- break;
- }
- }
+ doNeutronLoadBalancerPoolMemberDelete(ev.getLoadBalancerPoolMember());
break;
case UPDATE:
/**
break;
}
}
+
/**
* It is possible that the VIP has not been created yet.
* In that case, we create dummy configuration that will not program rules.
*/
LoadBalancerConfiguration lbConfig = new LoadBalancerConfiguration(loadBalancerName, loadBalancerVip);
+
+ /* Extract all other active members and include in LB config
+ */
+ String otherMemberID, otherMemberSubnetID, otherMemberIP, otherMemberMAC, otherMemberProtocol;
+ Boolean otherMemberAdminStateIsUp;
+ Integer otherMemberPort;
+
+ for (NeutronLoadBalancerPoolMember otherMember: neutronLBPool.getLoadBalancerPoolMembers()) {
+ otherMemberID = otherMember.getPoolMemberID();
+ if (otherMemberID.equals(memberID))
+ continue; //skip
+
+ otherMemberIP = otherMember.getPoolMemberAddress();
+ otherMemberAdminStateIsUp = otherMember.getPoolMemberAdminStateIsUp();
+ otherMemberSubnetID = otherMember.getPoolMemberSubnetID();
+ otherMemberPort = otherMember.getPoolMemberProtoPort();
+ otherMemberProtocol = memberProtocol;
+
+ if (otherMemberIP == null || otherMemberSubnetID == null || otherMemberAdminStateIsUp == null)
+ continue;
+ else if (otherMemberAdminStateIsUp.booleanValue()) {
+ otherMemberMAC = NeutronCacheUtils.getMacAddress(neutronPortsCache, otherMemberIP);
+ if (otherMemberMAC == null)
+ continue;
+ lbConfig.addMember(otherMemberID, otherMemberIP, otherMemberMAC, otherMemberProtocol, otherMemberPort);
+ }
+ }
+
lbConfig.addMember(memberID, memberIP, memberMAC, memberProtocol, memberPort);
return lbConfig;
}
* @return MAC address registered with that IP address
*/
public static String getMacAddress(INeutronPortCRUD neutronPortsCache, String ipAddr) {
- List<Neutron_IPs> fixedIPs;
- Iterator<Neutron_IPs> fixedIPIterator;
- Neutron_IPs ip;
+ if (ipAddr == null)
+ return null;
- List<NeutronPort> allPorts = neutronPortsCache.getAllPorts();
- Iterator<NeutronPort> i = allPorts.iterator();
- while (i.hasNext()) {
- NeutronPort port = i.next();
- fixedIPs = port.getFixedIPs();
- if (fixedIPs != null && fixedIPs.size() > 0) {
- fixedIPIterator = fixedIPs.iterator();
- while (fixedIPIterator.hasNext()) {
- ip = fixedIPIterator.next();
- if (ip.getIpAddress().equals(ipAddr))
- return port.getMacAddress();
- }
- }
- }
+ List<Neutron_IPs> fixedIPs;
+ Iterator<Neutron_IPs> fixedIPIterator;
+ Neutron_IPs ip;
+
+ List<NeutronPort> allPorts = neutronPortsCache.getAllPorts();
+ Iterator<NeutronPort> i = allPorts.iterator();
+ while (i.hasNext()) {
+ NeutronPort port = i.next();
+ fixedIPs = port.getFixedIPs();
+ if (fixedIPs != null && fixedIPs.size() > 0) {
+ fixedIPIterator = fixedIPs.iterator();
+ while (fixedIPIterator.hasNext()) {
+ ip = fixedIPIterator.next();
+ if (ip.getIpAddress().equals(ipAddr))
+ return port.getMacAddress();
+ }
+ }
+ }
return null;
}
}