From b6c5d34354c7153bebd2c51e89fd2e32f0dc343c Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 23 Feb 2018 13:48:06 -0500 Subject: [PATCH] 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 --- lib/zclient.c | 33 +++++++++++++++++++++++++++++++++ lib/zclient.h | 12 ++++++++++++ zebra/zebra_pbr.c | 18 +++++++++++++++++- zebra/zebra_pbr.h | 9 +++++++++ zebra/zserv.c | 40 ++++++++++++++++++++++++++++++++++++++++ zebra/zserv.h | 5 +++++ 6 files changed, 116 insertions(+), 1 deletion(-) diff --git a/lib/zclient.c b/lib/zclient.c index 3f2021a5b..fa3a5f669 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -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; } diff --git a/lib/zclient.h b/lib/zclient.h index a315a7ed5..1aa94b641 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -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); diff --git a/zebra/zebra_pbr.c b/zebra/zebra_pbr.c index 0096da942..4da09dc53 100644 --- a/zebra/zebra_pbr.c +++ b/zebra/zebra_pbr.c @@ -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; + } } /* diff --git a/zebra/zebra_pbr.h b/zebra/zebra_pbr.h index 9983de4f2..4b28b6ec3 100644 --- a/zebra/zebra_pbr.h +++ b/zebra/zebra_pbr.h @@ -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. */ diff --git a/zebra/zserv.c b/zebra/zserv.c index d05b058c7..1a2ad7f8b 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -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, ¬e, 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, diff --git a/zebra/zserv.h b/zebra/zserv.h index 4f0f5b046..851969372 100644 --- a/zebra/zserv.h +++ b/zebra/zserv.h @@ -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); -- 2.39.2