通讯量的监视和控制

对SWX2200的端口进行定期监视、当数据包的收信负荷率超过阈值时,即关闭端口,控制流量。
使用SWX2200-24G时、关闭端口之前,应缩小收信带宽、控制流量。采取措施后,收信负荷率仍然超过阈值时,应关闭关口。

RTX1200的设定例

LAN的接口设定
(使用LAN1端口)

ip lan1 address 192.168.0.1/24

LAN的接口设定
(使用LAN2端口)

pp select 1
pp always-on on
pppoe use lan2
pp auth accept pap chap
pp auth myname(连接ISP的ID) (连接ISP的密码)
ppp lcp mru on 1454
ppp ipcp ipaddress on
ppp ipcp msext on
ip pp mtu 1454
ip pp nat descriptor 1
pp enable 1
ip route default gateway pp 1

NAT的设定

nat descriptor type 1 masquerade

DHCP的设定

dhcp service server
dhcp server rfc2131 compliant except remain-silent
dhcp scope 1 192.168.0.2-192.168.0.100/24

DNS的设定

dns server(由ISP指定的DNS服务器的IP地址)
dns private address spoof on

SWX2200的设定

switch control use lan1 on

文件夹的设定

ip filter source-route on
ip filter directed-broadcast on
ip filter 1010 reject * * udp,tcp 135 *
ip filter 1011 reject * * udp,tcp * 135
ip filter 1012 reject * * udp,tcp netbios_ns-netbios_ssn *
ip filter 1013 reject * * udp,tcp * netbios_ns-netbios_ssn
ip filter 1014 reject * * udp,tcp 445 *
ip filter 1015 reject * * udp,tcp * 445
ip filter 1020 reject 192.168.0.0/24 *
ip filter 1030 pass * 192.168.0.0/24 icmp
ip filter 2000 reject * *
ip filter 3000 pass * *
ip filter dynamic 100 * * ftp
ip filter dynamic 101 * * www
ip filter dynamic 102 * * domain
ip filter dynamic 103 * * smtp
ip filter dynamic 104 * * pop3
ip filter dynamic 105 * * netmeeting
ip filter dynamic 106 * * tcp
ip filter dynamic 107 * * udp
pp select 1
ip pp secure filter in 1020 1030 2000
ip pp secure filter out 1010 1011 1012 1013 1014 1015 3000 dynamic 100 101 102 103 104 105 106 107
pp enable 1

Lua脚本日程的设定

schedule at 1 startup * lua /swx2200_lua_traffic_ctl_rtx1200.lua

Lua脚本例

设定值

--监视间隔(1 - 864000 秒)
idle_time = 60
-- 计算收信负荷率的时间(1, 2 .. )
avr_sec = 1
-- 收信负荷率的函数(1 - 99 %)
rcv_th = 30
-- [[
持续超出阈值时,缩小收信带宽的次数(1, 2, ..)
SWX2200-24G有效。需要指定比down_count更少的次数
]]
shaping_cnt = 3
-- 持续超过阈值时,关闭收信带宽的次数(1, 2, ..)
down_cnt = 5
--[[
缩小带宽时的速度等级(1 - 31)
switch control function set qos-speed-unit指令的设定值 (初始值 32M)
乘以shaping_ speed的值就是实际的带宽
仅SWX2200_24G有效
]]
shaping_speed = 10
--此次脚本输出的SYSLOG的登记(info, debug, notice)
log_level = "info"
--[[
将监视对象的交换机和监视的端口,用逗点分开列举
根据从MAC地址、或路由器到交换机的连接端口的路径信息指定
("00:a0:de:xx:xx:xx" 或者 "lan1:2")
列举监视的端口(port="1 357")
]]
sw_list = {
    { route = "lan1:1", port = "2-8"}
}
-- (传输: true / 不传输 false)
mail = false
-- 邮件的设定
mail_tbl = {
    smtp_address ="(SMTP服务器的地址)",
    from ="(发信方邮件地址)",
    to ="(投递方邮件地址)"
}

获得端口通信速度的函数

function port_speed(num, route)
    local rtn, str, val, rt_name
    local cmd = "switch control function get status-port-speed " .. num
    local ptn = "(%d+)"

    rt.command("switch select " .. route)
    rtn, str = rt.command(cmd)
    val = 0
    if (rtn) and (str) then
        str = str:match(ptn)
        if (str) then
            val = unitstr2num(str)
        end
    end
    return val
end

将线路速度变换为数值的函数

function unitstr2num(str)
    local val

    val = tonumber(str)
    if (val > 0) then
        val = val * 1024 * 1024
    end
    return val
end

获得收信字节数的函数

function port_rx_octet(num, route)
    local rtn, str
    local cmd = "switch control function get status-counter-octet-rx " .. num
    local ptn = "(%d+)"

    rt.command("switch select " .. route)
    rtn, str = rt.command(cmd)
    if (rtn) and (str) then
        str = string.match(str, ptn)
    end
    return tonumber(str)
end

根据字节数之间的差异和线路速度球的收信负荷率

function calc_load(port)
    local load, diff

    if (port.speed == 0) then
        return 0
    end

    if (port["octet1"] > port["octet2"]) then
        -- 超过计数器上线时
        diff = port.speed - port.octet1 * 8
        load = (diff + port["octet2"] * 8) / avr_sec
    else
        diff = port["octet2"] - port["octet1"]
        load = diff * 8 / avr_sec -- 速度(bps)
    end
    load = 100 * load / port.speed -- 负荷率
    return load
end

线路使用率超过阈值时,或正常返回恢复时信息的函数

function make_portmsg(port, route, load, stat)
    local rtn
    local str = ""

    if (stat == "shaping") then
        mail_tbl.text = string.format("由于收信负荷率超过了阈值、"..
                       "因此缩小了“switch(%s)的带宽。"..
                       "\r\n\r\n", route, port)
        mail_tbl.text = mail_tbl.text .. "\t将收信带宽的等级" .. shaping_speed ..
                "改为shaping_speed。\r\n"
        mail_tbl.text = mail_tbl.text .. "\t阈值: " .. rcv_th .. "%"
    elseif (stat == "down") then
        mail_tbl.text = string.format("由于收信负荷率超过了阈值、"..
                       "关闭switch(%s的端口ト%d。\r\n\r\n",
                       route, port)
        mail_tbl.text = mail_tbl.text .. "\t收信负荷率:" .. load .. "%\r\n"
        mail_tbl.text = mail_tbl.text .. "\t阈值:" .. rcv_th .. "%"
    end
end

计算超过阈值的连续次数的函数

function count_proc(t, val, port_num)
    local rtn = 0

    if (val > rcv_th) then
        -- 超过阈值时
        t.cnt = t.cnt + 1
        -- 24G限定
        if (port_num == 24) then
            if (t.stat == "normal") and (t.cnt == shaping_cnt) then
                t.stat = "shaping"
                rtn = 1
            end
        end

        if (t.stat ~= "down") and (t.cnt == down_cnt) then
            t.stat = "down"
            rtn = 1
        end
    else
        -- 收信负荷率在阈值以下时,设置计数器
        t.cnt = 0
    end
    return rtn, t
end

对端口的授信贷款/端口计数的函数

function exec_sw_cmd(route, stat, port)
    rtn, str = rt.command("switch select " .. route)

    if (rtn) then
        if (stat == "shaping") then
            -- 减少端口
            rt.command("switch control function set qos-policing-use "
                   .. port .. " on")
            rt.command("switch control function set qos-policing-speed "
                    .. port .. " " .. shaping_speed)
            -- 输出syslog
            msg = string.format("over the receive threshold. "..
                        "port%d speed down", port)
            rt.syslog(log_level, msg)
        elseif (stat == "down") then
            rt.command("switch control function set port-use ".. port .. " off")
            --输出 syslog
            msg = string.format("over the receive threshold. port%d down",
                         port)
            rt.syslog(log_level, msg)
        end
    end
end

获得现在日期时间的函数

function time_stamp()
    local t

    t = os.date("*t")
    return string.format("%d/%02d/%02d %02d:%02d:%02d",
        t.year, t.month, t.day, t.hour, t.min, t.sec)
end

发送邮件的函数

function send_mail(port, route, load, stat)
    local rtn

    make_portmsg(port, route, load, stat)
    mail_tbl.subject = string.format("receive load watch")
    rtn = rt.mail(mail_tbl)
    if (not rtn) then
        rt.syslog(log_level, "failed to send mail. swx2200_lua_traffic_ctl_rtx1200.lua")
    end
end

SW的搜索、以及机型,端口数的设定

function set_sw_tbl(tbl)
    for i, sw in ipairs(sw_list) do
        route = sw.route
        rtn, str = rt.command("switch control function get model-name ".. route)
        if (rtn) and (str) then
            str = string.match(str, "%w+%p(%d+).")
            if (str) then
                tbl[i] = {
                    route = route,
                    port_num = tonumber(str),
                    port_info = {},
                    check_port = {}
                }
            else
                stbl[i] = nil
            end
        else
            tbl[i] = nil
        end
    end
end

将SW的各端口信息初始化

function port_info_init(tbl, sw_num)
    local sw

    for i=1, sw_num do
        sw = tbl[i]
        if (sw ~= nil) then
            for j=1, sw.port_num do
                sw.port_info[j] = {
                    speed = 0, octet1 = 0, octet2 = 0, result = 0, cnt = 0, stat = "normal"
                }
            end
        end
    end
end

对SW的监视端口进行设定

function set_check_port(tbl, sw_num)
    local sw, port
    local min, max, port_val

        for i=1, sw_num do
        sw = tbl[i]
        if (sw ~= nil) then
            port = sw_list[i].port
            j = 1
            str = ""
            while (true) do
                port_val = string.match(port, str.."(.-),")
                if (port_val == nil) then
                    port_val = string.match(port, str .."(.-)$")
                    if (port_val == nil) then
                        break
                    end
                end
                --发现要素时
                min, max = string.match(port_val,"(%d+)%p(%d+)")
                if (min ~= nil) and (max ~= nil) then
                    --指定范围
                    min = tonumber(min)
                    max = tonumber(max)
                    for n = min, max do
                        sw.check_port[j] = n
                        j = j + 1
                        n = n + 1
                    end
                else
                    --指定单体
                    sw.check_port[j] = tonumber(port_val)
                    j = j + 1
                end
                str = str .. ".-,"
            end
        end
    end
end

获取SW的各端口字节数

function get_port_info(sw, port_num, str)
    local port
    --监视的端口时
    port = sw.port_info[port_num]
    if (str == "octet1") then
        -- 求的收信字节数(第1次)
        octet = port_rx_octet(port_num, sw.route)
        -- 保存字节数
        port["octet1"] = octet
    elseif (str == "octet2") then
        -- 计算收信字节数(第2次)
        octet = port_rx_octet(port_num, sw.route)
        -- 保存字节数
        port["octet2"] = octet
    end
end

主程序

local rtn, str, max
local sw, port
local port_info = {}
local sw_tbl = {}

-- 搜索被指定的SWX,辨别8G/24G。
set_sw_tbl(sw_tbl)
--SW个端口信息用阵列的初始化
port_info_init(sw_tbl, #sw_tbl)
--设置SW的监视端口编号
set_check_port(sw_tbl, #sw_tbl)

while (true) do
    for i = 1, #sw_tbl do
        sw = sw_tbl[i]
        num = 1
        check = sw.check_port[num]

        for j = 1, sw.port_num do
            if (j == check) then
                port = sw.port_info[j]
                max = port_speed(port_num, sw.route)
                port["speed"] = max
                if (max > 0) then
                    --第1次
                    get_port_info(sw, j, "octet1")
                    --等待计算时间
                    rt.sleep(avr_sec)
                    --第2次
                    get_port_info(sw, j, "octet2")
                    --计算收信负荷率
                    load = calc_load(port)
                    --超过阈值次数的计数
                    rtn, port = count_proc(port, load, sw.port_num)

                    if (rtn > 0) then
                        --[[

                         缩小端口收信带宽/关闭端口
                        ]]
                        exec_sw_cmd(sw.route, port.stat, j)
                        -- 发送邮件
                        if (mail) then
                            send_mail(j, sw.route, load, port.stat)
                        end
                    end
                end
                num = num + 1
                check = sw.check_port[num]

                if (check == nil) then
                    break
                end
            end
        end
    end
    -- 等待测定时间
    rt.sleep(idle_time)
end

返回顶部Return to Top

网络相关产品

服务支持

事业绍介