Skip to content

Commit 57adcec

Browse files
Merge pull request #95 from qiangzii/master
fix route and ip addr renew period for vlan
2 parents 58befa1 + 01c9731 commit 57adcec

File tree

4 files changed

+64
-17
lines changed

4 files changed

+64
-17
lines changed

pkg/allocator/allocator.go

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -311,14 +311,18 @@ func (a *Allocator) IPAddrReNew() {
311311
defer a.lock.Unlock()
312312

313313
for _, nic := range a.nics {
314-
nicKey := getNicKey(nic.Nic)
315-
if nic.isOK() && nic.Nic.VxNet.TunnelType == qcclient.TunnelTypeVlan {
316-
// renew ip lease
317-
err := networkutils.UpdateLinkIPAddrAndLease(nic.Nic)
318-
if err != nil {
319-
log.Errorf("update hostNic %s bridge ip addr lease error: %v", nicKey, err)
314+
if nic != nil {
315+
nicKey := getNicKey(nic.Nic)
316+
if nic.isOK() && nic.Nic.VxNet.TunnelType == constants.TunnelTypeVlan {
317+
brName := constants.GetHostNicBridgeName(int(nic.Nic.RouteTableNum))
318+
// renew ip lease
319+
err := networkutils.UpdateLinkIPAddrAndLease(nic.Nic)
320+
if err != nil {
321+
log.Errorf("renew hostNic %s bridge %s ip addr lease error: %v", nicKey, brName, err)
322+
} else {
323+
log.Infof("renew hostNic %s bridge %s ip addr lease success!", nicKey, brName)
324+
}
320325
}
321-
log.Infof("update hostNic %s bridge ip addr lease success!", nicKey)
322326
}
323327
}
324328
}
@@ -405,7 +409,7 @@ func (a *Allocator) getVxnetMaxNicNum() int {
405409
func (a *Allocator) run(stopCh <-chan struct{}) {
406410
jobTimer := time.NewTicker(time.Duration(a.conf.Sync) * time.Second).C
407411
freeTimer := time.NewTicker(time.Duration(a.conf.FreePeriod) * time.Minute).C
408-
ipAddrReNewTimer := time.NewTicker(time.Duration(1) * time.Hour).C
412+
409413
for {
410414
select {
411415
case <-stopCh:
@@ -417,7 +421,7 @@ func (a *Allocator) run(stopCh <-chan struct{}) {
417421
case <-freeTimer:
418422
log.Infof("period free sync")
419423
a.ClearFreeHostnic(false)
420-
case <-ipAddrReNewTimer:
424+
case <-constants.IpAddrReNewTicker.C:
421425
log.Infof("ip addr renew sync")
422426
a.IPAddrReNew()
423427
}

pkg/constants/types.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"errors"
2323
"fmt"
2424
"strings"
25+
"time"
2526

2627
"github.com/containernetworking/cni/pkg/types"
2728
"github.com/yunify/hostnic-cni/pkg/rpc"
@@ -88,6 +89,11 @@ const (
8889
EventDelete = "delete"
8990

9091
MetricsDummyNamespaceForSubnet = "Dummy-ns-for-unmapped-subnets"
92+
93+
TunnelTypeVlan = "vlan"
94+
95+
RouteExistsError = "file exists"
96+
RouteNotExistsError = "no such process"
9197
)
9298

9399
func GetHostNicBridgeName(routeTableNum int) string {
@@ -149,4 +155,7 @@ type K8sArgs struct {
149155
var (
150156
ErrNoAvailableNIC = errors.New("no free nic")
151157
ErrNicNotFound = errors.New("hostnic not found")
158+
159+
LastIPAddrRenewPeriod = 60 * 60 * time.Second //s, default 1h
160+
IpAddrReNewTicker = time.NewTicker(LastIPAddrRenewPeriod)
152161
)

pkg/networkutils/networkutil.go

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
"net"
77
"os"
88
"os/exec"
9+
"strings"
10+
"time"
911

1012
"github.com/containernetworking/plugins/pkg/ns"
1113
"github.com/containernetworking/plugins/pkg/utils/sysctl"
@@ -221,13 +223,14 @@ func (n NetworkUtils) setupBridgeNetwork(link netlink.Link, brName, tunnelType s
221223
if err != nil {
222224
return fmt.Errorf("failed to set link %s up: %v", la.Name, err)
223225
}
224-
if tunnelType == qcclient.TunnelTypeVlan {
226+
if tunnelType == constants.TunnelTypeVlan {
225227
// get an ip addr and add to br
226228
// 1.get an ip addr from dhcp server
227229
bootConf, err := getIPAddrFromDHCPServer(brName)
228230
if err != nil {
229231
return fmt.Errorf("failed to get ip address for link %s: %v", brName, err)
230232
}
233+
klog.Infof("get ip addr %+v success from dhcp server for link %s", bootConf.Addresses, brName)
231234

232235
// 2. replace addr to br
233236
err = replaceLinkIPAddr(br, bootConf.Addresses)
@@ -282,9 +285,21 @@ func (n NetworkUtils) setupRouteTable(nic *rpc.HostNic) error {
282285
},
283286
}
284287

285-
for _, r := range routes {
286-
if err := netlink.RouteAdd(&r); err != nil && !os.IsExist(err) {
287-
return fmt.Errorf("failed to add route %v: %v", r, err)
288+
// if tunnel type is vlan, clear route to repair hostnic
289+
if nic.VxNet.TunnelType == constants.TunnelTypeVlan {
290+
for _, r := range routes {
291+
// netlink.RouteDel return error if route not exists: no such process
292+
if err := netlink.RouteDel(&r); err != nil && !strings.Contains(err.Error(), constants.RouteNotExistsError) {
293+
return fmt.Errorf("failed to del route %v: %v", r, err)
294+
}
295+
}
296+
297+
} else {
298+
for _, r := range routes {
299+
// netlink.RouteAdd return error if route already exists: file exists ; shouldn't use os.IsExist here
300+
if err := netlink.RouteAdd(&r); err != nil && !strings.Contains(err.Error(), constants.RouteExistsError) {
301+
return fmt.Errorf("failed to add route %v: %v", r, err)
302+
}
288303
}
289304
}
290305

@@ -410,7 +425,11 @@ func ExecuteCommand(command string) (string, error) {
410425
}
411426

412427
func getIPAddrFromDHCPServer(ifname string) (*netboot.BootConf, error) {
413-
client := client4.NewClient()
428+
// client := client4.NewClient()
429+
client := &client4.Client{
430+
ReadTimeout: client4.DefaultReadTimeout * 5,
431+
WriteTimeout: client4.DefaultWriteTimeout * 5,
432+
}
414433
conv, err := client.Exchange(ifname)
415434
if err != nil {
416435
return nil, fmt.Errorf("dhcp client exchange error: %v", err)
@@ -424,11 +443,19 @@ func getIPAddrFromDHCPServer(ifname string) (*netboot.BootConf, error) {
424443
}
425444

426445
func replaceLinkIPAddr(link netlink.Link, addres []netboot.AddrConf) error {
446+
var shortestLeaseTime time.Duration
427447
ifName := link.Attrs().Name
428448
if len(addres) < 1 {
429449
return fmt.Errorf("there is no avaliable addr for link %s", ifName)
430450
}
431451
for _, addrConf := range addres {
452+
if shortestLeaseTime.Seconds() == 0 {
453+
shortestLeaseTime = addrConf.ValidLifetime
454+
}
455+
if addrConf.ValidLifetime.Seconds() < shortestLeaseTime.Seconds() {
456+
shortestLeaseTime = addrConf.ValidLifetime
457+
}
458+
432459
addr := &netlink.Addr{
433460
IPNet: &addrConf.IPNet,
434461
ValidLft: int(addrConf.ValidLifetime.Seconds()),
@@ -439,6 +466,13 @@ func replaceLinkIPAddr(link netlink.Link, addres []netboot.AddrConf) error {
439466
return fmt.Errorf("replace addr %+v to link %s error: %v", addr, ifName, err)
440467
}
441468
}
469+
470+
if shortestLeaseTime.Seconds()/2 != constants.LastIPAddrRenewPeriod.Seconds() && shortestLeaseTime != 0 {
471+
klog.Infof("update LastIPAddrRenewPeriod from %v to %v", constants.LastIPAddrRenewPeriod, shortestLeaseTime/2)
472+
constants.LastIPAddrRenewPeriod = shortestLeaseTime / 2
473+
constants.IpAddrReNewTicker.Reset(shortestLeaseTime / 2)
474+
}
475+
442476
return nil
443477
}
444478

@@ -450,9 +484,10 @@ func UpdateLinkIPAddrAndLease(nic *rpc.HostNic) error {
450484

451485
// 1. get an ip form dhcp server
452486
bootConf, err := getIPAddrFromDHCPServer(brName)
453-
if err != nil {
487+
if err != nil || bootConf.Addresses == nil {
454488
return fmt.Errorf("failed to get ip address for link %s: %v", brName, err)
455489
}
490+
klog.Infof("get ip addr %+v success from dhcp server for link %s", bootConf.Addresses, brName)
456491

457492
// 2. replace addr to br
458493
err = replaceLinkIPAddr(br, bootConf.Addresses)

pkg/qcclient/wrapper.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ const (
2828
reservedVIPCount = 12
2929
reservedVIPCountForVlan int64 = 7 //reserve 1/7 ip for hostnic br
3030

31-
TunnelTypeVlan = "vlan"
3231
)
3332

3433
var (
@@ -478,7 +477,7 @@ func (q *qingcloudAPIWrapper) getVxNets(ids []string, public bool) ([]*rpc.VxNet
478477
if qcVxNet.TunnelType != nil {
479478
vxnetItem.TunnelType = *qcVxNet.TunnelType
480479
}
481-
if vxnetItem.TunnelType == TunnelTypeVlan {
480+
if vxnetItem.TunnelType == constants.TunnelTypeVlan {
482481
// parse ip_network to get mask; if mask is 24, reserve more ip than specifc in config
483482
_, ipNet, err := net.ParseCIDR(vxnetItem.Network)
484483
if err != nil {

0 commit comments

Comments
 (0)