|
| 1 | +package main |
| 2 | + |
| 3 | +import ( |
| 4 | + "fmt" |
| 5 | + "os/exec" |
| 6 | + "strings" |
| 7 | +) |
| 8 | + |
| 9 | +func SetupNetworkBridge(bridgeName string, ethInterface string, tapInterface string, originalIP string) error { |
| 10 | + if err := runCommand("ip", "link", "add", "name", bridgeName, "type", "bridge"); err != nil { |
| 11 | + return fmt.Errorf("failed to create bridge: %v", err) |
| 12 | + } |
| 13 | + |
| 14 | + if err := runCommand("ip", "link", "set", "dev", bridgeName, "up"); err != nil { |
| 15 | + return cleanupBridge(bridgeName, fmt.Errorf("failed to bring bridge up: %v", err)) |
| 16 | + } |
| 17 | + |
| 18 | + if err := runCommand("ip", "link", "set", ethInterface, "master", bridgeName); err != nil { |
| 19 | + return cleanupBridge(bridgeName, fmt.Errorf("failed to add %s to bridge: %v", ethInterface, err)) |
| 20 | + } |
| 21 | + |
| 22 | + if err := runCommand("ip", "link", "set", "dev", ethInterface, "up"); err != nil { |
| 23 | + return cleanupBridge(bridgeName, fmt.Errorf("failed to bring %s up: %v", ethInterface, err)) |
| 24 | + } |
| 25 | + |
| 26 | + if err := runCommand("ip", "tuntap", "add", "dev", tapInterface, "mode", "tap"); err != nil { |
| 27 | + return cleanupBridge(bridgeName, fmt.Errorf("failed to create tap interface: %v", err)) |
| 28 | + } |
| 29 | + |
| 30 | + if err := runCommand("ip", "link", "set", tapInterface, "master", bridgeName); err != nil { |
| 31 | + return cleanupTap(tapInterface, cleanupBridge(bridgeName, |
| 32 | + fmt.Errorf("failed to add tap to bridge: %v", err))) |
| 33 | + } |
| 34 | + |
| 35 | + if err := runCommand("ip", "link", "set", tapInterface, "up"); err != nil { |
| 36 | + return cleanupTap(tapInterface, cleanupBridge(bridgeName, |
| 37 | + fmt.Errorf("failed to bring tap up: %v", err))) |
| 38 | + } |
| 39 | + |
| 40 | + if originalIP != "" { |
| 41 | + if err := runCommand("ip", "addr", "del", originalIP, "dev", ethInterface); err != nil { |
| 42 | + return cleanupTap(tapInterface, cleanupBridge(bridgeName, |
| 43 | + fmt.Errorf("failed to remove IP from %s: %v", ethInterface, err))) |
| 44 | + } |
| 45 | + } |
| 46 | + |
| 47 | + return nil |
| 48 | +} |
| 49 | + |
| 50 | +func runCommand(command string, args ...string) error { |
| 51 | + cmd := exec.Command(command, args...) |
| 52 | + if output, err := cmd.CombinedOutput(); err != nil { |
| 53 | + return fmt.Errorf("%s: %v, output: %s", strings.Join(cmd.Args, " "), err, string(output)) |
| 54 | + } |
| 55 | + return nil |
| 56 | +} |
| 57 | + |
| 58 | +func cleanupBridge(bridgeName string, err error) error { |
| 59 | + _ = runCommand("ip", "link", "del", bridgeName) |
| 60 | + return err |
| 61 | +} |
| 62 | + |
| 63 | +func cleanupTap(tapName string, err error) error { |
| 64 | + _ = runCommand("ip", "link", "del", tapName) |
| 65 | + return err |
| 66 | +} |
0 commit comments