static void rtnetlink_rcv(struct sock *sk, int len) { do { struct sk_buff *skb; if (rtnl_shlock_nowait()) return; while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { if (rtnetlink_rcv_skb(skb)) { if (skb->len) skb_queue_head(&sk->sk_receive_queue, skb); else kfree_skb(skb); break; } kfree_skb(skb); } up(&rtnl_sem); netdev_run_todo(); } while (rtnl && rtnl->sk_receive_queue.qlen); }
/* Note: we are only dealing with single part messages at the moment. */ static void netlink_receive_user_sk(struct sock *sk, int len) { do { struct sk_buff *skb; if (rtnl_shlock_nowait()) return; while ((skb = skb_dequeue(&sk->receive_queue)) != NULL) { netlink_receive_user_skb(skb); kfree_skb(skb); } up(&rtnl_sem); } while (nfnl && nfnl->receive_queue.qlen); }
static void ntl_receive(struct sock *sk, int len) { int err; struct sk_buff *skb; pid_t pid; struct nlmsghdr *nl_header; __u32 seq; struct pimfor_hdr *header; char *data; int version; int operation; unsigned long oid; int dev_id; int flags; unsigned long length; struct net_device *dev; #ifdef DRIVER_DEBUG printk(KERN_INFO "ntl_receive: sock %p, len %d \n", sk, len); #endif do { if (rtnl_shlock_nowait()) return; while ( (skb = skb_dequeue(&sk->receive_queue)) != NULL ) { pid = NETLINK_CB(skb).pid; nl_header = (struct nlmsghdr*) skb->data; seq = nl_header->nlmsg_seq; header = (struct pimfor_hdr*)(skb->data+(sizeof(struct nlmsghdr))); data = PIMFOR_DATA(header); if ( nl_header->nlmsg_type == NETLINK_TYPE_PIMFOR ) { pimfor_decode_header(header, &version, &operation, &oid, &dev_id, &flags, &length); if (version == PIMFOR_VERSION_1) { err = mgt_request( DEV_NETWORK, dev_id, pid, seq, operation, oid, data, length ); if ( err < 0 ) { printk(KERN_INFO "ntl_receive: mgt_request(%d, %d, %d, %x, %d, %x, %d) returned %d\n", DEV_NETWORK, dev_id, pid, seq, operation, oid, length, err ); netlink_ack(skb, nl_header, -EOPNOTSUPP ); } } else { printk(KERN_ERR "ntl_receive: version (%d) != PIMFOR_VERSION_1\n", version ); netlink_ack(skb, nl_header, -EOPNOTSUPP ); } } else { printk(KERN_ERR "nl_header->nlmsg_type (%d) != NETLINK_TYPE_PIMFOR\n", nl_header->nlmsg_type ); netlink_ack(skb, nl_header, -EOPNOTSUPP ); } kfree_skb(skb); } up(&rtnl_sem); } while (nl_sock && nl_sock->receive_queue.qlen); }