Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions calico-vpp-agent/connectivity/connectivity_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ func (s *ConnectivityServer) GetNodeIPs() (ip4 *net.IP, ip6 *net.IP) {
}

func (s *ConnectivityServer) GetNodeIPNet(isv6 bool) *net.IPNet {
if s.nodeBGPSpec == nil {
return nil
}
ip4, ip6 := s.nodeBGPSpec.IPv4Address, s.nodeBGPSpec.IPv6Address
if isv6 {
return ip6
Expand Down
69 changes: 61 additions & 8 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -887,17 +887,52 @@ func (c *LinuxInterfaceState) HasNodeIP4() bool {
return c.getNodeIP(false /* isIP6 */) != nil
}

func (c *LinuxInterfaceState) GetAddresses() []netlink.Addr {
ret := make([]netlink.Addr, 0)
// getUplinkAddressWithMask adapts IPv6 non-link-local host prefixes from /128
// to /64 when TranslateUplinkAddrMaskTo64 is enabled.
func getUplinkAddressWithMask(addr *net.IPNet) *net.IPNet {
if addr == nil || addr.IP == nil || addr.IP.To4() != nil || addr.IP.IsLinkLocalUnicast() {
return addr
}
debugCfg := GetCalicoVppDebug()
if debugCfg == nil || debugCfg.TranslateUplinkAddrMaskTo64 == nil || !*debugCfg.TranslateUplinkAddrMaskTo64 {
return addr
}
ones, bits := addr.Mask.Size()
if bits != 128 || ones != 128 {
return addr
}
return &net.IPNet{
IP: addr.IP,
Mask: net.CIDRMask(64, 128),
}
}

func (c *LinuxInterfaceState) getAddresses(translateMask bool) []netlink.Addr {
ret := make([]netlink.Addr, 0, len(c.addresses))
for _, addr := range c.addresses {
if addr.IP.IsLinkLocalUnicast() && isV6Cidr(addr.IPNet) {
continue
}
if translateMask {
addr.IPNet = getUplinkAddressWithMask(addr.IPNet)
}
ret = append(ret, addr)
}
return ret
}

// GetAddressesNoMaskTranslation returns non-link-local addresses exactly as
// discovered on Linux, without IPv6 /128 -> /64 adjustment.
func (c *LinuxInterfaceState) GetAddressesNoMaskTranslation() []netlink.Addr {
return c.getAddresses(false /* translateMask */)
}

// GetAddresses returns non-link-local addresses, applying optional IPv6
// /128 -> /64 translation for non-link-local addresses.
func (c *LinuxInterfaceState) GetAddresses() []netlink.Addr {
return c.getAddresses(true /* translateMask */)
}

func (c *LinuxInterfaceState) GetIPv6LinkLocal() *netlink.Addr {
for _, addr := range c.addresses {
if addr.IP.IsLinkLocalUnicast() && isV6Cidr(addr.IPNet) {
Expand All @@ -918,13 +953,31 @@ func (c *LinuxInterfaceState) GetRoutes() []netlink.Route {
return ret
}

func (c *LinuxInterfaceState) getNodeIP(isIP6 bool) *net.IPNet {
for _, addr := range c.GetAddresses() {
if vpplink.IsIP6(addr.IP) == isIP6 {
return addr.IPNet
func (c *LinuxInterfaceState) getNodeIPs() (ip4, ip6 *net.IPNet) {
for _, addr := range c.addresses {
if addr.IP.IsLinkLocalUnicast() && isV6Cidr(addr.IPNet) {
continue
}
if vpplink.IsIP6(addr.IP) {
if ip6 == nil {
ip6 = getUplinkAddressWithMask(addr.IPNet)
}
} else if ip4 == nil {
ip4 = addr.IPNet
}
if ip4 != nil && ip6 != nil {
break
}
}
return nil
return ip4, ip6
}

func (c *LinuxInterfaceState) getNodeIP(isIP6 bool) *net.IPNet {
ip4, ip6 := c.getNodeIPs()
if isIP6 {
return ip6
}
return ip4
}

func (c *LinuxInterfaceState) GetNodeIP6() string {
Expand All @@ -943,7 +996,7 @@ func (c *LinuxInterfaceState) GetNodeIP4() string {

func (c *LinuxInterfaceState) GetAddressesAsIPNet() []*net.IPNet {
ret := make([]*net.IPNet, 0)
for _, addr := range c.addresses {
for _, addr := range c.GetAddresses() {
ret = append(ret, addr.IPNet)
}
return ret
Expand Down
4 changes: 2 additions & 2 deletions vpp-manager/uplink/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ func (d *UplinkDriverData) removeLinuxIfConf(setIfDown bool) {
}
}
// Remove addresses to not have them conflict with vpptap0
for _, addr := range d.conf.GetAddresses() {
for _, addr := range d.conf.GetAddressesNoMaskTranslation() {
err := netlink.AddrDel(link, &addr)
if err != nil {
log.Errorf("Error removing address %s from tap interface : %+v", addr, err)
Expand All @@ -148,7 +148,7 @@ func (d *UplinkDriverData) restoreLinuxIfConf(link netlink.Link) {
if err != nil {
log.Errorf("Cannot restore mtu to %d: %v", d.conf.Mtu, err)
}
for _, addr := range d.conf.GetAddresses() {
for _, addr := range d.conf.GetAddressesNoMaskTranslation() {
log.Infof("restoring address %s", addr.String())
err := netlink.AddrAdd(link, &addr)
if err != nil {
Expand Down
34 changes: 7 additions & 27 deletions vpp-manager/vpp_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,26 +50,6 @@ type VppRunner struct {
uplinkDriver []uplink.UplinkDriver
}

// getUplinkAddressWithMask will update the mask of an ipv6 address
// and set it from /128 to /64 if the option 'TranslateUplinkAddrMaskTo64' is set
// this will not update Link-local addresses
func getUplinkAddressWithMask(addr *net.IPNet) *net.IPNet {
if addr == nil || addr.IP == nil || addr.IP.To4() != nil || addr.IP.IsLinkLocalUnicast() {
return addr
}
if !*config.GetCalicoVppDebug().TranslateUplinkAddrMaskTo64 {
return addr
}
ones, _ := addr.Mask.Size()
if ones != 128 {
return addr
}
return &net.IPNet{
IP: addr.IP,
Mask: net.CIDRMask(64, 128),
}
}

func NewVPPRunner(params *config.VppManagerParams, confs []*config.LinuxInterfaceState) *VppRunner {
return &VppRunner{
params: params,
Expand Down Expand Up @@ -181,7 +161,7 @@ func (v *VppRunner) configureGlobalPunt() (err error) {
// traffic 'for me' received on the PHY and on the pods in this node
// will end up here.
func (v *VppRunner) configurePunt(tapSwIfIndex uint32, ifState config.LinuxInterfaceState) (err error) {
for _, addr := range ifState.GetAddresses() {
for _, addr := range ifState.GetAddressesNoMaskTranslation() {
err = v.vpp.RouteAdd(&types.Route{
Table: common.PuntTableID,
Dst: addr.IPNet,
Expand Down Expand Up @@ -306,7 +286,7 @@ func (v *VppRunner) pickNextHopIP(ifState config.LinuxInterfaceState) (fakeNextH
foundV4, foundV6 := false, false
needsV4, needsV6 := false, false

for _, addr := range ifState.GetAddresses() {
for _, addr := range ifState.GetAddressesNoMaskTranslation() {
if addr.IP.To4() != nil {
needsV4 = true
} else {
Expand Down Expand Up @@ -392,7 +372,7 @@ func (v *VppRunner) configureLinuxTap(link netlink.Link, ifState config.LinuxInt
}
}
// Configure original addresses and routes on the new tap
for _, addr := range ifState.GetAddresses() {
for _, addr := range ifState.GetAddressesNoMaskTranslation() {
log.Infof("Adding address %+v to tap interface", addr)
err = netlink.AddrAdd(link, &addr)
if err == syscall.EEXIST {
Expand Down Expand Up @@ -529,7 +509,7 @@ func (v *VppRunner) setupTapVRF(ifSpec *config.UplinkInterfaceSpec, ifState *con
}
vrfs = append(vrfs, vrfID)

for _, addr := range ifState.GetAddresses() {
for _, addr := range ifState.GetAddressesNoMaskTranslation() {
if vpplink.IPFamilyFromIP(addr.IP) == ipFamily {
err = v.vpp.RouteAdd(&types.Route{
Table: vrfID,
Expand Down Expand Up @@ -632,10 +612,10 @@ func (v *VppRunner) configureVppUplinkInterface(
}

for _, addr := range ifState.GetAddresses() {
log.Infof("Adding address %s to uplink interface", getUplinkAddressWithMask(addr.IPNet).String())
err = v.vpp.AddInterfaceAddress(ifSpec.SwIfIndex, getUplinkAddressWithMask(addr.IPNet))
log.Infof("Adding address %s to uplink interface", addr.IPNet.String())
err = v.vpp.AddInterfaceAddress(ifSpec.SwIfIndex, addr.IPNet)
if err != nil {
return errors.Wrapf(err, "Error adding address %s to uplink interface", getUplinkAddressWithMask(addr.IPNet))
return errors.Wrapf(err, "Error adding address %s to uplink interface", addr.IPNet)
}
}
for _, route := range ifState.GetRoutes() {
Expand Down
Loading