2010-12-01 109 views
0

我不太了解Ruby,我需要理解这个脚本的作用。我知道它调用ebtables来添加为虚拟机配置网络的规则。但我不知道如何?这个脚本是做什么的?

这是代码:

#!/usr/bin/env ruby 

require 'pp' 
require 'rexml/document' 

VM_NAME=ARGV[0] 

# Uncomment to act only on the listed bridges. 
#FILTERED_BRIDGES = ['beth0'] 

def activate(rule) 
    system "sudo ebtables -A #{rule}" 
end 

def get_bridges 
    bridges = Hash.new 
    brctl_exit=`brctl show` 
    cur_bridge = "" 
    brctl_exit.split("\n")[1..-1].each do |l| 
     l = l.split 
     if l.length > 1 
      cur_bridge = l[0] 
      bridges[cur_bridge] = Array.new 
      bridges[cur_bridge] << l[3] 
     else 
      bridges[cur_bridge] << l[0] 
     end 
    end 
    bridges 
end 

def get_interfaces 
    bridges = get_bridges 
    if defined? FILTERED_BRIDGES 
     FILTERED_BRIDGES.collect {|k,v| bridges[k]}.flatten 
    else 
     bridges.values.flatten 
    end 
end 

nets=`virsh -c qemu:///system dumpxml #{VM_NAME}` 

doc=REXML::Document.new(nets).root 

interfaces = get_interfaces() 

doc.elements.each('/domain/devices/interface') {|net| 
    tap=net.elements['target'].attributes['dev'] 
    if interfaces.include? tap 
     iface_mac=net.elements['mac'].attributes['address'] 

     mac=iface_mac.split(':') 
     mac[-1]='00' 
     net_mac=mac.join(':') 


     in_rule="FORWARD -s ! #{net_mac}/ff:ff:ff:ff:ff:00 -o #{tap} -j DROP" 
     out_rule="FORWARD -s ! #{iface_mac} -i #{tap} -j DROP" 

     activate(in_rule) 
     activate(out_rule) 
    end 
} 

因此很明显,它提取MAC不会忽略(不知道哪些)并丢弃数据包/或他们的地方转发?

非常感谢您的帮助!

回答

1

脚本运行virsh -c qemu:///system dumpxml #{VM_NAME}其中VM_NAME是该脚本的第一个参数。

它实际运行两次,肯定是错误的。在第一次运行

nets=`virsh -c qemu:///system dumpxml #{VM_NAME}` 

然后运行时,它的第二时间,并将该XML输出在可变doc

doc=REXML::Document.new(nets).root 

然后循环的界面上,获得在元件<从属性dev的值目标。如果该值来自brctl show命令的结果,则它将从< mac>元素的地址属性中获取MAC地址。

MAC被拆分为数组:,该数组中的最后一个元素更改为'00',并从该数组创建net_mac

#{net_mac} in_rule任务将被新构建的net_mac取代。等等。

然后in_ruleout_rule应用于sudo ebtables -A #{rule}命令。

清除?

+0

非常感谢乔纳斯! :)为什么要用00改变mac的最后部分? – Zenet 2010-12-01 14:08:56