blob: 30a00224759060286706e33dfc619257a44516df [file] [log] [blame]
slowrdb071b22017-07-07 11:10:25 -07001/*
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 */
16package org.onosproject.artemis.impl.bgpspeakers;
17
18import org.apache.commons.net.telnet.TelnetClient;
19import org.onosproject.routing.bgp.BgpInfoService;
20
21import java.io.InputStream;
22import java.io.PrintStream;
23import java.util.Arrays;
24
25/**
26 * Quagga interface to connect and announce prefixes.
27 */
28public class QuaggaBgpSpeakers extends BgpSpeakers {
29 private static final String PASSWORD = "sdnip";
30
31 private TelnetClient telnet = new TelnetClient();
32 private InputStream in;
33 private PrintStream out;
34
35 public QuaggaBgpSpeakers(BgpInfoService bgpInfoService) {
36 super(bgpInfoService);
37 }
38
39 @Override
40 public void announceSubPrefixes(String[] prefixes) {
41 bgpSessions.forEach((session) -> {
42 String peerIp = session.remoteInfo().ip4Address().toString(),
43 localAs = String.valueOf(session.remoteInfo().as4Number());
44 assert peerIp != null;
45
46 try {
47 telnet.connect(peerIp, 2605);
48 in = telnet.getInputStream();
49 out = new PrintStream(telnet.getOutputStream());
50
51 readUntil("Password: ");
52 write(PASSWORD);
53 readUntil("> ");
54
55 // we user remote AS as local because he is iBGP neighbor.
56 announcePrefix(prefixes, localAs);
57
58 disconnect();
59
60 log.info("Announced " + prefixes[0] + " and " + prefixes[1] + " at " + peerIp);
61 } catch (Exception e) {
62 log.warn(e.getMessage());
63 }
64 });
65 }
66
67 /**
68 * Read telnet buffer until a pattern is met.
69 *
70 * @param pattern string pattern to match in terminal
71 * @return matched string
72 */
73 private String readUntil(String pattern) {
74 try {
75 char lastChar = pattern.charAt(pattern.length() - 1);
76 StringBuffer sb = new StringBuffer();
77 char ch = (char) in.read();
78 while (true) {
79 sb.append(ch);
80 if (ch == lastChar) {
81 if (sb.toString().endsWith(pattern)) {
82 return sb.toString();
83 }
84 }
85 ch = (char) in.read();
86 }
87 } catch (Exception e) {
88 log.warn(e.getMessage());
89 }
90 return null;
91 }
92
93 /**
94 * Write to the telnet client.
95 *
96 * @param value string to write
97 */
98 private void write(String value) {
99 try {
100 out.println(value);
101 out.flush();
102 } catch (Exception e) {
103 log.warn(e.getMessage());
104 }
105 }
106
107 /**
108 * Configure terminal and announce prefix inside the Quagga router.
109 *
110 * @param prefixes prefixes to announce
111 * @param localAs ASN of BGP Speaker
112 */
113 private void announcePrefix(String[] prefixes, String localAs) {
114 write("en");
115 readUntil("# ");
116 write("configure terminal");
117 readUntil("(config)# ");
118 write("router bgp " + localAs);
119 readUntil("(config-router)# ");
120 Arrays.stream(prefixes).forEach((prefix) -> {
121 write("network " + prefix);
122 readUntil("(config-router)# ");
123 });
124 write("end");
125 }
126
127 /**
128 * Disconnect from the telnet session.
129 */
130 private void disconnect() {
131 try {
132 telnet.disconnect();
133 } catch (Exception e) {
134 log.warn(e.getMessage());
135 }
136 }
137}