这篇博客主要介绍Golang语言下通过调用 vpp-api 来进行网关的管理、ABF的管理和路由的管理。博客主要以实践为主,提供源码。
由于是付费文章,照例先把来源讲清。代码使用 goVPP这个开源代码,您可以直接去看这个开源项目获取 vpp-api。
关于VPP的基本使用可以参考这篇博客:VPP使用介绍(route、tun、memif、abf)_我要出家当道士-CSDN博客详细介绍了VPP的安装、并介绍了其中TUN、Memif和ABF的使用https://blog.csdn.net/qq_37437983/article/details/121459438?spm=1001.2014.3001.5501
由于我使用的是Golang语言,所以可以使用goVPP;C的话,VPP的源码里面我记得提供了API接口的。
下面正式开始:其实实现的思路很简单,goVPP已经提供了api接口,源码利用也有使用的demo,但我们为了快速上手开发,使用的是vpp-dataplane,其对goVPP进行了二次封装,使用起来更加的方便快捷。
goVPP和VPP-dataplane的链接如下:https://github.com/FDio/govpphttps://github.com/FDio/govpphttps://github.com/projectcalico/vpp-dataplane
https://github.com/projectcalico/vpp-dataplane 我们主要调用 VPP-dataplane/vpplink/ 目录下的代码,下面举例,创建 host-interface。我们知道,host-interface 其实是 af-packet 输入,所以创建 host-interface 其实是创建 af-packet 接口。
1、首先获取本地接口信息
package net
import (
"errors"
"net"
"strconv"
"strings"
)
type Nic struct {
Name string
Ipv4 *net.IPNet
Mac net.HardwareAddr
}
func parseIp(s string) (*net.IPNet, error) {
i := strings.Index(s, "/")
if i < 0 {
return nil, errors.New("the ip address should be xxx.xxx.xxx.xxx/24")
}
addr, mask := s[:i], s[i+1:]
ip := net.ParseIP(addr)
n, _ := strconv.Atoi(mask)
if n > 32 || n < 0{
return nil, errors.New("ipv4 address' mask should be upper than 0 and lower than 32")
}
m := net.CIDRMask(n, 8*4)
return &net.IPNet{IP: ip, Mask: m}, nil
}
func GetIntfacesInfo() ([]Nic, error) {
interfaces, err := net.Interfaces()
if err != nil{
return nil, err
}
var nics []Nic
for i := 0; i < len(interfaces); i++{
intF, err := net.InterfaceByName(interfaces[i].Name)
if err != nil{
return nil, err
}
address, _ := intF.Addrs()
for _, v := range address{
ipStr := v.String()
if 4 != len(strings.Split(ipStr,".")) || nil == interfaces[i].HardwareAddr{
continue
}
ipNet, _ := parseIp(ipStr)
nic := Nic{
Name: interfaces[i].Name,
Ipv4: ipNet,
Mac: interfaces[i].HardwareAddr,
}
nics = append(nics, nic)
}
}
return nics, nil
}
2、之后调用 VPP-API 接口根据获取的本地接口信息创建 host-interface
package main
import (
"log"
vpplink "vppManager/api"
"vppManager/api/types"
"vppManager/net"
)
func createVppInt(){
link, _ := vpplink.NewVppLink("", nil)
err := link.Reconnect()
if err != nil{
log.Print("connect : ", err)
}
nics, err := net.GetIntfacesInfo()
if err != nil{
log.Print("get local nics' info Error : ", err)
}
for i := 0; i < len(nics); i++{
hostInt := types.GenericVppInterface{
//Name: nics[i].Name,
HostInterfaceName: nics[i].Name,
HardwareAddr: &nics[i].Mac,
}
intId, err := link.CreateAfPacket(&types.AfPacketInterface{GenericVppInterface:hostInt})
if err != nil{
log.Print("create interface : ", err)
return
}
err = link.InterfaceAdminUp(intId)
if err != nil{
log.Print("enable vpp interface Error : ", err)
return
}
err = link.AddInterfaceAddress(intId, nics[i].Ipv4)
if err != nil{
log.Print("set vpp interface ip address Error : ", err)
return
}
log.Print("success : ", intId)
}
}
func main(){
createVppInt()
}
代码开源地址:https://github.com/AtaoistPriest/VPPManagerhttps://github.com/AtaoistPriest/VPPManager ABF和路由管理的类似,可以看我另一篇 go 管理系统路由的代码。GO实现linux路由管理(增删查)_我要出家当道士-CSDN博客GO实现linux路由管理(增删查)
https://blog.csdn.net/qq_37437983/article/details/121620771?spm=1001.2014.3001.5501