Chinaunix首页 | 论坛 | 博客
  • 博客访问: 434481
  • 博文数量: 99
  • 博客积分: 65
  • 博客等级: 民兵
  • 技术积分: 1012
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-20 16:30
个人简介

linux kernel 工程师

文章分类

全部博文(99)

文章存档

2018年(5)

2017年(12)

2016年(27)

2015年(10)

2014年(43)

2012年(2)

我的朋友

分类: LINUX

2014-02-18 11:58:18

// family, 协议族,比如AF_INET
// type, 比如SOCK_DGRAM, SOCK_DRAM
// protocol,
int __sock_create(struct net *net, int family, int type, int protocol,
    struct socket **res, int kern)
{
 int err;
 struct socket *sock; // 这个socket结构最终赋值给res
 const struct net_proto_family *pf;

 /*
  *      Check protocol is in range
  */
 if (family < 0 || family >= NPROTO)
  return -EAFNOSUPPORT;
 if (type < 0 || type >= SOCK_MAX)
  return -EINVAL;

 /* Compatibility.

    This uglymoron is moved from INET layer to here to avoid
    deadlock in module load.
  */
 if (family == PF_INET && type == SOCK_PACKET) {
  static int warned;
  if (!warned) {
   warned = 1;
   printk(KERN_INFO "%s uses obsolete (PF_INET,SOCK_PACKET)\n",
          current->comm);
  }
  family = PF_PACKET;
 }

 err = security_socket_create(family, type, protocol, kern);
 if (err)
  return err;

 /*
  * Allocate the socket and allow the family to set things up. if
  * the protocol is 0, the family is instructed to select an appropriate
  * default.
  */
 sock = sock_alloc();  //sock_alloc->new_inode_pseudo->alloc_inode->sock_alloc_inode
 if (!sock) {
  if (net_ratelimit())
   printk(KERN_WARNING "socket: no more sockets\n");
  return -ENFILE; /* Not exactly a match, but its the
       closest posix thing */
 }

 sock->type = type;  //sock具备了类型

#ifdef CONFIG_MODULES
 /* Attempt to load a protocol module if the find failed.
  *
  * 12/09/1996 Marcin: But! this makes REALLY only sense, if the user
  * requested real, full-featured networking support upon configuration.
  * Otherwise module support will break!
  */
 if (rcu_access_pointer(net_families[family]) == NULL)
  request_module("net-pf-%d", family);
#endif

 rcu_read_lock();
 pf = rcu_dereference(net_families[family]);
 err = -EAFNOSUPPORT;
 if (!pf)
  goto out_release;

 /*
  * We will call the ->create function, that possibly is in a loadable
  * module, so we have to bump that loadable module refcnt first.
  */
 if (!try_module_get(pf->owner))
  goto out_release;

 /* Now protected by module ref count */
 rcu_read_unlock();

// 调用net_families[family]->create函数
// net_families[family]的安装通过sock_register函数完成
// 比如sock_register(&netlink_family_ops,sock_register(&inet_family_ops);
 err = pf->create(net, sock, protocol, kern);
 if (err < 0)
  goto out_module_put;

 /*
  * Now to bump the refcnt of the [loadable] module that owns this
  * socket at sock_release time we decrement its refcnt.
  */
 if (!try_module_get(sock->ops->owner))
  goto out_module_busy;

 /*
  * Now that we're done with the ->create function, the [loadable]
  * module can have its refcnt decremented
  */
 module_put(pf->owner);
 err = security_socket_post_create(sock, family, type, protocol, kern);
 if (err)
  goto out_sock_release;
 *res = sock;

 return 0;

out_module_busy:
 err = -EAFNOSUPPORT;
out_module_put:
 sock->ops = NULL;
 module_put(pf->owner);
out_sock_release:
 sock_release(sock);
 return err;

out_release:
 rcu_read_unlock();
 goto out_sock_release;
}

阅读(1375) | 评论(0) | 转发(0) |
0

上一篇:e1000网卡link_state update

下一篇:i2c_dev_init

给主人留下些什么吧!~~