Added support for parsing and handling BGP Confederation related AS Path
attributes. Note: BGP Confedertions are not supported (yet). Also, updated/simplified the MED comparison in the BGP Path Comparison implementation. Change-Id: Iabe01facffd2c6912f33f647841c1244d85282f3
Showing
4 changed files
with
190 additions
and
84 deletions
... | @@ -168,6 +168,12 @@ public final class BgpConstants { | ... | @@ -168,6 +168,12 @@ public final class BgpConstants { |
168 | /** BGP UPDATE AS_PATH Type: AS_SEQUENCE. */ | 168 | /** BGP UPDATE AS_PATH Type: AS_SEQUENCE. */ |
169 | public static final int AS_SEQUENCE = 2; | 169 | public static final int AS_SEQUENCE = 2; |
170 | 170 | ||
171 | + /** BGP UPDATE AS_PATH Type: AS_CONFED_SEQUENCE. */ | ||
172 | + public static final int AS_CONFED_SEQUENCE = 3; | ||
173 | + | ||
174 | + /** BGP UPDATE AS_PATH Type: AS_CONFED_SET. */ | ||
175 | + public static final int AS_CONFED_SET = 4; | ||
176 | + | ||
171 | /** | 177 | /** |
172 | * Gets the BGP AS_PATH type as a string. | 178 | * Gets the BGP AS_PATH type as a string. |
173 | * | 179 | * |
... | @@ -184,6 +190,12 @@ public final class BgpConstants { | ... | @@ -184,6 +190,12 @@ public final class BgpConstants { |
184 | case AS_SEQUENCE: | 190 | case AS_SEQUENCE: |
185 | typeString = "AS_SEQUENCE"; | 191 | typeString = "AS_SEQUENCE"; |
186 | break; | 192 | break; |
193 | + case AS_CONFED_SEQUENCE: | ||
194 | + typeString = "AS_CONFED_SEQUENCE"; | ||
195 | + break; | ||
196 | + case AS_CONFED_SET: | ||
197 | + typeString = "AS_CONFED_SET"; | ||
198 | + break; | ||
187 | default: | 199 | default: |
188 | break; | 200 | break; |
189 | } | 201 | } | ... | ... |
... | @@ -21,6 +21,7 @@ import java.util.ArrayList; | ... | @@ -21,6 +21,7 @@ import java.util.ArrayList; |
21 | import java.util.Objects; | 21 | import java.util.Objects; |
22 | 22 | ||
23 | import org.onlab.onos.sdnip.RouteEntry; | 23 | import org.onlab.onos.sdnip.RouteEntry; |
24 | +import org.onlab.onos.sdnip.bgp.BgpConstants.Update; | ||
24 | import org.onlab.packet.Ip4Address; | 25 | import org.onlab.packet.Ip4Address; |
25 | import org.onlab.packet.Ip4Prefix; | 26 | import org.onlab.packet.Ip4Prefix; |
26 | 27 | ||
... | @@ -35,8 +36,7 @@ public class BgpRouteEntry extends RouteEntry { | ... | @@ -35,8 +36,7 @@ public class BgpRouteEntry extends RouteEntry { |
35 | private final byte origin; // Route ORIGIN: IGP, EGP, INCOMPLETE | 36 | private final byte origin; // Route ORIGIN: IGP, EGP, INCOMPLETE |
36 | private final AsPath asPath; // The AS Path | 37 | private final AsPath asPath; // The AS Path |
37 | private final long localPref; // The local preference for the route | 38 | private final long localPref; // The local preference for the route |
38 | - private long multiExitDisc = | 39 | + private long multiExitDisc = Update.MultiExitDisc.LOWEST_MULTI_EXIT_DISC; |
39 | - BgpConstants.Update.MultiExitDisc.LOWEST_MULTI_EXIT_DISC; | ||
40 | 40 | ||
41 | /** | 41 | /** |
42 | * Class constructor. | 42 | * Class constructor. |
... | @@ -116,21 +116,33 @@ public class BgpRouteEntry extends RouteEntry { | ... | @@ -116,21 +116,33 @@ public class BgpRouteEntry extends RouteEntry { |
116 | * Tests whether the route is originated from the local AS. | 116 | * Tests whether the route is originated from the local AS. |
117 | * <p> | 117 | * <p> |
118 | * The route is considered originated from the local AS if the AS Path | 118 | * The route is considered originated from the local AS if the AS Path |
119 | - * is empty or if it begins with an AS_SET. | 119 | + * is empty or if it begins with an AS_SET (after skipping |
120 | + * AS_CONFED_SEQUENCE and AS_CONFED_SET). | ||
120 | * </p> | 121 | * </p> |
121 | * | 122 | * |
122 | * @return true if the route is originated from the local AS, otherwise | 123 | * @return true if the route is originated from the local AS, otherwise |
123 | * false | 124 | * false |
124 | */ | 125 | */ |
125 | boolean isLocalRoute() { | 126 | boolean isLocalRoute() { |
126 | - if (asPath.getPathSegments().isEmpty()) { | 127 | + PathSegment firstPathSegment = null; |
127 | - return true; | 128 | + |
129 | + // Find the first Path Segment by ignoring the AS_CONFED_* segments | ||
130 | + for (PathSegment pathSegment : asPath.getPathSegments()) { | ||
131 | + if ((pathSegment.getType() == Update.AsPath.AS_SET) || | ||
132 | + (pathSegment.getType() == Update.AsPath.AS_SEQUENCE)) { | ||
133 | + firstPathSegment = pathSegment; | ||
134 | + break; | ||
135 | + } | ||
136 | + } | ||
137 | + if (firstPathSegment == null) { | ||
138 | + return true; // Local route: no path segments | ||
128 | } | 139 | } |
129 | - PathSegment firstPathSegment = asPath.getPathSegments().get(0); | 140 | + // If the first path segment is AS_SET, the route is considered local |
130 | - if (firstPathSegment.getType() == BgpConstants.Update.AsPath.AS_SET) { | 141 | + if (firstPathSegment.getType() == Update.AsPath.AS_SET) { |
131 | return true; | 142 | return true; |
132 | } | 143 | } |
133 | - return false; | 144 | + |
145 | + return false; // The route is not local | ||
134 | } | 146 | } |
135 | 147 | ||
136 | /** | 148 | /** |
... | @@ -143,10 +155,25 @@ public class BgpRouteEntry extends RouteEntry { | ... | @@ -143,10 +155,25 @@ public class BgpRouteEntry extends RouteEntry { |
143 | * @return the BGP Neighbor AS number the route was received from. | 155 | * @return the BGP Neighbor AS number the route was received from. |
144 | */ | 156 | */ |
145 | long getNeighborAs() { | 157 | long getNeighborAs() { |
158 | + PathSegment firstPathSegment = null; | ||
159 | + | ||
146 | if (isLocalRoute()) { | 160 | if (isLocalRoute()) { |
147 | return BgpConstants.BGP_AS_0; | 161 | return BgpConstants.BGP_AS_0; |
148 | } | 162 | } |
149 | - PathSegment firstPathSegment = asPath.getPathSegments().get(0); | 163 | + |
164 | + // Find the first Path Segment by ignoring the AS_CONFED_* segments | ||
165 | + for (PathSegment pathSegment : asPath.getPathSegments()) { | ||
166 | + if ((pathSegment.getType() == Update.AsPath.AS_SET) || | ||
167 | + (pathSegment.getType() == Update.AsPath.AS_SEQUENCE)) { | ||
168 | + firstPathSegment = pathSegment; | ||
169 | + break; | ||
170 | + } | ||
171 | + } | ||
172 | + if (firstPathSegment == null) { | ||
173 | + // NOTE: Shouldn't happen - should be captured by isLocalRoute() | ||
174 | + return BgpConstants.BGP_AS_0; | ||
175 | + } | ||
176 | + | ||
150 | if (firstPathSegment.getSegmentAsNumbers().isEmpty()) { | 177 | if (firstPathSegment.getSegmentAsNumbers().isEmpty()) { |
151 | // TODO: Shouldn't happen. Should check during the parsing. | 178 | // TODO: Shouldn't happen. Should check during the parsing. |
152 | return BgpConstants.BGP_AS_0; | 179 | return BgpConstants.BGP_AS_0; |
... | @@ -211,11 +238,10 @@ public class BgpRouteEntry extends RouteEntry { | ... | @@ -211,11 +238,10 @@ public class BgpRouteEntry extends RouteEntry { |
211 | 238 | ||
212 | // Compare the MED if the neighbor AS is same: larger is better | 239 | // Compare the MED if the neighbor AS is same: larger is better |
213 | medLabel: { | 240 | medLabel: { |
214 | - boolean thisIsLocalRoute = isLocalRoute(); | 241 | + if (isLocalRoute() || other.isLocalRoute()) { |
215 | - if (thisIsLocalRoute != other.isLocalRoute()) { | 242 | + // Compare MEDs for non-local routes only |
216 | - break medLabel; // AS number is different | 243 | + break medLabel; |
217 | } | 244 | } |
218 | - if (!thisIsLocalRoute) { | ||
219 | long thisNeighborAs = getNeighborAs(); | 245 | long thisNeighborAs = getNeighborAs(); |
220 | if (thisNeighborAs != other.getNeighborAs()) { | 246 | if (thisNeighborAs != other.getNeighborAs()) { |
221 | break medLabel; // AS number is different | 247 | break medLabel; // AS number is different |
... | @@ -223,7 +249,6 @@ public class BgpRouteEntry extends RouteEntry { | ... | @@ -223,7 +249,6 @@ public class BgpRouteEntry extends RouteEntry { |
223 | if (thisNeighborAs == BgpConstants.BGP_AS_0) { | 249 | if (thisNeighborAs == BgpConstants.BGP_AS_0) { |
224 | break medLabel; // Invalid AS number | 250 | break medLabel; // Invalid AS number |
225 | } | 251 | } |
226 | - } | ||
227 | 252 | ||
228 | // Compare the MED | 253 | // Compare the MED |
229 | if (getMultiExitDisc() != other.getMultiExitDisc()) { | 254 | if (getMultiExitDisc() != other.getMultiExitDisc()) { |
... | @@ -253,13 +278,16 @@ public class BgpRouteEntry extends RouteEntry { | ... | @@ -253,13 +278,16 @@ public class BgpRouteEntry extends RouteEntry { |
253 | * A class to represent AS Path Segment. | 278 | * A class to represent AS Path Segment. |
254 | */ | 279 | */ |
255 | public static class PathSegment { | 280 | public static class PathSegment { |
256 | - private final byte type; // Segment type: AS_SET, AS_SEQUENCE | 281 | + // Segment type: AS_SET(1), AS_SEQUENCE(2), AS_CONFED_SEQUENCE(3), |
282 | + // AS_CONFED_SET(4) | ||
283 | + private final byte type; | ||
257 | private final ArrayList<Long> segmentAsNumbers; // Segment AS numbers | 284 | private final ArrayList<Long> segmentAsNumbers; // Segment AS numbers |
258 | 285 | ||
259 | /** | 286 | /** |
260 | * Constructor. | 287 | * Constructor. |
261 | * | 288 | * |
262 | - * @param type the Path Segment Type: 1=AS_SET, 2=AS_SEQUENCE | 289 | + * @param type the Path Segment Type: AS_SET(1), AS_SEQUENCE(2), |
290 | + * AS_CONFED_SEQUENCE(3), AS_CONFED_SET(4) | ||
263 | * @param segmentAsNumbers the Segment AS numbers | 291 | * @param segmentAsNumbers the Segment AS numbers |
264 | */ | 292 | */ |
265 | PathSegment(byte type, ArrayList<Long> segmentAsNumbers) { | 293 | PathSegment(byte type, ArrayList<Long> segmentAsNumbers) { |
... | @@ -268,9 +296,11 @@ public class BgpRouteEntry extends RouteEntry { | ... | @@ -268,9 +296,11 @@ public class BgpRouteEntry extends RouteEntry { |
268 | } | 296 | } |
269 | 297 | ||
270 | /** | 298 | /** |
271 | - * Gets the Path Segment Type: AS_SET, AS_SEQUENCE. | 299 | + * Gets the Path Segment Type: AS_SET(1), AS_SEQUENCE(2), |
300 | + * AS_CONFED_SEQUENCE(3), AS_CONFED_SET(4). | ||
272 | * | 301 | * |
273 | - * @return the Path Segment Type: AS_SET, AS_SEQUENCE | 302 | + * @return the Path Segment Type: AS_SET(1), AS_SEQUENCE(2), |
303 | + * AS_CONFED_SEQUENCE(3), AS_CONFED_SET(4) | ||
274 | */ | 304 | */ |
275 | public byte getType() { | 305 | public byte getType() { |
276 | return type; | 306 | return type; |
... | @@ -309,7 +339,7 @@ public class BgpRouteEntry extends RouteEntry { | ... | @@ -309,7 +339,7 @@ public class BgpRouteEntry extends RouteEntry { |
309 | @Override | 339 | @Override |
310 | public String toString() { | 340 | public String toString() { |
311 | return MoreObjects.toStringHelper(getClass()) | 341 | return MoreObjects.toStringHelper(getClass()) |
312 | - .add("type", BgpConstants.Update.AsPath.typeToString(type)) | 342 | + .add("type", Update.AsPath.typeToString(type)) |
313 | .add("segmentAsNumbers", this.segmentAsNumbers) | 343 | .add("segmentAsNumbers", this.segmentAsNumbers) |
314 | .toString(); | 344 | .toString(); |
315 | } | 345 | } |
... | @@ -333,15 +363,27 @@ public class BgpRouteEntry extends RouteEntry { | ... | @@ -333,15 +363,27 @@ public class BgpRouteEntry extends RouteEntry { |
333 | // | 363 | // |
334 | // Precompute the AS Path Length: | 364 | // Precompute the AS Path Length: |
335 | // - AS_SET counts as 1 | 365 | // - AS_SET counts as 1 |
366 | + // - AS_SEQUENCE counts how many AS numbers are included | ||
367 | + // - AS_CONFED_SEQUENCE and AS_CONFED_SET are ignored | ||
336 | // | 368 | // |
337 | int pl = 0; | 369 | int pl = 0; |
338 | for (PathSegment pathSegment : pathSegments) { | 370 | for (PathSegment pathSegment : pathSegments) { |
339 | - if (pathSegment.getType() == | 371 | + switch (pathSegment.getType()) { |
340 | - BgpConstants.Update.AsPath.AS_SET) { | 372 | + case Update.AsPath.AS_SET: |
341 | - pl++; | 373 | + pl++; // AS_SET counts as 1 |
342 | - continue; | 374 | + break; |
343 | - } | 375 | + case Update.AsPath.AS_SEQUENCE: |
376 | + // Count each AS number | ||
344 | pl += pathSegment.getSegmentAsNumbers().size(); | 377 | pl += pathSegment.getSegmentAsNumbers().size(); |
378 | + break; | ||
379 | + case Update.AsPath.AS_CONFED_SEQUENCE: | ||
380 | + break; // Ignore | ||
381 | + case Update.AsPath.AS_CONFED_SET: | ||
382 | + break; // Ignore | ||
383 | + default: | ||
384 | + // TODO: What to do if the Path Segment type is unknown? | ||
385 | + break; | ||
386 | + } | ||
345 | } | 387 | } |
346 | asPathLength = pl; | 388 | asPathLength = pl; |
347 | } | 389 | } |
... | @@ -444,7 +486,7 @@ public class BgpRouteEntry extends RouteEntry { | ... | @@ -444,7 +486,7 @@ public class BgpRouteEntry extends RouteEntry { |
444 | .add("prefix", prefix()) | 486 | .add("prefix", prefix()) |
445 | .add("nextHop", nextHop()) | 487 | .add("nextHop", nextHop()) |
446 | .add("bgpId", bgpSession.getRemoteBgpId()) | 488 | .add("bgpId", bgpSession.getRemoteBgpId()) |
447 | - .add("origin", BgpConstants.Update.Origin.typeToString(origin)) | 489 | + .add("origin", Update.Origin.typeToString(origin)) |
448 | .add("asPath", asPath) | 490 | .add("asPath", asPath) |
449 | .add("localPref", localPref) | 491 | .add("localPref", localPref) |
450 | .add("multiExitDisc", multiExitDisc) | 492 | .add("multiExitDisc", multiExitDisc) | ... | ... |
... | @@ -975,6 +975,10 @@ public class BgpSession extends SimpleChannelHandler { | ... | @@ -975,6 +975,10 @@ public class BgpSession extends SimpleChannelHandler { |
975 | case BgpConstants.Update.AsPath.AS_SET: | 975 | case BgpConstants.Update.AsPath.AS_SET: |
976 | // FALLTHROUGH | 976 | // FALLTHROUGH |
977 | case BgpConstants.Update.AsPath.AS_SEQUENCE: | 977 | case BgpConstants.Update.AsPath.AS_SEQUENCE: |
978 | + // FALLTHROUGH | ||
979 | + case BgpConstants.Update.AsPath.AS_CONFED_SEQUENCE: | ||
980 | + // FALLTHROUGH | ||
981 | + case BgpConstants.Update.AsPath.AS_CONFED_SET: | ||
978 | break; | 982 | break; |
979 | default: | 983 | default: |
980 | // ERROR: Invalid Path Segment Type | 984 | // ERROR: Invalid Path Segment Type | ... | ... |
... | @@ -28,30 +28,63 @@ import org.junit.Test; | ... | @@ -28,30 +28,63 @@ import org.junit.Test; |
28 | */ | 28 | */ |
29 | public class AsPathTest { | 29 | public class AsPathTest { |
30 | /** | 30 | /** |
31 | - * Generates an AS Path. | 31 | + * Generates Path Segments. |
32 | * | 32 | * |
33 | - * @return a generated AS Path | 33 | + * @return the generated Path Segments |
34 | */ | 34 | */ |
35 | - private BgpRouteEntry.AsPath generateAsPath() { | 35 | + private ArrayList<BgpRouteEntry.PathSegment> generatePathSegments() { |
36 | ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>(); | 36 | ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>(); |
37 | - byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE; | 37 | + byte pathSegmentType; |
38 | - ArrayList<Long> segmentAsNumbers1 = new ArrayList<>(); | 38 | + ArrayList<Long> segmentAsNumbers; |
39 | - segmentAsNumbers1.add((long) 1); | 39 | + BgpRouteEntry.PathSegment pathSegment; |
40 | - segmentAsNumbers1.add((long) 2); | 40 | + |
41 | - segmentAsNumbers1.add((long) 3); | 41 | + pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_CONFED_SEQUENCE; |
42 | - BgpRouteEntry.PathSegment pathSegment1 = | 42 | + segmentAsNumbers = new ArrayList<>(); |
43 | - new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1); | 43 | + segmentAsNumbers.add((long) 1); |
44 | - pathSegments.add(pathSegment1); | 44 | + segmentAsNumbers.add((long) 2); |
45 | + segmentAsNumbers.add((long) 3); | ||
46 | + pathSegment = | ||
47 | + new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers); | ||
48 | + pathSegments.add(pathSegment); | ||
45 | // | 49 | // |
46 | - byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET; | 50 | + pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_CONFED_SET; |
47 | - ArrayList<Long> segmentAsNumbers2 = new ArrayList<>(); | 51 | + segmentAsNumbers = new ArrayList<>(); |
48 | - segmentAsNumbers2.add((long) 4); | 52 | + segmentAsNumbers.add((long) 4); |
49 | - segmentAsNumbers2.add((long) 5); | 53 | + segmentAsNumbers.add((long) 5); |
50 | - segmentAsNumbers2.add((long) 6); | 54 | + segmentAsNumbers.add((long) 6); |
51 | - BgpRouteEntry.PathSegment pathSegment2 = | 55 | + pathSegment = |
52 | - new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2); | 56 | + new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers); |
53 | - pathSegments.add(pathSegment2); | 57 | + pathSegments.add(pathSegment); |
54 | // | 58 | // |
59 | + pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE; | ||
60 | + segmentAsNumbers = new ArrayList<>(); | ||
61 | + segmentAsNumbers.add((long) 7); | ||
62 | + segmentAsNumbers.add((long) 8); | ||
63 | + segmentAsNumbers.add((long) 9); | ||
64 | + pathSegment = | ||
65 | + new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers); | ||
66 | + pathSegments.add(pathSegment); | ||
67 | + // | ||
68 | + pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SET; | ||
69 | + segmentAsNumbers = new ArrayList<>(); | ||
70 | + segmentAsNumbers.add((long) 10); | ||
71 | + segmentAsNumbers.add((long) 11); | ||
72 | + segmentAsNumbers.add((long) 12); | ||
73 | + pathSegment = | ||
74 | + new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers); | ||
75 | + pathSegments.add(pathSegment); | ||
76 | + | ||
77 | + return pathSegments; | ||
78 | + } | ||
79 | + | ||
80 | + /** | ||
81 | + * Generates an AS Path. | ||
82 | + * | ||
83 | + * @return a generated AS Path | ||
84 | + */ | ||
85 | + private BgpRouteEntry.AsPath generateAsPath() { | ||
86 | + ArrayList<BgpRouteEntry.PathSegment> pathSegments = | ||
87 | + generatePathSegments(); | ||
55 | BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments); | 88 | BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments); |
56 | 89 | ||
57 | return asPath; | 90 | return asPath; |
... | @@ -65,9 +98,11 @@ public class AsPathTest { | ... | @@ -65,9 +98,11 @@ public class AsPathTest { |
65 | BgpRouteEntry.AsPath asPath = generateAsPath(); | 98 | BgpRouteEntry.AsPath asPath = generateAsPath(); |
66 | 99 | ||
67 | String expectedString = | 100 | String expectedString = |
68 | - "AsPath{pathSegments=" + | 101 | + "AsPath{pathSegments=[" + |
69 | - "[PathSegment{type=AS_SEQUENCE, segmentAsNumbers=[1, 2, 3]}, " + | 102 | + "PathSegment{type=AS_CONFED_SEQUENCE, segmentAsNumbers=[1, 2, 3]}, " + |
70 | - "PathSegment{type=AS_SET, segmentAsNumbers=[4, 5, 6]}]}"; | 103 | + "PathSegment{type=AS_CONFED_SET, segmentAsNumbers=[4, 5, 6]}, " + |
104 | + "PathSegment{type=AS_SEQUENCE, segmentAsNumbers=[7, 8, 9]}, " + | ||
105 | + "PathSegment{type=AS_SET, segmentAsNumbers=[10, 11, 12]}]}"; | ||
71 | assertThat(asPath.toString(), is(expectedString)); | 106 | assertThat(asPath.toString(), is(expectedString)); |
72 | } | 107 | } |
73 | 108 | ||
... | @@ -86,24 +121,8 @@ public class AsPathTest { | ... | @@ -86,24 +121,8 @@ public class AsPathTest { |
86 | @Test | 121 | @Test |
87 | public void testGetFields() { | 122 | public void testGetFields() { |
88 | // Create the fields to compare against | 123 | // Create the fields to compare against |
89 | - ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>(); | 124 | + ArrayList<BgpRouteEntry.PathSegment> pathSegments = |
90 | - byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE; | 125 | + generatePathSegments(); |
91 | - ArrayList<Long> segmentAsNumbers1 = new ArrayList<>(); | ||
92 | - segmentAsNumbers1.add((long) 1); | ||
93 | - segmentAsNumbers1.add((long) 2); | ||
94 | - segmentAsNumbers1.add((long) 3); | ||
95 | - BgpRouteEntry.PathSegment pathSegment1 = | ||
96 | - new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1); | ||
97 | - pathSegments.add(pathSegment1); | ||
98 | - // | ||
99 | - byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET; | ||
100 | - ArrayList<Long> segmentAsNumbers2 = new ArrayList<>(); | ||
101 | - segmentAsNumbers2.add((long) 4); | ||
102 | - segmentAsNumbers2.add((long) 5); | ||
103 | - segmentAsNumbers2.add((long) 6); | ||
104 | - BgpRouteEntry.PathSegment pathSegment2 = | ||
105 | - new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2); | ||
106 | - pathSegments.add(pathSegment2); | ||
107 | 126 | ||
108 | // Generate the entry to test | 127 | // Generate the entry to test |
109 | BgpRouteEntry.AsPath asPath = generateAsPath(); | 128 | BgpRouteEntry.AsPath asPath = generateAsPath(); |
... | @@ -116,6 +135,11 @@ public class AsPathTest { | ... | @@ -116,6 +135,11 @@ public class AsPathTest { |
116 | */ | 135 | */ |
117 | @Test | 136 | @Test |
118 | public void testGetAsPathLength() { | 137 | public void testGetAsPathLength() { |
138 | + // | ||
139 | + // NOTE: | ||
140 | + // - AS_CONFED_SEQUENCE and AS_CONFED_SET are excluded | ||
141 | + // - AS_SET counts as a single hop | ||
142 | + // | ||
119 | BgpRouteEntry.AsPath asPath = generateAsPath(); | 143 | BgpRouteEntry.AsPath asPath = generateAsPath(); |
120 | assertThat(asPath.getAsPathLength(), is(4)); | 144 | assertThat(asPath.getAsPathLength(), is(4)); |
121 | 145 | ||
... | @@ -145,23 +169,45 @@ public class AsPathTest { | ... | @@ -145,23 +169,45 @@ public class AsPathTest { |
145 | 169 | ||
146 | // Setup AS Path 2 | 170 | // Setup AS Path 2 |
147 | ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>(); | 171 | ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>(); |
148 | - byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE; | 172 | + byte pathSegmentType; |
149 | - ArrayList<Long> segmentAsNumbers1 = new ArrayList<>(); | 173 | + ArrayList<Long> segmentAsNumbers; |
150 | - segmentAsNumbers1.add((long) 1); | 174 | + BgpRouteEntry.PathSegment pathSegment; |
151 | - segmentAsNumbers1.add((long) 2); | 175 | + |
152 | - segmentAsNumbers1.add((long) 3); | 176 | + pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_CONFED_SEQUENCE; |
153 | - BgpRouteEntry.PathSegment pathSegment1 = | 177 | + segmentAsNumbers = new ArrayList<>(); |
154 | - new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1); | 178 | + segmentAsNumbers.add((long) 1); |
155 | - pathSegments.add(pathSegment1); | 179 | + segmentAsNumbers.add((long) 2); |
180 | + segmentAsNumbers.add((long) 3); | ||
181 | + pathSegment = | ||
182 | + new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers); | ||
183 | + pathSegments.add(pathSegment); | ||
184 | + // | ||
185 | + pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_CONFED_SET; | ||
186 | + segmentAsNumbers = new ArrayList<>(); | ||
187 | + segmentAsNumbers.add((long) 4); | ||
188 | + segmentAsNumbers.add((long) 5); | ||
189 | + segmentAsNumbers.add((long) 6); | ||
190 | + pathSegment = | ||
191 | + new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers); | ||
192 | + pathSegments.add(pathSegment); | ||
193 | + // | ||
194 | + pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE; | ||
195 | + segmentAsNumbers = new ArrayList<>(); | ||
196 | + segmentAsNumbers.add((long) 7); | ||
197 | + segmentAsNumbers.add((long) 8); | ||
198 | + segmentAsNumbers.add((long) 9); | ||
199 | + pathSegment = | ||
200 | + new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers); | ||
201 | + pathSegments.add(pathSegment); | ||
156 | // | 202 | // |
157 | - byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET; | 203 | + pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SET; |
158 | - ArrayList<Long> segmentAsNumbers2 = new ArrayList<>(); | 204 | + segmentAsNumbers = new ArrayList<>(); |
159 | - segmentAsNumbers2.add((long) 4); | 205 | + segmentAsNumbers.add((long) 10); |
160 | - segmentAsNumbers2.add((long) 55); // Different | 206 | + segmentAsNumbers.add((long) 111); // Different |
161 | - segmentAsNumbers2.add((long) 6); | 207 | + segmentAsNumbers.add((long) 12); |
162 | - BgpRouteEntry.PathSegment pathSegment2 = | 208 | + pathSegment = |
163 | - new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2); | 209 | + new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers); |
164 | - pathSegments.add(pathSegment2); | 210 | + pathSegments.add(pathSegment); |
165 | // | 211 | // |
166 | BgpRouteEntry.AsPath asPath2 = new BgpRouteEntry.AsPath(pathSegments); | 212 | BgpRouteEntry.AsPath asPath2 = new BgpRouteEntry.AsPath(pathSegments); |
167 | 213 | ||
... | @@ -176,9 +222,11 @@ public class AsPathTest { | ... | @@ -176,9 +222,11 @@ public class AsPathTest { |
176 | BgpRouteEntry.AsPath asPath = generateAsPath(); | 222 | BgpRouteEntry.AsPath asPath = generateAsPath(); |
177 | 223 | ||
178 | String expectedString = | 224 | String expectedString = |
179 | - "AsPath{pathSegments=" + | 225 | + "AsPath{pathSegments=[" + |
180 | - "[PathSegment{type=AS_SEQUENCE, segmentAsNumbers=[1, 2, 3]}, " + | 226 | + "PathSegment{type=AS_CONFED_SEQUENCE, segmentAsNumbers=[1, 2, 3]}, " + |
181 | - "PathSegment{type=AS_SET, segmentAsNumbers=[4, 5, 6]}]}"; | 227 | + "PathSegment{type=AS_CONFED_SET, segmentAsNumbers=[4, 5, 6]}, " + |
228 | + "PathSegment{type=AS_SEQUENCE, segmentAsNumbers=[7, 8, 9]}, " + | ||
229 | + "PathSegment{type=AS_SET, segmentAsNumbers=[10, 11, 12]}]}"; | ||
182 | assertThat(asPath.toString(), is(expectedString)); | 230 | assertThat(asPath.toString(), is(expectedString)); |
183 | } | 231 | } |
184 | } | 232 | } | ... | ... |
-
Please register or login to post a comment