mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-06 04:36:45 +00:00
Merge pull request #8124 from pguibert6WIND/ipsec_iptable_dplane
zebra: move netfilter contexts to zebra dplane
This commit is contained in:
commit
6ff2514b41
@ -1551,15 +1551,16 @@ bool zapi_ipset_notify_decode(struct stream *s, uint32_t *unique,
|
||||
enum zapi_ipset_notify_owner *note)
|
||||
{
|
||||
uint32_t uni;
|
||||
uint16_t notew;
|
||||
|
||||
STREAM_GET(note, s, sizeof(*note));
|
||||
STREAM_GETW(s, notew);
|
||||
|
||||
STREAM_GETL(s, uni);
|
||||
|
||||
if (zclient_debug)
|
||||
zlog_debug("%s: %u", __func__, uni);
|
||||
*unique = uni;
|
||||
|
||||
*note = (enum zapi_ipset_notify_owner)notew;
|
||||
return true;
|
||||
|
||||
stream_failure:
|
||||
@ -1571,8 +1572,9 @@ bool zapi_ipset_entry_notify_decode(struct stream *s, uint32_t *unique,
|
||||
enum zapi_ipset_entry_notify_owner *note)
|
||||
{
|
||||
uint32_t uni;
|
||||
uint16_t notew;
|
||||
|
||||
STREAM_GET(note, s, sizeof(*note));
|
||||
STREAM_GETW(s, notew);
|
||||
|
||||
STREAM_GETL(s, uni);
|
||||
|
||||
@ -1581,6 +1583,7 @@ bool zapi_ipset_entry_notify_decode(struct stream *s, uint32_t *unique,
|
||||
if (zclient_debug)
|
||||
zlog_debug("%s: %u", __func__, uni);
|
||||
*unique = uni;
|
||||
*note = (enum zapi_ipset_entry_notify_owner)notew;
|
||||
|
||||
return true;
|
||||
|
||||
@ -1593,14 +1596,16 @@ bool zapi_iptable_notify_decode(struct stream *s,
|
||||
enum zapi_iptable_notify_owner *note)
|
||||
{
|
||||
uint32_t uni;
|
||||
uint16_t notew;
|
||||
|
||||
STREAM_GET(note, s, sizeof(*note));
|
||||
STREAM_GETW(s, notew);
|
||||
|
||||
STREAM_GETL(s, uni);
|
||||
|
||||
if (zclient_debug)
|
||||
zlog_debug("%s: %u", __func__, uni);
|
||||
*unique = uni;
|
||||
*note = (enum zapi_iptable_notify_owner)notew;
|
||||
|
||||
return true;
|
||||
|
||||
|
@ -713,21 +713,21 @@ enum ipset_type {
|
||||
};
|
||||
|
||||
enum zapi_ipset_notify_owner {
|
||||
ZAPI_IPSET_FAIL_INSTALL,
|
||||
ZAPI_IPSET_FAIL_INSTALL = 0,
|
||||
ZAPI_IPSET_INSTALLED,
|
||||
ZAPI_IPSET_REMOVED,
|
||||
ZAPI_IPSET_FAIL_REMOVE,
|
||||
};
|
||||
|
||||
enum zapi_ipset_entry_notify_owner {
|
||||
ZAPI_IPSET_ENTRY_FAIL_INSTALL,
|
||||
ZAPI_IPSET_ENTRY_FAIL_INSTALL = 0,
|
||||
ZAPI_IPSET_ENTRY_INSTALLED,
|
||||
ZAPI_IPSET_ENTRY_REMOVED,
|
||||
ZAPI_IPSET_ENTRY_FAIL_REMOVE,
|
||||
};
|
||||
|
||||
enum zapi_iptable_notify_owner {
|
||||
ZAPI_IPTABLE_FAIL_INSTALL,
|
||||
ZAPI_IPTABLE_FAIL_INSTALL = 0,
|
||||
ZAPI_IPTABLE_INSTALLED,
|
||||
ZAPI_IPTABLE_REMOVED,
|
||||
ZAPI_IPTABLE_FAIL_REMOVE,
|
||||
|
@ -1350,6 +1350,14 @@ static enum netlink_msg_status nl_put_msg(struct nl_batch *bth,
|
||||
case DPLANE_OP_BR_PORT_UPDATE:
|
||||
return FRR_NETLINK_SUCCESS;
|
||||
|
||||
case DPLANE_OP_IPTABLE_ADD:
|
||||
case DPLANE_OP_IPTABLE_DELETE:
|
||||
case DPLANE_OP_IPSET_ADD:
|
||||
case DPLANE_OP_IPSET_DELETE:
|
||||
case DPLANE_OP_IPSET_ENTRY_ADD:
|
||||
case DPLANE_OP_IPSET_ENTRY_DELETE:
|
||||
return FRR_NETLINK_ERROR;
|
||||
|
||||
case DPLANE_OP_NONE:
|
||||
return FRR_NETLINK_ERROR;
|
||||
}
|
||||
|
@ -866,18 +866,24 @@ void zsend_rule_notify_owner(const struct zebra_dplane_ctx *ctx,
|
||||
zserv_send_message(client, s);
|
||||
}
|
||||
|
||||
void zsend_ipset_notify_owner(struct zebra_pbr_ipset *ipset,
|
||||
enum zapi_ipset_notify_owner note)
|
||||
void zsend_iptable_notify_owner(const struct zebra_dplane_ctx *ctx,
|
||||
uint16_t note)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct zserv *client;
|
||||
struct stream *s;
|
||||
struct zebra_pbr_iptable ipt;
|
||||
uint16_t cmd = ZEBRA_IPTABLE_NOTIFY_OWNER;
|
||||
|
||||
if (!dplane_ctx_get_pbr_iptable(ctx, &ipt))
|
||||
return;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_PACKET)
|
||||
zlog_debug("%s: Notifying %u", __func__, ipset->unique);
|
||||
zlog_debug("%s: Notifying %s id %u note %u", __func__,
|
||||
zserv_command_string(cmd), ipt.unique, note);
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) {
|
||||
if (ipset->sock == client->sock)
|
||||
if (ipt.sock == client->sock)
|
||||
break;
|
||||
}
|
||||
|
||||
@ -886,27 +892,32 @@ void zsend_ipset_notify_owner(struct zebra_pbr_ipset *ipset,
|
||||
|
||||
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
|
||||
|
||||
zclient_create_header(s, ZEBRA_IPSET_NOTIFY_OWNER, VRF_DEFAULT);
|
||||
zclient_create_header(s, cmd, VRF_DEFAULT);
|
||||
stream_put(s, ¬e, sizeof(note));
|
||||
stream_putl(s, ipset->unique);
|
||||
stream_put(s, ipset->ipset_name, ZEBRA_IPSET_NAME_SIZE);
|
||||
stream_putl(s, ipt.unique);
|
||||
stream_put(s, ipt.ipset_name, ZEBRA_IPSET_NAME_SIZE);
|
||||
stream_putw_at(s, 0, stream_get_endp(s));
|
||||
|
||||
zserv_send_message(client, s);
|
||||
}
|
||||
|
||||
void zsend_ipset_entry_notify_owner(struct zebra_pbr_ipset_entry *ipset,
|
||||
enum zapi_ipset_entry_notify_owner note)
|
||||
void zsend_ipset_notify_owner(const struct zebra_dplane_ctx *ctx, uint16_t note)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct zserv *client;
|
||||
struct stream *s;
|
||||
struct zebra_pbr_ipset ipset;
|
||||
uint16_t cmd = ZEBRA_IPSET_NOTIFY_OWNER;
|
||||
|
||||
if (!dplane_ctx_get_pbr_ipset(ctx, &ipset))
|
||||
return;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_PACKET)
|
||||
zlog_debug("%s: Notifying %u", __func__, ipset->unique);
|
||||
zlog_debug("%s: Notifying %s id %u note %u", __func__,
|
||||
zserv_command_string(cmd), ipset.unique, note);
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) {
|
||||
if (ipset->sock == client->sock)
|
||||
if (ipset.sock == client->sock)
|
||||
break;
|
||||
}
|
||||
|
||||
@ -915,27 +926,36 @@ void zsend_ipset_entry_notify_owner(struct zebra_pbr_ipset_entry *ipset,
|
||||
|
||||
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
|
||||
|
||||
zclient_create_header(s, ZEBRA_IPSET_ENTRY_NOTIFY_OWNER, VRF_DEFAULT);
|
||||
zclient_create_header(s, cmd, VRF_DEFAULT);
|
||||
stream_put(s, ¬e, sizeof(note));
|
||||
stream_putl(s, ipset->unique);
|
||||
stream_put(s, ipset->backpointer->ipset_name, ZEBRA_IPSET_NAME_SIZE);
|
||||
stream_putl(s, ipset.unique);
|
||||
stream_put(s, ipset.ipset_name, ZEBRA_IPSET_NAME_SIZE);
|
||||
stream_putw_at(s, 0, stream_get_endp(s));
|
||||
|
||||
zserv_send_message(client, s);
|
||||
}
|
||||
|
||||
void zsend_iptable_notify_owner(struct zebra_pbr_iptable *iptable,
|
||||
enum zapi_iptable_notify_owner note)
|
||||
void zsend_ipset_entry_notify_owner(const struct zebra_dplane_ctx *ctx,
|
||||
uint16_t note)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct zserv *client;
|
||||
struct stream *s;
|
||||
struct zebra_pbr_ipset_entry ipent;
|
||||
struct zebra_pbr_ipset ipset;
|
||||
uint16_t cmd = ZEBRA_IPSET_ENTRY_NOTIFY_OWNER;
|
||||
|
||||
if (!dplane_ctx_get_pbr_ipset_entry(ctx, &ipent))
|
||||
return;
|
||||
if (!dplane_ctx_get_pbr_ipset(ctx, &ipset))
|
||||
return;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_PACKET)
|
||||
zlog_debug("%s: Notifying %u", __func__, iptable->unique);
|
||||
zlog_debug("%s: Notifying %s id %u note %u", __func__,
|
||||
zserv_command_string(cmd), ipent.unique, note);
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) {
|
||||
if (iptable->sock == client->sock)
|
||||
if (ipent.sock == client->sock)
|
||||
break;
|
||||
}
|
||||
|
||||
@ -944,9 +964,10 @@ void zsend_iptable_notify_owner(struct zebra_pbr_iptable *iptable,
|
||||
|
||||
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
|
||||
|
||||
zclient_create_header(s, ZEBRA_IPTABLE_NOTIFY_OWNER, VRF_DEFAULT);
|
||||
zclient_create_header(s, cmd, VRF_DEFAULT);
|
||||
stream_put(s, ¬e, sizeof(note));
|
||||
stream_putl(s, iptable->unique);
|
||||
stream_putl(s, ipent.unique);
|
||||
stream_put(s, ipset.ipset_name, ZEBRA_IPSET_NAME_SIZE);
|
||||
stream_putw_at(s, 0, stream_get_endp(s));
|
||||
|
||||
zserv_send_message(client, s);
|
||||
|
@ -84,13 +84,13 @@ extern int zsend_route_notify_owner_ctx(const struct zebra_dplane_ctx *ctx,
|
||||
|
||||
extern void zsend_rule_notify_owner(const struct zebra_dplane_ctx *ctx,
|
||||
enum zapi_rule_notify_owner note);
|
||||
extern void zsend_ipset_notify_owner(struct zebra_pbr_ipset *ipset,
|
||||
enum zapi_ipset_notify_owner note);
|
||||
extern void
|
||||
zsend_ipset_entry_notify_owner(struct zebra_pbr_ipset_entry *ipset,
|
||||
enum zapi_ipset_entry_notify_owner note);
|
||||
extern void zsend_iptable_notify_owner(struct zebra_pbr_iptable *iptable,
|
||||
enum zapi_iptable_notify_owner note);
|
||||
|
||||
extern void zsend_iptable_notify_owner(const struct zebra_dplane_ctx *ctx,
|
||||
uint16_t note);
|
||||
extern void zsend_ipset_notify_owner(const struct zebra_dplane_ctx *ctx,
|
||||
uint16_t note);
|
||||
extern void zsend_ipset_entry_notify_owner(const struct zebra_dplane_ctx *ctx,
|
||||
uint16_t note);
|
||||
extern bool zserv_nexthop_num_warn(const char *caller, const struct prefix *p,
|
||||
const unsigned int nexthop_num);
|
||||
|
||||
|
@ -42,6 +42,7 @@
|
||||
DEFINE_MTYPE_STATIC(ZEBRA, DP_CTX, "Zebra DPlane Ctx")
|
||||
DEFINE_MTYPE_STATIC(ZEBRA, DP_INTF, "Zebra DPlane Intf")
|
||||
DEFINE_MTYPE_STATIC(ZEBRA, DP_PROV, "Zebra DPlane Provider")
|
||||
DEFINE_MTYPE_STATIC(ZEBRA, DP_NETFILTER, "Zebra Netfilter Internal Object")
|
||||
|
||||
#ifndef AOK
|
||||
# define AOK 0
|
||||
@ -307,6 +308,12 @@ struct zebra_dplane_ctx {
|
||||
struct dplane_mac_info macinfo;
|
||||
struct dplane_neigh_info neigh;
|
||||
struct dplane_rule_info rule;
|
||||
struct zebra_pbr_iptable iptable;
|
||||
struct zebra_pbr_ipset ipset;
|
||||
union {
|
||||
struct zebra_pbr_ipset_entry entry;
|
||||
struct zebra_pbr_ipset_info info;
|
||||
} ipset_entry;
|
||||
} u;
|
||||
|
||||
/* Namespace info, used especially for netlink kernel communication */
|
||||
@ -438,6 +445,14 @@ static struct zebra_dplane_globals {
|
||||
|
||||
_Atomic uint32_t dg_update_yields;
|
||||
|
||||
_Atomic uint32_t dg_iptable_in;
|
||||
_Atomic uint32_t dg_iptable_errors;
|
||||
|
||||
_Atomic uint32_t dg_ipset_in;
|
||||
_Atomic uint32_t dg_ipset_errors;
|
||||
_Atomic uint32_t dg_ipset_entry_in;
|
||||
_Atomic uint32_t dg_ipset_entry_errors;
|
||||
|
||||
/* Dataplane pthread */
|
||||
struct frr_pthread *dg_pthread;
|
||||
|
||||
@ -656,7 +671,29 @@ static void dplane_ctx_free_internal(struct zebra_dplane_ctx *ctx)
|
||||
case DPLANE_OP_NEIGH_DISCOVER:
|
||||
case DPLANE_OP_BR_PORT_UPDATE:
|
||||
case DPLANE_OP_NONE:
|
||||
case DPLANE_OP_IPSET_ADD:
|
||||
case DPLANE_OP_IPSET_DELETE:
|
||||
break;
|
||||
|
||||
case DPLANE_OP_IPSET_ENTRY_ADD:
|
||||
case DPLANE_OP_IPSET_ENTRY_DELETE:
|
||||
break;
|
||||
case DPLANE_OP_IPTABLE_ADD:
|
||||
case DPLANE_OP_IPTABLE_DELETE:
|
||||
if (ctx->u.iptable.interface_name_list) {
|
||||
struct listnode *node, *nnode;
|
||||
char *ifname;
|
||||
|
||||
for (ALL_LIST_ELEMENTS(
|
||||
ctx->u.iptable.interface_name_list, node,
|
||||
nnode, ifname)) {
|
||||
LISTNODE_DETACH(
|
||||
ctx->u.iptable.interface_name_list,
|
||||
node);
|
||||
XFREE(MTYPE_DP_NETFILTER, ifname);
|
||||
}
|
||||
list_delete(&ctx->u.iptable.interface_name_list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -895,6 +932,25 @@ const char *dplane_op2str(enum dplane_op_e op)
|
||||
case DPLANE_OP_NEIGH_DISCOVER:
|
||||
ret = "NEIGH_DISCOVER";
|
||||
break;
|
||||
|
||||
case DPLANE_OP_IPTABLE_ADD:
|
||||
ret = "IPTABLE_ADD";
|
||||
break;
|
||||
case DPLANE_OP_IPTABLE_DELETE:
|
||||
ret = "IPTABLE_DELETE";
|
||||
break;
|
||||
case DPLANE_OP_IPSET_ADD:
|
||||
ret = "IPSET_ADD";
|
||||
break;
|
||||
case DPLANE_OP_IPSET_DELETE:
|
||||
ret = "IPSET_DELETE";
|
||||
break;
|
||||
case DPLANE_OP_IPSET_ENTRY_ADD:
|
||||
ret = "IPSET_ENTRY_ADD";
|
||||
break;
|
||||
case DPLANE_OP_IPSET_ENTRY_DELETE:
|
||||
ret = "IPSET_ENTRY_DELETE";
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -1843,6 +1899,46 @@ dplane_ctx_get_br_port_backup_nhg_id(const struct zebra_dplane_ctx *ctx)
|
||||
return ctx->u.br_port.backup_nhg_id;
|
||||
}
|
||||
|
||||
/* Accessors for PBR iptable information */
|
||||
bool
|
||||
dplane_ctx_get_pbr_iptable(const struct zebra_dplane_ctx *ctx,
|
||||
struct zebra_pbr_iptable *table)
|
||||
{
|
||||
DPLANE_CTX_VALID(ctx);
|
||||
|
||||
memcpy(table, &ctx->u.iptable, sizeof(struct zebra_pbr_iptable));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dplane_ctx_get_pbr_ipset(const struct zebra_dplane_ctx *ctx,
|
||||
struct zebra_pbr_ipset *ipset)
|
||||
{
|
||||
DPLANE_CTX_VALID(ctx);
|
||||
|
||||
if (!ipset)
|
||||
return false;
|
||||
if (ctx->zd_op == DPLANE_OP_IPSET_ENTRY_ADD ||
|
||||
ctx->zd_op == DPLANE_OP_IPSET_ENTRY_DELETE) {
|
||||
memset(ipset, 0, sizeof(struct zebra_pbr_ipset));
|
||||
ipset->type = ctx->u.ipset_entry.info.type;
|
||||
memcpy(&ipset->ipset_name, &ctx->u.ipset_entry.info.ipset_name,
|
||||
ZEBRA_IPSET_NAME_SIZE);
|
||||
} else
|
||||
memcpy(ipset, &ctx->u.ipset, sizeof(struct zebra_pbr_ipset));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dplane_ctx_get_pbr_ipset_entry(const struct zebra_dplane_ctx *ctx,
|
||||
struct zebra_pbr_ipset_entry *entry)
|
||||
{
|
||||
DPLANE_CTX_VALID(ctx);
|
||||
|
||||
if (!entry)
|
||||
return false;
|
||||
memcpy(entry, &ctx->u.ipset_entry.entry, sizeof(struct zebra_pbr_ipset_entry));
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* End of dplane context accessors
|
||||
*/
|
||||
@ -2398,6 +2494,126 @@ static int dplane_ctx_rule_init(struct zebra_dplane_ctx *ctx,
|
||||
return AOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* dplane_ctx_iptable_init() - Initialize a context block for a PBR iptable
|
||||
* update.
|
||||
*
|
||||
* @ctx: Dataplane context to init
|
||||
* @op: Operation being performed
|
||||
* @new_rule: PBR iptable
|
||||
*
|
||||
* Return: Result status
|
||||
*/
|
||||
static int dplane_ctx_iptable_init(struct zebra_dplane_ctx *ctx,
|
||||
enum dplane_op_e op,
|
||||
struct zebra_pbr_iptable *iptable)
|
||||
{
|
||||
char *ifname;
|
||||
struct listnode *node;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) {
|
||||
zlog_debug(
|
||||
"init dplane ctx %s: Unique %u Fwmark %u Family %s Action %s",
|
||||
dplane_op2str(op), iptable->unique, iptable->fwmark,
|
||||
family2str(iptable->family),
|
||||
iptable->action == ZEBRA_IPTABLES_DROP ? "Drop"
|
||||
: "Forward");
|
||||
}
|
||||
|
||||
ctx->zd_op = op;
|
||||
ctx->zd_status = ZEBRA_DPLANE_REQUEST_SUCCESS;
|
||||
|
||||
dplane_ctx_ns_init(ctx, zebra_ns_lookup(NS_DEFAULT), false);
|
||||
ctx->zd_is_update = false;
|
||||
|
||||
ctx->zd_vrf_id = iptable->vrf_id;
|
||||
memcpy(&ctx->u.iptable, iptable, sizeof(struct zebra_pbr_iptable));
|
||||
ctx->u.iptable.interface_name_list = NULL;
|
||||
if (iptable->nb_interface > 0) {
|
||||
ctx->u.iptable.interface_name_list = list_new();
|
||||
for (ALL_LIST_ELEMENTS_RO(iptable->interface_name_list, node,
|
||||
ifname)) {
|
||||
listnode_add(ctx->u.iptable.interface_name_list,
|
||||
XSTRDUP(MTYPE_DP_NETFILTER, ifname));
|
||||
}
|
||||
}
|
||||
return AOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* dplane_ctx_ipset_init() - Initialize a context block for a PBR ipset update.
|
||||
*
|
||||
* @ctx: Dataplane context to init
|
||||
* @op: Operation being performed
|
||||
* @new_rule: PBR ipset
|
||||
*
|
||||
* Return: Result status
|
||||
*/
|
||||
static int dplane_ctx_ipset_init(struct zebra_dplane_ctx *ctx,
|
||||
enum dplane_op_e op,
|
||||
struct zebra_pbr_ipset *ipset)
|
||||
{
|
||||
if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) {
|
||||
zlog_debug("init dplane ctx %s: %s Unique %u Family %s Type %s",
|
||||
dplane_op2str(op), ipset->ipset_name, ipset->unique,
|
||||
family2str(ipset->family),
|
||||
zebra_pbr_ipset_type2str(ipset->type));
|
||||
}
|
||||
|
||||
ctx->zd_op = op;
|
||||
ctx->zd_status = ZEBRA_DPLANE_REQUEST_SUCCESS;
|
||||
|
||||
dplane_ctx_ns_init(ctx, zebra_ns_lookup(NS_DEFAULT), false);
|
||||
ctx->zd_is_update = false;
|
||||
|
||||
ctx->zd_vrf_id = ipset->vrf_id;
|
||||
|
||||
memcpy(&ctx->u.ipset, ipset, sizeof(struct zebra_pbr_ipset));
|
||||
return AOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* dplane_ctx_ipset_entry_init() - Initialize a context block for a PBR ipset
|
||||
* update.
|
||||
*
|
||||
* @ctx: Dataplane context to init
|
||||
* @op: Operation being performed
|
||||
* @new_rule: PBR ipset
|
||||
*
|
||||
* Return: Result status
|
||||
*/
|
||||
static int
|
||||
dplane_ctx_ipset_entry_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op,
|
||||
struct zebra_pbr_ipset_entry *ipset_entry)
|
||||
{
|
||||
struct zebra_pbr_ipset *ipset;
|
||||
|
||||
ipset = ipset_entry->backpointer;
|
||||
if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) {
|
||||
zlog_debug("init dplane ctx %s: %s Unique %u filter %u",
|
||||
dplane_op2str(op), ipset->ipset_name,
|
||||
ipset_entry->unique, ipset_entry->filter_bm);
|
||||
}
|
||||
|
||||
ctx->zd_op = op;
|
||||
ctx->zd_status = ZEBRA_DPLANE_REQUEST_SUCCESS;
|
||||
|
||||
dplane_ctx_ns_init(ctx, zebra_ns_lookup(NS_DEFAULT), false);
|
||||
ctx->zd_is_update = false;
|
||||
|
||||
ctx->zd_vrf_id = ipset->vrf_id;
|
||||
|
||||
memcpy(&ctx->u.ipset_entry.entry, ipset_entry,
|
||||
sizeof(struct zebra_pbr_ipset_entry));
|
||||
ctx->u.ipset_entry.entry.backpointer = NULL;
|
||||
ctx->u.ipset_entry.info.type = ipset->type;
|
||||
memcpy(&ctx->u.ipset_entry.info.ipset_name, &ipset->ipset_name,
|
||||
ZEBRA_IPSET_NAME_SIZE);
|
||||
|
||||
return AOK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Enqueue a new update,
|
||||
* and ensure an event is active for the dataplane pthread.
|
||||
@ -3608,6 +3824,139 @@ enum zebra_dplane_result dplane_pbr_rule_update(struct zebra_pbr_rule *old_rule,
|
||||
{
|
||||
return rule_update_internal(DPLANE_OP_RULE_UPDATE, new_rule, old_rule);
|
||||
}
|
||||
/*
|
||||
* Common helper api for iptable updates
|
||||
*/
|
||||
static enum zebra_dplane_result
|
||||
iptable_update_internal(enum dplane_op_e op, struct zebra_pbr_iptable *iptable)
|
||||
{
|
||||
enum zebra_dplane_result result = ZEBRA_DPLANE_REQUEST_FAILURE;
|
||||
struct zebra_dplane_ctx *ctx;
|
||||
int ret;
|
||||
|
||||
ctx = dplane_ctx_alloc();
|
||||
|
||||
ret = dplane_ctx_iptable_init(ctx, op, iptable);
|
||||
if (ret != AOK)
|
||||
goto done;
|
||||
|
||||
ret = dplane_update_enqueue(ctx);
|
||||
|
||||
done:
|
||||
atomic_fetch_add_explicit(&zdplane_info.dg_iptable_in, 1,
|
||||
memory_order_relaxed);
|
||||
|
||||
if (ret == AOK)
|
||||
result = ZEBRA_DPLANE_REQUEST_QUEUED;
|
||||
else {
|
||||
atomic_fetch_add_explicit(&zdplane_info.dg_iptable_errors, 1,
|
||||
memory_order_relaxed);
|
||||
dplane_ctx_free(&ctx);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
enum zebra_dplane_result
|
||||
dplane_pbr_iptable_add(struct zebra_pbr_iptable *iptable)
|
||||
{
|
||||
return iptable_update_internal(DPLANE_OP_IPTABLE_ADD, iptable);
|
||||
}
|
||||
|
||||
enum zebra_dplane_result
|
||||
dplane_pbr_iptable_delete(struct zebra_pbr_iptable *iptable)
|
||||
{
|
||||
return iptable_update_internal(DPLANE_OP_IPTABLE_DELETE, iptable);
|
||||
}
|
||||
|
||||
/*
|
||||
* Common helper api for ipset updates
|
||||
*/
|
||||
static enum zebra_dplane_result
|
||||
ipset_update_internal(enum dplane_op_e op, struct zebra_pbr_ipset *ipset)
|
||||
{
|
||||
enum zebra_dplane_result result = ZEBRA_DPLANE_REQUEST_FAILURE;
|
||||
struct zebra_dplane_ctx *ctx;
|
||||
int ret;
|
||||
|
||||
ctx = dplane_ctx_alloc();
|
||||
|
||||
ret = dplane_ctx_ipset_init(ctx, op, ipset);
|
||||
if (ret != AOK)
|
||||
goto done;
|
||||
|
||||
ret = dplane_update_enqueue(ctx);
|
||||
|
||||
done:
|
||||
atomic_fetch_add_explicit(&zdplane_info.dg_ipset_in, 1,
|
||||
memory_order_relaxed);
|
||||
|
||||
if (ret == AOK)
|
||||
result = ZEBRA_DPLANE_REQUEST_QUEUED;
|
||||
else {
|
||||
atomic_fetch_add_explicit(&zdplane_info.dg_ipset_errors, 1,
|
||||
memory_order_relaxed);
|
||||
dplane_ctx_free(&ctx);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
enum zebra_dplane_result dplane_pbr_ipset_add(struct zebra_pbr_ipset *ipset)
|
||||
{
|
||||
return ipset_update_internal(DPLANE_OP_IPSET_ADD, ipset);
|
||||
}
|
||||
|
||||
enum zebra_dplane_result dplane_pbr_ipset_delete(struct zebra_pbr_ipset *ipset)
|
||||
{
|
||||
return ipset_update_internal(DPLANE_OP_IPSET_DELETE, ipset);
|
||||
}
|
||||
|
||||
/*
|
||||
* Common helper api for ipset updates
|
||||
*/
|
||||
static enum zebra_dplane_result
|
||||
ipset_entry_update_internal(enum dplane_op_e op,
|
||||
struct zebra_pbr_ipset_entry *ipset_entry)
|
||||
{
|
||||
enum zebra_dplane_result result = ZEBRA_DPLANE_REQUEST_FAILURE;
|
||||
struct zebra_dplane_ctx *ctx;
|
||||
int ret;
|
||||
|
||||
ctx = dplane_ctx_alloc();
|
||||
|
||||
ret = dplane_ctx_ipset_entry_init(ctx, op, ipset_entry);
|
||||
if (ret != AOK)
|
||||
goto done;
|
||||
|
||||
ret = dplane_update_enqueue(ctx);
|
||||
|
||||
done:
|
||||
atomic_fetch_add_explicit(&zdplane_info.dg_ipset_entry_in, 1,
|
||||
memory_order_relaxed);
|
||||
|
||||
if (ret == AOK)
|
||||
result = ZEBRA_DPLANE_REQUEST_QUEUED;
|
||||
else {
|
||||
atomic_fetch_add_explicit(&zdplane_info.dg_ipset_entry_errors,
|
||||
1, memory_order_relaxed);
|
||||
dplane_ctx_free(&ctx);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
enum zebra_dplane_result
|
||||
dplane_pbr_ipset_entry_add(struct zebra_pbr_ipset_entry *ipset)
|
||||
{
|
||||
return ipset_entry_update_internal(DPLANE_OP_IPSET_ENTRY_ADD, ipset);
|
||||
}
|
||||
|
||||
enum zebra_dplane_result
|
||||
dplane_pbr_ipset_entry_delete(struct zebra_pbr_ipset_entry *ipset)
|
||||
{
|
||||
return ipset_entry_update_internal(DPLANE_OP_IPSET_ENTRY_DELETE, ipset);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handler for 'show dplane'
|
||||
@ -3693,6 +4042,24 @@ int dplane_show_helper(struct vty *vty, bool detailed)
|
||||
vty_out(vty, "Bridge port updates: %" PRIu64 "\n", incoming);
|
||||
vty_out(vty, "Bridge port errors: %" PRIu64 "\n", errs);
|
||||
|
||||
incoming = atomic_load_explicit(&zdplane_info.dg_iptable_in,
|
||||
memory_order_relaxed);
|
||||
errs = atomic_load_explicit(&zdplane_info.dg_iptable_errors,
|
||||
memory_order_relaxed);
|
||||
vty_out(vty, "IPtable updates: %" PRIu64 "\n", incoming);
|
||||
vty_out(vty, "IPtable errors: %" PRIu64 "\n", errs);
|
||||
incoming = atomic_load_explicit(&zdplane_info.dg_ipset_in,
|
||||
memory_order_relaxed);
|
||||
errs = atomic_load_explicit(&zdplane_info.dg_ipset_errors,
|
||||
memory_order_relaxed);
|
||||
vty_out(vty, "IPset updates: %" PRIu64 "\n", incoming);
|
||||
vty_out(vty, "IPset errors: %" PRIu64 "\n", errs);
|
||||
incoming = atomic_load_explicit(&zdplane_info.dg_ipset_entry_in,
|
||||
memory_order_relaxed);
|
||||
errs = atomic_load_explicit(&zdplane_info.dg_ipset_entry_errors,
|
||||
memory_order_relaxed);
|
||||
vty_out(vty, "IPset entry updates: %" PRIu64 "\n", incoming);
|
||||
vty_out(vty, "IPset entry errors: %" PRIu64 "\n", errs);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
@ -4103,6 +4470,33 @@ static void kernel_dplane_log_detail(struct zebra_dplane_ctx *ctx)
|
||||
|
||||
case DPLANE_OP_NONE:
|
||||
break;
|
||||
|
||||
case DPLANE_OP_IPTABLE_ADD:
|
||||
case DPLANE_OP_IPTABLE_DELETE: {
|
||||
struct zebra_pbr_iptable ipt;
|
||||
|
||||
if (dplane_ctx_get_pbr_iptable(ctx, &ipt))
|
||||
zlog_debug("Dplane iptable update op %s, unique(%u), ctx %p",
|
||||
dplane_op2str(dplane_ctx_get_op(ctx)), ipt.unique, ctx);
|
||||
} break;
|
||||
case DPLANE_OP_IPSET_ADD:
|
||||
case DPLANE_OP_IPSET_DELETE: {
|
||||
struct zebra_pbr_ipset ipset;
|
||||
|
||||
if (dplane_ctx_get_pbr_ipset(ctx, &ipset))
|
||||
zlog_debug("Dplane ipset update op %s, unique(%u), ctx %p",
|
||||
dplane_op2str(dplane_ctx_get_op(ctx)),
|
||||
ipset.unique, ctx);
|
||||
} break;
|
||||
case DPLANE_OP_IPSET_ENTRY_ADD:
|
||||
case DPLANE_OP_IPSET_ENTRY_DELETE: {
|
||||
struct zebra_pbr_ipset_entry ipent;
|
||||
|
||||
if (dplane_ctx_get_pbr_ipset_entry(ctx, &ipent))
|
||||
zlog_debug("Dplane ipset entry update op %s, unique(%u), ctx %p",
|
||||
dplane_op2str(dplane_ctx_get_op(ctx)),
|
||||
ipent.unique, ctx);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4199,6 +4593,29 @@ static void kernel_dplane_handle_result(struct zebra_dplane_ctx *ctx)
|
||||
1, memory_order_relaxed);
|
||||
break;
|
||||
|
||||
case DPLANE_OP_IPTABLE_ADD:
|
||||
case DPLANE_OP_IPTABLE_DELETE:
|
||||
if (res != ZEBRA_DPLANE_REQUEST_SUCCESS)
|
||||
atomic_fetch_add_explicit(
|
||||
&zdplane_info.dg_iptable_errors, 1,
|
||||
memory_order_relaxed);
|
||||
break;
|
||||
|
||||
case DPLANE_OP_IPSET_ADD:
|
||||
case DPLANE_OP_IPSET_DELETE:
|
||||
if (res != ZEBRA_DPLANE_REQUEST_SUCCESS)
|
||||
atomic_fetch_add_explicit(&zdplane_info.dg_ipset_errors,
|
||||
1, memory_order_relaxed);
|
||||
break;
|
||||
|
||||
case DPLANE_OP_IPSET_ENTRY_ADD:
|
||||
case DPLANE_OP_IPSET_ENTRY_DELETE:
|
||||
if (res != ZEBRA_DPLANE_REQUEST_SUCCESS)
|
||||
atomic_fetch_add_explicit(
|
||||
&zdplane_info.dg_ipset_entry_errors, 1,
|
||||
memory_order_relaxed);
|
||||
break;
|
||||
|
||||
/* Ignore 'notifications' - no-op */
|
||||
case DPLANE_OP_SYS_ROUTE_ADD:
|
||||
case DPLANE_OP_SYS_ROUTE_DELETE:
|
||||
@ -4215,6 +4632,28 @@ static void kernel_dplane_handle_result(struct zebra_dplane_ctx *ctx)
|
||||
}
|
||||
}
|
||||
|
||||
static void kernel_dplane_process_iptable(struct zebra_dplane_provider *prov,
|
||||
struct zebra_dplane_ctx *ctx)
|
||||
{
|
||||
zebra_pbr_process_iptable(ctx);
|
||||
dplane_provider_enqueue_out_ctx(prov, ctx);
|
||||
}
|
||||
|
||||
static void kernel_dplane_process_ipset(struct zebra_dplane_provider *prov,
|
||||
struct zebra_dplane_ctx *ctx)
|
||||
{
|
||||
zebra_pbr_process_ipset(ctx);
|
||||
dplane_provider_enqueue_out_ctx(prov, ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
kernel_dplane_process_ipset_entry(struct zebra_dplane_provider *prov,
|
||||
struct zebra_dplane_ctx *ctx)
|
||||
{
|
||||
zebra_pbr_process_ipset_entry(ctx);
|
||||
dplane_provider_enqueue_out_ctx(prov, ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
* Kernel provider callback
|
||||
*/
|
||||
@ -4236,11 +4675,21 @@ static int kernel_dplane_process_func(struct zebra_dplane_provider *prov)
|
||||
ctx = dplane_provider_dequeue_in_ctx(prov);
|
||||
if (ctx == NULL)
|
||||
break;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_DPLANE_DETAIL)
|
||||
kernel_dplane_log_detail(ctx);
|
||||
|
||||
TAILQ_INSERT_TAIL(&work_list, ctx, zd_q_entries);
|
||||
if ((dplane_ctx_get_op(ctx) == DPLANE_OP_IPTABLE_ADD
|
||||
|| dplane_ctx_get_op(ctx) == DPLANE_OP_IPTABLE_DELETE))
|
||||
kernel_dplane_process_iptable(prov, ctx);
|
||||
else if ((dplane_ctx_get_op(ctx) == DPLANE_OP_IPSET_ADD
|
||||
|| dplane_ctx_get_op(ctx) == DPLANE_OP_IPSET_DELETE))
|
||||
kernel_dplane_process_ipset(prov, ctx);
|
||||
else if ((dplane_ctx_get_op(ctx) == DPLANE_OP_IPSET_ENTRY_ADD
|
||||
|| dplane_ctx_get_op(ctx)
|
||||
== DPLANE_OP_IPSET_ENTRY_DELETE))
|
||||
kernel_dplane_process_ipset_entry(prov, ctx);
|
||||
else
|
||||
TAILQ_INSERT_TAIL(&work_list, ctx, zd_q_entries);
|
||||
}
|
||||
|
||||
kernel_update_multi(&work_list);
|
||||
|
@ -155,6 +155,16 @@ enum dplane_op_e {
|
||||
|
||||
/* bridge port update */
|
||||
DPLANE_OP_BR_PORT_UPDATE,
|
||||
|
||||
/* Policy based routing iptable update */
|
||||
DPLANE_OP_IPTABLE_ADD,
|
||||
DPLANE_OP_IPTABLE_DELETE,
|
||||
|
||||
/* Policy based routing ipset update */
|
||||
DPLANE_OP_IPSET_ADD,
|
||||
DPLANE_OP_IPSET_DELETE,
|
||||
DPLANE_OP_IPSET_ENTRY_ADD,
|
||||
DPLANE_OP_IPSET_ENTRY_DELETE,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -475,7 +485,19 @@ const struct prefix *
|
||||
dplane_ctx_rule_get_dst_ip(const struct zebra_dplane_ctx *ctx);
|
||||
const struct prefix *
|
||||
dplane_ctx_rule_get_old_dst_ip(const struct zebra_dplane_ctx *ctx);
|
||||
|
||||
/* Accessors for policy based routing iptable information */
|
||||
struct zebra_pbr_iptable;
|
||||
bool
|
||||
dplane_ctx_get_pbr_iptable(const struct zebra_dplane_ctx *ctx,
|
||||
struct zebra_pbr_iptable *table);
|
||||
struct zebra_pbr_ipset;
|
||||
bool
|
||||
dplane_ctx_get_pbr_ipset(const struct zebra_dplane_ctx *ctx,
|
||||
struct zebra_pbr_ipset *ipset);
|
||||
struct zebra_pbr_ipset_entry;
|
||||
bool
|
||||
dplane_ctx_get_pbr_ipset_entry(const struct zebra_dplane_ctx *ctx,
|
||||
struct zebra_pbr_ipset_entry *entry);
|
||||
/* Accessors for bridge port information */
|
||||
uint32_t dplane_ctx_get_br_port_flags(const struct zebra_dplane_ctx *ctx);
|
||||
uint32_t
|
||||
@ -648,6 +670,23 @@ enum zebra_dplane_result dplane_pbr_rule_delete(struct zebra_pbr_rule *rule);
|
||||
enum zebra_dplane_result
|
||||
dplane_pbr_rule_update(struct zebra_pbr_rule *old_rule,
|
||||
struct zebra_pbr_rule *new_rule);
|
||||
/* iptable */
|
||||
enum zebra_dplane_result
|
||||
dplane_pbr_iptable_add(struct zebra_pbr_iptable *iptable);
|
||||
enum zebra_dplane_result
|
||||
dplane_pbr_iptable_delete(struct zebra_pbr_iptable *iptable);
|
||||
|
||||
/* ipset */
|
||||
struct zebra_pbr_ipset;
|
||||
enum zebra_dplane_result dplane_pbr_ipset_add(struct zebra_pbr_ipset *ipset);
|
||||
enum zebra_dplane_result dplane_pbr_ipset_delete(struct zebra_pbr_ipset *ipset);
|
||||
|
||||
/* ipset entry */
|
||||
struct zebra_pbr_ipset_entry;
|
||||
enum zebra_dplane_result
|
||||
dplane_pbr_ipset_entry_add(struct zebra_pbr_ipset_entry *ipset);
|
||||
enum zebra_dplane_result
|
||||
dplane_pbr_ipset_entry_delete(struct zebra_pbr_ipset_entry *ipset);
|
||||
|
||||
/* Encode route information into data plane context. */
|
||||
int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op,
|
||||
|
@ -2715,6 +2715,12 @@ void zebra_nhg_dplane_result(struct zebra_dplane_ctx *ctx)
|
||||
case DPLANE_OP_NEIGH_DISCOVER:
|
||||
case DPLANE_OP_BR_PORT_UPDATE:
|
||||
case DPLANE_OP_NONE:
|
||||
case DPLANE_OP_IPTABLE_ADD:
|
||||
case DPLANE_OP_IPTABLE_DELETE:
|
||||
case DPLANE_OP_IPSET_ADD:
|
||||
case DPLANE_OP_IPSET_DELETE:
|
||||
case DPLANE_OP_IPSET_ENTRY_ADD:
|
||||
case DPLANE_OP_IPSET_ENTRY_DELETE:
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -542,6 +542,69 @@ void zebra_pbr_del_rule(struct zebra_pbr_rule *rule)
|
||||
__func__);
|
||||
}
|
||||
|
||||
void zebra_pbr_process_iptable(struct zebra_dplane_ctx *ctx)
|
||||
{
|
||||
int mode, ret = 0;
|
||||
struct zebra_pbr_iptable ipt;
|
||||
|
||||
if (dplane_ctx_get_op(ctx) == DPLANE_OP_IPTABLE_ADD)
|
||||
mode = 1;
|
||||
else
|
||||
mode = 0;
|
||||
|
||||
if (dplane_ctx_get_pbr_iptable(ctx, &ipt)) {
|
||||
ret = hook_call(zebra_pbr_iptable_update, mode, &ipt);
|
||||
if (ret)
|
||||
dplane_ctx_set_status(ctx,
|
||||
ZEBRA_DPLANE_REQUEST_SUCCESS);
|
||||
}
|
||||
if (!ret)
|
||||
dplane_ctx_set_status(ctx, ZEBRA_DPLANE_REQUEST_FAILURE);
|
||||
}
|
||||
|
||||
void zebra_pbr_process_ipset(struct zebra_dplane_ctx *ctx)
|
||||
{
|
||||
int mode, ret = 0;
|
||||
struct zebra_pbr_ipset ipset;
|
||||
|
||||
if (dplane_ctx_get_op(ctx) == DPLANE_OP_IPSET_ADD)
|
||||
mode = 1;
|
||||
else
|
||||
mode = 0;
|
||||
if (dplane_ctx_get_pbr_ipset(ctx, &ipset)) {
|
||||
ret = hook_call(zebra_pbr_ipset_update, mode, &ipset);
|
||||
if (ret)
|
||||
dplane_ctx_set_status(ctx,
|
||||
ZEBRA_DPLANE_REQUEST_SUCCESS);
|
||||
}
|
||||
if (!ret)
|
||||
dplane_ctx_set_status(ctx, ZEBRA_DPLANE_REQUEST_FAILURE);
|
||||
}
|
||||
|
||||
void zebra_pbr_process_ipset_entry(struct zebra_dplane_ctx *ctx)
|
||||
{
|
||||
int mode, ret = 0;
|
||||
struct zebra_pbr_ipset_entry ipset_entry;
|
||||
struct zebra_pbr_ipset ipset;
|
||||
|
||||
if (dplane_ctx_get_op(ctx) == DPLANE_OP_IPSET_ENTRY_ADD)
|
||||
mode = 1;
|
||||
else
|
||||
mode = 0;
|
||||
|
||||
if (!dplane_ctx_get_pbr_ipset_entry(ctx, &ipset_entry))
|
||||
return;
|
||||
if (!dplane_ctx_get_pbr_ipset(ctx, &ipset))
|
||||
return;
|
||||
ipset_entry.backpointer = &ipset;
|
||||
|
||||
ret = hook_call(zebra_pbr_ipset_entry_update, mode, &ipset_entry);
|
||||
if (ret)
|
||||
dplane_ctx_set_status(ctx, ZEBRA_DPLANE_REQUEST_SUCCESS);
|
||||
else
|
||||
dplane_ctx_set_status(ctx, ZEBRA_DPLANE_REQUEST_FAILURE);
|
||||
}
|
||||
|
||||
static void zebra_pbr_cleanup_rules(struct hash_bucket *b, void *data)
|
||||
{
|
||||
struct zebra_pbr_rule *rule = b->data;
|
||||
@ -632,13 +695,8 @@ static void *pbr_ipset_alloc_intern(void *arg)
|
||||
|
||||
void zebra_pbr_create_ipset(struct zebra_pbr_ipset *ipset)
|
||||
{
|
||||
int ret;
|
||||
|
||||
(void)hash_get(zrouter.ipset_hash, ipset, pbr_ipset_alloc_intern);
|
||||
ret = hook_call(zebra_pbr_ipset_update, 1, ipset);
|
||||
kernel_pbr_ipset_add_del_status(ipset,
|
||||
ret ? ZEBRA_DPLANE_INSTALL_SUCCESS
|
||||
: ZEBRA_DPLANE_INSTALL_FAILURE);
|
||||
(void)dplane_pbr_ipset_add(ipset);
|
||||
}
|
||||
|
||||
void zebra_pbr_destroy_ipset(struct zebra_pbr_ipset *ipset)
|
||||
@ -646,7 +704,7 @@ void zebra_pbr_destroy_ipset(struct zebra_pbr_ipset *ipset)
|
||||
struct zebra_pbr_ipset *lookup;
|
||||
|
||||
lookup = hash_lookup(zrouter.ipset_hash, ipset);
|
||||
hook_call(zebra_pbr_ipset_update, 0, ipset);
|
||||
(void)dplane_pbr_ipset_delete(ipset);
|
||||
if (lookup) {
|
||||
hash_release(zrouter.ipset_hash, lookup);
|
||||
XFREE(MTYPE_TMP, lookup);
|
||||
@ -711,14 +769,9 @@ static void *pbr_ipset_entry_alloc_intern(void *arg)
|
||||
|
||||
void zebra_pbr_add_ipset_entry(struct zebra_pbr_ipset_entry *ipset)
|
||||
{
|
||||
int ret;
|
||||
|
||||
(void)hash_get(zrouter.ipset_entry_hash, ipset,
|
||||
pbr_ipset_entry_alloc_intern);
|
||||
ret = hook_call(zebra_pbr_ipset_entry_update, 1, ipset);
|
||||
kernel_pbr_ipset_entry_add_del_status(ipset,
|
||||
ret ? ZEBRA_DPLANE_INSTALL_SUCCESS
|
||||
: ZEBRA_DPLANE_INSTALL_FAILURE);
|
||||
(void)dplane_pbr_ipset_entry_add(ipset);
|
||||
}
|
||||
|
||||
void zebra_pbr_del_ipset_entry(struct zebra_pbr_ipset_entry *ipset)
|
||||
@ -726,7 +779,7 @@ void zebra_pbr_del_ipset_entry(struct zebra_pbr_ipset_entry *ipset)
|
||||
struct zebra_pbr_ipset_entry *lookup;
|
||||
|
||||
lookup = hash_lookup(zrouter.ipset_entry_hash, ipset);
|
||||
hook_call(zebra_pbr_ipset_entry_update, 0, ipset);
|
||||
(void)dplane_pbr_ipset_entry_delete(ipset);
|
||||
if (lookup) {
|
||||
hash_release(zrouter.ipset_entry_hash, lookup);
|
||||
XFREE(MTYPE_TMP, lookup);
|
||||
@ -761,13 +814,8 @@ static void *pbr_iptable_alloc_intern(void *arg)
|
||||
|
||||
void zebra_pbr_add_iptable(struct zebra_pbr_iptable *iptable)
|
||||
{
|
||||
int ret;
|
||||
|
||||
(void)hash_get(zrouter.iptable_hash, iptable, pbr_iptable_alloc_intern);
|
||||
ret = hook_call(zebra_pbr_iptable_update, 1, iptable);
|
||||
kernel_pbr_iptable_add_del_status(iptable,
|
||||
ret ? ZEBRA_DPLANE_INSTALL_SUCCESS
|
||||
: ZEBRA_DPLANE_INSTALL_FAILURE);
|
||||
(void)dplane_pbr_iptable_add(iptable);
|
||||
}
|
||||
|
||||
void zebra_pbr_del_iptable(struct zebra_pbr_iptable *iptable)
|
||||
@ -775,7 +823,7 @@ void zebra_pbr_del_iptable(struct zebra_pbr_iptable *iptable)
|
||||
struct zebra_pbr_iptable *lookup;
|
||||
|
||||
lookup = hash_lookup(zrouter.iptable_hash, iptable);
|
||||
hook_call(zebra_pbr_iptable_update, 0, iptable);
|
||||
(void)dplane_pbr_iptable_delete(iptable);
|
||||
if (lookup) {
|
||||
struct listnode *node, *nnode;
|
||||
char *name;
|
||||
@ -812,6 +860,36 @@ void zebra_pbr_dplane_result(struct zebra_dplane_ctx *ctx)
|
||||
zsend_rule_notify_owner(ctx, res == ZEBRA_DPLANE_REQUEST_SUCCESS
|
||||
? ZAPI_RULE_REMOVED
|
||||
: ZAPI_RULE_FAIL_REMOVE);
|
||||
else if (op == DPLANE_OP_IPTABLE_ADD)
|
||||
zsend_iptable_notify_owner(ctx,
|
||||
res == ZEBRA_DPLANE_REQUEST_SUCCESS
|
||||
? ZAPI_IPTABLE_INSTALLED
|
||||
: ZAPI_IPTABLE_FAIL_INSTALL);
|
||||
else if (op == DPLANE_OP_IPTABLE_DELETE)
|
||||
zsend_iptable_notify_owner(ctx,
|
||||
res == ZEBRA_DPLANE_REQUEST_SUCCESS
|
||||
? ZAPI_IPTABLE_REMOVED
|
||||
: ZAPI_IPTABLE_FAIL_REMOVE);
|
||||
else if (op == DPLANE_OP_IPSET_ADD)
|
||||
zsend_ipset_notify_owner(ctx,
|
||||
res == ZEBRA_DPLANE_REQUEST_SUCCESS
|
||||
? ZAPI_IPSET_INSTALLED
|
||||
: ZAPI_IPSET_FAIL_INSTALL);
|
||||
else if (op == DPLANE_OP_IPSET_DELETE)
|
||||
zsend_ipset_notify_owner(ctx,
|
||||
res == ZEBRA_DPLANE_REQUEST_SUCCESS
|
||||
? ZAPI_IPSET_REMOVED
|
||||
: ZAPI_IPSET_FAIL_REMOVE);
|
||||
else if (op == DPLANE_OP_IPSET_ENTRY_ADD)
|
||||
zsend_ipset_entry_notify_owner(
|
||||
ctx, res == ZEBRA_DPLANE_REQUEST_SUCCESS
|
||||
? ZAPI_IPSET_ENTRY_INSTALLED
|
||||
: ZAPI_IPSET_ENTRY_FAIL_INSTALL);
|
||||
else if (op == DPLANE_OP_IPSET_ENTRY_DELETE)
|
||||
zsend_ipset_entry_notify_owner(
|
||||
ctx, res == ZEBRA_DPLANE_REQUEST_SUCCESS
|
||||
? ZAPI_IPSET_ENTRY_REMOVED
|
||||
: ZAPI_IPSET_ENTRY_FAIL_REMOVE);
|
||||
else
|
||||
flog_err(
|
||||
EC_ZEBRA_PBR_RULE_UPDATE,
|
||||
@ -822,85 +900,6 @@ void zebra_pbr_dplane_result(struct zebra_dplane_ctx *ctx)
|
||||
dplane_ctx_fini(&ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle success or failure of ipset (un)install in the kernel.
|
||||
*/
|
||||
void kernel_pbr_ipset_add_del_status(struct zebra_pbr_ipset *ipset,
|
||||
enum zebra_dplane_status res)
|
||||
{
|
||||
switch (res) {
|
||||
case ZEBRA_DPLANE_INSTALL_SUCCESS:
|
||||
zsend_ipset_notify_owner(ipset, ZAPI_IPSET_INSTALLED);
|
||||
break;
|
||||
case ZEBRA_DPLANE_INSTALL_FAILURE:
|
||||
zsend_ipset_notify_owner(ipset, ZAPI_IPSET_FAIL_INSTALL);
|
||||
break;
|
||||
case ZEBRA_DPLANE_DELETE_SUCCESS:
|
||||
zsend_ipset_notify_owner(ipset, ZAPI_IPSET_REMOVED);
|
||||
break;
|
||||
case ZEBRA_DPLANE_DELETE_FAILURE:
|
||||
zsend_ipset_notify_owner(ipset, ZAPI_IPSET_FAIL_REMOVE);
|
||||
break;
|
||||
case ZEBRA_DPLANE_STATUS_NONE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle success or failure of ipset (un)install in the kernel.
|
||||
*/
|
||||
void kernel_pbr_ipset_entry_add_del_status(
|
||||
struct zebra_pbr_ipset_entry *ipset,
|
||||
enum zebra_dplane_status res)
|
||||
{
|
||||
switch (res) {
|
||||
case ZEBRA_DPLANE_INSTALL_SUCCESS:
|
||||
zsend_ipset_entry_notify_owner(ipset,
|
||||
ZAPI_IPSET_ENTRY_INSTALLED);
|
||||
break;
|
||||
case ZEBRA_DPLANE_INSTALL_FAILURE:
|
||||
zsend_ipset_entry_notify_owner(ipset,
|
||||
ZAPI_IPSET_ENTRY_FAIL_INSTALL);
|
||||
break;
|
||||
case ZEBRA_DPLANE_DELETE_SUCCESS:
|
||||
zsend_ipset_entry_notify_owner(ipset,
|
||||
ZAPI_IPSET_ENTRY_REMOVED);
|
||||
break;
|
||||
case ZEBRA_DPLANE_DELETE_FAILURE:
|
||||
zsend_ipset_entry_notify_owner(ipset,
|
||||
ZAPI_IPSET_ENTRY_FAIL_REMOVE);
|
||||
break;
|
||||
case ZEBRA_DPLANE_STATUS_NONE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle success or failure of ipset (un)install in the kernel.
|
||||
*/
|
||||
void kernel_pbr_iptable_add_del_status(struct zebra_pbr_iptable *iptable,
|
||||
enum zebra_dplane_status res)
|
||||
{
|
||||
switch (res) {
|
||||
case ZEBRA_DPLANE_INSTALL_SUCCESS:
|
||||
zsend_iptable_notify_owner(iptable, ZAPI_IPTABLE_INSTALLED);
|
||||
break;
|
||||
case ZEBRA_DPLANE_INSTALL_FAILURE:
|
||||
zsend_iptable_notify_owner(iptable, ZAPI_IPTABLE_FAIL_INSTALL);
|
||||
break;
|
||||
case ZEBRA_DPLANE_DELETE_SUCCESS:
|
||||
zsend_iptable_notify_owner(iptable,
|
||||
ZAPI_IPTABLE_REMOVED);
|
||||
break;
|
||||
case ZEBRA_DPLANE_DELETE_FAILURE:
|
||||
zsend_iptable_notify_owner(iptable,
|
||||
ZAPI_IPTABLE_FAIL_REMOVE);
|
||||
break;
|
||||
case ZEBRA_DPLANE_STATUS_NONE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle rule delete notification from kernel.
|
||||
*/
|
||||
|
@ -64,6 +64,15 @@ struct zebra_pbr_rule {
|
||||
*
|
||||
* This is a filter mapped on ipset entries
|
||||
*/
|
||||
struct zebra_pbr_ipset_info {
|
||||
/* type is encoded as uint32_t
|
||||
* but value is an enum ipset_type
|
||||
*/
|
||||
uint32_t type;
|
||||
|
||||
char ipset_name[ZEBRA_IPSET_NAME_SIZE];
|
||||
};
|
||||
|
||||
struct zebra_pbr_ipset {
|
||||
/*
|
||||
* Originating zclient sock fd, so we can know who to send
|
||||
@ -85,6 +94,7 @@ struct zebra_pbr_ipset {
|
||||
char ipset_name[ZEBRA_IPSET_NAME_SIZE];
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* An IPSet Entry Filter
|
||||
*
|
||||
@ -177,6 +187,9 @@ void zebra_pbr_del_ipset_entry(struct zebra_pbr_ipset_entry *ipset);
|
||||
|
||||
void zebra_pbr_add_iptable(struct zebra_pbr_iptable *iptable);
|
||||
void zebra_pbr_del_iptable(struct zebra_pbr_iptable *iptable);
|
||||
void zebra_pbr_process_iptable(struct zebra_dplane_ctx *ctx);
|
||||
void zebra_pbr_process_ipset(struct zebra_dplane_ctx *ctx);
|
||||
void zebra_pbr_process_ipset_entry(struct zebra_dplane_ctx *ctx);
|
||||
|
||||
/*
|
||||
* Get to know existing PBR rules in the kernel - typically called at startup.
|
||||
@ -198,9 +211,6 @@ extern void kernel_pbr_ipset_entry_add_del_status(
|
||||
struct zebra_pbr_ipset_entry *ipset,
|
||||
enum zebra_dplane_status res);
|
||||
|
||||
extern void kernel_pbr_iptable_add_del_status(struct zebra_pbr_iptable *iptable,
|
||||
enum zebra_dplane_status res);
|
||||
|
||||
/*
|
||||
* Handle rule delete notification from kernel.
|
||||
*/
|
||||
|
@ -3887,6 +3887,12 @@ static int rib_process_dplane_results(struct thread *thread)
|
||||
case DPLANE_OP_RULE_ADD:
|
||||
case DPLANE_OP_RULE_DELETE:
|
||||
case DPLANE_OP_RULE_UPDATE:
|
||||
case DPLANE_OP_IPTABLE_ADD:
|
||||
case DPLANE_OP_IPTABLE_DELETE:
|
||||
case DPLANE_OP_IPSET_ADD:
|
||||
case DPLANE_OP_IPSET_DELETE:
|
||||
case DPLANE_OP_IPSET_ENTRY_ADD:
|
||||
case DPLANE_OP_IPSET_ENTRY_DELETE:
|
||||
zebra_pbr_dplane_result(ctx);
|
||||
break;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user