include ldpd/subdir.am
include babeld/subdir.am
include eigrpd/subdir.am
+include sharpd/subdir.am
include pimd/subdir.am
SUBDIRS = . @LIBRFP@ @RFPTEST@ \
fi
fi
AM_CONDITIONAL([DEV_BUILD], [test "x$enable_dev_build" = "xyes"])
+AM_CONDITIONAL([SHARPD], [test "x$enable_dev_build" = "xyes"])
dnl always want these CFLAGS
AC_C_FLAG([-fno-omit-frame-pointer])
return ZEBRA_ROUTE_NHRP;
else if (strmatch(s, "babel"))
return ZEBRA_ROUTE_BABEL;
+ else if (strmatch(s, "sharp"))
+ return ZEBRA_ROUTE_SHARP;
}
if (afi == AFI_IP6) {
if (strmatch(s, "kernel"))
return ZEBRA_ROUTE_NHRP;
else if (strmatch(s, "babel"))
return ZEBRA_ROUTE_BABEL;
+ else if (strmatch(s, "sharp"))
+ return ZEBRA_ROUTE_SHARP;
}
return -1;
}
# bgp unicast -> vnc
ZEBRA_ROUTE_BGP_DIRECT_EXT, bgp-direct-to-nve-groups, NULL, 'e', 0, 0, "BGP2VNC"
ZEBRA_ROUTE_BABEL, babel, babeld, 'A', 1, 1, "Babel"
+ZEBRA_ROUTE_SHARP, sharp, sharpd, 'D', 1, 1, "SHARP"
ZEBRA_ROUTE_ALL, wildcard, none, '-', 0, 0, "-"
ZEBRA_ROUTE_LDP, "Label Distribution Protocol (LDP)"
ZEBRA_ROUTE_VNC_DIRECT, "VNC direct (not via zebra) routes"
ZEBRA_ROUTE_BABEL, "Babel routing protocol (Babel)"
+ZEBRA_ROUTE_SHARP, "Super Happy Advanced Routing Protocol (sharpd)"
nhrpd=no
eigrpd=no
babeld=no
+sharpd=no
#
# Command line options for the daemons
#
nhrpd_options=("-A 127.0.0.1")
eigrpd_options=("-A 127.0.0.1")
babeld_options=("-A 127.0.0.1")
+sharpd_options=("-A 127.0.0.1")
#
# If the vtysh_enable is yes, then the unified config is read
--- /dev/null
+/*
+ * SHARP - main code
+ * Copyright (C) Cumulus Networks, Inc.
+ * Donald Sharp
+ *
+ * This file is part of FRR.
+ *
+ * FRR 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, or (at your option) any
+ * later version.
+ *
+ * FRR 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
+ */
+#include <zebra.h>
+
+#include <lib/version.h>
+#include "getopt.h"
+#include "thread.h"
+#include "prefix.h"
+#include "linklist.h"
+#include "if.h"
+#include "vector.h"
+#include "vty.h"
+#include "command.h"
+#include "filter.h"
+#include "plist.h"
+#include "stream.h"
+#include "log.h"
+#include "memory.h"
+#include "privs.h"
+#include "sigevent.h"
+#include "zclient.h"
+#include "keychain.h"
+#include "distribute.h"
+#include "libfrr.h"
+#include "routemap.h"
+
+#include "sharp_zebra.h"
+#include "sharp_vty.h"
+
+uint32_t total_routes = 0;
+uint32_t installed_routes = 0;
+uint32_t removed_routes = 0;
+
+zebra_capabilities_t _caps_p[] = {
+ ZCAP_NET_RAW, ZCAP_BIND, ZCAP_NET_ADMIN,
+};
+
+struct zebra_privs_t sharp_privs = {
+#if defined(FRR_USER) && defined(FRR_GROUP)
+ .user = FRR_USER,
+ .group = FRR_GROUP,
+#endif
+#if defined(VTY_GROUP)
+ .vty_group = VTY_GROUP,
+#endif
+ .caps_p = _caps_p,
+ .cap_num_p = array_size(_caps_p),
+ .cap_num_i = 0};
+
+struct option longopts[] = {{0}};
+
+/* Master of threads. */
+struct thread_master *master;
+
+/* SIGHUP handler. */
+static void sighup(void)
+{
+ zlog_info("SIGHUP received");
+}
+
+/* SIGINT / SIGTERM handler. */
+static void sigint(void)
+{
+ zlog_notice("Terminating on signal");
+
+ exit(0);
+}
+
+/* SIGUSR1 handler. */
+static void sigusr1(void)
+{
+ zlog_rotate();
+}
+
+struct quagga_signal_t sharp_signals[] = {
+ {
+ .signal = SIGHUP,
+ .handler = &sighup,
+ },
+ {
+ .signal = SIGUSR1,
+ .handler = &sigusr1,
+ },
+ {
+ .signal = SIGINT,
+ .handler = &sigint,
+ },
+ {
+ .signal = SIGTERM,
+ .handler = &sigint,
+ },
+};
+
+#define SHARP_VTY_PORT 2614
+
+FRR_DAEMON_INFO(sharpd, SHARP, .vty_port = SHARP_VTY_PORT,
+
+ .proghelp = "Implementation of a Sharp of routes daemon.",
+
+ .signals = sharp_signals,
+ .n_signals = array_size(sharp_signals),
+
+ .privs = &sharp_privs, )
+
+extern void sharp_vty_init(void);
+
+int main(int argc, char **argv, char **envp)
+{
+ frr_preinit(&sharpd_di, argc, argv);
+ frr_opt_add("", longopts, "");
+
+ while (1) {
+ int opt;
+
+ opt = frr_getopt(argc, argv, NULL);
+
+ if (opt == EOF)
+ break;
+
+ switch (opt) {
+ case 0:
+ break;
+ default:
+ frr_help_exit(1);
+ break;
+ }
+ }
+
+ master = frr_init();
+
+ vrf_init(NULL, NULL, NULL, NULL);
+
+ sharp_zebra_init();
+
+ /* Get configuration file. */
+ sharp_vty_init();
+
+ frr_config_fork();
+ frr_run(master);
+
+ /* Not reached. */
+ return 0;
+}
--- /dev/null
+/*
+ * SHARP - vty code
+ * Copyright (C) Cumulus Networks, Inc.
+ * Donald Sharp
+ *
+ * This file is part of FRR.
+ *
+ * FRR 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, or (at your option) any
+ * later version.
+ *
+ * FRR 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
+ */
+#include <zebra.h>
+
+#include "vty.h"
+#include "command.h"
+#include "prefix.h"
+#include "nexthop.h"
+#include "log.h"
+
+#include "sharpd/sharp_zebra.h"
+#include "sharpd/sharp_vty.h"
+#include "sharpd/sharp_vty_clippy.c"
+
+extern uint32_t total_routes;
+extern uint32_t installed_routes;
+extern uint32_t removed_routes;
+
+DEFPY (install_routes,
+ install_routes_cmd,
+ "install routes A.B.C.D$start nexthop A.B.C.D$nexthop (1-1000000)$routes",
+ "install some routes\n"
+ "Routes to install\n"
+ "Address to start /32 generation at\n"
+ "Nexthop to use\n"
+ "Nexthop address\n"
+ "How many to create\n")
+{
+ int i;
+ struct prefix p;
+ struct nexthop nhop;
+ uint32_t temp;
+
+ total_routes = routes;
+ installed_routes = 0;
+
+ memset(&p, 0, sizeof(p));
+ memset(&nhop, 0, sizeof(nhop));
+
+ p.family = AF_INET;
+ p.prefixlen = 32;
+ p.u.prefix4 = start;
+
+ nhop.gate.ipv4 = nexthop;
+ nhop.type = NEXTHOP_TYPE_IPV4;
+
+ zlog_debug("Inserting %ld routes", routes);
+
+ temp = ntohl(p.u.prefix4.s_addr);
+ for (i = 0 ; i < routes ; i++) {
+ route_add(&p, &nhop);
+ p.u.prefix4.s_addr = htonl(++temp);
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFPY (remove_routes,
+ remove_routes_cmd,
+ "remove routes A.B.C.D$start (1-1000000)$routes",
+ "Remove some routes\n"
+ "Routes to remove\n"
+ "Starting spot\n"
+ "Routes to uniinstall\n")
+{
+ int i;
+ struct prefix p;
+ uint32_t temp;
+
+ total_routes = routes;
+ removed_routes = 0;
+
+ memset(&p, 0, sizeof(p));
+
+ p.family = AF_INET;
+ p.prefixlen = 32;
+ p.u.prefix4 = start;
+
+ zlog_debug("Removing %ld routes", routes);
+
+ temp = ntohl(p.u.prefix4.s_addr);
+ for (i = 0; i < routes ; i++) {
+ route_delete(&p);
+ p.u.prefix4.s_addr = htonl(++temp);
+ }
+
+ return CMD_SUCCESS;
+}
+
+void sharp_vty_init(void)
+{
+ install_element(ENABLE_NODE, &install_routes_cmd);
+ install_element(ENABLE_NODE, &remove_routes_cmd);
+ return;
+}
--- /dev/null
+/*
+ * VTY library for SHARP
+ * Copyright (C) Cumulus Networks, Inc.
+ * Donald Sharp
+ *
+ * This file is part of FRR.
+ *
+ * FRR 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, or (at your option) any
+ * later version.
+ *
+ * FRR 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 __SHARP_VTY_H__
+#define __SHARP_VTY_H__
+
+extern void sharp_vty_init(void);
+#endif
--- /dev/null
+/*
+ * Zebra connect code.
+ * Copyright (C) Cumulus Networks, Inc.
+ * Donald Sharp
+ *
+ * This file is part of FRR.
+ *
+ * FRR 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, or (at your option) any
+ * later version.
+ *
+ * FRR 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
+ */
+#include <zebra.h>
+
+#include "thread.h"
+#include "command.h"
+#include "network.h"
+#include "prefix.h"
+#include "routemap.h"
+#include "table.h"
+#include "stream.h"
+#include "memory.h"
+#include "zclient.h"
+#include "filter.h"
+#include "plist.h"
+#include "log.h"
+#include "nexthop.h"
+
+#include "sharp_zebra.h"
+
+/* Zebra structure to hold current status. */
+struct zclient *zclient = NULL;
+
+/* For registering threads. */
+extern struct thread_master *master;
+
+static struct interface *zebra_interface_if_lookup(struct stream *s)
+{
+ char ifname_tmp[INTERFACE_NAMSIZ];
+
+ /* Read interface name. */
+ stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
+
+ /* And look it up. */
+ return if_lookup_by_name(ifname_tmp, VRF_DEFAULT);
+}
+
+/* Inteface addition message from zebra. */
+static int interface_add(int command, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id)
+{
+ struct interface *ifp;
+
+ ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
+
+ if (!ifp->info)
+ return 0;
+
+ return 0;
+}
+
+static int interface_delete(int command, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id)
+{
+ struct interface *ifp;
+ struct stream *s;
+
+ s = zclient->ibuf;
+ /* zebra_interface_state_read () updates interface structure in iflist
+ */
+ ifp = zebra_interface_state_read(s, vrf_id);
+
+ if (ifp == NULL)
+ return 0;
+
+ if_set_index(ifp, IFINDEX_INTERNAL);
+
+ return 0;
+}
+
+static int interface_address_add(int command, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id)
+{
+
+ zebra_interface_address_read(command, zclient->ibuf, vrf_id);
+
+ return 0;
+}
+
+static int interface_address_delete(int command, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id)
+{
+ struct connected *c;
+
+ c = zebra_interface_address_read(command, zclient->ibuf, vrf_id);
+
+ if (!c)
+ return 0;
+
+ connected_free(c);
+ return 0;
+}
+
+static int interface_state_up(int command, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id)
+{
+
+ zebra_interface_if_lookup(zclient->ibuf);
+
+ return 0;
+}
+
+static int interface_state_down(int command, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id)
+{
+
+ zebra_interface_state_read(zclient->ibuf, vrf_id);
+
+ return 0;
+}
+
+extern uint32_t total_routes;
+extern uint32_t installed_routes;
+
+static int notify_owner(int command, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id)
+{
+ struct prefix p;
+ enum zapi_route_notify_owner note;
+
+ if (!zapi_route_notify_decode(zclient->ibuf, &p, ¬e))
+ return -1;
+
+ installed_routes++;
+
+ if (total_routes == installed_routes)
+ zlog_debug("Installed All Items");
+ return 0;
+}
+
+static void zebra_connected(struct zclient *zclient)
+{
+ zclient_send_reg_requests(zclient, VRF_DEFAULT);
+}
+
+void route_add(struct prefix *p, struct nexthop *nh)
+{
+ struct zapi_route api;
+ struct zapi_nexthop *api_nh;
+
+ memset(&api, 0, sizeof(api));
+ api.vrf_id = VRF_DEFAULT;
+ api.type = ZEBRA_ROUTE_SHARP;
+ api.safi = SAFI_UNICAST;
+ memcpy(&api.prefix, p, sizeof(*p));
+
+ SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
+
+ api_nh = &api.nexthops[0];
+ api_nh->gate.ipv4 = nh->gate.ipv4;
+ api_nh->type = nh->type;
+ api_nh->ifindex = nh->ifindex;
+ api.nexthop_num = 1;
+
+ zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
+}
+
+void route_delete(struct prefix *p)
+{
+ struct zapi_route api;
+
+ memset(&api, 0, sizeof(api));
+ api.vrf_id = VRF_DEFAULT;
+ api.type = ZEBRA_ROUTE_SHARP;
+ api.safi = SAFI_UNICAST;
+ memcpy(&api.prefix, p, sizeof(*p));
+ zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
+
+ return;
+}
+
+extern struct zebra_privs_t sharp_privs;
+
+void sharp_zebra_init(void)
+{
+ struct zclient_options opt = { .receive_notify = true };
+
+ zclient = zclient_new_notify(master, &opt);
+
+ zclient_init(zclient, ZEBRA_ROUTE_SHARP, 0, &sharp_privs);
+ zclient->zebra_connected = zebra_connected;
+ zclient->interface_add = interface_add;
+ zclient->interface_delete = interface_delete;
+ zclient->interface_up = interface_state_up;
+ zclient->interface_down = interface_state_down;
+ zclient->interface_address_add = interface_address_add;
+ zclient->interface_address_delete = interface_address_delete;
+ zclient->notify_owner = notify_owner;
+}
--- /dev/null
+/*
+ * Zebra connect library for SHARP
+ * Copyright (C) Cumulus Networks, Inc.
+ * Donald Sharp
+ *
+ * This file is part of FRR.
+ *
+ * FRR 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, or (at your option) any
+ * later version.
+ *
+ * FRR 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 __SHARP_ZEBRA_H__
+#define __SHARP_ZEBRA_H__
+
+extern void sharp_zebra_init(void);
+
+extern void route_add(struct prefix *p, struct nexthop *nh);
+extern void route_delete(struct prefix *p);
+#endif
--- /dev/null
+!
+!
+log stdout
--- /dev/null
+#
+# sharpd
+#
+
+if SHARPD
+noinst_LIBRARIES += sharpd/libsharp.a
+sbin_PROGRAMS += sharpd/sharpd
+dist_examples_DATA += sharpd/sharpd.conf.sample
+endif
+
+sharpd_libsharp_a_SOURCES = \
+ sharpd/sharp_zebra.c \
+ sharpd/sharp_vty.c \
+ # end
+
+sharpd/sharp_vty_clippy.c: $(CLIPPY_DEPS)
+sharpd/sharp_vty.$(OBJEXT): sharpd/sharp_vty_clippy.c
+
+sharpd_sharpd_SOURCES = sharpd/sharp_main.c
+sharpd_sharpd_LDADD = sharpd/libsharp.a lib/libfrr.la @LIBCAP@
+
nhrpd=no
eigrpd=no
babeld=no
+sharpd=no
nhrpd_options=" --daemon -A 127.0.0.1"
eigrpd_options=" --daemon -A 127.0.0.1"
babeld_options=" --daemon -A 127.0.0.1"
+sharpd_options=" --daemon -A 127.0.0.1"
# The list of daemons to watch is automatically generated by the init script.
watchfrr_enable=yes
191 nhrp
192 eigrp
193 ldp
+194 sharp
\ No newline at end of file
# Local Daemon selection may be done by using /etc/frr/daemons.
# See /usr/share/doc/frr/README.Debian.gz for further information.
# Keep zebra first and do not list watchfrr!
-DAEMONS="zebra bgpd ripd ripngd ospfd ospf6d isisd babeld pimd ldpd nhrpd eigrpd"
+DAEMONS="zebra bgpd ripd ripngd ospfd ospf6d isisd babeld pimd ldpd nhrpd eigrpd sharpd"
MAX_INSTANCES=5
RELOAD_SCRIPT=/usr/lib/frr/frr-reload.py
vtysh_scan += $(top_srcdir)/babeld/babeld.c
endif
+if SHARPD
+vtysh_scan += $(top_srcdir)/sharpd/sharp_vty.c
+endif
+
if SNMP
vtysh_scan += $(top_srcdir)/lib/agentx.c
endif
$protocol = "VTYSH_RIPD";
}
elsif ($file =~ /lib\/routemap\.c$/) {
- $protocol = "VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ZEBRA|VTYSH_PIMD|VTYSH_EIGRPD";
+ $protocol = "VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ZEBRA|VTYSH_PIMD|VTYSH_EIGRPD|VTYSH_SHARPD";
}
elsif ($file =~ /lib\/vrf\.c$/) {
$protocol = "VTYSH_ALL";
{.fd = -1, .name = "nhrpd", .flag = VTYSH_NHRPD, .next = NULL},
{.fd = -1, .name = "eigrpd", .flag = VTYSH_EIGRPD, .next = NULL},
{.fd = -1, .name = "babeld", .flag = VTYSH_BABELD, .next = NULL},
+ {.fd = -1, .name = "sharpd", .flag = VTYSH_SHARPD, .next = NULL},
{.fd = -1, .name = "watchfrr", .flag = VTYSH_WATCHFRR, .next = NULL},
};
#define VTYSH_NHRPD 0x800
#define VTYSH_EIGRPD 0x1000
#define VTYSH_BABELD 0x2000
+#define VTYSH_SHARPD 0x4000
+
/* commands in REALLYALL are crucial to correct vtysh operation */
#define VTYSH_REALLYALL ~0U
/* watchfrr is not in ALL since library CLI functions should not be
* run on it (logging & co. should stay in a fixed/frozen config, and
* things like prefix lists are not even initialised) */
-#define VTYSH_ALL VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_LDPD|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD|VTYSH_NHRPD|VTYSH_EIGRPD|VTYSH_BABELD
+#define VTYSH_ALL VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_LDPD|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD|VTYSH_NHRPD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_SHARPD
#define VTYSH_RMAP VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_PIMD|VTYSH_EIGRPD
#define VTYSH_INTERFACE VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_ISISD|VTYSH_PIMD|VTYSH_NHRPD|VTYSH_EIGRPD|VTYSH_BABELD
#define VTYSH_NS VTYSH_ZEBRA
|| (proto == RTPROT_ISIS) || (proto == RTPROT_RIPNG)
|| (proto == RTPROT_NHRP) || (proto == RTPROT_EIGRP)
|| (proto == RTPROT_LDP) || (proto == RTPROT_BABEL)
- || (proto == RTPROT_RIP)) {
+ || (proto == RTPROT_RIP) || (proto == RTPROT_SHARP)) {
return 1;
}
case ZEBRA_ROUTE_LDP:
proto = RTPROT_LDP;
break;
+ case ZEBRA_ROUTE_SHARP:
+ proto = RTPROT_SHARP;
+ break;
default:
proto = RTPROT_ZEBRA;
break;
#define RTPROT_NHRP 191
#define RTPROT_EIGRP 192
#define RTPROT_LDP 193
+#define RTPROT_SHARP 194
void rt_netlink_init(void);