2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.ingressnat;
11 import com.google.common.collect.Sets;
12 import org.opendaylight.groupbasedpolicy.dto.EgKey;
13 import org.opendaylight.groupbasedpolicy.dto.EpKey;
14 import org.opendaylight.groupbasedpolicy.dto.IndexedTenant;
15 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
16 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
17 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowTable;
18 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.go.to.table._case.GoToTable;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2BridgeDomainId;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointKey;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg1;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg4;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg5;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.move.grouping.NxRegMove;
35 import java.util.Collection;
36 import java.util.Collections;
39 * <h1>Manage the table processing NAT translation (table=1)</h1>
41 * Ingress NAT translation flows, created for every L3 endpoints with NAT which also contain L2 context
43 * <i>Nat flow:</i><br>
46 * - nw_dst (destination ip address)<br>
48 * - loadReg0 {@link NxmNxReg0}<br>
49 * - loadReg1 {@link NxmNxReg1}<br>
50 * - loadReg4 {@link NxmNxReg4}<br>
51 * - loadReg5 {@link NxmNxReg5}<br>
52 * - loadReg6 {@link NxmNxReg6}<br>
54 * - {@link GoToTable} DESTINATION MAPPER table
56 * <i>Outside Arp flow:</i><br>
59 * - arp, (ethertype)<br>
60 * - set arp target transport address<br>
62 * - move eth_src = eth_dst {@link NxRegMove}<br>
63 * - set dl src_mac {@link MacAddress}<br>
64 * - load arp_op {@link NxRegLoad}<br>
65 * - move arp_sha = arp_tha {@link NxRegMove}<br>
66 * - load arp_sha {@link NxRegLoad}<br>
67 * - move arp_spa = arp_tpa {@link NxRegMove}<br>
68 * - load arp_spa {@link NxRegLoad}<br>
69 * - output:port {@link NodeConnectorId}
71 * Flows for ingress traffic. Created for every external endpoint without location<br>
73 * <i>Ingress external IP flow</i><br>
76 * - nw_src (source ip address)<br>
78 * - loadReg0 {@link NxmNxReg0}<br>
79 * - loadReg1 {@link NxmNxReg1}<br>
80 * - loadReg4 {@link NxmNxReg4}<br>
81 * - loadReg5 {@link NxmNxReg5}<br>
82 * - loadReg6 {@link NxmNxReg6}<br>
84 * - {@link GoToTable} DESTINATION MAPPER table
86 * <i>Ingress external Arp flow</i><br>
89 * - arp_spa (source arp address)<br>
91 * - loadReg0 {@link NxmNxReg0}<br>
92 * - loadReg1 {@link NxmNxReg1}<br>
93 * - loadReg4 {@link NxmNxReg4}<br>
94 * - loadReg5 {@link NxmNxReg5}<br>
95 * - loadReg6 {@link NxmNxReg6}<br>
97 * - {@link GoToTable} DESTINATION MAPPER table
100 public class IngressNatMapper extends FlowTable {
103 private static final Integer BASE = 1;
104 private static final Integer ARP_EXTERNAL = 80;
105 private static final Integer NAT_EXTERNAL = 90;
106 private static final Integer NAT = 100;
107 private static final Integer ARP = 150;
108 private final short tableId;
110 public IngressNatMapper(OfContext ctx, short tableId) {
112 this.tableId = tableId;
116 public short getTableId() {
121 public void sync(Endpoint endpoint, OfWriter ofWriter) {
122 NodeId endpointNodeId = ctx.getEndpointManager().getEndpointNodeId(endpoint);
123 if (endpointNodeId == null) {
124 LOG.warn("Endpoint {} has no location specified, skipped", endpoint);
127 IngressNatMapperFlows flows = new IngressNatMapperFlows(endpointNodeId, tableId);
128 syncFlows(flows, endpoint, ofWriter);
131 void syncFlows(IngressNatMapperFlows flows, Endpoint endpoint, OfWriter ofWriter) {
133 // To support provider networks, all external ingress traffic is currently passed here and
134 // if no match is found - no NAT is performed and processing continues in DestinationMapper.
137 short destinationMapperId = ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER();
138 flows.baseFlow(destinationMapperId, BASE, ofWriter);
140 // Flows for ingress NAT translation
141 Collection<EndpointL3> l3Endpoints = ctx.getEndpointManager().getL3EndpointsWithNat();
142 OrdinalFactory.EndpointFwdCtxOrdinals epFwdCtxOrdinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, endpoint);
143 EndpointKey endpointKey = endpoint.getKey();
144 for (EndpointL3 l3Endpoint : l3Endpoints) {
145 L2BridgeDomainId l2Context = l3Endpoint.getL2Context();
146 MacAddress macAddress = l3Endpoint.getMacAddress();
147 if (l2Context != null && macAddress != null) {
148 Endpoint l2EpFromL3Ep = ctx.getEndpointManager().getEndpoint(new EpKey(l2Context, macAddress));
149 if(endpointKey.equals(l2EpFromL3Ep.getKey())) {
150 if (epFwdCtxOrdinals != null) {
151 flows.createNatFlow(destinationMapperId, l3Endpoint, epFwdCtxOrdinals, NAT, ofWriter);
153 IndexedTenant tenant = ctx.getTenant(endpoint.getTenant());
154 if (tenant != null) {
155 flows.createArpFlow(tenant, l3Endpoint, ARP, ofWriter);
157 // L3 Endpoint found, end of loop
162 // Flows for ingress traffic that does not have to be translated.
163 for (EgKey endpointGroupKey : ctx.getEndpointManager().getEgKeysForEndpoint(endpoint)) {
164 for (EgKey peer : Sets.union(Collections.singleton(endpointGroupKey),
165 ctx.getCurrentPolicy().getPeers(endpointGroupKey))) {
166 for (Endpoint externalEndpoint : ctx.getEndpointManager().getExtEpsNoLocForGroup(peer)) {
167 if (epFwdCtxOrdinals != null) {
168 flows.createIngressExternalNatFlows(destinationMapperId, externalEndpoint, epFwdCtxOrdinals,
169 NAT_EXTERNAL, ofWriter);
170 flows.createIngressExternalArpFlows(destinationMapperId, externalEndpoint, epFwdCtxOrdinals,
171 ARP_EXTERNAL, ofWriter);