github.com/adityamillind98/moby@v23.0.0-rc.4+incompatible/libnetwork/drivers/macvlan/macvlan_joinleave.go (about) 1 //go:build linux 2 // +build linux 3 4 package macvlan 5 6 import ( 7 "fmt" 8 "net" 9 10 "github.com/docker/docker/libnetwork/driverapi" 11 "github.com/docker/docker/libnetwork/netutils" 12 "github.com/docker/docker/libnetwork/ns" 13 "github.com/docker/docker/libnetwork/osl" 14 "github.com/sirupsen/logrus" 15 ) 16 17 // Join method is invoked when a Sandbox is attached to an endpoint. 18 func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error { 19 defer osl.InitOSContext()() 20 n, err := d.getNetwork(nid) 21 if err != nil { 22 return err 23 } 24 endpoint := n.endpoint(eid) 25 if endpoint == nil { 26 return fmt.Errorf("could not find endpoint with id %s", eid) 27 } 28 // generate a name for the iface that will be renamed to eth0 in the sbox 29 containerIfName, err := netutils.GenerateIfaceName(ns.NlHandle(), vethPrefix, vethLen) 30 if err != nil { 31 return fmt.Errorf("error generating an interface name: %s", err) 32 } 33 // create the netlink macvlan interface 34 vethName, err := createMacVlan(containerIfName, n.config.Parent, n.config.MacvlanMode) 35 if err != nil { 36 return err 37 } 38 // bind the generated iface name to the endpoint 39 endpoint.srcName = vethName 40 ep := n.endpoint(eid) 41 if ep == nil { 42 return fmt.Errorf("could not find endpoint with id %s", eid) 43 } 44 // parse and match the endpoint address with the available v4 subnets 45 if !n.config.Internal { 46 if len(n.config.Ipv4Subnets) > 0 { 47 s := n.getSubnetforIPv4(ep.addr) 48 if s == nil { 49 return fmt.Errorf("could not find a valid ipv4 subnet for endpoint %s", eid) 50 } 51 v4gw, _, err := net.ParseCIDR(s.GwIP) 52 if err != nil { 53 return fmt.Errorf("gateway %s is not a valid ipv4 address: %v", s.GwIP, err) 54 } 55 err = jinfo.SetGateway(v4gw) 56 if err != nil { 57 return err 58 } 59 logrus.Debugf("Macvlan Endpoint Joined with IPv4_Addr: %s, Gateway: %s, MacVlan_Mode: %s, Parent: %s", 60 ep.addr.IP.String(), v4gw.String(), n.config.MacvlanMode, n.config.Parent) 61 } 62 // parse and match the endpoint address with the available v6 subnets 63 if len(n.config.Ipv6Subnets) > 0 { 64 s := n.getSubnetforIPv6(ep.addrv6) 65 if s == nil { 66 return fmt.Errorf("could not find a valid ipv6 subnet for endpoint %s", eid) 67 } 68 v6gw, _, err := net.ParseCIDR(s.GwIP) 69 if err != nil { 70 return fmt.Errorf("gateway %s is not a valid ipv6 address: %v", s.GwIP, err) 71 } 72 err = jinfo.SetGatewayIPv6(v6gw) 73 if err != nil { 74 return err 75 } 76 logrus.Debugf("Macvlan Endpoint Joined with IPv6_Addr: %s Gateway: %s MacVlan_Mode: %s, Parent: %s", 77 ep.addrv6.IP.String(), v6gw.String(), n.config.MacvlanMode, n.config.Parent) 78 } 79 } else { 80 if len(n.config.Ipv4Subnets) > 0 { 81 logrus.Debugf("Macvlan Endpoint Joined with IPv4_Addr: %s, MacVlan_Mode: %s, Parent: %s", 82 ep.addr.IP.String(), n.config.MacvlanMode, n.config.Parent) 83 } 84 if len(n.config.Ipv6Subnets) > 0 { 85 logrus.Debugf("Macvlan Endpoint Joined with IPv6_Addr: %s MacVlan_Mode: %s, Parent: %s", 86 ep.addrv6.IP.String(), n.config.MacvlanMode, n.config.Parent) 87 } 88 } 89 iNames := jinfo.InterfaceName() 90 err = iNames.SetNames(vethName, containerVethPrefix) 91 if err != nil { 92 return err 93 } 94 if err := d.storeUpdate(ep); err != nil { 95 return fmt.Errorf("failed to save macvlan endpoint %.7s to store: %v", ep.id, err) 96 } 97 return nil 98 } 99 100 // Leave method is invoked when a Sandbox detaches from an endpoint. 101 func (d *driver) Leave(nid, eid string) error { 102 defer osl.InitOSContext()() 103 network, err := d.getNetwork(nid) 104 if err != nil { 105 return err 106 } 107 endpoint, err := network.getEndpoint(eid) 108 if err != nil { 109 return err 110 } 111 if endpoint == nil { 112 return fmt.Errorf("could not find endpoint with id %s", eid) 113 } 114 115 return nil 116 } 117 118 // getSubnetforIP returns the ipv4 subnet to which the given IP belongs 119 func (n *network) getSubnetforIPv4(ip *net.IPNet) *ipv4Subnet { 120 for _, s := range n.config.Ipv4Subnets { 121 _, snet, err := net.ParseCIDR(s.SubnetIP) 122 if err != nil { 123 return nil 124 } 125 // first check if the mask lengths are the same 126 i, _ := snet.Mask.Size() 127 j, _ := ip.Mask.Size() 128 if i != j { 129 continue 130 } 131 if snet.Contains(ip.IP) { 132 return s 133 } 134 } 135 136 return nil 137 } 138 139 // getSubnetforIPv6 returns the ipv6 subnet to which the given IP belongs 140 func (n *network) getSubnetforIPv6(ip *net.IPNet) *ipv6Subnet { 141 for _, s := range n.config.Ipv6Subnets { 142 _, snet, err := net.ParseCIDR(s.SubnetIP) 143 if err != nil { 144 return nil 145 } 146 // first check if the mask lengths are the same 147 i, _ := snet.Mask.Size() 148 j, _ := ip.Mask.Size() 149 if i != j { 150 continue 151 } 152 if snet.Contains(ip.IP) { 153 return s 154 } 155 } 156 157 return nil 158 }