bgp4r 0.0.7 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/bgp/attribute.rb +2 -0
- data/bgp/path_attribute.rb +36 -14
- data/bgp4r.gemspec +4 -2
- data/examples/unit-testing/keepalive_set_to_zeo.rb +64 -0
- data/examples/unit-testing/malformed_update.rb +3 -3
- data/examples/unit-testing/unknown_transitive_attr.rb +102 -0
- data/test/attribute_test.rb +27 -13
- data/test/message_test.rb +27 -0
- metadata +5 -3
data/bgp/attribute.rb
CHANGED
data/bgp/path_attribute.rb
CHANGED
@@ -62,12 +62,19 @@ module BGP
|
|
62
62
|
def find(klass)
|
63
63
|
@attributes.find { |a| a.is_a?(klass) }
|
64
64
|
end
|
65
|
-
|
65
|
+
|
66
|
+
def find_by_type(type)
|
67
|
+
@attributes.find { |a| a.type == type }
|
68
|
+
end
|
69
|
+
|
66
70
|
def size
|
67
71
|
@attributes.size
|
68
72
|
end
|
69
73
|
|
70
74
|
def [](type)
|
75
|
+
if type.is_a?(Fixnum)
|
76
|
+
return find_by_type(type)
|
77
|
+
end
|
71
78
|
case type
|
72
79
|
when ORIGIN, :origin
|
73
80
|
find(Origin)
|
@@ -97,14 +104,18 @@ module BGP
|
|
97
104
|
find(Extended_communities)
|
98
105
|
when AS4_PATH, :as4_path
|
99
106
|
find(As4_path)
|
100
|
-
when AS4_AGGREGATOR, :as4_aggregator
|
101
|
-
find(As4_aggregator)
|
107
|
+
when AS4_AGGREGATOR, :as4_aggregator
|
102
108
|
end
|
103
109
|
end
|
104
110
|
|
105
|
-
def has?(
|
106
|
-
if
|
107
|
-
|
111
|
+
def has?(arg=nil)
|
112
|
+
if arg
|
113
|
+
case arg
|
114
|
+
when Class
|
115
|
+
@attributes.find { |a| a.is_a?(arg) }.nil? ? false : true
|
116
|
+
when Fixnum
|
117
|
+
@attributes.find { |a| a.type == arg }.nil? ? false : true
|
118
|
+
end
|
108
119
|
else
|
109
120
|
@attributes.collect { |attr| attr.class }
|
110
121
|
end
|
@@ -159,6 +170,23 @@ end
|
|
159
170
|
module BGP
|
160
171
|
|
161
172
|
class Attr
|
173
|
+
UnknownAttr = Class.new(Attr) do
|
174
|
+
attr_reader :type, :flags, :value
|
175
|
+
def initialize(*args)
|
176
|
+
if args.size>1
|
177
|
+
@flags, @type, len, @value=args
|
178
|
+
else
|
179
|
+
parse(*args)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
def encode
|
183
|
+
super(@value)
|
184
|
+
end
|
185
|
+
def parse(s)
|
186
|
+
@flags, @type, len, @value = super
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
162
190
|
include BGP::ATTR
|
163
191
|
def self.factory(s, as4byte=false)
|
164
192
|
flags, type = s.unpack('CC')
|
@@ -192,14 +220,8 @@ module BGP
|
|
192
220
|
when EXTENDED_COMMUNITY
|
193
221
|
Extended_communities.new(s)
|
194
222
|
else
|
195
|
-
|
196
|
-
|
197
|
-
else
|
198
|
-
len = s.slice!(0,1).unpack('C')[0]
|
199
|
-
end
|
200
|
-
s.slice!(0,len)
|
201
|
-
raise RuntimeError, "factory for #{type} to be implemented soon"
|
202
|
-
nil
|
223
|
+
# return a generic unknown attr.
|
224
|
+
UnknownAttr.new(s)
|
203
225
|
end
|
204
226
|
end
|
205
227
|
|
data/bgp4r.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{bgp4r}
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.8"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Jean-Michel Esnault"]
|
12
|
-
s.date = %q{2010-09-
|
12
|
+
s.date = %q{2010-09-30}
|
13
13
|
s.description = %q{BGP4R is a BGP-4 ruby library to create, send, and receive BGP messages in an object oriented manner}
|
14
14
|
s.email = %q{jesnault@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -52,8 +52,10 @@ Gem::Specification.new do |s|
|
|
52
52
|
"examples/routegen",
|
53
53
|
"examples/routegen.yml",
|
54
54
|
"examples/simple.rb",
|
55
|
+
"examples/unit-testing/keepalive_set_to_zeo.rb",
|
55
56
|
"examples/unit-testing/malformed_update.rb",
|
56
57
|
"examples/unit-testing/prepend_aspath.rb",
|
58
|
+
"examples/unit-testing/unknown_transitive_attr.rb",
|
57
59
|
"test/aggregator_test.rb",
|
58
60
|
"test/as_path_test.rb",
|
59
61
|
"test/atomic_aggregate_test.rb",
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
require 'bgp4r'
|
3
|
+
require 'timeout'
|
4
|
+
|
5
|
+
Thread.abort_on_exception=true
|
6
|
+
|
7
|
+
class TestBgp < Test::Unit::TestCase
|
8
|
+
|
9
|
+
include BGP
|
10
|
+
|
11
|
+
Log.create
|
12
|
+
Log.level=Logger::DEBUG
|
13
|
+
|
14
|
+
N100 = Class.new(BGP::Neighbor)
|
15
|
+
|
16
|
+
class RecvMsgHandler
|
17
|
+
def initialize(q)
|
18
|
+
@q = q
|
19
|
+
end
|
20
|
+
def update(bgp_msg)
|
21
|
+
@q.enq bgp_msg
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def setup
|
26
|
+
@n100 = N100.new(:my_as=> 100, :remote_addr => '40.0.0.2', :local_addr => '40.0.0.1', :id=> '13.11.19.59', :holdtime=>0)
|
27
|
+
start_peering
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_verify_that_200_is_prepended_to_aspath
|
31
|
+
assert @n100.is_established?, "Expected to be in Established state. <> #{@n100.state}"
|
32
|
+
queue = Queue.new
|
33
|
+
@n300.add_observer RecvMsgHandler.new(queue)
|
34
|
+
end
|
35
|
+
|
36
|
+
def teardown
|
37
|
+
[@n100].each { |n| n.stop }
|
38
|
+
sleep(0.5)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def start_peering
|
44
|
+
[@n100].each { |n|
|
45
|
+
n.capability :as4_byte
|
46
|
+
n.start
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
def recv(q, timeout=5)
|
51
|
+
begin
|
52
|
+
Timeout::timeout(timeout) do |t|
|
53
|
+
msg = q.deq
|
54
|
+
end
|
55
|
+
rescue Timeout::Error => e
|
56
|
+
nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def send_update_to(n)
|
61
|
+
n.send_message update1
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
@@ -9,8 +9,8 @@ class TestBgp < Test::Unit::TestCase
|
|
9
9
|
|
10
10
|
include BGP
|
11
11
|
|
12
|
-
|
13
|
-
|
12
|
+
Log.create
|
13
|
+
Log.level=Logger::DEBUG
|
14
14
|
|
15
15
|
N100 = Class.new(BGP::Neighbor)
|
16
16
|
|
@@ -68,7 +68,7 @@ class TestBgp < Test::Unit::TestCase
|
|
68
68
|
Origin.new(0),
|
69
69
|
Multi_exit_disc.new(100),
|
70
70
|
Local_pref.new(100),
|
71
|
-
As_path.new(100)
|
71
|
+
As_path.new(100)
|
72
72
|
),
|
73
73
|
Nlri.new('77.0.0.0/17', '78.0.0.0/18', '79.0.0.0/19')
|
74
74
|
)
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
require 'bgp4r'
|
3
|
+
require 'timeout'
|
4
|
+
|
5
|
+
Thread.abort_on_exception=true
|
6
|
+
|
7
|
+
class TestBgp < Test::Unit::TestCase
|
8
|
+
|
9
|
+
include BGP
|
10
|
+
|
11
|
+
Log.create
|
12
|
+
Log.level=Logger::DEBUG
|
13
|
+
|
14
|
+
N100 = Class.new(BGP::Neighbor)
|
15
|
+
N300 = Class.new(BGP::Neighbor)
|
16
|
+
|
17
|
+
class RecvMsgHandler
|
18
|
+
def initialize(q)
|
19
|
+
@q = q
|
20
|
+
end
|
21
|
+
def update(bgp_msg)
|
22
|
+
@q.enq bgp_msg
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def setup
|
27
|
+
@n100 = N100.new(:my_as=> 100, :remote_addr => '40.0.0.2', :local_addr => '40.0.0.1', :id=> '13.11.19.59')
|
28
|
+
@n300 = N300.new(:my_as=> 300, :remote_addr => '40.0.1.1', :local_addr => '40.0.1.2', :id=> '13.11.19.57')
|
29
|
+
start_peering
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_unknown_transitive_attribute
|
33
|
+
assert @n100.is_established?, "Expected to be in Established state. <> #{@n100.state}"
|
34
|
+
assert @n300.is_established?, "Expected to be in Established state. <> #{@n300.state}"
|
35
|
+
queue = Queue.new
|
36
|
+
@n300.add_observer RecvMsgHandler.new(queue)
|
37
|
+
@n100.send_message update_with_unknown_transitive_attribute
|
38
|
+
msg = recv(queue)
|
39
|
+
assert msg, "Did not receive expected BGP update message."
|
40
|
+
assert msg.path_attribute.has?(255), "The path attribute was expected to contain an attribute type 255"
|
41
|
+
assert_not_nil msg.path_attribute[255]
|
42
|
+
assert_equal 'AN OPTIONAL TRANSITIVE ATTR WITH TYPE 999', msg.path_attribute[255].value
|
43
|
+
end
|
44
|
+
|
45
|
+
def teardown
|
46
|
+
[@n100, @n300].each { |n| n.stop }
|
47
|
+
sleep(0.5)
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def start_peering
|
53
|
+
[@n100, @n300].each { |n|
|
54
|
+
n.capability :as4_byte
|
55
|
+
n.start
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
def recv(q, timeout=5)
|
60
|
+
begin
|
61
|
+
Timeout::timeout(timeout) do |t|
|
62
|
+
msg = q.deq
|
63
|
+
end
|
64
|
+
rescue Timeout::Error => e
|
65
|
+
nil
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def update_with_unknown_transitive_attribute
|
70
|
+
my_attr = Class.new(Attr)
|
71
|
+
my_attr.class_eval do
|
72
|
+
attr_reader :type, :flags, :value
|
73
|
+
attr_writer :value
|
74
|
+
def initialize(*args)
|
75
|
+
if args.size>1
|
76
|
+
@flags, @type, @value = args
|
77
|
+
else
|
78
|
+
arr = parse(*args)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
def parse(s)
|
82
|
+
@flags, @type, len, @value = super
|
83
|
+
end
|
84
|
+
def encode
|
85
|
+
super(value)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
update = Update.new(
|
89
|
+
Path_attribute.new(
|
90
|
+
Next_hop.new('40.0.0.1'),
|
91
|
+
Origin.new(0),
|
92
|
+
Multi_exit_disc.new(100),
|
93
|
+
Local_pref.new(100),
|
94
|
+
As_path.new(100),
|
95
|
+
my_attr.new(ATTR::OPTIONAL_TRANSITIVE, 255, 'AN OPTIONAL TRANSITIVE ATTR WITH TYPE 999'),
|
96
|
+
my_attr.new(ATTR::OPTIONAL_TRANSITIVE, 0, 'AN OPTIONAL TRANSITIVE ATTR WITH TYPE 0')
|
97
|
+
),
|
98
|
+
Nlri.new('77.0.0.0/17', '78.0.0.0/18', '79.0.0.0/19')
|
99
|
+
)
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
data/test/attribute_test.rb
CHANGED
@@ -26,20 +26,34 @@ require 'test/unit'
|
|
26
26
|
|
27
27
|
class ATTR_Test < Test::Unit::TestCase
|
28
28
|
include BGP
|
29
|
-
class Attr_test < Attr
|
30
|
-
def initialize
|
31
|
-
@type, @flags = 0, 0
|
32
|
-
end
|
33
|
-
def encode
|
34
|
-
@type=0xee
|
35
|
-
@flags=0xf
|
36
|
-
super()
|
37
|
-
end
|
38
|
-
end
|
39
29
|
def test_1
|
40
|
-
|
41
|
-
|
42
|
-
|
30
|
+
my_attr = Class.new(Attr)
|
31
|
+
my_attr.class_eval do
|
32
|
+
attr_reader :type, :flags, :value
|
33
|
+
attr_writer :value
|
34
|
+
def initialize(*args)
|
35
|
+
if args.size>1
|
36
|
+
@flags, @type, @value = args
|
37
|
+
else
|
38
|
+
arr = parse(*args)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
def parse(s)
|
42
|
+
@flags, @type, len, @value = super
|
43
|
+
end
|
44
|
+
def encode
|
45
|
+
super(value)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
assert_equal('40010101',my_attr.new(['40010101'].pack('H*')).to_shex)
|
49
|
+
assert_equal('40010101',my_attr.new(BGP::ATTR::WELL_KNOWN_MANDATORY, 1, [1].pack('C')).to_shex)
|
50
|
+
|
51
|
+
bogus_0 = my_attr.new(ATTR::OPTIONAL_TRANSITIVE, 0, 'A BOGUS OPTIONAL TRANSITIVE ATTR WITH TYPE 0')
|
52
|
+
bogus_999 = my_attr.new(ATTR::OPTIONAL_TRANSITIVE, 999, 'AN OPTIONAL TRANSITIVE ATTR WITH TYPE 999')
|
53
|
+
assert_equal bogus_0.to_shex, my_attr.new(bogus_0.encode).to_shex
|
54
|
+
assert_equal bogus_999.to_shex, my_attr.new(bogus_999.encode).to_shex
|
55
|
+
assert_equal 'A BOGUS OPTIONAL TRANSITIVE ATTR WITH TYPE 0', bogus_0.value
|
56
|
+
assert_equal 'AN OPTIONAL TRANSITIVE ATTR WITH TYPE 999', bogus_999.value
|
43
57
|
end
|
44
58
|
end
|
45
59
|
class Attr_factory_Test < Test::Unit::TestCase
|
data/test/message_test.rb
CHANGED
@@ -134,6 +134,33 @@ class Update_Test < Test::Unit::TestCase
|
|
134
134
|
assert m.as4byte?
|
135
135
|
end
|
136
136
|
|
137
|
+
def test_5
|
138
|
+
# build an update from a yaml description
|
139
|
+
# advertised 172.18.179.192/27
|
140
|
+
# origin igp
|
141
|
+
# nexthop 193.251.127.210
|
142
|
+
# metric 0
|
143
|
+
# locpref 310000
|
144
|
+
# community 3215:102 3215:210 3215:522 3215:588 3215:903 3215:7553 3215:8000 3215:8003
|
145
|
+
# originatorid 193.252.102.210
|
146
|
+
# cluster 0.0.17.49 0.0.29.76 0.0.29.79
|
147
|
+
require 'yaml'
|
148
|
+
require 'pp'
|
149
|
+
s = "
|
150
|
+
---
|
151
|
+
prefixes:202.44.2.0/24 202.44.3.0/24 202.44.5.0/24 202.44.6.0/24 202.44.7.0/24
|
152
|
+
origin: incomplete
|
153
|
+
nexthop: 10.0.0.1
|
154
|
+
metric: 0
|
155
|
+
localpref: 13000
|
156
|
+
community: 3230:10 3230:110 3230:411 3230:912 3230:1010 3230:5911
|
157
|
+
originator-id: 10.0.0.2
|
158
|
+
cluster: 0.0.0.1
|
159
|
+
"
|
160
|
+
|
161
|
+
|
162
|
+
end
|
163
|
+
|
137
164
|
end
|
138
165
|
|
139
166
|
class Open_Test < Test::Unit::TestCase
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 8
|
9
|
+
version: 0.0.8
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Jean-Michel Esnault
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-09-
|
17
|
+
date: 2010-09-30 00:00:00 -07:00
|
18
18
|
default_executable:
|
19
19
|
dependencies: []
|
20
20
|
|
@@ -63,8 +63,10 @@ files:
|
|
63
63
|
- examples/routegen
|
64
64
|
- examples/routegen.yml
|
65
65
|
- examples/simple.rb
|
66
|
+
- examples/unit-testing/keepalive_set_to_zeo.rb
|
66
67
|
- examples/unit-testing/malformed_update.rb
|
67
68
|
- examples/unit-testing/prepend_aspath.rb
|
69
|
+
- examples/unit-testing/unknown_transitive_attr.rb
|
68
70
|
- test/aggregator_test.rb
|
69
71
|
- test/as_path_test.rb
|
70
72
|
- test/atomic_aggregate_test.rb
|