Exemple #1
0
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;
}
Exemple #2
0
/**
 * 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);
}
Exemple #3
0
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;
}
Exemple #5
0
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;
}
Exemple #7
0
//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;
}
Exemple #9
0
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);
                }
        }
}
Exemple #11
0
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;
	}
}
Exemple #14
0
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;
}
Exemple #15
0
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);
}
Exemple #16
0
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;
}
Exemple #18
0
/**
 * 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;
}
Exemple #20
0
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;
}
Exemple #23
0
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;
}
Exemple #24
0
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);
}
Exemple #25
0
/* 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;
}
Exemple #28
0
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;
}