http://www.skyfree.org/linux/kernel_network/netlink.html
Netlink
Sockets Tour
Last
updated 2002-01-31 10:42 am
Cast a spell on the socket!
|
sock_fd = socket( AF_NETLINK,
SOCK_RAW, NETLINK_ROUTE );
|
| First
of all, open a NETLINK socket with socket(). |
| Argument |
Value |
Description |
|
1st: Address family |
AF_NETLINK |
Address
family is NETLINK |
|
2nd: Socket type |
SOCK_RAW |
Raw
network protocol access |
|
3rd: Netlink family |
NETLINK_ROUTE |
Modify most of
IPv4 control parameters
|
|
NETLINK_FIREWALL |
Receive packets
sent by IPv4 firewall
|
|
NETLINK_ARPD |
Manage ARP
table from user space
|
|
NETLINK_ROUTE6 |
IPv6 routing
table update
|
|
NETLINK_IP6_FW |
Currently not
implemented
|
|
NETLINK_TAPBASE |
Ethertap device
|
|
NETLINK_SKIP |
Reserved for
ENskip
|
Welcome to the dungeon of Linux networking code!
init/main.c/do_basic_setup()
|
Final setup functions are called from do_baseic_setup() in init/main.c. |
|
sock_init() is also called in this function. |
|
do_basic_setup() manages interesting jobs including initial RAM disk
(initrd), and so on.
|
| init/main.c |
static void __init do_basic_setup(void) {
...
/*
* Ok, at this point all CPU's should be initialized, so
* we can start looking into devices..
*/
...
/* Networking initialization needs a process context */
sock_init();
...
|
|
net/socket.c/sock_init()
|
At the beginning of function, you can see a familiar message. |
Initialize
address families. NPROTO is currently defined as 32.
include/linux/net.h:#define NPROTO 32 /* should be enough for now.. */
|
| net/socket.c |
void __init sock_init(void)
{
int i;
printk(KERN_INFO "Linux NET4.0 for Linux 2.2\n");
printk(KERN_INFO "Based upon Swansea University Computer Society NET3.039\n");
/*
* Initialize all address (protocol) families.
*/
for (i = 0; i < NPROTO; i++)
net_families[i] = NULL;
/*
* Initialize sock SLAB cache.
*/
sk_init();
/*
* Attach the firewall module if configured
*/
#ifdef CONFIG_FIREWALL
fwchain_init();
#endif
/*
* Initialize the protocols module.
*/
proto_init();
/*
* The netlink device handler may be needed early.
*/
#ifdef CONFIG_RTNETLINK
rtnetlink_init();
#endif
#ifdef CONFIG_NETLINK_DEV
init_netlink();
#endif
}
|
|
net/socket.c/proto_init()
|
Network protocol table is stored in a global array, protocols[],
which is defined in net/protocols.c. |
| All
of built in protocols will be kicked out. |
|
In short, net_families[ PF_NETLINK ] = &netlink_family_ops
will be executed. |
| net/socket.c |
void __init proto_init(void)
{
extern struct net_proto protocols[]; /* Network protocols */
struct net_proto *pro;
/* Kick all configured protocols. */
pro = protocols;
while (pro->name != NULL)
{
(*pro->init_func)(pro);
pro++;
}
/* We're all done... */
}
|
|
| net/protocols.c |
/*
* Protocol Table
*/
struct net_proto protocols[] = {
#ifdef CONFIG_NETLINK
{ "NETLINK", netlink_proto_init },
#endif
#ifdef CONFIG_PACKET
{ "PACKET", packet_proto_init },
#endif
#ifdef CONFIG_UNIX
{ "UNIX", unix_proto_init }, /* Unix domain socket family */
#endif
...
#ifdef CONFIG_INET
{ "INET", inet_proto_init }, /* TCP/IP */
#ifdef CONFIG_IPV6
{ "INET6", inet6_proto_init}, /* IPv6 */
#endif
#endif
...
{ NULL, NULL } /* End marker */
};
|
|
| net/netlink/af_netlink.c |
static int netlink_create(struct socket *sock, int protocol)
{
struct sock *sk;
sock->state = SS_UNCONNECTED;
if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM)
return -ESOCKTNOSUPPORT;
if (protocol<0 || protocol >= MAX_LINKS)
return -EPROTONOSUPPORT;
sock->ops = &netlink_ops;
sk = sk_alloc(PF_NETLINK, GFP_KERNEL, 1);
if (!sk)
return -ENOMEM;
sock_init_data(sock,sk);
sk->destruct = NULL;
sk->protocol=protocol;
return 0;
}
...
struct proto_ops netlink_ops = {
PF_NETLINK,
sock_no_dup,
netlink_release,
netlink_bind,
netlink_connect,
sock_no_socketpair,
sock_no_accept,
netlink_getname,
datagram_poll,
sock_no_ioctl,
sock_no_listen,
sock_no_shutdown,
sock_no_setsockopt,
sock_no_getsockopt,
sock_no_fcntl,
netlink_sendmsg,
netlink_recvmsg
};
struct net_proto_family netlink_family_ops = {
PF_NETLINK,
netlink_create
};
void netlink_proto_init(struct net_proto *pro)
{
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *ent;
#endif
struct sk_buff *dummy_skb;
if (sizeof(struct netlink_skb_parms) > sizeof(dummy_skb->cb)) {
printk(KERN_CRIT "netlink_proto_init: panic\n");
return;
}
sock_register(&netlink_family_ops);
#ifdef CONFIG_PROC_FS
ent = create_proc_entry("net/netlink", 0, 0);
ent->read_proc = netlink_read_proc;
#endif
}
|
|
| include/linux/net.h |
struct net_proto_family
{
int family;
int (*create)(struct socket *sock, int protocol);
/* These are counters for the number of different methods of
each we support */
short authentication;
short encryption;
short encrypt_net;
};
|
|
| net/socket.c |
/*
* The protocol list. Each protocol is registered in here.
*/
struct net_proto_family *net_families[NPROTO];
...
/*
* This function is called by a protocol handler that wants to
* advertise its address family, and have it linked into the
* SOCKET module.
*/
int sock_register(struct net_proto_family *ops)
{
if (ops->family >= NPROTO) {
printk(KERN_CRIT "protocol %d >= NPROTO(%d)\n", ops->family, NPROTO);
return -ENOBUFS;
}
net_families[ops->family]=ops;
return 0;
}
|
|
|