in plugins/vpc-branch-pat-eni/plugin/commands.go [56:152]
func (plugin *Plugin) Add(args *cniSkel.CmdArgs) error {
// Parse network configuration.
netConfig, err := config.New(args, true)
if err != nil {
log.Errorf("Failed to parse netconfig from args: %v.", err)
return err
}
log.Infof("Executing ADD with netconfig: %+v.", netConfig)
// Derive names from CNI network config.
patNetNSName := fmt.Sprintf(patNetNSNameFormat, netConfig.BranchVlanID)
tapBridgeName := fmt.Sprintf(tapBridgeNameFormat, netConfig.BranchVlanID)
tapLinkName := args.IfName
targetNetNSName := args.Netns
// Search for the target network namespace.
log.Infof("Searching for target netns %s.", targetNetNSName)
targetNetNS, err := netns.GetNetNSByName(targetNetNSName)
if err != nil {
log.Errorf("Failed to find target netns %s.", targetNetNSName)
return err
}
// Create the trunk ENI.
trunk, err := eni.NewTrunk(netConfig.TrunkName, netConfig.TrunkMACAddress, eni.TrunkIsolationModeVLAN)
if err != nil {
log.Errorf("Failed to find trunk interface %s: %v.", netConfig.TrunkName, err)
return err
}
// Search for the PAT network namespace.
log.Infof("Searching for PAT netns %s.", patNetNSName)
patNetNS, err := netns.GetNetNSByName(patNetNSName)
if err != nil {
// This is the first PAT interface request on this VLAN ID.
// Create the PAT network namespace.
branchName := fmt.Sprintf(branchLinkNameFormat, trunk.GetLinkName(), netConfig.BranchVlanID)
// Compute the branch ENI's VPC subnet.
branchSubnetPrefix := vpc.GetSubnetPrefix(&netConfig.BranchIPAddress)
branchSubnet, _ := vpc.NewSubnet(branchSubnetPrefix)
bridgeIPAddress, _ := vpc.GetIPAddressFromString(bridgeIPAddressString)
patNetNS, err = plugin.createPATNetworkNamespace(
patNetNSName, trunk,
branchName, netConfig.BranchMACAddress, netConfig.BranchVlanID,
&netConfig.BranchIPAddress, branchSubnet, bridgeIPAddress)
if err != nil {
log.Errorf("Failed to setup PAT netns %s: %v.", patNetNSName, err)
return err
}
} else {
// Reuse the PAT network namespace that was setup on this VLAN ID during a previous request.
log.Infof("Found PAT netns %s.", patNetNSName)
}
// Create the veth pair in PAT network namespace.
var vethPeerName string
err = patNetNS.Run(func() error {
var verr error
vethPeerName, verr = plugin.createVethPair(
netConfig.BranchVlanID, args.ContainerID, bridgeName, targetNetNS)
return verr
})
if err != nil {
log.Errorf("Failed to create veth pair: %v.", err)
return err
}
// Create the tap link in target network namespace.
log.Infof("Creating tap link %s.", tapLinkName)
err = targetNetNS.Run(func() error {
return plugin.createTapLink(tapBridgeName, vethPeerName, tapLinkName, netConfig.Uid, netConfig.Gid)
})
if err != nil {
log.Errorf("Failed to create tap link: %v.", err)
return err
}
// Generate CNI result.
// IP addresses, routes and DNS are configured by VPC DHCP servers.
result := &cniTypesCurrent.Result{
Interfaces: []*cniTypesCurrent.Interface{
{
Name: tapLinkName,
Mac: netConfig.BranchMACAddress.String(),
Sandbox: targetNetNSName,
},
},
}
log.Infof("Writing CNI result to stdout: %+v.", result)
return cniTypes.PrintResult(result, netConfig.CNIVersion)
}