lib, zebra: Add Rule insertion success/failure messages

Add code to allow rule insertion notifications to be
sent back up the stack.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
Donald Sharp 2018-02-23 13:48:06 -05:00
parent a03219780f
commit b6c5d34354
6 changed files with 116 additions and 1 deletions

View File

@ -1237,6 +1237,35 @@ stream_failure:
return false; return false;
} }
bool zapi_rule_notify_decode(struct stream *s, uint32_t *seqno,
uint32_t *priority, uint32_t *unique,
ifindex_t *ifindex,
enum zapi_rule_notify_owner *note)
{
uint32_t prio, seq, uni;
ifindex_t ifi;
STREAM_GET(note, s, sizeof(*note));
STREAM_GETL(s, seq);
STREAM_GETL(s, prio);
STREAM_GETL(s, uni);
STREAM_GETL(s, ifi);
if (zclient_debug)
zlog_debug("%s: %u %u %u %u", __PRETTY_FUNCTION__,
seq, prio, uni, ifi);
*seqno = seq;
*priority = prio;
*unique = uni;
*ifindex = ifi;
return true;
stream_failure:
return false;
}
struct nexthop *nexthop_from_zapi_nexthop(struct zapi_nexthop *znh) struct nexthop *nexthop_from_zapi_nexthop(struct zapi_nexthop *znh)
{ {
struct nexthop *n = nexthop_new(); struct nexthop *n = nexthop_new();
@ -2381,6 +2410,10 @@ static int zclient_read(struct thread *thread)
(*zclient->route_notify_owner)(command, zclient, length, (*zclient->route_notify_owner)(command, zclient, length,
vrf_id); vrf_id);
break; break;
case ZEBRA_RULE_NOTIFY_OWNER:
if (zclient->rule_notify_owner)
(*zclient->rule_notify_owner)(command, zclient, length,
vrf_id);
default: default:
break; break;
} }

View File

@ -218,6 +218,8 @@ struct zclient {
int (*pw_status_update)(int, struct zclient *, uint16_t, vrf_id_t); int (*pw_status_update)(int, struct zclient *, uint16_t, vrf_id_t);
int (*route_notify_owner)(int command, struct zclient *zclient, int (*route_notify_owner)(int command, struct zclient *zclient,
uint16_t length, vrf_id_t vrf_id); uint16_t length, vrf_id_t vrf_id);
int (*rule_notify_owner)(int command, struct zclient *zclient,
uint16_t length, vrf_id_t vrf_id);
}; };
/* Zebra API message flag. */ /* Zebra API message flag. */
@ -361,6 +363,12 @@ enum zapi_route_notify_owner {
ZAPI_ROUTE_REMOVE_FAIL, ZAPI_ROUTE_REMOVE_FAIL,
}; };
enum zapi_rule_notify_owner {
ZAPI_RULE_FAIL_INSTALL,
ZAPI_RULE_INSTALLED,
ZAPI_RULE_REMOVED,
};
/* Zebra MAC types */ /* Zebra MAC types */
#define ZEBRA_MACIP_TYPE_STICKY 0x01 /* Sticky MAC*/ #define ZEBRA_MACIP_TYPE_STICKY 0x01 /* Sticky MAC*/
#define ZEBRA_MACIP_TYPE_GW 0x02 /* gateway (SVI) mac*/ #define ZEBRA_MACIP_TYPE_GW 0x02 /* gateway (SVI) mac*/
@ -531,6 +539,10 @@ extern int zapi_route_decode(struct stream *, struct zapi_route *);
bool zapi_route_notify_decode(struct stream *s, struct prefix *p, bool zapi_route_notify_decode(struct stream *s, struct prefix *p,
uint32_t *tableid, uint32_t *tableid,
enum zapi_route_notify_owner *note); enum zapi_route_notify_owner *note);
bool zapi_rule_notify_decode(struct stream *s, uint32_t *seqno,
uint32_t *priority, uint32_t *unique,
ifindex_t *ifindex,
enum zapi_rule_notify_owner *note);
extern struct nexthop *nexthop_from_zapi_nexthop(struct zapi_nexthop *znh); extern struct nexthop *nexthop_from_zapi_nexthop(struct zapi_nexthop *znh);
extern bool zapi_nexthop_update_decode(struct stream *s, extern bool zapi_nexthop_update_decode(struct stream *s,
struct zapi_route *nhr); struct zapi_route *nhr);

View File

@ -58,7 +58,8 @@ uint32_t zebra_pbr_rules_hash_key(void *arg)
key = jhash_1word(0, key); key = jhash_1word(0, key);
return jhash_3words(rule->filter.src_port, rule->filter.dst_port, return jhash_3words(rule->filter.src_port, rule->filter.dst_port,
prefix_hash_key(&rule->filter.dst_ip), key); prefix_hash_key(&rule->filter.dst_ip),
jhash_1word(rule->unique, key));
} }
int zebra_pbr_rules_hash_equal(const void *arg1, const void *arg2) int zebra_pbr_rules_hash_equal(const void *arg1, const void *arg2)
@ -74,6 +75,9 @@ int zebra_pbr_rules_hash_equal(const void *arg1, const void *arg2)
if (r1->priority != r2->priority) if (r1->priority != r2->priority)
return 0; return 0;
if (r1->unique != r2->unique)
return 0;
if (r1->action.table != r2->action.table) if (r1->action.table != r2->action.table)
return 0; return 0;
@ -135,6 +139,18 @@ void zebra_pbr_del_rule(struct zebra_ns *zns, struct zebra_pbr_rule *rule)
void kernel_pbr_rule_add_del_status(struct zebra_pbr_rule *rule, void kernel_pbr_rule_add_del_status(struct zebra_pbr_rule *rule,
enum southbound_results res) enum southbound_results res)
{ {
switch (res) {
case SOUTHBOUND_INSTALL_SUCCESS:
zsend_rule_notify_owner(rule, ZAPI_RULE_INSTALLED);
break;
case SOUTHBOUND_INSTALL_FAILURE:
zsend_rule_notify_owner(rule, ZAPI_RULE_FAIL_INSTALL);
break;
case SOUTHBOUND_DELETE_SUCCESS:
break;
case SOUTHBOUND_DELETE_FAILURE:
break;
}
} }
/* /*

View File

@ -28,6 +28,7 @@
#include "prefix.h" #include "prefix.h"
#include "if.h" #include "if.h"
#include "rt.h" #include "rt.h"
/* /*
@ -84,9 +85,16 @@ struct zebra_pbr_action {
* order amongst rules. * order amongst rules.
*/ */
struct zebra_pbr_rule { struct zebra_pbr_rule {
/*
* Originating zclient sock fd, so we can know who to send
* back to.
*/
int sock;
uint32_t seq; uint32_t seq;
uint32_t priority; uint32_t priority;
struct interface *ifp; struct interface *ifp;
uint32_t unique;
struct zebra_pbr_filter filter; struct zebra_pbr_filter filter;
struct zebra_pbr_action action; struct zebra_pbr_action action;
}; };
@ -112,6 +120,7 @@ extern void kernel_del_pbr_rule(struct zebra_pbr_rule *rule);
*/ */
extern void kernel_read_pbr_rules(struct zebra_ns *zns); extern void kernel_read_pbr_rules(struct zebra_ns *zns);
enum southbound_results;
/* /*
* Handle success or failure of rule (un)install in the kernel. * Handle success or failure of rule (un)install in the kernel.
*/ */

View File

@ -1043,6 +1043,44 @@ int zsend_route_notify_owner(struct route_entry *re, struct prefix *p,
return zebra_server_send_message(client); return zebra_server_send_message(client);
} }
void zsend_rule_notify_owner(struct zebra_pbr_rule *rule,
enum zapi_rule_notify_owner note)
{
struct listnode *node;
struct zserv *client;
struct stream *s;
if (IS_ZEBRA_DEBUG_PACKET) {
zlog_debug("%s: Notifying %u",
__PRETTY_FUNCTION__, rule->unique);
}
for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) {
if (rule->sock == client->sock)
break;
}
if (!client)
return;
s = client->obuf;
stream_reset(s);
zclient_create_header(s, ZEBRA_RULE_NOTIFY_OWNER, VRF_DEFAULT);
stream_put(s, &note, sizeof(note));
stream_putl(s, rule->seq);
stream_putl(s, rule->priority);
stream_putl(s, rule->unique);
if (rule->ifp)
stream_putl(s, rule->ifp->ifindex);
else
stream_putl(s, 0);
stream_putw_at(s, 0, stream_get_endp(s));
zebra_server_send_message(client);
}
/* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */ /* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
int zsend_router_id_update(struct zserv *client, struct prefix *p, int zsend_router_id_update(struct zserv *client, struct prefix *p,
vrf_id_t vrf_id) vrf_id_t vrf_id)
@ -2602,8 +2640,10 @@ static inline void zread_rule(uint16_t command, struct zserv *client,
for (i = 0; i < total; i++) { for (i = 0; i < total; i++) {
memset(&zpr, 0, sizeof(zpr)); memset(&zpr, 0, sizeof(zpr));
zpr.sock = client->sock;
STREAM_GETL(s, zpr.seq); STREAM_GETL(s, zpr.seq);
STREAM_GETL(s, zpr.priority); STREAM_GETL(s, zpr.priority);
STREAM_GETL(s, zpr.unique);
STREAM_GETC(s, zpr.filter.src_ip.family); STREAM_GETC(s, zpr.filter.src_ip.family);
STREAM_GETC(s, zpr.filter.src_ip.prefixlen); STREAM_GETC(s, zpr.filter.src_ip.prefixlen);
STREAM_GET(&zpr.filter.src_ip.u.prefix, s, STREAM_GET(&zpr.filter.src_ip.u.prefix, s,

View File

@ -31,6 +31,7 @@
#include "zebra/zebra_ns.h" #include "zebra/zebra_ns.h"
#include "zebra/zebra_pw.h" #include "zebra/zebra_pw.h"
//#include "zebra/zebra_pbr.h"
/* Default port information. */ /* Default port information. */
#define ZEBRA_VTY_PORT 2601 #define ZEBRA_VTY_PORT 2601
@ -178,6 +179,10 @@ extern int zsend_pw_update(struct zserv *, struct zebra_pw *);
extern int zsend_route_notify_owner(struct route_entry *re, struct prefix *p, extern int zsend_route_notify_owner(struct route_entry *re, struct prefix *p,
enum zapi_route_notify_owner note); enum zapi_route_notify_owner note);
struct zebra_pbr_rule;
extern void zsend_rule_notify_owner(struct zebra_pbr_rule *rule,
enum zapi_rule_notify_owner note);
extern void zserv_nexthop_num_warn(const char *, const struct prefix *, extern void zserv_nexthop_num_warn(const char *, const struct prefix *,
const unsigned int); const unsigned int);
extern int zebra_server_send_message(struct zserv *client); extern int zebra_server_send_message(struct zserv *client);