static int ethertap_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; #ifdef CONFIG_ETHERTAP_MC struct ethhdr *eth = (struct ethhdr*)skb->data; #endif if (skb_headroom(skb) < 2) { static int once; struct sk_buff *skb2; if (!once) { once = 1; printk(KERN_DEBUG "%s: not aligned xmit by protocol %04x\n", dev->name, skb->protocol); } skb2 = skb_realloc_headroom(skb, 2); dev_kfree_skb(skb); if (skb2 == NULL) return 0; skb = skb2; } __skb_push(skb, 2); /* Make the same thing, which loopback does. */ if (skb_shared(skb)) { struct sk_buff *skb2 = skb; skb = skb_clone(skb, GFP_ATOMIC); /* Clone the buffer */ if (skb==NULL) { dev_kfree_skb(skb2); return 0; } dev_kfree_skb(skb2); } /* ... but do not orphan it here, netlink does it in any case. */ lp->stats.tx_bytes+=skb->len; lp->stats.tx_packets++; #ifndef CONFIG_ETHERTAP_MC netlink_broadcast(lp->nl, skb, 0, ~0, GFP_ATOMIC); #else if (dev->flags&IFF_NOARP) { netlink_broadcast(lp->nl, skb, 0, ~0, GFP_ATOMIC); return 0; } if (!(eth->h_dest[0]&1)) { /* Unicast packet */ __u32 pid; memcpy(&pid, eth->h_dest+2, 4); netlink_unicast(lp->nl, skb, ntohl(pid), MSG_DONTWAIT); } else netlink_broadcast(lp->nl, skb, 0, ethertap_mc_hash(eth->h_dest), GFP_ATOMIC); #endif return 0; }
int netlink_alloc(void) { struct sk_buff *skb = NULL; struct nlmsghdr *nlh = NULL; int err; u32 pid; nl_sk = netlink_kernel_create(28, 0, nl_data_ready, THIS_MODULE); if (!nl_sk) { printk("netlink_kernel_create failed\n"); return -1; } skb = skb_recv_datagram(nl_sk, 0, 0, &err); nlh = (struct nlmsghdr *)skb->data; printk("%s: received netlink message payload: %s", __FUNCTION__, NLMSG_DATA(nlh)); pid = nlh->nlmsg_pid; nlh->nlmsg_len = skb->len; NETLINK_CB(skb).pid = 0; NETLINK_CB(skb).dst_pid = pid; NETLINK_CB(skb).dst_group = 1; netlink_broadcast(nl_sk, skb, 0, 1, GFP_KERNEL); return 0; }
static void udp_broadcast(int gid,void *payload) { struct sk_buff *skb; struct nlmsghdr *nlh; int size=strlen(payload)+1; int len = NLMSG_SPACE(size); void *data; int ret; skb = alloc_skb(len, GFP_KERNEL); if (!skb) return; nlh= NLMSG_PUT(skb, 0, 0, 0, size); nlh->nlmsg_flags = 0; data=NLMSG_DATA(nlh); memcpy(data, payload, size); NETLINK_CB(skb).pid = 0; /* from kernel */ NETLINK_CB(skb).dst_group = gid; /* unicast */ //ret=netlink_unicast(netlink_sock, skb, pid, MSG_DONTWAIT); ret=netlink_broadcast(netlink_sock, skb, 0, gid, GFP_KERNEL); if (ret <0) { printk("send failed\n"); return; } return; nlmsg_failure: /* Used by NLMSG_PUT */ if (skb) kfree_skb(skb); }
int nl_send_multicast_message(int msg, gfp_t gfp_mask) { struct sk_buff *skb = NULL; struct nlmsghdr *nlh = NULL; int err; /* prepare netlink message */ skb = alloc_skb(NLMSG_SPACE(MAX_PAYLOAD), gfp_mask); if (!skb) { dev_err(shm_dev->dev, "%s:alloc_skb failed\n", __func__); err = -ENOMEM; goto out; } nlh = (struct nlmsghdr *)skb->data; nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD); dev_dbg(shm_dev->dev, "nlh->nlmsg_len = %d\n", nlh->nlmsg_len); nlh->nlmsg_pid = 0; /* from kernel */ nlh->nlmsg_flags = 0; *(int *)NLMSG_DATA(nlh) = msg; skb_put(skb, MAX_PAYLOAD); /* sender is in group 1<<0 */ NETLINK_CB(skb).pid = 0; /* from kernel */ /* to mcast group 1<<0 */ NETLINK_CB(skb).dst_group = 1; /*multicast the message to all listening processes*/ err = netlink_broadcast(shrm_nl_sk, skb, 0, 1, gfp_mask); dev_dbg(shm_dev->dev, "ret val from nl-multicast = %d\n", err); out: return err; }
static int deth_netlink_do_broadcast_addresses(struct sock* nl_sk, u32 index) { struct sk_buff* skb = nlmsg_new(sizeof(u32), 0); struct nlmsghdr* nlh; if (!skb) { printk(KERN_ERR "Failed to allocate new skb\n"); return -ENOBUFS; } nlh = nlmsg_put(skb, 0, 0, MULTICAST_ADDRESS_CHANGE, sizeof(u32), 0); if (nlh == NULL) { nlmsg_free(skb); return -EMSGSIZE; } memcpy(nlmsg_data(nlh), &index, sizeof(u32)); #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); }
static int __init init_mod(void) { struct sk_buff *skb = NULL; struct nlmsghdr *nlh; nl_sk = netlink_kernel_create(NL_EXAMPLE, NULL); if (nl_sk == 0) return -1; skb = alloc_skb(NLMSG_SPACE(MAX_PAYLOAD), GFP_KERNEL); nlh = (struct nlmsghdr *) skb_put(skb, NLMSG_SPACE(MAX_PAYLOAD)); nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD); nlh->nlmsg_pid = 0; nlh->nlmsg_flags = 0; strcpy(NLMSG_DATA(nlh), NETLINK_MESSAGE); NETLINK_CB(skb).pid = 0; NETLINK_CB(skb).dst_pid = 0; NETLINK_CB(skb).dst_groups = NL_GROUP; netlink_broadcast(nl_sk, skb, 0, NL_GROUP, GFP_KERNEL); sock_release(nl_sk->sk_socket); return -1; // Always remove module immediately after loading }
/* * Broadcast the message. Broadcast will return an error if * there are no listeners */ int nl_srv_bcast(struct sk_buff *skb) { int err = 0; int flags = GFP_KERNEL; if (in_interrupt() || irqs_disabled() || in_atomic()) flags = GFP_ATOMIC; #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0)) NETLINK_CB(skb).pid = 0; //sender's pid #else NETLINK_CB(skb).portid = 0; //sender's pid #endif NETLINK_CB(skb).dst_group = WLAN_NLINK_MCAST_GRP_ID; //destination group if (nl_srv_sock != NULL) { err = netlink_broadcast(nl_srv_sock, skb, 0, WLAN_NLINK_MCAST_GRP_ID, flags); } else { dev_kfree_skb(skb); } if ((err < 0) && (err != -ESRCH)) { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "NLINK: netlink_broadcast failed err = %d", err); } return err; }
/** * send_uevent - notify userspace by sending event trough netlink socket * * @signal: signal name * @obj: object path (kobject) * @buf: buffer used to pass auxiliary data like the hotplug environment * @buflen: * gfp_mask: */ static int send_uevent(const char *signal, const char *obj, const void *buf, int buflen, int gfp_mask) { struct sk_buff *skb; char *pos; int len; if (!uevent_sock) return -EIO; len = strlen(signal) + 1; len += strlen(obj) + 1; len += buflen; skb = alloc_skb(len, gfp_mask); if (!skb) return -ENOMEM; pos = skb_put(skb, len); pos += sprintf(pos, "%s@%s", signal, obj) + 1; memcpy(pos, buf, buflen); return netlink_broadcast(uevent_sock, skb, 0, 1, gfp_mask); }
/* send one ulog_buff_t to userspace */ static void ulog_send(struct ulog_net *ulog, unsigned int nlgroupnum) { ulog_buff_t *ub = &ulog->ulog_buffers[nlgroupnum]; pr_debug("ulog_send: timer is deleting\n"); del_timer(&ub->timer); if (!ub->skb) { pr_debug("ulog_send: nothing to send\n"); return; } /* last nlmsg needs NLMSG_DONE */ if (ub->qlen > 1) ub->lastnlh->nlmsg_type = NLMSG_DONE; NETLINK_CB(ub->skb).dst_group = nlgroupnum + 1; pr_debug("throwing %d packets to netlink group %u\n", ub->qlen, nlgroupnum + 1); netlink_broadcast(ulog->nflognl, ub->skb, 0, nlgroupnum + 1, GFP_ATOMIC); ub->qlen = 0; ub->skb = NULL; ub->lastnlh = NULL; }
static int my_sender_thread (void *data) { struct sk_buff *skb = NULL; struct nlmsghdr *nlh; do { skb = alloc_skb (NLMSG_SPACE (MAX_PAYLOAD), GFP_KERNEL); nlh = (struct nlmsghdr *)skb_put (skb, NLMSG_SPACE (MAX_PAYLOAD)); nlh->nlmsg_len = NLMSG_SPACE (MAX_PAYLOAD); nlh->nlmsg_pid = 0; nlh->nlmsg_flags = 0; strcpy (NLMSG_DATA (nlh), NETLINK_MESSAGE); NETLINK_CB (skb).pid = 0; /* NETLINK_CB (skb).dst_pid = 0; removed in 2.6.20 */ NETLINK_CB (skb).dst_group = NL_GROUP; netlink_broadcast (nl_sk, skb, 0, NL_GROUP, GFP_KERNEL); printk (KERN_INFO "my_sender_thread sent a message at jiffies=%ld\n", jiffies); set_current_state (TASK_INTERRUPTIBLE); schedule_timeout (seconds_to_jiffies (MSG_INTERVAL_SEC)); } while (!kthread_should_stop ()); return 0; } /* my_sender_thread */
void spectral_bcast_msg(struct ath_softc *sc) { struct ath_spectral *spectral=sc->sc_spectral; SPECTRAL_SAMP_MSG *msg=NULL; fd_set write_set; struct nlmsghdr *nlh=NULL; int status; FD_ZERO(&write_set); if ((spectral==NULL) || (spectral->spectral_sock==NULL)) { SPECTRAL_DPRINTK(sc, ATH_DEBUG_SPECTRAL2,"%s NULL pointers (spectral=%d) (sock=%d) (skb=%d)\n", __func__, (spectral==NULL),(spectral->spectral_sock==NULL),(spectral->spectral_skb==NULL)); dev_kfree_skb(spectral->spectral_skb); spectral->spectral_skb = NULL; return; } nlh = (struct nlmsghdr*)spectral->spectral_skb->data; msg = (SPECTRAL_SAMP_MSG*) NLMSG_DATA(spectral->spectral_nlh); print_samp_msg (msg, sc); status = netlink_broadcast(spectral->spectral_sock, spectral->spectral_skb, 0,1, GFP_ATOMIC); if (status == 0) { spectral->spectral_sent_msg++; //if (spectral->spectral_sent_msg % 10000 == 0) printk("sent 10000 netlink msgs\n"); } /* netlink will have freed the skb */ if (spectral->spectral_skb) { spectral->spectral_skb=NULL; } }
/* send one ulog_buff_t to userspace */ static void ulog_send(unsigned int nlgroupnum) { ulog_buff_t *ub = &ulog_buffers[nlgroupnum]; if (timer_pending(&ub->timer)) { DEBUGP("ipt_ULOG: ulog_send: timer was pending, deleting\n"); del_timer(&ub->timer); } if (!ub->skb) { DEBUGP("ipt_ULOG: ulog_send: nothing to send\n"); return; } /* last nlmsg needs NLMSG_DONE */ if (ub->qlen > 1) ub->lastnlh->nlmsg_type = NLMSG_DONE; NETLINK_CB(ub->skb).dst_group = nlgroupnum + 1; DEBUGP("ipt_ULOG: throwing %d packets to netlink group %u\n", ub->qlen, nlgroupnum + 1); netlink_broadcast(nflognl, ub->skb, 0, nlgroupnum + 1, GFP_ATOMIC); ub->qlen = 0; ub->skb = NULL; ub->lastnlh = NULL; }
void broadcast(struct sk_buff *netfilter_socket_buffer){ int res; struct sk_buff *broadcastSocketBuffer; struct nlmsghdr *netlink_header; broadcastSocketBuffer = nlmsg_new(netfilter_socket_buffer->len,0); if(!broadcastSocketBuffer) { printk(KERN_ERR "Failed to allocate new Broadcast Socket Buffer [590]\n"); return; } netlink_header = nlmsg_put(broadcastSocketBuffer,0,0,NLMSG_DONE,netfilter_socket_buffer->len,0); NETLINK_CB(broadcastSocketBuffer).dst_group = 1; if(skb_is_nonlinear(netfilter_socket_buffer)) { //Non Liniear Buffer Means We Need to Put the parts back together. skb_linearize(netfilter_socket_buffer); } memcpy(nlmsg_data(netlink_header), netfilter_socket_buffer->data, netfilter_socket_buffer->len); res = netlink_broadcast(netlink_broadcast_socket, broadcastSocketBuffer, 0, 1, GFP_ATOMIC); if(res < 0) { printk(KERN_ERR "Error (%d) while sending broadcast message. [590]\n",res); } }
/** * send_uevent - notify userspace by sending event trough netlink socket * * @signal: signal name * @obj: object path (kobject) * @envp: possible hotplug environment to pass with the message * @gfp_mask: */ static int send_uevent(const char *signal, const char *obj, char **envp, int gfp_mask) { struct sk_buff *skb; char *pos; int len; if (!uevent_sock) return -EIO; len = strlen(signal) + 1; len += strlen(obj) + 1; /* allocate buffer with the maximum possible message size */ skb = alloc_skb(len + BUFFER_SIZE, gfp_mask); if (!skb) return -ENOMEM; pos = skb_put(skb, len); sprintf(pos, "%s@%s", signal, obj); /* copy the environment key by key to our continuous buffer */ if (envp) { int i; for (i = 2; envp[i]; i++) { len = strlen(envp[i]) + 1; pos = skb_put(skb, len); strcpy(pos, envp[i]); } } return netlink_broadcast(uevent_sock, skb, 0, 1, gfp_mask); }
static void selnl_notify(int msgtype, void *data) { int len; sk_buff_data_t tmp; struct sk_buff *skb; struct nlmsghdr *nlh; len = selnl_msglen(msgtype); skb = alloc_skb(NLMSG_SPACE(len), GFP_USER); if (!skb) goto oom; tmp = skb->tail; nlh = NLMSG_PUT(skb, 0, 0, msgtype, len); selnl_add_payload(nlh, len, msgtype, data); nlh->nlmsg_len = skb->tail - tmp; NETLINK_CB(skb).dst_group = SELNLGRP_AVC; netlink_broadcast(selnl, skb, 0, SELNLGRP_AVC, GFP_USER); out: return; nlmsg_failure: kfree_skb(skb); oom: printk(KERN_ERR "SELinux: OOM in %s\n", __func__); goto out; }
static inline int ip_fw_domatch(struct ip_fwkernel *f, struct iphdr *ip, const char *rif, const ip_chainlabel label, struct sk_buff *skb, unsigned int slot, __u16 src_port, __u16 dst_port, unsigned int count, int tcpsyn) { f->counters[slot].bcnt+=ntohs(ip->tot_len); f->counters[slot].pcnt++; if (f->ipfw.fw_flg & IP_FW_F_PRN) { dump_packet(ip,rif,f,label,src_port,dst_port,count,tcpsyn); } ip->tos = (ip->tos & f->ipfw.fw_tosand) ^ f->ipfw.fw_tosxor; /* This functionality is useless in stock 2.0.x series, but we don't * discard the mark thing altogether, to avoid breaking ipchains (and, * more importantly, the ipfwadm wrapper) --PR */ if (f->ipfw.fw_flg & IP_FW_F_MARKABS) { skb->nfmark = f->ipfw.fw_mark; } else { skb->nfmark += f->ipfw.fw_mark; } if (f->ipfw.fw_flg & IP_FW_F_NETLINK) { #if defined(CONFIG_NETLINK_DEV) || defined(CONFIG_NETLINK_DEV_MODULE) size_t len = min_t(unsigned int, f->ipfw.fw_outputsize, ntohs(ip->tot_len)) + sizeof(__u32) + sizeof(skb->nfmark) + IFNAMSIZ; struct sk_buff *outskb=alloc_skb(len, GFP_ATOMIC); duprintf("Sending packet out NETLINK (length = %u).\n", (unsigned int)len); if (outskb) { /* Prepend length, mark & interface */ skb_put(outskb, len); *((__u32 *)outskb->data) = (__u32)len; *((__u32 *)(outskb->data+sizeof(__u32))) = skb->nfmark; strcpy(outskb->data+sizeof(__u32)*2, rif); memcpy(outskb->data+sizeof(__u32)*2+IFNAMSIZ, ip, len-(sizeof(__u32)*2+IFNAMSIZ)); netlink_broadcast(ipfwsk, outskb, 0, ~0, GFP_ATOMIC); } else { #endif if (net_ratelimit()) printk(KERN_WARNING "ip_fw: packet drop due to " "netlink failure\n"); return 0; #if defined(CONFIG_NETLINK_DEV) || defined(CONFIG_NETLINK_DEV_MODULE) } #endif }
int rtnetlink_send(struct sk_buff *skb, u32 pid, unsigned group, int echo) { int err = 0; NETLINK_CB(skb).dst_group = group; if (echo) atomic_inc(&skb->users); netlink_broadcast(rtnl, skb, pid, group, GFP_KERNEL); if (echo) err = netlink_unicast(rtnl, skb, pid, MSG_DONTWAIT); return err; }
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); }
void kaodv_netlink_send_debug_msg(char *buf, int len) { struct sk_buff *skb = NULL; skb = kaodv_netlink_build_msg(KAODVM_DEBUG, buf, len); if (skb == NULL) { printk("kaodv_netlink: skb=NULL\n"); return; } netlink_broadcast(kaodvnl, skb, peer_pid, AODVGRP_NOTIFY, GFP_USER); }
int nfnetlink_send(struct sk_buff *skb, u32 pid, unsigned group, int echo) { gfp_t allocation = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL; int err = 0; NETLINK_CB(skb).dst_group = group; if (echo) atomic_inc(&skb->users); netlink_broadcast(nfnl, skb, pid, group, allocation); if (echo) err = netlink_unicast(nfnl, skb, pid, MSG_DONTWAIT); return err; }
int user_comm_broadcast(void *data, int size) { struct nlmsghdr *nlh; struct sk_buff *skb; skb = alloc_skb(NLMSG_SPACE(size), GFP_ATOMIC); if (skb == NULL) return -1; nlh = NLMSG_PUT(skb, 0, 0, 0, size); memcpy(NLMSG_DATA(nlh), data, size); return netlink_broadcast(_sock, skb, 0, 1, GFP_ATOMIC); nlmsg_failure: kfree_skb(skb); printk(KERN_ERR "l2filter: error broadcast NLMSG_PUT fail\n"); return -1; }
/*---------------------------------------------------------------- * p80211ind_mlme * * Called by the MSD to deliver an mlme type indication message. * * Arguments: * wlandev WLAN device struct * skb skb containing message to deliver * * Returns: * nothing * * Call context: * Any ----------------------------------------------------------------*/ void p80211ind_mlme( wlandevice_t *wlandev, struct sk_buff *skb) { DBFENTER; if ( nl_indicate != NULL ) { /* TODO: Look at queuing mlme indications when requests are pending. */ netlink_broadcast(nl_indicate, skb, 0, P80211_NL_MCAST_GRP_MLME, GFP_ATOMIC); } else { WLAN_LOG_DEBUG(2,"Can't send indicate msg, no netlink i/f\n"); } DBFEXIT; return; }
static void ks_netlink_mcast_flush(struct ks_netlink_state *state) { struct sk_buff *skb; int err; if (state->lock_owner) return; while ((skb = skb_dequeue(&state->mcast_queue))) { err = netlink_broadcast(ksnl, skb, 0, KS_NETLINK_GROUP_TOPOLOGY, GFP_KERNEL | __GFP_WAIT); if (err < 0) { ks_msg(KERN_WARNING, "Netlink overflow detected at mcast_flush\n"); } } if (state->mcast_skb) { if (state->mcast_skb->len) { err = netlink_broadcast(ksnl, state->mcast_skb, 0, KS_NETLINK_GROUP_TOPOLOGY, GFP_KERNEL | __GFP_WAIT); if (err == -ENOBUFS) { ks_msg(KERN_WARNING, "Netlink overflow detected at" " mcast_flush2: %d\n", err); } } else kfree_skb(state->mcast_skb); state->mcast_skb = NULL; } }
void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change) { struct sk_buff *skb; int size = NLMSG_GOODSIZE; skb = alloc_skb(size, GFP_KERNEL); if (!skb) return; if (rtnetlink_fill_ifinfo(skb, dev, type, 0, 0, change) < 0) { kfree_skb(skb); return; } NETLINK_CB(skb).dst_groups = RTMGRP_LINK; netlink_broadcast(rtnl, skb, 0, RTMGRP_LINK, GFP_KERNEL); }
/*---------------------------------------------------------------- * p80211ind_distribution * * Called by the MSD to deliver a distribution system type * indication message. * * Arguments: * wlandev WLAN device struct * skb skb containing message to deliver * * Returns: * nothing * * Call context: * Any ----------------------------------------------------------------*/ void p80211ind_distribution( wlandevice_t *wlandev, struct sk_buff *skb) { DBFENTER; if ( nl_indicate != NULL ) { /* skb = alloc_skb(len, GFP_ATOMIC); skb_put(skb, len); memcpy(skb->data, msg, len); */ netlink_broadcast(nl_indicate, skb, 0, P80211_NL_MCAST_GRP_DIST, GFP_ATOMIC); } else { WLAN_LOG_DEBUG(2,"Can't send indicate msg, no netlink i/f\n"); } DBFEXIT; return; }
void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change) { struct sk_buff *skb; int size = NLMSG_SPACE(sizeof(struct ifinfomsg) + sizeof(struct rtnl_link_ifmap) + sizeof(struct rtnl_link_stats) + 128); skb = alloc_skb(size, GFP_KERNEL); if (!skb) return; if (rtnetlink_fill_ifinfo(skb, dev, type, 0, 0, change, 0) < 0) { kfree_skb(skb); return; } NETLINK_CB(skb).dst_group = RTNLGRP_LINK; netlink_broadcast(rtnl, skb, 0, RTNLGRP_LINK, GFP_KERNEL); }
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 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 ; }
/* * Create and broadcast and send it on the standard rtnetlink socket * This is a pure clone rtmsg_ifinfo() in net/core/rtnetlink.c * Andrzej Krzysztofowicz mandated that I used a IFLA_XXX field * within a RTM_NEWLINK event. */ static inline void rtmsg_iwinfo(struct net_device * dev, char * event, int event_len) { struct sk_buff *skb; int size = NLMSG_GOODSIZE; skb = alloc_skb(size, GFP_ATOMIC); if (!skb) return; if (rtnetlink_fill_iwinfo(skb, dev, RTM_NEWLINK, event, event_len) < 0) { kfree_skb(skb); return; } NETLINK_CB(skb).dst_groups = RTMGRP_LINK; netlink_broadcast(rtnl, skb, 0, RTMGRP_LINK, GFP_ATOMIC); }
/* send one ulog_buff_t to userspace */ static void ulog_send(struct ebt_ulog_net *ebt, unsigned int nlgroup) { ebt_ulog_buff_t *ub = &ebt->ulog_buffers[nlgroup]; del_timer(&ub->timer); if (!ub->skb) return; /* last nlmsg needs NLMSG_DONE */ if (ub->qlen > 1) ub->lastnlh->nlmsg_type = NLMSG_DONE; NETLINK_CB(ub->skb).dst_group = nlgroup + 1; netlink_broadcast(ebt->ebtulognl, ub->skb, 0, nlgroup + 1, GFP_ATOMIC); ub->qlen = 0; ub->skb = NULL; }