| 1289 | self._cbs[0] = fn |
| 1290 | |
| 1291 | class QueueStack: |
| 1292 | # Flag for map.push |
| 1293 | BPF_EXIST = 2 |
| 1294 | |
| 1295 | def __init__(self, bpf, map_id, map_fd, leaftype): |
| 1296 | self.bpf = bpf |
| 1297 | self.map_id = map_id |
| 1298 | self.map_fd = map_fd |
| 1299 | self.Leaf = leaftype |
| 1300 | self.ttype = lib.bpf_table_type_id(self.bpf.module, self.map_id) |
| 1301 | self.flags = lib.bpf_table_flags_id(self.bpf.module, self.map_id) |
| 1302 | self.max_entries = int(lib.bpf_table_max_entries_id(self.bpf.module, |
| 1303 | self.map_id)) |
| 1304 | |
| 1305 | def leaf_sprintf(self, leaf): |
| 1306 | buf = ct.create_string_buffer(ct.sizeof(self.Leaf) * 8) |
| 1307 | res = lib.bpf_table_leaf_snprintf(self.bpf.module, self.map_id, buf, |
| 1308 | len(buf), ct.byref(leaf)) |
| 1309 | if res < 0: |
| 1310 | raise Exception("Could not printf leaf") |
| 1311 | return buf.value |
| 1312 | |
| 1313 | def leaf_scanf(self, leaf_str): |
| 1314 | leaf = self.Leaf() |
| 1315 | res = lib.bpf_table_leaf_sscanf(self.bpf.module, self.map_id, leaf_str, |
| 1316 | ct.byref(leaf)) |
| 1317 | if res < 0: |
| 1318 | raise Exception("Could not scanf leaf") |
| 1319 | return leaf |
| 1320 | |
| 1321 | def push(self, leaf, flags=0): |
| 1322 | res = lib.bpf_update_elem(self.map_fd, None, ct.byref(leaf), flags) |
| 1323 | if res < 0: |
| 1324 | errstr = os.strerror(ct.get_errno()) |
| 1325 | raise Exception("Could not push to table: %s" % errstr) |
| 1326 | |
| 1327 | def pop(self): |
| 1328 | leaf = self.Leaf() |
| 1329 | res = lib.bpf_lookup_and_delete(self.map_fd, None, ct.byref(leaf)) |
| 1330 | if res < 0: |
| 1331 | raise KeyError("Could not pop from table") |
| 1332 | return leaf |
| 1333 | |
| 1334 | def peek(self): |
| 1335 | leaf = self.Leaf() |
| 1336 | res = lib.bpf_lookup_elem(self.map_fd, None, ct.byref(leaf)) |
| 1337 | if res < 0: |
| 1338 | raise KeyError("Could not peek table") |
| 1339 | return leaf |
| 1340 | |
| 1341 | def itervalues(self): |
| 1342 | # to avoid infinite loop, set maximum pops to max_entries |
| 1343 | cnt = self.max_entries |
| 1344 | while cnt: |
| 1345 | try: |
| 1346 | yield(self.pop()) |
| 1347 | cnt -= 1 |
| 1348 | except KeyError: |