diff --git a/configure.ac b/configure.ac index eb1f1de6c1..e15f384c21 100755 --- a/configure.ac +++ b/configure.ac @@ -309,6 +309,8 @@ AC_ARG_ENABLE(systemd, AS_HELP_STRING([--enable-systemd], [enable Systemd support])) AC_ARG_ENABLE(poll, AS_HELP_STRING([--enable-poll], [enable usage of Poll instead of select])) +AC_ARG_ENABLE(mpls, + AS_HELP_STRING([--enable-mpls], [enable MPLS support - requires compatible kernel])) AC_ARG_ENABLE(werror, AS_HELP_STRING([--enable-werror], [enable -Werror (recommended for developers only)])) AC_ARG_ENABLE(cumulus, @@ -360,6 +362,29 @@ if test "${enable_poll}" = "yes" ; then AC_DEFINE(HAVE_POLL,,Compile systemd support in) fi +dnl ---------- +dnl MPLS check +dnl ---------- +MPLS_METHOD="" +AC_MSG_CHECKING(whether this OS has MPLS stack) +if test "x${enable_mpls}" = "xyes"; then + case "$host" in + *-linux*) + AC_DEFINE(HAVE_MPLS,,Enable MPLS) + MPLS_METHOD="zebra_mpls_netlink.o" + AC_MSG_RESULT(Linux MPLS) + ;; + *) + AC_MSG_RESULT(Unsupported kernel) + MPLS_METHOD="zebra_mpls_null.o" + ;; + esac +else + AC_MSG_RESULT(disabled) + MPLS_METHOD="zebra_mpls_null.o" +fi +AC_SUBST(MPLS_METHOD) + if test "${enable_cumulus}" = "yes" ; then AC_DEFINE(HAVE_CUMULUS,,Compile Special Cumulus Code in) fi diff --git a/zebra/Makefile.am b/zebra/Makefile.am index 10f7850c96..b08c37f55e 100644 --- a/zebra/Makefile.am +++ b/zebra/Makefile.am @@ -12,9 +12,10 @@ rt_method = @RT_METHOD@ rtread_method = @RTREAD_METHOD@ kernel_method = @KERNEL_METHOD@ ioctl_method = @IOCTL_METHOD@ +mpls_method = @MPLS_METHOD@ otherobj = $(ioctl_method) $(ipforward) $(if_method) \ - $(rt_method) $(rtread_method) $(kernel_method) + $(rt_method) $(rtread_method) $(kernel_method) $(mpls_method) if HAVE_NETLINK othersrc = zebra_fpm_netlink.c @@ -38,7 +39,7 @@ testzebra_SOURCES = test_main.c zebra_rib.c interface.c connected.c debug.c \ zebra_vty.c zebra_ptm.c zebra_routemap.c zebra_ns.c zebra_vrf.c \ kernel_null.c redistribute_null.c ioctl_null.c misc_null.c zebra_rnh_null.c \ zebra_ptm_null.c rtadv_null.c if_null.c zserv_null.c zebra_static.c \ - zebra_memory.c zebra_mpls_null.c + zebra_memory.c zebra_mpls.c zebra_mpls_null.c noinst_HEADERS = \ zebra_memory.h \ diff --git a/zebra/kernel_null.c b/zebra/kernel_null.c index 0802570e60..17b3c7bc8d 100644 --- a/zebra/kernel_null.c +++ b/zebra/kernel_null.c @@ -30,7 +30,6 @@ #include "zebra/connected.h" #include "zebra/rt_netlink.h" #include "zebra/rib.h" -#include "zebra/zebra_mpls.h" int kernel_add_ipv4 (struct prefix *a, struct rib *b) { return 0; } int kernel_update_ipv4 (struct prefix *a, struct rib *b) { return 0; } @@ -66,9 +65,3 @@ int kernel_neigh_update (int a, int b, uint32_t c, char *d, int e) void kernel_init (struct zebra_ns *zns) { return; } void kernel_terminate (struct zebra_ns *zns) { return; } void route_read (struct zebra_ns *zns) { return; } - -int kernel_add_lsp (zebra_lsp_t *l) { return 0; } - -int kernel_del_lsp (zebra_lsp_t *l) { return 0; } - -int kernel_upd_lsp (zebra_lsp_t *l) { return 0; } diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 07d2923028..95c8892979 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -2805,7 +2805,7 @@ kernel_neigh_update (int add, int ifindex, uint32_t addr, char *lla, int llalen) /* * MPLS label forwarding table change via netlink interface. */ -static int +int netlink_mpls_multipath (int cmd, zebra_lsp_t *lsp) { mpls_lse_t lse; @@ -2977,7 +2977,7 @@ netlink_mpls_multipath (int cmd, zebra_lsp_t *lsp) /* * Handle failure in LSP install, clear flags for NHLFE. */ -static inline void +void clear_nhlfe_installed (zebra_lsp_t *lsp) { zebra_nhlfe_t *nhlfe; @@ -2994,80 +2994,6 @@ clear_nhlfe_installed (zebra_lsp_t *lsp) } } -/* - * Install Label Forwarding entry into the kernel. - */ -int -kernel_add_lsp (zebra_lsp_t *lsp) -{ - int ret; - - if (!lsp || !lsp->best_nhlfe) // unexpected - return -1; - - UNSET_FLAG (lsp->flags, LSP_FLAG_CHANGED); - ret = netlink_mpls_multipath (RTM_NEWROUTE, lsp); - if (!ret) - SET_FLAG (lsp->flags, LSP_FLAG_INSTALLED); - else - clear_nhlfe_installed (lsp); - - return ret; -} - -/* - * Update Label Forwarding entry in the kernel. This means that the Label - * forwarding entry is already installed and needs an update - either a new - * path is to be added, an installed path has changed (e.g., outgoing label) - * or an installed path (but not all paths) has to be removed. - * TODO: Performs a DEL followed by ADD now, need to change to REPLACE. Note - * that REPLACE was originally implemented for IPv4 nexthops but removed as - * it was not functioning when moving from swap to PHP as that was signaled - * through the metric field (before kernel-MPLS). This shouldn't be an issue - * any longer, so REPLACE can be reintroduced. - */ -int -kernel_upd_lsp (zebra_lsp_t *lsp) -{ - int ret; - - if (!lsp || !lsp->best_nhlfe) // unexpected - return -1; - - UNSET_FLAG (lsp->flags, LSP_FLAG_CHANGED); - - /* First issue a DEL and clear the installed flag. */ - netlink_mpls_multipath (RTM_DELROUTE, lsp); - UNSET_FLAG (lsp->flags, LSP_FLAG_INSTALLED); - - /* Then issue an ADD. */ - ret = netlink_mpls_multipath (RTM_NEWROUTE, lsp); - if (!ret) - SET_FLAG (lsp->flags, LSP_FLAG_INSTALLED); - else - clear_nhlfe_installed (lsp); - - return ret; -} - -/* - * Delete Label Forwarding entry from the kernel. - */ -int -kernel_del_lsp (zebra_lsp_t *lsp) -{ - if (!lsp) // unexpected - return -1; - - if (CHECK_FLAG (lsp->flags, LSP_FLAG_INSTALLED)) - { - netlink_mpls_multipath (RTM_DELROUTE, lsp); - UNSET_FLAG (lsp->flags, LSP_FLAG_INSTALLED); - } - - return 0; -} - extern struct thread_master *master; /* Kernel route reflection. */ diff --git a/zebra/rt_netlink.h b/zebra/rt_netlink.h index 80d035e839..7d8b2e7040 100644 --- a/zebra/rt_netlink.h +++ b/zebra/rt_netlink.h @@ -24,6 +24,8 @@ #ifdef HAVE_NETLINK +#include "zebra/zebra_mpls.h" + #define NL_PKT_BUF_SIZE 8192 #define NL_DEFAULT_ROUTE_METRIC 20 @@ -41,6 +43,11 @@ nl_msg_type_to_str (uint16_t msg_type); extern const char * nl_rtproto_to_str (u_char rtproto); +extern void +clear_nhlfe_installed (zebra_lsp_t *lsp); +extern int +netlink_mpls_multipath (int cmd, zebra_lsp_t *lsp); + extern int interface_lookup_netlink (struct zebra_ns *zns); extern int netlink_route_read (struct zebra_ns *zns); diff --git a/zebra/zebra_mpls_netlink.c b/zebra/zebra_mpls_netlink.c new file mode 100644 index 0000000000..f5678ede31 --- /dev/null +++ b/zebra/zebra_mpls_netlink.c @@ -0,0 +1,78 @@ +#include +#include "zebra/rt.h" +#include "zebra/rt_netlink.h" +#include "zebra/zebra_mpls.h" + +/* + * Install Label Forwarding entry into the kernel. + */ +int +kernel_add_lsp (zebra_lsp_t *lsp) +{ + int ret; + + if (!lsp || !lsp->best_nhlfe) // unexpected + return -1; + + UNSET_FLAG (lsp->flags, LSP_FLAG_CHANGED); + ret = netlink_mpls_multipath (RTM_NEWROUTE, lsp); + if (!ret) + SET_FLAG (lsp->flags, LSP_FLAG_INSTALLED); + else + clear_nhlfe_installed (lsp); + + return ret; +} + +/* + * Update Label Forwarding entry in the kernel. This means that the Label + * forwarding entry is already installed and needs an update - either a new + * path is to be added, an installed path has changed (e.g., outgoing label) + * or an installed path (but not all paths) has to be removed. + * TODO: Performs a DEL followed by ADD now, need to change to REPLACE. Note + * that REPLACE was originally implemented for IPv4 nexthops but removed as + * it was not functioning when moving from swap to PHP as that was signaled + * through the metric field (before kernel-MPLS). This shouldn't be an issue + * any longer, so REPLACE can be reintroduced. + */ +int +kernel_upd_lsp (zebra_lsp_t *lsp) +{ + int ret; + + if (!lsp || !lsp->best_nhlfe) // unexpected + return -1; + + UNSET_FLAG (lsp->flags, LSP_FLAG_CHANGED); + + /* First issue a DEL and clear the installed flag. */ + netlink_mpls_multipath (RTM_DELROUTE, lsp); + UNSET_FLAG (lsp->flags, LSP_FLAG_INSTALLED); + + /* Then issue an ADD. */ + ret = netlink_mpls_multipath (RTM_NEWROUTE, lsp); + if (!ret) + SET_FLAG (lsp->flags, LSP_FLAG_INSTALLED); + else + clear_nhlfe_installed (lsp); + + return ret; +} + +/* + * Delete Label Forwarding entry from the kernel. + */ +int +kernel_del_lsp (zebra_lsp_t *lsp) +{ + if (!lsp) // unexpected + return -1; + + if (CHECK_FLAG (lsp->flags, LSP_FLAG_INSTALLED)) + { + netlink_mpls_multipath (RTM_DELROUTE, lsp); + UNSET_FLAG (lsp->flags, LSP_FLAG_INSTALLED); + } + + return 0; +} diff --git a/zebra/zebra_mpls_null.c b/zebra/zebra_mpls_null.c index 2953138dbc..9022fe30d2 100644 --- a/zebra/zebra_mpls_null.c +++ b/zebra/zebra_mpls_null.c @@ -1,81 +1,7 @@ #include -#include "nexthop.h" -#include "zebra/rib.h" -#include "zebra/zserv.h" +#include "zebra/rt.h" #include "zebra/zebra_mpls.h" -int -mpls_str2label (const char *label_str, u_int8_t *num_labels, - mpls_label_t *labels) -{ - return 0; -} - -char * -mpls_label2str (u_int8_t num_labels, mpls_label_t *labels, - char *buf, int len) -{ - return NULL; -} - -int -zebra_mpls_lsp_label_consistent (struct zebra_vrf *zvrf, mpls_label_t in_label, - mpls_label_t out_label, enum nexthop_types_t gtype, - union g_addr *gate, char *ifname, ifindex_t ifindex) -{ - return 1; -} - -int -zebra_mpls_static_lsp_add (struct zebra_vrf *zvrf, mpls_label_t in_label, - mpls_label_t out_label, enum nexthop_types_t gtype, - union g_addr *gate, char *ifname, ifindex_t ifindex) -{ - return 0; -} - -int -zebra_mpls_static_lsp_del (struct zebra_vrf *zvrf, mpls_label_t in_label, - enum nexthop_types_t gtype, union g_addr *gate, - char *ifname, ifindex_t ifindex) -{ - return 0; -} - -void -zebra_mpls_lsp_schedule (struct zebra_vrf *zvrf) -{ -} - -void -zebra_mpls_print_lsp (struct vty *vty, struct zebra_vrf *zvrf, mpls_label_t label, - u_char use_json) -{ -} - -void -zebra_mpls_print_lsp_table (struct vty *vty, struct zebra_vrf *zvrf, - u_char use_json) -{ -} - -int -zebra_mpls_write_lsp_config (struct vty *vty, struct zebra_vrf *zvrf) -{ - return 0; -} - -void -zebra_mpls_close_tables (struct zebra_vrf *zvrf) -{ -} - -void -zebra_mpls_init_tables (struct zebra_vrf *zvrf) -{ -} - -void -zebra_mpls_init (void) -{ -} +int kernel_add_lsp (zebra_lsp_t *lsp) { return 0; } +int kernel_upd_lsp (zebra_lsp_t *lsp) { return 0; } +int kernel_del_lsp (zebra_lsp_t *lsp) { return 0; }