Skip to content

Commit 608e6ad

Browse files
committed
Vpp-manager refactoring
Signed-off-by: Nathan Skrzypczak <[email protected]>
1 parent 6df15fc commit 608e6ad

File tree

16 files changed

+596
-800
lines changed

16 files changed

+596
-800
lines changed

config/config.go

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -162,13 +162,13 @@ func RunHook(hookScript *string, hookName string, params *VppManagerParams, log
162162
if *hookScript == "" {
163163
return
164164
}
165-
template, err := TemplateScriptReplace(*hookScript, params, nil)
165+
template, err := TemplateScriptReplace(*hookScript, params)
166166
if err != nil {
167167
log.Warnf("Running hook %s errored with %s", hookName, err)
168168
return
169169
}
170170

171-
cmd := exec.Command("/bin/bash", "-c", template, hookName, params.UplinksSpecs[0].InterfaceName)
171+
cmd := exec.Command("/bin/bash", "-c", template, hookName, params.InterfacesById[0].Spec.InterfaceName)
172172
cmd.Stdout = os.Stdout
173173
cmd.Stderr = os.Stderr
174174
err = cmd.Run()
@@ -428,8 +428,6 @@ type CalicoVppInitialConfigConfigType struct { //out of agent and vppmanager
428428
// CorePattern is the pattern to use for VPP corefiles.
429429
// Usually "/var/lib/vpp/vppcore.%e.%p"
430430
CorePattern string `json:"corePattern"`
431-
ExtraAddrCount int `json:"extraAddrCount"`
432-
IfConfigSavePath string `json:"ifConfigSavePath"`
433431
// DefaultGWs Comma separated list of IPs to be
434432
// configured in VPP as default GW
435433
DefaultGWs string `json:"defaultGWs"`
@@ -619,9 +617,35 @@ const (
619617
VfioUnsafeNoIommuModeDISABLED UnsafeNoIommuMode = "disabled"
620618
)
621619

620+
type UplinkDriver interface {
621+
PreconfigureLinux() error
622+
CreateMainVppInterface(vpp *vpplink.VppLink, vppPid int, uplinkSpec *UplinkInterfaceSpec) error
623+
RestoreLinux()
624+
IsSupported(warn bool) bool
625+
GetName() string
626+
UpdateVppConfigFile(template string) string
627+
GetDefaultRxMode() types.RxMode
628+
}
629+
630+
type VppManagerInterface struct {
631+
Spec UplinkInterfaceSpec
632+
State *LinuxInterfaceState
633+
Driver UplinkDriver
634+
}
635+
636+
func (p *VppManagerParams) AllInterfacesPhysical() bool {
637+
for _, intf := range p.Interfaces {
638+
if intf.State.IsTunTap || intf.State.IsVeth {
639+
return false
640+
}
641+
}
642+
return true
643+
}
644+
622645
type VppManagerParams struct {
623-
UplinksSpecs []UplinkInterfaceSpec
624-
/* Capabilities */
646+
Interfaces map[string]*VppManagerInterface
647+
InterfacesById []*VppManagerInterface
648+
// Capabilities
625649
LoadedDrivers map[string]bool
626650
KernelVersion *KernelVersion
627651
AvailableHugePages int
@@ -744,23 +768,25 @@ func getCpusetCPU() (string, error) {
744768
return regexp.MustCompile("[,-]").Split(cpusetCPU, 2)[0], nil
745769
}
746770

747-
func TemplateScriptReplace(input string, params *VppManagerParams, conf []*LinuxInterfaceState) (template string, err error) {
771+
func TemplateScriptReplace(input string, params *VppManagerParams) (template string, err error) {
748772
template = input
749-
if conf != nil {
750-
/* We might template scripts before reading interface conf */
751-
template = strings.ReplaceAll(template, "__PCI_DEVICE_ID__", conf[0].PciID)
752-
for i, ifcConf := range conf {
753-
template = strings.ReplaceAll(template, "__PCI_DEVICE_ID_"+strconv.Itoa(i)+"__", ifcConf.PciID)
754-
}
773+
if len(params.Interfaces) > 0 {
774+
// We might template scripts before reading interface conf
775+
template = strings.ReplaceAll(template, "__PCI_DEVICE_ID__", params.InterfacesById[0].State.PciID)
776+
}
777+
for idx, intf := range params.InterfacesById {
778+
template = strings.ReplaceAll(template, "__PCI_DEVICE_ID_"+strconv.Itoa(idx)+"__", intf.State.PciID)
755779
}
756780
vppcpu, err := getCpusetCPU()
757781
if err != nil {
758782
return "", err
759783
}
760784
template = strings.ReplaceAll(template, "__CPUSET_CPUS_FIRST__", vppcpu)
761-
template = strings.ReplaceAll(template, "__VPP_DATAPLANE_IF__", params.UplinksSpecs[0].InterfaceName)
762-
for i, ifc := range params.UplinksSpecs {
763-
template = strings.ReplaceAll(template, "__VPP_DATAPLANE_IF_"+fmt.Sprintf("%d", i)+"__", ifc.InterfaceName)
785+
if len(params.Interfaces) > 0 {
786+
template = strings.ReplaceAll(template, "__VPP_DATAPLANE_IF__", params.InterfacesById[0].Spec.InterfaceName)
787+
}
788+
for idx, intf := range params.InterfacesById {
789+
template = strings.ReplaceAll(template, "__VPP_DATAPLANE_IF_"+fmt.Sprintf("%d", idx)+"__", intf.Spec.InterfaceName)
764790
}
765791
for key, value := range params.NodeAnnotations {
766792
template = strings.ReplaceAll(template, fmt.Sprintf("__NODE_ANNOTATION:%s__", key), value)

vpp-manager/hooks/network_manager_hook.go

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ type SystemType struct {
5252

5353
// NetworkManagerHook manages network configuration during VPP lifecycle
5454
type NetworkManagerHook struct {
55-
interfaceNames []string
56-
systemType SystemType
57-
log *logrus.Logger
55+
vppManagerParams *config.VppManagerParams
56+
systemType SystemType
57+
log *logrus.Logger
5858
}
5959

6060
// chrootCommand creates a command that will be executed in the host namespace
@@ -151,21 +151,16 @@ func (h *NetworkManagerHook) restartService(serviceName string) error {
151151
}
152152

153153
// NewNetworkManagerHook creates a new NetworkManagerHook instance
154-
func NewNetworkManagerHook(log *logrus.Logger) *NetworkManagerHook {
154+
func NewNetworkManagerHook(log *logrus.Logger, vppManagerParams *config.VppManagerParams) *NetworkManagerHook {
155155
hook := &NetworkManagerHook{
156-
log: log,
156+
log: log,
157+
vppManagerParams: vppManagerParams,
157158
}
158159

159160
hook.detectSystem()
160161
return hook
161162
}
162163

163-
// SetInterfaceNames updates the interface names of NetworkManagerHook instance
164-
func (h *NetworkManagerHook) SetInterfaceNames(interfaceNames []string) {
165-
h.interfaceNames = interfaceNames
166-
h.log.Infof("NetworkManagerHook: Interface names updated to %v", interfaceNames)
167-
}
168-
169164
// fixDNS modifies NetworkManager configuration to disable DNS management
170165
func (h *NetworkManagerHook) fixDNS() error {
171166
if !h.systemType.HasNetworkManager {
@@ -500,7 +495,7 @@ func (h *NetworkManagerHook) beforeVppRun() error {
500495
}
501496

502497
// Save network file for AWS systemd-networkd for each interface
503-
for _, interfaceName := range h.interfaceNames {
498+
for interfaceName := range h.vppManagerParams.Interfaces {
504499
err = h.saveNetworkFile(interfaceName)
505500
if err != nil {
506501
return err
@@ -519,7 +514,7 @@ func (h *NetworkManagerHook) vppRunning() error {
519514
}
520515

521516
// Tweak network file for AWS systemd-networkd for each interface
522-
for _, interfaceName := range h.interfaceNames {
517+
for interfaceName := range h.vppManagerParams.Interfaces {
523518
err = h.tweakNetworkFile(interfaceName)
524519
if err != nil {
525520
return err
@@ -538,7 +533,7 @@ func (h *NetworkManagerHook) vppDoneOk() error {
538533
}
539534

540535
// Remove the tweaked network file for AWS systemd-networkd for each interface
541-
for _, interfaceName := range h.interfaceNames {
536+
for interfaceName := range h.vppManagerParams.Interfaces {
542537
err = h.removeTweakedNetworkFile(interfaceName)
543538
if err != nil {
544539
return err
@@ -566,7 +561,7 @@ func (h *NetworkManagerHook) Execute(hookPoint HookPoint) error {
566561
return nil
567562
}
568563

569-
h.log.Infof("NetworkManagerHook: Executing %s for interfaces %v", hookPoint, h.interfaceNames)
564+
h.log.Infof("NetworkManagerHook: Executing %s for all interfaces", hookPoint)
570565

571566
var err error
572567
switch hookPoint {
@@ -616,11 +611,10 @@ func (h *NetworkManagerHook) useDefaultHookFallback(userHook *string) bool {
616611
// 2. If native hooks enabled -> run native Go hook
617612
// 3. If native hooks disabled & no user script -> fallback to default_hook.sh
618613
func (h *NetworkManagerHook) ExecuteWithUserScript(hookPoint HookPoint,
619-
hookScript *string,
620-
params *config.VppManagerParams) {
614+
hookScript *string) {
621615
// Check if user script is configured (highest priority - overrides everything)
622616
if hookScript != nil && *hookScript != "" {
623-
config.RunHook(hookScript, string(hookPoint), params, h.log)
617+
config.RunHook(hookScript, string(hookPoint), h.vppManagerParams, h.log)
624618
return
625619
}
626620

@@ -636,6 +630,6 @@ func (h *NetworkManagerHook) ExecuteWithUserScript(hookPoint HookPoint,
636630
// Fallback to default_hook.sh when native hooks are disabled
637631
if h.useDefaultHookFallback(hookScript) {
638632
h.log.Infof("Native hooks disabled, falling back to default_hook.sh for %s", hookPoint)
639-
config.RunHook(&config.DefaultHookScript, string(hookPoint), params, h.log)
633+
config.RunHook(&config.DefaultHookScript, string(hookPoint), h.vppManagerParams, h.log)
640634
}
641635
}

vpp-manager/main.go

Lines changed: 13 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,8 @@ func main() {
165165

166166
/* Initialize native Go NewNetworkManagerHook with empty interface names
167167
* We will update this later once we have the actual interface names */
168-
networkHook = hooks.NewNetworkManagerHook(log)
169-
networkHook.ExecuteWithUserScript(hooks.HookBeforeIfRead, config.HookScriptBeforeIfRead, params)
168+
networkHook = hooks.NewNetworkManagerHook(log, params)
169+
networkHook.ExecuteWithUserScript(hooks.HookBeforeIfRead, config.HookScriptBeforeIfRead)
170170

171171
err = utils.ClearVppManagerFiles()
172172
if err != nil {
@@ -183,44 +183,31 @@ func main() {
183183
log.Errorf("Error raising memlock limit, VPP may fail to start: %v", err)
184184
}
185185

186-
confs, err := startup.GetInterfaceConfig(params)
187-
if err != nil {
188-
log.Fatalf("Error getting initial interface configuration: %s", err)
189-
}
190-
191-
/* Update native Go NewNetworkManagerHook with all interface names */
192-
if len(params.UplinksSpecs) > 0 {
193-
interfaceNames := make([]string, len(params.UplinksSpecs))
194-
for i, spec := range params.UplinksSpecs {
195-
interfaceNames[i] = spec.InterfaceName
196-
}
197-
networkHook.SetInterfaceNames(interfaceNames)
198-
}
199-
200186
runningCond = sync.NewCond(&sync.Mutex{})
201187
go handleSignals()
202188

203189
ctx, cancel := context.WithCancel(context.Background())
204190
defer cancel()
205191
config.HandleUsr2Signal(ctx, log.WithFields(logrus.Fields{"component": "sighdlr"}))
206192

207-
startup.PrintVppManagerConfig(params, confs)
208-
209-
runner := NewVPPRunner(params, confs)
193+
startup.PrintVppManagerConfig(params)
210194

211195
makeNewVPPIndex()
212196

213-
if len(params.UplinksSpecs) == 1 && params.UplinksSpecs[0].VppDriver == "" {
214-
for _, driver := range uplink.SupportedUplinkDrivers(params, confs[0], &params.UplinksSpecs[0]) {
197+
if len(params.Interfaces) == 1 && params.InterfacesById[0].Spec.VppDriver == "" {
198+
intf := params.InterfacesById[0]
199+
for _, driver := range uplink.SupportedUplinkDrivers(params, intf) {
215200
err := utils.CleanupCoreFiles(config.GetCalicoVppInitialConfig().CorePattern, maxCoreFiles)
216201
if err != nil {
217202
log.Errorf("CleanupCoreFiles errored %s", err)
218203
}
204+
intf.Driver = driver
219205

220206
internalKill = false
221-
err = runner.Run([]uplink.UplinkDriver{driver})
207+
runner := NewVPPRunner(params)
208+
err = runner.Run()
222209
if err != nil {
223-
networkHook.ExecuteWithUserScript(hooks.HookVppErrored, config.HookScriptVppErrored, params)
210+
networkHook.ExecuteWithUserScript(hooks.HookVppErrored, config.HookScriptVppErrored)
224211
log.Errorf("VPP(%s) run failed with %s", driver.GetName(), err)
225212
}
226213
if vppProcess != nil && !internalKill {
@@ -236,15 +223,10 @@ func main() {
236223
log.Errorf("CleanupCoreFiles errored %s", err)
237224
}
238225

239-
var drivers []uplink.UplinkDriver
240-
for idx := 0; idx < len(params.UplinksSpecs); idx++ {
241-
drivers = append(drivers, uplink.NewUplinkDriver(params.UplinksSpecs[idx].VppDriver,
242-
params, confs[idx], &params.UplinksSpecs[idx]))
243-
}
244-
245-
err = runner.Run(drivers)
226+
runner := NewVPPRunner(params)
227+
err = runner.Run()
246228
if err != nil {
247-
networkHook.ExecuteWithUserScript(hooks.HookVppErrored, config.HookScriptVppErrored, params)
229+
networkHook.ExecuteWithUserScript(hooks.HookVppErrored, config.HookScriptVppErrored)
248230
log.Errorf("VPP run failed with %v", err)
249231
}
250232

vpp-manager/startup/interface_config.go

Lines changed: 0 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,7 @@
1616
package startup
1717

1818
import (
19-
"encoding/gob"
20-
"fmt"
2119
"net"
22-
"os"
2320

2421
"github.com/pkg/errors"
2522
log "github.com/sirupsen/logrus"
@@ -30,56 +27,6 @@ import (
3027
"github.com/projectcalico/vpp-dataplane/v3/vpplink"
3128
)
3229

33-
func GetInterfaceConfig(params *config.VppManagerParams) (conf []*config.LinuxInterfaceState, err error) {
34-
errs := []error{}
35-
conf = []*config.LinuxInterfaceState{}
36-
for _, ifSpec := range params.UplinksSpecs {
37-
configuration, err := loadInterfaceConfigFromLinux(ifSpec)
38-
errs = append(errs, err)
39-
conf = append(conf, configuration)
40-
}
41-
allLoaded := true
42-
for i := range errs {
43-
if errs[i] != nil {
44-
allLoaded = false
45-
log.Warnf("Could not load config from linux (%v)", errs[i])
46-
}
47-
}
48-
if allLoaded {
49-
err = saveConfig(params, conf)
50-
if err != nil {
51-
log.Warnf("Could not save interface config: %v", err)
52-
}
53-
} else {
54-
// Loading config failed, try loading from save file
55-
confFile, err2 := loadInterfaceConfigFromFile(params)
56-
if err2 != nil {
57-
return nil, err2
58-
}
59-
// If loaded from file replace non loaded interface configs
60-
for i := range conf {
61-
if conf[i] == nil {
62-
for j := range confFile {
63-
if confFile[j].InterfaceName == params.UplinksSpecs[i].InterfaceName {
64-
conf[i] = confFile[j]
65-
}
66-
}
67-
}
68-
}
69-
for i := range conf {
70-
if conf[i] == nil {
71-
return nil, fmt.Errorf("interface configs not found")
72-
}
73-
}
74-
log.Infof("Loaded config. Interfaces marked as down since loading config from linux failed.")
75-
// This ensures we don't try to set the interface down in runVpp()
76-
for _, config := range conf {
77-
config.IsUp = false
78-
}
79-
}
80-
return conf, nil
81-
}
82-
8330
func loadInterfaceConfigFromLinux(ifSpec config.UplinkInterfaceSpec) (*config.LinuxInterfaceState, error) {
8431
conf := config.LinuxInterfaceState{}
8532
link, err := netlink.LinkByName(ifSpec.InterfaceName)
@@ -146,53 +93,3 @@ func getNodeAddress(conf *config.LinuxInterfaceState, isV6 bool) string {
14693
}
14794
return ""
14895
}
149-
150-
func clearSavedConfig(params *config.VppManagerParams) {
151-
if config.GetCalicoVppInitialConfig().IfConfigSavePath == "" {
152-
return
153-
}
154-
err := os.Remove(config.GetCalicoVppInitialConfig().IfConfigSavePath)
155-
if err != nil {
156-
log.Warnf("could not delete saved interface config: %v", err)
157-
}
158-
}
159-
160-
func saveConfig(params *config.VppManagerParams, conf []*config.LinuxInterfaceState) error {
161-
if config.GetCalicoVppInitialConfig().IfConfigSavePath == "" {
162-
return nil
163-
}
164-
file, err := os.Create(config.GetCalicoVppInitialConfig().IfConfigSavePath)
165-
if err != nil {
166-
return errors.Wrap(err, "error opening save file")
167-
}
168-
enc := gob.NewEncoder(file)
169-
err = enc.Encode(conf)
170-
if err != nil {
171-
file.Close()
172-
clearSavedConfig(params)
173-
return errors.Wrap(err, "error encoding data")
174-
}
175-
err = file.Close()
176-
if err != nil {
177-
return errors.Wrap(err, "error closing file")
178-
}
179-
return nil
180-
}
181-
182-
func loadInterfaceConfigFromFile(params *config.VppManagerParams) ([]*config.LinuxInterfaceState, error) {
183-
conf := []*config.LinuxInterfaceState{}
184-
if config.GetCalicoVppInitialConfig().IfConfigSavePath == "" {
185-
return nil, fmt.Errorf("interface config save file not configured")
186-
}
187-
file, err := os.Open(config.GetCalicoVppInitialConfig().IfConfigSavePath)
188-
if err != nil {
189-
return nil, errors.Wrap(err, "error opening save file")
190-
}
191-
dec := gob.NewDecoder(file)
192-
err = dec.Decode(&conf)
193-
if err != nil {
194-
return nil, errors.Wrap(err, "decode error")
195-
}
196-
file.Close()
197-
return conf, nil
198-
}

0 commit comments

Comments
 (0)