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 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