]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd: Implement BGP confederation error handling (RFC5065, Par. 5)
authorVasilis Tsiligiannis <b_tsiligiannis@silverton.gr>
Sun, 19 Jul 2009 22:28:35 +0000 (01:28 +0300)
committerPaul Jakma <paul@quagga.net>
Tue, 28 Jul 2009 13:49:33 +0000 (14:49 +0100)
This patch implements BGP confederation error handling in Quagga as described
in RFC5065, paragraph 5.

* bgp_aspath.c: (aspath_confed_check, aspath_left_confed_check) new functions
* bgp_attr.c: (bgp_attr_aspath_check) apply previous and NOTIFY if there's
  a problem.

bgpd/bgp_aspath.c
bgpd/bgp_aspath.h
bgpd/bgp_attr.c

index 13f32b8675ee0bba34928e3c11251dd3d99b1e9e..e65541f977d98dabd90f8026d8cc3d1d2e9967a3 100644 (file)
@@ -1122,6 +1122,42 @@ aspath_private_as_check (struct aspath *aspath)
   return 1;
 }
 
+/* AS path confed check.  If aspath contains confed set or sequence then return 1. */
+int
+aspath_confed_check (struct aspath *aspath)
+{
+  struct assegment *seg;
+
+  if ( !(aspath && aspath->segments) )
+    return 0;
+
+  seg = aspath->segments;
+
+  while (seg)
+    {
+      if (seg->type == AS_CONFED_SET || seg->type == AS_CONFED_SEQUENCE)
+         return 1;
+      seg = seg->next;
+    }
+  return 0;
+}
+
+/* Leftmost AS path segment confed check.  If leftmost AS segment is of type
+  AS_CONFED_SEQUENCE or AS_CONFED_SET then return 1.  */
+int
+aspath_left_confed_check (struct aspath *aspath)
+{
+
+  if ( !(aspath && aspath->segments) )
+    return 0;
+
+  if ( (aspath->segments->type == AS_CONFED_SEQUENCE)
+      || (aspath->segments->type == AS_CONFED_SET) )
+    return 1;
+
+  return 0;
+}
+
 /* Merge as1 to as2.  as2 should be uninterned aspath. */
 static struct aspath *
 aspath_merge (struct aspath *as1, struct aspath *as2)
index 2b4625c8fae6ffd6d594371389114e14cf116183..9854d1867e1c49606b877955d38a73d2baf4ab0d 100644 (file)
@@ -88,6 +88,8 @@ extern unsigned int aspath_key_make (void *);
 extern int aspath_loop_check (struct aspath *, as_t);
 extern int aspath_private_as_check (struct aspath *);
 extern int aspath_firstas_check (struct aspath *, as_t);
+extern int aspath_confed_check (struct aspath *);
+extern int aspath_left_confed_check (struct aspath *);
 extern unsigned long aspath_count (void);
 extern unsigned int aspath_count_hops (struct aspath *);
 extern unsigned int aspath_count_confeds (struct aspath *);
index 9416837288b5f47bf69a447dffaf1ac4df81a189..a664858c5d700ac3a5010bea4d29ba2f023217f1 100644 (file)
@@ -872,6 +872,17 @@ static int bgp_attr_aspath_check( struct peer *peer,
 
   bgp = peer->bgp;
     
+  /* Confederation sanity check. */
+  if ((peer_sort (peer) == BGP_PEER_CONFED && ! aspath_left_confed_check (attr->aspath)) ||
+     (peer_sort (peer) == BGP_PEER_EBGP && aspath_confed_check (attr->aspath)))
+    {
+      zlog (peer->log, LOG_ERR, "Malformed AS path from %s", peer->host);
+      bgp_notify_send (peer, 
+                      BGP_NOTIFY_UPDATE_ERR, 
+                      BGP_NOTIFY_UPDATE_MAL_AS_PATH);
+      return -1;
+    }
+
   /* First AS check for EBGP. */
   if (bgp != NULL && bgp_flag_check (bgp, BGP_FLAG_ENFORCE_FIRST_AS))
     {