Exemplo n.º 1
0
static int ipvs_parse_stats(struct ip_vs_stats_user *stats, struct nlattr *nla)
{
	struct nlattr *attrs[IPVS_STATS_ATTR_MAX + 1];

	if (nla_parse_nested(attrs, IPVS_STATS_ATTR_MAX, nla, ipvs_stats_policy))
		return -1;

	if (!(attrs[IPVS_STATS_ATTR_CONNS] &&
	      attrs[IPVS_STATS_ATTR_INPKTS] &&
	      attrs[IPVS_STATS_ATTR_OUTPKTS] &&
	      attrs[IPVS_STATS_ATTR_INBYTES] &&
	      attrs[IPVS_STATS_ATTR_OUTBYTES] &&
	      attrs[IPVS_STATS_ATTR_CPS] &&
	      attrs[IPVS_STATS_ATTR_INPPS] &&
	      attrs[IPVS_STATS_ATTR_OUTPPS] &&
	      attrs[IPVS_STATS_ATTR_INBPS] &&
	      attrs[IPVS_STATS_ATTR_OUTBPS]))
		return -1;

	stats->conns = nla_get_u32(attrs[IPVS_STATS_ATTR_CONNS]);
	stats->inpkts = nla_get_u32(attrs[IPVS_STATS_ATTR_INPKTS]);
	stats->outpkts = nla_get_u32(attrs[IPVS_STATS_ATTR_OUTPKTS]);
	stats->inbytes = nla_get_u64(attrs[IPVS_STATS_ATTR_INBYTES]);
	stats->outbytes = nla_get_u64(attrs[IPVS_STATS_ATTR_OUTBYTES]);
	stats->cps = nla_get_u32(attrs[IPVS_STATS_ATTR_CPS]);
	stats->inpps = nla_get_u32(attrs[IPVS_STATS_ATTR_INPPS]);
	stats->outpps = nla_get_u32(attrs[IPVS_STATS_ATTR_OUTPPS]);
	stats->inbps = nla_get_u32(attrs[IPVS_STATS_ATTR_INBPS]);
	stats->outbps = nla_get_u32(attrs[IPVS_STATS_ATTR_OUTBPS]);

	return 0;

}
Exemplo n.º 2
0
static int print_iface_handler(struct nl_msg *msg, void *arg)
{
	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
	struct nlattr *tb_msg[NL802154_ATTR_MAX + 1];
	unsigned int *wpan_phy = arg;
	const char *indent = "";

	nla_parse(tb_msg, NL802154_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
		  genlmsg_attrlen(gnlh, 0), NULL);

	if (wpan_phy && tb_msg[NL802154_ATTR_WPAN_PHY]) {
		unsigned int thiswpan_phy = nla_get_u32(tb_msg[NL802154_ATTR_WPAN_PHY]);
		indent = "\t";
		if (*wpan_phy != thiswpan_phy)
			printf("phy#%d\n", thiswpan_phy);
		*wpan_phy = thiswpan_phy;
	}

	if (tb_msg[NL802154_ATTR_IFNAME])
		printf("%sInterface %s\n", indent, nla_get_string(tb_msg[NL802154_ATTR_IFNAME]));
	else
		printf("%sUnnamed/non-netdev interface\n", indent);

	if (tb_msg[NL802154_ATTR_IFINDEX])
		printf("%s\tifindex %d\n", indent, nla_get_u32(tb_msg[NL802154_ATTR_IFINDEX]));
	if (tb_msg[NL802154_ATTR_WPAN_DEV])
		printf("%s\twpan_dev 0x%llx\n", indent,
		       (unsigned long long)nla_get_u64(tb_msg[NL802154_ATTR_WPAN_DEV]));
	if (tb_msg[NL802154_ATTR_EXTENDED_ADDR])
		printf("%s\textended_addr 0x%016" PRIx64 "\n", indent,
		       le64toh(nla_get_u64(tb_msg[NL802154_ATTR_EXTENDED_ADDR])));
	if (tb_msg[NL802154_ATTR_SHORT_ADDR])
		printf("%s\tshort_addr 0x%04x\n", indent,
		       le16toh(nla_get_u16(tb_msg[NL802154_ATTR_SHORT_ADDR])));
	if (tb_msg[NL802154_ATTR_PAN_ID])
		printf("%s\tpan_id 0x%04x\n", indent,
		       le16toh(nla_get_u16(tb_msg[NL802154_ATTR_PAN_ID])));
	if (tb_msg[NL802154_ATTR_IFTYPE])
		printf("%s\ttype %s\n", indent, iftype_name(nla_get_u32(tb_msg[NL802154_ATTR_IFTYPE])));
	if (tb_msg[NL802154_ATTR_MAX_FRAME_RETRIES])
		printf("%s\tmax_frame_retries %d\n", indent, nla_get_s8(tb_msg[NL802154_ATTR_MAX_FRAME_RETRIES]));
	if (tb_msg[NL802154_ATTR_MIN_BE])
		printf("%s\tmin_be %d\n", indent, nla_get_u8(tb_msg[NL802154_ATTR_MIN_BE]));
	if (tb_msg[NL802154_ATTR_MAX_BE])
		printf("%s\tmax_be %d\n", indent, nla_get_u8(tb_msg[NL802154_ATTR_MAX_BE]));
	if (tb_msg[NL802154_ATTR_MAX_CSMA_BACKOFFS])
		printf("%s\tmax_csma_backoffs %d\n", indent, nla_get_u8(tb_msg[NL802154_ATTR_MAX_CSMA_BACKOFFS]));
	if (tb_msg[NL802154_ATTR_LBT_MODE])
		printf("%s\tlbt %d\n", indent, nla_get_u8(tb_msg[NL802154_ATTR_LBT_MODE]));
	if (tb_msg[NL802154_ATTR_ACKREQ_DEFAULT])
		printf("%s\tackreq_default %d\n", indent, nla_get_u8(tb_msg[NL802154_ATTR_ACKREQ_DEFAULT]));

	return NL_SKIP;
}
Exemplo n.º 3
0
static int ct_parse_timestamp(struct nfnl_ct *ct, struct nlattr *attr)
{
	struct nlattr *tb[CTA_TIMESTAMP_MAX + 1];
	int err;

	err = nla_parse_nested(tb, CTA_TIMESTAMP_MAX, attr,
			       ct_timestamp_policy);
	if (err < 0)
		return err;

	if (tb[CTA_TIMESTAMP_START] && tb[CTA_TIMESTAMP_STOP])
		nfnl_ct_set_timestamp(ct,
			      ntohll(nla_get_u64(tb[CTA_TIMESTAMP_START])),
			      ntohll(nla_get_u64(tb[CTA_TIMESTAMP_STOP])));

	return 0;
}
Exemplo n.º 4
0
	nla_for_each_nested(tidattr, tid_stats_attr, rem) {
		if (nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,
				     tidattr, stats_policy)) {
			printf("failed to parse nested stats attributes!");
			return;
		}
		printf("\n\t\t%d", i++);
		info = stats_info[NL80211_TID_STATS_RX_MSDU];
		if (info)
			printf("\t%llu", (unsigned long long)nla_get_u64(info));
		info = stats_info[NL80211_TID_STATS_TX_MSDU];
		if (info)
			printf("\t%llu", (unsigned long long)nla_get_u64(info));
		info = stats_info[NL80211_TID_STATS_TX_MSDU_RETRIES];
		if (info)
			printf("\t%llu", (unsigned long long)nla_get_u64(info));
		info = stats_info[NL80211_TID_STATS_TX_MSDU_FAILED];
		if (info)
			printf("\t\t%llu", (unsigned long long)nla_get_u64(info));
	}
Exemplo n.º 5
0
static int mac80211_cb_survey(struct nl_msg *msg, void *data)
{
	struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
	int freq;
	struct mac80211_info *mac80211_info = data;

	if (mac80211_parse_survey(msg, sinfo))
		goto out;

	freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
	if (sinfo[NL80211_SURVEY_INFO_IN_USE])
		{

		if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME] &&
			sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY]) {

			mac80211_info->channel_active_time = nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME]);
			mac80211_info->channel_busy_time = nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY]);

		}

		if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_RX])
			mac80211_info->channel_receive_time = nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_RX]);

		if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_TX])
			mac80211_info->channel_transmit_time = nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_TX]);

		if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY])
			mac80211_info->extension_channel_busy_time = nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY]);

		if (sinfo[NL80211_SURVEY_INFO_NOISE])
			mac80211_info->noise = nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);

		if (sinfo[NL80211_SURVEY_INFO_FREQUENCY])
			mac80211_info->frequency = freq;
	}

out:
	return NL_SKIP;
}
Exemplo n.º 6
0
static int ip_tun_build_state(struct net_device *dev, struct nlattr *attr,
			      struct lwtunnel_state **ts)
{
	struct ip_tunnel_info *tun_info;
	struct lwtunnel_state *new_state;
	struct nlattr *tb[IP_TUN_MAX + 1];
	int err;

	err = nla_parse_nested(tb, IP_TUN_MAX, attr, ip_tun_policy);
	if (err < 0)
		return err;

	new_state = lwtunnel_state_alloc(sizeof(*tun_info));
	if (!new_state)
		return -ENOMEM;

	new_state->type = LWTUNNEL_ENCAP_IP;

	tun_info = lwt_tun_info(new_state);

	if (tb[IP_TUN_ID])
		tun_info->key.tun_id = nla_get_u64(tb[IP_TUN_ID]);

	if (tb[IP_TUN_DST])
		tun_info->key.ipv4_dst = nla_get_be32(tb[IP_TUN_DST]);

	if (tb[IP_TUN_SRC])
		tun_info->key.ipv4_src = nla_get_be32(tb[IP_TUN_SRC]);

	if (tb[IP_TUN_TTL])
		tun_info->key.ipv4_ttl = nla_get_u8(tb[IP_TUN_TTL]);

	if (tb[IP_TUN_TOS])
		tun_info->key.ipv4_tos = nla_get_u8(tb[IP_TUN_TOS]);

	if (tb[IP_TUN_SPORT])
		tun_info->key.tp_src = nla_get_be16(tb[IP_TUN_SPORT]);

	if (tb[IP_TUN_DPORT])
		tun_info->key.tp_dst = nla_get_be16(tb[IP_TUN_DPORT]);

	if (tb[IP_TUN_FLAGS])
		tun_info->key.tun_flags = nla_get_u16(tb[IP_TUN_FLAGS]);

	tun_info->mode = IP_TUNNEL_INFO_TX;
	tun_info->options = NULL;
	tun_info->options_len = 0;

	*ts = new_state;

	return 0;
}
Exemplo n.º 7
0
static int ct_parse_counters(struct nfnl_ct *ct, int repl, struct nlattr *attr)
{
	struct nlattr *tb[CTA_COUNTERS_MAX+1];
	int err;

	err = nla_parse_nested(tb, CTA_COUNTERS_MAX, attr, ct_counters_policy);
	if (err < 0)
		return err;

	if (tb[CTA_COUNTERS_PACKETS])
		nfnl_ct_set_packets(ct, repl,
			ntohll(nla_get_u64(tb[CTA_COUNTERS_PACKETS])));
	if (tb[CTA_COUNTERS32_PACKETS])
		nfnl_ct_set_packets(ct, repl,
			ntohl(nla_get_u32(tb[CTA_COUNTERS32_PACKETS])));
	if (tb[CTA_COUNTERS_BYTES])
		nfnl_ct_set_bytes(ct, repl,
			ntohll(nla_get_u64(tb[CTA_COUNTERS_BYTES])));
	if (tb[CTA_COUNTERS32_BYTES])
		nfnl_ct_set_bytes(ct, repl,
			ntohl(nla_get_u32(tb[CTA_COUNTERS32_BYTES])));

	return 0;
}
Exemplo n.º 8
0
static int ip6_tun_build_state(struct net_device *dev, struct nlattr *attr,
			       unsigned int family, const void *cfg,
			       struct lwtunnel_state **ts)
{
	struct ip_tunnel_info *tun_info;
	struct lwtunnel_state *new_state;
	struct nlattr *tb[LWTUNNEL_IP6_MAX + 1];
	int err;

	err = nla_parse_nested(tb, LWTUNNEL_IP6_MAX, attr, ip6_tun_policy);
	if (err < 0)
		return err;

	new_state = lwtunnel_state_alloc(sizeof(*tun_info));
	if (!new_state)
		return -ENOMEM;

	new_state->type = LWTUNNEL_ENCAP_IP6;

	tun_info = lwt_tun_info(new_state);

	if (tb[LWTUNNEL_IP6_ID])
		tun_info->key.tun_id = nla_get_u64(tb[LWTUNNEL_IP6_ID]);

	if (tb[LWTUNNEL_IP6_DST])
		tun_info->key.u.ipv6.dst = nla_get_in6_addr(tb[LWTUNNEL_IP6_DST]);

	if (tb[LWTUNNEL_IP6_SRC])
		tun_info->key.u.ipv6.src = nla_get_in6_addr(tb[LWTUNNEL_IP6_SRC]);

	if (tb[LWTUNNEL_IP6_HOPLIMIT])
		tun_info->key.ttl = nla_get_u8(tb[LWTUNNEL_IP6_HOPLIMIT]);

	if (tb[LWTUNNEL_IP6_TC])
		tun_info->key.tos = nla_get_u8(tb[LWTUNNEL_IP6_TC]);

	if (tb[LWTUNNEL_IP6_FLAGS])
		tun_info->key.tun_flags = nla_get_u16(tb[LWTUNNEL_IP6_FLAGS]);

	tun_info->mode = IP_TUNNEL_INFO_TX | IP_TUNNEL_INFO_IPV6;
	tun_info->options_len = 0;

	*ts = new_state;

	return 0;
}
Exemplo n.º 9
0
Arquivo: upcall.c Projeto: mchalla/ivs
static void
ind_ovs_handle_packet_action(struct ind_ovs_upcall_thread *thread,
                             struct ind_ovs_port *port,
                             struct nl_msg *msg, struct nlattr **attrs)
{
    struct nlattr *key = attrs[OVS_PACKET_ATTR_KEY];
    struct nlattr *packet = attrs[OVS_PACKET_ATTR_PACKET];
    struct nlattr *userdata_nla = attrs[OVS_PACKET_ATTR_USERDATA];
    assert(key && packet && userdata_nla);

    struct ind_ovs_parsed_key pkey;
    ind_ovs_parse_key(key, &pkey);

    uint64_t userdata = nla_get_u64(userdata_nla);

    /* Send packet-in to controller */
    ind_ovs_upcall_request_pktin(pkey.in_port, port, packet, key,
                                 IVS_PKTIN_REASON(userdata),
                                 IVS_PKTIN_METADATA(userdata));
}
Exemplo n.º 10
0
Arquivo: kfm_ctl.c Projeto: kadoma/fms
static int 
kfm_genl_parse_mempage(struct kfm_mempage_u *umempage, struct nlattr **attrs)
{
	struct nlattr *nla_addr;
		
	if(attrs == NULL || umempage == NULL)
		return -EINVAL;

	nla_addr = attrs[KFM_MEMPAGE_ATTR_ADDR];
	
	if (!nla_addr)
		return -EINVAL;

	memset(umempage, 0, sizeof(*umempage));

	umempage->addr = nla_get_u64(nla_addr);
	
	KFM_DBG(7, "ADDR:0x%016llx", umempage->addr);
	
	return 0;
}
Exemplo n.º 11
0
int handle_immigration_confirmed(struct nl_msg *req_msg) {
	struct nl_msg *msg = NULL;
	struct nlattr *nla;
	int ret = 0;
	int seq;
	struct internal_state* state = get_current_state();

	// In params	
	int uid;
	int slot_index;
	char* name;
	pid_t local_pid;
	pid_t remote_pid;
	unsigned long jiffies;
	
	seq = nlmsg_hdr(req_msg)->nlmsg_seq;

	nla = nlmsg_find_attr(nlmsg_hdr(req_msg), sizeof(struct genlmsghdr), DIRECTOR_A_UID);
	if (nla == NULL)
		return  -EBADMSG;
	uid = nla_get_u32(nla);

	nla = nlmsg_find_attr(nlmsg_hdr(req_msg), sizeof(struct genlmsghdr), DIRECTOR_A_INDEX);
	if (nla == NULL)
		return  -EBADMSG;
	slot_index = nla_get_u32(nla);

	nla = nlmsg_find_attr(nlmsg_hdr(req_msg), sizeof(struct genlmsghdr), DIRECTOR_A_NAME);
	if (nla == NULL)
		return  -EBADMSG;
	//name = nl_data_get(nla_get_data(nla));
	name = nla_data(nla);

	nla = nlmsg_find_attr(nlmsg_hdr(req_msg), sizeof(struct genlmsghdr), DIRECTOR_A_JIFFIES);
	if (nla == NULL)
		return  -EBADMSG;
	jiffies = nla_get_u64(nla);

	nla = nlmsg_find_attr(nlmsg_hdr(req_msg), sizeof(struct genlmsghdr), DIRECTOR_A_PID);
	if (nla == NULL)
		return  -EBADMSG;
	local_pid = nla_get_u32(nla);

	nla = nlmsg_find_attr(nlmsg_hdr(req_msg), sizeof(struct genlmsghdr), DIRECTOR_A_REMOTE_PID);
	if (nla == NULL)
		return  -EBADMSG;
	remote_pid = nla_get_u32(nla);

	//printf("NPM CALLED FOR NAME: %s\n", name);
	if ( immigration_confirmed_callback )
        	immigration_confirmed_callback(uid, slot_index, name, jiffies, local_pid, remote_pid);
	
	if ( (ret=prepare_response_message(state->sk, DIRECTOR_ACK, state->gnl_fid, seq, &msg) ) != 0 ) {
		goto done;
	}
	
	ret = send_request_message(state->sk, msg, 0);
	goto done;	

error_del_resp:
	nlmsg_free(msg);
done:	
	return ret;
}
Exemplo n.º 12
0
static int ila_build_state(struct nlattr *nla,
			   unsigned int family, const void *cfg,
			   struct lwtunnel_state **ts,
			   struct netlink_ext_ack *extack)
{
	struct ila_lwt *ilwt;
	struct ila_params *p;
	struct nlattr *tb[ILA_ATTR_MAX + 1];
	struct lwtunnel_state *newts;
	const struct fib6_config *cfg6 = cfg;
	struct ila_addr *iaddr;
	int ret;

	if (family != AF_INET6)
		return -EINVAL;

	if (cfg6->fc_dst_len < 8 * sizeof(struct ila_locator) + 3) {
		/* Need to have full locator and at least type field
		 * included in destination
		 */
		return -EINVAL;
	}

	iaddr = (struct ila_addr *)&cfg6->fc_dst;

	if (!ila_addr_is_ila(iaddr) || ila_csum_neutral_set(iaddr->ident)) {
		/* Don't allow translation for a non-ILA address or checksum
		 * neutral flag to be set.
		 */
		return -EINVAL;
	}

	ret = nla_parse_nested(tb, ILA_ATTR_MAX, nla, ila_nl_policy, extack);
	if (ret < 0)
		return ret;

	if (!tb[ILA_ATTR_LOCATOR])
		return -EINVAL;

	newts = lwtunnel_state_alloc(sizeof(*ilwt));
	if (!newts)
		return -ENOMEM;

	ilwt = ila_lwt_lwtunnel(newts);
	ret = dst_cache_init(&ilwt->dst_cache, GFP_ATOMIC);
	if (ret) {
		kfree(newts);
		return ret;
	}

	p = ila_params_lwtunnel(newts);

	p->locator.v64 = (__force __be64)nla_get_u64(tb[ILA_ATTR_LOCATOR]);

	/* Precompute checksum difference for translation since we
	 * know both the old locator and the new one.
	 */
	p->locator_match = iaddr->loc;
	p->csum_diff = compute_csum_diff8(
		(__be32 *)&p->locator_match, (__be32 *)&p->locator);

	if (tb[ILA_ATTR_CSUM_MODE])
		p->csum_mode = nla_get_u8(tb[ILA_ATTR_CSUM_MODE]);

	ila_init_saved_csum(p);

	newts->type = LWTUNNEL_ENCAP_ILA;
	newts->flags |= LWTUNNEL_STATE_OUTPUT_REDIRECT |
			LWTUNNEL_STATE_INPUT_REDIRECT;

	if (cfg6->fc_dst_len == 8 * sizeof(struct in6_addr))
		ilwt->connected = 1;

	*ts = newts;

	return 0;
}
Exemplo n.º 13
0
static int tbf_change(struct Qdisc *sch, struct nlattr *opt,
		      struct netlink_ext_ack *extack)
{
	int err;
	struct tbf_sched_data *q = qdisc_priv(sch);
	struct nlattr *tb[TCA_TBF_MAX + 1];
	struct tc_tbf_qopt *qopt;
	struct Qdisc *child = NULL;
	struct psched_ratecfg rate;
	struct psched_ratecfg peak;
	u64 max_size;
	s64 buffer, mtu;
	u64 rate64 = 0, prate64 = 0;

	err = nla_parse_nested_deprecated(tb, TCA_TBF_MAX, opt, tbf_policy,
					  NULL);
	if (err < 0)
		return err;

	err = -EINVAL;
	if (tb[TCA_TBF_PARMS] == NULL)
		goto done;

	qopt = nla_data(tb[TCA_TBF_PARMS]);
	if (qopt->rate.linklayer == TC_LINKLAYER_UNAWARE)
		qdisc_put_rtab(qdisc_get_rtab(&qopt->rate,
					      tb[TCA_TBF_RTAB],
					      NULL));

	if (qopt->peakrate.linklayer == TC_LINKLAYER_UNAWARE)
			qdisc_put_rtab(qdisc_get_rtab(&qopt->peakrate,
						      tb[TCA_TBF_PTAB],
						      NULL));

	buffer = min_t(u64, PSCHED_TICKS2NS(qopt->buffer), ~0U);
	mtu = min_t(u64, PSCHED_TICKS2NS(qopt->mtu), ~0U);

	if (tb[TCA_TBF_RATE64])
		rate64 = nla_get_u64(tb[TCA_TBF_RATE64]);
	psched_ratecfg_precompute(&rate, &qopt->rate, rate64);

	if (tb[TCA_TBF_BURST]) {
		max_size = nla_get_u32(tb[TCA_TBF_BURST]);
		buffer = psched_l2t_ns(&rate, max_size);
	} else {
		max_size = min_t(u64, psched_ns_t2l(&rate, buffer), ~0U);
	}

	if (qopt->peakrate.rate) {
		if (tb[TCA_TBF_PRATE64])
			prate64 = nla_get_u64(tb[TCA_TBF_PRATE64]);
		psched_ratecfg_precompute(&peak, &qopt->peakrate, prate64);
		if (peak.rate_bytes_ps <= rate.rate_bytes_ps) {
			pr_warn_ratelimited("sch_tbf: peakrate %llu is lower than or equals to rate %llu !\n",
					peak.rate_bytes_ps, rate.rate_bytes_ps);
			err = -EINVAL;
			goto done;
		}

		if (tb[TCA_TBF_PBURST]) {
			u32 pburst = nla_get_u32(tb[TCA_TBF_PBURST]);
			max_size = min_t(u32, max_size, pburst);
			mtu = psched_l2t_ns(&peak, pburst);
		} else {
			max_size = min_t(u64, max_size, psched_ns_t2l(&peak, mtu));
		}
	} else {
		memset(&peak, 0, sizeof(peak));
	}

	if (max_size < psched_mtu(qdisc_dev(sch)))
		pr_warn_ratelimited("sch_tbf: burst %llu is lower than device %s mtu (%u) !\n",
				    max_size, qdisc_dev(sch)->name,
				    psched_mtu(qdisc_dev(sch)));

	if (!max_size) {
		err = -EINVAL;
		goto done;
	}

	if (q->qdisc != &noop_qdisc) {
		err = fifo_set_limit(q->qdisc, qopt->limit);
		if (err)
			goto done;
	} else if (qopt->limit > 0) {
		child = fifo_create_dflt(sch, &bfifo_qdisc_ops, qopt->limit,
					 extack);
		if (IS_ERR(child)) {
			err = PTR_ERR(child);
			goto done;
		}

		/* child is fifo, no need to check for noop_qdisc */
		qdisc_hash_add(child, true);
	}

	sch_tree_lock(sch);
	if (child) {
		qdisc_tree_flush_backlog(q->qdisc);
		qdisc_put(q->qdisc);
		q->qdisc = child;
	}
	q->limit = qopt->limit;
	if (tb[TCA_TBF_PBURST])
		q->mtu = mtu;
	else
		q->mtu = PSCHED_TICKS2NS(qopt->mtu);
	q->max_size = max_size;
	if (tb[TCA_TBF_BURST])
		q->buffer = buffer;
	else
		q->buffer = PSCHED_TICKS2NS(qopt->buffer);
	q->tokens = q->buffer;
	q->ptokens = q->mtu;

	memcpy(&q->rate, &rate, sizeof(struct psched_ratecfg));
	memcpy(&q->peak, &peak, sizeof(struct psched_ratecfg));

	sch_tree_unlock(sch);
	err = 0;
done:
	return err;
}
Exemplo n.º 14
0
static int tbf_change(struct Qdisc *sch, struct nlattr *opt)
{
	int err;
	struct tbf_sched_data *q = qdisc_priv(sch);
	struct nlattr *tb[TCA_TBF_MAX + 1];
	struct tc_tbf_qopt *qopt;
	struct Qdisc *child = NULL;
	struct psched_ratecfg rate;
	struct psched_ratecfg peak;
	u64 max_size;
	s64 buffer, mtu;
	u64 rate64 = 0, prate64 = 0;

	err = nla_parse_nested(tb, TCA_TBF_MAX, opt, tbf_policy);
	if (err < 0)
		return err;

	err = -EINVAL;
	if (tb[TCA_TBF_PARMS] == NULL)
		goto done;

	qopt = nla_data(tb[TCA_TBF_PARMS]);
	if (qopt->rate.linklayer == TC_LINKLAYER_UNAWARE)
		qdisc_put_rtab(qdisc_get_rtab(&qopt->rate,
					      tb[TCA_TBF_RTAB]));

	if (qopt->peakrate.linklayer == TC_LINKLAYER_UNAWARE)
			qdisc_put_rtab(qdisc_get_rtab(&qopt->peakrate,
						      tb[TCA_TBF_PTAB]));

	buffer = min_t(u64, PSCHED_TICKS2NS(qopt->buffer), ~0U);
	mtu = min_t(u64, PSCHED_TICKS2NS(qopt->mtu), ~0U);

	if (tb[TCA_TBF_RATE64])
		rate64 = nla_get_u64(tb[TCA_TBF_RATE64]);
	psched_ratecfg_precompute(&rate, &qopt->rate, rate64);

	max_size = min_t(u64, psched_ns_t2l(&rate, buffer), ~0U);

	if (qopt->peakrate.rate) {
		if (tb[TCA_TBF_PRATE64])
			prate64 = nla_get_u64(tb[TCA_TBF_PRATE64]);
		psched_ratecfg_precompute(&peak, &qopt->peakrate, prate64);
		if (peak.rate_bytes_ps <= rate.rate_bytes_ps) {
			pr_warn_ratelimited("sch_tbf: peakrate %llu is lower than or equals to rate %llu !\n",
					    peak.rate_bytes_ps, rate.rate_bytes_ps);
			err = -EINVAL;
			goto done;
		}

		max_size = min_t(u64, max_size, psched_ns_t2l(&peak, mtu));
	}

	if (max_size < psched_mtu(qdisc_dev(sch)))
		pr_warn_ratelimited("sch_tbf: burst %llu is lower than device %s mtu (%u) !\n",
				    max_size, qdisc_dev(sch)->name,
				    psched_mtu(qdisc_dev(sch)));

	if (!max_size) {
		err = -EINVAL;
		goto done;
	}

	if (q->qdisc != &noop_qdisc) {
		err = fifo_set_limit(q->qdisc, qopt->limit);
		if (err)
			goto done;
	} else if (qopt->limit > 0) {
		child = fifo_create_dflt(sch, &bfifo_qdisc_ops, qopt->limit);
		if (IS_ERR(child)) {
			err = PTR_ERR(child);
			goto done;
		}
	}

	sch_tree_lock(sch);
	if (child) {
		qdisc_tree_decrease_qlen(q->qdisc, q->qdisc->q.qlen);
		qdisc_destroy(q->qdisc);
		q->qdisc = child;
	}
	q->limit = qopt->limit;
	q->mtu = PSCHED_TICKS2NS(qopt->mtu);
	q->max_size = max_size;
	q->buffer = PSCHED_TICKS2NS(qopt->buffer);
	q->tokens = q->buffer;
	q->ptokens = q->mtu;

	memcpy(&q->rate, &rate, sizeof(struct psched_ratecfg));
	if (qopt->peakrate.rate) {
		memcpy(&q->peak, &peak, sizeof(struct psched_ratecfg));
		q->peak_present = true;
	} else {
		q->peak_present = false;
	}

	sch_tree_unlock(sch);
	err = 0;
done:
	return err;
}
static wifi_error gscan_get_hotlist_ap_found_results(u32 num_results,
                                            wifi_scan_result *results,
                                            u32 starting_index,
                                            struct nlattr **tb_vendor)
{
    u32 i = starting_index;
    struct nlattr *scanResultsInfo;
    int rem = 0;
    u32 len = 0;
    ALOGE("gscan_get_hotlist_ap_found_results: starting counter: %d", i);

    for (scanResultsInfo = (struct nlattr *) nla_data(tb_vendor[
            QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]),
            rem = nla_len(tb_vendor[
            QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST
            ]);
                nla_ok(scanResultsInfo, rem);
                scanResultsInfo = nla_next(scanResultsInfo, &(rem)))
    {
        struct nlattr *tb2[ QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1];
        nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX,
        (struct nlattr *) nla_data(scanResultsInfo),
                nla_len(scanResultsInfo), NULL);

        if (!
            tb2[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
                ])
        {
            ALOGE("gscan_get_hotlist_ap_found_results: "
                "RESULTS_SCAN_RESULT_TIME_STAMP not found");
            return WIFI_ERROR_INVALID_ARGS;
        }
        results[i].ts =
            nla_get_u64(
            tb2[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
                ]);
        if (!
            tb2[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID
                ])
        {
            ALOGE("gscan_get_hotlist_ap_found_results: "
                "RESULTS_SCAN_RESULT_SSID not found");
            return WIFI_ERROR_INVALID_ARGS;
        }
        len = nla_len(tb2[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]);
        len =
            sizeof(results->ssid) <= len ? sizeof(results->ssid) : len;
        memcpy((void *)&results[i].ssid,
            nla_data(
            tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]), len);
        if (!
            tb2[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID
                ])
        {
            ALOGE("gscan_get_hotlist_ap_found_results: "
                "RESULTS_SCAN_RESULT_BSSID not found");
            return WIFI_ERROR_INVALID_ARGS;
        }
        len = nla_len(
            tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]);
        len =
            sizeof(results->bssid) <= len ? sizeof(results->bssid) : len;
        memcpy(&results[i].bssid,
            nla_data(
            tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]), len);
        if (!
            tb2[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL
                ])
        {
            ALOGE("gscan_get_hotlist_ap_found_results: "
                "RESULTS_SCAN_RESULT_CHANNEL not found");
            return WIFI_ERROR_INVALID_ARGS;
        }
        results[i].channel =
            nla_get_u32(
            tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL]);
        if (!
            tb2[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI
                ])
        {
            ALOGE("gscan_get_hotlist_ap_found_results: "
                "RESULTS_SCAN_RESULT_RSSI not found");
            return WIFI_ERROR_INVALID_ARGS;
        }
        results[i].rssi =
            nla_get_u32(
            tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI]);
        if (!
            tb2[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT
                ])
        {
            ALOGE("gscan_get_hotlist_ap_found_results: "
                "RESULTS_SCAN_RESULT_RTT not found");
            return WIFI_ERROR_INVALID_ARGS;
        }
        results[i].rtt =
            nla_get_u32(
            tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT]);
        if (!
            tb2[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD
            ])
        {
            ALOGE("gscan_get_hotlist_ap_found_results: "
                "RESULTS_SCAN_RESULT_RTT_SD not found");
            return WIFI_ERROR_INVALID_ARGS;
        }
        results[i].rtt_sd =
            nla_get_u32(
            tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD]);

        ALOGE("gscan_get_hotlist_ap_found_results: ts  %lld ", results[i].ts);
        ALOGE("gscan_get_hotlist_ap_found_results: SSID  %s ",
            results[i].ssid) ;
        ALOGE("gscan_get_hotlist_ap_found_results: "
            "BSSID: %02x:%02x:%02x:%02x:%02x:%02x \n",
            results[i].bssid[0], results[i].bssid[1], results[i].bssid[2],
            results[i].bssid[3], results[i].bssid[4], results[i].bssid[5]);
        ALOGE("gscan_get_hotlist_ap_found_results: channel %d ",
            results[i].channel);
        ALOGE("gscan_get_hotlist_ap_found_results: rssi %d ", results[i].rssi);
        ALOGE("gscan_get_hotlist_ap_found_results: rtt %lld ", results[i].rtt);
        ALOGE("gscan_get_hotlist_ap_found_results: rtt_sd %lld ",
            results[i].rtt_sd);
        /* Increment loop index for next record */
        i++;
    }
    return WIFI_SUCCESS;
}
/* This function will be the main handler for incoming (from driver)  GSscan_SUBCMD.
 *  Calls the appropriate callback handler after parsing the vendor data.
 */
int GScanCommandEventHandler::handleEvent(WifiEvent &event)
{
    ALOGI("GScanCommandEventHandler::handleEvent: Got a GSCAN Event"
        " message from the Driver.");
    unsigned i=0;
    int ret = WIFI_SUCCESS;
    u32 status;
    wifi_scan_result *result = NULL;
    struct nlattr *tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1];

    WifiVendorCommand::handleEvent(event);

    nla_parse(tbVendor, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX,
                        (struct nlattr *)mVendorData,
                        mDataLen, NULL);

    switch(mSubcmd)
    {
        case QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT:
        {
            wifi_request_id reqId;
            u32 len = 0;
            u32 resultsBufSize = 0;
            u32 lengthOfInfoElements = 0;

            ALOGD("Event QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT "
                "received.");

            if (!tbVendor[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID])
            {
                ALOGE("%s: ATTR_GSCAN_RESULTS_REQUEST_ID not found. Exit.",
                    __func__);
                ret = WIFI_ERROR_INVALID_ARGS;
                break;
            }
            reqId = nla_get_u32(
                    tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
                    );
            /* If this is not for us, just ignore it. */
            if (reqId != mRequestId) {
                ALOGE("%s: Event has Req. ID:%d <> Ours:%d, ignore it.",
                    __func__, reqId, mRequestId);
                break;
            }

            /* Parse and extract the results. */
            if (!
                tbVendor[
                    QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_LENGTH
                ])
            {
                ALOGE("%s:RESULTS_SCAN_RESULT_IE_LENGTH not found", __func__);
                ret = WIFI_ERROR_INVALID_ARGS;
                break;
            }
            lengthOfInfoElements =
                nla_get_u32(
                tbVendor[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_LENGTH]);
            ALOGI("%s: RESULTS_SCAN_RESULT_IE_LENGTH =%d",
                __func__, lengthOfInfoElements);
            resultsBufSize =
                lengthOfInfoElements + sizeof(wifi_scan_result);
            result = (wifi_scan_result *) malloc (resultsBufSize);
            if (!result) {
                ALOGE("%s: Failed to alloc memory for result struct. Exit.\n",
                    __func__);
                ret = WIFI_ERROR_OUT_OF_MEMORY;
                break;
            }
            memset(result, 0, resultsBufSize);

            result->ie_length = lengthOfInfoElements;

            /* Extract and fill out the wifi_scan_result struct. */
            if (!
            tbVendor[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
                ])
            {
                ALOGE("%s: RESULTS_SCAN_RESULT_TIME_STAMP not found",
                    __func__);
                ret = WIFI_ERROR_INVALID_ARGS;
                break;
            }
            result->ts =
                nla_get_u64(
                tbVendor[
                    QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
                    ]);

            if (!
                tbVendor[
                    QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID
                    ])
            {
                ALOGE("%s: RESULTS_SCAN_RESULT_SSID not found", __func__);
                ret = WIFI_ERROR_INVALID_ARGS;
                break;
            }
            len = nla_len(tbVendor[
                    QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]);
            len =
                sizeof(result->ssid) <= len ? sizeof(result->ssid) : len;
            memcpy((void *)&result->ssid,
                nla_data(
                tbVendor[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]), len);

            if (!
                tbVendor[
                    QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID
                    ])
            {
                ALOGE("%s: RESULTS_SCAN_RESULT_BSSID not found", __func__);
                ret = WIFI_ERROR_INVALID_ARGS;
                break;
            }
            len = nla_len(
                tbVendor[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]);
            len =
                sizeof(result->bssid) <= len ? sizeof(result->bssid) : len;
            memcpy(&result->bssid,
                nla_data(
                tbVendor[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]), len);

            if (!
                tbVendor[
                    QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL
                    ])
            {
                ALOGE("%s: RESULTS_SCAN_RESULT_CHANNEL not found", __func__);
                ret = WIFI_ERROR_INVALID_ARGS;
                break;
            }
            result->channel =
                nla_get_u32(
                tbVendor[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL]);

            if (!
                tbVendor[
                    QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI
                    ])
            {
                ALOGE("%s: RESULTS_SCAN_RESULT_RSSI not found", __func__);
                ret = WIFI_ERROR_INVALID_ARGS;
                break;
            }
            result->rssi =
                nla_get_u32(
                tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI]
                );

            if (!
                tbVendor[
                    QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT
                    ])
            {
                ALOGE("%s: RESULTS_SCAN_RESULT_RTT not found", __func__);
                ret = WIFI_ERROR_INVALID_ARGS;
                break;
            }
            result->rtt =
                nla_get_u32(
                tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT]);

            if (!
                tbVendor[
                    QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD
                ])
            {
                ALOGE("%s: RESULTS_SCAN_RESULT_RTT_SD not found", __func__);
                ret = WIFI_ERROR_INVALID_ARGS;
                break;
            }
            result->rtt_sd =
                nla_get_u32(
                tbVendor[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD]);

            if (!
                tbVendor[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD])
            {
                ALOGE("%s: RESULTS_SCAN_RESULT_BEACON_PERIOD not found",
                    __func__);
                ret = WIFI_ERROR_INVALID_ARGS;
                break;
            }
            result->beacon_period =
                nla_get_u16(
                tbVendor[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD]);

            if (!
                tbVendor[
                    QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CAPABILITY
                    ])
            {
                ALOGE("%s: RESULTS_SCAN_RESULT_CAPABILITY not found", __func__);
                ret = WIFI_ERROR_INVALID_ARGS;
                break;
            }
            result->capability =
                nla_get_u16(
                tbVendor[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CAPABILITY]);

            if (!
                tbVendor[
                    QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_DATA
                ])
            {
                ALOGE("%s: RESULTS_SCAN_RESULT_IE_DATA not found", __func__);
                ret = WIFI_ERROR_INVALID_ARGS;
                break;
            }
            memcpy(&(result->ie_data[0]),
                nla_data(tbVendor[
                    QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_DATA]),
                lengthOfInfoElements);

            ALOGE("handleEvent:FULL_SCAN_RESULTS: ts  %lld ", result->ts);
            ALOGE("handleEvent:FULL_SCAN_RESULTS: SSID  %s ", result->ssid) ;
            ALOGE("handleEvent:FULL_SCAN_RESULTS: "
                "BSSID: %02x:%02x:%02x:%02x:%02x:%02x \n",
                result->bssid[0], result->bssid[1], result->bssid[2],
                result->bssid[3], result->bssid[4], result->bssid[5]);
            ALOGE("handleEvent:FULL_SCAN_RESULTS: channel %d ",
                result->channel);
            ALOGE("handleEvent:FULL_SCAN_RESULTS: rssi  %d ", result->rssi);
            ALOGE("handleEvent:FULL_SCAN_RESULTS: rtt  %lld ", result->rtt);
            ALOGE("handleEvent:FULL_SCAN_RESULTS: rtt_sd  %lld ",
                result->rtt_sd);
            ALOGE("handleEvent:FULL_SCAN_RESULTS: beacon period  %d ",
                result->beacon_period);
            ALOGE("handleEvent:FULL_SCAN_RESULTS: capability  %d ",
                result->capability);
            ALOGE("handleEvent:FULL_SCAN_RESULTS: IE length  %d ",
                result->ie_length);

            ALOGE("%s: Invoking the callback. \n", __func__);
            if (mHandler.on_full_scan_result) {
                (*mHandler.on_full_scan_result)(reqId, result);
                /* Reset flag and num counter. */
                free(result);
                result = NULL;
            }
        }
        break;

        case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE:
        {
            wifi_request_id id;
            u32 numResults = 0;

            ALOGD("Event "
                "QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE "
                "received.");

            if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]) {
                ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID"
                    "not found. Exit", __func__);
                ret = WIFI_ERROR_INVALID_ARGS;
                break;
            }
            id = nla_get_u32(
                    tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
                    );
            /* If this is not for us, then ignore it. */
            if (id != mRequestId) {
                ALOGE("%s: Event has Req. ID:%d <> ours:%d",
                    __func__, id, mRequestId);
                break;
            }
            if (!tbVendor[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]) {
                ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not found",
                    __func__);
                ret = WIFI_ERROR_INVALID_ARGS;
                break;
            }
            numResults = nla_get_u32(tbVendor[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]);
            ALOGE("%s: number of results:%d", __func__, numResults);

            /* Invoke the callback func to report the number of results. */
            ALOGE("%s: Calling on_scan_results_available handler",
                __func__);
            if (!mHandler.on_scan_results_available) {
                break;
            }
            (*mHandler.on_scan_results_available)(id, numResults);
        }
        break;

        case QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND:
        {
            wifi_request_id id;
            u32 resultsBufSize = 0;
            u32 numResults = 0;
            u32 startingIndex, sizeOfObtainedResults;

            ALOGD("Event QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND "
                "received.");

            id = nla_get_u32(
                    tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
                    );
            /* If this is not for us, just ignore it. */
            if (id != mRequestId) {
                ALOGE("%s: Event has Req. ID:%d <> ours:%d",
                    __func__, id, mRequestId);
                break;
            }
            if (!tbVendor[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]) {
                ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not found",
                    __func__);
                ret = WIFI_ERROR_INVALID_ARGS;
                break;
            }
            numResults = nla_get_u32(tbVendor[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]);
            ALOGE("%s: number of results:%d", __func__, numResults);

            /* Get the memory size of previous fragments, if any. */
            sizeOfObtainedResults = mHotlistApFoundNumResults *
                          sizeof(wifi_scan_result);

            mHotlistApFoundNumResults += numResults;
            resultsBufSize += mHotlistApFoundNumResults *
                                            sizeof(wifi_scan_result);

            /* Check if this chunck of scan results is a continuation of
             * a previous one.
             */
            if (mHotlistApFoundMoreData) {
                mHotlistApFoundResults = (wifi_scan_result *)
                            realloc (mHotlistApFoundResults, resultsBufSize);
            } else {
                mHotlistApFoundResults = (wifi_scan_result *)
                            malloc (resultsBufSize);
            }

            if (!mHotlistApFoundResults) {
                ALOGE("%s: Failed to alloc memory for results array. Exit.\n",
                    __func__);
                ret = WIFI_ERROR_OUT_OF_MEMORY;
                break;
            }
            /* Initialize the newly allocated memory area with 0. */
            memset((u8 *)mHotlistApFoundResults + sizeOfObtainedResults, 0,
                    resultsBufSize - sizeOfObtainedResults);

            ALOGE("%s: Num of AP FOUND results = %d. \n", __func__,
                                            mHotlistApFoundNumResults);

            /* To support fragmentation from firmware, monitor the
             * MORE_DTATA flag and cache results until MORE_DATA = 0.
             * Only then we can pass on the results to framework through
             * the callback function.
             */
            if (!tbVendor[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]) {
                ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_MORE_DATA not"
                    " found", __func__);
                ret = WIFI_ERROR_INVALID_ARGS;
                break;
            } else {
                mHotlistApFoundMoreData = nla_get_u8(
                    tbVendor[
                    QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]);
                ALOGE("%s: More data = %d. \n",
                    __func__, mHotlistApFoundMoreData);
            }

            ALOGE("%s: Extract hotlist_ap_found results.\n", __func__);
            startingIndex = mHotlistApFoundNumResults - numResults;
            ALOGE("%s: starting_index:%d",
                __func__, startingIndex);
            ret = gscan_get_hotlist_ap_found_results(numResults,
                                                mHotlistApFoundResults,
                                                startingIndex,
                                                tbVendor);
            /* If a parsing error occurred, exit and proceed for cleanup. */
            if (ret)
                break;
            /* Send the results if no more result data fragments are expected. */
            if (!mHotlistApFoundMoreData) {
                (*mHandler.on_hotlist_ap_found)(id,
                                                mHotlistApFoundNumResults,
                                                mHotlistApFoundResults);
                /* Reset flag and num counter. */
                free(mHotlistApFoundResults);
                mHotlistApFoundResults = NULL;
                mHotlistApFoundMoreData = false;
                mHotlistApFoundNumResults = 0;
            }
        }
        break;

        case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE:
        {
            wifi_request_id reqId;
            u32 numResults = 0, sizeOfObtainedResults;
            u32 startingIndex, index = 0;
            struct nlattr *scanResultsInfo;
            int rem = 0;

            ALOGD("Event QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE "
                "received.");

            if (!tbVendor[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID])
            {
                ALOGE("%s: ATTR_GSCAN_RESULTS_REQUEST_ID not found. Exit.",
                    __func__);
                ret = WIFI_ERROR_INVALID_ARGS;
                break;
            }
            reqId = nla_get_u32(
                    tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
                    );
            /* If this is not for us, just ignore it. */
            if (reqId != mRequestId) {
                ALOGE("%s: Event has Req. ID:%d <> ours:%d",
                    __func__, reqId, mRequestId);
                break;
            }
            if (!tbVendor[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE])
            {
                ALOGE("%s: ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not found."
                    "Exit.", __func__);
                ret = WIFI_ERROR_INVALID_ARGS;
                break;
            }
            numResults = nla_get_u32(tbVendor[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]);
            /* Get the memory size of previous fragments, if any. */
            sizeOfObtainedResults = sizeof(wifi_significant_change_result *) *
                                mSignificantChangeNumResults;

            index = mSignificantChangeNumResults;
            mSignificantChangeNumResults += numResults;
            /*
             * Check if this chunck of wifi_significant_change results is a
             * continuation of a previous one.
             */
            if (mSignificantChangeMoreData) {
                mSignificantChangeResults =
                    (wifi_significant_change_result **)
                        realloc (mSignificantChangeResults,
                        sizeof(wifi_significant_change_result *) *
                                mSignificantChangeNumResults);
            } else {
                mSignificantChangeResults =
                    (wifi_significant_change_result **)
                        malloc (sizeof(wifi_significant_change_result *) *
                                mSignificantChangeNumResults);
            }

            if (!mSignificantChangeResults) {
                ALOGE("%s: Failed to alloc memory for results array. Exit.\n",
                    __func__);
                ret = WIFI_ERROR_OUT_OF_MEMORY;
                break;
            }
            /* Initialize the newly allocated memory area with 0. */
            memset((u8 *)mSignificantChangeResults + sizeOfObtainedResults, 0,
                    sizeof(wifi_significant_change_result *) *
                                numResults);
            ALOGD("%s: mSignificantChangeMoreData = %d",
                    __func__, mSignificantChangeMoreData);

            for (scanResultsInfo = (struct nlattr *) nla_data(tbVendor[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]),
                rem = nla_len(tbVendor[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]);
                nla_ok(scanResultsInfo, rem);
                scanResultsInfo = nla_next(scanResultsInfo, &(rem)))
            {
                u32 num_rssi = 0;
                u32 resultsBufSize = 0;
                struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1];
                nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX,
                    (struct nlattr *) nla_data(scanResultsInfo),
                    nla_len(scanResultsInfo), NULL);
                if (!tb2[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI
                    ])
                {
                    ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_"
                        "SIGNIFICANT_CHANGE_RESULT_NUM_RSSI not found. "
                        "Exit.", __func__);
                    ret = WIFI_ERROR_INVALID_ARGS;
                    break;
                }
                num_rssi = nla_get_u32(tb2[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI
                        ]);
                resultsBufSize = sizeof(wifi_significant_change_result) +
                            num_rssi * sizeof(wifi_rssi);
                mSignificantChangeResults[index] =
                    (wifi_significant_change_result *) malloc (resultsBufSize);

                if (!mSignificantChangeResults[index]) {
                    ALOGE("%s: Failed to alloc memory for results array. Exit.\n",
                        __func__);
                    ret = WIFI_ERROR_OUT_OF_MEMORY;
                    break;
                }
                /* Initialize the newly allocated memory area with 0. */
                memset((u8 *)mSignificantChangeResults[index],
                        0, resultsBufSize);

                ALOGE("%s: For Significant Change results[%d], num_rssi:%d\n",
                    __func__, index, num_rssi);
                index++;
            }

            ALOGE("%s: Extract significant change results.\n", __func__);
            startingIndex =
                mSignificantChangeNumResults - numResults;
            ret = gscan_get_significant_change_results(numResults,
                                                mSignificantChangeResults,
                                                startingIndex,
                                                tbVendor);
            /* If a parsing error occurred, exit and proceed for cleanup. */
            if (ret)
                break;
            /* To support fragmentation from firmware, monitor the
             * MORE_DTATA flag and cache results until MORE_DATA = 0.
             * Only then we can pass on the results to framework through
             * the callback function.
             */
            if (!tbVendor[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]) {
                ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_MORE_DATA not"
                    " found. Stop parsing and exit.", __func__);
                break;
            }
            mSignificantChangeMoreData = nla_get_u8(
                tbVendor[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]);
            ALOGE("%s: More data = %d. \n",
                __func__, mSignificantChangeMoreData);

            /* Send the results if no more result fragments are expected */
            if (!mSignificantChangeMoreData) {
                ALOGE("%s: Invoking the callback. \n", __func__);
                (*mHandler.on_significant_change)(reqId,
                                              mSignificantChangeNumResults,
                                              mSignificantChangeResults);
                /* Reset flag and num counter. */
                for (index = 0; index  < mSignificantChangeNumResults; index++)
                {
                    free(mSignificantChangeResults[index]);
                    mSignificantChangeResults[index] = NULL;
                }
                free(mSignificantChangeResults);
                mSignificantChangeResults = NULL;
                mSignificantChangeNumResults = 0;
                mSignificantChangeMoreData = false;
            }
        }
        break;

        case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT:
        {
            wifi_scan_event scanEvent;
            u32 scanEventStatus = 0;
            wifi_request_id reqId;

            ALOGD("Event QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT "
                "received.");

            if (!tbVendor[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID])
            {
                ALOGE("%s: ATTR_GSCAN_RESULTS_REQUEST_ID not found. Exit.",
                    __func__);
                ret = WIFI_ERROR_INVALID_ARGS;
                break;
            }
            reqId = nla_get_u32(
                    tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
                    );
            /* If this is not for us, just ignore it. */
            if (reqId != mRequestId) {
                ALOGE("%s: Event has Req. ID:%d <> ours:%d",
                    __func__, reqId, mRequestId);
                break;
            }

            if (!tbVendor[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_EVENT_TYPE]) {
                ALOGE("%s: GSCAN_RESULTS_SCAN_EVENT_TYPE not"
                    " found. Stop parsing and exit.", __func__);
                break;
            }
            scanEvent = (wifi_scan_event) nla_get_u8(tbVendor[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_EVENT_TYPE]);

            if (!tbVendor[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_EVENT_STATUS]) {
                ALOGE("%s: GSCAN_RESULTS_SCAN_EVENT_STATUS not"
                    " found. Stop parsing and exit.", __func__);
                break;
            }
            scanEventStatus = nla_get_u32(tbVendor[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_EVENT_STATUS]);

            ALOGE("%s: Scan event type: %d, status = %d. \n", __func__,
                                    scanEvent, scanEventStatus);
            /* Send the results if no more result fragments are expected. */
            (*mHandler.on_scan_event)(scanEvent, scanEventStatus);
        }
        break;

        default:
            /* Error case should not happen print log */
            ALOGE("%s: Wrong GScan subcmd received %d", __func__, mSubcmd);
    }

    /* A parsing error occurred, do the cleanup of gscan result lists. */
    if (ret) {
        switch(mSubcmd)
        {
            case QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT:
            {
                free(result);
                result = NULL;
            }
            break;

            case QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND:
            {
                /* Reset flag and num counter. */
                free(mHotlistApFoundResults);
                mHotlistApFoundResults = NULL;
                mHotlistApFoundMoreData = false;
                mHotlistApFoundNumResults = 0;
            }
            break;

            case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE:
            {
                for (i = 0; i < mSignificantChangeNumResults; i++)
                {
                    if (mSignificantChangeResults[i]) {
                        free(mSignificantChangeResults[i]);
                        mSignificantChangeResults[i] = NULL;
                    }
                }
                free(mSignificantChangeResults);
                mSignificantChangeResults = NULL;
                mSignificantChangeNumResults = 0;
                mSignificantChangeMoreData = false;
            }
            break;

            case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE:
            break;

            case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT:
            break;

            default:
                ALOGE("%s: Parsing err handler: wrong GScan subcmd "
                    "received %d", __func__, mSubcmd);
        }
    }
    return NL_SKIP;
}
Exemplo n.º 17
0
static int queue_userspace_packet(int dp_ifindex, struct sk_buff *skb,
				  const struct dp_upcall_info *upcall_info)
{
	struct ovs_header *upcall;
	struct sk_buff *nskb = NULL;
	struct sk_buff *user_skb; /* to be queued to userspace */
	struct nlattr *nla;
	unsigned int len;
	int err;

	if (vlan_tx_tag_present(skb)) {
		nskb = skb_clone(skb, GFP_ATOMIC);
		if (!nskb)
			return -ENOMEM;

		nskb = __vlan_put_tag(nskb, vlan_tx_tag_get(nskb));
		if (!nskb)
			return -ENOMEM;

		nskb->vlan_tci = 0;
		skb = nskb;
	}

	if (nla_attr_size(skb->len) > USHRT_MAX) {
		err = -EFBIG;
		goto out;
	}

	len = sizeof(struct ovs_header);
	len += nla_total_size(skb->len);
	len += nla_total_size(FLOW_BUFSIZE);
	if (upcall_info->cmd == OVS_PACKET_CMD_ACTION)
		len += nla_total_size(8);

	user_skb = genlmsg_new(len, GFP_ATOMIC);
	if (!user_skb) {
		err = -ENOMEM;
		goto out;
	}

	upcall = genlmsg_put(user_skb, 0, 0, &dp_packet_genl_family,
			     0, upcall_info->cmd);
	upcall->dp_ifindex = dp_ifindex;

	nla = nla_nest_start(user_skb, OVS_PACKET_ATTR_KEY);
	ovs_flow_to_nlattrs(upcall_info->key, user_skb);
	nla_nest_end(user_skb, nla);

	if (upcall_info->userdata)
		nla_put_u64(user_skb, OVS_PACKET_ATTR_USERDATA,
			    nla_get_u64(upcall_info->userdata));

	nla = __nla_reserve(user_skb, OVS_PACKET_ATTR_PACKET, skb->len);

	skb_copy_and_csum_dev(skb, nla_data(nla));

	err = genlmsg_unicast(&init_net, user_skb, upcall_info->pid);

out:
	kfree_skb(nskb);
	return err;
}
static int print_iface_handler(struct nl_msg *msg, void *arg)
{
	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
	struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
	unsigned int *wiphy = arg;
	const char *indent = "";

	nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
		  genlmsg_attrlen(gnlh, 0), NULL);

	if (wiphy && tb_msg[NL80211_ATTR_WIPHY]) {
		unsigned int thiswiphy = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY]);
		indent = "\t";
		if (*wiphy != thiswiphy)
			printf("phy#%d\n", thiswiphy);
		*wiphy = thiswiphy;
	}

	if (tb_msg[NL80211_ATTR_IFNAME])
		printf("%sInterface %s\n", indent, nla_get_string(tb_msg[NL80211_ATTR_IFNAME]));
	else
		printf("%sUnnamed/non-netdev interface\n", indent);
	if (tb_msg[NL80211_ATTR_IFINDEX])
		printf("%s\tifindex %d\n", indent, nla_get_u32(tb_msg[NL80211_ATTR_IFINDEX]));
	if (tb_msg[NL80211_ATTR_WDEV])
		printf("%s\twdev 0x%llx\n", indent,
		       (unsigned long long)nla_get_u64(tb_msg[NL80211_ATTR_WDEV]));
	if (tb_msg[NL80211_ATTR_MAC]) {
		char mac_addr[20];
		mac_addr_n2a(mac_addr, nla_data(tb_msg[NL80211_ATTR_MAC]));
		printf("%s\taddr %s\n", indent, mac_addr);
	}
	if (tb_msg[NL80211_ATTR_SSID]) {
		printf("%s\tssid ", indent);
		print_ssid_escaped(nla_len(tb_msg[NL80211_ATTR_SSID]),
				   nla_data(tb_msg[NL80211_ATTR_SSID]));
		printf("\n");
	}
	if (tb_msg[NL80211_ATTR_IFTYPE])
		printf("%s\ttype %s\n", indent, iftype_name(nla_get_u32(tb_msg[NL80211_ATTR_IFTYPE])));
	if (!wiphy && tb_msg[NL80211_ATTR_WIPHY])
		printf("%s\twiphy %d\n", indent, nla_get_u32(tb_msg[NL80211_ATTR_WIPHY]));
	if (tb_msg[NL80211_ATTR_WIPHY_FREQ]) {
		uint32_t freq = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_FREQ]);

		printf("%s\tchannel %d (%d MHz)", indent,
		       ieee80211_frequency_to_channel(freq), freq);

		if (tb_msg[NL80211_ATTR_CHANNEL_WIDTH]) {
			printf(", width: %s",
				channel_width_name(nla_get_u32(tb_msg[NL80211_ATTR_CHANNEL_WIDTH])));
			if (tb_msg[NL80211_ATTR_CENTER_FREQ1])
				printf(", center1: %d MHz",
					nla_get_u32(tb_msg[NL80211_ATTR_CENTER_FREQ1]));
			if (tb_msg[NL80211_ATTR_CENTER_FREQ2])
				printf(", center2: %d MHz",
					nla_get_u32(tb_msg[NL80211_ATTR_CENTER_FREQ2]));
		} else if (tb_msg[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
			enum nl80211_channel_type channel_type;

			channel_type = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
			printf(" %s", channel_type_name(channel_type));
		}

		printf("\n");
	}

	return NL_SKIP;
}
Exemplo n.º 19
0
void
process_neigh_msg(struct nlmsghdr *nlmsg, int type) {
    int hdrlen, attrlen;
    struct nlattr *attr;
    struct ndmsg *nbh;
    switchlink_mac_addr_t mac_addr;
    bool mac_addr_valid = false;
    bool ipaddr_valid = false;
    switchlink_ip_addr_t ipaddr;

    assert((type == RTM_NEWNEIGH) || (type == RTM_DELNEIGH));
    nbh = nlmsg_data(nlmsg);
    hdrlen = sizeof(struct ndmsg);
    NL_LOG_DEBUG(("%sneigh: family = %d, ifindex = %d, state = 0x%x, "
                  "flags = 0x%x, type = %d\n",
                  ((type == RTM_NEWNEIGH) ? "new" : "del"),
                  nbh->ndm_family, nbh->ndm_ifindex, nbh->ndm_state,
                  nbh->ndm_flags, nbh->ndm_type));

    switchlink_db_interface_info_t ifinfo;
    if (switchlink_db_interface_get_info(nbh->ndm_ifindex, &ifinfo) !=
        SWITCHLINK_DB_STATUS_SUCCESS) {
        NL_LOG_DEBUG(("neigh: switchlink_db_interface_get_info failed\n"));
        return;
    }

    if (strncmp(ifinfo.ifname, SWITCHLINK_CPU_INTERFACE_NAME,
                SWITCHLINK_INTERFACE_NAME_LEN_MAX) == 0) {
        NL_LOG_DEBUG(("neigh: skipping neighbor on CPU interface\n"));
        return;
    }

    memset(&ipaddr, 0, sizeof(switchlink_ip_addr_t));
    attrlen = nlmsg_attrlen(nlmsg, hdrlen);
    attr = nlmsg_attrdata(nlmsg, hdrlen);
    while (nla_ok(attr, attrlen)) {
        int attr_type = nla_type(attr);
        switch (attr_type) {
            case NDA_DST:
                ipaddr_valid = true;
                ipaddr.family = nbh->ndm_family;
                if (nbh->ndm_family == AF_INET) {
                    ipaddr.ip.v4addr.s_addr = ntohl(nla_get_u32(attr));
                    ipaddr.prefix_len = 32;
                } else {
                    memcpy(&(ipaddr.ip.v6addr), nla_data(attr), nla_len(attr));
                    ipaddr.prefix_len = 128;
                }
                break;
            case NDA_LLADDR: {
                uint64_t lladdr;
                mac_addr_valid = true;
                lladdr = nla_get_u64(attr);
                memcpy(mac_addr, &lladdr, 6);
                break;
            }
            default:
                NL_LOG_DEBUG(("neigh: skipping attr(%d)\n", attr_type));
                break;
        }
        attr = nla_next(attr, &attrlen);
    }

    switchlink_handle_t intf_h = ifinfo.intf_h;
    switchlink_handle_t bridge_h = 0;
    if (ifinfo.intf_type == SWITCHLINK_INTF_TYPE_L2_ACCESS) {
        bridge_h = ifinfo.bridge_h;
        assert(bridge_h);
    }

    if (type == RTM_NEWNEIGH) {
        if (bridge_h && mac_addr_valid) {
            mac_create(mac_addr, bridge_h, intf_h);
        }
        if (ipaddr_valid) {
            if (mac_addr_valid) {
                neigh_create(g_default_vrf_h, &ipaddr, mac_addr, intf_h);
            } else {
                // mac address is not valid, remove the neighbor entry
                neigh_delete(g_default_vrf_h, &ipaddr, intf_h);
            }
        }
    } else {
        if (bridge_h && mac_addr_valid) {
            mac_delete(mac_addr, bridge_h);
        }
        if (ipaddr_valid) {
            neigh_delete(g_default_vrf_h, &ipaddr, intf_h);
        }
    }
}