bgp4r 0.0.13 → 0.0.14
Sign up to get free protection for your applications and to get access to all the features.
- data/bgp/messages/update.rb +8 -0
- data/bgp/nlris/label.rb +9 -1
- data/bgp/nlris/labeled.rb +11 -0
- data/bgp/nlris/nlri.rb +15 -4
- data/bgp/nlris/prefix.rb +11 -0
- data/bgp/nlris/rd.rb +13 -1
- data/bgp/nlris/vpn.rb +59 -10
- data/bgp/path_attributes/aggregator.rb +19 -0
- data/bgp/path_attributes/aigp.rb +63 -0
- data/bgp/path_attributes/as_path.rb +57 -0
- data/bgp/path_attributes/atomic_aggregate.rb +3 -0
- data/bgp/path_attributes/attribute.rb +10 -0
- data/bgp/path_attributes/attributes.rb +1 -0
- data/bgp/path_attributes/cluster_list.rb +24 -1
- data/bgp/path_attributes/communities.rb +32 -1
- data/bgp/path_attributes/extended_communities.rb +26 -0
- data/bgp/path_attributes/extended_community.rb +101 -16
- data/bgp/path_attributes/local_pref.rb +10 -0
- data/bgp/path_attributes/mp_reach.rb +21 -2
- data/bgp/path_attributes/mp_unreach.rb +5 -1
- data/bgp/path_attributes/multi_exit_disc.rb +10 -0
- data/bgp/path_attributes/next_hop.rb +20 -0
- data/bgp/path_attributes/origin.rb +14 -0
- data/bgp/path_attributes/originator_id.rb +17 -6
- data/bgp/path_attributes/path_attribute.rb +87 -2
- data/bgp/path_attributes/tlvs/tlv.rb +18 -0
- data/test/unit/messages/update_test.rb +79 -5
- data/test/unit/neighbor/neighbor_test.rb +0 -1
- data/test/unit/nlris/label_test.rb +6 -0
- data/test/unit/nlris/labeled_test.rb +12 -0
- data/test/unit/nlris/prefix_test.rb +5 -1
- data/test/unit/nlris/rd_test.rb +2 -0
- data/test/unit/nlris/vpn_test.rb +50 -0
- data/test/unit/path_attributes/aggregator_test.rb +6 -0
- data/test/unit/path_attributes/{aigp.rb → aigp_test.rb} +29 -0
- data/test/unit/path_attributes/as_path_test.rb +53 -0
- data/test/unit/path_attributes/atomic_aggregate_test.rb +3 -0
- data/test/unit/path_attributes/cluster_list_test.rb +15 -10
- data/test/unit/path_attributes/communities_test.rb +9 -4
- data/test/unit/path_attributes/extended_communities_test.rb +31 -3
- data/test/unit/path_attributes/extended_community_test.rb +52 -9
- data/test/unit/path_attributes/local_pref_test.rb +5 -0
- data/test/unit/path_attributes/mp_reach_test.rb +51 -4
- data/test/unit/path_attributes/mp_unreach_test.rb +9 -7
- data/test/unit/path_attributes/next_hop_test.rb +3 -0
- data/test/unit/path_attributes/origin_test.rb +1 -0
- data/test/unit/path_attributes/path_attribute_test.rb +53 -2
- data/test/unit/path_attributes/tlvs/tlv_test.rb +33 -0
- data/test/unit/path_attributes/tunnel_encapsulation_test (Jean-Michel's Laptop's conflicted copy 2011-11-02).rb +388 -0
- metadata +14 -4
data/bgp/messages/update.rb
CHANGED
@@ -183,6 +183,14 @@ class BGP::Update < BGP::Message
|
|
183
183
|
s.join("\n") + "\n" + msg.hexlify.join("\n") + "\n"
|
184
184
|
end
|
185
185
|
|
186
|
+
def to_hash
|
187
|
+
h = {}
|
188
|
+
h[:withdrawns] = @withdrawn.to_ary if @withdrawn
|
189
|
+
h[:path_attributes] = @path_attribute.to_hash if @path_attribute
|
190
|
+
h[:nlris] = @nlri.to_ary if @nlri
|
191
|
+
h
|
192
|
+
end
|
193
|
+
|
186
194
|
def self.withdrawn(u)
|
187
195
|
if u.nlri and u.nlri.size>0
|
188
196
|
Update.new(Withdrawn.new(*(u.nlri.nlris.collect { |n| n.to_s})))
|
data/bgp/nlris/label.rb
CHANGED
@@ -58,8 +58,10 @@ module BGP
|
|
58
58
|
@label_stack=[]
|
59
59
|
if args.size==1 and args[0].is_a?(String) and args[0].is_packed?
|
60
60
|
parse(args[0])
|
61
|
+
elsif args.size==1 and args[0].is_a?(Hash)
|
62
|
+
@label_stack = args[0][:labels].collect { |l| Label.new(l) }
|
61
63
|
else
|
62
|
-
args.
|
64
|
+
@label_stack = args.collect { |arg| (arg.is_a?(Label) ? arg : Label.new(arg)) }
|
63
65
|
end
|
64
66
|
end
|
65
67
|
def size
|
@@ -84,6 +86,12 @@ module BGP
|
|
84
86
|
"Label Stack=#{@label_stack.collect{ |l| l.label }.join(',')} (bottom)"
|
85
87
|
end
|
86
88
|
end
|
89
|
+
def to_ary
|
90
|
+
@label_stack.collect { |e| e.label }
|
91
|
+
end
|
92
|
+
def to_hash
|
93
|
+
@label_stack.size==1 ? {:label=>@label_stack[0].label} : {:labels=> to_ary}
|
94
|
+
end
|
87
95
|
def bit_length
|
88
96
|
@label_stack.compact.size*24
|
89
97
|
end
|
data/bgp/nlris/labeled.rb
CHANGED
@@ -17,6 +17,11 @@ module BGP
|
|
17
17
|
def initialize(*args)
|
18
18
|
if args.size>0 and args[0].is_a?(String) and args[0].is_packed?
|
19
19
|
parse(*args)
|
20
|
+
elsif args.size==1 and args[0].is_a?(Hash)
|
21
|
+
# TODO: a new_prefix :prefix=>, :labels=>
|
22
|
+
# :other=> ...
|
23
|
+
@prefix = Prefix.new(args[0][:prefix]) # assuming it's a Prefix, which it may not be
|
24
|
+
@labels = Label_stack.new(*args[0][:labels])
|
20
25
|
else
|
21
26
|
@prefix, *labels = args
|
22
27
|
@labels = Label_stack.new(*labels)
|
@@ -25,6 +30,9 @@ module BGP
|
|
25
30
|
#FIXME... a mixin path_id ????
|
26
31
|
def path_id
|
27
32
|
@prefix.path_id
|
33
|
+
rescue
|
34
|
+
# return nil
|
35
|
+
# RD: 0/0
|
28
36
|
end
|
29
37
|
def path_id=(val)
|
30
38
|
@prefix.path_id=val
|
@@ -40,6 +48,9 @@ module BGP
|
|
40
48
|
s
|
41
49
|
end
|
42
50
|
end
|
51
|
+
def to_hash
|
52
|
+
@labels.to_hash.merge(@prefix.to_hash)
|
53
|
+
end
|
43
54
|
def to_s
|
44
55
|
"#{@labels} #{@prefix}"
|
45
56
|
end
|
data/bgp/nlris/nlri.rb
CHANGED
@@ -94,18 +94,29 @@ module BGP
|
|
94
94
|
def to_s(indent=0)
|
95
95
|
@nlris.join("\n#{([' ']*indent).join}")
|
96
96
|
end
|
97
|
-
|
97
|
+
|
98
98
|
def size
|
99
99
|
@nlris.size
|
100
100
|
end
|
101
101
|
|
102
|
+
def to_ary
|
103
|
+
@nlris.collect { |n| n.to_s }
|
104
|
+
end
|
105
|
+
|
102
106
|
end
|
103
107
|
|
104
108
|
unless const_defined?(:Nlri)
|
105
|
-
Nlri = Class.new(Base_nlri)
|
106
|
-
|
109
|
+
Nlri = Class.new(Base_nlri) do
|
110
|
+
def to_hash
|
111
|
+
{:nlris=>to_ary}
|
112
|
+
end
|
113
|
+
end
|
114
|
+
Withdrawn = Class.new(Base_nlri) do
|
115
|
+
def to_hash
|
116
|
+
{:withdrawns=>to_ary}
|
117
|
+
end
|
118
|
+
end
|
107
119
|
end
|
108
|
-
|
109
120
|
class Nlri
|
110
121
|
def self.factory(s, afi, safi, path_id=nil)
|
111
122
|
if afi== 1 and safi==1
|
data/bgp/nlris/prefix.rb
CHANGED
@@ -54,6 +54,9 @@ class Prefix
|
|
54
54
|
@path_id=nil
|
55
55
|
if args.size>1 and args[0].is_a?(Integer)
|
56
56
|
@path_id, pfx, afi = args
|
57
|
+
elsif args.size==1 and args[0].is_a?(Hash)
|
58
|
+
@path_id = args[0][:path_id]
|
59
|
+
pfx = args[0][:prefix]
|
57
60
|
else
|
58
61
|
pfx, afi = args
|
59
62
|
end
|
@@ -108,6 +111,14 @@ class Prefix
|
|
108
111
|
end
|
109
112
|
end
|
110
113
|
|
114
|
+
def to_hash
|
115
|
+
if extended?
|
116
|
+
{:prefix=> pfx_to_s}.merge({:path_id=>@path_id})
|
117
|
+
else
|
118
|
+
{:prefix=> pfx_to_s}
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
111
122
|
def nexthop
|
112
123
|
to_s.split('/')[0]
|
113
124
|
end
|
data/bgp/nlris/rd.rb
CHANGED
@@ -54,9 +54,21 @@ module BGP
|
|
54
54
|
else
|
55
55
|
@admin, @assign, @enc_type, = admin, assign, 0
|
56
56
|
end
|
57
|
+
elsif args.size==1 and args[0].is_a?(Hash)
|
58
|
+
# assuming Rd.new :rd=> [100,100]
|
59
|
+
parse(Rd.new(*args[0][:rd]).encode)
|
57
60
|
end
|
58
61
|
end
|
59
|
-
|
62
|
+
|
63
|
+
def to_hash
|
64
|
+
#FIXME
|
65
|
+
if @admin.is_a?(IPAddr)
|
66
|
+
{:rd=> [@admin.to_s, @assign]}
|
67
|
+
else
|
68
|
+
{:rd=> [@admin, @assign]}
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
60
72
|
def encode
|
61
73
|
case @enc_type
|
62
74
|
when 0
|
data/bgp/nlris/vpn.rb
CHANGED
@@ -11,12 +11,20 @@ module BGP
|
|
11
11
|
class Vpn
|
12
12
|
attr_reader :prefix, :rd
|
13
13
|
def initialize(*args)
|
14
|
+
@prefix=nil
|
14
15
|
if args.size>0 and args[0].is_a?(String) and args[0].is_packed?
|
15
16
|
parse(*args)
|
16
17
|
else
|
17
|
-
|
18
|
-
|
19
|
-
|
18
|
+
case args[0]
|
19
|
+
when String, Prefix
|
20
|
+
prefix, *rd = args
|
21
|
+
self.prefix=(prefix)
|
22
|
+
self.rd=rd
|
23
|
+
when Rd
|
24
|
+
*rd = args
|
25
|
+
@prefix=nil
|
26
|
+
self.rd=rd
|
27
|
+
end
|
20
28
|
end
|
21
29
|
end
|
22
30
|
def prefix=(arg)
|
@@ -42,23 +50,38 @@ module BGP
|
|
42
50
|
end
|
43
51
|
def encode(len_included=true)
|
44
52
|
if len_included
|
45
|
-
[bit_length, @rd.encode,
|
53
|
+
[bit_length, @rd.encode, encode_prefix(false)].pack('Ca*a*')
|
46
54
|
else
|
47
|
-
@rd.encode +
|
55
|
+
@rd.encode + encode_prefix(false)
|
48
56
|
end
|
49
57
|
end
|
58
|
+
|
59
|
+
def encode_prefix(len_included)
|
60
|
+
if @prefix
|
61
|
+
if len_included
|
62
|
+
@prefix.encode_with_len_without_path_id
|
63
|
+
else
|
64
|
+
@prefix.encode_without_len_without_path_id
|
65
|
+
end
|
66
|
+
else
|
67
|
+
''
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
50
71
|
def encode_without_len_without_path_id
|
51
72
|
encode(false)
|
52
73
|
end
|
74
|
+
|
53
75
|
def path_id
|
54
76
|
@prefix.path_id
|
55
|
-
rescue
|
56
77
|
end
|
57
78
|
def path_id=(val)
|
58
79
|
@prefix.path_id=val
|
59
80
|
end
|
60
81
|
def bit_length
|
61
|
-
@rd.bit_length
|
82
|
+
len = @rd.bit_length
|
83
|
+
len += @prefix.mlen if @prefix
|
84
|
+
len
|
62
85
|
end
|
63
86
|
def ipv4?
|
64
87
|
@prefix.ipv4?
|
@@ -73,14 +96,40 @@ module BGP
|
|
73
96
|
nbits = s.slice!(0,1).unpack('C')[0]
|
74
97
|
rd,vpn = s.slice!(0,(7+nbits)/8).unpack("a8a*")
|
75
98
|
@rd = Rd.new(rd.is_packed)
|
76
|
-
@prefix= Prefix.new_ntop([nbits-64,vpn].pack('Ca*'), afi)
|
99
|
+
@prefix= Prefix.new_ntop([nbits-64,vpn].pack('Ca*'), afi) if vpn.size>0
|
77
100
|
end
|
78
101
|
def nexthop
|
79
102
|
@prefix.nexthop
|
80
103
|
end
|
81
|
-
def to_s
|
104
|
+
def to_s(afi=1)
|
82
105
|
#Label Stack=5806 (bottom) RD=3215:317720610, IPv4=10.45.142.64/32
|
83
|
-
"#{@rd.to_s(false)}, #{
|
106
|
+
"#{@rd.to_s(false)}, #{prefix_to_s(afi)}"
|
107
|
+
end
|
108
|
+
|
109
|
+
def to_hash
|
110
|
+
if @prefix
|
111
|
+
@rd.to_hash.merge(@prefix.to_hash)
|
112
|
+
else
|
113
|
+
@rd.to_hash
|
114
|
+
end
|
84
115
|
end
|
116
|
+
|
117
|
+
private
|
118
|
+
|
119
|
+
def prefix_to_s(afi)
|
120
|
+
if @prefix
|
121
|
+
@prefix.to_s_with_afi
|
122
|
+
else
|
123
|
+
case afi
|
124
|
+
when 1 ; 'IPv4=0.0.0.0/0'
|
125
|
+
when 2 ; 'IPv6=0::0/0'
|
126
|
+
else
|
127
|
+
''
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
85
132
|
end
|
86
133
|
end
|
134
|
+
|
135
|
+
load "../../test/unit/nlris/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
|
@@ -36,6 +36,9 @@ module BGP
|
|
36
36
|
@as = args[1]
|
37
37
|
elsif args[0].is_a?(self.class)
|
38
38
|
parse(args[0].encode, *args[1..-1])
|
39
|
+
elsif args[0].is_a?(Hash)
|
40
|
+
@ip_address = IPAddr.create(args[0][:address])
|
41
|
+
@as = args[0][:asn]
|
39
42
|
else
|
40
43
|
raise ArgumentError, "invalid argument, #{args.inspect}"
|
41
44
|
end
|
@@ -48,6 +51,10 @@ module BGP
|
|
48
51
|
def address
|
49
52
|
@ip_address.to_s
|
50
53
|
end
|
54
|
+
|
55
|
+
def asn
|
56
|
+
@as
|
57
|
+
end
|
51
58
|
|
52
59
|
def as(sep='')
|
53
60
|
case sep
|
@@ -78,6 +85,10 @@ module BGP
|
|
78
85
|
super([@as].pack(f) + @ip_address.hton)
|
79
86
|
end
|
80
87
|
|
88
|
+
def to_hash
|
89
|
+
{:asn=> asn, :address=> address}
|
90
|
+
end
|
91
|
+
|
81
92
|
end
|
82
93
|
|
83
94
|
class As4_aggregator < Aggregator
|
@@ -98,6 +109,14 @@ module BGP
|
|
98
109
|
end
|
99
110
|
|
100
111
|
end
|
112
|
+
|
113
|
+
class Aggregator
|
114
|
+
class << self
|
115
|
+
def new_hash(arg={})
|
116
|
+
new arg[:address], arg[:as]
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
101
120
|
|
102
121
|
end
|
103
122
|
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'bgp/path_attributes/attribute'
|
2
|
+
|
3
|
+
module BGP
|
4
|
+
|
5
|
+
class Aigp < Attr
|
6
|
+
|
7
|
+
def initialize(*args)
|
8
|
+
@flags, @type = OPTIONAL_NON_TRANSITIVE, ACCUMULATED_IGP_METRIC
|
9
|
+
if args[0].is_a?(String) and args[0].is_packed?
|
10
|
+
parse(args[0])
|
11
|
+
elsif args[0].is_a?(self.class)
|
12
|
+
parse(args[0].encode, *args[1..-1])
|
13
|
+
elsif args.size==1 and args[0].is_a?(Integer)
|
14
|
+
@aigp = args[0]
|
15
|
+
elsif args.empty?
|
16
|
+
@aigp=0
|
17
|
+
else
|
18
|
+
raise
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_i
|
23
|
+
@aigp.to_i
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_hash
|
27
|
+
{:metric=> to_i}
|
28
|
+
end
|
29
|
+
|
30
|
+
def accumulated_igp_metric
|
31
|
+
format("(0x%8.8x) %d", to_i, to_i)
|
32
|
+
end
|
33
|
+
alias metric accumulated_igp_metric
|
34
|
+
|
35
|
+
def to_s(method=:default)
|
36
|
+
super(accumulated_igp_metric, method)
|
37
|
+
end
|
38
|
+
|
39
|
+
def encode
|
40
|
+
super([1, 11, @aigp >> 32, @aigp & 0xffffffff].pack('CnN2'))
|
41
|
+
end
|
42
|
+
|
43
|
+
def parse(s)
|
44
|
+
@flags, @type, len, value=super(s)
|
45
|
+
_, _, high, low = value.unpack('CnNN')
|
46
|
+
@aigp = (high << 32) + low
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
class Aigp
|
52
|
+
class << self
|
53
|
+
def new_hash(_arg={})
|
54
|
+
arg = {:metric=>0}.merge(_arg)
|
55
|
+
new arg[:metric]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
load "../../test/unit/path_attributes/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
|
@@ -117,6 +117,9 @@ module BGP
|
|
117
117
|
super(:set, *args)
|
118
118
|
end
|
119
119
|
end
|
120
|
+
def to_hash
|
121
|
+
{:set=> as}
|
122
|
+
end
|
120
123
|
end
|
121
124
|
|
122
125
|
class As_path::Sequence < As_path::Segment
|
@@ -127,6 +130,9 @@ module BGP
|
|
127
130
|
super(:sequence, *args)
|
128
131
|
end
|
129
132
|
end
|
133
|
+
def to_hash
|
134
|
+
{:sequence=> as}
|
135
|
+
end
|
130
136
|
end
|
131
137
|
|
132
138
|
class As_path::Confed_set < As_path::Segment
|
@@ -137,6 +143,9 @@ module BGP
|
|
137
143
|
super(:confed_set, *args)
|
138
144
|
end
|
139
145
|
end
|
146
|
+
def to_hash
|
147
|
+
{:confed_set=> as}
|
148
|
+
end
|
140
149
|
end
|
141
150
|
|
142
151
|
class As_path::Confed_sequence < As_path::Segment
|
@@ -147,6 +156,9 @@ module BGP
|
|
147
156
|
super(:confed_sequence, *args)
|
148
157
|
end
|
149
158
|
end
|
159
|
+
def to_hash
|
160
|
+
{:confed_sequence=> as}
|
161
|
+
end
|
150
162
|
end
|
151
163
|
|
152
164
|
def integer?(arg)
|
@@ -204,6 +216,12 @@ module BGP
|
|
204
216
|
@segments.find { |s| s.seg_type == SEQUENCE }
|
205
217
|
end
|
206
218
|
|
219
|
+
def to_hash
|
220
|
+
h = {}
|
221
|
+
@segments.each { |s| h = h.merge(s.to_hash) }
|
222
|
+
{ :as_path=> h}
|
223
|
+
end
|
224
|
+
|
207
225
|
private
|
208
226
|
|
209
227
|
def parse(s,as4byte=false)
|
@@ -225,6 +243,45 @@ module BGP
|
|
225
243
|
end
|
226
244
|
end
|
227
245
|
|
246
|
+
class As_path
|
247
|
+
class << self
|
248
|
+
def new_hash(arg={})
|
249
|
+
o = new
|
250
|
+
[:set, :sequence, :confed_sequence, :confed_set].each do |set_type|
|
251
|
+
next unless arg.has_key? set_type
|
252
|
+
case set_type
|
253
|
+
when :set
|
254
|
+
o << As_path::Set.new(*arg[:set])
|
255
|
+
when :sequence
|
256
|
+
o << As_path::Sequence.new(*arg[:sequence])
|
257
|
+
when :confed_set
|
258
|
+
o << As_path::Confed_set.new(*arg[:confed_set])
|
259
|
+
when :confed_sequence
|
260
|
+
o << As_path::Confed_sequence.new(*arg[:confed_sequence])
|
261
|
+
else
|
262
|
+
raise
|
263
|
+
end
|
264
|
+
end
|
265
|
+
o
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
class << self
|
270
|
+
def new_set(*args)
|
271
|
+
new_hash :set=>args
|
272
|
+
end
|
273
|
+
def new_sequence(*args)
|
274
|
+
new_hash :sequence=>args
|
275
|
+
end
|
276
|
+
def new_confed_set(*args)
|
277
|
+
new_hash :confed_set=>args
|
278
|
+
end
|
279
|
+
def new_confed_sequence(*args)
|
280
|
+
new_hash :confed_sequence=>args
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
228
285
|
end
|
229
286
|
|
230
287
|
load "../../test/unit/path_attributes/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
|
@@ -45,6 +45,8 @@ module BGP
|
|
45
45
|
AS4_PATH = 17
|
46
46
|
AS4_AGGREGATOR = 18
|
47
47
|
|
48
|
+
ACCUMULATED_IGP_METRIC = 26
|
49
|
+
|
48
50
|
SET = 1
|
49
51
|
SEQUENCE = 2
|
50
52
|
CONFED_SEQUENCE = 3
|
@@ -136,6 +138,14 @@ module BGP
|
|
136
138
|
s +="]"
|
137
139
|
end
|
138
140
|
|
141
|
+
def is_optional?
|
142
|
+
(@flags&8>0)
|
143
|
+
end
|
144
|
+
|
145
|
+
def is_transitive?
|
146
|
+
(@flags&4>0)
|
147
|
+
end
|
148
|
+
|
139
149
|
def attribute_name
|
140
150
|
name.split('_').collect { |w| w.capitalize }.join(' ')
|
141
151
|
end
|
@@ -100,7 +100,11 @@ module BGP
|
|
100
100
|
def sort
|
101
101
|
Cluster_list.new(to_ary.sort)
|
102
102
|
end
|
103
|
-
|
103
|
+
|
104
|
+
def to_hash
|
105
|
+
{:cluster_ids=>@cluster_ids.collect { |c| c.to_s }}
|
106
|
+
end
|
107
|
+
|
104
108
|
def sort!
|
105
109
|
@cluster_ids = @cluster_ids.sort_by { |c| c.to_i }
|
106
110
|
self
|
@@ -111,6 +115,25 @@ module BGP
|
|
111
115
|
end
|
112
116
|
|
113
117
|
end
|
118
|
+
|
119
|
+
class Cluster_list
|
120
|
+
class << self
|
121
|
+
def new_hash(arg={})
|
122
|
+
o = new
|
123
|
+
[:cluster_ids].each do |set_type|
|
124
|
+
next unless arg.has_key? set_type
|
125
|
+
case set_type
|
126
|
+
when :cluster_ids
|
127
|
+
o << arg[set_type]
|
128
|
+
else
|
129
|
+
raise
|
130
|
+
end
|
131
|
+
end
|
132
|
+
o
|
133
|
+
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
114
137
|
|
115
138
|
end
|
116
139
|
|
@@ -27,7 +27,17 @@ module BGP
|
|
27
27
|
class Communities < Attr
|
28
28
|
|
29
29
|
class Community
|
30
|
-
|
30
|
+
|
31
|
+
class << self
|
32
|
+
def method_missing(name, *args, &block)
|
33
|
+
if name.to_s =~ /^(no_export|no_advertise|no_export_sub_confed|no_peer)$/
|
34
|
+
new name
|
35
|
+
else
|
36
|
+
super
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
31
41
|
unless const_defined? :NO_EXPORT
|
32
42
|
NO_EXPORT = 0xFFFFFF01
|
33
43
|
NO_ADVERTISE = 0xFFFFFF02
|
@@ -79,6 +89,22 @@ module BGP
|
|
79
89
|
|
80
90
|
end
|
81
91
|
|
92
|
+
class << self
|
93
|
+
def new_hash(arg={})
|
94
|
+
o = new
|
95
|
+
[:communities].each do |set_type|
|
96
|
+
next unless arg.has_key? set_type
|
97
|
+
case set_type
|
98
|
+
when :communities
|
99
|
+
o << arg[set_type]
|
100
|
+
else
|
101
|
+
raise
|
102
|
+
end
|
103
|
+
end
|
104
|
+
o
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
82
108
|
def initialize(*args)
|
83
109
|
@flags, @type = OPTIONAL_TRANSITIVE, COMMUNITIES
|
84
110
|
if args[0].is_a?(String) and args[0].is_packed?
|
@@ -114,6 +140,10 @@ module BGP
|
|
114
140
|
def to_s(method=:default)
|
115
141
|
super(communities, method)
|
116
142
|
end
|
143
|
+
|
144
|
+
def to_hash
|
145
|
+
{ :communities=> @communities.collect { |comm| comm.to_s } }
|
146
|
+
end
|
117
147
|
|
118
148
|
def encode
|
119
149
|
super(@communities.collect { |comm| comm.encode }.join)
|
@@ -171,4 +201,5 @@ module BGP
|
|
171
201
|
end
|
172
202
|
|
173
203
|
end
|
204
|
+
|
174
205
|
load "../../test/unit/path_attributes/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
|
@@ -28,6 +28,26 @@ module BGP
|
|
28
28
|
|
29
29
|
class Extended_communities < Attr
|
30
30
|
|
31
|
+
class << self
|
32
|
+
def new_hash(arg={})
|
33
|
+
o = new
|
34
|
+
arg.keys.each do |comm|
|
35
|
+
case comm
|
36
|
+
when :color ; o << Color.new(*arg[comm])
|
37
|
+
when :route_target ; o << Route_target.new(*arg[comm])
|
38
|
+
when :link_bandwidth ; o << Link_bandwidth.new(*arg[comm])
|
39
|
+
when :ospf_domain_id ; o << Ospf_domain_id.new(*arg[comm])
|
40
|
+
when :encapsulation ; o << Encapsulation.new(*arg[comm])
|
41
|
+
when :route_origin ; o << Route_origin.new(*arg[comm])
|
42
|
+
when :ospf_router_id ; o << Ospf_router_id.new(arg[comm])
|
43
|
+
else
|
44
|
+
raise
|
45
|
+
end
|
46
|
+
end
|
47
|
+
o
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
31
51
|
attr_reader :communities
|
32
52
|
|
33
53
|
def initialize(*args)
|
@@ -59,6 +79,12 @@ module BGP
|
|
59
79
|
end
|
60
80
|
alias << add
|
61
81
|
|
82
|
+
def to_hash
|
83
|
+
h = {}
|
84
|
+
@communities.each { |c| h = h.merge( { c.class.to_s.split('::').last.downcase.to_sym => c.instance_eval { value2 } }) }
|
85
|
+
h
|
86
|
+
end
|
87
|
+
|
62
88
|
def extended_communities
|
63
89
|
len = @communities.size*8
|
64
90
|
s=[]
|