# Copyright (c) Barefoot Networks, Inc. # Licensed under the Apache License, Version 2.0 (the "License") from programSerializer import ProgramSerializer # abstraction for isolating target-specific features # Base class for representing target-specific configuration class TargetConfig(object): def __init__(self, target): self.targetName = target def getIncludes(self): return "" def serializeLookup(self, serializer, tableName, key, value): serializer.appendFormat("{0} = bpf_map_lookup_elem(&{1}, &{2});", value, tableName, key) def serializeUpdate(self, serializer, tableName, key, value): serializer.appendFormat( "bpf_map_update_elem(&{0}, &{1}, &{2}, BPF_ANY);", tableName, key, value) def serializeLicense(self, serializer, licenseString): assert isinstance(serializer, ProgramSerializer) serializer.emitIndent() serializer.appendFormat( "char _license[] {0}(\"license\") = \"{1}\";", self.config.section, licenseString) serializer.newline() def serializeCodeSection(self, serializer): assert isinstance(serializer, ProgramSerializer) serializer.appendFormat("{0}(\"{1}\")", self.section, self.entrySection) def serializeTableDeclaration(self, serializer, tableName, isHash, keyType, valueType, size): assert isinstance(serializer, ProgramSerializer) assert isinstance(tableName, str) assert isinstance(isHash, bool) assert isinstance(keyType, str) assert isinstance(valueType, str) assert isinstance(size, int) serializer.emitIndent() serializer.appendFormat("struct {0} {1}(\"maps\") {2} = ", self.tableName, self.section, tableName) serializer.blockStart() serializer.emitIndent() serializer.append(".type = ") if isHash: serializer.appendLine("BPF_MAP_TYPE_HASH,") else: serializer.appendLine("BPF_MAP_TYPE_ARRAY,") serializer.emitIndent() serializer.appendFormat(".{0} = sizeof(struct {1}), ", self.tableKeyAttribute, keyType) serializer.newline() serializer.emitIndent() serializer.appendFormat(".{0} = sizeof(struct {1}), ", self.tableValueAttribute, valueType) serializer.newline() serializer.emitIndent() serializer.appendFormat(".{0} = {1}, ", self.tableSizeAttribute, size) serializer.newline() serializer.blockEnd(False) serializer.endOfStatement(True) def generateDword(self, serializer): serializer.appendFormat( "static inline {0}64 load_dword(void *skb, {0}64 off)", self.uprefix) serializer.newline() serializer.blockStart() serializer.emitIndent() serializer.appendFormat( ("return (({0}64)load_word(skb, off) << 32) | " + "load_word(skb, off + 4);"), self.uprefix) serializer.newline() serializer.blockEnd(True) # Represents a target that is compiled within the kernel # source tree samples folder and which attaches to a socket class KernelSamplesConfig(TargetConfig): def __init__(self): super(TargetConfig, self).__init__("Socket") self.entrySection = "socket1" self.section = "SEC" self.uprefix = "u" self.iprefix = "i" self.tableKeyAttribute = "key_size" self.tableValueAttribute = "value_size" self.tableSizeAttribute = "max_entries" self.tableName = "bpf_map_def" self.postamble = "" def getIncludes(self): return """ #include #include #include #include #include #include #include "bpf_helpers.h" """ # Represents a target compiled by bcc that uses the TC class BccConfig(TargetConfig): def __init__(self): super(BccConfig, self).__init__("BCC") self.uprefix = "u" self.iprefix = "i" self.postamble = "" def serializeTableDeclaration(self, serializer, tableName, isHash, keyType, valueType, size): assert isinstance(serializer, ProgramSerializer) assert isinstance(tableName, str) assert isinstance(isHash, bool) assert isinstance(keyType, str) assert isinstance(valueType, str) assert isinstance(size, int) serializer.emitIndent() if isHash: kind = "hash" else: kind = "array" serializer.appendFormat( "BPF_TABLE(\"{0}\", {1}, {2}, {3}, {4});", kind, keyType, valueType, tableName, size) serializer.newline() def serializeLookup(self, serializer, tableName, key, value): serializer.appendFormat("{0} = {1}.lookup(&{2});", value, tableName, key) def serializeUpdate(self, serializer, tableName, key, value): serializer.appendFormat("{0}.update(&{1}, &{2});", tableName, key, value) def generateDword(self, serializer): pass def serializeCodeSection(self, serializer): pass def getIncludes(self): return """ #include #include #include #include #include #include #include """ def serializeLicense(self, serializer, licenseString): assert isinstance(serializer, ProgramSerializer) pass