Shell2虚拟多网口,spi,rsyslog

Posted 码农编程录

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Shell2虚拟多网口,spi,rsyslog相关的知识,希望对你有一定的参考价值。

文章目录


1.BMC虚拟多网口:macvlan是kernel提供的一种网卡虚拟化技术,可将网卡(不一定是真实的物理网卡)虚拟出多个接口,这网卡称为master或父接口,这些虚拟接口和外面环境通信都是通过父接口

1.1 bridge:ip netns add ns001 / ns002

macvlan模拟的mac不同,如下第一行和第二行创建两个以ens32为父接口的macvlan1和macvlan2虚拟网口。

如下将ns绑定网卡,进入ns001虚拟环境,将网卡up起来。

如下添加ip,不通原因是bridge模式和父接口(.138)是不通的。

宿主机(.1)指的windows这台机器,如下两个都是往外ping。

1.2 private:FB Openbmc(AST2520实物芯片)和OcpOpenBMC(qemu ast2500-evb)以及X86 Ubuntu上验证过, Kernel版本均5.0+

编译Kernel

BMC/CPU OS的Linux Kernel Config里面加CONFIG_MACVLAN=m/y,如下是BMC:

如下在编译的服务器上编译完后,如果找不到就删除build目录重新编译。

如下在烧录的机器上烧录镜像后,vi第一行.dep文件。

如下不用insmod kernel/drivers/net/maclan.ko。

创建/启动网卡/获取DHCP地址

创建网卡以eth0为目标物理网口,虚拟网口的MAC地址自定义,这里mode可以选择private不能互通,bridge内部互通等。假设生成5个虚拟网口eth0.1-eth0.5,命令如下,ifconfig检查5个虚拟网口的IP地址和MAC地址(都不一样):

ip link add link eth0 dev eth0.1 address D6:D2:52:A8:28:28   type macvlan  mode private   
ip link add link eth0 dev eth0.2 address D6:D2:52:A8:28:29   type macvlan  mode private   
ip link add link eth0 dev eth0.3 address D6:D2:52:A8:28:2a   type macvlan  mode private   
ip link add link eth0 dev eth0.4 address D6:D2:52:A8:28:2b   type macvlan  mode private   
ip link add link eth0 dev eth0.5 address D6:D2:52:A8:28:2c   type macvlan  mode private   
ifconfig eth0.1 up
ifconfig eth0.2 up
ifconfig eth0.3 up
ifconfig eth0.4 up
ifconfig eth0.5 up
dhclient eth0.1
dhclient eth0.2
dhclient eth0.3
dhclient eth0.4
dhclient eth0.5

配置路由表

配置路由表的目的:由于5个网口都被分配在一个网段如10.75.159.0/24(掩码一样),导致Linux 内部路由会以高优先级的网口如eth0来响应外部的arp/icmp/tcp等各种网络请求。为了达到5个虚拟网口能在同网段以5个独立网口的形式工作,呈现5个独立网口MAC地址,需要配置路由表。获取Gateway网关地址:用route -n 命令获取路由表和Gateway(10.75.159.1)地址。

配置路由表:数量以实际虚拟网卡数量为准,需要替换网关IP和每个网口的IP。下面命令中10.75.159.1为网关地址,10.75.159.117等为虚拟网口的IP地址,10.75.159.0/24为网段和NETMASK

echo "210 eth0table" >> /etc/iproute2/rt_tables  210越大优先级越低
echo "220 eth1table" >> /etc/iproute2/rt_tables
echo "230 eth2table" >> /etc/iproute2/rt_tables
echo "240 eth3table" >> /etc/iproute2/rt_tables
echo "250 eth4table" >> /etc/iproute2/rt_tables

ip route add 10.75.159.0/24 dev eth0.1 src 10.75.159.117 table eth0table
ip route add 10.75.159.0/24 dev eth0.2 src 10.75.159.120  table eth1table
ip route add 10.75.159.0/24 dev eth0.3 src 10.75.159.121 table eth2table
ip route add 10.75.159.0/24 dev eth0.4 src 10.75.159.125  table eth3table
ip route add 10.75.159.0/24 dev eth0.5 src 10.75.159.132 table eth4table

ip route add default dev eth0.1 via 10.75.159.1 table eth0table
ip route add default dev eth0.2 via 10.75.159.1 table eth1table
ip route add default dev eth0.3 via 10.75.159.1 table eth2table
ip route add default dev eth0.4 via 10.75.159.1 table eth3table
ip route add default dev eth0.5 via 10.75.159.1 table eth4table

ip rule add from 10.75.159.117 table eth0table
ip rule add from 10.75.159.120 table eth1table
ip rule add from 10.75.159.121 table eth2table
ip rule add from 10.75.159.125 table eth3table
ip rule add from 10.75.159.132 table eth4table

远端服务器检查

远端服务器发起ping:通过发起ping,获取相应网口的MAC地址信息。

ping  10.75.159.117
ping  10.75.159.120
ping  10.75.159.121
ping  10.75.159.125
ping  10.75.159.132

如下远端服务器arp -a,可看到BMC侧IP的MAC地址与远端服务器获取的一致,符合预期。

使用tcp方式测试,BMC端 iperf -s -p port
测试服务器端 iperf -c BMCIP -t 1000 -i 3 -p port

iproute2










1.3

# creat_macvlan.sh
#!/bin/sh
IP_ROUTEFILE_PATH="/etc/iproute2/rt_tables"
priority_arry=(210 220 230 240)
tablename_arry=(eth0table eth1table eth2table eth3table)

#dynamic routing configuration for macvlan
dynamic_routing()

    #Initialize basic network information
    index=0
    for i in $(ifconfig | grep -o ^[a-z0-9.]* | grep -v lo); do
        ipaddr_array[$index]=$(ifconfig "$i" | sed -n 2p | awk ' print $2 ' | tr -d 'addr:')
        devname_array[$index]=$i
        gateway_array[$index]=$(route | grep "$devname_array[$index]" | grep 'default' | awk 'print $2')
        iprange_array[$index]="$ipaddr_array[$index]%[^0-9]*.0/24"
        index=$((index + 1))
    done

    #Create the table and initialize it
    index=0
    for i in "$tablename_arry[@]"; do
        tablename=$(cat $IP_ROUTEFILE_PATH | grep "$devname_array[$index]" | sed -n 1p | awk -F ' ' 'print$2')
        if [ "$tablename" != "$tablename_arry[$index]" ]; then
            echo "$priority_arry[$index] $tablename_arry[$index]" >> $IP_ROUTEFILE_PATH
        fi
        ip route flush table "$tablename_arry[$index]"
        index=$((index + 1))
    done

    #Configure dynamic routing for the table
    index=0
    for i in "$tablename_arry[@]"; do
        ip route add "$iprange_array[$index]" dev "$devname_array[$index]" src "$ipaddr_array[$index]" table "$tablename_arry[$index]"
        ip route add default dev "$devname_array[$index]" via "$gateway_array[$index]" table "$tablename_arry[$index]"
        ip rule add from "$ipaddr_array[$index]" table "$tablename_arry[$index]"
        index=$((index + 1))
    done


###Creat MAC Vlan
ip link add link eth0 dev eth1 type macvlan
ip link add link eth0 dev eth2 type macvlan
ip link add link eth0 dev eth3 type macvlan
ip link set eth1 up
ip link set eth2 up
ip link set eth3 up

sleep 2
#dhclient eth0.01
#dhclient eth0.02
#dhclient eth0.03

dynamic_routing
# macvlan.service

[Unit]
Description=Mac Vlan Server
After=-xyz.openbmc_project.Network.service

[Service]
ExecStart=/usr/bin/creat_macvlan.sh
Type=oneshot

[Install]
WantedBy=multi-user.target
# macvlan.bb
SUMMARY = "Phosphor BMC Macvlan"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://$COREBASE/meta/files/common-licenses/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"

inherit pkgconfig
inherit obmc-phosphor-systemd

SYSTEMD_SERVICE:$PN += "macvlan.service"

DEPENDS += "systemd"

SRC_URI += "file://macvlan.service \\
            file://creat_macvlan.sh \\
            "

do_install() 
    install -d $D$bindir

    install -m 0755 $WORKDIR/creat_macvlan.sh $D$bindir/creat_macvlan.sh


S = "$WORKDIR"

2.spi

#!/bin/bash
#shellcheck disable=SC1091
. /usr/local/bin/openbmc-utils.sh
layout_file="/etc/platform/__MACHINE__/fpgarom.layout"
PIDFILE="/var/run/spi_util.pid"

# ctrl+c或升级结束后或异常退出 退出都运行
trap "pre_exit" EXIT
pre_exit()

    #echo "Ready to exit $program"
    if [ "$spi" = "Bios" ] && [ -n "$come_power_ret" ] && [ "$come_power_ret" -ne 0 ];then
        if [ -n "$boot_source" ];then
            echo "$boot_source" > "$LCCPLD_SYSFS_DIR"/bios_select  #控制
        fi
        #lock
        echo 0x0 > "$LCCPLD_SYSFS_DIR"/lc_bios_spi_select
    elif [ "$spi" = "FPGA" ] && [ -n "$fpga_power_ret" ] && [ "$fpga_power_ret" -ne 0 ];then
        #lock
        echo 0x0 > "$LCCPLD_SYSFS_DIR"/lc_fpga_spi_select
    fi
    
    if [ -f "$out_file" ] || [ -L "$out_file" ];then
        rm -f "$out_file"
    fi
    if [ -f "$PIDFILE" ];then
        rm $PIDFILE
    fi


# check duplicate process,update one fpga/bios at the same time. 多进程对同一文件的读写冲突
check_duplicate_process()

    exec 8<>$PIDFILE  #exec后面的数字是[3, 9] 之间的整数
    flock -n 8 || (echo "Another process is running" && exit 1)  #-n是非阻塞的,一旦发现PIDFILE文件被占用,就打印后面echo,然后退出脚本;
    ret=$?
    if [ $ret -eq 1 ]; then
        exit 1
    fi
    pid=$$
    echo $pid >&8


#111111111111111111111111111111111111111111111111111111如下都是通过flashrom -p spi设备地址得到信息
check_flash_info()

    spi_no=$1
    flashrom -p linux_spi:dev=/dev/spidev"$spi_no".0


get_flash_first_type()

    spi_no=$1
    ori_str=$(check_flash_info "$spi_no")
    type=$(echo $ori_str | cut -d '"' -f 2)
    if [ "$type" ];then
        echo "$type"
        return 0
    else
        echo "Get flash type error: [$ori_str]"
        exit 1
    fi


get_flash_size()

    spi_no=$1
    ori_str=$(check_flash_info "$spi_no")
    flash_sz=$(echo $ori_str | cut -d '(' -f 4 | cut -d ' ' -f 1)
    echo "$flash_sz" | grep -E -q '^[0-9]+$'
    num_ret=$?
    if [ $num_ret -eq 0 ];then
        echo "$flash_sz"
        return 0
    else
        echo "Get flash size error: [$ori_str]"
        return 1
    fi


#111111111111111111111111111111111111111111111111111111111111111111如下最重要resize_file()
check_layout_image_exist()

    layout_file=$1
    image=$2  #primary/golden
    cut_ret=$(cut -d ' ' -f 2 "$1" | grep "$2")   # cut后面加文件
    if [ "$cut_ret" != "$image" ];then
        echo "cant not find $image in $layout_file "
        return 1
    else
        return 0
    fi


get_layout_image_startaddr()

    layout_file=$1
    image=$2
    while read -r line
    do
        cut_ret=$(echo "$line" | cut -d ' ' -f 2)
        if [ "$cut_ret" = "$image" ];then
            startaddr=$(echo "$line" | cut -d ':' -f 1) #逐行遍历
            startaddr=$((16#$startaddr)) #转16进制
            echo "$startaddr"
            return 0
        fi
    done < "$layout_file"
    return 1


# $1: input file size    $2: flash size    $3: output file path
pad_ff()

    out_file=$3
    pad_size=$(($2 - $1))
    dd if=/dev/zero bs=$pad_size count=1 | tr "\\000" "\\377" >> "$out_file"


# $1: image_size    $2: storage_sz     $3: image_startaddr    $4: out_file
pad_touchfile()

    image_size=$1  #bin大小
    storage_sz=$2   #flash大小
    image_startaddr=$3 # 真实起始地址
    out_file=$4  #备份的.bin(最后要烧录进flash的),下面操作都是对out_file操作
    dd if=/dev/zero bs="$image_startaddr" count=1 | tr "\\000" "\\377" >> "$out_file"  #头
    dd if="$in_file" bs="$image_size" count=1 >> "$out_file" # 中间
    declare -i left_size="$storage_sz"-"$image_startaddr"-"$image_size"
    dd if=/dev/zero bs="$left_size" count=1 | tr "\\000" "\\377" >> "$out_file"  #尾


resize_file()

    in_file=$1     # .bin
    out_file=$2    # /tmp/.bin
    spi_no=$3
    image_size=$4
    image_startaddr=$5
    in_file_sz=$(stat -c%s "$in_file")
    storage_sz=0

    if flash_sz=$(get_flash_size "$spi_no");then
        storage_sz=$((flash_sz * 1024))
    else
        echo "debug message: $flash_sz"
        exit 1
    fi
    if [ "$image_size" -eq 0 ] && [ "$image_startaddr" -eq 0 ];then  # 不用layout文件
        if [ "$in_file_sz" -ne $storage_sz ];then   #.bin < flash
            cp "$in_file" "$out_file"   # 拷贝.bin (不动bin原文件)
            pad_ff "$in_file_sz" $storage_sz "$out_file"   #尾追加,只能是bios,或mulit混合
        else
            ln -s "$(realpath "$in_file")" "$out_file"  
        fi
    else
        touch "$out_file"
        pad_touchfile "$image_size" $storage_sz "$image_startaddr" "$out_file"
    fi


#1111111111111111111111111111111111111111111111111111111111111如下最重要的是write_flash_to_file,erase和read不重要
read_flash_to_file()

    spi_no=$1
    tmp_file=$2
    type=$(get_flash_first_type "$spi_no")
    if ! flashrom -p linux_spi:dev=/dev/spidev"$spi_no".0 -r "$tmp_file" -c "$type";then
        echo "debug cmd: [flashrom -p linux_spi:dev=/dev/spidev$spi_no.0 -r $tmp_file -c $type]"
        exit 1
    fi


check_fpga_imagesize()
    if flash_sz=$(get_flash_size "$spi_no");then  # flash_sz   k
        storage_sz=$((flash_sz * 1024))  # B 字节
    else
        echo "debug message: $flash_sz"
        exit 1
    fi
    image_startaddr=$(get_layout_image_startaddr "$layout_file" "$image")  # image_startaddr 字节
    declare -i max_image_size="$storage_sz"-"$image_startaddr"
    file_sz=$(stat -c%s "$file")
    if [ "$file_sz" -gt "$max_image_size" ];then
        echo "The maximum image file size is $max_image_size B."
        exit 1
    fi


check_bios_imagesize()
    if flash_sz=$(get_flash_size "$spi_no");then
        max_image_size=$((flash_sz * 1024))
    else
        echo "debug message: $flash_sz"
        exit 1
    fi
    file_sz=$(stat -c%s "$file")
    if [ "$file_sz" -gt "$max_image_size" ];then
        echo "The maximum image file size is $max_image_size B."
        exit 1
    fi


write_flash_to_file()  # $spi_no    .bin    primary/golden

    spi_no=$1
    in_file=$2
    image=$3
    if [ $# -eq 3 ];then
        image_size=$(stat -c%s "$in_file")
        image_startaddr=$(get_layout_image_startaddr "$layout_file" "$image")
        mode="layout"
    else #不用layout文件
        image_size=0
        image_startaddr=0
        mode="normal"
    fi
    tmp_file=$(basename "$in_file")
    out_file="/tmp/spi$spi_no_$tmp_file"
    resize_file "$in_file" "$out_file" "$spi_no" $image_size $image_startaddr
    type=$(get_flash_first_type "$spi_no")
    if [ $mode = "normal" ];then
        if ! flashrom -p linux_spi:dev=/dev/spidev"$spi_no".0 -w "$out_file" -c "$type";then
            echo "debug cmd: [flashrom -p linux_spi:dev=/dev/spidev$spi_no.0 -w $out_file -c $type]"
            rm -f "$out_file"
            exit 1
        fi
    elif [ $mode = "layout" ];then
        if ! flashrom -p linux_spi:dev=/dev/spidev"$spi_no"以上是关于Shell2虚拟多网口,spi,rsyslog的主要内容,如果未能解决你的问题,请参考以下文章

裸机调试AM3358网口

plc网口通讯怎么接收坐标点坐标

Hyper-V虑拟机网卡设置方法

Linux 获取物理网口/或虚拟网络接口

centos+rsyslog(拷贝虚拟机文件移植到其他地方使用)

linux