Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ignore None values in kwargs #1246

Closed
ffourcot opened this issue Jan 14, 2025 · 4 comments
Closed

Ignore None values in kwargs #1246

ffourcot opened this issue Jan 14, 2025 · 4 comments

Comments

@ffourcot
Copy link
Collaborator

Hello,

We have a regression on code based on previous pyroute2 version. It looks like parameters given in kwargs are coded, even for None values.

I used strict_mode / ext_ack for a better error message from the kernel, but they are not mandatory to reproduce:

# this one is working
In [15]: IPRoute(ext_ack=True, strict_check=True).rule('add', table=10, priority=32000)
Out[15]: 
[{'attrs': [('NLMSGERR_ATTR_UNUSED', None)],
  'header': {'length': 36,
   'type': 2,
   'flags': 256,
   'sequence_number': 255,
   'pid': 3199518433,
   'error': None,
   'target': 'localhost',
   'stats': Stats(qsize=0, delta=0, delay=0)},
  'error': 0,
  'event': 'NLMSG_ERROR'}]

# adding src=None breaks it
In [16]: IPRoute(ext_ack=True, strict_check=True).rule('add', table=10, priority=32001, src=None)
---------------------------------------------------------------------------
NetlinkError                              Traceback (most recent call last)
Cell In [16], line 1
----> 1 IPRoute(ext_ack=True, strict_check=True).rule('add', table=10, priority=32001, src=None)

File pyroute2/pyroute2/iproute/linux.py:2493, in IPRoute.__getattr__.<locals>.synchronize_generic(*argv, **kwarg)
   2491 else:
   2492     task = collect_op
-> 2493 return self.event_loop.run_until_complete(task())

File /usr/lib/python3.11/asyncio/base_events.py:653, in BaseEventLoop.run_until_complete(self, future)
    650 if not future.done():
    651     raise RuntimeError('Event loop stopped before Future completed.')
--> 653 return future.result()

File pyroute2/pyroute2/iproute/linux.py:2483, in IPRoute.__getattr__.<locals>.synchronize_generic.<locals>.collect_op()
   2482 async def collect_op():
-> 2483     return await symbol(*argv, **kwarg)

File pyroute2/pyroute2/iproute/linux.py:2337, in RTNL_API.rule(self, command, **kwarg)
   2335 if command == 'dump':
   2336     return request.response()
-> 2337 return [x async for x in request.response()]

File pyroute2/pyroute2/iproute/linux.py:2337, in <listcomp>(.0)
   2335 if command == 'dump':
   2336     return request.response()
-> 2337 return [x async for x in request.response()]

File pyroute2/pyroute2/netlink/nlsocket.py:566, in NetlinkRequest.response(self)
    565 async def response(self):
--> 566     async for msg in self.sock.get(
    567         msg_seq=self.msg_seq,
    568         terminate=self.terminate,
    569         callback=self.callback,
    570     ):
    571         if self.dump_filter is not None and not self.match_one_message(
    572             self.dump_filter, msg
    573         ):
    574             continue

File pyroute2/netlink/core.py:468, in AsyncCoreSocket.get(self, msg_seq, terminate, callback, noraise)
    466         enough = True
    467 if not noraise and error:
--> 468     raise error

NetlinkError: (22, 'Invalid source address')

We have a lot of code assuming that None values are ignored in NLA encoding, should we update our code to use recent pyroute2 version or can you ignore this kind of values again?

Thanks

@svinota
Copy link
Owner

svinota commented Jan 14, 2025

I will fix that to keep the API compatible, sure thing.

Thanks for notifying.

@svinota svinota added the bug label Jan 14, 2025
@svinota
Copy link
Owner

svinota commented Jan 21, 2025

So look, what do we have in pre-0.9.1 as for now, line 474:

if request_filter is not None:
for field in msg.fields:
msg[field[0]] = request_filter.get_value(
field[0], default=0, mode='field'
)
# attach NLAs
for key, value in request_filter.items():
nla = type(msg).name2nla(key)
if msg.valid_nla(nla) and value is not None:
msg['attrs'].append([nla, value])
# extend with custom NLAs
if 'attrs' in request_filter:
msg['attrs'].extend(request_filter['attrs'])

It is not the best solution, some NLAs are in fact None as they are flags, but we solve that.

Regarding the issue above: it was triggered by another, but related issue, that set src_len when src was in the request, even when it's None.

The fix is on the way, thanks for reporting!

svinota added a commit that referenced this issue Jan 21, 2025
Don't set src/dst len if src/dst absent or is None

Bug-Url: #1246
svinota added a commit that referenced this issue Jan 21, 2025
Don't set src/dst len if src/dst absent or is None

Bug-Url: #1246
svinota added a commit that referenced this issue Jan 21, 2025
Don't set src/dst len if src/dst absent or is None

Bug-Url: #1246
svinota added a commit that referenced this issue Jan 21, 2025
requests: fix rule (src|dst)(_len)

Bug-Url: #1252
Bug-Url: #1246
@svinota
Copy link
Owner

svinota commented Jan 21, 2025

Pls check now, should be fixed in the master branch.

@ffourcot
Copy link
Collaborator Author

Tested and validated, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants