blob: d879f5961a439f411aaf011a3c4932e4bb2fb126 [file] [log] [blame]
Brian Stanke9a108972016-04-11 15:25:17 -04001/*
2 * Copyright 2016-present Open Networking Laboratory
3 *
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 */
16
17package org.onosproject.incubator.net.virtual.impl;
18
19
20import 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;
25import org.apache.felix.scr.annotations.Service;
26import org.onosproject.core.ApplicationId;
27import org.onosproject.core.CoreService;
28import org.onosproject.incubator.net.tunnel.TunnelId;
29import org.onosproject.incubator.net.virtual.DefaultVirtualLink;
30import org.onosproject.incubator.net.virtual.NetworkId;
31import org.onosproject.incubator.net.virtual.VirtualNetworkProvider;
32import org.onosproject.incubator.net.virtual.VirtualNetworkProviderRegistry;
33import org.onosproject.incubator.net.virtual.VirtualNetworkProviderService;
34import org.onosproject.net.ConnectPoint;
35import org.onosproject.net.EncapsulationType;
36import org.onosproject.net.intent.Constraint;
37import org.onosproject.net.intent.Intent;
38import org.onosproject.net.intent.IntentService;
39import org.onosproject.net.intent.IntentState;
40import org.onosproject.net.intent.Key;
41import org.onosproject.net.intent.PointToPointIntent;
42import org.onosproject.net.intent.constraint.EncapsulationConstraint;
43import org.onosproject.net.provider.AbstractProvider;
44import org.slf4j.Logger;
45
46import java.util.ArrayList;
47import java.util.List;
48
49import static com.google.common.base.Preconditions.checkNotNull;
50import static java.lang.Thread.sleep;
51import static org.slf4j.LoggerFactory.getLogger;
52
53/**
54 * Point to point intent VirtualNetworkProvider implementation.
55 */
56@Component(immediate = true)
57@Service
58public class PtToPtIntentVirtualNetworkProvider extends AbstractProvider implements VirtualNetworkProvider {
59
60 private final Logger log = getLogger(PtToPtIntentVirtualNetworkProvider.class);
61 private static final String NETWORK_ID_NULL = "Network ID cannot be null";
62 private static final String CONNECT_POINT_NULL = "Connect Point cannot be null";
63 private static final String INTENT_NULL = "Intent cannot be null";
64 protected static final String KEY_FORMAT = "networkId=%s src=%s dst=%s";
65 private static final int MAX_WAIT_COUNT = 30;
66
67 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
68 protected VirtualNetworkProviderRegistry providerRegistry;
69
70 private VirtualNetworkProviderService providerService;
71
72 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
73 protected IntentService intentService;
74
75 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
76 protected CoreService coreService;
77
78 protected static final String PTPT_INTENT_APPID = "org.onosproject.vnet.intent";
79 private ApplicationId appId;
80
81 /**
82 * Default constructor.
83 */
84 public PtToPtIntentVirtualNetworkProvider() {
85 super(DefaultVirtualLink.PID);
86 }
87
88 @Activate
89 public void activate() {
90 providerService = providerRegistry.register(this);
91 appId = coreService.registerApplication(PTPT_INTENT_APPID);
92
93 log.info("Started");
94 }
95
96 @Deactivate
97 public void deactivate() {
98 providerRegistry.unregister(this);
99 providerService = null;
100 log.info("Stopped");
101 }
102
103 @Override
104 public TunnelId createTunnel(NetworkId networkId, ConnectPoint src, ConnectPoint dst) {
105 checkNotNull(NETWORK_ID_NULL, networkId);
106 checkNotNull(CONNECT_POINT_NULL, src);
107 checkNotNull(CONNECT_POINT_NULL, dst);
108 String key = String.format(KEY_FORMAT, networkId.toString(), src.toString(), dst.toString());
109 Key intentKey = Key.of(key, appId);
110
111 List<Constraint> constraints = new ArrayList<>();
112 constraints.add(new EncapsulationConstraint(EncapsulationType.VLAN));
113
114 // TODO Currently there can only be one tunnel/intent between the src and dst across
115 // all virtual networks. We may want to support multiple intents between the same src/dst pairs.
116 PointToPointIntent intent = PointToPointIntent.builder()
117 .key(intentKey)
118 .appId(appId)
119 .ingressPoint(src)
120 .egressPoint(dst)
121 .constraints(constraints)
122 .build();
123 intentService.submit(intent);
124
125 // construct tunnelId from the key
126 return TunnelId.valueOf(key);
127 }
128
129 @Override
130 public void destroyTunnel(NetworkId networkId, TunnelId tunnelId) {
131 String key = tunnelId.id();
132 Key intentKey = Key.of(key, appId);
133 Intent intent = intentService.getIntent(intentKey);
134 checkNotNull(intent, INTENT_NULL);
135 intentService.withdraw(intent);
136 try {
137 int count = 0;
138 // Loop waiting for the intent to go into a withdrawn or failed state
139 // before attempting to purge it.
140 while (++count <= MAX_WAIT_COUNT) {
141 IntentState state = intentService.getIntentState(intentKey);
142 if ((state == IntentState.FAILED) || (state == IntentState.WITHDRAWN)) {
143 intentService.purge(intent);
144 break;
145 }
146 sleep(1000);
147 }
148 } catch (Exception e) {
149 log.error("Exception: " + e);
150 }
151 }
152}
153