bgp4r 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
data/bgp/attribute.rb CHANGED
@@ -168,6 +168,8 @@ module BGP
168
168
  include ATTR
169
169
  include Comparable
170
170
 
171
+ attr_reader :type
172
+
171
173
  def method_missing(name, *args, &block)
172
174
  if name == :encode4
173
175
  send :encode, *args, &block
@@ -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?(klass=nil)
106
- if klass
107
- @attributes.find { |a| a.is_a?(klass) }.nil? ? false : true
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
- if flags & 0x10==1
196
- len = s.slice!(0,2).unpack("n")[0]
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.7"
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}
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
- # Log.create
13
- # Log.level=Logger::DEBUG
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
@@ -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
- assert_equal('f0ee00',Attr_test.new.to_shex)
41
- attr = Attr_test.new
42
- assert_equal(attr.encode4, attr.encode)
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
- - 7
9
- version: 0.0.7
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-12 00:00:00 -07:00
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