————————————————
版权:本文转自cnblogs 刘超的通俗云计算
原文链接:
https://www.cnblogs.com/popsuper1982/p/5870181.html
https://www.cnblogs.com/popsuper1982/p/5886819.html
发布于:2016-9-13
四、内核态网络包处理
Openvswitch的内核模块openvswitch.ko会在网卡上注册一个函数netdev_frame_hook,每当有网络包到达网卡的时候,这个函数就会被调用。
static struct sk_buff *netdev_frame_hook(struct sk_buff *skb)
{
if (unlikely(skb->pkt_type == PACKET_LOOPBACK))
return skb;
port_receive(skb);
return NULL;
}
//上面的port_receive() 等价于netdev_port_receive()函数
#define port_receive(skb) netdev_port_receive(skb, NULL)
void netdev_port_receive(struct sk_buff *skb, struct ip_tunnel_info *tun_info)
{
struct vport *vport;
vport = ovs_netdev_get_vport(skb->dev);
……
skb_push(skb, ETH_HLEN);
ovs_skb_postpush_rcsum(skb, skb->data, ETH_HLEN);
ovs_vport_receive(vport, skb, tun_info);
return;
error:
kfree_skb(skb);
}
函数int ovs_vport_receive(struct vport vport, struct sk_buff skb, const struct ip_tunnel_info *tun_info)实现如下
int ovs_vport_receive(struct vport *vport, struct sk_buff *skb,
const struct ip_tunnel_info *tun_info)
{
struct sw_flow_key key;
......
/* Extract flow from 'skb' into 'key'. */
error = ovs_flow_key_extract(tun_info, skb, &key);
if (unlikely(error)) {
kfree_skb(skb);
return error;
}
ovs_dp_process_packet(skb, &key);
return 0;
}
在ovs_vport_receive() 这个函数里面,首先声明了变量struct sw_flow_key key;
如果我们看这个key的定义,可见这个key里面是一个大杂烩,数据包里面的几乎任何部分都可以作为key来查找flow表:
stru

OVS的内核模块在接收到网络包时,通过ovs_dp_process_packet()函数处理。它从包中提取TCP/IP五元组作为key查找流表。如果找到匹配项,直接执行actions;否则,通过netlink发送到用户态查找。流表由多个桶组成,每个桶包含多个flow表元素,key和actions存储在其中。
8817

被折叠的 条评论
为什么被折叠?



