|
11 | 11 | import time |
12 | 12 | import logging |
13 | 13 | import signal |
| 14 | +import threading |
14 | 15 |
|
15 | 16 | from enum import Enum |
16 | 17 | from _rtrlib import ffi, lib |
17 | 18 |
|
18 | | -import six |
19 | 19 | import rtrlib.callbacks as callbacks |
20 | | - |
21 | | -from .util import to_bytestr, is_integer, is_string, ip_str_to_addr |
| 20 | +import rtrlib.records as records |
| 21 | + |
| 22 | +from .util import (to_bytestr, |
| 23 | + is_integer, |
| 24 | + is_string, |
| 25 | + ip_str_to_addr, |
| 26 | + CallbackGenerator |
| 27 | + ) |
22 | 28 | from .exceptions import RTRInitError, PFXException, SyncTimeout |
23 | 29 |
|
24 | 30 |
|
@@ -208,6 +214,76 @@ def validate(self, asn, prefix, mask_len): |
208 | 214 |
|
209 | 215 | return PfxvState(result[0]) |
210 | 216 |
|
| 217 | + def for_each_ipv4_record(self, callback, data): |
| 218 | + r""" |
| 219 | + Iterate over all ipv4 records of the pfx table. |
| 220 | +
|
| 221 | + callback must take two arguments, the pfx_record and the data object. |
| 222 | +
|
| 223 | + For a more pythonic alternative see :py:meth:`ipv4_records` |
| 224 | +
|
| 225 | + :param callable callback: called for every record in the pfx table |
| 226 | + :param object data: arbitrary data object \ |
| 227 | + that is passed to the callback function |
| 228 | + """ |
| 229 | + data_handle = ffi.new_handle((callback, data)) |
| 230 | + |
| 231 | + lib.rtr_mgr_for_each_ipv4_record( |
| 232 | + self.rtr_manager_config, |
| 233 | + lib.pfx_table_callback, |
| 234 | + data_handle |
| 235 | + ) |
| 236 | + |
| 237 | + def ipv4_records(self): |
| 238 | + r""" |
| 239 | + Return iterator over all ipv4 records in the pfx table. |
| 240 | +
|
| 241 | + This iterator utilises threads to execute retrieve the records. \ |
| 242 | + If that is a problem for you take a look at \ |
| 243 | + :py:meth:`for_each_ipv4_record`. |
| 244 | + """ |
| 245 | + def callback(record, data): |
| 246 | + LOG.debug('Putting "%s" in queue', record) |
| 247 | + data.put_nowait(records.copy_pfx_record(record)) |
| 248 | + |
| 249 | + generator = CallbackGenerator(self.for_each_ipv4_record, callback) |
| 250 | + return generator |
| 251 | + |
| 252 | + def for_each_ipv6_record(self, callback, data): |
| 253 | + r""" |
| 254 | + Iterate over all ipv6 records of the pfx table. |
| 255 | +
|
| 256 | + callback must take two arguments, the pfx_record and the data object. |
| 257 | +
|
| 258 | + For a more pythonic alternative see :py:meth:`ipv6_records` |
| 259 | +
|
| 260 | + :param callable callback: called for every record in the pfx table |
| 261 | + :param object data: arbitrary data object \ |
| 262 | + that is passed to the callback function |
| 263 | + """ |
| 264 | + data_handle = ffi.new_handle((callback, data)) |
| 265 | + |
| 266 | + lib.rtr_mgr_for_each_ipv6_record( |
| 267 | + self.rtr_manager_config, |
| 268 | + lib.pfx_table_callback, |
| 269 | + data_handle |
| 270 | + ) |
| 271 | + |
| 272 | + def ipv6_records(self): |
| 273 | + r""" |
| 274 | + Return iterator over all ipv6 records in the pfx table. |
| 275 | +
|
| 276 | + This iterator utilises threads to execute retrieve the records. \ |
| 277 | + If that is a problem for you take a look at \ |
| 278 | + :py:meth:`for_each_ipv6_record`. |
| 279 | + """ |
| 280 | + def callback(record, data): |
| 281 | + LOG.debug('Putting "%s" in queue', record) |
| 282 | + data.put_nowait(records.copy_pfx_record(record)) |
| 283 | + |
| 284 | + generator = CallbackGenerator(self.for_each_ipv6_record, callback) |
| 285 | + return generator |
| 286 | + |
211 | 287 |
|
212 | 288 | class PfxvState(Enum): |
213 | 289 | """ |
|
0 commit comments