blob: 6124dff884ecdf5387948ba56643f6c6b5441211 [file] [log] [blame]
# 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(SocketConfig, 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 <uapi/linux/bpf.h>
#include <uapi/linux/if_ether.h>
#include <uapi/linux/if_packet.h>
#include <uapi/linux/ip.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#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 <uapi/linux/bpf.h>
#include <uapi/linux/if_ether.h>
#include <uapi/linux/if_packet.h>
#include <uapi/linux/ip.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/pkt_cls.h>
"""
def serializeLicense(self, serializer, licenseString):
assert isinstance(serializer, ProgramSerializer)
pass