static void get_wifi_wmm_ac_stat(wifi_wmm_ac_stat *stats, struct nlattr **tb_vendor) { stats->ac = (wifi_traffic_ac)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC]); stats->tx_mpdu = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU]); stats->rx_mpdu = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU]); stats->tx_mcast = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST]); stats->rx_mcast = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST]); stats->rx_ampdu = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU]); stats->tx_ampdu = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU]); stats->mpdu_lost = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST]); stats->retries = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES]); stats->retries_short = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT]); stats->retries_long = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG]); stats->contention_time_min = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN]); stats->contention_time_max = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX]); stats->contention_time_avg = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG]); stats->contention_num_samples = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES]); ALOGI("STATS IFACE: ac %u ", stats->ac); ALOGI("STATS IFACE: txMpdu %u ", stats->tx_mpdu) ; ALOGI("STATS IFACE: rxMpdu %u ", stats->rx_mpdu); ALOGI("STATS IFACE: txMcast %u ", stats->tx_mcast); ALOGI("STATS IFACE: rxMcast %u ", stats->rx_mcast); ALOGI("STATS IFACE: rxAmpdu %u ", stats->rx_ampdu); ALOGI("STATS IFACE: txAmpdu %u ", stats->tx_ampdu); ALOGI("STATS IFACE: mpduLost %u ", stats->mpdu_lost); ALOGI("STATS IFACE: retries %u ", stats->retries); ALOGI("STATS IFACE: retriesShort %u ", stats->retries_short); ALOGI("STATS IFACE: retriesLong %u ", stats->retries_long); ALOGI("STATS IFACE: contentionTimeMin %u ", stats->contention_time_min); ALOGI("STATS IFACE: contentionTimeMax %u ", stats->contention_time_max); ALOGI("STATS IFACE: contentionTimeAvg %u ", stats->contention_time_avg); ALOGI("STATS IFACE: contentionNumSamples %u ", stats->contention_num_samples); }
static int fq_codel_change(struct Qdisc *sch, struct nlattr *opt) { struct fq_codel_sched_data *q = qdisc_priv(sch); struct nlattr *tb[TCA_FQ_CODEL_MAX + 1]; int err; if (!opt) return -EINVAL; err = nla_parse_nested(tb, TCA_FQ_CODEL_MAX, opt, fq_codel_policy); if (err < 0) return err; if (tb[TCA_FQ_CODEL_FLOWS]) { if (q->flows) return -EINVAL; q->flows_cnt = nla_get_u32(tb[TCA_FQ_CODEL_FLOWS]); if (!q->flows_cnt || q->flows_cnt > 65536) return -EINVAL; } sch_tree_lock(sch); if (tb[TCA_FQ_CODEL_TARGET]) { u64 target = nla_get_u32(tb[TCA_FQ_CODEL_TARGET]); q->cparams.target = (target * NSEC_PER_USEC) >> CODEL_SHIFT; } if (tb[TCA_FQ_CODEL_CE_THRESHOLD]) { u64 val = nla_get_u32(tb[TCA_FQ_CODEL_CE_THRESHOLD]); q->cparams.ce_threshold = (val * NSEC_PER_USEC) >> CODEL_SHIFT; } if (tb[TCA_FQ_CODEL_INTERVAL]) { u64 interval = nla_get_u32(tb[TCA_FQ_CODEL_INTERVAL]); q->cparams.interval = (interval * NSEC_PER_USEC) >> CODEL_SHIFT; } if (tb[TCA_FQ_CODEL_LIMIT]) sch->limit = nla_get_u32(tb[TCA_FQ_CODEL_LIMIT]); if (tb[TCA_FQ_CODEL_ECN]) q->cparams.ecn = !!nla_get_u32(tb[TCA_FQ_CODEL_ECN]); if (tb[TCA_FQ_CODEL_QUANTUM]) q->quantum = max(256U, nla_get_u32(tb[TCA_FQ_CODEL_QUANTUM])); if (tb[TCA_FQ_CODEL_DROP_BATCH_SIZE]) q->drop_batch_size = min(1U, nla_get_u32(tb[TCA_FQ_CODEL_DROP_BATCH_SIZE])); if (tb[TCA_FQ_CODEL_MEMORY_LIMIT]) q->memory_limit = min(1U << 31, nla_get_u32(tb[TCA_FQ_CODEL_MEMORY_LIMIT])); while (sch->q.qlen > sch->limit || q->memory_usage > q->memory_limit) { struct sk_buff *skb = fq_codel_dequeue(sch); q->cstats.drop_len += qdisc_pkt_len(skb); kfree_skb(skb); q->cstats.drop_count++; } qdisc_tree_reduce_backlog(sch, q->cstats.drop_count, q->cstats.drop_len); q->cstats.drop_count = 0; q->cstats.drop_len = 0; sch_tree_unlock(sch); return 0; }
static int rule_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, struct nlmsghdr *n, struct nl_parser_param *pp) { struct rtnl_rule *rule; struct rtmsg *r; struct nlattr *tb[RTA_MAX+1]; int err = 1; rule = rtnl_rule_alloc(); if (!rule) { err = nl_errno(ENOMEM); goto errout; } rule->ce_msgtype = n->nlmsg_type; r = nlmsg_data(n); err = nlmsg_parse(n, sizeof(*r), tb, RTA_MAX, rule_policy); if (err < 0) goto errout; rule->r_family = r->rtm_family; rule->r_type = r->rtm_type; rule->r_dsfield = r->rtm_tos; rule->r_src_len = r->rtm_src_len; rule->r_dst_len = r->rtm_dst_len; rule->r_table = r->rtm_table; rule->ce_mask = (RULE_ATTR_FAMILY | RULE_ATTR_TYPE | RULE_ATTR_DSFIELD | RULE_ATTR_SRC_LEN | RULE_ATTR_DST_LEN |RULE_ATTR_TYPE); if (tb[RTA_PRIORITY]) { rule->r_prio = nla_get_u32(tb[RTA_PRIORITY]); rule->ce_mask |= RULE_ATTR_PRIO; } if (tb[RTA_SRC]) { rule->r_src = nla_get_addr(tb[RTA_SRC], r->rtm_family); if (!rule->r_src) { err = nl_errno(ENOMEM); goto errout; } nl_addr_set_prefixlen(rule->r_src, r->rtm_src_len); rule->ce_mask |= RULE_ATTR_SRC; } if (tb[RTA_DST]) { rule->r_dst = nla_get_addr(tb[RTA_DST], r->rtm_family); if (!rule->r_dst) { err = nl_errno(ENOMEM); goto errout; } nl_addr_set_prefixlen(rule->r_dst, r->rtm_dst_len); rule->ce_mask |= RULE_ATTR_DST; } if (tb[RTA_PROTOINFO]) { rule->r_mark = nla_get_u32(tb[RTA_PROTOINFO]); rule->ce_mask |= RULE_ATTR_MARK; } if (tb[RTA_IIF]) { nla_strlcpy(rule->r_iif, tb[RTA_IIF], IFNAMSIZ); rule->ce_mask |= RULE_ATTR_IIF; } if (tb[RTA_FLOW]) { rule->r_realms = nla_get_u32(tb[RTA_FLOW]); rule->ce_mask |= RULE_ATTR_REALMS; } if (tb[RTA_GATEWAY]) { rule->r_srcmap = nla_get_addr(tb[RTA_GATEWAY], r->rtm_family); if (!rule->r_srcmap) { err = nl_errno(ENOMEM); goto errout; } rule->ce_mask |= RULE_ATTR_SRCMAP; } err = pp->pp_cb((struct nl_object *) rule, pp); if (err < 0) goto errout; return P_ACCEPT; errout: rtnl_rule_put(rule); return err; }
static void __fill_bc_link_stat(struct tipc_nl_compat_msg *msg, struct nlattr *prop[], struct nlattr *stats[]) { tipc_tlv_sprintf(msg->rep, " Window:%u packets\n", nla_get_u32(prop[TIPC_NLA_PROP_WIN])); tipc_tlv_sprintf(msg->rep, " RX packets:%u fragments:%u/%u bundles:%u/%u\n", nla_get_u32(stats[TIPC_NLA_STATS_RX_INFO]), nla_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTS]), nla_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTED]), nla_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLES]), nla_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLED])); tipc_tlv_sprintf(msg->rep, " TX packets:%u fragments:%u/%u bundles:%u/%u\n", nla_get_u32(stats[TIPC_NLA_STATS_TX_INFO]), nla_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTS]), nla_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTED]), nla_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLES]), nla_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLED])); tipc_tlv_sprintf(msg->rep, " RX naks:%u defs:%u dups:%u\n", nla_get_u32(stats[TIPC_NLA_STATS_RX_NACKS]), nla_get_u32(stats[TIPC_NLA_STATS_RX_DEFERRED]), nla_get_u32(stats[TIPC_NLA_STATS_DUPLICATES])); tipc_tlv_sprintf(msg->rep, " TX naks:%u acks:%u dups:%u\n", nla_get_u32(stats[TIPC_NLA_STATS_TX_NACKS]), nla_get_u32(stats[TIPC_NLA_STATS_TX_ACKS]), nla_get_u32(stats[TIPC_NLA_STATS_RETRANSMITTED])); tipc_tlv_sprintf(msg->rep, " Congestion link:%u Send queue max:%u avg:%u", nla_get_u32(stats[TIPC_NLA_STATS_LINK_CONGS]), nla_get_u32(stats[TIPC_NLA_STATS_MAX_QUEUE]), nla_get_u32(stats[TIPC_NLA_STATS_AVG_QUEUE])); }
static int tipc_nl_compat_name_table_dump(struct tipc_nl_compat_msg *msg, struct nlattr **attrs) { char port_str[27]; struct tipc_name_table_query *ntq; struct nlattr *nt[TIPC_NLA_NAME_TABLE_MAX + 1]; struct nlattr *publ[TIPC_NLA_PUBL_MAX + 1]; u32 node, depth, type, lowbound, upbound; static const char * const scope_str[] = {"", " zone", " cluster", " node"}; nla_parse_nested(nt, TIPC_NLA_NAME_TABLE_MAX, attrs[TIPC_NLA_NAME_TABLE], NULL); nla_parse_nested(publ, TIPC_NLA_PUBL_MAX, nt[TIPC_NLA_NAME_TABLE_PUBL], NULL); ntq = (struct tipc_name_table_query *)TLV_DATA(msg->req); depth = ntohl(ntq->depth); type = ntohl(ntq->type); lowbound = ntohl(ntq->lowbound); upbound = ntohl(ntq->upbound); if (!(depth & TIPC_NTQ_ALLTYPES) && (type != nla_get_u32(publ[TIPC_NLA_PUBL_TYPE]))) return 0; if (lowbound && (lowbound > nla_get_u32(publ[TIPC_NLA_PUBL_UPPER]))) return 0; if (upbound && (upbound < nla_get_u32(publ[TIPC_NLA_PUBL_LOWER]))) return 0; tipc_tlv_sprintf(msg->rep, "%-10u ", nla_get_u32(publ[TIPC_NLA_PUBL_TYPE])); if (depth == 1) goto out; tipc_tlv_sprintf(msg->rep, "%-10u %-10u ", nla_get_u32(publ[TIPC_NLA_PUBL_LOWER]), nla_get_u32(publ[TIPC_NLA_PUBL_UPPER])); if (depth == 2) goto out; node = nla_get_u32(publ[TIPC_NLA_PUBL_NODE]); sprintf(port_str, "<%u.%u.%u:%u>", tipc_zone(node), tipc_cluster(node), tipc_node(node), nla_get_u32(publ[TIPC_NLA_PUBL_REF])); tipc_tlv_sprintf(msg->rep, "%-26s ", port_str); if (depth == 3) goto out; tipc_tlv_sprintf(msg->rep, "%-10u %s", nla_get_u32(publ[TIPC_NLA_PUBL_REF]), scope_str[nla_get_u32(publ[TIPC_NLA_PUBL_SCOPE])]); out: tipc_tlv_sprintf(msg->rep, "\n"); return 0; }
static int l2tp_nl_cmd_tunnel_create(struct sk_buff *skb, struct genl_info *info) { u32 tunnel_id; u32 peer_tunnel_id; int proto_version; int fd; int ret = 0; struct l2tp_tunnel_cfg cfg = { 0, }; struct l2tp_tunnel *tunnel; struct net *net = genl_info_net(info); if (!info->attrs[L2TP_ATTR_CONN_ID]) { ret = -EINVAL; goto out; } tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]); if (!info->attrs[L2TP_ATTR_PEER_CONN_ID]) { ret = -EINVAL; goto out; } peer_tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_PEER_CONN_ID]); if (!info->attrs[L2TP_ATTR_PROTO_VERSION]) { ret = -EINVAL; goto out; } proto_version = nla_get_u8(info->attrs[L2TP_ATTR_PROTO_VERSION]); if (!info->attrs[L2TP_ATTR_ENCAP_TYPE]) { ret = -EINVAL; goto out; } cfg.encap = nla_get_u16(info->attrs[L2TP_ATTR_ENCAP_TYPE]); fd = -1; if (info->attrs[L2TP_ATTR_FD]) { fd = nla_get_u32(info->attrs[L2TP_ATTR_FD]); } else { #if IS_ENABLED(CONFIG_IPV6) if (info->attrs[L2TP_ATTR_IP6_SADDR] && info->attrs[L2TP_ATTR_IP6_DADDR]) { cfg.local_ip6 = nla_data( info->attrs[L2TP_ATTR_IP6_SADDR]); cfg.peer_ip6 = nla_data( info->attrs[L2TP_ATTR_IP6_DADDR]); } else #endif if (info->attrs[L2TP_ATTR_IP_SADDR] && info->attrs[L2TP_ATTR_IP_DADDR]) { cfg.local_ip.s_addr = nla_get_in_addr( info->attrs[L2TP_ATTR_IP_SADDR]); cfg.peer_ip.s_addr = nla_get_in_addr( info->attrs[L2TP_ATTR_IP_DADDR]); } else { ret = -EINVAL; goto out; } if (info->attrs[L2TP_ATTR_UDP_SPORT]) cfg.local_udp_port = nla_get_u16(info->attrs[L2TP_ATTR_UDP_SPORT]); if (info->attrs[L2TP_ATTR_UDP_DPORT]) cfg.peer_udp_port = nla_get_u16(info->attrs[L2TP_ATTR_UDP_DPORT]); if (info->attrs[L2TP_ATTR_UDP_CSUM]) cfg.use_udp_checksums = nla_get_flag(info->attrs[L2TP_ATTR_UDP_CSUM]); #if IS_ENABLED(CONFIG_IPV6) if (info->attrs[L2TP_ATTR_UDP_ZERO_CSUM6_TX]) cfg.udp6_zero_tx_checksums = nla_get_flag(info->attrs[L2TP_ATTR_UDP_ZERO_CSUM6_TX]); if (info->attrs[L2TP_ATTR_UDP_ZERO_CSUM6_RX]) cfg.udp6_zero_rx_checksums = nla_get_flag(info->attrs[L2TP_ATTR_UDP_ZERO_CSUM6_RX]); #endif } if (info->attrs[L2TP_ATTR_DEBUG]) cfg.debug = nla_get_u32(info->attrs[L2TP_ATTR_DEBUG]); tunnel = l2tp_tunnel_find(net, tunnel_id); if (tunnel != NULL) { ret = -EEXIST; goto out; } ret = -EINVAL; switch (cfg.encap) { case L2TP_ENCAPTYPE_UDP: case L2TP_ENCAPTYPE_IP: ret = l2tp_tunnel_create(net, fd, proto_version, tunnel_id, peer_tunnel_id, &cfg, &tunnel); break; } if (ret >= 0) ret = l2tp_tunnel_notify(&l2tp_nl_family, info, tunnel, L2TP_CMD_TUNNEL_CREATE); out: return ret; }
/* Execute a list of actions against 'skb'. */ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb, const struct nlattr *attr, int len, struct ovs_key_ipv4_tunnel *tun_key, bool keep_skb) { /* Every output action needs a separate clone of 'skb', but the common * case is just a single output action, so that doing a clone and * then freeing the original skbuff is wasteful. So the following code * is slightly obscure just to avoid that. */ int prev_port = -1; const struct nlattr *a; int rem; for (a = attr, rem = len; rem > 0; a = nla_next(a, &rem)) { int err = 0; if (prev_port != -1) { do_output(dp, skb_clone(skb, GFP_ATOMIC), prev_port); prev_port = -1; } switch (nla_type(a)) { case OVS_ACTION_ATTR_OUTPUT: prev_port = nla_get_u32(a); break; case OVS_ACTION_ATTR_USERSPACE: output_userspace(dp, skb, a); break; case OVS_ACTION_ATTR_PUSH_VLAN: err = push_vlan(skb, nla_data(a)); if (unlikely(err)) /* skb already freed. */ return err; break; case OVS_ACTION_ATTR_POP_VLAN: err = pop_vlan(skb); break; case OVS_ACTION_ATTR_SET: err = execute_set_action(skb, nla_data(a), tun_key); break; case OVS_ACTION_ATTR_SAMPLE: err = sample(dp, skb, a, tun_key); break; } if (unlikely(err)) { kfree_skb(skb); return err; } } if (prev_port != -1) { if (keep_skb) skb = skb_clone(skb, GFP_ATOMIC); do_output(dp, skb, prev_port); } else if (!keep_skb) consume_skb(skb); return 0; }
static int can_changelink(struct net_device *dev, struct nlattr *tb[], struct nlattr *data[]) { struct can_priv *priv = netdev_priv(dev); int err; /* We need synchronization with dev->stop() */ ASSERT_RTNL(); if (data[IFLA_CAN_BITTIMING]) { struct can_bittiming bt; /* Do not allow changing bittiming while running */ if (dev->flags & IFF_UP) return -EBUSY; memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt)); if ((!bt.bitrate && !bt.tq) || (bt.bitrate && bt.tq)) return -EINVAL; err = can_get_bittiming(dev, &bt); if (err) return err; memcpy(&priv->bittiming, &bt, sizeof(bt)); if (priv->do_set_bittiming) { /* Finally, set the bit-timing registers */ err = priv->do_set_bittiming(dev); if (err) return err; } } if (data[IFLA_CAN_CTRLMODE]) { struct can_ctrlmode *cm; /* Do not allow changing controller mode while running */ if (dev->flags & IFF_UP) return -EBUSY; cm = nla_data(data[IFLA_CAN_CTRLMODE]); if (cm->flags & ~priv->ctrlmode_supported) return -EOPNOTSUPP; priv->ctrlmode &= ~cm->mask; priv->ctrlmode |= cm->flags; } if (data[IFLA_CAN_RESTART_MS]) { /* Do not allow changing restart delay while running */ if (dev->flags & IFF_UP) return -EBUSY; priv->restart_ms = nla_get_u32(data[IFLA_CAN_RESTART_MS]); } if (data[IFLA_CAN_RESTART]) { /* Do not allow a restart while not running */ if (!(dev->flags & IFF_UP)) return -EINVAL; err = can_restart_now(dev); if (err) return err; } return 0; }
int mtk_cfg80211_vendor_set_config(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) { WLAN_STATUS rStatus; UINT_32 u4BufLen; P_GLUE_INFO_T prGlueInfo = NULL; /* CMD_GSCN_REQ_T rCmdGscnParam; */ /* INT_32 i4Status = -EINVAL; */ P_PARAM_WIFI_GSCAN_CMD_PARAMS prWifiScanCmd; struct nlattr *attr[GSCAN_ATTRIBUTE_REPORT_EVENTS + 1]; struct nlattr *pbucket, *pchannel; UINT_32 len_basic, len_bucket, len_channel; int i, j, k; ASSERT(wiphy); ASSERT(wdev); if ((data == NULL) || !data_len) goto nla_put_failure; prWifiScanCmd = (P_PARAM_WIFI_GSCAN_CMD_PARAMS) kalMemAlloc(sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS), VIR_MEM_TYPE); if (!prWifiScanCmd) { DBGLOG(REQ, ERROR, "Can not alloc memory for PARAM_WIFI_GSCAN_CMD_PARAMS\n"); return -ENOMEM; } DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d \r\n", __func__, data_len); kalMemZero(prWifiScanCmd, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); kalMemZero(attr, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_REPORT_EVENTS + 1)); nla_parse_nested(attr, GSCAN_ATTRIBUTE_REPORT_EVENTS, (struct nlattr *)(data - NLA_HDRLEN), nla_parse_policy); len_basic = 0; for (k = GSCAN_ATTRIBUTE_NUM_BUCKETS; k <= GSCAN_ATTRIBUTE_REPORT_EVENTS; k++) { if (attr[k]) { switch (k) { case GSCAN_ATTRIBUTE_BASE_PERIOD: prWifiScanCmd->base_period = nla_get_u32(attr[k]); len_basic += NLA_ALIGN(attr[k]->nla_len); break; case GSCAN_ATTRIBUTE_NUM_BUCKETS: prWifiScanCmd->num_buckets = nla_get_u32(attr[k]); len_basic += NLA_ALIGN(attr[k]->nla_len); DBGLOG(REQ, TRACE, "attr=0x%x, num_buckets=%d nla_len=%d, \r\n", *(UINT_32 *) attr[k], prWifiScanCmd->num_buckets, attr[k]->nla_len); break; } } } pbucket = (struct nlattr *)((UINT_8 *) data + len_basic); DBGLOG(REQ, TRACE, "+++basic attribute size=%d pbucket=%p\r\n", len_basic, pbucket); for (i = 0; i < prWifiScanCmd->num_buckets; i++) { if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_REPORT_EVENTS, (struct nlattr *)pbucket, nla_parse_policy) < 0) goto nla_put_failure; len_bucket = 0; for (k = GSCAN_ATTRIBUTE_NUM_BUCKETS; k <= GSCAN_ATTRIBUTE_REPORT_EVENTS; k++) { if (attr[k]) { switch (k) { case GSCAN_ATTRIBUTE_BUCKETS_BAND: prWifiScanCmd->buckets[i].band = nla_get_u32(attr[k]); len_bucket += NLA_ALIGN(attr[k]->nla_len); break; case GSCAN_ATTRIBUTE_BUCKET_ID: prWifiScanCmd->buckets[i].bucket = nla_get_u32(attr[k]); len_bucket += NLA_ALIGN(attr[k]->nla_len); break; case GSCAN_ATTRIBUTE_BUCKET_PERIOD: prWifiScanCmd->buckets[i].period = nla_get_u32(attr[k]); len_bucket += NLA_ALIGN(attr[k]->nla_len); break; case GSCAN_ATTRIBUTE_REPORT_EVENTS: prWifiScanCmd->buckets[i].report_events = nla_get_u32(attr[k]); len_bucket += NLA_ALIGN(attr[k]->nla_len); break; case GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS: prWifiScanCmd->buckets[i].num_channels = nla_get_u32(attr[k]); len_bucket += NLA_ALIGN(attr[k]->nla_len); DBGLOG(REQ, TRACE, "bucket%d: attr=0x%x, num_channels=%d nla_len = %d, \r\n", i, *(UINT_32 *) attr[k], nla_get_u32(attr[k]), attr[k]->nla_len); break; } } } pbucket = (struct nlattr *)((UINT_8 *) pbucket + NLA_HDRLEN); /* request.attr_start(i) as nested attribute */ DBGLOG(REQ, TRACE, "+++pure bucket size=%d pbucket=%p \r\n", len_bucket, pbucket); pbucket = (struct nlattr *)((UINT_8 *) pbucket + len_bucket); /* pure bucket payload, not include channels */ /*don't need to use nla_parse_nested to parse channels */ /* the header of channel in bucket i */ pchannel = (struct nlattr *)((UINT_8 *) pbucket + NLA_HDRLEN); for (j = 0; j < prWifiScanCmd->buckets[i].num_channels; j++) { prWifiScanCmd->buckets[i].channels[j].channel = nla_get_u32(pchannel); len_channel = NLA_ALIGN(pchannel->nla_len); DBGLOG(REQ, TRACE, "attr=0x%x, channel=%d, \r\n", *(UINT_32 *) pchannel, nla_get_u32(pchannel)); pchannel = (struct nlattr *)((UINT_8 *) pchannel + len_channel); } pbucket = pchannel; } DBGLOG(REQ, TRACE, "base_period=%d, num_buckets=%d, bucket0: %d %d %d %d", prWifiScanCmd->base_period, prWifiScanCmd->num_buckets, prWifiScanCmd->buckets[0].bucket, prWifiScanCmd->buckets[0].period, prWifiScanCmd->buckets[0].band, prWifiScanCmd->buckets[0].report_events); DBGLOG(REQ, TRACE, "num_channels=%d, channel0=%d, channel1=%d; num_channels=%d, channel0=%d, channel1=%d", prWifiScanCmd->buckets[0].num_channels, prWifiScanCmd->buckets[0].channels[0].channel, prWifiScanCmd->buckets[0].channels[1].channel, prWifiScanCmd->buckets[1].num_channels, prWifiScanCmd->buckets[1].channels[0].channel, prWifiScanCmd->buckets[1].channels[1].channel); prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ASSERT(prGlueInfo); rStatus = kalIoctl(prGlueInfo, wlanoidSetGSCNAParam, prWifiScanCmd, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS), FALSE, FALSE, TRUE, FALSE, &u4BufLen); return 0; nla_put_failure: return -1; }
static int hash_net6_kadt(struct ip_set *set, const struct sk_buff *skb, const struct xt_action_param *par, enum ipset_adt adt, const struct ip_set_adt_opt *opt) { const struct ip_set_hash *h = set->data; ipset_adtfn adtfn = set->variant->adt[adt]; struct hash_net6_elem data = { .cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK }; if (data.cidr == 0) return -EINVAL; if (adt == IPSET_TEST) data.cidr = HOST_MASK; ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip.in6); ip6_netmask(&data.ip, data.cidr); return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags); } static int hash_net6_uadt(struct ip_set *set, struct nlattr *tb[], enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) { const struct ip_set_hash *h = set->data; ipset_adtfn adtfn = set->variant->adt[adt]; struct hash_net6_elem data = { .cidr = HOST_MASK }; u32 timeout = h->timeout; int ret; if (unlikely(!tb[IPSET_ATTR_IP] || !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) || !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS))) return -IPSET_ERR_PROTOCOL; if (unlikely(tb[IPSET_ATTR_IP_TO])) return -IPSET_ERR_HASH_RANGE_UNSUPPORTED; if (tb[IPSET_ATTR_LINENO]) *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &data.ip); if (ret) return ret; if (tb[IPSET_ATTR_CIDR]) data.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); if (!data.cidr || data.cidr > HOST_MASK) return -IPSET_ERR_INVALID_CIDR; ip6_netmask(&data.ip, data.cidr); if (tb[IPSET_ATTR_TIMEOUT]) { if (!with_timeout(h->timeout)) return -IPSET_ERR_TIMEOUT; timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); } if (tb[IPSET_ATTR_CADT_FLAGS] && adt == IPSET_ADD) { u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); if (cadt_flags & IPSET_FLAG_NOMATCH) flags |= (cadt_flags << 16); } ret = adtfn(set, &data, timeout, flags); return ip_set_eexist(ret, flags) ? 0 : ret; } /* Create hash:ip type of sets */ static int hash_net_create(struct ip_set *set, struct nlattr *tb[], u32 flags) { u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM; struct ip_set_hash *h; u8 hbits; size_t hsize; if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6)) return -IPSET_ERR_INVALID_FAMILY; if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) || !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) || !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) return -IPSET_ERR_PROTOCOL; if (tb[IPSET_ATTR_HASHSIZE]) { hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]); if (hashsize < IPSET_MIMINAL_HASHSIZE) hashsize = IPSET_MIMINAL_HASHSIZE; } if (tb[IPSET_ATTR_MAXELEM]) maxelem = ip_set_get_h32(tb[IPSET_ATTR_MAXELEM]); h = kzalloc(sizeof(*h) + sizeof(struct ip_set_hash_nets) * (set->family == NFPROTO_IPV4 ? 32 : 128), GFP_KERNEL); if (!h) return -ENOMEM; h->maxelem = maxelem; get_random_bytes(&h->initval, sizeof(h->initval)); h->timeout = IPSET_NO_TIMEOUT; hbits = htable_bits(hashsize); hsize = htable_size(hbits); if (hsize == 0) { kfree(h); return -ENOMEM; } h->table = ip_set_alloc(hsize); if (!h->table) { kfree(h); return -ENOMEM; } h->table->htable_bits = hbits; set->data = h; if (tb[IPSET_ATTR_TIMEOUT]) { h->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); set->variant = set->family == NFPROTO_IPV4 ? &hash_net4_tvariant : &hash_net6_tvariant; if (set->family == NFPROTO_IPV4) hash_net4_gc_init(set); else hash_net6_gc_init(set); } else { set->variant = set->family == NFPROTO_IPV4 ? &hash_net4_variant : &hash_net6_variant; } pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)\n", set->name, jhash_size(h->table->htable_bits), h->table->htable_bits, h->maxelem, set->data, h->table); return 0; }
static int u32_msg_parser(struct rtnl_tc *tc, void *data) { struct rtnl_u32 *u = data; struct nlattr *tb[TCA_U32_MAX + 1]; int err; err = tca_parse(tb, TCA_U32_MAX, tc, u32_policy); if (err < 0) return err; if (tb[TCA_U32_DIVISOR]) { u->cu_divisor = nla_get_u32(tb[TCA_U32_DIVISOR]); u->cu_mask |= U32_ATTR_DIVISOR; } if (tb[TCA_U32_SEL]) { u->cu_selector = nl_data_alloc_attr(tb[TCA_U32_SEL]); if (!u->cu_selector) goto errout_nomem; u->cu_mask |= U32_ATTR_SELECTOR; } if (tb[TCA_U32_HASH]) { u->cu_hash = nla_get_u32(tb[TCA_U32_HASH]); u->cu_mask |= U32_ATTR_HASH; } if (tb[TCA_U32_CLASSID]) { u->cu_classid = nla_get_u32(tb[TCA_U32_CLASSID]); u->cu_mask |= U32_ATTR_CLASSID; } if (tb[TCA_U32_LINK]) { u->cu_link = nla_get_u32(tb[TCA_U32_LINK]); u->cu_mask |= U32_ATTR_LINK; } if (tb[TCA_U32_ACT]) { u->cu_mask |= U32_ATTR_ACTION; err = rtnl_act_parse(&u->cu_act, tb[TCA_U32_ACT]); if (err) return err; } if (tb[TCA_U32_POLICE]) { u->cu_police = nl_data_alloc_attr(tb[TCA_U32_POLICE]); if (!u->cu_police) goto errout_nomem; u->cu_mask |= U32_ATTR_POLICE; } if (tb[TCA_U32_PCNT]) { struct tc_u32_sel *sel; size_t pcnt_size; if (!tb[TCA_U32_SEL]) { err = -NLE_MISSING_ATTR; goto errout; } sel = u->cu_selector->d_data; pcnt_size = sizeof(struct tc_u32_pcnt) + (sel->nkeys * sizeof(uint64_t)); if (nla_len(tb[TCA_U32_PCNT]) < pcnt_size) { err = -NLE_INVAL; goto errout; } u->cu_pcnt = nl_data_alloc_attr(tb[TCA_U32_PCNT]); if (!u->cu_pcnt) goto errout_nomem; u->cu_mask |= U32_ATTR_PCNT; } if (tb[TCA_U32_INDEV]) { nla_strlcpy(u->cu_indev, tb[TCA_U32_INDEV], IFNAMSIZ); u->cu_mask |= U32_ATTR_INDEV; } return 0; errout_nomem: err = -NLE_NOMEM; errout: return err; }
static int hash_net4_kadt(struct ip_set *set, const struct sk_buff *skb, const struct xt_action_param *par, enum ipset_adt adt, const struct ip_set_adt_opt *opt) { const struct ip_set_hash *h = set->data; ipset_adtfn adtfn = set->variant->adt[adt]; struct hash_net4_elem data = { .cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK }; if (data.cidr == 0) return -EINVAL; if (adt == IPSET_TEST) data.cidr = HOST_MASK; ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip); data.ip &= ip_set_netmask(data.cidr); return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags); } static int hash_net4_uadt(struct ip_set *set, struct nlattr *tb[], enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) { const struct ip_set_hash *h = set->data; ipset_adtfn adtfn = set->variant->adt[adt]; struct hash_net4_elem data = { .cidr = HOST_MASK }; u32 timeout = h->timeout; u32 ip = 0, ip_to, last; int ret; if (unlikely(!tb[IPSET_ATTR_IP] || !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) || !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS))) return -IPSET_ERR_PROTOCOL; if (tb[IPSET_ATTR_LINENO]) *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip); if (ret) return ret; if (tb[IPSET_ATTR_CIDR]) { data.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); if (!data.cidr || data.cidr > HOST_MASK) return -IPSET_ERR_INVALID_CIDR; } if (tb[IPSET_ATTR_TIMEOUT]) { if (!with_timeout(h->timeout)) return -IPSET_ERR_TIMEOUT; timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); } if (tb[IPSET_ATTR_CADT_FLAGS] && adt == IPSET_ADD) { u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); if (cadt_flags & IPSET_FLAG_NOMATCH) flags |= (cadt_flags << 16); } if (adt == IPSET_TEST || !tb[IPSET_ATTR_IP_TO]) { data.ip = htonl(ip & ip_set_hostmask(data.cidr)); ret = adtfn(set, &data, timeout, flags); return ip_set_eexist(ret, flags) ? 0 : ret; } ip_to = ip; if (tb[IPSET_ATTR_IP_TO]) { ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to); if (ret) return ret; if (ip_to < ip) swap(ip, ip_to); if (ip + UINT_MAX == ip_to) return -IPSET_ERR_HASH_RANGE; } if (retried) ip = h->next.ip; while (!after(ip, ip_to)) { data.ip = htonl(ip); last = ip_set_range_to_cidr(ip, ip_to, &data.cidr); ret = adtfn(set, &data, timeout, flags); if (ret && !ip_set_eexist(ret, flags)) return ret; else ret = 0; ip = last + 1; } return ret; } static bool hash_net_same_set(const struct ip_set *a, const struct ip_set *b) { const struct ip_set_hash *x = a->data; const struct ip_set_hash *y = b->data; /* Resizing changes htable_bits, so we ignore it */ return x->maxelem == y->maxelem && x->timeout == y->timeout; } /* The type variant functions: IPv6 */ struct hash_net6_elem { union nf_inet_addr ip; u16 padding0; u8 nomatch; u8 cidr; }; struct hash_net6_telem { union nf_inet_addr ip; u16 padding0; u8 nomatch; u8 cidr; unsigned long timeout; }; static inline bool hash_net6_data_equal(const struct hash_net6_elem *ip1, const struct hash_net6_elem *ip2, u32 *multi) { return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0 && ip1->cidr == ip2->cidr; } static inline bool hash_net6_data_isnull(const struct hash_net6_elem *elem) { return elem->cidr == 0; } static inline void hash_net6_data_copy(struct hash_net6_elem *dst, const struct hash_net6_elem *src) { dst->ip.in6 = src->ip.in6; dst->cidr = src->cidr; dst->nomatch = src->nomatch; }
// This function will be the main handler for incoming event LLStats_SUBCMD //Call the appropriate callback handler after parsing the vendor data. int LLStatsCommand::handleEvent(WifiEvent &event) { ALOGI("Got a LLStats message from Driver"); unsigned i=0; u32 status; WifiVendorCommand::handleEvent(event); // Parse the vendordata and get the attribute switch(mSubcmd) { case QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS: { wifi_request_id id; u32 resultsBufSize = 0; struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX + 1]; int rem; nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX, (struct nlattr *)mVendorData, mDataLen, NULL); resultsBufSize += (nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS]) * sizeof(wifi_channel_stat) + sizeof(wifi_radio_stat)); mResultsParams.radio_stat = (wifi_radio_stat *)malloc(resultsBufSize); memset(mResultsParams.radio_stat, 0, resultsBufSize); ALOGI(" rxTime is %u\n ", mResultsParams.radio_stat->rx_time); ALOGI(" NumChan is %d\n ", nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS])); if(mResultsParams.radio_stat){ wifi_channel_stat *pWifiChannelStats; u32 i =0; printf("sunil %d : %s \n",__LINE__,__func__); get_wifi_radio_stats(mResultsParams.radio_stat, tb_vendor); ALOGI(" radio is %u ", mResultsParams.radio_stat->radio); ALOGI(" onTime is %u ", mResultsParams.radio_stat->on_time); ALOGI(" txTime is %u ", mResultsParams.radio_stat->tx_time); ALOGI(" rxTime is %u ", mResultsParams.radio_stat->rx_time); ALOGI(" onTimeScan is %u ", mResultsParams.radio_stat->on_time_scan); ALOGI(" onTimeNbd is %u ", mResultsParams.radio_stat->on_time_nbd); ALOGI(" onTimeGscan is %u ", mResultsParams.radio_stat->on_time_gscan); ALOGI(" onTimeRoamScan is %u", mResultsParams.radio_stat->on_time_roam_scan); ALOGI(" onTimePnoScan is %u ", mResultsParams.radio_stat->on_time_pno_scan); ALOGI(" onTimeHs20 is %u ", mResultsParams.radio_stat->on_time_hs20); ALOGI(" numChannels is %u ", mResultsParams.radio_stat->num_channels); for ( i=0; i < mResultsParams.radio_stat->num_channels; i++) { pWifiChannelStats = (wifi_channel_stat *) ((u8 *)mResultsParams.radio_stat->channels + (i * sizeof(wifi_channel_stat))); ALOGI(" width is %u ", pWifiChannelStats->channel.width); ALOGI(" CenterFreq %u ", pWifiChannelStats->channel.center_freq); ALOGI(" CenterFreq0 %u ", pWifiChannelStats->channel.center_freq0); ALOGI(" CenterFreq1 %u ", pWifiChannelStats->channel.center_freq1); ALOGI(" onTime %u ", pWifiChannelStats->on_time); ALOGI(" ccaBusyTime %u ", pWifiChannelStats->cca_busy_time); } ALOGI(" rxTime is %u in %s:%d\n", mResultsParams.radio_stat->rx_time, __func__, __LINE__); } } break; case QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS: { wifi_request_id id; u32 resultsBufSize = 0; struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX + 1]; nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX, (struct nlattr *)mVendorData, mDataLen, NULL); resultsBufSize = sizeof(wifi_iface_stat); // Do we need no.of peers here?? mResultsParams.iface_stat = (wifi_iface_stat *) malloc (sizeof (wifi_iface_stat)); get_wifi_interface_info(&mResultsParams.iface_stat->info, tb_vendor); get_wifi_iface_stats(mResultsParams.iface_stat, tb_vendor); } break; case QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS: { wifi_request_id id; u32 resultsBufSize = 0, i=0, num_rates = 0; u32 numPeers; int rem; struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX + 1]; struct nlattr *peerInfo; wifi_iface_stat *pIfaceStat; nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX, (struct nlattr *)mVendorData, mDataLen, NULL); ALOGI(" rxTime is %u in %s:%d\n", mResultsParams.radio_stat->rx_time, __func__, __LINE__); ALOGI(" numPeers is %u in %s:%d\n", nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS]), __func__, __LINE__); ALOGI(" rxTe is %u in %s:%d\n", mResultsParams.radio_stat->rx_time, __func__, __LINE__); if((numPeers = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS])) > 0) { for (peerInfo = (struct nlattr *) nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO]), rem = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO]); nla_ok(peerInfo, rem); peerInfo = nla_next(peerInfo, &(rem))) { struct nlattr *tb2[ QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX+ 1]; nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX, (struct nlattr *) nla_data(peerInfo), nla_len(peerInfo), NULL); num_rates += nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES]); } resultsBufSize += (numPeers * sizeof(wifi_peer_info) + num_rates * sizeof(wifi_rate_stat) + sizeof (wifi_iface_stat)); pIfaceStat = (wifi_iface_stat *) malloc (resultsBufSize); if(pIfaceStat){ memcpy ( pIfaceStat, mResultsParams.iface_stat , sizeof(wifi_iface_stat)); wifi_peer_info *pPeerStats; pIfaceStat->num_peers = numPeers; for (peerInfo = (struct nlattr *) nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO]), rem = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO]); nla_ok(peerInfo, rem); peerInfo = nla_next(peerInfo, &(rem))) { struct nlattr *tb2[ QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX+ 1]; pPeerStats = (wifi_peer_info *) ((u8 *)pIfaceStat->peer_info + (i++ * sizeof(wifi_peer_info))); nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX, (struct nlattr *) nla_data(peerInfo), nla_len(peerInfo), NULL); get_wifi_peer_info(pPeerStats, tb2); } } if(mResultsParams.iface_stat) free (mResultsParams.iface_stat); mResultsParams.iface_stat = pIfaceStat; } // Number of Radios are 1 for now : TODO get this info from the driver mHandler.on_link_stats_results(mRequestId, mResultsParams.iface_stat, 1, mResultsParams.radio_stat); if(mResultsParams.radio_stat) { free(mResultsParams.radio_stat); mResultsParams.radio_stat = NULL; } if(mResultsParams.iface_stat) { free(mResultsParams.iface_stat); mResultsParams.iface_stat = NULL; } } break; default: //error case should not happen print log ALOGE("%s: Wrong LLStats subcmd received %d", __func__, mSubcmd); } return NL_SKIP; }
static void get_wifi_radio_stats(wifi_radio_stat *stats, struct nlattr **tb_vendor) { u32 i = 0; struct nlattr *chInfo; wifi_channel_stat *pChStats; int rem; printf("sunil %d : %s \n",__LINE__,__func__); stats->radio = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID]); printf("sunil %d : %s \n",__LINE__,__func__); stats->on_time = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME]); printf("sunil %d : %s \n",__LINE__,__func__); stats->tx_time = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME]); printf("sunil %d : %s \n",__LINE__,__func__); stats->rx_time = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME]); ALOGI("<<<< rxTime is %u ", stats->rx_time); stats->on_time_scan = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN]); stats->on_time_nbd = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD]); stats->on_time_gscan = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_GSCAN]); stats->on_time_roam_scan = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN]); stats->on_time_pno_scan = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN]); stats->on_time_hs20 = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20]); stats->num_channels = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS]); for (chInfo = (struct nlattr *) nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO]), rem = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO]); nla_ok(chInfo, rem); chInfo = nla_next(chInfo, &(rem))) { struct nlattr *tb2[ QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX+ 1]; pChStats = (wifi_channel_stat *) ((u8 *)stats->channels + (i++ * (sizeof(wifi_channel_stat)))); nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX, (struct nlattr *) nla_data(chInfo), nla_len(chInfo), NULL); pChStats->channel.width = (wifi_channel_width)nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH]); pChStats->channel.center_freq = (wifi_channel)nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ]); pChStats->channel.center_freq0 = (wifi_channel)nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0]); pChStats->channel.center_freq1 = (wifi_channel)nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1]); pChStats->on_time = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME]); pChStats->cca_busy_time = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME]); } }
/* * Relays a message from user space to the driver * * The skb is passed to the driver-specific function with the netlink * and generic netlink headers already stripped. * * This call will block while handling/relaying the message. */ static int wimax_gnl_doit_msg_from_user(struct sk_buff *skb, struct genl_info *info) { int result, ifindex; struct wimax_dev *wimax_dev; struct device *dev; struct nlmsghdr *nlh = info->nlhdr; char *pipe_name; void *msg_buf; size_t msg_len; might_sleep(); d_fnstart(3, NULL, "(skb %p info %p)\n", skb, info); result = -ENODEV; if (info->attrs[WIMAX_GNL_MSG_IFIDX] == NULL) { printk(KERN_ERR "WIMAX_GNL_MSG_FROM_USER: can't find IFIDX " "attribute\n"); goto error_no_wimax_dev; } ifindex = nla_get_u32(info->attrs[WIMAX_GNL_MSG_IFIDX]); wimax_dev = wimax_dev_get_by_genl_info(info, ifindex); if (wimax_dev == NULL) goto error_no_wimax_dev; dev = wimax_dev_to_dev(wimax_dev); /* Unpack arguments */ result = -EINVAL; if (info->attrs[WIMAX_GNL_MSG_DATA] == NULL) { dev_err(dev, "WIMAX_GNL_MSG_FROM_USER: can't find MSG_DATA " "attribute\n"); goto error_no_data; } msg_buf = nla_data(info->attrs[WIMAX_GNL_MSG_DATA]); msg_len = nla_len(info->attrs[WIMAX_GNL_MSG_DATA]); if (info->attrs[WIMAX_GNL_MSG_PIPE_NAME] == NULL) pipe_name = NULL; else { struct nlattr *attr = info->attrs[WIMAX_GNL_MSG_PIPE_NAME]; size_t attr_len = nla_len(attr); /* libnl-1.1 does not yet support NLA_NUL_STRING */ result = -ENOMEM; pipe_name = kstrndup(nla_data(attr), attr_len + 1, GFP_KERNEL); if (pipe_name == NULL) goto error_alloc; pipe_name[attr_len] = 0; } mutex_lock(&wimax_dev->mutex); result = wimax_dev_is_ready(wimax_dev); if (result < 0) goto error_not_ready; result = -ENOSYS; if (wimax_dev->op_msg_from_user == NULL) goto error_noop; d_printf(1, dev, "CRX: nlmsghdr len %u type %u flags 0x%04x seq 0x%x pid %u\n", nlh->nlmsg_len, nlh->nlmsg_type, nlh->nlmsg_flags, nlh->nlmsg_seq, nlh->nlmsg_pid); d_printf(1, dev, "CRX: wimax message %zu bytes\n", msg_len); d_dump(2, dev, msg_buf, msg_len); result = wimax_dev->op_msg_from_user(wimax_dev, pipe_name, msg_buf, msg_len, info); error_noop: error_not_ready: mutex_unlock(&wimax_dev->mutex); error_alloc: kfree(pipe_name); error_no_data: dev_put(wimax_dev->net_dev); error_no_wimax_dev: d_fnend(3, NULL, "(skb %p info %p) = %d\n", skb, info, result); return result; }
int mtk_cfg80211_vendor_set_scan_config(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) { WLAN_STATUS rStatus; UINT_32 u4BufLen; P_GLUE_INFO_T prGlueInfo = NULL; INT_32 i4Status = -EINVAL; /*PARAM_WIFI_GSCAN_CMD_PARAMS rWifiScanCmd;*/ P_PARAM_WIFI_GSCAN_CMD_PARAMS prWifiScanCmd; struct nlattr *attr[GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE + 1]; /* UINT_32 num_scans = 0; */ /* another attribute */ int k; ASSERT(wiphy); ASSERT(wdev); if ((data == NULL) || !data_len) goto nla_put_failure; DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d \r\n", __func__, data_len); /*kalMemZero(&rWifiScanCmd, sizeof(rWifiScanCmd));*/ prWifiScanCmd = kalMemAlloc(sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS), VIR_MEM_TYPE); if (prWifiScanCmd == NULL) goto nla_put_failure; kalMemZero(prWifiScanCmd, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); kalMemZero(attr, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE + 1)); if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE, (struct nlattr *)(data - NLA_HDRLEN), nla_parse_policy) < 0) goto nla_put_failure; for (k = GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN; k <= GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE; k++) { if (attr[k]) { switch (k) { case GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN: prWifiScanCmd->max_ap_per_scan = nla_get_u32(attr[k]); break; case GSCAN_ATTRIBUTE_REPORT_THRESHOLD: prWifiScanCmd->report_threshold = nla_get_u32(attr[k]); break; case GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE: prWifiScanCmd->num_scans = nla_get_u32(attr[k]); break; } } } DBGLOG(REQ, TRACE, "attr=0x%x, attr2=0x%x ", *(UINT_32 *) attr[GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN], *(UINT_32 *) attr[GSCAN_ATTRIBUTE_REPORT_THRESHOLD]); DBGLOG(REQ, TRACE, "max_ap_per_scan=%d, report_threshold=%d num_scans=%d \r\n", prWifiScanCmd->max_ap_per_scan, prWifiScanCmd->report_threshold, prWifiScanCmd->num_scans); prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ASSERT(prGlueInfo); rStatus = kalIoctl(prGlueInfo, wlanoidSetGSCNAConfig, prWifiScanCmd, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS), FALSE, FALSE, TRUE, FALSE, &u4BufLen); kalMemFree(prWifiScanCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); return 0; nla_put_failure: return i4Status; }
static int nl80211_freqlist_cb(struct nl_msg *msg, void *arg) { struct nlattr *tb_msg[NL80211_ATTR_MAX + 1]; struct genlmsghdr *gnlh = (struct genlmsghdr *) nlmsg_data(nlmsg_hdr(msg)); struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1]; struct nlattr *tb_freq[NL80211_FREQUENCY_ATTR_MAX + 1]; struct nlattr *nl_band, *nl_freq; int rem_band, rem_freq, num_freq = 0; uint32_t freq; struct nl80211_channel_block *chanb = (struct nl80211_channel_block *) arg; nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); if (!tb_msg[NL80211_ATTR_WIPHY_BANDS]) { return NL_SKIP; } if (tb_msg[NL80211_ATTR_WIPHY_NAME]) { if (strcmp(nla_get_string(tb_msg[NL80211_ATTR_WIPHY_NAME]), chanb->phyname) != 0) { return NL_SKIP; } } // Count the number of channels for (nl_band = (struct nlattr *) nla_data(tb_msg[NL80211_ATTR_WIPHY_BANDS]), rem_band = nla_len(tb_msg[NL80211_ATTR_WIPHY_BANDS]); nla_ok(nl_band, rem_band); nl_band = (struct nlattr *) nla_next(nl_band, &rem_band)) { nla_parse(tb_band, NL80211_BAND_ATTR_MAX, (struct nlattr *) nla_data(nl_band), nla_len(nl_band), NULL); for (nl_freq = (struct nlattr *) nla_data(tb_band[NL80211_BAND_ATTR_FREQS]), rem_freq = nla_len(tb_band[NL80211_BAND_ATTR_FREQS]); nla_ok(nl_freq, rem_freq); nl_freq = (struct nlattr *) nla_next(nl_freq, &rem_freq)) { nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX, (struct nlattr *) nla_data(nl_freq), nla_len(nl_freq), NULL); if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ]) continue; if (tb_freq[NL80211_FREQUENCY_ATTR_DISABLED]) continue; num_freq++; } } chanb->nfreqs = num_freq; chanb->channel_list = malloc(sizeof(int) * num_freq); num_freq = 0; // Assemble a return for (nl_band = (struct nlattr *) nla_data(tb_msg[NL80211_ATTR_WIPHY_BANDS]), rem_band = nla_len(tb_msg[NL80211_ATTR_WIPHY_BANDS]); nla_ok(nl_band, rem_band); nl_band = (struct nlattr *) nla_next(nl_band, &rem_band)) { nla_parse(tb_band, NL80211_BAND_ATTR_MAX, (struct nlattr *) nla_data(nl_band), nla_len(nl_band), NULL); for (nl_freq = (struct nlattr *) nla_data(tb_band[NL80211_BAND_ATTR_FREQS]), rem_freq = nla_len(tb_band[NL80211_BAND_ATTR_FREQS]); nla_ok(nl_freq, rem_freq); nl_freq = (struct nlattr *) nla_next(nl_freq, &rem_freq)) { nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX, (struct nlattr *) nla_data(nl_freq), nla_len(nl_freq), NULL); if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ]) continue; if (tb_freq[NL80211_FREQUENCY_ATTR_DISABLED]) continue; freq = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]); chanb->channel_list[num_freq++] = FreqToChan(freq); } } return NL_SKIP; }
int mtk_cfg80211_vendor_set_significant_change(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) { INT_32 i4Status = -EINVAL; P_PARAM_WIFI_SIGNIFICANT_CHANGE prWifiChangeCmd = NULL; UINT_8 flush = 0; /* struct nlattr *attr[GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1]; */ struct nlattr **attr = NULL; struct nlattr *paplist; int i, k; UINT_32 len_basic, len_aplist; ASSERT(wiphy); ASSERT(wdev); if ((data == NULL) || !data_len) goto nla_put_failure; DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d \r\n", __func__, data_len); for (i = 0; i < 6; i++) DBGLOG(REQ, LOUD, "0x%x 0x%x 0x%x 0x%x \r\n", *((UINT_32 *) data + i * 4), *((UINT_32 *) data + i * 4 + 1), *((UINT_32 *) data + i * 4 + 2), *((UINT_32 *) data + i * 4 + 3)); prWifiChangeCmd = kalMemAlloc(sizeof(PARAM_WIFI_SIGNIFICANT_CHANGE), VIR_MEM_TYPE); if (prWifiChangeCmd == NULL) goto nla_put_failure; kalMemZero(prWifiChangeCmd, sizeof(PARAM_WIFI_SIGNIFICANT_CHANGE)); attr = kalMemAlloc(sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1), VIR_MEM_TYPE); if (attr == NULL) goto nla_put_failure; kalMemZero(attr, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH, (struct nlattr *)(data - NLA_HDRLEN), nla_parse_policy) < 0) goto nla_put_failure; len_basic = 0; for (k = GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE; k <= GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH; k++) { if (attr[k]) { switch (k) { case GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE: prWifiChangeCmd->rssi_sample_size = nla_get_u16(attr[k]); len_basic += NLA_ALIGN(attr[k]->nla_len); break; case GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE: prWifiChangeCmd->lost_ap_sample_size = nla_get_u16(attr[k]); len_basic += NLA_ALIGN(attr[k]->nla_len); break; case GSCAN_ATTRIBUTE_MIN_BREACHING: prWifiChangeCmd->min_breaching = nla_get_u16(attr[k]); len_basic += NLA_ALIGN(attr[k]->nla_len); break; case GSCAN_ATTRIBUTE_NUM_AP: prWifiChangeCmd->num_ap = nla_get_u16(attr[k]); len_basic += NLA_ALIGN(attr[k]->nla_len); DBGLOG(REQ, TRACE, "attr=0x%x, num_ap=%d nla_len=%d, \r\n", *(UINT_32 *) attr[k], prWifiChangeCmd->num_ap, attr[k]->nla_len); break; case GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH: flush = nla_get_u8(attr[k]); len_basic += NLA_ALIGN(attr[k]->nla_len); break; } } } paplist = (struct nlattr *)((UINT_8 *) data + len_basic); DBGLOG(REQ, TRACE, "+++basic attribute size=%d flush=%d\r\n", len_basic, flush); if (paplist->nla_type == GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS) paplist = (struct nlattr *)((UINT_8 *) paplist + NLA_HDRLEN); for (i = 0; i < prWifiChangeCmd->num_ap; i++) { if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_RSSI_HIGH, (struct nlattr *)paplist, nla_parse_policy) < 0) goto nla_put_failure; paplist = (struct nlattr *)((UINT_8 *) paplist + NLA_HDRLEN); /* request.attr_start(i) as nested attribute */ len_aplist = 0; for (k = GSCAN_ATTRIBUTE_BSSID; k <= GSCAN_ATTRIBUTE_RSSI_HIGH; k++) { if (attr[k]) { switch (k) { case GSCAN_ATTRIBUTE_BSSID: kalMemCopy(prWifiChangeCmd->ap[i].bssid, nla_data(attr[k]), sizeof(mac_addr)); len_aplist += NLA_ALIGN(attr[k]->nla_len); break; case GSCAN_ATTRIBUTE_RSSI_LOW: prWifiChangeCmd->ap[i].low = nla_get_u32(attr[k]); len_aplist += NLA_ALIGN(attr[k]->nla_len); break; case GSCAN_ATTRIBUTE_RSSI_HIGH: prWifiChangeCmd->ap[i].high = nla_get_u32(attr[k]); len_aplist += NLA_ALIGN(attr[k]->nla_len); break; } } } if (((i + 1) % 4 == 0) || (i == prWifiChangeCmd->num_ap - 1)) DBGLOG(REQ, TRACE, "ap[%d], len_aplist=%d\n", i, len_aplist); else DBGLOG(REQ, TRACE, "ap[%d], len_aplist=%d \t", i, len_aplist); paplist = (struct nlattr *)((UINT_8 *) paplist + len_aplist); } DBGLOG(REQ, TRACE, "flush=%d, rssi_sample_size=%d lost_ap_sample_size=%d min_breaching=%d", flush, prWifiChangeCmd->rssi_sample_size, prWifiChangeCmd->lost_ap_sample_size, prWifiChangeCmd->min_breaching); DBGLOG(REQ, TRACE, "ap[0].channel=%d low=%d high=%d, ap[1].channel=%d low=%d high=%d", prWifiChangeCmd->ap[0].channel, prWifiChangeCmd->ap[0].low, prWifiChangeCmd->ap[0].high, prWifiChangeCmd->ap[1].channel, prWifiChangeCmd->ap[1].low, prWifiChangeCmd->ap[1].high); kalMemFree(prWifiChangeCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_SIGNIFICANT_CHANGE)); kalMemFree(attr, VIR_MEM_TYPE, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); return 0; nla_put_failure: if (prWifiChangeCmd) kalMemFree(prWifiChangeCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_SIGNIFICANT_CHANGE)); if (attr) kalMemFree(attr, VIR_MEM_TYPE, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); return i4Status; }
static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *info) { u32 tunnel_id = 0; u32 session_id; u32 peer_session_id; int ret = 0; struct l2tp_tunnel *tunnel; struct l2tp_session *session; struct l2tp_session_cfg cfg = { 0, }; struct net *net = genl_info_net(info); if (!info->attrs[L2TP_ATTR_CONN_ID]) { ret = -EINVAL; goto out; } tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]); tunnel = l2tp_tunnel_find(net, tunnel_id); if (!tunnel) { ret = -ENODEV; goto out; } if (!info->attrs[L2TP_ATTR_SESSION_ID]) { ret = -EINVAL; goto out; } session_id = nla_get_u32(info->attrs[L2TP_ATTR_SESSION_ID]); session = l2tp_session_find(net, tunnel, session_id); if (session) { ret = -EEXIST; goto out; } if (!info->attrs[L2TP_ATTR_PEER_SESSION_ID]) { ret = -EINVAL; goto out; } peer_session_id = nla_get_u32(info->attrs[L2TP_ATTR_PEER_SESSION_ID]); if (!info->attrs[L2TP_ATTR_PW_TYPE]) { ret = -EINVAL; goto out; } cfg.pw_type = nla_get_u16(info->attrs[L2TP_ATTR_PW_TYPE]); if (cfg.pw_type >= __L2TP_PWTYPE_MAX) { ret = -EINVAL; goto out; } if (tunnel->version > 2) { if (info->attrs[L2TP_ATTR_OFFSET]) cfg.offset = nla_get_u16(info->attrs[L2TP_ATTR_OFFSET]); if (info->attrs[L2TP_ATTR_DATA_SEQ]) cfg.data_seq = nla_get_u8(info->attrs[L2TP_ATTR_DATA_SEQ]); cfg.l2specific_type = L2TP_L2SPECTYPE_DEFAULT; if (info->attrs[L2TP_ATTR_L2SPEC_TYPE]) cfg.l2specific_type = nla_get_u8(info->attrs[L2TP_ATTR_L2SPEC_TYPE]); cfg.l2specific_len = 4; if (info->attrs[L2TP_ATTR_L2SPEC_LEN]) cfg.l2specific_len = nla_get_u8(info->attrs[L2TP_ATTR_L2SPEC_LEN]); if (info->attrs[L2TP_ATTR_COOKIE]) { u16 len = nla_len(info->attrs[L2TP_ATTR_COOKIE]); if (len > 8) { ret = -EINVAL; goto out; } cfg.cookie_len = len; memcpy(&cfg.cookie[0], nla_data(info->attrs[L2TP_ATTR_COOKIE]), len); } if (info->attrs[L2TP_ATTR_PEER_COOKIE]) { u16 len = nla_len(info->attrs[L2TP_ATTR_PEER_COOKIE]); if (len > 8) { ret = -EINVAL; goto out; } cfg.peer_cookie_len = len; memcpy(&cfg.peer_cookie[0], nla_data(info->attrs[L2TP_ATTR_PEER_COOKIE]), len); } if (info->attrs[L2TP_ATTR_IFNAME]) cfg.ifname = nla_data(info->attrs[L2TP_ATTR_IFNAME]); if (info->attrs[L2TP_ATTR_VLAN_ID]) cfg.vlan_id = nla_get_u16(info->attrs[L2TP_ATTR_VLAN_ID]); } if (info->attrs[L2TP_ATTR_DEBUG]) cfg.debug = nla_get_u32(info->attrs[L2TP_ATTR_DEBUG]); if (info->attrs[L2TP_ATTR_RECV_SEQ]) cfg.recv_seq = nla_get_u8(info->attrs[L2TP_ATTR_RECV_SEQ]); if (info->attrs[L2TP_ATTR_SEND_SEQ]) cfg.send_seq = nla_get_u8(info->attrs[L2TP_ATTR_SEND_SEQ]); if (info->attrs[L2TP_ATTR_LNS_MODE]) cfg.lns_mode = nla_get_u8(info->attrs[L2TP_ATTR_LNS_MODE]); if (info->attrs[L2TP_ATTR_RECV_TIMEOUT]) cfg.reorder_timeout = nla_get_msecs(info->attrs[L2TP_ATTR_RECV_TIMEOUT]); if (info->attrs[L2TP_ATTR_MTU]) cfg.mtu = nla_get_u16(info->attrs[L2TP_ATTR_MTU]); if (info->attrs[L2TP_ATTR_MRU]) cfg.mru = nla_get_u16(info->attrs[L2TP_ATTR_MRU]); #ifdef CONFIG_MODULES if (l2tp_nl_cmd_ops[cfg.pw_type] == NULL) { genl_unlock(); request_module("net-l2tp-type-%u", cfg.pw_type); genl_lock(); } #endif if ((l2tp_nl_cmd_ops[cfg.pw_type] == NULL) || (l2tp_nl_cmd_ops[cfg.pw_type]->session_create == NULL)) { ret = -EPROTONOSUPPORT; goto out; } /* Check that pseudowire-specific params are present */ switch (cfg.pw_type) { case L2TP_PWTYPE_NONE: break; case L2TP_PWTYPE_ETH_VLAN: if (!info->attrs[L2TP_ATTR_VLAN_ID]) { ret = -EINVAL; goto out; } break; case L2TP_PWTYPE_ETH: break; case L2TP_PWTYPE_PPP: case L2TP_PWTYPE_PPP_AC: break; case L2TP_PWTYPE_IP: default: ret = -EPROTONOSUPPORT; break; } ret = -EPROTONOSUPPORT; if (l2tp_nl_cmd_ops[cfg.pw_type]->session_create) ret = (*l2tp_nl_cmd_ops[cfg.pw_type]->session_create)(net, tunnel_id, session_id, peer_session_id, &cfg); if (ret >= 0) { session = l2tp_session_find(net, tunnel, session_id); if (session) ret = l2tp_session_notify(&l2tp_nl_family, info, session, L2TP_CMD_SESSION_CREATE); } out: return ret; }
int mtk_cfg80211_vendor_set_hotlist(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) { /*WLAN_STATUS rStatus;*/ P_GLUE_INFO_T prGlueInfo = NULL; CMD_SET_PSCAN_ADD_HOTLIST_BSSID rCmdPscnAddHotlist; INT_32 i4Status = -EINVAL; P_PARAM_WIFI_BSSID_HOTLIST prWifiHotlistCmd = NULL; UINT_8 flush = 0; /* struct nlattr *attr[GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1]; */ struct nlattr **attr = NULL; struct nlattr *paplist; int i, k; UINT_32 len_basic, len_aplist; ASSERT(wiphy); ASSERT(wdev); if ((data == NULL) || !data_len) goto nla_put_failure; DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d \r\n", __func__, data_len); for (i = 0; i < 5; i++) DBGLOG(REQ, LOUD, "0x%x 0x%x 0x%x 0x%x \r\n", *((UINT_32 *) data + i * 4), *((UINT_32 *) data + i * 4 + 1), *((UINT_32 *) data + i * 4 + 2), *((UINT_32 *) data + i * 4 + 3)); prWifiHotlistCmd = kalMemAlloc(sizeof(PARAM_WIFI_BSSID_HOTLIST), VIR_MEM_TYPE); if (prWifiHotlistCmd == NULL) goto nla_put_failure; kalMemZero(prWifiHotlistCmd, sizeof(PARAM_WIFI_BSSID_HOTLIST)); attr = kalMemAlloc(sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1), VIR_MEM_TYPE); if (attr == NULL) goto nla_put_failure; kalMemZero(attr, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_NUM_AP, (struct nlattr *)(data - NLA_HDRLEN), nla_parse_policy) < 0) goto nla_put_failure; len_basic = 0; for (k = GSCAN_ATTRIBUTE_HOTLIST_FLUSH; k <= GSCAN_ATTRIBUTE_NUM_AP; k++) { if (attr[k]) { switch (k) { case GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE: prWifiHotlistCmd->lost_ap_sample_size = nla_get_u32(attr[k]); len_basic += NLA_ALIGN(attr[k]->nla_len); break; case GSCAN_ATTRIBUTE_NUM_AP: prWifiHotlistCmd->num_ap = nla_get_u16(attr[k]); len_basic += NLA_ALIGN(attr[k]->nla_len); DBGLOG(REQ, TRACE, "attr=0x%x, num_ap=%d nla_len=%d, \r\n", *(UINT_32 *) attr[k], prWifiHotlistCmd->num_ap, attr[k]->nla_len); break; case GSCAN_ATTRIBUTE_HOTLIST_FLUSH: flush = nla_get_u8(attr[k]); len_basic += NLA_ALIGN(attr[k]->nla_len); break; } } } paplist = (struct nlattr *)((UINT_8 *) data + len_basic); DBGLOG(REQ, TRACE, "+++basic attribute size=%d flush=%d\r\n", len_basic, flush); if (paplist->nla_type == GSCAN_ATTRIBUTE_HOTLIST_BSSIDS) paplist = (struct nlattr *)((UINT_8 *) paplist + NLA_HDRLEN); for (i = 0; i < prWifiHotlistCmd->num_ap; i++) { if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_RSSI_HIGH, (struct nlattr *)paplist, nla_parse_policy) < 0) goto nla_put_failure; paplist = (struct nlattr *)((UINT_8 *) paplist + NLA_HDRLEN); /* request.attr_start(i) as nested attribute */ len_aplist = 0; for (k = GSCAN_ATTRIBUTE_BSSID; k <= GSCAN_ATTRIBUTE_RSSI_HIGH; k++) { if (attr[k]) { switch (k) { case GSCAN_ATTRIBUTE_BSSID: kalMemCopy(prWifiHotlistCmd->ap[i].bssid, nla_data(attr[k]), sizeof(mac_addr)); len_aplist += NLA_ALIGN(attr[k]->nla_len); break; case GSCAN_ATTRIBUTE_RSSI_LOW: prWifiHotlistCmd->ap[i].low = nla_get_u32(attr[k]); len_aplist += NLA_ALIGN(attr[k]->nla_len); break; case GSCAN_ATTRIBUTE_RSSI_HIGH: prWifiHotlistCmd->ap[i].high = nla_get_u32(attr[k]); len_aplist += NLA_ALIGN(attr[k]->nla_len); break; } } } if (((i + 1) % 4 == 0) || (i == prWifiHotlistCmd->num_ap - 1)) DBGLOG(REQ, TRACE, "ap[%d], len_aplist=%d\n", i, len_aplist); else DBGLOG(REQ, TRACE, "ap[%d], len_aplist=%d \t", i, len_aplist); paplist = (struct nlattr *)((UINT_8 *) paplist + len_aplist); } DBGLOG(REQ, TRACE, "flush=%d, lost_ap_sample_size=%d, Hotlist:ap[0].channel=%d low=%d high=%d, ap[1].channel=%d low=%d high=%d", flush, prWifiHotlistCmd->lost_ap_sample_size, prWifiHotlistCmd->ap[0].channel, prWifiHotlistCmd->ap[0].low, prWifiHotlistCmd->ap[0].high, prWifiHotlistCmd->ap[1].channel, prWifiHotlistCmd->ap[1].low, prWifiHotlistCmd->ap[1].high); memcpy(&(rCmdPscnAddHotlist.aucMacAddr), &(prWifiHotlistCmd->ap[0].bssid), 6 * sizeof(UINT_8)); rCmdPscnAddHotlist.ucFlags = (UINT_8) TRUE; prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ASSERT(prGlueInfo); kalMemFree(prWifiHotlistCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_BSSID_HOTLIST)); kalMemFree(attr, VIR_MEM_TYPE, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); return 0; nla_put_failure: if (prWifiHotlistCmd) kalMemFree(prWifiHotlistCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_BSSID_HOTLIST)); if (attr) kalMemFree(attr, VIR_MEM_TYPE, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); return i4Status; }
int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len) { struct ath6kl *ar = wiphy_priv(wiphy); struct nlattr *tb[ATH6KL_TM_ATTR_MAX + 1]; int err, buf_len; void *buf; err = nla_parse(tb, ATH6KL_TM_ATTR_MAX, data, len, ath6kl_tm_policy); if (err) return err; if (!tb[ATH6KL_TM_ATTR_CMD]) return -EINVAL; switch (nla_get_u32(tb[ATH6KL_TM_ATTR_CMD])) { case ATH6KL_TM_CMD_TCMD: if (!tb[ATH6KL_TM_ATTR_DATA]) return -EINVAL; buf = nla_data(tb[ATH6KL_TM_ATTR_DATA]); buf_len = nla_len(tb[ATH6KL_TM_ATTR_DATA]); ath6kl_wmi_test_cmd(ar->wmi, buf, buf_len); return 0; break; #ifdef ATH6KL_SUPPORT_WLAN_HB case ATH6KL_TM_CMD_WLAN_HB: { struct wlan_hb_params *hb_params; struct ath6kl_vif *vif; vif = ath6kl_vif_first(ar); if (!vif) return -EINVAL; if (!tb[ATH6KL_TM_ATTR_DATA]) { printk(KERN_ERR "%s: NO DATA\n", __func__); return -EINVAL; } buf = nla_data(tb[ATH6KL_TM_ATTR_DATA]); buf_len = nla_len(tb[ATH6KL_TM_ATTR_DATA]); hb_params = (struct wlan_hb_params *)buf; if (hb_params->cmd == NL80211_WLAN_HB_ENABLE) { if (hb_params->enable != 0) { if (ath6kl_enable_wow_hb(ar)) { printk(KERN_ERR "%s: enable hb wow fail\n", __func__); return -EINVAL; } if (hb_params->enable & WLAN_HB_TCP_ENABLE) { ar->wlan_hb_enable |= WLAN_HB_TCP_ENABLE; if (ath6kl_wmi_set_heart_beat_params( ar->wmi, vif->fw_vif_idx, WLAN_HB_TCP_ENABLE)) { printk(KERN_ERR "%s: set heart beat enable fail\n", __func__); return -EINVAL; } } else if (hb_params->enable & WLAN_HB_UDP_ENABLE) { ar->wlan_hb_enable |= WLAN_HB_UDP_ENABLE; } } else { ar->wlan_hb_enable = 0; #ifdef CONFIG_ANDROID if (ath6kl_android_enable_wow_default(ar)) { printk(KERN_ERR "%s: enable android defualt wow fail\n", __func__); } #endif if (ath6kl_wmi_set_heart_beat_params(ar->wmi, vif->fw_vif_idx, 0)) { printk(KERN_ERR "%s: set heart beat enable fail\n", __func__); return -EINVAL; } } } else if (hb_params->cmd == NL80211_WLAN_TCP_PARAMS) { if (ath6kl_wmi_heart_beat_set_tcp_params(ar->wmi, vif->fw_vif_idx, hb_params->params.tcp_params.src_port, hb_params->params.tcp_params.dst_port, hb_params->params.tcp_params.timeout)) { printk(KERN_ERR "%s: set heart beat tcp params fail\n", __func__); return -EINVAL; } } else if (hb_params->cmd == NL80211_WLAN_TCP_FILTER) { if (hb_params->params.tcp_filter.length > WMI_MAX_TCP_FILTER_SIZE) { printk(KERN_ERR "%s: size of tcp filter is too large: %d\n", __func__, hb_params->params.tcp_filter.length); return -E2BIG; } if (ath6kl_wmi_heart_beat_set_tcp_filter(ar->wmi, vif->fw_vif_idx, hb_params->params.tcp_filter.filter, hb_params->params.tcp_filter.length)) { printk(KERN_ERR "%s: set heart beat tcp filter fail\n", __func__); return -EINVAL; } } else if (hb_params->cmd == NL80211_WLAN_UDP_PARAMS) { if (ath6kl_wmi_heart_beat_set_udp_params(ar->wmi, vif->fw_vif_idx, hb_params->params.udp_params.src_port, hb_params->params.udp_params.dst_port, hb_params->params.udp_params.interval, hb_params->params.udp_params.timeout)) { printk(KERN_ERR "%s: set heart beat udp params fail\n", __func__); return -EINVAL; } } else if (hb_params->cmd == NL80211_WLAN_UDP_FILTER) { if (hb_params->params.udp_filter.length > WMI_MAX_UDP_FILTER_SIZE) { printk(KERN_ERR "%s: size of udp filter is too large: %d\n", __func__, hb_params->params.udp_filter.length); return -E2BIG; } if (ath6kl_wmi_heart_beat_set_udp_filter(ar->wmi, vif->fw_vif_idx, hb_params->params.udp_filter.filter, hb_params->params.udp_filter.length)) { printk(KERN_ERR "%s: set heart beat udp filter fail\n", __func__); return -EINVAL; } } else if (hb_params->cmd == NL80211_WLAN_NET_INFO) { if (ath6kl_wmi_heart_beat_set_network_info(ar->wmi, vif->fw_vif_idx, hb_params->params.net_info.device_ip, hb_params->params.net_info.server_ip, hb_params->params.net_info.gateway_ip, hb_params->params.net_info.gateway_mac)) { printk(KERN_ERR "%s: set heart beat network information fail\n", __func__); return -EINVAL; } } } return 0; break; #endif #ifdef ATH6KL_SUPPORT_WIFI_DISC case ATH6KL_TM_CMD_WIFI_DISC: { struct wifi_disc_params *disc_params; struct ath6kl_vif *vif; vif = ath6kl_vif_first(ar); if (!vif) return -EINVAL; if (!tb[ATH6KL_TM_ATTR_DATA]) { printk(KERN_ERR "%s: NO DATA\n", __func__); return -EINVAL; } buf = nla_data(tb[ATH6KL_TM_ATTR_DATA]); buf_len = nla_len(tb[ATH6KL_TM_ATTR_DATA]); disc_params = (struct wifi_disc_params *)buf; if (disc_params->cmd == NL80211_WIFI_DISC_IE) { u8 ie_hdr[6] = {0xDD, 0x00, 0x00, 0x03, 0x7f, 0x00}; u8 *ie = NULL; u16 ie_length = disc_params->params.ie_params.length; ie = kmalloc(ie_length+6, GFP_KERNEL); if (ie == NULL) return -ENOMEM; memcpy(ie, ie_hdr, 6); ie[1] = ie_length+4; memcpy(ie+6, disc_params->params.ie_params.ie, ie_length); if (ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, WMI_FRAME_PROBE_REQ, ie, ie_length+6)) { kfree(ie); printk(KERN_ERR "%s: wifi discovery set probe request ie fail\n", __func__); return -EINVAL; } if (ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, WMI_FRAME_PROBE_RESP, ie, ie_length+6)) { kfree(ie); printk(KERN_ERR "%s: wifi discovery set probe response ie fail\n", __func__); return -EINVAL; } kfree(ie); } else if (disc_params->cmd == NL80211_WIFI_DISC_IE_FILTER) { if (ath6kl_wmi_disc_ie_cmd(ar->wmi, vif->fw_vif_idx, disc_params->params.ie_filter_params.enable, disc_params->params.ie_filter_params.startPos, disc_params->params.ie_filter_params.filter, disc_params->params.ie_filter_params.length)) { printk(KERN_ERR "%s: wifi discovery set ie filter fail\n", __func__); return -EINVAL; } } else if (disc_params->cmd == NL80211_WIFI_DISC_START) { int band, freq, numPeers, random; if (disc_params->params.start_params.channel <= 14) band = IEEE80211_BAND_2GHZ; else band = IEEE80211_BAND_5GHZ; freq = ieee80211_channel_to_frequency( disc_params->params.start_params.channel, band); if (!freq) { printk(KERN_ERR "%s: wifi discovery start channel %d error\n", __func__, disc_params->params.start_params.channel); return -EINVAL; } if (disc_params->params.start_params.numPeers == 0) numPeers = 1; else if (disc_params->params.start_params.numPeers > 4) numPeers = 4; else numPeers = disc_params->params.start_params.numPeers; random = (disc_params->params.start_params.random == 0) ? 100 : disc_params->params.start_params.random; if (disc_params->params.start_params.txPower) ath6kl_wmi_set_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx, disc_params->params.start_params.txPower); /* disable scanning */ ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, 0xFFFF, 0, 0, 0, 0, 0, 0, 0, 0, 0); if (ath6kl_wmi_disc_mode_cmd(ar->wmi, vif->fw_vif_idx, 1, freq, disc_params->params.start_params.dwellTime, disc_params->params.start_params.sleepTime, random, numPeers, disc_params->params.start_params.peerTimeout )) { printk(KERN_ERR "%s: wifi discovery start fail\n", __func__); return -EINVAL; } /* change disc state to active */ ar->disc_active = true; } else if (disc_params->cmd == NL80211_WIFI_DISC_STOP) { /* change disc state to inactive */ ar->disc_active = false; if (ath6kl_wmi_disc_mode_cmd(ar->wmi, vif->fw_vif_idx, 0, 0, 0, 0, 0, 0, 0)) { printk(KERN_ERR "%s: wifi discovery stop fail\n", __func__); return -EINVAL; } } } return 0; break; #endif #ifdef ATH6KL_SUPPORT_WIFI_KTK case ATH6KL_TM_CMD_WIFI_KTK: { struct wifi_ktk_params *ktk_params; struct ath6kl_vif *vif; vif = ath6kl_vif_first(ar); if (!vif) return -EINVAL; if (!tb[ATH6KL_TM_ATTR_DATA]) { printk(KERN_ERR "%s: NO DATA\n", __func__); return -EINVAL; } buf = nla_data(tb[ATH6KL_TM_ATTR_DATA]); buf_len = nla_len(tb[ATH6KL_TM_ATTR_DATA]); ktk_params = (struct wifi_ktk_params *)buf; if (ktk_params->cmd == NL80211_WIFI_KTK_IE) { u8 ie_hdr[6] = {0xDD, 0x00, 0x00, 0x03, 0x7f, 0x00}; u8 *ie = NULL; u16 ie_length = ktk_params->params.ie_params.length; ie = kmalloc(ie_length+6, GFP_KERNEL); if (ie == NULL) return -ENOMEM; memcpy(ie, ie_hdr, 6); ie[1] = ie_length+4; memcpy(ie+6, ktk_params->params.ie_params.ie, ie_length); if (ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, WMI_FRAME_PROBE_RESP, ie, ie_length+6)) { kfree(ie); printk(KERN_ERR "%s: wifi ktk set probe response ie fail\n", __func__); return -EINVAL; } if (ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, WMI_FRAME_BEACON, ie, ie_length+6)) { kfree(ie); printk(KERN_ERR "%s: wifi ktk set beacon ie fail\n", __func__); return -EINVAL; } kfree(ie); } else if (ktk_params->cmd == NL80211_WIFI_KTK_IE_FILTER) { if (ath6kl_wmi_disc_ie_cmd(ar->wmi, vif->fw_vif_idx, ktk_params->params.ie_filter_params.enable, ktk_params->params.ie_filter_params.startPos, ktk_params->params.ie_filter_params.filter, ktk_params->params.ie_filter_params.length)) { printk(KERN_ERR "%s: wifi ktk set ie filter fail\n", __func__); return -EINVAL; } } else if (ktk_params->cmd == NL80211_WIFI_KTK_START) { ar->ktk_active = true; /* Clear the legacy ie pattern and filter */ if (ath6kl_wmi_disc_ie_cmd(ar->wmi, vif->fw_vif_idx, 0, 0, NULL, 0)) { printk(KERN_ERR "%s: wifi ktk clear ie filter fail\n", __func__); return -EINVAL; } memcpy(ar->ktk_passphrase, ktk_params->params.start_params.passphrase, 16); if (ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, 1, SPECIFIC_SSID_FLAG, ktk_params->params.start_params.ssid_len, ktk_params->params.start_params.ssid)) { printk(KERN_ERR "%s: wifi ktk set probedssid fail\n", __func__); return -EINVAL; } if (ath6kl_wmi_ibss_pm_caps_cmd(ar->wmi, vif->fw_vif_idx, ADHOC_PS_KTK, 5, 10, 10)) { printk(KERN_ERR "%s: wifi ktk set power save mode on fail\n", __func__); return -EINVAL; } } else if (ktk_params->cmd == NL80211_WIFI_KTK_STOP) { ar->ktk_active = false; if (ath6kl_wmi_ibss_pm_caps_cmd(ar->wmi, vif->fw_vif_idx, ADHOC_PS_DISABLE, 0, 0, 0)) { printk(KERN_ERR "%s: wifi ktk set power save mode off fail\n", __func__); return -EINVAL; } } } return 0; break; #endif default: return -EOPNOTSUPP; } }
int mtk_cfg80211_vendor_get_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) { /*WLAN_STATUS rStatus;*/ UINT_32 u4BufLen; P_GLUE_INFO_T prGlueInfo = NULL; PARAM_WIFI_GSCAN_GET_RESULT_PARAMS rGSscnResultParm; INT_32 i4Status = -EINVAL; struct nlattr *attr; UINT_32 get_num = 0, real_num = 0; UINT_8 flush = 0; /*PARAM_WIFI_GSCAN_RESULT result[4], *pResult; struct sk_buff *skb;*/ int i; /*int j;*/ /*UINT_32 scan_id;*/ ASSERT(wiphy); ASSERT(wdev); if ((data == NULL) || !data_len) goto nla_put_failure; DBGLOG(REQ, TRACE, "%s for vendor command: data_len=%d \r\n", __func__, data_len); for (i = 0; i < 2; i++) DBGLOG(REQ, LOUD, "0x%x 0x%x 0x%x 0x%x \r\n", *((UINT_32 *) data + i * 4), *((UINT_32 *) data + i * 4 + 1), *((UINT_32 *) data + i * 4 + 2), *((UINT_32 *) data + i * 4 + 3)); attr = (struct nlattr *)data; if (attr->nla_type == GSCAN_ATTRIBUTE_NUM_OF_RESULTS) { get_num = nla_get_u32(attr); attr = (struct nlattr *)((UINT_8 *) attr + attr->nla_len); } if (attr->nla_type == GSCAN_ATTRIBUTE_FLUSH_RESULTS) { flush = nla_get_u8(attr); attr = (struct nlattr *)((UINT_8 *) attr + attr->nla_len); } DBGLOG(REQ, TRACE, "number=%d, flush=%d \r\n", get_num, flush); prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ASSERT(prGlueInfo); real_num = (get_num < PSCAN_MAX_SCAN_CACHE_SIZE) ? get_num : PSCAN_MAX_SCAN_CACHE_SIZE; get_num = real_num; #if 0 /* driver buffer FW results and reports by buffer workaround for FW mismatch with hal results numbers */ g_GetResultsCmdCnt++; DBGLOG(REQ, INFO, "(g_GetResultsCmdCnt [%d], g_GetResultsBufferedCnt [%d]\n", g_GetResultsCmdCnt, g_GetResultsBufferedCnt); BOOLEAN fgIsGetResultFromBuffer = FALSE; UINT_8 BufferedResultReportIndex = 0; if (g_GetResultsBufferedCnt > 0) { DBGLOG(REQ, INFO, "(g_GetResultsBufferedCnt > 0), report buffered results instead of ask from FW\n"); /* reply the results to wifi_hal */ for (i = 0; i < MAX_BUFFERED_GSCN_RESULTS; i++) { if (g_arGscanResultsIndicateNumber[i] > 0) { real_num = g_arGscanResultsIndicateNumber[i]; get_num = real_num; g_arGscanResultsIndicateNumber[i] = 0; fgIsGetResultFromBuffer = TRUE; BufferedResultReportIndex = i; break; } } if (i == MAX_BUFFERED_GSCN_RESULTS) DBGLOG(REQ, TRACE, "all buffered results are invalid, unexpected case \r\n"); DBGLOG(REQ, TRACE, "BufferedResultReportIndex[%d] i = %d real_num[%d] get_num[%d] \r\n", BufferedResultReportIndex, i, real_num, get_num); } #endif rGSscnResultParm.get_num = get_num; rGSscnResultParm.flush = flush; #if 0/* //driver buffer FW results and reports by buffer workaround for FW results mismatch with hal results number */ if (fgIsGetResultFromBuffer) { nicRxProcessGSCNEvent(prGlueInfo->prAdapter, g_arGscnResultsTempBuffer[BufferedResultReportIndex]); g_GetResultsBufferedCnt--; g_GetResultsCmdCnt--; nicRxReturnRFB(prGlueInfo->prAdapter, g_arGscnResultsTempBuffer[BufferedResultReportIndex]); } else #endif { kalIoctl(prGlueInfo, wlanoidGetGSCNResult, &rGSscnResultParm, sizeof(PARAM_WIFI_GSCAN_GET_RESULT_PARAMS), FALSE, FALSE, TRUE, FALSE, &u4BufLen); } return 0; nla_put_failure: return i4Status; }
static int tipc_nl_compat_link_stat_dump(struct tipc_nl_compat_msg *msg, struct nlattr **attrs) { char *name; struct nlattr *link[TIPC_NLA_LINK_MAX + 1]; struct nlattr *prop[TIPC_NLA_PROP_MAX + 1]; struct nlattr *stats[TIPC_NLA_STATS_MAX + 1]; nla_parse_nested(link, TIPC_NLA_LINK_MAX, attrs[TIPC_NLA_LINK], NULL); nla_parse_nested(prop, TIPC_NLA_PROP_MAX, link[TIPC_NLA_LINK_PROP], NULL); nla_parse_nested(stats, TIPC_NLA_STATS_MAX, link[TIPC_NLA_LINK_STATS], NULL); name = (char *)TLV_DATA(msg->req); if (strcmp(name, nla_data(link[TIPC_NLA_LINK_NAME])) != 0) return 0; tipc_tlv_sprintf(msg->rep, "\nLink <%s>\n", nla_data(link[TIPC_NLA_LINK_NAME])); if (link[TIPC_NLA_LINK_BROADCAST]) { __fill_bc_link_stat(msg, prop, stats); return 0; } if (link[TIPC_NLA_LINK_ACTIVE]) tipc_tlv_sprintf(msg->rep, " ACTIVE"); else if (link[TIPC_NLA_LINK_UP]) tipc_tlv_sprintf(msg->rep, " STANDBY"); else tipc_tlv_sprintf(msg->rep, " DEFUNCT"); tipc_tlv_sprintf(msg->rep, " MTU:%u Priority:%u", nla_get_u32(link[TIPC_NLA_LINK_MTU]), nla_get_u32(prop[TIPC_NLA_PROP_PRIO])); tipc_tlv_sprintf(msg->rep, " Tolerance:%u ms Window:%u packets\n", nla_get_u32(prop[TIPC_NLA_PROP_TOL]), nla_get_u32(prop[TIPC_NLA_PROP_WIN])); tipc_tlv_sprintf(msg->rep, " RX packets:%u fragments:%u/%u bundles:%u/%u\n", nla_get_u32(link[TIPC_NLA_LINK_RX]) - nla_get_u32(stats[TIPC_NLA_STATS_RX_INFO]), nla_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTS]), nla_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTED]), nla_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLES]), nla_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLED])); tipc_tlv_sprintf(msg->rep, " TX packets:%u fragments:%u/%u bundles:%u/%u\n", nla_get_u32(link[TIPC_NLA_LINK_TX]) - nla_get_u32(stats[TIPC_NLA_STATS_TX_INFO]), nla_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTS]), nla_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTED]), nla_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLES]), nla_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLED])); tipc_tlv_sprintf(msg->rep, " TX profile sample:%u packets average:%u octets\n", nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_CNT]), nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_TOT]) / nla_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT])); tipc_tlv_sprintf(msg->rep, " 0-64:%u%% -256:%u%% -1024:%u%% -4096:%u%% ", perc(nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P0]), nla_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT])), perc(nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P1]), nla_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT])), perc(nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P2]), nla_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT])), perc(nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P3]), nla_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT]))); tipc_tlv_sprintf(msg->rep, "-16384:%u%% -32768:%u%% -66000:%u%%\n", perc(nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P4]), nla_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT])), perc(nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P5]), nla_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT])), perc(nla_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P6]), nla_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT]))); tipc_tlv_sprintf(msg->rep, " RX states:%u probes:%u naks:%u defs:%u dups:%u\n", nla_get_u32(stats[TIPC_NLA_STATS_RX_STATES]), nla_get_u32(stats[TIPC_NLA_STATS_RX_PROBES]), nla_get_u32(stats[TIPC_NLA_STATS_RX_NACKS]), nla_get_u32(stats[TIPC_NLA_STATS_RX_DEFERRED]), nla_get_u32(stats[TIPC_NLA_STATS_DUPLICATES])); tipc_tlv_sprintf(msg->rep, " TX states:%u probes:%u naks:%u acks:%u dups:%u\n", nla_get_u32(stats[TIPC_NLA_STATS_TX_STATES]), nla_get_u32(stats[TIPC_NLA_STATS_TX_PROBES]), nla_get_u32(stats[TIPC_NLA_STATS_TX_NACKS]), nla_get_u32(stats[TIPC_NLA_STATS_TX_ACKS]), nla_get_u32(stats[TIPC_NLA_STATS_RETRANSMITTED])); tipc_tlv_sprintf(msg->rep, " Congestion link:%u Send queue max:%u avg:%u", nla_get_u32(stats[TIPC_NLA_STATS_LINK_CONGS]), nla_get_u32(stats[TIPC_NLA_STATS_MAX_QUEUE]), nla_get_u32(stats[TIPC_NLA_STATS_AVG_QUEUE])); return 0; }
int mtk_cfg80211_vendor_get_channel_list(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) { INT_32 i4Status = -EINVAL; struct nlattr *attr; UINT_32 band = 0; UINT_32 num_channel; wifi_channel channels[4]; struct sk_buff *skb; ASSERT(wiphy); ASSERT(wdev); if ((data == NULL) || !data_len) return i4Status; DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d \r\n", __func__, data_len); attr = (struct nlattr *)data; if (attr->nla_type == GSCAN_ATTRIBUTE_BAND) band = nla_get_u32(attr); DBGLOG(REQ, INFO, "get channel list: band=%d \r\n", band); skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(wifi_channel) * 4); if (!skb) { DBGLOG(REQ, TRACE, "%s allocate skb failed:%x\n", __func__, i4Status); return -ENOMEM; } kalMemZero(channels, sizeof(wifi_channel) * 4); /*rStatus = kalIoctl(prGlueInfo, wlanoidQueryStatistics, &channel, sizeof(channel), TRUE, TRUE, TRUE, FALSE, &u4BufLen); */ /* only for test */ num_channel = 3; channels[0] = 2412; channels[1] = 2413; channels[2] = 2414; /*NLA_PUT_U32(skb, GSCAN_ATTRIBUTE_NUM_CHANNELS, num_channel);*/ { unsigned int __tmp = num_channel; if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_NUM_CHANNELS, sizeof(unsigned int), &__tmp) < 0)) goto nla_put_failure; } /*NLA_PUT(skb, GSCAN_ATTRIBUTE_CHANNEL_LIST, (sizeof(wifi_channel) * num_channel), channels);*/ if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_CHANNEL_LIST, (sizeof(wifi_channel) * num_channel), channels) < 0)) goto nla_put_failure; i4Status = cfg80211_vendor_cmd_reply(skb); return i4Status; nla_put_failure: kfree_skb(skb); return i4Status; }
/* * iwpm_add_and_query_mapping_cb - Process a port mapper response to * iwpm_add_and_query_mapping() */ int iwpm_add_and_query_mapping_cb(struct sk_buff *skb, struct netlink_callback *cb) { struct iwpm_sa_data *pm_msg; struct iwpm_nlmsg_request *nlmsg_request = NULL; struct nlattr *nltb[IWPM_NLA_RQUERY_MAPPING_MAX]; struct sockaddr_storage *local_sockaddr, *remote_sockaddr; struct sockaddr_storage *mapped_loc_sockaddr, *mapped_rem_sockaddr; const char *msg_type; u32 msg_seq; u16 err_code; msg_type = "Query Mapping response"; if (iwpm_parse_nlmsg(cb, IWPM_NLA_RQUERY_MAPPING_MAX, resp_query_policy, nltb, msg_type)) return -EINVAL; atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); msg_seq = nla_get_u32(nltb[IWPM_NLA_QUERY_MAPPING_SEQ]); nlmsg_request = iwpm_find_nlmsg_request(msg_seq); if (!nlmsg_request) { pr_info("%s: Could not find a matching request (seq = %u)\n", __func__, msg_seq); return -EINVAL; } pm_msg = nlmsg_request->req_buffer; local_sockaddr = (struct sockaddr_storage *) nla_data(nltb[IWPM_NLA_QUERY_LOCAL_ADDR]); remote_sockaddr = (struct sockaddr_storage *) nla_data(nltb[IWPM_NLA_QUERY_REMOTE_ADDR]); mapped_loc_sockaddr = (struct sockaddr_storage *) nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_LOC_ADDR]); mapped_rem_sockaddr = (struct sockaddr_storage *) nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_REM_ADDR]); err_code = nla_get_u16(nltb[IWPM_NLA_RQUERY_MAPPING_ERR]); if (err_code == IWPM_REMOTE_QUERY_REJECT) { pr_info("%s: Received a Reject (pid = %u, echo seq = %u)\n", __func__, cb->nlh->nlmsg_pid, msg_seq); nlmsg_request->err_code = IWPM_REMOTE_QUERY_REJECT; } if (iwpm_compare_sockaddr(local_sockaddr, &pm_msg->loc_addr) || iwpm_compare_sockaddr(remote_sockaddr, &pm_msg->rem_addr)) { pr_info("%s: Incorrect local sockaddr\n", __func__); nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR; goto query_mapping_response_exit; } if (mapped_loc_sockaddr->ss_family != local_sockaddr->ss_family || mapped_rem_sockaddr->ss_family != remote_sockaddr->ss_family) { pr_info("%s: Sockaddr family doesn't match the requested one\n", __func__); nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR; goto query_mapping_response_exit; } memcpy(&pm_msg->mapped_loc_addr, mapped_loc_sockaddr, sizeof(*mapped_loc_sockaddr)); memcpy(&pm_msg->mapped_rem_addr, mapped_rem_sockaddr, sizeof(*mapped_rem_sockaddr)); iwpm_print_sockaddr(&pm_msg->loc_addr, "query_mapping: Local sockaddr:"); iwpm_print_sockaddr(&pm_msg->mapped_loc_addr, "query_mapping: Mapped local sockaddr:"); iwpm_print_sockaddr(&pm_msg->rem_addr, "query_mapping: Remote sockaddr:"); iwpm_print_sockaddr(&pm_msg->mapped_rem_addr, "query_mapping: Mapped remote sockaddr:"); query_mapping_response_exit: nlmsg_request->request_done = 1; /* always for found request */ kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request); barrier(); up(&nlmsg_request->sem); return 0; }
int nfnlmsg_queue_msg_parse(struct nlmsghdr *nlh, struct nfnl_queue_msg **result) { struct nfnl_queue_msg *msg; struct nlattr *tb[NFQA_MAX+1]; struct nlattr *attr; int err; msg = nfnl_queue_msg_alloc(); if (!msg) return -NLE_NOMEM; msg->ce_msgtype = nlh->nlmsg_type; err = nlmsg_parse(nlh, sizeof(struct nfgenmsg), tb, NFQA_MAX, queue_policy); if (err < 0) goto errout; nfnl_queue_msg_set_group(msg, nfnlmsg_res_id(nlh)); nfnl_queue_msg_set_family(msg, nfnlmsg_family(nlh)); attr = tb[NFQA_PACKET_HDR]; if (attr) { struct nfqnl_msg_packet_hdr *hdr = nla_data(attr); nfnl_queue_msg_set_packetid(msg, ntohl(hdr->packet_id)); if (hdr->hw_protocol) nfnl_queue_msg_set_hwproto(msg, hdr->hw_protocol); nfnl_queue_msg_set_hook(msg, hdr->hook); } attr = tb[NFQA_MARK]; if (attr) nfnl_queue_msg_set_mark(msg, ntohl(nla_get_u32(attr))); attr = tb[NFQA_TIMESTAMP]; if (attr) { struct nfqnl_msg_packet_timestamp *timestamp = nla_data(attr); struct timeval tv; tv.tv_sec = ntohll(timestamp->sec); tv.tv_usec = ntohll(timestamp->usec); nfnl_queue_msg_set_timestamp(msg, &tv); } attr = tb[NFQA_IFINDEX_INDEV]; if (attr) nfnl_queue_msg_set_indev(msg, ntohl(nla_get_u32(attr))); attr = tb[NFQA_IFINDEX_OUTDEV]; if (attr) nfnl_queue_msg_set_outdev(msg, ntohl(nla_get_u32(attr))); attr = tb[NFQA_IFINDEX_PHYSINDEV]; if (attr) nfnl_queue_msg_set_physindev(msg, ntohl(nla_get_u32(attr))); attr = tb[NFQA_IFINDEX_PHYSOUTDEV]; if (attr) nfnl_queue_msg_set_physoutdev(msg, ntohl(nla_get_u32(attr))); attr = tb[NFQA_HWADDR]; if (attr) { struct nfqnl_msg_packet_hw *hw = nla_data(attr); nfnl_queue_msg_set_hwaddr(msg, hw->hw_addr, ntohs(hw->hw_addrlen)); } attr = tb[NFQA_PAYLOAD]; if (attr) { err = nfnl_queue_msg_set_payload(msg, nla_data(attr), nla_len(attr)); if (err < 0) goto errout; } *result = msg; return 0; errout: nfnl_queue_msg_put(msg); return err; }
static int list_set_uadt(struct ip_set *set, struct nlattr *tb[], enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) { struct list_set *map = set->data; ipset_adtfn adtfn = set->variant->adt[adt]; struct set_adt_elem e = { .refid = IPSET_INVALID_ID }; struct ip_set_ext ext = IP_SET_INIT_UEXT(set); struct ip_set *s; int ret = 0; if (unlikely(!tb[IPSET_ATTR_NAME] || !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) || !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS) || !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) || !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES))) return -IPSET_ERR_PROTOCOL; if (tb[IPSET_ATTR_LINENO]) *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); ret = ip_set_get_extensions(set, tb, &ext); if (ret) return ret; e.id = ip_set_get_byname(map->net, nla_data(tb[IPSET_ATTR_NAME]), &s); if (e.id == IPSET_INVALID_ID) return -IPSET_ERR_NAME; /* "Loop detection" */ if (s->type->features & IPSET_TYPE_NAME) { ret = -IPSET_ERR_LOOP; goto finish; } if (tb[IPSET_ATTR_CADT_FLAGS]) { u32 f = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); e.before = f & IPSET_FLAG_BEFORE; } if (e.before && !tb[IPSET_ATTR_NAMEREF]) { ret = -IPSET_ERR_BEFORE; goto finish; } if (tb[IPSET_ATTR_NAMEREF]) { e.refid = ip_set_get_byname(map->net, nla_data(tb[IPSET_ATTR_NAMEREF]), &s); if (e.refid == IPSET_INVALID_ID) { ret = -IPSET_ERR_NAMEREF; goto finish; } if (!e.before) e.before = -1; } if (adt != IPSET_TEST && SET_WITH_TIMEOUT(set)) set_cleanup_entries(set); ret = adtfn(set, &e, &ext, &ext, flags); finish: if (e.refid != IPSET_INVALID_ID) ip_set_put_byindex(map->net, e.refid); if (adt != IPSET_ADD || ret) ip_set_put_byindex(map->net, e.id); return ip_set_eexist(ret, flags) ? 0 : ret; }
static int do_execute_actions(struct datapath *dp, struct sk_buff *skb, const struct nlattr *attr, int len, bool keep_skb) { /* */ int prev_port = -1; const struct nlattr *a; int rem; for (a = attr, rem = len; rem > 0; a = nla_next(a, &rem)) { int err = 0; if (prev_port != -1) { do_output(dp, skb_clone(skb, GFP_ATOMIC), prev_port); prev_port = -1; } switch (nla_type(a)) { case OVS_ACTION_ATTR_OUTPUT: prev_port = nla_get_u32(a); break; case OVS_ACTION_ATTR_USERSPACE: output_userspace(dp, skb, a); break; case OVS_ACTION_ATTR_PUSH_VLAN: err = push_vlan(skb, nla_data(a)); if (unlikely(err)) /* */ return err; break; case OVS_ACTION_ATTR_POP_VLAN: err = pop_vlan(skb); break; case OVS_ACTION_ATTR_SET: err = execute_set_action(skb, nla_data(a)); break; case OVS_ACTION_ATTR_SAMPLE: err = sample(dp, skb, a); break; } if (unlikely(err)) { kfree_skb(skb); return err; } } if (prev_port != -1) { if (keep_skb) skb = skb_clone(skb, GFP_ATOMIC); do_output(dp, skb, prev_port); } else if (!keep_skb) consume_skb(skb); return 0; }
static int gred_change(struct Qdisc *sch, struct nlattr *opt) { struct gred_sched *table = qdisc_priv(sch); struct tc_gred_qopt *ctl; struct nlattr *tb[TCA_GRED_MAX + 1]; int err, prio = GRED_DEF_PRIO; u8 *stab; u32 max_P; struct gred_sched_data *prealloc; if (opt == NULL) return -EINVAL; err = nla_parse_nested(tb, TCA_GRED_MAX, opt, gred_policy); if (err < 0) return err; if (tb[TCA_GRED_PARMS] == NULL && tb[TCA_GRED_STAB] == NULL) { if (tb[TCA_GRED_LIMIT] != NULL) sch->limit = nla_get_u32(tb[TCA_GRED_LIMIT]); return gred_change_table_def(sch, opt); } if (tb[TCA_GRED_PARMS] == NULL || tb[TCA_GRED_STAB] == NULL || tb[TCA_GRED_LIMIT] != NULL) return -EINVAL; max_P = tb[TCA_GRED_MAX_P] ? nla_get_u32(tb[TCA_GRED_MAX_P]) : 0; err = -EINVAL; ctl = nla_data(tb[TCA_GRED_PARMS]); stab = nla_data(tb[TCA_GRED_STAB]); if (ctl->DP >= table->DPs) goto errout; if (gred_rio_mode(table)) { if (ctl->prio == 0) { int def_prio = GRED_DEF_PRIO; if (table->tab[table->def]) def_prio = table->tab[table->def]->prio; printk(KERN_DEBUG "GRED: DP %u does not have a prio " "setting default to %d\n", ctl->DP, def_prio); prio = def_prio; } else prio = ctl->prio; } prealloc = kzalloc(sizeof(*prealloc), GFP_KERNEL); sch_tree_lock(sch); err = gred_change_vq(sch, ctl->DP, ctl, prio, stab, max_P, &prealloc); if (err < 0) goto errout_locked; if (gred_rio_mode(table)) { gred_disable_wred_mode(table); if (gred_wred_mode_check(sch)) gred_enable_wred_mode(table); } err = 0; errout_locked: sch_tree_unlock(sch); kfree(prealloc); errout: return err; }
int nfnlmsg_ct_parse(struct nlmsghdr *nlh, struct nfnl_ct **result) { struct nfnl_ct *ct; struct nlattr *tb[CTA_MAX+1]; int err; ct = nfnl_ct_alloc(); if (!ct) return -NLE_NOMEM; ct->ce_msgtype = nlh->nlmsg_type; err = nlmsg_parse(nlh, sizeof(struct nfgenmsg), tb, CTA_MAX, ct_policy); if (err < 0) goto errout; nfnl_ct_set_family(ct, nfnlmsg_family(nlh)); if (tb[CTA_TUPLE_ORIG]) { err = ct_parse_tuple(ct, 0, tb[CTA_TUPLE_ORIG]); if (err < 0) goto errout; } if (tb[CTA_TUPLE_REPLY]) { err = ct_parse_tuple(ct, 1, tb[CTA_TUPLE_REPLY]); if (err < 0) goto errout; } if (tb[CTA_PROTOINFO]) { err = ct_parse_protoinfo(ct, tb[CTA_PROTOINFO]); if (err < 0) goto errout; } if (tb[CTA_STATUS]) nfnl_ct_set_status(ct, ntohl(nla_get_u32(tb[CTA_STATUS]))); if (tb[CTA_TIMEOUT]) nfnl_ct_set_timeout(ct, ntohl(nla_get_u32(tb[CTA_TIMEOUT]))); if (tb[CTA_MARK]) nfnl_ct_set_mark(ct, ntohl(nla_get_u32(tb[CTA_MARK]))); if (tb[CTA_USE]) nfnl_ct_set_use(ct, ntohl(nla_get_u32(tb[CTA_USE]))); if (tb[CTA_ID]) nfnl_ct_set_id(ct, ntohl(nla_get_u32(tb[CTA_ID]))); if (tb[CTA_ZONE]) nfnl_ct_set_zone(ct, ntohs(nla_get_u16(tb[CTA_ZONE]))); if (tb[CTA_COUNTERS_ORIG]) { err = ct_parse_counters(ct, 0, tb[CTA_COUNTERS_ORIG]); if (err < 0) goto errout; } if (tb[CTA_COUNTERS_REPLY]) { err = ct_parse_counters(ct, 1, tb[CTA_COUNTERS_REPLY]); if (err < 0) goto errout; } if (tb[CTA_TIMESTAMP]) { err = ct_parse_timestamp(ct, tb[CTA_TIMESTAMP]); if (err < 0) goto errout; } *result = ct; return 0; errout: nfnl_ct_put(ct); return err; }