diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/Makefile.am | 1 | ||||
| -rw-r--r-- | lib/command.c | 2 | ||||
| -rw-r--r-- | lib/command.h | 1 | ||||
| -rw-r--r-- | lib/log.c | 5 | ||||
| -rw-r--r-- | lib/pw.h | 53 | ||||
| -rw-r--r-- | lib/vty.c | 2 | ||||
| -rw-r--r-- | lib/zclient.c | 70 | ||||
| -rw-r--r-- | lib/zclient.h | 38 |
8 files changed, 172 insertions, 0 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am index 14b7130c8a..1f31806973 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -73,6 +73,7 @@ pkginclude_HEADERS = \ module.h \ hook.h \ libfrr.h \ + pw.h \ # end noinst_HEADERS = \ diff --git a/lib/command.c b/lib/command.c index 4912461adb..c2ee79035a 100644 --- a/lib/command.c +++ b/lib/command.c @@ -1392,6 +1392,7 @@ cmd_exit (struct vty *vty) vty_config_unlock (vty); break; case INTERFACE_NODE: + case PW_NODE: case NS_NODE: case VRF_NODE: case ZEBRA_NODE: @@ -1471,6 +1472,7 @@ DEFUN (config_end, break; case CONFIG_NODE: case INTERFACE_NODE: + case PW_NODE: case NS_NODE: case VRF_NODE: case ZEBRA_NODE: diff --git a/lib/command.h b/lib/command.h index 223f028144..313d73f7c8 100644 --- a/lib/command.h +++ b/lib/command.h @@ -130,6 +130,7 @@ enum node_type FORWARDING_NODE, /* IP forwarding node. */ PROTOCOL_NODE, /* protocol filtering node */ MPLS_NODE, /* MPLS config node */ + PW_NODE, /* Pseudowire config node */ VTY_NODE, /* Vty node. */ LINK_PARAMS_NODE, /* Link-parameters node */ }; @@ -937,6 +937,11 @@ static const struct zebra_desc_table command_types[] = { DESC_ENTRY (ZEBRA_LABEL_MANAGER_CONNECT), DESC_ENTRY (ZEBRA_GET_LABEL_CHUNK), DESC_ENTRY (ZEBRA_RELEASE_LABEL_CHUNK), + DESC_ENTRY (ZEBRA_PW_ADD), + DESC_ENTRY (ZEBRA_PW_DELETE), + DESC_ENTRY (ZEBRA_PW_SET), + DESC_ENTRY (ZEBRA_PW_UNSET), + DESC_ENTRY (ZEBRA_PW_STATUS_UPDATE), }; #undef DESC_ENTRY diff --git a/lib/pw.h b/lib/pw.h new file mode 100644 index 0000000000..63d8e52ddd --- /dev/null +++ b/lib/pw.h @@ -0,0 +1,53 @@ +/* Pseudowire definitions + * Copyright (C) 2016 Volta Networks, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef _FRR_PW_H +#define _FRR_PW_H + +/* L2VPN name length. */ +#define L2VPN_NAME_LEN 32 + +/* Pseudowire type - LDP and BGP use the same values. */ +#define PW_TYPE_ETHERNET_TAGGED 0x0004 /* RFC 4446 */ +#define PW_TYPE_ETHERNET 0x0005 /* RFC 4446 */ +#define PW_TYPE_WILDCARD 0x7FFF /* RFC 4863, RFC 6668 */ + +/* Pseudowire flags. */ +#define F_PSEUDOWIRE_CWORD 0x01 + +/* Pseudowire status. */ +#define PW_STATUS_DOWN 0 +#define PW_STATUS_UP 1 + +/* + * Protocol-specific information about the pseudowire. + */ +union pw_protocol_fields +{ + struct { + struct in_addr lsr_id; + uint32_t pwid; + char vpn_name[L2VPN_NAME_LEN]; + } ldp; + struct { + /* TODO */ + } bgp; +}; + +#endif /* _FRR_PW_H */ @@ -732,6 +732,7 @@ vty_end_config (struct vty *vty) break; case CONFIG_NODE: case INTERFACE_NODE: + case PW_NODE: case ZEBRA_NODE: case RIP_NODE: case RIPNG_NODE: @@ -1157,6 +1158,7 @@ vty_stop_input (struct vty *vty) break; case CONFIG_NODE: case INTERFACE_NODE: + case PW_NODE: case ZEBRA_NODE: case RIP_NODE: case RIPNG_NODE: diff --git a/lib/zclient.c b/lib/zclient.c index 6aea4bd0a3..9338f9c986 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -1715,6 +1715,72 @@ lm_release_label_chunk (struct zclient *zclient, uint32_t start, uint32_t end) 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) @@ -1899,6 +1965,10 @@ zclient_read (struct thread *thread) if (zclient->interface_link_params) (*zclient->interface_link_params) (command, zclient, length); break; + case ZEBRA_PW_STATUS_UPDATE: + if (zclient->pw_status_update) + (*zclient->pw_status_update) (command, zclient, length, vrf_id); + break; default: break; } diff --git a/lib/zclient.h b/lib/zclient.h index d3d0a202c5..489ed24c86 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -31,6 +31,12 @@ /* For vrf_bitmap_t. */ #include "vrf.h" +/* For union g_addr */ +#include "nexthop.h" + +/* For union pw_protocol_fields */ +#include "pw.h" + /* For input/output buffer to zebra. */ #define ZEBRA_MAX_PACKET_SIZ 4096 @@ -94,6 +100,11 @@ typedef enum { ZEBRA_LABEL_MANAGER_CONNECT, ZEBRA_GET_LABEL_CHUNK, ZEBRA_RELEASE_LABEL_CHUNK, + ZEBRA_PW_ADD, + ZEBRA_PW_DELETE, + ZEBRA_PW_SET, + ZEBRA_PW_UNSET, + ZEBRA_PW_STATUS_UPDATE, } zebra_message_types_t; struct redist_proto @@ -164,6 +175,7 @@ struct zclient int (*redistribute_route_ipv4_del) (int, struct zclient *, uint16_t, vrf_id_t); int (*redistribute_route_ipv6_add) (int, struct zclient *, uint16_t, vrf_id_t); int (*redistribute_route_ipv6_del) (int, struct zclient *, uint16_t, vrf_id_t); + int (*pw_status_update) (int, struct zclient *, uint16_t, vrf_id_t); }; /* Zebra API message flag. */ @@ -217,6 +229,27 @@ struct zapi_ipv4 vrf_id_t vrf_id; }; +struct zapi_pw +{ + char ifname[IF_NAMESIZE]; + ifindex_t ifindex; + int type; + int af; + union g_addr nexthop; + uint32_t local_label; + uint32_t remote_label; + uint8_t flags; + union pw_protocol_fields data; + uint8_t protocol; +}; + +struct zapi_pw_status +{ + char ifname[IF_NAMESIZE]; + ifindex_t ifindex; + uint32_t status; +}; + /* Prototypes of zebra client service functions. */ extern struct zclient *zclient_new (struct thread_master *); extern void zclient_init (struct zclient *, int, u_short); @@ -278,6 +311,11 @@ extern int lm_label_manager_connect (struct zclient *zclient); extern int lm_get_label_chunk (struct zclient *zclient, u_char keep, uint32_t chunk_size, uint32_t *start, uint32_t *end); extern int lm_release_label_chunk (struct zclient *zclient, uint32_t start, uint32_t end); +extern int zebra_send_pw(struct zclient *zclient, int command, struct zapi_pw *pw); +extern 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); + /* IPv6 prefix add and delete function prototype. */ struct zapi_ipv6 |
