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