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;
}
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 *n = nexthop_new();
@ -2381,6 +2410,10 @@ static int zclient_read(struct thread *thread)
(*zclient->route_notify_owner)(command, zclient, length,
vrf_id);
break;
case ZEBRA_RULE_NOTIFY_OWNER:
if (zclient->rule_notify_owner)
(*zclient->rule_notify_owner)(command, zclient, length,
vrf_id);
default:
break;
}

View File

@ -218,6 +218,8 @@ struct zclient {
int (*pw_status_update)(int, struct zclient *, uint16_t, vrf_id_t);
int (*route_notify_owner)(int command, struct zclient *zclient,
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. */
@ -361,6 +363,12 @@ enum zapi_route_notify_owner {
ZAPI_ROUTE_REMOVE_FAIL,
};
enum zapi_rule_notify_owner {
ZAPI_RULE_FAIL_INSTALL,
ZAPI_RULE_INSTALLED,
ZAPI_RULE_REMOVED,
};
/* Zebra MAC types */
#define ZEBRA_MACIP_TYPE_STICKY 0x01 /* Sticky 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,
uint32_t *tableid,
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 bool zapi_nexthop_update_decode(struct stream *s,
struct zapi_route *nhr);

View File

@ -58,7 +58,8 @@ uint32_t zebra_pbr_rules_hash_key(void *arg)
key = jhash_1word(0, key);
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)
@ -74,6 +75,9 @@ int zebra_pbr_rules_hash_equal(const void *arg1, const void *arg2)
if (r1->priority != r2->priority)
return 0;
if (r1->unique != r2->unique)
return 0;
if (r1->action.table != r2->action.table)
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,
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 "if.h"
#include "rt.h"
/*
@ -84,9 +85,16 @@ struct zebra_pbr_action {
* order amongst rules.
*/
struct zebra_pbr_rule {
/*
* Originating zclient sock fd, so we can know who to send
* back to.
*/
int sock;
uint32_t seq;
uint32_t priority;
struct interface *ifp;
uint32_t unique;
struct zebra_pbr_filter filter;
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);
enum southbound_results;
/*
* 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);
}
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. */
int zsend_router_id_update(struct zserv *client, struct prefix *p,
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++) {
memset(&zpr, 0, sizeof(zpr));
zpr.sock = client->sock;
STREAM_GETL(s, zpr.seq);
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.prefixlen);
STREAM_GET(&zpr.filter.src_ip.u.prefix, s,

View File

@ -31,6 +31,7 @@
#include "zebra/zebra_ns.h"
#include "zebra/zebra_pw.h"
//#include "zebra/zebra_pbr.h"
/* Default port information. */
#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,
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 *,
const unsigned int);
extern int zebra_server_send_message(struct zserv *client);