mirror of
https://git.freebsd.org/src.git
synced 2026-01-11 19:57:22 +00:00
libifconfig: Add netlink based helper to bring the interface up/down
Adds `ifconfig_set_up()` to set and unset the `IFF_UP` on a network interface using `RTM_NEWLINK`. Sponsored by: Google LLC (GSoC) Reviewed by: obiwac, mckusick (mentor), kp Approved by: obiwac, mckusick (mentor), kp Differential Revision: https://reviews.freebsd.org/D52128
This commit is contained in:
parent
6e6febb54d
commit
94ed4c1903
3 changed files with 84 additions and 0 deletions
|
|
@ -17,6 +17,7 @@ SRCS= libifconfig.c \
|
|||
libifconfig_internal.c \
|
||||
libifconfig_lagg.c \
|
||||
libifconfig_media.c \
|
||||
libifconfig_nl.c \
|
||||
libifconfig_sfp.c
|
||||
|
||||
GEN= libifconfig_sfp_tables.h \
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@
|
|||
#include <netinet/ip_carp.h>
|
||||
#include <netinet6/in6_var.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#define ND6_IFF_DEFAULTIF 0x8000
|
||||
|
||||
typedef enum {
|
||||
|
|
@ -381,3 +383,12 @@ int ifconfig_set_vlantag(ifconfig_handle_t *h, const char *name,
|
|||
* length of *lenp * IFNAMSIZ bytes.
|
||||
*/
|
||||
int ifconfig_list_cloners(ifconfig_handle_t *h, char **bufp, size_t *lenp);
|
||||
|
||||
/** Brings the interface up/down
|
||||
* @param h An open ifconfig state object
|
||||
* @param ifname The interface name
|
||||
* @param up true to bring the interface up, false to bring it down
|
||||
* @return 0 on success, nonzero on failure.
|
||||
* On failure, the error info on the handle is set.
|
||||
*/
|
||||
int ifconfig_set_up(ifconfig_handle_t *h, const char *ifname, bool up);
|
||||
|
|
|
|||
72
lib/libifconfig/libifconfig_nl.c
Normal file
72
lib/libifconfig/libifconfig_nl.c
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2025, Muhammad Saheed <saheed@FreeBSD.org>
|
||||
*/
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/netlink_snl.h>
|
||||
#include <netlink/route/common.h>
|
||||
#include <netlink/route/interface.h>
|
||||
|
||||
#include "libifconfig.h"
|
||||
#include "libifconfig_internal.h"
|
||||
|
||||
static int ifconfig_modify_flags(ifconfig_handle_t *h, const char *ifname,
|
||||
int ifi_flags, int ifi_change);
|
||||
|
||||
static int
|
||||
ifconfig_modify_flags(ifconfig_handle_t *h, const char *ifname, int ifi_flags,
|
||||
int ifi_change)
|
||||
{
|
||||
int ret = 0;
|
||||
struct snl_state ss;
|
||||
struct snl_writer nw;
|
||||
struct nlmsghdr *hdr;
|
||||
struct ifinfomsg *ifi;
|
||||
struct snl_errmsg_data e = { 0 };
|
||||
|
||||
if (!snl_init(&ss, NETLINK_ROUTE)) {
|
||||
ifconfig_error(h, NETLINK, ENOTSUP);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
snl_init_writer(&ss, &nw);
|
||||
hdr = snl_create_msg_request(&nw, NL_RTM_NEWLINK);
|
||||
ifi = snl_reserve_msg_object(&nw, struct ifinfomsg);
|
||||
snl_add_msg_attr_string(&nw, IFLA_IFNAME, ifname);
|
||||
|
||||
ifi->ifi_flags = ifi_flags;
|
||||
ifi->ifi_change = ifi_change;
|
||||
|
||||
hdr = snl_finalize_msg(&nw);
|
||||
if (hdr == NULL) {
|
||||
ifconfig_error(h, NETLINK, ENOMEM);
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!snl_send_message(&ss, hdr)) {
|
||||
ifconfig_error(h, NETLINK, EIO);
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!snl_read_reply_code(&ss, hdr->nlmsg_seq, &e)) {
|
||||
ifconfig_error(h, NETLINK, e.error);
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
snl_free(&ss);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
ifconfig_set_up(ifconfig_handle_t *h, const char *ifname, bool up)
|
||||
{
|
||||
int flag = up ? IFF_UP : ~IFF_UP;
|
||||
|
||||
return (ifconfig_modify_flags(h, ifname, flag, IFF_UP));
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue