Commit c58cb197 authored by 4ast's avatar 4ast

Merge pull request #519 from iovisor/bblanco_dev

Fixes for clang frontend bugs and misc
parents e0f2cd19 0845567a
...@@ -7,24 +7,31 @@ struct config { ...@@ -7,24 +7,31 @@ struct config {
}; };
BPF_TABLE("hash", int, struct config, conf, 1); BPF_TABLE("hash", int, struct config, conf, 1);
BPF_TABLE("hash", struct bpf_tunnel_key, int, tunkey2if, 1024); struct tunnel_key {
u32 tunnel_id;
u32 remote_ipv4;
};
BPF_TABLE("hash", struct tunnel_key, int, tunkey2if, 1024);
BPF_TABLE("hash", int, struct bpf_tunnel_key, if2tunkey, 1024); BPF_TABLE("hash", int, struct tunnel_key, if2tunkey, 1024);
// Handle packets from the encap device, demux into the dest tenant // Handle packets from the encap device, demux into the dest tenant
int handle_ingress(struct __sk_buff *skb) { int handle_ingress(struct __sk_buff *skb) {
struct bpf_tunnel_key tkey = {}; struct bpf_tunnel_key tkey = {};
struct tunnel_key key;
bpf_skb_get_tunnel_key(skb, &tkey, sizeof(tkey), 0); bpf_skb_get_tunnel_key(skb, &tkey, sizeof(tkey), 0);
int *ifindex = tunkey2if.lookup(&tkey); key.tunnel_id = tkey.tunnel_id;
key.remote_ipv4 = tkey.remote_ipv4;
int *ifindex = tunkey2if.lookup(&key);
if (ifindex) { if (ifindex) {
//bpf_trace_printk("ingress tunnel_id=%d remote_ip=%08x ifindex=%d\n", //bpf_trace_printk("ingress tunnel_id=%d remote_ip=%08x ifindex=%d\n",
// tkey.tunnel_id, tkey.remote_ipv4, *ifindex); // key.tunnel_id, key.remote_ipv4, *ifindex);
// mark from external // mark from external
skb->tc_index = 1; skb->tc_index = 1;
bpf_clone_redirect(skb, *ifindex, 1/*ingress*/); bpf_clone_redirect(skb, *ifindex, 1/*ingress*/);
} else { } else {
bpf_trace_printk("ingress invalid tunnel_id=%d\n", tkey.tunnel_id); bpf_trace_printk("ingress invalid tunnel_id=%d\n", key.tunnel_id);
} }
return 1; return 1;
...@@ -33,7 +40,8 @@ int handle_ingress(struct __sk_buff *skb) { ...@@ -33,7 +40,8 @@ int handle_ingress(struct __sk_buff *skb) {
// Handle packets from the tenant, mux into the encap device // Handle packets from the tenant, mux into the encap device
int handle_egress(struct __sk_buff *skb) { int handle_egress(struct __sk_buff *skb) {
int ifindex = skb->ifindex; int ifindex = skb->ifindex;
struct bpf_tunnel_key *tkey_p, tkey = {}; struct bpf_tunnel_key tkey = {};
struct tunnel_key *key_p;
int one = 1; int one = 1;
struct config *cfg = conf.lookup(&one); struct config *cfg = conf.lookup(&one);
...@@ -45,10 +53,10 @@ int handle_egress(struct __sk_buff *skb) { ...@@ -45,10 +53,10 @@ int handle_egress(struct __sk_buff *skb) {
return 1; return 1;
} }
tkey_p = if2tunkey.lookup(&ifindex); key_p = if2tunkey.lookup(&ifindex);
if (tkey_p) { if (key_p) {
tkey.tunnel_id = tkey_p->tunnel_id; tkey.tunnel_id = key_p->tunnel_id;
tkey.remote_ipv4 = tkey_p->remote_ipv4; tkey.remote_ipv4 = key_p->remote_ipv4;
bpf_skb_set_tunnel_key(skb, &tkey, sizeof(tkey), 0); bpf_skb_set_tunnel_key(skb, &tkey, sizeof(tkey), 0);
bpf_clone_redirect(skb, cfg->tunnel_ifindex, 0/*egress*/); bpf_clone_redirect(skb, cfg->tunnel_ifindex, 0/*egress*/);
} }
......
...@@ -47,7 +47,7 @@ def run(): ...@@ -47,7 +47,7 @@ def run():
ifc_gc.append(vx.ifname) ifc_gc.append(vx.ifname)
else: else:
with ipdb.create(ifname="vxlan0", kind="vxlan", vxlan_id=0, with ipdb.create(ifname="vxlan0", kind="vxlan", vxlan_id=0,
vxlan_link=ifc, vxlan_port=htons(4789), vxlan_link=ifc, vxlan_port=4789,
vxlan_collect_metadata=True, vxlan_collect_metadata=True,
vxlan_learning=False) as vx: vxlan_learning=False) as vx:
vx.up() vx.up()
...@@ -66,12 +66,14 @@ def run(): ...@@ -66,12 +66,14 @@ def run():
if i != host_id: if i != host_id:
v = ipdb.create(ifname="dummy%d%d" % (j , i), kind="dummy").up().commit() v = ipdb.create(ifname="dummy%d%d" % (j , i), kind="dummy").up().commit()
ipaddr = "172.16.1.%d" % (100 + i) ipaddr = "172.16.1.%d" % (100 + i)
tunkey2if_key = tunkey2if.Key(vni, IPAddress(ipaddr)) tunkey2if_key = tunkey2if.Key(vni)
tunkey2if_key.remote_ipv4 = IPAddress(ipaddr)
tunkey2if_leaf = tunkey2if.Leaf(v.index) tunkey2if_leaf = tunkey2if.Leaf(v.index)
tunkey2if[tunkey2if_key] = tunkey2if_leaf tunkey2if[tunkey2if_key] = tunkey2if_leaf
if2tunkey_key = if2tunkey.Key(v.index) if2tunkey_key = if2tunkey.Key(v.index)
if2tunkey_leaf = if2tunkey.Leaf(vni, IPAddress(ipaddr)) if2tunkey_leaf = if2tunkey.Leaf(vni)
if2tunkey_leaf.remote_ipv4 = IPAddress(ipaddr)
if2tunkey[if2tunkey_key] = if2tunkey_leaf if2tunkey[if2tunkey_key] = if2tunkey_leaf
ipr.tc("add", "sfq", v.index, "1:") ipr.tc("add", "sfq", v.index, "1:")
...@@ -124,7 +126,7 @@ def run(): ...@@ -124,7 +126,7 @@ def run():
while retry < 0: while retry < 0:
check = Popen(["ip", "addr", "show", "br%d" % j], stdout=PIPE, stderr=PIPE) check = Popen(["ip", "addr", "show", "br%d" % j], stdout=PIPE, stderr=PIPE)
out = check.stdout.read() out = check.stdout.read()
checkip = "99.1.%d" % j checkip = b"99.1.%d" % j
retry = out.find(checkip) retry = out.find(checkip)
try: try:
......
...@@ -156,7 +156,7 @@ static void parse_type(IRBuilder<> &B, vector<Value *> *args, string *fmt, ...@@ -156,7 +156,7 @@ static void parse_type(IRBuilder<> &B, vector<Value *> *args, string *fmt,
*fmt += " "; *fmt += " ";
} }
*fmt += "]"; *fmt += "]";
} else if (PointerType *pt = dyn_cast<PointerType>(type)) { } else if (isa<PointerType>(type)) {
*fmt += "0xl"; *fmt += "0xl";
if (is_writer) if (is_writer)
*fmt += "x"; *fmt += "x";
......
...@@ -73,6 +73,12 @@ bool BMapDeclVisitor::VisitRecordDecl(RecordDecl *D) { ...@@ -73,6 +73,12 @@ bool BMapDeclVisitor::VisitRecordDecl(RecordDecl *D) {
result_ += D->getName(); result_ += D->getName();
result_ += "\", ["; result_ += "\", [";
for (auto F : D->getDefinition()->fields()) { for (auto F : D->getDefinition()->fields()) {
if (F->isAnonymousStructOrUnion()) {
if (const RecordType *R = dyn_cast<RecordType>(F->getType()))
TraverseDecl(R->getDecl());
result_ += ", ";
continue;
}
result_ += "["; result_ += "[";
TraverseDecl(F); TraverseDecl(F);
if (const ConstantArrayType *T = dyn_cast<ConstantArrayType>(F->getType())) if (const ConstantArrayType *T = dyn_cast<ConstantArrayType>(F->getType()))
......
...@@ -72,7 +72,7 @@ class KernelSymbolCache(object): ...@@ -72,7 +72,7 @@ class KernelSymbolCache(object):
psym = ct.pointer(sym) psym = ct.pointer(sym)
if lib.bcc_symcache_resolve(self.cache, addr, psym) < 0: if lib.bcc_symcache_resolve(self.cache, addr, psym) < 0:
return "[unknown]", 0 return "[unknown]", 0
return sym.name, sym.offset return sym.name.decode(), sym.offset
def resolve_name(self, name): def resolve_name(self, name):
addr = ct.c_ulonglong() addr = ct.c_ulonglong()
...@@ -250,6 +250,7 @@ class BPF(object): ...@@ -250,6 +250,7 @@ class BPF(object):
def _decode_table_type(desc): def _decode_table_type(desc):
if isinstance(desc, basestring): if isinstance(desc, basestring):
return BPF.str2ctype[desc] return BPF.str2ctype[desc]
anon = []
fields = [] fields = []
for t in desc[1]: for t in desc[1]:
if len(t) == 2: if len(t) == 2:
...@@ -257,8 +258,17 @@ class BPF(object): ...@@ -257,8 +258,17 @@ class BPF(object):
elif len(t) == 3: elif len(t) == 3:
if isinstance(t[2], list): if isinstance(t[2], list):
fields.append((t[0], BPF._decode_table_type(t[1]) * t[2][0])) fields.append((t[0], BPF._decode_table_type(t[1]) * t[2][0]))
else: elif isinstance(t[2], int):
fields.append((t[0], BPF._decode_table_type(t[1]), t[2])) fields.append((t[0], BPF._decode_table_type(t[1]), t[2]))
elif isinstance(t[2], basestring) and (
t[2] == u"union" or t[2] == u"struct"):
name = t[0]
if name == "":
name = "__anon%d" % len(anon)
anon.append(name)
fields.append((name, BPF._decode_table_type(t)))
else:
raise Exception("Failed to decode type %s" % str(t))
else: else:
raise Exception("Failed to decode type %s" % str(t)) raise Exception("Failed to decode type %s" % str(t))
base = ct.Structure base = ct.Structure
...@@ -267,7 +277,8 @@ class BPF(object): ...@@ -267,7 +277,8 @@ class BPF(object):
base = ct.Union base = ct.Union
elif desc[2] == u"struct": elif desc[2] == u"struct":
base = ct.Structure base = ct.Structure
cls = type(str(desc[0]), (base,), dict(_fields_=fields)) cls = type(str(desc[0]), (base,), dict(_anonymous_=anon,
_fields_=fields))
return cls return cls
def get_table(self, name, keytype=None, leaftype=None, reducer=None): def get_table(self, name, keytype=None, leaftype=None, reducer=None):
...@@ -426,11 +437,12 @@ class BPF(object): ...@@ -426,11 +437,12 @@ class BPF(object):
def _check_path_symbol(cls, module, symname, addr): def _check_path_symbol(cls, module, symname, addr):
sym = bcc_symbol() sym = bcc_symbol()
psym = ct.pointer(sym) psym = ct.pointer(sym)
if lib.bcc_resolve_symname(module, symname, addr or 0x0, psym) < 0: if lib.bcc_resolve_symname(module.encode("ascii"),
symname.encode("ascii"), addr or 0x0, psym) < 0:
if not sym.module: if not sym.module:
raise Exception("could not find library %s" % module) raise Exception("could not find library %s" % module)
raise Exception("could not determine address of symbol %s" % symname) raise Exception("could not determine address of symbol %s" % symname)
return sym.module, sym.offset return sym.module.decode(), sym.offset
@staticmethod @staticmethod
def find_library(libname): def find_library(libname):
......
...@@ -320,5 +320,13 @@ BPF_TABLE("array", int, union emptyu, t3, 1); ...@@ -320,5 +320,13 @@ BPF_TABLE("array", int, union emptyu, t3, 1);
with self.assertRaises(Exception): with self.assertRaises(Exception):
b = BPF(text="""int failure(void *ctx) { if (); return 0; }""") b = BPF(text="""int failure(void *ctx) { if (); return 0; }""")
def test_nested_union(self):
text = """
BPF_TABLE("hash", struct bpf_tunnel_key, int, t1, 1);
"""
b = BPF(text=text)
t1 = b["t1"]
print(t1.Key().remote_ipv4)
if __name__ == "__main__": if __name__ == "__main__":
main() main()
...@@ -12,7 +12,7 @@ class TestHistogram(TestCase): ...@@ -12,7 +12,7 @@ class TestHistogram(TestCase):
def test_simple(self): def test_simple(self):
b = BPF(text=""" b = BPF(text="""
#include <uapi/linux/ptrace.h> #include <uapi/linux/ptrace.h>
#include <linux/bpf.h> struct bpf_map;
BPF_HISTOGRAM(hist1); BPF_HISTOGRAM(hist1);
BPF_HASH(stub); BPF_HASH(stub);
int kprobe__htab_map_delete_elem(struct pt_regs *ctx, struct bpf_map *map, u64 *k) { int kprobe__htab_map_delete_elem(struct pt_regs *ctx, struct bpf_map *map, u64 *k) {
...@@ -35,7 +35,7 @@ int kprobe__htab_map_delete_elem(struct pt_regs *ctx, struct bpf_map *map, u64 * ...@@ -35,7 +35,7 @@ int kprobe__htab_map_delete_elem(struct pt_regs *ctx, struct bpf_map *map, u64 *
def test_struct(self): def test_struct(self):
b = BPF(text=""" b = BPF(text="""
#include <uapi/linux/ptrace.h> #include <uapi/linux/ptrace.h>
#include <linux/bpf.h> struct bpf_map;
typedef struct { void *map; u64 slot; } Key; typedef struct { void *map; u64 slot; } Key;
BPF_HISTOGRAM(hist1, Key, 1024); BPF_HISTOGRAM(hist1, Key, 1024);
BPF_HASH(stub1); BPF_HASH(stub1);
......
...@@ -47,7 +47,7 @@ int kprobe__htab_map_lookup_elem(struct pt_regs *ctx, struct bpf_map *map, u64 * ...@@ -47,7 +47,7 @@ int kprobe__htab_map_lookup_elem(struct pt_regs *ctx, struct bpf_map *map, u64 *
stackid = stack_entries[k] stackid = stack_entries[k]
self.assertIsNotNone(stackid) self.assertIsNotNone(stackid)
stack = stack_traces[stackid].ip stack = stack_traces[stackid].ip
self.assertEqual(b.ksym(stack[0]), "htab_map_lookup_elem") self.assertEqual(b.ksym(stack[0]), b"htab_map_lookup_elem")
if __name__ == "__main__": if __name__ == "__main__":
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment