基于Opendaylight的SFC部署及实验

ps

  • 使用命令行下载慢的化可以先下载到本地,之后手动安装
  • chatgpt真好用(不过他有时会瞎说,看看就好)
  • 遇到问题2小时后解决不了直接重装系统(前提是可以靠重装解决

安装双系统

是否装双系统和实验没有任何关系,当然好处是不卡,以下所有内容都在第二个系统中进行。

【Ubuntu安装详细教程】 https://www.bilibili.com/video/BV1CG4y1h7bx/?share_source=copy_web&vd_source=4b3bd263fcce7c0dda5f423950a03d87

ubuntu版本:内核版本暂定为4.2(血的教训,不过版本错了可以换)

流程全部按照视频,压缩空间越大越好(血的教训,差点把我电脑干废)

进入系统后先更新源:sudo apt update

参考资料

  • Ubuntu 16.04 安装 java 8的方法:https://www.studyweb.cn/detail/java_173308.html
  • ubuntu18.04字体设置:https://www.likecs.com/show-204584993.html
  • Ubuntu网络下载速度慢解决方法:https://blog.csdn.net/weixin_46229691/article/details/120602520
  • Ubuntu卸载软件:3种卸载方式:https://cloud.tencent.com/developer/article/2080200
  • Ubuntu切换指定版本的内核:https://blog.csdn.net/weixin_40837318/article/details/123798456

  • maven :https://www.cnblogs.com/yhnet/articles/16540421.html

遇到的坑

  • Ubuntu18.04:Ubuntu软件无法从“extensions.gnome.org”下载更新:https://blog.csdn.net/weixin_51995147/article/details/125597896
  • Ubuntu vi命令键盘错乱问题解决:https://blog.csdn.net/qq_19734597/article/details/102816394

安装opendaylight&mininet

安装可参考:

  • OpendaylightCarbon()版本安装:https://www.shuzhiduo.com/A/lk5aQL3Z51/
  • odl feature:feature:install odl-netconf-api odl-netconf-mapping-api odl-netconf-util odl-netconf-netty-util odl-netconf-client odl-sfc-netconf odl-netconf-connector-all odl-netconf-notifications-api odl-mdsal-apidocs odl-mdsal-models odl-mdsal-binding odl-mdsal-binding-runtime odl-mdsal-common odl-mdsal-broker odl-mdsal-clustering-commons odl-mdsal-distributed-datastore odl-mdsal-remoterpc-connector odl-mdsal-broker-local odl-restconf odl-restconf-noauth odl-sfc-model odl-sfc-provider odl-sfc-provider-rest  odl-sfc-ovs odl-sfc-ui odl-sfc-sb-rest odl-sfc-openflow-renderer

实验用的sfc结构可直接从config导入:

{
  "service-functions": {
    "service-function": [
      {
        "name": "SF1",
        "type": "firewall",
        "sf-data-plane-locator": [
          {
            "name": "vxlan",
            "ip": "127.0.0.1",
            "port": 10000,
            "service-function-forwarder": "SFF1",
            "transport": "service-locator:vxlan-gpe"
          }
        ],
        "rest-uri": "http://127.0.0.1:5000",
        "ip-mgmt-address": "127.0.0.1"
      }
    ]
  }
};
{
  "service-function-forwarders": {
    "service-function-forwarder": [
      {
        "name": "SFF1",
        "ip-mgmt-address": "192.168.1.20",
        "sff-data-plane-locator": [
          {
            "name": "dp1",
            "service-function-forwarder-ovs:ovs-options": {},
            "data-plane-locator": {
              "transport": "service-locator:vxlan-gpe",
              "ip": "127.0.0.1",
              "port": 4789
            }
          }
        ],
        "service-node": "sff1",
        "service-function-dictionary": [
          {
            "name": "SF1",
            "failmode": "service-function-forwarder:open",
            "sff-sf-data-plane-locator": {
              "sff-dpl-name": "dp1",
              "sf-dpl-name": "vxlan"
            }
          }
        ],
        "rest-uri": "http://127.0.0.1:5000",
        "service-function-forwarder-ovs:ovs-bridge": {}
      }
    ]
  }
};
{
  "service-nodes": {
    "service-node": [
      {
        "name": "sff1",
        "ip-mgmt-address": "127.0.0.1"
      },
      {
        "name": "sf1",
        "service-function": [
          "dpi-1"
        ],
        "ip-mgmt-address": "127.0.0.1"
      },
      {
        "name": "Node1",
        "service-function-forwarder": [
          "SFF1"
        ],
        "service-function": [
          "SF1"
        ],
        "ip-mgmt-address": "127.0.0.1"
      }
    ]
  }
};
{
  "service-function-chains": {
    "service-function-chain": [
      {
        "name": "Chain-1",
        "sfc-service-function": [
          {
            "name": "firewall",
            "type": "firewall",
            "order": 0
          }
        ]
      }
    ]
  }
};

sff_agent启动代码(根据情况换参数)

sudo python3 sff_client.py --remote-sff-ip 127.0.0.1 --remote-sff-port 4789 --sfp-id 100 --sfp-index 255

遇到的坑

  • gihub下载慢,使用github520 :https://blog.csdn.net/niangoagao/article/details/120769564
  • 修改更新hostssudo: rcnscd:找不到命令:https://blog.csdn.net/qq_47911262/article/details/121918115
  • git clone 报错:fatal: unable to connect to github.com:github.com[0: x.x.x.x]: errno=Unknown err:https://blog.csdn.net/ZDbisheng/article/details/127767328
  • http://localhost:8181/index.html找不到服务器:https://www.codenong.com/cs105439116/

卸载python,并安装python3.4(如果自带3.x 则跳过)

Ubuntu操作系统中怎么将python卸载?Ubuntu卸载python的步骤是什么:https://www.ycpai.cn/python/f5NSGsf2.html

安装opendaylight-sfc

下载release版,别的都是坑:https://github.com/opendaylight/sfc/tags

搭建过程:

遇到的坑

  • Ubuntu 14.04 下解决maven访问速度慢问题:https://www.shuzhiduo.com/A/kjdwWOYOdN/
  • E: 无法获得锁 /var/lib/dpkg/lock - open (11: 资源暂时不可用)E: 无法锁定管理目录(/var/lib/dpkg/),是否有其他进程正占用它?:https://blog.csdn.net/weixin_54789940/article/details/127422929

  • 提示ModuleNotFoundError: No module named ‘flask‘:https://blog.csdn.net/IamBird/article/details/129100752
  • Non-resolvable parent POM: Could not transfer artifact org.opendaylight.odlparent:odlparent:pom:1.6.4-Beryllium-SR4 from/to opendaylight-mirror (https://nexus.opendaylight.org/content/repositories/public/): Network is unreachable (connect failed) and 'parent.relativePath' points at no local POM @ line 9, column 13 -> [Help 2]:添加国内镜像后任然无法编译:更换sfc的版本或者用点魔法
  • 安装了vmware tools还是不能复制粘贴,使用了很多种方法都不可以:xiamianpinglunqu:https://blog.csdn.net/m0_53600272/article/details/123902053

实验(跟着上面的网站)

遇到的坑

  • 实验过程中找不到包的问题(直接改源码)Python导包的路径问题:https://blog.csdn.net/weixin_41033366/article/details/115009968
  • 使用sff_client后在sfc_agent不显示sf收发包:
    • 原因是由于未知原因,sfc_globals.get_data_plane_path()为{},没有odlweb页面中显示的RSP
    • 这导致MySffSever中的_lookup_next_sf发生keyError异常,直接在sfc_agent中打印Could not determine next service hop. SP: %d, SI: %d,而没有走sf
    • 解决方法为
      • 在sfc_agent中的create_path()方法中的find_metadata()下添加以下代码
      •  with open('RSP.json', 'w') as f:
             json.dump(sfc_globals.get_data_plane_path(), f)
      • 即把RSP信息存储在json文件中,之后修改/sfc-py/sfc/common中的services.py下MySffSever中的_lookup_next_sf方法,将try代码块替换为
      • local_data_plane_path = sfc_globals.get_data_plane_path()
        if local_data_plane_path == {}:
        with open("RSP.json", "r") as outfile:
        local_data_plane_path = json.load(outfile)
        # logger.error("_lookup_next_sf: %s,json: %s",sfc_globals.get_data_plane_path(),local_data_plane_path)
        sff_name = super(MySffServer, self).get_name()
        # logger.error('sff_name 439 : %s service path : %s service index : %s',sff_name,service_path,service_index)
        next_hop = local_data_plane_path[sff_name][str(service_path)][str(service_index)]
        # logger.error('next_hop 440 : %s', next_hop)
      • 即如果sfc_globals.get_data_plane_path()为{},则读取RSP.json中的RSP数据
    • 重新运行sfc_agent,sff_client后可看到sf接受到包后又发送了出去

SFCDemo103工作流程

NSH-SFC概述

当前SFC的实现方案主要分为两种:一种基于NSH(network service header)。数据封装时,在L2或者L3数据后添加NSH头,然后进行L3或L4的封装。转发时,根据nshheader去转发SFC中的数据,整个过程都是依据同一个SPI(service path id)和递减的SI(service index);另一种无NSH头,在转发过程中,SFF需要不停对新来的数据包进行判断,确定是否属于某个SFC。ODL的子项目SFC就是第一种的实现。

NSH-SFC组件简述

Classifier:分类器,根据controller来的policy来决策是否给数据进行nsh封装,并且把数据发送至相应的sff。
Service Function(SF):网络中的Middleware,常见的有loadbalance,firework,NAT等。值得注意的是,在NSH方案下,如果SF没有NSH解析功能,那么需要在SF和其对应的SFF之间增加一个proxy。该proxy用于解析NSH,并且帮助完成nshheader中SI的自减算法(如果SI不能成功自减,那么SFF会认为这个数据没有被forward到该SF,从而再次forward向该SF,最后的结果就是产生网络风暴)。

Service Function Forwarder(SFF):SFC中的数据中转站,负责数据的转发。当SI=1的时候,SFF负责把nsh头部去掉。

NSH-SFC(with VxLAN)工作流程

  1. 控制层面定义SFC:
  2. 用户利用SDN提供的北向应用,创建sfc1,controller会做相应的配置工作,产生对应的数据通道(sfc1本身是一个chain,可以和vxlan的tunnel完美匹配。那么,定义了sfc1,同时可以对应一个vxlan。所以,可以理解为sfc1同时绑定了vxlan和NSH中的path信息)。
  3. 数据首先通过classifier,classifier为sfc1的数据打上nsh头信息,然后转交sff1。
  4. sff1将数据发送至sf1,sf1将数据处理完后,为nshheader中的si执行自减操作,然后返回到sff1.
  5. sff1将数据交到sff2,sff2重复sff的职责...
  6. 对于没有nsh解析能力的sf2,proxy会帮其完成nsh相关工作.
  7. 在si=0(有文档说si=1)的时候,sff会给数据包去nsh,那么整个sfc1流程就结束

NSH报文头

gpt:

NSH (Network Service Header)是一种用于在数据包中添加服务链路和网络功能信息的协议,可以帮助SDN控制器实现更加灵活的网络管理和配置。NSH头部包含了多个字段,如下所示:

![NSH Header Format](https://docs.opendaylight.org/en/stable-carbon/_images/nsh-header-format.png)

其中,NSH Base Header(NSH基础头部)是必需的,包括了Version、OAM Flag、Reserved1、Length、MD Type、Next Protocol、Service Path Identifier(SPI)和Service Index等字段。另外,NSH Context Headers(NSH上下文头部)是可选的,可以根据实际需要自行添加。例如,在ODL SFC中,Context Headers用于携带与网络功能相关的元数据信息。

NSH头部的长度由Length字段指定。具体而言,如果Version为0,则长度为4个字节;如果Version为1,则长度为8个字节。因此,NSH头部的长度可以为4或8个字节。
要使用Python在数据包前添加NSH报文头,请按照以下步骤进行操作:

1. 定义NSH基础头部(NSH Base Header)和UDP负载数据。

```python
# Define the NSH Base Header and UDP payload
nsh_base_header = b'\x01\x00\x00\x08\x01\x11\x11\x11\x22\x22\x22\x22\x33\x33\x33\x33'
udp_payload = b'\x12\x34\x56\x78\x9a\xbc\xde\xf0'
```

在这个示例代码中,我们定义了一个NSH基础头部和一个UDP负载数据。其中,NSH基础头部包括了Version、Length、MD Type、Next Protocol、SPI和Service Index等字段,具体的数值可以根据实际情况进行设置。

2. 将NSH基础头部和UDP负载数据合并成完整的数据包。

```python
# Combine the NSH base header and UDP payload to form the final data packet
data = nsh_base_header + udp_payload
```

在这一步中,我们将NSH基础头部和UDP负载数据合并成了完整的数据包。

3. 创建一个Raw Socket对象,并将数据包发送到目标设备或虚拟端口。

```python
import socket

# Create a raw socket
s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW)

# Set the interface to br-sfc virtual port
s.bind(('br-sfc', 0))

# Set the destination MAC address to broadcast
dest_mac = b'\xff\xff\xff\xff\xff\xff'

# Send the packet to the virtual port
s.send(dest_mac + data)
```

在这个示例代码中,我们创建了一个Raw Socket对象,并将其绑定到名为'br-sfc'的虚拟端口上。然后,我们设置目标MAC地址为广播地址b'\xff\xff\xff\xff\xff\xff',并通过Socket发送数据包。请注意,实际应用中可能需要根据具体情况修改目标MAC地址和虚拟端口名称。

通过以上步骤,我们可以使用Python将NSH报文头添加到数据包前,并将其发送到网络中的目标设备或虚拟交换机上的虚拟端口。
nsh_base_header = b'\x01\x00\x00\x08\x01\x11\x11\x11\x22\x22\x22\x22\x33\x33\x33\x33'是一个包含NSH基础头部信息的字节数组。具体而言,这个NSH Base Header包括了以下字段:

- Version:协议版本号,为1。
- OAM Flag(Operations, Administration and Maintenance Flag):OAM标志位,用于指示数据包是否需要进行OAM处理。在这个例子中,OAM Flag被设置为0,表示不需要进行OAM处理。
- Reserved1:保留字段,必须设置为0。
- Length:NSH Base Header的长度,为8个字节。
- MD Type(Metadata Type):元数据类型,用于指示Context Headers中元数据的类型和格式。在这个例子中,MD Type被设置为1,表示Context Headers使用RFC2685规定的元数据格式。
- Next Protocol:下一层协议类型,用于指示数据包中负载的上层协议类型。在这个例子中,Next Protocol被设置为17,表示UDP协议。
- Service Path Identifier(SPI):服务路径标识符,用于唯一标识服务路径。在这个例子中,SPI被设置为0x11111111。
- Service Index:服务索引,用于指示当前服务链路中的服务实例。在这个例子中,Service Index被设置为0x22222222。

因此,nsh_base_header = b'\x01\x00\x00\x08\x01\x11\x11\x11\x22\x22\x22\x22\x33\x33\x33\x33'包含了NSH基础头部的各个字段信息,可以用于构造完整的NSH报文。

参考资料

  • python之socket:https://www.cnblogs.com/csnd/p/16465082.html
  • Open vSwitch源码解析之基于VxLAN实现NSH解析功能 :https://www.sdnlab.com/16610.html
  • SDNLAB技术分享(一):ODL的SFC入门和Demo :https://www.sdnlab.com/13826.html
  • 什么是业务链?:https://info.support.huawei.com/info-finder/encyclopedia/zh/%E4%B8%9A%E5%8A%A1%E9%93%BE.html

一些概念

关于OVS

https://www.cnblogs.com/goldsunshine/p/10959199.html

OVS常用操作

https://blog.csdn.net/Light_Travlling/article/details/103500734

NSH相关

https://datatracker.ietf.org/doc/html/draft-quinn-sfc-arch-05

SFCdemo103官方虚拟机

初始化

demo地址:https://github.com/opendaylight/sfc/tree/master/sfc-demo/sfc103

Vagrant要下载最新版:https://developer.hashicorp.com/vagrant/downloads

  • Ubuntu系统下安装rpm安装包:https://blog.csdn.net/weixin_47872288/article/details/120771718

virtualbox 下载地址:http://download.virtualbox.org/virtualbox/

参考资料

超详细的 Vagrant 上手指南 - DavyCloud的文章 - 知乎 https://zhuanlan.zhihu.com/p/259833884

  • 超详细的 Vagrant 上手指南 - DavyCloud的文章 - 知乎 https://zhuanlan.zhihu.com/p/259833884
  • 基于协议无感知转发的服务功能链:http://www.c-s-a.org.cn/html/2018/9/6561.html
  • 在docker中加载镜像:
    • docker-compose 学习:通过 image 指令指定镜像搭建一个简单LNMP:https://blog.csdn.net/weixin_34151004/article/details/92110279

    • docker-compose的基本使用含yml文件基本使用:https://blog.csdn.net/xwnxwn/article/details/128066258

遇到的坑

  • Guest Additions和Virtualbox版本不对应问题及自动解决办法:https://www.pilishen.com/posts/Guest-Additions-and-Virtualbox-version-doesnot-match-debug-vbguest-plugin

  • 解决flag to force provisioning. Provisioners marked to run always will still run.:https://blog.csdn.net/weixin_38468437/article/details/80458329

  • ubuntu 安装vbox虚拟机:https://blog.csdn.net/u010312474/article/details/108622826

  • mount -t vboxsf -o uid=1000,gid=1000 vagrant /vagrant:https://www.cnblogs.com/chenzhenzhen/p/5419247.html
  • This system is currently not set up to build kernel modules.Please install the gcc make perl packages from your distribution.:https://blog.csdn.net/beetleinv/article/details/112829079

启动

进入到sfcdemo103后执行sudo ./demo.sh

vagrant up
vagrant ssh -c /vagrant/run_demo.sh
rm -fr ovs-debs

使用apt-get update会报错

gpt:

Ubuntu 15.10已于2016年停止支持,因此 apt-get update 可能会出现错误,因为 Ubuntu 更新服务器不再提供针对该版本的更新。建议升级到更高版本的 Ubuntu 或使用更受支持的 Linux 发行版。

如果您仍然需要在 Ubuntu 15.10 上运行特定的软件,请尝试手动编辑 /etc/apt/sources.list 文件并将其替换为适当的镜像源,例如阿里云、清华大学等国内的镜像源,然后再运行 apt-get update。

请注意,这种方法可能存在风险,并且由于 Ubuntu 15.10 不再受支持,可能存在未修复的安全漏洞和其他问题。强烈建议升级到受支持的操作系统版本。

解决方法

换源(https://zhuanlan.zhihu.com/p/530343925)

科大镜像源:https://mirrors.ustc.edu.cn/ubuntu-old-releases/

编辑/etc/apt/sorces.list,在末尾添加

deb https://mirrors.ustc.edu.cn/ubuntu-old-releases/ bionic main restricted universe multiverse
deb-src https://mirrors.ustc.edu.cn/ubuntu-old-releases/ bionic main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu-old-releases/ bionic-security main restricted universe multiverse
deb-src https://mirrors.ustc.edu.cn/ubuntu-old-releases/ bionic-security main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu-old-releases/ bionic-updates main restricted universe multiverse
deb-src https://mirrors.ustc.edu.cn/ubuntu-old-releases/ bionic-updates main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu-old-releases/ bionic-proposed main restricted universe multiverse
deb-src https://mirrors.ustc.edu.cn/ubuntu-old-releases/ bionic-proposed main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu-old-releases/ bionic-backports main restricted universe multiverse
deb-src https://mirrors.ustc.edu.cn/ubuntu-old-releases/ bionic-backports main restricted universe multiverse

然而换源后依然报错(微笑

参考资料

  • var/lib/docker无法进入:https://www.lmlphp.com/user/151215/article/item/3557530/
  • 如何换源:https://blog.csdn.net/zhulong20120418/article/details/83050350

关于sf1,sf2由状态始终为exited(1)的问题

在本实验中,由于docker创建容器后会执行sfc-demo/sfc103/start.sh  中的代码,而sf1,sf2由于初始化报错,状态始终为exited(1),使用docker logs 容器id  可查看详细报错。所以在执行 sudo ./run_demo.sh 前要把发生错误的代码注释掉.

创建成功后使用sudo docker exec -it 容器ID /bin/dash 进入容器手动执行

elif [ $host == 'sf1' ] || [ $host == 'sf2' ]; then
    cd /sfc/sfc-py;
#    pip3 install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple
#    nohup python3 sfc/sfc_agent.py --rest --odl-ip-port 192.168.1.5:8181 &
fi

如果在执行删除容器并重新创建后sf1,sf2状态依然为exited(1),则需要删除镜像重新创建容器。

该段代码在sf中启用了sfc_agent,这会使sf中运行一个services服务,这会根据sf的标签进行相应的转发操作,注释掉之后就不能进行包的转发

sf创建之后需要在sf的容器中运行被注释的代码

pip3 install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple

执行该段代码后会报错,经过一番折腾后,怀疑是系统自带的python2与后来下载的python3中的pip发生冲突,导致下载失败

解决方法

修改/sfc/sfc-demo/sfc103中的Dockerfile,将FROM 改为ubuntu:18.04,因为该版本自带python3.6,原版会下载16.04,其自带的python2.7会与之后RUN下载的冲突。取消pip下载改为通过wegt下载。如果坚持使用16.04,则需要先将自带的python卸载,之后再下载新的。

但是由于虚拟机ubuntu版本为15.10,已被弃用,所以该方法无效,但可用在宿主机(即在宿主机搭一个和虚拟机一样的环境)。

# FROM ubuntu:16.04
FROM ubuntu:18.04

MAINTAINER ericdia

ENV CONTROLLER=192.168.1.5
ENV BRIDGE=br-sfc

# RUN apt-get update && apt-get install -y git libtool m4 autoconf automake make \
#     libssl-dev libcap-ng-dev python3 python3-pip python-six vlan iptables wget \
#     net-tools init-system-helpers kmod uuid-runtime

RUN apt-get update \
    && apt-get remove --auto-remove python2.7 \
    && apt-get purge --auto-remove python2.7 \
    && apt-get autoclean python2.7 \
    && rm -rf /usr/lib/python2.7

RUN apt-get install -y git libtool m4 autoconf automake make \
    libssl-dev libcap-ng-dev python3 python3-pip python-six vlan iptables wget \
    net-tools init-system-helpers kmod uuid-runtime iputils-ping

ADD ovs-debs /tmp

RUN python3 /tmp/3.6/get-pip.py -i https://pypi.tuna.tsinghua.edu.cn/simple

#RUN dpkg -i /tmp/libopenvswitch_* /tmp/openvswitch-common* /tmp/openvswitch-switch*
RUN dpkg -i /tmp/openvswitch-common* /tmp/openvswitch-switch*
ADD ./start.sh /app/
WORKDIR /

ENTRYPOINT [ "/app/start.sh" ]

修改之后需要将sudo ./run_demo.sh 中被注释的代码还原。

参考资料

  • 停止所有容器:sudo docker stop $(sudo docker ps -a -q)
  • 删除所有容器:sudo docker rm $(sudo docker ps -a -q)
  • 如何优雅地删除Docker镜像和容器(超详细):https://blog.csdn.net/u014282578/article/details/127866389

  • docker-compose.yml 配置文件详解:https://blog.csdn.net/shixiaodongmain/article/details/127850973
  • 【Docker 1小时快速上手教程,无废话纯干货】 https://www.bilibili.com/video/BV11L411g7U1/?share_source=copy_web&vd_source=4b3bd263fcce7c0dda5f423950a03d87
  • 关于运行opendaylight时client: JAVA_HOME not set; results may vary:https://blog.csdn.net/weixin_41549104/article/details/109517562

  • Docker常用命令:https://blog.csdn.net/m0_51295655/article/details/128198412

  • pip3下载:https://blog.csdn.net/weixin_39763683/article/details/110328240
  • 解决fatal error: Python.h: No such file or directory报错:https://blog.csdn.net/weixin_35757704/article/details/124852304

  • ubuntu中,出现Failed to fetch http://…..时,需要换源:https://blog.csdn.net/qq_34214260/article/details/112690725
  • openflow概念:https://blog.csdn.net/weixin_44388689/article/details/125978689
  • docker安装:https://blog.csdn.net/u012563853/article/details/125295985
  • Docker容器与本地文件相互拷贝:https://blog.csdn.net/momo1994/article/details/124661749
  • OVS设置日志命令、日志文件说明:https://www.codenong.com/cs106386128/

  • Docker教程:Dockerfile中sed的使用:https://blog.csdn.net/qq_29229567/article/details/107684952

  • Dockerfile中echo使用: https://www.bbsmax.com/A/QV5ZaZp4Jy/
  • Linux系统中出现依赖libssl1.1.0问题:https://www.cnblogs.com/gambler/p/9574596.html

由于以上原因,放弃在虚拟机中实验,换为宿主机。

基于OVS的SFC环境搭建(SFCDemo103魔改版)

该需求的简单实验:https://www.iteye.com/blog/wx1569175208-2476644,先用这个测试环境是否搭建成功

进不去进这个:浅析OpendayLight SFChttps://blog.csdn.net/choufu8526/article/details/100655899

测试代码:python3 sff_client.py --remote-sff-ip 192.168.1.20 --remote-sff-port 6633 --sfp-id 106 --sfp-index 255按需修改

抓包:tcpdump -i eth0 -w ovs_traffic.pcap

tcmp bug:

mv /usr/sbin/tcpdump /usr/bin/tcpdump
ln -s /usr/bin/tcpdump /usr/sbin/tcpdump

sfc结构

{
  "service-functions": {
    "service-function": [
      {
        "name": "SF1",
        "type": "firewall",
        "sf-data-plane-locator": [
          {
            "name": "wzj-sf1",
            "ip": "172.17.0.1",
            "port": 6633,
            "service-function-forwarder": "SFF1",
            "transport": "service-locator:vxlan-gpe"
          }
        ],
        "rest-uri": "http://172.17.0.1:5000",
        "ip-mgmt-address": "172.17.0.1"
      }
    ]
  }
};
{
  "service-function-forwarders": {
    "service-function-forwarder": [
      {
        "name": "SFF1",
        "ip-mgmt-address": "127.0.0.1",
        "service-function-dictionary": [
          {
            "name": "SF1",
            "sff-interfaces": [
              {
                "sff-interface": "wzj-sf1"
              }
            ],
            "failmode": "service-function-forwarder:open",
            "sff-sf-data-plane-locator": {
              "sf-dpl-name": "wzj-sf1",
              "sff-dpl-name": "wzj-sf1"
            }
          }
        ],
        "sff-data-plane-locator": [
          {
            "name": "wzj-sf1",
            "service-function-forwarder-ovs:ovs-options": {
              "nsp": "flow",
              "dst-port": "6633",
              "nshc1": "flow",
              "nshc2": "flow",
              "nshc3": "flow",
              "nshc4": "flow",
              "nsi": "flow",
              "local-ip": "flow",
              "key": "flow",
              "remote-ip": "flow"
            },
            "data-plane-locator": {
              "transport": "service-locator:vxlan-gpe",
              "ip": "172.17.0.1",
              "port": 6633
            },
            "service-function-forwarder-ovs:ovs-bridge": {
              "bridge-name": "br-wzj"
            }
          }
        ],
        "service-node": "",
        "service-function-forwarder-ovs:ovs-bridge": {
          "bridge-name": "br-wzj"
        }
      }
    ]
  }
};

然而失败了,因为我的sfc_agent不知道为什么创建sf时没有反应,这个以前没有遇到过

对于sfc的api,odl提供了非常详细的api供外界调用,具体可以参照http://127.0.0.1:8181/apidoc/explorer/index.html进行查看

给sff发送数据包:

参考资料:

https://blog.csdn.net/u014381531/article/details/72397067

https://blog.csdn.net/Bluewingtan/article/details/55296667

获取rsp的odl接口:/restconf/operational/rendered-service-path:rendered-service-paths

遇到的坑

不过它下载的maven版本太低,需要自己照着别的教程下载一个高版本的,java+1

jian yi quan cheng zai root huan jing xia jin xing

sfc 构建慢可以用美国的魔法

OVS调试介绍

docker镜像导出保存为tar和tar包导入成docker镜像

ubutun下修改文件权限

docker export import后,导入镜像,启动时的错误,Error response from daemon: No command specified

以下为踩坑记录(一个坑解决1天,刚修好一个又出来一个)

关于ovs-vswitchd.log中的几个报错

报错1:etdev_max_backlog: open failed (No such file or directory)

首先是2023-03-18T09:04:23.290Z|00039|ofproto_dpif_xlate|INFO|/proc/sys/net/core/netdev_max_backlog: open failed (No such file or directory)

这个折腾好久都没解决(涉及到内核,但docker内没有找到相关文件),放弃

报错2:variable-length userdata feature probe failed (Invalid argument)

2023-03-18T09:04:10.040Z|00007|ofproto_dpif|INFO|system@ovs-system: Datapath does not support recirculation
2023-03-18T09:04:10.041Z|00008|ofproto_dpif|INFO|system@ovs-system: MPLS label stack length probed as 0
2023-03-18T09:04:10.041Z|00009|ofproto_dpif|INFO|system@ovs-system: datapath does not support masked set action feature.
2023-03-18T09:04:10.041Z|00010|ofproto_dpif|INFO|system@ovs-system: Datapath does not support unique flow ids
2023-03-18T09:04:10.041Z|00011|ofproto_dpif|INFO|system@ovs-system: Datapath does not support ct_state
2023-03-18T09:04:10.041Z|00012|ofproto_dpif|INFO|system@ovs-system: Datapath does not support ct_zone
2023-03-18T09:04:10.041Z|00013|ofproto_dpif|INFO|system@ovs-system: Datapath does not support ct_mark
2023-03-18T09:04:10.041Z|00014|ofproto_dpif|INFO|system@ovs-system: Datapath does not support ct_label
2023-03-18T09:04:10.041Z|00015|ofproto_dpif|INFO|system@ovs-system: Datapath does not support ct_state_nat
2023-03-18T09:04:10.057Z|00016|ofproto_dpif|WARN|system@ovs-system: variable-length userdata feature probe failed (Invalid argument)

报错3:|ERR|attribute tcp_flags has length 4 but should have lengt

chatgpt:

这个错误通常是由于OVS中的OpenFlow协议版本不兼容导致的。在某些版本的OpenFlow协议中,tcp_flags属性的长度为4,但在其他版本中,它的长度可能会不同。要解决此问题,您可以尝试将OVS和控制器之间使用的OpenFlow协议版本进行匹配,或者调整OVS的配置以正确处理这些不兼容的属性。

报错4:ovs-system: execute 2 failed (Invalid argument) on packet vlan_tci=0x0000,dl_src=ca:bf:bd:2b:f6:89,dl_dst=01:23:00:00:00:01,dl_type=0x88cc

chatgpt:

这个错误信息表示,Open vSwitch 在执行动作时遇到了问题。具体地说,这个动作涉及到试图将一个包从一个端口转发到另一个端口,但是在执行时出现了错误。

"vlan_tci=0x0000,dl_src=ca:bf:bd:2b:f6:89,dl_dst=01:23:00:00:00:01,dl_type=0x88cc" 部分表示这个包的详细信息。从这些信息中可以推断出,这个包是一个 LLDP(链路层发现协议)包,它正在试图从一个端口转发到另一个端口,但在转发过程中出现了问题。

造成这个问题的原因可能有很多种,以下是几个可能的原因:

1. 配置错误:可能有一些配置不正确,导致 Open vSwitch 无法正确处理这个包。

2. 版本冲突:有时,Open vSwitch 和内核模块之间的版本不兼容可能会导致执行错误。

3. 端口配置错误:有时,端口的配置不正确可能会导致执行错误,例如配置错误的 VLAN 值或未正确配置的端口类型。

针对这个问题,建议您进行以下操作:

1. 确认 Open vSwitch 的版本:检查您正在使用的 Open vSwitch 的版本,并确保它没有任何已知的问题。

2. 检查端口和 VLAN 配置:检查端口和 VLAN 的配置,查看是否存在任何配置错误。您可以使用 ovs-vsctl 命令来检查和修改端口和 VLAN 配置。

3. 检查内核模块配置:如果 Open vSwitch 与内核模块之间存在版本冲突,或配置不正确,那么可以尝试重新加载内核模块或更改其配置。

4. 查询社区:如果以上建议都无法解决该问题,请发布问题详细内容到 Open vSwitch 的社区中,以获取更具体的帮助和建议。

希望以上建议对您有所帮助,如有任何问题或疑问,欢迎随时与我联系。

怀疑是Open vSwitch 与内核模块之间存在版本冲突,因为宿主机内核是5.4,而ovs版本是2.5,版本不匹配(https://docs.openvswitch.org/en/latest/faq/releases/)

所以需要下载对应内核版本的ovs,尝试过解压版,但都失败了,所以使用deb安装。

关于使用deb安装ovs

chatgpt:

您可以通过以下步骤下载 Open vSwitch 的 deb 版本:

1. 打开 Terminal。

2. 安装 wget:在 Terminal 中输入以下命令并运行:

   ```
   sudo apt-get install wget
   ```

3. 下载 Open vSwitch 的 deb 包:在 Terminal 中输入以下命令并运行,将 VERSION 替换为您想要下载的 Open vSwitch 版本号:

   ```
   wget https://www.openvswitch.org/releases/openvswitch-VERSION.tar.gz
   ```

4. 解压并进入解压后的 Open vSwitch 文件夹:在 Terminal 中输入以下命令并运行,将 VERSION 替换为您下载的 Open vSwitch 版本号:

   ```
   tar -xvf openvswitch-VERSION.tar.gz
   cd openvswitch-VERSION
   ```

5. 安装构建所需的依赖项:在 Terminal 中输入以下命令并运行:

   ```
   sudo apt-get install -y build-essential fakeroot debhelper autoconf automake libssl-dev bzip2
   ```

6. 使用 dpkg-buildpackage 命令创建 deb 文件:在 Terminal 中输入以下命令并运行:

   ```
   dpkg-buildpackage -b --no-sign
   ```

7. 在终端中,可以看到几个 deb 文件已经生成。使用以下命令安装 Open vSwitch:

   ```
   sudo dpkg -i openvswitch-common_{VERSION}_amd64.deb
   sudo dpkg -i openvswitch-switch_{VERSION}_amd64.deb
   ```

其中 VERSION 将替换为您下载的 Open vSwitch 版本号。请注意,捆绑在 deb 包中的不同组件具有不同的名称,您需要相应地使用 dpkg 命令安装这些组件。

上述过程中第4步可解压至dev-ovs文件夹,之后创建deb文件,最后修改Dockerfile并添加安装命令,下为修改之后的Dockerfile

#FROM ubuntu:16.04
FROM ubuntu:18.04

MAINTAINER ericdia

ENV CONTROLLER=192.168.1.5
ENV BRIDGE=br-sfc

# RUN apt-get update && apt-get install -y git libtool m4 autoconf automake make \
#     libssl-dev libcap-ng-dev python3 python3-pip python-six vlan iptables wget \
#     net-tools init-system-helpers kmod uuid-runtime

RUN apt-get update \
    && apt-get remove --auto-remove python2.7 \
    && apt-get purge --auto-remove python2.7 \
    && apt-get autoclean python2.7 \
    && rm -rf /usr/lib/python2.7

RUN apt-get install -y git libtool m4 autoconf automake make \
    libssl-dev libcap-ng-dev python3 python-six vlan iptables wget \
    net-tools init-system-helpers kmod uuid-runtime iputils-ping \
    gcc zlib* python3.6-distutils python3-dev build-essential

ADD ovs-debs /tmp

RUN python3 /tmp/3.6/get-pip.py -i https://pypi.tuna.tsinghua.edu.cn/simple

RUN apt-get update  \
    && apt-get install -f -y libunbound2 libunwind8
#    && dpkg -i /tmp/libssl1.1_1.1.0g-2ubuntu4.1_amd64.deb

#RUN cd /tmp/openssl-3.0.1  \
#    && ./config --prefix=/usr/local/openssl  \
#    && make \
#    && make install
#
RUN dpkg -i /tmp/libopenvswitch_* /tmp/openvswitch-common* /tmp/openvswitch-switch*

RUN #dpkg -i  /tmp/openvswitch-common* /tmp/openvswitch-switch*

ADD ./start.sh /app/
WORKDIR /

ENTRYPOINT [ "/app/start.sh" ]

由于未知原因,安装新版ovs后创建容器后sf1会报错找不到ssl模块,修改Dockerfile即可,最终结果如上。

关于执行到ovs-ofctl dump-flows -OOpenflow13 br-sfc时没有输出的问题

chagpt:

`ovs-ofctl dump-flows -OOpenFlow13 br-sfc` 是一个用于查看 OVS 网桥上配置的 OpenFlow 流表项的命令。其中,`-OOpenFlow13` 表示使用 OpenFlow 1.3 协议进行通信,`br-sfc` 是要查看流表项的 OVS 网桥的名称。

如果该命令没有反应,请检查以下可能原因:

1. 检查 OVS 是否已正确安装和运行。

2. 检查 `br-sfc` 是否是真实存在的 OVS 网桥名称。

3. 检查 OpenFlow 协议版本是否正确,例如如果您的 OVS 使用了 OpenFlow 1.4 或 1.5 协议,则需要将命令中的 `-OOpenFlow13` 替换为 `-OOpenFlow14` 或 `-OOpenFlow15`。

4. 如果您使用了不同的 Shell/终端,请确保您在执行命令之前已经连接到了正确的主机或容器。

如果您仍然遇到问题,请尝试查阅 OVS 官方文档或咨询网络管理员以获取更多帮助。

如何检查OVS 组件是否正确安装?

chatgpt:

您可以通过以下方式检查 OVS 组件是否正确安装:

1. 检查 OVS 是否已经安装:使用以下命令检查 OVS 是否已安装:

   ```
   dpkg -l openvswitch-switch
   ```

   如果该命令输出结果中包含 `openvswitch-switch`,则表示 OVS 已经安装。

2. 检查 OVS 服务是否正在运行:使用以下命令检查 OVS 服务是否正在运行:

   ```
   systemctl status openvswitch-switch
   ```

   如果命令输出结果中显示 OVS 服务正在运行,则表示 OVS 已正常启动。

3. 检查 OVS 版本:使用以下命令检查 OVS 的版本:

   ```
   ovs-vsctl --version
   ```

   如果命令输出结果中显示了 OVS 的版本信息,则表示 OVS 已经正确安装并可用。

如果您在执行上述步骤时遇到任何问题或错误信息,请参阅 OVS 官方文档或咨询网络管理员。

使用 ovs-ofctl -V 查看 ovs使用的openflow协议版本,输出OpenFlow versions 0x1:0x6

chatgpt:

"OpenFlow versions 0x1:0x6" 是指 OpenFlow 协议的版本号,其中 0x1 表示版本 1,0x6 表示版本 6。

在OpenFlow versions 0x1:0x6的环境下使用openflow1.3会报错吗?

chatpgt:

在 OpenFlow versions 0x1:0x6 的环境下,使用 OpenFlow 1.3 可能会报错,因为 OpenFlow 1.3 是在版本 0x04 中引入的。如果控制器和交换机之间使用的 OpenFlow 协议版本不兼容,则可能会导致通信失败或出现其他错误。

因此,在使用 OpenFlow 1.3 之前,建议确认控制器和交换机之间支持的 OpenFlow 版本,并确保它们之间的协议版本匹配。如果您想要在 OpenFlow 1.3 环境下运行,请确保控制器和交换机都支持 OpenFlow 1.3,并将 OVS 配置为使用 OpenFlow 1.3 协议版本。

让ovs支持openflow1.3:

chatgpt:

要使 Open vSwitch (OVS) 支持 OpenFlow 1.3,您需要执行以下步骤:

1. 检查 OVS 版本:确保您的 OVS 版本支持 OpenFlow 1.3。在 OVS 2.3 及更高版本中,OpenFlow 1.3 已经被支持。

2. 启用 OpenFlow 1.3:使用 `ovs-vsctl` 命令来配置 OVS 的桥接器以使用 OpenFlow 1.3 协议(默认情况下,OVS 使用 OpenFlow 1.0)。例如,要将一个名为 `br0` 的桥接器配置为使用 OpenFlow 1.3,可以运行以下命令:

   ```
   ovs-vsctl set Bridge br0 protocols=OpenFlow13
   ```

3. 配置控制器:确保您的控制器也支持 OpenFlow 1.3,并已正确配置以使用该协议。如果您使用的是 Floodlight、OpenDaylight 或 Ryu 等流行的 OpenFlow 控制器,则它们应该已经支持 OpenFlow 1.3。

4. 测试连接:使用 `ovs-ofctl` 命令测试 OVS 和控制器之间的连接是否正常工作。例如,可以运行以下命令来列出 `br0` 上的所有流表项:

   ```
   ovs-ofctl dump-flows -O OpenFlow13 br0
   ```

如果一切设置正确,您应该能够成功地列出 `br0` 上的所有流表项。

请注意,尽管 OpenFlow 1.3 提供了一些新的功能和特性,但某些旧版设备可能不支持该协议。因此,在启用 OpenFlow 1.3 之前,请仔细检查您的网络设备是否支持该协议。

此时在classifier1中运行 ovs-ofctl dump-flows -OOpenflow13 br-sfc会输出流表:

 cookie=0x2b00000000000000, duration=1515.432s, table=0, n_packets=0, n_bytes=0, priority=100,dl_type=0x88cc actions=CONTROLLER:65535
 cookie=0x2b00000000000009, duration=648.799s, table=0, n_packets=17, n_bytes=1254, priority=2,in_port="veth-br" actions=output:"sff0-dpl",CONTROLLER:65535
 cookie=0x2b0000000000000a, duration=648.799s, table=0, n_packets=0, n_bytes=0, priority=2,in_port="sff0-dpl" actions=output:"veth-br",CONTROLLER:65535
 cookie=0x2b00000000000000, duration=1515.375s, table=0, n_packets=0, n_bytes=0, priority=0 actions=drop

chatgpt:

这是一个OpenFlow交换机的流表,使用OpenFlow 1.3协议。该交换机名为"br-sfc",有一个包含四个字段的流表条目,每个条目用逗号分隔。

第一个条目的匹配条件是数据链路层类型为0x88cc,匹配到后的动作是将包发送到控制器上(端口号为65535)。

第二个条目的匹配条件是输入端口为"veth-br",匹配到后的动作是将包转发到端口"sff0-dpl",同时也会把包发送到控制器。

第三个条目的匹配条件是输入端口为"sff0-dpl",匹配到后的动作是将包转发到端口"veth-br",同时也会把包发送到控制器。

第四个条目是默认的低优先级规则,没有匹配条件,它的动作是丢弃该包。

关于sff的流表的内容

root@sff1:/# ovs-ofctl dump-flows -OOpenflow13 br-sfc
OFPST_FLOW reply (OF1.3) (xid=0x2):
 cookie=0x2b00000000000005, duration=562.360s, table=0, n_packets=0, n_bytes=0, priority=100,dl_type=0x88cc actions=CONTROLLER:65535
 cookie=0x2b00000000000005, duration=562.360s, table=0, n_packets=0, n_bytes=0, priority=0 actions=drop
 cookie=0x14, duration=3.735s, table=0, n_packets=0, n_bytes=0, priority=5 actions=goto_table:1
 cookie=0x2b0000000000000b, duration=557.354s, table=0, n_packets=0, n_bytes=0, priority=2,in_port=1 actions=CONTROLLER:65535
 cookie=0x14, duration=3.735s, table=1, n_packets=0, n_bytes=0, priority=250,nsp=110 actions=goto_table:4
 cookie=0x14, duration=3.669s, table=1, n_packets=0, n_bytes=0, priority=250,nsp=8388718 actions=goto_table:4
 cookie=0x14, duration=3.735s, table=1, n_packets=0, n_bytes=0, priority=5 actions=drop
 cookie=0x14, duration=3.734s, table=2, n_packets=0, n_bytes=0, priority=5 actions=goto_table:3
 cookie=0x14, duration=3.734s, table=3, n_packets=0, n_bytes=0, priority=5 actions=goto_table:4
 cookie=0x14, duration=3.735s, table=4, n_packets=0, n_bytes=0, priority=550,nsi=254,nsp=110 actions=load:0xc0a80132->NXM_NX_TUN_IPV4_DST[],goto_table:10
 cookie=0x14, duration=3.735s, table=4, n_packets=0, n_bytes=0, priority=550,nsi=255,nsp=110 actions=load:0xc0a8011e->NXM_NX_TUN_IPV4_DST[],goto_table:10
 cookie=0x14, duration=3.669s, table=4, n_packets=0, n_bytes=0, priority=550,nsi=254,nsp=8388718 actions=load:0xc0a8011e->NXM_NX_TUN_IPV4_DST[],goto_table:10
 cookie=0x14, duration=3.734s, table=4, n_packets=0, n_bytes=0, priority=5 actions=goto_table:10
 cookie=0xba5eba1100000102, duration=3.669s, table=10, n_packets=0, n_bytes=0, priority=660,nsi=253,nsp=8388718,nshc1=0 actions=load:0x4->NXM_NX_TUN_GPE_NP[],IN_PORT
 cookie=0xba5eba1100000101, duration=3.734s, table=10, n_packets=0, n_bytes=0, priority=655,nsi=254,nsp=110,in_port=1 actions=move:NXM_NX_NSH_MDTYPE[]->NXM_NX_NSH_MDTYPE[],move:NXM_NX_NSH_NP[]->NXM_NX_NSH_NP[],move:NXM_NX_NSH_C1[]->NXM_NX_NSH_C1[],move:NXM_NX_NSH_C2[]->NXM_NX_NSH_C2[],move:NXM_NX_NSH_C3[]->NXM_NX_NSH_C3[],move:NXM_NX_NSH_C4[]->NXM_NX_NSH_C4[],move:NXM_NX_TUN_ID[0..31]->NXM_NX_TUN_ID[0..31],load:0x4->NXM_NX_TUN_GPE_NP[],IN_PORT
 cookie=0xba5eba1100000101, duration=3.734s, table=10, n_packets=0, n_bytes=0, priority=655,nsi=255,nsp=110,in_port=1 actions=move:NXM_NX_NSH_MDTYPE[]->NXM_NX_NSH_MDTYPE[],move:NXM_NX_NSH_NP[]->NXM_NX_NSH_NP[],move:NXM_NX_NSH_C1[]->NXM_NX_NSH_C1[],move:NXM_NX_NSH_C2[]->NXM_NX_NSH_C2[],move:NXM_NX_NSH_C3[]->NXM_NX_NSH_C3[],move:NXM_NX_NSH_C4[]->NXM_NX_NSH_C4[],move:NXM_NX_TUN_ID[0..31]->NXM_NX_TUN_ID[0..31],load:0x4->NXM_NX_TUN_GPE_NP[],IN_PORT
 cookie=0xba5eba1100000101, duration=3.669s, table=10, n_packets=0, n_bytes=0, priority=655,nsi=254,nsp=8388718,in_port=1 actions=move:NXM_NX_NSH_MDTYPE[]->NXM_NX_NSH_MDTYPE[],move:NXM_NX_NSH_NP[]->NXM_NX_NSH_NP[],move:NXM_NX_NSH_C1[]->NXM_NX_NSH_C1[],move:NXM_NX_NSH_C2[]->NXM_NX_NSH_C2[],move:NXM_NX_NSH_C3[]->NXM_NX_NSH_C3[],move:NXM_NX_NSH_C4[]->NXM_NX_NSH_C4[],move:NXM_NX_TUN_ID[0..31]->NXM_NX_TUN_ID[0..31],load:0x4->NXM_NX_TUN_GPE_NP[],IN_PORT
 cookie=0xba5eba1100000103, duration=3.669s, table=10, n_packets=0, n_bytes=0, priority=655,nsi=253,nsp=8388718,in_port=1 actions=move:NXM_NX_NSH_MDTYPE[]->NXM_NX_NSH_MDTYPE[],move:NXM_NX_NSH_NP[]->NXM_NX_NSH_NP[],move:NXM_NX_NSI[]->NXM_NX_NSI[],move:NXM_NX_NSP[0..23]->NXM_NX_NSP[0..23],move:NXM_NX_NSH_C1[]->NXM_NX_TUN_IPV4_DST[],move:NXM_NX_NSH_C2[]->NXM_NX_TUN_ID[0..31],load:0x4->NXM_NX_TUN_GPE_NP[],IN_PORT
 cookie=0xba5eba1100000101, duration=3.734s, table=10, n_packets=0, n_bytes=0, priority=650,nsi=254,nsp=110 actions=move:NXM_NX_NSH_MDTYPE[]->NXM_NX_NSH_MDTYPE[],move:NXM_NX_NSH_NP[]->NXM_NX_NSH_NP[],move:NXM_NX_NSH_C1[]->NXM_NX_NSH_C1[],move:NXM_NX_NSH_C2[]->NXM_NX_NSH_C2[],move:NXM_NX_NSH_C3[]->NXM_NX_NSH_C3[],move:NXM_NX_NSH_C4[]->NXM_NX_NSH_C4[],move:NXM_NX_TUN_ID[0..31]->NXM_NX_TUN_ID[0..31],load:0x4->NXM_NX_TUN_GPE_NP[],output:1
 cookie=0xba5eba1100000101, duration=3.734s, table=10, n_packets=0, n_bytes=0, priority=650,nsi=255,nsp=110 actions=move:NXM_NX_NSH_MDTYPE[]->NXM_NX_NSH_MDTYPE[],move:NXM_NX_NSH_NP[]->NXM_NX_NSH_NP[],move:NXM_NX_NSH_C1[]->NXM_NX_NSH_C1[],move:NXM_NX_NSH_C2[]->NXM_NX_NSH_C2[],move:NXM_NX_NSH_C3[]->NXM_NX_NSH_C3[],move:NXM_NX_NSH_C4[]->NXM_NX_NSH_C4[],move:NXM_NX_TUN_ID[0..31]->NXM_NX_TUN_ID[0..31],load:0x4->NXM_NX_TUN_GPE_NP[],output:1
 cookie=0xba5eba1100000101, duration=3.669s, table=10, n_packets=0, n_bytes=0, priority=650,nsi=254,nsp=8388718 actions=move:NXM_NX_NSH_MDTYPE[]->NXM_NX_NSH_MDTYPE[],move:NXM_NX_NSH_NP[]->NXM_NX_NSH_NP[],move:NXM_NX_NSH_C1[]->NXM_NX_NSH_C1[],move:NXM_NX_NSH_C2[]->NXM_NX_NSH_C2[],move:NXM_NX_NSH_C3[]->NXM_NX_NSH_C3[],move:NXM_NX_NSH_C4[]->NXM_NX_NSH_C4[],move:NXM_NX_TUN_ID[0..31]->NXM_NX_TUN_ID[0..31],load:0x4->NXM_NX_TUN_GPE_NP[],output:1
 cookie=0xba5eba1100000103, duration=3.669s, table=10, n_packets=0, n_bytes=0, priority=650,nsi=253,nsp=8388718 actions=move:NXM_NX_NSH_MDTYPE[]->NXM_NX_NSH_MDTYPE[],move:NXM_NX_NSH_NP[]->NXM_NX_NSH_NP[],move:NXM_NX_NSI[]->NXM_NX_NSI[],move:NXM_NX_NSP[0..23]->NXM_NX_NSP[0..23],move:NXM_NX_NSH_C1[]->NXM_NX_TUN_IPV4_DST[],move:NXM_NX_NSH_C2[]->NXM_NX_TUN_ID[0..31],load:0x4->NXM_NX_TUN_GPE_NP[],output:1
 cookie=0x14, duration=3.734s, table=10, n_packets=0, n_bytes=0, priority=5 actions=drop

chatgpt:

这段流表是基于OpenFlow 1.3协议的,共有10个表。其中:

- 表0包含两个规则,一个优先级为100,匹配以太网类型字段为0x88cc的帧并发送给控制器端口,另一个优先级为0,将匹配的数据包丢弃。
- 表1包含三个规则,其中优先级为5的规则将匹配的数据包丢弃,其他两个规则根据nsp字段值跳转到表4。
- 表2包含一条规则,优先级为5,将匹配的数据包跳转到表3。
- 表3包含一条规则,优先级为5,将匹配的数据包跳转到表4。
- 表4包含四条规则,分别根据nsi和nsp字段的值与load操作设置NXM_NX_TUN_IPV4_DST和NXM_NX_TUN_GPE_NP,然后跳转到表10。
- 表10包含九条规则,根据不同的条件进行匹配,并使用move和load操作对数据包头部信息进行设置,最终输出到指定的端口或丢弃。

表10包含了九个规则,其中每个规则都匹配特定的条件并执行相应的操作。具体来说:

- 规则1:优先级为660,匹配nsi为253、nsp为8388718、nshc1为0的数据包,并将NXM_NX_TUN_GPE_NP设置为0x4以及输出端口为IN_PORT。
- 规则2和规则3:优先级为655,分别匹配nsi为254、nsp为110以及nsi为255、nsp为110的数据包,并执行一系列move和load操作,最后将NXM_NX_TUN_GPE_NP设置为0x4以及输出端口为IN_PORT。
- 规则4:优先级为655,匹配nsi为254、nsp为8388718的数据包,并执行一系列move和load操作,最后将NXM_NX_TUN_GPE_NP设置为0x4以及输出端口为IN_PORT。
- 规则5、规则6、规则7:优先级为650,分别匹配nsi为254、nsp为110、nsi为255、nsp为110以及nsi为254、nsp为8388718的数据包,并执行一系列move和load操作,最后将NXM_NX_TUN_GPE_NP设置为0x4以及输出端口为1。
- 规则8:优先级为650,匹配nsi为254、nsp为110的数据包,并执行一系列move和load操作,最后将NXM_NX_TUN_GPE_NP设置为0x4以及输出端口为1。
- 规则9:优先级为5,匹配任何数据包,并将其丢弃。

总的来说,这些规则的作用是进行GPE封装(Generic Protocol Extension),并将封装后的流量输出到指定端口或丢弃。其中涉及到的头部信息包括NSH(Network Service Header)和TUN(Tunneling)等字段。

这段流表规则的意思是:

匹配优先级为650、nsp=149和nsi=254的数据包,然后执行以下操作:
- 将NSH头部中的MDTYPE字段设置为0
- 将NSH头部中的NP字段设置为0
- 将NSH头部中的C1字段替换为0
- 将NSH头部中的C2字段替换为0
- 将NSH头部中的C3字段替换为0
- 将NSH头部中的C4字段替换为0
- 将Tunnel ID字段的值赋给GPE协议头部中的NP字段
- 将数据包发送到与端口号1相关联的输出端口

其中,NSH(Network Service Header)是用于网络服务链路(SFC)标识的一种协议头,而GPE(Generic Protocol Extension)是一种通用的协议扩展方法。这个流表规则实现了将一个特定类型的数据包从SFC网络传输出去的功能。

这些字段属于NSH协议头部和GPE协议头部中的重要字段,它们的作用如下:

- `MDTYPE`字段:指示NSH后续包头类型,如果为0,则表示没有后续包头。
- `NP`字段:在NSH协议头部中表示网络服务路径(NSP)索引值,在GPE协议头部中表示下一个协议头(NPH)值。这个字段的作用是标识接下来的数据流需要经过哪条网络服务路径,或者指示当前数据包的下一个协议头类型。
- `C1-C4`字段:用于传输元数据,可根据应用程序需求设置不同的元数据值。
- `Tunnel ID`字段:用于标识隧道的唯一性,即用来区分不同的隧道。

通过修改这些字段的值,可以实现不同的网络功能,例如实现SFC网络服务路径的处理和转发、QoS保证和隧道隔离等。此外,GPE协议头部的NP字段还可以用于指定下一个协议头类型,如IPv4或IPv6等。

是的,这段NSH协议头包含了上面提到的所有字段,具体如下:

- `Version`: 占1个字节,固定为0x01。
- `Length`: 占1个字节,表示NSH基本头部长度,固定为4bytes。
- `NSI`: 占1个字节,表示网络服务实例索引(NSI)。
- `C1-C4`: 共占4个字节,每个字段占1个字节,用于传输元数据。
- `OAM`: 占2个字节,用于指示是否启用NSH OAM功能(目前未定义)。
- `Reserved`: 占2个字节,保留字段,必须为0。
- `MDTYPE`: 占1个字节,表示后续包头类型,如果为0,则表示没有后续包头。
- `Next Protocol`: 占1个字节,用于指示下一个协议头类型。
- `Network Service Header Context`: 占4个字节,用于传输NSH上下文信息。

因此,给定的`nsh_base_header`可以解析为一个完整的NSH基本头部。

C1-C4是NSH协议头部中用于传输元数据的四个字段,它们可以在SFC网络中用于各种不同的目的。例如,可以使用C1-C4字段来标识从源到目的节点的信息,如源IP地址、目的IP地址、端口号等。此外,还可以将一些特定的元数据信息编码为C1-C4字段,并在网络传输过程中进行保留和传递。这样,可以在网络服务路径中实现多种策略,如基于元数据进行流量分类、负载均衡、安全策略控制、故障排除等。因此,C1-C4字段在SFC网络中扮演了重要的角色,能够为不同应用程序提供个性化的网络功能和服务。

这个JSON配置是用于在SFC网络中给NSH协议头的C1-C4字段设置固定值,具体来说:

- `name`: 表示该元数据名称为“NSH1”。
- `context-header1`、`context-header2`、`context-header3`、`context-header4`: 分别表示将C1-C4字段分别设置为1、2、3、4。

在实际应用中,可以将这些元数据值(即1、2、3、4)与特定的服务功能进行关联,例如将NSH1元数据设置为源IP地址,在网络传输过程中保留并使用该值进行路由和服务链路操作。又或者将这些元数据值作为流量分类器的一部分,按照不同的NSH1值,将流量转发到不同的路径或服务链路中。通过设置C1-C4字段的值,可以为SFC网络提供更加灵活和个性化的服务功能。

如果在该流表规则中,将NSH协议头的C1-C4字段分别设置为1、2、3和4,则当数据包匹配到该流表规则时,将执行以下操作:

- 将NSH头部中的MDTYPE字段设置为0
- 将NSH头部中的NP字段设置为0
- 将NSH头部中的C1字段替换为1
- 将NSH头部中的C2字段替换为2
- 将NSH头部中的C3字段替换为3
- 将NSH头部中的C4字段替换为4
- 将Tunnel ID字段的值赋给GPE协议头部中的NP字段
- 将数据包发送到与端口号1相关联的输出端口

因此,在该流表规则下,数据包的NSH协议头的C1-C4字段将会被覆盖为固定的值,并且Tunnel ID字段的值也会被赋给GPE协议头部中的NP字段,然后数据包将被转发到与端口号1相关联的输出端口。

在这段流表中,output:1指定的是输出端口号,即将匹配到的数据包转发到端口号为1的物理接口上。

在SDN(Software Defined Networking)网络中,流表通常用于控制数据包的转发行为。每一条流表规则都由匹配条件和对应的操作组成,当一个数据包匹配到某个规则时,就会执行该规则所定义的操作。

在上述提供的流表规则中,output:1表示将匹配到该规则的数据包输出到端口号为1的物理接口上。这意味着,如果有一个数据包满足该规则中的所有匹配条件,那么它将被发送到端口号为1的连接设备上。

是的,一般情况下,端口号为1的连接设备指的是与该OVS交换机的第一个物理端口相连的网络设备。在SDN网络中,OVS交换机通常被用于实现虚拟化和服务链等功能,它会将不同的虚拟网络和物理网络连接起来,并根据SDN控制器下发的流表规则进行数据包转发。

因此,在这段流表规则中,output:1表示将匹配到该规则的数据包发送到与当前OVS交换机的第一个物理端口相连的设备上。具体而言,可能是与OVS交换机相连的另一个OVS交换机、一个物理服务器或者其他类型的网络设备等。

这段流表规则的意思是:

匹配优先级为5的数据包,然后执行以下操作:
- 将数据包发送到表格ID为3的下一个表格进行处理

该流表规则的作用是将优先级为5的数据包重定向到表格3进行下一步处理。具体的处理方式由表格3中的流表规则决定。在OpenFlow交换机中,resubmit动作可以将一个数据包发送到指定的下一个表格中,并从该表格开始重新进行流表匹配和转发。

这段流表规则的意思是:

匹配优先级为655、in_port为2、nsi为255、nsp为230的数据包,然后执行以下操作:
- 将NSH头部中的MDTYPE字段设置为0
- 将NSH头部中的NP字段设置为0
- 将NSH头部中的C1字段替换为与输入端口号相同的值
- 将NSH头部中的C2字段替换为与输入端口号不同的随机值
- 将NSH头部中的C3字段替换为0
- 将NSH头部中的C4字段替换为0
- 将Tunnel ID字段的值赋给GPE协议头部中的NP字段
- 将数据包发送到与输入端口号相同的输出端口

其中,NSH(Network Service Header)是用于网络服务链路(SFC)标识的一种协议头,而GPE(Generic Protocol Extension)是一种通用的协议扩展方法。这个流表规则实现了将一个特定类型的数据包从某一输入端口转发到与该端口号相同的输出端口,并重写NSH协议头的C1-C4字段的值以及GPE协议头的NP字段的值,以实现类似源地址转换和隔离等功能。

在OpenFlow交换机中,`CONTROLLER:65535`是一个特殊的“动作”(Action),它将匹配到的数据包发送到SDN控制器进行进一步处理或分析。具体来说,当流表规则中的`actions`字段设置为`CONTROLLER:65535`时,表示将匹配到的数据包发送到控制器的所有连接端口(即端口号为65535)。

通常,使用`CONTROLLER`动作可以实现以下目的:

1. 监听交换机上发生的事件和故障,以实现网络拓扑发现、故障诊断等功能。
2. 收集网络流量信息,进行分析和统计,以支持网络性能优化和安全管理。
3. 实现自定义的转发策略和服务链路,通过控制器对流表进行编程,可以动态地插入、删除和修改流表规则,从而实现灵活的流量控制和服务链路管理。

需要注意的是,由于`CONTROLLER`动作会将数据包发送到控制器进行处理,因此在大规模网络环境下,频繁使用该动作可能会导致控制器过载和网络延迟增大等问题。因此,在实际应用中,需要慎重考虑使用`CONTROLLER`动作的频率和范围。

通常情况下,控制器不会直接对受到的数据包进行转发。在SDN网络中,交换机的主要职责是处理数据包的转发和路由操作,而控制器则负责对网络进行管理和控制,并通过编写流表规则对数据包进行流量调度、服务链路配置等操作。

当交换机中的流表规则无法匹配当前的数据包时,或者需要进行动态的流量调度和服务链路切换时,交换机将会将数据包发送到SDN控制器。控制器收到这些数据包后,根据预设的策略和逻辑,会对其进行分析、处理、再生产新的流表规则,并将规则发送回交换机以实现数据包的转发或者其他操作。因此,SDN架构中的数据包转发和路由操作主要由交换机来完成,而控制器则提供管理和控制的能力,通过编写流表规则来指导交换机如何进行转发和处理。

关于odl中sff的配置代码

  {
                "name": "SFF1",
                "service-node": "sff1",
                "service-function-forwarder-ovs:ovs-bridge": {
                    "bridge-name": "br-sfc",
                },
                "sff-data-plane-locator": [
                    {
                        "name": "sff1-dpl",
                        "data-plane-locator": {
                            "transport": "service-locator:vxlan-gpe",
                            "port": 6633,
                            "ip": "192.168.1.20"
                        },
                        "service-function-forwarder-ovs:ovs-options": {
                            "remote-ip": "flow",
                            "dst-port": "6633",
                            "key": "flow",
                            "exts": "gpe",
                            "nsp": "flow",
                            "nsi": "flow",
                            "nshc1": "flow",
                            "nshc2": "flow",
                            "nshc3": "flow",
                            "nshc4": "flow"
                        }
                    }
                ],
                "service-function-dictionary": [
                    {
                        "name": "dpi-1",
                        "sff-sf-data-plane-locator": {
                             "sf-dpl-name": "dpi-1-dpl",
                             "sff-dpl-name": "sff1-dpl"
                        }
                    }
                ],
            },

关于ovs-vsctl show显示的内容

Manager "tcp:192.168.1.5:6640"
        is_connected: true
    Bridge br-sfc
        Controller "tcp:192.168.1.5:6653"
        Port "sff0-dpl"
            Interface "sff0-dpl"
                type: vxlan
                options: {dst_port="6633", exts=gpe, key=flow, "nshc1"=flow, "nshc2"=flow, "nshc3"=flow, "nshc4"=flow, nsi=flow, nsp=flow, remote_ip=flow}
        Port br-sfc
            Interface br-sfc
                type: internal
        Port veth-br
            Interface veth-br
    ovs_version: "2.12.4"

chatgpt:

这段代码是一个 Open vSwitch (OVS) 的配置文件,它描述了一个名为 `br-sfc` 的 OVS 桥接器及其相关端口和控制器信息。以下是每个部分的含义:

- `Manager "tcp:192.168.1.5:6640"`:指定了 OVS 的管理程序地址和端口。
- `Bridge br-sfc`:定义了一个名为 `br-sfc` 的 OVS 桥接器。
- `Controller "tcp:192.168.1.5:6653"`:指定了 `br-sfc` 桥接器使用的控制器地址和端口。
- `Port "sff0-dpl"`:定义了一个名为 `sff0-dpl` 的 OVS 端口,并指定了其类型为 VXLAN。此端口的选项包括使用的远程端口号、扩展协议使用 GPE、流标记以及 NSH 头字段信息。
- `Port br-sfc`:定义了一个名为 `br-sfc` 的内部端口,连接到桥接器 `br-sfc` 上。
- `Port veth-br`:定义了一个名为 `veth-br` 的物理端口,表示该端口与宿主机上的另一个虚拟网络设备 `veth-br` 相连。
- `ovs_version: "2.12.4"`:指定了当前 OVS 实例的版本号。

这些描述都是用 OVS 的命令行工具 `ovs-vsctl` 命令生成的配置信息。通常,管理员可以编辑这个配置文件来修改 OVS 的设置,比如新增、删除或修改端口、桥接器等信息。

关于如何测试ovs所在网络进行了数据转发的问题

gpt:

要测试 OVS 所在网络是否已配置数据转发,请按照以下步骤进行操作:

1. 连接到 OVS 网桥:使用 `ovs-vsctl` 命令连接到 OVS 网桥。例如,您可以使用以下命令查看网桥的状态:

   ```
   ovs-vsctl show
   ```

2. 添加流表项:使用 `ovs-ofctl` 命令向 OVS 网桥添加流表项。例如,您可以使用以下命令将端口 1 上的所有入站流量转发到端口 2:

   ```
   ovs-ofctl add-flow <bridge_name> in_port=1,actions=output:2
   ```

   在该命令中,`<bridge_name>` 是 OVS 网桥的名称。

3. 发送数据包:使用 `ping` 命令或其他工具向另一台设备发送数据包。例如,您可以使用以下命令向 IP 地址为 10.0.0.2 的设备发送 5 个 ICMP 数据包:

   ```
   ping 10.0.0.2 -c 5
   ```

4. 监视网络流量:使用网络分析工具(如 Wireshark)监视网络流量。检查是否从端口 1 接收到了 ICMP 数据包,并且它们是否被正确地转发到端口 2。

如果您成功接收到了 ICMP 数据包,那么您的 OVS 网桥已经成功配置了数据转发。如果出现任何问题,请参阅 OVS 文档或咨询网络管理员以获取更多帮助。

方案1:

chatgpt:

要使用tcpdump验证Open vSwitch (OVS)是否正常工作,可以通过捕获与虚拟交换机相关的网络流量来检查。以下是一些示例命令:

1. 监听与OVS相关的网络接口

```
sudo tcpdump -i <ovs_port>
```

其中,`<ovs_port>`是指在OVS配置中为虚拟交换机指定的端口。

2. 捕获特定类型的流量

```
sudo tcpdump -i <ovs_port> -nn -v icmp
```

此命令将只捕获ICMP流量,并输出有关数据包的详细信息。您可以根据需要更改协议类型和选项。

3. 使用Wireshark进行分析

如果要对流量进行更详细的分析,可以使用Wireshark等网络分析工具。首先,通过tcpdump捕获流量并将其保存到文件中:

```
sudo tcpdump -i <ovs_port> -w ovs_traffic.pcap
```

然后,使用Wireshark打开该文件以查看数据包并分析问题。

当我使用tcpdump -i br-sfc报错tcpdump: br-sfc: That device is not up

chatgpt:

这个错误提示表示tcpdump无法使用名为br-sfc的设备进行抓包,因为该设备未启用。您可以通过使用命令"ifconfig -a"来查看该设备的状态,并使用"ifconfig br-sfc up"命令将其启用。然后再尝试使用tcpdump进行抓包。

启用后可正常监控,之后可正常抓包并用wireshark分析。

关于tcpdump报错:error while loading shared libraries: libcrypto.so.1.0.0: cannot stat shared object: Permission denied的问题

环境:Linux sff1 4.2.8-040208-generic #201512150620 SMP Tue Dec 15 06:22:17 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

mv /usr/sbin/tcpdump /usr/bin/tcpdump
ln -s /usr/bin/tcpdump /usr/sbin/tcpdump

https://blog.csdn.net/doris_9800/article/details/104654802

方案2:

在docker容器中安装wireshark并监听端口

chatgpt:

要在宿主机中使用Wireshark监视Docker容器内的Open vSwitch(OVS),您可以执行以下步骤:

1. 在Docker容器中安装Wireshark,并将X11转发到本地计算机。

   ```
   docker run -it --rm \
     -e DISPLAY=$DISPLAY \
     -v /tmp/.X11-unix:/tmp/.X11-unix \
     wireshark
   ```

2. 在Docker容器中启动Wireshark,选择正确的网络接口以捕获与OVS相关的数据包。

3. 启动容器内的OVS服务,并配置桥接和流表规则等。

4. 使用Wireshark分析捕获的数据包以验证OVS是否正在正常工作,并排除任何潜在的网络问题。

请注意,为了能够捕获来自Docker容器的数据包,您需要在Docker守护程序上设置适当的网络配置。例如,您可能需要使用`--net=host`选项将容器连接到主机网络并启用特权访问以访问网络设备。此外,在某些情况下,您可能还需要配置Docker容器内的防火墙规则或重新路由表项等。

x11是啥?

gpt:

X11(也称为X Window System)是一个基于客户端-服务器模型的图形用户界面(GUI)系统,用于在UNIX和类UNIX操作系统上显示窗口和图形应用程序。X11提供了一种标准化的方式来处理窗口管理、字体渲染、输入事件和图形绘制等任务。

X11架构由三个主要组件组成:X Server、X Client和Window Manager。X Server是一个运行在主机上的后台进程,它负责与硬件交互并将图形输出发送到客户端。X Client是一个运行在远程计算机上的进程,它连接到X Server并请求显示窗口或图形应用程序。Window Manager是一种特殊类型的X Client,它控制窗口的布局、大小和外观,并接受来自用户的输入事件。

X11还提供了许多高级功能,如复合窗口管理、剪贴板、共享内存和OpenGL支持等。虽然X11已经存在了很长时间,但它仍然是许多UNIX和Linux系统上最常用的GUI系统之一。

上述代码的作用:

gpt:

这段代码是一个Docker命令,用于在容器中启动Wireshark网络分析工具,并将其显示输出到本地计算机的窗口系统上。

具体来说,该命令执行以下操作:

- `docker run`:运行一个新的Docker容器。
- `-it`:以交互式终端模式运行容器。
- `--rm`:在容器退出时自动删除它。
- `-e DISPLAY=$DISPLAY`:将X11显示环境变量传递到容器中,允许Wireshark在本地计算机的窗口系统上显示图形界面。
- `-v /tmp/.X11-unix:/tmp/.X11-unix`:将本地计算机的X11套接字目录(`/tmp/.X11-unix`)挂载到容器内部的同一位置,以便容器可以与本地计算机共享X11显示服务。
- `wireshark`:启动Wireshark容器,开始捕获和分析网络数据包。

请注意,为了使该命令正常工作,您需要先在本地计算机上安装并启动X Window System服务,并且需要授予Wireshark容器访问X11服务的权限。

在docker中安装wireshark:

gpt:

要在Docker中安装Wireshark,您需要执行以下步骤:

1. 启动一个新的Docker容器,在其中运行Wireshark。

   ```
   docker run -it --rm \
     --cap-add=NET_RAW --cap-add=NET_ADMIN \
     wireshark
   ```

2. 在Docker容器内部,使用以下命令安装Wireshark:

   ```
   apt-get update
   apt-get install -y wireshark
   ```

   这将从软件源中下载和安装Wireshark及其依赖项。如果提示您选择默认界面,请选择“否”。

3. 退出Wireshark并重新启动它。您现在应该能够使用Wireshark进行网络分析了。

请注意,在第1步中,我们使用`--cap-add`选项来授予Docker容器特权访问权限,以允许它打开网络接口和捕获数据包。此外,您还需要指定适当的网络配置,以使Docker容器能够访问网桥、路由器或交换机等网络设备。

关于宿主机重启后ovs无法启动的问题

重启前是好的,但ovs启动后报错:

modprobe: FATAL: Module openvswitch not found in directory /lib/modules/5.4.0-144-generic
2023-03-21T12:36:42.901145314Z  * Inserting openvswitch module
2023-03-21T12:36:42.904146408Z rmmod: ERROR: Module bridge is in use by: br_netfilter
2023-03-21T12:36:42.904208283Z  * removing bridge module
2023-03-21T12:36:42.941356440Z  * Starting ovsdb-server
2023-03-21T12:36:42.959730539Z  * Configuring Open vSwitch system IDs
2023-03-21T12:36:42.967010476Z modprobe: FATAL: Module openvswitch not found in directory /lib/modules/5.4.0-144-generic
2023-03-21T12:36:42.967137351Z  * Inserting openvswitch module
2023-03-21T12:36:42.970637674Z rmmod: ERROR: Module bridge is in use by: br_netfilter
2023-03-21T12:36:42.970771756Z  * removing bridge module

折腾了好久

chatgpt:

This error message indicates that the "depmod" command could not find the files "/lib/modules/5.4.0-144-generic/modules.order" and "/lib/modules/5.4.0-144-generic/modules.builtin". These files are typically generated by the "make modules_install" command during the installation of a new kernel.

To fix this issue, you may need to reinstall the kernel modules by running the following commands:

sudo make modules_install

sudo depmod -a

These commands will rebuild the kernel module dependencies and generate the missing files.

之后又报错:make: *** No rule to make target 'modules_install'.  Stop.

gpt:

This error message indicates that the "make" command cannot find a rule to make the "modules_install" target. This target is typically used to install kernel modules after they have been built.

To fix this issue, you may need to run the `make` command with the appropriate target or option for building and installing the kernel modules. For example, you can try running the following commands:

```
make modules
sudo make modules_install
```

The first command will build the kernel modules, and the second command will install them. If you have already built the modules, you can skip the first command and only run the second command.

继续报错:make: *** No rule to make target 'modules'.  Stop.

gpt:

This error message indicates that the "make" command cannot find a rule to make the "modules" target. This target is typically used to build kernel modules.

To fix this issue, you may need to ensure that you are in the correct directory where the kernel source code is located and that you have all the necessary dependencies installed. Once you are in the correct directory, you can try running the following command to build the kernel modules:

```
make -C /lib/modules/$(uname -r)/build M=$(pwd) modules
```

This command will build the kernel modules using the current directory as the source and place the output files in the appropriate module directories. If you still encounter issues, please provide more information about your system and the steps you took before encountering this error.

继续报错:make: *** /lib/modules/5.4.0-144-generic/build: No such file or directory.  Stop.

gpt:

This error message indicates that the "make" command cannot find the directory "/lib/modules/5.4.0-144-generic/build", which is typically a symlink to the directory containing the kernel source code.

To fix this issue, you may need to ensure that you have the correct kernel headers and development files installed. You can try running the following command to install them:

```
sudo apt-get install linux-headers-$(uname -r) build-essential
```

This command will install the kernel headers and development packages for the currently running kernel. Once you have installed these packages, you can try running the make command again.

If you still encounter issues after installing the necessary packages, please ensure that the kernel source code is located in the expected directory. If it is not, you will need to adjust the path in the "make" command accordingly.

执行后/lib/modules/5.4.0-144-generic有了对应文件,但是ovs依然无法启动。

最后看了一眼ovs版本,发现是与系统内核版本不匹配,重装后暂时好了,但是重启之后又不行了。

解决方法:

https://www.cnblogs.com/goldsunshine/p/10331606.html

关于运行ovs-ofctl dump-flows -OOpenflow13 br-sfc没有反应的问题

环境为Linux sff1 5.4.0-144-generic #161~18.04.1-Ubuntu,ovs_version: "2.12.4",distribution-karaf-0.6.0-Carbon

如果使用命令 `ovs-ofctl dump-flows -OOpenflow13 br-sfc` 没有任何输出,可能是因为 OpenFlow 代理(例如 Ryu 或 Floodlight)没有将 OpenFlow 流规则下发到 Open vSwitch(OVS)。请确保您已正确配置 OpenFlow 控制器并实现了所需的流规则。以下是一些常见问题和解决方法:

1. 检查 OVS 和控制器之间的连接是否正常。您可以使用命令 `ovs-vsctl show` 查看 OVS 配置,并查找控制器相关的配置选项。此外,您还可以尝试使用 ping 命令测试连接。

2. 确认控制器支持 OpenFlow 1.3 协议,并已配置正确。您可以查看控制器文档以获取更多信息。请注意,如果控制器不支持 OpenFlow 1.3,则需要将 `-OOpenflow13` 参数替换为适当的版本号。

3. 确认流表中存在适当的流规则。您可以使用命令 `ovs-ofctl dump-flows br-sfc` 查看所有流表规则并检查是否存在所需的规则。

4. 如果使用了 OpenFlow 加密,请确保已正确配置密钥并提供正确的信息以进行解密。

如果以上方法都没有解决问题,请查看 OVS 和控制器的日志以获取更多信息,并尝试重新启动 OVS 和/或控制器。

version negotiation failed (we support version 0x04, peer supports version 0x02 and earlier)

gpt:

这是一个警告消息,指出在尝试连接到名为 "br-sfc" 的 Open vSwitch(OVS)管理通道时,版本协商失败。消息中的 "we support version 0x02, peer supports version 0x01" 表示本地 OVS 支持 OpenFlow 协议版本 1.2,但远程 OVS 支持 OpenFlow 协议版本 1.1。

要解决此问题,您可以执行以下操作之一:

- 降低本地 OVS 支持的 OpenFlow 协议版本以与远程 OVS 兼容。您可以使用命令 `ovs-vsctl set Bridge br-sfc protocols=OpenFlow10,OpenFlow11` 将 "br-sfc" 桥接器的 OpenFlow 协议版本设置为 1.0 和 1.1。

- 升级远程 OVS 版本以支持本地 OVS 支持的 OpenFlow 协议版本。您可以查看远程 OVS 文档以了解如何进行更新或配置其规则以支持新的协议版本。

请注意,在进行任何更改之前,请确保您已正确备份 OVS 配置并了解更改可能带来的风险。

关于ovs netdev_vport|WARN|sff0-dpl: unknown vxlan argument 'nsp'的报错

完整报错

|WARN|sff0-dpl: unknown vxlan argument 'nsp'
sff0-dpl: unknown vxlan argument 'nshc2'
sff0-dpl: unknown vxlan argument 'nshc3'
sff0-dpl: unknown vxlan argument 'nshc4'
sff0-dpl: unknown vxlan argument 'nsi'
sff0-dpl: unknown vxlan argument 'nshc1'

gpt:

这个报错是 OVS 的问题。OVS 中的“netdev_vport”模块尝试使用 VXLAN 端口“sff0-dpl”,但在其配置中找不到一些参数,例如 'nsp'、'nsi'和'nshc'。这可能表示该 VXLAN 端口的配置存在问题或者 OVS 版本不支持这些参数。

建议您检查 OVS 的 VXLAN 端口配置,确认是否正确设置了这些参数值。此外,您可以尝试更新 OVS 版本,以查看是否已修复这些参数的支持。

但是通过ovs-vsctl show 可以看到options: {dst_port="6633", exts=gpe, key=flow, nshc1=flow, nshc2=flow, nshc3=flow, nshc4=flow, nsi=flow, nsp=flow, remote_ip=flow}

gpt:

如果您已经在 OVS 中正确设置了 VXLAN 端口“sff0-dpl”的配置,并在相应的配置中包括了 'nsp'、'nsi'和'nshc' 参数,那么这个报错可能是由于 OVS 版本不支持这些参数引起的。

建议您尝试更新 OVS 版本,以查看是否已修复这些参数的支持。另外,您还可以检查 OVS 发行说明文档,以确认当前版本是否支持这些参数。如果问题仍然存在,可以尝试将这些参数从 VXLAN 配置中删除,以避免这些错误消息的出现。

这是否证明我的ovs不支持nsh?

gpt:

是的,这些错误消息可以表示您使用的 OVS 版本不支持 NSH(Network Service Header)功能。
如果 Open vSwitch (OVS) 不支持 NSH 报文头,那么当 OVS 接收到包含 NSH 报文头的数据包时,它会将其视为普通数据包,并忽略其中的 NSH 头部信息。
这可能会导致 NSH 标识符和元数据等重要信息丢失,从而对网络功能虚拟化(NFV)应用程序的正确性产生负面影响。
因此,在使用 NSH 作为服务链编排协议时,需要确保所选的网络设备都支持 NSH 头部处理。
在流表中看到 NSH 相关信息并不一定意味着交换机支持 NSH。
流表中可能包含 NSH 标识符和元数据等字段,但这并不代表交换机本身已经实现了 NSH 头部的解析和处理功能。
因此,在使用 NSH 作为服务链编排协议时,需要确保所选的网络设备都完全支持 NSH 头部处理,而不是仅仅依靠流表中是否有相应字段来判断。
要检查 Open vSwitch (OVS) 是否支持 NSH(Network Service Header),可以使用以下命令:

ovs-vsctl --version

该命令将显示 OVS 的版本信息。如果 OVS 的版本为 2.6 或更高版本,并且包含 "supports nsh=true" 的文本,那么 OVS 支持 NSH。
此外,您还可以执行以下命令来确认是否加载了 NSH 内核模块:

lsmod | grep nsh

如果输出中包含 nsh 字符串,则 NSH 内核模块已经加载。如果 NSH 内核模块未加载,则需要先加载该模块才能正常支持 NSH 头部。

解决方法

换个支持nsh的ovs

关于使用ovs-ofctl dump-flows br-sfc只显示一条流表的问题

首先在odl安装特性:

opendaylight-user@root>feature:install odl-restconf
opendaylight-user@root>feature:install odl-l2switch-switch-ui
opendaylight-user@root>feature:install odl-openflowplugin-flow-services-ui
opendaylight-user@root>feature:install odl-mdsal-apidocs
opendaylight-user@root>feature:install odl-dluxapps-applications

之后可在web页面看到拓扑结构,节点等信息,而此时上面两项内容都为空。

gpt:

出现 OVS 没有连接到 ODL 控制器的问题可能有多种原因。以下是一些常见的可能原因:

1. ODL 控制器未正确配置:确保 ODL 控制器已正确地配置,并且正在运行与 OVS 相同的协议(如 OpenFlow)。

2. 网络配置问题:OVS 和 ODL 控制器之间的网络连接可能存在问题。检查网络配置,确保 OVS 和 ODL 控制器之间可以相互通信。

3. 防火墙问题:防火墙可能会阻止 OVS 和 ODL 控制器之间的通信。检查防火墙设置,确保允许 OVS 和 ODL 控制器之间的通信。

4. OpenFlow 协议版本不匹配:OVS 和 ODL 控制器使用的 OpenFlow 协议版本可能不匹配。确保 OVS 和 ODL 控制器都支持同一版本的 OpenFlow 协议。

5. OVS 配置错误:OVS 的配置文件可能存在错误。检查配置文件,确保与 ODL 控制器的配置匹配。

这只是一些可能的原因,具体取决于情况。如果以上方法均无法解决问题,您可能需要进一步调试或咨询相关专业人员。

解决方法

在安装OVS相关的组件之后,ODL系统在启动的时候会监听主机的6640端口,这就是用来支持OVSDB的端口(https://blog.csdn.net/huplion/article/details/78481945)。

也有可能是缺少feature,安装此网站中的feature:https://www.bbsmax.com/A/QW5Y3DN3zm/,还有这个:https://www.cnblogs.com/goldsunshine/p/11720310.html,并把本文章里参考参考链接里有关的feature都装一遍(删除所有feature:sudo ./karaf clean

也有可能是ovs版本问题,换个版本。

最后重启了以下odl又重新运行了以下./run_demo.sh解决了。

关于使用官方提供的ovs2.5执行dump-flows看不到nsh信息的问题

在odl web界面里把rsp删除重新建一个就有了

之前:

之后:

root@sff1:/# ovs-ofctl dump-flows -OOpenflow13 br-sfc
OFPST_FLOW reply (OF1.3) (xid=0x2):
 cookie=0x2b00000000000005, duration=562.360s, table=0, n_packets=0, n_bytes=0, priority=100,dl_type=0x88cc actions=CONTROLLER:65535
 cookie=0x2b00000000000005, duration=562.360s, table=0, n_packets=0, n_bytes=0, priority=0 actions=drop
 cookie=0x14, duration=3.735s, table=0, n_packets=0, n_bytes=0, priority=5 actions=goto_table:1
 cookie=0x2b0000000000000b, duration=557.354s, table=0, n_packets=0, n_bytes=0, priority=2,in_port=1 actions=CONTROLLER:65535
 cookie=0x14, duration=3.735s, table=1, n_packets=0, n_bytes=0, priority=250,nsp=110 actions=goto_table:4
 cookie=0x14, duration=3.669s, table=1, n_packets=0, n_bytes=0, priority=250,nsp=8388718 actions=goto_table:4
 cookie=0x14, duration=3.735s, table=1, n_packets=0, n_bytes=0, priority=5 actions=drop
 cookie=0x14, duration=3.734s, table=2, n_packets=0, n_bytes=0, priority=5 actions=goto_table:3
 cookie=0x14, duration=3.734s, table=3, n_packets=0, n_bytes=0, priority=5 actions=goto_table:4
 cookie=0x14, duration=3.735s, table=4, n_packets=0, n_bytes=0, priority=550,nsi=254,nsp=110 actions=load:0xc0a80132->NXM_NX_TUN_IPV4_DST[],goto_table:10
 cookie=0x14, duration=3.735s, table=4, n_packets=0, n_bytes=0, priority=550,nsi=255,nsp=110 actions=load:0xc0a8011e->NXM_NX_TUN_IPV4_DST[],goto_table:10
 cookie=0x14, duration=3.669s, table=4, n_packets=0, n_bytes=0, priority=550,nsi=254,nsp=8388718 actions=load:0xc0a8011e->NXM_NX_TUN_IPV4_DST[],goto_table:10
 cookie=0x14, duration=3.734s, table=4, n_packets=0, n_bytes=0, priority=5 actions=goto_table:10
 cookie=0xba5eba1100000102, duration=3.669s, table=10, n_packets=0, n_bytes=0, priority=660,nsi=253,nsp=8388718,nshc1=0 actions=load:0x4->NXM_NX_TUN_GPE_NP[],IN_PORT
 cookie=0xba5eba1100000101, duration=3.734s, table=10, n_packets=0, n_bytes=0, priority=655,nsi=254,nsp=110,in_port=1 actions=move:NXM_NX_NSH_MDTYPE[]->NXM_NX_NSH_MDTYPE[],move:NXM_NX_NSH_NP[]->NXM_NX_NSH_NP[],move:NXM_NX_NSH_C1[]->NXM_NX_NSH_C1[],move:NXM_NX_NSH_C2[]->NXM_NX_NSH_C2[],move:NXM_NX_NSH_C3[]->NXM_NX_NSH_C3[],move:NXM_NX_NSH_C4[]->NXM_NX_NSH_C4[],move:NXM_NX_TUN_ID[0..31]->NXM_NX_TUN_ID[0..31],load:0x4->NXM_NX_TUN_GPE_NP[],IN_PORT
 cookie=0xba5eba1100000101, duration=3.734s, table=10, n_packets=0, n_bytes=0, priority=655,nsi=255,nsp=110,in_port=1 actions=move:NXM_NX_NSH_MDTYPE[]->NXM_NX_NSH_MDTYPE[],move:NXM_NX_NSH_NP[]->NXM_NX_NSH_NP[],move:NXM_NX_NSH_C1[]->NXM_NX_NSH_C1[],move:NXM_NX_NSH_C2[]->NXM_NX_NSH_C2[],move:NXM_NX_NSH_C3[]->NXM_NX_NSH_C3[],move:NXM_NX_NSH_C4[]->NXM_NX_NSH_C4[],move:NXM_NX_TUN_ID[0..31]->NXM_NX_TUN_ID[0..31],load:0x4->NXM_NX_TUN_GPE_NP[],IN_PORT
 cookie=0xba5eba1100000101, duration=3.669s, table=10, n_packets=0, n_bytes=0, priority=655,nsi=254,nsp=8388718,in_port=1 actions=move:NXM_NX_NSH_MDTYPE[]->NXM_NX_NSH_MDTYPE[],move:NXM_NX_NSH_NP[]->NXM_NX_NSH_NP[],move:NXM_NX_NSH_C1[]->NXM_NX_NSH_C1[],move:NXM_NX_NSH_C2[]->NXM_NX_NSH_C2[],move:NXM_NX_NSH_C3[]->NXM_NX_NSH_C3[],move:NXM_NX_NSH_C4[]->NXM_NX_NSH_C4[],move:NXM_NX_TUN_ID[0..31]->NXM_NX_TUN_ID[0..31],load:0x4->NXM_NX_TUN_GPE_NP[],IN_PORT
 cookie=0xba5eba1100000103, duration=3.669s, table=10, n_packets=0, n_bytes=0, priority=655,nsi=253,nsp=8388718,in_port=1 actions=move:NXM_NX_NSH_MDTYPE[]->NXM_NX_NSH_MDTYPE[],move:NXM_NX_NSH_NP[]->NXM_NX_NSH_NP[],move:NXM_NX_NSI[]->NXM_NX_NSI[],move:NXM_NX_NSP[0..23]->NXM_NX_NSP[0..23],move:NXM_NX_NSH_C1[]->NXM_NX_TUN_IPV4_DST[],move:NXM_NX_NSH_C2[]->NXM_NX_TUN_ID[0..31],load:0x4->NXM_NX_TUN_GPE_NP[],IN_PORT
 cookie=0xba5eba1100000101, duration=3.734s, table=10, n_packets=0, n_bytes=0, priority=650,nsi=254,nsp=110 actions=move:NXM_NX_NSH_MDTYPE[]->NXM_NX_NSH_MDTYPE[],move:NXM_NX_NSH_NP[]->NXM_NX_NSH_NP[],move:NXM_NX_NSH_C1[]->NXM_NX_NSH_C1[],move:NXM_NX_NSH_C2[]->NXM_NX_NSH_C2[],move:NXM_NX_NSH_C3[]->NXM_NX_NSH_C3[],move:NXM_NX_NSH_C4[]->NXM_NX_NSH_C4[],move:NXM_NX_TUN_ID[0..31]->NXM_NX_TUN_ID[0..31],load:0x4->NXM_NX_TUN_GPE_NP[],output:1
 cookie=0xba5eba1100000101, duration=3.734s, table=10, n_packets=0, n_bytes=0, priority=650,nsi=255,nsp=110 actions=move:NXM_NX_NSH_MDTYPE[]->NXM_NX_NSH_MDTYPE[],move:NXM_NX_NSH_NP[]->NXM_NX_NSH_NP[],move:NXM_NX_NSH_C1[]->NXM_NX_NSH_C1[],move:NXM_NX_NSH_C2[]->NXM_NX_NSH_C2[],move:NXM_NX_NSH_C3[]->NXM_NX_NSH_C3[],move:NXM_NX_NSH_C4[]->NXM_NX_NSH_C4[],move:NXM_NX_TUN_ID[0..31]->NXM_NX_TUN_ID[0..31],load:0x4->NXM_NX_TUN_GPE_NP[],output:1
 cookie=0xba5eba1100000101, duration=3.669s, table=10, n_packets=0, n_bytes=0, priority=650,nsi=254,nsp=8388718 actions=move:NXM_NX_NSH_MDTYPE[]->NXM_NX_NSH_MDTYPE[],move:NXM_NX_NSH_NP[]->NXM_NX_NSH_NP[],move:NXM_NX_NSH_C1[]->NXM_NX_NSH_C1[],move:NXM_NX_NSH_C2[]->NXM_NX_NSH_C2[],move:NXM_NX_NSH_C3[]->NXM_NX_NSH_C3[],move:NXM_NX_NSH_C4[]->NXM_NX_NSH_C4[],move:NXM_NX_TUN_ID[0..31]->NXM_NX_TUN_ID[0..31],load:0x4->NXM_NX_TUN_GPE_NP[],output:1
 cookie=0xba5eba1100000103, duration=3.669s, table=10, n_packets=0, n_bytes=0, priority=650,nsi=253,nsp=8388718 actions=move:NXM_NX_NSH_MDTYPE[]->NXM_NX_NSH_MDTYPE[],move:NXM_NX_NSH_NP[]->NXM_NX_NSH_NP[],move:NXM_NX_NSI[]->NXM_NX_NSI[],move:NXM_NX_NSP[0..23]->NXM_NX_NSP[0..23],move:NXM_NX_NSH_C1[]->NXM_NX_TUN_IPV4_DST[],move:NXM_NX_NSH_C2[]->NXM_NX_TUN_ID[0..31],load:0x4->NXM_NX_TUN_GPE_NP[],output:1
 cookie=0x14, duration=3.734s, table=10, n_packets=0, n_bytes=0, priority=5 actions=drop

关于使用高版本OVS执行dump-flows看不到nsh信息的问题

环境:ovs2.9+,odl·distribution-karaf-0.6.0-Carbon

试着换个高版本的odl

odl下载地址

关于ODL WEB 拓扑界面中OVS不连接的问题

没解决

关于在内核版本为3.13.0-031300-generic的Ubuntu上运行npm install bower -g报错的问题

关键词:npm install bower -g

其一:

 npm ERR! Error: CERT_UNTRUSTED

npm ERR!     at SecurePair.<anonymous> (tls.js:1370:32)

npm ERR!     at SecurePair.EventEmitter.emit (events.js:92:17)

npm ERR!     at SecurePair.maybeInitFinished (tls.js:982:10)

npm ERR!     at CleartextStream.read [as _read] (tls.js:469:13)

npm ERR!     at CleartextStream.Readable.read (_stream_readable.js:320:10)

npm ERR!     at EncryptedStream.write [as _write] (tls.js:366:25)

npm ERR!     at doWrite (_stream_writable.js:221:10)

npm ERR!     at writeOrBuffer (_stream_writable.js:211:5)

npm ERR!     at EncryptedStream.Writable.write (_stream_writable.js:180:11)

npm ERR!     at write (_stream_readable.js:583:24)

npm ERR! If you need help, you may report this *entire* log,

npm ERR! including the npm and node versions, at:

npm ERR!     <http://github.com/isaacs/npm/issues&gt;

npm ERR! System Linux 3.10.0-1127.18.2.el7.x86_64

npm ERR! command "/usr/local/node/0.10.24/bin/node" "/usr/local/node/0.10.24/bin/npm" "install" "bower" "-g"

npm ERR! cwd /www/wwwroot/yuyue.fxzbcn.com/fastadmin

npm ERR! node -v v0.10.24

npm ERR! npm -v 1.3.21

npm ERR! 

npm ERR! Additional logging details can be found in:

npm ERR!     /www/wwwroot/yuyue.fxzbcn.com/fastadmin/npm-debug.log

npm ERR! not ok code 0 
 解决办法(https://www.dianthink.com/detail/606.html):
ssl验证问题,使用下面的命令取消ssl验证即可解决
npm config set strict-ssl false 
其二:
Error: connect ECONNREFUSED
npm ERR!     at errnoException (net.js:901:11)
npm ERR!     at Object.afterConnect [as oncomplete] (net.js:892:19)
npm ERR!  { [Error: connect ECONNREFUSED]
npm ERR!   code: 'ECONNREFUSED',
npm ERR!   errno: 'ECONNREFUSED',
npm ERR!   syscall: 'connect' }
npm ERR! 
npm ERR! If you are behind a proxy, please make sure that the
npm ERR! 'proxy' config is set properly.  See: 'npm help config'

npm ERR! System Linux 3.13.0-031300-generic
npm ERR! command "/usr/bin/nodejs" "/usr/bin/npm" "install" "bower" "-g"
npm ERR! cwd /home/sk/sfc-release-beryllium-sr4
npm ERR! node -v v0.10.25
npm ERR! npm -v 1.3.10
npm ERR! syscall connect
npm ERR! code ECONNREFUSED
npm ERR! errno ECONNREFUSED
npm ERR! stack Error: connect ECONNREFUSED
npm ERR! stack     at errnoException (net.js:901:11)
npm ERR! stack     at Object.afterConnect [as oncomplete] (net.js:892:19)
npm ERR! 
npm ERR! Additional logging details can be found in:
npm ERR!     /home/sk/sfc-release-beryllium-sr4/npm-debug.log
npm ERR! not ok code 0

gpt:

这是一个 npm 安装 bower 工具时的错误信息。错误代码为 ECONNREFUSED,表示连接被拒绝,可能是由于网络或代理问题导致的。

要解决这个问题,可以尝试检查网络连接是否正常、代理配置是否正确等。如果使用代理,请确保npm中的'proxy'设置正确,并参考npm文档进行配置。

另外,该日志文件还包含了更多的调试信息,可以查看 /home/sk/sfc-release-beryllium-sr4/npm-debug.log 文件以获取更详细的信息。

https://blog.csdn.net/lt012345/article/details/123934719

换成淘宝镜像源

https://blog.csdn.net/weixin_46474841/article/details/124430496

其三:

npm ERR! Error: EACCES, mkdir '/usr/local/lib/node_modules'
npm ERR!  { [Error: EACCES, mkdir '/usr/local/lib/node_modules']
npm ERR!   errno: 3,
npm ERR!   code: 'EACCES',
npm ERR!   path: '/usr/local/lib/node_modules',
npm ERR!   fstream_type: 'Directory',
npm ERR!   fstream_path: '/usr/local/lib/node_modules/bower',
npm ERR!   fstream_class: 'DirWriter',
npm ERR!   fstream_stack: 
npm ERR!    [ '/usr/lib/nodejs/fstream/lib/writer.js:171:23',
npm ERR!      '/usr/lib/nodejs/mkdirp/index.js:37:53',
npm ERR!      'Object.oncomplete (fs.js:107:15)' ] }
npm ERR! 
npm ERR! Please try running this command again as root/Administrator.

npm ERR! System Linux 3.13.0-031300-generic
npm ERR! command "/usr/bin/nodejs" "/usr/bin/npm" "install" "bower" "-g"
npm ERR! cwd /home/sk/sfc-release-beryllium-sr4
npm ERR! node -v v0.10.25
npm ERR! npm -v 1.3.10
npm ERR! path /usr/local/lib/node_modules
npm ERR! fstream_path /usr/local/lib/node_modules/bower
npm ERR! fstream_type Directory
npm ERR! fstream_class DirWriter
npm ERR! code EACCES
npm ERR! errno 3
npm ERR! stack Error: EACCES, mkdir '/usr/local/lib/node_modules'
npm ERR! fstream_stack /usr/lib/nodejs/fstream/lib/writer.js:171:23
npm ERR! fstream_stack /usr/lib/nodejs/mkdirp/index.js:37:53
npm ERR! fstream_stack Object.oncomplete (fs.js:107:15)
npm ERR! Error: EACCES, open 'npm-debug.log'
npm ERR!  { [Error: EACCES, open 'npm-debug.log'] errno: 3, code: 'EACCES', path: 'npm-debug.log' }
npm ERR! 
npm ERR! Please try running this command again as root/Administrator.

npm ERR! System Linux 3.13.0-031300-generic
npm ERR! command "/usr/bin/nodejs" "/usr/bin/npm" "install" "bower" "-g"
npm ERR! cwd /home/sk/sfc-release-beryllium-sr4
npm ERR! node -v v0.10.25
npm ERR! npm -v 1.3.10
npm ERR! path npm-debug.log
npm ERR! code EACCES
npm ERR! errno 3
npm ERR! stack Error: EACCES, open 'npm-debug.log'
npm ERR! 
npm ERR! Additional logging details can be found in:
npm ERR!     /home/sk/sfc-release-beryllium-sr4/npm-debug.log
npm ERR! not ok code 0
sk@ubuntu:~/sfc-release-beryllium-sr4$ su root
Password: 
root@ubuntu:/home/sk/sfc-release-beryllium-sr4# npm install vower -g
npm http GET https://registry.npm.taobao.org/vower

切换到root用户执行安装命令

jixubaocuo bower install 的wenti

https://www.cnblogs.com/Amagasaki/p/5518019.html

由于bower是在root用户下完成安装的,所以执行mvn clean install -DskipTests时要切换到root用户,zhi qian jiao cheng li yi zhi dou shi zai root xia jin xing的,mei kan qing。

dan huan shi mei you jie jue ,you yu sfc-ui module shi fei bi xuan bian yi xiang,(from readme),suo yi xiu gai pom.xml xu xiao bian yi gai module.

gpt:

Bower 是一个 Web 前端包管理器,用于方便地安装、更新和管理前端依赖库(如 JavaScript 库、CSS 框架、字体等)。它基于 Node.js 和 Git 实现,可以从多个源下载前端包,并提供了简单的命令行接口。Bower 可以与 Grunt 、Gulp 、Yeoman 等构建工具配合使用,以便自动化构建和任务管理。

Bower 的主要特点包括:

- 支持多种源和协议,可以从 Git 仓库、GitHub、Bower Registry、URL 等地方获取包。
- 提供简单的命令行接口,可以方便地查找、安装、更新和删除包。
- 允许使用配置文件指定依赖关系和版本范围,以及指定本地和远程包的路径、代理和缓存等选项。
- 支持钩子机制,可以在安装和更新包时执行自定义脚本。
- 可以与其他构建工具(如 Grunt 和 Gulp)无缝集成,方便进行自动化构建和部署。

总之,Bower 可以帮助开发人员更轻松地管理前端依赖库,提高生产效率。

关于OVS nsh-v8分支执行start_ovs.sh报错的问题

修改cd ovs为cd ~/ovs

Ubuntu 14.04 下解决maven访问速度慢问题

关键词:maven下载慢

https://www.shuzhiduo.com/A/kjdwWOYOdN/

关于VMware传输 (VMDB)错误14: Pipe connection has been broken的解决方法

https://blog.csdn.net/weixin_42596182/article/details/118354915

之后又报错

VMware Workstation 不可恢复错误: (mks)

ISBRendererComm: Lost connection to mksSandbox (2878)

日志文件位于“\vm\vmware.log”中。  

您可以请求支持。  

要收集数据提交给 VMware 技术支持,请选择“帮助”菜单中的“收集支持数据”。

也可以直接在 Workstation 文件夹中运行“vm-support”脚本。

我们将根据您的技术支持权利做出回应。

解决方法:

https://blog.csdn.net/Dark_Volcano/article/details/128658228

https://blog.51cto.com/u_9843231/6036748

然而都失败了

关于直接在windows中把Ubuntu所在磁盘格式化后启动计算机出现grub的问题

gpt:

当计算机启动时出现GRUB提示,表示引导程序无法找到有效的操作系统。这通常是由于磁盘格式化或分区调整等更改造成的。

如果您已经格式化了第二个系统所在的磁盘,建议使用Boot-Repair工具修复GRUB引导程序。您可以使用Live CD或USB启动计算机,然后按照官方文档中的说明安装和运行该工具。boot-repair会自动检测并修复GRUB引导程序,使其能够正确引导您的操作系统。

如果不想看到grub,可以直接:

此处因该有张图片

关于windows中安装vagrant报错:vagrant setup 无法打开指定的设备或文件

命令行里以管理员身份运行msi文件:https://www.dtidc.com/help/article/120.html

关于Ubuntu14下风扇一直高速旋转的方法

https://blog.csdn.net/hfyutdg/article/details/83957130

关于运行sudo ./karaf 卡主不动 日志报错Error resolving artifactorg.ops4j.pax.web:pax-web-features:xml的问题

查看日志得到完整报错,看上去是访问了只能用https访问的链接用来下载feature

Error getting feature for feature string odl-sfc-ui
java.io.IOException: Error resolving artifact org.ops4j.pax.web:pax-web-features:xml:features:3.1.4: Could not transfer artifact org.ops4j.pax.web:pax-web-features:xml:features:3.1.4 from/to central (http://repo1.maven.org/maven2/): Failed to transfer file: http://repo1.maven.org/maven2/org/ops4j/pax/web/pax-web-features/3.1.4/pax-web-features-3.1.4-features.xml.

访问了https://repo1.maven.org/maven2/org/ops4j/pax/web/pax-web-features/3.1.4/pax-web-features-3.1.4-features.xml竟然好了,不过没有解决根源问题,而且进不来odl web页面,可以试着找到他的本地下载链接报http改为https

通过搜索(/发现有两个文件包含该内容

sfc-release-beryllium-sr4/sfc-karaf/target/assembly/etc/org.ops4j.pax.url.mvn.cfg

sfc-release-beryllium-sr4/sfc-karaf/target/assembly/system/org/opendaylight/controller/commons.thirdparty/1.1.0/commons.thirdparty-1.1.0.pom

在这两个文件中修改为https://repo1.maven.org/xxxx

并重新编译sfc-karaf

然而并没有用,思路应该是对的,应该是没改对文件,于是直接执行 ./karaf clean 并下载特性

ubuntu怎么样修改只读文件:https://zhidao.baidu.com/question/370596653326446292.html

关于ubuntu14切换内核3.13分辨率无法调整的问题

关键词:分辨率 3.13

https://blog.csdn.net/zixiximm/article/details/53781421

然而并没有什么用,千万不要改,将就看

关于sudo:java: command not found的问题

关键词 :sudo:java: command not found

sudo Java:command not found的分析:events.jianshu.io/p/1087986364b7

sfc构建报错ould not resolve dependencies for project org.opendaylight.sfc:sfc-netconf:bundle:0.2.4-Beryllium-SR4

Failed to execute goal on project sfc-netconf: Could not resolve dependencies for project org.opendaylight.sfc:sfc-netconf:bundle:0.2.4-Beryllium-SR4: Failed to collect dependencies at org.opendaylight.netconf:sal-netconf-connector:jar:1.3.4-Beryllium-SR4: Failed to read artifact descriptor for org.opendaylight.netconf:sal-netconf-connector:jar:1.3.4-Beryllium-SR4: The following artifacts could not be resolved: org.opendaylight.netconf:netconf-parent:pom:1.0.4-Beryllium-SR4 (absent): Could not transfer artifact org.opendaylight.netconf:netconf-parent:pom:1.0.4-Beryllium-SR4 from/to alimaven (http://maven.aliyun.com/nexus/content/repositories/central/): Connection reset -> [Help 1]

下载Opendaylight官网提供的settings.xml并保存在当前用户目录:

root@ubuntu:/home/odl/sfc-oxygen# wget -q -O - https://raw.githubusercontent.com/opendaylight/odlparent/master/settings.xml > ~/.m2/settings.xml

关于使用ovs-ofct dump-flows br-sfc报错:ovs-ofctl: br-sfc: failed to connect to socket (Broken pipe)的问题

环境:Linux sff1 4.2.8-040208-generic #201512150620 SMP Tue Dec 15 06:22:17 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux;
查看日志发现是openvswitch没有加载到容器中的内核,下载与宿主机相同的内核并安装,然后重启ovs

但是还是不行,产看日志后有报错:FATAL: Could not load /lib/modules/4.4.154/modules.dep: No such file or directory 

 depmod -a

https://www.iteye.com/blog/laomn-2439337

关于把物理为网卡eth0添加到br-sfc网络不可达的问题

过程:

ovs-vsctl show
ifconfig eth0 0
#之后就ping不通了
ifconfig br-sfc 192.168.1.20
route add default gw 192.168.1.5

ovs-vsctl add-port br-sfc eth0

之后执行ping操作会报Destination Host Unreachable,

gpt:

物理网卡 eth0 连接到 OVS 网桥 br-sfc 后,如果其他主机无法 ping 通该 OVS 所在的主机,可能有以下原因:

1. 防火墙配置问题:检查 OVS 所在主机的防火墙配置,确保 ICMP 报文(ping)被允许通过。可以使用 iptables 或 firewalld 等工具来管理防火墙规则。

2. 网络拓扑问题:检查网络拓扑结构,确保主机和其他设备都正确连接到同一交换机或路由器,并处于同一 IP 子网中。

3. OVS 配置问题:检查 OVS 的配置文件,确保物理端口 eth0 已经成功添加到 br-sfc 网桥,并且没有其他配置错误。可以使用 ovs-vsctl 命令来管理 OVS 网桥的配置。

4. IP 地址冲突问题:检查 OVS 所在主机和其他设备的 IP 地址是否存在冲突,这可能会导致网络故障。

您可以通过一下几种方式来进一步排查问题:

1. 在 OVS 所在的主机上,执行 "ifconfig" 命令,检查其 IP 地址、子网掩码和其他网络接口配置信息是否正确。

2. 在 OVS 所在的主机上,执行 "ovs-vsctl show" 命令,检查 br-sfc 网桥的配置信息是否正确,以及 eth0 物理端口是否成功添加到网桥中。

3. 在其他主机上,执行 "ping" 命令,检查目标 IP 地址是否正确,并检查 ICMP 报文是否能够到达 OVS 所在的主机。如果 ping 不通,则可以使用 traceroute 命令来检查路由路径和网络拓扑。

4. 在 OVS 所在主机上,执行 "tcpdump" 命令,检查是否收到来自其他主机的 ICMP 报文。如果没有收到,则可能是网络拓扑问题或防火墙配置问题导致 ICMP 报文被阻止。

通过抓取本机的数据包tcpdump -i <ovs_port> -w ovs_traffic.pcap发现了arp数据包,目的地是网关192.168.1.5,但是sender mac是br-sfc的

gpt:

如果 OVS 所在的主机收到了 ARP 数据包,但是没有回应,可能有以下原因:

1. 防火墙配置问题:检查 OVS 所在主机的防火墙配置,确保 ARP 报文被允许通过。可以使用 iptables 或 firewalld 等工具来管理防火墙规则。

2. 网络拓扑问题:检查网络拓扑结构,确保主机和其他设备都正确连接到同一交换机或路由器,并处于同一 IP 子网中。

3. IP 地址冲突问题:检查 OVS 所在主机和其他设备的 IP 地址是否存在冲突,这可能会导致 ARP 请求失败。

4. OVS 配置问题:检查 OVS 的配置文件,确保其与网络拓扑相匹配,并且没有其他配置错误。可以使用 ovs-vsctl 命令来管理 OVS 网桥的配置。

5. ARP 缓存问题:如果之前已经进行过 ARP 请求并获取了目标主机的 MAC 地址,则 OVS 可能会缓存该信息以提高性能。在这种情况下,即使收到 ARP 请求,OVS 也不会发送 ARP 响应,而是直接从缓存中获取目标主机的 MAC 地址进行通信。

您可以通过以下方式来进一步排查此问题:

1. 在 OVS 所在主机上,执行 "tcpdump" 命令,检查是否收到了 ARP 请求和响应。如果只收到请求而没有响应,则可能是网络拓扑或防火墙配置问题。如果都没有收到,则可能是配置问题或硬件故障。

2. 在 OVS 所在主机上,执行 "arp -a" 命令,检查其 ARP 缓存中是否已经缓存了目标主机的 MAC 地址。如果存在,则说明 OVS 已经成功获取了目标主机的 MAC 地址,并且不会发送 ARP 响应。

3. 在其他主机上,使用 "arping" 命令向目标主机发送 ARP 请求,并观察 OVS 所在主机是否能够正确响应。如果响应了,则说明 OVS 配置正确,并且可以处理 ARP 请求和响应。

通过在别的主机h2上执行arp -a,输出如下:

sk-G501VW (192.168.1.5) at 02:42:e7:07:95:1a [ether] on eth0
sff1.sfc103_sfc103_mgmt (192.168.1.20) at 02:42:c0:a8:01:14 [ether] on eth0
sf1.sfc103_sfc103_mgmt (192.168.1.30) at 02:42:c0:a8:01:1e [ether] on eth0

显然问题出在arp,mac地址没有更新

gpt:

要清除 ARP 缓存,可以使用以下命令:

1. 在 Linux 上,可以使用 "ip" 命令来清除 ARP 缓存。具体命令如下:

   ```
   sudo ip neigh flush all
   ```

2. 在 Windows 上,可以使用 "arp" 命令来清除 ARP 缓存。具体命令如下:

   ```
   arp -d *
   ```

以上命令将会清空系统中所有的 ARP 缓存记录。

请注意,清除 ARP 缓存可能会导致一些网络连接出现短暂的中断,因为系统需要重新获取目标设备的 MAC 地址。在执行此操作之前,请先确认该操作不会影响生产环境中的服务和应用程序。

一顿操作后清除网关arp缓存和h2的缓存,之后让他们相互ping,可以ping通,但是清除h1和网关的缓存,依然无法ping通

手动设置mac地址依然无法ping通

尝试解决:

首先修改stat.sh,只启动ovs,其他操作都先注释,之后重新构建镜像

之后使用docker-compose down删除容器,之后docker-compose up -d 重启容器

ping一下看看

看一看到先有arp后有icmp,那么这时意味着mac地址已被学习,重新构建容器,执行添加网卡指令,之后ping并tcpdump -i <ovs_port> -w ovs_traffic.pcap 抓包,然而还是不通。

之后在h1上抓包,同时h1,h2互ping,h1的抓包结果为:

怀疑h1拓扑出了问题,脱离了局域网。

参考docker+ovs,原来是如此简单:https://www.modb.pro/db/146901的流程,将docker容器中的eth0网卡开启混杂模式ifconfig enp0s3 promisc(https://zhuanlan.zhihu.com/p/417136223)再绑到ovs上后,其他主机可以ping通,折腾了好久,泪目

参考资料:

  • OpenvSwitch系列之五 网桥特性功能配置:https://www.cnblogs.com/goldsunshine/p/11946098.html 
  • ovs安装与第一个bridge创建:https://cloud.tencent.com/developer/article/1334611
  • Docker之OVS网络:https://www.bbsmax.com/A/A7zgNNand4/
    • ip link set dev br0 up 和 ifconfig br0 up 有啥区别?
    • gpt:
`ip link set dev br0 up`和`ifconfig br0 up`都是启动Linux系统中的网络接口,但是它们之间存在一些区别。

1. 命令格式不同:`ip link set dev br0 up`命令使用iproute2工具,而`ifconfig br0 up`命令使用传统的ifconfig工具。iproute2工具是ifconfig的替代品,并且在新版本的Linux系统中更为常见。

2. 参数选项不同:`ip link set dev br0 up`命令只需要指定接口名称即可,而`ifconfig br0 up`命令则需要同时指定IP地址、子网掩码等参数,或者使用dhcp客户端自动获取IP地址。

3. 安全性和易用性:由于ifconfig命令已经过时,因此使用iproute2工具可以提高系统的安全性和易用性,如果可能的话,最好使用`ip link set dev br0 up`这样的新命令。

在实际使用中,如果只需要启动网络接口,那么两个命令的效果是相同的,都能够将指定的接口设置为启动状态。但是如果需要对其他网络接口参数进行配置,则推荐使用`ip link`等iproute2工具来完成。
  • docker+ovs,原来是如此简单:https://www.modb.pro/db/146901
  • Docker容器受控于SDN网络(正确的ovs-docker下载路径):https://www.likecs.com/show-308563447.html

关于ovs+docker实验环境的搭建

关键词:ovs安装

照着下面的资料搭环境docker容器一直互相ping不通,怀疑是ovs的问题,因为一直装的都是从sfc103官方虚拟机里拷出来的ovs2.5.9.deb安装包,从来没有怀疑过他的可用性

  • 环境搭建(都差不多)
    • 过OVS实现Docker容器通信(ubuntu20.04,ovs2.13.1):https://blog.csdn.net/qq_37579106/article/details/116400729
    • Docker+Ovs构建SDN网络(添加了ryu控制器):

      https://blog.csdn.net/weixin_40042248/article/details/120390840
    • docker run -it --name host1 --net none ymumu/ryu:0.1 /bin/bash
      docker run -it --name host2 --net none ymumu/ryu:0.1 /bin/bash
      
      ovs-vsctl add-br ovs
      wget http://github.com/openvswitch/ovs/raw/master/utilities/ovs-docker
      chmod a+x ovs-docker
      
      ovs-docker add-port ovs eth0-ovs host1 --ipaddress=10.0.1.2/24 --gateway=10.0.1.1
      ovs-docker add-port ovs eth0-ovs host2 --ipaddress=10.0.1.3/24 --gateway=10.0.1.1
    • docker+ovs,原来是如此简单:https://www.modb.pro/db/146901
    • cd usr/bin
      wget https://raw.githubusercontent.com/openvswitch/ovs/master/utilities/ovs-docker
      chmod a+rwx ovs-docker
      
      ovs-vsctl add-br br0
      docker run -it --net=none --privileged=true --name=h1 busybox
      docker run -it --net=none --privileged=true --name=h2 busybox
      
      ovs-docker add-port br0 eth0 h1
      ovs-docker add-port br0 eth0 h2
      
      ifconfig eth0 192.168.1.2
      ifconfig eth0 192.168.1.3

gpt:

Open vSwitch (OVS) 是一款开源的虚拟交换机软件,它可以在虚拟化环境中实现软件定义网络(SDN)和网络功能虚拟化(NFV)。其工作原理是通过将物理或虚拟主机连接到不同的 OVS 端口,从而创建虚拟网络。OVS 通过使用 OpenFlow 协议来管理流量转发,并且支持多种虚拟化技术,如 VXLAN、GRE 和 VLAN。

openvswitch.ko 是 OVS 的内核模块,负责在 Linux 内核空间中实现 OVS 的核心功能,包括数据包处理、流表匹配、隧道封装和解封装等。该模块与用户态的 ovs-vswitchd 进程协同工作,提供了完整的 OVS 功能。

因为之前了解了ovs的工作原理,遂去检查了一下openvswitch.ko是否被正常加载(linux 怎么查看内核里加载的模块:https://www.656463.com/wenda/linuxzmcknhljzdmk_80)

但是没有找到openvswitch.ko,那就装个新的ovs。

使用编译安装后可以ping通,流表也有计数(泪目,官方害人不浅)

之后将虚拟机的网卡设为混杂模式,并添加到ovs的网桥(具体过程见networkCardToOVSBeidge),之后更新arp表,即可实现宿主机与虚拟机的通信。

参考资料:

  • Docker启动常用容器命令及配置说明:https://blog.csdn.net/weixin_45698637/article/details/124213429
    • 进入正在执行的容器:docker attach 容器id
  • dpkg卸载deb包:https://www.bbsmax.com/A/rV57j3BWJP/

  • virtualbox虚拟机ubuntu安装出现的问题(增强功能,截图到剪切板,共享文件夹):https://zhuanlan.zhihu.com/p/492659609

  • 说不定有用的:
  • ovs安装:
    • OVS安装配置时出现configure: error:……,version newer than 5.0.x is not supported:https://blog.csdn.net/weixin_44260459/article/details/123727463
    • Open vSwitch安装及配置:https://www.cnblogs.com/goldsunshine/p/10331606.html
    • 编译Linux内核时出现“code model kernel does not support PIC mode”的解决方法(makefile在build文件夹里):https://blog.csdn.net/qq_44933518/article/details/105881723

    • Ubuntu下安装部署openvswitch和一些安装的异常处理(ovs安装)

关于ovs2.9+执行/sbin/lsmod | grep openvswitch只有两行输出的问题

环境:ovs2.9+,ubuntu内核4.2.8-040208-generic

我原版内核为4.15.0-208-generic,使用/sbin/lsmod | grep openvswitch有多行输出:

但是切换到4.2.8-040208-generic就不行了,搞不懂为啥

关于virtualbox切换内核后增强功能无法工作的问题

关键字:增强功能 virtualbox

照着https://zhuanlan.zhihu.com/p/492659609排错时执行 ./vboxadd setup时会报错,根据报错执行相应命令即可

关于虚拟机可以ping通宿主机,反过来不行的问题

关键词:宿主机ping不通虚拟机

参考资料:

网站里的方法没用就进一步改系统文件,按自己的需求改

vi /etc/network/interfaces

auto eth0
iface eth0 inet static
address 10.102.215.155
netmask 255.255.240.0
gateway 10.102.223.255

关于执行docker相关命令报错Get http:///var/run/docker.sock/v1.17/version: dial unix /var/run/docker.sock的问题

解决方法:

Get http:///var/run/docker.sock/v1.17/version: dial unix /var/run/docker.sock

service docker restart

关于ubuntu14中docker的一些问题

安装

下面这三个链接都尝试了一下,最后就装上了

参考资料:

拉取镜像报错410

docker pull ubuntu
Pulling repository ubuntu
FATA[0004] Error: Status 410 trying to pull repository library/ubuntu: "<html>\r\n<head><title>410 Gone</title></head>\r\n<body>\r\n<center><h1>410 Gone</h1></center>\r\n<hr><center>openresty</center>\r\n</body>\r\n</html>\r\n" 

碰到了两次

第一次的参考资料 ,加了镜像就行,后面的不用执行

第二次gpt:

这个错误的原因可能是 Docker Hub 上的 `library/ubuntu` 镜像已经被删除或不再可用。

建议尝试重新执行命令,或者使用其他可用的 Ubuntu 镜像。例如,您可以尝试使用 `ubuntu:latest` 或其他指定版本的镜像,如 `ubuntu:20.04`。另外,您也可以尝试使用其他的镜像仓库,如 Aliyun Container Registry(ACR)等。

docker: 'network' is not a docker command

升级失败

关于odl中的data plane locator

gpt:

在 OpenDaylight SFC 中,Data Plane Locator(DPL)的作用是定义服务功能链路中各个组成部分的接口,并为其分配唯一的标识符。具体而言,DPL 用于标识和分配每个服务功能(SF)和服务功能节点(SFF)的接口,并确定输入和输出接口在服务功能链中的位置。
当您创建 SF 和 SFF 时,需要填写 DPL 的信息,包括以下参数:

Data Plane Locator Type(DPL 类型):用于指定 DPL 的类型,通常有 VXLAN GPE 和 GRE 等选项。这个类型必须与您在网络中实际使用的数据平面技术相匹配。
Name(名称):用于标识服务功能或服务功能节点的名称。这个名称应该是唯一的,并且必须在整个服务功能链中进行唯一标识。
IP(IP 地址):用于标识服务功能或服务功能节点的 IP 地址。
Port(端口号):用于标识服务功能或服务功能节点的端口号,通常是 VxLAN 或 GRE 网络隧道的端口号。

在 OpenDaylight 中, SF 和 SFF 之间的数据流经过 DPL 配置的接口。因此,在 SF 和 SFF 创建时,需要正确地填写 DPL 的信息来确保在服务功能链中位置正确,以及输入和输出的接口都能够正确地识别。
要回答您的第二个问题,“SF 和 SFF 创建时,填写 DPL 信息的区别是什么?” ,答案是,SF 和 SFF 在创建时需要填写 DPL 的信息,但填写的信息的含义不太相同。当创建 SF 时,需要指定其接口的 DPL 信息,以确保 SF 能够使用正确的接口来接收和转发数据流。而创建 SFF 时,需要定义 SFF 在服务功能链中的位置和接口,以确保数据能够正确地在服务功能链上流动。
总之,Data Plane Locator 在 OpenDaylight SFC 中是一个重要的组件,它用于定义服务功能链路中各个组成部分的接口和位置。在创建 SF 和 SFF 时,正确地填写 DPL 的信息至关重要,这样可以确保 SF 和 SFF 能够正确地识别输入和输出端口,并且数据能够在服务功能链上正确流动。
是的,当您在创建 SF 时指定了一个 Data Plane Locator(DPL),创建 SFF 时,需要选择相同的 DPL。
这是因为服务功能节点(SFF)的接口必须与服务功能(SF)的接口匹配,以便数据流能够正确地在服务功能链中流动。在 OpenDaylight SFC 中,服务功能链是由 SFF 组成的,每个 SFF 可以与多个 SF 进行连接,并且在这些连接点上,需要有相同的 DPL。
在创建 SFF 时,可以选择与 SF 中使用的相同 DPL,也可以创建一个新的 DPL。如果您要选择新的 DPL,确保选择与 SF 中使用的 DPL 兼容的数据平面技术,这样可以确保服务功能链上的数据流正确流动。
总之,在创建 SF 和 SFF 时,需要正确地指定 DPL 信息,并确保它们相互匹配,以确保数据在服务功能链中正确地流动。

在docker中安装sf可以正常工作

首先下载装有sf的镜像,之后修改/sfc/sfc-demo/sfc103中的docker-compose.yml文件,将sf的image替换为下载的镜像的REPOSITORY(使用sudo docker images查看) ,最后运行run_demo.sh 重新构建sfc。

进入到sf容器之后按需执行/sfc/sfc-demo/sfc103的DockerFile中RUN后面的指令

必装软件

RUN apt-get update  \
    && apt-get remove --auto-remove python2.7 \
    && apt-get purge --auto-remove python2.7 \
    && apt-get autoclean python2.7  \
    && rm -rf /usr/lib/python2.7

RUN apt-get install -y git libtool m4 autoconf automake make \
    libssl-dev libcap-ng-dev python3 python-six vlan iptables wget \
    net-tools init-system-helpers kmod uuid-runtime iputils-ping \
    gcc zlib* python3-dev build-essential apt-utils  libffi-dev tcpdump vim iproute2

关于手动执行sfc_agent但未启动的问题

只需跟着报错修改源码即可

参考资料

firewall

防火墙主要是借助硬件和软件的作用于内部和外部网络的环境间产生一种保护的屏障,从而实现对计算机不安全网络因素的阻断。只有在防火墙同意情况下,用户才能够进入计算机内,如果不同意就会被阻挡于外,防火墙技术的警报功能十分强大,在外部的用户要进入到计算机内时,防火墙就会迅速的发出相应的警报,并提醒用户的行为,并进行自我的判断来决定是否允许外部的用户进入到内部,只要是在网络环境内的用户,这种防火墙都能够进行有效的查询,同时把查到信息朝用户进行显示,然后用户需要按照自身需要对防火墙实施相应设置,对不允许的用户行为进行阻断。通过防火墙还能够对信息数据的流量实施有效查看,并且还能够对数据信息的上传和下载速度进行掌握,便于用户对计算机使用的情况具有良好的控制判断,计算机的内部情况也可以通过这种防火墙进行查看,还具有启动与关闭程序的功能,而计算机系统的内部中具有的日志功能,其实也是防火墙对计算机的内部系统实时安全情况与每日流量情况进行的总结和整理。

创建命令

docker run -it --net=none --privileged=true --name=h4 firewall bash

输出日志

由于docker使用的时宿主机的内核,而iptables的日志是由内核记录的,所以只能在宿主机中找到日志,但是该日志是和其他日志混在了一起

需要更换日志保存位置(两个都试了一下才成功)

测试

记录所有日志

# 记录所有通过防火墙的日志
iptables -A INPUT -j LOG --log-prefix "[firewall]" 
iptables -A OUTPUT -j LOG --log-prefix "[firewall]" 
iptables -t mangle -A POSTROUTING -j LOG --log-prefix "[firewall]" --log-level debug

参考资料

proxy

负载均衡

负载均衡建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。
负载均衡(Load Balance)其意思就是分摊到多个操作单元上进行执行,例如Web服务器FTP服务器企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。

获取镜像

docker pull haproxy

参考资料

DNS

域名系统(英文:Domain Name System,缩写DNS)是互联网的一项服务。它作为将域名IP地址相互映射的一个分布式数据库,能够使人更方便地访问互联网。

参考资料

  • Linux版本之docker容器bind9搭建DNS服务器和配置域名使用:https://blog.csdn.net/qq_30442207/article/details/114971723
  • docker pull ubuntu/bind9

DPI

深度数据包检测(英语:Deep packet inspection,缩写为 DPI),又称完全数据包探测(complete packet inspection)或信息萃取(Information eXtraction,IX),是一种计算机网络数据包过滤技术,用来检查通过检测点之数据包数据部分(亦可能包含其标头),以搜索不匹配规范之协议、病毒垃圾邮件、入侵,或以预定之准则来决定数据包是否可通过或需被路由至其他不同目的地,亦或是为了收集统计数据之目的。IP数据包有许多个标头;正常运作下,网络设备只需要使用第一个标头(IP标头),而使用到第二个标头(TCPUDP等)则通常会与深度数据包检测相对,而被称之为浅度数据包检测(一般称为状态数据包检测)。

获取镜像

docker pull mangalaman93/ndpi

启动&日志获取

ndpiReader -i eth0  -v 2 -w ndpi.log -s 10

从容器中获取日志

ndpiReader强制结束后没有日志,需要使用自动停止,如果没有停止则不会生成日志,因此需要使用python中的docker模块检测有没有生成日志,且需要python3.6+环境,并会出现_ssl模块找不到

参考资料

IPS

Snort 是一个开源入侵防御系统(IPS)。Snort IPS 使用一系列规则来帮助定义恶意网络活动,并利用这些规则来查找与之匹配的数据包,并为用户生成警报。  Snort 也可以在线部署来阻止这些数据包。Snort 有三个主要用途。作为一个像 tcpdump 一样的数据包嗅探器,作为一个数据包记录器 -- 这对网络流量调试很有用,或者它可以作为一个完整的网络入侵防御系统。Snort 可以被下载和配置为个人和企业使用。

jaelkw/snort-app 用不了,创建不了容器

opennsm/snort apt-get install 报错

glanf/snort apt-get install 报错

linton/snort-base 可以用

ciscotalos/snort3 可以用,但资料少,不会输出日志

收到很多Bad Chk Sum的包,导致直接丢弃,没有日志,原因是:应用收包时,网卡会对udp头的checksum进行检查,当udp头的checksum不正确时,该包可能会被应用丢弃。开始认为是网卡丢包了,排查之后不是,那就是snort的问题,取消检测即可。

如何使用

二改后的镜像创建容器:sudo docker run -d -t -v snort2 snort2(镜像名) bash

配置参考,使用snort -v -c /opt/snort.conf -i eth0 -l /logs/ -k none启动

结束进程:kill -9 $(pgrep snort)

gpt:

要自动获取Snort进程的PID并使用kill -9命令结束它,你可以使用pgrep命令获取Snort进程的PID。pgrep命令可以根据进程名或其他搜索条件获取进程PID。
例如,如果你的Snort进程名为snort,你可以使用以下命令检索它的PID:
pgrep snort

这将返回与Snort进程匹配的PID。然后,你可以将返回的PID用于kill命令,例如:
kill -9 $(pgrep snort)

这个命令会发送一个强制终止信号(SIGKILL)给那些匹配名为snort的进程。
如果你希望使用Python脚本自动执行这个命令,可以将它们包含在脚本中,例如:
import subprocess

# 获取Snort进程的PID
pid = subprocess.check_output(["pgrep", "snort"])

# 终止Snort进程
subprocess.call(["kill", "-9", pid])

这个代码使用subprocess.check_output()函数获取匹配名为snort的进程的PID,然后使用subprocess.call()函数结束它。

实验环境:

snort.conf:

alert icmp any any -> any any (msg:"WARNING! There is http connect!" ;sid:26287)
alert tcp any any -> any any (msg:"WARNING! There is http connect!" ;sid:26283)
alert udp any any -> any any (msg:"WARNING! There is http connect!" ;sid:26281)

#output alert_csv : alert.csv  default

参考资料

NAT

NAT(Network Address Translation),是指网络地址转换,1994年提出的。
当在专用网内部的一些主机本来已经分配到了本地IP地址(即仅在本专用网内使用的专用地址),但又想和因特网上的主机通信(并不需要加密)时,可使用NAT方法。
这种方法需要在专用网(私网IP)连接到因特网(公网IP)的路由器上安装NAT软件。装有NAT软件的路由器叫做NAT路由器,它至少有一个有效的外部全球IP地址(公网IP地址)。这样,所有使用本地地址(私网IP地址)的主机在和外界通信时,都要在NAT路由器上将其本地地址转换成全球IP地址,才能和因特网连接。
另外,这种通过使用少量的全球IP地址(公网IP地址)代表较多的私有IP地址的方式,将有助于减缓可用的IP地址空间的枯竭。在RFC 2663中有对NAT的说明。

参考资料

基于docker的sfc(伪)

搭建环境

基于该网站的流程手动添加流表:https://www.modb.pro/db/146901

流表:https://www.cnblogs.com/wangjq19920210/p/11776824.html

模拟收发包

可以用python收发包

收发包也可以用hping3

手动下流表

编写openflow流表的文档指引

1主机(192.168.1.2),2sf(192.168.1.3,192.168.1.4)的流表:

ovs-ofctl add-flow br0 "cookie=0,priority=40001,ip,in_port=1,nw_dst=192.168.1.3 actions=output:2"
ovs-ofctl add-flow br0 "cookie=0,priority=40001,ip,in_port=2,nw_dst=192.168.1.4 actions=output:3"
ovs-ofctl add-flow br0 "cookie=0,priority=40001,ip,in_port=3,nw_dst=192.168.1.3 actions=output:2"
ovs-ofctl add-flow br0 "cookie=0,priority=40001,ip,in_port=2,nw_dst=192.168.1.2 actions=output:1"

容器外执行命令

docker 不进入容器执行命令

docker故障注入

注入工具:

  • 网络故障注入:Avalanche(基于linux tc的网络故障注入)
  • 文件系统故障注入:UnreliableFS
  • io故障注入:SCSI

  • 内核故障注入:swifi
  • 集合体:sidecar(需要魔改net部分)(部分基于stress)
    •   
      魔改版
      # -*- coding: UTF-8 -*-
      import os
      import time
      import logging
      import argparse
      
      
      # 将薛师兄代码里的数字转变为更加易懂的参数输入
      def fault_injection(fault_type, **kwargs):
          logging.info("Ready to inject fault.")
          duration = '10'
          if duration in kwargs and duration is not None:
              duration = kwargs['duration']
      
          # fault_type have 4 types: 'cpu', 'mem', 'disk', 'net'
          if fault_type == 'cpu':
              print("cpu error injection")
              logging.info(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
              # CPU Fault has 2 args: thread_num, duration
              if 'thread_num' not in kwargs or kwargs['thread_num'] is None:
                  thread_num = '4'
              else:
                  thread_num = kwargs['thread_num']
              # 切分为多进程
              pid = os.fork()
              # 子进程负责错误注入
              if pid == 0:
                  # using linux command to inject faults.
                  os.system("stress -c %s -t %s" % (thread_num, duration))
              # 父进程负责返回注入结果并继续监听 Server 端口
              else:
                  logging.info("stress -c %s -t %s" % (thread_num, duration))
      
          elif fault_type == 'mem':
              logging.info(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
              # Memory Fault has 3 args: thread_num, mem_size, duration
              if 'thread_num' not in kwargs or kwargs['thread_num'] is None:
                  thread_num = '4'
              else:
                  thread_num = kwargs['thread_num']
              if 'mem_size' not in kwargs or kwargs['mem_size'] is None:
                  mem_size = '128M'
              else:
                  mem_size = kwargs['mem_size']
      
              pid = os.fork()
              if pid == 0:
                  os.system("stress --vm %s --vm-bytes %s --vm-keep -t %s" % (thread_num, mem_size, duration))
              else:
                  logging.info("stress --vm %s --vm-bytes %s --vm-keep -t %s" % (thread_num, mem_size, duration))
      
          # iostat -x -k -d 1
          elif fault_type == 'disk':
              logging.info(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
              # args
              if 'io_times' not in kwargs or kwargs['io_times'] is None:
                  io_times = '4'
              else:
                  io_times = kwargs['io_times']
      
              pid = os.fork()
              if pid == 0:
                  os.system("stress -i %s -t %s" % (io_times, duration))
              else:
                  logging.info("stress -i %s -t %s" % (io_times, duration))
      
          elif fault_type == 'net':
              logging.info(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
              if 'net_port' not in kwargs or kwargs['net_port'] is None:
                  net_port = '100'
              else:
                  net_port = kwargs['net_port']
      
              net_card = 'eth0'
              if 'net_card' in kwargs:
                  net_card = kwargs['net_card']
      
              pid = os.fork()
              if pid == 0:
                  # os.system("iperf3 -s -p %s" % net_port)
                  if 'delay' in kwargs and kwargs['delay'] is not None:
                      os.system("tc qdisc add dev %s root netem delay %s" % (net_card, kwargs['delay']))
                  if 'max_delay' in kwargs and kwargs['max_delay'] is not None:
                      os.system(
                          "tc qdisc add dev %s root netem delay %s %s" % (net_card, kwargs['min_delay'], kwargs['max_delay']))
                  if 'loss' in kwargs and kwargs['loss'] is not None:
                      os.system("tc qdisc add dev %s root netem loss %s " % (net_card, kwargs['loss']))
                  # os.system("ping www.baidu.com")
                  time.sleep(int(duration))
                  os.system("tc qdisc del dev %s root" % net_card)
              else:
                  logging.info("iperf3 -s -p %s" % net_port)
      
          # 若错误类型不在这4种之内,则返回 None
          else:
              pass
      
          pass
      
      
      if __name__ == '__main__':
          # fault_type have 4 types: 'cpu', 'mem', 'disk', 'net'
      
          # cpu(CPU Fault has 2 args: thread_num, duration)消耗 CPU 资源
          # 产生 thread_num 个进程,每个进程都反复不停的计算随机数的平方根
      
          # mem(Memory Fault has 3 args: thread_num, mem_size, duration)内存
          # -m, --vm N                 产生 thread_num 个进程,每个进程不断分配和释放内存
          #     --vm-bytes B           指定分配内存的大小 mem_size
          #     --vm-stride B          不断的给部分内存赋值,让 COW(Copy On Write)发生(not use)
          #     --vm-hang N            指示每个消耗内存的进程在分配到内存后转入睡眠状态 N 秒,然后释放内存,
          #                            一直重复执行这个过程
          #     --vm-keep              一直占用内存,区别于不断的释放和重新分配(默认是不断释放并重新分配内存)
      
          # disk(io_times, duration)消耗 IO 资源
          # -i, --io N                 产生 io_times 个进程,每个进程反复调用 sync() 将内存上的内容写到硬盘上
      
          # net(net_card,delay ms,(max_dely ms,min_dely ms),loss %,durction)模拟出各种复杂的网络场景
          # 延时、延时波动 : delay ms,(max_dely ms,min_dely ms)
          # 随机丢包,代表随机丢包loss%
      
          parser = argparse.ArgumentParser()
      
          parser.add_argument('-fault_type', type=str, required=True)
          parser.add_argument('-thread_num', type=str)
          parser.add_argument('-duration', type=str)
          parser.add_argument('-mem_size', type=str)
          parser.add_argument('-io_times', type=str)
          parser.add_argument('-net_port', type=str)
          parser.add_argument('-net_card', type=str)
          parser.add_argument('-max_delay', type=str)
          parser.add_argument('-min_delay', type=str)
          parser.add_argument('-delay', type=str)
          parser.add_argument('-loss', type=str)
      
          args = parser.parse_args()
          fault_injection(args.fault_type, thread_num=args.thread_num,
                          duration=args.duration, mem_size=args.mem_size,
                          io_times=args.io_times, net_port=args.net_port,
                          net_card=args.net_card, max_delay=args.max_delay, min_delay=args.min_delay,
                          delay=args.delay, loss=args.loss)

参考资料

Docker搜集日志

系统日志

魔改版
 import subprocess
import time

while True:
    # 获取当前时间戳
    timestamp = int(time.time())

    # 执行 top 命令,获取数据并添加时间戳
    cmd = f'top -b -n 1 | awk \'{{print "{timestamp} " $0}}\''
    output = subprocess.check_output(cmd, shell=True, universal_newlines=True)

    # 将数据写入 log 文件
    with open("tap.log", "a") as f:
        f.write(output)

    # 等待 1 秒后再次执行
    time.sleep(1)

参考资料

如何查看linux系统中的日志 (常用指令)

如何用 Linux 查看日志、磁盘、CPU、内存使用情况?

linux下top指令参数详解及用法

深入了解Python中的时间戳(Timestamp)

网络日志

参考资料:

Linux实时监控网卡入流量和出流量(iftop、dstat、nethogs、nload)

未完待续

posted @ 2023-02-28 20:33  EA2218764AB  阅读(671)  评论(1编辑  收藏  举报