From: Geliang Tang <geliang@kernel.org>
To: Matthieu Baerts <matttbe@kernel.org>, mptcp@lists.linux.dev
Cc: Geliang Tang <tanggeliang@kylinos.cn>
Subject: Re: [PATCH mptcp-next v3 5/8] mptcp: userspace pm set_flags id support
Date: Fri, 10 Jan 2025 15:45:11 +0800 [thread overview]
Message-ID: <74351649e55ba9312705aa7a52a2f48750130bfd.camel@kernel.org> (raw)
In-Reply-To: <9f8c7031-4f5d-4195-93de-e23491799367@kernel.org>
Hi Matt,
On Thu, 2025-01-09 at 13:20 +0100, Matthieu Baerts wrote:
> Hi Geliang,
>
> Thank you for your reply!
>
> On 09/01/2025 04:40, Geliang Tang wrote:
> > Hi Matt,
> >
> > Thanks for the review!
> >
> > On Wed, 2025-01-08 at 19:51 +0100, Matthieu Baerts wrote:
> > > On 08/01/2025 19:47, Matthieu Baerts wrote:
> > > > Hi Geliang,
> > > >
> > > > On 08/01/2025 05:21, Geliang Tang wrote:
> > > > > From: Geliang Tang <tanggeliang@kylinos.cn>
> > > > >
> > > > > Similar to in-kernel PM, this patch adds address ID support
> > > > > to
> > > > > set_flags()
> > > > > interface of userspace PM, allowing it to work with either an
> > > > > address or
> > > > > an address ID.
> > > > >
> > > > > When an address ID is used,
> > > > > mptcp_userspace_pm_lookup_addr_by_id() helper
> > > > > is used to look up the address entry in the local address
> > > > > list
> > > > > instead of
> > > > > using mptcp_userspace_pm_lookup_addr().
> > > >
> > > > Mmh, I'm still not sure about that. As I was saying in [1], if
> > > > I'm
> > > > not
> > > > mistaken, with the userspace PM, it is possible not to find any
> > > > entries
> > > > here, e.g.: if a subflow using this address has not been added
> > > > or
> > > > the
> > > > address has not been announced. (I guess the initial address is
> > > > not
> > > > there then).
> >
> > The previous version (in [1]) did have this issue and
> > userspace_pm.sh
> > tests would fail because of it, but this new version has fixed it.
> >
> > mptcp_pm_nl_mp_prio_send_ack(msk,
> > entry ? &entry->addr : &local->addr,
> > remote, bkup);
> >
> > When the entry is not found, we continue to pass local->addr to
> > ensure
> > the same behavior as before.
>
> Yes indeed, the tests are fixed, but if 'entry' is NULL, the address
> you
> will give will be empty, so it will not be able to find any subflow
> to
> send the MP_PRIO, right?
>
> > > > Do you think this patch is worth it? Setting by ID for the in-
> > > > kernel PM
> > > > makes sense: unique ID for the netns, easier to type the ID
> > > > than
> > > > the
> > > > full address. While for the userspace PM, it will be managed by
> > > > a
> > > > daemon
> > > > that will have to track addresses anyway.
> >
> > I think it's still useful to extend this functionality while the
> > original behavior is not affected, at least it doesn't hurt.
>
> I'm sorry, I think it is not that simple: if we extend this
> functionality, it means we will have to maintain it. Here, the
> interface
> looks buggy because it will not work with all addresses: the initial
> ones, the ones not announced but implicitly used, etc.
>
> If the interface does not always work, I don't think we will
> recommend
> using it, then why do we need to maintain it?
>
> > We cannot assume that userspace PM is always managed by a daemon.
> > We
> > have exported its interfaces to BPF. We allow users to customize
> > path
> > managers. That means we also allow users to use their own userspace
> > PM
> > in any way.
>
> I think the BPF PM is different: it is a different interface.
>
> To interact with the userspace PM, it is required to monitor the
> MPTCP
> events sent via Netlink, e.g. to get the token. When a new subflow is
> created, the userspace will know which addresses (including the ID)
> it
> is linked to. In this case, why only setting the ID in the address
> structure if it doesn't always work, while setting the address will
> always work as expected.
>
> > Another consideration is that we need to maintain the consistency
> > between in-kernel PM and userspace PM.
>
> Not really: when they can do the same thing, yes, but the two
> interfaces
> are different. We don't have to keep the consistency if it doesn't
> make
> sense to do so.
>
> > For ease of maintenance, we need
> > to make these two PMs use the same code as much as possible, and
> > only
> > abstract their differences through PM interfaces such as get_addr,
> > dump_addr, set_flags, etc.
>
> Yes but there are some limits: if some code is shared between
> multiple
> interfaces, it is important not to break one of them when changing
> the
> code. In other words, if the behaviour is very similar (e.g.
> get_addr),
> that's fine. But if they start to be too different, you have complex
> common code where you need to think "OK, this one acts like that, but
> the other one like that", and complexity is not good for the
> maintenance. In this case, it sounds better to keep them separated.
>
> > At present, the biggest difference between
> > the two is that they use different linked lists (pernet-
> > > local_addr_list vs. msk->pm.userspace_pm_local_addr_list) to
> > > store
> > address entries, so we only need to put the code for operating the
> > linked lists into the interfaces of each PM. This is also the goal
> > of
> > adjusting the pm interfaces in this series.
>
> Yes, but that's not the only difference, because the interfaces are
> different.
>
> With the in-kernel PM, we act per netns, while with the userspace PM,
> it
> is per connection. Because of that, addresses lists are managed
> differently, leading to different concept, e.g. the list not having
> all
> addresses, the addresses not having ID 0 in one, but OK in the other,
> etc. With shared code that acts for both of them, you need to keep
> thinking about these differences when reading or writing code, and
> that's a source of error I think.
>
> > > > Or in other words, do you have a use-case for this? To me, it
> > > > looks
> > > > like
> > > > "yes, you can only set the ID, but it might not always work".
> > > > Then
> > > > maybe
> > > > better to always set the full address, no?
> >
> > If you're worried that this functionality isn't covered by tests,
> > I've
> > added a test that covers it in BPF path manager selftests:
> >
> > err = userspace_pm_set_flags(token, addr, "backup");
> > if (!ASSERT_OK(err, "userspace_pm_set_flags backup"))
> > goto close_accept;
> >
> > ...
> >
> > err = userspace_pm_set_flags_by_id(token, 100, "nobackup");
> > if (!ASSERT_OK(err, "userspace_pm_set_flags_by_id
> > nobackup"))
> > goto close_accept;
>
> I would need to check the BPF PM interface, but for me the userspace
> PM
> and BPF PM interfaces don't have to be the same, e.g. why having a
> dump
> if the BPF PM can directly access data from the kernel? Same here for
> the ID: it depends if all IDs are tracked in the corresponding list,
> e.g. it might not be the case with an "announced" list.
>
> But also yes, if something is exposed to userspace (via Netlink), it
> should be covered by a test (using the userspace Netlink interface)
>
> > > >
> > > > [1]
> > > > https://lore.kernel.org/mptcp/d01d0e8a-5606-4152-aabe-32e4402adeeb@kernel.org/
> > >
> > > Note: if we drop this patch (I think it is better), maybe patch
> > > 8/8
> > > is
> > > not worth it: not to have a "common" section with plenty of 'if
> > > (token)', no? Or do you really need them for the BPF PM?
> >
> > Here we are only adjusting set_flags interface of in-kernel PM and
> > userspace PM, which has nothing to do with the BPF PM
> > implementation.
> >
> > It seems that moving the code in mptcp_pm_nl_set_flags_doit() to
> > mptcp_pm_set_flags() can remove these 'if (token)':
> >
> > int mptcp_pm_nl_set_flags_doit(struct sk_buff *skb, struct
> > genl_info
> > *info)
> > {
> > return mptcp_pm_set_flags(info);
>
> I'm not sure whether it is useful to have one function simply calling
> another function that is only used once.
I kept this function in v4 to make it consistent with mptcp_pm_get_addr
and mptcp_pm_dump_addr.
And "mptcp: userspace pm set_flags id support" is moved out of this set
in v4.
Thanks,
-Geliang
>
> > }
> >
> > static int mptcp_pm_set_flags(struct genl_info *info)
> > {
> > struct mptcp_pm_addr_entry loc = { .addr = { .family =
> > AF_UNSPEC }, };
> > struct mptcp_addr_info rem = { .family = AF_UNSPEC, };
> > struct nlattr *attr_loc, *attr_rem;
> > int ret;
> >
> > if (GENL_REQ_ATTR_CHECK(info, MPTCP_PM_ATTR_ADDR))
> > return -EINVAL;
> >
> > attr_loc = info->attrs[MPTCP_PM_ATTR_ADDR];
> > ret = mptcp_pm_parse_entry(attr_loc, info, false, &loc);
> > if (ret < 0)
> > return ret;
> >
> > if (info->attrs[MPTCP_PM_ATTR_TOKEN]) {
> > if (GENL_REQ_ATTR_CHECK(info,
> > MPTCP_PM_ATTR_ADDR_REMOTE))
> > return -EINVAL;
> >
> > attr_rem = info->attrs[MPTCP_PM_ATTR_ADDR_REMOTE];
> > ret = mptcp_pm_parse_addr(attr_rem, info, &rem);
> > if (ret < 0)
> > return ret;
> >
> > if (rem.family == AF_UNSPEC) {
> > NL_SET_ERR_MSG_ATTR(info->extack, attr_rem,
> > "invalid remote address
> > family");
> > return -EINVAL;
> > }
> >
> > return mptcp_userspace_pm_set_flags(&loc, &rem,
> > info);
> > }
>
> The problem is the same: ↑ is specific to the userspace PM, why
> moving
> the code here in the common section then?
>
> Same for the code ↓.
>
> So at the end, the only common code is the parsing of the local
> address,
> so just GENL_REQ_ATTR_CHECK(MPTCP_PM_ATTR_ADDR) and
> mptcp_pm_parse_entry(MPTCP_PM_ATTR_ADDR). Is it worth it?
>
> So if we want to share code, all we can get I think is this:
>
> int mptcp_pm_nl_set_flags_doit(...)
> {
> (...)
>
> if (GENL_REQ_ATTR_CHECK(info, MPTCP_PM_ATTR_ADDR))
> return -EINVAL;
>
> attr_loc = info->attrs[MPTCP_PM_ATTR_ADDR];
> ret = mptcp_pm_parse_entry(attr_loc, info, false, &loc);
> if (ret < 0)
> return ret;
>
> if (info->attrs[MPTCP_PM_ATTR_TOKEN])
> return mptcp_userspace_pm_set_flags(&loc, info);
>
> return mptcp_pm_nl_set_flags(&loc, info);
> }
>
> Not a lot to share, but at least there is nothing PM specific here,
> except to pick the interface to continue with. And yes, that's
> something
> that could be done, but that's not much...
>
> >
> > if (loc.addr.family == AF_UNSPEC) {
> > if (!loc.addr.id) {
> > NL_SET_ERR_MSG_ATTR(info->extack, attr_loc,
> > "missing address ID");
> > return -EOPNOTSUPP;
> > }
> > }
> >
> > return mptcp_pm_nl_set_flags(&loc, info);
> > }
> >
> > WDYT?
> >
> > -Geliang
> >
> > >
> > > Cheers,
> > > Matt
> >
>
> Cheers,
> Matt
next prev parent reply other threads:[~2025-01-10 7:45 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-08 4:21 [PATCH mptcp-next v3 0/8] BPF path manager, part 2 Geliang Tang
2025-01-08 4:21 ` [PATCH mptcp-next v3 1/8] mptcp: make three pm wrappers static Geliang Tang
2025-01-08 4:21 ` [PATCH mptcp-next v3 2/8] mptcp: drop skb parameter of get_addr Geliang Tang
2025-01-08 4:21 ` [PATCH mptcp-next v3 3/8] mptcp: add id parameter for get_addr Geliang Tang
2025-01-08 4:21 ` [PATCH mptcp-next v3 4/8] mptcp: reuse sending nlmsg code in get_addr Geliang Tang
2025-01-08 4:21 ` [PATCH mptcp-next v3 5/8] mptcp: userspace pm set_flags id support Geliang Tang
2025-01-08 18:47 ` Matthieu Baerts
2025-01-08 18:51 ` Matthieu Baerts
2025-01-09 3:40 ` Geliang Tang
2025-01-09 12:20 ` Matthieu Baerts
2025-01-10 7:45 ` Geliang Tang [this message]
2025-01-08 4:21 ` [PATCH mptcp-next v3 6/8] mptcp: drop skb parameter of set_flags Geliang Tang
2025-01-08 4:21 ` [PATCH mptcp-next v3 7/8] mptcp: change rem type " Geliang Tang
2025-01-08 4:21 ` [PATCH mptcp-next v3 8/8] mptcp: add local & remote parameters for set_flags Geliang Tang
2025-01-08 5:30 ` [PATCH mptcp-next v3 0/8] BPF path manager, part 2 MPTCP CI
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=74351649e55ba9312705aa7a52a2f48750130bfd.camel@kernel.org \
--to=geliang@kernel.org \
--cc=matttbe@kernel.org \
--cc=mptcp@lists.linux.dev \
--cc=tanggeliang@kylinos.cn \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox