diff options
Diffstat (limited to 'sys/netlink/route')
| -rw-r--r-- | sys/netlink/route/iface.c | 1 | ||||
| -rw-r--r-- | sys/netlink/route/iface_drivers.c | 47 | ||||
| -rw-r--r-- | sys/netlink/route/route_var.h | 1 | 
3 files changed, 40 insertions, 9 deletions
| diff --git a/sys/netlink/route/iface.c b/sys/netlink/route/iface.c index 8b871576d0b2..9beb80792af4 100644 --- a/sys/netlink/route/iface.c +++ b/sys/netlink/route/iface.c @@ -403,6 +403,7 @@ static const struct nlattr_parser nla_p_linfo[] = {  NL_DECLARE_ATTR_PARSER(linfo_parser, nla_p_linfo);  static const struct nlattr_parser nla_p_if[] = { +	{ .type = IFLA_ADDRESS, .off = _OUT(ifla_address), .cb = nlattr_get_nla },  	{ .type = IFLA_IFNAME, .off = _OUT(ifla_ifname), .cb = nlattr_get_string },  	{ .type = IFLA_MTU, .off = _OUT(ifla_mtu), .cb = nlattr_get_uint32 },  	{ .type = IFLA_LINK, .off = _OUT(ifla_link), .cb = nlattr_get_uint32 }, diff --git a/sys/netlink/route/iface_drivers.c b/sys/netlink/route/iface_drivers.c index 4bf913d9c978..4f1540740ead 100644 --- a/sys/netlink/route/iface_drivers.c +++ b/sys/netlink/route/iface_drivers.c @@ -82,26 +82,55 @@ _nl_modify_ifp_generic(struct ifnet *ifp, struct nl_parsed_link *lattrs,  		}  	} -	if ((lattrs->ifi_change & IFF_UP) && (lattrs->ifi_flags & IFF_UP) == 0) { -		/* Request to down the interface */ -		if_down(ifp); +	if ((lattrs->ifi_change & IFF_UP) != 0 || lattrs->ifi_change == 0) { +		/* Request to up or down the interface */ +		if (lattrs->ifi_flags & IFF_UP) +			if_up(ifp); +		else +			if_down(ifp);  	}  	if (lattrs->ifla_mtu > 0) {  		if (nlp_has_priv(npt->nlp, PRIV_NET_SETIFMTU)) {  			struct ifreq ifr = { .ifr_mtu = lattrs->ifla_mtu }; -			error = ifhwioctl(SIOCSIFMTU, ifp, (char *)&ifr, curthread); +			error = ifhwioctl(SIOCSIFMTU, ifp, (char *)&ifr, +			    curthread); +			if (error != 0) { +				nlmsg_report_err_msg(npt, "Failed to set mtu"); +				return (error); +			}  		} else {  			nlmsg_report_err_msg(npt, "Not enough privileges to set mtu");  			return (EPERM);  		}  	} -	if (lattrs->ifi_change & IFF_PROMISC) { -		error = ifpromisc(ifp, lattrs->ifi_flags & IFF_PROMISC); -		if (error != 0) { -			nlmsg_report_err_msg(npt, "unable to set promisc"); -			return (error); +	if ((lattrs->ifi_change & IFF_PROMISC) != 0 || +	    lattrs->ifi_change == 0) +		/* +		 * When asking for IFF_PROMISC, set permanent flag instead +		 * (IFF_PPROMISC) as we have no way of doing promiscuity +		 * reference counting through ifpromisc().  Every call to this +		 * function either sets or unsets IFF_PROMISC, and ifi_change +		 * is usually set to 0xFFFFFFFF. +		 */ +		if_setppromisc(ifp, (lattrs->ifi_flags & IFF_PROMISC) != 0); + +	if (lattrs->ifla_address != NULL) { +		if (nlp_has_priv(npt->nlp, PRIV_NET_SETIFMAC)) { +			error = if_setlladdr(ifp, +			    NLA_DATA(lattrs->ifla_address), +			    NLA_DATA_LEN(lattrs->ifla_address)); +			if (error != 0) { +				nlmsg_report_err_msg(npt, +				    "setting IFLA_ADDRESS failed with error code: %d", +				    error); +				return (error); +			} +		} else { +			nlmsg_report_err_msg(npt, +			    "Not enough privileges to set IFLA_ADDRESS"); +			return (EPERM);  		}  	} diff --git a/sys/netlink/route/route_var.h b/sys/netlink/route/route_var.h index b84b34461e35..41f110038b54 100644 --- a/sys/netlink/route/route_var.h +++ b/sys/netlink/route/route_var.h @@ -69,6 +69,7 @@ struct nl_parsed_link {  	char		*ifla_cloner;  	char		*ifla_ifalias;  	struct nlattr	*ifla_idata; +	struct nlattr	*ifla_address;  	unsigned short	ifi_type;  	int		ifi_index;  	uint32_t	ifla_link; | 
