static int vrf_fib_rule(const struct net_device *dev, __u8 family, bool add_it) { struct fib_rule_hdr *frh; struct nlmsghdr *nlh; struct sk_buff *skb; int err; if (family == AF_INET6 && !ipv6_mod_enabled()) return 0; skb = nlmsg_new(vrf_fib_rule_nl_size(), GFP_KERNEL); if (!skb) return -ENOMEM; nlh = nlmsg_put(skb, 0, 0, 0, sizeof(*frh), 0); if (!nlh) goto nla_put_failure; /* rule only needs to appear once */ nlh->nlmsg_flags |= NLM_F_EXCL; frh = nlmsg_data(nlh); memset(frh, 0, sizeof(*frh)); frh->family = family; frh->action = FR_ACT_TO_TBL; if (nla_put_u8(skb, FRA_L3MDEV, 1)) goto nla_put_failure; if (nla_put_u32(skb, FRA_PRIORITY, FIB_RULE_PREF)) goto nla_put_failure; nlmsg_end(skb, nlh); /* fib_nl_{new,del}rule handling looks for net from skb->sk */ skb->sk = dev_net(dev)->rtnl; if (add_it) { err = fib_nl_newrule(skb, nlh, NULL); if (err == -EEXIST) err = 0; } else { err = fib_nl_delrule(skb, nlh, NULL); if (err == -ENOENT) err = 0; } nlmsg_free(skb); return err; nla_put_failure: nlmsg_free(skb); return -EMSGSIZE; }
/** * Add netlink and netfilter netlink headers to netlink message * @arg msg netlink message * @arg pid netlink process id * @arg seq sequence number of message * @arg subsys_id nfnetlink subsystem * @arg type nfnetlink message type * @arg flags message flags * @arg family nfnetlink address family * @arg res_id nfnetlink resource id */ int nfnlmsg_put(struct nl_msg *msg, uint32_t pid, uint32_t seq, uint8_t subsys_id, uint8_t type, int flags, uint8_t family, uint16_t res_id) { struct nlmsghdr *nlh; nlh = nlmsg_put(msg, pid, seq, NFNLMSG_TYPE(subsys_id, type), 0, flags); if (nlh == NULL) return -NLE_MSGSIZE; return nfnlmsg_append(msg, family, res_id); }
static void quota2_log(unsigned int hooknum, const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, const char *prefix) { ulog_packet_msg_t *pm; struct sk_buff *log_skb; size_t size; struct nlmsghdr *nlh; if (!qlog_nl_event) return; size = NLMSG_SPACE(sizeof(*pm)); size = max(size, (size_t)NLMSG_GOODSIZE); log_skb = alloc_skb(size, GFP_ATOMIC); if (!log_skb) { pr_err("xt_quota2: cannot alloc skb for logging\n"); return; } nlh = nlmsg_put(log_skb, /*pid*/0, /*seq*/0, qlog_nl_event, sizeof(*pm), 0); if (!nlh) { pr_err("xt_quota2: nlmsg_put failed\n"); kfree_skb(log_skb); return; } pm = nlmsg_data(nlh); if (skb->tstamp.tv64 == 0) __net_timestamp((struct sk_buff *)skb); pm->data_len = 0; pm->hook = hooknum; if (prefix != NULL) strlcpy(pm->prefix, prefix, sizeof(pm->prefix)); else *(pm->prefix) = '\0'; if (in) strlcpy(pm->indev_name, in->name, sizeof(pm->indev_name)); else pm->indev_name[0] = '\0'; if (out) strlcpy(pm->outdev_name, out->name, sizeof(pm->outdev_name)); else pm->outdev_name[0] = '\0'; NETLINK_CB(log_skb).dst_group = 1; pr_debug("throwing 1 packets to netlink group 1\n"); netlink_broadcast(nflognl, log_skb, 0, 1, GFP_ATOMIC); }
/* * Broadcast Logging service ready indication to any Logging application * Each netlink message will have a message of type tAniMsgHdr inside. */ void wlan_logging_srv_nl_ready_indication(void) { struct sk_buff *skb = NULL; struct nlmsghdr *nlh; tAniNlHdr *wnl = NULL; int payload_len; int err; static int rate_limit; payload_len = sizeof(tAniHdr) + sizeof(wlan_logging_ready) + sizeof(wnl->radio); skb = dev_alloc_skb(NLMSG_SPACE(payload_len)); if (NULL == skb) { if (!rate_limit) { LOGGING_TRACE(VOS_TRACE_LEVEL_ERROR, "NLINK: skb alloc fail %s", __func__); } rate_limit = 1; return; } rate_limit = 0; nlh = nlmsg_put(skb, 0, 0, ANI_NL_MSG_LOG, payload_len, NLM_F_REQUEST); if (NULL == nlh) { LOGGING_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: nlmsg_put() failed for msg size[%d]", __func__, payload_len); kfree_skb(skb); return; } wnl = (tAniNlHdr *) nlh; wnl->radio = 0; wnl->wmsg.type = ANI_NL_MSG_READY_IND_TYPE; wnl->wmsg.length = sizeof(wlan_logging_ready); memcpy((char*)&wnl->wmsg + sizeof(tAniHdr), wlan_logging_ready, sizeof(wlan_logging_ready)); /* sender is in group 1<<0 */ NETLINK_CB(skb).dst_group = WLAN_NLINK_MCAST_GRP_ID; /*multicast the message to all listening processes*/ err = nl_srv_bcast(skb); if (err) { LOGGING_TRACE(VOS_TRACE_LEVEL_INFO_LOW, "NLINK: Ready Indication Send Fail %s, err %d", __func__, err); } return; }
static void recv_msg(struct sk_buff *skb) { struct nlmsghdr *nlh; pid_t pid; struct sk_buff *skb_out; int msg_size; char *msg="mkm-ack"; int res; mutex_lock(&mkm_nl_mutex); msg_size = strlen(msg); nlh = nlmsg_hdr(skb); if(strncmp((char *)nlmsg_data(nlh),"mkm-syn",strlen("mkm-syn")) != 0) { printk(KERN_WARNING "MKM(monitor kernel module),received invaild mkm-syn messgae: %s\n",(char *)nlmsg_data(nlh)); mutex_unlock(&mkm_nl_mutex); return; } if((pid = nlh->nlmsg_pid)<= 0) { printk(KERN_WARNING "MKM(monitor kernel module),received invalid PID from mkm-syn message %i\n",pid); mutex_unlock(&mkm_nl_mutex); return ; } skb_out = nlmsg_new(msg_size,0); if(!skb_out) { printk(KERN_WARNING "MKM(monitor kernel module),failed to allocate new skb\n"); mutex_unlock(&mkm_nl_mutex); return ; } nlh = nlmsg_put(skb_out, 0, 0, NLMSG_DONE,msg_size, 0); NETLINK_CB(skb_out).dst_group = 0; strncpy(nlmsg_data(nlh), msg,msg_size); nlmsg_end(skb_out,nlh); res = nlmsg_unicast(nl_sock,skb_out,pid); if(res != 0) { printk(KERN_WARNING "MKM(monitor kernel module),failed to send mkm-ack message to %i\n",pid); mutex_unlock(&mkm_nl_mutex); return ; } mkm_userspace_pid = pid; mutex_unlock(&mkm_nl_mutex); printk("MKM(monitor kernel module) set ulevel pud to %i\n",mkm_userspace_pid); }
/* Utility function to send a netlink message to an application * in user space */ static int wlan_send_sock_msg_to_app(tAniHdr *wmsg, int radio, int src_mod, int pid) { int err = -1; int payload_len; int tot_msg_len; tAniNlHdr *wnl = NULL; struct sk_buff *skb; struct nlmsghdr *nlh; int wmsg_length = wmsg->length; static int nlmsg_seq; if (radio < 0 || radio > ANI_MAX_RADIOS) { LOGGING_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: invalid radio id [%d]", __func__, radio); return -EINVAL; } payload_len = wmsg_length + sizeof(wnl->radio); tot_msg_len = NLMSG_SPACE(payload_len); skb = dev_alloc_skb(tot_msg_len); if (skb == NULL) { LOGGING_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: dev_alloc_skb() failed for msg size[%d]", __func__, tot_msg_len); return -ENOMEM; } nlh = nlmsg_put(skb, pid, nlmsg_seq++, src_mod, payload_len, NLM_F_REQUEST); if (NULL == nlh) { LOGGING_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: nlmsg_put() failed for msg size[%d]", __func__, tot_msg_len); kfree_skb(skb); return -ENOMEM; } wnl = (tAniNlHdr *) nlh; wnl->radio = radio; memcpy(&wnl->wmsg, wmsg, wmsg_length); err = nl_srv_ucast(skb, pid, MSG_DONTWAIT); if (err) { LOGGING_TRACE(VOS_TRACE_LEVEL_INFO, "%s: Failed sending Msg Type [0x%X] to pid[%d]\n", __func__, wmsg->type, pid); } return err; }
//for receve and send of message to client application static void nl_recv_send_msg(struct sk_buff *skb) { static uint16_t *buf ; struct nlmsghdr *nlh; int pid; struct sk_buff *skb_out; int msg_size; int res; uint32_t ret ; uint32_t *read_buf; printk(KERN_INFO "Entering to kernel module \n"); nlh=(struct nlmsghdr*)skb->data; printk(KERN_INFO "Netlink received msg payload: %s\n",(char*)nlmsg_data(nlh)); pid = nlh->nlmsg_pid; /*pid of sending process */ buf = nlmsg_data(nlh); printk(KERN_INFO"data of buf before sending %x %x of size %d\n",*buf,*(buf+1), sizeof(buf)); gpio_set_value(gpio_pin_chipselect,0); // manually controlling chipselect by making it low /* spi_write function sends data using our spi */ res = spi_write(spi_pot_device,&buf,sizeof buf) ; printk(KERN_INFO "Write Result %d Size of Ret is %d\n",res,sizeof(ret)) ; /* spi_read to read the data form our spi */ res = spi_read(spi_pot_device,&ret,sizeof ret); printk(KERN_INFO "Got Result and ret val: %d %d\n",ret,res) ; gpio_set_value(gpio_pin_chipselect,1); // making again chipselect high read_buf = &ret; msg_size= strlen(read_buf); printk(KERN_INFO " buf value = %x \n",*read_buf); skb_out = nlmsg_new(msg_size,0); if(!skb_out) { printk(KERN_ERR "Failed to allocate new skb\n"); return; } nlh=nlmsg_put(skb_out,0,0,NLMSG_DONE,msg_size,0); NETLINK_CB(skb_out).dst_group = 0; // not in mcast group strncpy(nlmsg_data(nlh),read_buf,msg_size); res=nlmsg_unicast(nl_sk,skb_out,pid); if(res<0) printk(KERN_INFO "Error while sending bak to user\n"); }
/* * Create one netlink message for one interface * Contains port and master info as well as carrier and bridge state. */ static int br_fill_ifinfo(struct sk_buff *skb, const struct net_bridge_port *port, u32 pid, u32 seq, int event, unsigned int flags) { const struct net_bridge *br = port->br; const struct net_device *dev = port->dev; struct ifinfomsg *hdr; struct nlmsghdr *nlh; u8 operstate = netif_running(dev) ? dev->operstate : IF_OPER_DOWN; br_debug(br, "br_fill_info event %d port %s master %s\n", event, dev->name, br->dev->name); nlh = nlmsg_put(skb, pid, seq, event, sizeof(*hdr), flags); if (nlh == NULL) return -EMSGSIZE; hdr = nlmsg_data(nlh); hdr->ifi_family = AF_BRIDGE; hdr->__ifi_pad = 0; hdr->ifi_type = dev->type; hdr->ifi_index = dev->ifindex; hdr->ifi_flags = dev_get_flags(dev); hdr->ifi_change = 0; if (nla_put_string(skb, IFLA_IFNAME, dev->name) || nla_put_u32(skb, IFLA_MASTER, br->dev->ifindex) || nla_put_u32(skb, IFLA_MTU, dev->mtu) || nla_put_u8(skb, IFLA_OPERSTATE, operstate) || (dev->addr_len && nla_put(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr)) || (dev->ifindex != dev->iflink && nla_put_u32(skb, IFLA_LINK, dev->iflink))) goto nla_put_failure; if (event == RTM_NEWLINK) { struct nlattr *nest = nla_nest_start(skb, IFLA_PROTINFO | NLA_F_NESTED); if (nest == NULL || br_port_fill_attrs(skb, port) < 0) goto nla_put_failure; nla_nest_end(skb, nest); } return nlmsg_end(skb, nlh); nla_put_failure: nlmsg_cancel(skb, nlh); return -EMSGSIZE; }
int kni_nl_unicast(int pid, struct sk_buff *skb_in, struct net_device *dev) { struct sk_buff *skb; struct nlmsghdr *nlh; struct net *net = dev_net(dev); struct kni_net_namespace *kni_net = net_generic(net, kni_net_id); struct rw_kni_mbuf_metadata *meta_data; int size, err; unsigned char *data; size = NLMSG_ALIGN(sizeof(*meta_data) + skb_in->len); skb = nlmsg_new(size, GFP_KERNEL); if (skb == NULL){ return -ENOMEM; } nlh = nlmsg_put(skb, pid, 0, KNI_NETLINK_MSG_TX, 0, 0); if (nlh == NULL){ goto nlmsg_failure; } err = skb_linearize(skb_in); if (unlikely(err)){ goto nlmsg_failure; } meta_data = (struct rw_kni_mbuf_metadata *)nlmsg_data(nlh);; memset(meta_data, 0, sizeof(*meta_data)); data = (unsigned char *)(meta_data +1); RW_KNI_VF_SET_MDATA_ENCAP_TYPE(meta_data, skb_in->protocol); RW_KNI_VF_SET_MDATA_LPORTID(meta_data, dev->ifindex); RW_KNI_VF_SET_MDATA_L3_OFFSET(meta_data, skb_in->len); memcpy(data, skb_in->data, skb_in->len); //akki skb_put(skb, size); nlmsg_end(skb, nlh); return nlmsg_unicast(kni_net->netlink_sock, skb, pid); nlmsg_failure: nlmsg_cancel(skb, nlh); kfree_skb(skb); return -1; }
static void nl_recv_msg_udp(struct sk_buff *skb) { struct nlmsghdr *nlh; struct sk_buff *skb_out; int msg_size; char *msg="Hello from kernel"; int res; printk(KERN_INFO "Entering: %s\n", __FUNCTION__); msg_size=strlen(msg); nlh=(struct nlmsghdr*)skb->data; if (!gotPid) { pid = nlh->nlmsg_pid; /*pid of sending process */ gotPid=true; gotUserOrNotUdp(true); skb_out = nlmsg_new(msg_size,0); printk(KERN_INFO "Netlink received msg payload: %s\n",(char*)nlmsg_data(nlh)); if(!skb_out) { printk(KERN_ERR "Failed to allocate new skb\n"); return; } nlh = nlmsg_put(skb_out,0,0,NLMSG_DONE,msg_size,0); NETLINK_CB(skb_out).dst_group = 0; strncpy(nlmsg_data(nlh),msg,msg_size); res=nlmsg_unicast(nl_sk_udp,skb_out,pid); if (res<0){ printk(KERN_INFO "Error while sending back to user\n"); gotPid=false; gotUserOrNotUdp(false); } else { } }else { printk(KERN_INFO "Netlink received msg payload: %s\n",(char*)nlmsg_data(nlh)); skb_out = nlmsg_new(msg_size,0); if(!skb_out) { printk(KERN_ERR "Failed to allocate new skb\n"); return; } if (((char*)nlmsg_data(nlh))[0] == 'y'){ letItResumeUdp(false); }else{ letItResumeUdp(true); } } }
void nl_data_ready (struct sk_buff *__skb) { struct sk_buff *skb; struct nlmsghdr *nlh; u32 pid; int rc; int len = NLMSG_SPACE(1200); char str[100]; printk("net_link: data is ready to read.\n"); skb = skb_get(__skb); if (skb->len >= NLMSG_SPACE(0)) { nlh = nlmsg_hdr(skb); printk("net_link: recv %s.\n", (char *)NLMSG_DATA(nlh)); memcpy(str,NLMSG_DATA(nlh), sizeof(str)); printk("str[0] is %d\n",str[0]); pid = nlh->nlmsg_pid; printk("net_link: pid is %d\n", pid); kfree_skb(skb); skb = alloc_skb(len, GFP_ATOMIC); if (!skb){ printk(KERN_ERR "net_link: allocate failed.\n"); return; } nlh = nlmsg_put(skb,0,0,0,1200,0); NETLINK_CB(skb).pid = 0; if(str[0] == 1){ flag = 1; memcpy(NLMSG_DATA(nlh), "start", 6); } else if(str[0] == 2){ flag = 0; memcpy(NLMSG_DATA(nlh), "end", 4); } printk("net_link: going to send.\n"); rc = netlink_unicast(nl_sk, skb, pid, MSG_DONTWAIT); if (rc < 0) { printk(KERN_ERR "net_link: can not unicast skb (%d)\n", rc); } printk("net_link: send is ok.\n"); } return; }
static int sockev_client_cb(struct notifier_block *nb, unsigned long event, void *data) { struct sk_buff *skb; struct nlmsghdr *nlh; struct sknlsockevmsg *smsg; struct socket *sock; sock = (struct socket *)data; if (socknlmsgsk == 0) goto done; if ((socknlmsgsk == NULL) || (sock == NULL) || (sock->sk == NULL)) goto done; if (sock->sk->sk_family != AF_INET && sock->sk->sk_family != AF_INET6) goto done; if (event != SOCKEV_BIND && event != SOCKEV_LISTEN) goto done; skb = nlmsg_new(sizeof(struct sknlsockevmsg), GFP_KERNEL); if (skb == NULL) goto done; nlh = nlmsg_put(skb, 0, 0, event, sizeof(struct sknlsockevmsg), 0); if (nlh == NULL) { kfree_skb(skb); goto done; } NETLINK_CB(skb).dst_group = SKNLGRP_SOCKEV; smsg = nlmsg_data(nlh); smsg->pid = current->pid; _sockev_event(event, smsg->event, sizeof(smsg->event)); smsg->skfamily = sock->sk->sk_family; smsg->skstate = sock->sk->sk_state; smsg->skprotocol = sock->sk->sk_protocol; smsg->sktype = sock->sk->sk_type; smsg->skflags = sock->sk->sk_flags; nlmsg_notify(socknlmsgsk, skb, 0, SKNLGRP_SOCKEV, 0, GFP_KERNEL); done: return 0; }
void send_command_to_daemon(const int command /*struct sk_buff *skb */) { struct nlmsghdr *nlh; struct sk_buff *nl_skb; int res; MSG("here we will send command to native daemon\n"); if (!g_nl_sk) { ERR("invalid socket\n"); return; } if (pid == 0) { ERR("invalid native process pid\n"); return; } /*alloc data buffer for sending to native */ /*malloc data space at least 1500 bytes, which is ethernet data length */ nl_skb = alloc_skb(NLMSG_SPACE(MAX_NL_MSG_LEN), GFP_ATOMIC); if (nl_skb == NULL) { ERR("malloc skb error\n"); return; } MSG("malloc data space done\n"); /* ehdr = eth_hdr(skb); iph = ip_hdr(skb); */ /* nlh = NLMSG_PUT(nl_skb, 0, 0, 0, NLMSG_SPACE(1500)-sizeof(struct nlmsghdr)); */ nlh = nlmsg_put(nl_skb, 0, 0, 0, MAX_NL_MSG_LEN, 0); #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)) NETLINK_CB(nl_skb).pid = 0; #else NETLINK_CB(nl_skb).portid = 0; #endif /* memcpy(NLMSG_DATA(nlh), ACK, 5); */ *(char *)NLMSG_DATA(nlh) = command; res = netlink_unicast(g_nl_sk, nl_skb, pid, MSG_DONTWAIT); if (res == 0) { MSG("send to user space process error\n"); return; } else { ERR("send to user space process done, data length = %d\n", res); return; } }
static int tcf_add_notify(struct net *net, struct tc_action *a, u32 portid, u32 seq, int event, u16 flags) { struct tcamsg *t; struct nlmsghdr *nlh; struct sk_buff *skb; struct nlattr *nest; unsigned char *b; int err = 0; skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); if (!skb) return -ENOBUFS; b = skb_tail_pointer(skb); nlh = nlmsg_put(skb, portid, seq, event, sizeof(*t), flags); if (!nlh) goto out_kfree_skb; t = nlmsg_data(nlh); t->tca_family = AF_UNSPEC; t->tca__pad1 = 0; t->tca__pad2 = 0; nest = nla_nest_start(skb, TCA_ACT_TAB); if (nest == NULL) goto out_kfree_skb; if (tcf_action_dump(skb, a, 0, 0) < 0) goto out_kfree_skb; nla_nest_end(skb, nest); nlh->nlmsg_len = skb_tail_pointer(skb) - b; NETLINK_CB(skb).dst_group = RTNLGRP_TC; err = rtnetlink_send(skb, net, portid, RTNLGRP_TC, flags & NLM_F_ECHO); if (err > 0) err = 0; return err; out_kfree_skb: kfree_skb(skb); return -1; }
void dp_bfd_send_event(dp_bfd_session_s *session, u8 event, u8 degree) { struct sk_buff *skb = NULL; struct nlmsghdr *nlh; dp_bfd_event_s data; dp_bfd_auth_head_s *auth_head = (dp_bfd_auth_head_s *)&session->auth; skb = nlmsg_new(sizeof(data), GFP_KERNEL); nlh = nlmsg_put(skb, 0, 0, 0, sizeof(data), 0); NETLINK_CB(skb).dst_group = 1; NETLINK_CB(skb).pid = 0; /*写入数据*/ memset(&data, 0, sizeof(data)); data.ifindex = session->ifindex; data.src_addr = session->local_addr; data.dst_addr = session->remote_addr; data.state = session->state; data.event = event; data.mode = session->session_mode; data.dmti = session->packet.min_tx_interval/1000; data.rmri = session->packet.min_rx_interval/1000; data.rmeri = session->packet.min_echo_rx_interval/1000; data.detect_mult = session->packet.detect_mult; /* 认证数据 */ data.auth_type = auth_head->type; data.auth_key_id = auth_head->key_id; memcpy(data.auth_key, session->auth_key, 20); /* process */ data.process = session->process; data.degree = degree; memcpy(NLMSG_DATA(nlh), &data, sizeof(data)); if(dp_bfd_debug & DEBUG_BFD_EVENT) printk("ifindex = %x , src_addr = %x , dst_addr = %x , event = %d \n",data.ifindex,data.src_addr,data.dst_addr,data.event); /*广播*/ spin_lock(&g_bfd_skfd.lock); netlink_broadcast(g_bfd_skfd.bfd_skfd, skb, 0, 1,GFP_KERNEL); spin_unlock(&g_bfd_skfd.lock); }
void toi_send_netlink_message(struct user_helper_data *uhd, int type, void *params, size_t len) { struct sk_buff *skb; struct nlmsghdr *nlh; void *dest; struct task_struct *t; if (uhd->pid == -1) return; if (uhd->debug) printk(KERN_ERR "toi_send_netlink_message: Send " "message type %d.\n", type); skb = toi_get_skb(uhd); if (!skb) { printk(KERN_INFO "toi_netlink: Can't allocate skb!\n"); return; } nlh = nlmsg_put(skb, 0, uhd->sock_seq, type, len, 0); uhd->sock_seq++; dest = NLMSG_DATA(nlh); if (params && len > 0) memcpy(dest, params, len); netlink_unicast(uhd->nl, skb, uhd->pid, 0); toi_read_lock_tasklist(); t = find_task_by_pid_ns(uhd->pid, &init_pid_ns); if (!t) { toi_read_unlock_tasklist(); if (uhd->pid > -1) printk(KERN_INFO "Hmm. Can't find the userspace task" " %d.\n", uhd->pid); return; } wake_up_process(t); toi_read_unlock_tasklist(); yield(); }
/* * Create one netlink message for one interface * Contains port and master info as well as carrier and bridge state. */ static int br_fill_ifinfo(struct sk_buff *skb, const struct net_bridge_port *port, u32 pid, u32 seq, int event, unsigned int flags) { const struct net_bridge *br = port->br; const struct net_device *dev = port->dev; struct ifinfomsg *hdr; struct nlmsghdr *nlh; u8 operstate = netif_running(dev) ? dev->operstate : IF_OPER_DOWN; pr_debug("br_fill_info event %d port %s master %s\n", event, dev->name, br->dev->name); nlh = nlmsg_put(skb, pid, seq, event, sizeof(*hdr), flags); if (nlh == NULL) return -EMSGSIZE; hdr = nlmsg_data(nlh); hdr->ifi_family = AF_BRIDGE; hdr->__ifi_pad = 0; hdr->ifi_type = dev->type; hdr->ifi_index = dev->ifindex; hdr->ifi_flags = dev_get_flags(dev); hdr->ifi_change = 0; NLA_PUT_STRING(skb, IFLA_IFNAME, dev->name); NLA_PUT_U32(skb, IFLA_MASTER, br->dev->ifindex); NLA_PUT_U32(skb, IFLA_MTU, dev->mtu); NLA_PUT_U8(skb, IFLA_OPERSTATE, operstate); if (dev->addr_len) NLA_PUT(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr); if (dev->ifindex != dev->iflink) NLA_PUT_U32(skb, IFLA_LINK, dev->iflink); if (event == RTM_NEWLINK) NLA_PUT_U8(skb, IFLA_PROTINFO, port->state); return nlmsg_end(skb, nlh); nla_put_failure: nlmsg_cancel(skb, nlh); return -EMSGSIZE; }
/** * Add Generic Netlink headers to Netlink message * @arg msg Netlink message object * @arg port Netlink port or NL_AUTO_PORT * @arg seq Sequence number of message or NL_AUTO_SEQ * @arg family Numeric family identifier * @arg hdrlen Length of user header * @arg flags Additional Netlink message flags (optional) * @arg cmd Numeric command identifier * @arg version Interface version * * Calls nlmsg_put() on the specified message object to reserve space for * the Netlink header, the Generic Netlink header, and a user header of * specified length. Fills out the header fields with the specified * parameters. * * @par Example: * @code * struct nl_msg *msg; * struct my_hdr *user_hdr; * * if (!(msg = nlmsg_alloc())) * // ERROR * * user_hdr = genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, family_id, * sizeof(struct my_hdr), 0, MY_CMD_FOO, 0); * if (!user_hdr) * // ERROR * @endcode * * @see nlmsg_put() * * Returns Pointer to user header or NULL if an error occurred. */ void *genlmsg_put(struct nl_msg *msg, uint32_t port, uint32_t seq, int family, int hdrlen, int flags, uint8_t cmd, uint8_t version) { struct nlmsghdr *nlh; struct genlmsghdr hdr = { .cmd = cmd, .version = version, }; nlh = nlmsg_put(msg, port, seq, family, GENL_HDRLEN + hdrlen, flags); if (nlh == NULL) return NULL; memcpy(nlmsg_data(nlh), &hdr, sizeof(hdr)); NL_DBG(2, "msg %p: Added generic netlink header cmd=%d version=%d\n", msg, cmd, version); return nlmsg_data(nlh) + GENL_HDRLEN; }
int netlink_send(struct sock *sock, int group, u16 type, void *msg, int len) { static u32 seq; struct sk_buff *skb = NULL; struct nlmsghdr *nlh; int ret = 0; if (group > ND_MAX_GROUP) { printk(KERN_ERR "Group %d is invalied.\n", group); printk(KERN_ERR "Valid group is 0 ~ %d.\n", ND_MAX_GROUP); return -EINVAL; } skb = alloc_skb(NLMSG_SPACE(len), GFP_ATOMIC); if (!skb) { printk(KERN_ERR "netlink_broadcast ret=%d\n", ret); return -ENOMEM; } seq++; nlh = nlmsg_put(skb, 0, seq, type, len, 0); if (!nlh) { kfree_skb(skb); return -EMSGSIZE; } memcpy(nlmsg_data(nlh), msg, len); NETLINK_CB(skb).pid = 0; NETLINK_CB(skb).dst_group = 0; ret = netlink_broadcast(sock, skb, 0, group+1, GFP_ATOMIC); if (!ret) return len; else { if (ret != -ESRCH) { printk(KERN_ERR "netlink_broadcast g=%d, t=%d, l=%d, r=%d\n", group, type, len, ret); } ret = 0; } return ret; }
void send_cfcard_message(int level) { struct sk_buff *skb = NULL; struct nlmsghdr *nlh; struct cf_netlink_msg data; s32 ret; skb = nlmsg_new(NLMSG_SPACE(sizeof(data)), GFP_KERNEL); nlh = nlmsg_put(skb, 0, 0, 0, NLMSG_SPACE(sizeof(data)), 0); nlmsg_end(skb, nlh); NETLINK_CB(skb).dst_group = 1; NETLINK_CB(skb).pid = 0; data.log_level = level; memcpy(NLMSG_DATA(nlh), &data, sizeof(data)); ret = netlink_broadcast(g_cfcard_nl_sk, skb, 0, 1,GFP_KERNEL); return ; }
void sample_input (struct sk_buff *__skb) { struct sk_buff *skb; struct nlmsghdr *nlh; unsigned int pid; int rc; int len = NLMSG_SPACE(1200); char data[100]; int dlen=0; skb = skb_get(__skb); if (skb->len >= NLMSG_SPACE(0)) { nlh = nlmsg_hdr(skb); dlen= nlh->nlmsg_len; pid = nlh->nlmsg_pid;/*发送进程ID */ if(dlen>100)dlen=100; memset(data,0,100); memcpy(data,NLMSG_DATA(nlh),dlen); printk("net_link: recv '%s' from process %d.\n",data,pid); kfree_skb(skb); skb = alloc_skb(len, GFP_ATOMIC); if (!skb) { printk("net_link: alloc_skb failed.\n"); return; } nlh = nlmsg_put(skb,0,0,0,1200,0); nlh ->nlmsg_len=dlen; NETLINK_CB(skb).pid = 0;/* 发自内核*/ memcpy(NLMSG_DATA(nlh), data, strlen(data)); rc = netlink_unicast(nl_sk, skb, pid, MSG_DONTWAIT); if (rc < 0) { printk("net_link: unicast skb error\n"); } printk("net_link: send '%s' to process %d ok.\n",data,pid); } return; }
static void __nfulnl_send(struct nfulnl_instance *inst) { if (inst->qlen > 1) { struct nlmsghdr *nlh = nlmsg_put(inst->skb, 0, 0, NLMSG_DONE, sizeof(struct nfgenmsg), 0); if (WARN_ONCE(!nlh, "bad nlskb size: %u, tailroom %d\n", inst->skb->len, skb_tailroom(inst->skb))) { kfree_skb(inst->skb); goto out; } } nfnetlink_unicast(inst->skb, inst->net, inst->peer_portid, MSG_DONTWAIT); out: inst->qlen = 0; inst->skb = NULL; }
void sendMSG(__be32 src) { struct sk_buff *skb; struct nlmsghdr *nlh; int len = NLMSG_SPACE(sizeof(src)); skb = alloc_skb(len, GFP_ATOMIC); if (!skb) { printk(KERN_ERR "net_link: allocate failed.\n"); return; } nlh = nlmsg_put(skb,0,0,0,sizeof(src),0); NETLINK_CB(skb).pid = 0; /* from kernel */ memcpy(NLMSG_DATA(nlh), &src, sizeof(src)); netlink_unicast(nl_sk, skb, pid, MSG_DONTWAIT); return; }
static int deth_netlink_do_broadcast_packet(struct sock* nl_sk, const char* pkt, int size, u32 index) { int totsize = size + sizeof(u32); struct sk_buff* skb = nlmsg_new(totsize, 0); struct nlmsghdr* nlh; char* ptr; if (!skb) { printk(KERN_ERR "Failed to allocate new skb\n"); return -ENOBUFS; } nlh = nlmsg_put(skb, 0, 0, PACKET, totsize, 0); if (nlh == NULL) { nlmsg_free(skb); return -EMSGSIZE; } ptr = nlmsg_data(nlh); memcpy(ptr, &index, sizeof(u32)); ptr += sizeof(u32); memcpy(ptr, pkt, size); #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0) NETLINK_CB(skb).portid = 0; #else NETLINK_CB(skb).pid = 0; #endif NETLINK_CB(skb).dst_group = NETLINK_DETH_GROUP; return netlink_broadcast(nl_sk, skb, 0, NETLINK_DETH_GROUP, GFP_KERNEL); }
/* Caller must hold RTNL lock. */ static int dp_fill_ifinfo(struct sk_buff *skb, const struct vport *port, int event, unsigned int flags) { struct datapath *dp = port->dp; struct ifinfomsg *hdr; struct nlmsghdr *nlh; if (!port->ops->get_ifindex) return -ENODEV; nlh = nlmsg_put(skb, 0, 0, event, sizeof(*hdr), flags); if (nlh == NULL) return -EMSGSIZE; hdr = nlmsg_data(nlh); hdr->ifi_family = AF_BRIDGE; hdr->__ifi_pad = 0; hdr->ifi_type = ARPHRD_ETHER; hdr->ifi_index = port->ops->get_ifindex(port); hdr->ifi_flags = port->ops->get_dev_flags(port); hdr->ifi_change = 0; NLA_PUT_STRING(skb, IFLA_IFNAME, port->ops->get_name(port)); NLA_PUT_U32(skb, IFLA_MASTER, get_dpifindex(dp)); NLA_PUT_U32(skb, IFLA_MTU, port->ops->get_mtu(port)); #ifdef IFLA_OPERSTATE NLA_PUT_U8(skb, IFLA_OPERSTATE, port->ops->is_running(port) ? port->ops->get_operstate(port) : IF_OPER_DOWN); #endif NLA_PUT(skb, IFLA_ADDRESS, ETH_ALEN, port->ops->get_addr(port)); return nlmsg_end(skb, nlh); nla_put_failure: nlmsg_cancel(skb, nlh); return -EMSGSIZE; }
/* Function used to send message to the user space */ int adsp_unicast(struct msg_data param, int message, int flags, u32 pid) { struct sk_buff *skb; struct nlmsghdr *nlh; struct msg_data *msg; int ret = -1; skb = nlmsg_new(sizeof(struct msg_data), GFP_KERNEL); nlh = nlmsg_put(skb, pid, 0, message, sizeof(struct msg_data), flags); if (nlh == NULL){ nlmsg_free(skb); return -EMSGSIZE; } msg = nlmsg_data(nlh); msg->sensor_type = param.sensor_type; msg->param1 = param.param1; msg->param2 = param.param2; msg->param3 = param.param3; NETLINK_CB(skb).dst_group = 0; ret = nlmsg_unicast(data->adsp_skt, skb, PID); return ret; }
static int __nfulnl_send(struct nfulnl_instance *inst) { int status = -1; if (inst->qlen > 1) { struct nlmsghdr *nlh = nlmsg_put(inst->skb, 0, 0, NLMSG_DONE, sizeof(struct nfgenmsg), 0); if (!nlh) goto out; } status = nfnetlink_unicast(inst->skb, &init_net, inst->peer_portid, MSG_DONTWAIT); inst->qlen = 0; inst->skb = NULL; out: return status; }
static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct netlink_diag_req *req, u32 portid, u32 seq, u32 flags, int sk_ino) { struct nlmsghdr *nlh; struct netlink_diag_msg *rep; struct netlink_sock *nlk = nlk_sk(sk); nlh = nlmsg_put(skb, portid, seq, SOCK_DIAG_BY_FAMILY, sizeof(*rep), flags); if (!nlh) return -EMSGSIZE; rep = nlmsg_data(nlh); rep->ndiag_family = AF_NETLINK; rep->ndiag_type = sk->sk_type; rep->ndiag_protocol = sk->sk_protocol; rep->ndiag_state = sk->sk_state; rep->ndiag_ino = sk_ino; rep->ndiag_portid = nlk->portid; rep->ndiag_dst_portid = nlk->dst_portid; rep->ndiag_dst_group = nlk->dst_group; sock_diag_save_cookie(sk, rep->ndiag_cookie); if ((req->ndiag_show & NDIAG_SHOW_GROUPS) && sk_diag_dump_groups(sk, skb)) goto out_nlmsg_trim; if ((req->ndiag_show & NDIAG_SHOW_MEMINFO) && sock_diag_put_meminfo(sk, skb, NETLINK_DIAG_MEMINFO)) goto out_nlmsg_trim; nlmsg_end(skb, nlh); return 0; out_nlmsg_trim: nlmsg_cancel(skb, nlh); return -EMSGSIZE; }