-
Notifications
You must be signed in to change notification settings - Fork 316
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
lib/route: add initial support for br_vlan global_opts module #407
Draft
ronand-atl
wants to merge
3
commits into
thom311:main
Choose a base branch
from
ronand-atl:feat-br-vlan-global-opts
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
/* SPDX-License-Identifier: LGPL-2.1-only */ | ||
|
||
#ifndef NETLINK_BR_VLAN_GLOBAL_OPTS_H_ | ||
#define NETLINK_BR_VLAN_GLOBAL_OPTS_H_ | ||
|
||
#include <netlink/netlink.h> | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
struct rtnl_br_vlan_gopts; | ||
struct rtnl_br_vlan_gopts_entry; | ||
|
||
struct rtnl_br_vlan_gopts *rtnl_br_vlan_gopts_alloc(void); | ||
void rtnl_br_vlan_gopts_put(struct rtnl_br_vlan_gopts *gopts); | ||
|
||
struct rtnl_br_vlan_gopts_entry *rtnl_br_vlan_gopts_entry_alloc(void); | ||
void rtnl_br_vlan_gopts_entry_free(struct rtnl_br_vlan_gopts_entry *entry); | ||
struct rtnl_br_vlan_gopts_entry * | ||
rtnl_br_vlan_gopts_entry_clone(const struct rtnl_br_vlan_gopts_entry *entry); | ||
|
||
int rtnl_br_vlan_gopts_build_modify_request( | ||
const struct rtnl_br_vlan_gopts *gopts, struct nl_msg **result); | ||
|
||
int rtnl_br_vlan_gopts_modify(struct nl_sock *sk, | ||
const struct rtnl_br_vlan_gopts *gopts); | ||
|
||
int rtnl_br_vlan_gopts_build_get_request(uint32_t ifindex, | ||
struct nl_msg **result); | ||
|
||
int rtnl_br_vlan_gopts_get_kernel(struct nl_sock *sk, uint32_t ifindex, | ||
struct rtnl_br_vlan_gopts **result); | ||
|
||
int rtnl_br_vlan_gopts_set_ifindex(struct rtnl_br_vlan_gopts *gopts, | ||
uint32_t value); | ||
int rtnl_br_vlan_gopts_get_ifindex(const struct rtnl_br_vlan_gopts *gopts, | ||
uint32_t *out); | ||
|
||
int rtnl_br_vlan_gopts_set_entry(struct rtnl_br_vlan_gopts *gopts, | ||
const struct rtnl_br_vlan_gopts_entry *entry); | ||
int rtnl_br_vlan_gopts_set_entry_range( | ||
struct rtnl_br_vlan_gopts *gopts, | ||
const struct rtnl_br_vlan_gopts_entry *entry, uint16_t vid_end); | ||
|
||
int rtnl_br_vlan_gopts_unset_entry(struct rtnl_br_vlan_gopts *gopts, | ||
uint16_t vid); | ||
int rtnl_br_vlan_gopts_unset_entry_range(struct rtnl_br_vlan_gopts *gopts, | ||
uint16_t vid_start, uint16_t vid_end); | ||
|
||
int rtnl_br_vlan_gopts_get_entry(const struct rtnl_br_vlan_gopts *gopts, | ||
uint16_t vid, | ||
struct rtnl_br_vlan_gopts_entry **out); | ||
|
||
int rtnl_br_vlan_gopts_foreach_gopts_entry( | ||
const struct rtnl_br_vlan_gopts *gopts, | ||
void (*cb)(struct rtnl_br_vlan_gopts_entry *entry, void *arg), | ||
void *arg); | ||
|
||
int rtnl_br_vlan_gopts_entry_set_vid(struct rtnl_br_vlan_gopts_entry *entry, | ||
uint16_t value); | ||
int rtnl_br_vlan_gopts_entry_get_vid( | ||
const struct rtnl_br_vlan_gopts_entry *entry, uint16_t *out); | ||
|
||
int rtnl_br_vlan_gopts_entry_set_mcast_snooping( | ||
struct rtnl_br_vlan_gopts_entry *entry, uint8_t value); | ||
int rtnl_br_vlan_gopts_entry_unset_mcast_snooping( | ||
struct rtnl_br_vlan_gopts_entry *entry); | ||
int rtnl_br_vlan_gopts_entry_get_mcast_snooping( | ||
const struct rtnl_br_vlan_gopts_entry *entry, uint8_t *out); | ||
|
||
int rtnl_br_vlan_gopts_entry_set_mcast_igmp_version( | ||
struct rtnl_br_vlan_gopts_entry *entry, uint8_t value); | ||
int rtnl_br_vlan_gopts_entry_unset_mcast_igmp_version( | ||
struct rtnl_br_vlan_gopts_entry *entry); | ||
int rtnl_br_vlan_gopts_entry_get_mcast_igmp_version( | ||
const struct rtnl_br_vlan_gopts_entry *entry, uint8_t *out); | ||
|
||
int rtnl_br_vlan_gopts_entry_set_mcast_mld_version( | ||
struct rtnl_br_vlan_gopts_entry *entry, uint8_t value); | ||
int rtnl_br_vlan_gopts_entry_unset_mcast_mld_version( | ||
struct rtnl_br_vlan_gopts_entry *entry); | ||
int rtnl_br_vlan_gopts_entry_get_mcast_mld_version( | ||
const struct rtnl_br_vlan_gopts_entry *entry, uint8_t *out); | ||
|
||
int rtnl_br_vlan_gopts_entry_set_mcast_last_member_cnt( | ||
struct rtnl_br_vlan_gopts_entry *entry, uint32_t value); | ||
int rtnl_br_vlan_gopts_entry_unset_mcast_last_member_cnt( | ||
struct rtnl_br_vlan_gopts_entry *entry); | ||
int rtnl_br_vlan_gopts_entry_get_mcast_last_member_cnt( | ||
const struct rtnl_br_vlan_gopts_entry *entry, uint32_t *out); | ||
|
||
int rtnl_br_vlan_gopts_entry_set_mcast_startup_query_cnt( | ||
struct rtnl_br_vlan_gopts_entry *entry, uint32_t value); | ||
int rtnl_br_vlan_gopts_entry_unset_mcast_startup_query_cnt( | ||
struct rtnl_br_vlan_gopts_entry *entry); | ||
int rtnl_br_vlan_gopts_entry_get_mcast_startup_query_cnt( | ||
const struct rtnl_br_vlan_gopts_entry *entry, uint32_t *out); | ||
|
||
int rtnl_br_vlan_gopts_entry_set_mcast_last_member_intvl( | ||
struct rtnl_br_vlan_gopts_entry *entry, uint64_t value); | ||
int rtnl_br_vlan_gopts_entry_unset_mcast_last_member_intvl( | ||
struct rtnl_br_vlan_gopts_entry *entry); | ||
int rtnl_br_vlan_gopts_entry_get_mcast_last_member_intvl( | ||
const struct rtnl_br_vlan_gopts_entry *entry, uint64_t *out); | ||
|
||
int rtnl_br_vlan_gopts_entry_set_mcast_membership_intvl( | ||
struct rtnl_br_vlan_gopts_entry *entry, uint64_t value); | ||
int rtnl_br_vlan_gopts_entry_unset_mcast_membership_intvl( | ||
struct rtnl_br_vlan_gopts_entry *entry); | ||
int rtnl_br_vlan_gopts_entry_get_mcast_membership_intvl( | ||
const struct rtnl_br_vlan_gopts_entry *entry, uint64_t *out); | ||
|
||
int rtnl_br_vlan_gopts_entry_set_mcast_querier_intvl( | ||
struct rtnl_br_vlan_gopts_entry *entry, uint64_t value); | ||
int rtnl_br_vlan_gopts_entry_unset_mcast_querier_intvl( | ||
struct rtnl_br_vlan_gopts_entry *entry); | ||
int rtnl_br_vlan_gopts_entry_get_mcast_querier_intvl( | ||
const struct rtnl_br_vlan_gopts_entry *entry, uint64_t *out); | ||
|
||
int rtnl_br_vlan_gopts_entry_set_mcast_query_intvl( | ||
struct rtnl_br_vlan_gopts_entry *entry, uint64_t value); | ||
int rtnl_br_vlan_gopts_entry_unset_mcast_query_intvl( | ||
struct rtnl_br_vlan_gopts_entry *entry); | ||
int rtnl_br_vlan_gopts_entry_get_mcast_query_intvl( | ||
const struct rtnl_br_vlan_gopts_entry *entry, uint64_t *out); | ||
|
||
int rtnl_br_vlan_gopts_entry_set_mcast_query_response_intvl( | ||
struct rtnl_br_vlan_gopts_entry *entry, uint64_t value); | ||
int rtnl_br_vlan_gopts_entry_unset_mcast_query_response_intvl( | ||
struct rtnl_br_vlan_gopts_entry *entry); | ||
int rtnl_br_vlan_gopts_entry_get_mcast_query_response_intvl( | ||
const struct rtnl_br_vlan_gopts_entry *entry, uint64_t *out); | ||
|
||
int rtnl_br_vlan_gopts_entry_set_mcast_startup_query_intvl( | ||
struct rtnl_br_vlan_gopts_entry *entry, uint64_t value); | ||
int rtnl_br_vlan_gopts_entry_unset_mcast_startup_query_intvl( | ||
struct rtnl_br_vlan_gopts_entry *entry); | ||
int rtnl_br_vlan_gopts_entry_get_mcast_startup_query_intvl( | ||
const struct rtnl_br_vlan_gopts_entry *entry, uint64_t *out); | ||
|
||
int rtnl_br_vlan_gopts_entry_set_mcast_querier( | ||
struct rtnl_br_vlan_gopts_entry *entry, uint8_t value); | ||
int rtnl_br_vlan_gopts_entry_unset_mcast_querier( | ||
struct rtnl_br_vlan_gopts_entry *entry); | ||
int rtnl_br_vlan_gopts_entry_get_mcast_querier( | ||
const struct rtnl_br_vlan_gopts_entry *entry, uint8_t *out); | ||
|
||
int rtnl_br_vlan_gopts_entry_set_msti(struct rtnl_br_vlan_gopts_entry *entry, | ||
uint16_t value); | ||
int rtnl_br_vlan_gopts_entry_unset_msti(struct rtnl_br_vlan_gopts_entry *entry); | ||
int rtnl_br_vlan_gopts_entry_get_msti( | ||
const struct rtnl_br_vlan_gopts_entry *entry, uint16_t *out); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif /* NETLINK_BR_VLAN_GLOBAL_OPTS_H_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this code come from linux kernel headers (and do they call the functionality this way)? If kernel does it, that would be a strong reason to name them the same (and basically implement them the same). I didn't check. The commit message should explain how this new API relates to the list API in kernel (and optimally, they are obviously related and similar).
With these linked lists, often the head is a special object and not a regular entry. That is, often we could not meaningfully call
nl_list_entry(head, Node, lst_node)
. It should be clear what happens ifhead_1
orhead_2
point to such a special head element (or not).for example, we could define that
head_1
can be either a special element or not (it doesn't matter). But thathead_2
must point to a special head element which afterwards will be empty (and the content of list 2 moved over tohead_1
. Alternatively, we could define thathead_2
points to a regular element, and the entire list 2 will be joined. That is, list 2 is never empty, it at least contains head_2 element. In the latter case, `head_2 would not be empty afterwards.This should be defined (by having a code comment that explains how to use this). Optimally, we would also have unit tests, since it's not at all obvious whether this implementation is correct (which it probably is).
The same applies to
nl_list_insert_list_after()
. Also, don't donl_list_join
andnl_list_insert_list_after
something similar? Couldn'tnl_list_insert_list_after()
be named something likenl_list_join_front()
(am not not sure exactly, since I don't fully understand what they do(*))? However, their name is rather different. There should be code comment that explains the difference (and also makes it clear why they are named differently).(*) yes, I could spend some time trying to understand what they do, and then reason backwards whether the name makes sense. However, the name should make it clear upfront, and optimally a code comment explains the non-obvious details beyond a good name. Then I'd be more inclined to reason whether the implementation actually implements what the name+doc indicates.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if the code is copied from linux kernel, then we must take care to not use invalid licenses (libnl is LGPL2.1-only).
Granted, those functions seem so minimal, I don't think you can implement them any other way.
If you want to get inspired, then compare to https://github.com/c-util/c-list/blob/main/src/c-list.h which has a compatible license. The downside is, we really want that the API looks similar to what is in kernel, so that somebody familiar with kernel API understand it.
Use your best judgment :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would merge this patch early, even if no users are merged yet. I think it's generally useful API beyond this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with all your points. I myself found it hard to understand how the list module worked since it had no documentation. It also didn't help that I'd never seen that type of implementation of a linked list before. I'll make a separate PR adds the extra methods and documents the module. I can add some unit tests as well if you could give me some pointers on how to do that.
No it doesn't. I hadn't looked at the code in the Linux kernel for their list implementation until now. I wrote the code based on a method I worked out on paper. The closest thing the kernel has seems to be
list_splice_tail_init
ininclude/linux/list.h
. You seem to be able to use that function to do the same thing. It just has the parameters swapped around I think.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With API like
nl_list_add_tail()
it's mostly clear what the function is going to do. On the other hand, withnl_list_join()
there are more details that are not obvious.In this case, unit tests would go to
tests/check-direct.c
. This test statically links the libraries and runs without a separate namespace, so it's suited for testing "pure" internal code.That might be an argument for following kernel names and API. On the other hand, there is the potential licensing concern (??) and maybe
c-list.h
(below) would still be nicer.That's great :)
I am quite a fan of https://github.com/c-util/c-list/blob/main/src/c-list.h
It's 2024 and I wonder, whether we shouldn't re-use an existing, solid implementation. Granted, a circular, intrusive linked list is relatively easy to reimplement. But should we? In NetworkManager, c-list is used via
git-subtree
. Since it's header-only, it's easy to use.Import with
upgrade (if ever necessary) with
and then add
shared/c-list/src/
toMakefile.am
asI would do that. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the point would be that we submit such features to c-list "upstream", and just do a
git subtree pull
. That requires that upstream is susceptible to such patches. I think upstream is, otherwise there would be a problem with pulling it.Thereby others could potentially benefit to that contribution, not just some obscure part inside libnl3.
I don't think we need to rework existing code (unless somebody wants to send patches). It could be used only for new code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how about #412 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. I'll also make a PR that adds reverse iterators to that library. I've added the code; I've just got to adapt some of their tests. I'll probably submit that tomorrow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's the PR I made, for reference: c-util/c-list#14
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm.
In the meantime, for your WIP branch here, I think you can do: