/* * Format up to a page worth of forwarding table entries * userbuf -- where to copy result * maxnum -- maximum number of entries desired * (limited to a page for sanity) * offset -- number of records to skip */ static int brc_get_fdb_entries(struct net_device *dev, void __user *userbuf, unsigned long maxnum, unsigned long offset) { struct nlattr *attrs[BRC_GENL_A_MAX + 1]; struct sk_buff *request, *reply; int retval; int len; /* Clamp size to PAGE_SIZE, test maxnum to avoid overflow */ if (maxnum > PAGE_SIZE/sizeof(struct __fdb_entry)) maxnum = PAGE_SIZE/sizeof(struct __fdb_entry); request = brc_make_request(BRC_GENL_C_FDB_QUERY, dev->name, NULL); if (!request) return -ENOMEM; NLA_PUT_U64(request, BRC_GENL_A_FDB_COUNT, maxnum); NLA_PUT_U64(request, BRC_GENL_A_FDB_SKIP, offset); rtnl_unlock(); reply = brc_send_command(request, attrs); retval = PTR_ERR(reply); if (IS_ERR(reply)) goto exit; retval = -nla_get_u32(attrs[BRC_GENL_A_ERR_CODE]); if (retval < 0) goto exit_free_skb; retval = -EINVAL; if (!attrs[BRC_GENL_A_FDB_DATA]) goto exit_free_skb; len = nla_len(attrs[BRC_GENL_A_FDB_DATA]); if (len % sizeof(struct __fdb_entry) || len / sizeof(struct __fdb_entry) > maxnum) goto exit_free_skb; retval = len / sizeof(struct __fdb_entry); if (copy_to_user(userbuf, nla_data(attrs[BRC_GENL_A_FDB_DATA]), len)) retval = -EFAULT; exit_free_skb: kfree_skb(reply); exit: rtnl_lock(); return retval; nla_put_failure: kfree_skb(request); return -ENOMEM; }
static int l2tp_nl_session_send(struct sk_buff *skb, u32 pid, u32 seq, int flags, struct l2tp_session *session) { void *hdr; struct nlattr *nest; struct l2tp_tunnel *tunnel = session->tunnel; struct sock *sk = NULL; sk = tunnel->sock; hdr = genlmsg_put(skb, pid, seq, &l2tp_nl_family, flags, L2TP_CMD_SESSION_GET); if (IS_ERR(hdr)) return PTR_ERR(hdr); NLA_PUT_U32(skb, L2TP_ATTR_CONN_ID, tunnel->tunnel_id); NLA_PUT_U32(skb, L2TP_ATTR_SESSION_ID, session->session_id); NLA_PUT_U32(skb, L2TP_ATTR_PEER_CONN_ID, tunnel->peer_tunnel_id); NLA_PUT_U32(skb, L2TP_ATTR_PEER_SESSION_ID, session->peer_session_id); NLA_PUT_U32(skb, L2TP_ATTR_DEBUG, session->debug); NLA_PUT_U16(skb, L2TP_ATTR_PW_TYPE, session->pwtype); NLA_PUT_U16(skb, L2TP_ATTR_MTU, session->mtu); if (session->mru) NLA_PUT_U16(skb, L2TP_ATTR_MRU, session->mru); if (session->ifname && session->ifname[0]) NLA_PUT_STRING(skb, L2TP_ATTR_IFNAME, session->ifname); if (session->cookie_len) NLA_PUT(skb, L2TP_ATTR_COOKIE, session->cookie_len, &session->cookie[0]); if (session->peer_cookie_len) NLA_PUT(skb, L2TP_ATTR_PEER_COOKIE, session->peer_cookie_len, &session->peer_cookie[0]); NLA_PUT_U8(skb, L2TP_ATTR_RECV_SEQ, session->recv_seq); NLA_PUT_U8(skb, L2TP_ATTR_SEND_SEQ, session->send_seq); NLA_PUT_U8(skb, L2TP_ATTR_LNS_MODE, session->lns_mode); #ifdef CONFIG_XFRM if ((sk) && (sk->sk_policy[0] || sk->sk_policy[1])) NLA_PUT_U8(skb, L2TP_ATTR_USING_IPSEC, 1); #endif if (session->reorder_timeout) NLA_PUT_MSECS(skb, L2TP_ATTR_RECV_TIMEOUT, session->reorder_timeout); nest = nla_nest_start(skb, L2TP_ATTR_STATS); if (nest == NULL) goto nla_put_failure; NLA_PUT_U64(skb, L2TP_ATTR_TX_PACKETS, session->stats.tx_packets); NLA_PUT_U64(skb, L2TP_ATTR_TX_BYTES, session->stats.tx_bytes); NLA_PUT_U64(skb, L2TP_ATTR_TX_ERRORS, session->stats.tx_errors); NLA_PUT_U64(skb, L2TP_ATTR_RX_PACKETS, session->stats.rx_packets); NLA_PUT_U64(skb, L2TP_ATTR_RX_BYTES, session->stats.rx_bytes); NLA_PUT_U64(skb, L2TP_ATTR_RX_SEQ_DISCARDS, session->stats.rx_seq_discards); NLA_PUT_U64(skb, L2TP_ATTR_RX_OOS_PACKETS, session->stats.rx_oos_packets); NLA_PUT_U64(skb, L2TP_ATTR_RX_ERRORS, session->stats.rx_errors); nla_nest_end(skb, nest); return genlmsg_end(skb, hdr); nla_put_failure: genlmsg_cancel(skb, hdr); return -1; }
static int l2tp_nl_tunnel_send(struct sk_buff *skb, u32 pid, u32 seq, int flags, struct l2tp_tunnel *tunnel) { void *hdr; struct nlattr *nest; struct sock *sk = NULL; struct inet_sock *inet; hdr = genlmsg_put(skb, pid, seq, &l2tp_nl_family, flags, L2TP_CMD_TUNNEL_GET); if (IS_ERR(hdr)) return PTR_ERR(hdr); NLA_PUT_U8(skb, L2TP_ATTR_PROTO_VERSION, tunnel->version); NLA_PUT_U32(skb, L2TP_ATTR_CONN_ID, tunnel->tunnel_id); NLA_PUT_U32(skb, L2TP_ATTR_PEER_CONN_ID, tunnel->peer_tunnel_id); NLA_PUT_U32(skb, L2TP_ATTR_DEBUG, tunnel->debug); NLA_PUT_U16(skb, L2TP_ATTR_ENCAP_TYPE, tunnel->encap); nest = nla_nest_start(skb, L2TP_ATTR_STATS); if (nest == NULL) goto nla_put_failure; NLA_PUT_U64(skb, L2TP_ATTR_TX_PACKETS, tunnel->stats.tx_packets); NLA_PUT_U64(skb, L2TP_ATTR_TX_BYTES, tunnel->stats.tx_bytes); NLA_PUT_U64(skb, L2TP_ATTR_TX_ERRORS, tunnel->stats.tx_errors); NLA_PUT_U64(skb, L2TP_ATTR_RX_PACKETS, tunnel->stats.rx_packets); NLA_PUT_U64(skb, L2TP_ATTR_RX_BYTES, tunnel->stats.rx_bytes); NLA_PUT_U64(skb, L2TP_ATTR_RX_SEQ_DISCARDS, tunnel->stats.rx_seq_discards); NLA_PUT_U64(skb, L2TP_ATTR_RX_OOS_PACKETS, tunnel->stats.rx_oos_packets); NLA_PUT_U64(skb, L2TP_ATTR_RX_ERRORS, tunnel->stats.rx_errors); nla_nest_end(skb, nest); sk = tunnel->sock; if (!sk) goto out; inet = inet_sk(sk); switch (tunnel->encap) { case L2TP_ENCAPTYPE_UDP: NLA_PUT_U16(skb, L2TP_ATTR_UDP_SPORT, ntohs(inet->inet_sport)); NLA_PUT_U16(skb, L2TP_ATTR_UDP_DPORT, ntohs(inet->inet_dport)); NLA_PUT_U8(skb, L2TP_ATTR_UDP_CSUM, (sk->sk_no_check != UDP_CSUM_NOXMIT)); /* NOBREAK */ case L2TP_ENCAPTYPE_IP: NLA_PUT_BE32(skb, L2TP_ATTR_IP_SADDR, inet->inet_saddr); NLA_PUT_BE32(skb, L2TP_ATTR_IP_DADDR, inet->inet_daddr); break; } out: return genlmsg_end(skb, hdr); nla_put_failure: genlmsg_cancel(skb, hdr); return -1; }
static int handle_interface_add(struct nl802154_state *state, struct nl_cb *cb, struct nl_msg *msg, int argc, char **argv, enum id_input id) { char *name; enum nl802154_iftype type; uint64_t eui64 = 0; int tpset; if (argc < 1) return 1; name = argv[0]; argc--; argv++; tpset = get_if_type(&argc, &argv, &type, true); if (tpset) return tpset; tpset = get_eui64(&argc, &argv, &eui64); if (tpset) return tpset; if (argc) return 1; NLA_PUT_STRING(msg, NL802154_ATTR_IFNAME, name); NLA_PUT_U32(msg, NL802154_ATTR_IFTYPE, type); NLA_PUT_U64(msg, NL802154_ATTR_EXTENDED_ADDR, eui64); return 0; nla_put_failure: return -ENOBUFS; }