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