Skip to content

Commit

Permalink
feature: enable IPv6 networking
Browse files Browse the repository at this point in the history
* add ipv6 and fixed-cidr-v6 Daemon flag
* add IPv6 validation and integration test

Signed-off-by: Leno Hou <[email protected]>
  • Loading branch information
houstar committed Nov 19, 2018
1 parent 96ea245 commit 33df349
Show file tree
Hide file tree
Showing 8 changed files with 233 additions and 83 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ unit-test: modules plugin ## run go unit-test
done )

.PHONY: integration-test
integration-test: ## run daemon integration-test
integration-test: build-daemon-integration build-integration-test ## run daemon integration-test
@echo $@
@mkdir -p coverage
./hack/testing/run_daemon_integration.sh
Expand Down
14 changes: 7 additions & 7 deletions cli/update_daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ type DaemonUpdateCommand struct {
execRoot string
bridgeName string
bridgeIP string
fixedCIDR string
defaultGateway string
fixedCIDRv4 string
defaultGatewayv4 string
iptables bool
ipforward bool
userlandProxy bool
Expand Down Expand Up @@ -72,8 +72,8 @@ func (udc *DaemonUpdateCommand) addFlags() {
flagSet.StringVar(&udc.execRoot, "exec-root-dir", "", "update exec root directory for network")
flagSet.StringVar(&udc.bridgeName, "bridge-name", "", "update daemon bridge device")
flagSet.StringVar(&udc.bridgeIP, "bip", "", "update daemon bridge IP")
flagSet.StringVar(&udc.fixedCIDR, "fixed-cidr", "", "update daemon bridge fixed CIDR")
flagSet.StringVar(&udc.defaultGateway, "default-gateway", "", "update daemon bridge default gateway")
flagSet.StringVar(&udc.fixedCIDRv4, "fixed-cidr", "", "update daemon bridge fixed CIDR")
flagSet.StringVar(&udc.defaultGatewayv4, "default-gateway", "", "update daemon bridge default gateway")
flagSet.BoolVar(&udc.iptables, "iptables", true, "update daemon with iptables")
flagSet.BoolVar(&udc.ipforward, "ipforward", true, "udpate daemon with ipforward")
flagSet.BoolVar(&udc.userlandProxy, "userland-proxy", false, "update daemon with userland proxy")
Expand Down Expand Up @@ -143,15 +143,15 @@ func (udc *DaemonUpdateCommand) updateDaemonConfigFile() error {
}

if flagSet.Changed("bip") {
daemonConfig.NetworkConfig.BridgeConfig.IP = udc.bridgeIP
daemonConfig.NetworkConfig.BridgeConfig.IPv4 = udc.bridgeIP
}

if flagSet.Changed("fixed-cidr") {
daemonConfig.NetworkConfig.BridgeConfig.FixedCIDR = udc.fixedCIDR
daemonConfig.NetworkConfig.BridgeConfig.FixedCIDRv4 = udc.fixedCIDRv4
}

if flagSet.Changed("default-gateway") {
daemonConfig.NetworkConfig.BridgeConfig.GatewayIPv4 = udc.defaultGateway
daemonConfig.NetworkConfig.BridgeConfig.GatewayIPv4 = udc.defaultGatewayv4
}

if flagSet.Changed("iptables") {
Expand Down
28 changes: 27 additions & 1 deletion daemon/mgr/network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,34 @@ func Test_getIpamConfig(t *testing.T) {
want1: []*libnetwork.IpamConf{},
wantErr: false,
},
{
name: "getIpamConfigIPv6Normal",
args: args{
data: []apitypes.IPAMConfig{
{
AuxAddress: map[string]string{
"foo": "bar",
},
Gateway: "2002:db8:1::1",
IPRange: "2002:db8:1::1/68",
Subnet: "2002:db8:1::1/64",
},
},
},
want: []*libnetwork.IpamConf{},
wantErr: false,
want1: []*libnetwork.IpamConf{
{
PreferredPool: "2002:db8:1::1/64",
SubPool: "2002:db8:1::1/68",
Gateway: "2002:db8:1::1",
AuxAddresses: map[string]string{
"foo": "bar",
},
},
},
},
// TODO: add Invalid IPv4 subnet
// TODO: add IPv6 test

}
for _, tt := range tests {
Expand Down
9 changes: 6 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,12 @@ func setupFlags(cmd *cobra.Command) {
// network config
flagSet.StringVar(&cfg.NetworkConfig.ExecRoot, "exec-root-dir", "", "Set exec root directory for network")
flagSet.StringVar(&cfg.NetworkConfig.BridgeConfig.Name, "bridge-name", "", "Set default bridge name")
flagSet.StringVar(&cfg.NetworkConfig.BridgeConfig.IP, "bip", "", "Set bridge IP")
flagSet.StringVar(&cfg.NetworkConfig.BridgeConfig.GatewayIPv4, "default-gateway", "", "Set default bridge gateway")
flagSet.StringVar(&cfg.NetworkConfig.BridgeConfig.FixedCIDR, "fixed-cidr", "", "Set bridge fixed CIDR")
flagSet.StringVar(&cfg.NetworkConfig.BridgeConfig.IPv4, "bip", "", "Set bridge IP")
flagSet.StringVar(&cfg.NetworkConfig.BridgeConfig.GatewayIPv4, "default-gateway", "", "Set default IPv4 bridge gateway")
flagSet.StringVar(&cfg.NetworkConfig.BridgeConfig.FixedCIDRv4, "fixed-cidr", "", "Set bridge fixed CIDRv4")
flagSet.BoolVar(&cfg.NetworkConfig.BridgeConfig.EnableIPv6, "enable-ipv6", false, "Enable IPv6 networking")
flagSet.StringVar(&cfg.NetworkConfig.BridgeConfig.GatewayIPv6, "default-gateway-v6", "", "Set default IPv6 bridge gateway")
flagSet.StringVar(&cfg.NetworkConfig.BridgeConfig.FixedCIDRv6, "fixed-cidr-v6", "", "Set bridge fixed CIDRv6")
flagSet.IntVar(&cfg.NetworkConfig.BridgeConfig.Mtu, "mtu", 1500, "Set bridge MTU")
flagSet.BoolVar(&cfg.NetworkConfig.BridgeConfig.IPTables, "iptables", true, "Enable iptables")
flagSet.BoolVar(&cfg.NetworkConfig.BridgeConfig.IPForward, "ipforward", true, "Enable ipforward")
Expand Down
7 changes: 5 additions & 2 deletions network/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,12 @@ type Config struct {
// BridgeConfig defines the bridge network configuration.
type BridgeConfig struct {
Name string `json:"bridge-name,omitempty"`
IP string `json:"bip,omitempty"`
FixedCIDR string `json:"fixed-cidr,omitempty"`
IPv4 string `json:"bip,omitempty"`
FixedCIDRv4 string `json:"fixed-cidr,omitempty"`
GatewayIPv4 string `json:"default-gateway,omitempty"`
EnableIPv6 bool `json:"enable-ipv6,omitempty"`
FixedCIDRv6 string `json:"fixed-cidr-v6,omitempty"`
GatewayIPv6 string `json:"default-gateway-v6,omitempty"`
PreferredIP string `json:"preferred-ip,omitempty"`

Mtu int `json:"mtu,omitempty"`
Expand Down
133 changes: 91 additions & 42 deletions network/mode/bridge/bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ import (

// New is used to initialize bridge network.
func New(ctx context.Context, config network.BridgeConfig, manager mgr.NetworkMgr) error {
// TODO: support ipv6.

// clear exist bridge network
if err := manager.Remove(ctx, "bridge"); err != nil {
if !errtypes.IsNotfound(err) {
Expand All @@ -38,62 +36,33 @@ func New(ctx context.Context, config network.BridgeConfig, manager mgr.NetworkMg
}

// get bridge ip
bridgeIP := utils.StringDefault(config.IP, DefaultIPNet)
ipNet, err := netlink.ParseIPNet(bridgeIP)
bridgeIP := utils.StringDefault(config.IPv4, DefaultIPv4Net)
ipv4Net, err := netlink.ParseIPNet(bridgeIP)
if err != nil {
return fmt.Errorf("failed to parse ip %v", bridgeIP)
}
logrus.Debugf("initialize bridge network, bridge ip: %s.", ipNet)
logrus.Debugf("initialize bridge network, bridge ip: %s.", ipv4Net)

// init host bridge network.
_, err = initBridgeDevice(bridgeName, ipNet)
_, err = initBridgeDevice(bridgeName, ipv4Net)
if err != nil {
return err
}

// get bridge subnet
_, subnet, err := net.ParseCIDR(bridgeIP)
if err != nil {
return fmt.Errorf("failted to parse subnet %v", bridgeIP)
}
logrus.Debugf("initialize bridge network, bridge network: %s", subnet)

// get ip range
var ipRange string
if config.FixedCIDR != "" {
ipRange = config.FixedCIDR
} else {
ipRange = subnet.String()
}
logrus.Debugf("initialize bridge network, bridge ip range in subnet: %s", ipRange)

// get gateway
gateway := DefaultGateway
if config.GatewayIPv4 != "" {
gateway = config.GatewayIPv4
}
logrus.Debugf("initialize bridge network, gateway: %s", gateway)

ipamV4Conf := types.IPAMConfig{
AuxAddress: make(map[string]string),
Subnet: subnet.String(),
IPRange: ipRange,
Gateway: gateway,
}

ipam := &types.IPAM{
Driver: "default",
Config: []types.IPAMConfig{ipamV4Conf},
}

mtu := network.DefaultNetworkMtu
if config.Mtu != 0 {
mtu = config.Mtu
}

// create ipam
ipam, err := createIPAM(ctx, config)
if err != nil {
return fmt.Errorf("failed to create IPAM")
}

networkCreate := types.NetworkCreate{
Driver: "bridge",
EnableIPV6: false,
EnableIPV6: config.EnableIPv6,
Internal: false,
Options: map[string]string{
bridge.BridgeName: bridgeName,
Expand All @@ -115,6 +84,86 @@ func New(ctx context.Context, config network.BridgeConfig, manager mgr.NetworkMg
return err
}

func createIPAM(ctx context.Context, config network.BridgeConfig) (*types.IPAM, error) {
// get bridge ip
bridgeIP := utils.StringDefault(config.IPv4, DefaultIPv4Net)
ipv4Net, err := netlink.ParseIPNet(bridgeIP)
if err != nil {
return nil, fmt.Errorf("failed to parse ip %v", bridgeIP)
}
logrus.Debugf("initialize bridge network, bridge ip: %s.", ipv4Net)

// get bridge subnet
_, subnetv4, err := net.ParseCIDR(bridgeIP)
if err != nil {
return nil, fmt.Errorf("failted to parse subnet %v", bridgeIP)
}
logrus.Debugf("initialize bridge network, bridge network: %s", subnetv4)

// get ip range
var ipv4Range string
if config.FixedCIDRv4 != "" {
ipv4Range = config.FixedCIDRv4
} else {
ipv4Range = subnetv4.String()
}
logrus.Debugf("initialize bridge network, bridge ip range in subnet: %s", ipv4Range)

// get gateway
gatewayv4 := DefaultGatewayv4
if config.GatewayIPv4 != "" {
gatewayv4 = config.GatewayIPv4
}
logrus.Debugf("initialize bridge network, gateway: %s", gatewayv4)

ipamV4Conf := types.IPAMConfig{
AuxAddress: make(map[string]string),
Subnet: subnetv4.String(),
IPRange: ipv4Range,
Gateway: gatewayv4,
}

ipam := &types.IPAM{
Driver: "default",
Config: []types.IPAMConfig{ipamV4Conf},
}

if config.EnableIPv6 {
// get ipv6 subnet
FixedCIDRv6 := utils.StringDefault(config.FixedCIDRv6, DefaultIPv6Net)
_, subnetv6, err := net.ParseCIDR(FixedCIDRv6)
if err != nil {
return nil, fmt.Errorf("failted to parse subnet %v", FixedCIDRv6)
}
logrus.Debugf("initialize bridge network, bridge network: %s", subnetv6)

// get ipv6 range
var ipv6Range string
if config.FixedCIDRv6 != "" {
ipv6Range = config.FixedCIDRv6
} else {
ipv6Range = subnetv6.String()
}
logrus.Debugf("initialize bridge network, bridge ip range in subnet: %s", ipv6Range)

gatewayv6 := DefaultGatewayv6
if config.GatewayIPv6 != "" {
gatewayv6 = config.GatewayIPv6
}
logrus.Debugf("initialize bridge network, gateway: %s", gatewayv6)

ipamV6Conf := types.IPAMConfig{
AuxAddress: make(map[string]string),
Subnet: subnetv6.String(),
IPRange: ipv6Range,
Gateway: gatewayv6,
}
ipam.Config = append(ipam.Config, ipamV6Conf)
}

return ipam, nil
}

func containIP(ip net.IPNet, br netlink.Link) bool {
addrs, err := netlink.AddrList(br, netlink.FAMILY_V4)
if err == nil {
Expand Down
21 changes: 15 additions & 6 deletions network/mode/bridge/vars.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,23 @@ const (
// DefaultBridge defines the default bridge name.
DefaultBridge = "p0"

// DefaultIPNet defines the default bridge ip.
DefaultIPNet = "192.168.5.1/24"
// DefaultIPv4Net defines the default bridge ipv4.
DefaultIPv4Net = "192.168.5.1/24"

// DefaultIPRange defines the default bridge ip range in ipam.
DefaultIPRange = "192.168.5.1/24"
// DefaultIPv4Range defines the default bridge ipv4 range in ipam.
DefaultIPv4Range = "192.168.5.1/24"

// DefaultGateway defines the default bridge gateway.
DefaultGateway = "192.168.5.1"
// DefaultGatewayv4 defines the default bridge gateway ipv4.
DefaultGatewayv4 = "192.168.5.1"

// DefaultIPv6Net defines the default bridge ipv6.
DefaultIPv6Net = "2002:db8:1::1/64"

// DefaultIPv6Range defines the default bridge ipv6 range in ipam.
DefaultIPv6Range = "2002:db8:1::1/64"

// DefaultGatewayv6 defines the default bridge gateway ipv6.
DefaultGatewayv6 = "2002:db8:1::1"

// DefaultBindingIP defines the default binding ip.
DefaultBindingIP = "0.0.0.0"
Expand Down
Loading

0 comments on commit 33df349

Please sign in to comment.