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();
(*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;
}
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. */
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*/
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);
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)
if (r1->priority != r2->priority)
return 0;
+ if (r1->unique != r2->unique)
+ return 0;
+
if (r1->action.table != r2->action.table)
return 0;
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;
+ }
}
/*
#include "prefix.h"
#include "if.h"
+
#include "rt.h"
/*
* 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;
};
*/
extern void kernel_read_pbr_rules(struct zebra_ns *zns);
+enum southbound_results;
/*
* Handle success or failure of rule (un)install in the kernel.
*/
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)
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,
#include "zebra/zebra_ns.h"
#include "zebra/zebra_pw.h"
+//#include "zebra/zebra_pbr.h"
/* Default port information. */
#define ZEBRA_VTY_PORT 2601
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);