import java.util.Set;
import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-import org.opendaylight.controller.sal.utils.HexEncode;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.Dirty;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.RegMatch;
import org.opendaylight.groupbasedpolicy.resolver.ConditionGroup;
IndexedTenant tenant = ctx.policyResolver.getTenant(key.getTenantId());
EndpointGroup eg = tenant.getEndpointGroup(key.getEgId());
L2FloodDomain fd = tenant.resolveL2FloodDomain(eg.getNetworkDomain());
- Subnet sn = tenant.resolveSubnet(eg.getNetworkDomain());
+ Collection<Subnet> sns = tenant.resolveSubnets(eg.getNetworkDomain());
L3Context l3c = tenant.resolveL3Context(eg.getNetworkDomain());
int l3Id = 0;
groupAction(Long.valueOf(fdId)))));
writeFlow(t, tiid, flow.build());
}
-
+ for (Subnet sn : sns) {
+ writeRouterArpFlow(t, tiid, flowMap, nodeId, sn, l3Id);
+ }
+ }
+
+ private void writeRouterArpFlow(ReadWriteTransaction t,
+ InstanceIdentifier<Table> tiid,
+ Map<String, FlowCtx> flowMap,
+ NodeId nodeId,
+ Subnet sn,
+ int l3Id) {
if (sn != null && sn.getVirtualRouterIp() != null) {
if (sn.getVirtualRouterIp().getIpv4Address() != null) {
String ikey = sn.getVirtualRouterIp().getIpv4Address().getValue();
- flowId = new FlowId(new StringBuffer()
+ FlowId flowId = new FlowId(new StringBuffer()
.append("routerarp|")
.append(sn.getId().getValue())
.append("|")
addNxRegMatch(mb, RegMatch.of(NxmNxReg6.class,
Long.valueOf(l3Id)));
BigInteger routerMac =
- new BigInteger(1, HexEncode
- .bytesFromHexString(ROUTER_MAC
- .getValue()));
- /* XXX - TODO add output to inport action */
+ new BigInteger(1, bytesFromHexString(ROUTER_MAC
+ .getValue()));
FlowBuilder flowb = base()
.setPriority(150)
.setId(flowId)
}
}
}
-
+
private void syncEP(ReadWriteTransaction t,
InstanceIdentifier<Table> tiid,
Map<String, FlowCtx> flowMap,
}
}
}
+
+ static byte[] bytesFromHexString(String values) {
+ String target = "";
+ if (values != null) {
+ target = values;
+ }
+ String[] octets = target.split(":");
+
+ byte[] ret = new byte[octets.length];
+ for (int i = 0; i < octets.length; i++) {
+ ret[i] = Integer.valueOf(octets[i], 16).byteValue();
+ }
+ return ret;
+ }
}
package org.opendaylight.groupbasedpolicy.resolver;
+import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
import javax.annotation.concurrent.Immutable;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.NetworkDomainId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubnetId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.NetworkDomain;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.Tenant;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Contract;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ActionInstance;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ClassifierInstance;
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
+
/**
* Wrap some convenient indexes around a {@link Tenant} object
* @author readams
new HashMap<>();
private final Map<ActionName, ActionInstance> actions =
new HashMap<>();
+ private final Map<String, Set<SubnetId>> subnetMap = new HashMap<>();
public IndexedTenant(Tenant tenant) {
super();
if (tenant.getSubnet() != null) {
for (Subnet s : tenant.getSubnet()) {
networkDomains.put(s.getId().getValue(), s);
+ Set<SubnetId> sset = subnetMap.get(s.getParent().getValue());
+ if (sset == null) {
+ subnetMap.put(s.getParent().getValue(),
+ sset = new HashSet<SubnetId>());
+ }
+ sset.add(s.getId());
}
}
if (tenant.getSubjectFeatureInstances() != null) {
}
/**
- * If the specified network domain represents a subnet, return it.
+ * Resolve all subnets applicable to the given network domain ID
* @param id the {@link NetworkDomainId}
- * @return the {@link Subnet} if it exists, or <code>null</code> otherwise
+ * @return the set of subnets. Cannot be null, but could be empty.
*/
- public Subnet resolveSubnet(NetworkDomainId id) {
- NetworkDomain d = networkDomains.get(id.getValue());
- if (d == null) return null;
- if (d instanceof Subnet) return (Subnet)d;
- return null;
+ public Collection<Subnet> resolveSubnets(NetworkDomainId id) {
+ Set<SubnetId> sset = new HashSet<>();
+ HashSet<NetworkDomainId> visited = new HashSet<>();
+ while (id != null) {
+ if (visited.contains(id)) return null;
+ visited.add(id);
+ Set<SubnetId> cursset = subnetMap.get(id.getValue());
+ if (cursset != null)
+ sset.addAll(cursset);
+ NetworkDomain d = networkDomains.get(id.getValue());
+ if (d == null) break;
+ if (d instanceof Subnet) {
+ id = ((Subnet)d).getParent();
+ sset.add(((Subnet) d).getId());
+ }
+ else if (d instanceof L2BridgeDomain)
+ id = ((L2BridgeDomain)d).getParent();
+ else if (d instanceof L2FloodDomain)
+ id = ((L2FloodDomain)d).getParent();
+ else
+ id = null;
+ }
+ return Collections2.transform(sset, new Function<SubnetId, Subnet>() {
+ @Override
+ public Subnet apply(SubnetId input) {
+ return (Subnet)networkDomains.get(input.getValue());
+ }
+ });
}
// ******
if (domainClass.isInstance(d)) return domainClass.cast(d);
if (d instanceof Subnet)
id = ((Subnet)d).getParent();
- if (d instanceof L2BridgeDomain)
+ else if (d instanceof L2BridgeDomain)
id = ((L2BridgeDomain)d).getParent();
- if (d instanceof L2FloodDomain)
+ else if (d instanceof L2FloodDomain)
id = ((L2FloodDomain)d).getParent();
+ else
+ id = null;
}
return null;
}
import org.mockito.Matchers;
import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.sal.utils.HexEncode;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowTable.FlowCtx;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
assertEquals(nxMoveArpShaToArpThaAction(),
actions.get(3).getAction());
assertEquals(Integer.valueOf(3), actions.get(3).getOrder());
- assertEquals(nxLoadArpShaAction(new BigInteger(1, HexEncode
+ assertEquals(nxLoadArpShaAction(new BigInteger(1, DestinationMapper
.bytesFromHexString(DestinationMapper.ROUTER_MAC
.getValue()))),
actions.get(4).getAction());
actions.get(5).getAction());
assertEquals(Integer.valueOf(5), actions.get(5).getOrder());
assertTrue(nxLoadArpSpaAction("10.0.0.1").equals(actions.get(6).getAction()) ||
- nxLoadArpSpaAction("10.0.0.2").equals(actions.get(6).getAction()));
+ nxLoadArpSpaAction("10.0.1.1").equals(actions.get(6).getAction()) ||
+ nxLoadArpSpaAction("10.0.2.1").equals(actions.get(6).getAction()));
assertEquals(Integer.valueOf(6), actions.get(6).getOrder());
count += 1;
} else if (Objects.equals(localEp.getMacAddress(),
count += 1;
}
}
- assertEquals(7, count);
+ assertEquals(9, count);
t = dosync(flowMap);
verify(t, never()).put(any(LogicalDatastoreType.class),
L2FloodDomainId fd = new L2FloodDomainId("98e1439e-52d2-46f8-bd69-5136e6088771");
SubnetId sub = new SubnetId("4fcf8dfc-53b5-4aef-84d3-6b5586992fcb");
SubnetId sub2 = new SubnetId("c285a59f-fcb8-42e6-bf29-87ea522fd626");
+ SubnetId sub3 = new SubnetId("a0380d52-2a25-48ef-882c-a4d4cd9e00ec");
TenantId tid = new TenantId("1118c691-8520-47ad-80b8-4cf5e3fe3302");
EndpointGroupId eg = new EndpointGroupId("36dec84a-08c7-497b-80b6-a0035af72a12");
EndpointGroupId eg2 = new EndpointGroupId("632e5e11-7988-4eb5-8fe6-6c182d890276");
.setParent(fd)
.setIpPrefix(new IpPrefix(new Ipv4Prefix("10.0.0.1/24")))
.setVirtualRouterIp(new IpAddress(new Ipv4Address("10.0.0.1")))
+ .build(),
+ new SubnetBuilder()
+ .setId(sub3)
+ .setParent(bd)
+ .setIpPrefix(new IpPrefix(new Ipv4Prefix("10.0.2.1/24")))
+ .setVirtualRouterIp(new IpAddress(new Ipv4Address("10.0.2.1")))
.build()))
.setSubjectFeatureInstances(new SubjectFeatureInstancesBuilder()
.setClassifierInstance(ImmutableList.of(new ClassifierInstanceBuilder()
package org.opendaylight.groupbasedpolicy.resolver;
+import java.util.Collection;
+
import org.junit.Test;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2BridgeDomainId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2FloodDomainId;
@Test
public void testResolveND() throws Exception {
SubnetId sid = new SubnetId("dd25397d-d829-4c8d-8c01-31f129b8de8f");
+ SubnetId sid2 = new SubnetId("c752ba40-40aa-4a47-8138-9b7175b854fa");
L3ContextId l3id = new L3ContextId("f2311f52-890f-4095-8b85-485ec8b92b3c");
L2BridgeDomainId bdid= new L2BridgeDomainId("70aeb9ea-4ca1-4fb9-9780-22b04b84a0d6");
L2FloodDomainId fdid = new L2FloodDomainId("252fbac6-bb6e-4d16-808d-6f56d20e5cca");
Subnet s = new SubnetBuilder()
.setParent(fdid)
.setId(sid).build();
+ Subnet s2 = new SubnetBuilder()
+ .setParent(bdid)
+ .setId(sid2).build();
Tenant t = new TenantBuilder()
- .setSubnet(ImmutableList.of(s))
+ .setSubnet(ImmutableList.of(s, s2))
.setL2BridgeDomain(ImmutableList.of(bd))
.setL3Context(ImmutableList.of(l3c))
.setL2FloodDomain(ImmutableList.of(fd))
IndexedTenant it = new IndexedTenant(t);
assertNotNull(it.getNetworkDomain(sid));
- assertEquals(sid, it.resolveSubnet(sid).getId());
+ Collection<Subnet> sns = it.resolveSubnets(sid);
+ assertTrue(sns.contains(s));
+ assertTrue(sns.contains(s2));
assertEquals(l3id, it.resolveL3Context(sid).getId());
assertEquals(bdid, it.resolveL2BridgeDomain(sid).getId());
assertEquals(fdid, it.resolveL2FloodDomain(sid).getId());