• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/python
2# Copyright (c) PLUMgrid, Inc.
3# Licensed under the Apache License, Version 2.0 (the "License")
4
5from bcc import BPF
6from ctypes import c_uint, c_int, c_ulonglong, Structure
7import json
8from netaddr import IPAddress
9from os import rename
10from pyroute2 import IPRoute, NetNS, IPDB, NSPopen
11import sys
12from time import sleep
13
14ipr = IPRoute()
15ipdb = IPDB(nl=ipr)
16
17b = BPF(src_file="monitor.c", debug=0)
18ingress_fn = b.load_func("handle_ingress", BPF.SCHED_CLS)
19egress_fn = b.load_func("handle_egress", BPF.SCHED_CLS)
20outer_fn = b.load_func("handle_outer", BPF.SCHED_CLS)
21inner_fn = b.load_func("handle_inner", BPF.SCHED_CLS)
22stats = b.get_table("stats")
23# using jump table for inner and outer packet split
24parser = b.get_table("parser")
25parser[c_int(1)] = c_int(outer_fn.fd)
26parser[c_int(2)] = c_int(inner_fn.fd)
27
28ifc = ipdb.interfaces.eth0
29
30ipr.tc("add", "ingress", ifc.index, "ffff:")
31ipr.tc("add-filter", "bpf", ifc.index, ":1", fd=ingress_fn.fd,
32       name=ingress_fn.name, parent="ffff:", action="ok", classid=1)
33ipr.tc("add", "sfq", ifc.index, "1:")
34ipr.tc("add-filter", "bpf", ifc.index, ":1", fd=egress_fn.fd,
35       name=egress_fn.name, parent="1:", action="ok", classid=1)
36
37def stats2json(k, v):
38    return {
39        "vni": int(k.vni),
40        "outer_sip": str(IPAddress(k.outer_sip)),
41        "outer_dip": str(IPAddress(k.outer_dip)),
42        "inner_sip": str(IPAddress(k.inner_sip)),
43        "inner_dip": str(IPAddress(k.inner_dip)),
44        "tx_pkts": v.tx_pkts, "tx_bytes": v.tx_bytes,
45        "rx_pkts": v.rx_pkts, "rx_bytes": v.rx_bytes,
46    }
47
48def delta_stats(v, oldv):
49    return stats.Leaf(v.tx_pkts - oldv.tx_pkts, v.rx_pkts - oldv.rx_pkts,
50                      v.tx_bytes - oldv.tx_bytes, v.rx_bytes - oldv.rx_bytes)
51def key2str(k):
52    return "%s,%s,%d,%s,%s" % (IPAddress(k.outer_sip), IPAddress(k.outer_dip), k.vni,
53                               IPAddress(k.inner_sip), IPAddress(k.inner_dip))
54
55prev = {}
56
57while True:
58    result_total = []
59    result_delta = []
60    tmp = {}
61    # compute both the total and last-N-seconds statistics
62    for k, v in stats.items():
63        # subtract the previous totals from the current, or 0 if none exists
64        v2 = delta_stats(v, prev.get(key2str(k), stats.Leaf(0, 0, 0, 0)))
65        if v2.tx_pkts != 0 or v2.rx_pkts != 0:
66            result_delta.append(stats2json(k, v2))
67        tmp[key2str(k)] = v
68        result_total.append(stats2json(k, v))
69
70    prev = tmp
71
72    with open("./chord-transitions/data/tunnel.json.new", "w") as f:
73        json.dump(result_total, f)
74    rename("./chord-transitions/data/tunnel.json.new", "./chord-transitions/data/tunnel.json")
75    with open("./chord-transitions/data/tunnel-delta.json.new", "w") as f:
76        json.dump(result_delta, f)
77    rename("./chord-transitions/data/tunnel-delta.json.new", "./chord-transitions/data/tunnel-delta.json")
78    sleep(5)
79ipdb.release()
80
81