diff options
| author | ßingen <bingen@voltanet.io> | 2017-05-15 17:09:28 +0200 |
|---|---|---|
| committer | David Lamparter <equinox@opensourcerouting.org> | 2017-08-09 12:35:15 +0200 |
| commit | 6833ae01bc8cb0c15579d7098f2d525a6e36c8bb (patch) | |
| tree | f9495c40c9edc6fb7f68bf91a07e56eab003db6e /lib/zclient.c | |
| parent | 2f9c59f031a76db29235cf17dc6b1e62c39370ac (diff) | |
zebra: add pseudowire manager
Base framework for supporting MPLS pseudowires in FRR.
A consistent zserv interface is provided so that any client daemon
(e.g. ldpd, bgpd) can install/uninstall pseudowires in a standard
way. Static pseudowires can also be implemented by using the same
interface.
When zebra receives a request to install a pseudowire and the installation
in the kernel or hardware fails, a notification is sent back to the
client daemon and a new install attempt is made every 60 seconds (until
it succeeds).
Support for external dataplanes is provided by the use of hooks to
install/uninstall pseudowires.
Signed-off-by: ßingen <bingen@voltanet.io>
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Diffstat (limited to 'lib/zclient.c')
| -rw-r--r-- | lib/zclient.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/lib/zclient.c b/lib/zclient.c index a6252af403..893d769e3a 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -1834,6 +1834,69 @@ int lm_release_label_chunk(struct zclient *zclient, uint32_t start, return 0; } +int zebra_send_pw(struct zclient *zclient, int command, struct zapi_pw *pw) +{ + struct stream *s; + + /* Reset stream. */ + s = zclient->obuf; + stream_reset(s); + + zclient_create_header(s, command, VRF_DEFAULT); + stream_write(s, pw->ifname, IF_NAMESIZE); + stream_putl(s, pw->ifindex); + + /* Put type */ + stream_putl(s, pw->type); + + /* Put nexthop */ + stream_putl(s, pw->af); + switch (pw->af) { + case AF_INET: + stream_put_in_addr(s, &pw->nexthop.ipv4); + break; + case AF_INET6: + stream_write(s, (u_char *)&pw->nexthop.ipv6, 16); + break; + default: + zlog_err("%s: unknown af", __func__); + return -1; + } + + /* Put labels */ + stream_putl(s, pw->local_label); + stream_putl(s, pw->remote_label); + + /* Put flags */ + stream_putc(s, pw->flags); + + /* Protocol specific fields */ + stream_write(s, &pw->data, sizeof(union pw_protocol_fields)); + + /* Put length at the first point of the stream. */ + stream_putw_at(s, 0, stream_get_endp(s)); + + return zclient_send_message(zclient); +} + +/* + * Receive PW status update from Zebra and send it to LDE process. + */ +void zebra_read_pw_status_update(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id, + struct zapi_pw_status *pw) +{ + struct stream *s; + + memset(pw, 0, sizeof(struct zapi_pw_status)); + s = zclient->ibuf; + + /* Get data. */ + stream_get(pw->ifname, s, IF_NAMESIZE); + pw->ifindex = stream_getl(s); + pw->status = stream_getl(s); +} + /* Zebra client message read function. */ static int zclient_read(struct thread *thread) { @@ -2061,6 +2124,11 @@ static int zclient_read(struct thread *thread) (*zclient->local_macip_del)(command, zclient, length, vrf_id); break; + case ZEBRA_PW_STATUS_UPDATE: + if (zclient->pw_status_update) + (*zclient->pw_status_update)(command, zclient, length, + vrf_id); + break; default: break; } |
