xref: /freebsd/lib/libifconfig/libifconfig_nl.c (revision 94ed4c1903cf846a3f484373b8aae136762e9d09)
1*94ed4c19SMuhammad Saheed /*-
2*94ed4c19SMuhammad Saheed  * SPDX-License-Identifier: BSD-2-Clause
3*94ed4c19SMuhammad Saheed  *
4*94ed4c19SMuhammad Saheed  * Copyright (c) 2025, Muhammad Saheed <saheed@FreeBSD.org>
5*94ed4c19SMuhammad Saheed  */
6*94ed4c19SMuhammad Saheed 
7*94ed4c19SMuhammad Saheed #include <netlink/netlink.h>
8*94ed4c19SMuhammad Saheed #include <netlink/netlink_snl.h>
9*94ed4c19SMuhammad Saheed #include <netlink/route/common.h>
10*94ed4c19SMuhammad Saheed #include <netlink/route/interface.h>
11*94ed4c19SMuhammad Saheed 
12*94ed4c19SMuhammad Saheed #include "libifconfig.h"
13*94ed4c19SMuhammad Saheed #include "libifconfig_internal.h"
14*94ed4c19SMuhammad Saheed 
15*94ed4c19SMuhammad Saheed static int ifconfig_modify_flags(ifconfig_handle_t *h, const char *ifname,
16*94ed4c19SMuhammad Saheed     int ifi_flags, int ifi_change);
17*94ed4c19SMuhammad Saheed 
18*94ed4c19SMuhammad Saheed static int
ifconfig_modify_flags(ifconfig_handle_t * h,const char * ifname,int ifi_flags,int ifi_change)19*94ed4c19SMuhammad Saheed ifconfig_modify_flags(ifconfig_handle_t *h, const char *ifname, int ifi_flags,
20*94ed4c19SMuhammad Saheed     int ifi_change)
21*94ed4c19SMuhammad Saheed {
22*94ed4c19SMuhammad Saheed 	int ret = 0;
23*94ed4c19SMuhammad Saheed 	struct snl_state ss;
24*94ed4c19SMuhammad Saheed 	struct snl_writer nw;
25*94ed4c19SMuhammad Saheed 	struct nlmsghdr *hdr;
26*94ed4c19SMuhammad Saheed 	struct ifinfomsg *ifi;
27*94ed4c19SMuhammad Saheed 	struct snl_errmsg_data e = { 0 };
28*94ed4c19SMuhammad Saheed 
29*94ed4c19SMuhammad Saheed 	if (!snl_init(&ss, NETLINK_ROUTE)) {
30*94ed4c19SMuhammad Saheed 		ifconfig_error(h, NETLINK, ENOTSUP);
31*94ed4c19SMuhammad Saheed 		return (-1);
32*94ed4c19SMuhammad Saheed 	}
33*94ed4c19SMuhammad Saheed 
34*94ed4c19SMuhammad Saheed 	snl_init_writer(&ss, &nw);
35*94ed4c19SMuhammad Saheed 	hdr = snl_create_msg_request(&nw, NL_RTM_NEWLINK);
36*94ed4c19SMuhammad Saheed 	ifi = snl_reserve_msg_object(&nw, struct ifinfomsg);
37*94ed4c19SMuhammad Saheed 	snl_add_msg_attr_string(&nw, IFLA_IFNAME, ifname);
38*94ed4c19SMuhammad Saheed 
39*94ed4c19SMuhammad Saheed 	ifi->ifi_flags = ifi_flags;
40*94ed4c19SMuhammad Saheed 	ifi->ifi_change = ifi_change;
41*94ed4c19SMuhammad Saheed 
42*94ed4c19SMuhammad Saheed 	hdr = snl_finalize_msg(&nw);
43*94ed4c19SMuhammad Saheed 	if (hdr == NULL) {
44*94ed4c19SMuhammad Saheed 		ifconfig_error(h, NETLINK, ENOMEM);
45*94ed4c19SMuhammad Saheed 		ret = -1;
46*94ed4c19SMuhammad Saheed 		goto out;
47*94ed4c19SMuhammad Saheed 	}
48*94ed4c19SMuhammad Saheed 
49*94ed4c19SMuhammad Saheed 	if (!snl_send_message(&ss, hdr)) {
50*94ed4c19SMuhammad Saheed 		ifconfig_error(h, NETLINK, EIO);
51*94ed4c19SMuhammad Saheed 		ret = -1;
52*94ed4c19SMuhammad Saheed 		goto out;
53*94ed4c19SMuhammad Saheed 	}
54*94ed4c19SMuhammad Saheed 
55*94ed4c19SMuhammad Saheed 	if (!snl_read_reply_code(&ss, hdr->nlmsg_seq, &e)) {
56*94ed4c19SMuhammad Saheed 		ifconfig_error(h, NETLINK, e.error);
57*94ed4c19SMuhammad Saheed 		ret = -1;
58*94ed4c19SMuhammad Saheed 		goto out;
59*94ed4c19SMuhammad Saheed 	}
60*94ed4c19SMuhammad Saheed 
61*94ed4c19SMuhammad Saheed out:
62*94ed4c19SMuhammad Saheed 	snl_free(&ss);
63*94ed4c19SMuhammad Saheed 	return (ret);
64*94ed4c19SMuhammad Saheed }
65*94ed4c19SMuhammad Saheed 
66*94ed4c19SMuhammad Saheed int
ifconfig_set_up(ifconfig_handle_t * h,const char * ifname,bool up)67*94ed4c19SMuhammad Saheed ifconfig_set_up(ifconfig_handle_t *h, const char *ifname, bool up)
68*94ed4c19SMuhammad Saheed {
69*94ed4c19SMuhammad Saheed 	int flag = up ? IFF_UP : ~IFF_UP;
70*94ed4c19SMuhammad Saheed 
71*94ed4c19SMuhammad Saheed 	return (ifconfig_modify_flags(h, ifname, flag, IFF_UP));
72*94ed4c19SMuhammad Saheed }
73