/*
* Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.egressnat;
import org.opendaylight.groupbasedpolicy.dto.EpKey;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowTable;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.go.to.table._case.GoToTable;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2BridgeDomainId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
import java.util.Collection;
/**
* <h1>Manage the table that assigns source endpoint group, bridge domain, and
* router domain to registers to be used by other tables</h1>
*
* <i>NAT flow</i><br>
* Priority = 100<br>
* Matches:<br>
* - ipv4/ipv6 inside address<br>
* - ethernet type<br>
* - Reg6 {@link NxmNxReg6}<br>
* Actions:<br>
* - set_src ip address<br>
* - {@link GoToTable} EXTERNAL MAPPER table<br>
*/
public class EgressNatMapper extends FlowTable {
// Priorities
private static final Integer DROP = 1;
private static final Integer NAT = 100;
private final short tableId;
public EgressNatMapper(OfContext ctx, short tableId) {
super(ctx);
this.tableId = tableId;
}
@Override
public short getTableId() {
return tableId;
}
@Override
public void sync(Endpoint endpoint, OfWriter ofWriter) throws Exception {
NodeId endpointNodeId = ctx.getEndpointManager().getEndpointNodeId(endpoint);
if (endpointNodeId == null) {
LOG.warn("Endpoint {} has no location specified, skipped", endpoint);
return;
}
syncFlows(new EgressNatMapperFlows(endpointNodeId, tableId), endpoint, ofWriter);
}
void syncFlows(EgressNatMapperFlows flows, Endpoint endpoint, OfWriter ofWriter) {
// Drop
flows.dropFlow(DROP, null, ofWriter);
// NAT flows
short externalMapperId = ctx.getPolicyManager().getTABLEID_EXTERNAL_MAPPER();
Collection<EndpointL3> l3Endpoints = ctx.getEndpointManager().getL3EndpointsWithNat();
EndpointKey endpointKey = endpoint.getKey();
for (EndpointL3 l3Endpoint : l3Endpoints) {
L2BridgeDomainId l2Context = l3Endpoint.getL2Context();
MacAddress macAddress = l3Endpoint.getMacAddress();
if (l2Context != null && macAddress != null) {
Endpoint l2EpFromL3Ep = ctx.getEndpointManager().getEndpoint(new EpKey(l2Context, macAddress));
if(endpointKey.equals(l2EpFromL3Ep.getKey())) {
flows.natFlows(externalMapperId, l3Endpoint, NAT, ofWriter);
// L3 Endpoint found, end of loop
break;
}
}
}
}
}