Skip to content

Commit bc25ed8

Browse files
authored
Merge pull request #1040 from ywc689/v1.10.2
V1.10.2-release
2 parents 18114ee + 7a49e72 commit bc25ed8

File tree

13 files changed

+237
-60
lines changed

13 files changed

+237
-60
lines changed

src/VERSION

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,16 @@
11
#!/bin/sh
22
# program: dpvs
3-
# Jan 9, 2025 #
3+
# Jun 12, 2025 #
44
##
55
# Features
6-
# - dpvs: Upgrade dpdk from 20.11 to 24.11.
7-
# - dpvs: Support virtio-user kni implement.
8-
# - dpvs: Remove flow director and replace it with rte_flow completely.
9-
# - dpvs: IPv6 routes support flush and lpm differentiates identical prefix routes on different ports.
6+
# - tools: Implement a brand new Healthcheck that enables vip/vip-port/backend 3-tier topology, and supports flexible actioner/checker configurations for each layer.
107
#
118
# Bugfixes
12-
# - dpvs: Fix packet reception problem caused by TX_OFFLOAD_MBUF_FAST_FREE.
13-
# - dpvs: Fix dropped packet accounting problem caused by ARP replies from kni devices.
14-
# - dpvs: Fix some logging and header including problems.
15-
# - dpvs: Flush addrs and routes when vlan device removed.
16-
# - conf: Fix init attribute for serveral config items.
17-
# - script: Fix directory problems in dpdk build script dpdk-build.sh.
9+
# - dpvs: Fix empty nic bonding offload features.
10+
# - dpvs: Optimize TOA insertion performance by using memmove.
1811
#
1912

2013
export VERSION=1.10
21-
export RELEASE=1
14+
export RELEASE=2
2215

2316
echo $VERSION-$RELEASE

tools/healthcheck/conf/healthcheck.conf.template

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
###### Action Parameters
22
ActionParamsBlank: none
33
ActionParamsBackendUpdate: none
4-
ActionParamsKernelRouteAddDel:
4+
ActionParamsKernelRouteAddDel(Verdict):
55
ifname: string, lo
6+
with-route: string, yes|*no|true|*false
67
ActionParamsDpvsAddrAddDel:
78
dpvs-ifname: string, ""
89
ActionParamsDpvsAddrKernelRouteAddDel:
910
ifname: string, lo
11+
with-route: string, yes|*no|true|*false
1012
dpvs-ifname: string, ""
1113
ActionParamScript:
1214
script: string(filepath), ""
@@ -45,7 +47,7 @@ VACONF:
4547
down-policy: enum(int), VAPolicyOneOf(1)|*VAPolicyAllOf(2)
4648
action-timeout: duration, 2s
4749
action-sync-time: duration, 60s
48-
actioner: enum(string), Blank|*KernelRouteAddDel|DpvsAddrAddDel|DpvsAddrKernelRouteAddDel|Script
50+
actioner: enum(string), Blank|*KernelRouteAddDel(Verdict)|DpvsAddrAddDel|DpvsAddrKernelRouteAddDel|Script
4951
action-params: ActionParamsBlank|ActionParamsKernelRouteAddDel|ActionParamsDpvsAddrAddDel|ActionParamsDpvsAddrKernelRouteAddDel|ActionParamScript
5052

5153
###### Virtual Server Action Configuration

tools/healthcheck/pkg/actioner/actioner.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ type ActionMethod interface {
3737
validate(configs map[string]string) error
3838
}
3939

40+
type ActionMethodWithVerdict interface {
41+
// Verdict checks the real state for an action method.
42+
// It's useful to correct inconsistency when action result can be changed externally.
43+
Verdict(timeout time.Duration) (types.State, error)
44+
}
45+
4046
func registerMethod(name string, method ActionMethod) {
4147
if methods == nil {
4248
methods = make(map[string]ActionMethod)

tools/healthcheck/pkg/actioner/dpvs_addr_add_del.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
package actioner
1818

1919
/*
20-
BackendAction Actioner Params:
20+
DpvsAddrAddDel Actioner Params:
2121
-------------------------------------------------------
2222
name value
2323
-------------------------------------------------------

tools/healthcheck/pkg/actioner/dpvs_addr_kernel_route_add_del.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@
1717
package actioner
1818

1919
/*
20-
BackendAction Actioner Params:
20+
DpvsAddrKernelRouteAddDel Actioner Params:
2121
-------------------------------------------------------
2222
name value
2323
-------------------------------------------------------
2424
ifname linux network interface name
25+
with-route also add a host route
2526
dpvs-ifname dpvs netif port name
2627
2728
-------------------------------------------------------
@@ -101,6 +102,10 @@ func (a *DpvsAddrKernelRouteAction) validate(params map[string]string) error {
101102
return fmt.Errorf("empty action param %s", param)
102103
}
103104
// TODO: check if the interface exists on the system
105+
case "with-route":
106+
if _, err := utils.String2bool(val); err != nil {
107+
return fmt.Errorf("invalid action param %s=%s", param, val)
108+
}
104109
case "dpvs-ifname":
105110
if len(val) == 0 {
106111
return fmt.Errorf("empty action param %s", param)
@@ -126,7 +131,7 @@ func (a *DpvsAddrKernelRouteAction) create(target *utils.L3L4Addr, params map[st
126131
if err := a.validate(params); err != nil {
127132
return nil, fmt.Errorf("%s actioner param validation failed: %v", addrRouteActionerName, err)
128133
}
129-
krtParams := map[string]string{"ifname": params["ifname"]}
134+
krtParams := map[string]string{"ifname": params["ifname"], "with-route": params["with-route"]}
130135
daddrParams := map[string]string{"dpvs-ifname": params["dpvs-ifname"]}
131136

132137
daddrAction, err := a.DpvsAddrAction.create(target, daddrParams, extras...)

tools/healthcheck/pkg/actioner/kernel_route_add_del.go

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@
1717
package actioner
1818

1919
/*
20-
BackendAction Actioner Params:
20+
KernelRouteAddDel Actioner Params:
2121
-------------------------------------------------
2222
name value
2323
-------------------------------------------------
2424
ifname network interface name
25+
with-route also add a host route
2526
2627
-------------------------------------------------
2728
*/
@@ -50,8 +51,9 @@ func init() {
5051
}
5152

5253
type KernelRouteAction struct {
53-
target *utils.L3L4Addr
54-
ifname string
54+
target *utils.L3L4Addr
55+
ifname string
56+
withRoute bool
5557
}
5658

5759
func findLinkByAddr(addr net.IP) (netlink.Link, error) {
@@ -142,14 +144,16 @@ func (a *KernelRouteAction) Act(signal types.State, timeout time.Duration,
142144
}
143145
}
144146

145-
route := netlink.Route{
146-
LinkIndex: link.Attrs().Index,
147-
Dst: ipAddr.IPNet,
148-
}
149-
if err := netlink.RouteAdd(&route); err != nil {
150-
if !isExistError(err) {
151-
done <- fmt.Errorf("failed to add host route %v to %s: %w", addr, a.ifname, err)
152-
return
147+
if a.withRoute {
148+
route := netlink.Route{
149+
LinkIndex: link.Attrs().Index,
150+
Dst: ipAddr.IPNet,
151+
}
152+
if err := netlink.RouteAdd(&route); err != nil {
153+
if !isExistError(err) {
154+
done <- fmt.Errorf("failed to add host route %v to %s: %w", addr, a.ifname, err)
155+
return
156+
}
153157
}
154158
}
155159
} else { // DELETE
@@ -162,18 +166,19 @@ func (a *KernelRouteAction) Act(signal types.State, timeout time.Duration,
162166
}
163167
}
164168

165-
route := netlink.Route{
166-
LinkIndex: link.Attrs().Index,
167-
Dst: ipAddr.IPNet,
168-
}
169-
if err := netlink.RouteDel(&route); err != nil {
170-
if !isNotExistError(err) {
171-
done <- fmt.Errorf("failed to delete route %v from %s: %w", addr, a.ifname, err)
172-
return
169+
if a.withRoute {
170+
route := netlink.Route{
171+
LinkIndex: link.Attrs().Index,
172+
Dst: ipAddr.IPNet,
173+
}
174+
if err := netlink.RouteDel(&route); err != nil {
175+
if !isNotExistError(err) {
176+
done <- fmt.Errorf("failed to delete route %v from %s: %w", addr, a.ifname, err)
177+
return
178+
}
173179
}
174180
}
175181
}
176-
177182
done <- nil
178183
}()
179184

@@ -216,6 +221,10 @@ func (a *KernelRouteAction) validate(params map[string]string) error {
216221
return fmt.Errorf("empty action param %s", param)
217222
}
218223
// TODO: check if the interface exists on the system
224+
case "with-route":
225+
if _, err := utils.String2bool(val); err != nil {
226+
return fmt.Errorf("invalid action param %s=%s", param, val)
227+
}
219228
default:
220229
unsupported = append(unsupported, param)
221230
}
@@ -237,8 +246,10 @@ func (a *KernelRouteAction) create(target *utils.L3L4Addr, params map[string]str
237246
return nil, fmt.Errorf("%s actioner param validation failed: %v", kernelRouteActionerName, err)
238247
}
239248

249+
withRoute, _ := utils.String2bool(params["with-route"])
240250
return &KernelRouteAction{
241-
target: target.DeepCopy(),
242-
ifname: params["ifname"],
251+
target: target.DeepCopy(),
252+
ifname: params["ifname"],
253+
withRoute: withRoute,
243254
}, nil
244255
}
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
// /*
2+
// Copyright 2025 IQiYi Inc. All Rights Reserved.
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
// */
16+
17+
package actioner
18+
19+
/*
20+
KernelRouteAddDelVerdict Actioner Params:
21+
-------------------------------------------------
22+
name value
23+
-------------------------------------------------
24+
ifname network interface name
25+
with-route also add a host route
26+
27+
-------------------------------------------------
28+
*/
29+
30+
import (
31+
"context"
32+
"fmt"
33+
"time"
34+
35+
"github.com/golang/glog"
36+
"github.com/iqiyi/dpvs/tools/healthcheck/pkg/types"
37+
"github.com/iqiyi/dpvs/tools/healthcheck/pkg/utils"
38+
"github.com/vishvananda/netlink"
39+
)
40+
41+
var _ ActionMethod = (*KernelRouteVerdictAction)(nil)
42+
var _ ActionMethodWithVerdict = (*KernelRouteVerdictAction)(nil)
43+
44+
const kernelRouteVerdictActionerName = "KernelRouteAddDelVerdict"
45+
46+
func init() {
47+
registerMethod(kernelRouteVerdictActionerName, &KernelRouteVerdictAction{})
48+
}
49+
50+
// KernelRouteVerdictAction is the same as KernelRouteAction except it also implements
51+
// ActionMethodWithVerdict interface.
52+
type KernelRouteVerdictAction struct {
53+
KernelRouteAction
54+
}
55+
56+
func (a *KernelRouteVerdictAction) Act(signal types.State, timeout time.Duration,
57+
data ...interface{}) (interface{}, error) {
58+
return a.KernelRouteAction.Act(signal, timeout, data)
59+
}
60+
61+
func (a *KernelRouteVerdictAction) create(target *utils.L3L4Addr, params map[string]string,
62+
extras ...interface{}) (ActionMethod, error) {
63+
embeded, err := a.KernelRouteAction.create(target, params, extras)
64+
if embededObj, ok := embeded.(*KernelRouteAction); ok {
65+
method := &KernelRouteVerdictAction{
66+
KernelRouteAction: *embededObj,
67+
}
68+
return method, err
69+
}
70+
return nil, fmt.Errorf("failed to create %s embeded action for %s", kernelRouteVerdictActionerName,
71+
target.IP.String())
72+
}
73+
74+
func (a *KernelRouteVerdictAction) validate(params map[string]string) error {
75+
return a.KernelRouteAction.validate(params)
76+
}
77+
78+
func (a *KernelRouteVerdictAction) Verdict(timeout time.Duration) (types.State, error) {
79+
targetIP := a.target.IP
80+
if timeout <= 0 {
81+
return types.Unknown, fmt.Errorf("zero verdict timeout on %s actioner %v",
82+
kernelRouteVerdictActionerName, targetIP)
83+
}
84+
ctx, cancel := context.WithTimeout(context.Background(), timeout)
85+
defer cancel()
86+
87+
result := types.Unknown
88+
done := make(chan error, 1)
89+
90+
go func() {
91+
link, err := netlink.LinkByName(a.ifname)
92+
if err != nil {
93+
done <- fmt.Errorf("failed to get link by name: %w", err)
94+
return
95+
}
96+
addrs, err := netlink.AddrList(link, netlink.FAMILY_ALL)
97+
if err != nil {
98+
done <- fmt.Errorf("failed to get addrs on %s: %w", a.ifname, err)
99+
return
100+
}
101+
for _, addr := range addrs {
102+
if targetIP.Equal(addr.IP) {
103+
result = types.Healthy
104+
done <- nil
105+
return
106+
}
107+
}
108+
result = types.Unhealthy
109+
done <- nil
110+
}()
111+
112+
select {
113+
case <-ctx.Done():
114+
glog.Warningf("%s actioner %v verdict timeout", kernelRouteVerdictActionerName, targetIP)
115+
return types.Unknown, ctx.Err()
116+
case err := <-done:
117+
if err != nil {
118+
return types.Unknown, err
119+
}
120+
return result, nil
121+
}
122+
return types.Unknown, nil
123+
}

tools/healthcheck/pkg/checker/http_checker.go

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -246,15 +246,15 @@ func (c *HTTPChecker) validate(params map[string]string) error {
246246
return fmt.Errorf("empty http checker param: %s", param)
247247
}
248248
case "https":
249-
if _, err := string2bool(val); err != nil {
249+
if _, err := utils.String2bool(val); err != nil {
250250
return fmt.Errorf("invalid http checker param %s:%s", param, params[param])
251251
}
252252
case "tls-verify":
253-
if _, err := string2bool(val); err != nil {
253+
if _, err := utils.String2bool(val); err != nil {
254254
return fmt.Errorf("invalid http checker param %s:%s", param, params[param])
255255
}
256256
case "proxy":
257-
if _, err := string2bool(val); err != nil {
257+
if _, err := utils.String2bool(val); err != nil {
258258
return fmt.Errorf("invalid http checker param %s:%s", param, params[param])
259259
}
260260
case ParamProxyProto:
@@ -316,15 +316,15 @@ func (c *HTTPChecker) create(params map[string]string) (CheckMethod, error) {
316316
}
317317

318318
if val, ok := params["https"]; ok {
319-
checker.https, _ = string2bool(val)
319+
checker.https, _ = utils.String2bool(val)
320320
}
321321

322322
if val, ok := params["tls-verify"]; ok {
323-
checker.tlsVerify, _ = string2bool(val)
323+
checker.tlsVerify, _ = utils.String2bool(val)
324324
}
325325

326326
if val, ok := params["proxy"]; ok {
327-
checker.proxy, _ = string2bool(val)
327+
checker.proxy, _ = utils.String2bool(val)
328328
}
329329

330330
if val, ok := params[ParamProxyProto]; ok {
@@ -350,16 +350,6 @@ func (c *HTTPChecker) create(params map[string]string) (CheckMethod, error) {
350350
return checker, nil
351351
}
352352

353-
func string2bool(s string) (bool, error) {
354-
switch strings.ToLower(s) {
355-
case "yes", "true":
356-
return true, nil
357-
case "no", "false":
358-
return false, nil
359-
}
360-
return false, fmt.Errorf("invalid boolean string value: %s", s)
361-
}
362-
363353
func parseHttpHeaderParam(headers string) (map[string]string, error) {
364354
kvs := strings.Split(headers, ";;")
365355

0 commit comments

Comments
 (0)