コード例 #1
0
static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev,
				u32 pid, u32 seq,
				struct netlink_callback *cb,
				int flags)
{
	void *hdr;

	hdr = genlmsg_put(msg, pid, seq, &nfc_genl_family, flags,
			  NFC_CMD_GET_DEVICE);
	if (!hdr)
		return -EMSGSIZE;

	if (cb)
		genl_dump_check_consistent(cb, hdr, &nfc_genl_family);

	NLA_PUT_STRING(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev));
	NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx);
	NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols);
	NLA_PUT_U8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up);

	return genlmsg_end(msg, hdr);

nla_put_failure:
	genlmsg_cancel(msg, hdr);
	return -EMSGSIZE;
}
コード例 #2
0
static int nfc_genl_send_target(struct sk_buff *msg, struct nfc_target *target,
				struct netlink_callback *cb, int flags)
{
	void *hdr;

	hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
			  &nfc_genl_family, flags, NFC_CMD_GET_TARGET);
	if (!hdr)
		return -EMSGSIZE;

	genl_dump_check_consistent(cb, hdr, &nfc_genl_family);

	NLA_PUT_U32(msg, NFC_ATTR_TARGET_INDEX, target->idx);
	NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS, target->supported_protocols);
	NLA_PUT_U16(msg, NFC_ATTR_TARGET_SENS_RES, target->sens_res);
	NLA_PUT_U8(msg, NFC_ATTR_TARGET_SEL_RES, target->sel_res);
	if (target->nfcid1_len > 0)
		NLA_PUT(msg, NFC_ATTR_TARGET_NFCID1, target->nfcid1_len,
			target->nfcid1);
	if (target->sensb_res_len > 0)
		NLA_PUT(msg, NFC_ATTR_TARGET_SENSB_RES, target->sensb_res_len,
			target->sensb_res);
	if (target->sensf_res_len > 0)
		NLA_PUT(msg, NFC_ATTR_TARGET_SENSF_RES, target->sensf_res_len,
			target->sensf_res);

	return genlmsg_end(msg, hdr);

nla_put_failure:
	genlmsg_cancel(msg, hdr);
	return -EMSGSIZE;
}
コード例 #3
0
ファイル: netlink.c プロジェクト: aklein53/neard
int __near_netlink_dep_link_up(uint32_t idx, uint32_t target_idx,
				uint8_t comm_mode, uint8_t rf_mode)
{
	struct nl_msg *msg;
	void *hdr;
	int err;

	DBG("");

	msg = nlmsg_alloc();
	if (!msg)
		return -ENOMEM;

	hdr = genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, nfc_state->nfc_id, 0,
			NLM_F_REQUEST, NFC_CMD_DEP_LINK_UP, NFC_GENL_VERSION);
	if (!hdr) {
		err = -EINVAL;
		goto nla_put_failure;
	}

	err = -EMSGSIZE;

	NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, idx);
	NLA_PUT_U32(msg, NFC_ATTR_TARGET_INDEX, target_idx);
	NLA_PUT_U8(msg, NFC_ATTR_COMM_MODE, comm_mode);
	NLA_PUT_U8(msg, NFC_ATTR_RF_MODE, rf_mode);

	err = nl_send_msg(nfc_state->cmd_sock, msg, NULL, NULL);

nla_put_failure:
	nlmsg_free(msg);

	return err;
}
コード例 #4
0
int nfc_genl_device_added(struct nfc_dev *dev)
{
	struct sk_buff *msg;
	void *hdr;

	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
	if (!msg)
		return -ENOMEM;

	hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
			  NFC_EVENT_DEVICE_ADDED);
	if (!hdr)
		goto free_msg;

	NLA_PUT_STRING(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev));
	NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx);
	NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols);
	NLA_PUT_U8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up);

	genlmsg_end(msg, hdr);

	genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL);

	return 0;

nla_put_failure:
	genlmsg_cancel(msg, hdr);
free_msg:
	nlmsg_free(msg);
	return -EMSGSIZE;
}
コード例 #5
0
static gboolean
wifi_nl80211_set_mode (WifiData *data, const NM80211Mode mode)
{
	WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data;
	struct nl_msg *msg;
	int err;

	msg = nl80211_alloc_msg (nl80211, NL80211_CMD_SET_INTERFACE, 0);

	switch (mode) {
	case NM_802_11_MODE_INFRA:
		NLA_PUT_U32 (msg, NL80211_ATTR_IFTYPE, NL80211_IFTYPE_STATION);
		break;
	case NM_802_11_MODE_ADHOC:
		NLA_PUT_U32 (msg, NL80211_ATTR_IFTYPE, NL80211_IFTYPE_ADHOC);
		break;
	case NM_802_11_MODE_AP:
		NLA_PUT_U32 (msg, NL80211_ATTR_IFTYPE, NL80211_IFTYPE_AP);
		break;
	default:
		g_assert_not_reached ();
	}

	err = nl80211_send_and_recv (nl80211, msg, NULL, NULL);
	return err ? FALSE : TRUE;

 nla_put_failure:
	nlmsg_free (msg);
	return FALSE;
}
コード例 #6
0
ファイル: netlink.c プロジェクト: aklein53/neard
int __near_netlink_activate_target(uint32_t idx, uint32_t target_idx,
				   uint32_t protocol)
{
	struct nl_msg *msg;
	void *hdr;
	int err;

	DBG("");

	msg = nlmsg_alloc();
	if (!msg)
		return -ENOMEM;

	hdr = genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, nfc_state->nfc_id, 0,
			NLM_F_REQUEST, NFC_CMD_ACTIVATE_TARGET,
			NFC_GENL_VERSION);
	if (!hdr) {
		err = -EINVAL;
		goto nla_put_failure;
	}

	err = -EMSGSIZE;

	NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, idx);
	NLA_PUT_U32(msg, NFC_ATTR_TARGET_INDEX, target_idx);
	NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS, protocol);

	err = nl_send_msg(nfc_state->cmd_sock, msg, NULL, NULL);

nla_put_failure:
	nlmsg_free(msg);

	return err;
}
コード例 #7
0
ファイル: cqm.c プロジェクト: 62gs8ha/batphone
static int iw_cqm_rssi(struct nl80211_state *state, struct nl_cb *cb,
		       struct nl_msg *msg, int argc, char **argv)
{
	struct nl_msg *cqm = NULL;
	int thold = 0;
	int hyst = 0;
	int ret = -ENOSPC;

	/* get the required args */
	if (argc < 1 || argc > 2)
		return 1;

	if (strcmp(argv[0], "off")) {
		thold = atoi(argv[0]);

		if (thold == 0)
			return -EINVAL;

		if (argc == 2)
			hyst = atoi(argv[1]);
	}

	/* connection quality monitor attributes */
	cqm = nlmsg_alloc();

	NLA_PUT_U32(cqm, NL80211_ATTR_CQM_RSSI_THOLD, thold);
	NLA_PUT_U32(cqm, NL80211_ATTR_CQM_RSSI_HYST, hyst);

	nla_put_nested(msg, NL80211_ATTR_CQM, cqm);
	ret = 0;

 nla_put_failure:
	nlmsg_free(cqm);
	return ret;
}
コード例 #8
0
ファイル: libipvs.c プロジェクト: Am1GO/keepalived
int ipvs_stop_daemon(ipvs_daemon_t *dm)
{
	ipvs_func = ipvs_stop_daemon;
#ifdef LIBIPVS_USE_NL
	if (try_nl) {
		struct nlattr *nl_daemon;
		struct nl_msg *msg = ipvs_nl_message(IPVS_CMD_DEL_DAEMON, 0);
		if (!msg) return -1;

		nl_daemon = nla_nest_start(msg, IPVS_CMD_ATTR_DAEMON);
		if (!nl_daemon)
			goto nla_put_failure;

		NLA_PUT_U32(msg, IPVS_DAEMON_ATTR_STATE, dm->state);
		NLA_PUT_STRING(msg, IPVS_DAEMON_ATTR_MCAST_IFN, dm->mcast_ifn);
		NLA_PUT_U32(msg, IPVS_DAEMON_ATTR_SYNC_ID, dm->syncid);

		nla_nest_end(msg, nl_daemon);

		return ipvs_nl_send_message(msg, ipvs_nl_noop_cb, NULL);

nla_put_failure:
		nlmsg_free(msg);
		return -1;
	}
#endif
	return setsockopt(sockfd, IPPROTO_IP, IP_VS_SO_SET_STOPDAEMON,
			  (char *)dm, sizeof(*dm));
}
コード例 #9
0
void ath6kl_wlan_hb_event(struct ath6kl *ar, u8 value,
			void *buf, size_t buf_len)
{
	struct sk_buff *skb;

	if (!buf || buf_len == 0) {
		printk(KERN_ERR "buf buflen is empty\n");
		return;
	}

	skb = cfg80211_testmode_alloc_event_skb(ar->wiphy, buf_len, GFP_ATOMIC);

	if (!skb) {
		printk(KERN_ERR "failed to allocate testmode event skb!\n");
		return;
	}

	NLA_PUT_U32(skb, ATH6KL_TM_ATTR_CMD, ATH6KL_TM_CMD_WLAN_HB);
	NLA_PUT_U32(skb, ATH6KL_TM_ATTR_TYPE, value);
	NLA_PUT(skb, ATH6KL_TM_ATTR_DATA, buf_len, buf);
	cfg80211_testmode_event(skb, GFP_ATOMIC);
	return;

#ifdef _NLA_PUT_ERR_RTN
nla_put_failure:
	kfree_skb(skb);
	printk(KERN_ERR "nla_put failed on testmode event skb!\n");
#endif
}
コード例 #10
0
ファイル: wifi-probe.c プロジェクト: flandree/wifi-sniff
static struct nl_msg *gen_msg(int iface, char* ssid, int chan) {
	struct nl_msg *msg, *ssids, *freqs;

	msg  = nlmsg_alloc();
	ssids = nlmsg_alloc();
	freqs = nlmsg_alloc();

	if (!msg || !ssids || !freqs) {
		fprintf(stderr, "Failed to allocate netlink message");
	if(msg)
		nlmsg_free(msg);
	if(ssids)
		nlmsg_free(ssids);
	if(freqs)
		nlmsg_free(freqs);
		return NULL;
	}

	genlmsg_put(msg, 0, 0, handle_id, 0, 0, NL80211_CMD_TRIGGER_SCAN, 0);
	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, iface);

	NLA_PUT(ssids, 1, strlen(ssid), ssid);
	nla_put_nested(msg, NL80211_ATTR_SCAN_SSIDS, ssids);

	NLA_PUT_U32(freqs, 1, chan*5 + 2407);
	nla_put_nested(msg, NL80211_ATTR_SCAN_FREQUENCIES, freqs);


	return msg;
	nla_put_failure:

	nlmsg_free(msg);
	return NULL;
}
コード例 #11
0
int ieee802154_nl_scan_confirm(struct net_device *dev,
		u8 status, u8 scan_type, u32 unscanned, u8 page,
		u8 *edl/*                                   */)
{
	struct sk_buff *msg;

	pr_debug("%s\n", __func__);

	msg = ieee802154_nl_create(0, IEEE802154_SCAN_CONF);
	if (!msg)
		return -ENOBUFS;

	NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
	NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
	NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
			dev->dev_addr);

	NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status);
	NLA_PUT_U8(msg, IEEE802154_ATTR_SCAN_TYPE, scan_type);
	NLA_PUT_U32(msg, IEEE802154_ATTR_CHANNELS, unscanned);
	NLA_PUT_U8(msg, IEEE802154_ATTR_PAGE, page);

	if (edl)
		NLA_PUT(msg, IEEE802154_ATTR_ED_LIST, 27, edl);

	return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id);

nla_put_failure:
	nlmsg_free(msg);
	return -ENOBUFS;
}
コード例 #12
0
ファイル: u32.c プロジェクト: duki994/G900H-Platform-XXU1BOA7
static int u32_get_opts(struct rtnl_cls *cls, struct nl_msg *msg)
{
	struct rtnl_u32 *u = rtnl_cls_data(cls);
	
	if (u->cu_mask & U32_ATTR_DIVISOR)
		NLA_PUT_U32(msg, TCA_U32_DIVISOR, u->cu_divisor);

	if (u->cu_mask & U32_ATTR_HASH)
		NLA_PUT_U32(msg, TCA_U32_HASH, u->cu_hash);

	if (u->cu_mask & U32_ATTR_CLASSID)
		NLA_PUT_U32(msg, TCA_U32_CLASSID, u->cu_classid);

	if (u->cu_mask & U32_ATTR_LINK)
		NLA_PUT_U32(msg, TCA_U32_LINK, u->cu_link);

	if (u->cu_mask & U32_ATTR_SELECTOR)
		NLA_PUT_DATA(msg, TCA_U32_SEL, u->cu_selector);

	if (u->cu_mask & U32_ATTR_ACTION)
		NLA_PUT_DATA(msg, TCA_U32_ACT, u->cu_act);

	if (u->cu_mask & U32_ATTR_POLICE)
		NLA_PUT_DATA(msg, TCA_U32_POLICE, u->cu_police);

	if (u->cu_mask & U32_ATTR_INDEV)
		NLA_PUT_STRING(msg, TCA_U32_INDEV, u->cu_indev);

	return 0;

nla_put_failure:
	return -NLE_NOMEM;
}
コード例 #13
0
static int wpa_driver_set_power_save(void *priv, int state)
{
	struct i802_bss *bss = priv;
	struct wpa_driver_nl80211_data *drv = bss->drv;
	struct nl_msg *msg;
	int ret = -1;
	enum nl80211_ps_state ps_state;

	msg = nlmsg_alloc();
	if (!msg)
		return -1;

	genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
		    NL80211_CMD_SET_POWER_SAVE, 0);

	if (state == WPA_PS_ENABLED)
		ps_state = NL80211_PS_ENABLED;
	else
		ps_state = NL80211_PS_DISABLED;

	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
	NLA_PUT_U32(msg, NL80211_ATTR_PS_STATE, ps_state);

	ret = send_and_recv_msgs(drv, msg, NULL, NULL);
	msg = NULL;
	if (ret < 0)
		wpa_printf(MSG_ERROR, "nl80211: Set power mode fail: %d", ret);
nla_put_failure:
	nlmsg_free(msg);
	return ret;
}
コード例 #14
0
ファイル: rule.c プロジェクト: DINKIN/tuo
static struct nl_msg *build_rule_msg(struct rtnl_rule *tmpl, int cmd, int flags)
{
	struct nl_msg *msg;
	struct rtmsg rtm = {
		.rtm_type = RTN_UNSPEC
	};

	if (cmd == RTM_NEWRULE)
		rtm.rtm_type = RTN_UNICAST;
		
	if (tmpl->ce_mask & RULE_ATTR_FAMILY)
		rtm.rtm_family = tmpl->r_family;

	if (tmpl->ce_mask & RULE_ATTR_TABLE)
		rtm.rtm_table = tmpl->r_table;

	if (tmpl->ce_mask & RULE_ATTR_DSFIELD)
		rtm.rtm_tos = tmpl->r_dsfield;

	if (tmpl->ce_mask & RULE_ATTR_TYPE)
		rtm.rtm_type = tmpl->r_type;

	if (tmpl->ce_mask & RULE_ATTR_SRC_LEN)
		rtm.rtm_src_len = tmpl->r_src_len;

	if (tmpl->ce_mask & RULE_ATTR_DST_LEN)
		rtm.rtm_dst_len = tmpl->r_dst_len;

	msg = nlmsg_alloc_simple(cmd, flags);
	if (!msg)
		goto nla_put_failure;

	if (nlmsg_append(msg, &rtm, sizeof(rtm), NLMSG_ALIGNTO) < 0)
		goto nla_put_failure;

	if (tmpl->ce_mask & RULE_ATTR_SRC)
		NLA_PUT_ADDR(msg, RTA_SRC, tmpl->r_src);

	if (tmpl->ce_mask & RULE_ATTR_DST)
		NLA_PUT_ADDR(msg, RTA_DST, tmpl->r_dst);

	if (tmpl->ce_mask & RULE_ATTR_PRIO)
		NLA_PUT_U32(msg, RTA_PRIORITY, tmpl->r_prio);

	if (tmpl->ce_mask & RULE_ATTR_MARK)
		NLA_PUT_U32(msg, RTA_PROTOINFO, tmpl->r_mark);

	if (tmpl->ce_mask & RULE_ATTR_REALMS)
		NLA_PUT_U32(msg, RTA_FLOW, tmpl->r_realms);

	if (tmpl->ce_mask & RULE_ATTR_IIF)
		NLA_PUT_STRING(msg, RTA_IIF, tmpl->r_iif);

	return msg;

nla_put_failure:
	nlmsg_free(msg);
	return NULL;
}
コード例 #15
0
static int l2tp_nl_session_send(struct sk_buff *skb, u32 pid, u32 seq, int flags,
				struct l2tp_session *session)
{
	void *hdr;
	struct nlattr *nest;
	struct l2tp_tunnel *tunnel = session->tunnel;
	struct sock *sk = NULL;

	sk = tunnel->sock;

	hdr = genlmsg_put(skb, pid, seq, &l2tp_nl_family, flags, L2TP_CMD_SESSION_GET);
	if (IS_ERR(hdr))
		return PTR_ERR(hdr);

	NLA_PUT_U32(skb, L2TP_ATTR_CONN_ID, tunnel->tunnel_id);
	NLA_PUT_U32(skb, L2TP_ATTR_SESSION_ID, session->session_id);
	NLA_PUT_U32(skb, L2TP_ATTR_PEER_CONN_ID, tunnel->peer_tunnel_id);
	NLA_PUT_U32(skb, L2TP_ATTR_PEER_SESSION_ID, session->peer_session_id);
	NLA_PUT_U32(skb, L2TP_ATTR_DEBUG, session->debug);
	NLA_PUT_U16(skb, L2TP_ATTR_PW_TYPE, session->pwtype);
	NLA_PUT_U16(skb, L2TP_ATTR_MTU, session->mtu);
	if (session->mru)
		NLA_PUT_U16(skb, L2TP_ATTR_MRU, session->mru);

	if (session->ifname && session->ifname[0])
		NLA_PUT_STRING(skb, L2TP_ATTR_IFNAME, session->ifname);
	if (session->cookie_len)
		NLA_PUT(skb, L2TP_ATTR_COOKIE, session->cookie_len, &session->cookie[0]);
	if (session->peer_cookie_len)
		NLA_PUT(skb, L2TP_ATTR_PEER_COOKIE, session->peer_cookie_len, &session->peer_cookie[0]);
	NLA_PUT_U8(skb, L2TP_ATTR_RECV_SEQ, session->recv_seq);
	NLA_PUT_U8(skb, L2TP_ATTR_SEND_SEQ, session->send_seq);
	NLA_PUT_U8(skb, L2TP_ATTR_LNS_MODE, session->lns_mode);
#ifdef CONFIG_XFRM
	if ((sk) && (sk->sk_policy[0] || sk->sk_policy[1]))
		NLA_PUT_U8(skb, L2TP_ATTR_USING_IPSEC, 1);
#endif
	if (session->reorder_timeout)
		NLA_PUT_MSECS(skb, L2TP_ATTR_RECV_TIMEOUT, session->reorder_timeout);

	nest = nla_nest_start(skb, L2TP_ATTR_STATS);
	if (nest == NULL)
		goto nla_put_failure;
	NLA_PUT_U64(skb, L2TP_ATTR_TX_PACKETS, session->stats.tx_packets);
	NLA_PUT_U64(skb, L2TP_ATTR_TX_BYTES, session->stats.tx_bytes);
	NLA_PUT_U64(skb, L2TP_ATTR_TX_ERRORS, session->stats.tx_errors);
	NLA_PUT_U64(skb, L2TP_ATTR_RX_PACKETS, session->stats.rx_packets);
	NLA_PUT_U64(skb, L2TP_ATTR_RX_BYTES, session->stats.rx_bytes);
	NLA_PUT_U64(skb, L2TP_ATTR_RX_SEQ_DISCARDS, session->stats.rx_seq_discards);
	NLA_PUT_U64(skb, L2TP_ATTR_RX_OOS_PACKETS, session->stats.rx_oos_packets);
	NLA_PUT_U64(skb, L2TP_ATTR_RX_ERRORS, session->stats.rx_errors);
	nla_nest_end(skb, nest);

	return genlmsg_end(skb, hdr);

 nla_put_failure:
	genlmsg_cancel(skb, hdr);
	return -1;
}
コード例 #16
0
ファイル: mac80211.c プロジェクト: hhatto/netsniff-ng
static int nl80211_add_mon_if(struct nl80211_state *state, const char *device,
			      const char *mondevice)
{
	int ifindex, ret;
	struct nl_msg *msg;
	struct nl_cb *cb = NULL;
	int finished = 0;

	ifindex = device_ifindex(device);

	msg = nl80211_nlmsg_xalloc();

	genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0,
		    0, NL80211_CMD_NEW_INTERFACE, 0);

	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
	NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, mondevice);
	NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, NL80211_IFTYPE_MONITOR);

	ret = nl_send_auto_complete(state->nl_sock, msg);
	if (ret < 0) {
		if (ret == -ENFILE) {
			nlmsg_free(msg);
			return -EBUSY;
		}

		panic("Cannot send_auto_complete!\n");
	}

	cb = nl_cb_alloc(NL_CB_CUSTOM);
	if (!cb)
		panic("Cannot alloc nl_cb!\n");

	nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, nl80211_wait_handler, &finished);
	nl_cb_err(cb, NL_CB_CUSTOM, nl80211_error_handler, NULL);

	nl_recvmsgs(state->nl_sock, cb);

	if (!finished) {
		ret = nl_wait_for_ack(state->nl_sock);
		if (ret < 0) {
			if (ret == -ENFILE) {
				nlmsg_free(msg);
				return -EBUSY;
			}

			panic("Waiting for netlink ack failed!\n");
		}
	}

	nl_cb_put(cb);
	nlmsg_free(msg);
	return 0;

nla_put_failure:
	panic("nla put failure!\n");
	return -EIO; /* dummy */
}
コード例 #17
0
static int l2tp_nl_tunnel_send(struct sk_buff *skb, u32 pid, u32 seq, int flags,
			       struct l2tp_tunnel *tunnel)
{
	void *hdr;
	struct nlattr *nest;
	struct sock *sk = NULL;
	struct inet_sock *inet;

	hdr = genlmsg_put(skb, pid, seq, &l2tp_nl_family, flags,
			  L2TP_CMD_TUNNEL_GET);
	if (IS_ERR(hdr))
		return PTR_ERR(hdr);

	NLA_PUT_U8(skb, L2TP_ATTR_PROTO_VERSION, tunnel->version);
	NLA_PUT_U32(skb, L2TP_ATTR_CONN_ID, tunnel->tunnel_id);
	NLA_PUT_U32(skb, L2TP_ATTR_PEER_CONN_ID, tunnel->peer_tunnel_id);
	NLA_PUT_U32(skb, L2TP_ATTR_DEBUG, tunnel->debug);
	NLA_PUT_U16(skb, L2TP_ATTR_ENCAP_TYPE, tunnel->encap);

	nest = nla_nest_start(skb, L2TP_ATTR_STATS);
	if (nest == NULL)
		goto nla_put_failure;

	NLA_PUT_U64(skb, L2TP_ATTR_TX_PACKETS, tunnel->stats.tx_packets);
	NLA_PUT_U64(skb, L2TP_ATTR_TX_BYTES, tunnel->stats.tx_bytes);
	NLA_PUT_U64(skb, L2TP_ATTR_TX_ERRORS, tunnel->stats.tx_errors);
	NLA_PUT_U64(skb, L2TP_ATTR_RX_PACKETS, tunnel->stats.rx_packets);
	NLA_PUT_U64(skb, L2TP_ATTR_RX_BYTES, tunnel->stats.rx_bytes);
	NLA_PUT_U64(skb, L2TP_ATTR_RX_SEQ_DISCARDS, tunnel->stats.rx_seq_discards);
	NLA_PUT_U64(skb, L2TP_ATTR_RX_OOS_PACKETS, tunnel->stats.rx_oos_packets);
	NLA_PUT_U64(skb, L2TP_ATTR_RX_ERRORS, tunnel->stats.rx_errors);
	nla_nest_end(skb, nest);

	sk = tunnel->sock;
	if (!sk)
		goto out;

	inet = inet_sk(sk);

	switch (tunnel->encap) {
	case L2TP_ENCAPTYPE_UDP:
		NLA_PUT_U16(skb, L2TP_ATTR_UDP_SPORT, ntohs(inet->inet_sport));
		NLA_PUT_U16(skb, L2TP_ATTR_UDP_DPORT, ntohs(inet->inet_dport));
		NLA_PUT_U8(skb, L2TP_ATTR_UDP_CSUM, (sk->sk_no_check != UDP_CSUM_NOXMIT));
		/* NOBREAK */
	case L2TP_ENCAPTYPE_IP:
		NLA_PUT_BE32(skb, L2TP_ATTR_IP_SADDR, inet->inet_saddr);
		NLA_PUT_BE32(skb, L2TP_ATTR_IP_DADDR, inet->inet_daddr);
		break;
	}

out:
	return genlmsg_end(skb, hdr);

nla_put_failure:
	genlmsg_cancel(skb, hdr);
	return -1;
}
コード例 #18
0
ファイル: libipvs.c プロジェクト: Am1GO/keepalived
static int ipvs_nl_fill_service_attr(struct nl_msg *msg, ipvs_service_t *svc)
{
	struct nlattr *nl_service;
	struct ip_vs_flags flags = { .flags = svc->flags,
				     .mask = ~0 };

	nl_service = nla_nest_start(msg, IPVS_CMD_ATTR_SERVICE);
	if (!nl_service)
		return -1;

	NLA_PUT_U16(msg, IPVS_SVC_ATTR_AF, svc->af);

	if (svc->fwmark) {
		NLA_PUT_U32(msg, IPVS_SVC_ATTR_FWMARK, svc->fwmark);
	} else {
		NLA_PUT_U16(msg, IPVS_SVC_ATTR_PROTOCOL, svc->protocol);
		NLA_PUT(msg, IPVS_SVC_ATTR_ADDR, sizeof(svc->addr), &(svc->addr));
		NLA_PUT_U16(msg, IPVS_SVC_ATTR_PORT, svc->port);
	}

	NLA_PUT_STRING(msg, IPVS_SVC_ATTR_SCHED_NAME, svc->sched_name);
	if (svc->pe_name[0])
		NLA_PUT_STRING(msg, IPVS_SVC_ATTR_PE_NAME, svc->pe_name);
	NLA_PUT(msg, IPVS_SVC_ATTR_FLAGS, sizeof(flags), &flags);
	NLA_PUT_U32(msg, IPVS_SVC_ATTR_TIMEOUT, svc->timeout);
	NLA_PUT_U32(msg, IPVS_SVC_ATTR_NETMASK, svc->netmask);

	nla_nest_end(msg, nl_service);
	return 0;

nla_put_failure:
	return -1;
}
#endif

int ipvs_add_service(ipvs_service_t *svc)
{
	ipvs_func = ipvs_add_service;
#ifdef LIBIPVS_USE_NL
	if (try_nl) {
		struct nl_msg *msg = ipvs_nl_message(IPVS_CMD_NEW_SERVICE, 0);
		if (!msg) return -1;
		if (ipvs_nl_fill_service_attr(msg, svc)) {
			nlmsg_free(msg);
			return -1;
		}
		return ipvs_nl_send_message(msg, ipvs_nl_noop_cb, NULL);
	}
#endif

	CHECK_COMPAT_SVC(svc, -1);
	return setsockopt(sockfd, IPPROTO_IP, IP_VS_SO_SET_ADD, (char *)svc,
			  sizeof(struct ip_vs_service_kern));
out_err:
	return -1;
}
コード例 #19
0
static struct nl80211_msg_conveyor * nl80211_msg(const char *ifname, int cmd, int flags)
{
	static struct nl80211_msg_conveyor cv;

	int ifidx = -1, phyidx = -1;
	struct nl_msg *req = NULL;
	struct nl_cb *cb = NULL;

	if (nl80211_init() < 0)
		goto err;

	if (!strncmp(ifname, "phy", 3))
		phyidx = atoi(&ifname[3]);
	else if (!strncmp(ifname, "radio", 5))
		phyidx = atoi(&ifname[5]);
	else if (!strncmp(ifname, "mon.", 4))
		ifidx = if_nametoindex(&ifname[4]);
	else
		ifidx = if_nametoindex(ifname);

	if ((ifidx < 0) && (phyidx < 0))
		return NULL;

	req = nlmsg_alloc();
	if (!req)
		goto err;

	cb = nl_cb_alloc(NL_CB_DEFAULT);
	if (!cb)
		goto err;

	genlmsg_put(req, 0, 0, genl_family_get_id(nls->nl80211), 0,
		flags, cmd, 0);

	if (ifidx > -1)
		NLA_PUT_U32(req, NL80211_ATTR_IFINDEX, ifidx);

	if (phyidx > -1)
		NLA_PUT_U32(req, NL80211_ATTR_WIPHY, phyidx);

	cv.msg = req;
	cv.cb  = cb;

	return &cv;

err:
nla_put_failure:
	if (cb)
		nl_cb_put(cb);

	if (req)
		nlmsg_free(req);

	return NULL;
}
コード例 #20
0
ファイル: nl80211_control.c プロジェクト: 0x0d/lorcon
int nl80211_createvap(const char *interface, const char *newinterface, char *errstr) {
#ifndef HAVE_LINUX_NETLINK
	snprintf(errstr, LORCON_STATUS_MAX, "LORCON was not compiled with "
			 "netlink/nl80211 support, check the output of ./configure for why");
	return -1;
#else

	struct nl_sock *nl_handle;
	struct nl_cache *nl_cache;
	struct genl_family *nl80211;
	struct nl_msg *msg;

	if (if_nametoindex(newinterface) > 0) 
		return 1;

	if (nl80211_connect(interface, (void **) &nl_handle, 
						 (void **) &nl_cache, (void **) &nl80211, errstr) < 0)
		return -1;

	if ((msg = nlmsg_alloc()) == NULL) {
		snprintf(errstr, LORCON_STATUS_MAX, "nl80211_createvap() failed to allocate "
				 "message");
		nl80211_disconnect(nl_handle);
		return -1;
	}

	genlmsg_put(msg, 0, 0, genl_family_get_id(nl80211), 0, 0, 
				NL80211_CMD_NEW_INTERFACE, 0);
	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(interface));
	NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, newinterface);
	NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, NL80211_IFTYPE_MONITOR);

	if (nl_send_auto_complete(nl_handle, msg) < 0 || nl_wait_for_ack(nl_handle) < 0) {
nla_put_failure:
		snprintf(errstr, LORCON_STATUS_MAX, "nl80211_createvap() failed to create "
				 "interface '%s'", newinterface);
		nlmsg_free(msg);
		nl80211_disconnect(nl_handle);
		return -1;
	}

	nlmsg_free(msg);

	nl80211_disconnect(nl_handle);

	if (if_nametoindex(newinterface) <= 0) {
		snprintf(errstr, LORCON_STATUS_MAX, "nl80211_createvap() thought we made a "
				 "vap, but it wasn't there when we looked");
		return -1;
	}

	return 0;
#endif
}
コード例 #21
0
ファイル: exp.c プロジェクト: arend/libnl
static int nfnl_exp_build_message(const struct nfnl_exp *exp, int cmd, int flags,
				 struct nl_msg **result)
{
	struct nl_msg *msg;
	int err;

	msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_CTNETLINK_EXP, cmd, flags,
				   nfnl_exp_get_family(exp), 0);
	if (msg == NULL)
		return -NLE_NOMEM;

	if ((err = nfnl_exp_build_tuple(msg, exp, CTA_EXPECT_TUPLE)) < 0)
		goto err_out;

	if ((err = nfnl_exp_build_tuple(msg, exp, CTA_EXPECT_MASTER)) < 0)
		goto err_out;

	if ((err = nfnl_exp_build_tuple(msg, exp, CTA_EXPECT_MASK)) < 0)
		goto err_out;

	if (nfnl_exp_test_src(exp, NFNL_EXP_TUPLE_NAT)) {
		if ((err = nfnl_exp_build_nat(msg, exp)) < 0)
			goto err_out;
	}

	if (nfnl_exp_test_class(exp))
		NLA_PUT_U32(msg, CTA_EXPECT_CLASS, htonl(nfnl_exp_get_class(exp)));

	if (nfnl_exp_test_fn(exp))
		NLA_PUT_STRING(msg, CTA_EXPECT_FN, nfnl_exp_get_fn(exp));

	if (nfnl_exp_test_id(exp))
		NLA_PUT_U32(msg, CTA_EXPECT_ID, htonl(nfnl_exp_get_id(exp)));

	if (nfnl_exp_test_timeout(exp))
		NLA_PUT_U32(msg, CTA_EXPECT_TIMEOUT, htonl(nfnl_exp_get_timeout(exp)));

	if (nfnl_exp_test_helper_name(exp))
		NLA_PUT_STRING(msg, CTA_EXPECT_HELP_NAME, nfnl_exp_get_helper_name(exp));

	if (nfnl_exp_test_zone(exp))
		NLA_PUT_U16(msg, CTA_EXPECT_ZONE, htons(nfnl_exp_get_zone(exp)));

	if (nfnl_exp_test_flags(exp))
		NLA_PUT_U32(msg, CTA_EXPECT_FLAGS, htonl(nfnl_exp_get_flags(exp)));

	*result = msg;
	return 0;

nla_put_failure:
err_out:
	nlmsg_free(msg);
	return err;
}
コード例 #22
0
ファイル: nl80211_control.c プロジェクト: 0x0d/lorcon
int nl80211_setchannel_cache(const char *interface, void *handle,
							  void *family, int channel,
							  unsigned int chmode, char *errstr) {
#ifndef HAVE_LINUX_NETLINK
	snprintf(errstr, LORCON_STATUS_MAX, "LORCON was not compiled with netlink/nl80211 "
			 "support, check the output of ./configure for why");
	// Return the same error as we get if the device doesn't support nlfreq
	return -22;
#else
	struct nl_sock *nl_handle = (struct nl_sock *) handle;
	struct genl_family *nl80211 = (struct genl_family *) family;
	struct nl_msg *msg;
	int ret = 0;

	int chanmode[] = {
		NL80211_CHAN_NO_HT, NL80211_CHAN_HT20, 
		NL80211_CHAN_HT40PLUS, NL80211_CHAN_HT40MINUS
	};

	if (chmode > 4) {
		snprintf(errstr, LORCON_STATUS_MAX, "Invalid channel mode\n");
		return -1;
	}

	if ((msg = nlmsg_alloc()) == NULL) {
		snprintf(errstr, LORCON_STATUS_MAX, "nl80211_setchannel() failed to allocate "
				 "message");
		return -1;
	}

	genlmsg_put(msg, 0, 0, genl_family_get_id(nl80211), 0, 0, 
				NL80211_CMD_SET_WIPHY, 0);
	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(interface));
	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, ChanToFreq(channel));
	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, chanmode[chmode]);

	if ((ret = nl_send_auto_complete(nl_handle, msg)) >= 0) {
		if ((ret = nl_wait_for_ack(nl_handle)) < 0) 
			goto nla_put_failure;
	}

	nlmsg_free(msg);

	return 0;

nla_put_failure:
	snprintf(errstr, LORCON_STATUS_MAX, "nl80211_setchannel() could not set channel "
			 "%d/%d on interface '%s' err %d", channel, ChanToFreq(channel), 
			 interface, ret);
	nlmsg_free(msg);
	return ret;
#endif
}
コード例 #23
0
ファイル: acs.c プロジェクト: Lexus89/wifi-arsenal
static int go_offchan_freq(struct nl80211_state *state, int devidx, int freq)
{
	struct nl_cb *cb;
	struct nl_cb *s_cb;
	struct nl_msg *msg;
	int err;

	msg = nlmsg_alloc();
	if (!msg) {
		fprintf(stderr, "failed to allocate netlink message\n");
		return 2;
	}

	cb = nl_cb_alloc(nl_debug ? NL_CB_DEBUG : NL_CB_DEFAULT);
	s_cb = nl_cb_alloc(nl_debug ? NL_CB_DEBUG : NL_CB_DEFAULT);
	if (!cb || !s_cb) {
		fprintf(stderr, "failed to allocate netlink callbacks\n");
		err = 2;
		goto out_free_msg;
	}

	genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0,
		    0,
		    NL80211_CMD_REMAIN_ON_CHANNEL, 0);

	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, devidx);
	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
	/* 5 seconds is the max allowed, values passed are in ms */
	NLA_PUT_U32(msg, NL80211_ATTR_DURATION, 60);

	nl_socket_set_cb(state->nl_sock, s_cb);

	err = nl_send_auto_complete(state->nl_sock, msg);
	if (err < 0)
		goto out;

	err = 1;

	nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
	nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
	nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);

	while (err > 0)
		nl_recvmsgs(state->nl_sock, cb);
 out:
	nl_cb_put(cb);
 out_free_msg:
	nlmsg_free(msg);
	return err;
 nla_put_failure:
	fprintf(stderr, "building message failed\n");
	return 2;
}
コード例 #24
0
ファイル: nl80211_control.c プロジェクト: 0x0d/lorcon
int nl80211_setvapflag(const char *interface, char *errstr, int nflags, int *in_flags) {
#ifndef HAVE_LINUX_NETLINK
	snprintf(errstr, LORCON_STATUS_MAX, "LORCON was not compiled with netlink/nl80211 "
			 "support, check the output of ./configure for why");
	return -1;
#else

	struct nl_sock *nl_handle;
	struct nl_cache *nl_cache;
	struct genl_family *nl80211;
	struct nl_msg *msg;

	if (nl80211_connect(interface, (void **) &nl_handle, 
						 (void **) &nl_cache, (void **) &nl80211, errstr) < 0)
		return -1;

	if ((msg = nlmsg_alloc()) == NULL) {
		snprintf(errstr, LORCON_STATUS_MAX, "%s failed to allocate message",
				 __FUNCTION__);
		nl80211_disconnect(nl_handle);
		return -1;
	}

	genlmsg_put(msg, 0, 0, genl_family_get_id(nl80211), 0, 0, 
				NL80211_CMD_SET_INTERFACE, 0);

	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(interface));
	NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, NL80211_IFTYPE_MONITOR);

	nl80211_parseflags(nflags, in_flags, msg);

	if (nl_send_auto_complete(nl_handle, msg) >= 0) { 
		if (nl_wait_for_ack(nl_handle) < 0) {
			goto nla_put_failure;
		}
	} else {
nla_put_failure:
		snprintf(errstr, LORCON_STATUS_MAX, "%s failed to set flags on "
				 "interface '%s': %s", __FUNCTION__, interface,
				 strerror(errno));
		nlmsg_free(msg);
		nl80211_disconnect(nl_handle);
		return -1;
	}

	nlmsg_free(msg);

	nl80211_disconnect(nl_handle);

	return 0;
#endif
}
コード例 #25
0
ファイル: libipvs.c プロジェクト: Crazykev/ipvsadm
int ipvs_start_daemon(ipvs_daemon_t *dm)
{
	struct ip_vs_daemon_kern dmk;

	ipvs_func = ipvs_start_daemon;
#ifdef LIBIPVS_USE_NL
	if (try_nl) {
		struct nlattr *nl_daemon;
		struct nl_msg *msg = ipvs_nl_message(IPVS_CMD_NEW_DAEMON, 0);
		if (!msg) return -1;

		nl_daemon = nla_nest_start(msg, IPVS_CMD_ATTR_DAEMON);
		if (!nl_daemon)
			goto nla_put_failure;

		NLA_PUT_U32(msg, IPVS_DAEMON_ATTR_STATE, dm->state);
		NLA_PUT_STRING(msg, IPVS_DAEMON_ATTR_MCAST_IFN, dm->mcast_ifn);
		NLA_PUT_U32(msg, IPVS_DAEMON_ATTR_SYNC_ID, dm->syncid);
		if (dm->sync_maxlen)
			NLA_PUT_U16(msg, IPVS_DAEMON_ATTR_SYNC_MAXLEN,
				    dm->sync_maxlen);
		if (dm->mcast_port)
			NLA_PUT_U16(msg, IPVS_DAEMON_ATTR_MCAST_PORT,
				    dm->mcast_port);
		if (dm->mcast_ttl)
			NLA_PUT_U8(msg, IPVS_DAEMON_ATTR_MCAST_TTL,
				   dm->mcast_ttl);
		if (AF_INET6 == dm->mcast_af)
			NLA_PUT(msg, IPVS_DAEMON_ATTR_MCAST_GROUP6,
				sizeof(dm->mcast_group.in6),
				&dm->mcast_group.in6);
		else if (AF_INET == dm->mcast_af)
			NLA_PUT_U32(msg, IPVS_DAEMON_ATTR_MCAST_GROUP,
				    dm->mcast_group.ip);

		nla_nest_end(msg, nl_daemon);

		return ipvs_nl_send_message(msg, ipvs_nl_noop_cb, NULL);

nla_put_failure:
		nlmsg_free(msg);
		return -1;
	}
#endif
	memset(&dmk, 0, sizeof(dmk));
	dmk.state = dm->state;
	strcpy(dmk.mcast_ifn, dm->mcast_ifn);
	dmk.syncid = dm->syncid;
	return setsockopt(sockfd, IPPROTO_IP, IP_VS_SO_SET_STARTDAEMON,
			  (char *)&dmk, sizeof(dmk));
}
コード例 #26
0
ファイル: vendor.c プロジェクト: dimkr/iw
static int handle_vendor(struct nl80211_state *state,
			 struct nl_msg *msg, int argc, char **argv,
			 enum id_input id)
{
	unsigned int oui;
	unsigned int subcmd;
	char buf[2048] = {};
	int res, count = 0;
	FILE *file = NULL;

	if (argc < 3)
		return 1;

	res = sscanf(argv[0], "0x%x", &oui);
	if (res != 1) {
		printf("Vendor command must start with 0x\n");
		return 2;
	}

	res = sscanf(argv[1], "0x%x", &subcmd);
	if (res != 1) {
		printf("Sub command must start with 0x\n");
		return 2;
	}

	if (!strcmp(argv[2], "-"))
		file = stdin;
	else
		file = fopen(argv[2], "r");

	NLA_PUT_U32(msg, NL80211_ATTR_VENDOR_ID, oui);
	NLA_PUT_U32(msg, NL80211_ATTR_VENDOR_SUBCMD, subcmd);

	if (file) {
		count = read_file(file, buf, sizeof(buf));
		fclose(file);
	} else
		count = read_hex(argc - 2, &argv[2], buf, sizeof(buf));

	if (count < 0)
		return -EINVAL;

	if (count > 0)
		NLA_PUT(msg, NL80211_ATTR_VENDOR_DATA, count, buf);

	return 0;

nla_put_failure:
	return -ENOBUFS;
}
コード例 #27
0
ファイル: fib_rules.c プロジェクト: HuChundong/Endeavor3.1.10
static int fib4_rule_fill(struct fib_rule *rule, struct sk_buff *skb,
			  struct fib_rule_hdr *frh)
{
	struct fib4_rule *rule4 = (struct fib4_rule *) rule;

#ifdef FIB_RULE_DEBUG
	printk(KERN_DEBUG "[NET][IPV4][RULE] %s \n", __func__);
#endif

	frh->dst_len = rule4->dst_len;
	frh->src_len = rule4->src_len;
	frh->tos = rule4->tos;

	if (rule4->dst_len)
		NLA_PUT_BE32(skb, FRA_DST, rule4->dst);

	if (rule4->src_len)
		NLA_PUT_BE32(skb, FRA_SRC, rule4->src);

#ifdef CONFIG_IP_ROUTE_CLASSID
	if (rule4->tclassid)
		NLA_PUT_U32(skb, FRA_FLOW, rule4->tclassid);
#endif
	return 0;

nla_put_failure:
	return -ENOBUFS;
}
コード例 #28
0
static int wpa_driver_get_power_save(void *priv, int *state)
{
	struct i802_bss *bss = priv;
	struct wpa_driver_nl80211_data *drv = bss->drv;
	struct nl_msg *msg;
	int ret = -1;
	enum nl80211_ps_state ps_state;

	msg = nlmsg_alloc();
	if (!msg)
		return -1;

	genlmsg_put(msg, 0, 0, drv->global->nl80211_id, 0, 0,
		    NL80211_CMD_GET_POWER_SAVE, 0);

	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);

	ret = send_and_recv_msgs(drv, msg, get_power_mode_handler, state);
	msg = NULL;
	if (ret < 0)
		wpa_printf(MSG_ERROR, "nl80211: Get power mode fail: %d", ret);
nla_put_failure:
	nlmsg_free(msg);
	return ret;
}
コード例 #29
0
static char * nl80211_ifadd(const char *ifname)
{
	int phyidx;
	char *rv = NULL;
	static char nif[IFNAMSIZ] = { 0 };
	struct nl80211_msg_conveyor *req, *res;

	req = nl80211_msg(ifname, NL80211_CMD_NEW_INTERFACE, 0);
	if (req)
	{
		snprintf(nif, sizeof(nif), "tmp.%s", ifname);

		NLA_PUT_STRING(req->msg, NL80211_ATTR_IFNAME, nif);
		NLA_PUT_U32(req->msg, NL80211_ATTR_IFTYPE, NL80211_IFTYPE_STATION);

		nl80211_send(req, NULL, NULL);

		rv = nif;

	nla_put_failure:
		nl80211_free(req);
	}

	return rv;
}
コード例 #30
0
static int fib4_rule_fill(struct fib_rule *rule, struct sk_buff *skb,
			  struct fib_rule_hdr *frh)
{
	struct fib4_rule *rule4 = (struct fib4_rule *) rule;

	frh->family = AF_INET;
	frh->dst_len = rule4->dst_len;
	frh->src_len = rule4->src_len;
	frh->tos = rule4->tos;

	if (rule4->dst_len)
		NLA_PUT_BE32(skb, FRA_DST, rule4->dst);

	if (rule4->src_len)
		NLA_PUT_BE32(skb, FRA_SRC, rule4->src);

#ifdef CONFIG_NET_CLS_ROUTE
	if (rule4->tclassid)
		NLA_PUT_U32(skb, FRA_FLOW, rule4->tclassid);
#endif
	return 0;

nla_put_failure:
	return -ENOBUFS;
}