Added support for multiple IPv4 addresses and routes

This commit is contained in:
Onur Filiz 2016-12-12 16:03:10 -08:00
Родитель 9b63cd3635
Коммит 0e13965ced
3 изменённых файлов: 69 добавлений и 36 удалений

Просмотреть файл

@ -151,10 +151,18 @@ func (plugin *netPlugin) Add(args *cniSkel.CmdArgs) error {
// Create the endpoint.
epInfo := &network.EndpointInfo{
Id: endpointId,
IfName: args.IfName,
IPv4Address: result.IP4.IP,
NetNsPath: args.Netns,
Id: endpointId,
IfName: args.IfName,
NetNsPath: args.Netns,
}
// Populate addresses and routes.
if result.IP4 != nil {
epInfo.IPAddresses = append(epInfo.IPAddresses, result.IP4.IP)
for _, route := range result.IP4.Routes {
epInfo.Routes = append(epInfo.Routes, network.RouteInfo{Dst: route.Dst, Gw: route.GW})
}
}
err = plugin.nm.CreateEndpoint(networkId, epInfo)
@ -210,13 +218,15 @@ func (plugin *netPlugin) Delete(args *cniSkel.CmdArgs) error {
return nil
}
// Call into IPAM plugin to release the endpoint's address.
// Call into IPAM plugin to release the endpoint's addresses.
nwCfg.Ipam.Subnet = nwInfo.Subnets[0]
nwCfg.Ipam.Address = epInfo.IPv4Address.IP.String()
_, err = cni.CallPlugin(plugin.ipamPlugin, cni.CmdDel, args, nwCfg)
if err != nil {
log.Printf("[cni-net] Failed to release address, err:%v.", err)
return nil
for _, address := range epInfo.IPAddresses {
nwCfg.Ipam.Address = address.IP.String()
_, err = cni.CallPlugin(plugin.ipamPlugin, cni.CmdDel, args, nwCfg)
if err != nil {
log.Printf("[cni-net] Failed to release address, err:%v.", err)
return nil
}
}
log.Printf("[cni-net] DEL succeeded.")

Просмотреть файл

@ -203,7 +203,7 @@ func (plugin *netPlugin) createEndpoint(w http.ResponseWriter, r *http.Request)
epInfo := network.EndpointInfo{
Id: req.EndpointID,
IPv4Address: *ipv4Address,
IPAddresses: []net.IPNet{*ipv4Address},
}
err = plugin.nm.CreateEndpoint(req.NetworkID, &epInfo)
@ -273,8 +273,7 @@ func (plugin *netPlugin) join(w http.ResponseWriter, r *http.Request) {
resp := joinResponse{
InterfaceName: ifname,
Gateway: ep.IPv4Gateway.String(),
GatewayIPv6: ep.IPv6Gateway.String(),
Gateway: ep.Gateways[0].String(),
}
err = plugin.Listener.Encode(w, &resp)

Просмотреть файл

@ -27,10 +27,8 @@ type endpoint struct {
IfName string
HostIfName string
MacAddress net.HardwareAddr
IPv4Address net.IPNet
IPv6Address net.IPNet
IPv4Gateway net.IP
IPv6Gateway net.IP
IPAddresses []net.IPNet
Gateways []net.IP
}
// EndpointInfo contains read-only information about an endpoint.
@ -38,7 +36,14 @@ type EndpointInfo struct {
Id string
IfName string
NetNsPath string
IPv4Address net.IPNet
IPAddresses []net.IPNet
Routes []RouteInfo
}
// RouteInfo contains information about an IP route.
type RouteInfo struct {
Dst net.IPNet
Gw net.IP
}
// NewEndpoint creates a new endpoint in the network.
@ -54,8 +59,6 @@ func (nw *network) newEndpoint(epInfo *EndpointInfo) (*endpoint, error) {
return nil, errEndpointExists
}
ipAddr := epInfo.IPv4Address
// Create a veth pair.
hostIfName := fmt.Sprintf("%s%s", hostInterfacePrefix, epInfo.Id[:7])
contIfName := fmt.Sprintf("%s%s-2", hostInterfacePrefix, epInfo.Id[:7])
@ -97,9 +100,11 @@ func (nw *network) newEndpoint(epInfo *EndpointInfo) (*endpoint, error) {
// Setup MAC address translation rules for container interface.
log.Printf("[net] Setting up MAC address translation rules for endpoint %v.", contIfName)
err = ebtables.SetupDnatBasedOnIPV4Address(ipAddr.IP.String(), containerIf.HardwareAddr.String())
if err != nil {
goto cleanup
for _, ipAddr := range epInfo.IPAddresses {
err = ebtables.SetupDnatBasedOnIPV4Address(ipAddr.IP.String(), containerIf.HardwareAddr.String())
if err != nil {
goto cleanup
}
}
// If a network namespace for the container interface is specified...
@ -153,10 +158,29 @@ func (nw *network) newEndpoint(epInfo *EndpointInfo) (*endpoint, error) {
}
// Assign IP address to container network interface.
log.Printf("[net] Adding IP address %v to link %v.", ipAddr.String(), contIfName)
err = netlink.AddIpAddress(contIfName, ipAddr.IP, &ipAddr)
if err != nil {
goto cleanup
for _, ipAddr := range epInfo.IPAddresses {
log.Printf("[net] Adding IP address %v to link %v.", ipAddr.String(), contIfName)
err = netlink.AddIpAddress(contIfName, ipAddr.IP, &ipAddr)
if err != nil {
goto cleanup
}
}
// Add IP routes to container network interface.
for _, route := range epInfo.Routes {
log.Printf("[net] Adding IP route %+v to link %v.", route, contIfName)
nlRoute := &netlink.Route{
Family: netlink.GetIpAddressFamily(route.Gw),
Dst: &route.Dst,
Gw: route.Gw,
LinkIndex: containerIf.Index,
}
err = netlink.AddIpRoute(nlRoute)
if err != nil {
goto cleanup
}
}
// If inside the container network namespace...
@ -175,10 +199,8 @@ func (nw *network) newEndpoint(epInfo *EndpointInfo) (*endpoint, error) {
IfName: contIfName,
HostIfName: hostIfName,
MacAddress: containerIf.HardwareAddr,
IPv4Address: ipAddr,
IPv6Address: net.IPNet{},
IPv4Gateway: nw.extIf.IPv4Gateway,
IPv6Gateway: nw.extIf.IPv6Gateway,
IPAddresses: epInfo.IPAddresses,
Gateways: []net.IP{nw.extIf.IPv4Gateway},
}
nw.Endpoints[epInfo.Id] = ep
@ -216,10 +238,12 @@ func (nw *network) deleteEndpoint(endpointId string) error {
}
// Delete MAC address translation rule.
log.Printf("[net] Deleting MAC address translation rule for endpoint %v.", endpointId)
err = ebtables.RemoveDnatBasedOnIPV4Address(ep.IPv4Address.IP.String(), ep.MacAddress.String())
if err != nil {
goto cleanup
log.Printf("[net] Deleting MAC address translation rules for endpoint %v.", endpointId)
for _, ipAddr := range ep.IPAddresses {
err = ebtables.RemoveDnatBasedOnIPV4Address(ipAddr.IP.String(), ep.MacAddress.String())
if err != nil {
goto cleanup
}
}
// Remove the endpoint object.
@ -254,7 +278,7 @@ func (nw *network) getEndpoint(endpointId string) (*endpoint, error) {
func (ep *endpoint) getInfo() *EndpointInfo {
info := &EndpointInfo{
Id: ep.Id,
IPv4Address: ep.IPv4Address,
IPAddresses: ep.IPAddresses,
}
return info