Commit 6b0f5f68 authored by Maria Jan Matejka's avatar Maria Jan Matejka Committed by Ondrej Zajicek (work)
Browse files

Switchoff for MPLS in kernel.

parent 67a2eb91
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -31,6 +31,41 @@ AC_DEFUN([BIRD_CHECK_PTHREADS],
  CFLAGS="$bird_tmp_cflags"
])

AC_DEFUN([BIRD_CHECK_MPLS_KERNEL],
[
  AC_CACHE_CHECK(
    [for Linux MPLS headers],
    [bird_cv_mpls_kernel],
    [
      AC_COMPILE_IFELSE(
	[
	  AC_LANG_PROGRAM(
	    [
	      #include <linux/lwtunnel.h>
	      #include <linux/netlink.h>
	      #include <linux/rtnetlink.h>
	      #include <sys/socket.h>
	      void t(int arg);
	    ],
	    [
	      t(AF_MPLS);
	      t(RTA_VIA);
	      t(RTA_NEWDST);
	      t(RTA_ENCAP_TYPE);
	      t(RTA_ENCAP);
	      struct rtvia rtvia;
	      t(LWTUNNEL_ENCAP_MPLS);
	    ]
	  )
	],
	[bird_cv_mpls_kernel=yes],
	[bird_cv_mpls_kernel=no]
      )
    ]
  )
])


AC_DEFUN([BIRD_CHECK_GCC_OPTION],
[
  bird_tmp_cflags="$CFLAGS"
+21 −12
Original line number Diff line number Diff line
@@ -36,6 +36,12 @@ AC_ARG_ENABLE([libssh],
  [enable_libssh=try]
)

AC_ARG_ENABLE([mpls-kernel],
  [AS_HELP_STRING([--enable-mpls-kernel], [enable MPLS support in kernel protocol @<:@try@:>@])],
  [],
  [enable_mpls_kernel=try]
)

AC_ARG_WITH([protocols],
  [AS_HELP_STRING([--with-protocols=LIST], [include specified routing protocols @<:@all@:>@])],
  [],
@@ -239,6 +245,20 @@ if test "$enable_libssh" != no ; then
  fi
fi

if test "$enable_mpls_kernel" != no ; then
  BIRD_CHECK_MPLS_KERNEL

  if test "$bird_cv_mpls_kernel" = yes ; then
    AC_DEFINE([HAVE_MPLS_KERNEL], [1], [Define to 1 if kernel is MPLS capable])
  elif test "$enable_mpls_kernel" = yes ; then
    AC_MSG_ERROR([Kernel MPLS support not found.])
  fi

  if test "$enable_mpls_kernel" = try ; then
    enable_mpls_kernel="$bird_cv_mpls_kernel"
  fi
fi

all_protocols="$proto_bfd babel bgp ospf pipe radv rip $proto_rpki static"

all_protocols=`echo $all_protocols | sed 's/ /,/g'`
@@ -287,18 +307,6 @@ esac
AC_CHECK_HEADERS_ONCE([alloca.h syslog.h])
AC_CHECK_MEMBERS([struct sockaddr.sa_len], [], [], [#include <sys/socket.h>])

AC_CHECK_HEADERS([linux/lwtunnel.h],
  [AC_DEFINE([HAVE_LWTUNNEL], [1], [Define to 1 if you have the <linux/lwtunnel.h> header file.])],
  [],
  [] dnl Force new AC_CHECK_HEADER semantics
)

AC_CHECK_MEMBERS([struct rtvia.rtvia_family],
  [AC_DEFINE([HAVE_STRUCT_RTVIA], [1], [Define to 1 if you have rtvia structure.])],
  [],
  [#include <linux/rtnetlink.h>]
)

AC_C_BIGENDIAN(
  [AC_DEFINE([CPU_BIG_ENDIAN], [1], [Define to 1 if cpu is big endian])],
  [AC_DEFINE([CPU_LITTLE_ENDIAN], [1], [Define to 1 if cpu is little endian])],
@@ -396,6 +404,7 @@ AC_MSG_RESULT([ System configuration: $sysdesc])
AC_MSG_RESULT([        Debugging:		$enable_debug])
AC_MSG_RESULT([        POSIX threads:		$enable_pthreads])
AC_MSG_RESULT([        Routing protocols:	$protocols])
AC_MSG_RESULT([        Kernel MPLS support:	$enable_mpls_kernel])
AC_MSG_RESULT([        Client:			$enable_client])

rm -f $objdir/.*-stamp

sysdep/linux/lwtunnel.h

deleted100644 → 0
+0 −45
Original line number Diff line number Diff line
#ifndef _LWTUNNEL_H_
#define _LWTUNNEL_H_

#include <linux/types.h>

enum lwtunnel_encap_types {
	LWTUNNEL_ENCAP_NONE,
	LWTUNNEL_ENCAP_MPLS,
	LWTUNNEL_ENCAP_IP,
	LWTUNNEL_ENCAP_ILA,
	LWTUNNEL_ENCAP_IP6,
	__LWTUNNEL_ENCAP_MAX,
};

#define LWTUNNEL_ENCAP_MAX (__LWTUNNEL_ENCAP_MAX - 1)

enum lwtunnel_ip_t {
	LWTUNNEL_IP_UNSPEC,
	LWTUNNEL_IP_ID,
	LWTUNNEL_IP_DST,
	LWTUNNEL_IP_SRC,
	LWTUNNEL_IP_TTL,
	LWTUNNEL_IP_TOS,
	LWTUNNEL_IP_FLAGS,
	LWTUNNEL_IP_PAD,
	__LWTUNNEL_IP_MAX,
};

#define LWTUNNEL_IP_MAX (__LWTUNNEL_IP_MAX - 1)

enum lwtunnel_ip6_t {
	LWTUNNEL_IP6_UNSPEC,
	LWTUNNEL_IP6_ID,
	LWTUNNEL_IP6_DST,
	LWTUNNEL_IP6_SRC,
	LWTUNNEL_IP6_HOPLIMIT,
	LWTUNNEL_IP6_TC,
	LWTUNNEL_IP6_FLAGS,
	LWTUNNEL_IP6_PAD,
	__LWTUNNEL_IP6_MAX,
};

#define LWTUNNEL_IP6_MAX (__LWTUNNEL_IP6_MAX - 1)

#endif /* _LWTUNNEL_H_ */
+46 −25
Original line number Diff line number Diff line
@@ -30,14 +30,12 @@

#include <asm/types.h>
#include <linux/if.h>
#ifdef HAVE_LWTUNNEL
#include <linux/lwtunnel.h>
#else
#include "sysdep/linux/lwtunnel.h"
#endif
#include <linux/netlink.h>
#include <linux/rtnetlink.h>

#ifdef HAVE_MPLS_KERNEL
#include <linux/lwtunnel.h>
#endif

#ifndef MSG_TRUNC			/* Hack: Several versions of glibc miss this one :( */
#define MSG_TRUNC 0x20
@@ -59,13 +57,6 @@
#define RTA_VIA	 18
#endif

#ifndef HAVE_STRUCT_RTVIA
struct rtvia {
	unsigned short	rtvia_family;
	u8		rtvia_addr[0];
};
#endif

#ifndef RTA_NEWDST
#define RTA_NEWDST  19
#endif
@@ -361,9 +352,11 @@ static struct nl_want_attrs nexthop_attr_want6[BIRD_RTA_MAX] = {
  [RTA_ENCAP]	  = { 1, 0, 0 },
};

#ifdef HAVE_MPLS_KERNEL
static struct nl_want_attrs encap_mpls_want[BIRD_RTA_MAX] = {
  [RTA_DST]       = { 1, 0, 0 },
};
#endif

static struct nl_want_attrs rtm_attr_want4[BIRD_RTA_MAX] = {
  [RTA_DST]	  = { 1, 1, sizeof(ip4_addr) },
@@ -394,6 +387,7 @@ static struct nl_want_attrs rtm_attr_want6[BIRD_RTA_MAX] = {
  [RTA_ENCAP]	  = { 1, 0, 0 },
};

#ifdef HAVE_MPLS_KERNEL
static struct nl_want_attrs rtm_attr_want_mpls[BIRD_RTA_MAX] = {
  [RTA_DST]	  = { 1, 1, sizeof(u32) },
  [RTA_IIF]	  = { 1, 1, sizeof(u32) },
@@ -405,6 +399,7 @@ static struct nl_want_attrs rtm_attr_want_mpls[BIRD_RTA_MAX] = {
  [RTA_VIA]	  = { 1, 0, 0 },
  [RTA_NEWDST]	  = { 1, 0, 0 },
};
#endif


static int
@@ -456,6 +451,7 @@ static inline ip_addr rta_get_ipa(struct rtattr *a)
    return ipa_from_ip6(rta_get_ip6(a));
}

#ifdef HAVE_MPLS_KERNEL
static inline ip_addr rta_get_via(struct rtattr *a)
{
  struct rtvia *v = RTA_DATA(a);
@@ -474,6 +470,7 @@ static inline int rta_get_mpls(struct rtattr *a, u32 *stack)

  return mpls_get(RTA_DATA(a), RTA_PAYLOAD(a) & ~0x3, stack);
}
#endif

struct rtattr *
nl_add_attr(struct nlmsghdr *h, uint bufsize, uint code, const void *data, uint dlen)
@@ -542,6 +539,7 @@ nl_add_attr_ipa(struct nlmsghdr *h, uint bufsize, int code, ip_addr ipa)
    nl_add_attr_ip6(h, bufsize, code, ipa_to_ip6(ipa));
}

#ifdef HAVE_MPLS_KERNEL
static inline void
nl_add_attr_mpls(struct nlmsghdr *h, uint bufsize, int code, int len, u32 *stack)
{
@@ -583,6 +581,7 @@ nl_add_attr_via(struct nlmsghdr *h, uint bufsize, ip_addr ipa)

  nl_close_attr(h, nest);
}
#endif

static inline struct rtnexthop *
nl_open_nexthop(struct nlmsghdr *h, uint bufsize)
@@ -605,8 +604,9 @@ nl_close_nexthop(struct nlmsghdr *h, struct rtnexthop *nh)
}

static inline void
nl_add_nexthop(struct nlmsghdr *h, uint bufsize, struct nexthop *nh, int af)
nl_add_nexthop(struct nlmsghdr *h, uint bufsize, struct nexthop *nh, int af UNUSED)
{
#ifdef HAVE_MPLS_KERNEL
  if (nh->labels > 0)
    if (af == AF_MPLS)
      nl_add_attr_mpls(h, bufsize, RTA_NEWDST, nh->labels, nh->label);
@@ -618,6 +618,11 @@ nl_add_nexthop(struct nlmsghdr *h, uint bufsize, struct nexthop *nh, int af)
      nl_add_attr_via(h, bufsize, nh->gw);
    else
      nl_add_attr_ipa(h, bufsize, RTA_GATEWAY, nh->gw);
#else

  if (ipa_nonzero(nh->gw))
    nl_add_attr_ipa(h, bufsize, RTA_GATEWAY, nh->gw);
#endif
}

static void
@@ -716,6 +721,7 @@ nl_parse_multipath(struct krt_proto *p, struct rtattr *ra, int af)
      else
	rv->gw = IPA_NONE;

#ifdef HAVE_MPLS_KERNEL
      if (a[RTA_ENCAP_TYPE])
      {
	if (rta_get_u16(a[RTA_ENCAP_TYPE]) != LWTUNNEL_ENCAP_MPLS) {
@@ -729,6 +735,7 @@ nl_parse_multipath(struct krt_proto *p, struct rtattr *ra, int af)
	rv->labels = rta_get_mpls(enca[RTA_DST], rv->label);
	break;
      }
#endif


      len -= NLMSG_ALIGN(nh->rtnh_len);
@@ -1216,12 +1223,14 @@ nl_send_route(struct krt_proto *p, rte *e, struct ea_list *eattrs, int op, int d
  r->r.rtm_dst_len = net_pxlen(net->n.addr);
  r->r.rtm_protocol = RTPROT_BIRD;
  r->r.rtm_scope = RT_SCOPE_NOWHERE;
#ifdef HAVE_MPLS_KERNEL
  if (p->af == AF_MPLS)
  {
    u32 label = net_mpls(net->n.addr);
    nl_add_attr_mpls(&r->h, rsize, RTA_DST, 1, &label);
  }
  else
#endif
    nl_add_attr_ipa(&r->h, rsize, RTA_DST, net_prefix(net->n.addr));

  /*
@@ -1490,6 +1499,7 @@ nl_parse_route(struct nl_parse_state *s, struct nlmsghdr *h)
	net_fill_ip6(&dst, IP6_NONE, 0);
      break;

#ifdef HAVE_MPLS_KERNEL
    case AF_MPLS:
      if (!nl_parse_attrs(RTM_RTA(i), rtm_attr_want_mpls, a, sizeof(a)))
	return;
@@ -1502,6 +1512,7 @@ nl_parse_route(struct nl_parse_state *s, struct nlmsghdr *h)

      net_fill_mpls(&dst, rta_mpls_stack[0]);
      break;
#endif

    default:
      return;
@@ -1595,11 +1606,17 @@ nl_parse_route(struct nl_parse_state *s, struct nlmsghdr *h)
	  return;
	}

      if ((i->rtm_family != AF_MPLS) && a[RTA_GATEWAY] || (i->rtm_family == AF_MPLS) && a[RTA_VIA])
      if ((i->rtm_family != AF_MPLS) && a[RTA_GATEWAY]
#ifdef HAVE_MPLS_KERNEL
	  || (i->rtm_family == AF_MPLS) && a[RTA_VIA]
#endif
	  )
	{
#ifdef HAVE_MPLS_KERNEL
	  if (i->rtm_family == AF_MPLS)
	    ra->nh.gw = rta_get_via(a[RTA_VIA]);
	  else
#endif
	    ra->nh.gw = rta_get_ipa(a[RTA_GATEWAY]);

	  /* Silently skip strange 6to4 routes */
@@ -1637,6 +1654,7 @@ nl_parse_route(struct nl_parse_state *s, struct nlmsghdr *h)
      return;
    }

#ifdef HAVE_MPLS_KERNEL
  int labels = 0;
  if ((i->rtm_family == AF_MPLS) && a[RTA_NEWDST] && !ra->nh.next)
    labels = rta_get_mpls(a[RTA_NEWDST], ra->nh.label);
@@ -1666,6 +1684,7 @@ nl_parse_route(struct nl_parse_state *s, struct nlmsghdr *h)
  }
  else
    ra->nh.labels = labels;
#endif

  rte *e = rte_get_temp(ra);
  e->net = net;
@@ -1816,6 +1835,7 @@ krt_do_scan(struct krt_proto *p UNUSED) /* CONFIG_ALL_TABLES_AT_ONCE => p is NUL
      log(L_DEBUG "nl_scan_fire: Unknown packet received (type=%d)", h->nlmsg_type);
  nl_parse_end(&s);

#ifdef HAVE_MPLS_KERNEL
  nl_parse_begin(&s, 1, 1);
  nl_request_dump(AF_MPLS, RTM_GETROUTE);
  while (h = nl_get_scan())
@@ -1824,6 +1844,7 @@ krt_do_scan(struct krt_proto *p UNUSED) /* CONFIG_ALL_TABLES_AT_ONCE => p is NUL
    else
      log(L_DEBUG "nl_scan_fire: Unknown packet received (type=%d)", h->nlmsg_type);
  nl_parse_end(&s);
#endif
}

/*
+4 −0
Original line number Diff line number Diff line
@@ -1211,7 +1211,11 @@ struct protocol proto_unix_kernel = {
  .template =		"kernel%d",
  .attr_class =		EAP_KRT,
  .preference =		DEF_PREF_INHERITED,
#ifdef HAVE_MPLS_KERNEL
  .channel_mask =	NB_IP | NB_MPLS,
#else
  .channel_mask =	NB_IP,
#endif
  .proto_size =		sizeof(struct krt_proto),
  .config_size =	sizeof(struct krt_config),
  .preconfig =		krt_preconfig,