]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd-set-somark.patch
authorDonald Sharp <sharpd@cumulusnetworks.com>
Fri, 12 Jun 2015 14:59:11 +0000 (07:59 -0700)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Fri, 12 Jun 2015 14:59:11 +0000 (07:59 -0700)
BGP: Set SO_MARK on connecting sockets to ensure lookup in right routing table

In the presence of a function such as management VRF/MRF, bgpd needs to be able
to specify that it intends to run in the dataplane and not the front panel.
To ensure this, we add a mark in the connecting socket so that the kernel
does the routing lookup in the right table. This assumes that an appropriate
ip rule has been configured (outside the scope of this package).

While we've forced the mark to be 254 for now, it maybe required to make it
configurable at a later time.

bgpd/bgp_network.c
lib/sockunion.c
lib/sockunion.h

index 68934655f09948631e5397c493b9b48f7dacd8ef..c65119489c50ed9e0612b90ca5b625664f8970cd 100644 (file)
@@ -440,6 +440,8 @@ bgp_update_source (struct peer *peer)
     sockunion_bind (peer->fd, peer->update_source, 0, peer->update_source);
 }
 
+#define DATAPLANE_MARK 254     /* main table ID */
+
 /* BGP try to connect to the peer.  */
 int
 bgp_connect (struct peer *peer)
@@ -466,6 +468,9 @@ bgp_connect (struct peer *peer)
 
   sockopt_reuseaddr (peer->fd);
   sockopt_reuseport (peer->fd);
+  if (sockopt_mark_default(peer->fd, DATAPLANE_MARK, &bgpd_privs) < 0)
+    zlog_warn("Unable to set mark on FD for peer %s, err=%s", peer->host,
+             safe_strerror(errno));
   
 #ifdef IPTOS_PREC_INTERNETCONTROL
   if (bgpd_privs.change (ZPRIVS_RAISE))
index efd41362c6c723bc62850455ebb27eee72c4f080..59c5ba5dd0658d865a907115d9bba59ba76dac0d 100644 (file)
@@ -496,6 +496,25 @@ sockopt_cork (int sock, int onoff)
 #endif
 }
 
+int sockopt_mark_default(int sock, int mark, struct zebra_privs_t *cap)
+{
+#ifdef SO_MARK
+  int ret;
+
+  if ( cap->change (ZPRIVS_RAISE) )
+    zlog_err ("routing_socket: Can't raise privileges");
+
+  ret = setsockopt(sock, SOL_SOCKET, SO_MARK, &mark, sizeof(mark));
+
+  if ( cap->change (ZPRIVS_LOWER) )
+    zlog_err ("routing_socket: Can't lower privileges");
+
+  return ret;
+#else
+  return 0;
+#endif
+}
+
 int
 sockopt_minttl (int family, int sock, int minttl)
 {
index 8f0a9be37c1c34256416981032a2dfe1a878b420..78356e4cb76b62c6a73fe0f09520a6c82cceebd2 100644 (file)
@@ -23,6 +23,8 @@
 #ifndef _ZEBRA_SOCKUNION_H
 #define _ZEBRA_SOCKUNION_H
 
+#include "privs.h"
+
 #if 0
 union sockunion {
   struct sockinet {
@@ -99,6 +101,7 @@ extern int sockunion_bind (int sock, union sockunion *,
 extern int sockopt_ttl (int family, int sock, int ttl);
 extern int sockopt_minttl (int family, int sock, int minttl);
 extern int sockopt_cork (int sock, int onoff);
+extern int sockopt_mark_default(int sock, int mark, struct zebra_privs_t *);
 extern int sockunion_socket (union sockunion *su);
 extern const char *inet_sutop (union sockunion *su, char *str);
 extern enum connect_result sockunion_connect (int fd, union sockunion *su,