mirror of
https://gitee.com/openharmony/third_party_libnl
synced 2024-11-30 13:40:43 +00:00
lib/route: allow override of message type during link change
When rtnl_link_build_change_request() builds a change request, it sets the message type to RTM_NEWLINK by default. If the request fails, it changes the type to RTM_SETLINK, and resubmits. For some address families, this will result in a requested change never being applied by the kernel. An exmaple of this is the Linux bridge. When a netlink message of type RTM_NEWLINK is recieved, rather than failing, it simply ignores the message and does not return a failure. To fix this, this patch implements an override for address families that require it. The override can be set when an address family registers itself in libnl. This patch adds ao_override_rtm to the rtnl_link_af_ops structure. This patch adds a static function named af_request_type. This patch modifies rtnl_link_build_change_request to call af_request_type to properly set the request type if an address family wishes to override. Signed-off-by: Jef Oliver <jef.oliver@intel.com> Signed-off-by: Thomas Haller <thaller@redhat.com>
This commit is contained in:
parent
746bbba3e5
commit
5860c205d4
@ -146,6 +146,14 @@ struct rtnl_link_af_ops
|
||||
*/
|
||||
int (*ao_compare)(struct rtnl_link *,
|
||||
struct rtnl_link *, int, uint32_t, int);
|
||||
|
||||
/* RTM_NEWLINK override
|
||||
*
|
||||
* Called if a change link request is set to the kernel. If this is set
|
||||
* to anything other than zero, RTM_NEWLINK will be overriden with
|
||||
* RTM_SETLINK when rtnl_link_build_change_request() is called.
|
||||
*/
|
||||
const int ao_override_rtm;
|
||||
};
|
||||
|
||||
extern struct rtnl_link_af_ops *rtnl_link_af_ops_lookup(unsigned int);
|
||||
|
@ -108,6 +108,17 @@ static int af_free(struct rtnl_link *link, struct rtnl_link_af_ops *ops,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int af_request_type(int af_type)
|
||||
{
|
||||
struct rtnl_link_af_ops *ops;
|
||||
|
||||
ops = rtnl_link_af_ops_lookup(af_type);
|
||||
if (ops && ops->ao_override_rtm)
|
||||
return RTM_SETLINK;
|
||||
|
||||
return RTM_NEWLINK;
|
||||
}
|
||||
|
||||
static int af_clone(struct rtnl_link *link, struct rtnl_link_af_ops *ops,
|
||||
void *data, void *arg)
|
||||
{
|
||||
@ -1576,7 +1587,7 @@ int rtnl_link_build_change_request(struct rtnl_link *orig,
|
||||
.ifi_family = orig->l_family,
|
||||
.ifi_index = orig->l_index,
|
||||
};
|
||||
int err;
|
||||
int err, rt;
|
||||
|
||||
if (changes->ce_mask & LINK_ATTR_FLAGS) {
|
||||
ifi.ifi_flags = orig->l_flags & ~changes->l_flag_mask;
|
||||
@ -1596,7 +1607,9 @@ int rtnl_link_build_change_request(struct rtnl_link *orig,
|
||||
!strcmp(orig->l_name, changes->l_name))
|
||||
changes->ce_mask &= ~LINK_ATTR_IFNAME;
|
||||
|
||||
if ((err = build_link_msg(RTM_NEWLINK, &ifi, changes, flags, result)) < 0)
|
||||
rt = af_request_type(orig->l_family);
|
||||
|
||||
if ((err = build_link_msg(rt, &ifi, changes, flags, result)) < 0)
|
||||
goto errout;
|
||||
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user