Zebra分析之三-详解Thread机制
(2013-01-13 10:16:17)
标签:
杂谈 |
分类: Zebra/Zebos |
一个新的thread可以通过如下三种方式被创建,主要是看你需要创建的thread的类型:
1,
2,
3,
4,
上面这三个函数的处理过程都差不多:
1,
2,
3,
2. thread的调用
1,bgp daemon不断地从event queue中取出thread并且执行它。一旦该thread被执行了,将该thread的type设置为unuse。并且将该thread添加到unuse queue中。
2,如果event queue为空时,bgp daemon 通过select函数监控读、写、异常三个描述符集。一旦有某个描述符准备就绪,则将该描述符所对应的thread加入ready queue.
而对于timer queue中的thread,只有当select函数超时后才会进入ready queue.
3.zebrad端的thread
zebrad启动后会,在read queue中会出现两个thread,一个是等待来自local client端bgpd的连接,另一个是等待来自vty client端的连接。
第1个thread
zebra_init ( )-> zebra_serv_un ( )中创建一个thread,加入read queue。该thread的处理函数为zebra_accept,监听内部client的socket。
}
vty_accept,加入read
queue。作为vty server监听internet的vty socket.。
vty_create(vty_sock, &su);
根据vty_sock和ip地址信息su,创建一个新的vty。
}
根据new client vty的vty_sock创建新的VTY_READ thread,加入read queue,该thread的处理函数为vty_read。
}
sockunion_bind(accept_sock, &su, port, NULL);
将accept_socket文件描述符与一个特定的逻辑网络连系起来。服务器端使用su->sin.sin_addr.s_addr = htonl (INADDR_ANY);表示接受任何一个主机网络接口上的连接请求。
将accept_sock套接口设置成被动监听状态,用于接受连接,只能在服务器端使用。
}
sockunion_bind操作
int sockunion_bind (int sock, union sockunion *su, unsigned short port,
{
#ifdef HAVE_SIN_LEN
#endif
服务器一般将sin_addr.s_addr 字段设置为INADDR_ANY表示套接字应接收任何一个主机网络接口上的连接请求。
客户端将sin_addr.s_addr字段设置为服务器主机的IP地址。
#ifdef HAVE_IPV6
#ifdef SIN6_LEN
#endif
#if defined(LINUX_IPV6) || defined(NRL)
#else
#endif
#endif
}
vty_event操作
static void vty_event (enum event event, int sock, struct vty *vty)
{
}
第2 个thread
bgp_serv_sock( )-> bgp_serv_sock_family( )中创建一个thread,不是通过event的方式添加的。该thread的处理函数为bgp_accept。作为bgp_server,接受来自 internet上的bgp连接。
bgp_serv_sock_family操作
port =
179
void bgp_serv_sock_family (unsigned short port, int family)
{
}
VTY server和BGP server 在使用accept操作的方法如下:
他们均是通过创建一个THREAD_READ 类型的thread,加到Master的readlist的队列后面,thread 的处理函数会执行accept操作。
VTY accept:
BGP server accept:
bgpd和zebrad间通信
bgp和zebra是通过zebra message进行通信,格式如下:
报文头3字节 (前两字节length,后1字节为command type)
报文体长度不定。
#define
ZEBRA_INTERFACE_ADD
#define
ZEBRA_INTERFACE_DELETE
#define
ZEBRA_INTERFACE_ADDRESS_ADD
#define
ZEBRA_INTERFACE_ADDRESS_DELETE
#define
ZEBRA_INTERFACE_UP
#define
ZEBRA_INTERFACE_DOWN
#define
ZEBRA_IPV4_ROUTE_ADD
#define
ZEBRA_IPV4_ROUTE_DELETE
#define
ZEBRA_IPV6_ROUTE_ADD
#define
ZEBRA_IPV6_ROUTE_DELETE
#define
ZEBRA_REDISTRIBUTE_ADD
#define
ZEBRA_REDISTRIBUTE_DELETE
#define
ZEBRA_REDISTRIBUTE_DEFAULT_ADD
#define ZEBRA_REDISTRIBUTE_DEFAULT_DELETE 14
#define
ZEBRA_IPV4_NEXTHOP_LOOKUP
#define
ZEBRA_IPV6_NEXTHOP_LOOKUP
bgpd和zebrad之间的api接口
bgp端接受到message后,会执行相应的bgp action:
bgp action
func
int
(*interface_add) (int, struct zclient *,
zebra_size_t);
int
(*interface_delete) (int, struct zclient *,
zebra_size_t);
int
(*interface_up) (int, struct zclient *,
zebra_size_t);
int
(*interface_down) (int, struct zclient *,
zebra_size_t);
int
(*interface_address_add) (int, struct zclient *, zebra_size_t);
int
(*interface_address_delete) (int, struct zclient *,
zebra_size_t);
int
(*ipv4_route_add) (int, struct zclient *,
zebra_size_t);
int
(*ipv4_route_delete) (int, struct zclient *,
zebra_size_t);
int
(*ipv6_route_add) (int, struct zclient *,
zebra_size_t);
int
(*ipv6_route_delete) (int, struct zclient *,
zebra_size_t);
zebra 端接受到message后,会执行相应的zebra action:
zebra action
func
void
zread_interface_add (struct zserv *client, u_short
length)
void
zread_interface_delete (struct zserv *client, u_short
length)
void
zread_ipv4_add (struct zserv *client, u_short
length)
void
zread_ipv4_delete (struct zserv *client, u_short length)
void
zread_ipv6_add (struct zserv *client, u_short length)
void
zread_ipv6_delete (struct zserv *client, u_short length)
void
zebra_redistribute_add (int command, struct zserv *client, int
length)
void
zebra_redistribute_delete (int command, struct zserv *client, int
length)
voidzebra_redistribute_default_add (int command,
struct zserv
*client, int
length)
void zebra_redistribute_default_delete (int command,
struct zserv
*client, int length)
void
zread_ipv4_nexthop_lookup (struct zserv *client, u_short length)
void
zread_ipv6_nexthop_lookup (struct zserv *client, u_short length)
bgp action:将local_client_socket中数据,写入bgp数据库。
zebra action:将zebra数据库中的信息写入local_server_subsocket,让local client端进行读取。
bgp peer间通信
bgp_accept操作
int bgp_accept (struct thread *thread)
{
}
bgp_event操作
int bgp_event (struct thread *thread)
{
}