blob: 2d58a66b0c050440caef2b17cc01e0126f01ba8e [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07002 * Copyright 2014 Open Networking Laboratory
Thomas Vachuska781d18b2014-10-27 10:31:25 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * 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
Thomas Vachuska781d18b2014-10-27 10:31:25 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * 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.
Thomas Vachuska781d18b2014-10-27 10:31:25 -070015 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.config;
Jonathan Hart74f9c3b2014-09-29 20:03:50 -070017
18import static org.slf4j.LoggerFactory.getLogger;
19
20import java.io.File;
21import java.io.FileNotFoundException;
22import java.io.IOException;
Jonathan Hart70da5122014-10-01 16:37:42 -070023import java.util.HashSet;
24import java.util.Set;
Jonathan Hart74f9c3b2014-09-29 20:03:50 -070025
26import org.apache.felix.scr.annotations.Activate;
27import org.apache.felix.scr.annotations.Component;
28import org.apache.felix.scr.annotations.Deactivate;
29import org.apache.felix.scr.annotations.Reference;
30import org.apache.felix.scr.annotations.ReferenceCardinality;
Pavlin Radoslavov492cc3a2015-01-22 18:46:26 -080031import org.apache.felix.scr.annotations.Service;
Jonathan Hart6cd2f352015-01-13 17:44:45 -080032import org.onlab.packet.IpAddress;
33import org.onlab.packet.IpPrefix;
34import org.onlab.packet.MacAddress;
35import org.onlab.packet.VlanId;
Brian O'Connorabafb502014-12-02 22:26:20 -080036import org.onosproject.net.ConnectPoint;
37import org.onosproject.net.DeviceId;
38import org.onosproject.net.PortNumber;
39import org.onosproject.net.host.HostAdminService;
40import org.onosproject.net.host.InterfaceIpAddress;
41import org.onosproject.net.host.PortAddresses;
Jonathan Hart74f9c3b2014-09-29 20:03:50 -070042import org.slf4j.Logger;
43
Jonathan Hartd7bd9822014-10-20 18:18:02 -070044import com.fasterxml.jackson.databind.ObjectMapper;
45
Jonathan Hart74f9c3b2014-09-29 20:03:50 -070046/**
47 * Simple configuration module to read in supplementary network configuration
48 * from a file.
49 */
50@Component(immediate = true)
Pavlin Radoslavov492cc3a2015-01-22 18:46:26 -080051@Service
52public class NetworkConfigReader implements NetworkConfigService {
Jonathan Hart74f9c3b2014-09-29 20:03:50 -070053
54 private final Logger log = getLogger(getClass());
55
Pavlin Radoslavov0a297b12014-11-11 16:03:27 -080056 // Current working dir seems to be /opt/onos/apache-karaf-3.0.2
57 // TODO: Set the path to /opt/onos/config
58 private static final String CONFIG_DIR = "../config";
59 private static final String DEFAULT_CONFIG_FILE = "addresses.json";
Jonathan Hart74f9c3b2014-09-29 20:03:50 -070060 private String configFileName = DEFAULT_CONFIG_FILE;
61
62 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
63 protected HostAdminService hostAdminService;
64
65 @Activate
66 protected void activate() {
Jonathan Hart74f9c3b2014-09-29 20:03:50 -070067 AddressConfiguration config = readNetworkConfig();
Jonathan Hart74f9c3b2014-09-29 20:03:50 -070068 if (config != null) {
Pavlin Radoslavov0a297b12014-11-11 16:03:27 -080069 applyNetworkConfig(config);
Jonathan Hart74f9c3b2014-09-29 20:03:50 -070070 }
Saurav Dasfbe25c52015-03-04 11:12:00 -080071 log.info("Started network config reader");
Jonathan Hart74f9c3b2014-09-29 20:03:50 -070072 }
73
74 @Deactivate
75 protected void deactivate() {
76 log.info("Stopped");
77 }
78
Pavlin Radoslavov0a297b12014-11-11 16:03:27 -080079 /**
80 * Reads the network configuration.
81 *
82 * @return the network configuration on success, otherwise null
83 */
Jonathan Hart74f9c3b2014-09-29 20:03:50 -070084 private AddressConfiguration readNetworkConfig() {
Pavlin Radoslavov0a297b12014-11-11 16:03:27 -080085 File configFile = new File(CONFIG_DIR, configFileName);
Jonathan Hart74f9c3b2014-09-29 20:03:50 -070086 ObjectMapper mapper = new ObjectMapper();
87
88 try {
Pavlin Radoslavov0a297b12014-11-11 16:03:27 -080089 log.info("Loading config: {}", configFile.getAbsolutePath());
Jonathan Hart74f9c3b2014-09-29 20:03:50 -070090 AddressConfiguration config =
91 mapper.readValue(configFile, AddressConfiguration.class);
92
93 return config;
94 } catch (FileNotFoundException e) {
95 log.warn("Configuration file not found: {}", configFileName);
96 } catch (IOException e) {
Pavlin Radoslavov0a297b12014-11-11 16:03:27 -080097 log.error("Error loading configuration", e);
Jonathan Hart74f9c3b2014-09-29 20:03:50 -070098 }
99
100 return null;
101 }
102
Pavlin Radoslavov0a297b12014-11-11 16:03:27 -0800103 /**
104 * Applies the network configuration.
105 *
106 * @param config the network configuration to apply
107 */
108 private void applyNetworkConfig(AddressConfiguration config) {
109 for (AddressEntry entry : config.getAddresses()) {
110 ConnectPoint cp = new ConnectPoint(
111 DeviceId.deviceId(dpidToUri(entry.getDpid())),
112 PortNumber.portNumber(entry.getPortNumber()));
113
114 Set<InterfaceIpAddress> interfaceIpAddresses = new HashSet<>();
115 for (String strIp : entry.getIpAddresses()) {
116 // Get the IP address and the subnet mask length
117 try {
118 String[] splits = strIp.split("/");
119 if (splits.length != 2) {
Jonathan Hart6cd2f352015-01-13 17:44:45 -0800120 throw new IllegalArgumentException(
121 "Invalid IP address and prefix length format");
Pavlin Radoslavov0a297b12014-11-11 16:03:27 -0800122 }
123 // NOTE: IpPrefix will mask-out the bits after the prefix length.
124 IpPrefix subnet = IpPrefix.valueOf(strIp);
125 IpAddress addr = IpAddress.valueOf(splits[0]);
126 InterfaceIpAddress ia =
127 new InterfaceIpAddress(addr, subnet);
128 interfaceIpAddresses.add(ia);
129 } catch (IllegalArgumentException e) {
130 log.warn("Bad format for IP address in config: {}", strIp);
131 }
132 }
133
134 MacAddress macAddress = null;
135 if (entry.getMacAddress() != null) {
136 try {
137 macAddress = MacAddress.valueOf(entry.getMacAddress());
138 } catch (IllegalArgumentException e) {
139 log.warn("Bad format for MAC address in config: {}",
140 entry.getMacAddress());
141 }
142 }
143
Jonathan Hart6cd2f352015-01-13 17:44:45 -0800144 VlanId vlan = null;
145 if (entry.getVlan() == null) {
146 vlan = VlanId.NONE;
147 } else {
148 try {
149 vlan = VlanId.vlanId(entry.getVlan());
150 } catch (IllegalArgumentException e) {
151 log.warn("Bad format for VLAN id in config: {}",
152 entry.getVlan());
153 vlan = VlanId.NONE;
154 }
155 }
156
Pavlin Radoslavov0a297b12014-11-11 16:03:27 -0800157 PortAddresses addresses = new PortAddresses(cp,
Jonathan Hart6cd2f352015-01-13 17:44:45 -0800158 interfaceIpAddresses, macAddress, vlan);
Pavlin Radoslavov0a297b12014-11-11 16:03:27 -0800159 hostAdminService.bindAddressesToPort(addresses);
160 }
161 }
162
Jonathan Hart74f9c3b2014-09-29 20:03:50 -0700163 private static String dpidToUri(String dpid) {
164 return "of:" + dpid.replace(":", "");
165 }
166}