netns-vrf 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|