Esempio n. 1
0
def get_vlink_flow(uid):
    flows = []

    show = {"_id": 0, "bps": 1, "time.log": 1, "addr.src": 1, "addr.dst": 1}

    # vlink.sport, vlink.dport => db.ports.ui
    vlink = getvlink(uid)
    if not vlink:
        klog.e("NotFound: vlink: uid:", uid)
        return []

    klog.d(varfmt(vlink, "vlink"))

    sportip = vlink.get("sportip")
    dportip = vlink.get("dportip")

    src_equip = equip_fr_port_ip(sportip) or equip_fr_port_ip(
        vlink["sloopbackip"])
    dst_equip = equip_fr_port_ip(dportip) or equip_fr_port_ip(
        vlink["dloopbackip"])

    if not src_equip:
        klog.e("NotFound: src_equip: sportip:", sportip)
        return []

    next_hop_uid = dst_equip.get("uid", "<Null>")

    match = {"loopback.cur": src_equip["ip_str"], "port.nexthop": dportip}
    klog.d(varfmt(match, "db.logs.find: match"))
    logs = db.logs.find(match, show)
    for log in logs:
        try:
            timediff = time.time() - log["time"]["log"]
            if timediff > conf.DB_LOG_AGE_SKIP:
                continue

            _flow = "(%s) >>> (%s)@(%s) >>> (%s)@(%s) >>> (%s)" % (
                log["addr"]["src"], sportip, src_equip["ip_str"], dportip,
                dst_equip["ip_str"], log["addr"]["dst"])
            flow = {
                "_flow": _flow,
                "bps": log["bps"],
                "src": log["addr"]["src"],
                "dst": log["addr"]["dst"],
                "uid": uid,
                "next_hop_uid": next_hop_uid
            }
            flows.append(flow)
        except:
            klog.e(traceback.format_exc())
            klog.e("BAD LOG: ", varfmt(log, color=True))
            varprt(match, "find vlink")

    return flows
Esempio n. 2
0
def hget(scheme,
         hostname,
         port,
         path,
         method="GET",
         dat=None,
         hdr=None,
         timeout=None):
    '''Http get'''

    hdr = hdr or {}

    if scheme == "https":
        context = ssl._create_unverified_context()
        hc = httplib.HTTPSConnection(hostname, port, timeout, context=context)
    else:
        hc = httplib.HTTPConnection(hostname, port, timeout)

    params = json.dumps(dat)
    hc.request(method, path, params, hdr)
    r = hc.getresponse()
    dat = r.read()

    klog.d()
    klog.d("+" * 30)
    klog.d("METHOD : %s" % method)
    klog.d("STATUS : %d" % r.status)
    klog.d("REASON : %s" % r.reason)
    klog.d("  PATH : %s" % path)
    klog.d(varfmt(dmstr(dat).toDict(), "DUMP HGET DATA"))
    klog.d("-" * 30)
    klog.d()

    return r.status, r.reason, dat
Esempio n. 3
0
def flowv(cmdctx, calldic):
    '''Show flow for vlink

    .opt --l limit :100

    .opt --hi bpsMin :9999999999999

    .opt --lo bpsMax :0

    .opt --s searchPat :.*

    .arg uids
    uid list
    '''

    limit = int(calldic.nth_opt("l", 0, 100))
    bpshi = int(calldic.nth_opt("hi", 0, 9999999999999))
    bpslo = int(calldic.nth_opt("lo", 0, 0))

    uids = calldic.get_args()
    if not uids:
        uids = [e.get("uid") for e in db.vlinks.find()]

    pat = calldic.nth_opt("s", 0, ".*")
    pat = re.compile(pat)

    klog.d(varfmt(uids, "UID List"))
    res = []
    for uid in uids:
        res.extend(get_vlink_flow(uid))
    res = [f for f in res if pat.search(str(f))]
    res = sorted(res, lambda x, y: y.get("bps", 0) - x.get("bps", 0))
    res = filter(lambda x: bpslo <= x.get("bps", 0) <= bpshi, res)
    return res[:limit]
Esempio n. 4
0
    def act(self):
        lc_loops.inc()

        ctime = time.time() - self.keeptime
        query = {"time.log": {"$lt": ctime}}
        res = db.logs.delete_many(query)
        klog.d("%s" % varfmt(query))
        klog.d("%d deleted." % res.deleted_count)

        lc_logs.inc(res.deleted_count)

        return self.keeptime * 9 / 10
Esempio n. 5
0
def docmd_flow():
    calldic = idic()

    klog.d(varfmt(calldic, "calldic"))

    request = calldic["request"]

    if request == "ms_flow_set_topo":
        return ms_flow_set_topo(calldic)

    if request == "ms_flow_get_flow":
        return ms_flow_get_flow(calldic)

    return "Bad request '%s'" % request
Esempio n. 6
0
    def dotan(self, req=None):
        '''
        req: {
            "uid": "46",
            "user_data": {
                "tunnel_name": "xxxxxxxxxxxx"
                "path": "xxxxxxxxxxxx",
                "status": "xxxxxxxxxxxx",
                "hop_list": ["this", "is", "real", "hops"],
                "create_info": {
                    "uid": xxx,
                    "from_router_name": xxx,
                    "hop_list": ["this", 'is', 'set', 'hoplist'],
                    "...": "...",
                }
            },
            "callback": "http://127.0.0.1/path"
        }

        resp: {
            "uid": "lsp_0",
            "from_router_name": "",
            "to_router_name": "",
            "bandwidth": "",
            "to_router_uid": "",
            "from_router_uid": "",
            "name": "",
            "hop_list": [],
            "path": [],
            "status": 0,
            "priority": 7,
            "delay": "",
            "user_data": {}
        }
        '''

        userdata = req["args"]["user_data"]
        ci = req["args"]["user_data"]["create_info"]

        klog.d(varfmt(ci, "CI"))
        tunnel_name = ci["name"]

        hdr = token.todic()

        url_pathpat = self.url_pathpat.format(tunnel_name=tunnel_name)
        status, reason, res = hget(self.url_scheme, self.url_hostname,
                                   self.url_port, url_pathpat, self.method,
                                   None, hdr)
        if status != 200:
            return None

        resp = {
            "uid": ci["uid"],
            "from_router_name": ci["from_router_name"],
            "to_router_name": ci["to_router_name"],
            "bandwidth": ci["bandwidth"],
            "to_router_uid": ci["to_router_uid"],
            "from_router_uid": ci["from_router_uid"],
            "name": ci["name"],
            "hop_list": ci["hop_list"],
            "path": userdata["path"],
            "status": userdata["status"],
            "priority": ci["priority"],
            "delay": ci["delay"],
            "user_data": userdata,
        }

        return dotmap.DotMap(resp)
Esempio n. 7
0
    def dotan(self, req=None):
        klog.d("dotan")
        '''
        req: {
            "args": {
                "hop_list": [                                   <<
                    "PE11A",
                    "PE21A"
                ],
                "from_router_name": "",                         <<
                "to_router_name": "",                           <<
                "bandwidth": "",                                <<
                "to_router_uid": "",                            <<
                "from_router_uid": "",                          <<
                "callback": "http://127.0.0.1/path",            !!
                "name": "",                                     <<
                "priority": 7,                                  <<
                "delay": ""                                     <<
            },
            "request": "ms_controller_add_lsp",
            "ts": "20160718091442",
            "trans_id": 1468804482
        }

        resp: {
            "uid": "lsp_0",             !!
            "from_router_name": "",     <<
            "to_router_name": "",       <<
            "bandwidth": "",            <<
            "to_router_uid": "",        <<
            "from_router_uid": "",      <<
            "name": "",                 <<
            "hop_list": [],             <<
            "path": [],                 ??
            "status": 0,                !!
            "priority": 7,              <<
            "delay": "",                <<
            "user_data": {              !!
                "tunnel_name": "xxxxxxxxxxxx"
            }
        }
        '''

        args = dotmap.DotMap(req["args"])

        def getloopback(router_uid):
            e = einfo.fr_uid(router_uid)
            return e.get("ip_str") if e else None

        fr_ip = getloopback(args.get("from_router_uid")) or "222.222.222.222"
        if not fr_ip:
            klog.e("dotan")
            return None
        to_ip = getloopback(args.get("to_router_uid")) or "221.221.221.221"
        if not to_ip:
            klog.e("dotan")
            return None

        hdr = token.todic()

        tunnel_name = args.get("name")
        klog.d(tunnel_name)

        # 1. Fill the parameter will be sent to web service
        dic = dotmap.DotMap()
        dic["tunnel-name"] = tunnel_name
        dic["tunnel-type"] = "te"
        dic["manage-protocol"] = "netconf"
        dic["control-mode"] = "delegate"
        dic["path-setup-type"] = "rsvp-te"

        dic["source"] = {
            "ne-id": "d056ee16-63da-4621-a210-740a72c6b468",  # FIXME
            "ip-address": fr_ip
        }
        dic["destination"] = {
            "ne-id": "bbf4f50c-32cd-4bfb-ade8-e803d4334af0",  # FIXME
            "ip-address": to_ip
        }

        status, reason, res = hgetx(self, self.method, dic, hdr)
        varprt(hdr, "HDR")
        varprt(dic, "DIC")
        klog.d("status:%s" % status)
        if status != 201:
            klog.e("status is not 201, it is %d" % status)
            return None

        newlsp = dmstr(res)

        # 2. ensure approve (doc: 2.4.4) by PceReoptimizationByTunnel
        req = {
            "auto-approve": True,
            "reoptimization-by-tunnelname": {
                "tunnel-name": tunnel_name
            }
        }
        res = call(PceReoptimizationByTunnel, req)
        klog.d(varfmt(res, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"))

        if not res:
            return None

        # 3. prepare the return value
        ret = dotmap.DotMap()

        ret.name = args.name
        ret.from_router_name = args.from_router_name
        ret.from_router_uid = args.from_router_uid
        ret.to_router_name = args.to_router_name
        ret.to_router_uid = args.to_router_uid
        ret.bandwidth = args.bandwidth
        ret.delay = args.delay
        ret.priority = args.priority

        ret.uid = args.uid
        ret.path = []  # FIXME?
        ret.status = 0
        ret.hop_list = []  # FIXME: Should overwrite by returned information?

        # 4. Get hop_list and check status to ensure the lsp is created successfully
        start = time.time()
        while True:
            if time.time() - start > 30:
                return None

            obj = call(LspInfos)
            for d in obj.get("lsp-info", ()):
                if d.get("tunnel-name") == tunnel_name:

                    # Skip backup lsp
                    role = d["lsp-role"]
                    if role != "master":
                        continue

                    # XXX: wake till it up?
                    oper_state = d.get("oper-state")
                    ret.status = 1 if oper_state == "operate-up" else 0

                    # Fill the hop_list
                    for hop in d.hops.hop:
                        # klog.d("%s" % varfmt(hop, "hop in d.hops.hop"))
                        loopback = hop["lsr-id"]

                        e = einfo.fr_loopback(loopback)
                        if e:
                            # klog.d(varfmt(e, "equip"))
                            ret.hop_list.append(e.get("uid"))

                    # Fill user_data and return
                    ret.user_data.create_info = args
                    ret.user_data.tunnel_name = tunnel_name
                    ret.user_data.path = ret.path
                    ret.user_data.status = ret.status
                    ret.user_data.hop_list = ret.hop_list

                    ret.user_data.from_router_uid = args.from_router_uid

                    return ret

            time.sleep(0.5)

        # 4. Return
        return ret
Esempio n. 8
0
    def _on_pkg_v5(self, data, address):
        ##
        ## Header
        ##

        ## u_int16_t version;
        ## u_int16_t count;
        ## u_int32_t sysup_time;
        ## u_int32_t unix_secs;
        ## u_int32_t unix_nsecs;
        ## u_int32_t flow_sequence;
        ## u_int8_t engine_type;
        ## u_int8_t engine_id;
        ## u_int16_t sampling;

        fmt = '>HHIIIIBBH'
        hdr = HdrV5(*unpack(fmt, data[:24]))
        klog.d(varfmt(hdr, color=True))

        ##
        ## Record
        ##

        ofs = 24
        reclen = 48
        for i in range(hdr.count):
            ## struct in_addr src_addr;
            ## struct in_addr dst_addr;
            ## struct in_addr nexthop;
            ## u_int16_t in_if;
            ## u_int16_t out_if;
            ## u_int32_t packets;
            ## u_int32_t octets;
            ## u_int32_t first;
            ## u_int32_t last;
            ## u_int16_t src_port;
            ## u_int16_t dst_port;
            ## u_int8_t pad1;
            ## u_int8_t tcp_flags;
            ## u_int8_t ip_proto;
            ## u_int8_t tos;
            ## u_int16_t src_as;
            ## u_int16_t dst_as;
            ## u_int8_t src_mask;
            ## u_int8_t dst_mask;
            ## u_int16_t pad2;

            fmt = '>BBBBBBBBBBBBHHIIIIHHBBBBHHBBH'
            rec = RecV5(*unpack(fmt, data[ofs:ofs + reclen]))
            klog.d(varfmt(rec, color=True))
            ofs += reclen

            if self.onflow:
                segs = []
                segs.append(address[0])
                segs.append(time.strftime("%Y-%m-%d %H:%M:%S"))
                segs.append("%d.%d.%d.%d" % (rec.src_addr_a, rec.src_addr_b,
                                             rec.src_addr_c, rec.src_addr_d))
                segs.append("%d.%d.%d.%d" % (rec.dst_addr_a, rec.dst_addr_b,
                                             rec.dst_addr_c, rec.dst_addr_d))
                segs.append("%d.%d.%d.%d" % (rec.nexthop_a, rec.nexthop_b,
                                             rec.nexthop_c, rec.nexthop_d))
                segs.append(rec.packets)
                segs.append(rec.octets)
                segs.append(rec.src_mask)
                segs.append(rec.dst_mask)
                segs.append(rec.out_if)
                segs.append(rec.in_if)
                segs.append(rec.src_port)
                segs.append(rec.dst_port)
                segs.append("5")

                log = ""
                log += "NEWLOG: %s: " % address[0]
                log += "%d.%d.%d.%d " % (rec.src_addr_a, rec.src_addr_b,
                                         rec.src_addr_c, rec.src_addr_d)
                log += ">> "
                log += "%d.%d.%d.%d " % (rec.nexthop_a, rec.nexthop_b,
                                         rec.nexthop_c, rec.nexthop_d)
                log += ">> "
                log += "%d.%d.%d.%d " % (rec.dst_addr_a, rec.dst_addr_b,
                                         rec.dst_addr_c, rec.dst_addr_d)
                log += "*********"

                klog.d(log)

                self.onflow(address[0], rec)
Esempio n. 9
0
def netusage(asc=True):
    out = []
    for r in g_routers.values():
        for p in r.ports.values():
            klog.d(varfmt(p, "NetUsage", True))
            try:

                d = DotDict()

                ipaddr = p.get("__ipaddr__")
                dbport = db.ports.find_one({"ip_str": ipaddr})
                if not dbport:
                    klog.e("Port (%s) not found" % ipaddr)
                    if not conf.NETUSE_DEBUG:
                        continue
                else:
                    d.port_uid = dbport.get("uid")
                    d.if_name = dbport.get("if_name")

                    d["__obj_db__"] = dbport

                new = int(p.rti.new.ifHCOutOctets)
                old = int(p.rti.old.ifHCOutOctets)

                diff_bytes = new - old

                diff_seconds = p.rti.new.time - p.rti.old.time
                bw_in_bytes = int(p.ifHighSpeed) * 1000000 / 8

                d.utilization = 100.0 * diff_bytes / diff_seconds / bw_in_bytes

                d.__diff_seconds = diff_seconds

                b = sc.tos(diff_bytes, "b", False, 3)
                k = sc.tos(diff_bytes, "k", True, 3)
                m = sc.tos(diff_bytes, "m", True, 3)
                g = sc.tos(diff_bytes, "g", True, 3)
                text = "%sB or %sK or %sM or %sG Bytes" % (b, k, m, g)
                d.__diff_size = text

                b = sc.tos(bw_in_bytes, "b", False, 3)
                k = sc.tos(bw_in_bytes, "k", True, 3)
                m = sc.tos(bw_in_bytes, "m", True, 3)
                g = sc.tos(bw_in_bytes, "g", True, 3)
                text = "%sB or %sK or %sM or %sG Bytes" % (b, k, m, g)
                d.__bandwidth = text

                d.ip = p.__ipaddr__
                d.loopback = p.__loopback__

                setp = g_setport_fr_ip.get(d.ip)
                if setp:
                    d.port_uid = setp.uid
                    d.if_name = setp.if_name

                out.append(d)
            except:
                continue

    mul = 10000000000 if asc else -10000000000
    return sorted(out, lambda x, y: int(mul * (x.utilization - y.utilization)))
Esempio n. 10
0
def docmd_ms_link_links():
    calldic = idic()
    klog.d(varfmt(calldic, "calldic"))
    return g_cmdmap.get(calldic.request, "default")(calldic)
Esempio n. 11
0
def get_equip_flow(uid, limit=None, dir="o"):
    flows = []

    show = {
        "_id": 0,
        "bps": 1,
        "bytes": 1,
        "time.log": 1,
        "time.last": 1,
        "time.first": 1,
        "addr.src": 1,
        "addr.dst": 1,
        "port.nexthop": 1,
        "port.output": 1
    }

    equip = getequip(uid)
    if not equip:
        klog.e("No such equip, %s" % str(uid))
        return {}

    limit = limit or "40"
    dir = dir or "io"

    ip = equip["ip_str"]

    orlis = []
    if 'i' in dir:
        orlis.append({"loopback.nxt": ip})
    if 'o' in dir:
        orlis.append({"loopback.cur": ip})

    match = {"$or": orlis}

    logs = db.logs.find(match).sort("bps",
                                    pymongo.DESCENDING).limit(int(limit))
    tmq = time.time()
    for log in logs:
        try:
            timediff = time.time() - log["time"]["log"]
            if timediff > conf.DB_LOG_AGE_SKIP:
                continue

            bps = log["bps"]
            src = log["addr"]["src"]
            dst = log["addr"]["dst"]

            sportip = log["port"]["output"]
            dportip = log["port"]["nexthop"]

            src_equip = equip_fr_port_ip(sportip) or equip_fr_port_ip(
                log["loopback"]["cur"])
            dst_equip = equip_fr_port_ip(dportip) or equip_fr_port_ip(
                log["loopback"]["nxt"])

            seid = src_equip.get("uid", "<Null:output:%s>" % sportip)
            seip = src_equip.get("ip_str", "<Null:output:%s>" % sportip)
            spip = sportip
            deid = dst_equip.get("uid", "<Null:nexthop:%s>" % dportip)
            deip = dst_equip.get("ip_str", "<Null:nexthop:%s>" % dportip)
            dpip = dportip

            if ip == log["loopback"]["cur"]:
                direct = "LOOP" if deid == uid else "OUT"
            else:
                direct = "IN"

            # XXX: vlink = db.vlinks.find_one({"sportip": sportip, "dportip":
            # dportip})
            sloopbackip = src_equip.get("ip_str", "<Null>")
            dloopbackip = dst_equip.get("ip_str", "<Null>")

            vlink = db.vlinks.find_one({
                "sloopbackip": sloopbackip,
                "dloopbackip": dloopbackip
            })
            vlink_uid = vlink["uid"] if vlink else "<Bad>"

            dirdic = {
                "dir": direct,
                "from": {
                    "equip_uid": seid,
                    "equip_ip": seip,
                    "port_ip": spip
                },
                "to": {
                    "equip_uid": deid,
                    "equip_ip": deip,
                    "port_ip": dpip
                }
            }

            last = log["time"]["last"]
            first = log["time"]["first"]

            _bps = "{:.3f}G or {:.3f}M or {:.3f}K".format(
                btog(bps), btom(bps), btok(bps))

            _flow = "(%s) >>> (%s)@(%s) >>> (%s)@(%s) >>> (%s)" % (
                src, spip, seip, dpip, deip, dst)
            flow = {
                "_flow": _flow,
                "_bps": _bps,
                "_dir": dirdic,
                "_bytes": log["bytes"],
                "bps": bps,
                "src": src,
                "dst": dst,
                "next_hop_uid": deid,
                "uid": vlink_uid,
                "_time": "%d - %d = %d" % (last, first, last - first)
            }
            flows.append(flow)
        except:
            klog.e(traceback.format_exc())
            klog.e("BAD LOG: ", varfmt(log, color=True))

    tmh = time.time()
    print "cost ...:", (tmh - tmq)
    return flows
Esempio n. 12
0
 def savedic(dic):
     klog.d("Saving: ", varfmt(dic, color=True))
     db.logs.replace_one({"_id": dic["_id"]}, dic.todic(), True)
Esempio n. 13
0
    def rec2dic(routerip, rec):
        try:
            src_addr = "%d.%d.%d.%d" % (rec.src_addr_a, rec.src_addr_b,
                                        rec.src_addr_c, rec.src_addr_d)
            nexthop = "%d.%d.%d.%d" % (rec.nexthop_a, rec.nexthop_b,
                                       rec.nexthop_c, rec.nexthop_d)
            dst_addr = "%d.%d.%d.%d" % (rec.dst_addr_a, rec.dst_addr_b,
                                        rec.dst_addr_c, rec.dst_addr_d)

            in_if = rec.in_if
            out_if = rec.out_if

            packets = rec.packets
            octets = rec.octets

            first = rec.first
            last = rec.last

            src_port = rec.src_port
            dst_port = rec.dst_port

            # tcp_flags = rec.tcp_flags
            # ip_proto = rec.ip_proto
            # tos = rec.tos
            # src_as = rec.src_as
            # dst_as = rec.dst_as
            # src_mask = rec.src_mask
            # dst_mask = rec.dst_mask

            # XXX: Skip if nextHop is 0.0.0.0
            if nexthop == "0.0.0.0":
                klog.w("Skip when nextHop is 0.0.0.0: (%s)" % str(rec))
                return None, "nextHop is 0.0.0.0"

            # XXX: Inf is the port send netflow package
            # routerip is not must the loopback address
            inf = spi.scget("", "ipaddr", routerip)
            if not inf:
                klog.e("ERR: Not found:", routerip)
                return None, "Loopback not exists"

            loopback = inf["__loopback__"]

            dic = DotDict()

            dic.loopback.cur = loopback

            #
            # Flow Info
            #
            dic.addr.src = src_addr
            dic.addr.dst = dst_addr

            dic.port.nexthop = nexthop
            tmp = spi.scget("", "ipaddr", nexthop)
            if tmp:
                dic.loopback.nxt = tmp["__loopback__"]
            else:
                dic.loopback.nxt = "<%s: NotFound>" % (nexthop)
                klog.e("NotFound: nexthop: ", nexthop)
                return None, "nexthop not exists"

            dic["bytes"] = octets

            tmp = spi.scget(loopback, "ifindex", out_if)
            if tmp:
                dic.port.output = tmp["__ipaddr__"]
            else:
                dic.port.output = "<%s@%s>" % (out_if, loopback)
                klog.e("NotFound: %s@%s" % (out_if, loopback))

            tmp = spi.scget(loopback, "ifindex", in_if)
            if tmp:
                dic.port.input = tmp["__ipaddr__"]
            else:
                dic.port.input = "<%s@%s>" % (in_if, loopback)
                klog.e("NotFound: %s@%s" % (in_if, loopback))

            dic["_id"] = "{loopback.cur}::{addr.src}_to_{addr.dst}".format(
                **dic)

            diff = last - first
            bps = 8.0 * int(dic["bytes"]) * conf.SAMPLE_RATE / diff * 1000
            dic["bps"] = int(bps)

            dic.time.last = last
            dic.time.first = first

            dic.time.log = time.time()

            return dic, None
        except:
            klog.e(traceback.format_exc())
            klog.e("Except rec:", varfmt(rec, color=True))
            return None, "Except: %s" % traceback.format_exc()
Esempio n. 14
0
 def update(self):
     '''Scan mango and generate ifindex number and port ipaddr'''
     for dic in db.equips.find({}, {"_id": 0, "ip_str": 1, "community": 1}):
         klog.d(varfmt(dic))
         DeferDo(self.load_each, dic)