// testIPVS adds all of the services and destinations provided via the testing // table, then gets all of the services and destinations from IPVS before // comparing and reporting on the result. If everything worked correctly we // should end up with an exact match between what we added and what we got back // from IPVS. func testIPVS() { log.Println("Testing IPVS...") // Make sure we have a clean slate. if err := ipvs.Flush(); err != nil { log.Fatalf("Failed to flush IPVS table: %v\n", err) } // Add the test services and destinations to IPVS. log.Println("Adding services and destinations...") for _, test := range ipvsTests { svc := test.service log.Println(test.desc) log.Printf("=> Adding service %s\n", svc) svc.Destinations = nil for i := range test.destinations { dst := &test.destinations[i] log.Printf("--> Destination %s\n", dst) svc.Destinations = append(svc.Destinations, dst) } if err := ipvs.AddService(svc); err != nil { log.Fatalf("ipvs.AddService() failed: %v\n", err) } } // Get the services from IPVS and compare to what we added. Note that // the order of the returned services and destinations are not // guaranteed to match the order in which they were added. log.Println("Getting services from IPVS...") svcs, err := ipvs.GetServices() if err != nil { log.Fatalf("ipvs.GetServices() failed: %v\n", err) } if len(ipvsTests) != len(svcs) { log.Printf("ERROR: Added %d services but got %d!\n", len(ipvsTests), len(svcs)) } for _, test := range ipvsTests { svc := compareSvc(&test.service, svcs) if svc == nil { continue } if len(test.destinations) != len(svc.Destinations) { log.Printf("ERROR: Added %d destinations by got %d!\n", len(test.destinations), len(svc.Destinations)) } for _, testDst := range test.destinations { compareDst(&testDst, svc.Destinations) } } }
func main() { if err := ipvs.Init(); err != nil { log.Fatalf("IPVS initialisation failed: %v\n", err) } log.Printf("IPVS version %s\n", ipvs.Version()) testIPVS() testIPVSModification() // Clean up after ourselves... if err := ipvs.Flush(); err != nil { log.Fatalf("Failed to flush IPVS table: %v\n", err) } }
// IPVSFlush flushes all services and destinations from the IPVS table. func (ncc *SeesawNCC) IPVSFlush(in int, out *int) error { ipvsMutex.Lock() defer ipvsMutex.Unlock() return ipvs.Flush() }
// testIPVSModification adds, updates and deletes services and destinations // from the test configurations. At each step the service or destination is // retrieved from IPVS and compared against what should be configured. func testIPVSModification() { log.Println("Testing IPVS modifications...") // Make sure we have a clean slate. if err := ipvs.Flush(); err != nil { log.Fatalf("Failed to flush IPVS table: %v\n", err) } for _, test := range ipvsTests { var svc *ipvs.Service var err error testSvc := test.service testDst := test.destinations[0] // Add service. log.Printf("=> Adding service %s\n", testSvc) if err = ipvs.AddService(testSvc); err != nil { log.Fatalf("ipvs.AddService() failed: %v\n", err) } if svc, err = ipvs.GetService(&testSvc); err != nil { log.Fatalf("ipvs.GetService() failed: %v\n", err) } compareSvc(&testSvc, []*ipvs.Service{svc}) // Add destination. log.Printf("--> Adding destination %s\n", testDst) if err = ipvs.AddDestination(testSvc, testDst); err != nil { log.Fatalf("ipvs.AddDestination() failed: %v\n", err) } if svc, err = ipvs.GetService(&testSvc); err != nil { log.Fatalf("ipvs.GetService() failed: %v\n", err) } compareSvc(&testSvc, []*ipvs.Service{svc}) compareDst(&testDst, svc.Destinations) // Update service. testSvc.Scheduler = "lc" if err = ipvs.UpdateService(testSvc); err != nil { log.Fatalf("ipvs.UpdateService() failed: %v\n", err) } if svc, err = ipvs.GetService(&testSvc); err != nil { log.Fatalf("ipvs.GetService() failed: %v\n", err) } compareSvc(&testSvc, []*ipvs.Service{svc}) compareDst(&testDst, svc.Destinations) // Update destination. testDst.Weight = 1000 if err = ipvs.UpdateDestination(testSvc, testDst); err != nil { log.Fatalf("ipvs.UpdateDestination() failed: %v\n", err) } if svc, err = ipvs.GetService(&testSvc); err != nil { log.Fatalf("ipvs.GetService() failed: %v\n", err) } compareSvc(&testSvc, []*ipvs.Service{svc}) compareDst(&testDst, svc.Destinations) // Delete destination. if err = ipvs.DeleteDestination(testSvc, testDst); err != nil { log.Fatalf("ipvs.DeleteDestination() failed: %v\n", err) } if svc, err = ipvs.GetService(&testSvc); err != nil { log.Fatalf("ipvs.GetService() failed: %v\n", err) } if len(svc.Destinations) != 0 { log.Printf("ERROR: Service still has destinations\n") } // Delete service. if err = ipvs.DeleteService(testSvc); err != nil { log.Fatalf("ipvs.DeleteService() failed: %v\n", err) } // Make sure there is nothing left behind. svcs, err := ipvs.GetServices() if err != nil { log.Fatalf("ipvs.GetServices() failed: %v\n", err) } if len(svcs) != 0 { log.Printf("ERROR: IPVS services still exist!\n") for _, svc = range svcs { log.Printf("=> Got service %s\n", svc) } } } }
// Flush flushes all services and destinations from the IPVS table. func (ipvs *Ipvs) Flush() error { return gipvs.Flush() }