Skip to content

Commit

Permalink
dpvs-agent: implementation of ipset api
Browse files Browse the repository at this point in the history
Signed-off-by: ywc689 <[email protected]>
  • Loading branch information
ywc689 committed Aug 27, 2024
1 parent 14d1f0c commit 86a5ea5
Show file tree
Hide file tree
Showing 18 changed files with 2,898 additions and 34 deletions.
57 changes: 32 additions & 25 deletions include/conf/ipset.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
#define IPSET_F_FORCE 0x0001

enum ipset_op {
IPSET_OP_ADD,
IPSET_OP_ADD = 1,
IPSET_OP_DEL,
IPSET_OP_TEST,
IPSET_OP_CREATE,
Expand All @@ -43,34 +43,36 @@ enum ipset_op {
};

struct ipset_option {
int family;
union {
struct {
bool comment;
int hashsize;
int maxelem;
} create;
int32_t hashsize;
uint32_t maxelem;
uint8_t comment;
} __attribute__((__packed__)) create;
struct {
bool nomatch;
} add;
char padding[8];
uint8_t nomatch;
} __attribute__((__packed__)) add;
};
};
uint8_t family;
} __attribute__((__packed__));

struct ipset_param {
char type[IPSET_MAXNAMELEN];
char name[IPSET_MAXNAMELEN];
char comment[IPSET_MAXCOMLEN];
int opcode;
struct ipset_option option;
uint16_t opcode;
uint16_t flag;
struct ipset_option option;

uint8_t proto;
uint8_t cidr;
struct inet_addr_range range; /* port in host byteorder */
uint8_t mac[6];
char iface[IFNAMSIZ];
uint8_t mac[6];

/* for type with 2 nets */
uint8_t padding;
uint8_t cidr2;
struct inet_addr_range range2;
//uint8_t mac[2];
Expand All @@ -83,43 +85,48 @@ struct ipset_member {
uint8_t cidr;
uint8_t proto;
uint16_t port;
uint8_t mac[6];
char iface[IFNAMSIZ];
bool nomatch;
uint8_t mac[6];
uint8_t nomatch;

/* second net */
union inet_addr addr2;
uint8_t cidr2;
uint16_t port2;
uint8_t padding[2];
union inet_addr addr2;
};

struct ipset_info {
char name[IPSET_MAXNAMELEN];
char type[IPSET_MAXNAMELEN];
bool comment;
uint8_t comment;

uint8_t af;
uint8_t padding[2];

union {
struct ipset_bitmap_header {
struct inet_addr_range range;
uint8_t cidr;
uint8_t padding[3];
struct inet_addr_range range;
} bitmap;
struct ipset_hash_header {
int hashsize;
int maxelem;
uint8_t padding[4]; // aligned for dpvs-agent
int32_t hashsize;
uint32_t maxelem;
} hash;
};

int af;
size_t size;
int entries;
int references;
uint32_t size;
uint32_t entries;
uint32_t references;

void *members;
};

struct ipset_info_array {
int nipset;
struct ipset_info infos[0];
uint32_t nipset;
struct ipset_info infos[0];
} __attribute__((__packed__));

#endif /* __DPVS_IPSET_CONF_H__ */
2 changes: 1 addition & 1 deletion include/ipset/ipset.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
#define IPSET
#define RTE_LOGTYPE_IPSET RTE_LOGTYPE_USER1

#define IPSET_ADT_MAX 3
#define IPSET_ADT_MAX IPSET_OP_MAX

struct ipset;

Expand Down
13 changes: 10 additions & 3 deletions src/ipset/ipset_bitmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ bitmap_add(struct ipset *set, void *value, uint16_t flag)

/* To avoid same IP, different MAC or other elements */
if (ret || test_bit(e->id, map->members)) {
if (flag & IPSET_F_FORCE)
if (flag & IPSET_F_FORCE)
return EDPVS_OK;
return EDPVS_EXIST;
}
Expand All @@ -51,8 +51,11 @@ bitmap_del(struct ipset *set, void *value, uint16_t flag)
if (e->id >= map->elements)
return EDPVS_INVAL;

if (!do(del, value, map))
if (!do(del, value, map)) {
if (flag & IPSET_F_FORCE)
return EDPVS_OK;
return EDPVS_NOTEXIST;
}

set->elements--;
return EDPVS_OK;
Expand All @@ -70,7 +73,11 @@ bitmap_test(struct ipset *set, void *value, uint16_t flag)
return do(test, value, map, set->dsize);
}

ipset_adtfn bitmap_adtfn[IPSET_ADT_MAX] = { bitmap_add, bitmap_del, bitmap_test };
ipset_adtfn bitmap_adtfn[IPSET_ADT_MAX] = {
[ IPSET_OP_ADD ] = bitmap_add,
[ IPSET_OP_DEL ] = bitmap_del,
[ IPSET_OP_TEST ] = bitmap_test
};

void
bitmap_flush(struct ipset *set)
Expand Down
8 changes: 7 additions & 1 deletion src/ipset/ipset_hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ hash_del(struct ipset *set, void *value, uint16_t flag)
return EDPVS_OK;
}
}
if (flag & IPSET_F_FORCE)
return EDPVS_OK;
return EDPVS_NOTEXIST;
}

Expand Down Expand Up @@ -245,7 +247,11 @@ hash_test(struct ipset *set, void *value, uint16_t flag)
return 0;
}

ipset_adtfn hash_adtfn[IPSET_ADT_MAX] = { hash_add, hash_del, hash_test };
ipset_adtfn hash_adtfn[IPSET_ADT_MAX] = {
[ IPSET_OP_ADD ] = hash_add,
[ IPSET_OP_DEL ] = hash_del,
[ IPSET_OP_TEST ] = hash_test
};

void
hash_flush(struct ipset *set)
Expand Down
2 changes: 1 addition & 1 deletion tools/dpip/ipset.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ static int
addr_arg_parse(char *arg, struct inet_addr_range *range, uint8_t *cidr)
{
char *ip1, *ip2, *sep;
int *af = &param.option.family;
uint8_t *af = &param.option.family;

/* ip/cidr */
if (cidr && (sep = strstr(arg, "/"))) {
Expand Down
23 changes: 23 additions & 0 deletions tools/dpvs-agent/cmd/dpvs-agent-server/api_init.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
rotatelogs "github.com/lestrrat-go/file-rotatelogs"

"github.com/dpvs-agent/cmd/device"
"github.com/dpvs-agent/cmd/ipset"
"github.com/dpvs-agent/cmd/ipvs"
"github.com/dpvs-agent/pkg/ipc/pool"
"github.com/dpvs-agent/pkg/settings"
Expand Down Expand Up @@ -187,6 +188,8 @@ func (agent *DpvsAgentServer) instantiateAPI(restAPI *operations.DpvsAgentAPI) {

logger := hclog.Default().Named("main")

//////////////////////////////////// ipvs ///////////////////////////////////////////

// delete
restAPI.VirtualserverDeleteVsVipPortHandler = ipvs.NewDelVsItem(cp, logger)
restAPI.VirtualserverDeleteVsVipPortLaddrHandler = ipvs.NewDelVsLaddr(cp, logger)
Expand All @@ -210,6 +213,8 @@ func (agent *DpvsAgentServer) instantiateAPI(restAPI *operations.DpvsAgentAPI) {
// post
restAPI.VirtualserverPostVsVipPortRsHandler = ipvs.NewPostVsRs(cp, logger)

//////////////////////////////////// device ///////////////////////////////////////////

// get
// restAPI.DeviceGetDeviceNameAddrHandler
// restAPI.DeviceGetDeviceNameRouteHandler
Expand All @@ -230,6 +235,24 @@ func (agent *DpvsAgentServer) instantiateAPI(restAPI *operations.DpvsAgentAPI) {
restAPI.DeviceDeleteDeviceNameVlanHandler = device.NewDelDeviceVlan(cp, logger)
restAPI.DeviceDeleteDeviceNameNetlinkAddrHandler = device.NewDelDeviceNetlinkAddr(cp, logger)

//////////////////////////////////// ipset ///////////////////////////////////////////

// GET
restAPI.IpsetGetHandler = ipset.NewIpsetGet(cp, logger)
restAPI.IpsetGetAllHandler = ipset.NewIpsetGetAll(cp, logger)

// POST
restAPI.IpsetIsInHandler = ipset.NewIpsetIsIn(cp, logger)
restAPI.IpsetAddMemberHandler = ipset.NewIpsetAddMember(cp, logger)

// PUT
restAPI.IpsetCreateHandler = ipset.NewIpsetCreate(cp, logger)
restAPI.IpsetReplaceMemberHandler = ipset.NewIpsetReplaceMember(cp, logger)

// DELETE
restAPI.IpsetDestroyHandler = ipset.NewIpsetDestroy(cp, logger)
restAPI.IpsetDelMemberHandler = ipset.NewIpsetDelMember(cp, logger)

switch strings.ToLower(agent.InitMode) {
case "network":
case "local":
Expand Down
79 changes: 79 additions & 0 deletions tools/dpvs-agent/cmd/ipset/add_member.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright 2023 IQiYi Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package ipset

import (
"fmt"

"github.com/dpvs-agent/pkg/ipc/pool"
"github.com/dpvs-agent/pkg/ipc/types"
api "github.com/dpvs-agent/restapi/operations/ipset"
"github.com/go-openapi/runtime/middleware"
"github.com/hashicorp/go-hclog"
)

type ipsetAddMember struct {
connPool *pool.ConnPool
logger hclog.Logger
}

func NewIpsetAddMember(cp *pool.ConnPool, parentLogger hclog.Logger) *ipsetAddMember {
logger := hclog.Default()
if parentLogger != nil {
logger = parentLogger.Named("ipsetAddMember")
}
return &ipsetAddMember{connPool: cp, logger: logger}
}

func (h *ipsetAddMember) Handle(params api.AddMemberParams) middleware.Responder {
if params.IpsetParam == nil {
return api.NewAddMemberBadRequest().WithPayload("missing ipset param")
}

if *params.IpsetParam.Name != params.Name {
return api.NewAddMemberBadRequest().WithPayload("ipset name mismatch")
}

if params.IpsetParam.CreationOptions != nil {
return api.NewAddMemberBadRequest().WithPayload("CreationOptions set in adding member")
}

conf := types.IPSetParamArray{}
if err := conf.Build(types.IPSET_OP_ADD, params.IpsetParam); err != nil {
return api.NewAddMemberBadRequest().WithPayload(fmt.Sprintf(
"build AddMember param failed: %s", err.Error()))
}

if err := conf.Check(); err != nil {
return api.NewAddMemberBadRequest().WithPayload(fmt.Sprintf(
"AddMember params check failed: %s", err.Error()))
}

err, derr := conf.AddDelMember(h.connPool, h.logger)
if derr == types.EDPVS_EXIST {
return api.NewAddMemberOK().WithPayload(fmt.Sprintf("%s (may partially succeed)", derr.String()))
}
if err != nil {
h.logger.Error("Ipset AddMember failed.", "setName", params.Name, "Reason", err.Error())
if derr == types.EDPVS_NOTEXIST {
return api.NewAddMemberNotFound().WithPayload(derr.String())
}
return api.NewAddMemberFailure().WithPayload(err.Error())
}

h.logger.Info("Ipset AddMember succeed.", "setName", params.Name)
return api.NewAddMemberCreated().WithPayload(fmt.Sprintf("ipset %s add members succeed",
params.Name))
}
Loading

0 comments on commit 86a5ea5

Please sign in to comment.