netns-vrf 0.0.3
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/bin/netns-vrf +161 -0
- data/lib/netns-vrf/interface.rb +33 -0
- data/lib/netns-vrf/ip.rb +25 -0
- data/lib/netns-vrf/netns.rb +35 -0
- data/lib/netns-vrf/route.rb +30 -0
- data/lib/netns-vrf.rb +7 -0
- metadata +52 -0
data/bin/netns-vrf
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'netns-vrf'
|
4
|
+
|
5
|
+
def help
|
6
|
+
puts "usage: netns-vrf [options]\n\n"
|
7
|
+
puts "options: "
|
8
|
+
puts " - create [VRF_NAME]"
|
9
|
+
puts " - delete [VRF_NAME]"
|
10
|
+
puts " - show [VRF_NAME:optional]"
|
11
|
+
puts " - interface (push|remove) [IFACE_NAME] [VRF_NAME]"
|
12
|
+
puts " - ip address (inet|inet6) (add|delete) [IP_ADDRESS] [IFACE_NAME] [VRF_NAME]"
|
13
|
+
puts " - ip route (inet|inet6) (add|delete) [DESTINATION_PREFIX] [NEXT_HOP] [IFACE_NAME] [VRF_NAME]\n\n"
|
14
|
+
exit 0
|
15
|
+
end
|
16
|
+
|
17
|
+
begin
|
18
|
+
if ARGV[0]
|
19
|
+
case ARGV[0]
|
20
|
+
when 'create'
|
21
|
+
if ARGV[1]
|
22
|
+
vrf_name = ARGV[1]
|
23
|
+
vrf_instance = VRFLite::NetNs.new(vrf_name)
|
24
|
+
vrf_instance.build
|
25
|
+
puts "+ vrf created: #{vrf_name}"
|
26
|
+
else
|
27
|
+
help
|
28
|
+
end
|
29
|
+
|
30
|
+
when 'delete'
|
31
|
+
if ARGV[1]
|
32
|
+
vrf_name = ARGV[1]
|
33
|
+
vrf_instance = VRFLite::NetNs.new(vrf_name)
|
34
|
+
vrf_instance.destroy
|
35
|
+
puts "+ vrf deleted: #{vrf_name}"
|
36
|
+
else
|
37
|
+
help
|
38
|
+
end
|
39
|
+
|
40
|
+
when 'show'
|
41
|
+
vrf_name = ARGV[1] if ARGV[1]
|
42
|
+
vrf_name = nil if not ARGV[1]
|
43
|
+
vrf_table = VRFLite::NetNs.new(vrf_name)
|
44
|
+
vrf_table_array = vrf_table.display
|
45
|
+
vrf_table_array.each do |vta|
|
46
|
+
puts "display vrf: #{vta}"
|
47
|
+
puts "--------------------------"
|
48
|
+
vrf_local_link = `ip netns exec #{vta} ip address show`
|
49
|
+
puts "#{vrf_local_link}"
|
50
|
+
puts "--------------------------\n\n"
|
51
|
+
end
|
52
|
+
|
53
|
+
when 'interface'
|
54
|
+
if ARGV[1] and ARGV[2] and ARGV[3]
|
55
|
+
action_switch, if_name, vrf_name = ARGV[1..3]
|
56
|
+
interface = VRFLite::Interface.new(if_name, vrf_name)
|
57
|
+
if action_switch == "push"
|
58
|
+
if_action = interface.add_to_vrf
|
59
|
+
action_type = 0
|
60
|
+
elsif action_switch == "remove"
|
61
|
+
if_action = interface.del_from_vrf
|
62
|
+
action_type = 1
|
63
|
+
else
|
64
|
+
help
|
65
|
+
end
|
66
|
+
if if_action.to_i == 0 and action_type == 0
|
67
|
+
puts "+ interface #{if_name} correctly added to vrf: #{vrf_name}"
|
68
|
+
elsif if_action.to_i == 0 and action_type == 1
|
69
|
+
puts "+ interface #{if_name} correctly removed from vrf: #{vrf_name}"
|
70
|
+
else
|
71
|
+
puts "+ interface #{if_name} not found in the system: #{if_action}:#{action_type}"
|
72
|
+
end
|
73
|
+
else
|
74
|
+
help
|
75
|
+
end
|
76
|
+
|
77
|
+
when 'ip'
|
78
|
+
help if not ARGV[1]
|
79
|
+
case ARGV[1]
|
80
|
+
when 'address'
|
81
|
+
if ARGV[2] == "inet" || ARGV[2] == "inet6" && ARGV[3..6]
|
82
|
+
action_switch, ip_addr, if_name, vrf_name = ARGV[3..6]
|
83
|
+
ip = VRFLite::IP.new(ip_addr, if_name, vrf_name)
|
84
|
+
if action_switch == "add" && ARGV[2] == "inet"
|
85
|
+
ip_action = ip.add_to_vrf
|
86
|
+
action_type = 0
|
87
|
+
elsif action_switch == "add" && ARGV[2] == "inet6"
|
88
|
+
ip_action = ip.add_ip6_to_vrf
|
89
|
+
action_type = 0
|
90
|
+
elsif action_switch == "delete" && ARGV[2] == "inet"
|
91
|
+
ip_action = ip.del_from_vrf
|
92
|
+
action_type = 1
|
93
|
+
elsif action_switch = "delete" && ARGV[2] == "inet6"
|
94
|
+
ip_action = ip.del_ip6_to_vrf
|
95
|
+
action_type = 1
|
96
|
+
else
|
97
|
+
help
|
98
|
+
end
|
99
|
+
if ip_action.to_i == 0 and action_type == 0
|
100
|
+
puts "+ IP address #{ip_addr} correctly added to interface #{if_name} : VRF #{vrf_name}"
|
101
|
+
elsif ip_action.to_i == 0 and action_type == 1
|
102
|
+
puts "+ IP address #{ip_addr} correctly deleted from interface #{if_name} : VRF #{vrf_name}"
|
103
|
+
else
|
104
|
+
puts "+ unable to add/delete IP address #{ip_addr} to/from interface #{if_name} : VRF #{vrf_name}"
|
105
|
+
end
|
106
|
+
else
|
107
|
+
help
|
108
|
+
end
|
109
|
+
when 'route'
|
110
|
+
if ARGV[2] == "inet" || ARGV[2] == "inet6" && ARGV[3..7]
|
111
|
+
action_switch, ip_dst, ip_next_hop, if_name, vrf_name = ARGV[3..7]
|
112
|
+
static_route = VRFLite::Route.new(ip_dst, ip_next_hop, if_name, vrf_name)
|
113
|
+
if action_switch == "add" && ARGV[2] == "inet"
|
114
|
+
routing_action = static_route.add_to_vrf_inet
|
115
|
+
action_type = 0
|
116
|
+
elsif action_switch == "add" && ARGV[2] == "inet6"
|
117
|
+
routing_action = static_route.add_to_vrf_inet6
|
118
|
+
action_type = 0
|
119
|
+
elsif action_switch == "delete" && ARGV[2] == "inet"
|
120
|
+
routing_action = static_route.del_from_vrf_inet
|
121
|
+
action_type = 1
|
122
|
+
elsif action_switch == "delete" && ARGV[2] == "inet6"
|
123
|
+
routing_action = static_route.del_from_vrf_inet6
|
124
|
+
action_type = 1
|
125
|
+
elsif action_switch == "show" && ip_dst
|
126
|
+
vrf_name = ip_dst
|
127
|
+
route_show = `ip netns exec #{vrf_name} ip route show`.chop if ARGV[2] == "inet"
|
128
|
+
route_show = `ip netns exec #{vrf_name} ip route show`.chop if ARGV[2] == "inet6"
|
129
|
+
puts "display vrf #{vrf_name} routing table:\n\n"
|
130
|
+
puts route_show
|
131
|
+
puts "\n\n"
|
132
|
+
routing_action = "1"
|
133
|
+
action_type = 1
|
134
|
+
else
|
135
|
+
help
|
136
|
+
end
|
137
|
+
if routing_action.to_i == 0 and action_type == 0
|
138
|
+
puts "+ route to #{ip_dst} added - nexthop: #{ip_next_hop} - iface: #{if_name} - VRF #{vrf_name}"
|
139
|
+
elsif routing_action.to_i == 0 and action_type == 1
|
140
|
+
puts "+ route to #{ip_dst} correctly deleted"
|
141
|
+
elsif routing_action.to_i == 1 and action_type == 1
|
142
|
+
else
|
143
|
+
puts "+ unable to add/delete route."
|
144
|
+
end
|
145
|
+
else
|
146
|
+
help
|
147
|
+
end
|
148
|
+
|
149
|
+
else
|
150
|
+
help
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
|
155
|
+
else
|
156
|
+
help
|
157
|
+
end
|
158
|
+
else
|
159
|
+
help
|
160
|
+
end
|
161
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module VRFLite
|
2
|
+
class Interface
|
3
|
+
def initialize(if_name, vrf_name)
|
4
|
+
@if_name = if_name
|
5
|
+
@vrf_name = vrf_name
|
6
|
+
end
|
7
|
+
def add_to_vrf
|
8
|
+
dev_file = File.open("/proc/net/dev", "r")
|
9
|
+
dev_file.each do |dev|
|
10
|
+
if dev =~ /#{@if_name}:/ # check if the interface is in default vrf before pushing it to vrf #
|
11
|
+
system("ip link set #{@if_name} netns #{@vrf_name}")
|
12
|
+
system("ip netns exec #{@vrf_name} ip link set #{@if_name} up")
|
13
|
+
@lock = 0
|
14
|
+
return @lock.to_i
|
15
|
+
else
|
16
|
+
@lock = 1 # device is not in default netns #
|
17
|
+
end
|
18
|
+
end
|
19
|
+
return @lock.to_i
|
20
|
+
end
|
21
|
+
def del_from_vrf
|
22
|
+
dev_location = `ip netns exec #{@vrf_name} cat /proc/net/dev | grep ':' | cut -d ':' -f 1 | grep #{@if_name} | head -n 1`.chop # got to find a way to lookup the dev file of the netns #
|
23
|
+
if dev_location != ''
|
24
|
+
system("ip netns exec #{@vrf_name} ip link set #{@if_name} down")
|
25
|
+
system("ip netns exec #{@vrf_name} ip link del #{@if_name}")
|
26
|
+
return 0
|
27
|
+
else
|
28
|
+
return 1 # device is not in vrf #
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
data/lib/netns-vrf/ip.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
module VRFLite
|
2
|
+
class IP
|
3
|
+
def initialize(ip_addr, if_name, vrf_name)
|
4
|
+
@if_name = if_name
|
5
|
+
@vrf_name = vrf_name
|
6
|
+
@ip_addr = ip_addr
|
7
|
+
end
|
8
|
+
def add_to_vrf
|
9
|
+
system("ip netns exec #{@vrf_name} ip address add #{@ip_addr} dev #{@if_name}")
|
10
|
+
return 0
|
11
|
+
end
|
12
|
+
def del_from_vrf
|
13
|
+
system("ip netns exec #{@vrf_name} ip address del #{@ip_addr} dev #{@if_name}")
|
14
|
+
return 0
|
15
|
+
end
|
16
|
+
def add_ip6_to_vrf
|
17
|
+
system("ip netns exec #{@vrf_name} ip -6 address add #{@ip_addr} dev #{@if_name}")
|
18
|
+
return 0
|
19
|
+
end
|
20
|
+
def del_ip6_from_vrf
|
21
|
+
system("ip netns exec #{@vrf_name} ip -6 address del #{@ip_addr} dev #{@if_name}")
|
22
|
+
return 0
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module VRFLite
|
2
|
+
class NetNs # provides: build / destroy / display on NetNS #
|
3
|
+
def initialize(vrf_name)
|
4
|
+
@vrf_name = vrf_name
|
5
|
+
end
|
6
|
+
|
7
|
+
def build
|
8
|
+
system("ip netns add #{@vrf_name}")
|
9
|
+
system("ip netns exec #{@vrf_name} ip link set lo up") # initialize stack loopback #
|
10
|
+
return 0
|
11
|
+
end
|
12
|
+
|
13
|
+
def destroy
|
14
|
+
system("ip netns delete #{@vrf_name}")
|
15
|
+
return 0
|
16
|
+
end
|
17
|
+
|
18
|
+
def display
|
19
|
+
vrf_config = []
|
20
|
+
if @vrf_name == nil || @vrf_name == "all"
|
21
|
+
net_ns = Dir["/var/run/netns/*"]
|
22
|
+
else
|
23
|
+
net_ns = Dir["/var/run/netns/#{@vrf_name}"]
|
24
|
+
end
|
25
|
+
net_ns.each do |ns|
|
26
|
+
vrf_path = net_ns.to_s.split '/'
|
27
|
+
vrf_id = vrf_path[4].chop.chop
|
28
|
+
vrf_config << vrf_id
|
29
|
+
end
|
30
|
+
return vrf_config if @vrf_name != nil || @vrf_name == "all"
|
31
|
+
return vrf_config[0..-1]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module VRFLite
|
2
|
+
class Route
|
3
|
+
def initialize(vrf_rt_dst, vrf_gw, if_name, vrf_name)
|
4
|
+
@if_name = if_name
|
5
|
+
@vrf_name = vrf_name
|
6
|
+
@vrf_gw = vrf_gw
|
7
|
+
@vrf_rt_dst = vrf_rt_dst
|
8
|
+
end
|
9
|
+
def add_to_vrf_inet
|
10
|
+
system("ip netns exec #{@vrf_name} ip route add #{@vrf_rt_dst} via #{@vrf_gw} dev #{@if_name}")
|
11
|
+
return 0
|
12
|
+
end
|
13
|
+
def del_from_vrf_inet
|
14
|
+
system("ip netns exec #{@vrf_name} ip route del #{@vrf_rt_dst} via #{@vrf_gw} dev #{@if_name}")
|
15
|
+
return 0
|
16
|
+
end
|
17
|
+
|
18
|
+
def add_to_vrf_inet6
|
19
|
+
system("ip netns exec #{@vrf_name} ip -6 route add #{@vrf_rt_dst} via #{@vrf_gw} dev #{@if_name}")
|
20
|
+
return 0
|
21
|
+
end
|
22
|
+
|
23
|
+
def del_from_vrf_inet6
|
24
|
+
system("ip netns exec #{@vrf_name} ip -6 route del #{@vrf_rt_dst} via #{@vrf_gw} dev #{@if_name}")
|
25
|
+
return 0
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
data/lib/netns-vrf.rb
ADDED
metadata
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: netns-vrf
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Samer Abdel-Hafez
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-05-12 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: linux vrf-lite command line wannabe
|
15
|
+
email:
|
16
|
+
- sam@arahant.net
|
17
|
+
executables:
|
18
|
+
- netns-vrf
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files: []
|
21
|
+
files:
|
22
|
+
- lib/netns-vrf.rb
|
23
|
+
- lib/netns-vrf/ip.rb
|
24
|
+
- lib/netns-vrf/route.rb
|
25
|
+
- lib/netns-vrf/interface.rb
|
26
|
+
- lib/netns-vrf/netns.rb
|
27
|
+
- bin/netns-vrf
|
28
|
+
homepage: http://github.com/nopedial/netns-vrf
|
29
|
+
licenses: []
|
30
|
+
post_install_message:
|
31
|
+
rdoc_options: []
|
32
|
+
require_paths:
|
33
|
+
- lib
|
34
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
35
|
+
none: false
|
36
|
+
requirements:
|
37
|
+
- - ! '>='
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
requirements: []
|
47
|
+
rubyforge_project: netns-vrf
|
48
|
+
rubygems_version: 1.8.23
|
49
|
+
signing_key:
|
50
|
+
specification_version: 3
|
51
|
+
summary: quick and dirty linux netns wrapper
|
52
|
+
test_files: []
|