blob: dad8e3bd90f045f7fff76d5ced8a2869e6cb74b2 [file] [log] [blame]
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Sho SHIMIZU6c28f832015-02-20 16:12:19 -080016package org.onosproject.net.intent.impl.compiler;
Brian O'Connor66630c82014-10-02 21:08:19 -070017
Thomas Vachuskaab753e12016-06-13 19:41:05 -070018import com.google.common.collect.ImmutableList;
Pier Ventre98308ab2016-10-12 14:35:05 -070019import com.google.common.collect.ImmutableSet;
Brian O'Connor66630c82014-10-02 21:08:19 -070020import org.apache.felix.scr.annotations.Activate;
21import org.apache.felix.scr.annotations.Component;
22import org.apache.felix.scr.annotations.Deactivate;
23import org.apache.felix.scr.annotations.Reference;
24import org.apache.felix.scr.annotations.ReferenceCardinality;
Brian O'Connorabafb502014-12-02 22:26:20 -080025import org.onosproject.net.DefaultLink;
26import org.onosproject.net.DefaultPath;
Pier Ventre98308ab2016-10-12 14:35:05 -070027import org.onosproject.net.DeviceId;
28import org.onosproject.net.FilteredConnectPoint;
Brian O'Connorabafb502014-12-02 22:26:20 -080029import org.onosproject.net.Host;
30import org.onosproject.net.Link;
31import org.onosproject.net.Path;
32import org.onosproject.net.flow.TrafficSelector;
33import org.onosproject.net.host.HostService;
34import org.onosproject.net.intent.HostToHostIntent;
35import org.onosproject.net.intent.Intent;
Pier Ventre98308ab2016-10-12 14:35:05 -070036import org.onosproject.net.intent.IntentCompilationException;
37import org.onosproject.net.intent.LinkCollectionIntent;
Brian O'Connorabafb502014-12-02 22:26:20 -080038import org.onosproject.net.intent.PathIntent;
39import org.onosproject.net.intent.constraint.AsymmetricPathConstraint;
Pier Ventre98308ab2016-10-12 14:35:05 -070040import org.slf4j.Logger;
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080041
Thomas Vachuska5dd52f72014-11-28 19:27:45 -080042import java.util.ArrayList;
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080043import java.util.Arrays;
44import java.util.List;
Thomas Vachuskaab753e12016-06-13 19:41:05 -070045import java.util.Objects;
Pier Ventre98308ab2016-10-12 14:35:05 -070046import java.util.Set;
47import java.util.stream.Collectors;
Brian O'Connor66630c82014-10-02 21:08:19 -070048
Pier Ventre98308ab2016-10-12 14:35:05 -070049import static org.onosproject.net.Link.Type.EDGE;
Brian O'Connorabafb502014-12-02 22:26:20 -080050import static org.onosproject.net.flow.DefaultTrafficSelector.builder;
Pier Ventre98308ab2016-10-12 14:35:05 -070051import static org.slf4j.LoggerFactory.getLogger;
tomf5c9d922014-10-03 15:22:03 -070052
Brian O'Connor66630c82014-10-02 21:08:19 -070053/**
54 * A intent compiler for {@link HostToHostIntent}.
55 */
56@Component(immediate = true)
57public class HostToHostIntentCompiler
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080058 extends ConnectivityIntentCompiler<HostToHostIntent> {
Brian O'Connor66630c82014-10-02 21:08:19 -070059
Pier Ventre98308ab2016-10-12 14:35:05 -070060 private final Logger log = getLogger(getClass());
61
62 private static final String DEVICE_ID_NOT_FOUND = "Didn't find device id in the link";
63
tomf5c9d922014-10-03 15:22:03 -070064 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
65 protected HostService hostService;
66
Brian O'Connor66630c82014-10-02 21:08:19 -070067 @Activate
68 public void activate() {
Brian O'Connor66630c82014-10-02 21:08:19 -070069 intentManager.registerCompiler(HostToHostIntent.class, this);
70 }
71
72 @Deactivate
73 public void deactivate() {
74 intentManager.unregisterCompiler(HostToHostIntent.class);
75 }
76
77 @Override
Sho SHIMIZUec07ffd2016-02-22 20:45:21 -080078 public List<Intent> compile(HostToHostIntent intent, List<Intent> installable) {
Thomas Vachuskaab753e12016-06-13 19:41:05 -070079 // If source and destination are the same, there are never any installables.
80 if (Objects.equals(intent.one(), intent.two())) {
81 return ImmutableList.of();
82 }
83
Thomas Vachuska5dd52f72014-11-28 19:27:45 -080084 boolean isAsymmetric = intent.constraints().contains(new AsymmetricPathConstraint());
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080085 Path pathOne = getPath(intent, intent.one(), intent.two());
Thomas Vachuska5dd52f72014-11-28 19:27:45 -080086 Path pathTwo = isAsymmetric ?
87 getPath(intent, intent.two(), intent.one()) : invertPath(pathOne);
Brian O'Connor66630c82014-10-02 21:08:19 -070088
tomf5c9d922014-10-03 15:22:03 -070089 Host one = hostService.getHost(intent.one());
90 Host two = hostService.getHost(intent.two());
91
Pier Ventre98308ab2016-10-12 14:35:05 -070092 return Arrays.asList(createLinkCollectionIntent(pathOne, one, two, intent),
93 createLinkCollectionIntent(pathTwo, two, one, intent));
tomf5c9d922014-10-03 15:22:03 -070094 }
95
Thomas Vachuska5dd52f72014-11-28 19:27:45 -080096 // Inverts the specified path. This makes an assumption that each link in
97 // the path has a reverse link available. Under most circumstances, this
98 // assumption will hold.
99 private Path invertPath(Path path) {
100 List<Link> reverseLinks = new ArrayList<>(path.links().size());
101 for (Link link : path.links()) {
102 reverseLinks.add(0, reverseLink(link));
103 }
104 return new DefaultPath(path.providerId(), reverseLinks, path.cost());
105 }
106
107 // Produces a reverse variant of the specified link.
108 private Link reverseLink(Link link) {
Ray Milkey2693bda2016-01-22 16:08:14 -0800109 return DefaultLink.builder().providerId(link.providerId())
110 .src(link.dst())
111 .dst(link.src())
112 .type(link.type())
113 .state(link.state())
114 .isExpected(link.isExpected())
115 .build();
Thomas Vachuska5dd52f72014-11-28 19:27:45 -0800116 }
117
tomf5c9d922014-10-03 15:22:03 -0700118 // Creates a path intent from the specified path and original connectivity intent.
119 private Intent createPathIntent(Path path, Host src, Host dst,
120 HostToHostIntent intent) {
tom85258ee2014-10-07 00:10:02 -0700121 TrafficSelector selector = builder(intent.selector())
tomf5c9d922014-10-03 15:22:03 -0700122 .matchEthSrc(src.mac()).matchEthDst(dst.mac()).build();
Ray Milkeyebc5d222015-03-18 15:45:36 -0700123 return PathIntent.builder()
124 .appId(intent.appId())
Yuta HIGUCHI652f27f2016-10-31 16:54:30 -0700125 .key(intent.key())
Ray Milkeyebc5d222015-03-18 15:45:36 -0700126 .selector(selector)
127 .treatment(intent.treatment())
128 .path(path)
129 .constraints(intent.constraints())
130 .priority(intent.priority())
131 .build();
tomf5c9d922014-10-03 15:22:03 -0700132 }
133
Pier Ventre98308ab2016-10-12 14:35:05 -0700134 private FilteredConnectPoint getFilteredPointFromLink(Link link) {
135 FilteredConnectPoint filteredConnectPoint;
136 if (link.src().elementId() instanceof DeviceId) {
137 filteredConnectPoint = new FilteredConnectPoint(link.src());
138 } else if (link.dst().elementId() instanceof DeviceId) {
139 filteredConnectPoint = new FilteredConnectPoint(link.dst());
140 } else {
141 throw new IntentCompilationException(DEVICE_ID_NOT_FOUND);
142 }
143 return filteredConnectPoint;
144 }
145
146 private Intent createLinkCollectionIntent(Path path,
147 Host src,
148 Host dst,
149 HostToHostIntent intent) {
150 /*
151 * The path contains also the edge links, these are not necessary
152 * for the LinkCollectionIntent.
153 */
154 Set<Link> coreLinks = path.links()
155 .stream()
156 .filter(link -> !link.type().equals(EDGE))
157 .collect(Collectors.toSet());
158
159 Link ingressLink = path.links().get(0);
160 Link egressLink = path.links().get(path.links().size() - 1);
161
162 FilteredConnectPoint ingressPoint = getFilteredPointFromLink(ingressLink);
163 FilteredConnectPoint egressPoint = getFilteredPointFromLink(egressLink);
164
165 TrafficSelector selector = builder(intent.selector())
166 .matchEthSrc(src.mac())
167 .matchEthDst(dst.mac())
168 .build();
169
170 return LinkCollectionIntent.builder()
171 .key(intent.key())
172 .appId(intent.appId())
173 .selector(selector)
174 .treatment(intent.treatment())
175 .links(coreLinks)
176 .filteredIngressPoints(ImmutableSet.of(
177 ingressPoint
178 ))
179 .filteredEgressPoints(ImmutableSet.of(
180 egressPoint
181 ))
182 .applyTreatmentOnEgress(true)
183 .constraints(intent.constraints())
184 .priority(intent.priority())
185 .build();
186 }
187
Brian O'Connor66630c82014-10-02 21:08:19 -0700188}