diff options
Diffstat (limited to 'lib/zclient.c')
| -rw-r--r-- | lib/zclient.c | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/lib/zclient.c b/lib/zclient.c index d23f62dcd7..e1ce40ce70 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -36,6 +36,7 @@ #include "nexthop.h" #include "mpls.h" #include "sockopt.h" +#include "pbr.h" DEFINE_MTYPE_STATIC(LIB, ZCLIENT, "Zclient") DEFINE_MTYPE_STATIC(LIB, REDIST_INST, "Redistribution instance IDs") @@ -1229,6 +1230,55 @@ stream_failure: return 0; } +static void zapi_encode_prefix(struct stream *s, + struct prefix *p, + uint8_t family) +{ + struct prefix any; + + if (!p) { + memset(&any, 0, sizeof(any)); + any.family = family; + p = &any; + } + + stream_putc(s, p->family); + stream_putc(s, p->prefixlen); + stream_put(s, &p->u.prefix, prefix_blen(p)); +} + +int zapi_pbr_rule_encode(uint8_t cmd, struct stream *s, + struct pbr_rule *zrule) +{ + stream_reset(s); + zclient_create_header(s, cmd, zrule->vrf_id); + + /* + * We are sending one item at a time at the moment + */ + stream_putl(s, 1); + + stream_putl(s, zrule->seq); + stream_putl(s, zrule->priority); + stream_putl(s, zrule->unique); + + zapi_encode_prefix(s, &(zrule->filter.src_ip), + zrule->filter.src_ip.family); + stream_putw(s, zrule->filter.src_port); /* src port */ + zapi_encode_prefix(s, &(zrule->filter.dst_ip), + zrule->filter.src_ip.family); + stream_putw(s, zrule->filter.dst_port); /* dst port */ + stream_putw(s, zrule->filter.fwmark); /* fwmark */ + + stream_putl(s, zrule->action.table); + stream_putl(s, zrule->ifindex); + + /* Put length at the first point of the stream. */ + stream_putw_at(s, 0, stream_get_endp(s)); + + return 0; +} + bool zapi_route_notify_decode(struct stream *s, struct prefix *p, uint32_t *tableid, enum zapi_route_notify_owner *note) @@ -1279,6 +1329,50 @@ stream_failure: return false; } +bool zapi_ipset_notify_decode(struct stream *s, + uint32_t *unique, + enum zapi_ipset_notify_owner *note) +{ + uint32_t uni; + + STREAM_GET(note, s, sizeof(*note)); + + STREAM_GETL(s, uni); + + if (zclient_debug) + zlog_debug("%s: %u", __PRETTY_FUNCTION__, uni); + *unique = uni; + + return true; + +stream_failure: + return false; +} + +bool zapi_ipset_entry_notify_decode(struct stream *s, + uint32_t *unique, + char *ipset_name, + enum zapi_ipset_entry_notify_owner *note) +{ + uint32_t uni; + + STREAM_GET(note, s, sizeof(*note)); + + STREAM_GETL(s, uni); + + STREAM_GET(ipset_name, s, + ZEBRA_IPSET_NAME_SIZE); + + if (zclient_debug) + zlog_debug("%s: %u", __PRETTY_FUNCTION__, uni); + *unique = uni; + + return true; + +stream_failure: + return false; +} + struct nexthop *nexthop_from_zapi_nexthop(struct zapi_nexthop *znh) { struct nexthop *n = nexthop_new(); @@ -1991,6 +2085,40 @@ int lm_label_manager_connect(struct zclient *zclient) return (int)result; } +/* + * Asynchronous label chunk request + * + * @param zclient Zclient used to connect to label manager (zebra) + * @param keep Avoid garbage collection + * @param chunk_size Amount of labels requested + * @result 0 on success, -1 otherwise + */ +int zclient_send_get_label_chunk( + struct zclient *zclient, + uint8_t keep, + uint32_t chunk_size) +{ + struct stream *s; + + if (zclient_debug) + zlog_debug("Getting Label Chunk"); + + if (zclient->sock < 0) + return -1; + + s = zclient->obuf; + stream_reset(s); + + zclient_create_header(s, ZEBRA_GET_LABEL_CHUNK, VRF_DEFAULT); + stream_putc(s, keep); + stream_putl(s, chunk_size); + + /* Put length at the first point of the stream. */ + stream_putw_at(s, 0, stream_get_endp(s)); + + return zclient_send_message(zclient); +} + /** * Function to request a label chunk in a syncronous way * @@ -2604,6 +2732,12 @@ static int zclient_read(struct thread *thread) if (zclient->rule_notify_owner) (*zclient->rule_notify_owner)(command, zclient, length, vrf_id); + break; + case ZEBRA_GET_LABEL_CHUNK: + if (zclient->label_chunk) + (*zclient->label_chunk)(command, zclient, length, + vrf_id); + break; default: break; } |
