bgp4r 0.0.11 → 0.0.12
Sign up to get free protection for your applications and to get access to all the features.
- data/bgp/common.rb +14 -13
- data/bgp/iana.rb +26 -1
- data/bgp/messages/capability.rb +3 -2
- data/bgp/messages/message.rb +3 -2
- data/bgp/messages/open.rb +2 -1
- data/bgp/messages/update.rb +80 -30
- data/bgp/neighbor/add_path_cap.rb +125 -0
- data/bgp/{neighbor.rb → neighbor/neighbor.rb} +64 -68
- data/bgp/nlris/nlri.rb +289 -15
- data/bgp/nlris/prefix.rb +3 -2
- data/bgp/nlris/vpn.rb +1 -8
- data/bgp/optional_parameters/add_path.rb +160 -0
- data/bgp/optional_parameters/capabilities.rb +1 -0
- data/bgp/optional_parameters/capability.rb +6 -0
- data/bgp/optional_parameters/graceful_restart.rb +6 -6
- data/bgp/optional_parameters/optional_parameter.rb +1 -0
- data/bgp/path_attributes/as_path.rb +1 -1
- data/bgp/path_attributes/attribute.rb +12 -5
- data/bgp/path_attributes/mp_reach.rb +142 -96
- data/bgp/path_attributes/mp_unreach.rb +73 -20
- data/bgp/path_attributes/path_attribute.rb +28 -5
- data/bgp4r.gemspec +21 -6
- data/bgp4r.rb +1 -1
- data/examples/unit-testing/malformed_update.rb +2 -1
- data/examples/unit-testing/test.rb +82 -0
- data/examples/unit-testing/test1.rb +82 -0
- data/examples/unit-testing/test2.rb +44 -0
- data/test/common_test.rb +7 -0
- data/test/helpers/server.rb +20 -0
- data/test/iana_test.rb +43 -0
- data/test/messages/open_test.rb +7 -2
- data/test/messages/update_test.rb +133 -36
- data/test/neighbor/add_path_cap_test.rb +54 -0
- data/test/neighbor/neighbor_test.rb +161 -0
- data/test/nlris/ext_nlri_test.rb +25 -60
- data/test/nlris/nlri_test.rb +93 -115
- data/test/optional_parameters/add_path_test.rb +53 -0
- data/test/optional_parameters/capability_test.rb +10 -0
- data/test/optional_parameters/graceful_restart_test.rb +1 -0
- data/test/path_attributes/mp_reach_test.rb +206 -8
- data/test/path_attributes/mp_unreach_test.rb +113 -5
- data/test/path_attributes/path_attribute_test.rb +34 -2
- metadata +20 -7
- data/test/neighbor_test.rb +0 -62
@@ -0,0 +1,160 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2010 Jean-Michel Esnault.
|
3
|
+
# All rights reserved.
|
4
|
+
# See LICENSE.txt for permissions.
|
5
|
+
#
|
6
|
+
#
|
7
|
+
# This file is part of BGP4R.
|
8
|
+
#
|
9
|
+
# BGP4R is free software: you can redistribute it and/or modify
|
10
|
+
# it under the terms of the GNU General Public License as published by
|
11
|
+
# the Free Software Foundation, either version 3 of the License, or
|
12
|
+
# (at your option) any later version.
|
13
|
+
#
|
14
|
+
# BGP4R is distributed in the hope that it will be useful,
|
15
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
16
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
17
|
+
# GNU General Public License for more details.
|
18
|
+
#
|
19
|
+
# You should have received a copy of the GNU General Public License
|
20
|
+
# along with BGP4R. If not, see <http://www.gnu.org/licenses/>.
|
21
|
+
#++
|
22
|
+
|
23
|
+
require 'bgp/optional_parameters/capability'
|
24
|
+
|
25
|
+
module BGP::OPT_PARM::CAP
|
26
|
+
|
27
|
+
#
|
28
|
+
# Belongs to Neighbor this is a session attribute....
|
29
|
+
# def include_path_id?(speeker, peer, sr, afi, safi)
|
30
|
+
# # when sending afi, safi, speaker agrees to send and peer to receive
|
31
|
+
# # when receiving afi, safi, speaker agrees to recv and peer agress to send
|
32
|
+
# case sr
|
33
|
+
# when :recv
|
34
|
+
# speeker.has?(:recv, afi, safi) && peer.has?(:send, afi, safi)
|
35
|
+
# when :send
|
36
|
+
# speeker.has?(:send, afi, safi) && peer.has?(:recv, afi, safi)
|
37
|
+
# end
|
38
|
+
# end
|
39
|
+
|
40
|
+
class Add_path < BGP::OPT_PARM::Capability
|
41
|
+
|
42
|
+
class << self
|
43
|
+
def new_array(arg)
|
44
|
+
o = new
|
45
|
+
arg.each { |t| o.add(*t) }
|
46
|
+
o
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def initialize(*args)
|
51
|
+
@af={}
|
52
|
+
if args.size>1
|
53
|
+
super(OPT_PARM::CAP_ADD_PATH)
|
54
|
+
add(*args)
|
55
|
+
elsif args.size==1 and args[0].is_a?(String)
|
56
|
+
parse(*args)
|
57
|
+
elsif args.empty?
|
58
|
+
super(OPT_PARM::CAP_ADD_PATH)
|
59
|
+
else
|
60
|
+
raise
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def add(sr, afi,safi)
|
65
|
+
@af[[_afi(afi), _safi(safi)]] = _send_recv(sr)
|
66
|
+
end
|
67
|
+
|
68
|
+
def parse(s)
|
69
|
+
families = super(s)
|
70
|
+
while families.size>0
|
71
|
+
afi, safi, sr = families.slice!(0,4).unpack('nCC')
|
72
|
+
@af[[afi,safi]]=sr
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# 0001 01 01
|
77
|
+
# 0002 80 02
|
78
|
+
# 0002 01 03
|
79
|
+
|
80
|
+
def send? afi, safi
|
81
|
+
has? :send, afi, safi
|
82
|
+
end
|
83
|
+
|
84
|
+
def recv? afi, safi
|
85
|
+
has? :recv, afi, safi
|
86
|
+
end
|
87
|
+
|
88
|
+
def has?(sr, afi, safi)
|
89
|
+
case sr
|
90
|
+
when :recv
|
91
|
+
@af.has_key?([afi,safi]) && (2..3) === @af[[afi,safi]]
|
92
|
+
when :send
|
93
|
+
@af.has_key?([afi,safi]) && (@af[[afi,safi]] == 1 or @af[[afi,safi]] ==3)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def encode
|
98
|
+
s = []
|
99
|
+
s << @af.to_a.sort.collect { |e| e.flatten.pack('nCC') }
|
100
|
+
super s.join
|
101
|
+
end
|
102
|
+
|
103
|
+
def to_s
|
104
|
+
s = []
|
105
|
+
s << "\n Add-path Extension (#{CAP_ADD_PATH}), length: #{encode.size}"
|
106
|
+
s = s.join("\n ")
|
107
|
+
super + (s + (['']+@af.to_a.collect { |e| address_family_to_s(*e)}).join("\n "))
|
108
|
+
end
|
109
|
+
|
110
|
+
private
|
111
|
+
|
112
|
+
def address_family_to_s(af, sr)
|
113
|
+
afi, safi = af
|
114
|
+
"AFI #{IANA.afi(afi)} (#{afi}), SAFI #{IANA.safi(safi)} (#{safi}), #{send_recv_to_s(sr)}"
|
115
|
+
end
|
116
|
+
|
117
|
+
def _send_recv(val)
|
118
|
+
case val
|
119
|
+
when :send, 1 ; 1
|
120
|
+
when :recv, :receive, 2 ; 2
|
121
|
+
when :send_and_recv, :send_recv, :send_and_receive, 3 ; 3
|
122
|
+
else
|
123
|
+
val
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def send_recv_to_s(val)
|
128
|
+
case val
|
129
|
+
when 1 ; 'SEND (1)'
|
130
|
+
when 2 ; 'RECV (2)'
|
131
|
+
when 3 ; 'SEND_AND_RECV (3)'
|
132
|
+
else
|
133
|
+
'bogus'
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def _afi(val)
|
138
|
+
if val.is_a?(Fixnum)
|
139
|
+
val
|
140
|
+
elsif val == :ipv4
|
141
|
+
1
|
142
|
+
elsif val == :ipv6
|
143
|
+
2
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def _safi(val)
|
148
|
+
if val.is_a?(Fixnum)
|
149
|
+
val
|
150
|
+
elsif val == :unicast
|
151
|
+
1
|
152
|
+
elsif val == :multicast
|
153
|
+
2
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
load "../../test/optional_parameters/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
|
@@ -7,6 +7,7 @@ require 'bgp/optional_parameters/optional_parameter'
|
|
7
7
|
require 'bgp/optional_parameters/orf'
|
8
8
|
require 'bgp/optional_parameters/route_refresh'
|
9
9
|
require 'bgp/optional_parameters/as4'
|
10
|
+
require 'bgp/optional_parameters/add_path'
|
10
11
|
|
11
12
|
module BGP::OPT_PARM
|
12
13
|
module DYN_CAP
|
@@ -114,6 +114,8 @@ module BGP::OPT_PARM
|
|
114
114
|
CAP::Orf.new(s)
|
115
115
|
when CAP_GR
|
116
116
|
CAP::Graceful_restart.new(s)
|
117
|
+
when CAP_ADD_PATH
|
118
|
+
CAP::Add_path.new(s)
|
117
119
|
when CAP_DYNAMIC
|
118
120
|
CAP::Dynamic.new(s)
|
119
121
|
else
|
@@ -134,8 +136,12 @@ module BGP::OPT_PARM
|
|
134
136
|
DYN_CAP::Route_refresh.new(code)
|
135
137
|
when CAP_ORF,CAP_ORF_CISCO
|
136
138
|
DYN_CAP::Orf.new(s)
|
139
|
+
when CAP_ADD_PATH
|
140
|
+
DYN_CAP::Add_path.new(s)
|
137
141
|
when CAP_GR
|
138
142
|
DYN_CAP::Graceful_restart.new(s)
|
143
|
+
when CAP_ADD_PATH
|
144
|
+
CAP::Add_path.new(s)
|
139
145
|
else
|
140
146
|
Capability::Unknown.new(s)
|
141
147
|
end
|
@@ -29,7 +29,7 @@ class Graceful_restart < BGP::OPT_PARM::Capability
|
|
29
29
|
def initialize(*args)
|
30
30
|
if args.size>1
|
31
31
|
@restart_state, @restart_time = args
|
32
|
-
@
|
32
|
+
@tuples = []
|
33
33
|
super(OPT_PARM::CAP_GR)
|
34
34
|
else
|
35
35
|
parse(*args)
|
@@ -37,16 +37,16 @@ class Graceful_restart < BGP::OPT_PARM::Capability
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def add(afi,safi,flags)
|
40
|
-
@
|
40
|
+
@tuples << [_afi(afi), _safi(safi), flags]
|
41
41
|
end
|
42
42
|
|
43
43
|
def parse(s)
|
44
|
-
@
|
44
|
+
@tuples = []
|
45
45
|
o1, families = super(s).unpack('na*')
|
46
46
|
@restart_state = o1 >> 12
|
47
47
|
@restart_time = o1 & 0xfff
|
48
48
|
while families.size>0
|
49
|
-
@
|
49
|
+
@tuples << families.slice!(0,4).unpack('nCC')
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
@@ -54,7 +54,7 @@ class Graceful_restart < BGP::OPT_PARM::Capability
|
|
54
54
|
def encode
|
55
55
|
s = []
|
56
56
|
s << [(@restart_state << 12) + @restart_time].pack('n')
|
57
|
-
s << @
|
57
|
+
s << @tuples.collect { |af| af.pack('nCC') }
|
58
58
|
super s.join
|
59
59
|
end
|
60
60
|
def to_s
|
@@ -62,7 +62,7 @@ class Graceful_restart < BGP::OPT_PARM::Capability
|
|
62
62
|
s << "\n Graceful Restart Extension (#{CAP_GR}), length: 4"
|
63
63
|
s << " Restart Flags: #{restart_flag}, Restart Time #{@restart_time}s"
|
64
64
|
s = s.join("\n ")
|
65
|
-
super + (s + (['']+@
|
65
|
+
super + (s + (['']+@tuples.collect { |af| address_family(*af)}).join("\n "))
|
66
66
|
end
|
67
67
|
|
68
68
|
private
|
@@ -61,16 +61,23 @@ module BGP
|
|
61
61
|
OPTIONAL_TRANSITIVE = OPTIONAL | TRANSITIVE
|
62
62
|
OPTIONAL_NON_TRANSITIVE = OPTIONAL
|
63
63
|
|
64
|
-
def
|
65
|
-
len, len_fmt = value.size, 'C'
|
64
|
+
def len_fmt(len)
|
66
65
|
if len>255
|
67
66
|
@flags |= EXTENDED_LENGTH
|
68
|
-
|
67
|
+
@_len_fmt='n'
|
68
|
+
else
|
69
|
+
@_len_fmt = 'C'
|
70
|
+
@flags &= ~EXTENDED_LENGTH
|
69
71
|
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def encode(value='',value_fmt=nil)
|
75
|
+
len = value.size
|
76
|
+
len_fmt(len)
|
70
77
|
if value_fmt
|
71
|
-
[@flags<<4, @type, len, *value].pack("CC#{
|
78
|
+
[@flags<<4, @type, len, *value].pack("CC#{@_len_fmt}#{value_fmt}")
|
72
79
|
else
|
73
|
-
([@flags<<4, @type, len].pack("CC#{
|
80
|
+
([@flags<<4, @type, len].pack("CC#{@_len_fmt}") + value).is_packed
|
74
81
|
end
|
75
82
|
end
|
76
83
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
#--
|
1
|
+
#--
|
2
2
|
# Copyright 2008, 2009 Jean-Michel Esnault.
|
3
3
|
# All rights reserved.
|
4
4
|
# See LICENSE.txt for permissions.
|
@@ -24,119 +24,165 @@ require 'bgp/path_attributes/attribute'
|
|
24
24
|
require 'bgp/nlris/nlris'
|
25
25
|
|
26
26
|
module BGP
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
27
|
+
|
28
|
+
class Mp_reach < Attr
|
29
|
+
|
30
|
+
attr_reader :safi, :nlris, :path_id
|
31
|
+
|
32
|
+
def initialize(*args)
|
33
|
+
@safi, @nexthops, @nlris, @path_id= 1, [], [], nil # default is ipv4/unicast
|
34
|
+
@flags, @type = OPTIONAL, MP_REACH
|
35
|
+
if args[0].is_a?(String) and args[0].is_packed?
|
36
|
+
parse(*args)
|
37
|
+
elsif args[0].is_a?(self.class)
|
38
|
+
s = args.shift.encode
|
39
|
+
parse(s, *args)
|
40
|
+
elsif args[0].is_a?(Hash) and args.size==1
|
41
|
+
set(*args)
|
42
|
+
else
|
43
|
+
raise ArgumentError, "invalid argument"
|
44
44
|
end
|
45
|
-
|
46
|
-
|
47
|
-
|
45
|
+
end
|
46
|
+
|
47
|
+
def afi
|
48
|
+
@afi ||= @nexthops[0].afi
|
49
|
+
end
|
50
|
+
|
51
|
+
def set(h)
|
52
|
+
@safi = h[:safi]
|
53
|
+
@path_id = path_id = h[:path_id]
|
54
|
+
case @safi
|
55
|
+
when 1,2,4 ; @nexthops = [h[:nexthop]].flatten.collect { |nh| Prefix.new(nh) }
|
56
|
+
when 128,129 ; @nexthops = [h[:nexthop]].flatten.collect { |nh| Vpn.new(nh) }
|
57
|
+
else
|
48
58
|
end
|
49
|
-
|
50
|
-
|
51
|
-
@
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
59
|
+
case @safi
|
60
|
+
when 1
|
61
|
+
@nlris = [h[:nlris]].flatten.collect do |n|
|
62
|
+
case n
|
63
|
+
when String
|
64
|
+
nlri = Inet_unicast.new(n)
|
65
|
+
path_id ? Ext_Nlri.new(path_id, nlri) : nlri
|
66
|
+
when Hash
|
67
|
+
path_id = n[:path_id] if n[:path_id]
|
68
|
+
nlri = Inet_unicast.new(n[:prefix])
|
69
|
+
path_id ? Ext_Nlri.new(path_id, nlri) : nlri
|
70
|
+
else
|
71
|
+
raise ArgumentError, "Invalid: #{n.inspect}"
|
72
|
+
end
|
56
73
|
end
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
74
|
+
when 2
|
75
|
+
@nlris = [h[:nlris]].flatten.collect do |n|
|
76
|
+
case n
|
77
|
+
when String
|
78
|
+
nlri = Inet_multicast.new(n)
|
79
|
+
path_id ? Ext_Nlri.new(path_id, nlri) : nlri
|
80
|
+
when Hash
|
81
|
+
path_id = n[:path_id] if n[:path_id]
|
82
|
+
nlri = Inet_multicast.new(n[:prefix])
|
83
|
+
path_id ? Ext_Nlri.new(path_id, nlri) : nlri
|
84
|
+
else
|
85
|
+
raise ArgumentError, "Invalid: #{n.inspect}"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
when 4
|
89
|
+
@nlris = [h[:nlris]].flatten.collect do |n|
|
90
|
+
path_id = n[:path_id] || @path_id
|
91
|
+
prefix = n[:prefix].is_a?(String) ? Prefix.new(n[:prefix]) : n[:prefix]
|
92
|
+
nlri = Labeled.new(prefix, *n[:label])
|
93
|
+
path_id ? Ext_Nlri.new(path_id, nlri) : nlri
|
94
|
+
end
|
95
|
+
when 128,129
|
96
|
+
@nlris = [h[:nlris]].flatten.collect do |n|
|
97
|
+
path_id = n[:path_id] || @path_id
|
66
98
|
prefix = n[:prefix].is_a?(Prefix) ? n[:prefix] : Prefix.new(n[:prefix])
|
67
99
|
rd = n[:rd].is_a?(Rd) ? n[:rd] : Rd.new(*n[:rd])
|
68
|
-
Labeled.new(Vpn.new(prefix,rd), *n[:label])
|
69
|
-
|
100
|
+
nlri = Labeled.new(Vpn.new(prefix,rd), *n[:label])
|
101
|
+
path_id ? Ext_Nlri.new(path_id, nlri) : nlri
|
70
102
|
end
|
103
|
+
else
|
71
104
|
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def nexthops
|
108
|
+
@nexthops.collect { |nh| nh.nexthop }.join(", ")
|
109
|
+
end
|
110
|
+
|
111
|
+
def mp_reach
|
112
|
+
"\n AFI #{IANA.afi(afi)} (#{afi}), SAFI #{IANA.safi(safi)} (#{safi})" +
|
113
|
+
"\n nexthop: " + nexthops +
|
114
|
+
(['']+ @nlris.collect { |nlri| nlri.to_s }).join("\n ")
|
115
|
+
end
|
116
|
+
|
117
|
+
def to_s(method=:default)
|
118
|
+
super(mp_reach, method)
|
119
|
+
end
|
120
|
+
|
121
|
+
def to_hash
|
122
|
+
end
|
123
|
+
|
124
|
+
def parse(s,arg=false)
|
72
125
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
def mp_reach
|
78
|
-
"\n AFI #{IANA.afi(afi)} (#{afi}), SAFI #{IANA.safi(safi)} (#{safi})" +
|
79
|
-
"\n nexthop: " + nexthops +
|
80
|
-
(['']+ @nlris.collect { |nlri| nlri.to_s }).join("\n ")
|
81
|
-
end
|
82
|
-
|
83
|
-
def to_s(method=:default)
|
84
|
-
super(mp_reach, method)
|
85
|
-
end
|
126
|
+
@flags, @type, len, value = super(s)
|
127
|
+
@afi, @safi, nh_len = value.slice!(0,4).unpack('nCC')
|
128
|
+
parse_next_hops value.slice!(0,nh_len).is_packed
|
129
|
+
value.slice!(0,1)
|
86
130
|
|
87
|
-
|
131
|
+
if arg.respond_to?(:path_id?)
|
132
|
+
path_id_flag = arg.path_id? :recv, @afi, @safi
|
133
|
+
else
|
134
|
+
path_id_flag = arg
|
88
135
|
end
|
89
136
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
@nlris << Nlri.factory(value.slice!(0,(blen+7)/8+1), @afi, @safi)
|
137
|
+
while value.size>0
|
138
|
+
path_id = value.slice!(0,4).unpack('N')[0] if path_id_flag
|
139
|
+
blen = value.slice(0,1).unpack('C')[0]
|
140
|
+
nlri = Nlri.factory(value.slice!(0,(blen+7)/8+1), @afi, @safi)
|
141
|
+
if path_id_flag
|
142
|
+
@nlris << Ext_Nlri.new(path_id, nlri)
|
143
|
+
else
|
144
|
+
@nlris << nlri
|
99
145
|
end
|
100
|
-
raise RuntimeError, "leftover afer parsing: #{value.unpack('H*')}" if value.size>0
|
101
|
-
|
102
146
|
end
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
@nexthops << Vpn.new([64+32,s.slice!(0,12)].pack('Ca*'))
|
116
|
-
else
|
117
|
-
raise RuntimeError, "cannot parse nexthop for safi #{@safi}"
|
147
|
+
raise RuntimeError, "leftover afer parsing: #{value.unpack('H*')}" if value.size>0
|
148
|
+
end
|
149
|
+
|
150
|
+
def parse_next_hops(s)
|
151
|
+
while s.size>0
|
152
|
+
case @safi
|
153
|
+
when 1,2,4
|
154
|
+
case @afi
|
155
|
+
when 1
|
156
|
+
@nexthops << Prefix.new([32,s.slice!(0,4)].pack('Ca*'),1)
|
157
|
+
when 2
|
158
|
+
@nexthops << Prefix.new([128,s.slice!(0,16)].pack('Ca*'),2)
|
118
159
|
end
|
160
|
+
when 128,129
|
161
|
+
@nexthops << Vpn.new([64+32,s.slice!(0,12)].pack('Ca*'))
|
162
|
+
else
|
163
|
+
raise RuntimeError, "cannot parse nexthop for safi #{@safi}"
|
119
164
|
end
|
120
165
|
end
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
end
|
131
|
-
|
132
|
-
def new_unreach
|
133
|
-
s = encode(:mp_unreach)
|
134
|
-
s[1]= [MP_UNREACH].pack('C')
|
135
|
-
Mp_unreach.new(s)
|
166
|
+
end
|
167
|
+
|
168
|
+
def encode(what=:mp_reach)
|
169
|
+
case what
|
170
|
+
when :mp_reach
|
171
|
+
nexthops = @nexthops.collect { |nh| nh.encode(false) }.join
|
172
|
+
super([afi, @safi, nexthops.size, nexthops, 0, @nlris.collect { |n| n.encode }.join].pack('nCCa*Ca*'))
|
173
|
+
when :mp_unreach
|
174
|
+
super([afi, @safi, @nlris.collect { |n| n.encode }.join].pack('nCa*'))
|
136
175
|
end
|
137
|
-
|
138
176
|
end
|
139
|
-
|
177
|
+
|
178
|
+
def new_unreach
|
179
|
+
s = encode(:mp_unreach)
|
180
|
+
s[1]= [MP_UNREACH].pack('C')
|
181
|
+
Mp_unreach.new(s)
|
182
|
+
end
|
183
|
+
|
184
|
+
end
|
185
|
+
|
140
186
|
end
|
141
187
|
|
142
188
|
load "../../test/path_attributes/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
|