Just For Coding

Keep learning, keep living …

Linux内核模块开发

Linux内核支持动态加载或卸载模块。这种机制使得不用重新编译内核就可以方便地扩展内核功能,也减小了内核镜像的大小。一般情况下,Linux设备驱动都以模块形式来实现,需要时再加载。

内核模块的扩展名为.ko, 一般位于/lib/modules/<kernel_version>/kernel目录下。

本文通过一个”hello world”级别的内核模块,来展示内核模块如何开发。

NFQUEUE和libnetfilter_queue实例分析

NFQUEUEiptables的一种规则目标, 它用于将网络数据包从内核传给用户态进程, 由用户态进程来裁决如何处理该数据包,并将裁决结果返回内核。传输通道为以数字标识的队列。队列由固定长度的链表实现,链表元素为数据包及元数据(kernel skb结构)。在内核中,Netfilter框架尝试将符合规则的数据包放入队列中。若队列已满,则丢弃该数据包。因此,若用户态进程处理过慢,则会严重影响网络性能。内核与用户态进程之间基于NFNETLINK通信,数据包需要在内核态与用户态之间进行拷贝,因而这种机制的性能比较差。

下面,以实例来说明NFQUEUE机制。

下面的命令会将发送给本机80端口的TCP数据包送往队列80:

1
iptables -A INPUT -p tcp --dport 80 -j NFQUEUE —-queue-num 80

ARP响应实例研究

之前文章<<ARP代理实例研究>>提到: 在默认配置下,只要ARP请求中的目标IP配置在本机,无论其是否配置在收到ARP请求数据包的接口上,Linux收包接口都会以身MAC地址发送ARP响应。若是不希望接口响应所有本机IP,可以通过修改arp_ignore参数来调整。

那么如果机器上多个网卡连接在同一交换机,这样多个网卡会收到相同的ARP请求。若多个网卡都回复,则客户端应该收到多个ARP响应。这种情况下,Linux是如何处理的呢?

ARP代理实例研究

ARP代理指网络接口对要查询的IP不属于本机的ARP请求以自身的MAC地址给予ARP响应。从而发送到该目的IP的数据包被捕获到代理设备,代理设备再从其他网络接口将数据包转发至目的IP。

ARP代理的一个典型应用场景是防火墙部署。通过将防火墙部署在被保护主机前面,开启ARP代理功能,可以不修改被保护主机的网络配置,将流量引导至防火墙对流量进行过滤。部署前后结构如图:

在默认配置下,只要ARP请求中的目标IP配置在本机,无论其是否配置在收到数据包的接口上,Linux收包接口都会以身MAC地址发送ARP响应。若是不希望接口响应所有本机IP,可以通过修改arp_ignore参数来调整,可以参考之前的文章<<ARP协议介绍>>

OpenStack Keystone介绍

OpenStack由一系列REST API服务组成,如NOVA提供计算服务,GLANCE提供镜像服务,NEUTRON提供网络服务。Keystone是这些服务之一,它为其他服务提供统一的身份认证和授权服务。它的工作模式如图:

WSGI介绍

Web应用程序的处理逻辑可以概括为:

  • 接收HTTP请求
  • 处理业务逻辑
  • 发送HTTP响应给客户端

其中,接收HTTP请求和发送HTTP响应,主要是解析HTTP请求,构造HTTP协议响应,这些与业务无关,不需要每次开发Web应用程序都重新实现,因而已经存在许多独立可以直接使用的组件,这种组件称为WebServer,而业务逻辑处理部分则称为Application。WebServer和Application之间通过约定好的协议或规范进行通信。

WSGI(Web Server Gateway Interface)是Python社区提出的WebServer与Application之间通信的规范, 当前版本为v1.0.1, 定义在PEP 3333(https://www.python.org/dev/peps/pep-3333/)。

RDO安装all-in-one模式OpenStack虚拟网络架构分析

RDO是在RHEL,Fedora, CentOS等系统上部署OpenStack的方案。简单的试用或研究OpenStack可以选择all-in-one模式安装。这种模式将所有的OpenStack组件都部署在同一台机器上。本文来分析这种模式下虚拟网络的架构。

all-in-one模式安装完成时,RDO自动完成了以下工作:

  • 创建了外部网络public: 172.24.4.224/28
  • 创建了租户demo
  • 为租户demo创建了私有网络private: 10.0.0.0/24
  • 为租户demo创建路由器router1, 将private和public连接在一起

我们登录demo租户,创建两个虚拟机,网络拓朴图如下:

本文基于该拓朴分析虚拟网络架构。

Open vSwitch上OpenFlow流表操作示例

Open vSwitch提供了OpenFlow命令行工具: ovs-ofctl, 用法及流表语法等细节参考: ovs-ofctl(8)。

本文将通过简单的PING实验来展示OVS上的OpenFlow操作,实验环境宿主机为CentOS7。

创建虚拟交换机:

1
ovs-vsctl add-br br-int

创建TAP设备:

1
2
ip tuntap add tap0 mode tap
ip tuntap add tap1 mode tap

将设备连接到虚拟交换机:

1
2
ovs-vsctl add-port br-int tap0
ovs-vsctl add-port br-int tap1

SDN和OpenFlow介绍

传统网络架构下,数据转发和转发决策逻辑都集中在网络设备内部,而各厂商的网络设备都有自己的配置方法, 运维和管理的复杂性很高。云计算等业务发展对网络调整的迅速响应需求越来越高,传统方式网络架构越来越不能满足灵活性要求。因而业界提出了SDN方案,将数据平面和控制平面分离,数据平面由网络设备完成,而决策逻辑交由独立的控制器来完成,从而控制器能够对整个网络进行全局管控。除此之外,控制器对上层应用程序提供API(称为北向API),上层的业务逻辑可以使用北向API处理流量和部署服务,网络控制逻辑可以直接通过编写程序来完成,网络调整的响应速度大为加快,灵活性大为提高。控制器与负责转发数据的网络设备之间通过标准协议交互转发策略,这之间协议称为南向协议或南向API。

整体架构如图:

OpenFlow是一种南向API协议,并且定义了交换机规范。实现OpenFlow规范的交换机称为OpenFlow交换机。

基于IPTABLES MARK机制实现策略路由

MARK是IPTABLES的一种规则目标,它用于给匹配了相应规则的数据包设置标签。它只能用于mangle表中。然而,标签并不是设置于数据包内容中,而是设置在内核中数据包的载体上。如果需要在数据包内容中设置标签,可以使用TOS规则目标,它可以修改IP数据包头的TOS值。

MARK是一个32位整数值, MARK目标可以使用3种方法来设置mark值:

  • --set-mark value: 直接设置mark值为value
  • --and-mark value: 将mark值与value做位与运算后设置为新mark值
  • --or-mark value: 将mark值与value做位或运算后设置为新mark值

比如,将从网络接口tun0进入的、目标端口为5222的TCP数据包设置mark值为1:

1
iptables -t mangle -A PREROUTING -j MARK --set-mark 1 -i tun0 -p tcp --dport 5222