in cmd/routed-eni-cni-plugin/driver/driver.go [382:470]
func (os *linuxNetwork) SetupPodENINetwork(hostVethName string, contVethName string, netnsPath string, v4Addr *net.IPNet,
v6Addr *net.IPNet, vlanID int, eniMAC string, subnetGW string, parentIfIndex int, mtu int, log logger.Logger) error {
hostVeth, err := setupVeth(hostVethName, contVethName, netnsPath, v4Addr, v6Addr, os.netLink, os.ns, mtu, os.procSys, log)
if err != nil {
return errors.Wrapf(err, "SetupPodENINetwork failed to setup veth pair.")
}
vlanTableID := vlanID + 100
vlanLink := buildVlanLink(vlanID, parentIfIndex, eniMAC)
// 1a. clean up if vlan already exists (necessary when trunk ENI changes).
if oldVlan, err := os.netLink.LinkByName(vlanLink.Name); err == nil {
if err = os.netLink.LinkDel(oldVlan); err != nil {
return errors.Wrapf(err, "SetupPodENINetwork: failed to delete old vlan %s", vlanLink.Name)
}
log.Debugf("Cleaned up old vlan: %s", vlanLink.Name)
}
// 1b. clean up any previous hostVeth ip rule
oldVlanRule := os.netLink.NewRule()
oldVlanRule.IifName = hostVethName
oldVlanRule.Priority = vlanRulePriority
// loop is required to clean up all existing rules created on the host (when pod with same name are recreated multiple times)
for {
if err := os.netLink.RuleDel(oldVlanRule); err != nil {
if !containsNoSuchRule(err) {
return errors.Wrapf(err, "SetupPodENINetwork: failed to delete hostveth rule for %s", hostVeth.Attrs().Name)
}
break
}
}
// 2. add new vlan link
err = os.netLink.LinkAdd(vlanLink)
if err != nil {
return errors.Wrapf(err, "SetupPodENINetwork: failed to add vlan link.")
}
// 3. bring up the vlan
if err = os.netLink.LinkSetUp(vlanLink); err != nil {
return errors.Wrapf(err, "SetupPodENINetwork: failed to set link %q up", vlanLink.Name)
}
// 4. create default routes for vlan
routes := buildRoutesForVlan(vlanTableID, vlanLink.Index, net.ParseIP(subnetGW))
for _, r := range routes {
if err := os.netLink.RouteReplace(&r); err != nil {
return errors.Wrapf(err, "SetupPodENINetwork: unable to replace route entry %s via %s", r.Dst.IP.String(), subnetGW)
}
}
var addr *net.IPNet
if v4Addr != nil {
addr = v4Addr
} else if v6Addr != nil {
addr = v6Addr
}
// 5. create route entry for hostveth.
route := netlink.Route{
LinkIndex: hostVeth.Attrs().Index,
Scope: netlink.SCOPE_LINK,
Dst: addr,
Table: vlanTableID,
}
if err := os.netLink.RouteReplace(&route); err != nil {
return errors.Wrapf(err, "SetupPodENINetwork: unable to add or replace route entry for %s", route.Dst.IP.String())
}
log.Debugf("Successfully set host route to be %s/0", route.Dst.IP.String())
// 6. Add ip rules for the pod.
vlanRule := os.netLink.NewRule()
vlanRule.Table = vlanTableID
vlanRule.Priority = vlanRulePriority
vlanRule.IifName = vlanLink.Name
err = os.netLink.RuleAdd(vlanRule)
if err != nil && !isRuleExistsError(err) {
return errors.Wrapf(err, "SetupPodENINetwork: unable to add ip rule for vlan link %s ", vlanLink.Name)
}
vlanRule.IifName = hostVeth.Attrs().Name
err = os.netLink.RuleAdd(vlanRule)
if err != nil && !isRuleExistsError(err) {
return errors.Wrapf(err, "SetupPodENINetwork: unable to add ip rule for host veth %s", hostVethName)
}
return nil
}